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