LCOV - code coverage report
Current view: top level - EnergyPlus - CostEstimateManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 23.7 % 587 139
Test Date: 2025-05-22 16:09:37 Functions: 100.0 % 5 5

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <algorithm>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : #include <ObjexxFCL/Array1D.hh>
      54              : #include <ObjexxFCL/member.functions.hh>
      55              : 
      56              : // EnergyPlus Headers
      57              : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
      58              : #include <EnergyPlus/Construction.hh>
      59              : #include <EnergyPlus/CostEstimateManager.hh>
      60              : #include <EnergyPlus/DXCoils.hh>
      61              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      62              : // #include <EnergyPlus/DataDaylighting.hh>
      63              : #include <EnergyPlus/DataHeatBalance.hh>
      64              : #include <EnergyPlus/DataIPShortCuts.hh>
      65              : #include <EnergyPlus/DataPhotovoltaics.hh>
      66              : #include <EnergyPlus/DataSurfaces.hh>
      67              : #include <EnergyPlus/DaylightingManager.hh>
      68              : #include <EnergyPlus/HeatingCoils.hh>
      69              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      70              : #include <EnergyPlus/PlantChillers.hh>
      71              : #include <EnergyPlus/UtilityRoutines.hh>
      72              : 
      73              : namespace EnergyPlus {
      74              : 
      75              : namespace CostEstimateManager {
      76              : 
      77              :     // Module containing the routines dealing with the Cost Estimation capability of EnergyPlus
      78              : 
      79              :     // MODULE INFORMATION:
      80              :     //       AUTHOR         B. Griffith
      81              :     //       DATE WRITTEN   April-May 2004
      82              :     //       MODIFIED       na
      83              :     //       RE-ENGINEERED  na
      84              : 
      85              :     // PURPOSE OF THIS MODULE:
      86              :     // produce a construction cost estimate report based on
      87              :     // input and certain building calculations by EnergyPlus
      88              : 
      89              :     // METHODOLOGY EMPLOYED:
      90              :     // Routine gets called once, Just before tabular reports.
      91              :     // Cost Estimate objects are child objects that will inherit from
      92              :     // other input objects.
      93              :     // Uses a Line Item metaphor where each Cost Estimate object is a line
      94              :     // Create report using utility subroutines taken from OutputReportTabular (by J.Glazer)
      95              : 
      96              :     // Using/Aliasing
      97              : 
      98              :     constexpr std::array<std::string_view, static_cast<int>(ParentObject::Num)> ParentObjectNamesUC{"GENERAL",
      99              :                                                                                                     "CONSTRUCTION",
     100              :                                                                                                     "COIL:DX",
     101              :                                                                                                     "COIL:COOLING:DX",
     102              :                                                                                                     "COIL:COOLING:DX:SINGLESPEED",
     103              :                                                                                                     "COIL:HEATING:FUEL",
     104              :                                                                                                     "CHILLER:ELECTRIC",
     105              :                                                                                                     "DAYLIGHTING:CONTROLS",
     106              :                                                                                                     "SHADING:ZONE:DETAILED",
     107              :                                                                                                     "LIGHTS",
     108              :                                                                                                     "GENERATOR:PHOTOVOLTAIC"};
     109              : 
     110          162 :     void SimCostEstimate(EnergyPlusData &state)
     111              :     {
     112              : 
     113              :         // SUBROUTINE INFORMATION:
     114              :         //       AUTHOR         BGriffith
     115              :         //       DATE WRITTEN   April 2004
     116              :         //       MODIFIED       na
     117              :         //       RE-ENGINEERED  na
     118              : 
     119              :         // PURPOSE OF THIS SUBROUTINE:
     120              :         // Entry point; manage calls to other subroutines
     121              : 
     122          162 :         if (state.dataCostEstimateManager->GetCostInput) {
     123           89 :             GetCostEstimateInput(state);
     124           89 :             state.dataCostEstimateManager->GetCostInput = false;
     125              :         }
     126              : 
     127              :         // Need to add check Costs before this will work properly
     128              : 
     129          162 :         if (state.dataGlobal->KickOffSimulation) return;
     130              : 
     131           77 :         if (state.dataCostEstimateManager->DoCostEstimate) {
     132            0 :             CalcCostEstimate(state);
     133              :         }
     134              :     }
     135              : 
     136           90 :     void GetCostEstimateInput(EnergyPlusData &state)
     137              :     {
     138              : 
     139              :         // SUBROUTINE INFORMATION:
     140              :         //       AUTHOR         BGriffith
     141              :         //       DATE WRITTEN   April 2004
     142              :         //       MODIFIED       na
     143              :         //       RE-ENGINEERED  na
     144              : 
     145              :         // PURPOSE OF THIS SUBROUTINE:
     146              :         // Get Cost Estimation object input.
     147              : 
     148              :         // Using/Aliasing
     149              : 
     150              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     151              :         int Item; // Item to be "gotten"
     152              :         int NumCostAdjust;
     153              :         int NumRefAdjust;
     154              :         int NumAlphas;           // Number of Alphas for each GetObjectItem call
     155              :         int NumNumbers;          // Number of Numbers for each GetObjectItem call
     156              :         int IOStatus;            // Used in GetObjectItem
     157           90 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
     158              : 
     159           90 :         int NumLineItems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ComponentCost:LineItem");
     160              : 
     161           90 :         if (NumLineItems == 0) {
     162           89 :             state.dataCostEstimateManager->DoCostEstimate = false;
     163           89 :             return;
     164              :         } else {
     165            1 :             state.dataCostEstimateManager->DoCostEstimate = true;
     166              :             //    WriteTabularFiles = .TRUE.
     167              :         }
     168              : 
     169            1 :         if (!allocated(state.dataCostEstimateManager->CostLineItem)) {
     170            1 :             state.dataCostEstimateManager->CostLineItem.allocate(NumLineItems);
     171              :         }
     172            1 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     173            1 :         cCurrentModuleObject = "ComponentCost:LineItem";
     174              : 
     175            7 :         for (Item = 1; Item <= NumLineItems; ++Item) {
     176           12 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     177              :                                                                      cCurrentModuleObject,
     178              :                                                                      Item,
     179            6 :                                                                      state.dataIPShortCut->cAlphaArgs,
     180              :                                                                      NumAlphas,
     181            6 :                                                                      state.dataIPShortCut->rNumericArgs,
     182              :                                                                      NumNumbers,
     183              :                                                                      IOStatus);
     184            6 :             state.dataCostEstimateManager->CostLineItem(Item).LineName = state.dataIPShortCut->cAlphaArgs(1);
     185            6 :             state.dataCostEstimateManager->CostLineItem(Item).ParentObjType =
     186            6 :                 static_cast<ParentObject>(getEnumValue(ParentObjectNamesUC, state.dataIPShortCut->cAlphaArgs(3)));
     187            6 :             state.dataCostEstimateManager->CostLineItem(Item).ParentObjName = state.dataIPShortCut->cAlphaArgs(4);
     188            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerEach = state.dataIPShortCut->rNumericArgs(1);
     189            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter = state.dataIPShortCut->rNumericArgs(2);
     190            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap = state.dataIPShortCut->rNumericArgs(3);
     191            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP = state.dataIPShortCut->rNumericArgs(4);
     192            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerCubicMeter = state.dataIPShortCut->rNumericArgs(5);
     193            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerCubMeterPerSec = state.dataIPShortCut->rNumericArgs(6);
     194            6 :             state.dataCostEstimateManager->CostLineItem(Item).PerUAinWattperDelK = state.dataIPShortCut->rNumericArgs(7);
     195            6 :             state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataIPShortCut->rNumericArgs(8);
     196              :         }
     197              : 
     198              :         // most input error checking to be performed later within Case construct in Calc routine.
     199              : 
     200            1 :         cCurrentModuleObject = "ComponentCost:Adjustments";
     201            1 :         NumCostAdjust = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     202            1 :         if (NumCostAdjust == 1) {
     203            0 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     204              :                                                                      cCurrentModuleObject,
     205              :                                                                      1,
     206            0 :                                                                      state.dataIPShortCut->cAlphaArgs,
     207              :                                                                      NumAlphas,
     208            0 :                                                                      state.dataIPShortCut->rNumericArgs,
     209              :                                                                      NumNumbers,
     210              :                                                                      IOStatus);
     211            0 :             state.dataCostEstimateManager->CurntBldg.MiscCostperSqMeter = state.dataIPShortCut->rNumericArgs(1);
     212            0 :             state.dataCostEstimateManager->CurntBldg.DesignFeeFrac = state.dataIPShortCut->rNumericArgs(2);
     213            0 :             state.dataCostEstimateManager->CurntBldg.ContractorFeeFrac = state.dataIPShortCut->rNumericArgs(3);
     214            0 :             state.dataCostEstimateManager->CurntBldg.ContingencyFrac = state.dataIPShortCut->rNumericArgs(4);
     215            0 :             state.dataCostEstimateManager->CurntBldg.BondCostFrac = state.dataIPShortCut->rNumericArgs(5);
     216            0 :             state.dataCostEstimateManager->CurntBldg.CommissioningFrac = state.dataIPShortCut->rNumericArgs(6);
     217            0 :             state.dataCostEstimateManager->CurntBldg.RegionalModifier = state.dataIPShortCut->rNumericArgs(7);
     218              : 
     219            1 :         } else if (NumCostAdjust > 1) {
     220            0 :             ShowSevereError(state, format("{}: Only one instance of this object is allowed.", cCurrentModuleObject));
     221            0 :             ErrorsFound = true;
     222              :         }
     223              : 
     224            1 :         cCurrentModuleObject = "ComponentCost:Reference";
     225            1 :         NumRefAdjust = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     226            1 :         if (NumRefAdjust == 1) {
     227            0 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     228              :                                                                      cCurrentModuleObject,
     229              :                                                                      1,
     230            0 :                                                                      state.dataIPShortCut->cAlphaArgs,
     231              :                                                                      NumAlphas,
     232            0 :                                                                      state.dataIPShortCut->rNumericArgs,
     233              :                                                                      NumNumbers,
     234              :                                                                      IOStatus);
     235            0 :             state.dataCostEstimateManager->RefrncBldg.LineItemTot = state.dataIPShortCut->rNumericArgs(1);
     236            0 :             state.dataCostEstimateManager->RefrncBldg.MiscCostperSqMeter = state.dataIPShortCut->rNumericArgs(2);
     237            0 :             state.dataCostEstimateManager->RefrncBldg.DesignFeeFrac = state.dataIPShortCut->rNumericArgs(3);
     238            0 :             state.dataCostEstimateManager->RefrncBldg.ContractorFeeFrac = state.dataIPShortCut->rNumericArgs(4);
     239            0 :             state.dataCostEstimateManager->RefrncBldg.ContingencyFrac = state.dataIPShortCut->rNumericArgs(5);
     240            0 :             state.dataCostEstimateManager->RefrncBldg.BondCostFrac = state.dataIPShortCut->rNumericArgs(6);
     241            0 :             state.dataCostEstimateManager->RefrncBldg.CommissioningFrac = state.dataIPShortCut->rNumericArgs(7);
     242            0 :             state.dataCostEstimateManager->RefrncBldg.RegionalModifier = state.dataIPShortCut->rNumericArgs(8);
     243              : 
     244            1 :         } else if (NumRefAdjust > 1) {
     245            0 :             ShowSevereError(state, format("{} : Only one instance of this object is allowed.", cCurrentModuleObject));
     246            0 :             ErrorsFound = true;
     247              :         }
     248              : 
     249            1 :         if (ErrorsFound) {
     250            0 :             ShowFatalError(state, "Errors found in processing cost estimate input");
     251              :         }
     252              : 
     253            1 :         CheckCostEstimateInput(state, ErrorsFound);
     254              : 
     255            1 :         if (ErrorsFound) {
     256            0 :             ShowFatalError(state, "Errors found in processing cost estimate input");
     257              :         }
     258              :     }
     259              : 
     260            1 :     void CheckCostEstimateInput(EnergyPlusData &state, bool &ErrorsFound) // Set to true if errors in input, fatal at end of routine
     261              :     {
     262              : 
     263              :         // SUBROUTINE INFORMATION:
     264              :         //       AUTHOR         BGriffith
     265              :         //       DATE WRITTEN   April 2004
     266              :         //       MODIFIED       February 2005, M. J. Witte
     267              :         //                        Add subscript to DX coil variables due to new multimode DX coil
     268              :         //       RE-ENGINEERED  na
     269              : 
     270              :         // PURPOSE OF THIS SUBROUTINE:
     271              :         // Calculates the Cost Estimate based on inputs.
     272              : 
     273              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     274              :         int Item;            // do-loop counter for line items
     275              :         int ThisConstructID; // hold result of FindItem searching for Construct name
     276              :         int ThisSurfID;      // hold result from findItem
     277              :         int ThisZoneID;      // hold result from findItem
     278              : 
     279            1 :         std::string ThisConstructStr;
     280            1 :         auto &Zone(state.dataHeatBal->Zone);
     281              : 
     282              :         int thisCoil; // index of named coil in its derived type
     283              :         int thisChil;
     284              :         int thisPV;
     285              : 
     286              :         // Setup working data structure for line items
     287            7 :         for (Item = 1; Item <= (int)state.dataCostEstimateManager->CostLineItem.size(); ++Item) { // Loop thru cost line items
     288              : 
     289            6 :             state.dataCostEstimateManager->CostLineItem(Item).LineNumber = Item;
     290              : 
     291            6 :             switch (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType) {
     292            0 :             case ParentObject::General: {
     293            0 :             } break;
     294            0 :             case ParentObject::Construction: {
     295              : 
     296              :                 // test input for problems
     297              :                 //  is PerSquareMeter non-zero? if it is are other cost per values set?
     298              :                 //   issue warning that 'Cost Estimate requested for Constructions with zero cost per unit area
     299            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter == 0) {
     300            0 :                     ShowSevereError(state,
     301            0 :                                     format("ComponentCost:LineItem: \"{}\" Construction object needs non-zero construction costs per square meter",
     302            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     303            0 :                     ErrorsFound = true;
     304              :                 }
     305              : 
     306            0 :                 ThisConstructStr = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     307            0 :                 ThisConstructID = Util::FindItem(ThisConstructStr, state.dataConstruction->Construct);
     308            0 :                 if (ThisConstructID == 0) { // do any surfaces have the specified construction? If not issue warning.
     309            0 :                     ShowWarningError(state,
     310            0 :                                      format("ComponentCost:LineItem: \"{}\" Construction=\"{}\", no surfaces have the Construction specified",
     311            0 :                                             state.dataCostEstimateManager->CostLineItem(Item).LineName,
     312            0 :                                             state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     313            0 :                     ShowContinueError(state, "No costs will be calculated for this Construction.");
     314              :                     //        ErrorsFound = .TRUE.
     315            0 :                     continue;
     316              :                 }
     317            0 :             } break;
     318            6 :             case ParentObject::CoilDX:
     319              :             case ParentObject::CoilCoolingDX:
     320              :             case ParentObject::CoilCoolingDXSingleSpeed: {
     321              :                 // test if too many pricing methods are set in user input
     322            8 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     323            2 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     324            0 :                     ShowSevereError(state,
     325            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     326            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     327            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     328            0 :                     ErrorsFound = true;
     329              :                 }
     330            8 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     331            2 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     332            0 :                     ShowSevereError(state,
     333            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     334            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     335            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     336            0 :                     ErrorsFound = true;
     337              :                 }
     338            8 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) &&
     339            2 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     340            0 :                     ShowSevereError(state,
     341            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     342            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     343            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     344            0 :                     ErrorsFound = true;
     345              :                 }
     346              :                 //  check for wildcard * in object name..
     347            6 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     348              : 
     349            3 :                 } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     350            0 :                     ShowSevereError(state,
     351            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     352            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     353            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     354            0 :                     ErrorsFound = true;
     355              : 
     356              :                 } else { // assume name is probably useful
     357            3 :                     bool coilFound = false;
     358            3 :                     auto &parentObjName = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     359            6 :                     if ((state.dataCostEstimateManager->CostLineItem(Item).ParentObjType == ParentObject::CoilDX) ||
     360            3 :                         (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType == ParentObject::CoilCoolingDXSingleSpeed)) {
     361            0 :                         if (Util::FindItem(parentObjName, state.dataDXCoils->DXCoil) > 0) coilFound = true;
     362            3 :                     } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType == ParentObject::CoilCoolingDX) {
     363            3 :                         if (CoilCoolingDX::factory(state, parentObjName) != -1) {
     364            3 :                             coilFound = true;
     365              :                         }
     366              :                     }
     367            3 :                     if (!coilFound) {
     368            0 :                         ShowWarningError(
     369              :                             state,
     370            0 :                             format("ComponentCost:LineItem: \"{}\", {}, invalid coil specified",
     371            0 :                                    state.dataCostEstimateManager->CostLineItem(Item).LineName,
     372            0 :                                    ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     373            0 :                         ShowContinueError(state,
     374            0 :                                           format("Coil Specified=\"{}\", calculations will not be completed for this item.",
     375            0 :                                                  state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     376              :                     }
     377              :                 }
     378            6 :             } break;
     379            0 :             case ParentObject::CoilHeatingFuel: {
     380              :                 // test if too many pricing methods are set in user input
     381            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     382            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     383            0 :                     ShowSevereError(state,
     384            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, too many pricing methods specified",
     385            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     386            0 :                     ErrorsFound = true;
     387              :                 }
     388            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     389            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     390            0 :                     ShowSevereError(state,
     391            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, too many pricing methods specified",
     392            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     393            0 :                     ErrorsFound = true;
     394              :                 }
     395            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) &&
     396            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     397            0 :                     ShowSevereError(state,
     398            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, too many pricing methods specified",
     399            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     400            0 :                     ErrorsFound = true;
     401              :                 }
     402              :                 //  check for wildcard * in object name..
     403            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     404              : 
     405            0 :                 } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     406            0 :                     ShowSevereError(state,
     407            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, need to specify a Reference Object Name",
     408            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     409            0 :                     ErrorsFound = true;
     410              : 
     411              :                 } else { // assume name is probably useful
     412            0 :                     thisCoil = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataHeatingCoils->HeatingCoil);
     413            0 :                     if (thisCoil == 0) {
     414            0 :                         ShowWarningError(state,
     415            0 :                                          format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, invalid coil specified",
     416            0 :                                                 state.dataCostEstimateManager->CostLineItem(Item).LineName));
     417            0 :                         ShowContinueError(state,
     418            0 :                                           format("Coil Specified=\"{}\", calculations will not be completed for this item.",
     419            0 :                                                  state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     420              :                     }
     421              :                 }
     422            0 :             } break;
     423            0 :             case ParentObject::ChillerElectric: {
     424            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     425            0 :                     ShowSevereError(state,
     426            0 :                                     format("ComponentCost:LineItem: \"{}\", Chiller:Electric, need to specify a Reference Object Name",
     427            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     428            0 :                     ErrorsFound = true;
     429              :                 }
     430            0 :                 thisChil = 0;
     431            0 :                 int chillNum = 0;
     432            0 :                 for (auto const &ch : state.dataPlantChillers->ElectricChiller) {
     433            0 :                     chillNum++;
     434            0 :                     if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == ch.Name) {
     435            0 :                         thisChil = chillNum;
     436              :                     }
     437              :                 }
     438            0 :                 if (thisChil == 0) {
     439            0 :                     ShowWarningError(state,
     440            0 :                                      format("ComponentCost:LineItem: \"{}\", Chiller:Electric, invalid chiller specified.",
     441            0 :                                             state.dataCostEstimateManager->CostLineItem(Item).LineName));
     442            0 :                     ShowContinueError(state,
     443            0 :                                       format("Chiller Specified=\"{}\", calculations will not be completed for this item.",
     444            0 :                                              state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     445              :                 }
     446            0 :             } break;
     447            0 :             case ParentObject::DaylightingControls: {
     448            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     449            0 :                 } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     450            0 :                     ShowSevereError(state,
     451            0 :                                     format("ComponentCost:LineItem: \"{}\", Daylighting:Controls, need to specify a Reference Object Name",
     452            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     453            0 :                     ErrorsFound = true;
     454              :                 } else {
     455            0 :                     ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     456            0 :                     if (ThisZoneID > 0) {
     457            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDayltg->ZoneDaylight(ThisZoneID).totRefPts;
     458              :                     } else {
     459            0 :                         ShowSevereError(state,
     460            0 :                                         format("ComponentCost:LineItem: \"{}\", Daylighting:Controls, need to specify a valid zone name",
     461            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     462            0 :                         ShowContinueError(state, format("Zone specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     463            0 :                         ErrorsFound = true;
     464              :                     }
     465              :                 }
     466            0 :             } break;
     467            0 :             case ParentObject::ShadingZoneDetailed: {
     468            0 :                 if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     469            0 :                     ThisSurfID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataSurface->Surface);
     470            0 :                     if (ThisSurfID > 0) {
     471            0 :                         ThisZoneID = Util::FindItem(state.dataSurface->Surface(ThisSurfID).ZoneName, Zone);
     472            0 :                         if (ThisZoneID == 0) {
     473            0 :                             ShowSevereError(state,
     474            0 :                                             format("ComponentCost:LineItem: \"{}\", Shading:Zone:Detailed, need to specify a valid zone name",
     475            0 :                                                    state.dataCostEstimateManager->CostLineItem(Item).LineName));
     476            0 :                             ShowContinueError(state, format("Zone specified=\"{}\".", state.dataSurface->Surface(ThisSurfID).ZoneName));
     477            0 :                             ErrorsFound = true;
     478              :                         }
     479              :                     } else {
     480            0 :                         ShowSevereError(state,
     481            0 :                                         format("ComponentCost:LineItem: \"{}\", Shading:Zone:Detailed, need to specify a valid surface name",
     482            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     483            0 :                         ShowContinueError(state,
     484            0 :                                           format("Surface specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     485            0 :                         ErrorsFound = true;
     486              :                     }
     487              :                 } else {
     488            0 :                     ShowSevereError(state,
     489            0 :                                     format("ComponentCost:LineItem: \"{}\", Shading:Zone:Detailed, specify a Reference Object Name",
     490            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     491            0 :                     ErrorsFound = true;
     492              :                 }
     493            0 :             } break;
     494            0 :             case ParentObject::Lights: {
     495            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     496            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     497            0 :                     ShowSevereError(state,
     498            0 :                                     format("ComponentCost:LineItem: \"{}\", Lights, too many pricing methods specified",
     499            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     500            0 :                     ErrorsFound = true;
     501              :                 }
     502            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     503            0 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     504            0 :                         ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     505            0 :                         if (ThisZoneID == 0) {
     506            0 :                             ShowSevereError(state,
     507            0 :                                             format("ComponentCost:LineItem: \"{}\", Lights, need to specify a valid zone name",
     508            0 :                                                    state.dataCostEstimateManager->CostLineItem(Item).LineName));
     509            0 :                             ShowContinueError(state,
     510            0 :                                               format("Zone specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     511            0 :                             ErrorsFound = true;
     512              :                         }
     513              :                     } else {
     514            0 :                         ShowSevereError(state,
     515            0 :                                         format("ComponentCost:LineItem: \"{}\", Lights, need to specify a Reference Object Name",
     516            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     517            0 :                         ErrorsFound = true;
     518              :                     }
     519              :                 }
     520            0 :             } break;
     521            0 :             case ParentObject::GeneratorPhotovoltaic: {
     522            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     523            0 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     524            0 :                         thisPV = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataPhotovoltaic->PVarray);
     525            0 :                         if (thisPV > 0) {
     526            0 :                             if (state.dataPhotovoltaic->PVarray(thisPV).PVModelType != DataPhotovoltaics::PVModel::Simple) {
     527            0 :                                 ShowSevereError(state,
     528            0 :                                                 format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, only available for model type "
     529              :                                                        "PhotovoltaicPerformance:Simple",
     530            0 :                                                        state.dataCostEstimateManager->CostLineItem(Item).LineName));
     531            0 :                                 ErrorsFound = true;
     532              :                             }
     533              :                         } else {
     534            0 :                             ShowSevereError(state,
     535            0 :                                             format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, need to specify a valid PV array",
     536            0 :                                                    state.dataCostEstimateManager->CostLineItem(Item).LineName));
     537            0 :                             ShowContinueError(state,
     538            0 :                                               format("PV Array specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     539            0 :                             ErrorsFound = true;
     540              :                         }
     541              :                     } else {
     542            0 :                         ShowSevereError(state,
     543            0 :                                         format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, need to specify a Reference Object Name",
     544            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     545            0 :                         ErrorsFound = true;
     546              :                     }
     547              :                 } else {
     548            0 :                     ShowSevereError(state,
     549            0 :                                     format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, need to specify a per-kilowatt cost ",
     550            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     551            0 :                     ErrorsFound = true;
     552              :                 }
     553            0 :             } break;
     554            0 :             default: {
     555            0 :                 ShowWarningError(state,
     556            0 :                                  format("ComponentCost:LineItem: \"{}\", invalid cost item -- not included in cost estimate.",
     557            0 :                                         state.dataCostEstimateManager->CostLineItem(Item).LineName));
     558            0 :                 ShowContinueError(
     559              :                     state,
     560            0 :                     format("... invalid object type={}",
     561            0 :                            format(ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)])));
     562            0 :             } break;
     563              :             }
     564              :         }
     565            1 :     }
     566              : 
     567            1 :     void CalcCostEstimate(EnergyPlusData &state)
     568              :     {
     569              : 
     570              :         // SUBROUTINE INFORMATION:
     571              :         //       AUTHOR         BGriffith
     572              :         //       DATE WRITTEN   April 2004
     573              :         //       MODIFIED       February 2005, M. J. Witte
     574              :         //                        Add subscript to DX coil variables due to new multimode DX coil
     575              :         //       RE-ENGINEERED  na
     576              : 
     577              :         // PURPOSE OF THIS SUBROUTINE:
     578              :         // Calculates the Cost Estimate based on inputs.
     579              : 
     580              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     581              :         int Item;            // do-loop counter for line items
     582              :         int ThisConstructID; // hold result of FindItem searching for Construct name
     583              :         int ThisSurfID;      // hold result from findItem
     584              :         int ThisZoneID;      // hold result from findItem
     585              : 
     586            1 :         auto &Zone(state.dataHeatBal->Zone);
     587            1 :         std::string ThisConstructStr;
     588              : 
     589            1 :         Array1D_bool uniqueSurfMask;
     590            1 :         Array1D<Real64> SurfMultipleARR;
     591              :         int surf;     // do-loop counter for checking for surfaces for uniqueness
     592              :         int thisCoil; // index of named coil in its derived type
     593              :         bool WildcardObjNames;
     594              :         int thisChil;
     595              :         int thisPV;
     596              :         Real64 Multipliers;
     597              : 
     598              :         // Setup working data structure for line items
     599            7 :         for (Item = 1; Item <= (int)state.dataCostEstimateManager->CostLineItem.size(); ++Item) { // Loop thru cost line items
     600              : 
     601            6 :             state.dataCostEstimateManager->CostLineItem(Item).LineNumber = Item;
     602              : 
     603            6 :             switch (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType) {
     604            0 :             case ParentObject::General: {
     605            0 :                 state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     606            0 :                 state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     607            0 :                 state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     608            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     609            0 :             } break;
     610            0 :             case ParentObject::Construction: {
     611            0 :                 ThisConstructStr = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     612            0 :                 ThisConstructID = Util::FindItem(ThisConstructStr, state.dataConstruction->Construct);
     613              :                 // need to determine unique surfaces... some surfaces are shared by zones and hence doubled
     614            0 :                 uniqueSurfMask.dimension(state.dataSurface->TotSurfaces, true); // init to true and change duplicates to false
     615            0 :                 SurfMultipleARR.dimension(state.dataSurface->TotSurfaces, 1.0);
     616            0 :                 for (surf = 1; surf <= state.dataSurface->TotSurfaces; ++surf) {
     617            0 :                     if (state.dataSurface->Surface(surf).ExtBoundCond >= 1) {
     618            0 :                         if (state.dataSurface->Surface(surf).ExtBoundCond < surf) { // already cycled through
     619            0 :                             uniqueSurfMask(surf) = false;
     620              :                         }
     621              :                     }
     622            0 :                     if (state.dataSurface->Surface(surf).Construction == 0) { // throw out others for now
     623            0 :                         uniqueSurfMask(surf) = false;
     624              :                     }
     625            0 :                     if (state.dataSurface->Surface(surf).Zone > 0) {
     626            0 :                         SurfMultipleARR(surf) =
     627            0 :                             Zone(state.dataSurface->Surface(surf).Zone).Multiplier * Zone(state.dataSurface->Surface(surf).Zone).ListMultiplier;
     628              :                     }
     629              :                 }
     630              :                 // determine which surfaces have the construction type  and if any are duplicates..
     631            0 :                 Real64 Qty(0.0);
     632            0 :                 for (int i = 1; i <= state.dataSurface->TotSurfaces; ++i) {
     633            0 :                     auto const &s(state.dataSurface->Surface(i));
     634            0 :                     if (uniqueSurfMask(i) && (s.Construction == ThisConstructID)) Qty += s.Area * SurfMultipleARR(i);
     635              :                 }
     636            0 :                 state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty;
     637            0 :                 state.dataCostEstimateManager->CostLineItem(Item).Units = "m2";
     638            0 :                 state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter;
     639            0 :                 state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     640            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     641              : 
     642            0 :                 uniqueSurfMask.deallocate();
     643            0 :                 SurfMultipleARR.deallocate();
     644            0 :             } break;
     645            0 :             case ParentObject::CoilDX:
     646              :             case ParentObject::CoilCoolingDXSingleSpeed: {
     647            0 :                 WildcardObjNames = false;
     648            0 :                 thisCoil = 0;
     649              :                 //  check for wildcard * in object name..
     650            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     651            0 :                     WildcardObjNames = true;
     652            0 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     653            0 :                     thisCoil = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataDXCoils->DXCoil);
     654              :                 }
     655              : 
     656            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) {
     657            0 :                     if (WildcardObjNames) {
     658            0 :                         Real64 Qty(0.0);
     659            0 :                         for (auto const &e : state.dataDXCoils->DXCoil)
     660            0 :                             Qty += e.RatedTotCap(1);
     661            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     662            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     663            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     664            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     665            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     666              :                     }
     667            0 :                     if (thisCoil > 0) {
     668            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDXCoils->DXCoil(thisCoil).RatedTotCap(1) / 1000.0;
     669            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     670            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     671            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     672            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     673              :                     }
     674              :                 }
     675              : 
     676            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) {
     677            0 :                     if (WildcardObjNames) state.dataCostEstimateManager->CostLineItem(Item).Qty = double(state.dataDXCoils->NumDXCoils);
     678            0 :                     if (thisCoil > 0) state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     679            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     680            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     681            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     682            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     683              :                 }
     684              : 
     685            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0) {
     686            0 :                     if (WildcardObjNames) {
     687            0 :                         Real64 Qty(0.0);
     688            0 :                         for (auto const &e : state.dataDXCoils->DXCoil) {
     689            0 :                             int maxSpeed = e.RatedCOP.size();
     690            0 :                             Qty += e.RatedCOP(maxSpeed) * e.RatedTotCap(maxSpeed);
     691              :                         }
     692            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     693            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     694            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     695            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     696            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     697              :                     }
     698            0 :                     if (thisCoil > 0) {
     699            0 :                         int maxSpeed = state.dataDXCoils->DXCoil(thisCoil).RatedCOP.size();
     700            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDXCoils->DXCoil(thisCoil).RatedCOP(maxSpeed) *
     701            0 :                                                                                 state.dataDXCoils->DXCoil(thisCoil).RatedTotCap(maxSpeed) / 1000.0;
     702            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     703            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     704            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     705            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     706              :                     }
     707              :                 }
     708            0 :             } break;
     709            6 :             case ParentObject::CoilCoolingDX: {
     710            6 :                 WildcardObjNames = false;
     711            6 :                 auto &parentObjName = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     712            6 :                 bool coilFound = false;
     713              :                 //  check for wildcard * in object name..
     714            6 :                 if (parentObjName == "*") { // wildcard, apply to all such components
     715            3 :                     WildcardObjNames = true;
     716            3 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     717              :                     // Purposefully not calling the factory here
     718              :                     // Input validation happens before we get to this point
     719              :                     // The factory throws a severe error when the coil is not found
     720              :                     // Finding the coil like this here to protects against another SevereError being thrown out of context
     721            3 :                     auto &v = state.dataCoilCoolingDX->coilCoolingDXs;
     722            3 :                     auto isInCoils = [&parentObjName](const CoilCoolingDX &coil) { return coil.name == parentObjName; };
     723            3 :                     auto it = std::find_if(v.begin(), v.end(), isInCoils);
     724            3 :                     if (it != v.end()) {
     725            3 :                         thisCoil = std::distance(v.begin(), it);
     726            3 :                         coilFound = true;
     727              :                     }
     728              :                 }
     729              : 
     730            6 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) {
     731            2 :                     if (WildcardObjNames) {
     732            1 :                         Real64 Qty(0.0);
     733            2 :                         for (auto const &e : state.dataCoilCoolingDX->coilCoolingDXs)
     734            1 :                             Qty += e.performance.normalMode.ratedGrossTotalCap;
     735            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     736            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     737            1 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     738            1 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     739            1 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     740              :                     }
     741            2 :                     if (coilFound) {
     742            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty =
     743            1 :                             state.dataCoilCoolingDX->coilCoolingDXs[thisCoil].performance.normalMode.ratedGrossTotalCap / 1000.0;
     744            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     745            1 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     746            1 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     747            1 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     748              :                     }
     749              :                 }
     750              : 
     751            6 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) {
     752            2 :                     if (WildcardObjNames)
     753            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = double(state.dataCoilCoolingDX->coilCoolingDXs.size());
     754            2 :                     if (coilFound) state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     755            2 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     756            2 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     757            2 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     758            2 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     759              :                 }
     760              : 
     761            6 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0) {
     762            2 :                     if (WildcardObjNames) {
     763            1 :                         Real64 Qty(0.0);
     764            2 :                         for (auto const &e : state.dataCoilCoolingDX->coilCoolingDXs) {
     765            1 :                             auto const &maxSpeed = e.performance.normalMode.speeds.back();
     766            1 :                             Real64 COP = maxSpeed.original_input_specs.gross_rated_cooling_COP;
     767            1 :                             Qty += COP * e.performance.normalMode.ratedGrossTotalCap;
     768              :                         }
     769            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     770            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     771            1 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     772            1 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     773            1 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     774              :                     }
     775            2 :                     if (coilFound) {
     776            1 :                         auto const &maxSpeed = state.dataCoilCoolingDX->coilCoolingDXs[thisCoil].performance.normalMode.speeds.back();
     777            1 :                         Real64 COP = maxSpeed.original_input_specs.gross_rated_cooling_COP;
     778            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty =
     779            1 :                             COP * state.dataCoilCoolingDX->coilCoolingDXs[thisCoil].performance.normalMode.ratedGrossTotalCap / 1000.0;
     780            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     781            1 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     782            1 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     783            1 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     784              :                     }
     785              :                 }
     786            6 :             } break;
     787            0 :             case ParentObject::CoilHeatingFuel: {
     788            0 :                 WildcardObjNames = false;
     789            0 :                 thisCoil = 0;
     790              :                 //  check for wildcard * in object name..
     791            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     792            0 :                     WildcardObjNames = true;
     793            0 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     794            0 :                     thisCoil = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataHeatingCoils->HeatingCoil);
     795              :                 }
     796              : 
     797            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) {
     798            0 :                     if (WildcardObjNames) {
     799            0 :                         Real64 Qty(0.0);
     800            0 :                         for (auto const &e : state.dataHeatingCoils->HeatingCoil)
     801            0 :                             if (e.HCoilType_Num == 1) Qty += e.NominalCapacity;
     802            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     803            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot heat cap.)";
     804            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     805            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     806            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     807              :                     }
     808            0 :                     if (thisCoil > 0) {
     809            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty =
     810            0 :                             state.dataHeatingCoils->HeatingCoil(thisCoil).NominalCapacity / 1000.0;
     811            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot heat cap.)";
     812            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     813            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     814            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     815              :                     }
     816              :                 }
     817              : 
     818            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) {
     819            0 :                     if (WildcardObjNames) state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataHeatingCoils->NumHeatingCoils;
     820            0 :                     if (thisCoil > 0) state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     821            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     822            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     823            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     824            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     825              :                 }
     826              : 
     827            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0) {
     828            0 :                     if (WildcardObjNames) {
     829            0 :                         Real64 Qty(0.0);
     830            0 :                         for (auto const &e : state.dataHeatingCoils->HeatingCoil)
     831            0 :                             if (e.HCoilType_Num == 1) Qty += e.Efficiency * e.NominalCapacity;
     832            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     833            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*Eff (total, rated) ";
     834            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     835            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     836            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     837              :                     }
     838            0 :                     if (thisCoil > 0) {
     839            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataHeatingCoils->HeatingCoil(thisCoil).Efficiency *
     840            0 :                                                                                 state.dataHeatingCoils->HeatingCoil(thisCoil).NominalCapacity /
     841              :                                                                                 1000.0;
     842            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*Eff (total, rated) ";
     843            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     844            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     845            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     846              :                     }
     847              :                 }
     848            0 :             } break;
     849            0 :             case ParentObject::ChillerElectric: {
     850            0 :                 thisChil = 0;
     851            0 :                 int chillNum = 0;
     852            0 :                 for (auto const &ch : state.dataPlantChillers->ElectricChiller) {
     853            0 :                     chillNum++;
     854            0 :                     if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == ch.Name) {
     855            0 :                         thisChil = chillNum;
     856              :                     }
     857              :                 }
     858            0 :                 if ((thisChil > 0) && (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0)) {
     859            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataPlantChillers->ElectricChiller(thisChil).NomCap / 1000.0;
     860            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     861            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     862            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     863            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     864              :                 }
     865            0 :                 if ((thisChil > 0) && (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     866            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty =
     867            0 :                         state.dataPlantChillers->ElectricChiller(thisChil).COP * state.dataPlantChillers->ElectricChiller(thisChil).NomCap / 1000.0;
     868            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     869            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     870            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     871            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     872              :                 }
     873            0 :                 if ((thisChil > 0) && (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     874            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     875            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     876            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     877            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     878            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     879              :                 }
     880            0 :             } break;
     881            0 :             case ParentObject::DaylightingControls: {
     882            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     883            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = sum(state.dataDayltg->ZoneDaylight, &Dayltg::ZoneDaylightCalc::totRefPts);
     884            0 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     885            0 :                     ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     886            0 :                     if (ThisZoneID > 0) {
     887            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDayltg->ZoneDaylight(ThisZoneID).totRefPts;
     888              :                     }
     889              :                 }
     890              : 
     891            0 :                 state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     892            0 :                 state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     893            0 :                 state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     894            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     895            0 :             } break;
     896            0 :             case ParentObject::ShadingZoneDetailed: {
     897            0 :                 if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     898            0 :                     ThisSurfID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataSurface->Surface);
     899            0 :                     if (ThisSurfID > 0) {
     900            0 :                         ThisZoneID = Util::FindItem(state.dataSurface->Surface(ThisSurfID).ZoneName, Zone);
     901            0 :                         if (ThisZoneID > 0) {
     902            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty =
     903            0 :                                 state.dataSurface->Surface(ThisSurfID).Area * Zone(ThisZoneID).Multiplier * Zone(ThisZoneID).ListMultiplier;
     904            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Units = "m2";
     905            0 :                             state.dataCostEstimateManager->CostLineItem(Item).ValuePer =
     906            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter;
     907            0 :                             state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     908            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     909              :                         }
     910              :                     }
     911              :                 }
     912            0 :             } break;
     913            0 :             case ParentObject::Lights: {
     914            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach != 0.0) {
     915            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     916            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     917            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     918            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     919            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     920              :                 }
     921              : 
     922            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     923            0 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     924            0 :                         ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     925            0 :                         if (ThisZoneID > 0) {
     926            0 :                             Real64 Qty(0.0);
     927            0 :                             for (auto const &e : state.dataHeatBal->Lights)
     928            0 :                                 if (e.ZonePtr == ThisZoneID) Qty += e.DesignLevel;
     929            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty =
     930            0 :                                 (Zone(ThisZoneID).Multiplier * Zone(ThisZoneID).ListMultiplier / 1000.0) *
     931              :                                 Qty; // this handles more than one light object per zone.
     932            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Units = "kW";
     933            0 :                             state.dataCostEstimateManager->CostLineItem(Item).ValuePer =
     934            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     935            0 :                             state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     936            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     937              :                         }
     938              :                     }
     939              :                 }
     940            0 :             } break;
     941            0 :             case ParentObject::GeneratorPhotovoltaic: {
     942            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     943            0 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     944            0 :                         thisPV = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataPhotovoltaic->PVarray);
     945            0 :                         if (thisPV > 0) {
     946              :                             ThisZoneID =
     947            0 :                                 Util::FindItem(state.dataSurface->Surface(state.dataPhotovoltaic->PVarray(thisPV).SurfacePtr).ZoneName, Zone);
     948            0 :                             if (ThisZoneID == 0) {
     949            0 :                                 Multipliers = 1.0;
     950              :                             } else {
     951            0 :                                 Multipliers = Zone(ThisZoneID).Multiplier * Zone(ThisZoneID).ListMultiplier;
     952              :                             }
     953            0 :                             if (state.dataPhotovoltaic->PVarray(thisPV).PVModelType == DataPhotovoltaics::PVModel::Simple) {
     954            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty =
     955            0 :                                     1000.0 * state.dataPhotovoltaic->PVarray(thisPV).SimplePVModule.AreaCol *
     956            0 :                                     state.dataPhotovoltaic->PVarray(thisPV).SimplePVModule.PVEfficiency * Multipliers / 1000.0;
     957              :                             }
     958            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (rated)";
     959            0 :                             state.dataCostEstimateManager->CostLineItem(Item).ValuePer =
     960            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     961            0 :                             state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     962            0 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     963              :                         }
     964              :                     }
     965              :                 }
     966            0 :             } break;
     967            0 :             default:
     968            0 :                 break;
     969              :             }
     970              :         }
     971              : 
     972              :         // now sum up the line items, result for the current building
     973              : 
     974            1 :         state.dataCostEstimateManager->CurntBldg.LineItemTot = sum(state.dataCostEstimateManager->CostLineItem, &CostLineItemStruct::LineSubTotal);
     975            1 :     }
     976              : 
     977              : } // namespace CostEstimateManager
     978              : 
     979              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1