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