Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 : #include <string>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Fmath.hh>
55 :
56 : // EnergyPlus Headers
57 : #include <EnergyPlus/Autosizing/Base.hh>
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/CurveManager.hh>
60 : #include <EnergyPlus/Data/EnergyPlusData.hh>
61 : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
62 : #include <EnergyPlus/DataHVACGlobals.hh>
63 : #include <EnergyPlus/DataIPShortCuts.hh>
64 : #include <EnergyPlus/DataLoopNode.hh>
65 : #include <EnergyPlus/DataSizing.hh>
66 : #include <EnergyPlus/EMSManager.hh>
67 : #include <EnergyPlus/FluidProperties.hh>
68 : #include <EnergyPlus/General.hh>
69 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
70 : #include <EnergyPlus/NodeInputManager.hh>
71 : #include <EnergyPlus/OutputProcessor.hh>
72 : #include <EnergyPlus/OutputReportPredefined.hh>
73 : #include <EnergyPlus/Plant/DataPlant.hh>
74 : #include <EnergyPlus/Plant/PlantLocation.hh>
75 : #include <EnergyPlus/PlantCentralGSHP.hh>
76 : #include <EnergyPlus/PlantUtilities.hh>
77 : #include <EnergyPlus/ScheduleManager.hh>
78 : #include <EnergyPlus/UtilityRoutines.hh>
79 :
80 : namespace EnergyPlus::PlantCentralGSHP {
81 :
82 : // MODULE INFORMATION:
83 : // AUTHOR PNNL
84 : // DATE WRITTEN Feb 2013
85 : // MODIFIED na
86 : // RE-ENGINEERED na
87 : // PURPOSE OF THIS MODULE:
88 : // This module simulates the performance of the Central Plant GSHP systems
89 : // It currently includes one object: ChillerHeaterPerformance:Electric:EIR.
90 : // The other object available for this central CGSHP system such as HeatPumpPerformance:WaterToWater:EIR
91 : // will be implemented later.
92 :
93 : // METHODOLOGY EMPLOYED:
94 : // Once the PlantLoopManager determines that the Central Plant GSHP
95 : // is available to meet a loop cooling and heating demands, it calls simulate
96 : // which in turn calls the electric PlantCentralGSHP model. The PlantCentralGSHP model is based on
97 : // polynomial fits of chiller/heater or heat pump performance data.
98 :
99 6 : PlantComponent *WrapperSpecs::factory(EnergyPlusData &state, std::string const &objectName)
100 : {
101 : // Process the input data
102 6 : if (state.dataPlantCentralGSHP->getWrapperInputFlag) {
103 2 : GetWrapperInput(state);
104 2 : state.dataPlantCentralGSHP->getWrapperInputFlag = false;
105 : }
106 :
107 : // Now look for this particular object
108 6 : for (auto &thisWrapper : state.dataPlantCentralGSHP->Wrapper) {
109 6 : if (thisWrapper.Name == objectName) {
110 6 : return &thisWrapper;
111 : }
112 12 : }
113 : // If we didn't find it, fatal
114 : ShowFatalError(state, format("LocalPlantCentralGSHPFactory: Error getting inputs for object named: {}", objectName)); // LCOV_EXCL_LINE
115 : // Shut up the compiler
116 : return nullptr; // LCOV_EXCL_LINE
117 : }
118 :
119 30 : void WrapperSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &calledFromLocation)
120 : {
121 30 : this->initialize(state, 0.0, calledFromLocation.loopNum);
122 30 : this->SizeWrapper(state);
123 30 : }
124 :
125 30 : void WrapperSpecs::getDesignCapacities(
126 : [[maybe_unused]] EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
127 : {
128 30 : MinLoad = 0.0;
129 30 : MaxLoad = 0.0;
130 30 : OptLoad = 0.0;
131 30 : if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) { // Chilled water loop
132 10 : if (this->ControlMode == CondenserType::SmartMixing) { // control mode is SmartMixing
133 45 : for (int NumChillerHeater = 1; NumChillerHeater <= this->ChillerHeaterNums; ++NumChillerHeater) {
134 35 : MaxLoad += this->ChillerHeater(NumChillerHeater).RefCapCooling * this->ChillerHeater(NumChillerHeater).MaxPartLoadRatCooling;
135 35 : OptLoad += this->ChillerHeater(NumChillerHeater).RefCapCooling * this->ChillerHeater(NumChillerHeater).OptPartLoadRatCooling;
136 35 : MinLoad += this->ChillerHeater(NumChillerHeater).RefCapCooling * this->ChillerHeater(NumChillerHeater).MinPartLoadRatCooling;
137 : }
138 : }
139 20 : } else if (calledFromLocation.loopNum == this->HWPlantLoc.loopNum) { // Hot water loop
140 10 : if (this->ControlMode == CondenserType::SmartMixing) { // control mode is SmartMixing
141 45 : for (int NumChillerHeater = 1; NumChillerHeater <= this->ChillerHeaterNums; ++NumChillerHeater) {
142 35 : MaxLoad += this->ChillerHeater(NumChillerHeater).RefCapClgHtg * this->ChillerHeater(NumChillerHeater).MaxPartLoadRatClgHtg;
143 35 : OptLoad += this->ChillerHeater(NumChillerHeater).RefCapClgHtg * this->ChillerHeater(NumChillerHeater).OptPartLoadRatClgHtg;
144 35 : MinLoad += this->ChillerHeater(NumChillerHeater).RefCapClgHtg * this->ChillerHeater(NumChillerHeater).MinPartLoadRatClgHtg;
145 : }
146 : } // End of control mode determination
147 : }
148 30 : }
149 :
150 6 : void WrapperSpecs::getSizingFactor(Real64 &SizFac)
151 : {
152 6 : SizFac = 1.0;
153 6 : }
154 :
155 153658 : void WrapperSpecs::simulate(
156 : EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, [[maybe_unused]] bool RunFlag)
157 : {
158 153658 : if (calledFromLocation.loopNum != this->GLHEPlantLoc.loopNum) {
159 :
160 102440 : this->initialize(state, CurLoad, calledFromLocation.loopNum);
161 102440 : this->CalcWrapperModel(state, CurLoad, calledFromLocation.loopNum);
162 :
163 51218 : } else if (calledFromLocation.loopNum == this->GLHEPlantLoc.loopNum) {
164 51218 : PlantUtilities::UpdateChillerComponentCondenserSide(state,
165 51218 : calledFromLocation.loopNum,
166 : this->GLHEPlantLoc.loopSideNum,
167 : DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump,
168 : this->GLHEInletNodeNum,
169 : this->GLHEOutletNodeNum,
170 : this->Report.GLHERate,
171 : this->Report.GLHEInletTemp,
172 : this->Report.GLHEOutletTemp,
173 : this->Report.GLHEmdot,
174 : FirstHVACIteration);
175 :
176 : // Use the first chiller heater's evaporator capacity ratio to determine dominant load
177 51218 : this->SimulClgDominant = false;
178 51218 : this->SimulHtgDominant = false;
179 51218 : if (this->WrapperCoolingLoad > 0 && this->WrapperHeatingLoad > 0) {
180 4536 : Real64 SimulLoadRatio = this->WrapperCoolingLoad / this->WrapperHeatingLoad;
181 4536 : if (SimulLoadRatio > this->ChillerHeater(1).ClgHtgToCoolingCapRatio) {
182 4536 : this->SimulClgDominant = true;
183 4536 : this->SimulHtgDominant = false;
184 : } else {
185 0 : this->SimulHtgDominant = true;
186 0 : this->SimulClgDominant = false;
187 : }
188 : }
189 : }
190 153658 : }
191 :
192 30 : void WrapperSpecs::SizeWrapper(EnergyPlusData &state)
193 : {
194 : // SUBROUTINE INFORMATION:
195 : // AUTHOR Yunzhi Huang, PNNL
196 : // DATE WRITTEN Feb 2013
197 : // MODIFIED November 2013 Daeho Kang, add component sizing table entries
198 : // RE-ENGINEERED na
199 :
200 : // PURPOSE OF THIS SUBROUTINE:
201 : // This subroutine is for sizing all the components under each 'CentralHeatPumpSystem' object,
202 : // for which capacities and flow rates have not been specified in the input.
203 :
204 : // METHODOLOGY EMPLOYED:
205 : // Obtains evaporator flow rate from the plant sizing array. Calculates reference capacity from
206 : // the evaporator (or load side) flow rate and the chilled water loop design delta T. The condenser
207 : // flow (or source side) rate is calculated from the reference capacity, the COP, and the condenser
208 : // loop design delta T.
209 :
210 : static constexpr std::string_view RoutineName("SizeCGSHPChillerHeater");
211 :
212 : // auto-size the chiller heater components
213 30 : if (this->ControlMode == CondenserType::SmartMixing) {
214 :
215 135 : for (int NumChillerHeater = 1; NumChillerHeater <= this->ChillerHeaterNums; ++NumChillerHeater) {
216 105 : bool ErrorsFound = false;
217 :
218 : // find the appropriate Plant Sizing object
219 105 : int PltSizNum = this->CWPlantLoc.loop->PlantSizNum;
220 :
221 : // if ( Wrapper( WrapperNum ).ChillerHeater( NumChillerHeater ).CondVolFlowRate == AutoSize ) {
222 105 : int PltSizCondNum = this->GLHEPlantLoc.loop->PlantSizNum;
223 : //}
224 :
225 105 : Real64 tmpNomCap = this->ChillerHeater(NumChillerHeater).RefCapCooling;
226 105 : Real64 tmpEvapVolFlowRate = this->ChillerHeater(NumChillerHeater).EvapVolFlowRate;
227 105 : Real64 tmpCondVolFlowRate = this->ChillerHeater(NumChillerHeater).CondVolFlowRate;
228 :
229 : // auto-size the Evaporator Flow Rate
230 105 : if (PltSizNum > 0) {
231 105 : if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
232 84 : tmpEvapVolFlowRate = state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate * this->ChillerHeater(NumChillerHeater).SizFac;
233 84 : this->ChillerHeater(NumChillerHeater).tmpEvapVolFlowRate = tmpEvapVolFlowRate;
234 84 : if (!this->ChillerHeater(NumChillerHeater).EvapVolFlowRateWasAutoSized) {
235 84 : tmpEvapVolFlowRate = this->ChillerHeater(NumChillerHeater).EvapVolFlowRate;
236 : }
237 :
238 : } else {
239 21 : if (this->ChillerHeater(NumChillerHeater).EvapVolFlowRateWasAutoSized) {
240 0 : tmpEvapVolFlowRate = 0.0;
241 : }
242 21 : this->ChillerHeater(NumChillerHeater).tmpEvapVolFlowRate = tmpEvapVolFlowRate;
243 : }
244 105 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
245 21 : if (this->ChillerHeater(NumChillerHeater).EvapVolFlowRateWasAutoSized) {
246 0 : this->ChillerHeater(NumChillerHeater).EvapVolFlowRate = tmpEvapVolFlowRate;
247 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
248 0 : BaseSizer::reportSizerOutput(state,
249 : "ChillerHeaterPerformance:Electric:EIR",
250 0 : this->ChillerHeater(NumChillerHeater).Name,
251 : "Design Size Reference Chilled Water Flow Rate [m3/s]",
252 : tmpEvapVolFlowRate);
253 : }
254 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
255 0 : BaseSizer::reportSizerOutput(state,
256 : "ChillerHeaterPerformance:Electric:EIR",
257 0 : this->ChillerHeater(NumChillerHeater).Name,
258 : "Initial Design Size Reference Chilled Water Flow Rate [m3/s]",
259 : tmpEvapVolFlowRate);
260 : }
261 : } else {
262 42 : if (this->ChillerHeater(NumChillerHeater).EvapVolFlowRate > 0.0 && tmpEvapVolFlowRate > 0.0 &&
263 42 : state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
264 :
265 : // Hardsized evaporator design volume flow rate for reporting
266 7 : Real64 EvapVolFlowRateUser = this->ChillerHeater(NumChillerHeater).EvapVolFlowRate;
267 14 : BaseSizer::reportSizerOutput(state,
268 : "ChillerHeaterPerformance:Electric:EIR",
269 7 : this->ChillerHeater(NumChillerHeater).Name,
270 : "Design Size Reference Chilled Water Flow Rate [m3/s]",
271 : tmpEvapVolFlowRate,
272 : "User-Specified Reference Chilled Water Flow Rate [m3/s]",
273 : EvapVolFlowRateUser);
274 7 : tmpEvapVolFlowRate = EvapVolFlowRateUser;
275 7 : if (state.dataGlobal->DisplayExtraWarnings) {
276 3 : if ((std::abs(tmpEvapVolFlowRate - EvapVolFlowRateUser) / EvapVolFlowRateUser) >
277 3 : state.dataSize->AutoVsHardSizingThreshold) {
278 0 : ShowMessage(state,
279 0 : format("SizeChillerHeaterPerformanceElectricEIR: Potential issue with equipment sizing for {}",
280 0 : this->ChillerHeater(NumChillerHeater).Name));
281 0 : ShowContinueError(
282 0 : state, format("User-Specified Reference Chilled Water Flow Rate of {:.5R} [m3/s]", EvapVolFlowRateUser));
283 0 : ShowContinueError(
284 : state,
285 0 : format("differs from Design Size Reference Chilled Water Flow Rate of {:.5R} [m3/s]", tmpEvapVolFlowRate));
286 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
287 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
288 : }
289 : }
290 : }
291 : }
292 : }
293 : } else {
294 0 : if (this->ChillerHeater(NumChillerHeater).EvapVolFlowRateWasAutoSized) {
295 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
296 0 : ShowSevereError(state, "Autosizing of CGSHP Chiller Heater evap flow rate requires a loop Sizing:Plant object");
297 0 : ShowContinueError(state,
298 0 : format("Occurs in CGSHP Chiller Heater Performance object={}", this->ChillerHeater(NumChillerHeater).Name));
299 0 : ErrorsFound = true;
300 : }
301 : } else {
302 0 : if (this->ChillerHeater(NumChillerHeater).EvapVolFlowRate > 0.0 && state.dataPlnt->PlantFinalSizesOkayToReport &&
303 0 : !this->mySizesReported) {
304 0 : BaseSizer::reportSizerOutput(state,
305 : "ChillerHeaterPerformance:Electric:EIR",
306 0 : this->ChillerHeater(NumChillerHeater).Name,
307 : "User-Specified Reference Chilled Water Flow Rate [m3/s]",
308 0 : this->ChillerHeater(NumChillerHeater).EvapVolFlowRate);
309 : }
310 : }
311 : }
312 :
313 : // auto-size the Reference Cooling Capacity
314 : // each individual chiller heater module is sized to be capable of supporting the total load on the wrapper
315 105 : if (PltSizNum > 0) {
316 105 : if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow && tmpEvapVolFlowRate > 0.0) {
317 84 : Real64 Cp = this->CWPlantLoc.loop->glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
318 :
319 84 : Real64 rho = this->CWPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
320 84 : tmpNomCap = Cp * rho * state.dataSize->PlantSizData(PltSizNum).DeltaT * tmpEvapVolFlowRate;
321 84 : if (!this->ChillerHeater(NumChillerHeater).RefCapCoolingWasAutoSized) {
322 84 : tmpNomCap = this->ChillerHeater(NumChillerHeater).RefCapCooling;
323 : }
324 : } else {
325 21 : if (this->ChillerHeater(NumChillerHeater).RefCapCoolingWasAutoSized) {
326 0 : tmpNomCap = 0.0;
327 : }
328 : }
329 105 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
330 21 : if (this->ChillerHeater(NumChillerHeater).RefCapCoolingWasAutoSized) {
331 0 : this->ChillerHeater(NumChillerHeater).RefCapCooling = tmpNomCap;
332 :
333 : // Now that we have the Reference Cooling Capacity, we need to also initialize the Heating side
334 : // given the ratios
335 0 : this->ChillerHeater(NumChillerHeater).RefCapClgHtg =
336 0 : this->ChillerHeater(NumChillerHeater).RefCapCooling * this->ChillerHeater(NumChillerHeater).ClgHtgToCoolingCapRatio;
337 :
338 0 : this->ChillerHeater(NumChillerHeater).RefPowerClgHtg =
339 0 : (this->ChillerHeater(NumChillerHeater).RefCapCooling / this->ChillerHeater(NumChillerHeater).RefCOPCooling) *
340 0 : this->ChillerHeater(NumChillerHeater).ClgHtgtoCogPowerRatio;
341 :
342 0 : this->ChillerHeater(NumChillerHeater).RefCOPClgHtg =
343 0 : this->ChillerHeater(NumChillerHeater).RefCapClgHtg / this->ChillerHeater(NumChillerHeater).RefPowerClgHtg;
344 :
345 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
346 0 : BaseSizer::reportSizerOutput(state,
347 : "ChillerHeaterPerformance:Electric:EIR",
348 0 : this->ChillerHeater(NumChillerHeater).Name,
349 : "Design Size Reference Capacity [W]",
350 : tmpNomCap);
351 : }
352 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
353 0 : BaseSizer::reportSizerOutput(state,
354 : "ChillerHeaterPerformance:Electric:EIR",
355 0 : this->ChillerHeater(NumChillerHeater).Name,
356 : "Initial Design Size Reference Capacity [W]",
357 : tmpNomCap);
358 : }
359 : } else {
360 42 : if (this->ChillerHeater(NumChillerHeater).RefCapCooling > 0.0 && tmpNomCap > 0.0 &&
361 42 : state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
362 :
363 : // Hardsized nominal capacity cooling power for reporting
364 7 : Real64 NomCapUser = this->ChillerHeater(NumChillerHeater).RefCapCooling;
365 14 : BaseSizer::reportSizerOutput(state,
366 : "ChillerHeaterPerformance:Electric:EIR",
367 7 : this->ChillerHeater(NumChillerHeater).Name,
368 : "Design Size Reference Capacity [W]",
369 : tmpNomCap,
370 : "User-Specified Reference Capacity [W]",
371 : NomCapUser);
372 7 : tmpNomCap = NomCapUser;
373 7 : if (state.dataGlobal->DisplayExtraWarnings) {
374 3 : if ((std::abs(tmpNomCap - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
375 0 : ShowMessage(state,
376 0 : format("SizeChillerHeaterPerformanceElectricEIR: Potential issue with equipment sizing for {}",
377 0 : this->ChillerHeater(NumChillerHeater).Name));
378 0 : ShowContinueError(state, format("User-Specified Reference Capacity of {:.2R} [W]", NomCapUser));
379 0 : ShowContinueError(state, format("differs from Design Size Reference Capacity of {:.2R} [W]", tmpNomCap));
380 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
381 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
382 : }
383 : }
384 : }
385 : }
386 : }
387 : } else {
388 0 : if (this->ChillerHeater(NumChillerHeater).RefCapCoolingWasAutoSized) {
389 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
390 0 : ShowSevereError(
391 : state,
392 0 : format("Size ChillerHeaterPerformance:Electric:EIR=\"{}\", autosize error.", this->ChillerHeater(NumChillerHeater).Name));
393 0 : ShowContinueError(state, "Autosizing of CGSHP Chiller Heater reference capacity requires");
394 0 : ShowContinueError(state, "a cooling loop Sizing:Plant object.");
395 0 : ErrorsFound = true;
396 : }
397 : } else {
398 0 : if (this->ChillerHeater(NumChillerHeater).RefCapCooling > 0.0 && state.dataPlnt->PlantFinalSizesOkayToReport &&
399 0 : !this->mySizesReported) {
400 0 : BaseSizer::reportSizerOutput(state,
401 : "ChillerHeaterPerformance:Electric:EIR",
402 0 : this->ChillerHeater(NumChillerHeater).Name,
403 : "User-Specified Reference Capacity [W]",
404 0 : this->ChillerHeater(NumChillerHeater).RefCapCooling);
405 : }
406 : }
407 : }
408 :
409 : // auto-size the condenser volume flow rate
410 : // each individual chiller heater module is sized to be capable of supporting the total load on the wrapper
411 105 : if (PltSizCondNum > 0) {
412 105 : if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
413 84 : Real64 rho = this->GLHEPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
414 : // TODO: JM 2018-12-06 I wonder why Cp isn't calculated at the same temp as rho...
415 252 : Real64 Cp = this->GLHEPlantLoc.loop->glycol->getSpecificHeat(
416 84 : state, this->ChillerHeater(NumChillerHeater).TempRefCondInCooling, RoutineName);
417 84 : tmpCondVolFlowRate =
418 84 : tmpNomCap *
419 84 : (1.0 + (1.0 / this->ChillerHeater(NumChillerHeater).RefCOPCooling) * this->ChillerHeater(NumChillerHeater).OpenMotorEff) /
420 84 : (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
421 84 : this->ChillerHeater(NumChillerHeater).tmpCondVolFlowRate = tmpCondVolFlowRate;
422 84 : if (!this->ChillerHeater(NumChillerHeater).CondVolFlowRateWasAutoSized) {
423 84 : tmpCondVolFlowRate = this->ChillerHeater(NumChillerHeater).CondVolFlowRate;
424 : }
425 :
426 : } else {
427 21 : if (this->ChillerHeater(NumChillerHeater).CondVolFlowRateWasAutoSized) {
428 0 : tmpCondVolFlowRate = 0.0;
429 : }
430 21 : this->ChillerHeater(NumChillerHeater).tmpCondVolFlowRate = tmpCondVolFlowRate;
431 : }
432 105 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
433 21 : if (this->ChillerHeater(NumChillerHeater).CondVolFlowRateWasAutoSized) {
434 0 : this->ChillerHeater(NumChillerHeater).CondVolFlowRate = tmpCondVolFlowRate;
435 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
436 0 : BaseSizer::reportSizerOutput(state,
437 : "ChillerHeaterPerformance:Electric:EIR",
438 0 : this->ChillerHeater(NumChillerHeater).Name,
439 : "Design Size Reference Condenser Water Flow Rate [m3/s]",
440 : tmpCondVolFlowRate);
441 : }
442 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
443 0 : BaseSizer::reportSizerOutput(state,
444 : "ChillerHeaterPerformance:Electric:EIR",
445 0 : this->ChillerHeater(NumChillerHeater).Name,
446 : "Initial Design Size Reference Condenser Water Flow Rate [m3/s]",
447 : tmpCondVolFlowRate);
448 : }
449 : } else {
450 42 : if (this->ChillerHeater(NumChillerHeater).CondVolFlowRate > 0.0 && tmpCondVolFlowRate > 0.0 &&
451 42 : state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
452 :
453 : // Hardsized condenser design volume flow rate for reporting
454 7 : Real64 CondVolFlowRateUser = this->ChillerHeater(NumChillerHeater).CondVolFlowRate;
455 14 : BaseSizer::reportSizerOutput(state,
456 : "ChillerHeaterPerformance:Electric:EIR",
457 7 : this->ChillerHeater(NumChillerHeater).Name,
458 : "Design Size Reference Condenser Water Flow Rate [m3/s]",
459 : tmpCondVolFlowRate,
460 : "User-Specified Reference Condenser Water Flow Rate [m3/s]",
461 : CondVolFlowRateUser);
462 7 : if (state.dataGlobal->DisplayExtraWarnings) {
463 3 : if ((std::abs(tmpCondVolFlowRate - CondVolFlowRateUser) / CondVolFlowRateUser) >
464 3 : state.dataSize->AutoVsHardSizingThreshold) {
465 0 : ShowMessage(state,
466 0 : format("SizeChillerHeaterPerformanceElectricEIR: Potential issue with equipment sizing for {}",
467 0 : this->ChillerHeater(NumChillerHeater).Name));
468 0 : ShowContinueError(
469 0 : state, format("User-Specified Reference Condenser Water Flow Rate of {:.5R} [m3/s]", CondVolFlowRateUser));
470 0 : ShowContinueError(
471 : state,
472 0 : format("differs from Design Size Reference Condenser Water Flow Rate of {:.5R} [m3/s]", tmpCondVolFlowRate));
473 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
474 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
475 : }
476 : }
477 : }
478 : }
479 : }
480 : } else {
481 0 : if (this->ChillerHeater(NumChillerHeater).CondVolFlowRateWasAutoSized) {
482 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
483 0 : ShowSevereError(
484 : state,
485 0 : format("Size ChillerHeaterPerformance:Electric:EIR=\"{}\", autosize error.", this->ChillerHeater(NumChillerHeater).Name));
486 0 : ShowContinueError(state, "Autosizing of CGSHP Chiller Heater condenser flow rate requires");
487 0 : ShowContinueError(state, "a condenser loop Sizing:Plant object.");
488 0 : ErrorsFound = true;
489 : }
490 : } else {
491 0 : if (this->ChillerHeater(NumChillerHeater).CondVolFlowRate > 0.0 && state.dataPlnt->PlantFinalSizesOkayToReport &&
492 0 : !this->mySizesReported) {
493 0 : BaseSizer::reportSizerOutput(state,
494 : "ChillerHeaterPerformance:Electric:EIR",
495 0 : this->ChillerHeater(NumChillerHeater).Name,
496 : "User-Specified Reference Condenser Water Flow Rate [m3/s]",
497 0 : this->ChillerHeater(NumChillerHeater).CondVolFlowRate);
498 : }
499 : }
500 : }
501 :
502 105 : if (state.dataPlnt->PlantFinalSizesOkayToReport && !this->mySizesReported) {
503 : // create predefined report
504 7 : std::string equipName = this->ChillerHeater(NumChillerHeater).Name;
505 14 : OutputReportPredefined::PreDefTableEntry(
506 7 : state, state.dataOutRptPredefined->pdchMechType, equipName, "ChillerHeaterPerformance:Electric:EIR");
507 14 : OutputReportPredefined::PreDefTableEntry(
508 7 : state, state.dataOutRptPredefined->pdchMechNomEff, equipName, this->ChillerHeater(NumChillerHeater).RefCOPCooling);
509 14 : OutputReportPredefined::PreDefTableEntry(
510 7 : state, state.dataOutRptPredefined->pdchMechNomCap, equipName, this->ChillerHeater(NumChillerHeater).RefCapCooling);
511 7 : }
512 :
513 105 : if (ErrorsFound) {
514 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
515 : }
516 : }
517 :
518 : // sum individual volume flows and register wrapper inlets
519 30 : Real64 TotalEvapVolFlowRate = 0.0;
520 30 : Real64 TotalCondVolFlowRate = 0.0;
521 30 : Real64 TotalHotWaterVolFlowRate = 0.0;
522 135 : for (int NumChillerHeater = 1; NumChillerHeater <= this->ChillerHeaterNums; ++NumChillerHeater) {
523 105 : TotalEvapVolFlowRate += this->ChillerHeater(NumChillerHeater).tmpEvapVolFlowRate;
524 105 : TotalCondVolFlowRate += this->ChillerHeater(NumChillerHeater).tmpCondVolFlowRate;
525 105 : TotalHotWaterVolFlowRate += this->ChillerHeater(NumChillerHeater).DesignHotWaterVolFlowRate;
526 : }
527 :
528 30 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->CHWInletNodeNum, TotalEvapVolFlowRate);
529 30 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->HWInletNodeNum, TotalHotWaterVolFlowRate);
530 : // save the reference condenser water volumetric flow rate for use by the condenser water loop sizing algorithms
531 30 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->GLHEInletNodeNum, TotalCondVolFlowRate);
532 :
533 30 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
534 6 : this->mySizesReported = true;
535 : }
536 :
537 30 : return;
538 : }
539 : }
540 :
541 2 : void GetWrapperInput(EnergyPlusData &state)
542 : {
543 : // SUBROUTINE INFORMATION:
544 : // AUTHOR: Yunzhi Huang and Daeho Kang, PNNL
545 : // DATE WRITTEN: Feb 2013
546 :
547 : // PURPOSE OF THIS SUBROUTINE:
548 : // This routine will get the input required by the Wrapper model.
549 :
550 : static constexpr std::string_view routineName = "GetWrapperInput";
551 :
552 2 : bool ErrorsFound(false); // True when input errors are found
553 : int NumAlphas; // Number of elements in the alpha array
554 : int NumNums; // Number of elements in the numeric array
555 : int IOStat; // IO Status when calling get input subroutine
556 :
557 2 : state.dataIPShortCut->cCurrentModuleObject = "CentralHeatPumpSystem";
558 4 : state.dataPlantCentralGSHP->numWrappers =
559 2 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
560 :
561 2 : if (state.dataPlantCentralGSHP->numWrappers <= 0) {
562 0 : ShowSevereError(state, format("No {} equipment specified in input file", state.dataIPShortCut->cCurrentModuleObject));
563 : }
564 :
565 2 : state.dataPlantCentralGSHP->Wrapper.allocate(state.dataPlantCentralGSHP->numWrappers);
566 :
567 : // Load arrays with electric EIR chiller data
568 4 : for (int WrapperNum = 1; WrapperNum <= state.dataPlantCentralGSHP->numWrappers; ++WrapperNum) {
569 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
570 2 : state.dataIPShortCut->cCurrentModuleObject,
571 : WrapperNum,
572 2 : state.dataIPShortCut->cAlphaArgs,
573 : NumAlphas,
574 2 : state.dataIPShortCut->rNumericArgs,
575 : NumNums,
576 : IOStat,
577 : _,
578 2 : state.dataIPShortCut->lAlphaFieldBlanks,
579 2 : state.dataIPShortCut->cAlphaFieldNames,
580 2 : state.dataIPShortCut->cNumericFieldNames);
581 :
582 2 : ErrorObjectHeader eoh{routineName, state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
583 :
584 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).Name = state.dataIPShortCut->cAlphaArgs(1);
585 :
586 : // initialize nth chiller heater index (including identical units) for current wrapper
587 2 : if (Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataIPShortCut->cCurrentModuleObject, ErrorsFound)) {
588 0 : continue;
589 : }
590 :
591 2 : if (state.dataIPShortCut->cAlphaArgs(2) == "SMARTMIXING") {
592 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).ControlMode = CondenserType::SmartMixing;
593 : }
594 :
595 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).CHWInletNodeNum =
596 4 : NodeInputManager::GetOnlySingleNode(state,
597 2 : state.dataIPShortCut->cAlphaArgs(3),
598 : ErrorsFound,
599 : DataLoopNode::ConnectionObjectType::CentralHeatPumpSystem,
600 2 : state.dataIPShortCut->cAlphaArgs(1),
601 : DataLoopNode::NodeFluidType::Water,
602 : DataLoopNode::ConnectionType::Inlet,
603 : NodeInputManager::CompFluidStream::Primary,
604 : DataLoopNode::ObjectIsNotParent); // node name : connection should be careful!
605 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).CHWOutletNodeNum =
606 6 : NodeInputManager::GetOnlySingleNode(state,
607 2 : state.dataIPShortCut->cAlphaArgs(4),
608 : ErrorsFound,
609 : DataLoopNode::ConnectionObjectType::CentralHeatPumpSystem,
610 2 : state.dataIPShortCut->cAlphaArgs(1),
611 : DataLoopNode::NodeFluidType::Water,
612 : DataLoopNode::ConnectionType::Outlet,
613 : NodeInputManager::CompFluidStream::Primary,
614 : DataLoopNode::ObjectIsNotParent);
615 4 : BranchNodeConnections::TestCompSet(state,
616 2 : state.dataIPShortCut->cCurrentModuleObject,
617 2 : state.dataIPShortCut->cAlphaArgs(1),
618 2 : state.dataIPShortCut->cAlphaArgs(3),
619 2 : state.dataIPShortCut->cAlphaArgs(4),
620 : "Chilled Water Nodes");
621 :
622 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).GLHEInletNodeNum =
623 4 : NodeInputManager::GetOnlySingleNode(state,
624 2 : state.dataIPShortCut->cAlphaArgs(5),
625 : ErrorsFound,
626 : DataLoopNode::ConnectionObjectType::CentralHeatPumpSystem,
627 2 : state.dataIPShortCut->cAlphaArgs(1),
628 : DataLoopNode::NodeFluidType::Water,
629 : DataLoopNode::ConnectionType::Inlet,
630 : NodeInputManager::CompFluidStream::Secondary,
631 : DataLoopNode::ObjectIsNotParent); // node name : connection should be careful!
632 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).GLHEOutletNodeNum =
633 6 : NodeInputManager::GetOnlySingleNode(state,
634 2 : state.dataIPShortCut->cAlphaArgs(6),
635 : ErrorsFound,
636 : DataLoopNode::ConnectionObjectType::CentralHeatPumpSystem,
637 2 : state.dataIPShortCut->cAlphaArgs(1),
638 : DataLoopNode::NodeFluidType::Water,
639 : DataLoopNode::ConnectionType::Outlet,
640 : NodeInputManager::CompFluidStream::Secondary,
641 : DataLoopNode::ObjectIsNotParent);
642 4 : BranchNodeConnections::TestCompSet(state,
643 2 : state.dataIPShortCut->cCurrentModuleObject,
644 2 : state.dataIPShortCut->cAlphaArgs(1),
645 2 : state.dataIPShortCut->cAlphaArgs(5),
646 2 : state.dataIPShortCut->cAlphaArgs(6),
647 : "GLHE Nodes");
648 :
649 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).HWInletNodeNum =
650 4 : NodeInputManager::GetOnlySingleNode(state,
651 2 : state.dataIPShortCut->cAlphaArgs(7),
652 : ErrorsFound,
653 : DataLoopNode::ConnectionObjectType::CentralHeatPumpSystem,
654 2 : state.dataIPShortCut->cAlphaArgs(1),
655 : DataLoopNode::NodeFluidType::Water,
656 : DataLoopNode::ConnectionType::Inlet,
657 : NodeInputManager::CompFluidStream::Tertiary,
658 : DataLoopNode::ObjectIsNotParent); // node name : connection should be careful!
659 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).HWOutletNodeNum =
660 6 : NodeInputManager::GetOnlySingleNode(state,
661 2 : state.dataIPShortCut->cAlphaArgs(8),
662 : ErrorsFound,
663 : DataLoopNode::ConnectionObjectType::CentralHeatPumpSystem,
664 2 : state.dataIPShortCut->cAlphaArgs(1),
665 : DataLoopNode::NodeFluidType::Water,
666 : DataLoopNode::ConnectionType::Outlet,
667 : NodeInputManager::CompFluidStream::Tertiary,
668 : DataLoopNode::ObjectIsNotParent);
669 4 : BranchNodeConnections::TestCompSet(state,
670 2 : state.dataIPShortCut->cCurrentModuleObject,
671 2 : state.dataIPShortCut->cAlphaArgs(1),
672 2 : state.dataIPShortCut->cAlphaArgs(7),
673 2 : state.dataIPShortCut->cAlphaArgs(8),
674 : "Hot Water Nodes");
675 :
676 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).AncillaryPower = state.dataIPShortCut->rNumericArgs(1);
677 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(9)) {
678 : // Leave this as nullptr
679 0 : } else if ((state.dataPlantCentralGSHP->Wrapper(WrapperNum).ancillaryPowerSched =
680 0 : Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(9))) == nullptr) {
681 0 : ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(9), state.dataIPShortCut->cAlphaArgs(9));
682 : }
683 :
684 2 : int NumberOfComp = (NumAlphas - 9) / 3;
685 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).NumOfComp = NumberOfComp;
686 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp.allocate(NumberOfComp);
687 :
688 2 : if (state.dataPlantCentralGSHP->Wrapper(WrapperNum).NumOfComp == 0) {
689 0 : ShowSevereError(state,
690 0 : format("GetWrapperInput: No component names on {}={}",
691 0 : state.dataIPShortCut->cCurrentModuleObject,
692 0 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).Name));
693 0 : ErrorsFound = true;
694 : } else {
695 2 : int Comp = 0;
696 2 : int NumChHtrPerWrapper = 0;
697 5 : for (int loop = 10; loop <= NumAlphas; loop += 3) {
698 3 : ++Comp;
699 3 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperPerformanceObjectType =
700 6 : state.dataIPShortCut->cAlphaArgs(loop);
701 3 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperComponentName = state.dataIPShortCut->cAlphaArgs(loop + 1);
702 :
703 3 : if (state.dataIPShortCut->lAlphaFieldBlanks(loop + 2)) {
704 0 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).chSched =
705 0 : Sched::GetScheduleAlwaysOn(state); // Not an availability schedule, but defaults to constant-1.0
706 3 : } else if ((state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).chSched =
707 6 : Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(loop + 2))) == nullptr) {
708 0 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).chSched =
709 0 : Sched::GetScheduleAlwaysOn(state); // Not an availabilty schedule, but defaults to constant-1.0
710 0 : ShowWarningItemNotFound(state,
711 : eoh,
712 0 : state.dataIPShortCut->cAlphaFieldNames(loop + 2),
713 0 : state.dataIPShortCut->cAlphaArgs(loop + 2),
714 : "The Control Schedule is treated as AlwaysOn instead.");
715 : }
716 :
717 3 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperIdenticalObjectNum =
718 3 : state.dataIPShortCut->rNumericArgs(1 + Comp);
719 3 : if (state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperPerformanceObjectType ==
720 : "CHILLERHEATERPERFORMANCE:ELECTRIC:EIR") {
721 :
722 : // count number of chiller heaters (including identical units) for current wrapper
723 3 : if (state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperIdenticalObjectNum > 1) {
724 3 : NumChHtrPerWrapper += state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperIdenticalObjectNum;
725 : } else {
726 0 : ++NumChHtrPerWrapper;
727 : }
728 :
729 : // count total number of chiller heaters (not including identical units) for ALL wrappers
730 3 : ++state.dataPlantCentralGSHP->numChillerHeaters;
731 : }
732 : }
733 :
734 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).ChillerHeaterNums = NumChHtrPerWrapper;
735 : }
736 :
737 2 : if (ErrorsFound) {
738 0 : ShowFatalError(
739 : state,
740 0 : format("GetWrapperInput: Invalid {} Input, preceding condition(s) cause termination.", state.dataIPShortCut->cCurrentModuleObject));
741 : }
742 :
743 : // ALLOCATE ARRAYS
744 2 : if ((state.dataPlantCentralGSHP->numChillerHeaters == 0) &&
745 0 : (state.dataPlantCentralGSHP->Wrapper(WrapperNum).ControlMode == CondenserType::SmartMixing)) {
746 0 : ShowFatalError(state,
747 0 : format("SmartMixing Control Mode in object {} : {} need to apply to ChillerHeaterPerformance:Electric:EIR object(s).",
748 0 : state.dataIPShortCut->cCurrentModuleObject,
749 0 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).Name));
750 : }
751 : }
752 :
753 2 : if (state.dataPlantCentralGSHP->numChillerHeaters > 0) {
754 :
755 4 : for (int WrapperNum = 1; WrapperNum <= state.dataPlantCentralGSHP->numWrappers; ++WrapperNum) {
756 2 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).ChillerHeater.allocate(state.dataPlantCentralGSHP->Wrapper(WrapperNum).ChillerHeaterNums);
757 : }
758 2 : GetChillerHeaterInput(state);
759 : }
760 :
761 4 : for (int WrapperNum = 1; WrapperNum <= state.dataPlantCentralGSHP->numWrappers; ++WrapperNum) {
762 2 : int ChillerHeaterNum = 0; // initialize nth chiller heater index (including identical units) for current wrapper
763 5 : for (int Comp = 1; Comp <= state.dataPlantCentralGSHP->Wrapper(WrapperNum).NumOfComp; ++Comp) {
764 3 : if (state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperPerformanceObjectType ==
765 : "CHILLERHEATERPERFORMANCE:ELECTRIC:EIR") {
766 3 : std::string CompName = state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperComponentName;
767 3 : int CompIndex = Util::FindItemInList(CompName, state.dataPlantCentralGSHP->ChillerHeater);
768 : // User may enter invalid name rather than selecting one from the object list
769 3 : if (CompIndex <= 0) {
770 0 : ShowSevereError(state, format("GetWrapperInput: Invalid Chiller Heater Modules Performance Component Name ={}", CompName));
771 0 : ShowContinueError(state, "Select the name of ChillerHeaterPerformance:Electric:EIR object(s) from the object list.");
772 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
773 : }
774 3 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperPerformanceObjectIndex = CompIndex;
775 3 : if (state.dataPlantCentralGSHP->ChillerHeater(CompIndex).VariableFlow) {
776 3 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).VariableFlowCH = true;
777 : }
778 10 : for (int i_CH = 1; i_CH <= state.dataPlantCentralGSHP->Wrapper(WrapperNum).WrapperComp(Comp).WrapperIdenticalObjectNum; ++i_CH) {
779 : // increment nth chiller heater index (including identical units) for current wrapper
780 7 : ++ChillerHeaterNum;
781 7 : state.dataPlantCentralGSHP->Wrapper(WrapperNum).ChillerHeater(ChillerHeaterNum) =
782 14 : state.dataPlantCentralGSHP->ChillerHeater(CompIndex);
783 : }
784 3 : }
785 : }
786 : }
787 :
788 : // Release memory from temporary arrays; values now copied into their associated Wrapper in above loop
789 2 : if (allocated(state.dataPlantCentralGSHP->ChillerHeater)) {
790 2 : state.dataPlantCentralGSHP->ChillerHeater.deallocate();
791 : }
792 :
793 : // Set up output variables
794 4 : for (int WrapperNum = 1; WrapperNum <= state.dataPlantCentralGSHP->numWrappers; ++WrapperNum) {
795 : } // End of wrapper count
796 2 : }
797 :
798 2 : void WrapperSpecs::setupOutputVars(EnergyPlusData &state)
799 : {
800 4 : SetupOutputVariable(state,
801 : "Chiller Heater System Cooling Electricity Energy",
802 : Constant::Units::J,
803 2 : this->Report.TotElecCooling,
804 : OutputProcessor::TimeStepType::System,
805 : OutputProcessor::StoreType::Sum,
806 2 : this->Name,
807 : Constant::eResource::Electricity,
808 : OutputProcessor::Group::Plant,
809 : OutputProcessor::EndUseCat::Cooling);
810 :
811 4 : SetupOutputVariable(state,
812 : "Chiller Heater System Heating Electricity Energy",
813 : Constant::Units::J,
814 2 : this->Report.TotElecHeating,
815 : OutputProcessor::TimeStepType::System,
816 : OutputProcessor::StoreType::Sum,
817 2 : this->Name,
818 : Constant::eResource::Electricity,
819 : OutputProcessor::Group::Plant,
820 : OutputProcessor::EndUseCat::Heating);
821 :
822 4 : SetupOutputVariable(state,
823 : "Chiller Heater System Cooling Electricity Rate",
824 : Constant::Units::W,
825 2 : this->Report.TotElecCoolingPwr,
826 : OutputProcessor::TimeStepType::System,
827 : OutputProcessor::StoreType::Average,
828 2 : this->Name);
829 :
830 4 : SetupOutputVariable(state,
831 : "Chiller Heater System Heating Electricity Rate",
832 : Constant::Units::W,
833 2 : this->Report.TotElecHeatingPwr,
834 : OutputProcessor::TimeStepType::System,
835 : OutputProcessor::StoreType::Average,
836 2 : this->Name);
837 :
838 4 : SetupOutputVariable(state,
839 : "Chiller Heater System Cooling Energy",
840 : Constant::Units::J,
841 2 : this->Report.CoolingEnergy,
842 : OutputProcessor::TimeStepType::System,
843 : OutputProcessor::StoreType::Sum,
844 2 : this->Name,
845 : Constant::eResource::EnergyTransfer,
846 : OutputProcessor::Group::Plant,
847 : OutputProcessor::EndUseCat::Chillers);
848 :
849 4 : SetupOutputVariable(state,
850 : "Chiller Heater System Heating Energy",
851 : Constant::Units::J,
852 2 : this->Report.HeatingEnergy,
853 : OutputProcessor::TimeStepType::System,
854 : OutputProcessor::StoreType::Sum,
855 2 : this->Name,
856 : Constant::eResource::EnergyTransfer,
857 : OutputProcessor::Group::Plant,
858 : OutputProcessor::EndUseCat::Boilers);
859 :
860 4 : SetupOutputVariable(state,
861 : "Chiller Heater System Source Heat Transfer Energy",
862 : Constant::Units::J,
863 2 : this->Report.GLHEEnergy,
864 : OutputProcessor::TimeStepType::System,
865 : OutputProcessor::StoreType::Sum,
866 2 : this->Name,
867 : Constant::eResource::EnergyTransfer,
868 : OutputProcessor::Group::Plant,
869 : OutputProcessor::EndUseCat::HeatRejection);
870 :
871 4 : SetupOutputVariable(state,
872 : "Chiller Heater System Cooling Rate",
873 : Constant::Units::W,
874 2 : this->Report.CoolingRate,
875 : OutputProcessor::TimeStepType::System,
876 : OutputProcessor::StoreType::Average,
877 2 : this->Name);
878 :
879 4 : SetupOutputVariable(state,
880 : "Chiller Heater System Heating Rate",
881 : Constant::Units::W,
882 2 : this->Report.HeatingRate,
883 : OutputProcessor::TimeStepType::System,
884 : OutputProcessor::StoreType::Average,
885 2 : this->Name);
886 :
887 4 : SetupOutputVariable(state,
888 : "Chiller Heater System Source Heat Transfer Rate",
889 : Constant::Units::W,
890 2 : this->Report.GLHERate,
891 : OutputProcessor::TimeStepType::System,
892 : OutputProcessor::StoreType::Average,
893 2 : this->Name);
894 :
895 4 : SetupOutputVariable(state,
896 : "Chiller Heater System Cooling Mass Flow Rate",
897 : Constant::Units::kg_s,
898 2 : this->Report.CHWmdot,
899 : OutputProcessor::TimeStepType::System,
900 : OutputProcessor::StoreType::Average,
901 2 : this->Name);
902 :
903 4 : SetupOutputVariable(state,
904 : "Chiller Heater System Heating Mass Flow Rate",
905 : Constant::Units::kg_s,
906 2 : this->Report.HWmdot,
907 : OutputProcessor::TimeStepType::System,
908 : OutputProcessor::StoreType::Average,
909 2 : this->Name);
910 :
911 4 : SetupOutputVariable(state,
912 : "Chiller Heater System Source Mass Flow Rate",
913 : Constant::Units::kg_s,
914 2 : this->Report.GLHEmdot,
915 : OutputProcessor::TimeStepType::System,
916 : OutputProcessor::StoreType::Average,
917 2 : this->Name);
918 :
919 4 : SetupOutputVariable(state,
920 : "Chiller Heater System Cooling Inlet Temperature",
921 : Constant::Units::C,
922 2 : this->Report.CHWInletTemp,
923 : OutputProcessor::TimeStepType::System,
924 : OutputProcessor::StoreType::Average,
925 2 : this->Name);
926 :
927 4 : SetupOutputVariable(state,
928 : "Chiller Heater System Heating Inlet Temperature",
929 : Constant::Units::C,
930 2 : this->Report.HWInletTemp,
931 : OutputProcessor::TimeStepType::System,
932 : OutputProcessor::StoreType::Average,
933 2 : this->Name);
934 :
935 4 : SetupOutputVariable(state,
936 : "Chiller Heater System Source Inlet Temperature",
937 : Constant::Units::C,
938 2 : this->Report.GLHEInletTemp,
939 : OutputProcessor::TimeStepType::System,
940 : OutputProcessor::StoreType::Average,
941 2 : this->Name);
942 :
943 4 : SetupOutputVariable(state,
944 : "Chiller Heater System Cooling Outlet Temperature",
945 : Constant::Units::C,
946 2 : this->Report.CHWOutletTemp,
947 : OutputProcessor::TimeStepType::System,
948 : OutputProcessor::StoreType::Average,
949 2 : this->Name);
950 :
951 4 : SetupOutputVariable(state,
952 : "Chiller Heater System Heating Outlet Temperature",
953 : Constant::Units::C,
954 2 : this->Report.HWOutletTemp,
955 : OutputProcessor::TimeStepType::System,
956 : OutputProcessor::StoreType::Average,
957 2 : this->Name);
958 :
959 4 : SetupOutputVariable(state,
960 : "Chiller Heater System Source Outlet Temperature",
961 : Constant::Units::C,
962 2 : this->Report.GLHEOutletTemp,
963 : OutputProcessor::TimeStepType::System,
964 : OutputProcessor::StoreType::Average,
965 2 : this->Name);
966 :
967 2 : if (this->ChillerHeaterNums > 0) {
968 :
969 9 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
970 :
971 7 : SetupOutputVariable(state,
972 14 : format("Chiller Heater Operation Mode Unit {}", ChillerHeaterNum),
973 : Constant::Units::None,
974 7 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode,
975 : OutputProcessor::TimeStepType::System,
976 : OutputProcessor::StoreType::Average,
977 7 : this->ChillerHeater(ChillerHeaterNum).Name);
978 :
979 21 : SetupOutputVariable(state,
980 14 : format("Chiller Heater Part Load Ratio Unit {}", ChillerHeaterNum),
981 : Constant::Units::None,
982 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatio,
983 : OutputProcessor::TimeStepType::System,
984 : OutputProcessor::StoreType::Average,
985 7 : this->ChillerHeater(ChillerHeaterNum).Name);
986 :
987 21 : SetupOutputVariable(state,
988 14 : format("Chiller Heater Cycling Ratio Unit {}", ChillerHeaterNum),
989 : Constant::Units::None,
990 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatio,
991 : OutputProcessor::TimeStepType::System,
992 : OutputProcessor::StoreType::Average,
993 7 : this->ChillerHeater(ChillerHeaterNum).Name);
994 :
995 21 : SetupOutputVariable(state,
996 14 : format("Chiller Heater Cooling Electricity Rate Unit {}", ChillerHeaterNum),
997 : Constant::Units::W,
998 7 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower,
999 : OutputProcessor::TimeStepType::System,
1000 : OutputProcessor::StoreType::Average,
1001 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1002 :
1003 21 : SetupOutputVariable(state,
1004 14 : format("Chiller Heater Heating Electricity Rate Unit {}", ChillerHeaterNum),
1005 : Constant::Units::W,
1006 7 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower,
1007 : OutputProcessor::TimeStepType::System,
1008 : OutputProcessor::StoreType::Average,
1009 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1010 :
1011 21 : SetupOutputVariable(state,
1012 14 : format("Chiller Heater Cooling Electricity Energy Unit {}", ChillerHeaterNum),
1013 : Constant::Units::J,
1014 7 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy,
1015 : OutputProcessor::TimeStepType::System,
1016 : OutputProcessor::StoreType::Sum,
1017 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1018 :
1019 21 : SetupOutputVariable(state,
1020 14 : format("Chiller Heater Heating Electricity Energy Unit {}", ChillerHeaterNum),
1021 : Constant::Units::J,
1022 7 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy,
1023 : OutputProcessor::TimeStepType::System,
1024 : OutputProcessor::StoreType::Sum,
1025 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1026 :
1027 21 : SetupOutputVariable(state,
1028 14 : format("Chiller Heater Cooling Rate Unit {}", ChillerHeaterNum),
1029 : Constant::Units::W,
1030 7 : this->ChillerHeater(ChillerHeaterNum).Report.QEvap,
1031 : OutputProcessor::TimeStepType::System,
1032 : OutputProcessor::StoreType::Average,
1033 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1034 :
1035 21 : SetupOutputVariable(state,
1036 14 : format("Chiller Heater Cooling Energy Unit {}", ChillerHeaterNum),
1037 : Constant::Units::J,
1038 7 : this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy,
1039 : OutputProcessor::TimeStepType::System,
1040 : OutputProcessor::StoreType::Sum,
1041 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1042 :
1043 21 : SetupOutputVariable(state,
1044 14 : format("Chiller Heater False Load Heat Transfer Rate Unit {}", ChillerHeaterNum),
1045 : Constant::Units::W,
1046 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate,
1047 : OutputProcessor::TimeStepType::System,
1048 : OutputProcessor::StoreType::Average,
1049 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1050 :
1051 21 : SetupOutputVariable(state,
1052 14 : format("Chiller Heater False Load Heat Transfer Energy Unit {}", ChillerHeaterNum),
1053 : Constant::Units::J,
1054 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoad,
1055 : OutputProcessor::TimeStepType::System,
1056 : OutputProcessor::StoreType::Sum,
1057 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1058 :
1059 21 : SetupOutputVariable(state,
1060 14 : format("Chiller Heater Evaporator Inlet Temperature Unit {}", ChillerHeaterNum),
1061 : Constant::Units::C,
1062 7 : this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTemp,
1063 : OutputProcessor::TimeStepType::System,
1064 : OutputProcessor::StoreType::Average,
1065 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1066 :
1067 21 : SetupOutputVariable(state,
1068 14 : format("Chiller Heater Evaporator Outlet Temperature Unit {}", ChillerHeaterNum),
1069 : Constant::Units::C,
1070 7 : this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp,
1071 : OutputProcessor::TimeStepType::System,
1072 : OutputProcessor::StoreType::Average,
1073 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1074 :
1075 21 : SetupOutputVariable(state,
1076 14 : format("Chiller Heater Evaporator Mass Flow Rate Unit {}", ChillerHeaterNum),
1077 : Constant::Units::kg_s,
1078 7 : this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot,
1079 : OutputProcessor::TimeStepType::System,
1080 : OutputProcessor::StoreType::Average,
1081 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1082 :
1083 21 : SetupOutputVariable(state,
1084 14 : format("Chiller Heater Condenser Heat Transfer Rate Unit {}", ChillerHeaterNum),
1085 : Constant::Units::W,
1086 7 : this->ChillerHeater(ChillerHeaterNum).Report.QCond,
1087 : OutputProcessor::TimeStepType::System,
1088 : OutputProcessor::StoreType::Average,
1089 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1090 :
1091 21 : SetupOutputVariable(state,
1092 14 : format("Chiller Heater Condenser Heat Transfer Energy Unit {}", ChillerHeaterNum),
1093 : Constant::Units::J,
1094 7 : this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy,
1095 : OutputProcessor::TimeStepType::System,
1096 : OutputProcessor::StoreType::Sum,
1097 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1098 :
1099 21 : SetupOutputVariable(state,
1100 14 : format("Chiller Heater COP Unit {}", ChillerHeaterNum),
1101 : Constant::Units::W_W,
1102 7 : this->ChillerHeater(ChillerHeaterNum).Report.ActualCOP,
1103 : OutputProcessor::TimeStepType::System,
1104 : OutputProcessor::StoreType::Average,
1105 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1106 :
1107 21 : SetupOutputVariable(state,
1108 14 : format("Chiller Heater Capacity Temperature Modifier Multiplier Unit {}", ChillerHeaterNum),
1109 : Constant::Units::None,
1110 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFT,
1111 : OutputProcessor::TimeStepType::System,
1112 : OutputProcessor::StoreType::Average,
1113 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1114 :
1115 21 : SetupOutputVariable(state,
1116 14 : format("Chiller Heater EIR Temperature Modifier Multiplier Unit {}", ChillerHeaterNum),
1117 : Constant::Units::None,
1118 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFT,
1119 : OutputProcessor::TimeStepType::System,
1120 : OutputProcessor::StoreType::Average,
1121 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1122 :
1123 21 : SetupOutputVariable(state,
1124 14 : format("Chiller Heater EIR Part Load Modifier Multiplier Unit {}", ChillerHeaterNum),
1125 : Constant::Units::None,
1126 7 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLR,
1127 : OutputProcessor::TimeStepType::System,
1128 : OutputProcessor::StoreType::Average,
1129 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1130 :
1131 21 : SetupOutputVariable(state,
1132 14 : format("Chiller Heater Condenser Inlet Temperature Unit {}", ChillerHeaterNum),
1133 : Constant::Units::C,
1134 7 : this->ChillerHeater(ChillerHeaterNum).Report.CondInletTemp,
1135 : OutputProcessor::TimeStepType::System,
1136 : OutputProcessor::StoreType::Average,
1137 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1138 :
1139 21 : SetupOutputVariable(state,
1140 14 : format("Chiller Heater Condenser Outlet Temperature Unit {}", ChillerHeaterNum),
1141 : Constant::Units::C,
1142 7 : this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp,
1143 : OutputProcessor::TimeStepType::System,
1144 : OutputProcessor::StoreType::Average,
1145 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1146 :
1147 21 : SetupOutputVariable(state,
1148 14 : format("Chiller Heater Condenser Mass Flow Rate Unit {}", ChillerHeaterNum),
1149 : Constant::Units::kg_s,
1150 7 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot,
1151 : OutputProcessor::TimeStepType::System,
1152 : OutputProcessor::StoreType::Average,
1153 7 : this->ChillerHeater(ChillerHeaterNum).Name);
1154 : } // End of individual chiller heater count for current wrapper
1155 :
1156 : } // End of individual chiller heater output
1157 2 : }
1158 :
1159 2 : void GetChillerHeaterInput(EnergyPlusData &state)
1160 : {
1161 : // SUBROUTINE INFORMATION:
1162 : // AUTHOR: Kyung Tae Yun, Mississippi State University
1163 : // DATE WRITTEN: Feb 2013
1164 :
1165 : // PURPOSE OF THIS SUBROUTINE:
1166 : // This routine will get the input required by the ChillerHeaterPerformance:Electric:EIR model.
1167 :
1168 2 : bool CHErrorsFound(false); // True when input errors are found
1169 : int NumAlphas; // Number of elements in the alpha array
1170 : int NumNums; // Number of elements in the numeric array
1171 : int IOStat; // IO Status when calling get input subroutine
1172 2 : Array1D<Real64> CurveValArray(11); // Used to evaluate PLFFPLR curve objects
1173 :
1174 2 : state.dataIPShortCut->cCurrentModuleObject = "ChillerHeaterPerformance:Electric:EIR";
1175 4 : state.dataPlantCentralGSHP->numChillerHeaters =
1176 2 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
1177 :
1178 2 : if (state.dataPlantCentralGSHP->numChillerHeaters <= 0) {
1179 0 : ShowSevereError(state, format("No {} equipment specified in input file", state.dataIPShortCut->cCurrentModuleObject));
1180 0 : CHErrorsFound = true;
1181 : }
1182 :
1183 : // Allocate temporary ChillerHeater and ChillerHeaterReport arrays
1184 2 : if (allocated(state.dataPlantCentralGSHP->ChillerHeater)) {
1185 0 : state.dataPlantCentralGSHP->ChillerHeater.deallocate();
1186 : }
1187 2 : state.dataPlantCentralGSHP->ChillerHeater.allocate(state.dataPlantCentralGSHP->numChillerHeaters);
1188 :
1189 : // Load arrays with electric EIR chiller data
1190 5 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= state.dataPlantCentralGSHP->numChillerHeaters; ++ChillerHeaterNum) {
1191 9 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1192 3 : state.dataIPShortCut->cCurrentModuleObject,
1193 : ChillerHeaterNum,
1194 3 : state.dataIPShortCut->cAlphaArgs,
1195 : NumAlphas,
1196 3 : state.dataIPShortCut->rNumericArgs,
1197 : NumNums,
1198 : IOStat,
1199 : _,
1200 3 : state.dataIPShortCut->lAlphaFieldBlanks,
1201 3 : state.dataIPShortCut->cAlphaFieldNames,
1202 3 : state.dataIPShortCut->cNumericFieldNames);
1203 :
1204 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).Name = state.dataIPShortCut->cAlphaArgs(1);
1205 3 : Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataIPShortCut->cCurrentModuleObject, CHErrorsFound);
1206 :
1207 3 : if (Util::SameString(state.dataIPShortCut->cAlphaArgs(4), "LEAVINGCONDENSER")) {
1208 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondModeCooling = CondenserModeTemperature::LeavingCondenser;
1209 : } else { // only other option and default value is EnteringCondenser
1210 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondModeCooling = CondenserModeTemperature::EnteringCondenser;
1211 : }
1212 :
1213 : // Performance curves
1214 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTCoolingIDX =
1215 3 : Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(5));
1216 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTCoolingIDX == 0) {
1217 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1218 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
1219 0 : CHErrorsFound = true;
1220 : }
1221 :
1222 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTCoolingIDX =
1223 3 : Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(6));
1224 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTCoolingIDX == 0) {
1225 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1226 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(6), state.dataIPShortCut->cAlphaArgs(6)));
1227 0 : CHErrorsFound = true;
1228 : }
1229 :
1230 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX =
1231 3 : Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(7));
1232 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX == 0) {
1233 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1234 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(7), state.dataIPShortCut->cAlphaArgs(7)));
1235 0 : CHErrorsFound = true;
1236 : }
1237 :
1238 3 : if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), "LEAVINGCONDENSER")) {
1239 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondModeHeating = CondenserModeTemperature::LeavingCondenser;
1240 : } else { // only other option and default value is EnteringCondenser
1241 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondModeHeating = CondenserModeTemperature::EnteringCondenser;
1242 : }
1243 :
1244 : // Performance curves
1245 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTHeatingIDX =
1246 3 : Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(9));
1247 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTHeatingIDX == 0) {
1248 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1249 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(9), state.dataIPShortCut->cAlphaArgs(9)));
1250 0 : CHErrorsFound = true;
1251 : }
1252 :
1253 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTHeatingIDX =
1254 3 : Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(10));
1255 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTHeatingIDX == 0) {
1256 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1257 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(10), state.dataIPShortCut->cAlphaArgs(10)));
1258 0 : CHErrorsFound = true;
1259 : }
1260 :
1261 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX =
1262 3 : Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(11));
1263 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX == 0) {
1264 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1265 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(11), state.dataIPShortCut->cAlphaArgs(11)));
1266 0 : CHErrorsFound = true;
1267 : }
1268 :
1269 3 : if (state.dataIPShortCut->cAlphaArgs(2) == "CONSTANTFLOW") {
1270 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ConstantFlow = true;
1271 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).VariableFlow = false;
1272 3 : } else if (state.dataIPShortCut->cAlphaArgs(2) == "VARIABLEFLOW") {
1273 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ConstantFlow = false;
1274 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).VariableFlow = true;
1275 : } else { // Assume a constant flow chiller if none is specified
1276 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ConstantFlow = true;
1277 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).VariableFlow = false;
1278 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1279 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2)));
1280 0 : ShowContinueError(state, "simulation assumes CONSTANTFLOW and continues..");
1281 : }
1282 :
1283 3 : if (ChillerHeaterNum > 1) {
1284 1 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ConstantFlow !=
1285 1 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum - 1).ConstantFlow) {
1286 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ConstantFlow = true;
1287 0 : ShowWarningError(state,
1288 0 : format("Water flow mode is different from the other chiller heater(s) {}={}",
1289 0 : state.dataIPShortCut->cCurrentModuleObject,
1290 0 : state.dataIPShortCut->cAlphaArgs(1)));
1291 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2)));
1292 0 : ShowContinueError(state, "Simulation assumes CONSTANTFLOW and continues..");
1293 : }
1294 : }
1295 :
1296 3 : if (Util::SameString(state.dataIPShortCut->cAlphaArgs(3), "WaterCooled")) {
1297 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).condenserType = CondenserType::WaterCooled;
1298 : } else {
1299 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1300 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cAlphaFieldNames(3), state.dataIPShortCut->cAlphaArgs(3)));
1301 0 : ShowContinueError(state, "Valid entries is WaterCooled");
1302 0 : CHErrorsFound = true;
1303 : }
1304 :
1305 : // Chiller rated performance data
1306 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapCooling = state.dataIPShortCut->rNumericArgs(1);
1307 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapCooling == DataSizing::AutoSize) {
1308 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapCoolingWasAutoSized = true;
1309 : }
1310 3 : if (state.dataIPShortCut->rNumericArgs(1) == 0.0) {
1311 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1312 0 : ShowContinueError(state,
1313 0 : format("Entered in {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(1), state.dataIPShortCut->rNumericArgs(1)));
1314 0 : CHErrorsFound = true;
1315 : }
1316 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCOPCooling = state.dataIPShortCut->rNumericArgs(2);
1317 3 : if (state.dataIPShortCut->rNumericArgs(2) == 0.0) {
1318 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1319 0 : ShowContinueError(state,
1320 0 : format("Entered in {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(2), state.dataIPShortCut->rNumericArgs(2)));
1321 0 : CHErrorsFound = true;
1322 : }
1323 :
1324 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefEvapOutCooling = state.dataIPShortCut->rNumericArgs(3);
1325 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondInCooling = state.dataIPShortCut->rNumericArgs(4);
1326 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondOutCooling = state.dataIPShortCut->rNumericArgs(5);
1327 :
1328 : // Reference Heating Mode Ratios for Capacity and Power
1329 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ClgHtgToCoolingCapRatio = state.dataIPShortCut->rNumericArgs(6);
1330 3 : if (state.dataIPShortCut->rNumericArgs(6) == 0.0) {
1331 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1332 0 : ShowContinueError(state,
1333 0 : format("Entered in {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(6), state.dataIPShortCut->rNumericArgs(6)));
1334 0 : CHErrorsFound = true;
1335 : }
1336 :
1337 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ClgHtgtoCogPowerRatio = state.dataIPShortCut->rNumericArgs(7);
1338 3 : if (state.dataIPShortCut->rNumericArgs(7) == 0.0) {
1339 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1340 0 : ShowContinueError(state,
1341 0 : format("Entered in {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(7), state.dataIPShortCut->rNumericArgs(7)));
1342 0 : CHErrorsFound = true;
1343 : }
1344 :
1345 3 : if (!state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapCoolingWasAutoSized) {
1346 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapClgHtg =
1347 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ClgHtgToCoolingCapRatio *
1348 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapCooling;
1349 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefPowerClgHtg =
1350 3 : (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapCooling /
1351 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCOPCooling) *
1352 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ClgHtgtoCogPowerRatio;
1353 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCOPClgHtg =
1354 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefCapClgHtg /
1355 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).RefPowerClgHtg;
1356 : }
1357 :
1358 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg = state.dataIPShortCut->rNumericArgs(8);
1359 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondOutClgHtg = state.dataIPShortCut->rNumericArgs(9);
1360 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondInClgHtg = state.dataIPShortCut->rNumericArgs(10);
1361 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempLowLimitEvapOut = state.dataIPShortCut->rNumericArgs(11);
1362 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate = state.dataIPShortCut->rNumericArgs(12);
1363 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate == DataSizing::AutoSize) {
1364 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).EvapVolFlowRateWasAutoSized = true;
1365 : }
1366 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondVolFlowRate = state.dataIPShortCut->rNumericArgs(13);
1367 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondVolFlowRate == DataSizing::AutoSize) {
1368 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).CondVolFlowRateWasAutoSized = true;
1369 : }
1370 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).DesignHotWaterVolFlowRate = state.dataIPShortCut->rNumericArgs(14);
1371 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).OpenMotorEff = state.dataIPShortCut->rNumericArgs(15);
1372 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).OptPartLoadRatCooling = state.dataIPShortCut->rNumericArgs(16);
1373 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).OptPartLoadRatClgHtg = state.dataIPShortCut->rNumericArgs(17);
1374 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).SizFac = state.dataIPShortCut->rNumericArgs(18);
1375 :
1376 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).SizFac <= 0.0) {
1377 0 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).SizFac = 1.0;
1378 : }
1379 :
1380 6 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).OpenMotorEff < 0.0 ||
1381 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).OpenMotorEff > 1.0) {
1382 0 : ShowSevereError(state,
1383 0 : format("GetCurveInput: For {}: {}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1384 0 : ShowContinueError(state, format("{} = {:.3R}", state.dataIPShortCut->cNumericFieldNames(14), state.dataIPShortCut->rNumericArgs(14)));
1385 0 : ShowContinueError(state, format("{} must be greater than or equal to zero", state.dataIPShortCut->cNumericFieldNames(14)));
1386 0 : ShowContinueError(state, format("{} must be less than or equal to one", state.dataIPShortCut->cNumericFieldNames(14)));
1387 0 : CHErrorsFound = true;
1388 : }
1389 :
1390 : // Check the CAP-FT, EIR-FT, and PLR curves and warn user if different from 1.0 by more than +-10%
1391 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTCoolingIDX > 0) {
1392 12 : Real64 CurveVal = Curve::CurveValue(state,
1393 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTCoolingIDX,
1394 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefEvapOutCooling,
1395 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondInCooling);
1396 3 : if (CurveVal > 1.10 || CurveVal < 0.90) {
1397 0 : ShowWarningError(state, "Capacity ratio as a function of temperature curve output is not equal to 1.0");
1398 0 : ShowContinueError(state,
1399 0 : format("(+ or - 10%) at reference conditions for {}= {}",
1400 0 : state.dataIPShortCut->cCurrentModuleObject,
1401 0 : state.dataIPShortCut->cAlphaArgs(1)));
1402 0 : ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
1403 : }
1404 : }
1405 :
1406 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTCoolingIDX > 0) {
1407 12 : Real64 CurveVal = Curve::CurveValue(state,
1408 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTCoolingIDX,
1409 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefEvapOutCooling,
1410 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondInCooling);
1411 3 : if (CurveVal > 1.10 || CurveVal < 0.90) {
1412 0 : ShowWarningError(state, "Energy input ratio as a function of temperature curve output is not equal to 1.0");
1413 0 : ShowContinueError(state,
1414 0 : format("(+ or - 10%) at reference conditions for {}= {}",
1415 0 : state.dataIPShortCut->cCurrentModuleObject,
1416 0 : state.dataIPShortCut->cAlphaArgs(1)));
1417 0 : ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
1418 : }
1419 : }
1420 :
1421 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX > 0) {
1422 3 : Real64 CurveVal = Curve::CurveValue(state, state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX, 1.0);
1423 :
1424 3 : if (CurveVal > 1.10 || CurveVal < 0.90) {
1425 0 : ShowWarningError(state, "Energy input ratio as a function of part-load ratio curve output is not equal to 1.0");
1426 0 : ShowContinueError(state,
1427 0 : format("(+ or - 10%) at reference conditions for {}= {}",
1428 0 : state.dataIPShortCut->cCurrentModuleObject,
1429 0 : state.dataIPShortCut->cAlphaArgs(1)));
1430 0 : ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
1431 : }
1432 : }
1433 :
1434 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX > 0) {
1435 3 : bool FoundNegValue = false;
1436 36 : for (int CurveCheck = 0; CurveCheck <= 10; ++CurveCheck) {
1437 99 : Real64 CurveValTmp = Curve::CurveValue(
1438 33 : state, state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX, double(CurveCheck / 10.0));
1439 33 : if (CurveValTmp < 0.0) {
1440 0 : FoundNegValue = true;
1441 : }
1442 33 : CurveValArray(CurveCheck + 1) = int(CurveValTmp * 100.0) / 100.0;
1443 : }
1444 3 : if (FoundNegValue) {
1445 0 : ShowWarningError(state, "Energy input ratio as a function of part-load ratio curve shows negative values ");
1446 0 : ShowContinueError(state, format("for {}= {}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1447 0 : ShowContinueError(state, "EIR as a function of PLR curve output at various part-load ratios shown below:");
1448 0 : ShowContinueError(state, "PLR = 0.00 0.10 0.20 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00");
1449 :
1450 0 : ShowContinueError(state, fmt::format("Curve Output = {:7.2F}", fmt::join(CurveValArray, ",")));
1451 :
1452 0 : CHErrorsFound = true;
1453 : }
1454 : }
1455 :
1456 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTHeatingIDX > 0) {
1457 12 : Real64 CurveVal = Curve::CurveValue(state,
1458 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerCapFTHeatingIDX,
1459 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg,
1460 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondInClgHtg);
1461 3 : if (CurveVal > 1.10 || CurveVal < 0.90) {
1462 6 : ShowWarningError(state, "Capacity ratio as a function of temperature curve output is not equal to 1.0");
1463 6 : ShowContinueError(state,
1464 9 : format("(+ or - 10%) at reference conditions for {}= {}",
1465 3 : state.dataIPShortCut->cCurrentModuleObject,
1466 3 : state.dataIPShortCut->cAlphaArgs(1)));
1467 3 : ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
1468 : }
1469 : }
1470 :
1471 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTHeatingIDX > 0) {
1472 12 : Real64 CurveVal = Curve::CurveValue(state,
1473 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFTHeatingIDX,
1474 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg,
1475 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).TempRefCondInClgHtg);
1476 3 : if (CurveVal > 1.10 || CurveVal < 0.90) {
1477 6 : ShowWarningError(state, "Energy input ratio as a function of temperature curve output is not equal to 1.0");
1478 6 : ShowContinueError(state,
1479 9 : format("(+ or - 10%) at reference conditions for {}= {}",
1480 3 : state.dataIPShortCut->cCurrentModuleObject,
1481 3 : state.dataIPShortCut->cAlphaArgs(1)));
1482 3 : ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
1483 : }
1484 : }
1485 :
1486 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX > 0) {
1487 3 : Real64 CurveVal = Curve::CurveValue(state, state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX, 1.0);
1488 :
1489 3 : if (CurveVal > 1.10 || CurveVal < 0.90) {
1490 0 : ShowWarningError(state, "Energy input ratio as a function of part-load ratio curve output is not equal to 1.0");
1491 0 : ShowContinueError(state,
1492 0 : format("(+ or - 10%) at reference conditions for {}= {}",
1493 0 : state.dataIPShortCut->cCurrentModuleObject,
1494 0 : state.dataIPShortCut->cAlphaArgs(1)));
1495 0 : ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
1496 : }
1497 : }
1498 :
1499 3 : if (state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX > 0) {
1500 3 : bool FoundNegValue = false;
1501 36 : for (int CurveCheck = 0; CurveCheck <= 10; ++CurveCheck) {
1502 99 : Real64 CurveValTmp = Curve::CurveValue(
1503 33 : state, state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX, double(CurveCheck / 10.0));
1504 33 : if (CurveValTmp < 0.0) {
1505 0 : FoundNegValue = true;
1506 : }
1507 33 : CurveValArray(CurveCheck + 1) = int(CurveValTmp * 100.0) / 100.0;
1508 : }
1509 3 : if (FoundNegValue) {
1510 0 : ShowWarningError(state, "Energy input ratio as a function of part-load ratio curve shows negative values ");
1511 0 : ShowContinueError(state, format("for {}= {}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
1512 0 : ShowContinueError(state, "EIR as a function of PLR curve output at various part-load ratios shown below:");
1513 0 : ShowContinueError(state, "PLR = 0.00 0.10 0.20 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00");
1514 :
1515 0 : std::string const curve_output = fmt::format("Curve Output = {:7.2F}", fmt::join(CurveValArray, ","));
1516 0 : ShowContinueError(state, curve_output);
1517 :
1518 0 : CHErrorsFound = true;
1519 0 : }
1520 : }
1521 :
1522 3 : Curve::GetCurveMinMaxValues(state,
1523 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX,
1524 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).MinPartLoadRatClgHtg,
1525 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).MaxPartLoadRatClgHtg);
1526 :
1527 3 : Curve::GetCurveMinMaxValues(state,
1528 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX,
1529 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).MinPartLoadRatCooling,
1530 3 : state.dataPlantCentralGSHP->ChillerHeater(ChillerHeaterNum).MaxPartLoadRatCooling);
1531 : }
1532 :
1533 2 : if (CHErrorsFound) {
1534 0 : ShowFatalError(state, format("Errors found in processing input for {}", state.dataIPShortCut->cCurrentModuleObject));
1535 : }
1536 2 : }
1537 :
1538 102470 : void WrapperSpecs::initialize(EnergyPlusData &state,
1539 : Real64 MyLoad, // Demand Load
1540 : int LoopNum // Loop Number Index
1541 : )
1542 : {
1543 : // SUBROUTINE INFORMATION:
1544 : // AUTHOR Daeho Kang, PNNL
1545 : // DATE WRITTEN Feb 2013
1546 : // MODIFIED na
1547 : // RE-ENGINEERED na
1548 :
1549 : // PURPOSE OF THIS SUBROUTINE:
1550 : // This subroutine is for initializations of the CentralHeatPumpSystem variables
1551 :
1552 : // METHODOLOGY EMPLOYED:
1553 : // Uses the status flags to trigger initializations.
1554 :
1555 : static constexpr std::string_view RoutineName("InitCGSHPHeatPump");
1556 :
1557 102470 : if (this->setupOutputVarsFlag) {
1558 2 : this->setupOutputVars(state);
1559 2 : this->setupOutputVarsFlag = false;
1560 : }
1561 :
1562 102470 : if (this->MyWrapperFlag) {
1563 : // Locate the chillers on the plant loops for later usage
1564 2 : bool errFlag = false;
1565 6 : PlantUtilities::ScanPlantLoopsForObject(state,
1566 : this->Name,
1567 : DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump,
1568 2 : this->CWPlantLoc,
1569 : errFlag,
1570 : _,
1571 : _,
1572 : _,
1573 2 : this->CHWInletNodeNum,
1574 : _);
1575 :
1576 6 : PlantUtilities::ScanPlantLoopsForObject(state,
1577 : this->Name,
1578 : DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump,
1579 2 : this->HWPlantLoc,
1580 : errFlag,
1581 : _,
1582 : _,
1583 : _,
1584 2 : this->HWInletNodeNum,
1585 : _);
1586 :
1587 6 : PlantUtilities::ScanPlantLoopsForObject(state,
1588 : this->Name,
1589 : DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump,
1590 2 : this->GLHEPlantLoc,
1591 : errFlag,
1592 : _,
1593 : _,
1594 : _,
1595 2 : this->GLHEInletNodeNum,
1596 : _);
1597 :
1598 2 : PlantUtilities::InterConnectTwoPlantLoopSides(
1599 2 : state, this->CWPlantLoc, this->GLHEPlantLoc, DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump, true);
1600 :
1601 2 : PlantUtilities::InterConnectTwoPlantLoopSides(
1602 2 : state, this->HWPlantLoc, this->GLHEPlantLoc, DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump, true);
1603 :
1604 2 : PlantUtilities::InterConnectTwoPlantLoopSides(
1605 2 : state, this->CWPlantLoc, this->HWPlantLoc, DataPlant::PlantEquipmentType::CentralGroundSourceHeatPump, true);
1606 :
1607 2 : if (this->VariableFlowCH) {
1608 : // Reset flow priority
1609 2 : if (LoopNum == this->CWPlantLoc.loopNum) {
1610 2 : DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
1611 0 : } else if (LoopNum == this->HWPlantLoc.loopNum) {
1612 0 : DataPlant::CompData::getPlantComponent(state, this->HWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
1613 : }
1614 :
1615 : // check if setpoint on outlet node - chilled water loop
1616 2 : if (state.dataLoopNodes->Node(this->CHWOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) {
1617 2 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1618 2 : if (!this->CoolSetPointErrDone) {
1619 4 : ShowWarningError(state,
1620 4 : format("Missing temperature setpoint on cooling side for CentralHeatPumpSystem named {}", this->Name));
1621 4 : ShowContinueError(state,
1622 : " A temperature setpoint is needed at the outlet node of a CentralHeatPumpSystem, use a SetpointManager");
1623 4 : ShowContinueError(state,
1624 : " The overall loop setpoint will be assumed for CentralHeatPumpSystem. The simulation continues ... ");
1625 2 : this->CoolSetPointErrDone = true;
1626 : }
1627 : } else {
1628 : // need call to EMS to check node
1629 0 : bool FatalError = false; // but not really fatal yet, but should be.
1630 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->CHWOutletNodeNum, HVAC::CtrlVarType::Temp, FatalError);
1631 0 : state.dataLoopNodes->NodeSetpointCheck(this->CHWOutletNodeNum).needsSetpointChecking = false;
1632 0 : if (FatalError) {
1633 0 : if (!this->CoolSetPointErrDone) {
1634 0 : ShowWarningError(state,
1635 0 : format("Missing temperature setpoint on cooling side for CentralHeatPumpSystem named {}", this->Name));
1636 0 : ShowContinueError(state, "A temperature setpoint is needed at the outlet node of a CentralHeatPumpSystem ");
1637 0 : ShowContinueError(state, "use a Setpoint Manager to establish a setpoint at the chiller side outlet node ");
1638 0 : ShowContinueError(state, "or use an EMS actuator to establish a setpoint at the outlet node ");
1639 0 : ShowContinueError(state, "The overall loop setpoint will be assumed for chiller side. The simulation continues ... ");
1640 0 : this->CoolSetPointErrDone = true;
1641 : }
1642 : }
1643 : }
1644 2 : this->CoolSetPointSetToLoop = true;
1645 2 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).TempSetPoint =
1646 2 : state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
1647 : }
1648 :
1649 2 : if (state.dataLoopNodes->Node(this->HWOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) {
1650 2 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1651 2 : if (!this->HeatSetPointErrDone) {
1652 4 : ShowWarningError(state,
1653 4 : format("Missing temperature setpoint on heating side for CentralHeatPumpSystem named {}", this->Name));
1654 4 : ShowContinueError(state,
1655 : " A temperature setpoint is needed at the outlet node of a CentralHeatPumpSystem, use a SetpointManager");
1656 4 : ShowContinueError(state,
1657 : " The overall loop setpoint will be assumed for CentralHeatPumpSystem. The simulation continues ... ");
1658 2 : this->HeatSetPointErrDone = true;
1659 : }
1660 : } else {
1661 : // need call to EMS to check node
1662 0 : bool FatalError = false; // but not really fatal yet, but should be.
1663 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->HWOutletNodeNum, HVAC::CtrlVarType::Temp, FatalError);
1664 0 : state.dataLoopNodes->NodeSetpointCheck(this->HWOutletNodeNum).needsSetpointChecking = false;
1665 0 : if (FatalError) {
1666 0 : if (!this->HeatSetPointErrDone) {
1667 0 : ShowWarningError(state,
1668 0 : format("Missing temperature setpoint on heating side for CentralHeatPumpSystem named {}", this->Name));
1669 0 : ShowContinueError(state, "A temperature setpoint is needed at the outlet node of a CentralHeatPumpSystem ");
1670 0 : ShowContinueError(state, "use a Setpoint Manager to establish a setpoint at the chiller side outlet node ");
1671 0 : ShowContinueError(state, "or use an EMS actuator to establish a setpoint at the outlet node ");
1672 0 : ShowContinueError(state, "The overall loop setpoint will be assumed for chiller side. The simulation continues ... ");
1673 0 : this->HeatSetPointErrDone = true;
1674 : }
1675 : }
1676 : }
1677 2 : this->HeatSetPointSetToLoop = true;
1678 2 : state.dataLoopNodes->Node(this->HWOutletNodeNum).TempSetPoint =
1679 2 : state.dataLoopNodes->Node(this->HWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
1680 : }
1681 : }
1682 2 : this->MyWrapperFlag = false;
1683 : }
1684 :
1685 102470 : if (this->MyWrapperEnvrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
1686 :
1687 11 : if (this->ControlMode == CondenserType::SmartMixing) {
1688 :
1689 11 : this->CHWVolFlowRate = 0.0;
1690 11 : this->HWVolFlowRate = 0.0;
1691 11 : this->GLHEVolFlowRate = 0.0;
1692 :
1693 50 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
1694 39 : this->CHWVolFlowRate += this->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate;
1695 39 : this->HWVolFlowRate += this->ChillerHeater(ChillerHeaterNum).DesignHotWaterVolFlowRate;
1696 39 : this->GLHEVolFlowRate += this->ChillerHeater(ChillerHeaterNum).CondVolFlowRate;
1697 : }
1698 :
1699 11 : Real64 rho = this->CWPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
1700 :
1701 11 : this->CHWMassFlowRateMax = this->CHWVolFlowRate * rho;
1702 11 : this->HWMassFlowRateMax = this->HWVolFlowRate * rho;
1703 11 : this->GLHEMassFlowRateMax = this->GLHEVolFlowRate * rho;
1704 :
1705 11 : PlantUtilities::InitComponentNodes(state, 0.0, this->CHWMassFlowRateMax, this->CHWInletNodeNum, this->CHWOutletNodeNum);
1706 11 : PlantUtilities::InitComponentNodes(state, 0.0, this->HWMassFlowRateMax, this->HWInletNodeNum, this->HWOutletNodeNum);
1707 11 : PlantUtilities::InitComponentNodes(state, 0.0, this->GLHEMassFlowRateMax, this->GLHEInletNodeNum, this->GLHEOutletNodeNum);
1708 :
1709 : // Initialize nodes for individual chiller heaters
1710 50 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
1711 39 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRateMin = 0.0;
1712 39 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRateMinAvail = 0.0;
1713 39 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRateMax = rho * this->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate;
1714 78 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRateMaxAvail =
1715 39 : rho * this->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate;
1716 39 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRate = 0.0;
1717 39 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateMin = 0.0;
1718 39 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateMinAvail = 0.0;
1719 39 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateMax = rho * this->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate;
1720 78 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateMaxAvail =
1721 39 : rho * this->ChillerHeater(ChillerHeaterNum).EvapVolFlowRate;
1722 39 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRate = 0.0;
1723 39 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateRequest = 0.0;
1724 : }
1725 : }
1726 11 : this->MyWrapperEnvrnFlag = false;
1727 : }
1728 :
1729 102470 : if (!state.dataGlobal->BeginEnvrnFlag) {
1730 102048 : this->MyWrapperEnvrnFlag = true;
1731 : }
1732 :
1733 102470 : if (this->CoolSetPointSetToLoop) {
1734 : // IF (CurCoolingLoad > 0.0d0) THEN
1735 102470 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).TempSetPoint =
1736 102470 : state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
1737 : }
1738 : // IF (CurHeatingLoad > 0.0d0) THEN
1739 102470 : if (this->HeatSetPointSetToLoop) {
1740 102470 : state.dataLoopNodes->Node(this->HWOutletNodeNum).TempSetPoint =
1741 102470 : state.dataLoopNodes->Node(this->HWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
1742 : // ENDIF
1743 : }
1744 :
1745 : Real64 mdotCHW; // Chilled water mass flow rate
1746 : Real64 mdotHW; // Hot water mass flow rate
1747 : Real64 mdotGLHE; // Condenser water mass flow rate
1748 :
1749 : // Switch over the mass flow rate to the condenser loop, i.e., ground heat exchanger
1750 102470 : if (LoopNum == this->CWPlantLoc.loopNum) { // called for on cooling loop
1751 51230 : if (MyLoad < -1.0) { // calling for cooling
1752 9568 : mdotCHW = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRateMax;
1753 : } else {
1754 41662 : mdotCHW = 0.0;
1755 : }
1756 51230 : if (this->WrapperHeatingLoad > 1.0) {
1757 21478 : mdotHW = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRateMax;
1758 : } else {
1759 29752 : mdotHW = 0.0;
1760 : }
1761 51230 : if ((MyLoad < -1.0) || (this->WrapperHeatingLoad > 1.0)) {
1762 26524 : mdotGLHE = state.dataLoopNodes->Node(this->GLHEInletNodeNum).MassFlowRateMax;
1763 : } else {
1764 24706 : mdotGLHE = 0.0;
1765 : }
1766 :
1767 51240 : } else if (LoopNum == this->HWPlantLoc.loopNum) {
1768 51230 : if (MyLoad > 1.0) {
1769 21478 : mdotHW = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRateMax;
1770 : } else {
1771 29752 : mdotHW = 0.0;
1772 : }
1773 51230 : if (this->WrapperCoolingLoad > 1.0) {
1774 9568 : mdotCHW = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRateMax;
1775 : } else {
1776 41662 : mdotCHW = 0.0;
1777 : }
1778 51230 : if ((MyLoad > 1.0) || (this->WrapperCoolingLoad > 1.0)) {
1779 26510 : mdotGLHE = state.dataLoopNodes->Node(this->GLHEInletNodeNum).MassFlowRateMax;
1780 : } else {
1781 24720 : mdotGLHE = 0.0;
1782 : }
1783 :
1784 10 : } else if (LoopNum == this->GLHEPlantLoc.loopNum) {
1785 10 : if (this->WrapperCoolingLoad > 1.0) {
1786 0 : mdotCHW = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRateMax;
1787 : } else {
1788 10 : mdotCHW = 0.0;
1789 : }
1790 10 : if (this->WrapperHeatingLoad > 1.0) {
1791 0 : mdotHW = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRateMax;
1792 : } else {
1793 10 : mdotHW = 0.0;
1794 : }
1795 10 : if ((this->WrapperHeatingLoad > 1.0) || (this->WrapperCoolingLoad > 1.0)) {
1796 0 : mdotGLHE = state.dataLoopNodes->Node(this->GLHEInletNodeNum).MassFlowRateMax;
1797 : } else {
1798 10 : mdotGLHE = 0.0;
1799 : }
1800 : }
1801 :
1802 102470 : PlantUtilities::SetComponentFlowRate(state, mdotCHW, this->CHWInletNodeNum, this->CHWOutletNodeNum, this->CWPlantLoc);
1803 :
1804 102470 : PlantUtilities::SetComponentFlowRate(state, mdotHW, this->HWInletNodeNum, this->HWOutletNodeNum, this->HWPlantLoc);
1805 :
1806 102470 : PlantUtilities::SetComponentFlowRate(state, mdotGLHE, this->GLHEInletNodeNum, this->GLHEOutletNodeNum, this->GLHEPlantLoc);
1807 102470 : }
1808 :
1809 9568 : void WrapperSpecs::CalcChillerModel(EnergyPlusData &state)
1810 : {
1811 : // SUBROUTINE INFORMATION:
1812 : // AUTHOR Daeho Kang, PNNL
1813 : // DATE WRITTEN Feb 2013
1814 : // MODIFIED na
1815 : // RE-ENGINEERED na
1816 :
1817 : // PURPOSE OF THIS SUBROUTINE:
1818 : // Simulate a ChillerHeaterPerformance:Electric:EIR using curve fit
1819 :
1820 : // METHODOLOGY EMPLOYED:
1821 : // Use empirical curve fits to model performance at off-reference conditions
1822 :
1823 : // REFERENCES:
1824 : // 1. DOE-2 Engineers Manual, Version 2.1A, November 1982, LBL-11353
1825 :
1826 : static constexpr std::string_view RoutineName("CalcChillerHeaterModel");
1827 : static constexpr std::string_view RoutineNameElecEIRChiller("CalcElectricEIRChillerModel");
1828 :
1829 : bool IsLoadCoolRemaining;
1830 9568 : bool NextCompIndicator(false); // Component indicator when identical chiller heaters exist
1831 9568 : int CompNum = 0; // Component number in the loop REAL(r64) :: FRAC
1832 9568 : int IdenticalUnitCounter = 0; // Pointer to count number of identical unit passed
1833 9568 : Real64 CurAvailCHWMassFlowRate(0.0); // Maximum available mass flow rate for current chiller heater
1834 :
1835 : // Cooling load evaporator should meet
1836 9568 : Real64 EvaporatorLoad = this->WrapperCoolingLoad;
1837 :
1838 : // Chilled water inlet mass flow rate
1839 9568 : Real64 CHWInletMassFlowRate = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRate;
1840 :
1841 43248 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
1842 :
1843 : // Initialize local variables for each chiller heater
1844 33680 : int CurrentMode = 0;
1845 33680 : state.dataPlantCentralGSHP->ChillerCapFT = 0.0;
1846 33680 : state.dataPlantCentralGSHP->ChillerEIRFT = 0.0;
1847 33680 : state.dataPlantCentralGSHP->ChillerEIRFPLR = 0.0;
1848 33680 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = 0.0;
1849 33680 : state.dataPlantCentralGSHP->ChillerCyclingRatio = 0.0;
1850 33680 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = 0.0;
1851 :
1852 33680 : Real64 CHPower = 0.0;
1853 33680 : Real64 QCondenser = 0.0;
1854 33680 : Real64 QEvaporator = 0.0;
1855 33680 : Real64 FRAC = 1.0;
1856 33680 : Real64 ActualCOP = 0.0;
1857 33680 : Real64 EvapInletTemp = state.dataLoopNodes->Node(this->CHWInletNodeNum).Temp;
1858 33680 : Real64 CondInletTemp = state.dataLoopNodes->Node(this->GLHEInletNodeNum).Temp;
1859 33680 : Real64 EvapOutletTemp = EvapInletTemp;
1860 33680 : Real64 CondOutletTemp = CondInletTemp;
1861 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = 0;
1862 :
1863 : // Find proper schedule values
1864 33680 : if (this->NumOfComp != this->ChillerHeaterNums) { // Identical units exist
1865 33680 : if (ChillerHeaterNum == 1) {
1866 9568 : IdenticalUnitCounter = 0;
1867 9568 : NextCompIndicator = false;
1868 9568 : CompNum = ChillerHeaterNum;
1869 : }
1870 33680 : if (NextCompIndicator) {
1871 4976 : ++CompNum;
1872 : }
1873 33680 : if (CompNum == 1) {
1874 23728 : if (ChillerHeaterNum != this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
1875 14160 : NextCompIndicator = false;
1876 9568 : } else if (ChillerHeaterNum == this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
1877 9568 : NextCompIndicator = true;
1878 : }
1879 9952 : } else if (CompNum > 1) {
1880 9952 : if ((ChillerHeaterNum - ((ChillerHeaterNum - 1) - IdenticalUnitCounter)) != this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
1881 4976 : NextCompIndicator = false;
1882 9952 : } else if ((ChillerHeaterNum - ((ChillerHeaterNum - 1) - IdenticalUnitCounter)) ==
1883 4976 : this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
1884 4976 : NextCompIndicator = true;
1885 : }
1886 : }
1887 33680 : ++IdenticalUnitCounter;
1888 33680 : int IdenticalUnitRemaining = this->WrapperComp(CompNum).WrapperIdenticalObjectNum - IdenticalUnitCounter;
1889 33680 : if (IdenticalUnitRemaining == 0) {
1890 14544 : IdenticalUnitCounter = 0;
1891 : }
1892 0 : } else if (this->NumOfComp == this->ChillerHeaterNums) {
1893 0 : ++CompNum;
1894 : }
1895 :
1896 33680 : if (CompNum > this->NumOfComp) {
1897 0 : ShowSevereError(state, format("CalcChillerModel: ChillerHeater=\"{}\", calculated component number too big.", this->Name));
1898 0 : ShowContinueError(state, format("Max number of components=[{}], indicated component number=[{}].", this->NumOfComp, CompNum));
1899 0 : ShowFatalError(state, "Program terminates due to preceding condition.");
1900 : }
1901 :
1902 : Real64 EvapMassFlowRate; // Actual evaporator mass flow rate
1903 : Real64 CondMassFlowRate; // Condenser mass flow rate
1904 :
1905 : // Check whether this chiller heater needs to run
1906 33680 : if (EvaporatorLoad > 0.0 && (this->WrapperComp(CompNum).chSched->getCurrentVal() > 0.0)) {
1907 24923 : IsLoadCoolRemaining = true;
1908 :
1909 : // Calculate density ratios to adjust mass flow rates from initialized ones
1910 : // Hot water temperature is known, but evaporator mass flow rates will be adjusted in the following "Do" loop
1911 24923 : Real64 InitDensity = this->CWPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
1912 24923 : Real64 EvapDensity = this->CWPlantLoc.loop->glycol->getDensity(state, EvapInletTemp, RoutineName);
1913 24923 : Real64 CondDensity = this->CWPlantLoc.loop->glycol->getDensity(state, CondInletTemp, RoutineName);
1914 :
1915 : // Calculate density ratios to adjust mass flow rates from initialized ones
1916 :
1917 : // Fraction between standardized density and local density in the chilled water side
1918 24923 : Real64 CHWDensityRatio = EvapDensity / InitDensity;
1919 :
1920 : // Fraction between standardized density and local density in the condenser side
1921 24923 : Real64 GLHEDensityRatio = CondDensity / InitDensity;
1922 24923 : CondMassFlowRate = this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateMaxAvail;
1923 24923 : EvapMassFlowRate = this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRateMaxAvail;
1924 24923 : EvapMassFlowRate *= CHWDensityRatio;
1925 24923 : CondMassFlowRate *= GLHEDensityRatio;
1926 :
1927 : // Check available flows from plant and then adjust as necessary
1928 24923 : if (CurAvailCHWMassFlowRate == 0) { // The very first chiller heater to operate
1929 9747 : CurAvailCHWMassFlowRate = CHWInletMassFlowRate;
1930 15176 : } else if (ChillerHeaterNum > 1) {
1931 15176 : CurAvailCHWMassFlowRate -= this->ChillerHeater(ChillerHeaterNum - 1).EvapOutletNode.MassFlowRate;
1932 : }
1933 24923 : EvapMassFlowRate = min(CurAvailCHWMassFlowRate, EvapMassFlowRate);
1934 : } else {
1935 8757 : IsLoadCoolRemaining = false;
1936 8757 : EvapMassFlowRate = 0.0;
1937 8757 : CondMassFlowRate = 0.0;
1938 8757 : CurrentMode = 0;
1939 : }
1940 :
1941 : // Chiller heater is on when cooling load for this chiller heater remains and chilled water available
1942 33680 : if (IsLoadCoolRemaining && (EvapMassFlowRate > 0) && (this->WrapperComp(CompNum).chSched->getCurrentVal() > 0)) {
1943 : // Indicate current mode is cooling-only mode. Simultaneous clg/htg mode will be set later
1944 24167 : CurrentMode = 1;
1945 :
1946 : // Assign proper performance curve information depending on the control mode
1947 : // Cooling curve is used only for cooling-only mode, and the others (Simultaneous and heating) read the heating curve
1948 24167 : if (this->SimulClgDominant || this->SimulHtgDominant) {
1949 10048 : this->ChillerHeater(ChillerHeaterNum).RefCap = this->ChillerHeater(ChillerHeaterNum).RefCapClgHtg;
1950 10048 : this->ChillerHeater(ChillerHeaterNum).RefCOP = this->ChillerHeater(ChillerHeaterNum).RefCOPClgHtg;
1951 10048 : this->ChillerHeater(ChillerHeaterNum).TempRefEvapOut = this->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg;
1952 10048 : this->ChillerHeater(ChillerHeaterNum).TempRefCondIn = this->ChillerHeater(ChillerHeaterNum).TempRefCondInClgHtg;
1953 10048 : this->ChillerHeater(ChillerHeaterNum).TempRefCondOut = this->ChillerHeater(ChillerHeaterNum).TempRefCondOutClgHtg;
1954 10048 : this->ChillerHeater(ChillerHeaterNum).OptPartLoadRat = this->ChillerHeater(ChillerHeaterNum).OptPartLoadRatClgHtg;
1955 10048 : this->ChillerHeater(ChillerHeaterNum).CondMode = this->ChillerHeater(ChillerHeaterNum).CondModeHeating;
1956 10048 : this->ChillerHeater(ChillerHeaterNum).ChillerCapFTIDX = this->ChillerHeater(ChillerHeaterNum).ChillerCapFTHeatingIDX;
1957 10048 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTIDX = this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTHeatingIDX;
1958 10048 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX = this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX;
1959 : } else {
1960 14119 : this->ChillerHeater(ChillerHeaterNum).RefCap = this->ChillerHeater(ChillerHeaterNum).RefCapCooling;
1961 14119 : this->ChillerHeater(ChillerHeaterNum).RefCOP = this->ChillerHeater(ChillerHeaterNum).RefCOPCooling;
1962 14119 : this->ChillerHeater(ChillerHeaterNum).TempRefEvapOut = this->ChillerHeater(ChillerHeaterNum).TempRefEvapOutCooling;
1963 14119 : this->ChillerHeater(ChillerHeaterNum).TempRefCondIn = this->ChillerHeater(ChillerHeaterNum).TempRefCondInCooling;
1964 14119 : this->ChillerHeater(ChillerHeaterNum).TempRefCondOut = this->ChillerHeater(ChillerHeaterNum).TempRefCondOutCooling;
1965 14119 : this->ChillerHeater(ChillerHeaterNum).OptPartLoadRat = this->ChillerHeater(ChillerHeaterNum).OptPartLoadRatCooling;
1966 14119 : this->ChillerHeater(ChillerHeaterNum).CondMode = this->ChillerHeater(ChillerHeaterNum).CondModeCooling;
1967 14119 : this->ChillerHeater(ChillerHeaterNum).ChillerCapFTIDX = this->ChillerHeater(ChillerHeaterNum).ChillerCapFTCoolingIDX;
1968 14119 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTIDX = this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTCoolingIDX;
1969 14119 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX = this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRCoolingIDX;
1970 : }
1971 :
1972 : // Only used to read curve values
1973 24167 : CondOutletTemp = this->ChillerHeater(ChillerHeaterNum).TempRefCondOutCooling;
1974 24167 : Real64 CondTempforCurve = this->setChillerHeaterCondTemp(state, ChillerHeaterNum, CondInletTemp, CondOutletTemp);
1975 :
1976 : // Chiller reference capacity
1977 24167 : Real64 ChillerRefCap = this->ChillerHeater(ChillerHeaterNum).RefCap;
1978 24167 : Real64 ReferenceCOP = this->ChillerHeater(ChillerHeaterNum).RefCOP;
1979 24167 : Real64 TempLowLimitEout = this->ChillerHeater(ChillerHeaterNum).TempLowLimitEvapOut;
1980 24167 : Real64 EvapOutletTempSetPoint = this->ChillerHeater(ChillerHeaterNum).TempRefEvapOutCooling;
1981 :
1982 : // Calculate Chiller Capacity as a function of temperature and error check
1983 24167 : state.dataPlantCentralGSHP->ChillerCapFT = this->calcChillerCapFT(state, ChillerHeaterNum, EvapOutletTempSetPoint, CondTempforCurve);
1984 :
1985 : // Calculate the specific heat of chilled water
1986 24167 : Real64 Cp = this->CWPlantLoc.loop->glycol->getSpecificHeat(state, EvapInletTemp, RoutineName);
1987 :
1988 : // Calculate cooling load this chiller should meet and the other chillers are demanded
1989 24167 : EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
1990 :
1991 : // Minimum capacity of the evaporator
1992 : Real64 EvaporatorCapMin =
1993 24167 : this->ChillerHeater(ChillerHeaterNum).MinPartLoadRatCooling * this->ChillerHeater(ChillerHeaterNum).RefCapCooling;
1994 :
1995 : // Remaining cooling load the other chiller heaters should meet
1996 24167 : Real64 CoolingLoadToMeet = min(this->ChillerHeater(ChillerHeaterNum).RefCapCooling, max(std::abs(EvaporatorLoad), EvaporatorCapMin));
1997 :
1998 : // Available chiller capacity as a function of temperature
1999 : // Chiller available capacity at current operating conditions [W]
2000 24167 : Real64 AvailChillerCap = ChillerRefCap * state.dataPlantCentralGSHP->ChillerCapFT;
2001 :
2002 : Real64 PartLoadRat; // Operating part load ratio
2003 : Real64 MinPartLoadRat; // Min allowed operating fraction of full load
2004 : Real64 MaxPartLoadRat; // Max allowed operating fraction of full load
2005 :
2006 24167 : Curve::GetCurveMinMaxValues(state, this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX, MinPartLoadRat, MaxPartLoadRat);
2007 :
2008 : // Set load this chiller heater should meet
2009 24167 : QEvaporator = min(CoolingLoadToMeet, (AvailChillerCap * MaxPartLoadRat));
2010 24167 : EvapOutletTemp = EvapOutletTempSetPoint;
2011 24167 : Real64 EvapDeltaTemp = EvapInletTemp - EvapOutletTemp;
2012 :
2013 : // Calculate temperatures for constant flow and mass flow rates for variable flow
2014 24167 : if (EvapMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
2015 24167 : if (this->SimulHtgDominant) { // Evaporator operates at full capacity for heating
2016 0 : PartLoadRat = max(0.0, min((ChillerRefCap / AvailChillerCap), MaxPartLoadRat));
2017 0 : QEvaporator = AvailChillerCap * PartLoadRat;
2018 0 : EvapDeltaTemp = QEvaporator / EvapMassFlowRate / Cp;
2019 0 : EvapOutletTemp = EvapInletTemp - EvapDeltaTemp;
2020 : } else { // Cooling only mode or cooling dominant simultaneous htg/clg mode
2021 24167 : if (this->VariableFlowCH) { // Variable flow
2022 24167 : Real64 EvapMassFlowRateCalc = QEvaporator / EvapDeltaTemp / Cp;
2023 24167 : if (EvapMassFlowRateCalc > EvapMassFlowRate) {
2024 10176 : EvapMassFlowRateCalc = EvapMassFlowRate;
2025 10176 : Real64 EvapDeltaTempCalc = QEvaporator / EvapMassFlowRate / Cp;
2026 10176 : EvapOutletTemp = EvapInletTemp - EvapDeltaTempCalc;
2027 10176 : if (EvapDeltaTempCalc > EvapDeltaTemp) {
2028 10067 : QEvaporator = EvapMassFlowRate * Cp * EvapDeltaTemp;
2029 : }
2030 : }
2031 24167 : EvapMassFlowRate = EvapMassFlowRateCalc;
2032 : } else { // Constant Flow
2033 0 : Real64 EvapOutletTempCalc = EvapInletTemp - EvapDeltaTemp;
2034 0 : if (EvapOutletTempCalc > EvapOutletTemp) { // Load to meet should be adjusted
2035 0 : EvapOutletTempCalc = EvapOutletTemp;
2036 0 : QEvaporator = EvapMassFlowRate * Cp * EvapDeltaTemp;
2037 : }
2038 0 : EvapOutletTemp = EvapOutletTempCalc;
2039 : } // End of flow control decision
2040 : } // End of operation mode
2041 : } else {
2042 0 : QEvaporator = 0.0;
2043 0 : EvapOutletTemp = EvapInletTemp;
2044 : }
2045 :
2046 : // Run evaporator checks and adjust outlet temp and QEvaporator if necessary
2047 24167 : WrapperSpecs::checkEvapOutletTemp(
2048 : state, ChillerHeaterNum, EvapOutletTemp, TempLowLimitEout, EvapInletTemp, QEvaporator, EvapMassFlowRate, Cp);
2049 :
2050 : // Calculate part load once more since evaporator capacity might be modified
2051 24167 : WrapperSpecs::calcPLRAndCyclingRatio(state, AvailChillerCap, PartLoadRat, MinPartLoadRat, MaxPartLoadRat, QEvaporator, FRAC);
2052 :
2053 : // Determine chiller compressor power and transfer heat calculation
2054 24167 : state.dataPlantCentralGSHP->ChillerEIRFT =
2055 24167 : max(0.0, Curve::CurveValue(state, this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTIDX, EvapOutletTemp, CondTempforCurve));
2056 24167 : state.dataPlantCentralGSHP->ChillerEIRFPLR =
2057 24167 : max(0.0, Curve::CurveValue(state, this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX, PartLoadRat));
2058 :
2059 24167 : if (ReferenceCOP <= 0.0) {
2060 0 : CHPower = 0.0;
2061 : } else {
2062 24167 : CHPower =
2063 24167 : (AvailChillerCap / ReferenceCOP) * state.dataPlantCentralGSHP->ChillerEIRFPLR * state.dataPlantCentralGSHP->ChillerEIRFT * FRAC;
2064 : }
2065 :
2066 24167 : QCondenser =
2067 24167 : CHPower * this->ChillerHeater(ChillerHeaterNum).OpenMotorEff + QEvaporator + state.dataPlantCentralGSHP->ChillerFalseLoadRate;
2068 :
2069 24167 : if (CHPower == 0.0) {
2070 0 : ActualCOP = 0.0;
2071 : } else {
2072 24167 : ActualCOP = (QEvaporator + state.dataPlantCentralGSHP->ChillerFalseLoadRate) / CHPower;
2073 : }
2074 :
2075 24167 : if (CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
2076 24167 : Cp = this->GLHEPlantLoc.loop->glycol->getSpecificHeat(state, CondInletTemp, RoutineNameElecEIRChiller);
2077 24167 : CondOutletTemp = QCondenser / CondMassFlowRate / Cp + CondInletTemp;
2078 : } else {
2079 0 : ShowSevereError(
2080 0 : state, format("CalcChillerheaterModel: Condenser flow = 0, for Chillerheater={}", this->ChillerHeater(ChillerHeaterNum).Name));
2081 0 : ShowContinueErrorTimeStamp(state, "");
2082 : }
2083 :
2084 : // Determine load next chillers should meet
2085 24167 : if (EvaporatorLoad < QEvaporator) {
2086 3270 : EvaporatorLoad = 0.0; // No remaining load so the rest will be off
2087 : } else {
2088 20897 : EvaporatorLoad -= QEvaporator;
2089 : }
2090 :
2091 : // Initialize reporting variable when this chiller doesn't need to operate
2092 24167 : if (QEvaporator == 0.0) {
2093 0 : CurrentMode = 0;
2094 0 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = 0.0;
2095 0 : state.dataPlantCentralGSHP->ChillerCyclingRatio = 0.0;
2096 0 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = 0.0;
2097 0 : EvapMassFlowRate = 0.0;
2098 0 : CondMassFlowRate = 0.0;
2099 0 : CHPower = 0.0;
2100 0 : QCondenser = 0.0;
2101 0 : EvapOutletTemp = EvapInletTemp;
2102 0 : CondOutletTemp = CondInletTemp;
2103 0 : EvaporatorLoad = 0.0;
2104 : }
2105 :
2106 : } // End of calculation for cooling
2107 :
2108 : // Set variables to the arrays
2109 33680 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.MassFlowRate = EvapMassFlowRate;
2110 33680 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.MassFlowRate = CondMassFlowRate;
2111 33680 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.Temp = EvapOutletTemp;
2112 33680 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.Temp = EvapInletTemp;
2113 33680 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.Temp = CondOutletTemp;
2114 33680 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.Temp = CondInletTemp;
2115 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = CurrentMode;
2116 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatio = state.dataPlantCentralGSHP->ChillerPartLoadRatio;
2117 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatio = state.dataPlantCentralGSHP->ChillerCyclingRatio;
2118 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate = state.dataPlantCentralGSHP->ChillerFalseLoadRate;
2119 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFT = state.dataPlantCentralGSHP->ChillerCapFT;
2120 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFT = state.dataPlantCentralGSHP->ChillerEIRFT;
2121 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLR = state.dataPlantCentralGSHP->ChillerEIRFPLR;
2122 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower = CHPower;
2123 33680 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower = 0.0;
2124 33680 : this->ChillerHeater(ChillerHeaterNum).Report.QEvap = QEvaporator;
2125 33680 : this->ChillerHeater(ChillerHeaterNum).Report.QCond = QCondenser;
2126 33680 : this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp = EvapOutletTemp;
2127 33680 : this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTemp = EvapInletTemp;
2128 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp = CondOutletTemp;
2129 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CondInletTemp = CondInletTemp;
2130 33680 : this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot = EvapMassFlowRate;
2131 33680 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot = CondMassFlowRate;
2132 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ActualCOP = ActualCOP;
2133 :
2134 33680 : if (this->SimulClgDominant || this->SimulHtgDominant) { // Store for using these cooling side data in the hot water loop
2135 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = CurrentMode;
2136 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatioSimul = state.dataPlantCentralGSHP->ChillerPartLoadRatio;
2137 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatioSimul = state.dataPlantCentralGSHP->ChillerCyclingRatio;
2138 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRateSimul = state.dataPlantCentralGSHP->ChillerFalseLoadRate;
2139 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFTSimul = state.dataPlantCentralGSHP->ChillerCapFT;
2140 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFTSimul = state.dataPlantCentralGSHP->ChillerEIRFT;
2141 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLRSimul = state.dataPlantCentralGSHP->ChillerEIRFPLR;
2142 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingPowerSimul = CHPower;
2143 13566 : this->ChillerHeater(ChillerHeaterNum).Report.QEvapSimul = QEvaporator;
2144 13566 : this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTempSimul = EvapOutletTemp;
2145 13566 : this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTempSimul = EvapInletTemp;
2146 13566 : this->ChillerHeater(ChillerHeaterNum).Report.EvapmdotSimul = EvapMassFlowRate;
2147 13566 : if (this->SimulClgDominant) {
2148 13566 : this->ChillerHeater(ChillerHeaterNum).Report.QCondSimul = QCondenser;
2149 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTempSimul = CondOutletTemp;
2150 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CondInletTempSimul = CondInletTemp;
2151 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CondmdotSimul = CondMassFlowRate;
2152 : }
2153 : }
2154 : }
2155 9568 : }
2156 :
2157 21478 : void WrapperSpecs::CalcChillerHeaterModel(EnergyPlusData &state)
2158 : {
2159 : // SUBROUTINE INFORMATION:
2160 : // AUTHOR Daeho Kang, PNNL
2161 : // DATE WRITTEN Feb 2013
2162 : // MODIFIED na
2163 : // RE-ENGINEERED na
2164 :
2165 : // PURPOSE OF THIS SUBROUTINE:
2166 : // Simulate a ChillerHeaterPerformance:Electric:EIR using curve fit
2167 :
2168 : // METHODOLOGY EMPLOYED:
2169 : // Use empirical curve fits to model performance at off-reference conditions
2170 :
2171 : // REFERENCES:
2172 : // 1. DOE-2 Engineers Manual, Version 2.1A, November 1982, LBL-11353
2173 :
2174 : static constexpr std::string_view RoutineName("CalcChillerHeaterModel");
2175 :
2176 : bool IsLoadHeatRemaining; // Ture if heating load remains for this chiller heater
2177 21478 : bool NextCompIndicator(false); // Component indicator when identical chiller heaters exist
2178 21478 : int CompNum(0); // Component number
2179 21478 : int IdenticalUnitCounter = 0; // Pointer to count number of identical unit passed
2180 : int IdenticalUnitRemaining; // Pointer to count number of identical unit available for a component
2181 21478 : Real64 CondenserLoad(0.0); // Remaining heating load that this wrapper should meet
2182 21478 : Real64 CurAvailHWMassFlowRate(0.0); // Maximum available hot water mass within the wrapper bank
2183 :
2184 21478 : CondenserLoad = this->WrapperHeatingLoad;
2185 21478 : Real64 HWInletMassFlowRate = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRate;
2186 :
2187 94338 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
2188 :
2189 : // Set module level inlet and outlet nodes and initialize other local variables
2190 72860 : int CurrentMode = 0;
2191 72860 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = 0.0;
2192 72860 : state.dataPlantCentralGSHP->ChillerCyclingRatio = 0.0;
2193 72860 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = 0.0;
2194 72860 : Real64 CHPower = 0.0;
2195 72860 : Real64 QCondenser = 0.0;
2196 72860 : Real64 QEvaporator = 0.0;
2197 72860 : Real64 FRAC = 1.0;
2198 72860 : Real64 CondDeltaTemp = 0.0;
2199 72860 : Real64 CoolingPower = 0.0;
2200 72860 : Real64 ActualCOP = 0.0;
2201 72860 : Real64 EvapInletTemp = state.dataLoopNodes->Node(this->GLHEInletNodeNum).Temp;
2202 72860 : Real64 CondInletTemp = state.dataLoopNodes->Node(this->HWInletNodeNum).Temp;
2203 72860 : Real64 EvapOutletTemp = EvapInletTemp;
2204 72860 : Real64 CondOutletTemp = CondInletTemp;
2205 :
2206 : // Find proper schedule values
2207 72860 : if (this->NumOfComp != this->ChillerHeaterNums) { // Identical units exist
2208 72860 : if (ChillerHeaterNum == 1) {
2209 21478 : IdenticalUnitCounter = 0;
2210 21478 : NextCompIndicator = false;
2211 21478 : CompNum = ChillerHeaterNum;
2212 : }
2213 72860 : if (NextCompIndicator) {
2214 8426 : ++CompNum;
2215 : }
2216 72860 : if (CompNum == 1) {
2217 56008 : if (ChillerHeaterNum != this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
2218 34530 : NextCompIndicator = false;
2219 21478 : } else if (ChillerHeaterNum == this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
2220 21478 : NextCompIndicator = true;
2221 : }
2222 16852 : } else if (CompNum > 1) {
2223 16852 : if ((ChillerHeaterNum - ((ChillerHeaterNum - 1) - IdenticalUnitCounter)) != this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
2224 8426 : NextCompIndicator = false;
2225 16852 : } else if ((ChillerHeaterNum - ((ChillerHeaterNum - 1) - IdenticalUnitCounter)) ==
2226 8426 : this->WrapperComp(CompNum).WrapperIdenticalObjectNum) {
2227 8426 : NextCompIndicator = true;
2228 : }
2229 : }
2230 72860 : ++IdenticalUnitCounter;
2231 72860 : IdenticalUnitRemaining = this->WrapperComp(CompNum).WrapperIdenticalObjectNum - IdenticalUnitCounter;
2232 72860 : if (IdenticalUnitRemaining == 0) {
2233 29904 : IdenticalUnitCounter = 0;
2234 : }
2235 0 : } else if (this->NumOfComp == this->ChillerHeaterNums) {
2236 0 : ++CompNum;
2237 : }
2238 :
2239 : Real64 CondMassFlowRate; // Condenser mass flow rate through this chiller heater
2240 : Real64 EvapMassFlowRate; // Evaporator mass flow rate through this chiller heater
2241 :
2242 : // Check to see if this chiller heater needs to run
2243 72860 : if (CondenserLoad > 0.0 && (this->WrapperComp(CompNum).chSched->getCurrentVal() > 0)) {
2244 63832 : IsLoadHeatRemaining = true;
2245 :
2246 : // Calculate density ratios to adjust mass flow rates from initialized ones
2247 : // Hot water temperature is known, but condenser mass flow rates will be adjusted in the following "Do" loop
2248 63832 : Real64 InitDensity = this->CWPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
2249 63832 : Real64 EvapDensity = this->CWPlantLoc.loop->glycol->getDensity(state, EvapInletTemp, RoutineName);
2250 63832 : Real64 CondDensity = this->CWPlantLoc.loop->glycol->getDensity(state, CondInletTemp, RoutineName);
2251 :
2252 : // Calculate density ratios to adjust mass flow rates from initialized ones
2253 63832 : Real64 HWDensityRatio = CondDensity / InitDensity;
2254 63832 : Real64 GLHEDensityRatio = EvapDensity / InitDensity;
2255 63832 : EvapMassFlowRate = this->ChillerHeater(ChillerHeaterNum).EvapInletNode.MassFlowRateMaxAvail;
2256 63832 : CondMassFlowRate = this->ChillerHeater(ChillerHeaterNum).CondInletNode.MassFlowRateMaxAvail;
2257 63832 : EvapMassFlowRate *= GLHEDensityRatio;
2258 63832 : CondMassFlowRate *= HWDensityRatio;
2259 :
2260 : // Check flows from plant to adjust as necessary
2261 63832 : if (CurAvailHWMassFlowRate == 0) { // First chiller heater which is on
2262 21492 : CurAvailHWMassFlowRate = HWInletMassFlowRate;
2263 42340 : } else if (ChillerHeaterNum > 1) {
2264 42340 : CurAvailHWMassFlowRate -= this->ChillerHeater(ChillerHeaterNum - 1).CondOutletNode.MassFlowRate;
2265 : }
2266 63832 : CondMassFlowRate = min(CurAvailHWMassFlowRate, CondMassFlowRate);
2267 :
2268 : // It is not enforced to be the smaller of CH max temperature and plant temp setpoint.
2269 : // Hot water temperatures at the individual CHs' outlet may be greater than plant setpoint temp,
2270 : // but should be lower than the CHs max temp
2271 63832 : CondOutletTemp = this->ChillerHeater(ChillerHeaterNum).TempRefCondOutClgHtg;
2272 63832 : CondDeltaTemp = CondOutletTemp - CondInletTemp;
2273 :
2274 63832 : if (CondDeltaTemp < 0.0) { // Hot water temperature is greater than the maximum
2275 0 : if (this->ChillerHeater(ChillerHeaterNum).ChillerEIRRefTempErrorIndex == 0) {
2276 0 : ShowSevereMessage(state,
2277 0 : format("CalcChillerHeaterModel: ChillerHeaterPerformance:Electric:EIR=\"{}\", DeltaTemp < 0",
2278 0 : this->ChillerHeater(ChillerHeaterNum).Name));
2279 0 : ShowContinueError(
2280 0 : state, format(" Reference Simultaneous Cooling-Heating Mode Leaving Condenser Water Temperature [{:.1R}]", CondOutletTemp));
2281 0 : ShowContinueError(state, format("is below condenser inlet temperature of [{:.1R}].", CondInletTemp));
2282 0 : ShowContinueErrorTimeStamp(state, "");
2283 0 : ShowContinueError(state, " Reset reference temperature to one greater than the inlet temperature ");
2284 : }
2285 0 : ShowRecurringSevereErrorAtEnd(state,
2286 0 : "ChillerHeaterPerformance:Electric:EIR=\"" + this->ChillerHeater(ChillerHeaterNum).Name +
2287 : "\": Reference temperature problems continue.",
2288 0 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRRefTempErrorIndex,
2289 : CondDeltaTemp,
2290 : CondDeltaTemp,
2291 : _,
2292 : "deltaC",
2293 : "deltaC");
2294 0 : QCondenser = 0.0;
2295 0 : IsLoadHeatRemaining = false;
2296 : }
2297 :
2298 63832 : if (ChillerHeaterNum > 1) {
2299 : // Operation mode needs to be set in a simultaneous clg/htg mode
2300 : // Always off even heating load remains if this CH is assumed to be off in the loop 1
2301 42354 : if (this->SimulClgDominant) {
2302 6006 : if (this->ChillerHeater(ChillerHeaterNum).Report.QEvapSimul == 0.0) {
2303 1177 : CurrentMode = 0;
2304 1177 : IsLoadHeatRemaining = false;
2305 : } else { // Heat recovery
2306 4829 : CurrentMode = 3;
2307 : }
2308 : }
2309 : } // End of simulataneous clg/htg mode detemination
2310 :
2311 : } else { // chiller heater is off
2312 9028 : IsLoadHeatRemaining = false;
2313 9028 : CondMassFlowRate = 0.0;
2314 9028 : EvapMassFlowRate = 0.0;
2315 9028 : CurrentMode = 0;
2316 9028 : if (this->SimulClgDominant) {
2317 3010 : if (this->ChillerHeater(ChillerHeaterNum).Report.QEvapSimul > 0.0) {
2318 683 : CurrentMode = 4; // Simultaneous cooling dominant mode: 4
2319 : }
2320 : } // End of mode determination
2321 : } // End of system operation determinatoin
2322 :
2323 72860 : if (IsLoadHeatRemaining && CondMassFlowRate > 0.0 && (this->WrapperComp(CompNum).chSched->getCurrentVal() > 0)) { // System is on
2324 : // Operation mode
2325 60077 : if (this->SimulHtgDominant) {
2326 0 : if (this->ChillerHeater(ChillerHeaterNum).Report.QEvapSimul == 0.0) {
2327 0 : CurrentMode = 5; // No cooling necessary // Why is this not an enum?
2328 : } else { // Heat recovery mode. Both chilled water and hot water loops are connected. No condenser flow.
2329 0 : CurrentMode = 3;
2330 : }
2331 : }
2332 :
2333 : // Mode 3 and 5 use cooling side data stored from the chilled water loop
2334 : // Mode 4 uses all data from the chilled water loop due to no heating demand
2335 : // Fix for Defect #10065: When the heating load is dominant and the Current Mode is 3,
2336 : // simulation must go through the "heating" side to properly update the power consumption.
2337 : // Otherwise, the power consumption could come back zero for heating and cooling.
2338 60077 : if (this->SimulClgDominant || (CurrentMode == 3 && !this->SimulHtgDominant)) {
2339 8988 : CurrentMode = 3;
2340 8988 : QCondenser = this->ChillerHeater(ChillerHeaterNum).Report.QCondSimul;
2341 8988 : this->adjustChillerHeaterCondFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp);
2342 : } else { // Either Mode 2 or 3 (heating dominant) or 5
2343 51089 : if (this->SimulHtgDominant) {
2344 0 : CurrentMode = 5;
2345 : } else {
2346 51089 : CurrentMode = 2;
2347 : }
2348 :
2349 51089 : state.dataPlantCentralGSHP->ChillerCapFT = 0.0;
2350 51089 : state.dataPlantCentralGSHP->ChillerEIRFT = 0.0;
2351 51089 : state.dataPlantCentralGSHP->ChillerEIRFPLR = 0.0;
2352 :
2353 : // Assign curve values to local data array
2354 51089 : this->ChillerHeater(ChillerHeaterNum).RefCap = this->ChillerHeater(ChillerHeaterNum).RefCapClgHtg;
2355 51089 : this->ChillerHeater(ChillerHeaterNum).RefCOP = this->ChillerHeater(ChillerHeaterNum).RefCOPClgHtg;
2356 51089 : this->ChillerHeater(ChillerHeaterNum).TempRefEvapOut = this->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg;
2357 51089 : this->ChillerHeater(ChillerHeaterNum).TempRefCondOut = this->ChillerHeater(ChillerHeaterNum).TempRefCondOutClgHtg;
2358 51089 : this->ChillerHeater(ChillerHeaterNum).OptPartLoadRat = this->ChillerHeater(ChillerHeaterNum).OptPartLoadRatClgHtg;
2359 51089 : this->ChillerHeater(ChillerHeaterNum).CondMode = this->ChillerHeater(ChillerHeaterNum).CondModeHeating;
2360 51089 : this->ChillerHeater(ChillerHeaterNum).ChillerCapFTIDX = this->ChillerHeater(ChillerHeaterNum).ChillerCapFTHeatingIDX;
2361 51089 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTIDX = this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTHeatingIDX;
2362 51089 : this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX = this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRHeatingIDX;
2363 :
2364 : // Reference condenser temperature for the performance curve reading: set to entering or leaving condenser temperature based on user
2365 : // input
2366 102178 : Real64 CondTempforCurve = this->setChillerHeaterCondTemp(
2367 51089 : state, ChillerHeaterNum, CondInletTemp, this->ChillerHeater(ChillerHeaterNum).TempRefCondOutClgHtg);
2368 :
2369 51089 : Real64 ChillerRefCap = this->ChillerHeater(ChillerHeaterNum).RefCap;
2370 51089 : Real64 ReferenceCOP = this->ChillerHeater(ChillerHeaterNum).RefCOP;
2371 51089 : EvapOutletTemp = this->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg;
2372 51089 : Real64 TempLowLimitEout = this->ChillerHeater(ChillerHeaterNum).TempLowLimitEvapOut;
2373 51089 : Real64 EvapOutletTempSetPoint = this->ChillerHeater(ChillerHeaterNum).TempRefEvapOutClgHtg;
2374 :
2375 : // Calculate Chiller Capacity as a function of temperature and error check
2376 51089 : state.dataPlantCentralGSHP->ChillerCapFT = this->calcChillerCapFT(state, ChillerHeaterNum, EvapOutletTempSetPoint, CondTempforCurve);
2377 :
2378 : // Available chiller capacity as a function of temperature
2379 51089 : Real64 AvailChillerCap = ChillerRefCap * state.dataPlantCentralGSHP->ChillerCapFT;
2380 :
2381 : Real64 PartLoadRat; // Operating part load ratio
2382 : Real64 MinPartLoadRat; // Min allowed operating fraction of full load
2383 : Real64 MaxPartLoadRat; // Max allowed operating fraction of full load
2384 51089 : Curve::GetCurveMinMaxValues(state, this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX, MinPartLoadRat, MaxPartLoadRat);
2385 :
2386 : // Part load ratio based on reference capacity and available chiller capacity
2387 51089 : if (AvailChillerCap > 0) {
2388 51089 : PartLoadRat = max(0.0, min((ChillerRefCap / AvailChillerCap), MaxPartLoadRat));
2389 : } else {
2390 0 : PartLoadRat = 0.0;
2391 : }
2392 :
2393 : Real64 Cp =
2394 51089 : this->HWPlantLoc.loop->glycol->getSpecificHeat(state, this->ChillerHeater(ChillerHeaterNum).EvapInletNode.Temp, RoutineName);
2395 :
2396 : // Calculate evaporator heat transfer
2397 51089 : if (EvapMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
2398 51089 : QEvaporator = AvailChillerCap * PartLoadRat;
2399 51089 : Real64 EvapDeltaTemp = QEvaporator / EvapMassFlowRate / Cp;
2400 51089 : EvapOutletTemp = EvapInletTemp - EvapDeltaTemp;
2401 : }
2402 :
2403 : // Run evaporator checks and adjust outlet temp and QEvaporator if necessary
2404 102178 : WrapperSpecs::checkEvapOutletTemp(state,
2405 : ChillerHeaterNum,
2406 : EvapOutletTemp,
2407 : TempLowLimitEout,
2408 51089 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.Temp,
2409 : QEvaporator,
2410 : EvapMassFlowRate,
2411 : Cp);
2412 :
2413 51089 : WrapperSpecs::calcPLRAndCyclingRatio(state, AvailChillerCap, PartLoadRat, MinPartLoadRat, MaxPartLoadRat, QEvaporator, FRAC);
2414 :
2415 51089 : state.dataPlantCentralGSHP->ChillerEIRFT =
2416 51089 : max(0.0, Curve::CurveValue(state, this->ChillerHeater(ChillerHeaterNum).ChillerEIRFTIDX, EvapOutletTemp, CondTempforCurve));
2417 51089 : state.dataPlantCentralGSHP->ChillerEIRFPLR =
2418 51089 : max(0.0, Curve::CurveValue(state, this->ChillerHeater(ChillerHeaterNum).ChillerEIRFPLRIDX, PartLoadRat));
2419 51089 : CHPower =
2420 51089 : (AvailChillerCap / ReferenceCOP) * state.dataPlantCentralGSHP->ChillerEIRFPLR * state.dataPlantCentralGSHP->ChillerEIRFT * FRAC;
2421 :
2422 51089 : if (CHPower <= 0.0) {
2423 0 : ActualCOP = 0.0;
2424 : } else {
2425 51089 : ActualCOP = (QEvaporator + state.dataPlantCentralGSHP->ChillerFalseLoadRate) / CHPower;
2426 : }
2427 :
2428 51089 : QCondenser =
2429 51089 : CHPower * this->ChillerHeater(ChillerHeaterNum).OpenMotorEff + QEvaporator + state.dataPlantCentralGSHP->ChillerFalseLoadRate;
2430 51089 : Real64 qCondenserFullLoad = QCondenser;
2431 :
2432 : // Determine heating load for this heater and pass the remaining load to the next chiller heater
2433 51089 : Real64 CondenserCapMin = QCondenser * MinPartLoadRat;
2434 51089 : Real64 HeatingLoadToMeet = min(QCondenser, max(std::abs(CondenserLoad), CondenserCapMin));
2435 :
2436 : // Set load this chiller heater should meet and temperatures given
2437 51089 : QCondenser = min(HeatingLoadToMeet, QCondenser);
2438 :
2439 : // Calculate outlet temperature for constant flow and mass flow rate for variable flow
2440 : // Limit mass flow rate for this chiller heater to the available mass at given temperature conditions
2441 : // when mass flow rate calculated to meet the load is greater than the maximum available
2442 : // then recalculate heating load this chiller heater can meet
2443 51089 : if (CurrentMode == 2 || this->SimulHtgDominant) {
2444 51089 : if (CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance && CondDeltaTemp > 0.0) {
2445 50694 : this->adjustChillerHeaterCondFlowTemp(state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp);
2446 50694 : if (qCondenserFullLoad > 0.0) {
2447 50694 : Real64 constexpr diffTolerance = 0.0001;
2448 50694 : if (((qCondenserFullLoad - QCondenser) / qCondenserFullLoad) > diffTolerance) {
2449 : // QCondenser was reduced, so reduce evaporator side quantities by a factor of the condenser based PLR
2450 50640 : PartLoadRat = max(MinPartLoadRat, min((QCondenser / qCondenserFullLoad), MaxPartLoadRat));
2451 50640 : QCondenser = PartLoadRat * qCondenserFullLoad;
2452 50640 : this->adjustChillerHeaterCondFlowTemp(
2453 : state, QCondenser, CondMassFlowRate, CondOutletTemp, CondInletTemp, CondDeltaTemp);
2454 : // In most situations here, QCondenser will not be reduced here, but it has to be taken into account. This will
2455 : // potentially violate the minPLR but this will keep the solution simple for now.
2456 : // So, basically multiply all terms in the energy balance by the same factor to maintain the energy balance.
2457 50640 : Real64 modifiedPLR = QCondenser / qCondenserFullLoad;
2458 50640 : QEvaporator *= modifiedPLR;
2459 50640 : CHPower *= modifiedPLR;
2460 50640 : PartLoadRat = modifiedPLR;
2461 50640 : state.dataPlantCentralGSHP->ChillerFalseLoadRate *= modifiedPLR;
2462 : // Now re-adjust things on the evaporator side to get the correct flows/temperatures
2463 50640 : this->adjustChillerHeaterEvapFlowTemp(state, QEvaporator, EvapMassFlowRate, EvapOutletTemp, EvapInletTemp);
2464 : }
2465 : }
2466 50694 : } else {
2467 395 : QCondenser = 0.0;
2468 395 : CondOutletTemp = CondInletTemp;
2469 : }
2470 51089 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = PartLoadRat;
2471 : }
2472 :
2473 : } // End of calculation depending on the modes
2474 :
2475 : // Determine load next chiller heater meets
2476 60077 : if (CondenserLoad < QCondenser) { // Heating load is met by this chiller heater
2477 2517 : CondenserLoad = 0.0;
2478 : } else {
2479 57560 : CondenserLoad -= QCondenser;
2480 : }
2481 :
2482 60077 : if (QCondenser == 0.0) {
2483 395 : CurrentMode = 0;
2484 395 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = 0.0;
2485 395 : state.dataPlantCentralGSHP->ChillerCyclingRatio = 0.0;
2486 395 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = 0.0;
2487 395 : EvapMassFlowRate = 0.0;
2488 395 : CondMassFlowRate = 0.0;
2489 395 : CHPower = 0.0;
2490 395 : QEvaporator = 0.0;
2491 395 : EvapOutletTemp = EvapInletTemp;
2492 395 : CondOutletTemp = CondInletTemp;
2493 395 : CondenserLoad = 0.0;
2494 : }
2495 :
2496 : // Heat recovery or cooling dominant modes need to use the evaporator side information
2497 60077 : if (CurrentMode == 3 || CurrentMode == 4) {
2498 8988 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatioSimul;
2499 8988 : state.dataPlantCentralGSHP->ChillerCyclingRatio = this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatioSimul;
2500 8988 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRateSimul;
2501 8988 : state.dataPlantCentralGSHP->ChillerCapFT = this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFTSimul;
2502 8988 : state.dataPlantCentralGSHP->ChillerEIRFT = this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFTSimul;
2503 8988 : state.dataPlantCentralGSHP->ChillerEIRFPLR = this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLRSimul;
2504 8988 : QEvaporator = this->ChillerHeater(ChillerHeaterNum).Report.QEvapSimul;
2505 8988 : EvapOutletTemp = this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTempSimul;
2506 8988 : EvapInletTemp = this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTempSimul;
2507 8988 : EvapMassFlowRate = this->ChillerHeater(ChillerHeaterNum).Report.EvapmdotSimul;
2508 8988 : if (this->SimulClgDominant) {
2509 8988 : CHPower = this->ChillerHeater(ChillerHeaterNum).Report.CoolingPowerSimul;
2510 8988 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower = 0.0;
2511 : }
2512 : }
2513 : }
2514 :
2515 : // Check if it is mode 4, then skip binding local variables
2516 72860 : if (CurrentMode == 4) {
2517 683 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = CurrentMode;
2518 : } else {
2519 72177 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.MassFlowRate = EvapMassFlowRate;
2520 72177 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.MassFlowRate = CondMassFlowRate;
2521 72177 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.Temp = EvapOutletTemp;
2522 72177 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.Temp = EvapInletTemp;
2523 72177 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.Temp = CondOutletTemp;
2524 72177 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.Temp = CondInletTemp;
2525 72177 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = CurrentMode;
2526 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatio = state.dataPlantCentralGSHP->ChillerPartLoadRatio;
2527 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatio = state.dataPlantCentralGSHP->ChillerCyclingRatio;
2528 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate = state.dataPlantCentralGSHP->ChillerFalseLoadRate;
2529 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFT = state.dataPlantCentralGSHP->ChillerCapFT;
2530 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFT = state.dataPlantCentralGSHP->ChillerEIRFT;
2531 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLR = state.dataPlantCentralGSHP->ChillerEIRFPLR;
2532 72177 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower = CoolingPower;
2533 72177 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower = CHPower;
2534 72177 : this->ChillerHeater(ChillerHeaterNum).Report.QEvap = QEvaporator;
2535 72177 : this->ChillerHeater(ChillerHeaterNum).Report.QCond = QCondenser;
2536 72177 : this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp = EvapOutletTemp;
2537 72177 : this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTemp = EvapInletTemp;
2538 72177 : this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp = CondOutletTemp;
2539 72177 : this->ChillerHeater(ChillerHeaterNum).Report.CondInletTemp = CondInletTemp;
2540 72177 : this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot = EvapMassFlowRate;
2541 72177 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot = CondMassFlowRate;
2542 72177 : this->ChillerHeater(ChillerHeaterNum).Report.ActualCOP = ActualCOP;
2543 : }
2544 : }
2545 21478 : }
2546 :
2547 110322 : void WrapperSpecs::adjustChillerHeaterCondFlowTemp(EnergyPlusData &state,
2548 : Real64 &QCondenser,
2549 : Real64 &CondMassFlowRate,
2550 : Real64 &CondOutletTemp,
2551 : Real64 const CondInletTemp,
2552 : Real64 const CondDeltaTemp)
2553 : {
2554 : // Based on whether this is variable or constant flow, adjust either flow or outlet temperature and also the load
2555 : static constexpr std::string_view RoutineName("adjustChillerHeaterCondFlowTemp");
2556 110322 : Real64 Cp = this->HWPlantLoc.loop->glycol->getSpecificHeat(state, CondInletTemp, RoutineName);
2557 :
2558 110322 : if (this->VariableFlowCH) { // Variable Flow (adjust flow and condenser load as needed)
2559 110322 : Real64 CondMassFlowRateCalc = QCondenser / CondDeltaTemp / Cp;
2560 110322 : if (CondMassFlowRateCalc > CondMassFlowRate) {
2561 90181 : CondMassFlowRateCalc = CondMassFlowRate;
2562 90181 : Real64 CondDeltaTempCalc = QCondenser / CondMassFlowRate / Cp;
2563 90181 : if (CondDeltaTempCalc > CondDeltaTemp) { // Load to meet should be adjusted
2564 89500 : QCondenser = CondMassFlowRate * Cp * CondDeltaTemp;
2565 : }
2566 : }
2567 110322 : CondMassFlowRate = CondMassFlowRateCalc;
2568 : } else { // Constant Flow (adjust outlet temperature and condenser load as needed)
2569 0 : Real64 CondDeltaTempCalc = QCondenser / CondMassFlowRate / Cp;
2570 0 : Real64 CondOutletTempCalc = CondDeltaTempCalc + CondInletTemp;
2571 0 : if (CondOutletTempCalc > CondOutletTemp) { // Load to meet should be adjusted
2572 0 : CondOutletTempCalc = CondOutletTemp;
2573 0 : QCondenser = CondMassFlowRate * Cp * CondDeltaTemp;
2574 : }
2575 0 : CondOutletTemp = CondOutletTempCalc;
2576 : }
2577 110322 : }
2578 :
2579 50640 : void WrapperSpecs::adjustChillerHeaterEvapFlowTemp(
2580 : EnergyPlusData &state, Real64 const qEvaporator, Real64 &evapMassFlowRate, Real64 &evapOutletTemp, Real64 const evapInletTemp)
2581 : {
2582 : // Adjust flow and outlet temperature for the evaporator side without modifying the heat transfer rate
2583 50640 : Real64 constexpr lowLoad = 0.001;
2584 : static constexpr std::string_view routineName("adjustChillerHeaterEvapFlowTemp");
2585 50640 : Real64 Cp = this->HWPlantLoc.loop->glycol->getSpecificHeat(state, evapInletTemp, routineName);
2586 50640 : Real64 evapDeltaTemp = evapInletTemp - evapOutletTemp;
2587 :
2588 50640 : if ((qEvaporator < lowLoad) || (evapDeltaTemp <= 0.0)) {
2589 0 : evapMassFlowRate = 0.0;
2590 0 : evapOutletTemp = evapInletTemp;
2591 : } else {
2592 50640 : if (this->VariableFlowCH) { // for variable flow, adjust flow if higher than max value passed in
2593 50640 : Real64 evapMassFlowRateCalc = qEvaporator / evapDeltaTemp / Cp;
2594 50640 : if (evapMassFlowRateCalc > evapMassFlowRate) {
2595 0 : evapMassFlowRateCalc = evapMassFlowRate;
2596 : }
2597 50640 : evapMassFlowRate = evapMassFlowRateCalc;
2598 : }
2599 : // Adjust temperature for either flow type to maintain agreement with qEvaporator
2600 50640 : evapDeltaTemp = qEvaporator / evapMassFlowRate / Cp;
2601 50640 : evapOutletTemp = evapInletTemp - evapDeltaTemp;
2602 : }
2603 50640 : }
2604 :
2605 75256 : Real64 WrapperSpecs::setChillerHeaterCondTemp([[maybe_unused]] EnergyPlusData &state,
2606 : int const numChillerHeater,
2607 : Real64 const condEnteringTemp,
2608 : Real64 const condLeavingTemp)
2609 : {
2610 : Real64 setChillerHeaterCondTemp;
2611 75256 : if (this->ChillerHeater(numChillerHeater).CondMode == CondenserModeTemperature::EnteringCondenser) {
2612 14119 : setChillerHeaterCondTemp = condEnteringTemp;
2613 : } else { // by default, if not EnteringCondenser, then this can only be LeavingCondenser
2614 61137 : setChillerHeaterCondTemp = condLeavingTemp;
2615 : }
2616 75256 : return setChillerHeaterCondTemp;
2617 : }
2618 :
2619 75256 : Real64 WrapperSpecs::calcChillerCapFT(EnergyPlusData &state, int const numChillerHeater, Real64 const evapOutletTemp, Real64 const condTemp)
2620 : {
2621 : // Calculate the chiller capacity as a function of temperature
2622 75256 : Real64 chillCapFT = Curve::CurveValue(state, this->ChillerHeater(numChillerHeater).ChillerCapFTIDX, evapOutletTemp, condTemp);
2623 :
2624 : // Tracks errors for when the capacity is calculated as less than zero
2625 75256 : if (chillCapFT < 0) {
2626 0 : if (this->ChillerHeater(numChillerHeater).ChillerCapFTError < 1 && !state.dataGlobal->WarmupFlag) {
2627 0 : ++this->ChillerHeater(numChillerHeater).ChillerCapFTError;
2628 0 : ShowWarningError(state, format("ChillerHeaterPerformance:Electric:EIR \"{}\":", this->ChillerHeater(numChillerHeater).Name));
2629 0 : ShowContinueError(state, format(" ChillerHeater Capacity as a Function of Temperature curve output is negative ({:.3R}).", chillCapFT));
2630 0 : ShowContinueError(state,
2631 0 : format(" Negative value occurs using an Evaporator Outlet Temp of {:.1R} and a Condenser Inlet Temp of {:.1R}.",
2632 : evapOutletTemp,
2633 : condTemp));
2634 0 : ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
2635 0 : } else if (!state.dataGlobal->WarmupFlag) {
2636 0 : ++this->ChillerHeater(numChillerHeater).ChillerCapFTError;
2637 0 : ShowRecurringWarningErrorAtEnd(
2638 : state,
2639 0 : "ChillerHeaterPerformance:Electric:EIR \"" + this->ChillerHeater(numChillerHeater).Name +
2640 : "\": ChillerHeater Capacity as a Function of Temperature curve output is negative warning continues...",
2641 0 : this->ChillerHeater(numChillerHeater).ChillerCapFTErrorIndex,
2642 : chillCapFT,
2643 : chillCapFT);
2644 : }
2645 0 : chillCapFT = 0.0;
2646 : }
2647 75256 : return chillCapFT;
2648 : }
2649 :
2650 75256 : void WrapperSpecs::checkEvapOutletTemp([[maybe_unused]] EnergyPlusData &state,
2651 : int const numChillerHeater,
2652 : Real64 &evapOutletTemp,
2653 : Real64 const lowTempLimitEout,
2654 : Real64 const evapInletTemp,
2655 : Real64 &qEvaporator,
2656 : Real64 const evapMassFlowRate,
2657 : Real64 const Cp)
2658 : {
2659 : // Check evaporator temperature low limit and adjust capacity if needed
2660 75256 : if (evapOutletTemp < lowTempLimitEout) {
2661 7498 : if ((evapInletTemp - lowTempLimitEout) > DataPlant::DeltaTempTol) {
2662 7498 : evapOutletTemp = lowTempLimitEout;
2663 7498 : Real64 evapDeltaTemp = evapInletTemp - evapOutletTemp;
2664 7498 : qEvaporator = evapMassFlowRate * Cp * evapDeltaTemp;
2665 : } else {
2666 0 : qEvaporator = 0.0;
2667 0 : evapOutletTemp = evapInletTemp;
2668 : }
2669 : }
2670 :
2671 : // Check if the outlet temperature exceeds the node minimum temperature and adjust capacity if needed
2672 75256 : if (evapOutletTemp < this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin) {
2673 0 : if ((evapInletTemp - this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin) > DataPlant::DeltaTempTol) {
2674 0 : evapOutletTemp = this->ChillerHeater(numChillerHeater).EvapOutletNode.TempMin;
2675 0 : Real64 evapDeltaTemp = evapInletTemp - evapOutletTemp;
2676 0 : qEvaporator = evapMassFlowRate * Cp * evapDeltaTemp;
2677 : } else {
2678 0 : qEvaporator = 0.0;
2679 0 : evapOutletTemp = evapInletTemp;
2680 : }
2681 : }
2682 75256 : }
2683 :
2684 75256 : void WrapperSpecs::calcPLRAndCyclingRatio(EnergyPlusData &state,
2685 : Real64 const availChillerCap,
2686 : Real64 &actualPartLoadRatio,
2687 : Real64 const minPartLoadRatio,
2688 : Real64 const maxPartLoadRatio,
2689 : Real64 const qEvaporator,
2690 : Real64 &frac)
2691 : {
2692 : // Calculate PLR (actualPartLoadRatio) based on evaporator load and available capacity, factoring in max PLR
2693 75256 : if (availChillerCap <= 0.0) {
2694 0 : actualPartLoadRatio = 0;
2695 0 : frac = 1.0;
2696 : } else {
2697 75256 : actualPartLoadRatio = max(0.0, min((qEvaporator / availChillerCap), maxPartLoadRatio));
2698 : // If chiller cycles below minimum part load ratio, frac = amount of time chiller is ON during this time step
2699 75256 : if (minPartLoadRatio > 0.0) {
2700 75256 : frac = min(1.0, (actualPartLoadRatio / minPartLoadRatio));
2701 : } else {
2702 0 : frac = 1.0;
2703 : }
2704 75256 : actualPartLoadRatio = max(actualPartLoadRatio, minPartLoadRatio);
2705 : }
2706 :
2707 75256 : state.dataPlantCentralGSHP->ChillerCyclingRatio = frac;
2708 :
2709 : // Evaporator part load ratio
2710 75256 : state.dataPlantCentralGSHP->ChillerPartLoadRatio = actualPartLoadRatio;
2711 :
2712 : // Calculate the load due to false loading on chiller over and above water side load
2713 75256 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = (availChillerCap * actualPartLoadRatio * frac) - qEvaporator;
2714 75256 : if (state.dataPlantCentralGSHP->ChillerFalseLoadRate < HVAC::SmallLoad) {
2715 75256 : state.dataPlantCentralGSHP->ChillerFalseLoadRate = 0.0;
2716 : }
2717 75256 : }
2718 :
2719 102440 : void WrapperSpecs::CalcWrapperModel(EnergyPlusData &state, Real64 &MyLoad, int const LoopNum)
2720 : {
2721 : // SUBROUTINE INFORMATION:
2722 : // AUTHOR Daeho Kang, PNNL
2723 : // DATE WRITTEN Feb 2013
2724 : // MODIFIED na
2725 : // RE-ENGINEERED na
2726 :
2727 : // PURPOSE OF THIS SUBROUTINE:
2728 : // Calculate node information connected to plant & condenser loop
2729 :
2730 : // METHODOLOGY EMPLOYED:
2731 : // Use empirical curve fits to model performance at off-reference conditions
2732 :
2733 102440 : Real64 CurHeatingLoad = 0.0; // Total heating load chiller heater bank (wrapper) meets
2734 : Real64 CHWOutletTemp; // Chiller heater bank chilled water outlet temperature
2735 : Real64 CHWOutletMassFlowRate; // Chiller heater bank chilled water outlet mass flow rate
2736 : Real64 HWOutletTemp; // Chiller heater bank hot water outlet temperature
2737 : Real64 GLHEOutletTemp; // Chiller heater bank condenser loop outlet temperature
2738 : Real64 GLHEOutletMassFlowRate; // Chiller heater bank condenser loop outlet mass flow rate
2739 102440 : Real64 WrapperElecPowerCool(0.0); // Chiller heater bank total cooling electricity [W]
2740 102440 : Real64 WrapperElecPowerHeat(0.0); // Chiller heater bank total heating electricity [W]
2741 102440 : Real64 WrapperCoolRate(0.0); // Chiller heater bank total cooling rate [W]
2742 102440 : Real64 WrapperHeatRate(0.0); // Chiller heater bank total heating rate [W]
2743 102440 : Real64 WrapperGLHERate(0.0); // Chiller heater bank total condenser heat transfer rate [W]
2744 102440 : Real64 WrapperElecEnergyCool(0.0); // Chiller heater bank total electric cooling energy [J]
2745 102440 : Real64 WrapperElecEnergyHeat(0.0); // Chiller heater bank total electric heating energy [J]
2746 102440 : Real64 WrapperCoolEnergy(0.0); // Chiller heater bank total cooling energy [J]
2747 102440 : Real64 WrapperHeatEnergy(0.0); // Chiller heater bank total heating energy [J]
2748 102440 : Real64 WrapperGLHEEnergy(0.0); // Chiller heater bank total condenser heat transfer energy [J]
2749 :
2750 : // Chiller heater bank chilled water inlet mass flow rate
2751 102440 : Real64 CHWInletMassFlowRate = 0.0;
2752 :
2753 102440 : Real64 HWInletMassFlowRate = 0.0;
2754 102440 : Real64 GLHEInletMassFlowRate = 0.0;
2755 102440 : Real64 CHWInletTemp = state.dataLoopNodes->Node(this->CHWInletNodeNum).Temp;
2756 :
2757 : // Chiller heater bank hot water inlet temperature
2758 102440 : Real64 HWInletTemp = state.dataLoopNodes->Node(this->HWInletNodeNum).Temp;
2759 :
2760 : // Chiller heater bank condenser loop inlet temperature
2761 102440 : Real64 GLHEInletTemp = state.dataLoopNodes->Node(this->GLHEInletNodeNum).Temp;
2762 :
2763 102440 : Real64 CurCoolingLoad = 0.0; // Total cooling load chiller heater bank (wrapper) meets
2764 :
2765 : // Initiate loads and inlet temperatures each loop
2766 102440 : if (LoopNum == this->CWPlantLoc.loopNum) {
2767 51220 : CHWInletMassFlowRate = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRateMaxAvail;
2768 51220 : HWInletMassFlowRate = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRate;
2769 51220 : GLHEInletMassFlowRate = state.dataLoopNodes->Node(this->GLHEInletNodeNum).MassFlowRateMaxAvail;
2770 51220 : DataPlant::LoopSideLocation LoopSideNum = this->CWPlantLoc.loopSideNum;
2771 51220 : this->WrapperCoolingLoad = 0.0;
2772 51220 : CurCoolingLoad = std::abs(MyLoad);
2773 51220 : this->WrapperCoolingLoad = CurCoolingLoad;
2774 : // Set actual mass flow rate at the nodes when it's locked
2775 51220 : if (state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSideNum).FlowLock == DataPlant::FlowLock::Locked) {
2776 25604 : CHWInletMassFlowRate = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRate;
2777 : }
2778 51220 : if (CHWInletMassFlowRate == 0.0) {
2779 20844 : GLHEInletMassFlowRate = 0.0;
2780 : }
2781 :
2782 51220 : } else if (LoopNum == this->HWPlantLoc.loopNum) {
2783 51220 : CHWInletMassFlowRate = state.dataLoopNodes->Node(this->CHWInletNodeNum).MassFlowRate;
2784 51220 : HWInletMassFlowRate = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRateMaxAvail;
2785 51220 : GLHEInletMassFlowRate = state.dataLoopNodes->Node(this->GLHEInletNodeNum).MassFlowRateMaxAvail;
2786 51220 : DataPlant::LoopSideLocation LoopSideNum = this->HWPlantLoc.loopSideNum;
2787 51220 : this->WrapperHeatingLoad = 0.0;
2788 51220 : CurHeatingLoad = MyLoad;
2789 51220 : this->WrapperHeatingLoad = CurHeatingLoad;
2790 : // Set actual mass flow rate at the nodes when it's locked
2791 51220 : if (state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSideNum).FlowLock == DataPlant::FlowLock::Locked) {
2792 25604 : HWInletMassFlowRate = state.dataLoopNodes->Node(this->HWInletNodeNum).MassFlowRate;
2793 : }
2794 51220 : if (HWInletMassFlowRate == 0.0) {
2795 14868 : GLHEInletMassFlowRate = 0.0;
2796 : }
2797 : }
2798 :
2799 102440 : if (LoopNum == this->CWPlantLoc.loopNum) {
2800 51220 : if (this->ControlMode == CondenserType::SmartMixing) {
2801 51220 : if (CurCoolingLoad > 0.0 && CHWInletMassFlowRate > 0.0 && GLHEInletMassFlowRate > 0) {
2802 :
2803 9568 : this->CalcChillerModel(state);
2804 9568 : this->UpdateChillerRecords(state);
2805 :
2806 : // Initialize local variables only for calculating mass-weighed temperatures
2807 9568 : CHWOutletTemp = 0.0;
2808 9568 : GLHEOutletTemp = 0.0;
2809 9568 : CHWOutletMassFlowRate = 0.0;
2810 9568 : GLHEOutletMassFlowRate = 0.0;
2811 :
2812 43248 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
2813 :
2814 : // Calculated mass flow rate used by individual chiller heater and bypasses
2815 33680 : CHWOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot;
2816 33680 : CHWOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp *
2817 33680 : (this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot / CHWInletMassFlowRate);
2818 33680 : WrapperElecPowerCool += this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower;
2819 33680 : WrapperCoolRate += this->ChillerHeater(ChillerHeaterNum).Report.QEvap;
2820 33680 : WrapperElecEnergyCool += this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy;
2821 33680 : WrapperCoolEnergy += this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy;
2822 33680 : if (GLHEInletMassFlowRate > 0.0) {
2823 33680 : GLHEOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum).Report.Condmdot;
2824 33680 : if (GLHEOutletMassFlowRate > GLHEInletMassFlowRate) {
2825 6232 : GLHEOutletMassFlowRate = GLHEInletMassFlowRate;
2826 : }
2827 33680 : GLHEOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp *
2828 33680 : (this->ChillerHeater(ChillerHeaterNum).Report.Condmdot / GLHEInletMassFlowRate);
2829 33680 : WrapperGLHERate += this->ChillerHeater(ChillerHeaterNum).Report.QCond;
2830 33680 : WrapperGLHEEnergy += this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy;
2831 : } else {
2832 0 : GLHEInletMassFlowRate = 0.0;
2833 0 : GLHEOutletMassFlowRate = 0.0;
2834 0 : GLHEOutletTemp = GLHEInletTemp;
2835 0 : WrapperGLHERate = 0.0;
2836 0 : WrapperGLHEEnergy = 0.0;
2837 : }
2838 : } // End of summation of mass flow rates and mass weighted temperatrue
2839 :
2840 : // Calculate temperatures for the mixed flows in the chiller bank
2841 9568 : Real64 CHWBypassMassFlowRate = CHWInletMassFlowRate - CHWOutletMassFlowRate;
2842 9568 : if (CHWBypassMassFlowRate > 0.0) {
2843 7212 : CHWOutletTemp += CHWInletTemp * CHWBypassMassFlowRate / CHWInletMassFlowRate;
2844 : } else {
2845 : // CHWOutletTemp = CHWOutletTemp; // Self-assignment commented out
2846 : }
2847 :
2848 9568 : if (GLHEInletMassFlowRate > 0.0) {
2849 9568 : Real64 GLHEBypassMassFlowRate = GLHEInletMassFlowRate - GLHEOutletMassFlowRate;
2850 9568 : if (GLHEBypassMassFlowRate > 0.0) {
2851 4946 : GLHEOutletTemp += GLHEInletTemp * GLHEBypassMassFlowRate / GLHEInletMassFlowRate;
2852 : } else {
2853 : // GLHEOutletTemp = GLHEOutletTemp; // Self-assignment commented out
2854 : }
2855 : } else {
2856 0 : GLHEOutletTemp = GLHEInletTemp;
2857 : }
2858 :
2859 9568 : HWOutletTemp = HWInletTemp;
2860 :
2861 9568 : if (this->ancillaryPowerSched != nullptr) {
2862 0 : WrapperElecPowerCool += (this->AncillaryPower * this->ancillaryPowerSched->getCurrentVal());
2863 : }
2864 :
2865 9568 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).Temp = CHWOutletTemp;
2866 9568 : state.dataLoopNodes->Node(this->HWOutletNodeNum).Temp = HWOutletTemp;
2867 9568 : state.dataLoopNodes->Node(this->GLHEOutletNodeNum).Temp = GLHEOutletTemp;
2868 :
2869 9568 : } else {
2870 :
2871 : // Initialize local variables
2872 41652 : CHWOutletTemp = CHWInletTemp;
2873 41652 : HWOutletTemp = HWInletTemp;
2874 41652 : GLHEOutletTemp = GLHEInletTemp;
2875 :
2876 187422 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
2877 145770 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.MassFlowRate = 0.0;
2878 145770 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.MassFlowRate = 0.0;
2879 145770 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.Temp = CHWInletTemp;
2880 145770 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.Temp = CHWInletTemp;
2881 145770 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.Temp = GLHEInletTemp;
2882 145770 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.Temp = GLHEInletTemp;
2883 145770 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = 0;
2884 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatio = 0.0;
2885 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatio = 0.0;
2886 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate = 0.0;
2887 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFT = 0.0;
2888 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFT = 0.0;
2889 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLR = 0.0;
2890 145770 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower = 0.0;
2891 145770 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower = 0.0;
2892 145770 : this->ChillerHeater(ChillerHeaterNum).Report.QEvap = 0.0;
2893 145770 : this->ChillerHeater(ChillerHeaterNum).Report.QCond = 0.0;
2894 145770 : this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp = CHWOutletTemp;
2895 145770 : this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTemp = CHWInletTemp;
2896 145770 : this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp = GLHEOutletTemp;
2897 145770 : this->ChillerHeater(ChillerHeaterNum).Report.CondInletTemp = GLHEInletTemp;
2898 145770 : this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot = 0.0;
2899 145770 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot = 0.0;
2900 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoad = 0.0;
2901 145770 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy = 0.0;
2902 145770 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy = 0.0;
2903 145770 : this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy = 0.0;
2904 145770 : this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy = 0.0;
2905 145770 : this->ChillerHeater(ChillerHeaterNum).Report.ActualCOP = 0.0;
2906 : }
2907 : }
2908 :
2909 51220 : if (this->SimulHtgDominant || this->SimulClgDominant) {
2910 4536 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).Temp = CHWOutletTemp;
2911 4536 : this->Report.CHWInletTempSimul = CHWInletTemp;
2912 4536 : this->Report.CHWOutletTempSimul = CHWOutletTemp;
2913 4536 : this->Report.CHWmdotSimul = CHWInletMassFlowRate;
2914 4536 : this->Report.GLHEInletTempSimul = GLHEInletTemp;
2915 4536 : this->Report.GLHEOutletTempSimul = GLHEOutletTemp;
2916 4536 : this->Report.GLHEmdotSimul = GLHEInletMassFlowRate;
2917 4536 : this->Report.TotElecCoolingSimul = WrapperElecEnergyCool;
2918 4536 : this->Report.CoolingEnergySimul = WrapperCoolEnergy;
2919 4536 : this->Report.TotElecCoolingPwrSimul = WrapperElecPowerCool;
2920 4536 : this->Report.CoolingRateSimul = WrapperCoolRate;
2921 :
2922 : } else {
2923 :
2924 46684 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).Temp = CHWOutletTemp;
2925 46684 : state.dataLoopNodes->Node(this->HWOutletNodeNum).Temp = HWOutletTemp;
2926 46684 : state.dataLoopNodes->Node(this->GLHEOutletNodeNum).Temp = GLHEOutletTemp;
2927 46684 : this->Report.CHWInletTemp = CHWInletTemp;
2928 46684 : this->Report.CHWOutletTemp = CHWOutletTemp;
2929 46684 : this->Report.HWInletTemp = HWInletTemp;
2930 46684 : this->Report.HWOutletTemp = HWOutletTemp;
2931 46684 : this->Report.GLHEInletTemp = GLHEInletTemp;
2932 46684 : this->Report.GLHEOutletTemp = GLHEOutletTemp;
2933 46684 : this->Report.CHWmdot = CHWInletMassFlowRate;
2934 46684 : this->Report.HWmdot = HWInletMassFlowRate;
2935 46684 : this->Report.GLHEmdot = GLHEInletMassFlowRate;
2936 46684 : this->Report.TotElecCooling = WrapperElecEnergyCool;
2937 46684 : this->Report.TotElecHeating = WrapperElecEnergyHeat;
2938 46684 : this->Report.CoolingEnergy = WrapperCoolEnergy;
2939 46684 : this->Report.HeatingEnergy = WrapperHeatEnergy;
2940 46684 : this->Report.GLHEEnergy = WrapperGLHEEnergy;
2941 46684 : this->Report.TotElecCoolingPwr = WrapperElecPowerCool;
2942 46684 : this->Report.TotElecHeatingPwr = WrapperElecPowerHeat;
2943 46684 : this->Report.CoolingRate = WrapperCoolRate;
2944 46684 : this->Report.HeatingRate = WrapperHeatRate;
2945 46684 : this->Report.GLHERate = WrapperGLHERate;
2946 : }
2947 51220 : PlantUtilities::SetComponentFlowRate(state, CHWInletMassFlowRate, this->CHWInletNodeNum, this->CHWOutletNodeNum, this->CWPlantLoc);
2948 :
2949 51220 : PlantUtilities::SetComponentFlowRate(state, HWInletMassFlowRate, this->HWInletNodeNum, this->HWOutletNodeNum, this->HWPlantLoc);
2950 :
2951 51220 : PlantUtilities::SetComponentFlowRate(state, GLHEInletMassFlowRate, this->GLHEInletNodeNum, this->GLHEOutletNodeNum, this->GLHEPlantLoc);
2952 :
2953 : } // End of cooling
2954 :
2955 51220 : } else if (LoopNum == this->HWPlantLoc.loopNum) { // Hot water loop
2956 51220 : if (this->ControlMode == CondenserType::SmartMixing) { // Chiller heater component
2957 51220 : if (CurHeatingLoad > 0.0 && HWInletMassFlowRate > 0.0) {
2958 :
2959 21478 : this->CalcChillerHeaterModel(state);
2960 21478 : this->UpdateChillerHeaterRecords(state);
2961 :
2962 : // Calculate individual CH units's temperatures and mass flow rates
2963 21478 : CHWOutletTemp = 0.0;
2964 21478 : HWOutletTemp = 0.0;
2965 21478 : GLHEOutletTemp = 0.0;
2966 21478 : CHWOutletMassFlowRate = 0.0;
2967 21478 : Real64 HWOutletMassFlowRate = 0.0;
2968 21478 : GLHEOutletMassFlowRate = 0.0;
2969 :
2970 21478 : if (this->SimulHtgDominant || this->SimulClgDominant) {
2971 4508 : if (this->SimulClgDominant) {
2972 18032 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
2973 13524 : int CurrentMode = this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode;
2974 13524 : CHWInletTemp = this->Report.CHWInletTempSimul;
2975 13524 : GLHEInletTemp = this->Report.GLHEInletTempSimul;
2976 13524 : CHWInletMassFlowRate = this->Report.CHWmdotSimul;
2977 13524 : GLHEInletMassFlowRate = this->Report.GLHEmdotSimul;
2978 :
2979 13524 : if (CurrentMode != 0) { // This chiller heater unit is on
2980 10020 : if (CurrentMode == 3) { // Heat recovery mode. Both chilled water and hot water connections
2981 9337 : CHWOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum)
2982 9337 : .Report.EvapmdotSimul; // Wrapper evaporator side to plant chilled water loop
2983 9337 : HWOutletMassFlowRate +=
2984 9337 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot; // Wrapper condenser side to plant hot water loop
2985 9337 : if (HWInletMassFlowRate > 0.0) {
2986 9337 : HWOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp *
2987 9337 : (this->ChillerHeater(ChillerHeaterNum).Report.Condmdot /
2988 : HWInletMassFlowRate); // Only calculate in the heat recovery mode
2989 : } else {
2990 0 : HWOutletTemp = HWInletTemp;
2991 : }
2992 : } else { // Mode 4. Cooling-only mode with other heat recovery units. Condenser flows.
2993 683 : CHWOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum)
2994 683 : .Report.EvapmdotSimul; // Wrapper evaporator side to plant chilled water loop
2995 : // Sum condenser node mass flow rates and mass weighed temperatures
2996 683 : if (GLHEInletMassFlowRate > 0.0) {
2997 683 : GLHEOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum).Report.CondmdotSimul;
2998 683 : if (GLHEOutletMassFlowRate > GLHEInletMassFlowRate) {
2999 4 : GLHEOutletMassFlowRate = GLHEInletMassFlowRate;
3000 : }
3001 683 : GLHEOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTempSimul *
3002 683 : (this->ChillerHeater(ChillerHeaterNum).Report.CondmdotSimul / GLHEInletMassFlowRate);
3003 683 : WrapperGLHERate += this->ChillerHeater(ChillerHeaterNum).Report.QCondSimul;
3004 683 : WrapperGLHEEnergy += this->ChillerHeater(ChillerHeaterNum).Report.CondEnergySimul;
3005 : } else {
3006 0 : GLHEInletMassFlowRate = 0.0;
3007 0 : GLHEOutletMassFlowRate = 0.0;
3008 0 : GLHEOutletTemp = GLHEInletTemp;
3009 0 : WrapperGLHERate = 0.0;
3010 0 : WrapperGLHEEnergy = 0.0;
3011 : }
3012 : }
3013 : } else { // This chiller heater is off
3014 : // Check if any unit is cooling only mode
3015 3504 : if (ChillerHeaterNum == this->ChillerHeaterNums) { // All units are heat revocery mode. No condenser flow
3016 3504 : GLHEOutletMassFlowRate = 0.0;
3017 3504 : GLHEInletMassFlowRate = 0.0;
3018 3504 : GLHEOutletTemp = GLHEInletTemp;
3019 : } else { // At leaset, one of chiller heater units is cooling-only mode
3020 : // GLHEOutletMassFlowRate = GLHEOutletMassFlowRate; // Self-assignment commented out
3021 : // GLHEOutletTemp = GLHEOutletTemp; // Self-assignment commented out
3022 : }
3023 : }
3024 : // Calculate mass weighed chilled water temperatures
3025 13524 : if (CHWInletMassFlowRate > 0.0) {
3026 13524 : CHWOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTempSimul *
3027 13524 : (this->ChillerHeater(ChillerHeaterNum).Report.EvapmdotSimul / CHWInletMassFlowRate);
3028 : } else {
3029 0 : CHWOutletTemp = CHWInletTemp;
3030 : }
3031 :
3032 13524 : WrapperElecPowerCool += this->ChillerHeater(ChillerHeaterNum).Report.CoolingPowerSimul; // Cooling electricity
3033 13524 : WrapperCoolRate += this->ChillerHeater(ChillerHeaterNum).Report.QEvapSimul;
3034 13524 : WrapperElecEnergyCool += this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergySimul;
3035 13524 : WrapperCoolEnergy += this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergySimul;
3036 : // Avoid double counting wrapper energy use
3037 13524 : WrapperElecPowerHeat = 0.0;
3038 13524 : WrapperHeatRate = 0.0;
3039 13524 : WrapperHeatEnergy = 0.0;
3040 : }
3041 :
3042 : // Calculate chilled water temperature
3043 4508 : if (CHWInletMassFlowRate > 0.0) {
3044 4508 : Real64 CHWBypassMassFlowRate = CHWInletMassFlowRate - CHWOutletMassFlowRate;
3045 4508 : if (CHWBypassMassFlowRate > 0.0) {
3046 1034 : CHWOutletTemp += CHWInletTemp * CHWBypassMassFlowRate / CHWInletMassFlowRate;
3047 : } else { // No bypass withnin a wrapper
3048 : // CHWOutletTemp = CHWOutletTemp; // Self-assignment commented out
3049 : }
3050 : } else {
3051 0 : CHWOutletTemp = CHWInletTemp;
3052 : }
3053 : // Calculate hot water outlet temperature
3054 4508 : if (HWInletMassFlowRate > 0.0) {
3055 4508 : Real64 HWBypassMassFlowRate = HWInletMassFlowRate - HWOutletMassFlowRate;
3056 4508 : if (HWBypassMassFlowRate > 0.0) {
3057 14 : HWOutletTemp += HWInletTemp * HWBypassMassFlowRate / HWInletMassFlowRate;
3058 : } else {
3059 : // HWOutletTemp = HWOutletTemp; // Self-assignment commented out
3060 : }
3061 : } else {
3062 0 : HWOutletTemp = HWInletTemp;
3063 : }
3064 : // Calculate condenser outlet temperature
3065 4508 : if (GLHEInletMassFlowRate > 0.0) {
3066 1004 : Real64 GLHEBypassMassFlowRate = GLHEInletMassFlowRate - GLHEOutletMassFlowRate;
3067 1004 : if (GLHEBypassMassFlowRate > 0.0) {
3068 1000 : GLHEOutletTemp += GLHEInletTemp * GLHEBypassMassFlowRate / GLHEInletMassFlowRate;
3069 : } else {
3070 : // GLHEOutletTemp = GLHEOutletTemp; // Self-assignment commented out
3071 : }
3072 : } else {
3073 3504 : GLHEOutletTemp = GLHEInletTemp;
3074 : }
3075 :
3076 : // Add ancilliary power if scheduled
3077 4508 : if (this->ancillaryPowerSched != nullptr) {
3078 0 : WrapperElecPowerCool += (this->AncillaryPower * this->ancillaryPowerSched->getCurrentVal());
3079 : }
3080 :
3081 : // Electricity should be counted once for cooling in this mode
3082 4508 : WrapperElecEnergyHeat = 0.0;
3083 :
3084 0 : } else if (this->SimulHtgDominant) { // Heating dominant simultaneous clg/htg mode
3085 :
3086 0 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
3087 : // Set temperatures and mass flow rates for the cooling side
3088 0 : int CurrentMode = this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode;
3089 0 : CHWInletTemp = this->Report.CHWInletTempSimul;
3090 0 : CHWInletMassFlowRate = this->Report.CHWmdotSimul;
3091 :
3092 0 : if (CurrentMode != 0) { // This chiller heater unit is on
3093 0 : if (CurrentMode == 3) { // Heat recovery mode. Both chilled water and hot water connections
3094 0 : CHWOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum)
3095 0 : .Report.EvapmdotSimul; // Wrapper evaporator side to plant chilled water loop
3096 0 : HWOutletMassFlowRate +=
3097 0 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot; // Wrapper condenser side to plant hot water loop
3098 0 : if (CHWInletMassFlowRate > 0.0) {
3099 0 : CHWOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTempSimul *
3100 0 : (this->ChillerHeater(ChillerHeaterNum).Report.EvapmdotSimul /
3101 : CHWInletMassFlowRate); // Only need to calculate in the heat recovery mode
3102 : } else {
3103 0 : CHWOutletTemp = CHWInletTemp;
3104 : }
3105 : } else { // Mode 5. Heating only mode with other heat recovery units
3106 0 : HWOutletMassFlowRate +=
3107 0 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot; // Wrapper condenser side to plant hot water loop
3108 0 : if (GLHEInletMassFlowRate > 0.0) {
3109 0 : GLHEOutletMassFlowRate +=
3110 0 : this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot; // Wrapper evaporator side to plant condenser loop
3111 0 : if (GLHEOutletMassFlowRate > GLHEInletMassFlowRate) {
3112 0 : GLHEOutletMassFlowRate = GLHEInletMassFlowRate;
3113 : }
3114 0 : GLHEOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp *
3115 0 : (this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot / GLHEInletMassFlowRate);
3116 0 : WrapperGLHERate += this->ChillerHeater(ChillerHeaterNum).Report.QEvap;
3117 0 : WrapperGLHEEnergy += this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy;
3118 : } else {
3119 0 : GLHEInletMassFlowRate = 0.0;
3120 0 : GLHEOutletMassFlowRate = 0.0;
3121 0 : GLHEOutletTemp = GLHEInletTemp;
3122 0 : WrapperGLHERate = 0.0;
3123 0 : WrapperGLHEEnergy = 0.0;
3124 : }
3125 : } // End of heat recovery mode
3126 :
3127 : } else { // This chiller heater is off
3128 :
3129 : // Check if any unit is heating only mode
3130 0 : if (ChillerHeaterNum == this->ChillerHeaterNums) { // All are heat revocery mode. No condenser flow
3131 0 : GLHEOutletMassFlowRate = 0.0;
3132 0 : GLHEInletMassFlowRate = 0.0;
3133 0 : GLHEOutletTemp = GLHEInletTemp;
3134 : } else { // At leaset, one of chiller heater units is heating only mode
3135 : // GLHEOutletMassFlowRate = GLHEOutletMassFlowRate; // Self-assignment commented out
3136 : // GLHEOutletTemp = GLHEOutletTemp; // Self-assignment commented out
3137 : }
3138 : }
3139 :
3140 : // Calculate mass weighed hot water temperatures
3141 0 : if (HWInletMassFlowRate > 0.0) {
3142 0 : HWOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp *
3143 0 : (this->ChillerHeater(ChillerHeaterNum).Report.Condmdot /
3144 : HWInletMassFlowRate); // Always heating as long as heating load remains
3145 : } else {
3146 0 : HWOutletTemp = HWInletTemp;
3147 : }
3148 :
3149 0 : WrapperElecPowerHeat += this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower;
3150 0 : WrapperHeatRate += this->ChillerHeater(ChillerHeaterNum).Report.QCond;
3151 0 : WrapperElecEnergyHeat += this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy;
3152 0 : WrapperHeatEnergy += this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy;
3153 :
3154 : // Avoid double counting wrapper energy use
3155 0 : WrapperElecPowerCool = 0.0;
3156 0 : WrapperCoolRate = 0.0;
3157 : }
3158 : // Calculate chilled water outlet temperature
3159 0 : if (CHWInletMassFlowRate > 0.0) {
3160 0 : Real64 CHWBypassMassFlowRate = CHWInletMassFlowRate - CHWOutletMassFlowRate;
3161 0 : if (CHWBypassMassFlowRate > 0.0) {
3162 0 : CHWOutletTemp += CHWInletTemp * CHWBypassMassFlowRate / CHWInletMassFlowRate;
3163 : } else { // No bypass withnin a wrapper
3164 : // CHWOutletTemp = CHWOutletTemp; // Self-assignment commented out
3165 : }
3166 : } else {
3167 0 : CHWOutletTemp = CHWInletTemp;
3168 : }
3169 : // Calculate hot water outlet temperature
3170 0 : if (HWInletMassFlowRate > 0.0) {
3171 0 : Real64 HWBypassMassFlowRate = HWInletMassFlowRate - HWOutletMassFlowRate;
3172 0 : if (HWBypassMassFlowRate > 0.0) {
3173 0 : HWOutletTemp += HWInletTemp * HWBypassMassFlowRate / HWInletMassFlowRate;
3174 : } else {
3175 : // HWOutletTemp = HWOutletTemp; // Self-assignment commented out
3176 : }
3177 : } else {
3178 0 : HWOutletTemp = HWInletTemp;
3179 : }
3180 : // Calculate condenser outlet temperature
3181 0 : if (GLHEInletMassFlowRate > 0.0) {
3182 0 : Real64 GLHEBypassMassFlowRate = GLHEInletMassFlowRate - GLHEOutletMassFlowRate;
3183 0 : if (GLHEBypassMassFlowRate > 0.0) {
3184 0 : GLHEOutletTemp += GLHEInletTemp * GLHEBypassMassFlowRate / GLHEInletMassFlowRate;
3185 : } else {
3186 : // GLHEOutletTemp = GLHEOutletTemp; // Self-assignment commented out
3187 : }
3188 : } else {
3189 0 : GLHEOutletTemp = GLHEInletTemp;
3190 : }
3191 :
3192 : // Check if ancilliary power is used
3193 0 : if (this->ancillaryPowerSched != nullptr) {
3194 0 : WrapperElecPowerHeat += (this->AncillaryPower * this->ancillaryPowerSched->getCurrentVal());
3195 : }
3196 :
3197 : // Electricity should be counted once
3198 0 : WrapperElecEnergyCool = 0.0;
3199 :
3200 : } // End of simultaneous clg/htg mode calculations
3201 :
3202 4508 : } else { // Heating only mode (mode 2)
3203 :
3204 76306 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
3205 59336 : HWOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum).Report.Condmdot;
3206 59336 : HWOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp *
3207 59336 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot / HWInletMassFlowRate;
3208 59336 : WrapperElecPowerHeat += this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower;
3209 59336 : WrapperHeatRate += this->ChillerHeater(ChillerHeaterNum).Report.QCond;
3210 59336 : WrapperElecEnergyHeat += this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy;
3211 59336 : WrapperHeatEnergy += this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy;
3212 :
3213 59336 : if (GLHEInletMassFlowRate > 0.0) {
3214 59336 : GLHEOutletMassFlowRate += this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot;
3215 59336 : if (GLHEOutletMassFlowRate > GLHEInletMassFlowRate) {
3216 1420 : GLHEOutletMassFlowRate = GLHEInletMassFlowRate;
3217 : }
3218 59336 : GLHEOutletTemp += this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp *
3219 59336 : (this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot / GLHEInletMassFlowRate);
3220 59336 : WrapperGLHERate += this->ChillerHeater(ChillerHeaterNum).Report.QEvap;
3221 59336 : WrapperGLHEEnergy += this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy;
3222 : } else { // No source water flow
3223 0 : GLHEOutletMassFlowRate = 0.0;
3224 0 : GLHEInletMassFlowRate = 0.0;
3225 0 : GLHEOutletTemp = GLHEInletTemp;
3226 0 : WrapperGLHERate = 0.0;
3227 0 : WrapperGLHEEnergy = 0.0;
3228 : }
3229 : }
3230 :
3231 : // Calculate hot water outlet temperature
3232 16970 : if (HWInletMassFlowRate > 0.0) {
3233 16970 : Real64 HWBypassMassFlowRate = HWInletMassFlowRate - HWOutletMassFlowRate;
3234 16970 : if (HWBypassMassFlowRate > 0.0) {
3235 11764 : HWOutletTemp += HWInletTemp * HWBypassMassFlowRate / HWInletMassFlowRate;
3236 : } else {
3237 : // HWOutletTemp = HWOutletTemp; // Self-assignment commented out
3238 5206 : if (HWOutletTemp > HWInletTemp) {
3239 5206 : HWOutletTemp = HWInletTemp;
3240 : }
3241 : }
3242 : } else {
3243 0 : HWOutletTemp = HWInletTemp;
3244 : }
3245 :
3246 : // Calculate condenser outlet temperature
3247 16970 : if (GLHEInletMassFlowRate > 0.0) {
3248 16970 : Real64 GLHEBypassMassFlowRate = GLHEInletMassFlowRate - GLHEOutletMassFlowRate;
3249 16970 : if (GLHEBypassMassFlowRate > 0.0) {
3250 15550 : GLHEOutletTemp += GLHEInletTemp * GLHEBypassMassFlowRate / GLHEInletMassFlowRate;
3251 : } else {
3252 : // GLHEOutletTemp = GLHEOutletTemp; // Self-assignment commented out
3253 : }
3254 : } else {
3255 0 : GLHEOutletTemp = GLHEInletTemp;
3256 : }
3257 :
3258 16970 : CHWOutletTemp = CHWInletTemp;
3259 :
3260 : // Add ancilliary power if necessary
3261 16970 : if (this->ancillaryPowerSched != nullptr) {
3262 0 : WrapperElecPowerHeat += (this->AncillaryPower * this->ancillaryPowerSched->getCurrentVal());
3263 : }
3264 :
3265 : } // End of calculations
3266 :
3267 21478 : PlantUtilities::SetComponentFlowRate(state, CHWInletMassFlowRate, this->CHWInletNodeNum, this->CHWOutletNodeNum, this->CWPlantLoc);
3268 :
3269 21478 : PlantUtilities::SetComponentFlowRate(state, HWInletMassFlowRate, this->HWInletNodeNum, this->HWOutletNodeNum, this->HWPlantLoc);
3270 :
3271 21478 : PlantUtilities::SetComponentFlowRate(
3272 21478 : state, GLHEInletMassFlowRate, this->GLHEInletNodeNum, this->GLHEOutletNodeNum, this->GLHEPlantLoc);
3273 :
3274 : // Local variables
3275 21478 : this->Report.CHWInletTemp = CHWInletTemp;
3276 21478 : this->Report.CHWOutletTemp = CHWOutletTemp;
3277 21478 : this->Report.HWInletTemp = HWInletTemp;
3278 21478 : this->Report.HWOutletTemp = HWOutletTemp;
3279 21478 : this->Report.GLHEInletTemp = GLHEInletTemp;
3280 21478 : this->Report.GLHEOutletTemp = GLHEOutletTemp;
3281 21478 : this->Report.CHWmdot = CHWInletMassFlowRate;
3282 21478 : this->Report.HWmdot = HWInletMassFlowRate;
3283 21478 : this->Report.GLHEmdot = GLHEInletMassFlowRate;
3284 21478 : this->Report.TotElecCooling = WrapperElecEnergyCool;
3285 21478 : this->Report.TotElecHeating = WrapperElecEnergyHeat;
3286 21478 : this->Report.CoolingEnergy = WrapperCoolEnergy;
3287 21478 : this->Report.HeatingEnergy = WrapperHeatEnergy;
3288 21478 : this->Report.GLHEEnergy = WrapperGLHEEnergy;
3289 21478 : this->Report.TotElecCoolingPwr = WrapperElecPowerCool;
3290 21478 : this->Report.TotElecHeatingPwr = WrapperElecPowerHeat;
3291 21478 : this->Report.CoolingRate = WrapperCoolRate;
3292 21478 : this->Report.HeatingRate = WrapperHeatRate;
3293 21478 : this->Report.GLHERate = WrapperGLHERate;
3294 :
3295 21478 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).Temp = CHWOutletTemp;
3296 21478 : state.dataLoopNodes->Node(this->HWOutletNodeNum).Temp = HWOutletTemp;
3297 21478 : state.dataLoopNodes->Node(this->GLHEOutletNodeNum).Temp = GLHEOutletTemp;
3298 :
3299 21478 : } else { // Central chiller heater system is off
3300 :
3301 29742 : CHWOutletTemp = CHWInletTemp;
3302 29742 : HWOutletTemp = HWInletTemp;
3303 29742 : GLHEOutletTemp = GLHEInletTemp;
3304 29742 : state.dataLoopNodes->Node(this->CHWOutletNodeNum).Temp = CHWOutletTemp;
3305 29742 : state.dataLoopNodes->Node(this->HWOutletNodeNum).Temp = HWOutletTemp;
3306 29742 : state.dataLoopNodes->Node(this->GLHEOutletNodeNum).Temp = GLHEOutletTemp;
3307 :
3308 29742 : if (this->WrapperCoolingLoad == 0.0 && !this->SimulHtgDominant) {
3309 :
3310 111228 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
3311 86518 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.MassFlowRate = 0.0;
3312 86518 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.MassFlowRate = 0.0;
3313 86518 : this->ChillerHeater(ChillerHeaterNum).EvapOutletNode.Temp = CHWInletTemp;
3314 86518 : this->ChillerHeater(ChillerHeaterNum).EvapInletNode.Temp = CHWInletTemp;
3315 86518 : this->ChillerHeater(ChillerHeaterNum).CondOutletNode.Temp = GLHEInletTemp;
3316 86518 : this->ChillerHeater(ChillerHeaterNum).CondInletNode.Temp = GLHEInletTemp;
3317 86518 : this->ChillerHeater(ChillerHeaterNum).Report.CurrentMode = 0;
3318 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerPartLoadRatio = 0.0;
3319 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCyclingRatio = 0.0;
3320 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate = 0.0;
3321 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerCapFT = 0.0;
3322 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFT = 0.0;
3323 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerEIRFPLR = 0.0;
3324 86518 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower = 0.0;
3325 86518 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower = 0.0;
3326 86518 : this->ChillerHeater(ChillerHeaterNum).Report.QEvap = 0.0;
3327 86518 : this->ChillerHeater(ChillerHeaterNum).Report.QCond = 0.0;
3328 86518 : this->ChillerHeater(ChillerHeaterNum).Report.EvapOutletTemp = CHWOutletTemp;
3329 86518 : this->ChillerHeater(ChillerHeaterNum).Report.EvapInletTemp = CHWInletTemp;
3330 86518 : this->ChillerHeater(ChillerHeaterNum).Report.CondOutletTemp = GLHEOutletTemp;
3331 86518 : this->ChillerHeater(ChillerHeaterNum).Report.CondInletTemp = GLHEInletTemp;
3332 86518 : this->ChillerHeater(ChillerHeaterNum).Report.Evapmdot = 0.0;
3333 86518 : this->ChillerHeater(ChillerHeaterNum).Report.Condmdot = 0.0;
3334 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoad = 0.0;
3335 86518 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy = 0.0;
3336 86518 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy = 0.0;
3337 86518 : this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy = 0.0;
3338 86518 : this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy = 0.0;
3339 86518 : this->ChillerHeater(ChillerHeaterNum).Report.ActualCOP = 0.0;
3340 : }
3341 :
3342 24710 : this->Report.CHWInletTemp = CHWInletTemp;
3343 24710 : this->Report.CHWOutletTemp = CHWOutletTemp;
3344 24710 : this->Report.HWInletTemp = HWInletTemp;
3345 24710 : this->Report.HWOutletTemp = HWOutletTemp;
3346 24710 : this->Report.GLHEInletTemp = GLHEInletTemp;
3347 24710 : this->Report.GLHEOutletTemp = GLHEOutletTemp;
3348 24710 : this->Report.CHWmdot = CHWInletMassFlowRate;
3349 24710 : this->Report.HWmdot = HWInletMassFlowRate;
3350 24710 : this->Report.GLHEmdot = GLHEInletMassFlowRate;
3351 24710 : this->Report.TotElecCooling = WrapperElecEnergyCool;
3352 24710 : this->Report.TotElecHeating = WrapperElecEnergyHeat;
3353 24710 : this->Report.CoolingEnergy = WrapperCoolEnergy;
3354 24710 : this->Report.HeatingEnergy = WrapperHeatEnergy;
3355 24710 : this->Report.GLHEEnergy = WrapperGLHEEnergy;
3356 24710 : this->Report.TotElecCoolingPwr = WrapperElecPowerCool;
3357 24710 : this->Report.TotElecHeatingPwr = WrapperElecPowerHeat;
3358 24710 : this->Report.CoolingRate = WrapperCoolRate;
3359 24710 : this->Report.HeatingRate = WrapperHeatRate;
3360 24710 : this->Report.GLHERate = WrapperGLHERate;
3361 :
3362 24710 : PlantUtilities::SetComponentFlowRate(
3363 24710 : state, CHWInletMassFlowRate, this->CHWInletNodeNum, this->CHWOutletNodeNum, this->CWPlantLoc);
3364 :
3365 24710 : PlantUtilities::SetComponentFlowRate(state, HWInletMassFlowRate, this->HWInletNodeNum, this->HWOutletNodeNum, this->HWPlantLoc);
3366 :
3367 24710 : PlantUtilities::SetComponentFlowRate(
3368 24710 : state, GLHEInletMassFlowRate, this->GLHEInletNodeNum, this->GLHEOutletNodeNum, this->GLHEPlantLoc);
3369 : }
3370 :
3371 : } // Heating loop calculation
3372 : }
3373 : }
3374 102440 : }
3375 :
3376 9568 : void WrapperSpecs::UpdateChillerRecords(EnergyPlusData &state) // Wrapper number
3377 : {
3378 :
3379 : // SUBROUTINE INFORMATION:
3380 : // AUTHOR: Daeho Kang, PNNL
3381 : // DATE WRITTEN: Feb 2013
3382 :
3383 : // PURPOSE OF THIS SUBROUTINE:
3384 : // Update chiller heater variables
3385 :
3386 : Real64 SecInTimeStep; // Number of seconds per HVAC system time step, to convert from W (J/s) to J
3387 : int ChillerHeaterNum; // Chiller heater number
3388 :
3389 9568 : SecInTimeStep = state.dataHVACGlobal->TimeStepSysSec;
3390 :
3391 43248 : for (ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
3392 67360 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoad =
3393 33680 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate * SecInTimeStep;
3394 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy = this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower * SecInTimeStep;
3395 33680 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy = this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower * SecInTimeStep;
3396 33680 : this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy = this->ChillerHeater(ChillerHeaterNum).Report.QEvap * SecInTimeStep;
3397 33680 : this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy = this->ChillerHeater(ChillerHeaterNum).Report.QCond * SecInTimeStep;
3398 33680 : if (this->SimulClgDominant || this->SimulHtgDominant) {
3399 13566 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadSimul = this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoad;
3400 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergySimul = this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy;
3401 13566 : this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergySimul = this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy;
3402 13566 : this->ChillerHeater(ChillerHeaterNum).Report.CondEnergySimul = this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy;
3403 : }
3404 : }
3405 9568 : }
3406 :
3407 21478 : void WrapperSpecs::UpdateChillerHeaterRecords(EnergyPlusData &state) // Wrapper number
3408 : {
3409 :
3410 : // SUBROUTINE INFORMATION:
3411 : // AUTHOR: Daeho Kang, PNNL
3412 : // DATE WRITTEN: Feb 2013
3413 :
3414 : // Number of seconds per HVAC system time step, to convert from W (J/s) to J
3415 21478 : Real64 SecInTimeStep = state.dataHVACGlobal->TimeStepSysSec;
3416 :
3417 94338 : for (int ChillerHeaterNum = 1; ChillerHeaterNum <= this->ChillerHeaterNums; ++ChillerHeaterNum) {
3418 145720 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoad =
3419 72860 : this->ChillerHeater(ChillerHeaterNum).Report.ChillerFalseLoadRate * SecInTimeStep;
3420 72860 : this->ChillerHeater(ChillerHeaterNum).Report.CoolingEnergy = this->ChillerHeater(ChillerHeaterNum).Report.CoolingPower * SecInTimeStep;
3421 72860 : this->ChillerHeater(ChillerHeaterNum).Report.HeatingEnergy = this->ChillerHeater(ChillerHeaterNum).Report.HeatingPower * SecInTimeStep;
3422 72860 : this->ChillerHeater(ChillerHeaterNum).Report.EvapEnergy = this->ChillerHeater(ChillerHeaterNum).Report.QEvap * SecInTimeStep;
3423 72860 : this->ChillerHeater(ChillerHeaterNum).Report.CondEnergy = this->ChillerHeater(ChillerHeaterNum).Report.QCond * SecInTimeStep;
3424 : }
3425 21478 : }
3426 2 : void WrapperSpecs::oneTimeInit_new([[maybe_unused]] EnergyPlusData &state)
3427 : {
3428 2 : }
3429 :
3430 0 : void WrapperSpecs::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
3431 : {
3432 0 : }
3433 :
3434 : } // namespace EnergyPlus::PlantCentralGSHP
|