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
|