LCOV - code coverage report
Current view: top level - EnergyPlus - CostEstimateManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 297 570 52.1 %
Date: 2023-01-17 19:17:23 Functions: 6 7 85.7 %

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

Generated by: LCOV version 1.13