LCOV - code coverage report
Current view: top level - EnergyPlus - CostEstimateManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 49.7 % 604 300
Test Date: 2025-06-02 07:23:51 Functions: 80.0 % 5 4

            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         1616 :     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         1616 :         if (state.dataCostEstimateManager->GetCostInput) {
     123          800 :             GetCostEstimateInput(state);
     124          800 :             state.dataCostEstimateManager->GetCostInput = false;
     125              :         }
     126              : 
     127              :         // Need to add check Costs before this will work properly
     128              : 
     129         1616 :         if (state.dataGlobal->KickOffSimulation) {
     130          817 :             return;
     131              :         }
     132              : 
     133          799 :         if (state.dataCostEstimateManager->DoCostEstimate) {
     134           40 :             CalcCostEstimate(state);
     135              :         }
     136              :     }
     137              : 
     138          800 :     void GetCostEstimateInput(EnergyPlusData &state)
     139              :     {
     140              : 
     141              :         // SUBROUTINE INFORMATION:
     142              :         //       AUTHOR         BGriffith
     143              :         //       DATE WRITTEN   April 2004
     144              :         //       MODIFIED       na
     145              :         //       RE-ENGINEERED  na
     146              : 
     147              :         // PURPOSE OF THIS SUBROUTINE:
     148              :         // Get Cost Estimation object input.
     149              : 
     150              :         // Using/Aliasing
     151              : 
     152              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     153              :         int Item; // Item to be "gotten"
     154              :         int NumCostAdjust;
     155              :         int NumRefAdjust;
     156              :         int NumAlphas;           // Number of Alphas for each GetObjectItem call
     157              :         int NumNumbers;          // Number of Numbers for each GetObjectItem call
     158              :         int IOStatus;            // Used in GetObjectItem
     159          800 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
     160              : 
     161          800 :         int NumLineItems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ComponentCost:LineItem");
     162              : 
     163          800 :         if (NumLineItems == 0) {
     164          759 :             state.dataCostEstimateManager->DoCostEstimate = false;
     165          759 :             return;
     166              :         } else {
     167           41 :             state.dataCostEstimateManager->DoCostEstimate = true;
     168              :             //    WriteTabularFiles = .TRUE.
     169              :         }
     170              : 
     171           41 :         if (!allocated(state.dataCostEstimateManager->CostLineItem)) {
     172           41 :             state.dataCostEstimateManager->CostLineItem.allocate(NumLineItems);
     173              :         }
     174           41 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     175           41 :         cCurrentModuleObject = "ComponentCost:LineItem";
     176              : 
     177         2969 :         for (Item = 1; Item <= NumLineItems; ++Item) {
     178         5856 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     179              :                                                                      cCurrentModuleObject,
     180              :                                                                      Item,
     181         2928 :                                                                      state.dataIPShortCut->cAlphaArgs,
     182              :                                                                      NumAlphas,
     183         2928 :                                                                      state.dataIPShortCut->rNumericArgs,
     184              :                                                                      NumNumbers,
     185              :                                                                      IOStatus);
     186         2928 :             state.dataCostEstimateManager->CostLineItem(Item).LineName = state.dataIPShortCut->cAlphaArgs(1);
     187         2928 :             state.dataCostEstimateManager->CostLineItem(Item).ParentObjType =
     188         2928 :                 static_cast<ParentObject>(getEnumValue(ParentObjectNamesUC, state.dataIPShortCut->cAlphaArgs(3)));
     189         2928 :             state.dataCostEstimateManager->CostLineItem(Item).ParentObjName = state.dataIPShortCut->cAlphaArgs(4);
     190         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerEach = state.dataIPShortCut->rNumericArgs(1);
     191         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter = state.dataIPShortCut->rNumericArgs(2);
     192         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap = state.dataIPShortCut->rNumericArgs(3);
     193         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP = state.dataIPShortCut->rNumericArgs(4);
     194         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerCubicMeter = state.dataIPShortCut->rNumericArgs(5);
     195         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerCubMeterPerSec = state.dataIPShortCut->rNumericArgs(6);
     196         2928 :             state.dataCostEstimateManager->CostLineItem(Item).PerUAinWattperDelK = state.dataIPShortCut->rNumericArgs(7);
     197         2928 :             state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataIPShortCut->rNumericArgs(8);
     198              :         }
     199              : 
     200              :         // most input error checking to be performed later within Case construct in Calc routine.
     201              : 
     202           41 :         cCurrentModuleObject = "ComponentCost:Adjustments";
     203           41 :         NumCostAdjust = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     204           41 :         if (NumCostAdjust == 1) {
     205           10 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     206              :                                                                      cCurrentModuleObject,
     207              :                                                                      1,
     208            5 :                                                                      state.dataIPShortCut->cAlphaArgs,
     209              :                                                                      NumAlphas,
     210            5 :                                                                      state.dataIPShortCut->rNumericArgs,
     211              :                                                                      NumNumbers,
     212              :                                                                      IOStatus);
     213            5 :             state.dataCostEstimateManager->CurntBldg.MiscCostperSqMeter = state.dataIPShortCut->rNumericArgs(1);
     214            5 :             state.dataCostEstimateManager->CurntBldg.DesignFeeFrac = state.dataIPShortCut->rNumericArgs(2);
     215            5 :             state.dataCostEstimateManager->CurntBldg.ContractorFeeFrac = state.dataIPShortCut->rNumericArgs(3);
     216            5 :             state.dataCostEstimateManager->CurntBldg.ContingencyFrac = state.dataIPShortCut->rNumericArgs(4);
     217            5 :             state.dataCostEstimateManager->CurntBldg.BondCostFrac = state.dataIPShortCut->rNumericArgs(5);
     218            5 :             state.dataCostEstimateManager->CurntBldg.CommissioningFrac = state.dataIPShortCut->rNumericArgs(6);
     219            5 :             state.dataCostEstimateManager->CurntBldg.RegionalModifier = state.dataIPShortCut->rNumericArgs(7);
     220              : 
     221           36 :         } else if (NumCostAdjust > 1) {
     222            0 :             ShowSevereError(state, format("{}: Only one instance of this object is allowed.", cCurrentModuleObject));
     223            0 :             ErrorsFound = true;
     224              :         }
     225              : 
     226           41 :         cCurrentModuleObject = "ComponentCost:Reference";
     227           41 :         NumRefAdjust = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     228           41 :         if (NumRefAdjust == 1) {
     229            2 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     230              :                                                                      cCurrentModuleObject,
     231              :                                                                      1,
     232            1 :                                                                      state.dataIPShortCut->cAlphaArgs,
     233              :                                                                      NumAlphas,
     234            1 :                                                                      state.dataIPShortCut->rNumericArgs,
     235              :                                                                      NumNumbers,
     236              :                                                                      IOStatus);
     237            1 :             state.dataCostEstimateManager->RefrncBldg.LineItemTot = state.dataIPShortCut->rNumericArgs(1);
     238            1 :             state.dataCostEstimateManager->RefrncBldg.MiscCostperSqMeter = state.dataIPShortCut->rNumericArgs(2);
     239            1 :             state.dataCostEstimateManager->RefrncBldg.DesignFeeFrac = state.dataIPShortCut->rNumericArgs(3);
     240            1 :             state.dataCostEstimateManager->RefrncBldg.ContractorFeeFrac = state.dataIPShortCut->rNumericArgs(4);
     241            1 :             state.dataCostEstimateManager->RefrncBldg.ContingencyFrac = state.dataIPShortCut->rNumericArgs(5);
     242            1 :             state.dataCostEstimateManager->RefrncBldg.BondCostFrac = state.dataIPShortCut->rNumericArgs(6);
     243            1 :             state.dataCostEstimateManager->RefrncBldg.CommissioningFrac = state.dataIPShortCut->rNumericArgs(7);
     244            1 :             state.dataCostEstimateManager->RefrncBldg.RegionalModifier = state.dataIPShortCut->rNumericArgs(8);
     245              : 
     246           40 :         } else if (NumRefAdjust > 1) {
     247            0 :             ShowSevereError(state, format("{} : Only one instance of this object is allowed.", cCurrentModuleObject));
     248            0 :             ErrorsFound = true;
     249              :         }
     250              : 
     251           41 :         if (ErrorsFound) {
     252            0 :             ShowFatalError(state, "Errors found in processing cost estimate input");
     253              :         }
     254              : 
     255           41 :         CheckCostEstimateInput(state, ErrorsFound);
     256              : 
     257           41 :         if (ErrorsFound) {
     258            0 :             ShowFatalError(state, "Errors found in processing cost estimate input");
     259              :         }
     260              :     }
     261              : 
     262           41 :     void CheckCostEstimateInput(EnergyPlusData &state, bool &ErrorsFound) // Set to true if errors in input, fatal at end of routine
     263              :     {
     264              : 
     265              :         // SUBROUTINE INFORMATION:
     266              :         //       AUTHOR         BGriffith
     267              :         //       DATE WRITTEN   April 2004
     268              :         //       MODIFIED       February 2005, M. J. Witte
     269              :         //                        Add subscript to DX coil variables due to new multimode DX coil
     270              :         //       RE-ENGINEERED  na
     271              : 
     272              :         // PURPOSE OF THIS SUBROUTINE:
     273              :         // Calculates the Cost Estimate based on inputs.
     274              : 
     275              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     276              :         int Item;            // do-loop counter for line items
     277              :         int ThisConstructID; // hold result of FindItem searching for Construct name
     278              :         int ThisSurfID;      // hold result from findItem
     279              :         int ThisZoneID;      // hold result from findItem
     280              : 
     281           41 :         std::string ThisConstructStr;
     282           41 :         auto &Zone(state.dataHeatBal->Zone);
     283              : 
     284              :         int thisCoil; // index of named coil in its derived type
     285              :         int thisChil;
     286              :         int thisPV;
     287              : 
     288              :         // Setup working data structure for line items
     289         2969 :         for (Item = 1; Item <= (int)state.dataCostEstimateManager->CostLineItem.size(); ++Item) { // Loop thru cost line items
     290              : 
     291         2928 :             state.dataCostEstimateManager->CostLineItem(Item).LineNumber = Item;
     292              : 
     293         2928 :             switch (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType) {
     294         1763 :             case ParentObject::General: {
     295         1763 :             } break;
     296          383 :             case ParentObject::Construction: {
     297              : 
     298              :                 // test input for problems
     299              :                 //  is PerSquareMeter non-zero? if it is are other cost per values set?
     300              :                 //   issue warning that 'Cost Estimate requested for Constructions with zero cost per unit area
     301          383 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter == 0) {
     302            0 :                     ShowSevereError(state,
     303            0 :                                     format("ComponentCost:LineItem: \"{}\" Construction object needs non-zero construction costs per square meter",
     304            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     305            0 :                     ErrorsFound = true;
     306              :                 }
     307              : 
     308          383 :                 ThisConstructStr = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     309          383 :                 ThisConstructID = Util::FindItem(ThisConstructStr, state.dataConstruction->Construct);
     310          383 :                 if (ThisConstructID == 0) { // do any surfaces have the specified construction? If not issue warning.
     311            2 :                     ShowWarningError(state,
     312            2 :                                      format("ComponentCost:LineItem: \"{}\" Construction=\"{}\", no surfaces have the Construction specified",
     313            1 :                                             state.dataCostEstimateManager->CostLineItem(Item).LineName,
     314            1 :                                             state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     315            2 :                     ShowContinueError(state, "No costs will be calculated for this Construction.");
     316              :                     //        ErrorsFound = .TRUE.
     317            1 :                     continue;
     318              :                 }
     319          382 :             } break;
     320            3 :             case ParentObject::CoilDX:
     321              :             case ParentObject::CoilCoolingDX:
     322              :             case ParentObject::CoilCoolingDXSingleSpeed: {
     323              :                 // test if too many pricing methods are set in user input
     324            4 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     325            1 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     326            0 :                     ShowSevereError(state,
     327            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     328            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     329            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     330            0 :                     ErrorsFound = true;
     331              :                 }
     332            4 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     333            1 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     334            0 :                     ShowSevereError(state,
     335            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     336            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     337            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     338            0 :                     ErrorsFound = true;
     339              :                 }
     340            4 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) &&
     341            1 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     342            0 :                     ShowSevereError(state,
     343            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     344            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     345            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     346            0 :                     ErrorsFound = true;
     347              :                 }
     348              :                 //  check for wildcard * in object name..
     349            3 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     350              : 
     351            0 :                 } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     352            0 :                     ShowSevereError(state,
     353            0 :                                     format("ComponentCost:LineItem: \"{}\", {}, too many pricing methods specified",
     354            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName,
     355            0 :                                            ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     356            0 :                     ErrorsFound = true;
     357              : 
     358              :                 } else { // assume name is probably useful
     359            0 :                     bool coilFound = false;
     360            0 :                     auto &parentObjName = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     361            0 :                     if ((state.dataCostEstimateManager->CostLineItem(Item).ParentObjType == ParentObject::CoilDX) ||
     362            0 :                         (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType == ParentObject::CoilCoolingDXSingleSpeed)) {
     363            0 :                         if (Util::FindItem(parentObjName, state.dataDXCoils->DXCoil) > 0) {
     364            0 :                             coilFound = true;
     365              :                         }
     366            0 :                     } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType == ParentObject::CoilCoolingDX) {
     367            0 :                         if (CoilCoolingDX::factory(state, parentObjName) != -1) {
     368            0 :                             coilFound = true;
     369              :                         }
     370              :                     }
     371            0 :                     if (!coilFound) {
     372            0 :                         ShowWarningError(
     373              :                             state,
     374            0 :                             format("ComponentCost:LineItem: \"{}\", {}, invalid coil specified",
     375            0 :                                    state.dataCostEstimateManager->CostLineItem(Item).LineName,
     376            0 :                                    ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)]));
     377            0 :                         ShowContinueError(state,
     378            0 :                                           format("Coil Specified=\"{}\", calculations will not be completed for this item.",
     379            0 :                                                  state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     380              :                     }
     381              :                 }
     382            3 :             } break;
     383            0 :             case ParentObject::CoilHeatingFuel: {
     384              :                 // test if too many pricing methods are set in user input
     385            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     386            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     387            0 :                     ShowSevereError(state,
     388            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, too many pricing methods specified",
     389            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     390            0 :                     ErrorsFound = true;
     391              :                 }
     392            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     393            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     394            0 :                     ShowSevereError(state,
     395            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, too many pricing methods specified",
     396            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     397            0 :                     ErrorsFound = true;
     398              :                 }
     399            0 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) &&
     400            0 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     401            0 :                     ShowSevereError(state,
     402            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, too many pricing methods specified",
     403            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     404            0 :                     ErrorsFound = true;
     405              :                 }
     406              :                 //  check for wildcard * in object name..
     407            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     408              : 
     409            0 :                 } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     410            0 :                     ShowSevereError(state,
     411            0 :                                     format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, need to specify a Reference Object Name",
     412            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     413            0 :                     ErrorsFound = true;
     414              : 
     415              :                 } else { // assume name is probably useful
     416            0 :                     thisCoil = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataHeatingCoils->HeatingCoil);
     417            0 :                     if (thisCoil == 0) {
     418            0 :                         ShowWarningError(state,
     419            0 :                                          format("ComponentCost:LineItem: \"{}\", Coil:Heating:Fuel, invalid coil specified",
     420            0 :                                                 state.dataCostEstimateManager->CostLineItem(Item).LineName));
     421            0 :                         ShowContinueError(state,
     422            0 :                                           format("Coil Specified=\"{}\", calculations will not be completed for this item.",
     423            0 :                                                  state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     424              :                     }
     425              :                 }
     426            0 :             } break;
     427            5 :             case ParentObject::ChillerElectric: {
     428            5 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     429            0 :                     ShowSevereError(state,
     430            0 :                                     format("ComponentCost:LineItem: \"{}\", Chiller:Electric, need to specify a Reference Object Name",
     431            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     432            0 :                     ErrorsFound = true;
     433              :                 }
     434            5 :                 thisChil = 0;
     435            5 :                 int chillNum = 0;
     436           10 :                 for (auto const &ch : state.dataPlantChillers->ElectricChiller) {
     437            5 :                     chillNum++;
     438            5 :                     if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == ch.Name) {
     439            5 :                         thisChil = chillNum;
     440              :                     }
     441            5 :                 }
     442            5 :                 if (thisChil == 0) {
     443            0 :                     ShowWarningError(state,
     444            0 :                                      format("ComponentCost:LineItem: \"{}\", Chiller:Electric, invalid chiller specified.",
     445            0 :                                             state.dataCostEstimateManager->CostLineItem(Item).LineName));
     446            0 :                     ShowContinueError(state,
     447            0 :                                       format("Chiller Specified=\"{}\", calculations will not be completed for this item.",
     448            0 :                                              state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     449              :                 }
     450            5 :             } break;
     451           73 :             case ParentObject::DaylightingControls: {
     452           73 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     453           73 :                 } else if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     454            0 :                     ShowSevereError(state,
     455            0 :                                     format("ComponentCost:LineItem: \"{}\", Daylighting:Controls, need to specify a Reference Object Name",
     456            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     457            0 :                     ErrorsFound = true;
     458              :                 } else {
     459           73 :                     ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     460           73 :                     if (ThisZoneID > 0) {
     461           73 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDayltg->ZoneDaylight(ThisZoneID).totRefPts;
     462              :                     } else {
     463            0 :                         ShowSevereError(state,
     464            0 :                                         format("ComponentCost:LineItem: \"{}\", Daylighting:Controls, need to specify a valid zone name",
     465            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     466            0 :                         ShowContinueError(state, format("Zone specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     467            0 :                         ErrorsFound = true;
     468              :                     }
     469              :                 }
     470           73 :             } break;
     471           40 :             case ParentObject::ShadingZoneDetailed: {
     472           40 :                 if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     473           40 :                     ThisSurfID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataSurface->Surface);
     474           40 :                     if (ThisSurfID > 0) {
     475           40 :                         ThisZoneID = Util::FindItem(state.dataSurface->Surface(ThisSurfID).ZoneName, Zone);
     476           40 :                         if (ThisZoneID == 0) {
     477            0 :                             ShowSevereError(state,
     478            0 :                                             format("ComponentCost:LineItem: \"{}\", Shading:Zone:Detailed, need to specify a valid zone name",
     479            0 :                                                    state.dataCostEstimateManager->CostLineItem(Item).LineName));
     480            0 :                             ShowContinueError(state, format("Zone specified=\"{}\".", state.dataSurface->Surface(ThisSurfID).ZoneName));
     481            0 :                             ErrorsFound = true;
     482              :                         }
     483              :                     } else {
     484            0 :                         ShowSevereError(state,
     485            0 :                                         format("ComponentCost:LineItem: \"{}\", Shading:Zone:Detailed, need to specify a valid surface name",
     486            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     487            0 :                         ShowContinueError(state,
     488            0 :                                           format("Surface specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     489            0 :                         ErrorsFound = true;
     490              :                     }
     491              :                 } else {
     492            0 :                     ShowSevereError(state,
     493            0 :                                     format("ComponentCost:LineItem: \"{}\", Shading:Zone:Detailed, specify a Reference Object Name",
     494            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     495            0 :                     ErrorsFound = true;
     496              :                 }
     497           40 :             } break;
     498          646 :             case ParentObject::Lights: {
     499         1292 :                 if ((state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) &&
     500          646 :                     (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     501            0 :                     ShowSevereError(state,
     502            0 :                                     format("ComponentCost:LineItem: \"{}\", Lights, too many pricing methods specified",
     503            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     504            0 :                     ErrorsFound = true;
     505              :                 }
     506          646 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     507          646 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     508          646 :                         ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     509          646 :                         if (ThisZoneID == 0) {
     510            0 :                             ShowSevereError(state,
     511            0 :                                             format("ComponentCost:LineItem: \"{}\", Lights, need to specify a valid zone name",
     512            0 :                                                    state.dataCostEstimateManager->CostLineItem(Item).LineName));
     513            0 :                             ShowContinueError(state,
     514            0 :                                               format("Zone specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     515            0 :                             ErrorsFound = true;
     516              :                         }
     517              :                     } else {
     518            0 :                         ShowSevereError(state,
     519            0 :                                         format("ComponentCost:LineItem: \"{}\", Lights, need to specify a Reference Object Name",
     520            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     521            0 :                         ErrorsFound = true;
     522              :                     }
     523              :                 }
     524          646 :             } break;
     525           15 :             case ParentObject::GeneratorPhotovoltaic: {
     526           15 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     527           15 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     528           15 :                         thisPV = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataPhotovoltaic->PVarray);
     529           15 :                         if (thisPV > 0) {
     530           15 :                             if (state.dataPhotovoltaic->PVarray(thisPV).PVModelType != DataPhotovoltaics::PVModel::Simple) {
     531            0 :                                 ShowSevereError(state,
     532            0 :                                                 format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, only available for model type "
     533              :                                                        "PhotovoltaicPerformance:Simple",
     534            0 :                                                        state.dataCostEstimateManager->CostLineItem(Item).LineName));
     535            0 :                                 ErrorsFound = true;
     536              :                             }
     537              :                         } else {
     538            0 :                             ShowSevereError(state,
     539            0 :                                             format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, need to specify a valid PV array",
     540            0 :                                                    state.dataCostEstimateManager->CostLineItem(Item).LineName));
     541            0 :                             ShowContinueError(state,
     542            0 :                                               format("PV Array specified=\"{}\".", state.dataCostEstimateManager->CostLineItem(Item).ParentObjName));
     543            0 :                             ErrorsFound = true;
     544              :                         }
     545              :                     } else {
     546            0 :                         ShowSevereError(state,
     547            0 :                                         format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, need to specify a Reference Object Name",
     548            0 :                                                state.dataCostEstimateManager->CostLineItem(Item).LineName));
     549            0 :                         ErrorsFound = true;
     550              :                     }
     551              :                 } else {
     552            0 :                     ShowSevereError(state,
     553            0 :                                     format("ComponentCost:LineItem: \"{}\", Generator:Photovoltaic, need to specify a per-kilowatt cost ",
     554            0 :                                            state.dataCostEstimateManager->CostLineItem(Item).LineName));
     555            0 :                     ErrorsFound = true;
     556              :                 }
     557           15 :             } break;
     558            0 :             default: {
     559            0 :                 ShowWarningError(state,
     560            0 :                                  format("ComponentCost:LineItem: \"{}\", invalid cost item -- not included in cost estimate.",
     561            0 :                                         state.dataCostEstimateManager->CostLineItem(Item).LineName));
     562            0 :                 ShowContinueError(
     563              :                     state,
     564            0 :                     format("... invalid object type={}",
     565            0 :                            format(ParentObjectNamesUC[static_cast<int>(state.dataCostEstimateManager->CostLineItem(Item).ParentObjType)])));
     566            0 :             } break;
     567              :             }
     568              :         }
     569           41 :     }
     570              : 
     571           40 :     void CalcCostEstimate(EnergyPlusData &state)
     572              :     {
     573              : 
     574              :         // SUBROUTINE INFORMATION:
     575              :         //       AUTHOR         BGriffith
     576              :         //       DATE WRITTEN   April 2004
     577              :         //       MODIFIED       February 2005, M. J. Witte
     578              :         //                        Add subscript to DX coil variables due to new multimode DX coil
     579              :         //       RE-ENGINEERED  na
     580              : 
     581              :         // PURPOSE OF THIS SUBROUTINE:
     582              :         // Calculates the Cost Estimate based on inputs.
     583              : 
     584              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     585              :         int Item;            // do-loop counter for line items
     586              :         int ThisConstructID; // hold result of FindItem searching for Construct name
     587              :         int ThisSurfID;      // hold result from findItem
     588              :         int ThisZoneID;      // hold result from findItem
     589              : 
     590           40 :         auto &Zone(state.dataHeatBal->Zone);
     591           40 :         std::string ThisConstructStr;
     592              : 
     593           40 :         Array1D_bool uniqueSurfMask;
     594           40 :         Array1D<Real64> SurfMultipleARR;
     595              :         int surf;     // do-loop counter for checking for surfaces for uniqueness
     596              :         int thisCoil; // index of named coil in its derived type
     597              :         bool WildcardObjNames;
     598              :         int thisChil;
     599              :         int thisPV;
     600              :         Real64 Multipliers;
     601              : 
     602              :         // Setup working data structure for line items
     603         2937 :         for (Item = 1; Item <= (int)state.dataCostEstimateManager->CostLineItem.size(); ++Item) { // Loop thru cost line items
     604              : 
     605         2897 :             state.dataCostEstimateManager->CostLineItem(Item).LineNumber = Item;
     606              : 
     607         2897 :             switch (state.dataCostEstimateManager->CostLineItem(Item).ParentObjType) {
     608         1748 :             case ParentObject::General: {
     609         1748 :                 state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     610         1748 :                 state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     611         1748 :                 state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     612         1748 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     613         1748 :             } break;
     614          372 :             case ParentObject::Construction: {
     615          372 :                 ThisConstructStr = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     616          372 :                 ThisConstructID = Util::FindItem(ThisConstructStr, state.dataConstruction->Construct);
     617              :                 // need to determine unique surfaces... some surfaces are shared by zones and hence doubled
     618          372 :                 uniqueSurfMask.dimension(state.dataSurface->TotSurfaces, true); // init to true and change duplicates to false
     619          372 :                 SurfMultipleARR.dimension(state.dataSurface->TotSurfaces, 1.0);
     620        62664 :                 for (surf = 1; surf <= state.dataSurface->TotSurfaces; ++surf) {
     621        62292 :                     if (state.dataSurface->Surface(surf).ExtBoundCond >= 1) {
     622        39212 :                         if (state.dataSurface->Surface(surf).ExtBoundCond < surf) { // already cycled through
     623         6969 :                             uniqueSurfMask(surf) = false;
     624              :                         }
     625              :                     }
     626        62292 :                     if (state.dataSurface->Surface(surf).Construction == 0) { // throw out others for now
     627          986 :                         uniqueSurfMask(surf) = false;
     628              :                     }
     629        62292 :                     if (state.dataSurface->Surface(surf).Zone > 0) {
     630        61306 :                         SurfMultipleARR(surf) =
     631        61306 :                             Zone(state.dataSurface->Surface(surf).Zone).Multiplier * Zone(state.dataSurface->Surface(surf).Zone).ListMultiplier;
     632              :                     }
     633              :                 }
     634              :                 // determine which surfaces have the construction type  and if any are duplicates..
     635          372 :                 Real64 Qty(0.0);
     636        62664 :                 for (int i = 1; i <= state.dataSurface->TotSurfaces; ++i) {
     637        62292 :                     auto const &s(state.dataSurface->Surface(i));
     638        62292 :                     if (uniqueSurfMask(i) && (s.Construction == ThisConstructID)) {
     639         5020 :                         Qty += s.Area * SurfMultipleARR(i);
     640              :                     }
     641              :                 }
     642          372 :                 state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty;
     643          372 :                 state.dataCostEstimateManager->CostLineItem(Item).Units = "m2";
     644          372 :                 state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter;
     645          372 :                 state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     646          372 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     647              : 
     648          372 :                 uniqueSurfMask.deallocate();
     649          372 :                 SurfMultipleARR.deallocate();
     650          372 :             } break;
     651            0 :             case ParentObject::CoilDX:
     652              :             case ParentObject::CoilCoolingDXSingleSpeed: {
     653            0 :                 WildcardObjNames = false;
     654            0 :                 thisCoil = 0;
     655              :                 //  check for wildcard * in object name..
     656            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     657            0 :                     WildcardObjNames = true;
     658            0 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     659            0 :                     thisCoil = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataDXCoils->DXCoil);
     660              :                 }
     661              : 
     662            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) {
     663            0 :                     if (WildcardObjNames) {
     664            0 :                         Real64 Qty(0.0);
     665            0 :                         for (auto const &e : state.dataDXCoils->DXCoil) {
     666            0 :                             Qty += e.RatedTotCap(1);
     667              :                         }
     668            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 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            0 :                     if (thisCoil > 0) {
     675            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDXCoils->DXCoil(thisCoil).RatedTotCap(1) / 1000.0;
     676            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     677            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     678            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     679            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     680              :                     }
     681              :                 }
     682              : 
     683            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) {
     684            0 :                     if (WildcardObjNames) {
     685            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = double(state.dataDXCoils->NumDXCoils);
     686              :                     }
     687            0 :                     if (thisCoil > 0) {
     688            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     689              :                     }
     690            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     691            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     692            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     693            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     694              :                 }
     695              : 
     696            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0) {
     697            0 :                     if (WildcardObjNames) {
     698            0 :                         Real64 Qty(0.0);
     699            0 :                         for (auto const &e : state.dataDXCoils->DXCoil) {
     700            0 :                             int maxSpeed = e.RatedCOP.size();
     701            0 :                             Qty += e.RatedCOP(maxSpeed) * e.RatedTotCap(maxSpeed);
     702              :                         }
     703            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     704            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     705            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     706            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     707            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     708              :                     }
     709            0 :                     if (thisCoil > 0) {
     710            0 :                         int maxSpeed = state.dataDXCoils->DXCoil(thisCoil).RatedCOP.size();
     711            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDXCoils->DXCoil(thisCoil).RatedCOP(maxSpeed) *
     712            0 :                                                                                 state.dataDXCoils->DXCoil(thisCoil).RatedTotCap(maxSpeed) / 1000.0;
     713            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     714            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     715            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     716            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     717              :                     }
     718              :                 }
     719            0 :             } break;
     720            3 :             case ParentObject::CoilCoolingDX: {
     721            3 :                 WildcardObjNames = false;
     722            3 :                 auto &parentObjName = state.dataCostEstimateManager->CostLineItem(Item).ParentObjName;
     723            3 :                 bool coilFound = false;
     724              :                 //  check for wildcard * in object name..
     725            3 :                 if (parentObjName == "*") { // wildcard, apply to all such components
     726            3 :                     WildcardObjNames = true;
     727            0 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     728              :                     // Purposefully not calling the factory here
     729              :                     // Input validation happens before we get to this point
     730              :                     // The factory throws a severe error when the coil is not found
     731              :                     // Finding the coil like this here to protects against another SevereError being thrown out of context
     732            0 :                     auto &v = state.dataCoilCoolingDX->coilCoolingDXs;
     733            0 :                     auto isInCoils = [&parentObjName](const CoilCoolingDX &coil) { return coil.name == parentObjName; };
     734            0 :                     auto it = std::find_if(v.begin(), v.end(), isInCoils);
     735            0 :                     if (it != v.end()) {
     736            0 :                         thisCoil = std::distance(v.begin(), it);
     737            0 :                         coilFound = true;
     738              :                     }
     739            0 :                 }
     740              : 
     741            3 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) {
     742            1 :                     if (WildcardObjNames) {
     743            1 :                         Real64 Qty(0.0);
     744            2 :                         for (auto const &e : state.dataCoilCoolingDX->coilCoolingDXs) {
     745            1 :                             Qty += e.performance.normalMode.ratedGrossTotalCap;
     746            1 :                         }
     747            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     748            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     749            1 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     750            1 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     751            1 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     752              :                     }
     753            1 :                     if (coilFound) {
     754            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty =
     755            0 :                             state.dataCoilCoolingDX->coilCoolingDXs[thisCoil].performance.normalMode.ratedGrossTotalCap / 1000.0;
     756            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     757            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     758            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     759            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     760              :                     }
     761              :                 }
     762              : 
     763            3 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) {
     764            1 :                     if (WildcardObjNames) {
     765            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = double(state.dataCoilCoolingDX->coilCoolingDXs.size());
     766              :                     }
     767            1 :                     if (coilFound) {
     768            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     769              :                     }
     770            1 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     771            1 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     772            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     773            1 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     774              :                 }
     775              : 
     776            3 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0) {
     777            1 :                     if (WildcardObjNames) {
     778            1 :                         Real64 Qty(0.0);
     779            2 :                         for (auto const &e : state.dataCoilCoolingDX->coilCoolingDXs) {
     780            1 :                             auto const &maxSpeed = e.performance.normalMode.speeds.back();
     781            1 :                             Real64 COP = maxSpeed.original_input_specs.gross_rated_cooling_COP;
     782            1 :                             Qty += COP * e.performance.normalMode.ratedGrossTotalCap;
     783            1 :                         }
     784            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     785            1 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     786            1 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     787            1 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     788            1 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     789              :                     }
     790            1 :                     if (coilFound) {
     791            0 :                         auto const &maxSpeed = state.dataCoilCoolingDX->coilCoolingDXs[thisCoil].performance.normalMode.speeds.back();
     792            0 :                         Real64 COP = maxSpeed.original_input_specs.gross_rated_cooling_COP;
     793            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty =
     794            0 :                             COP * state.dataCoilCoolingDX->coilCoolingDXs[thisCoil].performance.normalMode.ratedGrossTotalCap / 1000.0;
     795            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     796            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     797            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     798            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     799              :                     }
     800              :                 }
     801            3 :             } break;
     802            0 :             case ParentObject::CoilHeatingFuel: {
     803            0 :                 WildcardObjNames = false;
     804            0 :                 thisCoil = 0;
     805              :                 //  check for wildcard * in object name..
     806            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     807            0 :                     WildcardObjNames = true;
     808            0 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     809            0 :                     thisCoil = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataHeatingCoils->HeatingCoil);
     810              :                 }
     811              : 
     812            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0) {
     813            0 :                     if (WildcardObjNames) {
     814            0 :                         Real64 Qty(0.0);
     815            0 :                         for (auto const &e : state.dataHeatingCoils->HeatingCoil) {
     816            0 :                             if (e.HCoilType_Num == 1) {
     817            0 :                                 Qty += e.NominalCapacity;
     818              :                             }
     819              :                         }
     820            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     821            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot heat cap.)";
     822            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     823            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     824            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     825              :                     }
     826            0 :                     if (thisCoil > 0) {
     827            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty =
     828            0 :                             state.dataHeatingCoils->HeatingCoil(thisCoil).NominalCapacity / 1000.0;
     829            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot heat cap.)";
     830            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     831            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     832            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     833              :                     }
     834              :                 }
     835              : 
     836            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0) {
     837            0 :                     if (WildcardObjNames) {
     838            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataHeatingCoils->NumHeatingCoils;
     839              :                     }
     840            0 :                     if (thisCoil > 0) {
     841            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     842              :                     }
     843            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     844            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     845            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     846            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     847              :                 }
     848              : 
     849            0 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0) {
     850            0 :                     if (WildcardObjNames) {
     851            0 :                         Real64 Qty(0.0);
     852            0 :                         for (auto const &e : state.dataHeatingCoils->HeatingCoil) {
     853            0 :                             if (e.HCoilType_Num == 1) {
     854            0 :                                 Qty += e.Efficiency * e.NominalCapacity;
     855              :                             }
     856              :                         }
     857            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = Qty / 1000.0;
     858            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*Eff (total, rated) ";
     859            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     860            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     861            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     862              :                     }
     863            0 :                     if (thisCoil > 0) {
     864            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataHeatingCoils->HeatingCoil(thisCoil).Efficiency *
     865            0 :                                                                                 state.dataHeatingCoils->HeatingCoil(thisCoil).NominalCapacity /
     866              :                                                                                 1000.0;
     867            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*Eff (total, rated) ";
     868            0 :                         state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     869            0 :                         state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     870            0 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     871              :                     }
     872              :                 }
     873            0 :             } break;
     874            5 :             case ParentObject::ChillerElectric: {
     875            5 :                 thisChil = 0;
     876            5 :                 int chillNum = 0;
     877           10 :                 for (auto const &ch : state.dataPlantChillers->ElectricChiller) {
     878            5 :                     chillNum++;
     879            5 :                     if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == ch.Name) {
     880            5 :                         thisChil = chillNum;
     881              :                     }
     882            5 :                 }
     883            5 :                 if ((thisChil > 0) && (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap > 0.0)) {
     884            5 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataPlantChillers->ElectricChiller(thisChil).NomCap / 1000.0;
     885            5 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (tot cool cap.)";
     886            5 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     887            5 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     888            5 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     889              :                 }
     890            5 :                 if ((thisChil > 0) && (state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP > 0.0)) {
     891            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty =
     892            0 :                         state.dataPlantChillers->ElectricChiller(thisChil).COP * state.dataPlantChillers->ElectricChiller(thisChil).NomCap / 1000.0;
     893            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "kW*COP (total, rated) ";
     894            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerKWCapPerCOP;
     895            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     896            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     897              :                 }
     898            5 :                 if ((thisChil > 0) && (state.dataCostEstimateManager->CostLineItem(Item).PerEach > 0.0)) {
     899            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     900            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     901            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     902            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     903            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     904              :                 }
     905            5 :             } break;
     906           73 :             case ParentObject::DaylightingControls: {
     907           73 :                 if (state.dataCostEstimateManager->CostLineItem(Item).ParentObjName == "*") { // wildcard, apply to all such components
     908            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = sum(state.dataDayltg->ZoneDaylight, &Dayltg::ZoneDaylightCalc::totRefPts);
     909           73 :                 } else if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     910           73 :                     ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     911           73 :                     if (ThisZoneID > 0) {
     912           73 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty = state.dataDayltg->ZoneDaylight(ThisZoneID).totRefPts;
     913              :                     }
     914              :                 }
     915              : 
     916           73 :                 state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     917           73 :                 state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     918           73 :                 state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     919           73 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     920           73 :             } break;
     921           40 :             case ParentObject::ShadingZoneDetailed: {
     922           40 :                 if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     923           40 :                     ThisSurfID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataSurface->Surface);
     924           40 :                     if (ThisSurfID > 0) {
     925           40 :                         ThisZoneID = Util::FindItem(state.dataSurface->Surface(ThisSurfID).ZoneName, Zone);
     926           40 :                         if (ThisZoneID > 0) {
     927           40 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty =
     928           40 :                                 state.dataSurface->Surface(ThisSurfID).Area * Zone(ThisZoneID).Multiplier * Zone(ThisZoneID).ListMultiplier;
     929           40 :                             state.dataCostEstimateManager->CostLineItem(Item).Units = "m2";
     930           40 :                             state.dataCostEstimateManager->CostLineItem(Item).ValuePer =
     931           40 :                                 state.dataCostEstimateManager->CostLineItem(Item).PerSquareMeter;
     932           40 :                             state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     933           40 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     934              :                         }
     935              :                     }
     936              :                 }
     937           40 :             } break;
     938          641 :             case ParentObject::Lights: {
     939          641 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerEach != 0.0) {
     940            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Qty = 1.0;
     941            0 :                     state.dataCostEstimateManager->CostLineItem(Item).Units = "Ea.";
     942            0 :                     state.dataCostEstimateManager->CostLineItem(Item).ValuePer = state.dataCostEstimateManager->CostLineItem(Item).PerEach;
     943            0 :                     state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     944            0 :                         state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     945              :                 }
     946              : 
     947          641 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     948          641 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     949          641 :                         ThisZoneID = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, Zone);
     950          641 :                         if (ThisZoneID > 0) {
     951          641 :                             Real64 Qty(0.0);
     952        54096 :                             for (auto const &e : state.dataHeatBal->Lights) {
     953        53455 :                                 if (e.ZonePtr == ThisZoneID) {
     954          641 :                                     Qty += e.DesignLevel;
     955              :                                 }
     956          641 :                             }
     957          641 :                             state.dataCostEstimateManager->CostLineItem(Item).Qty =
     958          641 :                                 (Zone(ThisZoneID).Multiplier * Zone(ThisZoneID).ListMultiplier / 1000.0) *
     959              :                                 Qty; // this handles more than one light object per zone.
     960          641 :                             state.dataCostEstimateManager->CostLineItem(Item).Units = "kW";
     961          641 :                             state.dataCostEstimateManager->CostLineItem(Item).ValuePer =
     962          641 :                                 state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     963          641 :                             state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     964          641 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     965              :                         }
     966              :                     }
     967              :                 }
     968          641 :             } break;
     969           15 :             case ParentObject::GeneratorPhotovoltaic: {
     970           15 :                 if (state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap != 0.0) {
     971           15 :                     if (!state.dataCostEstimateManager->CostLineItem(Item).ParentObjName.empty()) {
     972           15 :                         thisPV = Util::FindItem(state.dataCostEstimateManager->CostLineItem(Item).ParentObjName, state.dataPhotovoltaic->PVarray);
     973           15 :                         if (thisPV > 0) {
     974              :                             ThisZoneID =
     975           15 :                                 Util::FindItem(state.dataSurface->Surface(state.dataPhotovoltaic->PVarray(thisPV).SurfacePtr).ZoneName, Zone);
     976           15 :                             if (ThisZoneID == 0) {
     977            0 :                                 Multipliers = 1.0;
     978              :                             } else {
     979           15 :                                 Multipliers = Zone(ThisZoneID).Multiplier * Zone(ThisZoneID).ListMultiplier;
     980              :                             }
     981           15 :                             if (state.dataPhotovoltaic->PVarray(thisPV).PVModelType == DataPhotovoltaics::PVModel::Simple) {
     982           15 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty =
     983           15 :                                     1000.0 * state.dataPhotovoltaic->PVarray(thisPV).SimplePVModule.AreaCol *
     984           15 :                                     state.dataPhotovoltaic->PVarray(thisPV).SimplePVModule.PVEfficiency * Multipliers / 1000.0;
     985              :                             }
     986           15 :                             state.dataCostEstimateManager->CostLineItem(Item).Units = "kW (rated)";
     987           15 :                             state.dataCostEstimateManager->CostLineItem(Item).ValuePer =
     988           15 :                                 state.dataCostEstimateManager->CostLineItem(Item).PerKiloWattCap;
     989           15 :                             state.dataCostEstimateManager->CostLineItem(Item).LineSubTotal =
     990           15 :                                 state.dataCostEstimateManager->CostLineItem(Item).Qty * state.dataCostEstimateManager->CostLineItem(Item).ValuePer;
     991              :                         }
     992              :                     }
     993              :                 }
     994           15 :             } break;
     995            0 :             default:
     996            0 :                 break;
     997              :             }
     998              :         }
     999              : 
    1000              :         // now sum up the line items, result for the current building
    1001              : 
    1002           40 :         state.dataCostEstimateManager->CurntBldg.LineItemTot = sum(state.dataCostEstimateManager->CostLineItem, &CostLineItemStruct::LineSubTotal);
    1003           40 :     }
    1004              : 
    1005              : } // namespace CostEstimateManager
    1006              : 
    1007              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1