LCOV - code coverage report
Current view: top level - EnergyPlus - CostEstimateManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 295 591 49.9 %
Date: 2024-08-23 23:50:59 Functions: 4 5 80.0 %

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

Generated by: LCOV version 1.14