Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <AirflowNetwork/Solver.hpp>
57 : #include <EnergyPlus/Autosizing/Base.hh>
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/DXCoils.hh>
60 : #include <EnergyPlus/Data/EnergyPlusData.hh>
61 : #include <EnergyPlus/DataAirSystems.hh>
62 : #include <EnergyPlus/DataEnvironment.hh>
63 : #include <EnergyPlus/DataHVACGlobals.hh>
64 : #include <EnergyPlus/DataLoopNode.hh>
65 : #include <EnergyPlus/DataSizing.hh>
66 : #include <EnergyPlus/DataZoneControls.hh>
67 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
68 : #include <EnergyPlus/DataZoneEquipment.hh>
69 : #include <EnergyPlus/EMSManager.hh>
70 : #include <EnergyPlus/Fans.hh>
71 : #include <EnergyPlus/FluidProperties.hh>
72 : #include <EnergyPlus/General.hh>
73 : #include <EnergyPlus/GeneralRoutines.hh>
74 : #include <EnergyPlus/HVACMultiSpeedHeatPump.hh>
75 : #include <EnergyPlus/HeatingCoils.hh>
76 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
77 : #include <EnergyPlus/NodeInputManager.hh>
78 : #include <EnergyPlus/OutputProcessor.hh>
79 : #include <EnergyPlus/Plant/DataPlant.hh>
80 : #include <EnergyPlus/PlantUtilities.hh>
81 : #include <EnergyPlus/Psychrometrics.hh>
82 : #include <EnergyPlus/ScheduleManager.hh>
83 : #include <EnergyPlus/SteamCoils.hh>
84 : #include <EnergyPlus/UtilityRoutines.hh>
85 : #include <EnergyPlus/WaterCoils.hh>
86 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
87 :
88 : namespace EnergyPlus {
89 :
90 : namespace HVACMultiSpeedHeatPump {
91 :
92 : // Module containing the Multi Speed Heat Pump simulation routines
93 :
94 : // MODULE INFORMATION:
95 : // AUTHOR Lixing Gu, Florida Solar Energy Center
96 : // DATE WRITTEN June 2007
97 : // MODIFIED Bereket Nigusse, FSEC, June 2010 - deprecated supply air flow fraction through controlled
98 : // zone from the furnace object input field. Now, the flow fraction is calculated internally
99 : // Brent Griffith, NREL, Dec 2010 -- upgrade to new plant for heat recovery, general fluid props.
100 : // Bereket Nigusse, FSEC, Jan. 2012 -- added hot water and steam heating coil
101 :
102 : // RE-ENGINEERED na
103 :
104 : // PURPOSE OF THIS MODULE:
105 : // To encapsulate the data and algorithms required to simulate Multi Speed Heat Pump in
106 : // EnergyPlus.
107 :
108 : // Module currently models air-cooled or evap-cooled direct expansion systems
109 : // (split or packaged) with mulptiple speeds. Air-side performance is modeled to determine
110 : // coil discharge air conditions. The module also determines the DX unit's energy
111 : // usage. Neither the air-side performance nor the energy usage includes the effect
112 : // of supply air fan heat/energy usage. The supply air fan is modeled by other modules.
113 :
114 : // USE STATEMENTS:
115 : // Use statements for data only modules
116 : // Using/Aliasing
117 : using namespace DataLoopNode;
118 : using DataHVACGlobals::BlowThru;
119 : using DataHVACGlobals::Coil_HeatingElectric;
120 : using DataHVACGlobals::Coil_HeatingElectric_MultiStage;
121 : using DataHVACGlobals::Coil_HeatingGas_MultiStage;
122 : using DataHVACGlobals::Coil_HeatingGasOrOtherFuel;
123 : using DataHVACGlobals::Coil_HeatingSteam;
124 : using DataHVACGlobals::Coil_HeatingWater;
125 : using DataHVACGlobals::ContFanCycCoil;
126 : using DataHVACGlobals::CycFanCycCoil;
127 : using DataHVACGlobals::DrawThru;
128 : using DataHVACGlobals::SmallAirVolFlow;
129 : using DataHVACGlobals::SmallLoad;
130 : using DataHVACGlobals::SmallMassFlow;
131 : using namespace Psychrometrics;
132 : using namespace ScheduleManager;
133 :
134 : // Curve Types
135 : enum class CurveType
136 : {
137 : Invalid = -1,
138 : Linear, // Linear curve type
139 : BiLinear, // Bi-linear curve type
140 : Quadratic, // Quadratic curve type
141 : BiQuadratic, // Bi-quadratic curve type
142 : Cubic, // Cubic curve type
143 : Num
144 : };
145 :
146 : static constexpr std::string_view fluidNameSteam("STEAM");
147 :
148 251050 : void SimMSHeatPump(EnergyPlusData &state,
149 : std::string_view CompName, // Name of the unitary engine driven heat pump system
150 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system time step
151 : int const AirLoopNum, // air loop index
152 : int &CompIndex // Index to changeover-bypass VAV system
153 : )
154 : {
155 :
156 : // SUBROUTINE INFORMATION:
157 : // AUTHOR Lixing Gu, Florida Solar Energy Center
158 : // DATE WRITTEN June. 2007
159 : // MODIFIED na
160 : // RE-ENGINEERED na
161 :
162 : // PURPOSE OF THIS SUBROUTINE:
163 : // Manages the simulation of multispeed heat pump.
164 :
165 : // Using/Aliasing
166 :
167 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
168 : int MSHeatPumpNum; // index of fan coil unit being simulated
169 : Real64 OnOffAirFlowRatio; // Ratio of compressor ON airflow to average airflow over timestep
170 : Real64 QZnLoad; // Zone load required by all zones served by this air loop system
171 : Real64 QSensUnitOut; // MSHP sensible capacity output [W]
172 :
173 : // First time SimMSHeatPump is called, get the input
174 251050 : if (state.dataHVACMultiSpdHP->GetInputFlag) {
175 11 : GetMSHeatPumpInput(state);
176 11 : state.dataHVACMultiSpdHP->GetInputFlag = false; // Set GetInputFlag false so you don't get coil inputs again
177 : }
178 :
179 251050 : if (CompIndex == 0) {
180 11 : MSHeatPumpNum = UtilityRoutines::FindItemInList(CompName, state.dataHVACMultiSpdHP->MSHeatPump);
181 11 : if (MSHeatPumpNum == 0) {
182 0 : ShowFatalError(state, "MultiSpeed Heat Pump is not found=" + std::string{CompName});
183 : }
184 11 : CompIndex = MSHeatPumpNum;
185 : } else {
186 251039 : MSHeatPumpNum = CompIndex;
187 251039 : if (MSHeatPumpNum > state.dataHVACMultiSpdHP->NumMSHeatPumps || MSHeatPumpNum < 1) {
188 0 : ShowFatalError(state,
189 0 : format("SimMSHeatPump: Invalid CompIndex passed={}, Number of MultiSpeed Heat Pumps={}, Heat Pump name={}",
190 : MSHeatPumpNum,
191 0 : state.dataHVACMultiSpdHP->NumMSHeatPumps,
192 0 : CompName));
193 : }
194 251039 : if (state.dataHVACMultiSpdHP->CheckEquipName(MSHeatPumpNum)) {
195 11 : if (CompName != state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).Name) {
196 0 : ShowFatalError(state,
197 0 : format("SimMSHeatPump: Invalid CompIndex passed={}, Heat Pump name={}{}",
198 : MSHeatPumpNum,
199 : CompName,
200 0 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).Name));
201 : }
202 11 : state.dataHVACMultiSpdHP->CheckEquipName(MSHeatPumpNum) = false;
203 : }
204 : }
205 :
206 251050 : OnOffAirFlowRatio = 0.0;
207 :
208 : // Initialize the engine driven heat pump
209 251050 : InitMSHeatPump(state, MSHeatPumpNum, FirstHVACIteration, AirLoopNum, QZnLoad, OnOffAirFlowRatio);
210 :
211 251050 : SimMSHP(state, MSHeatPumpNum, FirstHVACIteration, AirLoopNum, QSensUnitOut, QZnLoad, OnOffAirFlowRatio);
212 :
213 : // Update the unit outlet nodes
214 251050 : UpdateMSHeatPump(state, MSHeatPumpNum);
215 :
216 : // Report the result of the simulation
217 251050 : ReportMSHeatPump(state, MSHeatPumpNum);
218 251050 : }
219 :
220 : //******************************************************************************
221 :
222 251050 : void SimMSHP(EnergyPlusData &state,
223 : int const MSHeatPumpNum, // number of the current engine driven Heat Pump being simulated
224 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
225 : int const AirLoopNum, // air loop index
226 : Real64 &QSensUnitOut, // cooling/heating deliveded to zones [W]
227 : Real64 const QZnReq, // required zone load
228 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
229 : )
230 : {
231 :
232 : // SUBROUTINE INFORMATION:
233 : // AUTHOR Lixing Gu
234 : // DATE WRITTEN June 2007
235 : // MODIFIED na
236 : // RE-ENGINEERED Revised based on SimPTHP
237 :
238 : // PURPOSE OF THIS SUBROUTINE:
239 : // Simulate a multispeed heat pump; adjust its output to match the
240 : // required system load.
241 :
242 : // METHODOLOGY EMPLOYED:
243 : // Calls ControlMSHPOutput to obtain the desired unit output
244 :
245 : // Using/Aliasing
246 : using namespace DataZoneEnergyDemands;
247 : using DataHVACGlobals::SmallLoad;
248 : using DataHVACGlobals::SmallMassFlow;
249 :
250 : // Locals
251 : Real64 SupHeaterLoad;
252 :
253 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
254 : Real64 PartLoadFrac; // compressor part load fraction
255 : Real64 SpeedRatio; // compressor speed ratio
256 : bool UnitOn; // TRUE if unit is on
257 : int OutletNode; // MSHP air outlet node
258 : int InletNode; // MSHP air inlet node
259 : Real64 AirMassFlow; // air mass flow rate [kg/s]
260 : int OpMode; // operating mode (fan cycling or continious; DX coil always cycles)
261 : int ZoneNum; // Controlled zone number
262 : Real64 QTotUnitOut;
263 : int SpeedNum; // Speed number
264 : DataHVACGlobals::CompressorOperation CompressorOp; // compressor operation; 1=on, 0=off
265 : Real64 SaveMassFlowRate; // saved inlet air mass flow rate [kg/s]
266 :
267 : // zero the fan, DX coils, and supplemental electric heater electricity consumption
268 251050 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
269 251050 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
270 251050 : state.dataHVACMultiSpdHP->SaveCompressorPLR = 0.0;
271 251050 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
272 251050 : state.dataHVACGlobal->SuppHeatingCoilPower = 0.0;
273 :
274 251050 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
275 :
276 : // initialize local variables
277 251050 : UnitOn = true;
278 251050 : OutletNode = MSHeatPump(MSHeatPumpNum).AirOutletNodeNum;
279 251050 : InletNode = MSHeatPump(MSHeatPumpNum).AirInletNodeNum;
280 251050 : AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
281 251050 : OpMode = MSHeatPump(MSHeatPumpNum).OpMode;
282 251050 : ZoneNum = MSHeatPump(MSHeatPumpNum).ControlZoneNum;
283 251050 : CompressorOp = DataHVACGlobals::CompressorOperation::On;
284 :
285 : // set the on/off flags
286 251050 : if (MSHeatPump(MSHeatPumpNum).OpMode == CycFanCycCoil) {
287 : // cycling unit only runs if there is a cooling or heating load.
288 192078 : if (std::abs(QZnReq) < SmallLoad || AirMassFlow < SmallMassFlow || state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
289 113274 : UnitOn = false;
290 : }
291 58972 : } else if (MSHeatPump(MSHeatPumpNum).OpMode == ContFanCycCoil) {
292 : // continuous unit: fan runs if scheduled on; coil runs only if there is a cooling or heating load
293 58972 : if (AirMassFlow < SmallMassFlow) {
294 0 : UnitOn = false;
295 : }
296 : }
297 :
298 251050 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
299 :
300 251050 : SaveMassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
301 251050 : if (MSHeatPump(MSHeatPumpNum).EMSOverrideCoilSpeedNumOn) {
302 31675 : Real64 SpeedVal = MSHeatPump(MSHeatPumpNum).EMSOverrideCoilSpeedNumValue;
303 :
304 41167 : if (!FirstHVACIteration && MSHeatPump(MSHeatPumpNum).OpMode == CycFanCycCoil && QZnReq < 0.0 &&
305 9492 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
306 0 : CompressorOp = DataHVACGlobals::CompressorOperation::Off;
307 0 : ControlMSHPOutputEMS(state,
308 : MSHeatPumpNum,
309 : FirstHVACIteration,
310 : CompressorOp,
311 : OpMode,
312 : QZnReq,
313 : SpeedVal,
314 : SpeedNum,
315 : SpeedRatio,
316 : PartLoadFrac,
317 : OnOffAirFlowRatio,
318 : SupHeaterLoad);
319 0 : if (ceil(SpeedVal) == MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling && SpeedRatio == 1.0) {
320 0 : state.dataLoopNodes->Node(InletNode).MassFlowRate = SaveMassFlowRate;
321 0 : CompressorOp = DataHVACGlobals::CompressorOperation::On;
322 0 : ControlMSHPOutputEMS(state,
323 : MSHeatPumpNum,
324 : FirstHVACIteration,
325 : CompressorOp,
326 : OpMode,
327 : QZnReq,
328 : SpeedVal,
329 : SpeedNum,
330 : SpeedRatio,
331 : PartLoadFrac,
332 : OnOffAirFlowRatio,
333 : SupHeaterLoad);
334 : }
335 : } else {
336 31675 : ControlMSHPOutputEMS(state,
337 : MSHeatPumpNum,
338 : FirstHVACIteration,
339 : CompressorOp,
340 : OpMode,
341 : QZnReq,
342 : SpeedVal,
343 : SpeedNum,
344 : SpeedRatio,
345 : PartLoadFrac,
346 : OnOffAirFlowRatio,
347 : SupHeaterLoad);
348 : }
349 : } else {
350 253266 : if (!FirstHVACIteration && MSHeatPump(MSHeatPumpNum).OpMode == CycFanCycCoil && QZnReq < 0.0 &&
351 33891 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
352 : // for cycling fan, cooling load, check whether furnace can meet load with compressor off
353 0 : CompressorOp = DataHVACGlobals::CompressorOperation::Off;
354 0 : ControlMSHPOutput(state,
355 : MSHeatPumpNum,
356 : FirstHVACIteration,
357 : CompressorOp,
358 : OpMode,
359 : QZnReq,
360 : ZoneNum,
361 : SpeedNum,
362 : SpeedRatio,
363 : PartLoadFrac,
364 : OnOffAirFlowRatio,
365 : SupHeaterLoad);
366 0 : if (SpeedNum == MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling && SpeedRatio == 1.0) {
367 : // compressor on (reset inlet air mass flow rate to starting value)
368 0 : state.dataLoopNodes->Node(InletNode).MassFlowRate = SaveMassFlowRate;
369 0 : CompressorOp = DataHVACGlobals::CompressorOperation::On;
370 0 : ControlMSHPOutput(state,
371 : MSHeatPumpNum,
372 : FirstHVACIteration,
373 : CompressorOp,
374 : OpMode,
375 : QZnReq,
376 : ZoneNum,
377 : SpeedNum,
378 : SpeedRatio,
379 : PartLoadFrac,
380 : OnOffAirFlowRatio,
381 : SupHeaterLoad);
382 : }
383 : } else {
384 : // compressor on
385 219375 : ControlMSHPOutput(state,
386 : MSHeatPumpNum,
387 : FirstHVACIteration,
388 : CompressorOp,
389 : OpMode,
390 : QZnReq,
391 : ZoneNum,
392 : SpeedNum,
393 : SpeedRatio,
394 : PartLoadFrac,
395 : OnOffAirFlowRatio,
396 : SupHeaterLoad);
397 : }
398 : }
399 :
400 251050 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType != MultiSpeedHeatingCoil) {
401 42110 : state.dataHVACMultiSpdHP->SaveCompressorPLR = PartLoadFrac;
402 : } else {
403 208940 : if (SpeedNum > 1) {
404 113599 : state.dataHVACMultiSpdHP->SaveCompressorPLR = 1.0;
405 : }
406 :
407 208940 : if (PartLoadFrac == 1.0 && state.dataHVACMultiSpdHP->SaveCompressorPLR < 1.0 && (!MSHeatPump(MSHeatPumpNum).Staged)) {
408 2200 : PartLoadFrac = state.dataHVACMultiSpdHP->SaveCompressorPLR;
409 : }
410 : }
411 :
412 251050 : CalcMSHeatPump(state,
413 : MSHeatPumpNum,
414 : FirstHVACIteration,
415 : CompressorOp,
416 : SpeedNum,
417 : SpeedRatio,
418 : PartLoadFrac,
419 : QSensUnitOut,
420 : QZnReq,
421 : OnOffAirFlowRatio,
422 : SupHeaterLoad);
423 :
424 : // calculate delivered capacity
425 251050 : AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
426 :
427 502100 : QTotUnitOut = AirMassFlow * (state.dataLoopNodes->Node(OutletNode).Enthalpy -
428 251050 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).NodeNumOfControlledZone).Enthalpy);
429 :
430 : // report variables
431 251050 : MSHeatPump(MSHeatPumpNum).CompPartLoadRatio = state.dataHVACMultiSpdHP->SaveCompressorPLR;
432 251050 : if (MSHeatPump(MSHeatPumpNum).OpMode == CycFanCycCoil) {
433 192078 : if (SupHeaterLoad > 0.0) {
434 69926 : MSHeatPump(MSHeatPumpNum).FanPartLoadRatio = 1.0;
435 : } else {
436 122152 : if (SpeedNum < 2) {
437 105525 : MSHeatPump(MSHeatPumpNum).FanPartLoadRatio = PartLoadFrac;
438 : } else {
439 16627 : MSHeatPump(MSHeatPumpNum).FanPartLoadRatio = 1.0;
440 : }
441 : }
442 : } else {
443 58972 : if (UnitOn) {
444 58972 : MSHeatPump(MSHeatPumpNum).FanPartLoadRatio = 1.0;
445 : } else {
446 0 : if (SpeedNum < 2) {
447 0 : MSHeatPump(MSHeatPumpNum).FanPartLoadRatio = PartLoadFrac;
448 : } else {
449 0 : MSHeatPump(MSHeatPumpNum).FanPartLoadRatio = 1.0;
450 : }
451 : }
452 : }
453 :
454 251050 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::HeatingMode) {
455 104900 : MSHeatPump(MSHeatPumpNum).TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
456 104900 : MSHeatPump(MSHeatPumpNum).SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
457 104900 : MSHeatPump(MSHeatPumpNum).LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
458 104900 : MSHeatPump(MSHeatPumpNum).TotCoolEnergyRate = 0.0;
459 104900 : MSHeatPump(MSHeatPumpNum).SensCoolEnergyRate = 0.0;
460 104900 : MSHeatPump(MSHeatPumpNum).LatCoolEnergyRate = 0.0;
461 : }
462 251050 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::CoolingMode) {
463 100962 : MSHeatPump(MSHeatPumpNum).TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
464 100962 : MSHeatPump(MSHeatPumpNum).SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
465 100962 : MSHeatPump(MSHeatPumpNum).LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
466 100962 : MSHeatPump(MSHeatPumpNum).TotHeatEnergyRate = 0.0;
467 100962 : MSHeatPump(MSHeatPumpNum).SensHeatEnergyRate = 0.0;
468 100962 : MSHeatPump(MSHeatPumpNum).LatHeatEnergyRate = 0.0;
469 : }
470 :
471 502100 : MSHeatPump(MSHeatPumpNum).AuxElecPower = MSHeatPump(MSHeatPumpNum).AuxOnCyclePower * state.dataHVACMultiSpdHP->SaveCompressorPLR +
472 251050 : MSHeatPump(MSHeatPumpNum).AuxOffCyclePower * (1.0 - state.dataHVACMultiSpdHP->SaveCompressorPLR);
473 251050 : Real64 locFanElecPower = 0.0;
474 251050 : locFanElecPower = Fans::GetFanPower(state, MSHeatPump(MSHeatPumpNum).FanNum);
475 753150 : MSHeatPump(MSHeatPumpNum).ElecPower = locFanElecPower + state.dataHVACGlobal->DXElecCoolingPower + state.dataHVACGlobal->DXElecHeatingPower +
476 753150 : state.dataHVACGlobal->ElecHeatingCoilPower + state.dataHVACGlobal->SuppHeatingCoilPower +
477 251050 : MSHeatPump(MSHeatPumpNum).AuxElecPower;
478 251050 : }
479 :
480 : //******************************************************************************
481 :
482 11 : void GetMSHeatPumpInput(EnergyPlusData &state)
483 : {
484 : // SUBROUTINE INFORMATION:
485 : // AUTHOR: Lixing Gu, FSEC
486 : // DATE WRITTEN: July 2007
487 : // MODIFIED na
488 : // RE-ENGINEERED na
489 :
490 : // PURPOSE OF THIS SUBROUTINE:
491 : // This routine will get the input required by the multispeed heat pump model
492 :
493 : // Using/Aliasing
494 : using BranchNodeConnections::TestCompSet;
495 : using DataHVACGlobals::FanType_SimpleConstVolume;
496 : using DataHVACGlobals::FanType_SimpleOnOff;
497 : using DataSizing::AutoSize;
498 : using Fans::GetFanIndex;
499 : using Fans::GetFanInletNode;
500 : using Fans::GetFanOutletNode;
501 : using Fans::GetFanType;
502 : using Fans::GetFanVolFlow;
503 : using FluidProperties::FindGlycol;
504 :
505 : using BranchNodeConnections::SetUpCompSets;
506 : using DXCoils::GetDXCoilIndex;
507 : using NodeInputManager::GetOnlySingleNode;
508 11 : auto &GetDXCoilInletNode(DXCoils::GetCoilInletNode);
509 11 : auto &GetDXCoilOutletNode(DXCoils::GetCoilOutletNode);
510 : using DXCoils::GetDXCoilNumberOfSpeeds;
511 11 : auto &GetHeatingCoilInletNode(HeatingCoils::GetCoilInletNode);
512 11 : auto &GetHeatingCoilOutletNode(HeatingCoils::GetCoilOutletNode);
513 11 : auto &GetHeatingCoilCapacity(HeatingCoils::GetCoilCapacity);
514 : using HeatingCoils::GetCoilIndex;
515 : using HeatingCoils::GetCoilInletNode;
516 : using HeatingCoils::GetCoilOutletNode;
517 : using HeatingCoils::GetHeatingCoilIndex;
518 : using HeatingCoils::GetHeatingCoilNumberOfStages;
519 : using WaterCoils::GetCoilMaxWaterFlowRate;
520 : using WaterCoils::GetCoilWaterInletNode;
521 11 : auto &GetWaterCoilInletNode(WaterCoils::GetCoilInletNode);
522 11 : auto &GetWaterCoilOutletNode(WaterCoils::GetCoilOutletNode);
523 11 : auto &GetSteamCoilAirInletNode(SteamCoils::GetCoilAirInletNode);
524 : using SteamCoils::GetCoilAirOutletNode;
525 : using SteamCoils::GetCoilSteamInletNode;
526 : using SteamCoils::GetSteamCoilIndex;
527 11 : auto &GetCoilMaxSteamFlowRate(SteamCoils::GetCoilMaxSteamFlowRate);
528 : using DXCoils::SetMSHPDXCoilHeatRecoveryFlag;
529 : using FluidProperties::GetSatDensityRefrig;
530 :
531 : // Locals
532 : // PARAMETERS
533 : static constexpr std::string_view RoutineName("GetMSHeatPumpInput: "); // include trailing blank space
534 : static constexpr std::string_view RoutineNameNoColon("GetMSHeatPumpInput");
535 :
536 : // LOCAL VARIABLES
537 : int MSHPNum; // Engine driven heat pump count
538 : int NumAlphas; // Number of elements in the alpha array
539 : int NumNumbers; // Number of Numbers for each GetObjectItem call
540 : int IOStatus; // Used in GetObjectItem
541 11 : bool ErrorsFound(false); // True when input errors found
542 : bool IsNotOK; // Flag to verify name
543 : bool AirNodeFound; // True when an air node is found
544 : bool AirLoopFound; // True when an air loop is found
545 : int FanType; // Fan type
546 : int i; // Index to speeds
547 : int j; // Index to speeds
548 : bool Found; // Flag to find autosize
549 : int HeatingCoilInletNode; // Heating coil inlet node number
550 : int HeatingCoilOutletNode; // Heating coil outlet node number
551 : int CoolingCoilInletNode; // Cooling coil inlet node number
552 : int CoolingCoilOutletNode; // Cooling coil outlet node number
553 : int SuppHeatCoilInletNode; // Supplemental heating coil inlet node number
554 : int SuppHeatCoilOutletNode; // Supplemental heating coil outlet node number
555 : bool LocalError; // Local error flag
556 22 : Array1D_string Alphas; // Alpha input items for object
557 22 : Array1D_string cAlphaFields; // Alpha field names
558 22 : Array1D_string cNumericFields; // Numeric field names
559 22 : Array1D<Real64> Numbers; // Numeric input items for object
560 22 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
561 22 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
562 11 : int MaxNums(0); // Maximum number of numeric input fields
563 11 : int MaxAlphas(0); // Maximum number of alpha input fields
564 11 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
565 : // certain object in the input file
566 : bool errFlag;
567 : int SteamIndex; // steam coil steam inlet density
568 : Real64 SteamDensity; // density of steam at 100C
569 :
570 11 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
571 :
572 11 : if (MSHeatPump.allocated()) return;
573 :
574 22 : state.dataHVACMultiSpdHP->CurrentModuleObject =
575 11 : "AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed"; // Object type for getting and error messages
576 :
577 22 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
578 11 : state, state.dataHVACMultiSpdHP->CurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
579 11 : MaxNums = max(MaxNums, NumNumbers);
580 11 : MaxAlphas = max(MaxAlphas, NumAlphas);
581 :
582 11 : Alphas.allocate(MaxAlphas);
583 11 : cAlphaFields.allocate(MaxAlphas);
584 11 : Numbers.dimension(MaxNums, 0.0);
585 11 : cNumericFields.allocate(MaxNums);
586 11 : lAlphaBlanks.dimension(MaxAlphas, true);
587 11 : lNumericBlanks.dimension(MaxNums, true);
588 :
589 11 : state.dataHVACMultiSpdHP->NumMSHeatPumps =
590 11 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataHVACMultiSpdHP->CurrentModuleObject);
591 :
592 11 : if (state.dataHVACMultiSpdHP->NumMSHeatPumps <= 0) {
593 0 : ShowSevereError(state, "No " + state.dataHVACMultiSpdHP->CurrentModuleObject + " objects specified in input file.");
594 0 : ErrorsFound = true;
595 : }
596 :
597 : // ALLOCATE ARRAYS
598 11 : MSHeatPump.allocate(state.dataHVACMultiSpdHP->NumMSHeatPumps);
599 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport.allocate(state.dataHVACMultiSpdHP->NumMSHeatPumps);
600 11 : state.dataHVACMultiSpdHP->CheckEquipName.dimension(state.dataHVACMultiSpdHP->NumMSHeatPumps, true);
601 :
602 : // Load arrays with reformulated electric EIR chiller data
603 22 : for (MSHPNum = 1; MSHPNum <= state.dataHVACMultiSpdHP->NumMSHeatPumps; ++MSHPNum) {
604 :
605 11 : HeatingCoilInletNode = 0;
606 11 : HeatingCoilOutletNode = 0;
607 11 : CoolingCoilInletNode = 0;
608 11 : CoolingCoilOutletNode = 0;
609 11 : SuppHeatCoilInletNode = 0;
610 11 : SuppHeatCoilOutletNode = 0;
611 :
612 22 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
613 11 : state.dataHVACMultiSpdHP->CurrentModuleObject,
614 : MSHPNum,
615 : Alphas,
616 : NumAlphas,
617 : Numbers,
618 : NumNumbers,
619 : IOStatus,
620 : lNumericBlanks,
621 : lAlphaBlanks,
622 : cAlphaFields,
623 : cNumericFields);
624 11 : UtilityRoutines::IsNameEmpty(state, Alphas(1), state.dataHVACMultiSpdHP->CurrentModuleObject, ErrorsFound);
625 :
626 11 : MSHeatPump(MSHPNum).Name = Alphas(1);
627 11 : if (lAlphaBlanks(2)) {
628 0 : MSHeatPump(MSHPNum).AvaiSchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
629 : } else {
630 11 : MSHeatPump(MSHPNum).AvaiSchedPtr = GetScheduleIndex(state, Alphas(2));
631 11 : if (MSHeatPump(MSHPNum).AvaiSchedPtr == 0) {
632 0 : ShowSevereError(state,
633 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\" " + cAlphaFields(2) +
634 0 : " not found: " + Alphas(2));
635 0 : ErrorsFound = true;
636 : }
637 : }
638 :
639 11 : MSHeatPump(MSHPNum).AirInletNodeName = Alphas(3);
640 11 : MSHeatPump(MSHPNum).AirOutletNodeName = Alphas(4);
641 11 : MSHeatPump(MSHPNum).AirInletNodeNum = GetOnlySingleNode(state,
642 11 : Alphas(3),
643 : ErrorsFound,
644 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed,
645 11 : Alphas(1),
646 : DataLoopNode::NodeFluidType::Air,
647 : DataLoopNode::ConnectionType::Inlet,
648 : NodeInputManager::CompFluidStream::Primary,
649 11 : ObjectIsParent);
650 :
651 11 : MSHeatPump(MSHPNum).AirOutletNodeNum = GetOnlySingleNode(state,
652 11 : Alphas(4),
653 : ErrorsFound,
654 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed,
655 11 : Alphas(1),
656 : DataLoopNode::NodeFluidType::Air,
657 : DataLoopNode::ConnectionType::Outlet,
658 : NodeInputManager::CompFluidStream::Primary,
659 11 : ObjectIsParent);
660 :
661 11 : TestCompSet(state, state.dataHVACMultiSpdHP->CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
662 :
663 : // Get the Controlling Zone or Location of the engine driven heat pump Thermostat
664 11 : MSHeatPump(MSHPNum).ControlZoneNum = UtilityRoutines::FindItemInList(Alphas(5), state.dataHeatBal->Zone);
665 11 : MSHeatPump(MSHPNum).ControlZoneName = Alphas(5);
666 11 : if (MSHeatPump(MSHPNum).ControlZoneNum == 0) {
667 0 : ShowSevereError(state,
668 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\" " + cAlphaFields(5) +
669 0 : " not found: " + MSHeatPump(MSHPNum).ControlZoneName);
670 0 : ErrorsFound = true;
671 : }
672 :
673 : // Get the node number for the zone with the thermostat
674 11 : if (MSHeatPump(MSHPNum).ControlZoneNum > 0) {
675 11 : AirNodeFound = false;
676 11 : AirLoopFound = false;
677 11 : int ControlledZoneNum = MSHeatPump(MSHPNum).ControlZoneNum;
678 : // Find the controlled zone number for the specified thermostat location
679 11 : MSHeatPump(MSHPNum).NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
680 : // Determine if furnace is on air loop served by the thermostat location specified
681 11 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
682 11 : int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
683 11 : if (AirLoopNumber > 0) {
684 11 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
685 17 : for (int CompNum = 1;
686 17 : CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
687 : ++CompNum) {
688 51 : if (!UtilityRoutines::SameString(
689 17 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name,
690 45 : MSHeatPump(MSHPNum).Name) ||
691 22 : !UtilityRoutines::SameString(
692 11 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
693 11 : state.dataHVACMultiSpdHP->CurrentModuleObject))
694 6 : continue;
695 11 : AirLoopFound = true;
696 11 : MSHeatPump(MSHPNum).AirLoopNumber = AirLoopNumber;
697 11 : break;
698 : }
699 11 : MSHeatPump(MSHPNum).ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
700 11 : if (AirLoopFound) break;
701 : }
702 22 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
703 11 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != MSHeatPump(MSHPNum).ControlZoneNum) continue;
704 11 : AirNodeFound = true;
705 : }
706 11 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
707 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != MSHeatPump(MSHPNum).ControlZoneNum)
708 0 : continue;
709 0 : AirNodeFound = true;
710 : }
711 14 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneTempPredictorCorrector->NumStageCtrZone; ++TstatZoneNum) {
712 3 : if (state.dataZoneCtrls->StageControlledZone(TstatZoneNum).ActualZoneNum != MSHeatPump(MSHPNum).ControlZoneNum) continue;
713 1 : AirNodeFound = true;
714 : }
715 : }
716 11 : if (AirLoopFound) break;
717 : }
718 11 : if (!AirNodeFound) {
719 0 : ShowSevereError(state,
720 0 : "Did not find Air Node (" + cAlphaFields(5) + "), " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = \"\"" +
721 0 : MSHeatPump(MSHPNum).Name);
722 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
723 0 : ErrorsFound = true;
724 : }
725 11 : if (!AirLoopFound) {
726 0 : ShowSevereError(state,
727 0 : "Did not find correct AirLoopHVAC for " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " +
728 0 : MSHeatPump(MSHPNum).Name);
729 0 : ShowContinueError(state, "The " + cAlphaFields(5) + " = " + Alphas(5) + " is not served by this Primary Air Loop equipment.");
730 0 : ErrorsFound = true;
731 : }
732 : }
733 :
734 : // Get supply fan data
735 11 : MSHeatPump(MSHPNum).FanName = Alphas(7);
736 11 : if (UtilityRoutines::SameString(Alphas(6), "Fan:OnOff") || UtilityRoutines::SameString(Alphas(6), "Fan:ConstantVolume")) {
737 11 : if (UtilityRoutines::SameString(Alphas(6), "Fan:OnOff")) {
738 11 : MSHeatPump(MSHPNum).FanType = FanType_SimpleOnOff;
739 33 : SetUpCompSets(state,
740 11 : state.dataHVACMultiSpdHP->CurrentModuleObject,
741 11 : MSHeatPump(MSHPNum).Name,
742 : "Fan:OnOff",
743 11 : MSHeatPump(MSHPNum).FanName,
744 : "UNDEFINED",
745 22 : "UNDEFINED");
746 11 : MSHeatPump(MSHPNum).FanInletNode = GetFanInletNode(state, "Fan:OnOff", MSHeatPump(MSHPNum).FanName, ErrorsFound);
747 11 : MSHeatPump(MSHPNum).FanOutletNode = GetFanOutletNode(state, "Fan:OnOff", MSHeatPump(MSHPNum).FanName, ErrorsFound);
748 : } else {
749 0 : MSHeatPump(MSHPNum).FanType = FanType_SimpleConstVolume;
750 0 : SetUpCompSets(state,
751 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
752 0 : MSHeatPump(MSHPNum).Name,
753 : "Fan:ConstantVolume",
754 0 : MSHeatPump(MSHPNum).FanName,
755 : "UNDEFINED",
756 0 : "UNDEFINED");
757 0 : MSHeatPump(MSHPNum).FanInletNode = GetFanInletNode(state, "Fan:ConstantVolume", MSHeatPump(MSHPNum).FanName, ErrorsFound);
758 0 : MSHeatPump(MSHPNum).FanOutletNode = GetFanOutletNode(state, "Fan:ConstantVolume", MSHeatPump(MSHPNum).FanName, ErrorsFound);
759 : }
760 11 : GetFanIndex(state, Alphas(7), MSHeatPump(MSHPNum).FanNum, ErrorsFound, state.dataHVACMultiSpdHP->CurrentModuleObject);
761 11 : GetFanType(state, Alphas(7), FanType, ErrorsFound);
762 11 : if (FanType != MSHeatPump(MSHPNum).FanType) {
763 0 : ShowSevereError(state,
764 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " + cAlphaFields(6) +
765 0 : " and " + cAlphaFields(7) + " do not match in Fan objects.");
766 0 : ShowContinueError(state, "The entered " + cAlphaFields(7) + " = " + Alphas(7) + " and " + cAlphaFields(6) + " = " + Alphas(6));
767 0 : ErrorsFound = true;
768 : }
769 : } else {
770 0 : ShowSevereError(state,
771 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " + cAlphaFields(6) +
772 0 : " is not allowed = " + Alphas(6));
773 0 : ShowContinueError(state, "Valid choices are Fan:OnOff or Fan:ConstantVolume");
774 0 : ErrorsFound = true;
775 : }
776 :
777 : // Get supply fan placement data
778 11 : if (UtilityRoutines::SameString(Alphas(8), "BlowThrough") || UtilityRoutines::SameString(Alphas(8), "DrawThrough")) {
779 11 : if (UtilityRoutines::SameString(Alphas(8), "BlowThrough")) {
780 11 : MSHeatPump(MSHPNum).FanPlaceType = BlowThru;
781 : } else {
782 0 : MSHeatPump(MSHPNum).FanPlaceType = DrawThru;
783 : }
784 : } else {
785 0 : ShowSevereError(state,
786 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " + cAlphaFields(8) +
787 0 : " is not allowed = " + Alphas(8));
788 0 : ShowContinueError(state, "Valid choices are BlowThrough or DrawThrough");
789 0 : ErrorsFound = true;
790 : }
791 :
792 11 : MSHeatPump(MSHPNum).FanSchedule = Alphas(9);
793 11 : MSHeatPump(MSHPNum).FanSchedPtr = GetScheduleIndex(state, Alphas(9));
794 11 : if (MSHeatPump(MSHPNum).FanSchedPtr == 0) {
795 0 : ShowSevereError(state,
796 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\" " + cAlphaFields(9) +
797 0 : " not found: " + Alphas(9));
798 0 : ErrorsFound = true;
799 : }
800 :
801 11 : if (MSHeatPump(MSHPNum).FanSchedPtr > 0 && MSHeatPump(MSHPNum).FanType == FanType_SimpleConstVolume) {
802 0 : if (!CheckScheduleValueMinMax(state, MSHeatPump(MSHPNum).FanSchedPtr, ">", 0.0, "<=", 1.0)) {
803 0 : ShowSevereError(state, state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
804 0 : ShowContinueError(state,
805 0 : cAlphaFields(9) + " must be continuous (fan operating mode schedule values > 0) for " + cAlphaFields(6) +
806 : " = Fan:ConstantVolume.");
807 0 : ShowContinueError(state, "Error found in " + cAlphaFields(9) + " = " + Alphas(9));
808 0 : ShowContinueError(state, "schedule values must be (>0., <=1.)");
809 0 : ErrorsFound = true;
810 : }
811 : }
812 :
813 11 : if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:DX:MultiSpeed")) {
814 9 : MSHeatPump(MSHPNum).HeatCoilType = MultiSpeedHeatingCoil;
815 9 : MSHeatPump(MSHPNum).HeatCoilNum =
816 18 : state.dataInputProcessing->inputProcessor->getObjectItemNum(state, "Coil:Heating:DX:MultiSpeed", Alphas(11));
817 9 : MSHeatPump(MSHPNum).DXHeatCoilName = Alphas(11);
818 9 : if (MSHeatPump(MSHPNum).HeatCoilNum <= 0) {
819 0 : ShowSevereError(state, "Configuration error in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
820 0 : ShowContinueError(state, cAlphaFields(11) + " \"" + Alphas(11) + "\" not found.");
821 0 : ShowContinueError(state, cAlphaFields(10) + " must be Coil:Heating:DX:MultiSpeed ");
822 0 : ShowFatalError(state,
823 0 : std::string{RoutineName} + "Errors found in getting " + state.dataHVACMultiSpdHP->CurrentModuleObject +
824 : " input. Preceding condition(s) causes termination.");
825 0 : ErrorsFound = true;
826 : }
827 9 : LocalError = false;
828 18 : GetDXCoilIndex(
829 18 : state, MSHeatPump(MSHPNum).DXHeatCoilName, MSHeatPump(MSHPNum).DXHeatCoilIndex, LocalError, "Coil:Heating:DX:MultiSpeed");
830 9 : if (LocalError) {
831 0 : ShowSevereError(state, "The index of " + cAlphaFields(11) + " is not found \"" + Alphas(11) + "\"");
832 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
833 0 : ErrorsFound = true;
834 0 : LocalError = false;
835 : }
836 9 : HeatingCoilInletNode = GetDXCoilInletNode(state, Alphas(10), Alphas(11), LocalError);
837 9 : if (LocalError) {
838 0 : ShowSevereError(state, "The inlet node number of " + cAlphaFields(11) + " is not found \"" + Alphas(11) + "\"");
839 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
840 0 : ErrorsFound = true;
841 0 : LocalError = false;
842 : }
843 9 : HeatingCoilOutletNode = GetDXCoilOutletNode(state, Alphas(10), Alphas(11), LocalError);
844 9 : if (LocalError) {
845 0 : ShowSevereError(state, "The outlet node number of " + cAlphaFields(11) + " is not found \"" + Alphas(11) + "\"");
846 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
847 0 : ErrorsFound = true;
848 0 : LocalError = false;
849 : }
850 9 : MSHeatPump(MSHPNum).MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, MSHeatPump(MSHPNum).DXHeatCoilIndex, LocalError);
851 9 : if (LocalError) {
852 0 : ShowContinueError(state,
853 0 : "...for heating coil. Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
854 0 : LocalError = false;
855 : }
856 27 : SetUpCompSets(state,
857 9 : state.dataHVACMultiSpdHP->CurrentModuleObject,
858 9 : MSHeatPump(MSHPNum).Name,
859 : "Coil:Heating:DX:MultiSpeed",
860 9 : MSHeatPump(MSHPNum).DXHeatCoilName,
861 : "UNDEFINED",
862 18 : "UNDEFINED");
863 5 : } else if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Electric:MultiStage") ||
864 3 : UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Gas:MultiStage")) {
865 :
866 2 : if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Electric:MultiStage")) {
867 1 : MSHeatPump(MSHPNum).HeatCoilType = Coil_HeatingElectric_MultiStage;
868 1 : MSHeatPump(MSHPNum).HeatCoilNum =
869 2 : state.dataInputProcessing->inputProcessor->getObjectItemNum(state, "Coil:Heating:Electric:MultiStage", Alphas(11));
870 1 : if (MSHeatPump(MSHPNum).HeatCoilNum <= 0) {
871 0 : ShowSevereError(state, "Configuration error in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
872 0 : ShowContinueError(state, cAlphaFields(11) + " \"" + Alphas(11) + "\" not found.");
873 0 : ShowContinueError(state, cAlphaFields(10) + " must be Coil:Heating:Electric:MultiStage ");
874 0 : ShowFatalError(state,
875 0 : std::string{RoutineName} + "Errors found in getting " + state.dataHVACMultiSpdHP->CurrentModuleObject +
876 : " input. Preceding condition(s) causes termination.");
877 0 : ErrorsFound = true;
878 : }
879 : } else {
880 1 : MSHeatPump(MSHPNum).HeatCoilType = Coil_HeatingGas_MultiStage;
881 1 : MSHeatPump(MSHPNum).HeatCoilNum =
882 2 : state.dataInputProcessing->inputProcessor->getObjectItemNum(state, "Coil:Heating:Gas:MultiStage", Alphas(11));
883 1 : if (MSHeatPump(MSHPNum).HeatCoilNum <= 0) {
884 0 : ShowSevereError(state, "Configuration error in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
885 0 : ShowContinueError(state, cAlphaFields(11) + " \"" + Alphas(11) + "\" not found.");
886 0 : ShowContinueError(state, cAlphaFields(10) + " must be Coil:Heating:Gas:MultiStage ");
887 0 : ShowFatalError(state,
888 0 : std::string{RoutineName} + "Errors found in getting " + state.dataHVACMultiSpdHP->CurrentModuleObject +
889 : " input. Preceding condition(s) causes termination.");
890 0 : ErrorsFound = true;
891 : }
892 : }
893 2 : MSHeatPump(MSHPNum).HeatCoilName = Alphas(11);
894 2 : LocalError = false;
895 2 : if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Electric:MultiStage")) {
896 1 : GetCoilIndex(state, MSHeatPump(MSHPNum).HeatCoilName, MSHeatPump(MSHPNum).HeatCoilIndex, LocalError);
897 : } else {
898 1 : GetCoilIndex(state, MSHeatPump(MSHPNum).HeatCoilName, MSHeatPump(MSHPNum).HeatCoilIndex, LocalError);
899 : }
900 2 : if (LocalError) {
901 0 : ShowSevereError(state, "The index of " + cAlphaFields(11) + " is not found \"" + Alphas(11) + "\"");
902 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
903 0 : ErrorsFound = true;
904 0 : LocalError = false;
905 : }
906 2 : HeatingCoilInletNode = GetCoilInletNode(state, Alphas(10), Alphas(11), LocalError);
907 2 : if (LocalError) {
908 0 : ShowSevereError(state, "The inlet node number of " + cAlphaFields(11) + " is not found \"" + Alphas(11) + "\"");
909 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
910 0 : ErrorsFound = true;
911 0 : LocalError = false;
912 : }
913 2 : HeatingCoilOutletNode = GetCoilOutletNode(state, Alphas(10), Alphas(11), LocalError);
914 2 : if (LocalError) {
915 0 : ShowSevereError(state, "The outlet node number of " + cAlphaFields(11) + " is not found \"" + Alphas(11) + "\"");
916 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
917 0 : ErrorsFound = true;
918 0 : LocalError = false;
919 : }
920 2 : if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Electric:MultiStage")) {
921 3 : SetUpCompSets(state,
922 1 : state.dataHVACMultiSpdHP->CurrentModuleObject,
923 1 : MSHeatPump(MSHPNum).Name,
924 : "Coil:Heating:Electric:MultiStage",
925 1 : MSHeatPump(MSHPNum).HeatCoilName,
926 : "UNDEFINED",
927 2 : "UNDEFINED");
928 : } else {
929 3 : SetUpCompSets(state,
930 1 : state.dataHVACMultiSpdHP->CurrentModuleObject,
931 1 : MSHeatPump(MSHPNum).Name,
932 : "Coil:Heating:Gas:MultiStage",
933 1 : MSHeatPump(MSHPNum).HeatCoilName,
934 : "UNDEFINED",
935 2 : "UNDEFINED");
936 : }
937 0 : } else if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Water")) {
938 0 : MSHeatPump(MSHPNum).HeatCoilType = Coil_HeatingWater;
939 0 : ValidateComponent(state, Alphas(10), Alphas(11), IsNotOK, state.dataHVACMultiSpdHP->CurrentModuleObject);
940 0 : if (IsNotOK) {
941 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + Alphas(1));
942 0 : ErrorsFound = true;
943 : } else { // mine data from heating coil object
944 :
945 0 : MSHeatPump(MSHPNum).HeatCoilName = Alphas(11);
946 : // Get the Heating Coil water Inlet or control Node number
947 0 : errFlag = false;
948 0 : MSHeatPump(MSHPNum).CoilControlNode =
949 0 : GetCoilWaterInletNode(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).HeatCoilName, errFlag);
950 0 : if (errFlag) {
951 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
952 0 : ErrorsFound = true;
953 : }
954 :
955 : // Get the ReHeat Coil hot water max volume flow rate
956 0 : errFlag = false;
957 0 : MSHeatPump(MSHPNum).MaxCoilFluidFlow =
958 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).HeatCoilName, errFlag);
959 0 : if (errFlag) {
960 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
961 0 : ErrorsFound = true;
962 : }
963 :
964 : // Get the lemental Heating Coil Inlet Node
965 0 : errFlag = false;
966 0 : HeatingCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).HeatCoilName, errFlag);
967 0 : MSHeatPump(MSHPNum).CoilAirInletNode = HeatingCoilInletNode;
968 0 : if (errFlag) {
969 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
970 0 : ErrorsFound = true;
971 : }
972 :
973 : // Get the lemental Heating Coil Outlet Node
974 0 : errFlag = false;
975 0 : HeatingCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).HeatCoilName, errFlag);
976 0 : if (errFlag) {
977 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
978 0 : ErrorsFound = true;
979 : }
980 0 : SetUpCompSets(state,
981 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
982 0 : MSHeatPump(MSHPNum).Name,
983 : "Coil:Heating:Water",
984 0 : MSHeatPump(MSHPNum).HeatCoilName,
985 0 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
986 0 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
987 : }
988 0 : } else if (UtilityRoutines::SameString(Alphas(10), "Coil:Heating:Steam")) {
989 0 : MSHeatPump(MSHPNum).HeatCoilType = Coil_HeatingSteam;
990 0 : ValidateComponent(state, Alphas(10), Alphas(11), IsNotOK, state.dataHVACMultiSpdHP->CurrentModuleObject);
991 0 : if (IsNotOK) {
992 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
993 0 : ErrorsFound = true;
994 : } else { // mine data from heating coil object
995 :
996 0 : MSHeatPump(MSHPNum).HeatCoilName = Alphas(11);
997 0 : errFlag = false;
998 0 : MSHeatPump(MSHPNum).HeatCoilNum = GetSteamCoilIndex(state, Alphas(10), MSHeatPump(MSHPNum).HeatCoilName, errFlag);
999 0 : if (MSHeatPump(MSHPNum).HeatCoilNum == 0) {
1000 0 : ShowSevereError(state,
1001 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + " illegal " + cAlphaFields(10) + " = " +
1002 0 : MSHeatPump(MSHPNum).HeatCoilName);
1003 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1004 0 : ErrorsFound = true;
1005 : }
1006 :
1007 : // Get the lemental Heating Coil steam inlet node number
1008 0 : errFlag = false;
1009 0 : MSHeatPump(MSHPNum).CoilControlNode =
1010 0 : GetCoilAirOutletNode(state, "Coil:Heating:Steam", MSHeatPump(MSHPNum).HeatCoilName, errFlag);
1011 0 : if (errFlag) {
1012 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1013 0 : ErrorsFound = true;
1014 : }
1015 :
1016 : // Get the lemental Heating Coil steam max volume flow rate
1017 0 : MSHeatPump(MSHPNum).MaxCoilFluidFlow = GetCoilMaxSteamFlowRate(state, MSHeatPump(MSHPNum).HeatCoilNum, errFlag);
1018 0 : if (MSHeatPump(MSHPNum).MaxCoilFluidFlow > 0.0) {
1019 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1020 0 : SteamDensity =
1021 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataHVACMultiSpdHP->TempSteamIn, 1.0, SteamIndex, RoutineNameNoColon);
1022 0 : MSHeatPump(MSHPNum).MaxCoilFluidFlow *= SteamDensity;
1023 : }
1024 :
1025 : // Get the lemental Heating Coil Inlet Node
1026 0 : errFlag = false;
1027 0 : HeatingCoilInletNode =
1028 0 : GetSteamCoilAirInletNode(state, MSHeatPump(MSHPNum).HeatCoilNum, MSHeatPump(MSHPNum).HeatCoilName, errFlag);
1029 0 : MSHeatPump(MSHPNum).CoilAirInletNode = HeatingCoilInletNode;
1030 0 : if (errFlag) {
1031 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1032 0 : ErrorsFound = true;
1033 : }
1034 :
1035 : // Get the lemental Heating Coil Outlet Node
1036 0 : errFlag = false;
1037 0 : HeatingCoilOutletNode = GetCoilAirOutletNode(state, MSHeatPump(MSHPNum).HeatCoilNum, MSHeatPump(MSHPNum).HeatCoilName, errFlag);
1038 0 : if (errFlag) {
1039 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1040 0 : ErrorsFound = true;
1041 : }
1042 :
1043 0 : SetUpCompSets(state,
1044 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
1045 0 : MSHeatPump(MSHPNum).Name,
1046 : "Coil:Heating:Steam",
1047 0 : MSHeatPump(MSHPNum).HeatCoilName,
1048 0 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
1049 0 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
1050 : }
1051 : } else {
1052 0 : ShowSevereError(state,
1053 0 : "The allowed " + cAlphaFields(10) +
1054 0 : " are Coil:Heating:DX:MultiSpeed, Coil:Heating:Electric:MultiStage, and Coil:Heating:Gas:MultiStage in " +
1055 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1056 0 : ShowContinueError(state, "The entered " + cAlphaFields(10) + " = \"" + Alphas(10) + "\".");
1057 0 : ErrorsFound = true;
1058 : }
1059 :
1060 : // MSHeatPump(MSHPNum).MinOATCompressor = Numbers(1); // deprecated, now uses coil MinOAT inputs
1061 :
1062 11 : if (UtilityRoutines::SameString(Alphas(12), "Coil:Cooling:DX:MultiSpeed")) {
1063 11 : MSHeatPump(MSHPNum).CoolCoilType = MultiSpeedCoolingCoil;
1064 11 : MSHeatPump(MSHPNum).DXCoolCoilName = Alphas(13);
1065 11 : if (state.dataInputProcessing->inputProcessor->getObjectItemNum(state, "Coil:Cooling:DX:MultiSpeed", Alphas(13)) <= 0) {
1066 0 : ShowSevereError(state, "Configuration error in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1067 0 : ShowContinueError(state, cAlphaFields(13) + " \"" + Alphas(13) + "\" not found.");
1068 0 : ShowContinueError(state, cAlphaFields(12) + " must be Coil:Cooling:DX:MultiSpeed ");
1069 0 : ShowFatalError(state,
1070 0 : std::string{RoutineName} + "Errors found in getting " + state.dataHVACMultiSpdHP->CurrentModuleObject +
1071 : " input. Preceding condition(s) causes termination.");
1072 0 : ErrorsFound = true;
1073 : }
1074 11 : LocalError = false;
1075 22 : GetDXCoilIndex(
1076 22 : state, MSHeatPump(MSHPNum).DXCoolCoilName, MSHeatPump(MSHPNum).DXCoolCoilIndex, LocalError, "Coil:Cooling:DX:MultiSpeed");
1077 11 : if (LocalError) {
1078 0 : ShowSevereError(state, "The index of " + cAlphaFields(13) + " is not found \"" + Alphas(13) + "\"");
1079 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1080 0 : ErrorsFound = true;
1081 0 : LocalError = false;
1082 : }
1083 11 : CoolingCoilInletNode = GetDXCoilInletNode(state, Alphas(12), Alphas(13), LocalError);
1084 11 : if (LocalError) {
1085 0 : ShowSevereError(state, "The inlet node number of " + cAlphaFields(13) + " is not found \"" + Alphas(13) + "\"");
1086 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1087 0 : ErrorsFound = true;
1088 0 : LocalError = false;
1089 : }
1090 11 : CoolingCoilOutletNode = GetDXCoilOutletNode(state, Alphas(12), Alphas(13), LocalError);
1091 11 : if (LocalError) {
1092 0 : ShowSevereError(state, "The outlet node number of " + cAlphaFields(13) + " is not found \"" + Alphas(13) + "\"");
1093 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1094 0 : ErrorsFound = true;
1095 0 : LocalError = false;
1096 : }
1097 11 : MSHeatPump(MSHPNum).MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, MSHeatPump(MSHPNum).DXCoolCoilIndex, LocalError);
1098 11 : if (LocalError) {
1099 0 : ShowContinueError(state,
1100 0 : "...for cooling coil. Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1101 0 : LocalError = false;
1102 : }
1103 : } else {
1104 0 : ShowSevereError(state,
1105 0 : "The allowed " + cAlphaFields(12) + " is Coil:Cooling:DX:MultiSpeed in " +
1106 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1107 0 : ShowContinueError(state, "The entered " + cAlphaFields(12) + " = \"" + Alphas(12) + "\".");
1108 0 : ErrorsFound = true;
1109 : }
1110 33 : SetUpCompSets(state,
1111 11 : state.dataHVACMultiSpdHP->CurrentModuleObject,
1112 11 : MSHeatPump(MSHPNum).Name,
1113 : "Coil:Cooling:DX:MultiSpeed",
1114 11 : MSHeatPump(MSHPNum).DXCoolCoilName,
1115 : "UNDEFINED",
1116 22 : "UNDEFINED");
1117 :
1118 : // Get supplemental heating coil data
1119 11 : MSHeatPump(MSHPNum).SuppHeatCoilName = Alphas(15);
1120 11 : if (UtilityRoutines::SameString(Alphas(14), "Coil:Heating:Fuel")) {
1121 11 : MSHeatPump(MSHPNum).SuppHeatCoilType = SuppHeatingCoilGas;
1122 11 : errFlag = false;
1123 11 : MSHeatPump(MSHPNum).SuppHeatCoilNum = GetHeatingCoilIndex(state, "Coil:Heating:Fuel", Alphas(15), errFlag);
1124 11 : if (MSHeatPump(MSHPNum).SuppHeatCoilNum <= 0 || errFlag) {
1125 0 : ShowContinueError(state, "Configuration error in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1126 0 : ShowContinueError(state, cAlphaFields(15) + " of type Coil:Heating:Fuel \"" + Alphas(15) + "\" not found.");
1127 0 : ErrorsFound = true;
1128 : }
1129 :
1130 : // Get the Supplemental Heating Coil Node Numbers
1131 11 : LocalError = false;
1132 11 : SuppHeatCoilInletNode = GetHeatingCoilInletNode(state, Alphas(14), Alphas(15), LocalError);
1133 11 : if (LocalError) {
1134 0 : ShowSevereError(state, "The inlet node number of " + cAlphaFields(15) + " is not found \"" + Alphas(15) + "\"");
1135 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1136 0 : ErrorsFound = true;
1137 0 : LocalError = false;
1138 : }
1139 11 : SuppHeatCoilOutletNode = GetHeatingCoilOutletNode(state, Alphas(14), Alphas(15), LocalError);
1140 11 : if (LocalError) {
1141 0 : ShowSevereError(state, "The outlet node number of " + cAlphaFields(15) + " is not found \"" + Alphas(15) + "\"");
1142 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1143 0 : ErrorsFound = true;
1144 0 : LocalError = false;
1145 : }
1146 :
1147 : // Get supplemental heating coil capacity to see if it is autosize
1148 11 : MSHeatPump(MSHPNum).DesignSuppHeatingCapacity = GetHeatingCoilCapacity(state, Alphas(14), Alphas(15), LocalError);
1149 11 : if (LocalError) {
1150 0 : ShowSevereError(state, "The capacity " + cAlphaFields(15) + " is not found \"" + Alphas(15) + "\"");
1151 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1152 0 : ErrorsFound = true;
1153 0 : LocalError = false;
1154 : }
1155 33 : SetUpCompSets(state,
1156 11 : state.dataHVACMultiSpdHP->CurrentModuleObject,
1157 11 : MSHeatPump(MSHPNum).Name,
1158 : "Coil:Heating:Fuel",
1159 11 : MSHeatPump(MSHPNum).SuppHeatCoilName,
1160 : "UNDEFINED",
1161 22 : "UNDEFINED");
1162 : }
1163 11 : if (UtilityRoutines::SameString(Alphas(14), "Coil:Heating:Electric")) {
1164 0 : MSHeatPump(MSHPNum).SuppHeatCoilType = SuppHeatingCoilElec;
1165 0 : errFlag = false;
1166 0 : MSHeatPump(MSHPNum).SuppHeatCoilNum = GetHeatingCoilIndex(state, "Coil:Heating:Electric", Alphas(15), errFlag);
1167 0 : if (MSHeatPump(MSHPNum).SuppHeatCoilNum <= 0 || errFlag) {
1168 0 : ShowContinueError(state, "Configuration error in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1169 0 : ShowContinueError(state, cAlphaFields(15) + " of type Coil:Heating:Electric \"" + Alphas(15) + "\" not found.");
1170 0 : ErrorsFound = true;
1171 : }
1172 :
1173 : // Get the Supplemental Heating Coil Node Numbers
1174 0 : LocalError = false;
1175 0 : SuppHeatCoilInletNode = GetHeatingCoilInletNode(state, Alphas(14), Alphas(15), LocalError);
1176 0 : if (LocalError) {
1177 0 : ShowSevereError(state, "The inlet node number of " + cAlphaFields(15) + " is not found \"" + Alphas(15) + "\"");
1178 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1179 0 : ErrorsFound = true;
1180 0 : LocalError = false;
1181 : }
1182 0 : SuppHeatCoilOutletNode = GetHeatingCoilOutletNode(state, Alphas(14), Alphas(15), LocalError);
1183 0 : if (LocalError) {
1184 0 : ShowSevereError(state, "The outlet node number of " + cAlphaFields(15) + " is not found \"" + Alphas(15) + "\"");
1185 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1186 0 : ErrorsFound = true;
1187 0 : LocalError = false;
1188 : }
1189 :
1190 : // Get supplemental heating coil capacity to see if it is autosize
1191 0 : MSHeatPump(MSHPNum).DesignSuppHeatingCapacity = GetHeatingCoilCapacity(state, Alphas(14), Alphas(15), LocalError);
1192 0 : if (LocalError) {
1193 0 : ShowSevereError(state, "The capacity " + cAlphaFields(15) + " is not found \"" + Alphas(15) + "\"");
1194 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + Alphas(1) + "\"");
1195 0 : ErrorsFound = true;
1196 0 : LocalError = false;
1197 : }
1198 :
1199 0 : SetUpCompSets(state,
1200 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
1201 0 : MSHeatPump(MSHPNum).Name,
1202 : "Coil:Heating:Electric",
1203 0 : MSHeatPump(MSHPNum).SuppHeatCoilName,
1204 : "UNDEFINED",
1205 0 : "UNDEFINED");
1206 : }
1207 :
1208 11 : if (UtilityRoutines::SameString(Alphas(14), "Coil:Heating:Water")) {
1209 0 : MSHeatPump(MSHPNum).SuppHeatCoilType = Coil_HeatingWater;
1210 0 : ValidateComponent(state, Alphas(14), MSHeatPump(MSHPNum).SuppHeatCoilName, IsNotOK, state.dataHVACMultiSpdHP->CurrentModuleObject);
1211 0 : if (IsNotOK) {
1212 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + Alphas(1));
1213 0 : ErrorsFound = true;
1214 : } else { // mine data from heating coil object
1215 :
1216 : // Get the Heating Coil water Inlet or control Node number
1217 0 : errFlag = false;
1218 0 : MSHeatPump(MSHPNum).SuppCoilControlNode =
1219 0 : GetCoilWaterInletNode(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1220 0 : if (errFlag) {
1221 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1222 0 : ErrorsFound = true;
1223 : }
1224 :
1225 : // Get the ReHeat Coil hot water max volume flow rate
1226 0 : errFlag = false;
1227 0 : MSHeatPump(MSHPNum).MaxSuppCoilFluidFlow =
1228 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1229 0 : if (errFlag) {
1230 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1231 0 : ErrorsFound = true;
1232 : }
1233 :
1234 : // Get the Supplemental Heating Coil Inlet Node
1235 0 : errFlag = false;
1236 0 : SuppHeatCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1237 0 : MSHeatPump(MSHPNum).SuppCoilAirInletNode = SuppHeatCoilInletNode;
1238 0 : if (errFlag) {
1239 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1240 0 : ErrorsFound = true;
1241 : }
1242 :
1243 : // Get the Supplemental Heating Coil Outlet Node
1244 0 : errFlag = false;
1245 0 : SuppHeatCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1246 0 : MSHeatPump(MSHPNum).SuppCoilAirOutletNode = SuppHeatCoilOutletNode;
1247 0 : if (errFlag) {
1248 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1249 0 : ErrorsFound = true;
1250 : }
1251 0 : SetUpCompSets(state,
1252 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
1253 0 : MSHeatPump(MSHPNum).Name,
1254 : "Coil:Heating:Water",
1255 0 : MSHeatPump(MSHPNum).SuppHeatCoilName,
1256 0 : state.dataLoopNodes->NodeID(SuppHeatCoilInletNode),
1257 0 : state.dataLoopNodes->NodeID(SuppHeatCoilOutletNode));
1258 : }
1259 : }
1260 11 : if (UtilityRoutines::SameString(Alphas(14), "Coil:Heating:Steam")) {
1261 0 : MSHeatPump(MSHPNum).SuppHeatCoilType = Coil_HeatingSteam;
1262 0 : ValidateComponent(state, Alphas(14), MSHeatPump(MSHPNum).SuppHeatCoilName, IsNotOK, state.dataHVACMultiSpdHP->CurrentModuleObject);
1263 0 : if (IsNotOK) {
1264 0 : ShowContinueError(state, "...occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1265 0 : ErrorsFound = true;
1266 : } else { // mine data from heating coil object
1267 :
1268 0 : errFlag = false;
1269 0 : MSHeatPump(MSHPNum).SuppHeatCoilNum = GetSteamCoilIndex(state, Alphas(14), MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1270 0 : if (MSHeatPump(MSHPNum).SuppHeatCoilNum == 0) {
1271 0 : ShowSevereError(state,
1272 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + " illegal " + cAlphaFields(14) + " = " +
1273 0 : MSHeatPump(MSHPNum).SuppHeatCoilName);
1274 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1275 0 : ErrorsFound = true;
1276 : }
1277 :
1278 : // Get the Supplemental Heating Coil steam inlet node number
1279 0 : errFlag = false;
1280 0 : MSHeatPump(MSHPNum).SuppCoilControlNode =
1281 0 : GetCoilAirOutletNode(state, "Coil:Heating:Steam", MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1282 0 : if (errFlag) {
1283 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1284 0 : ErrorsFound = true;
1285 : }
1286 :
1287 : // Get the Supplemental Heating Coil steam max volume flow rate
1288 0 : MSHeatPump(MSHPNum).MaxSuppCoilFluidFlow = GetCoilMaxSteamFlowRate(state, MSHeatPump(MSHPNum).SuppHeatCoilNum, errFlag);
1289 0 : if (MSHeatPump(MSHPNum).MaxSuppCoilFluidFlow > 0.0) {
1290 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1291 0 : SteamDensity =
1292 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataHVACMultiSpdHP->TempSteamIn, 1.0, SteamIndex, RoutineNameNoColon);
1293 0 : MSHeatPump(MSHPNum).MaxSuppCoilFluidFlow *= SteamDensity;
1294 : }
1295 :
1296 : // Get the Supplemental Heating Coil Inlet Node
1297 0 : errFlag = false;
1298 0 : SuppHeatCoilInletNode =
1299 0 : GetSteamCoilAirInletNode(state, MSHeatPump(MSHPNum).SuppHeatCoilNum, MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1300 0 : MSHeatPump(MSHPNum).SuppCoilAirInletNode = SuppHeatCoilInletNode;
1301 0 : if (errFlag) {
1302 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1303 0 : ErrorsFound = true;
1304 : }
1305 :
1306 : // Get the Supplemental Heating Coil Outlet Node
1307 0 : errFlag = false;
1308 0 : SuppHeatCoilOutletNode =
1309 0 : GetCoilAirOutletNode(state, MSHeatPump(MSHPNum).SuppHeatCoilNum, MSHeatPump(MSHPNum).SuppHeatCoilName, errFlag);
1310 0 : MSHeatPump(MSHPNum).SuppCoilAirOutletNode = SuppHeatCoilOutletNode;
1311 0 : if (errFlag) {
1312 0 : ShowContinueError(state, "Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHPNum).Name);
1313 0 : ErrorsFound = true;
1314 : }
1315 :
1316 0 : SetUpCompSets(state,
1317 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
1318 0 : MSHeatPump(MSHPNum).Name,
1319 : "Coil:Heating:Steam",
1320 0 : MSHeatPump(MSHPNum).SuppHeatCoilName,
1321 0 : state.dataLoopNodes->NodeID(SuppHeatCoilInletNode),
1322 0 : state.dataLoopNodes->NodeID(SuppHeatCoilOutletNode));
1323 : }
1324 : }
1325 :
1326 11 : if (MSHeatPump(MSHPNum).SuppHeatCoilType == 0) {
1327 0 : ShowSevereError(state,
1328 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " + cAlphaFields(14) +
1329 0 : " is not allowed = " + Alphas(14));
1330 0 : ShowContinueError(state, "Valid choices are Coil:Heating:Fuel,Coil:Heating:Electric,Coil:Heating:Steam,or Coil:Heating:Water");
1331 0 : ErrorsFound = true;
1332 : }
1333 :
1334 11 : MSHeatPump(MSHPNum).SuppMaxAirTemp = Numbers(2);
1335 11 : MSHeatPump(MSHPNum).SuppMaxOATemp = Numbers(3);
1336 11 : if (MSHeatPump(MSHPNum).SuppMaxOATemp > 21.0) {
1337 0 : ShowSevereError(state,
1338 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " + cNumericFields(3) +
1339 : " is greater than 21.0");
1340 0 : ShowContinueError(state, format("The input value is {:.2R}", Numbers(3)));
1341 0 : ErrorsFound = true;
1342 : }
1343 :
1344 11 : MSHeatPump(MSHPNum).AuxOnCyclePower = Numbers(4);
1345 11 : MSHeatPump(MSHPNum).AuxOffCyclePower = Numbers(5);
1346 11 : if (MSHeatPump(MSHPNum).AuxOnCyclePower < 0.0) {
1347 0 : ShowSevereError(state,
1348 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", A negative value for " +
1349 0 : cNumericFields(4) + " is not allowed ");
1350 0 : ErrorsFound = true;
1351 : }
1352 11 : if (MSHeatPump(MSHPNum).AuxOffCyclePower < 0.0) {
1353 0 : ShowSevereError(state,
1354 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", A negative value for " +
1355 0 : cNumericFields(5) + " is not allowed ");
1356 0 : ErrorsFound = true;
1357 : }
1358 :
1359 : // Heat recovery
1360 11 : MSHeatPump(MSHPNum).DesignHeatRecFlowRate = Numbers(6);
1361 11 : if (MSHeatPump(MSHPNum).DesignHeatRecFlowRate > 0.0) {
1362 0 : MSHeatPump(MSHPNum).HeatRecActive = true;
1363 0 : MSHeatPump(MSHPNum).DesignHeatRecMassFlowRate =
1364 0 : RhoH2O(DataGlobalConstants::HWInitConvTemp) * MSHeatPump(MSHPNum).DesignHeatRecFlowRate;
1365 0 : MSHeatPump(MSHPNum).HeatRecInletNodeNum =
1366 0 : GetOnlySingleNode(state,
1367 0 : Alphas(16),
1368 : ErrorsFound,
1369 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed,
1370 0 : Alphas(1),
1371 : DataLoopNode::NodeFluidType::Water,
1372 : DataLoopNode::ConnectionType::Inlet,
1373 : NodeInputManager::CompFluidStream::Tertiary,
1374 0 : ObjectIsNotParent);
1375 0 : if (MSHeatPump(MSHPNum).HeatRecInletNodeNum == 0) {
1376 0 : ShowSevereError(state,
1377 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", Missing " +
1378 0 : cAlphaFields(16) + '.');
1379 0 : ErrorsFound = true;
1380 : }
1381 0 : MSHeatPump(MSHPNum).HeatRecOutletNodeNum =
1382 0 : GetOnlySingleNode(state,
1383 0 : Alphas(17),
1384 : ErrorsFound,
1385 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed,
1386 0 : Alphas(1),
1387 : DataLoopNode::NodeFluidType::Water,
1388 : DataLoopNode::ConnectionType::Outlet,
1389 : NodeInputManager::CompFluidStream::Tertiary,
1390 0 : ObjectIsNotParent);
1391 0 : if (MSHeatPump(MSHPNum).HeatRecOutletNodeNum == 0) {
1392 0 : ShowSevereError(state,
1393 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", Missing " +
1394 0 : cAlphaFields(17) + '.');
1395 0 : ErrorsFound = true;
1396 : }
1397 0 : TestCompSet(state, state.dataHVACMultiSpdHP->CurrentModuleObject, Alphas(1), Alphas(16), Alphas(17), "MSHP Heat receovery Nodes");
1398 0 : SetMSHPDXCoilHeatRecoveryFlag(state, MSHeatPump(MSHPNum).DXCoolCoilIndex);
1399 0 : if (MSHeatPump(MSHPNum).DXHeatCoilIndex > 0) {
1400 0 : SetMSHPDXCoilHeatRecoveryFlag(state, MSHeatPump(MSHPNum).DXHeatCoilIndex);
1401 : }
1402 : } else {
1403 11 : MSHeatPump(MSHPNum).HeatRecActive = false;
1404 11 : MSHeatPump(MSHPNum).DesignHeatRecMassFlowRate = 0.0;
1405 11 : MSHeatPump(MSHPNum).HeatRecInletNodeNum = 0;
1406 11 : MSHeatPump(MSHPNum).HeatRecOutletNodeNum = 0;
1407 11 : if (!lAlphaBlanks(16) || !lAlphaBlanks(17)) {
1408 0 : ShowWarningError(state,
1409 0 : "Since " + cNumericFields(6) + " = 0.0, heat recovery is inactive for " +
1410 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + Alphas(1));
1411 0 : ShowContinueError(state, "However, " + cAlphaFields(16) + " or " + cAlphaFields(17) + " was specified.");
1412 : }
1413 : }
1414 11 : MSHeatPump(MSHPNum).MaxHeatRecOutletTemp = Numbers(7);
1415 11 : if (MSHeatPump(MSHPNum).MaxHeatRecOutletTemp < 0.0) {
1416 0 : ShowSevereError(state,
1417 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", The value for " +
1418 0 : cNumericFields(7) + " is below 0.0");
1419 0 : ErrorsFound = true;
1420 : }
1421 11 : if (MSHeatPump(MSHPNum).MaxHeatRecOutletTemp > 100.0) {
1422 0 : ShowSevereError(state,
1423 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", The value for " +
1424 0 : cNumericFields(7) + " is above 100.0");
1425 0 : ErrorsFound = true;
1426 : }
1427 :
1428 11 : MSHeatPump(MSHPNum).IdleVolumeAirRate = Numbers(8);
1429 11 : if (MSHeatPump(MSHPNum).IdleVolumeAirRate < 0.0 && MSHeatPump(MSHPNum).IdleVolumeAirRate != AutoSize) {
1430 0 : ShowSevereError(state,
1431 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " + cNumericFields(8) +
1432 : " cannot be less than zero.");
1433 0 : ErrorsFound = true;
1434 : }
1435 :
1436 : // AirFlowControl only valid if fan opmode = ContFanCycCoil
1437 11 : if (MSHeatPump(MSHPNum).IdleVolumeAirRate == 0.0) {
1438 0 : MSHeatPump(MSHPNum).AirFlowControl = AirflowControl::UseCompressorOnFlow;
1439 : } else {
1440 11 : MSHeatPump(MSHPNum).AirFlowControl = AirflowControl::UseCompressorOffFlow;
1441 : }
1442 :
1443 : // Initialize last mode of compressor operation
1444 11 : MSHeatPump(MSHPNum).LastMode = ModeOfOperation::HeatingMode;
1445 :
1446 11 : MSHeatPump(MSHPNum).NumOfSpeedHeating = Numbers(9);
1447 11 : if (MSHeatPump(MSHPNum).NumOfSpeedHeating < 2 || MSHeatPump(MSHPNum).NumOfSpeedHeating > 4) {
1448 2 : if (MSHeatPump(MSHPNum).HeatCoilType == MultiSpeedHeatingCoil) {
1449 0 : ShowSevereError(state,
1450 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", The maximum " + cNumericFields(9) +
1451 : " is 4, and the minimum number is 2");
1452 0 : ShowContinueError(state, format("The input value is {:.0R}", Numbers(9)));
1453 0 : ErrorsFound = true;
1454 : }
1455 : }
1456 11 : MSHeatPump(MSHPNum).NumOfSpeedCooling = Numbers(10);
1457 11 : if (MSHeatPump(MSHPNum).NumOfSpeedCooling < 2 || MSHeatPump(MSHPNum).NumOfSpeedCooling > 4) {
1458 0 : ShowSevereError(state,
1459 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", The maximum " + cNumericFields(10) +
1460 : " is 4, and the minimum number is 2");
1461 0 : ShowContinueError(state, format("The input value is {:.0R}", Numbers(10)));
1462 0 : ErrorsFound = true;
1463 : }
1464 :
1465 : // Generate a dynamic array for heating
1466 11 : if (MSHeatPump(MSHPNum).NumOfSpeedHeating > 0) {
1467 11 : MSHeatPump(MSHPNum).HeatMassFlowRate.allocate(MSHeatPump(MSHPNum).NumOfSpeedHeating);
1468 11 : MSHeatPump(MSHPNum).HeatVolumeFlowRate.allocate(MSHeatPump(MSHPNum).NumOfSpeedHeating);
1469 11 : MSHeatPump(MSHPNum).HeatingSpeedRatio.allocate(MSHeatPump(MSHPNum).NumOfSpeedHeating);
1470 11 : MSHeatPump(MSHPNum).HeatingSpeedRatio = 1.0;
1471 39 : for (i = 1; i <= MSHeatPump(MSHPNum).NumOfSpeedHeating; ++i) {
1472 28 : MSHeatPump(MSHPNum).HeatVolumeFlowRate(i) = Numbers(10 + i);
1473 28 : if (MSHeatPump(MSHPNum).HeatCoilType == MultiSpeedHeatingCoil) {
1474 26 : if (MSHeatPump(MSHPNum).HeatVolumeFlowRate(i) <= 0.0 && MSHeatPump(MSHPNum).HeatVolumeFlowRate(i) != AutoSize) {
1475 0 : ShowSevereError(state,
1476 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " +
1477 0 : cNumericFields(10 + i) + " must be greater than zero.");
1478 0 : ErrorsFound = true;
1479 : }
1480 : }
1481 : }
1482 : // Ensure flow rate at high speed should be greater or equal to the flow rate at low speed
1483 28 : for (i = 2; i <= MSHeatPump(MSHPNum).NumOfSpeedHeating; ++i) {
1484 17 : if (MSHeatPump(MSHPNum).HeatVolumeFlowRate(i) == AutoSize) continue;
1485 17 : Found = false;
1486 17 : for (j = i - 1; j >= 1; --j) {
1487 17 : if (MSHeatPump(MSHPNum).HeatVolumeFlowRate(i) != AutoSize) {
1488 17 : Found = true;
1489 17 : break;
1490 : }
1491 : }
1492 17 : if (Found) {
1493 17 : if (MSHeatPump(MSHPNum).HeatVolumeFlowRate(i) < MSHeatPump(MSHPNum).HeatVolumeFlowRate(j)) {
1494 0 : ShowSevereError(state,
1495 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " +
1496 0 : cNumericFields(10 + i));
1497 0 : ShowContinueError(state, " cannot be less than " + cNumericFields(10 + j));
1498 0 : ErrorsFound = true;
1499 : }
1500 : }
1501 : }
1502 : }
1503 :
1504 11 : if (state.dataGlobal->DoCoilDirectSolutions) {
1505 1 : int MaxNumber = std::max(MSHeatPump(MSHPNum).NumOfSpeedCooling, MSHeatPump(MSHPNum).NumOfSpeedHeating);
1506 1 : MSHeatPump(MSHPNum).FullOutput.allocate(MaxNumber);
1507 1 : DXCoils::DisableLatentDegradation(state, MSHeatPump(MSHPNum).DXCoolCoilIndex);
1508 : }
1509 : // Generate a dynamic array for cooling
1510 11 : if (MSHeatPump(MSHPNum).NumOfSpeedCooling > 0) {
1511 11 : MSHeatPump(MSHPNum).CoolMassFlowRate.allocate(MSHeatPump(MSHPNum).NumOfSpeedCooling);
1512 11 : MSHeatPump(MSHPNum).CoolVolumeFlowRate.allocate(MSHeatPump(MSHPNum).NumOfSpeedCooling);
1513 11 : MSHeatPump(MSHPNum).CoolingSpeedRatio.allocate(MSHeatPump(MSHPNum).NumOfSpeedCooling);
1514 11 : MSHeatPump(MSHPNum).CoolingSpeedRatio = 1.0;
1515 45 : for (i = 1; i <= MSHeatPump(MSHPNum).NumOfSpeedCooling; ++i) {
1516 34 : MSHeatPump(MSHPNum).CoolVolumeFlowRate(i) = Numbers(14 + i);
1517 34 : if (MSHeatPump(MSHPNum).CoolVolumeFlowRate(i) <= 0.0 && MSHeatPump(MSHPNum).CoolVolumeFlowRate(i) != AutoSize) {
1518 0 : ShowSevereError(state,
1519 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " +
1520 0 : cNumericFields(14 + i) + " must be greater than zero.");
1521 0 : ErrorsFound = true;
1522 : }
1523 : }
1524 : // Ensure flow rate at high speed should be greater or equal to the flow rate at low speed
1525 34 : for (i = 2; i <= MSHeatPump(MSHPNum).NumOfSpeedCooling; ++i) {
1526 23 : if (MSHeatPump(MSHPNum).CoolVolumeFlowRate(i) == AutoSize) continue;
1527 23 : Found = false;
1528 23 : for (j = i - 1; j >= 1; --j) {
1529 23 : if (MSHeatPump(MSHPNum).CoolVolumeFlowRate(i) != AutoSize) {
1530 23 : Found = true;
1531 23 : break;
1532 : }
1533 : }
1534 23 : if (Found) {
1535 23 : if (MSHeatPump(MSHPNum).CoolVolumeFlowRate(i) < MSHeatPump(MSHPNum).CoolVolumeFlowRate(j)) {
1536 0 : ShowSevereError(state,
1537 0 : state.dataHVACMultiSpdHP->CurrentModuleObject + ", \"" + MSHeatPump(MSHPNum).Name + "\", " +
1538 0 : cNumericFields(14 + i));
1539 0 : ShowContinueError(state, " cannot be less than " + cNumericFields(14 + j));
1540 0 : ErrorsFound = true;
1541 : }
1542 : }
1543 : }
1544 : }
1545 :
1546 : // Check node integrity
1547 11 : if (MSHeatPump(MSHPNum).FanPlaceType == BlowThru) {
1548 11 : if (MSHeatPump(MSHPNum).FanInletNode != MSHeatPump(MSHPNum).AirInletNodeNum) {
1549 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1550 0 : ShowContinueError(state,
1551 0 : "When a blow through fan is specified, the fan inlet node name must be the same as the " + cAlphaFields(3));
1552 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).FanInletNode));
1553 0 : ShowContinueError(state, "..." + cAlphaFields(3) + " = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).AirInletNodeNum));
1554 0 : ErrorsFound = true;
1555 : }
1556 11 : if (MSHeatPump(MSHPNum).FanOutletNode != CoolingCoilInletNode) {
1557 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1558 0 : ShowContinueError(
1559 : state,
1560 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil inlet node name.");
1561 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).FanOutletNode));
1562 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
1563 0 : ErrorsFound = true;
1564 : }
1565 11 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
1566 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1567 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
1568 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
1569 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
1570 0 : ErrorsFound = true;
1571 : }
1572 11 : if (HeatingCoilOutletNode != SuppHeatCoilInletNode) {
1573 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1574 0 : ShowContinueError(state,
1575 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the reheat coil "
1576 : "inlet node name.");
1577 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
1578 0 : ShowContinueError(state, "...Reheat coil inlet node name = " + state.dataLoopNodes->NodeID(SuppHeatCoilInletNode));
1579 0 : ErrorsFound = true;
1580 : }
1581 11 : if (SuppHeatCoilOutletNode != MSHeatPump(MSHPNum).AirOutletNodeNum) {
1582 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1583 0 : ShowContinueError(state, "The supplemental heating coil outlet node name must be the same as the " + cAlphaFields(4));
1584 0 : ShowContinueError(state,
1585 0 : "...Supplemental heating coil outlet node name = " + state.dataLoopNodes->NodeID(SuppHeatCoilOutletNode));
1586 0 : ShowContinueError(state, "..." + cAlphaFields(4) + " = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).AirOutletNodeNum));
1587 0 : ErrorsFound = true;
1588 : }
1589 : } else {
1590 0 : if (CoolingCoilInletNode != MSHeatPump(MSHPNum).AirInletNodeNum) {
1591 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1592 0 : ShowContinueError(
1593 0 : state, "When a draw through fan is specified, the cooling coil inlet node name must be the same as the " + cAlphaFields(3));
1594 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
1595 0 : ShowContinueError(state, "..." + cAlphaFields(3) + " = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).AirInletNodeNum));
1596 0 : ErrorsFound = true;
1597 : }
1598 0 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
1599 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1600 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
1601 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
1602 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
1603 0 : ErrorsFound = true;
1604 : }
1605 0 : if (HeatingCoilOutletNode != MSHeatPump(MSHPNum).FanInletNode) {
1606 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1607 0 : ShowContinueError(
1608 : state,
1609 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
1610 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
1611 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).FanInletNode));
1612 0 : ErrorsFound = true;
1613 : }
1614 0 : if (MSHeatPump(MSHPNum).FanOutletNode != SuppHeatCoilInletNode) {
1615 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1616 0 : ShowContinueError(
1617 : state, "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil inlet node name.");
1618 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).FanOutletNode));
1619 0 : ShowContinueError(state, "...Reheat coil inlet node name = " + state.dataLoopNodes->NodeID(SuppHeatCoilInletNode));
1620 0 : ErrorsFound = true;
1621 : }
1622 0 : if (SuppHeatCoilOutletNode != MSHeatPump(MSHPNum).AirOutletNodeNum) {
1623 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1624 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the " + cAlphaFields(4));
1625 0 : ShowContinueError(state, "...Reheat coil outlet node name = " + state.dataLoopNodes->NodeID(SuppHeatCoilOutletNode));
1626 0 : ShowContinueError(state, "..." + cAlphaFields(4) + " = " + state.dataLoopNodes->NodeID(MSHeatPump(MSHPNum).AirOutletNodeNum));
1627 0 : ErrorsFound = true;
1628 : }
1629 : }
1630 :
1631 : // Ensure the numbers of speeds defined in the parent object are equal to the numbers defined in coil objects
1632 11 : if (MSHeatPump(MSHPNum).HeatCoilType == MultiSpeedHeatingCoil) {
1633 9 : i = GetDXCoilNumberOfSpeeds(state, Alphas(10), Alphas(11), ErrorsFound);
1634 9 : if (MSHeatPump(MSHPNum).NumOfSpeedHeating != i) {
1635 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1636 0 : ShowContinueError(state,
1637 0 : "The " + cNumericFields(9) + " is not equal to the number defined in " + cAlphaFields(11) + " = " + Alphas(11));
1638 0 : ErrorsFound = true;
1639 : }
1640 3 : } else if (MSHeatPump(MSHPNum).HeatCoilType == Coil_HeatingElectric_MultiStage ||
1641 1 : MSHeatPump(MSHPNum).HeatCoilType == Coil_HeatingGas_MultiStage) {
1642 2 : i = GetHeatingCoilNumberOfStages(state, Alphas(10), Alphas(11), ErrorsFound);
1643 2 : if (MSHeatPump(MSHPNum).NumOfSpeedHeating != i) {
1644 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1645 0 : ShowContinueError(state,
1646 0 : "The " + cNumericFields(9) + " is not equal to the number defined in " + cAlphaFields(11) + " = " + Alphas(11));
1647 0 : ErrorsFound = true;
1648 : }
1649 : }
1650 11 : i = GetDXCoilNumberOfSpeeds(state, Alphas(12), Alphas(13), ErrorsFound);
1651 11 : if (MSHeatPump(MSHPNum).NumOfSpeedCooling != i) {
1652 0 : ShowSevereError(state, "For " + state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHPNum).Name + "\"");
1653 0 : ShowContinueError(state,
1654 0 : "The " + cNumericFields(10) + " is not equal to the number defined in " + cAlphaFields(13) + " = " + Alphas(13));
1655 0 : ErrorsFound = true;
1656 : }
1657 : }
1658 :
1659 11 : if (ErrorsFound) {
1660 0 : ShowFatalError(state,
1661 0 : std::string{RoutineName} + "Errors found in getting " + state.dataHVACMultiSpdHP->CurrentModuleObject +
1662 : " input. Preceding condition(s) causes termination.");
1663 : }
1664 : // End of multispeed heat pump
1665 :
1666 22 : for (MSHPNum = 1; MSHPNum <= state.dataHVACMultiSpdHP->NumMSHeatPumps; ++MSHPNum) {
1667 : // Setup Report Variables for MSHP Equipment
1668 44 : SetupOutputVariable(state,
1669 : "Unitary System Ancillary Electricity Rate",
1670 : OutputProcessor::Unit::W,
1671 11 : MSHeatPump(MSHPNum).AuxElecPower,
1672 : OutputProcessor::SOVTimeStepType::System,
1673 : OutputProcessor::SOVStoreType::Average,
1674 22 : MSHeatPump(MSHPNum).Name);
1675 44 : SetupOutputVariable(state,
1676 : "Unitary System Cooling Ancillary Electricity Energy",
1677 : OutputProcessor::Unit::J,
1678 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).AuxElecCoolConsumption,
1679 : OutputProcessor::SOVTimeStepType::System,
1680 : OutputProcessor::SOVStoreType::Summed,
1681 11 : MSHeatPump(MSHPNum).Name,
1682 : _,
1683 : "Electricity",
1684 : "Cooling",
1685 : _,
1686 11 : "System");
1687 44 : SetupOutputVariable(state,
1688 : "Unitary System Heating Ancillary Electricity Energy",
1689 : OutputProcessor::Unit::J,
1690 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).AuxElecHeatConsumption,
1691 : OutputProcessor::SOVTimeStepType::System,
1692 : OutputProcessor::SOVStoreType::Summed,
1693 11 : MSHeatPump(MSHPNum).Name,
1694 : _,
1695 : "Electricity",
1696 : "Heating",
1697 : _,
1698 11 : "System");
1699 44 : SetupOutputVariable(state,
1700 : "Unitary System Fan Part Load Ratio",
1701 : OutputProcessor::Unit::None,
1702 11 : MSHeatPump(MSHPNum).FanPartLoadRatio,
1703 : OutputProcessor::SOVTimeStepType::System,
1704 : OutputProcessor::SOVStoreType::Average,
1705 22 : MSHeatPump(MSHPNum).Name);
1706 44 : SetupOutputVariable(state,
1707 : "Unitary System Compressor Part Load Ratio",
1708 : OutputProcessor::Unit::None,
1709 11 : MSHeatPump(MSHPNum).CompPartLoadRatio,
1710 : OutputProcessor::SOVTimeStepType::System,
1711 : OutputProcessor::SOVStoreType::Average,
1712 22 : MSHeatPump(MSHPNum).Name);
1713 44 : SetupOutputVariable(state,
1714 : "Unitary System Electricity Rate",
1715 : OutputProcessor::Unit::W,
1716 11 : MSHeatPump(MSHPNum).ElecPower,
1717 : OutputProcessor::SOVTimeStepType::System,
1718 : OutputProcessor::SOVStoreType::Average,
1719 22 : MSHeatPump(MSHPNum).Name);
1720 44 : SetupOutputVariable(state,
1721 : "Unitary System Electricity Energy",
1722 : OutputProcessor::Unit::J,
1723 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).ElecPowerConsumption,
1724 : OutputProcessor::SOVTimeStepType::System,
1725 : OutputProcessor::SOVStoreType::Summed,
1726 22 : MSHeatPump(MSHPNum).Name);
1727 44 : SetupOutputVariable(state,
1728 : "Unitary System DX Coil Cycling Ratio",
1729 : OutputProcessor::Unit::None,
1730 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).CycRatio,
1731 : OutputProcessor::SOVTimeStepType::System,
1732 : OutputProcessor::SOVStoreType::Average,
1733 22 : MSHeatPump(MSHPNum).Name);
1734 44 : SetupOutputVariable(state,
1735 : "Unitary System DX Coil Speed Ratio",
1736 : OutputProcessor::Unit::None,
1737 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).SpeedRatio,
1738 : OutputProcessor::SOVTimeStepType::System,
1739 : OutputProcessor::SOVStoreType::Average,
1740 22 : MSHeatPump(MSHPNum).Name);
1741 44 : SetupOutputVariable(state,
1742 : "Unitary System DX Coil Speed Level",
1743 : OutputProcessor::Unit::None,
1744 11 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).SpeedNum,
1745 : OutputProcessor::SOVTimeStepType::System,
1746 : OutputProcessor::SOVStoreType::Average,
1747 22 : MSHeatPump(MSHPNum).Name);
1748 44 : SetupOutputVariable(state,
1749 : "Unitary System Total Cooling Rate",
1750 : OutputProcessor::Unit::W,
1751 11 : MSHeatPump(MSHPNum).TotCoolEnergyRate,
1752 : OutputProcessor::SOVTimeStepType::System,
1753 : OutputProcessor::SOVStoreType::Average,
1754 22 : MSHeatPump(MSHPNum).Name);
1755 44 : SetupOutputVariable(state,
1756 : "Unitary System Total Heating Rate",
1757 : OutputProcessor::Unit::W,
1758 11 : MSHeatPump(MSHPNum).TotHeatEnergyRate,
1759 : OutputProcessor::SOVTimeStepType::System,
1760 : OutputProcessor::SOVStoreType::Average,
1761 22 : MSHeatPump(MSHPNum).Name);
1762 44 : SetupOutputVariable(state,
1763 : "Unitary System Sensible Cooling Rate",
1764 : OutputProcessor::Unit::W,
1765 11 : MSHeatPump(MSHPNum).SensCoolEnergyRate,
1766 : OutputProcessor::SOVTimeStepType::System,
1767 : OutputProcessor::SOVStoreType::Average,
1768 22 : MSHeatPump(MSHPNum).Name);
1769 44 : SetupOutputVariable(state,
1770 : "Unitary System Sensible Heating Rate",
1771 : OutputProcessor::Unit::W,
1772 11 : MSHeatPump(MSHPNum).SensHeatEnergyRate,
1773 : OutputProcessor::SOVTimeStepType::System,
1774 : OutputProcessor::SOVStoreType::Average,
1775 22 : MSHeatPump(MSHPNum).Name);
1776 44 : SetupOutputVariable(state,
1777 : "Unitary System Latent Cooling Rate",
1778 : OutputProcessor::Unit::W,
1779 11 : MSHeatPump(MSHPNum).LatCoolEnergyRate,
1780 : OutputProcessor::SOVTimeStepType::System,
1781 : OutputProcessor::SOVStoreType::Average,
1782 22 : MSHeatPump(MSHPNum).Name);
1783 44 : SetupOutputVariable(state,
1784 : "Unitary System Latent Heating Rate",
1785 : OutputProcessor::Unit::W,
1786 11 : MSHeatPump(MSHPNum).LatHeatEnergyRate,
1787 : OutputProcessor::SOVTimeStepType::System,
1788 : OutputProcessor::SOVStoreType::Average,
1789 22 : MSHeatPump(MSHPNum).Name);
1790 11 : if (MSHeatPump(MSHPNum).HeatRecActive) {
1791 0 : SetupOutputVariable(state,
1792 : "Unitary System Heat Recovery Rate",
1793 : OutputProcessor::Unit::W,
1794 0 : MSHeatPump(MSHPNum).HeatRecoveryRate,
1795 : OutputProcessor::SOVTimeStepType::System,
1796 : OutputProcessor::SOVStoreType::Average,
1797 0 : MSHeatPump(MSHPNum).Name);
1798 0 : SetupOutputVariable(state,
1799 : "Unitary System Heat Recovery Inlet Temperature",
1800 : OutputProcessor::Unit::C,
1801 0 : MSHeatPump(MSHPNum).HeatRecoveryInletTemp,
1802 : OutputProcessor::SOVTimeStepType::System,
1803 : OutputProcessor::SOVStoreType::Average,
1804 0 : MSHeatPump(MSHPNum).Name);
1805 0 : SetupOutputVariable(state,
1806 : "Unitary System Heat Recovery Outlet Temperature",
1807 : OutputProcessor::Unit::C,
1808 0 : MSHeatPump(MSHPNum).HeatRecoveryOutletTemp,
1809 : OutputProcessor::SOVTimeStepType::System,
1810 : OutputProcessor::SOVStoreType::Average,
1811 0 : MSHeatPump(MSHPNum).Name);
1812 0 : SetupOutputVariable(state,
1813 : "Unitary System Heat Recovery Fluid Mass Flow Rate",
1814 : OutputProcessor::Unit::kg_s,
1815 0 : MSHeatPump(MSHPNum).HeatRecoveryMassFlowRate,
1816 : OutputProcessor::SOVTimeStepType::System,
1817 : OutputProcessor::SOVStoreType::Average,
1818 0 : MSHeatPump(MSHPNum).Name);
1819 0 : SetupOutputVariable(state,
1820 : "Unitary System Heat Recovery Energy",
1821 : OutputProcessor::Unit::J,
1822 0 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHPNum).HeatRecoveryEnergy,
1823 : OutputProcessor::SOVTimeStepType::System,
1824 : OutputProcessor::SOVStoreType::Summed,
1825 0 : MSHeatPump(MSHPNum).Name);
1826 : }
1827 : }
1828 11 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
1829 4 : for (int coilNUM = 1; coilNUM <= int(state.dataHVACMultiSpdHP->MSHeatPump.size()); ++coilNUM) {
1830 8 : SetupEMSActuator(state,
1831 : "Coil Speed Control",
1832 2 : state.dataHVACMultiSpdHP->MSHeatPump(coilNUM).Name,
1833 : "Unitary System DX Coil Speed Value",
1834 : "[]",
1835 2 : state.dataHVACMultiSpdHP->MSHeatPump(coilNUM).EMSOverrideCoilSpeedNumOn,
1836 6 : state.dataHVACMultiSpdHP->MSHeatPump(coilNUM).EMSOverrideCoilSpeedNumValue);
1837 : }
1838 : }
1839 : }
1840 :
1841 : //******************************************************************************
1842 :
1843 251050 : void InitMSHeatPump(EnergyPlusData &state,
1844 : int const MSHeatPumpNum, // Engine driven heat pump number
1845 : bool const FirstHVACIteration, // TRUE if first HVAC iteration
1846 : int const AirLoopNum, // air loop index
1847 : Real64 &QZnReq, // Heating/Cooling load for all served zones
1848 : Real64 &OnOffAirFlowRatio // Ratio of compressor ON airflow to average airflow over timestep
1849 : )
1850 : {
1851 :
1852 : // SUBROUTINE INFORMATION:
1853 : // AUTHOR: Lixing Gu, FSEC
1854 : // DATE WRITTEN: July 2007
1855 : // MODIFIED Bereket Nigusse, June 2010 - added a procedure to calculate supply air flow fraction
1856 : // through controlled zone
1857 : // RE-ENGINEERED na
1858 :
1859 : // PURPOSE OF THIS SUBROUTINE:
1860 : // This subroutine is for initializations of the multispeed heat pump (MSHP) components.
1861 :
1862 : // METHODOLOGY EMPLOYED:
1863 : // Uses the status flags to trigger initializations. The MSHP system is simulated with no load (coils off) to
1864 : // determine the outlet temperature. A setpoint temperature is calculated on FirstHVACIteration = TRUE.
1865 : // Once the setpoint is calculated, the inlet mass flow rate on FirstHVACIteration = FALSE is used to
1866 : // determine the bypass fraction. The simulation converges quickly on mass flow rate. If the zone
1867 : // temperatures float in the deadband, additional iterations are required to converge on mass flow rate.
1868 :
1869 : // Using/Aliasing
1870 : using DataSizing::AutoSize;
1871 : using Fans::GetFanIndex;
1872 : using Fans::GetFanVolFlow;
1873 : using FluidProperties::GetDensityGlycol;
1874 : using FluidProperties::GetSatDensityRefrig;
1875 :
1876 : using PlantUtilities::InitComponentNodes;
1877 : using PlantUtilities::ScanPlantLoopsForObject;
1878 : using PlantUtilities::SetComponentFlowRate;
1879 : using Psychrometrics::PsyRhoAirFnPbTdbW;
1880 : using ScheduleManager::GetCurrentScheduleValue;
1881 : using SteamCoils::SimulateSteamCoilComponents;
1882 251050 : auto &GetCoilMaxSteamFlowRate(SteamCoils::GetCoilMaxSteamFlowRate);
1883 251050 : auto &GetSteamCoilCapacity(SteamCoils::GetCoilCapacity);
1884 : using DXCoils::GetDXCoilAvailSchPtr;
1885 : using WaterCoils::GetCoilMaxWaterFlowRate;
1886 : using WaterCoils::SimulateWaterCoilComponents;
1887 :
1888 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1889 : static constexpr std::string_view RoutineName("InitMSHeatPump");
1890 : int InNode; // Inlet node number in MSHP loop
1891 : int OutNode; // Outlet node number in MSHP loop
1892 : int ZoneInNode; // Zone inlet node number in the controlled zone for MSHP
1893 : Real64 RhoAir; // Air density at InNode
1894 :
1895 : Real64 QSensUnitOut; // Output of MSHP system with coils off
1896 : Real64 PartLoadFrac; // Part-load ratio
1897 : int ZoneNum;
1898 : int i; // Index to speed
1899 : int NumOfSpeedCooling; // Number of speeds for cooling
1900 : int NumOfSpeedHeating; // Number of speeds for heating
1901 : Real64 DeltaMassRate; // Difference of mass flow rate between inlet node and system outlet node
1902 :
1903 251050 : int ZoneInSysIndex(0); // number of zone inlet nodes counter in an airloop
1904 251050 : int NumAirLoopZones(0); // number of zone inlet nodes in an air loop
1905 251050 : int ZoneInletNodeNum(0); // zone inlet nodes node number
1906 251050 : Real64 SumOfMassFlowRateMax(0.0); // the sum of mass flow rates at inlet to zones in an airloop
1907 251050 : Real64 CntrlZoneTerminalUnitMassFlowRateMax(0.0); // Maximum mass flow rate through controlled zone terminal unit
1908 : bool errFlag;
1909 : Real64 rho; // local fluid density
1910 : Real64 MdotHR; // local temporary for heat recovery fluid mass flow rate (kg/s)
1911 : Real64 ZoneLoadToCoolSPSequenced;
1912 : Real64 ZoneLoadToHeatSPSequenced;
1913 :
1914 251050 : bool ErrorsFound(false); // flag returned from mining call
1915 251050 : int SteamIndex(0); // index of steam quality for steam heating coil
1916 251050 : Real64 mdot(0.0); // local temporary for mass flow rate (kg/s)
1917 251050 : Real64 SteamDensity(0.0); // density of steam at 100C, used for steam heating coils
1918 251050 : Real64 CoilMaxVolFlowRate(0.0); // coil fluid maximum volume flow rate
1919 251050 : Real64 QActual(0.0); // coil actual capacity
1920 251050 : int CoilAvailSchPtr(0); // DX coil availability schedule pointer
1921 :
1922 251050 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
1923 :
1924 251050 : InNode = MSHeatPump(MSHeatPumpNum).AirInletNodeNum;
1925 251050 : OutNode = MSHeatPump(MSHeatPumpNum).AirOutletNodeNum;
1926 251050 : NumOfSpeedCooling = MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling;
1927 251050 : NumOfSpeedHeating = MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating;
1928 :
1929 251050 : ++state.dataHVACMultiSpdHP->AirLoopPass;
1930 251050 : if (state.dataHVACMultiSpdHP->AirLoopPass > 2) state.dataHVACMultiSpdHP->AirLoopPass = 1;
1931 :
1932 251050 : if (MSHeatPump(MSHeatPumpNum).MyPlantScantFlag && allocated(state.dataPlnt->PlantLoop)) {
1933 11 : if (MSHeatPump(MSHeatPumpNum).HeatRecActive) {
1934 0 : errFlag = false;
1935 0 : ScanPlantLoopsForObject(state,
1936 0 : MSHeatPump(MSHeatPumpNum).Name,
1937 : DataPlant::PlantEquipmentType::MultiSpeedHeatPumpRecovery,
1938 0 : MSHeatPump(MSHeatPumpNum).HRPlantLoc,
1939 : errFlag,
1940 : _,
1941 : _,
1942 : _,
1943 : _,
1944 : _);
1945 0 : if (errFlag) {
1946 0 : ShowFatalError(state, "InitMSHeatPump: Program terminated for previous conditions.");
1947 : }
1948 :
1949 0 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
1950 : } else {
1951 11 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
1952 : }
1953 11 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingWater) {
1954 0 : errFlag = false;
1955 0 : ScanPlantLoopsForObject(state,
1956 0 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
1957 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
1958 0 : MSHeatPump(MSHeatPumpNum).plantLoc,
1959 : errFlag,
1960 : _,
1961 : _,
1962 : _,
1963 : _,
1964 : _);
1965 0 : if (errFlag) {
1966 0 : ShowFatalError(state, "InitMSHeatPump: Program terminated for previous conditions.");
1967 : }
1968 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow =
1969 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHeatPumpNum).HeatCoilName, ErrorsFound);
1970 :
1971 0 : if (MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow > 0.0) {
1972 0 : rho = GetDensityGlycol(state,
1973 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).plantLoc.loopNum).FluidName,
1974 : DataGlobalConstants::HWInitConvTemp,
1975 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).plantLoc.loopNum).FluidIndex,
1976 : RoutineName);
1977 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow =
1978 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHeatPumpNum).HeatCoilName, ErrorsFound) * rho;
1979 : }
1980 : // fill outlet node for coil
1981 0 : MSHeatPump(MSHeatPumpNum).CoilOutletNode =
1982 0 : DataPlant::CompData::getPlantComponent(state, MSHeatPump(MSHeatPumpNum).plantLoc).NodeNumOut;
1983 0 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
1984 :
1985 11 : } else if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingSteam) {
1986 0 : errFlag = false;
1987 0 : ScanPlantLoopsForObject(state,
1988 0 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
1989 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
1990 0 : MSHeatPump(MSHeatPumpNum).plantLoc,
1991 : errFlag,
1992 : _,
1993 : _,
1994 : _,
1995 : _,
1996 : _);
1997 0 : if (errFlag) {
1998 0 : ShowFatalError(state, "InitMSHeatPump: Program terminated for previous conditions.");
1999 : }
2000 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow = GetCoilMaxSteamFlowRate(state, MSHeatPump(MSHeatPumpNum).HeatCoilNum, ErrorsFound);
2001 0 : if (MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow > 0.0) {
2002 0 : SteamIndex =
2003 : 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed // TODO: Why do you want to re-look this up?
2004 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, state.dataHVACMultiSpdHP->TempSteamIn, 1.0, SteamIndex, RoutineName);
2005 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow *= SteamDensity;
2006 : }
2007 :
2008 : // fill outlet node for coil
2009 0 : MSHeatPump(MSHeatPumpNum).CoilOutletNode =
2010 0 : DataPlant::CompData::getPlantComponent(state, MSHeatPump(MSHeatPumpNum).plantLoc).NodeNumOut;
2011 0 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
2012 : }
2013 11 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == Coil_HeatingWater) {
2014 0 : errFlag = false;
2015 0 : ScanPlantLoopsForObject(state,
2016 0 : MSHeatPump(MSHeatPumpNum).SuppHeatCoilName,
2017 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
2018 0 : MSHeatPump(MSHeatPumpNum).SuppPlantLoc,
2019 : errFlag,
2020 : _,
2021 : _,
2022 : _,
2023 : _,
2024 : _);
2025 0 : if (errFlag) {
2026 0 : ShowFatalError(state, "InitMSHeatPump: Program terminated for previous conditions.");
2027 : }
2028 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow =
2029 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHeatPumpNum).SuppHeatCoilName, ErrorsFound);
2030 :
2031 0 : if (MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow > 0.0) {
2032 0 : rho = GetDensityGlycol(state,
2033 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).SuppPlantLoc.loopNum).FluidName,
2034 : DataGlobalConstants::HWInitConvTemp,
2035 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).SuppPlantLoc.loopNum).FluidIndex,
2036 : RoutineName);
2037 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow =
2038 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHeatPumpNum).SuppHeatCoilName, ErrorsFound) * rho;
2039 : }
2040 : // fill outlet node for coil
2041 0 : MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode =
2042 0 : DataPlant::CompData::getPlantComponent(state, MSHeatPump(MSHeatPumpNum).SuppPlantLoc).NodeNumOut;
2043 0 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
2044 :
2045 11 : } else if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == Coil_HeatingSteam) {
2046 0 : errFlag = false;
2047 0 : ScanPlantLoopsForObject(state,
2048 0 : MSHeatPump(MSHeatPumpNum).SuppHeatCoilName,
2049 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
2050 0 : MSHeatPump(MSHeatPumpNum).SuppPlantLoc,
2051 : errFlag,
2052 : _,
2053 : _,
2054 : _,
2055 : _,
2056 : _);
2057 0 : if (errFlag) {
2058 0 : ShowFatalError(state, "InitMSHeatPump: Program terminated for previous conditions.");
2059 : }
2060 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow =
2061 0 : GetCoilMaxSteamFlowRate(state, MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum, ErrorsFound);
2062 0 : if (MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow > 0.0) {
2063 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
2064 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, state.dataHVACMultiSpdHP->TempSteamIn, 1.0, SteamIndex, RoutineName);
2065 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow *= SteamDensity;
2066 : }
2067 :
2068 : // fill outlet node for coil
2069 0 : MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode =
2070 0 : DataPlant::CompData::getPlantComponent(state, MSHeatPump(MSHeatPumpNum).SuppPlantLoc).NodeNumOut;
2071 0 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
2072 : }
2073 251039 : } else if (MSHeatPump(MSHeatPumpNum).MyPlantScantFlag && !state.dataGlobal->AnyPlantInModel) {
2074 0 : MSHeatPump(MSHeatPumpNum).MyPlantScantFlag = false;
2075 : }
2076 :
2077 251050 : if (!state.dataGlobal->SysSizingCalc && MSHeatPump(MSHeatPumpNum).MySizeFlag) {
2078 11 : GetFanVolFlow(state, MSHeatPump(MSHeatPumpNum).FanNum, MSHeatPump(MSHeatPumpNum).FanVolFlow);
2079 11 : SizeMSHeatPump(state, MSHeatPumpNum);
2080 11 : MSHeatPump(MSHeatPumpNum).FlowFraction = 1.0;
2081 11 : MSHeatPump(MSHeatPumpNum).MySizeFlag = false;
2082 : // Pass the fan cycling schedule index up to the air loop. Set the air loop unitary system flag.
2083 11 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CycFanSchedPtr = MSHeatPump(MSHeatPumpNum).FanSchedPtr;
2084 11 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
2085 11 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
2086 : false; // affects child coil sizing by allowing coil to size itself instead of parent telling coil what size to use
2087 11 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).FanOpMode = MSHeatPump(MSHeatPumpNum).OpMode;
2088 : }
2089 :
2090 251050 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && MSHeatPump(MSHeatPumpNum).MyCheckFlag) {
2091 11 : int zoneNum = MSHeatPump(MSHeatPumpNum).ControlZoneNum;
2092 11 : int zoneInlet = MSHeatPump(MSHeatPumpNum).ZoneInletNode;
2093 11 : int coolingPriority = 0;
2094 11 : int heatingPriority = 0;
2095 : // setup furnace zone equipment sequence information based on finding matching air terminal
2096 11 : if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex > 0) {
2097 11 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex)
2098 11 : .getPrioritiesForInletNode(state, zoneInlet, coolingPriority, heatingPriority);
2099 11 : MSHeatPump(MSHeatPumpNum).ZoneSequenceCoolingNum = coolingPriority;
2100 11 : MSHeatPump(MSHeatPumpNum).ZoneSequenceHeatingNum = heatingPriority;
2101 : }
2102 11 : MSHeatPump(MSHeatPumpNum).MyCheckFlag = false;
2103 11 : if (MSHeatPump(MSHeatPumpNum).ZoneSequenceCoolingNum == 0 || MSHeatPump(MSHeatPumpNum).ZoneSequenceHeatingNum == 0) {
2104 0 : ShowSevereError(state,
2105 0 : "AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed, \"" + MSHeatPump(MSHeatPumpNum).Name +
2106 0 : "\": Airloop air terminal in the zone equipment list for zone = " + MSHeatPump(MSHeatPumpNum).ControlZoneName +
2107 : " not found or is not allowed Zone Equipment Cooling or Heating Sequence = 0.");
2108 0 : ShowFatalError(state,
2109 : "Subroutine InitMSHeatPump: Errors found in getting AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed input. Preceding "
2110 : "condition(s) causes termination.");
2111 : }
2112 : }
2113 :
2114 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
2115 251050 : NumAirLoopZones =
2116 251050 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
2117 251050 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && MSHeatPump(MSHeatPumpNum).MyFlowFracFlag) {
2118 11 : state.dataHVACMultiSpdHP->FlowFracFlagReady = true;
2119 34 : for (ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
2120 : // zone inlet nodes for cooling
2121 23 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
2122 23 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
2123 : // the data structure for the zones inlet nodes has not been filled
2124 0 : state.dataHVACMultiSpdHP->FlowFracFlagReady = false;
2125 : }
2126 : }
2127 : // zone inlet nodes for heating
2128 23 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
2129 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
2130 : // the data structure for the zones inlet nodes has not been filled
2131 0 : state.dataHVACMultiSpdHP->FlowFracFlagReady = false;
2132 : }
2133 : }
2134 : }
2135 : }
2136 251050 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataHVACMultiSpdHP->FlowFracFlagReady) {
2137 251050 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
2138 708180 : for (ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
2139 457130 : ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
2140 457130 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
2141 457130 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == MSHeatPump(MSHeatPumpNum).ControlZoneNum) {
2142 251050 : CntrlZoneTerminalUnitMassFlowRateMax = state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
2143 : }
2144 : }
2145 251050 : if (SumOfMassFlowRateMax != 0.0 && MSHeatPump(MSHeatPumpNum).MyFlowFracFlag) {
2146 11 : if (CntrlZoneTerminalUnitMassFlowRateMax >= SmallAirVolFlow) {
2147 11 : MSHeatPump(MSHeatPumpNum).FlowFraction = CntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
2148 : } else {
2149 0 : ShowSevereError(state, state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHeatPumpNum).Name);
2150 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
2151 : }
2152 44 : BaseSizer::reportSizerOutput(state,
2153 11 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2154 11 : MSHeatPump(MSHeatPumpNum).Name,
2155 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
2156 22 : MSHeatPump(MSHeatPumpNum).FlowFraction);
2157 11 : MSHeatPump(MSHeatPumpNum).MyFlowFracFlag = false;
2158 : }
2159 : }
2160 :
2161 : // Do the Begin Environment initializations
2162 251050 : if (state.dataGlobal->BeginEnvrnFlag && MSHeatPump(MSHeatPumpNum).MyEnvrnFlag) {
2163 66 : RhoAir = state.dataEnvrn->StdRhoAir;
2164 : // set the mass flow rates from the input volume flow rates
2165 270 : for (i = 1; i <= NumOfSpeedCooling; ++i) {
2166 204 : MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(i) = RhoAir * MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i);
2167 : }
2168 234 : for (i = 1; i <= NumOfSpeedHeating; ++i) {
2169 168 : MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(i) = RhoAir * MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i);
2170 : }
2171 66 : MSHeatPump(MSHeatPumpNum).IdleMassFlowRate = RhoAir * MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate;
2172 : // set the node max and min mass flow rates
2173 66 : state.dataLoopNodes->Node(InNode).MassFlowRateMax =
2174 66 : max(MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(NumOfSpeedCooling), MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(NumOfSpeedHeating));
2175 66 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail =
2176 66 : max(MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(NumOfSpeedCooling), MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(NumOfSpeedHeating));
2177 66 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
2178 66 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
2179 66 : state.dataLoopNodes->Node(OutNode) = state.dataLoopNodes->Node(InNode);
2180 66 : MSHeatPump(MSHeatPumpNum).LoadLoss = 0.0;
2181 :
2182 66 : if ((MSHeatPump(MSHeatPumpNum).HeatRecActive) && (!MSHeatPump(MSHeatPumpNum).MyPlantScantFlag)) {
2183 :
2184 0 : rho = GetDensityGlycol(state,
2185 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).HRPlantLoc.loopNum).FluidName,
2186 : DataGlobalConstants::HWInitConvTemp,
2187 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).HRPlantLoc.loopNum).FluidIndex,
2188 : RoutineName);
2189 :
2190 0 : MSHeatPump(MSHeatPumpNum).DesignHeatRecMassFlowRate = MSHeatPump(MSHeatPumpNum).DesignHeatRecFlowRate * rho;
2191 :
2192 0 : InitComponentNodes(state,
2193 : 0.0,
2194 0 : MSHeatPump(MSHeatPumpNum).DesignHeatRecMassFlowRate,
2195 0 : MSHeatPump(MSHeatPumpNum).HeatRecInletNodeNum,
2196 0 : MSHeatPump(MSHeatPumpNum).HeatRecOutletNodeNum);
2197 : }
2198 66 : if (MSHeatPump(MSHeatPumpNum).CoilControlNode > 0) {
2199 0 : if (MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow == AutoSize) {
2200 0 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingWater) {
2201 0 : SimulateWaterCoilComponents(
2202 0 : state, MSHeatPump(MSHeatPumpNum).HeatCoilName, FirstHVACIteration, MSHeatPump(MSHeatPumpNum).HeatCoilNum);
2203 :
2204 0 : CoilMaxVolFlowRate =
2205 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHeatPumpNum).HeatCoilName, ErrorsFound);
2206 0 : if (CoilMaxVolFlowRate != AutoSize) {
2207 0 : rho = GetDensityGlycol(state,
2208 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).plantLoc.loopNum).FluidName,
2209 : DataGlobalConstants::HWInitConvTemp,
2210 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).plantLoc.loopNum).FluidIndex,
2211 : RoutineName);
2212 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow = CoilMaxVolFlowRate * rho;
2213 : }
2214 0 : InitComponentNodes(state,
2215 : 0.0,
2216 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow,
2217 0 : MSHeatPump(MSHeatPumpNum).CoilControlNode,
2218 0 : MSHeatPump(MSHeatPumpNum).CoilOutletNode);
2219 : }
2220 0 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingSteam) {
2221 :
2222 0 : SimulateSteamCoilComponents(state,
2223 0 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
2224 : FirstHVACIteration,
2225 0 : MSHeatPump(MSHeatPumpNum).HeatCoilNum,
2226 : 1.0,
2227 : QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
2228 0 : CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(state, MSHeatPump(MSHeatPumpNum).HeatCoilNum, ErrorsFound);
2229 :
2230 0 : if (CoilMaxVolFlowRate != AutoSize) {
2231 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
2232 0 : SteamDensity =
2233 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataHVACMultiSpdHP->TempSteamIn, 1.0, SteamIndex, RoutineName);
2234 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
2235 : }
2236 0 : InitComponentNodes(state,
2237 : 0.0,
2238 0 : MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow,
2239 0 : MSHeatPump(MSHeatPumpNum).CoilControlNode,
2240 0 : MSHeatPump(MSHeatPumpNum).CoilOutletNode);
2241 : }
2242 : }
2243 : }
2244 66 : if (MSHeatPump(MSHeatPumpNum).SuppCoilControlNode > 0) {
2245 0 : if (MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow == AutoSize) {
2246 0 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == Coil_HeatingWater) {
2247 0 : SimulateWaterCoilComponents(
2248 0 : state, MSHeatPump(MSHeatPumpNum).SuppHeatCoilName, FirstHVACIteration, MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum);
2249 :
2250 0 : CoilMaxVolFlowRate =
2251 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", MSHeatPump(MSHeatPumpNum).SuppHeatCoilName, ErrorsFound);
2252 0 : if (CoilMaxVolFlowRate != AutoSize) {
2253 0 : rho = GetDensityGlycol(state,
2254 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).SuppPlantLoc.loopNum).FluidName,
2255 : DataGlobalConstants::HWInitConvTemp,
2256 0 : state.dataPlnt->PlantLoop(MSHeatPump(MSHeatPumpNum).SuppPlantLoc.loopNum).FluidIndex,
2257 : RoutineName);
2258 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
2259 : }
2260 0 : InitComponentNodes(state,
2261 : 0.0,
2262 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow,
2263 0 : MSHeatPump(MSHeatPumpNum).SuppCoilControlNode,
2264 0 : MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode);
2265 : }
2266 0 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == Coil_HeatingSteam) {
2267 :
2268 0 : SimulateSteamCoilComponents(state,
2269 0 : MSHeatPump(MSHeatPumpNum).SuppHeatCoilName,
2270 : FirstHVACIteration,
2271 0 : MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum,
2272 : 1.0,
2273 : QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
2274 0 : CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(state, MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum, ErrorsFound);
2275 :
2276 0 : if (CoilMaxVolFlowRate != AutoSize) {
2277 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
2278 0 : SteamDensity =
2279 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataHVACMultiSpdHP->TempSteamIn, 1.0, SteamIndex, RoutineName);
2280 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
2281 : }
2282 0 : InitComponentNodes(state,
2283 : 0.0,
2284 0 : MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow,
2285 0 : MSHeatPump(MSHeatPumpNum).SuppCoilControlNode,
2286 0 : MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode);
2287 : }
2288 : }
2289 : }
2290 66 : MSHeatPump(MSHeatPumpNum).MyEnvrnFlag = false;
2291 : } // end one time inits
2292 :
2293 251050 : if (!state.dataGlobal->BeginEnvrnFlag) {
2294 250456 : MSHeatPump(MSHeatPumpNum).MyEnvrnFlag = true;
2295 : }
2296 :
2297 : // IF MSHP system was not autosized and the fan is autosized, check that fan volumetric flow rate is greater than MSHP flow rates
2298 251050 : if (!state.dataGlobal->DoingSizing && MSHeatPump(MSHeatPumpNum).CheckFanFlow) {
2299 11 : state.dataHVACMultiSpdHP->CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed";
2300 11 : GetFanVolFlow(state, MSHeatPump(MSHeatPumpNum).FanNum, MSHeatPump(MSHeatPumpNum).FanVolFlow);
2301 11 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow != AutoSize) {
2302 : // Check fan versus system supply air flow rates
2303 11 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow < MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(NumOfSpeedCooling)) {
2304 0 : ShowWarningError(state,
2305 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the MSHP system air flow rate when cooling is "
2306 : "required ({:.7T}).",
2307 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2308 0 : MSHeatPump(MSHeatPumpNum).FanVolFlow,
2309 0 : MSHeatPump(MSHeatPumpNum).FanName,
2310 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(NumOfSpeedCooling)));
2311 0 : ShowContinueError(
2312 : state, " The MSHP system flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
2313 0 : ShowContinueError(state, " Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHeatPumpNum).Name);
2314 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(NumOfSpeedCooling) = MSHeatPump(MSHeatPumpNum).FanVolFlow;
2315 : // Check flow rates in other speeds and ensure flow rates are not above the max flow rate
2316 0 : for (i = NumOfSpeedCooling - 1; i >= 1; --i) {
2317 0 : if (MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) > MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i + 1)) {
2318 0 : ShowContinueError(state,
2319 0 : format(" The MSHP system flow rate when cooling is required is reset to the flow rate at higher speed "
2320 : "and the simulation continues at Speed{}.",
2321 0 : i));
2322 0 : ShowContinueError(state,
2323 0 : " Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHeatPumpNum).Name);
2324 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) = MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i + 1);
2325 : }
2326 : }
2327 : }
2328 11 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow < MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(NumOfSpeedHeating)) {
2329 0 : ShowWarningError(state,
2330 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the MSHP system air flow rate when heating is "
2331 : "required ({:.7T}).",
2332 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2333 0 : MSHeatPump(MSHeatPumpNum).FanVolFlow,
2334 0 : MSHeatPump(MSHeatPumpNum).FanName,
2335 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(NumOfSpeedHeating)));
2336 0 : ShowContinueError(
2337 : state, " The MSHP system flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
2338 0 : ShowContinueError(state, " Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHeatPumpNum).Name);
2339 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(NumOfSpeedHeating) = MSHeatPump(MSHeatPumpNum).FanVolFlow;
2340 0 : for (i = NumOfSpeedHeating - 1; i >= 1; --i) {
2341 0 : if (MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) > MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i + 1)) {
2342 0 : ShowContinueError(state,
2343 0 : format(" The MSHP system flow rate when heating is required is reset to the flow rate at higher speed "
2344 : "and the simulation continues at Speed{}.",
2345 0 : i));
2346 0 : ShowContinueError(
2347 0 : state, " Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " system = " + MSHeatPump(MSHeatPumpNum).Name);
2348 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) = MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i + 1);
2349 : }
2350 : }
2351 : }
2352 11 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow < MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate &&
2353 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate != 0.0) {
2354 0 : ShowWarningError(state,
2355 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the MSHP system air flow rate when no heating "
2356 : "or cooling is needed ({:.7T}).",
2357 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2358 0 : MSHeatPump(MSHeatPumpNum).FanVolFlow,
2359 0 : MSHeatPump(MSHeatPumpNum).FanName,
2360 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate));
2361 0 : ShowContinueError(state,
2362 : " The MSHP system flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
2363 : "simulation continues.");
2364 0 : ShowContinueError(state, " Occurs in " + state.dataHVACMultiSpdHP->CurrentModuleObject + " = " + MSHeatPump(MSHeatPumpNum).Name);
2365 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate = MSHeatPump(MSHeatPumpNum).FanVolFlow;
2366 : }
2367 11 : RhoAir = state.dataEnvrn->StdRhoAir;
2368 : // set the mass flow rates from the reset volume flow rates
2369 45 : for (i = 1; i <= NumOfSpeedCooling; ++i) {
2370 34 : MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(i) = RhoAir * MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i);
2371 34 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow > 0.0) {
2372 34 : MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(i) =
2373 34 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) / MSHeatPump(MSHeatPumpNum).FanVolFlow;
2374 : }
2375 : }
2376 39 : for (i = 1; i <= NumOfSpeedHeating; ++i) {
2377 28 : MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(i) = RhoAir * MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i);
2378 28 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow > 0.0) {
2379 28 : MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(i) =
2380 28 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) / MSHeatPump(MSHeatPumpNum).FanVolFlow;
2381 : }
2382 : }
2383 11 : MSHeatPump(MSHeatPumpNum).IdleMassFlowRate = RhoAir * MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate;
2384 11 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow > 0.0) {
2385 11 : MSHeatPump(MSHeatPumpNum).IdleSpeedRatio = MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate / MSHeatPump(MSHeatPumpNum).FanVolFlow;
2386 : }
2387 : // set the node max and min mass flow rates based on reset volume flow rates
2388 11 : state.dataLoopNodes->Node(InNode).MassFlowRateMax =
2389 11 : max(MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(NumOfSpeedCooling), MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(NumOfSpeedHeating));
2390 11 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail =
2391 11 : max(MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(NumOfSpeedCooling), MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(NumOfSpeedHeating));
2392 11 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
2393 11 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
2394 11 : state.dataLoopNodes->Node(OutNode) = state.dataLoopNodes->Node(InNode);
2395 11 : MSHeatPump(MSHeatPumpNum).CheckFanFlow = false;
2396 : }
2397 : }
2398 :
2399 251050 : if (MSHeatPump(MSHeatPumpNum).FanSchedPtr > 0) {
2400 251050 : if (GetCurrentScheduleValue(state, MSHeatPump(MSHeatPumpNum).FanSchedPtr) == 0.0) {
2401 192078 : MSHeatPump(MSHeatPumpNum).OpMode = CycFanCycCoil;
2402 : } else {
2403 58972 : MSHeatPump(MSHeatPumpNum).OpMode = ContFanCycCoil;
2404 : }
2405 : }
2406 :
2407 : // Calcuate air distribution losses
2408 251050 : if (!FirstHVACIteration && state.dataHVACMultiSpdHP->AirLoopPass == 1) {
2409 52072 : ZoneInNode = MSHeatPump(MSHeatPumpNum).ZoneInletNode;
2410 104144 : DeltaMassRate = state.dataLoopNodes->Node(OutNode).MassFlowRate -
2411 52072 : state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / MSHeatPump(MSHeatPumpNum).FlowFraction;
2412 52072 : if (DeltaMassRate < 0.0) DeltaMassRate = 0.0;
2413 52072 : Real64 MassFlowRate(0.0); // parent mass flow rate
2414 52072 : Real64 LatentOutput(0.0); // latent output rate
2415 52072 : Real64 TotalOutput(0.0); // total output rate
2416 52072 : Real64 SensibleOutputDelta(0.0); // delta sensible output rate
2417 52072 : Real64 LatentOutputDelta(0.0); // delta latent output rate
2418 52072 : Real64 TotalOutputDelta(0.0); // delta total output rate
2419 52072 : MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / MSHeatPump(MSHeatPumpNum).FlowFraction;
2420 52072 : Real64 MinHumRat = state.dataLoopNodes->Node(ZoneInNode).HumRat;
2421 52072 : if (state.dataLoopNodes->Node(OutNode).Temp < state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).NodeNumOfControlledZone).Temp)
2422 19008 : MinHumRat = state.dataLoopNodes->Node(OutNode).HumRat;
2423 156216 : CalcZoneSensibleLatentOutput(MassFlowRate,
2424 52072 : state.dataLoopNodes->Node(OutNode).Temp,
2425 : MinHumRat,
2426 52072 : state.dataLoopNodes->Node(ZoneInNode).Temp,
2427 : MinHumRat,
2428 52072 : MSHeatPump(MSHeatPumpNum).LoadLoss,
2429 : LatentOutput,
2430 : TotalOutput);
2431 104144 : CalcZoneSensibleLatentOutput(DeltaMassRate,
2432 52072 : state.dataLoopNodes->Node(OutNode).Temp,
2433 : MinHumRat,
2434 52072 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).NodeNumOfControlledZone).Temp,
2435 : MinHumRat,
2436 : SensibleOutputDelta,
2437 : LatentOutputDelta,
2438 : TotalOutputDelta);
2439 52072 : MSHeatPump(MSHeatPumpNum).LoadLoss = MSHeatPump(MSHeatPumpNum).LoadLoss + SensibleOutputDelta;
2440 52072 : if (std::abs(MSHeatPump(MSHeatPumpNum).LoadLoss) < 1.0e-6) MSHeatPump(MSHeatPumpNum).LoadLoss = 0.0;
2441 : }
2442 :
2443 : // Returns load only for zones requesting cooling (heating). If in deadband, Qzoneload = 0.
2444 251050 : ZoneNum = MSHeatPump(MSHeatPumpNum).ControlZoneNum;
2445 251050 : if ((MSHeatPump(MSHeatPumpNum).ZoneSequenceCoolingNum > 0) && (MSHeatPump(MSHeatPumpNum).ZoneSequenceHeatingNum > 0)) {
2446 502100 : ZoneLoadToCoolSPSequenced = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(MSHeatPump(MSHeatPumpNum).ControlZoneNum)
2447 251050 : .SequencedOutputRequiredToCoolingSP(MSHeatPump(MSHeatPumpNum).ZoneSequenceCoolingNum);
2448 502100 : ZoneLoadToHeatSPSequenced = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(MSHeatPump(MSHeatPumpNum).ControlZoneNum)
2449 251050 : .SequencedOutputRequiredToHeatingSP(MSHeatPump(MSHeatPumpNum).ZoneSequenceHeatingNum);
2450 251050 : if (ZoneLoadToHeatSPSequenced > SmallLoad && ZoneLoadToCoolSPSequenced > SmallLoad) {
2451 109908 : QZnReq = ZoneLoadToHeatSPSequenced;
2452 141142 : } else if (ZoneLoadToHeatSPSequenced < (-1.0 * SmallLoad) && ZoneLoadToCoolSPSequenced < (-1.0 * SmallLoad)) {
2453 102790 : QZnReq = ZoneLoadToCoolSPSequenced;
2454 38352 : } else if (ZoneLoadToHeatSPSequenced <= (-1.0 * SmallLoad) && ZoneLoadToCoolSPSequenced >= SmallLoad) {
2455 36548 : QZnReq = 0.0;
2456 : } else {
2457 1804 : QZnReq = 0.0; // Autodesk:Init Case added to prevent use of uninitialized value (occurred in MultiSpeedACFurnace example)
2458 : }
2459 251050 : QZnReq /= MSHeatPump(MSHeatPumpNum).FlowFraction;
2460 : } else {
2461 0 : QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputRequired / MSHeatPump(MSHeatPumpNum).FlowFraction;
2462 : }
2463 251050 : if (state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) QZnReq = 0.0;
2464 :
2465 251050 : if (QZnReq > SmallLoad) {
2466 104900 : MSHeatPump(MSHeatPumpNum).HeatCoolMode = ModeOfOperation::HeatingMode;
2467 146150 : } else if (QZnReq < (-1.0 * SmallLoad)) {
2468 100962 : MSHeatPump(MSHeatPumpNum).HeatCoolMode = ModeOfOperation::CoolingMode;
2469 : } else {
2470 45188 : MSHeatPump(MSHeatPumpNum).HeatCoolMode = ModeOfOperation::Invalid;
2471 : }
2472 :
2473 : // Determine the staged status
2474 251050 : if (allocated(state.dataZoneCtrls->StageZoneLogic)) {
2475 20164 : if (state.dataZoneCtrls->StageZoneLogic(ZoneNum)) {
2476 20164 : MSHeatPump(MSHeatPumpNum).Staged = true;
2477 20164 : MSHeatPump(MSHeatPumpNum).StageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).StageNum;
2478 : } else {
2479 0 : if (MSHeatPump(MSHeatPumpNum).MyStagedFlag) {
2480 0 : ShowWarningError(state,
2481 : "ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to this "
2482 : "AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed object = ");
2483 0 : ShowContinueError(state, MSHeatPump(MSHeatPumpNum).Name + ". Please make correction. Simulation continues...");
2484 0 : MSHeatPump(MSHeatPumpNum).MyStagedFlag = false;
2485 : }
2486 : }
2487 : }
2488 : // Set the inlet node mass flow rate
2489 251050 : if (MSHeatPump(MSHeatPumpNum).OpMode == ContFanCycCoil) {
2490 : // constant fan mode
2491 58972 : if (QZnReq > SmallLoad && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
2492 29362 : state.dataHVACMultiSpdHP->CompOnMassFlow = MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(1);
2493 29362 : state.dataHVACMultiSpdHP->CompOnFlowRatio = MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(1);
2494 29362 : MSHeatPump(MSHeatPumpNum).LastMode = ModeOfOperation::HeatingMode;
2495 29610 : } else if (QZnReq < (-1.0 * SmallLoad) && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
2496 29410 : state.dataHVACMultiSpdHP->CompOnMassFlow = MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(1);
2497 29410 : state.dataHVACMultiSpdHP->CompOnFlowRatio = MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(1);
2498 29410 : MSHeatPump(MSHeatPumpNum).LastMode = ModeOfOperation::CoolingMode;
2499 : } else {
2500 200 : state.dataHVACMultiSpdHP->CompOnMassFlow = MSHeatPump(MSHeatPumpNum).IdleMassFlowRate;
2501 200 : state.dataHVACMultiSpdHP->CompOnFlowRatio = MSHeatPump(MSHeatPumpNum).IdleSpeedRatio;
2502 : }
2503 58972 : state.dataHVACMultiSpdHP->CompOffMassFlow = MSHeatPump(MSHeatPumpNum).IdleMassFlowRate;
2504 58972 : state.dataHVACMultiSpdHP->CompOffFlowRatio = MSHeatPump(MSHeatPumpNum).IdleSpeedRatio;
2505 : } else {
2506 : // cycling fan mode
2507 192078 : if (QZnReq > SmallLoad && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
2508 75538 : state.dataHVACMultiSpdHP->CompOnMassFlow = MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(1);
2509 75538 : state.dataHVACMultiSpdHP->CompOnFlowRatio = MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(1);
2510 116540 : } else if (QZnReq < (-1.0 * SmallLoad) && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
2511 71552 : state.dataHVACMultiSpdHP->CompOnMassFlow = MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(1);
2512 71552 : state.dataHVACMultiSpdHP->CompOnFlowRatio = MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(1);
2513 : } else {
2514 44988 : state.dataHVACMultiSpdHP->CompOnMassFlow = 0.0;
2515 44988 : state.dataHVACMultiSpdHP->CompOnFlowRatio = 0.0;
2516 : }
2517 192078 : state.dataHVACMultiSpdHP->CompOffMassFlow = 0.0;
2518 192078 : state.dataHVACMultiSpdHP->CompOffFlowRatio = 0.0;
2519 : }
2520 :
2521 : // Set the inlet node mass flow rate
2522 251050 : if (GetCurrentScheduleValue(state, MSHeatPump(MSHeatPumpNum).AvaiSchedPtr) > 0.0 && state.dataHVACMultiSpdHP->CompOnMassFlow != 0.0) {
2523 187106 : OnOffAirFlowRatio = 1.0;
2524 187106 : if (FirstHVACIteration) {
2525 65686 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirInletNodeNum).MassFlowRate = state.dataHVACMultiSpdHP->CompOnMassFlow;
2526 65686 : PartLoadFrac = 0.0;
2527 : } else {
2528 121420 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode != ModeOfOperation::Invalid) {
2529 121320 : PartLoadFrac = 1.0;
2530 : } else {
2531 100 : PartLoadFrac = 0.0;
2532 : }
2533 : }
2534 : } else {
2535 63944 : PartLoadFrac = 0.0;
2536 63944 : state.dataLoopNodes->Node(InNode).MassFlowRate = 0.0;
2537 63944 : state.dataLoopNodes->Node(OutNode).MassFlowRate = 0.0;
2538 63944 : state.dataLoopNodes->Node(OutNode).MassFlowRateMaxAvail = 0.0;
2539 63944 : OnOffAirFlowRatio = 1.0;
2540 : }
2541 :
2542 : // Check availability of DX coils
2543 251050 : if (GetCurrentScheduleValue(state, MSHeatPump(MSHeatPumpNum).AvaiSchedPtr) > 0.0) {
2544 226554 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::CoolingMode) {
2545 164012 : CoilAvailSchPtr = GetDXCoilAvailSchPtr( // TODO: Why isn't this stored on the struct?
2546 : state,
2547 : "Coil:Cooling:DX:MultiSpeed",
2548 82006 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
2549 : ErrorsFound,
2550 82006 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex);
2551 82006 : if (ErrorsFound) {
2552 0 : ShowFatalError(state, "InitMSHeatPump, The previous error causes termination.");
2553 : }
2554 82006 : if (GetCurrentScheduleValue(state, CoilAvailSchPtr) == 0.0) {
2555 0 : if (MSHeatPump(MSHeatPumpNum).CoolCountAvail == 0) {
2556 0 : ++MSHeatPump(MSHeatPumpNum).CoolCountAvail;
2557 0 : ShowWarningError(state,
2558 0 : MSHeatPump(MSHeatPumpNum).Name +
2559 0 : " is ready to perform cooling, but its DX cooling coil = " + MSHeatPump(MSHeatPumpNum).DXCoolCoilName +
2560 0 : " is not available at Available Schedule = " + GetScheduleName(state, CoilAvailSchPtr) + '.');
2561 0 : ShowContinueErrorTimeStamp(state,
2562 0 : format("Availability schedule returned={:.1R}", GetCurrentScheduleValue(state, CoilAvailSchPtr)));
2563 : } else {
2564 0 : ++MSHeatPump(MSHeatPumpNum).CoolCountAvail;
2565 0 : ShowRecurringWarningErrorAtEnd(state,
2566 0 : MSHeatPump(MSHeatPumpNum).Name + ": Cooling coil is still not available ...",
2567 0 : MSHeatPump(MSHeatPumpNum).CoolIndexAvail,
2568 0 : GetCurrentScheduleValue(state, CoilAvailSchPtr),
2569 0 : GetCurrentScheduleValue(state, CoilAvailSchPtr));
2570 : }
2571 : }
2572 : }
2573 331454 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::HeatingMode &&
2574 104900 : MSHeatPump(MSHeatPumpNum).HeatCoilType == MultiSpeedHeatingCoil) {
2575 160876 : CoilAvailSchPtr = GetDXCoilAvailSchPtr(state,
2576 : "Coil:Heating:DX:MultiSpeed",
2577 80438 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
2578 : ErrorsFound,
2579 80438 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex);
2580 80438 : if (ErrorsFound) {
2581 0 : ShowFatalError(state, "InitMSHeatPump, The previous error causes termination.");
2582 : }
2583 80438 : if (GetCurrentScheduleValue(state, CoilAvailSchPtr) == 0.0) {
2584 0 : if (MSHeatPump(MSHeatPumpNum).HeatCountAvail == 0) {
2585 0 : ++MSHeatPump(MSHeatPumpNum).HeatCountAvail;
2586 0 : ShowWarningError(state,
2587 0 : MSHeatPump(MSHeatPumpNum).Name +
2588 0 : " is ready to perform heating, but its DX heating coil = " + MSHeatPump(MSHeatPumpNum).DXCoolCoilName +
2589 0 : " is not available at Available Schedule = " + GetScheduleName(state, CoilAvailSchPtr) + '.');
2590 0 : ShowContinueErrorTimeStamp(state,
2591 0 : format("Availability schedule returned={:.1R}", GetCurrentScheduleValue(state, CoilAvailSchPtr)));
2592 : } else {
2593 0 : ++MSHeatPump(MSHeatPumpNum).HeatCountAvail;
2594 0 : ShowRecurringWarningErrorAtEnd(state,
2595 0 : MSHeatPump(MSHeatPumpNum).Name + ": Heating coil is still not available ...",
2596 0 : MSHeatPump(MSHeatPumpNum).HeatIndexAvail,
2597 0 : GetCurrentScheduleValue(state, CoilAvailSchPtr),
2598 0 : GetCurrentScheduleValue(state, CoilAvailSchPtr));
2599 : }
2600 : }
2601 : }
2602 : }
2603 :
2604 251050 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).CycRatio = 0.0;
2605 251050 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedRatio = 0.0;
2606 251050 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedNum = 0;
2607 :
2608 251050 : CalcMSHeatPump(state,
2609 : MSHeatPumpNum,
2610 : FirstHVACIteration,
2611 : DataHVACGlobals::CompressorOperation::On,
2612 : 1,
2613 : 0.0,
2614 : PartLoadFrac,
2615 : QSensUnitOut,
2616 : QZnReq,
2617 : OnOffAirFlowRatio,
2618 251050 : state.dataHVACMultiSpdHP->SupHeaterLoad);
2619 :
2620 251050 : auto &e = MSHeatPump(MSHeatPumpNum);
2621 : {
2622 251050 : e.TotHeatEnergyRate = 0.0;
2623 251050 : e.SensHeatEnergyRate = 0.0;
2624 251050 : e.LatHeatEnergyRate = 0.0;
2625 251050 : e.TotCoolEnergyRate = 0.0;
2626 251050 : e.SensCoolEnergyRate = 0.0;
2627 251050 : e.LatCoolEnergyRate = 0.0;
2628 : }
2629 : // If unit is scheduled OFF, setpoint is equal to inlet node temperature.
2630 : //!!LKL Discrepancy with < 0
2631 251050 : if (GetCurrentScheduleValue(state, MSHeatPump(MSHeatPumpNum).AvaiSchedPtr) == 0.0) {
2632 24496 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
2633 24496 : return;
2634 : }
2635 :
2636 413660 : if ((MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::Invalid && MSHeatPump(MSHeatPumpNum).OpMode == CycFanCycCoil) ||
2637 187106 : state.dataHVACMultiSpdHP->CompOnMassFlow == 0.0) {
2638 39448 : QZnReq = 0.0;
2639 39448 : PartLoadFrac = 0.0;
2640 39448 : state.dataLoopNodes->Node(InNode).MassFlowRate = 0.0;
2641 39448 : state.dataLoopNodes->Node(OutNode).MassFlowRateMaxAvail = 0.0;
2642 : }
2643 226554 : MSHeatPump(MSHeatPumpNum).LoadMet = 0.0;
2644 226554 : SetAverageAirFlow(state, MSHeatPumpNum, PartLoadFrac, OnOffAirFlowRatio);
2645 :
2646 : // Init maximum available Heat Recovery flow rate
2647 226554 : if ((MSHeatPump(MSHeatPumpNum).HeatRecActive) && (!MSHeatPump(MSHeatPumpNum).MyPlantScantFlag)) {
2648 0 : if (PartLoadFrac > 0.0) {
2649 0 : if (FirstHVACIteration) {
2650 0 : MdotHR = MSHeatPump(MSHeatPumpNum).DesignHeatRecMassFlowRate;
2651 : } else {
2652 0 : if (MSHeatPump(MSHeatPumpNum).HeatRecoveryMassFlowRate > 0.0) {
2653 0 : MdotHR = MSHeatPump(MSHeatPumpNum).HeatRecoveryMassFlowRate;
2654 : } else {
2655 0 : MdotHR = MSHeatPump(MSHeatPumpNum).DesignHeatRecMassFlowRate;
2656 : }
2657 : }
2658 : } else {
2659 0 : MdotHR = 0.0;
2660 : }
2661 :
2662 0 : SetComponentFlowRate(state,
2663 : MdotHR,
2664 0 : MSHeatPump(MSHeatPumpNum).HeatRecInletNodeNum,
2665 0 : MSHeatPump(MSHeatPumpNum).HeatRecOutletNodeNum,
2666 0 : MSHeatPump(MSHeatPumpNum).HRPlantLoc);
2667 : }
2668 :
2669 : // get operating capacity of water and steam coil
2670 226554 : if (FirstHVACIteration) {
2671 80400 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingWater) {
2672 : // set air-side and steam-side mass flow rates
2673 0 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).CoilAirInletNode).MassFlowRate = state.dataHVACMultiSpdHP->CompOnMassFlow;
2674 0 : mdot = MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow;
2675 0 : SetComponentFlowRate(state,
2676 : mdot,
2677 0 : MSHeatPump(MSHeatPumpNum).CoilControlNode,
2678 0 : MSHeatPump(MSHeatPumpNum).CoilOutletNode,
2679 0 : MSHeatPump(MSHeatPumpNum).plantLoc);
2680 : // simulate water coil to find operating capacity
2681 0 : SimulateWaterCoilComponents(
2682 0 : state, MSHeatPump(MSHeatPumpNum).HeatCoilName, FirstHVACIteration, MSHeatPump(MSHeatPumpNum).HeatCoilNum, QActual);
2683 : } // from IF(MSHeatPump(MSHeatPumpNum)%HeatCoilType == Coil_HeatingWater) THEN
2684 :
2685 80400 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingSteam) {
2686 :
2687 : // set air-side and steam-side mass flow rates
2688 0 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).CoilAirInletNode).MassFlowRate = state.dataHVACMultiSpdHP->CompOnMassFlow;
2689 0 : mdot = MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow;
2690 0 : SetComponentFlowRate(state,
2691 : mdot,
2692 0 : MSHeatPump(MSHeatPumpNum).CoilControlNode,
2693 0 : MSHeatPump(MSHeatPumpNum).CoilOutletNode,
2694 0 : MSHeatPump(MSHeatPumpNum).plantLoc);
2695 :
2696 : // simulate steam coil to find operating capacity
2697 0 : SimulateSteamCoilComponents(state,
2698 0 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
2699 : FirstHVACIteration,
2700 0 : MSHeatPump(MSHeatPumpNum).HeatCoilNum,
2701 : 1.0,
2702 : QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
2703 :
2704 : } // from IF(MSHeatPump(MSHeatPumpNum)%HeatCoilType == Coil_HeatingSteam) THEN
2705 80400 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == Coil_HeatingWater) {
2706 : // set air-side and steam-side mass flow rates
2707 0 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).SuppCoilAirInletNode).MassFlowRate = state.dataHVACMultiSpdHP->CompOnMassFlow;
2708 0 : mdot = MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow;
2709 0 : SetComponentFlowRate(state,
2710 : mdot,
2711 0 : MSHeatPump(MSHeatPumpNum).SuppCoilControlNode,
2712 0 : MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode,
2713 0 : MSHeatPump(MSHeatPumpNum).SuppPlantLoc);
2714 : // simulate water coil to find operating capacity
2715 0 : SimulateWaterCoilComponents(
2716 0 : state, MSHeatPump(MSHeatPumpNum).SuppHeatCoilName, FirstHVACIteration, MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum, QActual);
2717 0 : MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity = QActual;
2718 :
2719 : } // from IF(MSHeatPump(MSHeatPumpNum)%SuppHeatCoilType == Coil_HeatingWater) THEN
2720 :
2721 80400 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == Coil_HeatingSteam) {
2722 :
2723 : // set air-side and steam-side mass flow rates
2724 0 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).SuppCoilAirInletNode).MassFlowRate = state.dataHVACMultiSpdHP->CompOnMassFlow;
2725 0 : mdot = MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow;
2726 0 : SetComponentFlowRate(state,
2727 : mdot,
2728 0 : MSHeatPump(MSHeatPumpNum).SuppCoilControlNode,
2729 0 : MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode,
2730 0 : MSHeatPump(MSHeatPumpNum).SuppPlantLoc);
2731 :
2732 : // simulate steam coil to find operating capacity
2733 0 : SimulateSteamCoilComponents(state,
2734 0 : MSHeatPump(MSHeatPumpNum).SuppHeatCoilName,
2735 : FirstHVACIteration,
2736 0 : MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum,
2737 : 1.0,
2738 : QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
2739 0 : MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity =
2740 0 : GetSteamCoilCapacity(state, "Coil:Heating:Steam", MSHeatPump(MSHeatPumpNum).SuppHeatCoilName, ErrorsFound);
2741 :
2742 : } // from IF(MSHeatPump(MSHeatPumpNum)%SuppHeatCoilType == Coil_HeatingSteam) THEN
2743 : } // from IF( FirstHVACIteration ) THEN
2744 : }
2745 :
2746 : //******************************************************************************
2747 :
2748 11 : void SizeMSHeatPump(EnergyPlusData &state, int const MSHeatPumpNum) // Engine driven heat pump number
2749 : {
2750 : // SUBROUTINE INFORMATION:
2751 : // AUTHOR: Lixing Gu, FSEC
2752 : // DATE WRITTEN: June 2007
2753 : // MODIFIED na
2754 : // RE-ENGINEERED na
2755 :
2756 : // PURPOSE OF THIS SUBROUTINE:
2757 : // This subroutine is for sizing multispeed heat pump airflow rates and flow fraction.
2758 :
2759 : // Using/Aliasing
2760 : using namespace DataSizing;
2761 :
2762 : using PlantUtilities::RegisterPlantCompDesignFlow;
2763 :
2764 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2765 : int NumOfSpeedCooling; // Number of speeds for cooling
2766 : int NumOfSpeedHeating; // Number of speeds for heating
2767 : int i; // Index to speed
2768 :
2769 11 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
2770 11 : if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0) {
2771 11 : if (MSHeatPump(MSHeatPumpNum).FanType == DataHVACGlobals::FanType_SystemModelObject) {
2772 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanVecIndex = MSHeatPump(MSHeatPumpNum).FanNum;
2773 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanModelType = DataAirSystems::ObjectVectorOOFanSystemModel;
2774 : } else {
2775 11 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).SupFanNum = MSHeatPump(MSHeatPumpNum).FanNum;
2776 11 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanModelType = DataAirSystems::StructArrayLegacyFanModels;
2777 : }
2778 11 : if (MSHeatPump(MSHeatPumpNum).FanPlaceType == BlowThru) {
2779 11 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanLocation = DataAirSystems::FanPlacement::BlowThru;
2780 0 : } else if (MSHeatPump(MSHeatPumpNum).FanPlaceType == DrawThru) {
2781 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanLocation = DataAirSystems::FanPlacement::DrawThru;
2782 : }
2783 : }
2784 :
2785 11 : NumOfSpeedCooling = MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling;
2786 11 : NumOfSpeedHeating = MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating;
2787 :
2788 45 : for (i = NumOfSpeedCooling; i >= 1; --i) {
2789 :
2790 34 : if (MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) == AutoSize) {
2791 0 : if (state.dataSize->CurSysNum > 0) {
2792 0 : if (i == NumOfSpeedCooling) {
2793 0 : CheckSysSizing(state, state.dataHVACMultiSpdHP->CurrentModuleObject, MSHeatPump(MSHeatPumpNum).Name);
2794 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
2795 0 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow < MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) &&
2796 0 : MSHeatPump(MSHeatPumpNum).FanVolFlow != AutoSize) {
2797 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) = MSHeatPump(MSHeatPumpNum).FanVolFlow;
2798 0 : ShowWarningError(state, state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHeatPumpNum).Name + "\"");
2799 0 : ShowContinueError(state,
2800 : "The supply air flow rate at high speed is less than the autosized value for the supply air flow rate "
2801 : "in cooling mode. Consider autosizing the fan for this simulation.");
2802 0 : ShowContinueError(
2803 : state,
2804 : "The air flow rate at high speed in cooling mode is reset to the supply air flow rate and the simulation continues.");
2805 : }
2806 : } else {
2807 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) =
2808 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(NumOfSpeedCooling) * i / NumOfSpeedCooling;
2809 : }
2810 0 : if (MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) < SmallAirVolFlow) {
2811 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate = 0.0;
2812 : }
2813 : // Ensure the flow rate at lower speed has to be less or equal to the flow rate at higher speed
2814 0 : if (i != NumOfSpeedCooling) {
2815 0 : if (MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) > MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i + 1)) {
2816 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i) = MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i + 1);
2817 : }
2818 : }
2819 0 : BaseSizer::reportSizerOutput(state,
2820 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2821 0 : MSHeatPump(MSHeatPumpNum).Name,
2822 0 : format("Speed {} Supply Air Flow Rate During Cooling Operation [m3/s]", i),
2823 0 : MSHeatPump(MSHeatPumpNum).CoolVolumeFlowRate(i));
2824 : }
2825 : }
2826 : }
2827 :
2828 39 : for (i = NumOfSpeedHeating; i >= 1; --i) {
2829 28 : if (MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) == AutoSize) {
2830 0 : if (state.dataSize->CurSysNum > 0) {
2831 0 : if (i == NumOfSpeedHeating) {
2832 0 : CheckSysSizing(state, state.dataHVACMultiSpdHP->CurrentModuleObject, MSHeatPump(MSHeatPumpNum).Name);
2833 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
2834 0 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow < MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) &&
2835 0 : MSHeatPump(MSHeatPumpNum).FanVolFlow != AutoSize) {
2836 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) = MSHeatPump(MSHeatPumpNum).FanVolFlow;
2837 0 : ShowWarningError(state, state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHeatPumpNum).Name + "\"");
2838 0 : ShowContinueError(state,
2839 : "The supply air flow rate at high speed is less than the autosized value for the maximum air flow rate "
2840 : "in heating mode. Consider autosizing the fan for this simulation.");
2841 0 : ShowContinueError(state,
2842 : "The maximum air flow rate at high speed in heating mode is reset to the supply air flow rate and the "
2843 : "simulation continues.");
2844 : }
2845 : } else {
2846 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) =
2847 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(NumOfSpeedHeating) * i / NumOfSpeedHeating;
2848 : }
2849 0 : if (MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) < SmallAirVolFlow) {
2850 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) = 0.0;
2851 : }
2852 : // Ensure the flow rate at lower speed has to be less or equal to the flow rate at higher speed
2853 0 : if (i != NumOfSpeedHeating) {
2854 0 : if (MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) > MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i + 1)) {
2855 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i) = MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i + 1);
2856 : }
2857 : }
2858 0 : BaseSizer::reportSizerOutput(state,
2859 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2860 0 : MSHeatPump(MSHeatPumpNum).Name,
2861 0 : format("Speed{}Supply Air Flow Rate During Heating Operation [m3/s]", i),
2862 0 : MSHeatPump(MSHeatPumpNum).HeatVolumeFlowRate(i));
2863 : }
2864 : }
2865 : }
2866 :
2867 11 : if (MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate == AutoSize) {
2868 0 : if (state.dataSize->CurSysNum > 0) {
2869 0 : CheckSysSizing(state, state.dataHVACMultiSpdHP->CurrentModuleObject, MSHeatPump(MSHeatPumpNum).Name);
2870 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
2871 0 : if (MSHeatPump(MSHeatPumpNum).FanVolFlow < MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate &&
2872 0 : MSHeatPump(MSHeatPumpNum).FanVolFlow != AutoSize) {
2873 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate = MSHeatPump(MSHeatPumpNum).FanVolFlow;
2874 0 : ShowWarningError(state, state.dataHVACMultiSpdHP->CurrentModuleObject + " \"" + MSHeatPump(MSHeatPumpNum).Name + "\"");
2875 0 : ShowContinueError(state,
2876 : "The supply air flow rate is less than the autosized value for the maximum air flow rate when no heating or "
2877 : "cooling is needed. Consider autosizing the fan for this simulation.");
2878 0 : ShowContinueError(state,
2879 : "The maximum air flow rate when no heating or cooling is needed is reset to the supply air flow rate and the "
2880 : "simulation continues.");
2881 : }
2882 0 : if (MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate < SmallAirVolFlow) {
2883 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate = 0.0;
2884 : }
2885 :
2886 0 : BaseSizer::reportSizerOutput(state,
2887 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2888 0 : MSHeatPump(MSHeatPumpNum).Name,
2889 : "Supply Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2890 0 : MSHeatPump(MSHeatPumpNum).IdleVolumeAirRate);
2891 : }
2892 : }
2893 :
2894 11 : if (MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp == AutoSize) {
2895 0 : if (state.dataSize->CurSysNum > 0) {
2896 0 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == 1) { // Gas
2897 0 : CheckZoneSizing(state, "Coil:Heating:Fuel", MSHeatPump(MSHeatPumpNum).Name);
2898 : } else {
2899 0 : CheckZoneSizing(state, "Coil:Heating:Electric", MSHeatPump(MSHeatPumpNum).Name);
2900 : }
2901 0 : MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatSupTemp;
2902 0 : BaseSizer::reportSizerOutput(state,
2903 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2904 0 : MSHeatPump(MSHeatPumpNum).Name,
2905 : "Maximum Supply Air Temperature from Supplemental Heater [C]",
2906 0 : MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp);
2907 : }
2908 : }
2909 :
2910 11 : if (MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity == AutoSize) {
2911 0 : if (state.dataSize->CurSysNum > 0) {
2912 0 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilType == 1) { // Gas
2913 0 : CheckSysSizing(state, "Coil:Heating:Fuel", MSHeatPump(MSHeatPumpNum).Name);
2914 : } else {
2915 0 : CheckSysSizing(state, "Coil:Heating:Electric", MSHeatPump(MSHeatPumpNum).Name);
2916 : }
2917 0 : MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatCap;
2918 : } else {
2919 0 : MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity = 0.0;
2920 : }
2921 0 : BaseSizer::reportSizerOutput(state,
2922 0 : state.dataHVACMultiSpdHP->CurrentModuleObject,
2923 0 : MSHeatPump(MSHeatPumpNum).Name,
2924 : "Supplemental Heating Coil Nominal Capacity [W]",
2925 0 : MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity);
2926 : }
2927 11 : state.dataSize->SuppHeatCap = MSHeatPump(MSHeatPumpNum).DesignSuppHeatingCapacity;
2928 :
2929 11 : if (MSHeatPump(MSHeatPumpNum).HeatRecActive) {
2930 0 : RegisterPlantCompDesignFlow(state, MSHeatPump(MSHeatPumpNum).HeatRecInletNodeNum, MSHeatPump(MSHeatPumpNum).DesignHeatRecFlowRate);
2931 : }
2932 11 : }
2933 :
2934 : //******************************************************************************
2935 :
2936 31675 : void ControlMSHPOutputEMS(EnergyPlusData &state,
2937 : int const MSHeatPumpNum, // Unit index of engine driven heat pump
2938 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
2939 : DataHVACGlobals::CompressorOperation const CompressorOp, // compressor operation; 1=on, 0=off
2940 : int const OpMode, // operating mode: CycFanCycCoil | ContFanCycCoil
2941 : Real64 const QZnReq, // cooling or heating output needed by zone [W]
2942 : Real64 const SpeedVal, // continuous speed value
2943 : int &SpeedNum, // discrete speed level
2944 : Real64 &SpeedRatio, // unit speed ratio for DX coils
2945 : Real64 &PartLoadFrac, // unit part load fraction
2946 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
2947 : Real64 &SupHeaterLoad // Supplemental heater load [W]
2948 :
2949 : )
2950 : {
2951 31675 : OnOffAirFlowRatio = 0.0;
2952 31675 : SupHeaterLoad = 0.0;
2953 :
2954 31675 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
2955 :
2956 : // Get EMS output
2957 31675 : SpeedNum = ceil(SpeedVal);
2958 31675 : bool useMaxedSpeed = false;
2959 63350 : std::string useMaxedSpeedCoilName;
2960 31675 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::HeatingMode) {
2961 18467 : if (SpeedNum > MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating) {
2962 0 : SpeedNum = MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating;
2963 0 : useMaxedSpeed = true;
2964 0 : useMaxedSpeedCoilName = MSHeatPump(MSHeatPumpNum).DXHeatCoilName;
2965 : }
2966 13208 : } else if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::CoolingMode) {
2967 12656 : if (SpeedNum > MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling) {
2968 0 : SpeedNum = MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling;
2969 0 : useMaxedSpeed = true;
2970 0 : useMaxedSpeedCoilName = MSHeatPump(MSHeatPumpNum).DXCoolCoilName;
2971 : }
2972 : }
2973 31675 : if (useMaxedSpeed) {
2974 0 : MSHeatPump(MSHeatPumpNum).CoilSpeedErrIndex++;
2975 0 : ShowRecurringWarningErrorAtEnd(state,
2976 0 : "Wrong coil speed EMS override value, for unit=\"" + useMaxedSpeedCoilName +
2977 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
2978 0 : MSHeatPump(MSHeatPumpNum).CoilSpeedErrIndex,
2979 : SpeedVal,
2980 : SpeedVal,
2981 : _,
2982 : "",
2983 : "");
2984 : }
2985 : // Calculate TempOutput
2986 31675 : Real64 TempOutput = 0.0; // unit output when iteration limit exceeded [W]
2987 :
2988 31675 : if (SpeedNum == 1) {
2989 7736 : SpeedRatio = 0.0;
2990 7736 : if (useMaxedSpeed || floor(SpeedVal) == SpeedVal) {
2991 7736 : PartLoadFrac = 1;
2992 : } else {
2993 0 : PartLoadFrac = SpeedVal - floor(SpeedVal);
2994 : }
2995 7736 : CalcMSHeatPump(state,
2996 : MSHeatPumpNum,
2997 : FirstHVACIteration,
2998 : CompressorOp,
2999 : SpeedNum,
3000 : SpeedRatio,
3001 : PartLoadFrac,
3002 : TempOutput,
3003 : QZnReq,
3004 : OnOffAirFlowRatio,
3005 : SupHeaterLoad);
3006 : } else {
3007 23939 : PartLoadFrac = 0.0;
3008 23939 : if (useMaxedSpeed || floor(SpeedVal) == SpeedVal) {
3009 0 : SpeedRatio = 1;
3010 : } else {
3011 23939 : SpeedRatio = SpeedVal - floor(SpeedVal);
3012 : }
3013 23939 : CalcMSHeatPump(state,
3014 : MSHeatPumpNum,
3015 : FirstHVACIteration,
3016 : CompressorOp,
3017 : SpeedNum,
3018 : SpeedRatio,
3019 : PartLoadFrac,
3020 : TempOutput,
3021 : QZnReq,
3022 : OnOffAirFlowRatio,
3023 : SupHeaterLoad);
3024 : }
3025 :
3026 31675 : ControlMSHPSupHeater(state,
3027 : MSHeatPumpNum,
3028 : FirstHVACIteration,
3029 : CompressorOp,
3030 : OpMode,
3031 : QZnReq,
3032 : TempOutput,
3033 : SpeedNum,
3034 : SpeedRatio,
3035 : PartLoadFrac,
3036 : OnOffAirFlowRatio,
3037 : SupHeaterLoad);
3038 31675 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).CycRatio = PartLoadFrac;
3039 31675 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedRatio = SpeedRatio;
3040 31675 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedNum = SpeedNum;
3041 31675 : }
3042 :
3043 31675 : void ControlMSHPSupHeater(EnergyPlusData &state,
3044 : int const MSHeatPumpNum, // Unit index of engine driven heat pump
3045 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
3046 : DataHVACGlobals::CompressorOperation const CompressorOp, // compressor operation; 1=on, 0=off
3047 : int const OpMode, // operating mode: CycFanCycCoil | ContFanCycCoil
3048 : Real64 const QZnReq, // cooling or heating output needed by zone [W]
3049 : int const EMSOutput, // unit full output when compressor is operating [W]vvvv
3050 : int const SpeedNum, // Speed number
3051 : Real64 SpeedRatio, // unit speed ratio for DX coils
3052 : Real64 PartLoadFrac, // unit part load fraction
3053 : Real64 OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
3054 : Real64 &SupHeaterLoad // Supplemental heater load [W]
3055 :
3056 : )
3057 : {
3058 : // if the DX heating coil cannot meet the load, trim with supplemental heater
3059 : // occurs with constant fan mode when compressor is on or off
3060 : // occurs with cycling fan mode when compressor PLR is equal to 1
3061 31675 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
3062 :
3063 31675 : if ((QZnReq > SmallLoad && QZnReq > EMSOutput)) {
3064 : Real64 TempOutput;
3065 18427 : if (state.dataEnvrn->OutDryBulbTemp <= MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp) {
3066 18427 : SupHeaterLoad = QZnReq - EMSOutput;
3067 : } else {
3068 0 : SupHeaterLoad = 0.0;
3069 : }
3070 18427 : CalcMSHeatPump(state,
3071 : MSHeatPumpNum,
3072 : FirstHVACIteration,
3073 : CompressorOp,
3074 : SpeedNum,
3075 : SpeedRatio,
3076 : PartLoadFrac,
3077 : TempOutput,
3078 : QZnReq,
3079 : OnOffAirFlowRatio,
3080 : SupHeaterLoad);
3081 : }
3082 :
3083 : // check the outlet of the supplemental heater to be lower than the maximum supplemental heater supply air temperature
3084 35171 : if (state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).Temp > MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp &&
3085 3496 : SupHeaterLoad > 0.0) {
3086 :
3087 : // If the supply air temperature is to high, turn off the supplemental heater to recalculate the outlet temperature
3088 3496 : SupHeaterLoad = 0.0;
3089 : Real64 QCoilActual; // coil load actually delivered returned to calling component
3090 3496 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, SupHeaterLoad, OpMode, QCoilActual);
3091 :
3092 : // If the outlet temperature is below the maximum supplemental heater supply air temperature, reduce the load passed to
3093 : // the supplemental heater, otherwise leave the supplemental heater off. If the supplemental heater is to be turned on,
3094 : // use the outlet conditions when the supplemental heater was off (CALL above) as the inlet conditions for the calculation
3095 : // of supplemental heater load to just meet the maximum supply air temperature from the supplemental heater.
3096 3496 : if (state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).Temp < MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp) {
3097 3496 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).HumRat);
3098 3496 : SupHeaterLoad =
3099 6992 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirInletNodeNum).MassFlowRate * CpAir *
3100 3496 : (MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp - state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).Temp);
3101 :
3102 : } else {
3103 0 : SupHeaterLoad = 0.0;
3104 : }
3105 : }
3106 31675 : }
3107 :
3108 219375 : void ControlMSHPOutput(EnergyPlusData &state,
3109 : int const MSHeatPumpNum, // Unit index of engine driven heat pump
3110 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
3111 : DataHVACGlobals::CompressorOperation const CompressorOp, // compressor operation; 1=on, 0=off
3112 : int const OpMode, // operating mode: CycFanCycCoil | ContFanCycCoil
3113 : Real64 const QZnReq, // cooling or heating output needed by zone [W]
3114 : int const ZoneNum [[maybe_unused]], // Index to zone number
3115 : int &SpeedNum, // Speed number
3116 : Real64 &SpeedRatio, // unit speed ratio for DX coils
3117 : Real64 &PartLoadFrac, // unit part load fraction
3118 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
3119 : Real64 &SupHeaterLoad // Supplemental heater load [W]
3120 : )
3121 : {
3122 :
3123 : // SUBROUTINE INFORMATION:
3124 : // AUTHOR Lixing Gu
3125 : // DATE WRITTEN June 2007
3126 : // MODIFIED na
3127 : // RE-ENGINEERED Revised for multispeed heat pump use based on ControlPTHPOutput
3128 :
3129 : // PURPOSE OF THIS SUBROUTINE:
3130 : // Determine the part load fraction at low speed, and speed ratio at high speed for this time step.
3131 :
3132 : // METHODOLOGY EMPLOYED:
3133 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
3134 :
3135 : using General::SolveRoot;
3136 : using Psychrometrics::PsyCpAirFnW;
3137 :
3138 : // SUBROUTINE PARAMETER DEFINITIONS:
3139 219375 : int constexpr MaxIte(500); // maximum number of iterations
3140 :
3141 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3142 : Real64 FullOutput; // unit full output when compressor is operating [W]
3143 : Real64 LowOutput; // unit full output at low speed [W]
3144 : Real64 TempOutput; // unit output when iteration limit exceeded [W]
3145 : Real64 NoCompOutput; // output when no active compressor [W]
3146 : Real64 ErrorToler; // error tolerance
3147 : int SolFla; // Flag of RegulaFalsi solver
3148 : Real64 CpAir; // air specific heat
3149 : Real64 OutsideDryBulbTemp; // Outside air temperature at external node height
3150 : Real64 QCoilActual; // coil load actually delivered returned to calling component
3151 : int i; // Speed index
3152 :
3153 219375 : SupHeaterLoad = 0.0;
3154 219375 : PartLoadFrac = 0.0;
3155 219375 : SpeedRatio = 0.0;
3156 219375 : SpeedNum = 1;
3157 :
3158 219375 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
3159 :
3160 219375 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
3161 :
3162 : //!!LKL Discrepancy with < 0
3163 297365 : if (GetCurrentScheduleValue(state, MSHeatPump(MSHeatPumpNum).AvaiSchedPtr) == 0.0) return;
3164 :
3165 : // Get result when DX coil is off
3166 194879 : CalcMSHeatPump(state,
3167 : MSHeatPumpNum,
3168 : FirstHVACIteration,
3169 : CompressorOp,
3170 : SpeedNum,
3171 : SpeedRatio,
3172 : PartLoadFrac,
3173 : NoCompOutput,
3174 : QZnReq,
3175 : OnOffAirFlowRatio,
3176 : SupHeaterLoad);
3177 :
3178 : // If cooling and NoCompOutput < QZnReq, the coil needs to be off
3179 : // If heating and NoCompOutput > QZnReq, the coil needs to be off
3180 389758 : if ((QZnReq < (-1.0 * SmallLoad) && NoCompOutput < QZnReq) || (QZnReq > SmallLoad && NoCompOutput > QZnReq) ||
3181 194879 : std::abs(QZnReq) <= SmallLoad) {
3182 39096 : return;
3183 : }
3184 :
3185 : // Get full load result
3186 155783 : PartLoadFrac = 1.0;
3187 155783 : SpeedRatio = 1.0;
3188 155783 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::HeatingMode) {
3189 86433 : SpeedNum = MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating;
3190 86433 : if (MSHeatPump(MSHeatPumpNum).Staged && std::abs(MSHeatPump(MSHeatPumpNum).StageNum) < SpeedNum) {
3191 7300 : SpeedNum = std::abs(MSHeatPump(MSHeatPumpNum).StageNum);
3192 7300 : if (SpeedNum == 1) SpeedRatio = 0.0;
3193 : }
3194 : }
3195 155783 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::CoolingMode) {
3196 69350 : SpeedNum = MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling;
3197 69350 : if (MSHeatPump(MSHeatPumpNum).Staged && std::abs(MSHeatPump(MSHeatPumpNum).StageNum) < SpeedNum) {
3198 7264 : SpeedNum = std::abs(MSHeatPump(MSHeatPumpNum).StageNum);
3199 7264 : if (SpeedNum == 1) SpeedRatio = 0.0;
3200 : }
3201 : }
3202 :
3203 155783 : CalcMSHeatPump(state,
3204 : MSHeatPumpNum,
3205 : FirstHVACIteration,
3206 : CompressorOp,
3207 : SpeedNum,
3208 : SpeedRatio,
3209 : PartLoadFrac,
3210 : FullOutput,
3211 : QZnReq,
3212 : OnOffAirFlowRatio,
3213 : SupHeaterLoad);
3214 :
3215 155783 : if (QZnReq < (-1.0 * SmallLoad)) {
3216 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCompOutput
3217 : // Check that this is the case; if not set PartLoadFrac = 0.0 (off) and return
3218 69350 : if (FullOutput >= 0.0 || FullOutput >= NoCompOutput) {
3219 0 : PartLoadFrac = 0.0;
3220 0 : SpeedRatio = 0.0;
3221 0 : SpeedNum = 0;
3222 0 : return;
3223 : }
3224 : // ! If the QZnReq <= FullOutput the unit needs to run full out
3225 69350 : if (QZnReq <= FullOutput) {
3226 14398 : PartLoadFrac = 1.0;
3227 14398 : SpeedRatio = 1.0;
3228 14398 : if (MSHeatPump(MSHeatPumpNum).Staged && SpeedNum == 1) SpeedRatio = 0.0;
3229 14398 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).CycRatio = PartLoadFrac;
3230 14398 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedRatio = SpeedRatio;
3231 14398 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedNum = SpeedNum;
3232 14398 : return;
3233 : }
3234 54952 : ErrorToler = 0.001; // Error tolerance for convergence from input deck
3235 : } else {
3236 : // Since we are heating, we expect FullOutput to be > 0 and FullOutput > NoCompOutput
3237 : // Check that this is the case; if not set PartLoadFrac = 0.0 (off)
3238 86433 : if (FullOutput <= 0.0 || FullOutput <= NoCompOutput) {
3239 23991 : PartLoadFrac = 0.0;
3240 23991 : SpeedRatio = 0.0;
3241 : // may need supplemental heating so don't return in heating mode
3242 : }
3243 86433 : if (QZnReq >= FullOutput) {
3244 62525 : PartLoadFrac = 1.0;
3245 62525 : SpeedRatio = 1.0;
3246 : // may need supplemental heating so don't return in heating mode
3247 : }
3248 86433 : ErrorToler = 0.001; // Error tolerance for convergence from input deck
3249 : }
3250 :
3251 : // Direct solution
3252 141385 : if (state.dataGlobal->DoCoilDirectSolutions && !MSHeatPump(MSHeatPumpNum).Staged) {
3253 9136 : Real64 TempOutput0 = 0.0;
3254 9136 : MSHeatPump(MSHeatPumpNum).FullOutput = 0.0;
3255 :
3256 : // heating
3257 9136 : if (QZnReq > SmallLoad && QZnReq < FullOutput) {
3258 6 : CalcMSHeatPump(
3259 : state, MSHeatPumpNum, FirstHVACIteration, CompressorOp, 1, 0.0, 0.0, TempOutput0, QZnReq, OnOffAirFlowRatio, SupHeaterLoad);
3260 :
3261 20 : for (int i = 1; i <= MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating; ++i) {
3262 20 : if (i == 1) {
3263 6 : CalcMSHeatPump(state,
3264 : MSHeatPumpNum,
3265 : FirstHVACIteration,
3266 : CompressorOp,
3267 : i,
3268 : 0.0,
3269 : 1.0,
3270 6 : MSHeatPump(MSHeatPumpNum).FullOutput(i),
3271 : QZnReq,
3272 : OnOffAirFlowRatio,
3273 : SupHeaterLoad);
3274 6 : if (QZnReq <= MSHeatPump(MSHeatPumpNum).FullOutput(i)) {
3275 0 : SpeedNum = i;
3276 0 : PartLoadFrac = (QZnReq - TempOutput0) / (MSHeatPump(MSHeatPumpNum).FullOutput(i) - TempOutput0);
3277 0 : CalcMSHeatPump(state,
3278 : MSHeatPumpNum,
3279 : FirstHVACIteration,
3280 : CompressorOp,
3281 : i,
3282 : 0.0,
3283 : PartLoadFrac,
3284 : TempOutput,
3285 : QZnReq,
3286 : OnOffAirFlowRatio,
3287 : SupHeaterLoad);
3288 0 : break;
3289 : }
3290 : } else {
3291 14 : CalcMSHeatPump(state,
3292 : MSHeatPumpNum,
3293 : FirstHVACIteration,
3294 : CompressorOp,
3295 : i,
3296 : 1.0,
3297 : 1.0,
3298 14 : MSHeatPump(MSHeatPumpNum).FullOutput(i),
3299 : QZnReq,
3300 : OnOffAirFlowRatio,
3301 : SupHeaterLoad);
3302 14 : if (QZnReq <= MSHeatPump(MSHeatPumpNum).FullOutput(i)) {
3303 6 : SpeedNum = i;
3304 6 : PartLoadFrac = 1.0;
3305 12 : SpeedRatio = (QZnReq - MSHeatPump(MSHeatPumpNum).FullOutput(i - 1)) /
3306 6 : (MSHeatPump(MSHeatPumpNum).FullOutput(i) - MSHeatPump(MSHeatPumpNum).FullOutput(i - 1));
3307 6 : CalcMSHeatPump(state,
3308 : MSHeatPumpNum,
3309 : FirstHVACIteration,
3310 : CompressorOp,
3311 : i,
3312 : SpeedRatio,
3313 : 1.0,
3314 : TempOutput,
3315 : QZnReq,
3316 : OnOffAirFlowRatio,
3317 : SupHeaterLoad);
3318 6 : break;
3319 : }
3320 : }
3321 : }
3322 : }
3323 :
3324 : // Coolling
3325 9136 : if (QZnReq < (-1.0 * SmallLoad) && QZnReq > FullOutput) {
3326 4376 : CalcMSHeatPump(
3327 : state, MSHeatPumpNum, FirstHVACIteration, CompressorOp, 1, 0.0, 0.0, TempOutput0, QZnReq, OnOffAirFlowRatio, SupHeaterLoad);
3328 13497 : for (int i = 1; i <= MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling; ++i) {
3329 13497 : if (i == 1) {
3330 4376 : CalcMSHeatPump(state,
3331 : MSHeatPumpNum,
3332 : FirstHVACIteration,
3333 : CompressorOp,
3334 : i,
3335 : 0.0,
3336 : 1.0,
3337 4376 : MSHeatPump(MSHeatPumpNum).FullOutput(i),
3338 : QZnReq,
3339 : OnOffAirFlowRatio,
3340 : SupHeaterLoad);
3341 4376 : if (QZnReq >= MSHeatPump(MSHeatPumpNum).FullOutput(i)) {
3342 172 : SpeedNum = i;
3343 172 : PartLoadFrac = (QZnReq - TempOutput0) / (MSHeatPump(MSHeatPumpNum).FullOutput(i) - TempOutput0);
3344 172 : CalcMSHeatPump(state,
3345 : MSHeatPumpNum,
3346 : FirstHVACIteration,
3347 : CompressorOp,
3348 : i,
3349 : 0.0,
3350 : PartLoadFrac,
3351 : TempOutput,
3352 : QZnReq,
3353 : OnOffAirFlowRatio,
3354 : SupHeaterLoad);
3355 172 : break;
3356 : }
3357 : } else {
3358 9121 : CalcMSHeatPump(state,
3359 : MSHeatPumpNum,
3360 : FirstHVACIteration,
3361 : CompressorOp,
3362 : i,
3363 : 1.0,
3364 : 1.0,
3365 9121 : MSHeatPump(MSHeatPumpNum).FullOutput(i),
3366 : QZnReq,
3367 : OnOffAirFlowRatio,
3368 : SupHeaterLoad);
3369 9121 : if (QZnReq >= MSHeatPump(MSHeatPumpNum).FullOutput(i)) {
3370 4204 : SpeedNum = i;
3371 4204 : PartLoadFrac = 1.0;
3372 8408 : SpeedRatio = (QZnReq - MSHeatPump(MSHeatPumpNum).FullOutput(i - 1)) /
3373 4204 : (MSHeatPump(MSHeatPumpNum).FullOutput(i) - MSHeatPump(MSHeatPumpNum).FullOutput(i - 1));
3374 4204 : CalcMSHeatPump(state,
3375 : MSHeatPumpNum,
3376 : FirstHVACIteration,
3377 : CompressorOp,
3378 : i,
3379 : SpeedRatio,
3380 : 1.0,
3381 : TempOutput,
3382 : QZnReq,
3383 : OnOffAirFlowRatio,
3384 : SupHeaterLoad);
3385 4204 : break;
3386 : }
3387 : }
3388 : }
3389 : }
3390 : } else {
3391 : // Calculate the part load fraction
3392 206727 : if (((QZnReq > SmallLoad && QZnReq < FullOutput) || (QZnReq < (-1.0 * SmallLoad) && QZnReq > FullOutput)) &&
3393 74478 : (!MSHeatPump(MSHeatPumpNum).Staged)) {
3394 : // Check whether the low speed coil can meet the load or not
3395 74097 : CalcMSHeatPump(
3396 : state, MSHeatPumpNum, FirstHVACIteration, CompressorOp, 1, 0.0, 1.0, LowOutput, QZnReq, OnOffAirFlowRatio, SupHeaterLoad);
3397 74097 : if ((QZnReq > 0.0 && QZnReq <= LowOutput) || (QZnReq < 0.0 && QZnReq >= LowOutput)) {
3398 55037 : SpeedRatio = 0.0;
3399 55037 : SpeedNum = 1;
3400 : auto f = [&state, MSHeatPumpNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, CompressorOp](
3401 1194150 : Real64 const PartLoadFrac) {
3402 : // Calculates residual function ((ActualOutput - QZnReq)/QZnReq); MSHP output depends on PLR which is being varied to zero
3403 : // the residual.
3404 : Real64 ActualOutput; // delivered capacity of MSHP
3405 199025 : Real64 tmpAirFlowRatio = OnOffAirFlowRatio;
3406 199025 : Real64 tmpHeaterLoad = SupHeaterLoad;
3407 398050 : CalcMSHeatPump(state,
3408 : MSHeatPumpNum,
3409 : FirstHVACIteration,
3410 : CompressorOp,
3411 : 1,
3412 : 0.0,
3413 : PartLoadFrac,
3414 : ActualOutput,
3415 : QZnReq,
3416 : tmpAirFlowRatio,
3417 : tmpHeaterLoad);
3418 597075 : return (ActualOutput - QZnReq) / QZnReq;
3419 55037 : };
3420 55037 : SolveRoot(state, ErrorToler, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
3421 55037 : if (SolFla == -1) {
3422 0 : if (!state.dataGlobal->WarmupFlag) {
3423 0 : if (state.dataHVACMultiSpdHP->ErrCountCyc == 0) {
3424 0 : ++state.dataHVACMultiSpdHP->ErrCountCyc; // TODO: Why is the error count shared among all heat pump units?
3425 0 : ShowWarningError(
3426 0 : state, "Iteration limit exceeded calculating DX unit cycling ratio, for unit=" + MSHeatPump(MSHeatPumpNum).Name);
3427 0 : ShowContinueErrorTimeStamp(state, format("Cycling ratio returned={:.2R}", PartLoadFrac));
3428 : } else {
3429 0 : ++state.dataHVACMultiSpdHP->ErrCountCyc;
3430 0 : ShowRecurringWarningErrorAtEnd(
3431 : state,
3432 0 : MSHeatPump(MSHeatPumpNum).Name +
3433 : "\": Iteration limit warning exceeding calculating DX unit cycling ratio continues...",
3434 0 : MSHeatPump(MSHeatPumpNum).ErrIndexCyc,
3435 : PartLoadFrac,
3436 : PartLoadFrac);
3437 : }
3438 : }
3439 55037 : } else if (SolFla == -2) {
3440 0 : ShowFatalError(state,
3441 0 : "DX unit cycling ratio calculation failed: cycling limits exceeded, for unit=" +
3442 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName);
3443 55037 : }
3444 : } else {
3445 : // Check to see which speed to meet the load
3446 19060 : PartLoadFrac = 1.0;
3447 19060 : SpeedRatio = 1.0;
3448 19060 : if (QZnReq < (-1.0 * SmallLoad)) { // Cooling
3449 38716 : for (i = 2; i <= MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling; ++i) {
3450 38716 : CalcMSHeatPump(state,
3451 : MSHeatPumpNum,
3452 : FirstHVACIteration,
3453 : CompressorOp,
3454 : i,
3455 : SpeedRatio,
3456 : PartLoadFrac,
3457 : TempOutput,
3458 : QZnReq,
3459 : OnOffAirFlowRatio,
3460 : SupHeaterLoad);
3461 38716 : if (QZnReq >= TempOutput) {
3462 19048 : SpeedNum = i;
3463 19048 : break;
3464 : }
3465 : }
3466 : } else {
3467 28 : for (i = 2; i <= MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating; ++i) {
3468 28 : CalcMSHeatPump(state,
3469 : MSHeatPumpNum,
3470 : FirstHVACIteration,
3471 : CompressorOp,
3472 : i,
3473 : SpeedRatio,
3474 : PartLoadFrac,
3475 : TempOutput,
3476 : QZnReq,
3477 : OnOffAirFlowRatio,
3478 : SupHeaterLoad);
3479 28 : if (QZnReq <= TempOutput) {
3480 12 : SpeedNum = i;
3481 12 : break;
3482 : }
3483 : }
3484 : }
3485 : auto f = [&state, OnOffAirFlowRatio, SupHeaterLoad, MSHeatPumpNum, FirstHVACIteration, CompressorOp, SpeedNum, QZnReq](
3486 354264 : Real64 const SpeedRatio) {
3487 : // Calculates residual function ((ActualOutput - QZnReq)/QZnReq) MSHP output depends on PLR which is being varied to zero the
3488 : // residual.
3489 59044 : Real64 localAirFlowRatio = OnOffAirFlowRatio;
3490 59044 : Real64 localHeaterLoad = SupHeaterLoad;
3491 : Real64 ActualOutput;
3492 118088 : CalcMSHeatPump(state,
3493 : MSHeatPumpNum,
3494 : FirstHVACIteration,
3495 : CompressorOp,
3496 : SpeedNum,
3497 : SpeedRatio,
3498 : 1.0,
3499 : ActualOutput,
3500 : QZnReq,
3501 : localAirFlowRatio,
3502 : localHeaterLoad);
3503 177132 : return (ActualOutput - QZnReq) / QZnReq;
3504 19060 : };
3505 19060 : SolveRoot(state, ErrorToler, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
3506 19060 : if (SolFla == -1) {
3507 0 : if (!state.dataGlobal->WarmupFlag) {
3508 0 : if (state.dataHVACMultiSpdHP->ErrCountVar == 0) {
3509 0 : ++state.dataHVACMultiSpdHP->ErrCountVar;
3510 0 : ShowWarningError(
3511 0 : state, "Iteration limit exceeded calculating DX unit speed ratio, for unit=" + MSHeatPump(MSHeatPumpNum).Name);
3512 0 : ShowContinueErrorTimeStamp(state, format("Speed ratio returned=[{:.2R}], Speed number ={}", SpeedRatio, SpeedNum));
3513 : } else {
3514 0 : ++state.dataHVACMultiSpdHP->ErrCountVar;
3515 0 : ShowRecurringWarningErrorAtEnd(
3516 : state,
3517 0 : MSHeatPump(MSHeatPumpNum).Name +
3518 : "\": Iteration limit warning exceeding calculating DX unit speed ratio continues...",
3519 0 : MSHeatPump(MSHeatPumpNum).ErrIndexVar,
3520 : SpeedRatio,
3521 : SpeedRatio);
3522 : }
3523 : }
3524 19060 : } else if (SolFla == -2) {
3525 0 : ShowFatalError(state,
3526 0 : "DX unit compressor speed calculation failed: speed limits exceeded, for unit=" +
3527 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName);
3528 : }
3529 : }
3530 : } else {
3531 : // Staged thermostat performance
3532 58152 : if (MSHeatPump(MSHeatPumpNum).StageNum != 0) {
3533 7681 : SpeedNum = std::abs(MSHeatPump(MSHeatPumpNum).StageNum);
3534 7681 : if (SpeedNum == 1) {
3535 688 : CalcMSHeatPump(
3536 : state, MSHeatPumpNum, FirstHVACIteration, CompressorOp, 1, 0.0, 1.0, LowOutput, QZnReq, OnOffAirFlowRatio, SupHeaterLoad);
3537 688 : SpeedRatio = 0.0;
3538 688 : if ((QZnReq > 0.0 && QZnReq <= LowOutput) || (QZnReq < 0.0 && QZnReq >= LowOutput)) {
3539 : auto f = [&state, MSHeatPumpNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, CompressorOp](
3540 6780 : Real64 const PartLoadFrac) {
3541 : // Calculates residual function ((ActualOutput - QZnReq)/QZnReq); MSHP output depends on PLR which is being varied to
3542 : // zero the residual.
3543 : Real64 ActualOutput; // delivered capacity of MSHP
3544 1130 : Real64 tmpAirFlowRatio = OnOffAirFlowRatio;
3545 1130 : Real64 tmpHeaterLoad = SupHeaterLoad;
3546 2260 : CalcMSHeatPump(state,
3547 : MSHeatPumpNum,
3548 : FirstHVACIteration,
3549 : CompressorOp,
3550 : 1,
3551 : 0.0,
3552 : PartLoadFrac,
3553 : ActualOutput,
3554 : QZnReq,
3555 : tmpAirFlowRatio,
3556 : tmpHeaterLoad);
3557 3390 : return (ActualOutput - QZnReq) / QZnReq;
3558 140 : };
3559 140 : SolveRoot(state, ErrorToler, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
3560 140 : if (SolFla == -1) {
3561 0 : if (!state.dataGlobal->WarmupFlag) {
3562 0 : if (state.dataHVACMultiSpdHP->ErrCountCyc == 0) {
3563 0 : ++state.dataHVACMultiSpdHP->ErrCountCyc;
3564 0 : ShowWarningError(state,
3565 0 : "Iteration limit exceeded calculating DX unit cycling ratio, for unit=" +
3566 0 : MSHeatPump(MSHeatPumpNum).Name);
3567 0 : ShowContinueErrorTimeStamp(state, format("Cycling ratio returned={:.2R}", PartLoadFrac));
3568 : } else {
3569 0 : ++state.dataHVACMultiSpdHP->ErrCountCyc;
3570 0 : ShowRecurringWarningErrorAtEnd(
3571 : state,
3572 0 : MSHeatPump(MSHeatPumpNum).Name +
3573 : "\": Iteration limit warning exceeding calculating DX unit cycling ratio continues...",
3574 0 : MSHeatPump(MSHeatPumpNum).ErrIndexCyc,
3575 : PartLoadFrac,
3576 : PartLoadFrac);
3577 : }
3578 : }
3579 140 : } else if (SolFla == -2) {
3580 0 : ShowFatalError(state,
3581 0 : "DX unit cycling ratio calculation failed: cycling limits exceeded, for unit=" +
3582 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName);
3583 140 : }
3584 : } else {
3585 548 : FullOutput = LowOutput;
3586 548 : PartLoadFrac = 1.0;
3587 : }
3588 : } else {
3589 6993 : if (MSHeatPump(MSHeatPumpNum).StageNum < 0) {
3590 241 : SpeedNum = min(MSHeatPump(MSHeatPumpNum).NumOfSpeedCooling, std::abs(MSHeatPump(MSHeatPumpNum).StageNum));
3591 : } else {
3592 6752 : SpeedNum = min(MSHeatPump(MSHeatPumpNum).NumOfSpeedHeating, std::abs(MSHeatPump(MSHeatPumpNum).StageNum));
3593 : }
3594 6993 : CalcMSHeatPump(state,
3595 : MSHeatPumpNum,
3596 : FirstHVACIteration,
3597 : CompressorOp,
3598 : SpeedNum,
3599 : 0.0,
3600 : 1.0,
3601 : LowOutput,
3602 : QZnReq,
3603 : OnOffAirFlowRatio,
3604 : SupHeaterLoad);
3605 6993 : if ((QZnReq > 0.0 && QZnReq >= LowOutput) || (QZnReq < 0.0 && QZnReq <= LowOutput)) {
3606 6969 : CalcMSHeatPump(state,
3607 : MSHeatPumpNum,
3608 : FirstHVACIteration,
3609 : CompressorOp,
3610 : SpeedNum,
3611 : 1.0,
3612 : 1.0,
3613 : FullOutput,
3614 : QZnReq,
3615 : OnOffAirFlowRatio,
3616 : SupHeaterLoad);
3617 6969 : if ((QZnReq > 0.0 && QZnReq <= FullOutput) || (QZnReq < 0.0 && QZnReq >= FullOutput)) {
3618 : auto f =
3619 : [&state, OnOffAirFlowRatio, SupHeaterLoad, MSHeatPumpNum, FirstHVACIteration, CompressorOp, SpeedNum, QZnReq](
3620 3984 : Real64 const SpeedRatio) {
3621 : // Calculates residual function ((ActualOutput - QZnReq)/QZnReq) MSHP output depends on PLR which is being
3622 : // varied to zero the residual.
3623 664 : Real64 localAirFlowRatio = OnOffAirFlowRatio;
3624 664 : Real64 localHeaterLoad = SupHeaterLoad;
3625 : Real64 ActualOutput;
3626 1328 : CalcMSHeatPump(state,
3627 : MSHeatPumpNum,
3628 : FirstHVACIteration,
3629 : CompressorOp,
3630 : SpeedNum,
3631 : SpeedRatio,
3632 : 1.0,
3633 : ActualOutput,
3634 : QZnReq,
3635 : localAirFlowRatio,
3636 : localHeaterLoad);
3637 1992 : return (ActualOutput - QZnReq) / QZnReq;
3638 217 : };
3639 217 : SolveRoot(state, ErrorToler, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
3640 217 : if (SolFla == -1) {
3641 0 : if (!state.dataGlobal->WarmupFlag) {
3642 0 : if (state.dataHVACMultiSpdHP->ErrCountVar == 0) {
3643 0 : ++state.dataHVACMultiSpdHP->ErrCountVar;
3644 0 : ShowWarningError(state,
3645 0 : "Iteration limit exceeded calculating DX unit speed ratio, for unit=" +
3646 0 : MSHeatPump(MSHeatPumpNum).Name);
3647 0 : ShowContinueErrorTimeStamp(
3648 0 : state, format("Speed ratio returned=[{:.2R}], Speed number ={}", SpeedRatio, SpeedNum));
3649 : } else {
3650 0 : ++state.dataHVACMultiSpdHP->ErrCountVar;
3651 0 : ShowRecurringWarningErrorAtEnd(
3652 : state,
3653 0 : MSHeatPump(MSHeatPumpNum).Name +
3654 : "\": Iteration limit warning exceeding calculating DX unit speed ratio continues...",
3655 0 : MSHeatPump(MSHeatPumpNum).ErrIndexVar,
3656 : SpeedRatio,
3657 : SpeedRatio);
3658 : }
3659 : }
3660 217 : } else if (SolFla == -2) {
3661 0 : ShowFatalError(state,
3662 0 : "DX unit compressor speed calculation failed: speed limits exceeded, for unit=" +
3663 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName);
3664 217 : }
3665 : } else {
3666 6752 : SpeedRatio = 1.0;
3667 6969 : }
3668 : } else { // lowOutput provides a larger capacity than needed
3669 24 : SpeedRatio = 0.0;
3670 : }
3671 : }
3672 : }
3673 : }
3674 : }
3675 :
3676 : // if the DX heating coil cannot meet the load, trim with supplemental heater
3677 : // occurs with constant fan mode when compressor is on or off
3678 : // occurs with cycling fan mode when compressor PLR is equal to 1
3679 141385 : if ((QZnReq > SmallLoad && QZnReq > FullOutput)) {
3680 62525 : PartLoadFrac = 1.0;
3681 62525 : SpeedRatio = 1.0;
3682 62525 : if (MSHeatPump(MSHeatPumpNum).Staged && SpeedNum == 1) SpeedRatio = 0.0;
3683 62525 : if (OutsideDryBulbTemp <= MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp) {
3684 62525 : SupHeaterLoad = QZnReq - FullOutput;
3685 : } else {
3686 0 : SupHeaterLoad = 0.0;
3687 : }
3688 62525 : CalcMSHeatPump(state,
3689 : MSHeatPumpNum,
3690 : FirstHVACIteration,
3691 : CompressorOp,
3692 : SpeedNum,
3693 : SpeedRatio,
3694 : PartLoadFrac,
3695 : TempOutput,
3696 : QZnReq,
3697 : OnOffAirFlowRatio,
3698 : SupHeaterLoad);
3699 : }
3700 :
3701 : // check the outlet of the supplemental heater to be lower than the maximum supplemental heater supply air temperature
3702 152012 : if (state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).Temp > MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp &&
3703 10627 : SupHeaterLoad > 0.0) {
3704 :
3705 : // If the supply air temperature is to high, turn off the supplemental heater to recalculate the outlet temperature
3706 10627 : SupHeaterLoad = 0.0;
3707 10627 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, SupHeaterLoad, OpMode, QCoilActual);
3708 :
3709 : // If the outlet temperature is below the maximum supplemental heater supply air temperature, reduce the load passed to
3710 : // the supplemental heater, otherwise leave the supplemental heater off. If the supplemental heater is to be turned on,
3711 : // use the outlet conditions when the supplemental heater was off (CALL above) as the inlet conditions for the calculation
3712 : // of supplemental heater load to just meet the maximum supply air temperature from the supplemental heater.
3713 10627 : if (state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).Temp < MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp) {
3714 10627 : CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).HumRat);
3715 10627 : SupHeaterLoad =
3716 21254 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirInletNodeNum).MassFlowRate * CpAir *
3717 10627 : (MSHeatPump(MSHeatPumpNum).SuppMaxAirTemp - state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).AirOutletNodeNum).Temp);
3718 :
3719 : } else {
3720 0 : SupHeaterLoad = 0.0;
3721 : }
3722 : }
3723 :
3724 141385 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).CycRatio = PartLoadFrac;
3725 141385 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedRatio = SpeedRatio;
3726 141385 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).SpeedNum = SpeedNum;
3727 : }
3728 :
3729 : //******************************************************************************
3730 :
3731 1375024 : void CalcMSHeatPump(EnergyPlusData &state,
3732 : int const MSHeatPumpNum, // Engine driven heat pump number
3733 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
3734 : DataHVACGlobals::CompressorOperation const CompressorOp, // Compressor on/off; 1=on, 0=off
3735 : int const SpeedNum, // Speed number
3736 : Real64 const SpeedRatio, // Compressor speed ratio
3737 : Real64 const PartLoadFrac, // Compressor part load fraction
3738 : Real64 &LoadMet, // Load met by unit (W)
3739 : Real64 const QZnReq, // Zone load (W)
3740 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
3741 : Real64 &SupHeaterLoad // supplemental heater load (W)
3742 : )
3743 : {
3744 : // SUBROUTINE INFORMATION:
3745 : // AUTHOR: Lixing Gu, FSEC
3746 : // DATE WRITTEN: June 2007
3747 : // MODIFIED na
3748 : // RE-ENGINEERED na
3749 :
3750 : // PURPOSE OF THIS SUBROUTINE:
3751 : // This routine will calcultes MSHP performance based on given system load
3752 :
3753 : // METHODOLOGY EMPLOYED:
3754 : // na
3755 :
3756 : // REFERENCES: na
3757 :
3758 : // Using/Aliasing
3759 : using DXCoils::SimDXCoilMultiSpeed;
3760 : using Fans::SimulateFanComponents;
3761 : using HeatingCoils::SimulateHeatingCoilComponents;
3762 :
3763 : // Locals
3764 : // SUBROUTINE ARGUMENT DEFINITIONS:
3765 :
3766 : // SUBROUTINE PARAMETER DEFINITIONS:
3767 : // INTEGER, PARAMETER :: On = 1 ! Compressor on flag
3768 : // INTEGER, PARAMETER :: Off = 2 ! Compressor off flag
3769 :
3770 : // INTERFACE BLOCK SPECIFICATIONS
3771 : // na
3772 :
3773 : // DERIVMS TYPE DEFINITIONS
3774 : // na
3775 :
3776 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3777 : int OutletNode; // MSHP air outlet node
3778 : int InletNode; // MSHP air inlet node
3779 : Real64 OutsideDryBulbTemp; // Outdoor dry bulb temperature [C]
3780 : Real64 AirMassFlow; // Air mass flow rate [kg/s]
3781 : int FanInletNode; // MSHP air outlet node
3782 : int FanOutletNode; // MSHP air inlet node
3783 : Real64 SavePartloadRatio;
3784 : Real64 SaveSpeedRatio;
3785 : Real64 QCoilActual; // coil load actually delivered returned to calling component
3786 : Real64 MinWaterFlow; // minimum water flow rate
3787 : Real64 ErrorToler; // supplemental heating coil convergence tollerance
3788 :
3789 1375024 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
3790 :
3791 1375024 : OutletNode = MSHeatPump(MSHeatPumpNum).AirOutletNodeNum;
3792 1375024 : InletNode = MSHeatPump(MSHeatPumpNum).AirInletNodeNum;
3793 1375024 : if (MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex > 0) {
3794 1064645 : if (state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex).IsSecondaryDXCoilInZone) {
3795 0 : OutsideDryBulbTemp = state.dataZoneTempPredictorCorrector
3796 0 : ->zoneHeatBalance(state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex).SecZonePtr)
3797 : .ZT;
3798 : } else {
3799 1064645 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
3800 : }
3801 310379 : } else if (MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex > 0) {
3802 310379 : if (state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex).IsSecondaryDXCoilInZone) {
3803 0 : OutsideDryBulbTemp = state.dataZoneTempPredictorCorrector
3804 0 : ->zoneHeatBalance(state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex).SecZonePtr)
3805 : .ZT;
3806 : } else {
3807 310379 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
3808 : }
3809 : } else {
3810 0 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
3811 : }
3812 1375024 : FanOutletNode = MSHeatPump(MSHeatPumpNum).FanOutletNode;
3813 1375024 : FanInletNode = MSHeatPump(MSHeatPumpNum).FanInletNode;
3814 :
3815 1375024 : state.dataHVACMultiSpdHP->SaveCompressorPLR = 0.0;
3816 1375024 : SavePartloadRatio = 0.0;
3817 1375024 : MinWaterFlow = 0.0;
3818 1375024 : ErrorToler = 0.001;
3819 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
3820 1375024 : SetAverageAirFlow(state, MSHeatPumpNum, PartLoadFrac, OnOffAirFlowRatio, SpeedNum, SpeedRatio);
3821 :
3822 1375024 : AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
3823 : // if blow through, simulate fan then coils
3824 1375024 : if (MSHeatPump(MSHeatPumpNum).FanPlaceType == BlowThru) {
3825 5500096 : SimulateFanComponents(state,
3826 1375024 : MSHeatPump(MSHeatPumpNum).FanName,
3827 : FirstHVACIteration,
3828 1375024 : MSHeatPump(MSHeatPumpNum).FanNum,
3829 1375024 : state.dataHVACMultiSpdHP->FanSpeedRatio);
3830 1375024 : if (QZnReq < (-1.0 * SmallLoad)) {
3831 644036 : if (OutsideDryBulbTemp > MSHeatPump(MSHeatPumpNum).MinOATCompressorCooling) {
3832 2576144 : SimDXCoilMultiSpeed(state,
3833 644036 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
3834 : SpeedRatio,
3835 : PartLoadFrac,
3836 644036 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
3837 : SpeedNum,
3838 644036 : MSHeatPump(MSHeatPumpNum).OpMode,
3839 : CompressorOp);
3840 644036 : SavePartloadRatio = PartLoadFrac;
3841 644036 : SaveSpeedRatio = SpeedRatio;
3842 : } else {
3843 0 : SimDXCoilMultiSpeed(state,
3844 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
3845 : 0.0,
3846 : 0.0,
3847 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
3848 : SpeedNum,
3849 0 : MSHeatPump(MSHeatPumpNum).OpMode,
3850 : CompressorOp);
3851 : }
3852 644036 : state.dataHVACMultiSpdHP->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex);
3853 : } else {
3854 2923952 : SimDXCoilMultiSpeed(state,
3855 730988 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
3856 : 0.0,
3857 : 0.0,
3858 730988 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
3859 : SpeedNum,
3860 730988 : MSHeatPump(MSHeatPumpNum).OpMode,
3861 : CompressorOp);
3862 : }
3863 1375024 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == MultiSpeedHeatingCoil) {
3864 1064645 : if (QZnReq > SmallLoad) {
3865 399621 : if (OutsideDryBulbTemp > MSHeatPump(MSHeatPumpNum).MinOATCompressorHeating) {
3866 17088 : SimDXCoilMultiSpeed(state,
3867 4272 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
3868 : SpeedRatio,
3869 : PartLoadFrac,
3870 4272 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
3871 : SpeedNum,
3872 4272 : MSHeatPump(MSHeatPumpNum).OpMode,
3873 : CompressorOp);
3874 4272 : SavePartloadRatio = PartLoadFrac;
3875 4272 : SaveSpeedRatio = SpeedRatio;
3876 : } else {
3877 1581396 : SimDXCoilMultiSpeed(state,
3878 395349 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
3879 : 0.0,
3880 : 0.0,
3881 395349 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
3882 : SpeedNum,
3883 395349 : MSHeatPump(MSHeatPumpNum).OpMode,
3884 : CompressorOp);
3885 : }
3886 399621 : state.dataHVACMultiSpdHP->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex);
3887 : } else {
3888 2660096 : SimDXCoilMultiSpeed(state,
3889 665024 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
3890 : 0.0,
3891 : 0.0,
3892 665024 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
3893 : SpeedNum,
3894 665024 : MSHeatPump(MSHeatPumpNum).OpMode,
3895 : CompressorOp);
3896 : }
3897 502581 : } else if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingElectric_MultiStage ||
3898 192202 : MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingGas_MultiStage) {
3899 310379 : if (QZnReq > SmallLoad) {
3900 604029 : SimulateHeatingCoilComponents(state,
3901 201343 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
3902 : FirstHVACIteration,
3903 : _,
3904 : 0,
3905 : _,
3906 : _,
3907 201343 : MSHeatPump(MSHeatPumpNum).OpMode,
3908 : PartLoadFrac,
3909 : SpeedNum,
3910 : SpeedRatio);
3911 : } else {
3912 327108 : SimulateHeatingCoilComponents(state,
3913 109036 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
3914 : FirstHVACIteration,
3915 : _,
3916 : 0,
3917 : _,
3918 : _,
3919 109036 : MSHeatPump(MSHeatPumpNum).OpMode,
3920 : 0.0,
3921 : SpeedNum,
3922 : 0.0);
3923 : }
3924 : } else {
3925 0 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, QZnReq, MSHeatPump(MSHeatPumpNum).OpMode, QCoilActual, PartLoadFrac);
3926 : }
3927 : // Call twice to ensure the fan outlet conditions are updated
3928 5500096 : SimulateFanComponents(state,
3929 1375024 : MSHeatPump(MSHeatPumpNum).FanName,
3930 : FirstHVACIteration,
3931 1375024 : MSHeatPump(MSHeatPumpNum).FanNum,
3932 1375024 : state.dataHVACMultiSpdHP->FanSpeedRatio);
3933 1375024 : if (QZnReq < (-1.0 * SmallLoad)) {
3934 644036 : if (OutsideDryBulbTemp > MSHeatPump(MSHeatPumpNum).MinOATCompressorCooling) {
3935 2576144 : SimDXCoilMultiSpeed(state,
3936 644036 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
3937 : SpeedRatio,
3938 : PartLoadFrac,
3939 644036 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
3940 : SpeedNum,
3941 644036 : MSHeatPump(MSHeatPumpNum).OpMode,
3942 : CompressorOp);
3943 644036 : SavePartloadRatio = PartLoadFrac;
3944 644036 : SaveSpeedRatio = SpeedRatio;
3945 : } else {
3946 0 : SimDXCoilMultiSpeed(state,
3947 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
3948 : 0.0,
3949 : 0.0,
3950 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
3951 : SpeedNum,
3952 0 : MSHeatPump(MSHeatPumpNum).OpMode,
3953 : CompressorOp);
3954 : }
3955 644036 : state.dataHVACMultiSpdHP->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex);
3956 : } else {
3957 2923952 : SimDXCoilMultiSpeed(state,
3958 730988 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
3959 : 0.0,
3960 : 0.0,
3961 730988 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
3962 : SpeedNum,
3963 730988 : MSHeatPump(MSHeatPumpNum).OpMode,
3964 : CompressorOp);
3965 : }
3966 1375024 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == MultiSpeedHeatingCoil) {
3967 1064645 : if (QZnReq > SmallLoad) {
3968 399621 : if (OutsideDryBulbTemp > MSHeatPump(MSHeatPumpNum).MinOATCompressorHeating) {
3969 17088 : SimDXCoilMultiSpeed(state,
3970 4272 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
3971 : SpeedRatio,
3972 : PartLoadFrac,
3973 4272 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
3974 : SpeedNum,
3975 4272 : MSHeatPump(MSHeatPumpNum).OpMode,
3976 : CompressorOp);
3977 4272 : SavePartloadRatio = PartLoadFrac;
3978 4272 : SaveSpeedRatio = SpeedRatio;
3979 : } else {
3980 1581396 : SimDXCoilMultiSpeed(state,
3981 395349 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
3982 : 0.0,
3983 : 0.0,
3984 395349 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
3985 : SpeedNum,
3986 395349 : MSHeatPump(MSHeatPumpNum).OpMode,
3987 : CompressorOp);
3988 : }
3989 399621 : state.dataHVACMultiSpdHP->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex);
3990 : } else {
3991 2660096 : SimDXCoilMultiSpeed(state,
3992 665024 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
3993 : 0.0,
3994 : 0.0,
3995 665024 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
3996 : SpeedNum,
3997 665024 : MSHeatPump(MSHeatPumpNum).OpMode,
3998 : CompressorOp);
3999 : }
4000 502581 : } else if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingElectric_MultiStage ||
4001 192202 : MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingGas_MultiStage) {
4002 310379 : if (QZnReq > SmallLoad) {
4003 604029 : SimulateHeatingCoilComponents(state,
4004 201343 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
4005 : FirstHVACIteration,
4006 : _,
4007 : 0,
4008 : _,
4009 : _,
4010 201343 : MSHeatPump(MSHeatPumpNum).OpMode,
4011 : PartLoadFrac,
4012 : SpeedNum,
4013 : SpeedRatio);
4014 : } else {
4015 327108 : SimulateHeatingCoilComponents(state,
4016 109036 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
4017 : FirstHVACIteration,
4018 : _,
4019 : 0,
4020 : _,
4021 : _,
4022 109036 : MSHeatPump(MSHeatPumpNum).OpMode,
4023 : 0.0,
4024 : SpeedNum,
4025 : 0.0);
4026 : }
4027 : } else {
4028 0 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, QZnReq, MSHeatPump(MSHeatPumpNum).OpMode, QCoilActual, PartLoadFrac);
4029 : }
4030 : // Simulate supplemental heating coil for blow through fan
4031 1375024 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum > 0) {
4032 1375024 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, SupHeaterLoad, MSHeatPump(MSHeatPumpNum).OpMode, QCoilActual);
4033 : }
4034 : } else { // otherwise simulate DX coils then fan then supplemental heater
4035 0 : if (QZnReq < (-1.0 * SmallLoad)) {
4036 0 : if (OutsideDryBulbTemp > MSHeatPump(MSHeatPumpNum).MinOATCompressorCooling) {
4037 0 : SimDXCoilMultiSpeed(state,
4038 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
4039 : SpeedRatio,
4040 : PartLoadFrac,
4041 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
4042 : SpeedNum,
4043 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4044 : CompressorOp);
4045 0 : SavePartloadRatio = PartLoadFrac;
4046 0 : SaveSpeedRatio = SpeedRatio;
4047 : } else {
4048 0 : SimDXCoilMultiSpeed(state,
4049 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
4050 : 0.0,
4051 : 0.0,
4052 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
4053 : SpeedNum,
4054 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4055 : CompressorOp);
4056 : }
4057 0 : state.dataHVACMultiSpdHP->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex);
4058 : } else {
4059 0 : SimDXCoilMultiSpeed(state,
4060 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilName,
4061 : 0.0,
4062 : 0.0,
4063 0 : MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex,
4064 : SpeedNum,
4065 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4066 : CompressorOp);
4067 : }
4068 0 : if (MSHeatPump(MSHeatPumpNum).HeatCoilType == MultiSpeedHeatingCoil) {
4069 0 : if (QZnReq > SmallLoad) {
4070 0 : if (OutsideDryBulbTemp > MSHeatPump(MSHeatPumpNum).MinOATCompressorHeating) {
4071 0 : SimDXCoilMultiSpeed(state,
4072 0 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
4073 : SpeedRatio,
4074 : PartLoadFrac,
4075 0 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
4076 : SpeedNum,
4077 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4078 : CompressorOp);
4079 0 : SavePartloadRatio = PartLoadFrac;
4080 0 : SaveSpeedRatio = SpeedRatio;
4081 : } else {
4082 0 : SimDXCoilMultiSpeed(state,
4083 0 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
4084 : 0.0,
4085 : 0.0,
4086 0 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
4087 : SpeedNum,
4088 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4089 : CompressorOp);
4090 : }
4091 0 : state.dataHVACMultiSpdHP->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex);
4092 : } else {
4093 0 : SimDXCoilMultiSpeed(state,
4094 0 : MSHeatPump(MSHeatPumpNum).DXHeatCoilName,
4095 : 0.0,
4096 : 0.0,
4097 0 : MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex,
4098 : SpeedNum,
4099 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4100 : CompressorOp);
4101 : }
4102 0 : } else if (MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingElectric_MultiStage ||
4103 0 : MSHeatPump(MSHeatPumpNum).HeatCoilType == Coil_HeatingGas_MultiStage) {
4104 0 : if (QZnReq > SmallLoad) {
4105 0 : SimulateHeatingCoilComponents(state,
4106 0 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
4107 : FirstHVACIteration,
4108 : _,
4109 : 0,
4110 : _,
4111 : _,
4112 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4113 : PartLoadFrac,
4114 : SpeedNum,
4115 : SpeedRatio);
4116 : } else {
4117 0 : SimulateHeatingCoilComponents(state,
4118 0 : MSHeatPump(MSHeatPumpNum).HeatCoilName,
4119 : FirstHVACIteration,
4120 : _,
4121 : 0,
4122 : _,
4123 : _,
4124 0 : MSHeatPump(MSHeatPumpNum).OpMode,
4125 : 0.0,
4126 : SpeedNum,
4127 : 0.0);
4128 : }
4129 : } else {
4130 0 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, QZnReq, MSHeatPump(MSHeatPumpNum).OpMode, QCoilActual, PartLoadFrac);
4131 : }
4132 0 : SimulateFanComponents(state,
4133 0 : MSHeatPump(MSHeatPumpNum).FanName,
4134 : FirstHVACIteration,
4135 0 : MSHeatPump(MSHeatPumpNum).FanNum,
4136 0 : state.dataHVACMultiSpdHP->FanSpeedRatio);
4137 : // Simulate supplemental heating coil for draw through fan
4138 0 : if (MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum > 0) {
4139 0 : CalcNonDXHeatingCoils(state, MSHeatPumpNum, FirstHVACIteration, SupHeaterLoad, MSHeatPump(MSHeatPumpNum).OpMode, QCoilActual);
4140 : }
4141 : }
4142 :
4143 : // calculate sensible load met
4144 1375024 : Real64 SensibleOutput(0.0); // sensible output rate
4145 : // calculate sensible load met using delta enthalpy at a constant (minimum) humidity ratio)
4146 1375024 : Real64 MinHumRat = state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).NodeNumOfControlledZone).HumRat;
4147 1375024 : if (state.dataLoopNodes->Node(OutletNode).Temp < state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).NodeNumOfControlledZone).Temp)
4148 676329 : MinHumRat = state.dataLoopNodes->Node(OutletNode).HumRat;
4149 1375024 : SensibleOutput = AirMassFlow *
4150 1375024 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
4151 : MinHumRat,
4152 1375024 : state.dataLoopNodes->Node(MSHeatPump(MSHeatPumpNum).NodeNumOfControlledZone).Temp,
4153 : MinHumRat);
4154 1375024 : LoadMet = SensibleOutput - MSHeatPump(MSHeatPumpNum).LoadLoss;
4155 :
4156 1375024 : MSHeatPump(MSHeatPumpNum).LoadMet = LoadMet;
4157 1375024 : }
4158 :
4159 251050 : void UpdateMSHeatPump(EnergyPlusData &state, int const MSHeatPumpNum) // Engine driven heat pump number
4160 : {
4161 : // SUBROUTINE INFORMATION:
4162 : // AUTHOR: Lixing Gu, FSEC
4163 : // DATE WRITTEN: June 2007
4164 : // MODIFIED na
4165 : // RE-ENGINEERED na
4166 :
4167 : // PURPOSE OF THIS SUBROUTINE:
4168 : // This routine will update MSHP performance and calculate heat recovery rate and crankcase heater power
4169 :
4170 : // METHODOLOGY EMPLOYED:
4171 : // na
4172 :
4173 : // Locals
4174 : // SUBROUTINE ARGUMENT DEFINITIONS:
4175 :
4176 : // Calculate heat recovery
4177 251050 : if (state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecActive) {
4178 0 : MSHPHeatRecovery(state, MSHeatPumpNum);
4179 : }
4180 :
4181 251050 : if (state.afn->distribution_simulated) {
4182 15112 : state.dataAirLoop->AirLoopAFNInfo(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirLoopNumber).LoopSystemOnMassFlowrate =
4183 15112 : state.dataHVACMultiSpdHP->CompOnMassFlow;
4184 15112 : state.dataAirLoop->AirLoopAFNInfo(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirLoopNumber).LoopSystemOffMassFlowrate =
4185 15112 : state.dataHVACMultiSpdHP->CompOffMassFlow;
4186 15112 : state.dataAirLoop->AirLoopAFNInfo(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirLoopNumber).LoopFanOperationMode =
4187 15112 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).OpMode;
4188 15112 : state.dataAirLoop->AirLoopAFNInfo(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirLoopNumber).LoopOnOffFanPartLoadRatio =
4189 15112 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).FanPartLoadRatio;
4190 15112 : state.dataAirLoop->AirLoopAFNInfo(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirLoopNumber).LoopCompCycRatio =
4191 15112 : state.dataHVACMultiSpdHP->MSHeatPumpReport(MSHeatPumpNum).CycRatio;
4192 : }
4193 251050 : }
4194 :
4195 : //******************************************************************************
4196 :
4197 251050 : void ReportMSHeatPump(EnergyPlusData &state, int const MSHeatPumpNum) // Engine driven heat pump number
4198 : {
4199 : // SUBROUTINE INFORMATION:
4200 : // AUTHOR: Lixing Gu, FSEC
4201 : // DATE WRITTEN: June 2007
4202 : // MODIFIED na
4203 : // RE-ENGINEERED na
4204 :
4205 : // PURPOSE OF THIS SUBROUTINE:
4206 : // This routine will write values to output variables in MSHP
4207 :
4208 : // METHODOLOGY EMPLOYED:
4209 :
4210 : // REFERENCES: na
4211 :
4212 : // Using/Aliasing
4213 251050 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
4214 :
4215 : // Locals
4216 : // SUBROUTINE ARGUMENT DEFINITIONS:
4217 : // SUBROUTINE PARAMETER DEFINITIONS:
4218 : // na
4219 :
4220 : // INTERFACE BLOCK SPECIFICATIONS:
4221 : // na
4222 :
4223 : // DERIVED TYPE DEFINITIONS:
4224 : // na
4225 :
4226 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4227 : Real64 ReportingConstant;
4228 :
4229 251050 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
4230 251050 : auto &MSHeatPumpReport(state.dataHVACMultiSpdHP->MSHeatPumpReport);
4231 :
4232 251050 : ReportingConstant = TimeStepSys * DataGlobalConstants::SecInHour;
4233 251050 : MSHeatPumpReport(MSHeatPumpNum).ElecPowerConsumption = MSHeatPump(MSHeatPumpNum).ElecPower * ReportingConstant; // + &
4234 251050 : MSHeatPumpReport(MSHeatPumpNum).HeatRecoveryEnergy = MSHeatPump(MSHeatPumpNum).HeatRecoveryRate * ReportingConstant;
4235 :
4236 251050 : MSHeatPumpReport(MSHeatPumpNum).AuxElecHeatConsumption = 0.0;
4237 251050 : MSHeatPumpReport(MSHeatPumpNum).AuxElecCoolConsumption = 0.0;
4238 :
4239 502100 : MSHeatPump(MSHeatPumpNum).AuxElecPower = MSHeatPump(MSHeatPumpNum).AuxOnCyclePower * state.dataHVACMultiSpdHP->SaveCompressorPLR +
4240 251050 : MSHeatPump(MSHeatPumpNum).AuxOffCyclePower * (1.0 - state.dataHVACMultiSpdHP->SaveCompressorPLR);
4241 251050 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::CoolingMode) {
4242 100962 : MSHeatPumpReport(MSHeatPumpNum).AuxElecCoolConsumption =
4243 100962 : MSHeatPump(MSHeatPumpNum).AuxOnCyclePower * state.dataHVACMultiSpdHP->SaveCompressorPLR * ReportingConstant;
4244 : }
4245 251050 : if (MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::HeatingMode) {
4246 104900 : MSHeatPumpReport(MSHeatPumpNum).AuxElecHeatConsumption =
4247 104900 : MSHeatPump(MSHeatPumpNum).AuxOnCyclePower * state.dataHVACMultiSpdHP->SaveCompressorPLR * ReportingConstant;
4248 : }
4249 251050 : if (MSHeatPump(MSHeatPumpNum).LastMode == ModeOfOperation::HeatingMode) {
4250 198268 : MSHeatPumpReport(MSHeatPumpNum).AuxElecHeatConsumption +=
4251 198268 : MSHeatPump(MSHeatPumpNum).AuxOffCyclePower * (1.0 - state.dataHVACMultiSpdHP->SaveCompressorPLR) * ReportingConstant;
4252 : } else {
4253 52782 : MSHeatPumpReport(MSHeatPumpNum).AuxElecCoolConsumption +=
4254 52782 : MSHeatPump(MSHeatPumpNum).AuxOffCyclePower * (1.0 - state.dataHVACMultiSpdHP->SaveCompressorPLR) * ReportingConstant;
4255 : }
4256 :
4257 251050 : if (MSHeatPump(MSHeatPumpNum).FirstPass) {
4258 11 : if (!state.dataGlobal->SysSizingCalc) {
4259 33 : DataSizing::resetHVACSizingGlobals(
4260 33 : state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, MSHeatPump(MSHeatPumpNum).FirstPass);
4261 : }
4262 : }
4263 :
4264 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
4265 251050 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
4266 251050 : }
4267 :
4268 0 : void MSHPHeatRecovery(EnergyPlusData &state, int const MSHeatPumpNum) // Number of the current electric MSHP being simulated
4269 : {
4270 : // SUBROUTINE INFORMATION:
4271 : // AUTHOR: Lixing Gu
4272 : // DATE WRITTEN: June 2007
4273 : // MODIFIED: na
4274 : // RE-ENGINEERED Revised to calculate MSHP heat recovery rate based on EIR Chiller heat recovery subroutine
4275 : // PURPOSE OF THIS SUBROUTINE:
4276 : // Calculate the heat recovered from MSHP
4277 :
4278 : // Using/Aliasing
4279 0 : auto &MSHPWasteHeat = state.dataHVACGlobal->MSHPWasteHeat;
4280 : using FluidProperties::GetSpecificHeatGlycol;
4281 : using PlantUtilities::SafeCopyPlantNode;
4282 :
4283 : // SUBROUTINE PARAMETER DEFINITIONS:
4284 : static constexpr std::string_view RoutineName("MSHPHeatRecovery");
4285 :
4286 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4287 : int HeatRecInNode; // Node number of heat recovery water inlet node
4288 : int HeatRecOutNode; // Node number of heat recovery water outlet node
4289 : Real64 QHeatRec; // Total heat recovered [W]
4290 : Real64 HeatRecInletTemp; // Heat reclaim inlet temp [C]
4291 : Real64 HeatRecOutletTemp; // Heat reclaim outlet temp [C]
4292 : Real64 HeatRecMassFlowRate; // Heat reclaim mass flow rate [m3/s]
4293 : Real64 CpHeatRec; // Heat reclaim water inlet specific heat [J/kg-K]
4294 :
4295 : // Begin routine
4296 0 : HeatRecInNode = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecInletNodeNum;
4297 0 : HeatRecOutNode = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecOutletNodeNum;
4298 :
4299 : // Inlet node to the heat recovery heat exchanger
4300 0 : HeatRecInletTemp = state.dataLoopNodes->Node(HeatRecInNode).Temp;
4301 :
4302 : // Set heat recovery mass flow rates
4303 0 : HeatRecMassFlowRate = state.dataLoopNodes->Node(HeatRecInNode).MassFlowRate;
4304 :
4305 0 : QHeatRec = MSHPWasteHeat;
4306 :
4307 0 : if (HeatRecMassFlowRate > 0.0) {
4308 :
4309 0 : CpHeatRec =
4310 0 : GetSpecificHeatGlycol(state,
4311 0 : state.dataPlnt->PlantLoop(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HRPlantLoc.loopNum).FluidName,
4312 : HeatRecInletTemp,
4313 0 : state.dataPlnt->PlantLoop(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HRPlantLoc.loopNum).FluidIndex,
4314 : RoutineName);
4315 :
4316 0 : HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + HeatRecInletTemp;
4317 0 : if (HeatRecOutletTemp > state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).MaxHeatRecOutletTemp) {
4318 0 : HeatRecOutletTemp = max(HeatRecInletTemp, state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).MaxHeatRecOutletTemp);
4319 0 : QHeatRec = HeatRecMassFlowRate * CpHeatRec * (HeatRecOutletTemp - HeatRecInletTemp);
4320 : }
4321 : } else {
4322 0 : HeatRecOutletTemp = HeatRecInletTemp;
4323 0 : QHeatRec = 0.0;
4324 : }
4325 :
4326 0 : SafeCopyPlantNode(state, HeatRecInNode, HeatRecOutNode);
4327 : // changed outputs
4328 0 : state.dataLoopNodes->Node(HeatRecOutNode).Temp = HeatRecOutletTemp;
4329 :
4330 0 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecoveryRate = QHeatRec;
4331 0 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecoveryInletTemp = HeatRecInletTemp;
4332 0 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecoveryOutletTemp = HeatRecOutletTemp;
4333 0 : state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatRecoveryMassFlowRate = HeatRecMassFlowRate;
4334 0 : }
4335 :
4336 1601578 : void SetAverageAirFlow(EnergyPlusData &state,
4337 : int const MSHeatPumpNum, // Unit index
4338 : Real64 const PartLoadRatio, // unit part load ratio
4339 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to average airflow over timestep
4340 : Optional_int_const SpeedNum, // Speed number
4341 : Optional<Real64 const> SpeedRatio // Speed ratio
4342 : )
4343 : {
4344 :
4345 : // SUBROUTINE INFORMATION:
4346 : // AUTHOR Lixing
4347 : // DATE WRITTEN June 2007
4348 : // MODIFIED na
4349 : // RE-ENGINEERED Resived to meet requirements of multispeed heat pump based on the same subroutine
4350 : // in PTHP module
4351 :
4352 : // PURPOSE OF THIS SUBROUTINE:
4353 : // Set the average air mass flow rates using the part load fraction of the heat pump for this time step
4354 : // Set OnOffAirFlowRatio to be used by DX coils
4355 :
4356 : // Using/Aliasing
4357 1601578 : auto &MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
4358 1601578 : auto &MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
4359 :
4360 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4361 : int InletNode; // inlet node number for PTHPNum
4362 : Real64 AverageUnitMassFlow; // average supply air mass flow rate over time step
4363 :
4364 1601578 : MSHPMassFlowRateLow = 0.0; // Mass flow rate at low speed
4365 1601578 : MSHPMassFlowRateHigh = 0.0; // Mass flow rate at high speed
4366 :
4367 3033516 : if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).ControlZoneNum) &&
4368 1431938 : present(SpeedNum)) {
4369 1245024 : if (state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::HeatingMode) {
4370 600964 : if (SpeedNum == 1) {
4371 353664 : state.dataHVACMultiSpdHP->CompOnMassFlow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(SpeedNum);
4372 353664 : state.dataHVACMultiSpdHP->CompOnFlowRatio = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(SpeedNum);
4373 353664 : MSHPMassFlowRateLow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(1);
4374 353664 : MSHPMassFlowRateHigh = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(1);
4375 247300 : } else if (SpeedNum > 1) {
4376 247300 : state.dataHVACMultiSpdHP->CompOnMassFlow =
4377 494600 : SpeedRatio * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(SpeedNum) +
4378 247300 : (1.0 - SpeedRatio) * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(SpeedNum - 1);
4379 247300 : state.dataHVACMultiSpdHP->CompOnFlowRatio =
4380 494600 : SpeedRatio * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(SpeedNum) +
4381 247300 : (1.0 - SpeedRatio) * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(SpeedNum - 1);
4382 247300 : MSHPMassFlowRateLow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(SpeedNum - 1);
4383 247300 : MSHPMassFlowRateHigh = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(SpeedNum);
4384 : }
4385 644060 : } else if (state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatCoolMode == ModeOfOperation::CoolingMode) {
4386 644036 : if (SpeedNum == 1) {
4387 411908 : state.dataHVACMultiSpdHP->CompOnMassFlow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(SpeedNum);
4388 411908 : state.dataHVACMultiSpdHP->CompOnFlowRatio = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(SpeedNum);
4389 411908 : MSHPMassFlowRateLow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(1);
4390 411908 : MSHPMassFlowRateHigh = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(1);
4391 232128 : } else if (SpeedNum > 1) {
4392 232128 : state.dataHVACMultiSpdHP->CompOnMassFlow =
4393 464256 : SpeedRatio * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(SpeedNum) +
4394 232128 : (1.0 - SpeedRatio) * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(SpeedNum - 1);
4395 232128 : state.dataHVACMultiSpdHP->CompOnFlowRatio =
4396 464256 : SpeedRatio * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(SpeedNum) +
4397 232128 : (1.0 - SpeedRatio) * state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(SpeedNum - 1);
4398 232128 : MSHPMassFlowRateLow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(SpeedNum - 1);
4399 232128 : MSHPMassFlowRateHigh = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(SpeedNum);
4400 : }
4401 : }
4402 : }
4403 1601578 : InletNode = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirInletNodeNum;
4404 :
4405 : // Set up fan flow rate during compressor off time
4406 1601578 : if (state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).OpMode == ContFanCycCoil && present(SpeedNum)) {
4407 470768 : if (state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AirFlowControl == AirflowControl::UseCompressorOnFlow &&
4408 0 : state.dataHVACMultiSpdHP->CompOnMassFlow > 0.0) {
4409 0 : if (state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).LastMode == ModeOfOperation::HeatingMode) {
4410 0 : state.dataHVACMultiSpdHP->CompOffMassFlow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatMassFlowRate(SpeedNum);
4411 0 : state.dataHVACMultiSpdHP->CompOffFlowRatio = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).HeatingSpeedRatio(SpeedNum);
4412 : } else {
4413 0 : state.dataHVACMultiSpdHP->CompOffMassFlow = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolMassFlowRate(SpeedNum);
4414 0 : state.dataHVACMultiSpdHP->CompOffFlowRatio = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).CoolingSpeedRatio(SpeedNum);
4415 : }
4416 : }
4417 : }
4418 :
4419 1601578 : if (present(SpeedNum)) {
4420 1375024 : if (SpeedNum > 1) {
4421 479444 : AverageUnitMassFlow = state.dataHVACMultiSpdHP->CompOnMassFlow;
4422 479444 : state.dataHVACMultiSpdHP->FanSpeedRatio = state.dataHVACMultiSpdHP->CompOnFlowRatio;
4423 : } else {
4424 895580 : AverageUnitMassFlow =
4425 895580 : (PartLoadRatio * state.dataHVACMultiSpdHP->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataHVACMultiSpdHP->CompOffMassFlow);
4426 895580 : if (state.dataHVACMultiSpdHP->CompOffFlowRatio > 0.0) {
4427 552458 : state.dataHVACMultiSpdHP->FanSpeedRatio = (PartLoadRatio * state.dataHVACMultiSpdHP->CompOnFlowRatio) +
4428 276229 : ((1 - PartLoadRatio) * state.dataHVACMultiSpdHP->CompOffFlowRatio);
4429 : } else {
4430 619351 : state.dataHVACMultiSpdHP->FanSpeedRatio = state.dataHVACMultiSpdHP->CompOnFlowRatio;
4431 : }
4432 : }
4433 : } else {
4434 226554 : AverageUnitMassFlow =
4435 226554 : (PartLoadRatio * state.dataHVACMultiSpdHP->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataHVACMultiSpdHP->CompOffMassFlow);
4436 226554 : if (state.dataHVACMultiSpdHP->CompOffFlowRatio > 0.0) {
4437 58972 : state.dataHVACMultiSpdHP->FanSpeedRatio =
4438 58972 : (PartLoadRatio * state.dataHVACMultiSpdHP->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataHVACMultiSpdHP->CompOffFlowRatio);
4439 : } else {
4440 167582 : state.dataHVACMultiSpdHP->FanSpeedRatio = state.dataHVACMultiSpdHP->CompOnFlowRatio;
4441 : }
4442 : }
4443 :
4444 : //!!LKL Discrepancy with > 0
4445 1601578 : if (GetCurrentScheduleValue(state, state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum).AvaiSchedPtr) == 0.0) {
4446 48992 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
4447 48992 : OnOffAirFlowRatio = 0.0;
4448 : } else {
4449 1552586 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
4450 1552586 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AverageUnitMassFlow;
4451 1552586 : if (AverageUnitMassFlow > 0.0) {
4452 1161408 : OnOffAirFlowRatio = state.dataHVACMultiSpdHP->CompOnMassFlow / AverageUnitMassFlow;
4453 : } else {
4454 391178 : OnOffAirFlowRatio = 0.0;
4455 : }
4456 : }
4457 1601578 : }
4458 :
4459 1389147 : void CalcNonDXHeatingCoils(EnergyPlusData &state,
4460 : int const MSHeatPumpNum, // multispeed heatpump index
4461 : bool const FirstHVACIteration, // flag for first HVAC iteration in the time step
4462 : Real64 const HeatingLoad, // supplemental coil load to be met by unit (watts)
4463 : int const FanMode, // fan operation mode
4464 : Real64 &HeatCoilLoadmet, // Heating Load Met
4465 : Optional<Real64 const> PartLoadFrac)
4466 : {
4467 :
4468 : // SUBROUTINE INFORMATION:
4469 : // AUTHOR Bereket Nigusse, FSEC/UCF
4470 : // DATE WRITTEN January 2012
4471 : // MODIFIED na
4472 : // RE-ENGINEERED na
4473 :
4474 : // PURPOSE OF THIS SUBROUTINE:
4475 : // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
4476 :
4477 : // METHODOLOGY EMPLOYED:
4478 : // Simply calls the different heating coil component. The hot water flow rate matching the coil load
4479 : // is calculated iteratively.
4480 :
4481 : // REFERENCES:
4482 : // na
4483 :
4484 : // USE STATEMENTS:
4485 :
4486 : // Using/Aliasing
4487 : using DataHVACGlobals::SmallLoad;
4488 :
4489 : using General::SolveRoot;
4490 : using HeatingCoils::SimulateHeatingCoilComponents;
4491 : using PlantUtilities::SetComponentFlowRate;
4492 : using SteamCoils::SimulateSteamCoilComponents;
4493 : using WaterCoils::SimulateWaterCoilComponents;
4494 :
4495 : // Locals
4496 : static constexpr std::string_view CurrentModuleObject("AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed");
4497 :
4498 : // SUBROUTINE ARGUMENT DEFINITIONS:
4499 :
4500 : // SUBROUTINE PARAMETER DEFINITIONS:
4501 1389147 : Real64 constexpr ErrTolerance(0.001); // convergence limit for hotwater coil
4502 1389147 : int constexpr SolveMaxIter(50);
4503 :
4504 : // INTERFACE BLOCK SPECIFICATIONS
4505 : // na
4506 :
4507 : // DERIVED TYPE DEFINITIONS
4508 : // na
4509 :
4510 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4511 : Real64 QCoilActual; // actual heating load met
4512 : Real64 mdot; // heating coil steam or hot water mass flow rate
4513 : Real64 MinWaterFlow; // coil minimum hot water mass flow rate, kg/s
4514 : Real64 MaxHotWaterFlow; // coil maximum hot water mass flow rate, kg/s
4515 : Real64 HotWaterMdot; // actual hot water mass flow rate
4516 : int SolFlag;
4517 :
4518 : int HeatCoilType;
4519 : int HeatCoilNum;
4520 : Real64 MaxCoilFluidFlow;
4521 : Real64 SteamCoilHeatingLoad;
4522 : int CoilControlNode;
4523 : int CoilOutletNode;
4524 1389147 : PlantLocation plantLoc{};
4525 :
4526 1389147 : QCoilActual = 0.0;
4527 :
4528 1389147 : auto &MSHeatPump(state.dataHVACMultiSpdHP->MSHeatPump);
4529 :
4530 1389147 : if (present(PartLoadFrac)) {
4531 0 : HeatCoilType = MSHeatPump(MSHeatPumpNum).HeatCoilType;
4532 0 : state.dataHVACMultiSpdHP->HeatCoilName = MSHeatPump(MSHeatPumpNum).HeatCoilName;
4533 0 : HeatCoilNum = MSHeatPump(MSHeatPumpNum).HeatCoilNum;
4534 0 : MaxCoilFluidFlow = MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow;
4535 0 : CoilControlNode = MSHeatPump(MSHeatPumpNum).CoilControlNode;
4536 0 : CoilOutletNode = MSHeatPump(MSHeatPumpNum).CoilOutletNode;
4537 0 : plantLoc = MSHeatPump(MSHeatPumpNum).plantLoc;
4538 : } else {
4539 1389147 : HeatCoilType = MSHeatPump(MSHeatPumpNum).SuppHeatCoilType;
4540 1389147 : state.dataHVACMultiSpdHP->HeatCoilName = MSHeatPump(MSHeatPumpNum).SuppHeatCoilName;
4541 1389147 : HeatCoilNum = MSHeatPump(MSHeatPumpNum).SuppHeatCoilNum;
4542 1389147 : MaxCoilFluidFlow = MSHeatPump(MSHeatPumpNum).MaxSuppCoilFluidFlow;
4543 1389147 : CoilControlNode = MSHeatPump(MSHeatPumpNum).SuppCoilControlNode;
4544 1389147 : CoilOutletNode = MSHeatPump(MSHeatPumpNum).SuppCoilOutletNode;
4545 1389147 : plantLoc = MSHeatPump(MSHeatPumpNum).SuppPlantLoc;
4546 : }
4547 :
4548 1389147 : MSHeatPump(MSHeatPumpNum).HotWaterPlantLoc = plantLoc;
4549 1389147 : MSHeatPump(MSHeatPumpNum).HotWaterCoilControlNode = CoilControlNode;
4550 1389147 : MSHeatPump(MSHeatPumpNum).HotWaterCoilOutletNode = CoilOutletNode;
4551 1389147 : MSHeatPump(MSHeatPumpNum).HotWaterCoilName = state.dataHVACMultiSpdHP->HeatCoilName;
4552 1389147 : MSHeatPump(MSHeatPumpNum).HotWaterCoilNum = HeatCoilNum;
4553 :
4554 1389147 : if (HeatingLoad > SmallLoad) {
4555 :
4556 161904 : switch (HeatCoilType) {
4557 161904 : case SuppHeatingCoilGas:
4558 : case SuppHeatingCoilElec: {
4559 323808 : SimulateHeatingCoilComponents(
4560 161904 : state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatingLoad, HeatCoilNum, QCoilActual, true, FanMode);
4561 161904 : } break;
4562 0 : case Coil_HeatingWater: {
4563 0 : if (present(PartLoadFrac)) {
4564 0 : MaxHotWaterFlow = MaxCoilFluidFlow * PartLoadFrac;
4565 0 : SetComponentFlowRate(state, MaxHotWaterFlow, CoilControlNode, CoilOutletNode, plantLoc);
4566 0 : SimulateWaterCoilComponents(state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatCoilNum, QCoilActual, FanMode);
4567 : } else {
4568 0 : MaxHotWaterFlow = MaxCoilFluidFlow;
4569 0 : SetComponentFlowRate(state, MaxHotWaterFlow, CoilControlNode, CoilOutletNode, plantLoc);
4570 0 : SimulateWaterCoilComponents(state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatCoilNum, QCoilActual, FanMode);
4571 0 : if (QCoilActual > (HeatingLoad + SmallLoad)) {
4572 : // control water flow to obtain output matching HeatingLoad
4573 0 : SolFlag = 0;
4574 0 : MinWaterFlow = 0.0;
4575 0 : auto f = [&state, MSHeatPumpNum, FirstHVACIteration, HeatingLoad](Real64 const HWFlow) {
4576 : // Calculates residual function (QCoilActual - SupHeatCoilLoad) / SupHeatCoilLoad
4577 : // coil actual output depends on the hot water flow rate which is varied to minimize the residual.
4578 0 : Real64 targetHeatingCoilLoad = HeatingLoad;
4579 0 : Real64 calcHeatingCoilLoad = targetHeatingCoilLoad;
4580 0 : Real64 mdot = HWFlow;
4581 0 : auto &hp = state.dataHVACMultiSpdHP->MSHeatPump(MSHeatPumpNum);
4582 0 : PlantUtilities::SetComponentFlowRate(
4583 : state, mdot, hp.HotWaterCoilControlNode, hp.HotWaterCoilOutletNode, hp.HotWaterPlantLoc);
4584 : // simulate the hot water supplemental heating coil
4585 0 : WaterCoils::SimulateWaterCoilComponents(
4586 : state, hp.HotWaterCoilName, FirstHVACIteration, hp.HotWaterCoilNum, calcHeatingCoilLoad, hp.OpMode);
4587 0 : if (targetHeatingCoilLoad != 0.0) {
4588 0 : return (calcHeatingCoilLoad - targetHeatingCoilLoad) / targetHeatingCoilLoad;
4589 : } else { // Autodesk:Return Condition added to assure return value is set
4590 0 : return 0.0;
4591 : }
4592 0 : };
4593 0 : SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
4594 0 : if (SolFlag == -1) {
4595 0 : if (MSHeatPump(MSHeatPumpNum).HotWaterCoilMaxIterIndex == 0) {
4596 0 : ShowWarningMessage(state,
4597 0 : "CalcNonDXHeatingCoils: Hot water coil control failed for " + std::string{CurrentModuleObject} +
4598 0 : "=\"" + MSHeatPump(MSHeatPumpNum).Name + "\"");
4599 0 : ShowContinueErrorTimeStamp(state, "");
4600 0 : ShowContinueError(state,
4601 0 : format(" Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
4602 : }
4603 0 : ShowRecurringWarningErrorAtEnd(
4604 : state,
4605 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}",
4606 : SolveMaxIter,
4607 : CurrentModuleObject,
4608 0 : MSHeatPump(MSHeatPumpNum).Name),
4609 0 : MSHeatPump(MSHeatPumpNum).HotWaterCoilMaxIterIndex);
4610 0 : } else if (SolFlag == -2) {
4611 0 : if (MSHeatPump(MSHeatPumpNum).HotWaterCoilMaxIterIndex2 == 0) {
4612 0 : ShowWarningMessage(state,
4613 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for " +
4614 0 : std::string{CurrentModuleObject} + "=\"" + MSHeatPump(MSHeatPumpNum).Name + "\"");
4615 0 : ShowContinueErrorTimeStamp(state, "");
4616 0 : ShowContinueError(state, "...Bad hot water maximum flow rate limits");
4617 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
4618 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
4619 : }
4620 0 : ShowRecurringWarningErrorAtEnd(state,
4621 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for " +
4622 0 : std::string{CurrentModuleObject} + "=\"" + MSHeatPump(MSHeatPumpNum).Name + "\"",
4623 0 : MSHeatPump(MSHeatPumpNum).HotWaterCoilMaxIterIndex2,
4624 : MaxHotWaterFlow,
4625 : MinWaterFlow,
4626 : _,
4627 : "[kg/s]",
4628 : "[kg/s]");
4629 : }
4630 : // simulate hot water supplemental heating coil
4631 0 : SimulateWaterCoilComponents(
4632 0 : state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatCoilNum, QCoilActual, FanMode);
4633 : }
4634 : }
4635 0 : } break;
4636 0 : case Coil_HeatingSteam: {
4637 0 : if (present(PartLoadFrac)) {
4638 0 : mdot = MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow * PartLoadFrac;
4639 0 : SteamCoilHeatingLoad = HeatingLoad * PartLoadFrac;
4640 : } else {
4641 0 : mdot = MSHeatPump(MSHeatPumpNum).MaxCoilFluidFlow;
4642 0 : SteamCoilHeatingLoad = HeatingLoad;
4643 : }
4644 0 : SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
4645 : // simulate steam supplemental heating coil
4646 0 : SimulateSteamCoilComponents(
4647 0 : state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatCoilNum, SteamCoilHeatingLoad, QCoilActual, FanMode);
4648 0 : } break;
4649 0 : default:
4650 0 : break;
4651 : }
4652 :
4653 : } else { // end of IF (HeatingLoad > SmallLoad) THEN
4654 :
4655 1227243 : switch (HeatCoilType) {
4656 1227243 : case SuppHeatingCoilGas:
4657 : case SuppHeatingCoilElec: {
4658 2454486 : SimulateHeatingCoilComponents(
4659 1227243 : state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatingLoad, HeatCoilNum, QCoilActual, true, FanMode);
4660 1227243 : } break;
4661 0 : case Coil_HeatingWater: {
4662 0 : mdot = 0.0;
4663 0 : SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
4664 0 : SimulateWaterCoilComponents(state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatCoilNum, QCoilActual, FanMode);
4665 0 : } break;
4666 0 : case Coil_HeatingSteam: {
4667 0 : mdot = 0.0;
4668 0 : SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
4669 : // simulate the steam supplemental heating coil
4670 0 : SimulateSteamCoilComponents(
4671 0 : state, state.dataHVACMultiSpdHP->HeatCoilName, FirstHVACIteration, HeatCoilNum, HeatingLoad, QCoilActual, FanMode);
4672 0 : } break;
4673 0 : default:
4674 0 : break;
4675 : }
4676 : }
4677 1389147 : HeatCoilLoadmet = QCoilActual;
4678 1389147 : }
4679 :
4680 : } // namespace HVACMultiSpeedHeatPump
4681 :
4682 2313 : } // namespace EnergyPlus
|