Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ headers
49 : #include <string>
50 :
51 : // EnergyPlus headers
52 : #include <AirflowNetwork/Solver.hpp>
53 : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
54 : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
55 : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
56 : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
57 : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
58 : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
59 : #include <EnergyPlus/BranchInputManager.hh>
60 : #include <EnergyPlus/BranchNodeConnections.hh>
61 : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
62 : #include <EnergyPlus/DXCoils.hh>
63 : #include <EnergyPlus/Data/EnergyPlusData.hh>
64 : #include <EnergyPlus/DataHVACControllers.hh>
65 : #include <EnergyPlus/DataHVACGlobals.hh>
66 : #include <EnergyPlus/DataHVACSystems.hh>
67 : #include <EnergyPlus/DataHeatBalFanSys.hh>
68 : #include <EnergyPlus/DataHeatBalance.hh>
69 : #include <EnergyPlus/DataSizing.hh>
70 : #include <EnergyPlus/DataZoneControls.hh>
71 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
72 : #include <EnergyPlus/DataZoneEquipment.hh>
73 : #include <EnergyPlus/EMSManager.hh>
74 : #include <EnergyPlus/Fans.hh>
75 : #include <EnergyPlus/FaultsManager.hh>
76 : #include <EnergyPlus/FluidProperties.hh>
77 : #include <EnergyPlus/General.hh>
78 : #include <EnergyPlus/GeneralRoutines.hh>
79 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
80 : #include <EnergyPlus/HeatingCoils.hh>
81 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
82 : #include <EnergyPlus/MixedAir.hh>
83 : #include <EnergyPlus/NodeInputManager.hh>
84 : #include <EnergyPlus/OutputReportPredefined.hh>
85 : #include <EnergyPlus/PackagedThermalStorageCoil.hh>
86 : #include <EnergyPlus/Plant/DataPlant.hh>
87 : #include <EnergyPlus/PlantUtilities.hh>
88 : #include <EnergyPlus/Psychrometrics.hh>
89 : #include <EnergyPlus/ReportCoilSelection.hh>
90 : #include <EnergyPlus/SZVAVModel.hh>
91 : #include <EnergyPlus/ScheduleManager.hh>
92 : #include <EnergyPlus/SetPointManager.hh>
93 : #include <EnergyPlus/SimAirServingZones.hh>
94 : #include <EnergyPlus/SingleDuct.hh>
95 : #include <EnergyPlus/SteamCoils.hh>
96 : #include <EnergyPlus/UnitarySystem.hh>
97 : #include <EnergyPlus/UserDefinedComponents.hh>
98 : #include <EnergyPlus/UtilityRoutines.hh>
99 : #include <EnergyPlus/VariableSpeedCoils.hh>
100 : #include <EnergyPlus/WaterCoils.hh>
101 : #include <EnergyPlus/WaterToAirHeatPump.hh>
102 : #include <EnergyPlus/WaterToAirHeatPumpSimple.hh>
103 : #include <EnergyPlus/ZonePlenum.hh>
104 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
105 :
106 : namespace EnergyPlus {
107 : namespace UnitarySystems {
108 :
109 : // Coil type for SimWater and SimSteamCoil
110 : int constexpr CoolingCoil = 0;
111 : int constexpr HeatingCoil = 1;
112 : int constexpr SuppHeatCoil = 2;
113 :
114 : static constexpr std::string_view blankString("");
115 : static const std::string blankStdString("");
116 :
117 9735155 : void UnitarySys::simulate(EnergyPlusData &state,
118 : std::string_view Name,
119 : bool const FirstHVACIteration,
120 : int const AirLoopNum,
121 : int &CompIndex,
122 : bool &HeatActive,
123 : bool &CoolActive,
124 : int const ZoneOAUnitNum,
125 : Real64 const OAUCoilOutTemp,
126 : bool const ZoneEquipment,
127 : Real64 &sysOutputProvided,
128 : Real64 &latOutputProvided)
129 : {
130 9735155 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
131 :
132 : // Obtains and Allocates unitary system related parameters from input file
133 9735155 : if (this->m_ThisSysInputShouldBeGotten) {
134 644 : getUnitarySystemInput(state, Name, ZoneEquipment, ZoneOAUnitNum);
135 : }
136 9735155 : CompIndex = this->m_EquipCompNum;
137 9735155 : state.dataUnitarySystems->FanSpeedRatio = 1.0;
138 9735155 : this->initUnitarySystems(state, AirLoopNum, FirstHVACIteration, OAUCoilOutTemp);
139 9735155 : if (!this->m_OKToPrintSizing) {
140 0 : return;
141 : }
142 :
143 : // MassFlowRateMaxAvail issues are impeding non-VAV air loop equipment by limiting air flow
144 : // temporarily open up flow limits while simulating, and then set this same value at the INLET after this parent has simulated
145 9735155 : Real64 tempMassFlowRateMaxAvail = state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail;
146 : // this is not working for CoilSystem simulated with UnitarySystem. Try to protect when this happens.
147 9735155 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
148 2674018 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = this->m_DesignMassFlowRate;
149 : }
150 :
151 9735155 : bool HXUnitOn = false;
152 9735155 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
153 3680464 : this->controlUnitarySystemtoSP(
154 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
155 : } else {
156 6054691 : this->controlUnitarySystemtoLoad(
157 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
158 : }
159 :
160 : // Report the current output
161 9735155 : this->reportUnitarySystem(state, AirLoopNum);
162 :
163 : // CoolActive = false; // set in call from ZoneEquipmentManager
164 9735155 : if (this->m_CoolingPartLoadFrac * double(CompressorOn) > 0.0) {
165 3741919 : CoolActive = true;
166 : }
167 : // HeatActive = false; // set in call from ZoneEquipmentManager
168 9735155 : if (this->m_HeatingPartLoadFrac * double(CompressorOn) > 0.0 || this->m_SuppHeatPartLoadFrac * double(CompressorOn) > 0.0) {
169 2241121 : HeatActive = true;
170 : }
171 :
172 : // set econo lockout flag
173 : // If the system is not an equipment of Outdoor air unit
174 9735155 : if (AirLoopNum > 0 && !state.dataAirLoop->AirLoopControlInfo.empty() && this->m_AirLoopEquipment) {
175 :
176 6280157 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor =
177 6918798 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor &&
178 638641 : (this->m_HeatCompPartLoadRatio > 0.0 || this->m_SpeedRatio > 0.0 || this->m_CycRatio > 0.0);
179 :
180 6280157 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating =
181 7015819 : HeatActive && (state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor ||
182 735662 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithHeating);
183 : }
184 :
185 : // Calculate heat recovery
186 9735155 : if (this->m_HeatRecActive) {
187 0 : this->unitarySystemHeatRecovery(state);
188 : }
189 :
190 : // Coils should have been sized by now. Set this flag to false in case other equipment is downstream of Unitary System.
191 : // No, can't do this since there are other checks that need this flag (e.g., HVACManager, SetHeatToReturnAirFlag())
192 : // AirLoopControlInfo(AirLoopNum)%UnitarySys = .FALSE.
193 :
194 9735155 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
195 2674018 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = tempMassFlowRateMaxAvail;
196 : }
197 : }
198 :
199 124 : DesignSpecMSHP *DesignSpecMSHP::factory(EnergyPlusData &state, HVAC::UnitarySysType type, std::string const &objectName)
200 : {
201 :
202 124 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
203 21 : DesignSpecMSHP::getDesignSpecMSHP(state);
204 21 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
205 : }
206 352 : for (auto &dSpec : state.dataUnitarySystems->designSpecMSHP) {
207 352 : if (Util::SameString(dSpec.name, objectName) && dSpec.m_type == type) {
208 124 : return &dSpec;
209 : }
210 248 : }
211 0 : ShowSevereError(state, format("Design Specification MultiSpeed Heat Pump factory: Error getting inputs for system named: {}", objectName));
212 0 : return nullptr;
213 : }
214 :
215 22 : void DesignSpecMSHP::getDesignSpecMSHP(EnergyPlusData &state)
216 : {
217 22 : bool errorsFound(false);
218 :
219 22 : DesignSpecMSHP::getDesignSpecMSHPdata(state, errorsFound);
220 :
221 22 : if (errorsFound) {
222 0 : ShowFatalError(state, "Design Specification MultiSpeed Heat Pump: Previous errors cause termination.");
223 : }
224 22 : }
225 :
226 22 : void DesignSpecMSHP::getDesignSpecMSHPdata(EnergyPlusData &state, bool errorsFound)
227 : {
228 22 : std::string const cCurrentModuleObject = "UnitarySystemPerformance:Multispeed";
229 :
230 22 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
231 22 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end()) {
232 0 : errorsFound = true;
233 : } else {
234 22 : int designSpecNum = 0;
235 22 : auto &instancesValue = instances.value();
236 85 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
237 :
238 : // *************** used only to eliminate unused object warning when using only Json type getInput **********
239 63 : int TotalArgs = 0;
240 63 : int NumAlphas = 0;
241 63 : int NumNumbers = 0;
242 63 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
243 63 : int IOStatus = 0;
244 63 : Array1D_string Alphas(NumAlphas);
245 63 : Array1D<Real64> Numbers(NumNumbers, 0.0);
246 63 : Array1D_bool lNumericBlanks(NumNumbers, true);
247 63 : Array1D_bool lAlphaBlanks(NumAlphas, true);
248 63 : Array1D_string cAlphaFields(NumAlphas);
249 63 : Array1D_string cNumericFields(NumNumbers);
250 63 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
251 : cCurrentModuleObject,
252 : ++designSpecNum,
253 : Alphas,
254 : NumAlphas,
255 : Numbers,
256 : NumNumbers,
257 : IOStatus,
258 : lNumericBlanks,
259 : lAlphaBlanks,
260 : cAlphaFields,
261 : cNumericFields);
262 : // **********************************************************************************************************
263 :
264 63 : auto const &fields = instance.value();
265 63 : std::string const &thisObjectName = instance.key();
266 63 : DesignSpecMSHP thisDesignSpec;
267 :
268 63 : thisDesignSpec.name = Util::makeUPPER(thisObjectName);
269 126 : thisDesignSpec.numOfSpeedHeating = fields.at("number_of_speeds_for_heating").get<int>(); // required field
270 63 : thisDesignSpec.numOfSpeedCooling = fields.at("number_of_speeds_for_cooling").get<int>(); // required field
271 63 : int maxSpeeds = max(thisDesignSpec.numOfSpeedHeating, thisDesignSpec.numOfSpeedCooling);
272 63 : thisDesignSpec.m_type = HVAC::UnitarySysType::Furnace_HeatOnly; // add global int value for factory
273 :
274 126 : if (auto it = fields.find("single_mode_operation"); it != fields.end()) { // not required field
275 63 : std::string loc_m_SingleModeOp = Util::makeUPPER(it.value().get<std::string>());
276 63 : if (Util::SameString(loc_m_SingleModeOp, "Yes")) {
277 1 : thisDesignSpec.m_SingleModeFlag = true;
278 : }
279 126 : }
280 :
281 126 : if (auto it = fields.find("no_load_supply_air_flow_rate_ratio"); it != fields.end()) { // not required field
282 39 : thisDesignSpec.noLoadAirFlowRateRatio = it.value().get<Real64>();
283 63 : }
284 :
285 63 : thisDesignSpec.heatingVolFlowRatio.resize(maxSpeeds + 1);
286 63 : thisDesignSpec.coolingVolFlowRatio.resize(maxSpeeds + 1);
287 :
288 63 : auto speedFlowRatios = fields.find("flow_ratios");
289 63 : if (speedFlowRatios != fields.end()) {
290 63 : auto &flowRatioArray = speedFlowRatios.value();
291 63 : int numSpeedInputs = flowRatioArray.size();
292 63 : if (numSpeedInputs >= maxSpeeds) {
293 63 : int speedNum = -1;
294 393 : for (auto const &flowRatio : flowRatioArray) {
295 330 : speedNum += 1;
296 330 : if (speedNum < (maxSpeeds + 1)) {
297 191 : auto &cobj = flowRatio.at("cooling_speed_supply_air_flow_ratio");
298 191 : thisDesignSpec.coolingVolFlowRatio[speedNum] =
299 302 : (cobj.type() == nlohmann::detail::value_t::string && Util::SameString(cobj.get<std::string>(), "Autosize"))
300 302 : ? DataSizing::AutoSize
301 80 : : cobj.get<Real64>();
302 :
303 191 : auto &hobj = flowRatio.at("heating_speed_supply_air_flow_ratio");
304 191 : thisDesignSpec.heatingVolFlowRatio[speedNum] =
305 302 : (hobj.type() == nlohmann::detail::value_t::string && Util::SameString(hobj.get<std::string>(), "Autosize"))
306 302 : ? DataSizing::AutoSize
307 80 : : hobj.get<Real64>();
308 : }
309 63 : }
310 : } else {
311 0 : ShowSevereError(state, format("{}: Error getting inputs for system named: {}", cCurrentModuleObject, thisObjectName));
312 0 : ShowContinueError(state,
313 0 : format("Number of speed inputs ({:.0T} is less than number of speeds ({:.0T}).",
314 0 : Real64(numSpeedInputs),
315 0 : Real64(maxSpeeds)));
316 0 : errorsFound = true;
317 : }
318 : }
319 63 : state.dataUnitarySystems->designSpecMSHP.push_back(thisDesignSpec);
320 85 : }
321 : }
322 22 : } // namespace UnitarySystems
323 :
324 763 : HVACSystemData *UnitarySys::factory(
325 : EnergyPlusData &state, HVAC::UnitarySysType const type, std::string const &objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
326 : {
327 763 : if (state.dataUnitarySystems->getInputOnceFlag) {
328 168 : UnitarySys::getUnitarySystemInput(state, objectName, ZoneEquipment, ZoneOAUnitNum);
329 168 : state.dataUnitarySystems->getInputOnceFlag = false;
330 : }
331 763 : int sysNum = -1;
332 12866 : for (auto &sys : state.dataUnitarySystems->unitarySys) {
333 12866 : ++sysNum;
334 12866 : if (Util::SameString(sys.Name, objectName) && type == HVAC::UnitarySysType::Unitary_AnyCoilType) {
335 763 : state.dataUnitarySystems->unitarySys[sysNum].m_UnitarySysNum = sysNum;
336 763 : return &sys;
337 : }
338 1526 : }
339 0 : ShowFatalError(state, format("UnitarySystem factory: Error getting inputs for system named: {}", objectName));
340 0 : return nullptr;
341 : }
342 :
343 125 : int getDesignSpecMSHPIndex(
344 : EnergyPlusData &state, // lookup vector index for design spec object name in object array EnergyPlus::UnitarySystems::designSpecMSHP
345 : std::string_view objectName // IDF name in input
346 : )
347 : {
348 125 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
349 1 : DesignSpecMSHP::getDesignSpecMSHP(state);
350 1 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
351 : }
352 125 : int index = -1;
353 353 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->designSpecMSHP.size(); ++loop) {
354 353 : DesignSpecMSHP *thisDesignSpecMSHPObjec = &state.dataUnitarySystems->designSpecMSHP[loop];
355 353 : if (Util::SameString(objectName, thisDesignSpecMSHPObjec->name)) {
356 125 : index = loop;
357 125 : return index;
358 : }
359 : }
360 0 : ShowSevereError(state, format("getDesignSpecMSHPIndex: did not find UnitarySystemPerformance:Multispeed name ={}. Check inputs", objectName));
361 0 : return index;
362 : }
363 :
364 3052 : int getUnitarySystemIndex(
365 : EnergyPlusData &state, // lookup vector index for UnitarySystem object name in object array EnergyPlus::UnitarySystems::unitarySys
366 : std::string_view objectName // IDF name in input
367 : )
368 : {
369 3052 : int index = -1;
370 77196 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->unitarySys.size(); ++loop) {
371 75670 : UnitarySys *thisUnitarySysObjec = &state.dataUnitarySystems->unitarySys[loop];
372 75670 : if (Util::SameString(objectName, thisUnitarySysObjec->Name)) {
373 1526 : index = loop;
374 1526 : break;
375 : }
376 : }
377 3052 : return index;
378 : }
379 :
380 9735155 : void UnitarySys::initUnitarySystems(EnergyPlusData &state, int const AirLoopNum, bool const FirstHVACIteration, Real64 const OAUCoilOutTemp)
381 : {
382 : static constexpr std::string_view routineName("InitUnitarySystems");
383 :
384 : // only access for zone equipment, UnitaySystem does not yet have input for Availability Manager List Name
385 23141573 : if (this->m_IsZoneEquipment &&
386 12932646 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
387 3197491 : !state.dataAvail->ZoneComp.empty()) {
388 : // need to move to better location and save thisObjectIndex and thisObjectType in struct
389 : // this->m_EquipCompNum is by parent type, not total UnitarySystems
390 : // e.g., PTAC = 1,2,3; PTHP = 1,2; PTWSHP = 1,2,3,4; UnitarySystems = 9 total
391 3197491 : DataZoneEquipment::ZoneEquipType thisObjectType = DataZoneEquipment::ZoneEquipType::Invalid;
392 3197491 : switch (this->m_sysType) {
393 1084926 : case SysType::PackagedAC:
394 1084926 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
395 1084926 : break;
396 92466 : case SysType::PackagedHP:
397 92466 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump;
398 92466 : break;
399 2020099 : case SysType::PackagedWSHP:
400 2020099 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir;
401 2020099 : break;
402 0 : default:
403 0 : break;
404 : }
405 3197491 : if (this->m_ZoneCompFlag) {
406 330 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).AvailManagerListName = this->m_AvailManagerListName;
407 330 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).ZoneNum = this->ControlZoneNum;
408 330 : this->m_ZoneCompFlag = false;
409 : }
410 3197491 : this->m_AvailStatus = state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).availStatus;
411 : }
412 :
413 : // sizing does not execute until SysSizing is complete. This means we may not know plant connections for zone equipment.
414 : // when adding ((this->m_IsZoneEquipment && !state.dataGlobal->SysSizingCalc) || ()) here, eio gets out of sorts
415 9735155 : if (!state.dataGlobal->SysSizingCalc && this->m_MySizingCheckFlag && !this->m_ThisSysInputShouldBeGotten) {
416 763 : if (AirLoopNum > 0) {
417 404 : if (this->m_FanExists && (this->m_CoolCoilExists && (this->m_HeatCoilExists || this->m_SuppCoilExists))) {
418 108 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
419 : }
420 404 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
421 404 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
422 67 : DXCoils::SetCoilSystemCoolingData(state, this->m_CoolingCoilName, this->Name);
423 : }
424 : // associates an air loop fan on main branch with a coil on main branch where parent does not have a fan
425 404 : if (!this->m_FanExists) {
426 295 : if (state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanType != HVAC::FanType::Invalid) {
427 292 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
428 292 : if (this->m_CoolCoilExists) {
429 291 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
430 : state,
431 291 : this->m_CoolingCoilName,
432 291 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
433 291 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
434 291 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
435 : primaryAirSystems.supFanNum);
436 : }
437 292 : if (this->m_HeatCoilExists) {
438 1 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
439 : state,
440 1 : this->m_HeatingCoilName,
441 1 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
442 1 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
443 1 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
444 : primaryAirSystems.supFanNum);
445 : }
446 292 : if (this->m_SuppCoilExists) {
447 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
448 : state,
449 0 : this->m_SuppHeatCoilName,
450 0 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
451 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
452 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
453 : primaryAirSystems.supFanNum);
454 : }
455 : }
456 : }
457 : }
458 763 : this->sizeSystem(state, FirstHVACIteration, AirLoopNum);
459 763 : this->m_MySizingCheckFlag = false;
460 763 : if (AirLoopNum > 0) {
461 404 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = this->m_FanOpMode;
462 404 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).cycFanSched = this->m_fanOpModeSched;
463 359 : } else if (AirLoopNum < 0) {
464 8 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
465 0 : ShowSevereError(state, format("{}: {}", this->UnitType, this->Name));
466 0 : ShowContinueError(state, " Invalid application of Control Type = SingleZoneVAV in outdoor air system.");
467 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
468 : }
469 : }
470 : }
471 :
472 9735155 : if (this->m_MyFanFlag) { // should include " && !this->m_MySizingCheckFlag"
473 1793 : if (this->m_ActualFanVolFlowRate != DataSizing::AutoSize) {
474 763 : if (this->m_ActualFanVolFlowRate > 0.0) {
475 763 : this->m_HeatingFanSpeedRatio = this->m_MaxHeatAirVolFlow / this->m_ActualFanVolFlowRate;
476 763 : this->m_CoolingFanSpeedRatio = this->m_MaxCoolAirVolFlow / this->m_ActualFanVolFlowRate;
477 763 : this->m_NoHeatCoolSpeedRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
478 763 : if (this->m_FanExists && !this->m_MultiOrVarSpeedHeatCoil && !this->m_MultiOrVarSpeedCoolCoil) {
479 371 : bool fanHasPowerSpeedRatioCurve = false;
480 371 : if (this->m_FanType == HVAC::FanType::SystemModel) {
481 32 : if (dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex))->powerModFuncFlowFracCurveNum > 0) {
482 2 : fanHasPowerSpeedRatioCurve = true;
483 : }
484 : } else {
485 339 : if (dynamic_cast<Fans::FanComponent *>(state.dataFans->fans(this->m_FanIndex))->powerRatioAtSpeedRatioCurveNum > 0) {
486 5 : fanHasPowerSpeedRatioCurve = true;
487 : }
488 : }
489 371 : if (fanHasPowerSpeedRatioCurve) {
490 :
491 7 : if (this->m_ActualFanVolFlowRate == this->m_MaxHeatAirVolFlow &&
492 6 : this->m_ActualFanVolFlowRate == this->m_MaxCoolAirVolFlow &&
493 5 : this->m_ActualFanVolFlowRate == this->m_MaxNoCoolHeatAirVolFlow) {
494 1 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
495 2 : ShowContinueError(
496 2 : state, format("...For fan type and name = {} \"{}\"", HVAC::fanTypeNames[(int)this->m_FanType], this->m_FanName));
497 2 : ShowContinueError(state,
498 : "...Fan power ratio function of speed ratio curve has no impact if fan volumetric flow rate is the "
499 : "same as the unitary system volumetric flow rate.");
500 2 : ShowContinueError(state,
501 2 : format("...Fan volumetric flow rate = {:.5R} m3/s.", this->m_ActualFanVolFlowRate));
502 1 : ShowContinueError(state, format("...Unitary system volumetric flow rate = {:.5R} m3/s.", this->m_MaxHeatAirVolFlow));
503 : }
504 : }
505 : }
506 763 : if (this->m_MultiOrVarSpeedHeatCoil || this->m_MultiOrVarSpeedCoolCoil) {
507 158 : if (this->m_MultiOrVarSpeedCoolCoil) {
508 158 : int NumSpeeds = this->m_NumOfSpeedCooling;
509 158 : if (this->m_MSCoolingSpeedRatio.empty()) {
510 0 : this->m_MSCoolingSpeedRatio.resize(NumSpeeds + 1);
511 : }
512 158 : if (this->m_CoolVolumeFlowRate.empty()) {
513 0 : this->m_CoolVolumeFlowRate.resize(NumSpeeds + 1);
514 : }
515 587 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
516 429 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
517 : }
518 : }
519 158 : if (this->m_MultiOrVarSpeedHeatCoil) {
520 23 : int NumSpeeds = this->m_NumOfSpeedHeating;
521 23 : if (this->m_MSHeatingSpeedRatio.empty()) {
522 0 : this->m_MSHeatingSpeedRatio.resize(NumSpeeds + 1);
523 : }
524 23 : if (this->m_HeatVolumeFlowRate.empty()) {
525 0 : this->m_HeatVolumeFlowRate.resize(NumSpeeds + 1);
526 : }
527 139 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
528 116 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
529 : }
530 : }
531 158 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
532 : }
533 : }
534 763 : this->m_MyFanFlag = false;
535 : } else {
536 1030 : if (this->m_FanExists) {
537 1030 : this->m_ActualFanVolFlowRate = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
538 : }
539 : // do not set false this->m_MyFanFlag so that next pass specific initialization and warning are executed
540 : }
541 : }
542 :
543 : // Scan hot water and steam heating coil plant components for one time initializations
544 9735155 : if (this->m_MyPlantScanFlag && !state.dataPlnt->PlantLoop.empty()) {
545 548 : if (this->m_HeatRecActive) {
546 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
547 0 : PlantUtilities::ScanPlantLoopsForObject(state,
548 : this->Name,
549 : DataPlant::PlantEquipmentType::UnitarySysRecovery,
550 0 : this->m_HRPlantLoc,
551 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
552 : _,
553 : _,
554 : _,
555 : _,
556 : _);
557 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
558 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
559 : }
560 : }
561 548 : DataPlant::PlantEquipmentType TypeOfCoilWaterCooling{DataPlant::PlantEquipmentType::Invalid};
562 548 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed ||
563 528 : this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
564 40 : std::string CoolingCoilType = "";
565 20 : std::string CoolingCoilName = "";
566 20 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
567 20 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
568 20 : CoolingCoilType = "Coil:Cooling:Water";
569 20 : CoolingCoilName = this->m_CoolingCoilName;
570 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
571 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
572 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
573 0 : CoolingCoilName = this->m_CoolingCoilName;
574 : } else {
575 : TypeOfCoilWaterCooling = static_cast<DataPlant::PlantEquipmentType>(
576 0 : HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(state,
577 0 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
578 0 : this->m_CoolingCoilName,
579 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
580 : true));
581 0 : if (TypeOfCoilWaterCooling == static_cast<DataPlant::PlantEquipmentType>(HVAC::Coil_CoolingWater)) {
582 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
583 0 : CoolingCoilType = "Coil:Cooling:Water";
584 0 : } else if (TypeOfCoilWaterCooling == static_cast<DataPlant::PlantEquipmentType>(HVAC::Coil_CoolingWaterDetailed)) {
585 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
586 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
587 : }
588 0 : CoolingCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(state,
589 0 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
590 0 : this->m_CoolingCoilName,
591 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag);
592 : }
593 20 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
594 40 : PlantUtilities::ScanPlantLoopsForObject(state,
595 : CoolingCoilName,
596 : TypeOfCoilWaterCooling,
597 20 : this->CoolCoilPlantLoc,
598 20 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
599 : _,
600 : _,
601 : _,
602 : _,
603 : _);
604 20 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
605 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
606 : }
607 20 : this->MaxCoolCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
608 20 : state, CoolingCoilType, CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
609 :
610 20 : if (this->MaxCoolCoilFluidFlow > 0.0) {
611 : Real64 rho =
612 5 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
613 5 : this->MaxCoolCoilFluidFlow *= rho;
614 : }
615 : // fill outlet node for coil
616 20 : this->CoolCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->CoolCoilPlantLoc).NodeNumOut;
617 20 : }
618 548 : DataPlant::PlantEquipmentType TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::Invalid;
619 548 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
620 11 : std::string HeatingCoilType = "";
621 11 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
622 9 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
623 9 : HeatingCoilType = "Coil:Heating:Water";
624 : // this doesn't work good here, sizing may not have executed yet
625 : // air loops seem to work OK, zone equipment not so much, this->m_MaxHeatAirVolFlow = -99999.0
626 : // moved to sizing but left this original call
627 9 : WaterCoils::SetCoilDesFlow(state,
628 9 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
629 9 : this->m_HeatingCoilName,
630 : this->m_MaxHeatAirVolFlow,
631 9 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
632 : } else {
633 2 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
634 2 : HeatingCoilType = "Coil:Heating:Steam";
635 : }
636 11 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
637 22 : PlantUtilities::ScanPlantLoopsForObject(state,
638 : this->m_HeatingCoilName,
639 : TypeOfCoilWaterHeating,
640 11 : this->HeatCoilPlantLoc,
641 11 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
642 : _,
643 : _,
644 : _,
645 : _,
646 : _);
647 11 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
648 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
649 : }
650 11 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
651 9 : this->MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
652 9 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
653 :
654 9 : if (this->MaxHeatCoilFluidFlow > 0.0) {
655 2 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
656 2 : .glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
657 2 : this->MaxHeatCoilFluidFlow =
658 2 : WaterCoils::GetCoilMaxWaterFlowRate(
659 4 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
660 : rho;
661 : }
662 : } else {
663 2 : this->MaxHeatCoilFluidFlow =
664 2 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
665 2 : if (this->MaxHeatCoilFluidFlow > 0.0) {
666 2 : Real64 TempSteamIn = 100.0;
667 2 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
668 2 : this->MaxHeatCoilFluidFlow *= SteamDensity;
669 : }
670 : }
671 : // fill outlet node for coil
672 11 : this->HeatCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->HeatCoilPlantLoc).NodeNumOut;
673 11 : }
674 :
675 548 : this->m_MyPlantScanFlag = false;
676 9734607 : } else if (this->m_MyPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
677 215 : this->m_MyPlantScanFlag = false;
678 : }
679 :
680 : // Scan Supplemental hot water and steam heating coil plant components for one time initializations
681 9735155 : if (this->m_MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
682 763 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
683 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
684 0 : PlantUtilities::ScanPlantLoopsForObject(state,
685 : this->m_SuppHeatCoilName,
686 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
687 0 : this->m_SuppCoilPlantLoc,
688 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
689 : _,
690 : _,
691 : _,
692 : _,
693 : _);
694 0 : WaterCoils::SetCoilDesFlow(state,
695 0 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
696 0 : this->m_SuppHeatCoilName,
697 : this->m_MaxHeatAirVolFlow,
698 0 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
699 :
700 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
701 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
702 : }
703 0 : this->m_MaxSuppCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
704 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
705 :
706 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
707 : Real64 rho =
708 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
709 0 : this->m_MaxSuppCoilFluidFlow =
710 0 : WaterCoils::GetCoilMaxWaterFlowRate(
711 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
712 : rho;
713 : }
714 : // fill outlet node for coil
715 0 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
716 :
717 763 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
718 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
719 0 : PlantUtilities::ScanPlantLoopsForObject(state,
720 : this->m_SuppHeatCoilName,
721 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
722 0 : this->m_SuppCoilPlantLoc,
723 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
724 : _,
725 : _,
726 : _,
727 : _,
728 : _);
729 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
730 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
731 : }
732 0 : this->m_MaxSuppCoilFluidFlow =
733 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
734 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
735 0 : Real64 TempSteamIn = 100.0;
736 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
737 0 : this->m_MaxSuppCoilFluidFlow *= SteamDensity;
738 : }
739 :
740 : // fill outlet node for coil
741 0 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
742 : }
743 :
744 763 : this->m_MySuppCoilPlantScanFlag = false;
745 :
746 9734392 : } else if (this->m_MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
747 0 : this->m_MySuppCoilPlantScanFlag = false;
748 : }
749 :
750 : // do the Begin Environment initializations
751 9735155 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag) {
752 4555 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
753 4555 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
754 4555 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
755 4555 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
756 4555 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
757 4555 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
758 4555 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
759 4555 : if (this->OAMixerExists) {
760 1883 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMax = max(this->m_CoolOutAirMassFlow, this->m_HeatOutAirMassFlow);
761 1883 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMin = 0.0;
762 1883 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMinAvail = 0.0;
763 : }
764 4555 : this->m_CompPartLoadRatio = 0.0;
765 4555 : this->m_CoolingCoilSensDemand = 0.0;
766 4555 : this->m_CoolingCoilLatentDemand = 0.0;
767 4555 : this->m_HeatingCoilSensDemand = 0.0;
768 4555 : this->m_SenLoadLoss = 0.0;
769 4555 : if (this->m_Humidistat) {
770 153 : this->m_LatLoadLoss = 0.0;
771 : }
772 :
773 4555 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
774 :
775 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
776 :
777 0 : this->m_DesignHeatRecMassFlowRate = this->m_DesignHRWaterVolumeFlow * rho;
778 :
779 0 : PlantUtilities::InitComponentNodes(
780 : state, 0.0, this->m_DesignHeatRecMassFlowRate, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
781 : }
782 : // set fluid-side hardware limits
783 4555 : if (this->CoolCoilFluidInletNode > 0) {
784 :
785 109 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
786 : // If water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
787 15 : std::string CoolingCoilType = "";
788 15 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
789 15 : CoolingCoilType = "Coil:Cooling:Water";
790 : } else {
791 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
792 : }
793 15 : WaterCoils::SimulateWaterCoilComponents(state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex);
794 15 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
795 15 : state, CoolingCoilType, this->m_CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
796 15 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
797 15 : Real64 rho = state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum)
798 15 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
799 15 : this->MaxCoolCoilFluidFlow = CoilMaxVolFlowRate * rho;
800 : }
801 15 : }
802 :
803 109 : PlantUtilities::InitComponentNodes(
804 : state, 0.0, this->MaxCoolCoilFluidFlow, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum);
805 : }
806 4555 : if (this->HeatCoilFluidInletNode > 0) {
807 :
808 62 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
809 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
810 7 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
811 7 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
812 7 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
813 7 : state, "Coil:Heating:Water", this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
814 7 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
815 7 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
816 7 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
817 7 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
818 : }
819 : }
820 : // If steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
821 7 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
822 0 : SteamCoils::SimulateSteamCoilComponents(
823 : state,
824 : this->m_HeatingCoilName,
825 : FirstHVACIteration,
826 0 : this->m_HeatingCoilIndex,
827 0 : 1.0,
828 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity
829 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(
830 0 : state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
831 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
832 0 : Real64 TempSteamIn = 100.0;
833 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
834 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
835 : }
836 : }
837 : }
838 :
839 62 : PlantUtilities::InitComponentNodes(
840 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
841 : }
842 4555 : if (this->m_SuppCoilFluidInletNode > 0) {
843 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
844 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
845 : // If water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
846 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
847 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
848 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
849 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
850 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum)
851 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
852 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
853 : }
854 : }
855 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
856 0 : SteamCoils::SimulateSteamCoilComponents(
857 : state,
858 : this->m_SuppHeatCoilName,
859 : FirstHVACIteration,
860 0 : this->m_SuppHeatCoilIndex,
861 0 : 1.0,
862 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity
863 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(
864 0 : state, this->m_SuppHeatCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
865 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
866 0 : Real64 TempSteamIn = 100.0;
867 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
868 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
869 : }
870 : }
871 0 : PlantUtilities::InitComponentNodes(
872 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
873 : }
874 : }
875 4555 : this->m_MyEnvrnFlag = false;
876 : }
877 :
878 9735155 : if (!state.dataGlobal->BeginEnvrnFlag) {
879 9692841 : this->m_MyEnvrnFlag = true;
880 : }
881 :
882 : // Init maximum available Heat Recovery flow rate
883 9735155 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
884 0 : Real64 mdotHR = 0.0;
885 0 : if (this->m_sysAvailSched->getCurrentVal() > 0.0) {
886 0 : if (FirstHVACIteration) {
887 0 : mdotHR = this->m_DesignHeatRecMassFlowRate;
888 : } else {
889 0 : if (this->m_HeatRecoveryMassFlowRate > 0.0) {
890 0 : mdotHR = this->m_HeatRecoveryMassFlowRate;
891 : } else {
892 0 : mdotHR = this->m_DesignHeatRecMassFlowRate;
893 : }
894 : }
895 : } else {
896 0 : mdotHR = 0.0;
897 : }
898 :
899 0 : mdotHR = min(state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).MassFlowRateMaxAvail, mdotHR);
900 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate = mdotHR;
901 : }
902 :
903 : // get operating capacity of water and steam coil
904 9735155 : if (FirstHVACIteration || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
905 4196437 : if (FirstHVACIteration) {
906 4055416 : this->m_IterationCounter = 0;
907 4055416 : std::fill(this->m_IterationMode.begin(), this->m_IterationMode.end(), 0);
908 :
909 : // for systems without a fan, just read the inlet node flow rate and let air loop decide flow
910 4055416 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint && this->m_sysType == SysType::Unitary && this->m_FanExists) {
911 15416 : if (this->m_sysAvailSched->getCurrentVal() > 0.0) {
912 15407 : if (this->m_LastMode == CoolingMode) {
913 7286 : if (this->m_MultiOrVarSpeedCoolCoil) {
914 5402 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
915 : } else {
916 1884 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxCoolAirMassFlow;
917 : }
918 8121 : } else if (this->m_LastMode == HeatingMode) {
919 8115 : if (this->m_MultiOrVarSpeedHeatCoil) {
920 1125 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_HeatMassFlowRate[this->m_NumOfSpeedHeating];
921 : } else {
922 6990 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxHeatAirMassFlow;
923 : }
924 : } else {
925 6 : if (this->m_MultiOrVarSpeedCoolCoil) {
926 3 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
927 : } else {
928 3 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
929 : }
930 : }
931 : } else {
932 9 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = 0.0;
933 : }
934 : }
935 4055416 : if (this->m_WaterHRPlantLoopModel) {
936 : // initialize loop water temp on FirstHVACIteration
937 5377 : Real64 airInTemp = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp;
938 5377 : Real64 companionAirInTemp = state.dataLoopNodes->Node(this->m_HRcoolCoilAirInNode).Temp;
939 5377 : Real64 oneHalfAirDeltaT = (companionAirInTemp - airInTemp) / 2.0;
940 5377 : Real64 initialLoopTemp = airInTemp + oneHalfAirDeltaT;
941 5377 : if (initialLoopTemp > this->m_minWaterLoopTempForHR && std::abs(oneHalfAirDeltaT) > this->m_minAirToWaterTempOffset) {
942 12 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp = initialLoopTemp;
943 12 : this->temperatureOffsetControlStatus = 1;
944 : } else {
945 5365 : this->temperatureOffsetControlStatus = 0;
946 : }
947 : }
948 : }
949 4196437 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
950 :
951 : // set water-side mass flow rates
952 145296 : Real64 mdot = this->MaxCoolCoilFluidFlow;
953 145296 : PlantUtilities::SetComponentFlowRate(
954 145296 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
955 : // simulate water coil to find operating capacity
956 290592 : WaterCoils::SimulateWaterCoilComponents(state,
957 : this->m_CoolingCoilName,
958 : FirstHVACIteration,
959 145296 : this->m_CoolingCoilIndex,
960 145296 : state.dataUnitarySystems->initUnitarySystemsQActual);
961 145296 : this->m_DesignCoolingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
962 :
963 : } // from IF(UnitarySystem(UnitarySysNum)%CoolingCoilType_Num == Coil_CoolingWater .OR. Coil_CoolingWaterDetailed
964 4196437 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
965 :
966 : // set water-side mass flow rates
967 25768 : Real64 mdot = this->MaxHeatCoilFluidFlow;
968 25768 : PlantUtilities::SetComponentFlowRate(
969 25768 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
970 : // simulate water coil to find operating capacity
971 51536 : WaterCoils::SimulateWaterCoilComponents(state,
972 : this->m_HeatingCoilName,
973 : FirstHVACIteration,
974 25768 : this->m_HeatingCoilIndex,
975 25768 : state.dataUnitarySystems->initUnitarySystemsQActual);
976 25768 : this->m_DesignHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
977 :
978 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingWater) THEN
979 :
980 4196437 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
981 :
982 : // set water-side mass flow rates
983 2968 : Real64 mdot = this->MaxHeatCoilFluidFlow;
984 2968 : PlantUtilities::SetComponentFlowRate(
985 2968 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
986 : // simulate steam coil to find operating capacity
987 8904 : SteamCoils::SimulateSteamCoilComponents(
988 : state,
989 : this->m_HeatingCoilName,
990 : FirstHVACIteration,
991 2968 : this->m_HeatingCoilIndex,
992 5936 : 1.0,
993 2968 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
994 2968 : this->m_DesignHeatingCapacity = SteamCoils::GetCoilCapacity(state,
995 2968 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
996 2968 : this->m_HeatingCoilName,
997 2968 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
998 :
999 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
1000 4196437 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
1001 :
1002 : // set steam-side mass flow rates
1003 0 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
1004 0 : PlantUtilities::SetComponentFlowRate(
1005 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1006 : // simulate water coil to find operating capacity
1007 0 : if (mdot > 0.0) { // not sure why this is here and not used for other coil types, wouldn't capacity be 0 if water flow = 0? Maybe a
1008 : // speed issue where coil doesn't need to be simulation if mdot=0.
1009 0 : WaterCoils::SimulateWaterCoilComponents(state,
1010 : this->m_SuppHeatCoilName,
1011 : FirstHVACIteration,
1012 0 : this->m_SuppHeatCoilIndex,
1013 0 : state.dataUnitarySystems->initUnitarySystemsQActual);
1014 0 : this->m_DesignSuppHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
1015 : } else {
1016 0 : this->m_DesignSuppHeatingCapacity = 0.0;
1017 : }
1018 :
1019 : } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingWater) THEN
1020 :
1021 4196437 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
1022 :
1023 : // set air-side and steam-side mass flow rates
1024 0 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
1025 0 : PlantUtilities::SetComponentFlowRate(
1026 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1027 : // simulate steam coil to find operating capacity
1028 0 : SteamCoils::SimulateSteamCoilComponents(
1029 : state,
1030 : this->m_SuppHeatCoilName,
1031 : FirstHVACIteration,
1032 0 : this->m_SuppHeatCoilIndex,
1033 0 : 1.0,
1034 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1035 0 : this->m_DesignSuppHeatingCapacity = SteamCoils::GetCoilCapacity(
1036 0 : state, "Coil:Heating:Steam", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
1037 :
1038 : } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN
1039 : } // from IF( FirstHVACIteration ) THEN
1040 :
1041 9735155 : this->m_IterationCounter += 1;
1042 :
1043 9735155 : if (this->m_MySetPointCheckFlag) {
1044 4760 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACGlobal->DoSetPointTest) {
1045 763 : bool e = false;
1046 763 : if (this->m_CoolCoilExists) {
1047 762 : e = this->checkNodeSetPoint(state, AirLoopNum, this->CoolCtrlNode, CoolingCoil, OAUCoilOutTemp);
1048 : }
1049 763 : if (this->m_HeatCoilExists) {
1050 445 : e = this->checkNodeSetPoint(state, AirLoopNum, this->HeatCtrlNode, HeatingCoil, OAUCoilOutTemp) || e;
1051 : }
1052 763 : if (this->m_SuppCoilExists) {
1053 225 : e = this->checkNodeSetPoint(state, AirLoopNum, this->SuppCtrlNode, SuppHeatCoil, OAUCoilOutTemp) || e;
1054 : }
1055 763 : if (e) {
1056 0 : ShowFatalError(state, "Previous errors cause termination.");
1057 : }
1058 763 : this->m_MySetPointCheckFlag = false;
1059 : }
1060 : }
1061 :
1062 9735155 : if (m_setFaultModelInput) {
1063 1961807 : if ((!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
1064 :
1065 : // check FaultsManager if connection exists
1066 758 : FaultsManager::SetFaultyCoilSATSensor(state, this->UnitType, this->Name, this->m_FaultyCoilSATFlag, this->m_FaultyCoilSATIndex);
1067 758 : if (this->m_FaultyCoilSATFlag) {
1068 0 : if (this->m_ControlType != UnitarySysCtrlType::Setpoint) {
1069 0 : ShowWarningError(state,
1070 0 : format("{}: {}",
1071 0 : state.dataFaultsMgr->FaultsCoilSATSensor(this->m_FaultyCoilSATIndex).type,
1072 0 : state.dataFaultsMgr->FaultsCoilSATSensor(this->m_FaultyCoilSATIndex).Name));
1073 0 : ShowContinueError(state, format("For : {}: {}", this->UnitType, this->Name));
1074 0 : ShowContinueError(state,
1075 : "The specified unitary system is not controlled on leaving air temperature. The coil SAT sensor "
1076 : "fault model will not be applied.");
1077 0 : this->m_FaultyCoilSATFlag = false;
1078 : }
1079 : }
1080 758 : m_setFaultModelInput = false;
1081 : }
1082 : }
1083 :
1084 : // re-set water-side economizer flags each time step
1085 9735155 : if (this->m_TemperatureOffsetControlActive && !this->m_WaterHRPlantLoopModel) {
1086 60192 : if (state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp >
1087 60192 : (state.dataLoopNodes->Node(this->AirInNode).Temp - this->m_minAirToWaterTempOffset)) {
1088 : // disable coilsystem if entering fluid temp is > entering air temp minus user specified temp offset
1089 59690 : this->temperatureOffsetControlStatus = 0;
1090 : } else {
1091 : // enable coilsystem waterside economizer mode
1092 502 : this->temperatureOffsetControlStatus = 1;
1093 : }
1094 : }
1095 9735155 : if (AirLoopNum > 0) {
1096 6280157 : if (this->m_sysType == SysType::CoilCoolingWater) {
1097 76032 : if (this->m_waterSideEconomizerFlag) { // CoilSystem:Cooling:Water has an input for economizer lockout
1098 76032 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1099 76032 : if (state.dataUnitarySystems->economizerFlag) {
1100 : // user input economizer lockout will disable heat recovery loop AND water economizer
1101 54 : this->temperatureOffsetControlStatus = 0;
1102 : }
1103 : } else {
1104 0 : state.dataUnitarySystems->economizerFlag = false;
1105 : }
1106 : } else {
1107 6204125 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1108 : }
1109 : // get OA controller info
1110 6280157 : this->OASysIndex = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).OASysNum;
1111 6280157 : if (this->OASysIndex > 0) {
1112 6025340 : this->OAControllerIndex = state.dataAirLoop->OutsideAirSys(this->OASysIndex).OAControllerIndex;
1113 6025340 : if (this->OAControllerIndex > 0) {
1114 6025340 : this->OAControllerEconomizerStagingType = state.dataMixedAir->OAController(this->OAControllerIndex).EconomizerStagingType;
1115 : }
1116 : }
1117 : }
1118 :
1119 9735155 : this->m_CoolingPartLoadFrac = 0.0;
1120 9735155 : this->m_HeatingPartLoadFrac = 0.0;
1121 9735155 : this->m_SuppHeatPartLoadFrac = 0.0;
1122 9735155 : this->m_CoolingCycRatio = 0.0;
1123 9735155 : this->m_CoolingSpeedRatio = 0.0;
1124 9735155 : this->m_CoolingSpeedNum = 0;
1125 9735155 : this->m_HeatingCycRatio = 0.0;
1126 9735155 : this->m_HeatingSpeedRatio = 0.0;
1127 9735155 : this->m_HeatingSpeedNum = 0;
1128 9735155 : this->m_SuppHeatingSpeedNum = 0;
1129 9735155 : this->m_HeatingCoilSensDemand = 0.0;
1130 9735155 : this->m_CoolingCoilSensDemand = 0.0;
1131 9735155 : this->m_CoolingCoilLatentDemand = 0.0;
1132 9735155 : this->m_DehumidInducedHeatingDemandRate = 0.0;
1133 9735155 : this->CoolCoilWaterFlowRatio = 0.0;
1134 9735155 : this->HeatCoilWaterFlowRatio = 0.0;
1135 :
1136 : // water/steam coil initialization
1137 9735155 : if (this->CoolCoilFluidInletNode > 0) {
1138 272541 : Real64 mdot = 0.0;
1139 272541 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
1140 : }
1141 9735155 : if (this->HeatCoilFluidInletNode > 0) {
1142 78594 : Real64 mdot = 0.0;
1143 78594 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
1144 : }
1145 9735155 : if (this->m_SuppCoilFluidInletNode > 0) {
1146 0 : Real64 mdot = 0.0;
1147 0 : PlantUtilities::SetComponentFlowRate(
1148 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1149 : }
1150 :
1151 9735155 : this->m_InitHeatPump = true;
1152 9735155 : state.dataUnitarySystems->m_massFlow1 = 0.0;
1153 9735155 : state.dataUnitarySystems->m_massFlow2 = 0.0;
1154 9735155 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
1155 9735155 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
1156 9735155 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1157 : // this should be done in the child. DXElecHeatingPower not reset to 0 if coil is off, ZoneSysAvailManager
1158 : // zero the fan and DX coils electricity consumption
1159 3197491 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
1160 3197491 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
1161 3197491 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
1162 3197491 : state.dataHVACGlobal->DefrostElecPower = 0.0;
1163 : }
1164 9735155 : }
1165 :
1166 1432 : bool UnitarySys::checkNodeSetPoint(EnergyPlusData &state,
1167 : int const AirLoopNum, // number of the current air loop being simulated
1168 : int const ControlNode, // Node to test for set point
1169 : int const CoilType, // True if cooling coil, then test for HumRatMax set point
1170 : Real64 const OAUCoilOutTemp // the coil inlet temperature of OutdoorAirUnit
1171 : )
1172 : {
1173 :
1174 : // SUBROUTINE INFORMATION:
1175 : // AUTHOR Richard Raustad
1176 : // DATE WRITTEN March 2013
1177 :
1178 : // PURPOSE OF THIS SUBROUTINE:
1179 : // This subroutine checks for proper set point at control node.
1180 : constexpr static std::array<std::string_view, 3> coilTypes = {"cooling", "heating", "supplemental"};
1181 1432 : bool SetPointErrorFlag = false;
1182 :
1183 1432 : if (ControlNode == 0) {
1184 919 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1185 0 : int coilOutNode = this->CoolCoilOutletNodeNum;
1186 0 : if (CoilType == HeatingCoil) {
1187 0 : coilOutNode = this->HeatCoilOutletNodeNum;
1188 : }
1189 0 : if (CoilType == SuppHeatCoil) {
1190 0 : coilOutNode = this->SuppCoilOutletNodeNum;
1191 : }
1192 :
1193 0 : ShowSevereError(state, format("checkNodeSetPoint: Missing {} set point in {} = {}", coilTypes[CoilType], this->UnitType, this->Name));
1194 0 : ShowContinueError(state,
1195 0 : format("...Setpoint is required at system air outlet node = {} or {} coil air outlet node = {}",
1196 0 : state.dataLoopNodes->NodeID(this->AirOutNode),
1197 0 : coilTypes[CoilType],
1198 0 : state.dataLoopNodes->NodeID(coilOutNode)));
1199 0 : SetPointErrorFlag = true;
1200 : }
1201 919 : return SetPointErrorFlag;
1202 : }
1203 :
1204 513 : if (AirLoopNum == -1) { // Outdoor Air Unit
1205 8 : state.dataLoopNodes->Node(ControlNode).TempSetPoint = OAUCoilOutTemp; // Set the coil outlet temperature
1206 8 : if (this->m_ISHundredPercentDOASDXCoil) {
1207 0 : this->frostControlSetPointLimit(state,
1208 0 : this->m_DesiredOutletTemp,
1209 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
1210 0 : state.dataEnvrn->OutBaroPress,
1211 : this->DesignMinOutletTemp,
1212 : 1);
1213 : }
1214 : } else { // Not an Outdoor air unit
1215 :
1216 505 : if (state.dataLoopNodes->Node(ControlNode).TempSetPoint == DataLoopNode::SensedNodeFlagValue &&
1217 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1218 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1219 0 : ShowSevereError(state, format("{}: Missing temperature setpoint for unitary system = {}", this->UnitType, this->Name));
1220 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1221 0 : SetPointErrorFlag = true;
1222 : } else {
1223 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, ControlNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
1224 0 : if (SetPointErrorFlag) {
1225 0 : ShowSevereError(state, format("{}: Missing temperature setpoint for unitary system = {}", this->UnitType, this->Name));
1226 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1227 0 : ShowContinueError(state, " or use an EMS actuator to establish a temperature setpoint at the coil control node.");
1228 : }
1229 : }
1230 : }
1231 1054 : if ((this->m_DehumidControlType_Num != DehumCtrlType::None) &&
1232 44 : (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) &&
1233 549 : this->m_ControlType == UnitarySysCtrlType::Setpoint && CoilType == CoolingCoil) {
1234 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel &&
1235 0 : state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
1236 0 : ShowSevereError(state,
1237 0 : format("{}: Missing humidity ratio setpoint (HUMRATMAX) for unitary system = {}", this->UnitType, this->Name));
1238 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1239 0 : SetPointErrorFlag = true;
1240 0 : } else if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
1241 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, ControlNode, HVAC::CtrlVarType::MaxHumRat, SetPointErrorFlag);
1242 0 : if (SetPointErrorFlag) {
1243 0 : ShowSevereError(
1244 : state,
1245 0 : format("{}: Missing maximum humidity ratio setpoint (HUMRATMAX) for unitary system = {}", this->UnitType, this->Name));
1246 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1247 0 : ShowContinueError(state, " or use an EMS actuator to establish a maximum humidity ratio setpoint.");
1248 : }
1249 : }
1250 : }
1251 : }
1252 513 : return SetPointErrorFlag; // these later errors will also cause a fatal error
1253 : }
1254 :
1255 48207 : void UnitarySys::frostControlSetPointLimit(EnergyPlusData &state,
1256 : Real64 &TempSetPoint, // temperature setpoint of the sensor node
1257 : Real64 &HumRatSetPoint, // humidity ratio setpoint of the sensor node
1258 : Real64 const BaroPress, // barometric pressure, Pa [N/m^2]
1259 : Real64 const TfrostControl, // minimum temperature limit for frost control
1260 : int const ControlMode // temperature or humidity control mode
1261 : )
1262 : {
1263 :
1264 : // SUBROUTINE INFORMATION:
1265 : // AUTHOR Bereket Nigusse, FSEC
1266 : // DATE WRITTEN January 2013
1267 :
1268 : // PURPOSE OF THIS SUBROUTINE:
1269 : // Controls the frost formation condition based on user specified minimum DX coil outlet
1270 : // air temperature. Resets the cooling setpoint based on the user specified limiting
1271 : // temperature for frost control.
1272 :
1273 : // SUBROUTINE PARAMETER DEFINITIONS:
1274 48207 : int constexpr RunOnSensible(1); // identifier for temperature (sensible load) control
1275 48207 : int constexpr RunOnLatent(2); // identifier for humidity (latent load) control
1276 : static constexpr std::string_view routineName("FrostControlSetPointLimit");
1277 :
1278 48207 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate;
1279 57180 : if (ControlMode == RunOnSensible && AirMassFlow > HVAC::SmallAirVolFlow &&
1280 8973 : TempSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp) {
1281 8267 : if (TempSetPoint < TfrostControl) {
1282 0 : TempSetPoint = TfrostControl;
1283 0 : this->m_FrostControlStatus = 1;
1284 : }
1285 45809 : } else if (ControlMode == RunOnLatent && AirMassFlow > HVAC::SmallAirVolFlow &&
1286 5869 : HumRatSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat) {
1287 5869 : Real64 HumRatioSat = Psychrometrics::PsyWFnTdpPb(state, TfrostControl, BaroPress, routineName);
1288 5869 : if (HumRatioSat > HumRatSetPoint) {
1289 331 : HumRatSetPoint = HumRatioSat;
1290 331 : this->m_FrostControlStatus = 2;
1291 : }
1292 : } else {
1293 34071 : this->m_FrostControlStatus = 0;
1294 : }
1295 48207 : }
1296 :
1297 933 : void UnitarySys::getUnitarySystemInput(EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
1298 : {
1299 :
1300 933 : bool errorsFound(false);
1301 933 : UnitarySys::allocateUnitarySys(state);
1302 :
1303 933 : UnitarySys::getDXCoilSystemData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1304 933 : UnitarySys::getCoilWaterSystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1305 933 : UnitarySys::getPackagedTerminalUnitData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1306 933 : UnitarySys::getUnitarySystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1307 :
1308 933 : if (errorsFound) {
1309 0 : ShowFatalError(state, "getUnitarySystemInputData: previous errors cause termination. Check inputs");
1310 : }
1311 :
1312 : // all systems should have been processed at this point? I think so, so don't need to if test this call?
1313 1866 : if (int(state.dataUnitarySystems->unitarySys.size()) == state.dataUnitarySystems->numUnitarySystems &&
1314 933 : state.dataZoneEquip->ZoneEquipInputsFilled) {
1315 898 : if (state.dataUnitarySystems->setupOutputOnce) {
1316 170 : setupAllOutputVars(state, state.dataUnitarySystems->numUnitarySystems);
1317 : }
1318 : }
1319 933 : }
1320 :
1321 763 : void UnitarySys::sizeSystem(EnergyPlusData &state, bool const FirstHVACIteration, int const AirLoopNum)
1322 : {
1323 :
1324 : // SUBROUTINE INFORMATION:
1325 : // AUTHOR Richard Raustad, FSEC
1326 : // DATE WRITTEN February 2013
1327 :
1328 : // PURPOSE OF THIS SUBROUTINE:
1329 : // This subroutine is for sizing unitary system components for which nominal capacities
1330 : // and flow rates have not been specified in the input. Coil sizing is preformed in the coil module.
1331 : // Future modifications will size coils here and "push" this info to the specific coil.
1332 :
1333 : // METHODOLOGY EMPLOYED:
1334 : // Obtains heating capacities and flow rates from the zone or system sizing arrays.
1335 : // NOTE: In UNITARYSYSTEM:HEATPUMP:AIRTOAIR we are sizing the heating capacity to be
1336 : // equal to the cooling capacity. Thus the cooling and
1337 : // and heating capacities of a DX heat pump system will be identical. In real life the ARI
1338 : // heating and cooling capacities are close but not identical.
1339 :
1340 : // SUBROUTINE PARAMETER DEFINITIONS:
1341 : static constexpr std::string_view RoutineName("SizeUnitarySystem");
1342 :
1343 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1344 : int Iter; // iteration count
1345 : int MSHPIndex; // Index to design Specification object
1346 : Real64 SystemFlow; // AirloopHVAC flow rate [m3/s]
1347 : Real64 BranchFanFlow; // branch fan flow rate [m3/s]
1348 : bool ErrFound; // logical error flag
1349 : HVAC::AirDuctType SaveCurDuctType; // used during sizing to save the current duct type
1350 : Real64 QActual; // water coil output [W]
1351 : Real64 capacityMultiplier; // used for ASHRAE model sizing
1352 :
1353 : Real64 TempSize; // DataSizing::AutoSized value of input field
1354 763 : int FieldNum = 2; // IDD numeric field number where input field description is found
1355 : int SizingMethod; // Integer representation of sizing method (e.g., HVAC::CoolingAirflowSizing, DataSizing::HeatingCapacitySizing,
1356 : // etc.)
1357 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
1358 763 : Real64 SumOfMassFlowRateMax(0.0); // the sum of zone inlet mass flow rates
1359 : Real64 minNoLoadFlow; // used for sizing MaxNoCoolHeatVolFlow for SingleZoneVAV method
1360 763 : Real64 dummy(0.0);
1361 : //////////// hoisted into namespace ////////////////////////////////////////////////
1362 : // static int NumUnitarySystemsSized( 0 ); // counter used to delete UnitarySystemNumericFields array after last system is sized
1363 : ////////////////////////////////////////////////////////////////////////////////////
1364 : // References
1365 763 : DataSizing::ZoneEqSizingData *select_EqSizing = nullptr;
1366 :
1367 763 : auto &OASysEqSizing = state.dataSize->OASysEqSizing;
1368 :
1369 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
1370 763 : if (state.dataSize->CurOASysNum > 0) {
1371 2 : select_EqSizing = &OASysEqSizing(state.dataSize->CurOASysNum);
1372 761 : } else if (state.dataSize->CurSysNum > 0) {
1373 402 : select_EqSizing = &state.dataSize->UnitarySysEqSizing(state.dataSize->CurSysNum);
1374 : // this was resetting data set by OutdoorAirUnit when UnitarySystem is child
1375 : // question is then who resets these (#8751 temporary fix)?
1376 : // move here for now and only reset UnitarySystem flags, then find better way to do this
1377 402 : select_EqSizing->AirFlow = false;
1378 402 : select_EqSizing->CoolingAirFlow = false;
1379 402 : select_EqSizing->HeatingAirFlow = false;
1380 402 : select_EqSizing->AirVolFlow = 0.0;
1381 402 : select_EqSizing->CoolingAirVolFlow = 0.0;
1382 402 : select_EqSizing->HeatingAirVolFlow = 0.0;
1383 402 : select_EqSizing->Capacity = false;
1384 402 : select_EqSizing->CoolingCapacity = false;
1385 402 : select_EqSizing->HeatingCapacity = false;
1386 402 : select_EqSizing->DesCoolingLoad = 0.0;
1387 402 : select_EqSizing->DesHeatingLoad = 0.0;
1388 402 : select_EqSizing->OAVolFlow = 0.0; // UnitarySys doesn't have OA
1389 359 : } else if (state.dataSize->CurZoneEqNum > 0) {
1390 359 : select_EqSizing = &state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
1391 359 : state.dataSize->ZoneEqUnitarySys = true;
1392 : // UnitarySystem never set this flag. Probably should for zone equipment.
1393 359 : if ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
1394 330 : this->m_IsDXCoil) {
1395 330 : state.dataSize->ZoneEqDXCoil = true;
1396 : }
1397 :
1398 : } else {
1399 0 : assert(false);
1400 : }
1401 : // Object Data, points to specific array
1402 763 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
1403 :
1404 : // coil sizing requires this information to check proper flow/capacity limits (#8761)
1405 763 : if (this->m_ISHundredPercentDOASDXCoil) {
1406 6 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::DOAS; // uses 100% DX coil flow limits
1407 : } else {
1408 757 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::Regular; // uses normal DX coil flow limits
1409 : }
1410 : // sizing may need to know what type of coil is being sized
1411 763 : state.dataSize->DataCoolCoilType = this->m_CoolingCoilType_Num;
1412 763 : state.dataSize->DataCoolCoilIndex = this->m_CoolingCoilIndex;
1413 :
1414 : bool anyEMSRan;
1415 763 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::UnitarySystemSizing, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point
1416 : bool HardSizeNoDesRun; // Indicator to a hard-sized field with no design sizing data
1417 :
1418 : // Initiate all reporting variables
1419 1178 : if (((state.dataSize->CurOASysNum > 0 || state.dataSize->CurSysNum > 0) && state.dataSize->SysSizingRunDone) ||
1420 415 : (state.dataSize->CurZoneEqNum > 0 && state.dataSize->ZoneSizingRunDone)) {
1421 707 : HardSizeNoDesRun = false;
1422 : } else {
1423 56 : HardSizeNoDesRun = true;
1424 : }
1425 763 : std::string SizingString;
1426 763 : std::string CompName = this->Name;
1427 763 : std::string CompType = this->UnitType;
1428 763 : int CoolingSAFlowMethod = this->m_CoolingSAFMethod;
1429 763 : int HeatingSAFlowMethod = this->m_HeatingSAFMethod;
1430 : // can't reset this to 0 for systems where DX heating coil is in downstream unit and DX cooling coil is in upstream unit
1431 : // DXCoolCap = 0.0;
1432 763 : state.dataSize->UnitaryHeatCap = 0.0;
1433 763 : state.dataSize->SuppHeatCap = 0.0;
1434 763 : bool TempCoolingLoad = state.dataUnitarySystems->CoolingLoad;
1435 763 : bool TempHeatingLoad = state.dataUnitarySystems->HeatingLoad;
1436 763 : state.dataUnitarySystems->CoolingLoad = true;
1437 763 : state.dataUnitarySystems->HeatingLoad = false;
1438 763 : state.dataSize->ZoneCoolingOnlyFan = false;
1439 763 : state.dataSize->ZoneHeatingOnlyFan = false;
1440 763 : bool IsAutoSize = false;
1441 763 : Real64 SysCoolingFlow = 0.0;
1442 763 : Real64 SysHeatingFlow = 0.0;
1443 763 : Real64 CoolCapAtPeak = 0.0;
1444 763 : Real64 HeatCapAtPeak = 0.0;
1445 :
1446 763 : if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0 && this->m_FanExists) {
1447 109 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum = this->m_FanIndex;
1448 109 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanType = this->m_FanType;
1449 109 : state.dataSize->DataFanType = this->m_FanType;
1450 109 : state.dataSize->DataFanIndex = this->m_FanIndex;
1451 :
1452 109 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanPlace = this->m_FanPlace;
1453 654 : } else if (state.dataSize->CurZoneEqNum > 0 && this->m_FanExists) {
1454 351 : state.dataSize->DataFanType = this->m_FanType;
1455 351 : state.dataSize->DataFanIndex = this->m_FanIndex;
1456 351 : state.dataSize->DataFanPlacement = this->m_FanPlace;
1457 : }
1458 :
1459 763 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for scalable capacity sizing
1460 34 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
1461 : }
1462 :
1463 763 : Real64 coolingCapacityMultiplier = 1.0;
1464 763 : Real64 heatingCapacityMultiplier = 1.0;
1465 763 : if (this->m_HVACSizingIndex > 0) {
1466 0 : if (this->m_CoolingCapMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
1467 0 : coolingCapacityMultiplier = this->m_DesignCoolingCapacity;
1468 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
1469 : }
1470 0 : if (this->m_HeatingCapMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
1471 0 : heatingCapacityMultiplier = this->m_DesignHeatingCapacity;
1472 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
1473 : }
1474 : }
1475 :
1476 : // zone equipment that have OA mixers will need to know the OA flow rate to size coil inlet conditions
1477 763 : bool SizingDesRunThisZone = false;
1478 763 : if (this->OAMixerExists) {
1479 300 : if (state.dataSize->CurZoneEqNum > 0) {
1480 300 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1481 300 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize || this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
1482 110 : CheckZoneSizing(state, this->UnitType, this->Name);
1483 : }
1484 : // initialize OA flow for sizing other inputs (e.g., capacity)
1485 300 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
1486 110 : EqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
1487 : } else {
1488 190 : EqSizing.OAVolFlow = this->m_CoolOutAirVolFlow;
1489 : }
1490 300 : if (this->m_HeatOutAirVolFlow != DataSizing::AutoSize) {
1491 190 : EqSizing.OAVolFlow = max(EqSizing.OAVolFlow, this->m_HeatOutAirVolFlow);
1492 : }
1493 : }
1494 : }
1495 :
1496 763 : PrintFlag = false;
1497 : // STEP 1: find the DataSizing::AutoSized cooling air flow rate and capacity
1498 : // Note: this call will request fan heat and size the fan.
1499 : // Either the few lines above are too early, or there needs to be a way to avoid requesting fan heat from
1500 : // BaseSizerWithFanHeatInputs::initializeWithinEP so the fan doesn't size until the parent wants it to size.
1501 : // see PackagedTerminalHeatPumpVSAS.idf where fan is not sized large enough for cooling coil air flow rate.
1502 :
1503 : // delay fan sizing in case a VS fan is used and air flow needs to be modified above max design flow
1504 : // this may also mean capacity result does not include fan heat? and table diffs?
1505 : // and causes unit test failures, e.g., UnitarySystemModel_MultispeedDXCoilSizing.
1506 : // comment this out until the PTUnit to UnitarySystem #9273 branch is merged, so nothing changes
1507 : // until this is implemented, unbalanced air flow warnings show up in VS coil PTUnits
1508 : // int saveDataFanIndex = state.dataSize->DataFanIndex;
1509 : // state.dataSize->DataFanIndex = -1;
1510 :
1511 763 : bool coolingAirFlowIsAutosized = this->m_MaxCoolAirVolFlow == DataSizing::AutoSize;
1512 763 : bool heatingAirFlowIsAutosized = this->m_MaxHeatAirVolFlow == DataSizing::AutoSize;
1513 763 : if (this->m_CoolCoilExists) {
1514 762 : if (!this->m_HeatCoilExists) {
1515 318 : state.dataSize->ZoneCoolingOnlyFan = true;
1516 : }
1517 762 : TempSize = this->m_MaxCoolAirVolFlow;
1518 762 : SaveCurDuctType = state.dataSize->CurDuctType;
1519 : // might want to rethink this method. Tries to find the larger of cooling or heating capacity
1520 : // however, if there is no heating coil the cooling air flow rate is used, not the main flow rate
1521 : // this is fine if there are no other systems on the branch. CoilSystem does not do this (#8761).
1522 762 : if (this->m_sysType == SysType::Unitary) {
1523 131 : state.dataSize->CurDuctType = HVAC::AirDuctType::Cooling;
1524 : }
1525 762 : bool errorsFound = false;
1526 762 : if ((CoolingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (CoolingSAFlowMethod == DataSizing::None)) {
1527 762 : CoolingAirFlowSizer sizingCoolingAirFlow;
1528 762 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1529 762 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1530 762 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1531 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1532 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1533 0 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1534 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1535 0 : } else if (CoolingSAFlowMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
1536 0 : TempSize = DataSizing::AutoSize;
1537 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1538 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1539 0 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1540 0 : SysCoolingFlow *= this->m_MaxCoolAirVolFlow;
1541 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1542 0 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerCoolingCapacity) {
1543 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
1544 0 : TempSize = DataSizing::AutoSize;
1545 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1546 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1547 0 : state.dataSize->DataFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1548 0 : SizingMethod = HVAC::CoolingCapacitySizing;
1549 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
1550 0 : state.dataSize->DataTotCapCurveIndex =
1551 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1552 0 : state.dataSize->DataIsDXCoil = true;
1553 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
1554 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1555 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1556 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1557 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1558 0 : state.dataSize->DataIsDXCoil = true;
1559 : }
1560 0 : CoolingCapacitySizer sizerCoolingCapacity;
1561 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
1562 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1563 0 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1564 0 : SysCoolingFlow = CoolCapAtPeak * this->m_MaxCoolAirVolFlow;
1565 0 : state.dataSize->DataTotCapCurveIndex = 0;
1566 0 : EqSizing.CoolingCapacity = true;
1567 0 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1568 0 : } else {
1569 0 : SysCoolingFlow = this->m_DesignCoolingCapacity * this->m_MaxCoolAirVolFlow;
1570 0 : CoolCapAtPeak = this->m_DesignCoolingCapacity;
1571 0 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1572 : }
1573 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1574 : } else {
1575 : // should never happen
1576 0 : ShowSevereError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
1577 0 : ShowContinueError(state, "Illegal entry for Cooling Supply Air Flow Rate Method.");
1578 : }
1579 :
1580 762 : state.dataSize->CurDuctType = SaveCurDuctType;
1581 762 : EqSizing.CoolingAirFlow = true;
1582 762 : EqSizing.CoolingAirVolFlow = SysCoolingFlow;
1583 :
1584 : // Cooling airflow should be known at this point. Now find DataSizing::AutoSized design cooling capacity.
1585 762 : if (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity < 0.0) {
1586 602 : SizingMethod = HVAC::CoolingCapacitySizing;
1587 602 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1588 602 : TempSize = DataSizing::AutoSize;
1589 : // could probably move this up outside the IF and delete then next group below in the else
1590 602 : switch (this->m_CoolingCoilType_Num) {
1591 50 : case HVAC::CoilDX_Cooling: {
1592 100 : state.dataSize->DataTotCapCurveIndex =
1593 50 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1594 50 : state.dataSize->DataIsDXCoil = true;
1595 50 : } break;
1596 376 : case HVAC::CoilDX_CoolingSingleSpeed:
1597 : case HVAC::CoilDX_MultiSpeedCooling:
1598 : case HVAC::CoilDX_CoolingTwoSpeed:
1599 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
1600 376 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1601 376 : state.dataSize->DataIsDXCoil = true;
1602 376 : } break;
1603 7 : case HVAC::Coil_CoolingAirToAirVariableSpeed: {
1604 7 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1605 7 : state.dataSize->DataIsDXCoil = true;
1606 7 : } break;
1607 3 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
1608 3 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1609 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1610 : // state.dataSize->DataIsDXCoil = true;
1611 3 : } break;
1612 166 : default: {
1613 166 : } break;
1614 : }
1615 1204 : CoolingCapacitySizer sizerCoolingCapacity;
1616 602 : sizerCoolingCapacity.overrideSizingString(SizingString);
1617 602 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1618 602 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1619 602 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1620 : // this probably needs to be more specific. Letting heating coil size itself if user has scalable sizing
1621 602 : if (this->m_HVACSizingIndex <= 0) {
1622 602 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1623 : }
1624 : // CoilSystem does not size the cooling coil (#8761)
1625 602 : if ((this->m_sysType == SysType::Unitary) || (this->m_sysType == SysType::PackagedAC) || (this->m_sysType == SysType::PackagedHP) ||
1626 408 : (this->m_sysType == SysType::PackagedWSHP)) {
1627 349 : EqSizing.CoolingCapacity = true;
1628 349 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1629 : }
1630 762 : } else if (!HardSizeNoDesRun && (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1631 : // corrected code for #8756
1632 89 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1633 8 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1634 3 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1635 86 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1636 86 : state.dataSize->DataIsDXCoil = true;
1637 : }
1638 89 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
1639 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1640 2 : state.dataSize->DataIsDXCoil = true;
1641 : }
1642 89 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
1643 0 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1644 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1645 : // state.dataSize->DataIsDXCoil = true;
1646 : }
1647 : // PTUnit does not call CapacitySizer and adjust capacity based on flow per capacity limits
1648 89 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) {
1649 47 : state.dataSize->DataIsDXCoil = false;
1650 : }
1651 89 : SizingMethod = HVAC::CoolingCapacitySizing;
1652 89 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1653 89 : if (this->m_CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
1654 89 : (this->m_CoolingCapMethod == DataSizing::CoolingDesignCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1655 0 : TempSize = this->m_DesignCoolingCapacity;
1656 : } else {
1657 89 : TempSize = DataSizing::AutoSize;
1658 : }
1659 89 : CoolingCapacitySizer sizerCoolingCapacity;
1660 89 : sizerCoolingCapacity.overrideSizingString(SizingString);
1661 89 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1662 89 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1663 89 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1664 89 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1665 89 : EqSizing.CoolingCapacity = true;
1666 89 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1667 89 : } else {
1668 : // something seems missing here based on multiple conditional if above
1669 71 : if (this->m_DesignCoolingCapacity != DataSizing::AutoSize) {
1670 71 : CoolCapAtPeak = this->m_DesignCoolingCapacity;
1671 : }
1672 : }
1673 762 : state.dataSize->DataIsDXCoil = false;
1674 762 : state.dataSize->DataTotCapCurveIndex = 0;
1675 762 : state.dataSize->DataFlowUsedForSizing = 0.0;
1676 : }
1677 :
1678 : // STEP 2: find the DataSizing::AutoSized heating air flow rate and capacity
1679 763 : if (this->m_HeatCoilExists) {
1680 445 : if (!this->m_CoolCoilExists) {
1681 1 : state.dataSize->ZoneHeatingOnlyFan = true;
1682 : }
1683 445 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1684 445 : SizingMethod = HVAC::HeatingAirflowSizing;
1685 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1686 445 : TempSize = this->m_MaxHeatAirVolFlow;
1687 445 : SaveCurDuctType = state.dataSize->CurDuctType;
1688 445 : state.dataSize->CurDuctType = HVAC::AirDuctType::Heating;
1689 445 : if ((HeatingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (HeatingSAFlowMethod == DataSizing::None)) {
1690 445 : bool errorsFound = false;
1691 445 : HeatingAirFlowSizer sizingHeatingAirFlow;
1692 445 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1693 445 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1694 445 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1695 445 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1696 0 : bool errorsFound = false;
1697 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1698 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1699 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1700 0 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1701 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1702 0 : } else if (HeatingSAFlowMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
1703 0 : TempSize = DataSizing::AutoSize;
1704 0 : bool errorsFound = false;
1705 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1706 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1707 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1708 0 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1709 0 : SysHeatingFlow *= this->m_MaxHeatAirVolFlow;
1710 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1711 0 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerHeatingCapacity) {
1712 0 : TempSize = DataSizing::AutoSize;
1713 0 : bool errorsFound = false;
1714 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1715 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1716 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1717 0 : state.dataSize->DataFlowUsedForSizing = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1718 0 : SizingMethod = HVAC::HeatingCapacitySizing;
1719 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
1720 0 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1721 0 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
1722 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1723 0 : state.dataSize->DataIsDXCoil = true;
1724 : }
1725 0 : if (state.dataSize->CurSysNum > 0) {
1726 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1727 : false; // set to false to allow calculation of actual heating capacity
1728 : }
1729 0 : HeatingCapacitySizer sizerHeatingCapacity;
1730 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
1731 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1732 0 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1733 0 : if (state.dataSize->CurSysNum > 0) {
1734 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1735 : }
1736 0 : SysHeatingFlow = HeatCapAtPeak * this->m_MaxHeatAirVolFlow;
1737 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1738 0 : EqSizing.HeatingCapacity = true;
1739 0 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1740 0 : } else {
1741 : // should never happen
1742 0 : ShowSevereError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
1743 0 : ShowContinueError(state, "Illegal entry for Heating Supply Air Flow Rate Method.");
1744 : }
1745 :
1746 445 : state.dataSize->CurDuctType = SaveCurDuctType;
1747 445 : EqSizing.HeatingAirFlow = true;
1748 445 : EqSizing.HeatingAirVolFlow = SysHeatingFlow;
1749 :
1750 : // Heating airflow should be known at this point. Now find DataSizing::AutoSized design heating capacity.
1751 445 : if (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
1752 415 : SizingMethod = HVAC::HeatingCapacitySizing;
1753 415 : if (m_sysType == SysType::Unitary || m_sysType == SysType::CoilCoolingDX || m_sysType == SysType::CoilCoolingWater) {
1754 100 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1755 : }
1756 415 : TempSize = DataSizing::AutoSize;
1757 415 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1758 415 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1759 45 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1760 45 : state.dataSize->DataIsDXCoil = true;
1761 : }
1762 : // should have VS coil capFT here also
1763 415 : if (this->m_sysType == SysType::PackagedWSHP && this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1764 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1765 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1766 : // state.dataSize->DataIsDXCoil = true;
1767 : }
1768 : // PTUnit does not call CapacitySizer and adjust capacity based on flow per capacity limits
1769 415 : if (this->m_sysType == SysType::PackagedHP) {
1770 22 : state.dataSize->DataIsDXCoil = false;
1771 : }
1772 415 : if (state.dataSize->CurSysNum > 0) {
1773 94 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1774 : false; // set to false to allow calculation of actual heating capacity
1775 : }
1776 415 : bool errorsFound = false;
1777 415 : HeatingCapacitySizer sizerHeatingCapacity;
1778 415 : sizerHeatingCapacity.overrideSizingString(SizingString);
1779 415 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1780 415 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1781 415 : if (state.dataSize->CurSysNum > 0) {
1782 94 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1783 : }
1784 415 : EqSizing.HeatingCapacity = true;
1785 415 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1786 415 : } else {
1787 30 : if (!HardSizeNoDesRun &&
1788 18 : (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity != DataSizing::AutoSize)) {
1789 : // should have other DX heating coil types here
1790 18 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1791 3 : SizingMethod = HVAC::HeatingCapacitySizing;
1792 3 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1793 3 : TempSize = DataSizing::AutoSize;
1794 3 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1795 3 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1796 3 : state.dataSize->DataIsDXCoil = true;
1797 3 : if (state.dataSize->CurSysNum > 0) {
1798 3 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1799 : false; // set to false to allow calculation of actual heating capacity
1800 : }
1801 3 : bool errorsFound = false;
1802 3 : HeatingCapacitySizer sizerHeatingCapacity;
1803 3 : sizerHeatingCapacity.overrideSizingString(SizingString);
1804 3 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1805 3 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1806 3 : if (state.dataSize->CurSysNum > 0) {
1807 3 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1808 : }
1809 3 : EqSizing.HeatingCapacity = true;
1810 3 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1811 3 : }
1812 18 : } else {
1813 : // something seems missing here based on multiple conditional if above
1814 12 : if (this->m_DesignHeatingCapacity != DataSizing::AutoSize) {
1815 12 : HeatCapAtPeak = this->m_DesignHeatingCapacity;
1816 : }
1817 : }
1818 : }
1819 : // if ( ! UnitarySystem( UnitarySysNum ).CoolCoilExists )DXCoolCap = HeatCapAtPeak;
1820 445 : state.dataSize->DataIsDXCoil = false;
1821 445 : state.dataSize->DataTotCapCurveIndex = 0;
1822 445 : state.dataSize->DataFlowUsedForSizing = 0.0;
1823 445 : if (this->m_sysType == SysType::PackagedAC) {
1824 147 : EqSizing.HeatingCapacity = false;
1825 : }
1826 : }
1827 :
1828 763 : bool isWSVarSpeedCoolCoil = this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
1829 763 : bool isWSVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
1830 763 : bool isVarSpeedCoolCoil = this->m_HeatingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed;
1831 763 : bool isVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed;
1832 :
1833 763 : Real64 saveRawHeatingCapacity = HeatCapAtPeak;
1834 :
1835 : // STEP 3A: Find VS cooling coil air flow to capacity ratio and adjust design air flow
1836 1099 : if (EqSizing.DesCoolingLoad > 0.0 && state.dataSize->CurZoneEqNum > 0 &&
1837 336 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
1838 333 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1839 175 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed))) {
1840 9 : Real64 coolingToHeatingCapRatio = 1.0;
1841 9 : if ((isWSVarSpeedCoolCoil && this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) ||
1842 6 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1843 6 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
1844 9 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NormSpedLevel;
1845 : Real64 coolingAirFlowToCapacityRatio =
1846 9 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1847 9 : EqSizing.CoolingAirVolFlow = EqSizing.DesCoolingLoad * coolingAirFlowToCapacityRatio;
1848 9 : if (EqSizing.DesHeatingLoad > 0.0) {
1849 7 : coolingToHeatingCapRatio = EqSizing.DesCoolingLoad / EqSizing.DesHeatingLoad;
1850 : }
1851 : }
1852 9 : if (((isWSVarSpeedHeatCoil || isVarSpeedHeatCoil) && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) ||
1853 4 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1854 4 : this->m_CoolingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed)) {
1855 5 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
1856 : Real64 heatingAirFlowToCapacityRatio =
1857 5 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1858 5 : EqSizing.DesHeatingLoad *= coolingToHeatingCapRatio;
1859 5 : EqSizing.HeatingAirVolFlow = EqSizing.DesHeatingLoad * heatingAirFlowToCapacityRatio;
1860 : }
1861 : }
1862 :
1863 : // STEP 3B: use the greater of cooling and heating air flow rates for system flow
1864 : // previous version of E+ used maximum flow rate for unitary systems. Keep this methodology for now.
1865 : // Delete next 2 lines and uncomment 2 lines inside next if (HeatPump) statement to allow non-heat pump systems to operate at different flow
1866 : // rates (might require additional change to if block logic).
1867 : // UnitarySystem is sizing heating coil size = cooling coil size for 5Zone_Unitary_HXAssistedCoil (not a heat pump)
1868 : // and WaterSideEconomizer_PreCoolCoil (not a heat pump)
1869 : // and 5Zone_Unitary_VSDesuperheatWaterHeater (not a heat pump)
1870 763 : if ((!isWSVarSpeedHeatCoil &&
1871 759 : (((this->m_sysType == SysType::PackagedAC && !isVarSpeedCoolCoil) && (this->m_sysType == SysType::PackagedHP && !isVarSpeedHeatCoil)) ||
1872 759 : (this->m_sysType == SysType::Unitary && this->m_HeatPump))) ||
1873 729 : (this->m_sysType == SysType::Unitary &&
1874 98 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
1875 64 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
1876 63 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling))) {
1877 102 : EqSizing.CoolingAirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1878 102 : EqSizing.HeatingAirVolFlow = EqSizing.CoolingAirVolFlow;
1879 : }
1880 :
1881 : // STEP 4: set heat pump coil capacities equal to greater of cooling or heating capacity
1882 : // if a heat pump, use maximum values and set main air flow and capacity variables
1883 763 : if (this->m_sysType == SysType::PackagedHP && !isVarSpeedCoolCoil) {
1884 : // PTPH allows the cooling coil to set DataCoolCoilCap so cooling coil sets capacity
1885 : // This is wrong since a larger heating load should set HP capacity (next else if)
1886 28 : EqSizing.HeatingCapacity = false;
1887 735 : } else if (this->m_HeatPump && (state.dataSize->CurZoneEqNum == 0 || !isWSVarSpeedCoolCoil)) {
1888 188 : EqSizing.AirFlow = true;
1889 188 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1890 188 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit &&
1891 187 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1892 187 : EqSizing.Capacity = true;
1893 187 : EqSizing.DesCoolingLoad = max(EqSizing.DesCoolingLoad, EqSizing.DesHeatingLoad);
1894 187 : EqSizing.DesHeatingLoad = EqSizing.DesCoolingLoad;
1895 187 : state.dataSize->DXCoolCap = EqSizing.DesCoolingLoad;
1896 : }
1897 547 : } else if (!this->m_CoolCoilExists && state.dataSize->CurZoneEqNum > 0) {
1898 0 : state.dataSize->DXCoolCap = EqSizing.DesHeatingLoad;
1899 : }
1900 :
1901 : // now size fans as necessary
1902 : // comment this out until the PTUnit to UnitarySystem #9273 branch is merged, so nothing changes
1903 : // until this is implemented, unbalanced air flow warning show up in VS coil PTUnits
1904 : // state.dataSize->DataFanIndex = saveDataFanIndex;
1905 :
1906 : // Some parent objects report sizing, some do not
1907 763 : if (this->m_OKToPrintSizing) {
1908 763 : if (this->m_sysType != SysType::CoilCoolingDX && this->m_sysType != SysType::CoilCoolingWater) {
1909 462 : PrintFlag = true;
1910 : }
1911 : }
1912 : // STEP 5: report system parameters (e.g., air flow rates, capacities, etc.)
1913 763 : if (this->m_FanExists) {
1914 460 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1915 330 : PrintFlag = false;
1916 : }
1917 :
1918 460 : EqSizing.SystemAirFlow = true;
1919 460 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1920 460 : if (this->m_DesignFanVolFlowRate <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1921 395 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
1922 : }
1923 460 : state.dataSize->DataEMSOverrideON = this->m_DesignFanVolFlowRateEMSOverrideOn;
1924 460 : state.dataSize->DataEMSOverride = this->m_DesignFanVolFlowRateEMSOverrideValue;
1925 :
1926 460 : bool errorsFound = false;
1927 460 : SystemAirFlowSizer sizerSystemAirFlow;
1928 460 : std::string sizingString = "Supply Air Flow Rate [m3/s]";
1929 460 : sizerSystemAirFlow.overrideSizingString(sizingString);
1930 460 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1931 460 : this->m_DesignFanVolFlowRate = sizerSystemAirFlow.size(state, this->m_DesignFanVolFlowRate, errorsFound);
1932 :
1933 460 : state.dataSize->DataEMSOverrideON = false;
1934 460 : EqSizing.SystemAirFlow = false;
1935 :
1936 460 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1937 330 : PrintFlag = true;
1938 : }
1939 460 : }
1940 :
1941 : // not sure what to do if UnitarySystem has only 1 coil type and flow needs to occur when present coil is off
1942 : // how does constant fan operating mode pertain here?
1943 763 : if (this->m_HeatCoilExists && !this->m_CoolCoilExists) {
1944 1 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
1945 0 : this->m_MaxCoolAirVolFlow = EqSizing.HeatingAirVolFlow;
1946 : }
1947 762 : } else if (this->m_CoolCoilExists && !this->m_HeatCoilExists) {
1948 318 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
1949 0 : this->m_MaxHeatAirVolFlow = EqSizing.CoolingAirVolFlow;
1950 : }
1951 318 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1952 : }
1953 :
1954 : // PT Units report sizing for cooling then heating, UnitarySystem reverses that order
1955 : // temporarily reverse reporting for PT units so eio diffs are cleaner, remove later
1956 763 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1957 330 : if (this->m_CoolCoilExists) {
1958 : // allow design size to report
1959 330 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
1960 47 : EqSizing.CoolingAirFlow = false;
1961 : }
1962 330 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1963 283 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1964 : }
1965 330 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
1966 330 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
1967 330 : TempSize = this->m_MaxCoolAirVolFlow;
1968 330 : bool errorsFound = false;
1969 330 : CoolingAirFlowSizer sizingCoolingAirFlow;
1970 330 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
1971 330 : if (state.dataGlobal->isEpJSON) {
1972 0 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
1973 : }
1974 330 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1975 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1976 330 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1977 330 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1978 330 : state.dataSize->DataEMSOverrideON = false;
1979 330 : state.dataSize->DataConstantUsedForSizing = 0.0;
1980 330 : }
1981 330 : if (this->m_HeatCoilExists) {
1982 : // allow design size to report
1983 330 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
1984 47 : EqSizing.HeatingAirFlow = false;
1985 : }
1986 330 : SizingMethod = HVAC::HeatingAirflowSizing;
1987 330 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1988 283 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1989 : }
1990 330 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
1991 330 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1992 2 : EqSizing.AirFlow = false;
1993 : }
1994 330 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1995 330 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
1996 330 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
1997 330 : TempSize = this->m_MaxHeatAirVolFlow;
1998 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1999 330 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
2000 330 : bool errorsFound = false;
2001 330 : HeatingAirFlowSizer sizingHeatingAirFlow;
2002 330 : sizingHeatingAirFlow.overrideSizingString(SizingString);
2003 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2004 330 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2005 330 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
2006 330 : state.dataSize->DataEMSOverrideON = false;
2007 330 : state.dataSize->DataConstantUsedForSizing = 0.0;
2008 330 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2009 2 : EqSizing.AirFlow = saveEqSizingAirFlow;
2010 : }
2011 330 : }
2012 :
2013 330 : } else {
2014 433 : if (this->m_HeatCoilExists) {
2015 :
2016 115 : SizingMethod = HVAC::HeatingAirflowSizing;
2017 115 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2018 102 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
2019 : }
2020 115 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
2021 115 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2022 2 : EqSizing.AirFlow = false;
2023 : }
2024 115 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
2025 115 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
2026 115 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
2027 115 : TempSize = this->m_MaxHeatAirVolFlow;
2028 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2029 115 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
2030 115 : bool errorsFound = false;
2031 115 : HeatingAirFlowSizer sizingHeatingAirFlow;
2032 115 : sizingHeatingAirFlow.overrideSizingString(SizingString);
2033 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2034 115 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2035 115 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
2036 115 : state.dataSize->DataEMSOverrideON = false;
2037 115 : state.dataSize->DataConstantUsedForSizing = 0.0;
2038 115 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2039 2 : EqSizing.AirFlow = saveEqSizingAirFlow;
2040 : }
2041 115 : }
2042 :
2043 433 : if (this->m_CoolCoilExists) {
2044 :
2045 432 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2046 367 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
2047 : }
2048 432 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
2049 432 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
2050 432 : TempSize = this->m_MaxCoolAirVolFlow;
2051 432 : bool errorsFound = false;
2052 432 : CoolingAirFlowSizer sizingCoolingAirFlow;
2053 432 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
2054 432 : if (state.dataGlobal->isEpJSON) {
2055 3 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
2056 : }
2057 432 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
2058 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2059 432 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2060 432 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
2061 432 : state.dataSize->DataEMSOverrideON = false;
2062 432 : state.dataSize->DataConstantUsedForSizing = 0.0;
2063 432 : }
2064 : }
2065 :
2066 : // If not set, set DesignFanVolFlowRate as greater of cooling and heating to make sure this value > 0.
2067 : // If fan is hard-sized, use that value, otherwise the fan will size to DesignFanVolFlowRate
2068 763 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2069 255 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2070 255 : if (this->m_ActualFanVolFlowRate > 0.0) {
2071 0 : this->m_DesignFanVolFlowRate = this->m_ActualFanVolFlowRate;
2072 : }
2073 255 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2074 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2075 0 : ShowFatalError(state, "Unable to determine fan air flow rate.");
2076 : }
2077 : }
2078 763 : if (!this->m_FanExists) {
2079 303 : this->m_ActualFanVolFlowRate = this->m_DesignFanVolFlowRate;
2080 : }
2081 :
2082 763 : if (this->m_CoolCoilExists || this->m_HeatCoilExists || this->m_SuppCoilExists) {
2083 763 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2084 : // set no load air flow ratio local var
2085 763 : Real64 NoLoadCoolingAirFlowRateRatio = 1.0;
2086 763 : Real64 NoLoadHeatingAirFlowRateRatio = 1.0;
2087 763 : if (MSHPIndex > -1) {
2088 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling > 0) {
2089 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0] == DataSizing::AutoSize) {
2090 : NoLoadCoolingAirFlowRateRatio =
2091 24 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling));
2092 : } else {
2093 : NoLoadCoolingAirFlowRateRatio =
2094 38 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0]);
2095 : }
2096 : }
2097 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating > 0) {
2098 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0] == DataSizing::AutoSize) {
2099 : NoLoadHeatingAirFlowRateRatio =
2100 24 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating));
2101 : } else {
2102 : NoLoadHeatingAirFlowRateRatio =
2103 38 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0]);
2104 : }
2105 : }
2106 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio > 0.0) {
2107 62 : this->m_NoLoadAirFlowRateRatio = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2108 : } else {
2109 0 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2110 : }
2111 : } else {
2112 701 : if ((this->m_CoolCoilExists || this->m_HeatCoilExists) && this->m_useNoLoadLowSpeedAirFlow) {
2113 682 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2114 673 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
2115 : Real64 MaxSpeedFlowRate =
2116 9 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2117 9 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2118 9 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) >
2119 : 0.0) { // these are the air flow at speed fields, and could be 0
2120 9 : NoLoadCoolingAirFlowRateRatio =
2121 9 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2122 : } else {
2123 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2124 : }
2125 682 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
2126 : // for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum)
2127 : // for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum)
2128 : // PerfModeNum = DehumidModeNum * 2 + CapacityStageNum
2129 : // RatedAirVolFlowRate(PerfModeNum) so PerfModeNum = 1 to NumCapacityStages to find air flow rate
2130 9 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2131 9 : .RatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages);
2132 12 : if (MaxSpeedFlowRate > 0.0 &&
2133 3 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2134 3 : NoLoadCoolingAirFlowRateRatio =
2135 3 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2136 : } else { // if any flow rates are autosized use the ratio of number of capacity stages
2137 6 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages;
2138 : }
2139 664 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2140 : // RatedAirVolFlowRate(1) = high speed, RatedAirVolFlowRate2= low speed
2141 67 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1);
2142 74 : if (MaxSpeedFlowRate > 0.0 &&
2143 7 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 != DataSizing::AutoSize) {
2144 7 : NoLoadCoolingAirFlowRateRatio =
2145 7 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 / MaxSpeedFlowRate;
2146 : } else { // above flow rates for this coil could be autosized, use 1/2 for two speed coil
2147 60 : NoLoadCoolingAirFlowRateRatio = 0.5;
2148 : }
2149 597 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
2150 : // MSRatedAirVolFlowRate
2151 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2152 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2153 0 : if (MaxSpeedFlowRate > 0.0 &&
2154 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2155 0 : NoLoadCoolingAirFlowRateRatio =
2156 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2157 : } else { // if any flow rates are autosized use the ratio of number of speeds
2158 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2159 : }
2160 597 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2161 34 : NoLoadCoolingAirFlowRateRatio = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex]
2162 17 : .performance.normalMode.speeds[0]
2163 : .original_input_specs.evaporator_air_flow_fraction;
2164 : }
2165 682 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
2166 679 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2167 : Real64 MaxSpeedFlowRate =
2168 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2169 3 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2170 3 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) >
2171 : 0.0) { // these are the air flow at speed fields, and could be 0
2172 3 : NoLoadHeatingAirFlowRateRatio =
2173 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2174 : } else {
2175 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2176 : }
2177 682 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
2178 : // MSRatedAirVolFlowRate
2179 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex)
2180 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2181 0 : if (MaxSpeedFlowRate > 0.0 &&
2182 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2183 0 : NoLoadHeatingAirFlowRateRatio =
2184 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2185 : } else { // if any flow rates are autosized use the ratio of number of speeds
2186 0 : NoLoadHeatingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
2187 : }
2188 : }
2189 682 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2190 : }
2191 : }
2192 763 : if (this->m_NoCoolHeatSAFMethod <= DataSizing::SupplyAirFlowRate && this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
2193 0 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
2194 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2195 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
2196 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
2197 0 : minNoLoadFlow = 0.6667; // TODO: Should this have a Coil:Cooling:DX block?
2198 : } else {
2199 0 : if (this->m_NoLoadAirFlowRateRatio < 1.0) {
2200 0 : minNoLoadFlow = this->m_NoLoadAirFlowRateRatio;
2201 : } else {
2202 0 : minNoLoadFlow = 0.5;
2203 : }
2204 : }
2205 0 : if (this->m_MaxCoolAirVolFlow >= this->m_MaxHeatAirVolFlow) {
2206 0 : state.dataSize->DataFractionUsedForSizing =
2207 0 : min(minNoLoadFlow, (this->m_MaxHeatAirVolFlow / this->m_MaxCoolAirVolFlow) - 0.01);
2208 : } else {
2209 0 : state.dataSize->DataFractionUsedForSizing =
2210 0 : min(minNoLoadFlow, (this->m_MaxCoolAirVolFlow / this->m_MaxHeatAirVolFlow) - 0.01);
2211 : }
2212 : } else {
2213 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2214 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2215 : }
2216 763 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
2217 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.CoolingAirVolFlow;
2218 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2219 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2220 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2221 763 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
2222 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.HeatingAirVolFlow;
2223 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2224 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2225 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2226 763 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerCoolingCapacity) {
2227 0 : if (EqSizing.DesCoolingLoad <= 0.0) {
2228 : // water coils not sizing yet
2229 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2230 0 : WaterCoils::SimulateWaterCoilComponents(
2231 0 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2232 0 : EqSizing.DesCoolingLoad = WaterCoils::GetWaterCoilCapacity(
2233 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
2234 : }
2235 : }
2236 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesCoolingLoad;
2237 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2238 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2239 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2240 763 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerHeatingCapacity) {
2241 0 : if (EqSizing.DesHeatingLoad <= 0.0) {
2242 : // water coil not sizing yet
2243 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2244 0 : WaterCoils::SimulateWaterCoilComponents(
2245 0 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2246 0 : EqSizing.DesHeatingLoad = WaterCoils::GetWaterCoilCapacity(
2247 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
2248 : }
2249 : }
2250 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesHeatingLoad;
2251 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2252 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2253 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2254 : } else {
2255 763 : state.dataSize->DataFractionUsedForSizing = this->m_NoLoadAirFlowRateRatio;
2256 : }
2257 :
2258 763 : FieldNum = 11; // N11 , \field No Load Supply Air Flow Rate
2259 763 : state.dataSize->DataEMSOverrideON = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideOn;
2260 763 : state.dataSize->DataEMSOverride = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideValue;
2261 763 : TempSize = this->m_MaxNoCoolHeatAirVolFlow;
2262 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2263 763 : SizingString = "No Load Supply Air Flow Rate [m3/s]";
2264 763 : bool errorsFound = false;
2265 763 : SystemAirFlowSizer sizerSystemAirFlow;
2266 763 : sizerSystemAirFlow.overrideSizingString(SizingString);
2267 763 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2268 763 : this->m_MaxNoCoolHeatAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
2269 763 : state.dataSize->DataEMSOverrideON = false;
2270 763 : state.dataSize->DataConstantUsedForSizing = 0.0;
2271 763 : state.dataSize->DataFractionUsedForSizing = 0.0;
2272 763 : }
2273 :
2274 763 : if (this->m_MaxCoolAirVolFlow > 0.0) {
2275 762 : this->LowSpeedCoolFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxCoolAirVolFlow;
2276 : }
2277 763 : if (this->m_MaxHeatAirVolFlow > 0.0) {
2278 445 : this->LowSpeedHeatFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxHeatAirVolFlow;
2279 : }
2280 :
2281 763 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for use in component sizing
2282 34 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
2283 : }
2284 :
2285 763 : if (this->OAMixerExists) {
2286 300 : IsAutoSize = false;
2287 300 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
2288 110 : IsAutoSize = true;
2289 : }
2290 300 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2291 0 : if (this->m_CoolOutAirVolFlow > 0.0) {
2292 0 : BaseSizer::reportSizerOutput(state,
2293 : this->UnitType,
2294 : this->Name,
2295 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2296 : this->m_CoolOutAirVolFlow);
2297 : }
2298 : } else {
2299 300 : CheckZoneSizing(state, this->UnitType, this->Name);
2300 300 : Real64 CoolOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2301 300 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2302 3 : CoolOutAirVolFlowDes = 0.0;
2303 : }
2304 300 : if (IsAutoSize) {
2305 110 : this->m_CoolOutAirVolFlow = CoolOutAirVolFlowDes;
2306 110 : BaseSizer::reportSizerOutput(
2307 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]", CoolOutAirVolFlowDes);
2308 : } else {
2309 190 : if (this->m_CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2310 47 : Real64 CoolOutAirVolFlowUser = this->m_CoolOutAirVolFlow;
2311 47 : BaseSizer::reportSizerOutput(state,
2312 : this->UnitType,
2313 : this->Name,
2314 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2315 : CoolOutAirVolFlowDes,
2316 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2317 : CoolOutAirVolFlowUser);
2318 47 : if (state.dataGlobal->DisplayExtraWarnings) {
2319 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
2320 0 : state.dataSize->AutoVsHardSizingThreshold) {
2321 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2322 0 : ShowContinueError(
2323 : state,
2324 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
2325 0 : ShowContinueError(state,
2326 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
2327 : CoolOutAirVolFlowDes));
2328 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2329 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2330 : }
2331 : }
2332 : }
2333 : }
2334 : }
2335 :
2336 300 : IsAutoSize = false;
2337 300 : if (this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
2338 110 : IsAutoSize = true;
2339 : }
2340 300 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2341 0 : if (this->m_HeatOutAirVolFlow > 0.0) {
2342 0 : BaseSizer::reportSizerOutput(state,
2343 : this->UnitType,
2344 : this->Name,
2345 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2346 : this->m_HeatOutAirVolFlow);
2347 : }
2348 : } else {
2349 300 : CheckZoneSizing(state, this->UnitType, this->Name);
2350 300 : Real64 HeatOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2351 300 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2352 3 : HeatOutAirVolFlowDes = 0.0;
2353 : }
2354 300 : if (IsAutoSize) {
2355 110 : this->m_HeatOutAirVolFlow = HeatOutAirVolFlowDes;
2356 110 : BaseSizer::reportSizerOutput(
2357 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]", HeatOutAirVolFlowDes);
2358 : } else {
2359 190 : if (this->m_HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2360 47 : Real64 HeatOutAirVolFlowUser = this->m_HeatOutAirVolFlow;
2361 47 : BaseSizer::reportSizerOutput(state,
2362 : this->UnitType,
2363 : this->Name,
2364 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
2365 : HeatOutAirVolFlowDes,
2366 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2367 : HeatOutAirVolFlowUser);
2368 47 : if (state.dataGlobal->DisplayExtraWarnings) {
2369 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
2370 0 : state.dataSize->AutoVsHardSizingThreshold) {
2371 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2372 0 : ShowContinueError(
2373 : state,
2374 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
2375 0 : ShowContinueError(state,
2376 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
2377 : HeatOutAirVolFlowDes));
2378 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2379 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2380 : }
2381 : }
2382 : }
2383 : }
2384 : }
2385 :
2386 300 : IsAutoSize = false;
2387 300 : if (this->m_NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
2388 110 : IsAutoSize = true;
2389 : }
2390 300 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2391 0 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0) {
2392 0 : BaseSizer::reportSizerOutput(state,
2393 : this->UnitType,
2394 : this->Name,
2395 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2396 : this->m_NoCoolHeatOutAirVolFlow);
2397 : }
2398 : } else {
2399 300 : CheckZoneSizing(state, this->UnitType, this->Name);
2400 : Real64 NoCoolHeatOutAirVolFlowDes =
2401 300 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, this->m_MaxNoCoolHeatAirVolFlow);
2402 300 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2403 100 : NoCoolHeatOutAirVolFlowDes = 0.0;
2404 : }
2405 300 : if (IsAutoSize) {
2406 110 : this->m_NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
2407 110 : BaseSizer::reportSizerOutput(state,
2408 : this->UnitType,
2409 : this->Name,
2410 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2411 : NoCoolHeatOutAirVolFlowDes);
2412 : } else {
2413 190 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2414 39 : Real64 NoCoolHeatOutAirVolFlowUser = this->m_NoCoolHeatOutAirVolFlow;
2415 39 : BaseSizer::reportSizerOutput(state,
2416 : this->UnitType,
2417 : this->Name,
2418 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2419 : NoCoolHeatOutAirVolFlowDes,
2420 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2421 : NoCoolHeatOutAirVolFlowUser);
2422 39 : if (state.dataGlobal->DisplayExtraWarnings) {
2423 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
2424 0 : state.dataSize->AutoVsHardSizingThreshold) {
2425 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2426 0 : ShowContinueError(state,
2427 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2428 : NoCoolHeatOutAirVolFlowUser));
2429 0 : ShowContinueError(
2430 : state,
2431 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2432 : NoCoolHeatOutAirVolFlowDes));
2433 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2434 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2435 : }
2436 : }
2437 : }
2438 : }
2439 : }
2440 : }
2441 763 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2442 183 : PrintFlag = false;
2443 : }
2444 :
2445 763 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2446 330 : if (this->m_AirFlowControl == UseCompFlow::On) {
2447 21 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2448 21 : this->m_NoLoadAirFlowRateRatio = 1.0;
2449 : }
2450 330 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2451 324 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2452 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
2453 6 : if (this->m_AirFlowControl == UseCompFlow::On) {
2454 2 : Real64 airFlowAdjustmentRatio = 1.0;
2455 2 : if (!coolingAirFlowIsAutosized) {
2456 2 : airFlowAdjustmentRatio =
2457 2 : this->m_MaxCoolAirVolFlow /
2458 2 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2459 2 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2460 : }
2461 2 : this->m_MaxNoCoolHeatAirVolFlow =
2462 2 : airFlowAdjustmentRatio * state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1);
2463 : }
2464 : }
2465 6 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2466 3 : if (this->m_AirFlowControl == UseCompFlow::On) {
2467 1 : Real64 airFlowAdjustmentRatio = 1.0;
2468 1 : if (!heatingAirFlowIsAutosized) {
2469 1 : airFlowAdjustmentRatio =
2470 1 : this->m_MaxHeatAirVolFlow /
2471 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2472 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2473 : }
2474 1 : if (this->m_CoolCoilExists) {
2475 1 : this->m_MaxNoCoolHeatAirVolFlow =
2476 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2477 : airFlowAdjustmentRatio *
2478 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1));
2479 : } else {
2480 0 : this->m_MaxNoCoolHeatAirVolFlow =
2481 0 : airFlowAdjustmentRatio *
2482 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1);
2483 : }
2484 : }
2485 : }
2486 : }
2487 : }
2488 :
2489 : // Change the Volume Flow Rates to Mass Flow Rates
2490 763 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
2491 763 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
2492 763 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2493 763 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2494 763 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2495 763 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2496 763 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2497 :
2498 : // initialize multi-speed coils
2499 763 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) ||
2500 759 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
2501 14 : if (this->m_NumOfSpeedCooling > 0) {
2502 14 : if (this->m_CoolVolumeFlowRate.empty()) {
2503 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2504 : }
2505 14 : if (this->m_CoolMassFlowRate.empty()) {
2506 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2507 : }
2508 14 : if (this->m_MSCoolingSpeedRatio.empty()) {
2509 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2510 : }
2511 : }
2512 :
2513 14 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2514 14 : if (MSHPIndex > -1) {
2515 16 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1; --Iter) {
2516 14 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2517 14 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2518 14 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2519 : }
2520 : }
2521 : }
2522 :
2523 14 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2524 : blankString,
2525 14 : this->m_CoolingCoilIndex,
2526 : HVAC::FanOp::Invalid, // Invalid instead of off?
2527 : HVAC::CompressorOp::Off,
2528 : 0.0,
2529 : 1,
2530 : 0.0,
2531 : 0.0,
2532 : 0.0,
2533 : 0.0); // conduct the sizing operation in the VS WSHP
2534 14 : if (this->m_NumOfSpeedCooling != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds) {
2535 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2536 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2537 0 : ShowFatalError(state,
2538 0 : format("Cooling coil = {}: {}",
2539 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).VarSpeedCoilType,
2540 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).Name));
2541 : }
2542 14 : state.dataSize->DXCoolCap = VariableSpeedCoils::GetCoilCapacityVariableSpeed(
2543 14 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
2544 14 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2545 14 : if (this->m_DXHeatingCoil) {
2546 8 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2547 : }
2548 :
2549 124 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2550 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2551 110 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2552 160 : this->m_MSCoolingSpeedRatio[Iter] =
2553 80 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2554 80 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedCooling);
2555 80 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * this->m_MSCoolingSpeedRatio[Iter];
2556 80 : this->m_CoolMassFlowRate[Iter] = this->MaxCoolAirMassFlow * this->m_MSCoolingSpeedRatio[Iter];
2557 : } else {
2558 60 : this->m_CoolVolumeFlowRate[Iter] =
2559 30 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter);
2560 30 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2561 : // this is divided by the system max air flow, not the cooling coil max air flow, doesn't seem correct
2562 30 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2563 : }
2564 : }
2565 :
2566 14 : if (MSHPIndex > -1) {
2567 2 : this->m_MaxNoCoolHeatAirVolFlow =
2568 2 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2569 2 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2570 2 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2571 12 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2572 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2573 : }
2574 :
2575 749 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
2576 : // mine data from heat exchanger assisted cooling coil
2577 : // Get DX heat exchanger assisted cooling coil index
2578 3 : int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilType_Num;
2579 3 : if (childCCType_Num == HVAC::CoilDX_Cooling) {
2580 0 : int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilIndex;
2581 0 : if (childCCIndex < 0) {
2582 0 : ShowWarningError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
2583 0 : ShowFatalError(state, "No cooling coil = Coil:Cooling:DX found.");
2584 0 : ErrFound = true;
2585 : }
2586 0 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
2587 0 : this->m_NumOfSpeedCooling = newCoil.performance.normalMode.speeds.size();
2588 0 : if (this->m_NumOfSpeedCooling > 0) {
2589 0 : if (this->m_CoolVolumeFlowRate.empty()) {
2590 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2591 : }
2592 0 : if (this->m_CoolMassFlowRate.empty()) {
2593 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2594 : }
2595 0 : if (this->m_MSCoolingSpeedRatio.empty()) {
2596 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2597 : }
2598 : }
2599 :
2600 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2601 0 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2602 0 : if (MSHPIndex > -1) {
2603 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2604 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2605 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2606 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2607 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2608 : }
2609 : }
2610 : }
2611 :
2612 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2613 0 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2614 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2615 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2616 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2617 : }
2618 :
2619 : // Use discrete/continuous control algorithm regardless of number of speeds
2620 0 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2621 0 : this->m_DiscreteSpeedCoolingCoil = true;
2622 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2623 0 : this->m_ContSpeedCoolingCoil = true;
2624 : }
2625 :
2626 0 : newCoil.size(state);
2627 0 : if (MSHPIndex == -1) {
2628 0 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2629 0 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2630 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2631 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2632 0 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2633 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2634 : } else {
2635 0 : this->m_MSCoolingSpeedRatio[Iter] =
2636 0 : this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2637 : }
2638 : }
2639 : }
2640 :
2641 0 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2642 0 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2643 0 : if (this->m_HeatPump) {
2644 0 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2645 : }
2646 :
2647 0 : if (MSHPIndex > -1) {
2648 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2649 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2650 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2651 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2652 : }
2653 0 : this->m_CoolVolumeFlowRate[Iter] =
2654 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2655 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2656 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2657 : }
2658 0 : this->m_MaxNoCoolHeatAirVolFlow =
2659 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2660 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2661 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2662 0 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2663 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2664 : }
2665 : }
2666 746 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2667 53 : if (this->m_NumOfSpeedCooling > 0) {
2668 53 : if (this->m_CoolVolumeFlowRate.empty()) {
2669 17 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2670 : }
2671 53 : if (this->m_CoolMassFlowRate.empty()) {
2672 17 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2673 : }
2674 53 : if (this->m_MSCoolingSpeedRatio.empty()) {
2675 17 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2676 : }
2677 : }
2678 :
2679 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2680 53 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2681 53 : if (MSHPIndex > -1) {
2682 86 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2683 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2684 66 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2685 62 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2686 62 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2687 : }
2688 : }
2689 : }
2690 :
2691 : // mine capacity from Coil:Cooling:DX object
2692 53 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
2693 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2694 53 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2695 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2696 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2697 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2698 : }
2699 :
2700 : // Use discrete/continuous control algorithm regardless of number of speeds
2701 53 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2702 51 : this->m_DiscreteSpeedCoolingCoil = true;
2703 2 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2704 2 : this->m_ContSpeedCoolingCoil = true;
2705 : }
2706 :
2707 53 : newCoil.size(state);
2708 53 : if (MSHPIndex == -1) {
2709 : // Gotta loop backwards since we may try to access the last element when there are no fans
2710 82 : for (Iter = this->m_NumOfSpeedCooling; Iter >= 1; --Iter) {
2711 49 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2712 49 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2713 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2714 49 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2715 47 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2716 : } else {
2717 2 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2718 : }
2719 : }
2720 : }
2721 :
2722 53 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2723 53 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2724 53 : if (this->m_HeatPump) {
2725 19 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2726 : }
2727 :
2728 53 : if (MSHPIndex > -1) {
2729 86 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2730 66 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2731 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2732 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2733 : }
2734 132 : this->m_CoolVolumeFlowRate[Iter] =
2735 66 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2736 66 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2737 66 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2738 : }
2739 20 : this->m_MaxNoCoolHeatAirVolFlow =
2740 20 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2741 20 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2742 20 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2743 33 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2744 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2745 : }
2746 :
2747 693 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2748 105 : if (this->m_NumOfSpeedCooling > 0) {
2749 105 : if (this->m_CoolVolumeFlowRate.empty()) {
2750 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2751 : }
2752 105 : if (this->m_CoolMassFlowRate.empty()) {
2753 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2754 : }
2755 105 : if (this->m_MSCoolingSpeedRatio.empty()) {
2756 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2757 : }
2758 : }
2759 :
2760 : // set the multi-speed high flow rate variable in case a non-zero air flow rate resides on the coil inlet during sizing (e.g., upstream
2761 : // system ran prior to this one)
2762 210 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
2763 210 : EqSizing.CoolingAirVolFlow *
2764 105 : state.dataEnvrn->StdRhoAir; // doesn't matter what this value is since only coil size is needed and CompressorOn = 0 here
2765 105 : DXCoils::SimDXCoilMultiSpeed(state, blankString, 1.0, 1.0, this->m_CoolingCoilIndex, 0, HVAC::FanOp::Invalid, HVAC::CompressorOp::Off);
2766 105 : if (!HardSizeNoDesRun && EqSizing.Capacity) {
2767 : // do nothing, the vars EqSizing.DesCoolingLoad and DataSizing::DXCoolCap are already set earlier and the values could be max of the
2768 : // cooling and heating autosized values. Thus resetting them here to user specified value may not be the design size used else where
2769 : } else {
2770 200 : state.dataSize->DXCoolCap =
2771 100 : DXCoils::GetCoilCapacityByIndexType(state, this->m_CoolingCoilIndex, this->m_CoolingCoilType_Num, ErrFound);
2772 100 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2773 : }
2774 105 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2775 :
2776 105 : if (MSHPIndex > -1) {
2777 : // use reverse order since we divide by CoolVolumeFlowRate(max)
2778 117 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2779 79 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2780 7 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2781 7 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2782 : }
2783 158 : this->m_CoolVolumeFlowRate[Iter] =
2784 79 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2785 79 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2786 79 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2787 : }
2788 38 : this->m_MaxNoCoolHeatAirVolFlow =
2789 38 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2790 38 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2791 38 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2792 67 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2793 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2794 : } else {
2795 201 : for (Iter = this->m_NumOfSpeedCooling; Iter > 0; --Iter) {
2796 134 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * Iter / this->m_NumOfSpeedCooling;
2797 134 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2798 134 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2799 : }
2800 67 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2801 67 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2802 : }
2803 588 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2804 20 : if (this->m_NumOfSpeedCooling > 0) {
2805 1 : if (this->m_CoolVolumeFlowRate.empty()) {
2806 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2807 : }
2808 1 : if (this->m_CoolMassFlowRate.empty()) {
2809 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2810 : }
2811 1 : if (this->m_MSCoolingSpeedRatio.empty()) {
2812 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2813 : }
2814 : }
2815 20 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2816 :
2817 20 : if (MSHPIndex > -1) {
2818 5 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2819 4 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2820 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2821 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2822 : }
2823 8 : this->m_CoolVolumeFlowRate[Iter] =
2824 4 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2825 4 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2826 4 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2827 : }
2828 1 : this->m_MaxNoCoolHeatAirVolFlow =
2829 1 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2830 1 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2831 1 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2832 19 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2833 19 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2834 : }
2835 : }
2836 :
2837 763 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2838 750 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2839 13 : if (this->m_NumOfSpeedHeating > 0) {
2840 13 : if (this->m_HeatVolumeFlowRate.empty()) {
2841 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2842 : }
2843 13 : if (this->m_HeatMassFlowRate.empty()) {
2844 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2845 : }
2846 13 : if (this->m_MSHeatingSpeedRatio.empty()) {
2847 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2848 : }
2849 : }
2850 :
2851 13 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2852 :
2853 13 : if (MSHPIndex > -1) {
2854 : // use reverse order since we divide by HeatVolumeFlowRate(max)
2855 51 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2856 38 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2857 26 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint &&
2858 0 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2859 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage)) {
2860 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2861 : } else {
2862 26 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2863 26 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2864 : }
2865 : } else {
2866 12 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2867 12 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2868 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] < 1.0 &&
2869 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
2870 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2871 0 : ShowContinueError(
2872 0 : state, format("Design specification object = {}", state.dataUnitarySystems->designSpecMSHP[MSHPIndex].name));
2873 0 : ShowContinueError(state,
2874 : "When control type = SetPointBased the outlet air temperature must change with coil capacity, if "
2875 : "air flow also changes outlet air temperature will be relatively constant.");
2876 0 : ShowContinueError(
2877 : state,
2878 0 : format("Speed {} Supply Air Flow Ratio During Heating Operation will be set = 1.0 and the simulation continues",
2879 : Iter));
2880 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2881 : }
2882 : }
2883 : }
2884 76 : this->m_HeatVolumeFlowRate[Iter] =
2885 38 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2886 38 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2887 38 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2888 : }
2889 13 : if (this->m_CoolCoilExists) {
2890 13 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2891 13 : this->m_MaxNoCoolHeatAirVolFlow =
2892 13 : min(this->m_MaxNoCoolHeatAirVolFlow,
2893 13 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2894 13 : this->MaxNoCoolHeatAirMassFlow =
2895 13 : min(this->MaxNoCoolHeatAirMassFlow,
2896 13 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2897 13 : this->m_NoLoadAirFlowRateRatio =
2898 13 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2899 : } else {
2900 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2901 : }
2902 0 : } else if (MSHPIndex > -1) {
2903 0 : this->m_MaxNoCoolHeatAirVolFlow =
2904 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2905 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2906 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2907 : } else {
2908 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2909 : }
2910 : }
2911 750 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
2912 746 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2913 7 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2914 7 : if (MSHPIndex > -1) {
2915 11 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2916 10 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2917 10 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2918 10 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2919 : }
2920 : }
2921 : }
2922 :
2923 7 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2924 : blankString,
2925 7 : this->m_HeatingCoilIndex,
2926 : HVAC::FanOp::Invalid,
2927 : HVAC::CompressorOp::Off,
2928 : 0.0,
2929 : 1,
2930 : 0.0,
2931 : 0.0,
2932 : 0.0,
2933 : 0.0); // conduct the sizing operation in the VS WSHP
2934 :
2935 7 : if (this->m_NumOfSpeedHeating != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds) {
2936 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2937 0 : ShowContinueError(state, "Number of heating speeds does not match coil object.");
2938 0 : ShowFatalError(state,
2939 0 : format("Heating coil = {}: {}",
2940 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).VarSpeedCoilType,
2941 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).Name));
2942 : }
2943 :
2944 7 : if (this->m_NumOfSpeedHeating > 0) {
2945 7 : if (this->m_HeatVolumeFlowRate.empty()) {
2946 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2947 : }
2948 7 : if (this->m_HeatMassFlowRate.empty()) {
2949 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2950 : }
2951 7 : if (this->m_MSHeatingSpeedRatio.empty()) {
2952 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2953 : }
2954 : }
2955 :
2956 77 : for (Iter = this->m_NumOfSpeedHeating; Iter >= 1; --Iter) {
2957 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2958 70 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2959 : // SpeedRatio is only used in OnOff fan and should represent the ratio of flow to fan max flow
2960 100 : this->m_MSHeatingSpeedRatio[Iter] =
2961 50 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2962 50 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedHeating);
2963 50 : this->m_HeatVolumeFlowRate[Iter] = this->m_MaxHeatAirVolFlow * this->m_MSHeatingSpeedRatio[Iter];
2964 50 : this->m_HeatMassFlowRate[Iter] = this->MaxHeatAirMassFlow * this->m_MSHeatingSpeedRatio[Iter];
2965 : } else {
2966 40 : this->m_HeatVolumeFlowRate[Iter] =
2967 20 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter);
2968 20 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2969 20 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2970 : // this is divided by the system max air flow, not the heating coil max air flow
2971 20 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2972 : } else {
2973 : // if there is no fan this doesn't matter? Should calculate SpeedRatio in fan model? and get rid of SpeedRatio variable?
2974 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_HeatVolumeFlowRate[this->m_NumOfSpeedHeating];
2975 : }
2976 : }
2977 : }
2978 :
2979 7 : if (this->m_CoolCoilExists && this->m_NumOfSpeedHeating > 0) {
2980 14 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2981 1 : this->m_MaxNoCoolHeatAirVolFlow =
2982 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2983 1 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2984 1 : this->MaxNoCoolHeatAirMassFlow =
2985 1 : min(this->MaxNoCoolHeatAirMassFlow,
2986 1 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2987 1 : this->m_NoLoadAirFlowRateRatio =
2988 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2989 6 : } else if (this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2990 0 : this->m_MaxNoCoolHeatAirVolFlow =
2991 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2992 0 : this->MaxNoCoolHeatAirMassFlow =
2993 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2994 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2995 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2996 6 : } else if (!this->m_CoolVolumeFlowRate.empty()) {
2997 : // what the heck is this next line? should be min of min cooling and min heating flow rates?
2998 : // this is calculated above so likely not even needed here, just have to be sure it's always calculated
2999 6 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
3000 6 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
3001 3 : this->m_sysType == SysType::PackagedWSHP) {
3002 4 : if (!this->m_MultiOrVarSpeedCoolCoil && !this->m_MultiOrVarSpeedHeatCoil) {
3003 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3004 : }
3005 4 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
3006 : } else {
3007 : // this should be min of min cooling and min heating flow rates?
3008 2 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
3009 : }
3010 6 : this->m_NoLoadAirFlowRateRatio =
3011 6 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
3012 : } else {
3013 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
3014 : }
3015 0 : } else if (MSHPIndex > -1) {
3016 0 : this->m_MaxNoCoolHeatAirVolFlow =
3017 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3018 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
3019 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
3020 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3021 : } else {
3022 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
3023 : }
3024 : }
3025 763 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3026 : // pass air flow rate to zone water coil
3027 9 : if (state.dataSize->CurZoneEqNum > 0) {
3028 7 : WaterCoils::SetCoilDesFlow(state,
3029 7 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
3030 7 : this->m_HeatingCoilName,
3031 : this->m_MaxHeatAirVolFlow,
3032 7 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
3033 : }
3034 :
3035 9 : if (this->m_NumOfSpeedHeating > 0) {
3036 1 : if (this->m_HeatVolumeFlowRate.empty()) {
3037 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
3038 : }
3039 1 : if (this->m_HeatMassFlowRate.empty()) {
3040 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
3041 : }
3042 1 : if (this->m_MSHeatingSpeedRatio.empty()) {
3043 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
3044 : }
3045 : }
3046 :
3047 9 : MSHPIndex = this->m_DesignSpecMSHPIndex;
3048 9 : if (MSHPIndex > -1) {
3049 5 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
3050 4 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
3051 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
3052 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
3053 : }
3054 8 : this->m_HeatVolumeFlowRate[Iter] =
3055 4 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
3056 4 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
3057 4 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
3058 : }
3059 1 : if (this->m_CoolCoilExists) {
3060 1 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > 0) {
3061 0 : this->m_MaxNoCoolHeatAirVolFlow =
3062 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
3063 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
3064 0 : this->MaxNoCoolHeatAirMassFlow =
3065 0 : min(this->MaxNoCoolHeatAirMassFlow,
3066 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
3067 0 : this->m_NoLoadAirFlowRateRatio =
3068 0 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
3069 : } else {
3070 1 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
3071 1 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
3072 1 : this->m_NoLoadAirFlowRateRatio =
3073 1 : min(this->m_NoLoadAirFlowRateRatio, (this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate));
3074 : }
3075 : } else {
3076 0 : this->m_MaxNoCoolHeatAirVolFlow =
3077 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3078 0 : this->MaxNoCoolHeatAirMassFlow =
3079 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3080 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
3081 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3082 : }
3083 : }
3084 : }
3085 :
3086 : // Not sure if this may be needed for special cases
3087 763 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow < 0.0) {
3088 0 : if (!state.dataSize->SysSizingRunDone) {
3089 0 : int BranchNum = BranchInputManager::GetAirBranchIndex(state, "AirloopHVAC:UnitarySystem", this->Name);
3090 0 : BranchFanFlow = 0.0;
3091 0 : if (BranchNum > 0.0) {
3092 0 : std::string FanType = "";
3093 0 : std::string FanName = "";
3094 0 : BranchInputManager::GetBranchFanTypeName(state, BranchNum, FanType, FanName, ErrFound);
3095 0 : if (!ErrFound) {
3096 0 : BranchFanFlow = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
3097 : }
3098 0 : }
3099 0 : if (BranchFanFlow > 0.0) {
3100 0 : this->m_MaxCoolAirVolFlow = BranchFanFlow;
3101 : } else {
3102 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3103 0 : if (SystemFlow > 0.0) {
3104 0 : this->m_MaxCoolAirVolFlow = SystemFlow;
3105 : } else {
3106 : // what do I do?
3107 : }
3108 : }
3109 : }
3110 : }
3111 :
3112 : // why is this here?
3113 763 : this->m_SenLoadLoss = 0.0;
3114 763 : if (this->m_Humidistat) {
3115 25 : this->m_LatLoadLoss = 0.0;
3116 : }
3117 :
3118 763 : switch (this->m_sysType) {
3119 175 : case SysType::PackagedAC:
3120 : case SysType::PackagedHP:
3121 175 : PrintFlag = false;
3122 175 : break;
3123 588 : default:
3124 588 : break;
3125 : }
3126 763 : if (this->m_CoolCoilExists) {
3127 762 : SizingMethod = HVAC::CoolingCapacitySizing;
3128 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3129 762 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
3130 40 : WaterCoils::SimulateWaterCoilComponents(
3131 40 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3132 20 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3133 40 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
3134 20 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3135 20 : state.dataSize->DataFractionUsedForSizing = 1.0;
3136 20 : SizingMethod = HVAC::AutoCalculateSizing;
3137 20 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3138 742 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
3139 : std::string HXCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(
3140 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3141 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
3142 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound, true);
3143 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(
3144 0 : state, blankString, true, HVAC::CompressorOp::On, 1.0, this->m_CoolingCoilIndex, HVAC::FanOp::Cycling, false, 1.0, false);
3145 0 : state.dataSize->DataConstantUsedForSizing =
3146 0 : WaterCoils::GetWaterCoilCapacity(state, Util::makeUPPER(HVAC::cAllCoilTypes(ActualCoolCoilType)), HXCoilName, ErrFound);
3147 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3148 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3149 0 : SizingMethod = HVAC::AutoCalculateSizing;
3150 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3151 742 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3152 154 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3153 : blankString,
3154 154 : this->m_CoolingCoilIndex,
3155 : this->m_CoolingCoilSensDemand,
3156 : this->m_CoolingCoilLatentDemand,
3157 : HVAC::FanOp::Invalid,
3158 : HVAC::CompressorOp::Off,
3159 : 0.0,
3160 : FirstHVACIteration);
3161 154 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3162 154 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3163 154 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3164 154 : state.dataSize->DataFractionUsedForSizing = 1.0;
3165 154 : SizingMethod = HVAC::AutoCalculateSizing;
3166 154 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3167 154 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
3168 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3169 : }
3170 : // airflow sizing with multispeed fan
3171 308 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3172 154 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3173 154 : if (this->m_NumOfSpeedCooling > 1) {
3174 2 : int FanIndex = this->m_FanIndex;
3175 6 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
3176 4 : if (this->m_DesignSpecMSHPIndex > -1) {
3177 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] ==
3178 : DataSizing::AutoSize) {
3179 2 : this->m_CoolVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedCooling) * AirFlowRate;
3180 : } else {
3181 0 : this->m_CoolVolumeFlowRate[i] =
3182 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
3183 : }
3184 : } else {
3185 2 : this->m_CoolVolumeFlowRate[i] =
3186 2 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3187 : }
3188 4 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3189 : }
3190 : }
3191 588 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
3192 5 : WaterToAirHeatPump::SimWatertoAirHP(state,
3193 : blankString,
3194 5 : this->m_CoolingCoilIndex,
3195 : this->MaxCoolAirMassFlow,
3196 : this->m_FanOpMode,
3197 : FirstHVACIteration,
3198 5 : this->m_InitHeatPump,
3199 : 0.0,
3200 : 0.0,
3201 : HVAC::CompressorOp::Off,
3202 : 0.0);
3203 10 : state.dataSize->DataConstantUsedForSizing =
3204 5 : WaterToAirHeatPump::GetCoilCapacity(state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3205 5 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3206 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
3207 5 : SizingMethod = HVAC::AutoCalculateSizing;
3208 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
3209 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3210 5 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3211 : }
3212 583 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
3213 4 : PackagedThermalStorageCoil::SimTESCoil(
3214 4 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, 0.0);
3215 4 : PackagedThermalStorageCoil::GetTESCoilCoolingCapacity(
3216 4 : state, this->m_CoolingCoilName, state.dataSize->DataConstantUsedForSizing, ErrFound, CompType);
3217 4 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3218 4 : state.dataSize->DataFractionUsedForSizing = 1.0;
3219 4 : SizingMethod = HVAC::AutoCalculateSizing;
3220 : }
3221 :
3222 762 : TempSize = this->m_DesignCoolingCapacity;
3223 762 : state.dataSize->DataFlowUsedForSizing = this->m_MaxCoolAirVolFlow;
3224 762 : SizingString = "Nominal Cooling Capacity [W]";
3225 762 : bool errorsFound = false;
3226 762 : CoolingCapacitySizer sizerCoolingCapacity;
3227 762 : sizerCoolingCapacity.overrideSizingString(SizingString);
3228 762 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3229 762 : this->m_DesignCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
3230 762 : state.dataSize->DataConstantUsedForSizing = 0.0;
3231 762 : state.dataSize->DataFractionUsedForSizing = 0.0;
3232 762 : state.dataSize->DataFlowUsedForSizing = 0.0;
3233 762 : }
3234 :
3235 763 : if (this->m_HeatCoilExists) {
3236 445 : SizingMethod = HVAC::HeatingCapacitySizing;
3237 :
3238 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3239 445 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3240 18 : WaterCoils::SimulateWaterCoilComponents(
3241 18 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3242 9 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3243 18 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
3244 9 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3245 9 : state.dataSize->DataFractionUsedForSizing = 1.0;
3246 9 : SizingMethod = HVAC::AutoCalculateSizing;
3247 9 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3248 436 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3249 154 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3250 : blankString,
3251 154 : this->m_HeatingCoilIndex,
3252 : this->m_HeatingCoilSensDemand,
3253 : dummy,
3254 : HVAC::FanOp::Invalid, // Invalid instead of off?
3255 : HVAC::CompressorOp::Off,
3256 : 0.0,
3257 : FirstHVACIteration);
3258 154 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3259 154 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3260 154 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3261 154 : state.dataSize->DataFractionUsedForSizing = 1.0;
3262 154 : SizingMethod = HVAC::AutoCalculateSizing;
3263 154 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3264 154 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3265 : // adjusted cooling coil capacity
3266 154 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3267 : blankString,
3268 154 : this->m_CoolingCoilIndex,
3269 : this->m_CoolingCoilSensDemand,
3270 : this->m_CoolingCoilLatentDemand,
3271 : HVAC::FanOp::Invalid, // Invalid instead of off?
3272 : HVAC::CompressorOp::Off,
3273 : 0.0,
3274 : FirstHVACIteration);
3275 154 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3276 154 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3277 154 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3278 : }
3279 154 : state.dataSize->DataFractionUsedForSizing = 1.0;
3280 154 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3281 : // airflow sizing with multispeed fan
3282 308 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3283 154 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3284 154 : if (this->m_NumOfSpeedHeating > 1) {
3285 2 : int FanIndex = this->m_FanIndex;
3286 6 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
3287 4 : if (this->m_DesignSpecMSHPIndex > -1) {
3288 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] ==
3289 : DataSizing::AutoSize) {
3290 2 : this->m_HeatVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedHeating) * AirFlowRate;
3291 : } else {
3292 0 : this->m_HeatVolumeFlowRate[i] =
3293 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
3294 : }
3295 : } else {
3296 2 : this->m_HeatVolumeFlowRate[i] =
3297 2 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3298 : }
3299 4 : this->m_HeatMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3300 : }
3301 : }
3302 : }
3303 :
3304 445 : TempSize = this->m_DesignHeatingCapacity;
3305 445 : SizingString = "Nominal Heating Capacity [W]";
3306 445 : if (state.dataSize->CurSysNum > 0) {
3307 109 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
3308 : false; // set to false to allow calculation of parent object heating capacity
3309 : }
3310 445 : bool errorsFound = false;
3311 445 : HeatingCapacitySizer sizerHeatingCapacity;
3312 445 : sizerHeatingCapacity.overrideSizingString(SizingString);
3313 445 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3314 445 : TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3315 445 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3316 154 : state.dataSize->DXCoolCap = TempSize;
3317 : }
3318 445 : if (state.dataSize->CurSysNum > 0) {
3319 109 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
3320 : }
3321 445 : this->m_DesignHeatingCapacity = TempSize;
3322 445 : state.dataSize->DataConstantUsedForSizing = 0.0;
3323 445 : state.dataSize->DataFractionUsedForSizing = 0.0;
3324 445 : state.dataSize->DataHeatSizeRatio = 1.0;
3325 445 : }
3326 :
3327 763 : if (!HardSizeNoDesRun && (EqSizing.Capacity && EqSizing.DesHeatingLoad > 0.0)) {
3328 : // vars EqSizing.DesHeatingLoad is already set earlier and supplemental heating coil should
3329 : // be sized to design value instead of user specified value if HardSizeNoDesRun is false
3330 181 : state.dataSize->UnitaryHeatCap = EqSizing.DesHeatingLoad;
3331 :
3332 : } else {
3333 582 : state.dataSize->UnitaryHeatCap = this->m_DesignHeatingCapacity;
3334 : }
3335 :
3336 763 : if (this->m_sysType == SysType::PackagedWSHP) {
3337 155 : PrintFlag = true;
3338 : }
3339 :
3340 763 : if ((this->m_HeatCoilExists || this->m_SuppCoilExists) && this->m_ControlType != UnitarySysCtrlType::CCMASHRAE) {
3341 445 : TempSize = this->DesignMaxOutletTemp;
3342 445 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
3343 445 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3344 183 : PrintFlag = true;
3345 183 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
3346 183 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
3347 183 : }
3348 445 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3349 445 : this->DesignMaxOutletTemp = sizerMaxHeaterOutTemp.size(state, TempSize, ErrFound);
3350 445 : }
3351 :
3352 763 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3353 183 : PrintFlag = false;
3354 : }
3355 :
3356 763 : if (this->m_SuppCoilExists) {
3357 225 : switch (this->m_sysType) {
3358 183 : case SysType::PackagedWSHP:
3359 : case SysType::PackagedHP:
3360 183 : if (this->m_HVACSizingIndex <= 0) {
3361 183 : EqSizing.HeatingCapacity = false; // ensure PTHP supplemental heating coil sizes to load
3362 : }
3363 183 : break;
3364 42 : default:
3365 42 : break;
3366 : }
3367 :
3368 225 : TempSize = this->m_DesignSuppHeatingCapacity;
3369 225 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
3370 225 : if (TempSize == DataSizing::AutoSize) {
3371 207 : IsAutoSize = true;
3372 207 : if (this->m_sysType == SysType::Unitary) {
3373 29 : PrintFlag = false;
3374 : }
3375 207 : bool errorsFound = false;
3376 207 : HeatingCapacitySizer sizerHeatingCapacity;
3377 207 : sizerHeatingCapacity.overrideSizingString(SizingString);
3378 207 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3379 207 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3380 207 : }
3381 : // logic here isn't accurate. Replicating temporarily to minimize diffs in AutoSizingLibrary refactor
3382 225 : TempSize = this->m_DesignSuppHeatingCapacity;
3383 :
3384 225 : if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && IsAutoSize) {
3385 2 : state.dataSize->DataConstantUsedForSizing = max(this->m_DesignSuppHeatingCapacity, this->m_DesignCoolingCapacity);
3386 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3387 2 : TempSize = DataSizing::AutoSize;
3388 : // pass design size to supplemental heater
3389 2 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3390 223 : } else if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
3391 4 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3392 : } else {
3393 219 : if (state.dataSize->CurZoneEqNum > 0) {
3394 184 : state.dataSize->SuppHeatCap = saveRawHeatingCapacity;
3395 : } else {
3396 35 : state.dataSize->SuppHeatCap = this->m_DesignHeatingCapacity;
3397 : }
3398 : }
3399 :
3400 225 : if (this->m_OKToPrintSizing &&
3401 225 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3402 42 : PrintFlag = true;
3403 : }
3404 225 : state.dataSize->DataCoilIsSuppHeater = true;
3405 225 : bool errorsFound = false;
3406 225 : HeatingCapacitySizer sizerHeatingCapacity;
3407 225 : sizerHeatingCapacity.overrideSizingString(SizingString);
3408 225 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3409 225 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3410 225 : state.dataSize->DataConstantUsedForSizing = 0.0;
3411 225 : state.dataSize->DataFractionUsedForSizing = 0.0;
3412 225 : state.dataSize->DataCoilIsSuppHeater = false;
3413 : }
3414 :
3415 : // register plant flow rate. Not sure this has ever been tested.
3416 763 : if (this->m_HeatRecActive) {
3417 0 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->m_HeatRecoveryInletNodeNum, this->m_DesignHRWaterVolumeFlow);
3418 : }
3419 :
3420 : // Set flow rate for unitary system with no fan
3421 763 : if (state.dataSize->CurOASysNum == 0 && state.dataSize->CurZoneEqNum == 0 && this->m_DesignFanVolFlowRate <= 0.0) {
3422 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3423 0 : if (SystemFlow > 0.0) {
3424 0 : this->m_DesignFanVolFlowRate = SystemFlow;
3425 : } else {
3426 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3427 : }
3428 0 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
3429 : }
3430 :
3431 : // Moved from InitLoadBasedControl
3432 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
3433 763 : if (this->m_AirLoopEquipment && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
3434 103 : int NumAirLoopZones = 0; // number of zone inlet nodes in an air loop
3435 103 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
3436 103 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = true;
3437 103 : NumAirLoopZones =
3438 103 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
3439 224 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3440 : // zone inlet nodes for cooling
3441 121 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
3442 121 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
3443 : // the data structure for the zones inlet nodes has not been filled
3444 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3445 : }
3446 : }
3447 : // zone inlet nodes for heating
3448 121 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
3449 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
3450 : // the data structure for the zones inlet nodes has not been filled
3451 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3452 : }
3453 : }
3454 : }
3455 : }
3456 103 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady) {
3457 103 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
3458 224 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3459 121 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
3460 121 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3461 121 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == this->ControlZoneNum) {
3462 103 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
3463 103 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3464 : }
3465 : }
3466 103 : if (SumOfMassFlowRateMax != 0.0) {
3467 103 : if (state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
3468 103 : this->ControlZoneMassFlowFrac =
3469 103 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
3470 : } else {
3471 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3472 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
3473 0 : this->ControlZoneMassFlowFrac = 1.0;
3474 : }
3475 103 : this->m_SmallLoadTolerance = 5.0 / this->ControlZoneMassFlowFrac; // adjust 5W load tolerance by control zone fraction
3476 103 : BaseSizer::reportSizerOutput(state,
3477 : this->UnitType,
3478 : this->Name,
3479 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
3480 : this->ControlZoneMassFlowFrac);
3481 : }
3482 : }
3483 103 : } else {
3484 660 : this->ControlZoneMassFlowFrac = 1.0;
3485 : }
3486 :
3487 : // should only report for those that allow SZVAV inputs, e.g., control type == CCMASHRAE
3488 763 : PrintFlag = true;
3489 :
3490 763 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3491 0 : bool SizingDesRunThisSys = false;
3492 0 : state.dataSize->DataZoneUsedForSizing = this->ControlZoneNum;
3493 0 : CheckThisZoneForSizing(state, state.dataSize->DataZoneUsedForSizing, SizingDesRunThisSys);
3494 :
3495 0 : capacityMultiplier = 0.5; // one-half of design zone load
3496 0 : if (SizingDesRunThisSys) {
3497 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesCoolLoad * capacityMultiplier;
3498 : } else {
3499 0 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignCoolingCapacity * capacityMultiplier;
3500 : }
3501 0 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3502 0 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3503 0 : ASHRAEMinSATCoolingSizer sizerASHRAEMinSATCooling;
3504 0 : std::string stringOverride = "Minimum Supply Air Temperature [C]";
3505 0 : if (state.dataGlobal->isEpJSON) {
3506 0 : stringOverride = "minimum_supply_air_temperature [C]";
3507 : }
3508 0 : sizerASHRAEMinSATCooling.overrideSizingString(stringOverride);
3509 0 : sizerASHRAEMinSATCooling.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3510 0 : this->DesignMinOutletTemp = sizerASHRAEMinSATCooling.size(state, this->DesignMinOutletTemp, ErrFound);
3511 :
3512 0 : if (SizingDesRunThisSys) {
3513 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesHeatLoad * capacityMultiplier;
3514 : } else {
3515 0 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignHeatingCapacity * capacityMultiplier;
3516 : }
3517 0 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3518 0 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3519 0 : ASHRAEMaxSATHeatingSizer sizerASHRAEMaxSATHeating;
3520 0 : stringOverride = "Maximum Supply Air Temperature [C]";
3521 0 : if (state.dataGlobal->isEpJSON) {
3522 0 : stringOverride = "maximum_supply_air_temperature [C]";
3523 : }
3524 0 : sizerASHRAEMaxSATHeating.overrideSizingString(stringOverride);
3525 0 : sizerASHRAEMaxSATHeating.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3526 0 : this->DesignMaxOutletTemp = sizerASHRAEMaxSATHeating.size(state, this->DesignMaxOutletTemp, ErrFound);
3527 :
3528 0 : state.dataSize->DataCapacityUsedForSizing = 0.0; // reset so other routines don't use this inadvertently
3529 0 : state.dataSize->DataFlowUsedForSizing = 0.0;
3530 0 : state.dataSize->DataZoneUsedForSizing = 0;
3531 :
3532 : // check that MaxNoCoolHeatAirVolFlow is less than both MaxCoolAirVolFlow and MaxHeatAirVolFlow
3533 0 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3534 0 : if (this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxCoolAirVolFlow || this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxHeatAirVolFlow) {
3535 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3536 0 : ShowContinueError(
3537 : state,
3538 : " For SingleZoneVAV control the No Load Supply Air Flow Rate must be less than both the cooling and heating supply "
3539 : "air flow rates.");
3540 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow) - 0.01;
3541 0 : ShowContinueError(
3542 : state,
3543 0 : format(" The SingleZoneVAV control No Load Supply Air Flow Rate is reset to {:.5T} and the simulation continues.",
3544 0 : this->m_MaxNoCoolHeatAirVolFlow));
3545 : }
3546 : }
3547 0 : }
3548 :
3549 763 : state.dataUnitarySystems->CoolingLoad = TempCoolingLoad;
3550 763 : state.dataUnitarySystems->HeatingLoad = TempHeatingLoad;
3551 : // if (++NumUnitarySystemsSized == NumUnitarySystem)
3552 : // UnitarySystemNumericFields.deallocate(); // remove temporary array for field names at end of sizing
3553 763 : } // namespace UnitarySystems
3554 :
3555 1526 : void UnitarySys::processInputSpec(EnergyPlusData &state,
3556 : const UnitarySysInputSpec &input_data,
3557 : int sysNum,
3558 : bool &errorsFound,
3559 : bool const ZoneEquipment,
3560 : int const ZoneOAUnitNum)
3561 : {
3562 : static constexpr std::string_view routineName = "UnitarySys::processInputSpec";
3563 :
3564 : using namespace OutputReportPredefined;
3565 :
3566 : static constexpr std::string_view unitarySysHeatPumpPerformanceObjectType("UnitarySystemPerformance:Multispeed");
3567 :
3568 1526 : std::string const &cCurrentModuleObject = input_data.system_type;
3569 : DataLoopNode::ConnectionObjectType objType = static_cast<DataLoopNode::ConnectionObjectType>(
3570 1526 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(input_data.system_type)));
3571 1526 : std::string const &thisObjectName = input_data.name;
3572 :
3573 1526 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisObjectName};
3574 :
3575 1526 : this->Name = Util::makeUPPER(thisObjectName);
3576 1526 : sysNum = getUnitarySystemIndex(state, thisObjectName);
3577 1526 : this->m_UnitarySysNum = sysNum;
3578 :
3579 1526 : if (ZoneEquipment) {
3580 732 : this->m_IsZoneEquipment = true;
3581 : }
3582 1526 : if (state.dataUnitarySystems->getInputOnceFlag) {
3583 1526 : this->AirInNode = NodeInputManager::GetOnlySingleNode(state,
3584 763 : input_data.air_inlet_node_name,
3585 : errorsFound,
3586 : objType,
3587 : thisObjectName,
3588 : DataLoopNode::NodeFluidType::Air,
3589 : DataLoopNode::ConnectionType::Inlet,
3590 : NodeInputManager::CompFluidStream::Primary,
3591 : DataLoopNode::ObjectIsParent);
3592 : } else {
3593 763 : this->AirInNode = Util::FindItemInList(input_data.air_inlet_node_name, state.dataLoopNodes->NodeID);
3594 : }
3595 :
3596 1526 : if (state.dataUnitarySystems->getInputOnceFlag) {
3597 1526 : this->AirOutNode = NodeInputManager::GetOnlySingleNode(state,
3598 763 : input_data.air_outlet_node_name,
3599 : errorsFound,
3600 : objType,
3601 : thisObjectName,
3602 : DataLoopNode::NodeFluidType::Air,
3603 : DataLoopNode::ConnectionType::Outlet,
3604 : NodeInputManager::CompFluidStream::Primary,
3605 : DataLoopNode::ObjectIsParent);
3606 : } else {
3607 763 : this->AirOutNode = Util::FindItemInList(input_data.air_outlet_node_name, state.dataLoopNodes->NodeID);
3608 : }
3609 :
3610 : // need to read in all information needed to SetupOutputVariable in setupAllOutputVars
3611 : // as soon as all systems are read in, regardless if all information is available, reports will be set up.
3612 : // make sure we have all the information needed to process reports (see IF blocks in setupAllOutputVars).
3613 : // all coil types, which comps exist, control type, heat recovery active, cooling coil index.
3614 1526 : bool errFlag = false;
3615 1526 : bool PrintMessage = false;
3616 :
3617 1526 : if (!input_data.design_specification_multispeed_object_type.empty() && !input_data.design_specification_multispeed_object_name.empty()) {
3618 120 : this->m_DesignSpecMultispeedHPType = input_data.design_specification_multispeed_object_type;
3619 120 : this->m_DesignSpecMultispeedHPName = input_data.design_specification_multispeed_object_name;
3620 120 : DesignSpecMSHP thisDesignSpec;
3621 120 : this->m_CompPointerMSHP = thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, this->m_DesignSpecMultispeedHPName);
3622 120 : this->m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, this->m_DesignSpecMultispeedHPName);
3623 120 : }
3624 :
3625 : // these are needed for call from GetOASysNumHeat(Cool)ingCoils
3626 1526 : this->m_HeatingCoilName = input_data.heating_coil_name;
3627 1526 : this->m_HeatingCoilTypeName = input_data.heating_coil_object_type;
3628 1526 : if (!this->m_HeatingCoilTypeName.empty()) {
3629 890 : this->m_HeatCoilExists = true;
3630 : }
3631 1526 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num == 0) {
3632 445 : if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:VariableSpeed")) {
3633 3 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingAirToAirVariableSpeed;
3634 442 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:MultiSpeed")) {
3635 13 : this->m_HeatingCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
3636 429 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Water")) {
3637 9 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWater;
3638 9 : if (this->m_DesignSpecMSHPIndex > -1) {
3639 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
3640 1 : if (this->m_NumOfSpeedHeating > 1) {
3641 1 : this->m_MultiSpeedHeatingCoil = true;
3642 1 : this->m_MultiOrVarSpeedHeatCoil = true;
3643 : }
3644 : }
3645 420 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Steam")) {
3646 2 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
3647 418 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:EquationFit")) {
3648 154 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPSimple;
3649 264 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation")) {
3650 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHP;
3651 259 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3652 4 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
3653 255 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric:MultiStage")) {
3654 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingElectric_MultiStage;
3655 255 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Gas:MultiStage")) {
3656 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingGas_MultiStage;
3657 431 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Fuel") ||
3658 431 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric") ||
3659 296 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Desuperheater")) {
3660 214 : this->m_HeatingCoilType_Num =
3661 214 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
3662 41 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:UserDefined")) {
3663 0 : this->m_HeatingCoilType_Num = HVAC::Coil_UserDefined;
3664 41 : } else if (this->m_HeatCoilExists) {
3665 41 : this->m_HeatingCoilType_Num =
3666 41 : DXCoils::GetCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag, PrintMessage);
3667 : }
3668 :
3669 445 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
3670 432 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
3671 432 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
3672 13 : this->m_MultiSpeedHeatingCoil = true;
3673 432 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
3674 428 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
3675 7 : this->m_VarSpeedHeatingCoil = true;
3676 : }
3677 : }
3678 :
3679 1526 : this->m_CoolingCoilName = input_data.cooling_coil_name;
3680 1526 : if (!input_data.cooling_coil_object_type.empty()) { // not required field
3681 1524 : this->m_CoolCoilExists = true;
3682 : }
3683 : // Find the type of coil. do not print message since this may not be the correct coil type.
3684 1526 : errFlag = false;
3685 1526 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num == 0) {
3686 762 : if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:VariableSpeed")) {
3687 10 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
3688 752 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:MultiSpeed")) {
3689 38 : this->m_CoolingCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3690 714 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water")) {
3691 20 : this->m_IsDXCoil = false;
3692 20 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3693 20 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3694 20 : if (this->m_DesignSpecMSHPIndex > -1) {
3695 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3696 1 : if (this->m_NumOfSpeedCooling > 1) {
3697 1 : this->m_DiscreteSpeedCoolingCoil = true;
3698 1 : this->m_MultiOrVarSpeedCoolCoil = true;
3699 : }
3700 : }
3701 694 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water:DetailedGeometry")) {
3702 0 : this->m_IsDXCoil = false;
3703 0 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterDetailed;
3704 0 : if (this->m_DesignSpecMSHPIndex > -1) {
3705 0 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3706 0 : if (this->m_NumOfSpeedCooling > 1) {
3707 0 : this->m_DiscreteSpeedCoolingCoil = true;
3708 0 : this->m_MultiOrVarSpeedCoolCoil = true;
3709 : }
3710 : }
3711 694 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
3712 9 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
3713 685 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
3714 3 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3715 3 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3716 682 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
3717 0 : this->m_IsDXCoil = false;
3718 0 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3719 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3720 682 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:EquationFit")) {
3721 154 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPSimple;
3722 528 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation")) {
3723 5 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHP;
3724 523 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3725 4 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
3726 519 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed")) {
3727 395 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
3728 124 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoSpeed")) {
3729 67 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
3730 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:UserDefined")) {
3731 0 : this->m_IsDXCoil = false;
3732 0 : this->m_CoolingCoilType_Num = HVAC::Coil_UserDefined;
3733 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed:ThermalStorage")) {
3734 4 : this->m_CoolingCoilType_Num = HVAC::CoilDX_PackagedThermalStorageCooling;
3735 53 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX")) { // CoilCoolingDX
3736 53 : this->m_CoolingCoilType_Num = HVAC::CoilDX_Cooling;
3737 53 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
3738 53 : if (this->m_CoolingCoilIndex == -1) {
3739 0 : ShowFatalError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
3740 : } else {
3741 : // set variable speed coil flag as necessary
3742 53 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
3743 53 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
3744 53 : if (this->m_NumOfSpeedCooling > 1) {
3745 36 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
3746 35 : this->m_DiscreteSpeedCoolingCoil = true;
3747 1 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
3748 1 : this->m_ContSpeedCoolingCoil = true;
3749 : }
3750 36 : this->m_MultiOrVarSpeedCoolCoil = true;
3751 : }
3752 : }
3753 : }
3754 :
3755 762 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
3756 38 : this->m_DiscreteSpeedCoolingCoil = true;
3757 724 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
3758 720 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
3759 14 : this->m_ContSpeedCoolingCoil = true;
3760 : }
3761 : }
3762 :
3763 1526 : if (!input_data.supplemental_heating_coil_object_type.empty()) {
3764 450 : this->m_SuppCoilExists = true;
3765 : }
3766 :
3767 1526 : if (!input_data.supply_fan_object_type.empty() && !input_data.supply_fan_name.empty()) {
3768 920 : this->m_FanExists = true;
3769 : }
3770 :
3771 : constexpr static std::array<std::string_view, static_cast<int>(UnitarySysCtrlType::Num)> UnitarySysCtrlTypeNamesUC = {
3772 : "NONE", "LOAD", "SETPOINT", "SINGLEZONEVAV"};
3773 1526 : this->m_ControlType = static_cast<UnitarySysCtrlType>(getEnumValue(UnitarySysCtrlTypeNamesUC, Util::makeUPPER(input_data.control_type)));
3774 1526 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3775 0 : this->m_ValidASHRAECoolCoil = true;
3776 0 : this->m_ValidASHRAEHeatCoil = true;
3777 : }
3778 :
3779 1526 : this->m_DesignHRWaterVolumeFlow = input_data.design_heat_recovery_water_flow_rate;
3780 1526 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
3781 0 : this->m_HeatRecActive = true;
3782 : }
3783 :
3784 1526 : errFlag = false;
3785 1526 : if (!input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) {
3786 600 : this->OAMixerIndex = MixedAir::GetOAMixerIndex(state, input_data.oa_mixer_name);
3787 600 : ValidateComponent(state, input_data.oa_mixer_type, input_data.oa_mixer_name, errFlag, cCurrentModuleObject);
3788 600 : if (errFlag) {
3789 0 : ShowContinueError(state, format("specified in {} = \"{}\".", cCurrentModuleObject, input_data.oa_mixer_name));
3790 0 : errorsFound = true;
3791 0 : errFlag = false;
3792 : } else {
3793 600 : this->OAMixerExists = true;
3794 : // OANodeNums = outside air mixer node numbers, OANodeNums(4) = outside air mixer mixed air node
3795 600 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, input_data.oa_mixer_name, errFlag);
3796 600 : if (errFlag) {
3797 0 : ShowContinueError(state, format("that was specified in {} = {}", cCurrentModuleObject, input_data.oa_mixer_name));
3798 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
3799 0 : errorsFound = true;
3800 0 : errFlag = false;
3801 : } else {
3802 600 : this->m_OAMixerNodes[0] = OANodeNums(1); // inlet
3803 600 : this->m_OAMixerNodes[1] = OANodeNums(2); // relief
3804 600 : this->m_OAMixerNodes[2] = OANodeNums(3); // return
3805 600 : this->m_OAMixerNodes[3] = OANodeNums(4); // mixed
3806 : }
3807 600 : }
3808 1852 : } else if ((input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) ||
3809 926 : (!input_data.oa_mixer_type.empty() && input_data.oa_mixer_name.empty())) {
3810 0 : ShowSevereError(state, format("Missing one of {} Outdoor Air Mixer inputs.", cCurrentModuleObject));
3811 0 : ShowContinueError(state, format("..OutdoorAir:Mixer type = {}", input_data.oa_mixer_type));
3812 0 : ShowContinueError(state, format("..OutdoorAir:Mixer name = {}", input_data.oa_mixer_name));
3813 0 : errorsFound = true;
3814 : }
3815 1526 : this->m_HeatConvTol = input_data.heat_conv_tol;
3816 1526 : this->m_CoolConvTol = input_data.cool_conv_tol;
3817 :
3818 : // Early calls to ATMixer don't have enough info to pass GetInput. Need to get the data next time through.
3819 1526 : if (sysNum == -1 || !state.dataZoneEquip->ZoneEquipInputsFilled) {
3820 763 : return;
3821 : }
3822 :
3823 763 : this->m_CoolOutAirVolFlow = input_data.cooling_oa_flow_rate;
3824 763 : this->m_HeatOutAirVolFlow = input_data.heating_oa_flow_rate;
3825 763 : this->m_NoCoolHeatOutAirVolFlow = input_data.no_load_oa_flow_rate;
3826 :
3827 763 : if (ZoneEquipment) {
3828 351 : this->m_OKToPrintSizing = true;
3829 : }
3830 :
3831 763 : this->m_IterationMode.resize(3);
3832 :
3833 763 : std::string loc_m_CoolingSAFMethod = input_data.cooling_supply_air_flow_rate_method;
3834 763 : Real64 loc_m_CoolingSAFMethod_SAFlow = input_data.cooling_supply_air_flow_rate;
3835 763 : Real64 loc_m_CoolingSAFMethod_SAFlowPerFloorArea = input_data.cooling_supply_air_flow_rate_per_floor_area;
3836 763 : Real64 loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.cooling_fraction_of_autosized_cooling_supply_air_flow_rate;
3837 763 : Real64 loc_m_CoolingSAFMethod_FlowPerCoolingCapacity = input_data.cooling_supply_air_flow_rate_per_unit_of_capacity;
3838 763 : std::string loc_m_HeatingSAFMethod = input_data.heating_supply_air_flow_rate_method;
3839 763 : Real64 loc_m_HeatingSAFMethod_SAFlow = input_data.heating_supply_air_flow_rate;
3840 763 : Real64 loc_m_HeatingSAFMethod_SAFlowPerFloorArea = input_data.heating_supply_air_flow_rate_per_floor_area;
3841 763 : Real64 loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.heating_fraction_of_autosized_heating_supply_air_flow_rate;
3842 763 : Real64 loc_m_HeatingSAFMethod_FlowPerHeatingCapacity = input_data.heating_supply_air_flow_rate_per_unit_of_capacity;
3843 763 : std::string loc_m_NoCoolHeatSAFMethod = input_data.no_load_supply_air_flow_rate_method;
3844 763 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlow = input_data.no_load_supply_air_flow_rate;
3845 763 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = input_data.no_load_supply_air_flow_rate_per_floor_area;
3846 763 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.no_load_fraction_of_autosized_cooling_supply_air_flow_rate;
3847 763 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.no_load_fraction_of_autosized_heating_supply_air_flow_rate;
3848 763 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity =
3849 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation;
3850 763 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity =
3851 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation;
3852 :
3853 763 : int FanInletNode = 0;
3854 763 : int FanOutletNode = 0;
3855 763 : Real64 FanVolFlowRate = 0.0;
3856 763 : int CoolingCoilInletNode = 0;
3857 763 : int CoolingCoilOutletNode = 0;
3858 763 : int HeatingCoilInletNode = 0;
3859 763 : int HeatingCoilOutletNode = 0;
3860 763 : int SupHeatCoilInletNode = 0;
3861 763 : int SupHeatCoilOutletNode = 0;
3862 :
3863 763 : bool isNotOK = false;
3864 :
3865 763 : if (input_data.availability_schedule_name.empty()) {
3866 86 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3867 677 : } else if ((this->m_sysAvailSched = Sched::GetSchedule(state, input_data.availability_schedule_name)) == nullptr) {
3868 0 : ShowWarningItemNotFound(state,
3869 : eoh,
3870 : "Availability Schedule Name",
3871 : input_data.availability_schedule_name,
3872 : "Set the default as Always On. Simulation continues.");
3873 0 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3874 : }
3875 :
3876 763 : if (!input_data.controlling_zone_or_thermostat_location.empty()) { // not required field
3877 124 : this->ControlZoneNum = Util::FindItemInList(input_data.controlling_zone_or_thermostat_location, state.dataHeatBal->Zone);
3878 639 : } else if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3879 330 : if (this->m_sysType == SysType::Unitary) {
3880 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3881 0 : ShowContinueError(state, "Controlling Zone or Thermostat Location cannot be blank when Control Type = Load or SingleZoneVAV");
3882 0 : errorsFound = true;
3883 : }
3884 : }
3885 :
3886 : // check that control zone name is valid for load based control
3887 763 : if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3888 : // bypass this error for PTUnits
3889 454 : if (this->ControlZoneNum == 0 &&
3890 330 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3891 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3892 0 : ShowContinueError(state, "When Control Type = Load or SingleZoneVAV");
3893 0 : ShowContinueError(state,
3894 0 : format(" Controlling Zone or Thermostat Location must be a valid zone name, zone name = {}",
3895 0 : input_data.controlling_zone_or_thermostat_location));
3896 0 : errorsFound = true;
3897 : }
3898 : }
3899 :
3900 763 : if (Util::SameString(input_data.dehumidification_control_type, "None")) {
3901 739 : this->m_DehumidControlType_Num = DehumCtrlType::None;
3902 739 : this->m_Humidistat = false;
3903 24 : } else if (Util::SameString(input_data.dehumidification_control_type, "CoolReheat")) {
3904 13 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
3905 13 : this->m_Humidistat = true;
3906 11 : } else if (Util::SameString(input_data.dehumidification_control_type, "Multimode")) {
3907 11 : this->m_DehumidControlType_Num = DehumCtrlType::Multimode;
3908 11 : this->m_Humidistat = true;
3909 : }
3910 763 : if (this->m_Humidistat && this->m_ControlType == UnitarySysCtrlType::Load) {
3911 9 : bool AirNodeFound = false;
3912 42 : for (int HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
3913 33 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != this->ControlZoneNum) {
3914 24 : continue;
3915 : }
3916 9 : AirNodeFound = true;
3917 : }
3918 9 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3919 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3920 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
3921 0 : ShowContinueError(
3922 0 : state, format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3923 0 : errorsFound = true;
3924 : }
3925 : }
3926 :
3927 763 : Real64 TotalFloorAreaOnAirLoop = 0.0;
3928 763 : int AirLoopNumber = 0;
3929 763 : bool AirNodeFound = false;
3930 763 : bool AirLoopFound = false;
3931 763 : bool OASysFound = false;
3932 763 : bool ZoneEquipmentFound = false;
3933 763 : bool ZoneInletNodeFound = false;
3934 :
3935 : // Get AirTerminal mixer data
3936 763 : SingleDuct::GetATMixer(state,
3937 : thisObjectName,
3938 763 : this->m_ATMixerName,
3939 763 : this->m_ATMixerIndex,
3940 763 : this->ATMixerType,
3941 763 : this->m_ATMixerPriNode,
3942 763 : this->m_ATMixerSecNode,
3943 763 : this->ATMixerOutNode,
3944 : this->AirOutNode);
3945 763 : if (this->ATMixerType == HVAC::MixerType::InletSide || this->ATMixerType == HVAC::MixerType::SupplySide) {
3946 34 : this->ATMixerExists = true;
3947 : }
3948 : // check that heat pump doesn't have local outside air and DOA
3949 763 : if (this->ATMixerExists && this->m_OAMixerNodes[0] > 0 &&
3950 0 : (input_data.cooling_oa_flow_rate != 0.0 || input_data.heating_oa_flow_rate != 0.0 || input_data.no_load_oa_flow_rate != 0.0)) {
3951 0 : ShowSevereError(state,
3952 0 : format("{} = \"{}\". System has local as well as central outdoor air specified", cCurrentModuleObject, this->Name));
3953 0 : errorsFound = true;
3954 : }
3955 :
3956 : // if part of ZoneHVAC:OutdoorAirUnit bypass most checks for connection to air loop or OASystem
3957 763 : if (ZoneOAUnitNum > 0) {
3958 8 : OASysFound = true;
3959 : }
3960 :
3961 763 : if (ZoneEquipment) {
3962 351 : int ControlledZoneNum = 0;
3963 351 : int ZoneExhNum = 0;
3964 351 : bool ZoneExhaustNodeFound = false;
3965 351 : bool InducedNodeFound = false;
3966 :
3967 351 : if (!this->ATMixerExists) {
3968 317 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3969 317 : if (ZoneExhaustNodeFound) {
3970 316 : ZoneEquipmentFound = true;
3971 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3972 : // this should be zoneExhaustNode
3973 316 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum);
3974 316 : this->ControlZoneNum = ControlledZoneNum;
3975 316 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3976 316 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3977 : } else { // find if the inlet node is an induced node from zone plenum
3978 1 : int ZoneInletNum = 0;
3979 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3980 1 : if (ZoneInletNodeFound) {
3981 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3982 : this->AirInNode,
3983 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3984 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3985 1 : if (InducedNodeFound) {
3986 1 : this->m_ZoneInletNode = this->AirOutNode;
3987 1 : ZoneEquipmentFound = true;
3988 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3989 : }
3990 : }
3991 : }
3992 34 : } else if (this->ATMixerType == HVAC::MixerType::InletSide) {
3993 21 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->m_ATMixerSecNode, ControlledZoneNum, ZoneExhNum);
3994 21 : if (ZoneExhaustNodeFound) {
3995 20 : ZoneEquipmentFound = true;
3996 20 : this->m_ZoneInletNode = this->AirOutNode;
3997 20 : this->ControlZoneNum = ControlledZoneNum;
3998 20 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3999 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
4000 20 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
4001 : } else {
4002 1 : int ZoneInletNum = 0;
4003 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
4004 1 : if (ZoneInletNodeFound) {
4005 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
4006 : this->m_ATMixerSecNode,
4007 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
4008 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
4009 1 : if (InducedNodeFound) {
4010 1 : this->m_ZoneInletNode = this->AirOutNode;
4011 1 : ZoneEquipmentFound = true;
4012 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4013 : }
4014 : }
4015 : }
4016 13 : } else if (this->ATMixerType == HVAC::MixerType::SupplySide) {
4017 13 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
4018 13 : if (ZoneExhaustNodeFound) {
4019 12 : ZoneEquipmentFound = true;
4020 12 : this->m_ZoneInletNode = this->ATMixerOutNode;
4021 12 : this->ControlZoneNum = ControlledZoneNum;
4022 12 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4023 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
4024 12 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->ATMixerOutNode, this->ControlZoneNum);
4025 : } else {
4026 1 : int ZoneInletNum = 0;
4027 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->ATMixerOutNode, this->ControlZoneNum, ZoneInletNum);
4028 1 : if (ZoneInletNodeFound) {
4029 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
4030 : this->AirInNode,
4031 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
4032 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
4033 1 : if (InducedNodeFound) {
4034 1 : this->m_ZoneInletNode = this->ATMixerOutNode;
4035 1 : ZoneEquipmentFound = true;
4036 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4037 : }
4038 : }
4039 : }
4040 : }
4041 351 : if (!ZoneExhaustNodeFound && !InducedNodeFound) {
4042 : // Exhaust Node was not found
4043 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4044 0 : ShowContinueError(state,
4045 0 : format("Incorrect or misspelled Air Inlet Node Name or Exhaust Node Name or Induced Node Name. = {}",
4046 0 : input_data.air_inlet_node_name));
4047 0 : ShowContinueError(
4048 : state,
4049 0 : format("Air Inlet Node {} name does not match any controlled zone exhaust node name. Check ZoneHVAC:EquipmentConnections "
4050 : "object inputs.",
4051 0 : input_data.air_inlet_node_name));
4052 0 : ShowContinueError(state, "or Induced Air Outlet Node Name specified in AirLoopHVAC:ReturnPlenum object.");
4053 0 : errorsFound = true;
4054 351 : } else if (!ZoneInletNodeFound) {
4055 0 : bool ZoneInletNodeExists = false;
4056 0 : int InletControlledZoneNum = 0;
4057 0 : int ZoneInletNum = 0;
4058 0 : ZoneInletNodeExists = searchZoneInletNodes(state, this->AirOutNode, InletControlledZoneNum, ZoneInletNum);
4059 0 : if (!ZoneInletNodeExists) {
4060 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4061 0 : ShowContinueError(state, format("Incorrect or misspelled Air Outlet Node Name = {}", input_data.air_outlet_node_name));
4062 0 : ShowContinueError(state,
4063 : "Node name does not match any controlled zone inlet node name. Check ZoneHVAC:EquipmentConnections "
4064 : "object inputs.");
4065 0 : errorsFound = true;
4066 : }
4067 : }
4068 : } else {
4069 : // check if the UnitarySystem is connected to an air loop
4070 :
4071 : int compIndex;
4072 : int branchIndex;
4073 412 : AirLoopFound = searchTotalComponents(state, this->AirloopEqType, thisObjectName, compIndex, branchIndex, AirLoopNumber);
4074 412 : if (AirLoopFound && (this->ControlZoneNum > 0)) {
4075 : // Find the controlled zone number for the specified thermostat location
4076 103 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
4077 :
4078 : // Determine if system is on air loop served by the thermostat location specified
4079 103 : int ZoneInletNum = 0;
4080 103 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
4081 103 : if (ZoneInletNodeFound) {
4082 103 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
4083 103 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
4084 : }
4085 :
4086 1063 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4087 960 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4088 857 : continue;
4089 : }
4090 103 : AirNodeFound = true;
4091 : }
4092 103 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4093 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4094 0 : continue;
4095 : }
4096 0 : AirNodeFound = true;
4097 : }
4098 103 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4099 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4100 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4101 0 : ShowContinueError(
4102 : state,
4103 0 : format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
4104 0 : errorsFound = true;
4105 : }
4106 :
4107 103 : if (this->ControlZoneNum > 0) {
4108 : // Find the controlled zone number for the specified thermostat location
4109 103 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
4110 :
4111 : // Determine if system is on air loop served by the thermostat location specified
4112 103 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
4113 103 : if (ZoneInletNodeFound) {
4114 103 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
4115 103 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
4116 : }
4117 :
4118 : // if (this->m_ZoneInletNode == 0) AirLoopFound = false;
4119 1063 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4120 960 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4121 857 : continue;
4122 : }
4123 103 : AirNodeFound = true;
4124 : }
4125 103 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4126 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4127 0 : continue;
4128 : }
4129 0 : AirNodeFound = true;
4130 : }
4131 103 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4132 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4133 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4134 0 : ShowContinueError(state,
4135 0 : format("specified Controlling Zone or Thermostat Location name = {}",
4136 0 : input_data.controlling_zone_or_thermostat_location));
4137 0 : errorsFound = true;
4138 : }
4139 : }
4140 : }
4141 :
4142 : // check if the UnitarySystem is connected to an outside air system
4143 412 : if (!AirLoopFound && state.dataAirLoop->NumOASystems > 0) {
4144 4 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
4145 2 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
4146 4 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum), thisObjectName) ||
4147 2 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject)) {
4148 0 : continue;
4149 : }
4150 2 : AirLoopNumber = OASysNum;
4151 2 : OASysFound = true;
4152 2 : break;
4153 : }
4154 : }
4155 : }
4156 : }
4157 :
4158 763 : if (AirLoopNumber == 0 && !ZoneEquipmentFound &&
4159 8 : (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE)) {
4160 0 : std::string_view zoneName = input_data.controlling_zone_or_thermostat_location;
4161 0 : if (zoneName.empty() && this->ControlZoneNum > 0) {
4162 0 : zoneName = state.dataHeatBal->Zone(this->ControlZoneNum).Name;
4163 : }
4164 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4165 0 : ShowContinueError(state, "Did not find proper connections for AirLoopHVAC or ZoneHVAC system.");
4166 0 : ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}", zoneName));
4167 0 : if (!AirNodeFound && !ZoneEquipmentFound) {
4168 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4169 0 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
4170 : // ShowContinueError(state, format("specified {} = {}", cAlphaFields(iControlZoneAlphaNum), Alphas(iControlZoneAlphaNum)));
4171 0 : ShowContinueError(state,
4172 : "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
4173 : }
4174 0 : errorsFound = true;
4175 : }
4176 :
4177 763 : if (!AirLoopFound && !ZoneEquipmentFound && !OASysFound) {
4178 : // Unsuccessful attempt to get all input data.
4179 0 : return;
4180 763 : } else if (ZoneEquipmentFound || OASysFound ||
4181 402 : (AirLoopFound && (this->m_ZoneInletNode > 0 || this->m_ControlType == UnitarySysCtrlType::Setpoint))) {
4182 763 : this->m_OKToPrintSizing = true;
4183 763 : this->m_ThisSysInputShouldBeGotten = false;
4184 : }
4185 :
4186 763 : this->m_AvailManagerListName = input_data.avail_manager_list_name;
4187 :
4188 763 : if (!input_data.design_spec_zonehvac_sizing_object_name.empty()) {
4189 0 : this->m_HVACSizingIndex = Util::FindItemInList(input_data.design_spec_zonehvac_sizing_object_name, state.dataSize->ZoneHVACSizing);
4190 0 : if (this->m_HVACSizingIndex == 0) {
4191 0 : ShowSevereError(
4192 : state,
4193 0 : format("Design Specification ZoneHVAC Sizing Object Name = {} not found.", input_data.design_spec_zonehvac_sizing_object_name));
4194 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, this->Name));
4195 0 : errorsFound = true;
4196 : }
4197 : }
4198 :
4199 763 : if (!ZoneEquipment) {
4200 1236 : BranchNodeConnections::TestCompSet(state,
4201 : cCurrentModuleObject,
4202 824 : Util::makeUPPER(thisObjectName),
4203 412 : input_data.air_inlet_node_name,
4204 412 : input_data.air_outlet_node_name,
4205 : "Air Nodes");
4206 : }
4207 :
4208 763 : std::string const &loc_fanType = input_data.supply_fan_object_type;
4209 763 : std::string const &loc_m_FanName = input_data.supply_fan_name;
4210 :
4211 763 : if (!loc_m_FanName.empty() && !loc_fanType.empty()) {
4212 460 : this->m_FanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(loc_fanType)));
4213 :
4214 460 : this->m_FanIndex = Fans::GetFanIndex(state, loc_m_FanName);
4215 460 : if (this->m_FanIndex == 0) {
4216 0 : ShowSevereItemNotFound(state, eoh, "fan_name", loc_m_FanName);
4217 0 : errorsFound = true;
4218 : } else {
4219 460 : auto const *fan = state.dataFans->fans(this->m_FanIndex);
4220 460 : FanVolFlowRate = fan->maxAirFlowRate;
4221 460 : if (FanVolFlowRate == DataSizing::AutoSize) {
4222 395 : this->m_RequestAutoSize = true;
4223 : }
4224 460 : this->m_ActualFanVolFlowRate = FanVolFlowRate;
4225 460 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
4226 460 : FanInletNode = fan->inletNodeNum;
4227 460 : FanOutletNode = fan->outletNodeNum;
4228 460 : this->m_fanAvailSched = fan->availSched;
4229 : }
4230 :
4231 460 : this->m_FanExists = true;
4232 460 : this->m_FanName = loc_m_FanName;
4233 303 : } else if (!loc_m_FanName.empty() || !loc_fanType.empty()) {
4234 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4235 0 : ShowContinueError(state, format("Invalid Fan Type or Name: Fan Name = {}, Fan Type = {}", loc_m_FanName, loc_fanType));
4236 0 : errorsFound = true;
4237 : }
4238 :
4239 : // Add fan to component sets array
4240 763 : if (this->m_FanExists && this->m_FanCompNotSetYet) {
4241 920 : BranchNodeConnections::SetUpCompSets(state,
4242 : cCurrentModuleObject,
4243 : thisObjectName,
4244 : loc_fanType,
4245 : loc_m_FanName,
4246 460 : state.dataLoopNodes->NodeID(FanInletNode),
4247 460 : state.dataLoopNodes->NodeID(FanOutletNode));
4248 460 : this->m_FanCompNotSetYet = false;
4249 : }
4250 :
4251 763 : this->m_FanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Util::makeUPPER(input_data.fan_placement)));
4252 763 : if (this->m_FanPlace == HVAC::FanPlace::Invalid && this->m_FanExists) {
4253 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4254 0 : ShowContinueError(state, format("Illegal Fan Placement = {}", input_data.fan_placement));
4255 0 : errorsFound = true;
4256 : }
4257 :
4258 763 : if (input_data.supply_air_fan_operating_mode_schedule_name.empty()) {
4259 309 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4260 : // Fan operating mode must be constant fan so that the coil outlet temp is proportional to PLR
4261 : // Cycling fan always outputs the full load outlet air temp so should not be used with set point based control
4262 308 : this->m_FanOpMode = HVAC::FanOp::Continuous;
4263 : } else {
4264 1 : this->m_FanOpMode = HVAC::FanOp::Cycling;
4265 1 : if (this->m_FanType != HVAC::FanType::OnOff && this->m_FanType != HVAC::FanType::SystemModel && this->m_FanExists) {
4266 0 : ShowSevereEmptyField(state,
4267 : eoh,
4268 : "Fan Operating Mode Schedule Name",
4269 : "Fan type must be Fan:OnOff or Fan:SystemModel when Supply Air Fan Operating Mode Schedule Name is blank.");
4270 0 : errorsFound = true;
4271 : }
4272 : }
4273 454 : } else if ((this->m_fanOpModeSched = Sched::GetSchedule(state, input_data.supply_air_fan_operating_mode_schedule_name)) == nullptr) {
4274 0 : ShowSevereItemNotFound(state, eoh, "Fan Operating Mode Schedule Name", input_data.supply_air_fan_operating_mode_schedule_name);
4275 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iFanSchedAlphaNum), Alphas(iFanSchedAlphaNum)));
4276 0 : errorsFound = true;
4277 458 : } else if ((this->m_ControlType == UnitarySysCtrlType::Setpoint || this->m_FanType == HVAC::FanType::Constant) &&
4278 4 : !this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
4279 0 : Sched::ShowSevereBadMinMax(state,
4280 : eoh,
4281 : "Supply Air Fan Operating Mode Schedule Name",
4282 : input_data.supply_air_fan_operating_mode_schedule_name,
4283 : Clusive::Ex,
4284 : 0.0,
4285 : Clusive::In,
4286 : 1.0);
4287 0 : errorsFound = true;
4288 : }
4289 :
4290 763 : PrintMessage = true;
4291 : // Get coil data
4292 763 : this->m_HeatingSizingRatio = input_data.dx_heating_coil_sizing_ratio;
4293 763 : int HeatingCoilPLFCurveIndex = 0;
4294 763 : if (!this->m_HeatingCoilTypeName.empty()) {
4295 445 : PrintMessage = false;
4296 : } else {
4297 318 : this->m_ValidASHRAEHeatCoil = false;
4298 : }
4299 :
4300 763 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4301 :
4302 41 : this->m_DXHeatingCoil = true;
4303 :
4304 41 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4305 41 : if (isNotOK) {
4306 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4307 0 : errorsFound = true;
4308 :
4309 : } else { // mine data from DX heating coil
4310 :
4311 : // Get DX heating coil index
4312 41 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4313 41 : if (errFlag) {
4314 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4315 0 : errorsFound = true;
4316 0 : errFlag = false;
4317 : } else {
4318 41 : auto &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4319 41 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4320 41 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedTotCap(1);
4321 41 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4322 35 : this->m_RequestAutoSize = true;
4323 : }
4324 41 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate(1);
4325 41 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4326 35 : this->m_RequestAutoSize = true;
4327 : }
4328 41 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4329 41 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4330 41 : thisHeatCoil.HeatSizeRatio = this->m_HeatingSizingRatio;
4331 : }
4332 : }
4333 :
4334 722 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4335 719 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
4336 :
4337 7 : this->m_DXHeatingCoil = true;
4338 :
4339 7 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4340 7 : if (isNotOK) {
4341 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4342 0 : errorsFound = true;
4343 : } else {
4344 7 : this->m_HeatingCoilIndex =
4345 7 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4346 7 : if (errFlag) {
4347 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4348 0 : errorsFound = true;
4349 0 : errFlag = false;
4350 : } else {
4351 7 : auto const &thisHeatCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex);
4352 7 : this->m_NumOfSpeedHeating = thisHeatCoil.NumOfSpeeds;
4353 7 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4354 7 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4355 7 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4356 5 : this->m_RequestAutoSize = true;
4357 : } else {
4358 2 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NumOfSpeeds) /
4359 2 : thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NormSpedLevel) * thisHeatCoil.RatedAirVolFlowRate;
4360 : }
4361 7 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4362 7 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4363 7 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4364 7 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4365 5 : this->m_RequestAutoSize = true;
4366 : }
4367 : }
4368 : }
4369 722 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
4370 13 : this->m_DXHeatingCoil = true;
4371 13 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4372 13 : if (isNotOK) {
4373 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4374 0 : errorsFound = true;
4375 : } else {
4376 13 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, this->m_HeatingCoilTypeName);
4377 13 : if (errFlag) {
4378 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4379 0 : errorsFound = true;
4380 0 : errFlag = false;
4381 : } else {
4382 13 : auto const &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4383 13 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4384 13 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(1);
4385 13 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4386 8 : this->m_RequestAutoSize = true;
4387 : }
4388 13 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4389 13 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4390 13 : this->m_DesignHeatingCapacity = thisHeatCoil.MSRatedTotCap(thisHeatCoil.NumOfSpeeds);
4391 : }
4392 : }
4393 702 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
4394 702 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
4395 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4396 0 : if (isNotOK) {
4397 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4398 0 : errorsFound = true;
4399 : } else {
4400 0 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4401 0 : if (errFlag) {
4402 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4403 0 : errorsFound = true;
4404 0 : errFlag = false;
4405 : } else {
4406 0 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4407 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4408 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4409 0 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4410 0 : this->m_DesignHeatingCapacity = thisHeatCoil.MSNominalCapacity(thisHeatCoil.NumOfStages);
4411 0 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4412 0 : this->m_RequestAutoSize = true;
4413 : }
4414 : }
4415 : }
4416 702 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
4417 488 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
4418 214 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4419 214 : if (isNotOK) {
4420 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4421 0 : errorsFound = true;
4422 : } else { // mine data from heating coil
4423 214 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4424 214 : if (errFlag) {
4425 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4426 0 : errorsFound = true;
4427 0 : errFlag = false;
4428 : } else {
4429 214 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4430 214 : this->m_DesignHeatingCapacity = thisHeatCoil.NominalCapacity;
4431 214 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4432 209 : this->m_RequestAutoSize = true;
4433 : }
4434 214 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4435 214 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4436 214 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4437 214 : HeatingCoilPLFCurveIndex = thisHeatCoil.PLFCurveIndex;
4438 : // These heating coil types do not have an air flow input field
4439 214 : if (this->m_RequestAutoSize) {
4440 209 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4441 : }
4442 : }
4443 : } // IF (IsNotOK) THEN
4444 :
4445 702 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
4446 9 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4447 9 : if (isNotOK) {
4448 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4449 0 : errorsFound = true;
4450 : } else { // mine data from heating coil object
4451 9 : this->m_HeatingCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_HeatingCoilName, errFlag);
4452 9 : if (errFlag) {
4453 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4454 0 : errorsFound = true;
4455 0 : errFlag = false;
4456 : } else {
4457 9 : auto const &thisHeatCoil = state.dataWaterCoils->WaterCoil(this->m_HeatingCoilIndex);
4458 9 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4459 9 : this->HeatCoilFluidInletNode = thisHeatCoil.WaterInletNodeNum;
4460 9 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxWaterVolFlowRate;
4461 9 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4462 9 : this->m_RequestAutoSize = true;
4463 9 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4464 : }
4465 9 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4466 9 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4467 : }
4468 : }
4469 :
4470 479 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
4471 2 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4472 2 : if (isNotOK) {
4473 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4474 0 : errorsFound = true;
4475 : } else { // mine data from heating coil object
4476 2 : this->m_HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_HeatingCoilName, errFlag);
4477 2 : if (errFlag) {
4478 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4479 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4480 0 : errorsFound = true;
4481 0 : errFlag = false;
4482 : } else {
4483 2 : auto const &thisHeatCoil = state.dataSteamCoils->SteamCoil(this->m_HeatingCoilIndex);
4484 2 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4485 2 : this->HeatCoilFluidInletNode = thisHeatCoil.SteamInletNodeNum;
4486 2 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxSteamVolFlowRate;
4487 2 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4488 0 : this->m_RequestAutoSize = true;
4489 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4490 : }
4491 2 : if (this->MaxHeatCoilFluidFlow > 0.0) {
4492 2 : Real64 TempSteamIn = 100.0;
4493 2 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
4494 2 : this->MaxHeatCoilFluidFlow *= SteamDensity;
4495 2 : errFlag = false;
4496 : }
4497 2 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4498 2 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4499 2 : if (this->m_RequestAutoSize) {
4500 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4501 : }
4502 : }
4503 : }
4504 :
4505 477 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
4506 154 : this->m_DXHeatingCoil = true;
4507 154 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4508 154 : if (isNotOK) {
4509 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4510 0 : errorsFound = true;
4511 : } else { // mine data from heating coil object
4512 154 : this->m_HeatingCoilIndex =
4513 154 : WaterToAirHeatPumpSimple::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4514 154 : if (errFlag) {
4515 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4516 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4517 0 : errorsFound = true;
4518 0 : errFlag = false;
4519 : } else {
4520 154 : auto const &thisHeatCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_HeatingCoilIndex);
4521 154 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4522 154 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4523 154 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4524 154 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4525 154 : this->m_RequestAutoSize = true;
4526 : }
4527 154 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4528 154 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4529 : }
4530 : }
4531 :
4532 323 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
4533 5 : this->m_DXHeatingCoil = true;
4534 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4535 5 : if (isNotOK) {
4536 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4537 0 : errorsFound = true;
4538 : } else { // mine data from heating coil object
4539 5 : this->m_HeatingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4540 5 : if (errFlag) {
4541 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4542 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4543 0 : errorsFound = true;
4544 0 : errFlag = false;
4545 : } else {
4546 5 : auto const &thisHeatCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_HeatingCoilIndex);
4547 5 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4548 5 : this->m_DesignHeatingCapacity = thisHeatCoil.HeatingCapacity;
4549 5 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4550 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4551 : }
4552 : }
4553 :
4554 318 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
4555 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4556 0 : if (isNotOK) {
4557 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4558 0 : errorsFound = true;
4559 : } else { // mine data from Heating coil object
4560 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
4561 0 : state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, cCurrentModuleObject);
4562 0 : if (errFlag) {
4563 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4564 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4565 0 : errorsFound = true;
4566 0 : errFlag = false;
4567 : } else {
4568 0 : auto const &thisHeatCoil = state.dataUserDefinedComponents->UserCoil(this->m_HeatingCoilIndex);
4569 0 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4570 : // **** How to get this info ****
4571 : // UnitarySystem( UnitarySysNum ).DesignHeatingCapacity =
4572 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
4573 0 : HeatingCoilInletNode = thisHeatCoil.Air(1).InletNodeNum;
4574 0 : HeatingCoilOutletNode = thisHeatCoil.Air(1).OutletNodeNum;
4575 : }
4576 : }
4577 :
4578 318 : } else if (this->m_HeatCoilExists) {
4579 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4580 0 : ShowContinueError(state, format("Illegal Heating Coil Object Type = {}", this->m_HeatingCoilTypeName));
4581 0 : errorsFound = true;
4582 : } // IF (this->m_HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
4583 :
4584 : // coil outlet node set point has priority, IF not exist, then use system outlet node
4585 763 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
4586 334 : this->HeatCtrlNode = this->AirOutNode;
4587 : }
4588 763 : if (SetPointManager::NodeHasSPMCtrlVarType(state, HeatingCoilOutletNode, HVAC::CtrlVarType::Temp)) {
4589 60 : this->HeatCtrlNode = HeatingCoilOutletNode;
4590 : }
4591 :
4592 763 : this->HeatCoilInletNodeNum = HeatingCoilInletNode;
4593 763 : this->HeatCoilOutletNodeNum = HeatingCoilOutletNode;
4594 :
4595 : // Add heating coil to component sets array
4596 763 : if (this->m_HeatCoilExists && this->m_HeatCompNotSetYet) {
4597 445 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
4598 864 : BranchNodeConnections::SetUpCompSets(state,
4599 : cCurrentModuleObject,
4600 : thisObjectName,
4601 : this->m_HeatingCoilTypeName,
4602 : this->m_HeatingCoilName,
4603 432 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
4604 432 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4605 : } else {
4606 13 : BranchNodeConnections::SetUpCompSets(
4607 : state, cCurrentModuleObject, thisObjectName, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, "UNDEFINED", "UNDEFINED");
4608 : }
4609 445 : this->m_HeatCompNotSetYet = false;
4610 : }
4611 :
4612 : // Get Cooling Coil Information IF available
4613 763 : if (!input_data.cooling_coil_object_type.empty() && !this->m_CoolingCoilName.empty()) {
4614 :
4615 762 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4616 462 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4617 462 : if (isNotOK) {
4618 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4619 0 : errorsFound = true;
4620 :
4621 : } else { // mine data from DX cooling coil
4622 :
4623 462 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4624 67 : this->m_NumOfSpeedCooling = 2;
4625 67 : this->m_MultiOrVarSpeedCoolCoil = true;
4626 : } else {
4627 395 : this->m_NumOfSpeedCooling = 1;
4628 395 : this->m_MultiOrVarSpeedCoolCoil = false;
4629 : }
4630 :
4631 : // Get DX cooling coil index
4632 462 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4633 462 : if (isNotOK) {
4634 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4635 0 : errorsFound = true;
4636 : } else {
4637 462 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
4638 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
4639 : }
4640 462 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4641 462 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4642 462 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(1);
4643 462 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4644 368 : this->m_RequestAutoSize = true;
4645 : }
4646 462 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4647 462 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4648 365 : this->m_RequestAutoSize = true;
4649 : }
4650 462 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4651 462 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4652 462 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4653 :
4654 462 : if (this->m_FanExists) {
4655 181 : thisCoolCoil.SupplyFanName = this->m_FanName;
4656 181 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4657 181 : thisCoolCoil.supplyFanType = this->m_FanType;
4658 181 : if (this->m_FanType != HVAC::FanType::Invalid) {
4659 181 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
4660 : state,
4661 181 : thisCoolCoil.Name,
4662 181 : thisCoolCoil.DXCoilType,
4663 181 : state.dataFans->fans(thisCoolCoil.SupplyFanIndex)->Name,
4664 : this->m_FanType,
4665 : thisCoolCoil.SupplyFanIndex);
4666 : }
4667 : }
4668 462 : if (this->m_HeatCoilExists) {
4669 180 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4670 180 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4671 180 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4672 180 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4673 180 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4674 180 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4675 28 : this->m_HeatPump = true;
4676 : }
4677 : }
4678 :
4679 : // Push heating coil PLF curve index to DX coil
4680 462 : if (HeatingCoilPLFCurveIndex > 0) {
4681 2 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4682 : }
4683 : }
4684 : } // IF (IsNotOK) THEN
4685 :
4686 762 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
4687 53 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4688 53 : if (isNotOK) {
4689 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4690 0 : errorsFound = true;
4691 :
4692 : } else {
4693 : // // call CoilCoolingDX constructor
4694 53 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
4695 53 : if (this->m_CoolingCoilIndex == -1) {
4696 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4697 0 : errorsFound = true;
4698 : } else {
4699 :
4700 : // mine data from coil object
4701 : // TODO: Need to check for autosize on these I guess
4702 53 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
4703 53 : this->m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4704 53 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4705 53 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4706 50 : this->m_RequestAutoSize = true;
4707 : }
4708 53 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4709 50 : this->m_RequestAutoSize = true;
4710 : }
4711 53 : this->m_coolingCoilAvailSched = newCoil.availSched;
4712 53 : CoolingCoilInletNode = newCoil.evapInletNodeIndex;
4713 53 : CoolingCoilOutletNode = newCoil.evapOutletNodeIndex;
4714 53 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4715 53 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
4716 53 : this->m_MinOATCompressorCooling = newCoil.performance.minOutdoorDrybulb;
4717 53 : newCoil.supplyFanName = this->m_FanName;
4718 53 : newCoil.supplyFanIndex = this->m_FanIndex;
4719 53 : newCoil.supplyFanType = this->m_FanType;
4720 53 : if (newCoil.SubcoolReheatFlag) {
4721 1 : this->m_Humidistat = true;
4722 1 : if (this->m_NumOfSpeedCooling > 1) {
4723 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4724 0 : this->FullLatOutput.resize(this->m_NumOfSpeedCooling + 1);
4725 0 : this->SpeedSHR.resize(this->m_NumOfSpeedCooling + 1);
4726 : }
4727 1 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4728 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4729 0 : ShowContinueError(state,
4730 : "Setpoint control is not available for SubcoolReheat cooling coil. Load control is forced. "
4731 : "Simulation continues.");
4732 0 : this->m_ControlType = UnitarySysCtrlType::Load;
4733 : }
4734 : }
4735 53 : newCoil.setData(this->m_FanIndex, this->m_FanType, this->m_FanName, this->m_SuppCoilPlantLoc.loopNum);
4736 :
4737 : // Push heating coil PLF curve index to DX coil
4738 : // if ( HeatingCoilPLFCurveIndex > 0 ) {
4739 : // SetDXCoolingCoilData( UnitarySystem( UnitarySysNum ).CoolingCoilIndex, ErrorsFound,
4740 : // HeatingCoilPLFCurveIndex );
4741 : // }
4742 : }
4743 :
4744 53 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > 1) {
4745 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4746 : }
4747 :
4748 53 : if (this->m_HeatCoilExists) {
4749 51 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4750 51 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4751 51 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4752 51 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4753 51 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4754 44 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4755 19 : this->m_HeatPump = true;
4756 : }
4757 : }
4758 : }
4759 :
4760 247 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
4761 9 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4762 9 : if (isNotOK) {
4763 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4764 0 : errorsFound = true;
4765 :
4766 : } else { // mine data from DX cooling coil
4767 :
4768 : // Get DX cooling coil index
4769 9 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4770 9 : if (isNotOK) {
4771 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4772 0 : errorsFound = true;
4773 : } else {
4774 9 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4775 9 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4776 9 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(thisCoolCoil.NumCapacityStages);
4777 9 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4778 6 : this->m_RequestAutoSize = true;
4779 : }
4780 9 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4781 9 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4782 6 : this->m_RequestAutoSize = true;
4783 : }
4784 9 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4785 9 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4786 9 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4787 :
4788 : // Push heating coil PLF curve index to DX coil
4789 9 : if (HeatingCoilPLFCurveIndex > 0) {
4790 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4791 : }
4792 :
4793 9 : if (this->m_HeatCoilExists) {
4794 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4795 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4796 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4797 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4798 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4799 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4800 0 : this->m_HeatPump = true;
4801 : }
4802 : }
4803 : }
4804 : } // IF (IsNotOK) THEN
4805 :
4806 238 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
4807 3 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4808 3 : if (isNotOK) {
4809 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4810 0 : errorsFound = true;
4811 :
4812 : } else { // mine data from heat exchanger assisted cooling coil
4813 :
4814 : // Get DX heat exchanger assisted cooling coil index
4815 3 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4816 3 : if (isNotOK) {
4817 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4818 0 : errorsFound = true;
4819 : }
4820 :
4821 : std::string ChildCoolingCoilName =
4822 3 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4823 : std::string ChildCoolingCoilType =
4824 3 : HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4825 3 : if (isNotOK) {
4826 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4827 0 : errorsFound = true;
4828 : }
4829 :
4830 3 : if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
4831 :
4832 0 : int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
4833 0 : if (childCCIndex < 0) {
4834 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4835 0 : errorsFound = true;
4836 : }
4837 :
4838 0 : auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
4839 0 : this->m_coolingCoilAvailSched = newCoil.availSched;
4840 :
4841 : // thisSys.m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4842 : // Get Coil:Cooling:DX coil air flow rate. Later fields will overwrite this IF input field is present
4843 0 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4844 : // if (thisSys.m_DesignCoolingCapacity == DataSizing::AutoSize) thisSys.m_RequestAutoSize = true;
4845 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4846 0 : this->m_RequestAutoSize = true;
4847 : }
4848 :
4849 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4850 0 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4851 :
4852 3 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) {
4853 :
4854 2 : this->m_coolingCoilAvailSched = DXCoils::GetDXCoilAvailSched(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4855 2 : if (isNotOK) {
4856 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4857 0 : errorsFound = true;
4858 : }
4859 :
4860 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
4861 2 : this->m_MaxCoolAirVolFlow = DXCoils::GetDXCoilAirFlow(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4862 2 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4863 2 : this->m_RequestAutoSize = true;
4864 : }
4865 2 : if (errFlag) {
4866 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4867 0 : errFlag = false;
4868 0 : errorsFound = true;
4869 : }
4870 :
4871 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4872 2 : this->m_CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(
4873 : state,
4874 : "COIL:COOLING:DX:SINGLESPEED",
4875 4 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag),
4876 : errFlag);
4877 :
4878 2 : if (errFlag) {
4879 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4880 0 : errFlag = false;
4881 0 : errorsFound = true;
4882 : }
4883 :
4884 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED")) {
4885 1 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4886 1 : this->m_MaxCoolAirVolFlow =
4887 1 : VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4888 1 : if (errFlag) {
4889 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4890 0 : errFlag = false;
4891 0 : errorsFound = true;
4892 : }
4893 1 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, ChildCoolingCoilName, errFlag);
4894 1 : if (errFlag) {
4895 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4896 0 : errFlag = false;
4897 0 : errorsFound = true;
4898 : }
4899 : }
4900 :
4901 : // Get DX cooling coil capacity
4902 3 : this->m_DesignCoolingCapacity =
4903 3 : HVACHXAssistedCoolingCoil::GetCoilCapacity(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4904 3 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4905 3 : this->m_RequestAutoSize = true;
4906 : }
4907 3 : if (errFlag) {
4908 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4909 0 : errFlag = false;
4910 0 : errorsFound = true;
4911 : }
4912 :
4913 : // Get the Cooling Coil Nodes
4914 : CoolingCoilInletNode =
4915 3 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4916 : CoolingCoilOutletNode =
4917 3 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4918 3 : if (errFlag) {
4919 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4920 0 : errFlag = false;
4921 0 : errorsFound = true;
4922 : }
4923 :
4924 : // Push heating coil PLF curve index to DX coil
4925 3 : if (HeatingCoilPLFCurveIndex > 0) {
4926 : // get the actual index to the DX cooling coil object
4927 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4928 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4929 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4930 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4931 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4932 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4933 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4934 : }
4935 : // what could we do for VS coil here? odd thing here
4936 : }
4937 :
4938 3 : if (this->m_HeatCoilExists) {
4939 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4940 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4941 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4942 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4943 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4944 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4945 0 : this->m_HeatPump = true;
4946 : }
4947 : }
4948 :
4949 3 : } // IF (IsNotOK) THEN
4950 235 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
4951 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4952 0 : if (isNotOK) {
4953 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4954 0 : errorsFound = true;
4955 :
4956 : } else { // mine data from heat exchanger assisted cooling coil
4957 :
4958 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4959 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4960 : std::string HXCoilName =
4961 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4962 :
4963 0 : if (errFlag) {
4964 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4965 0 : errFlag = false;
4966 0 : errorsFound = true;
4967 : }
4968 :
4969 : // Get DX heat exchanger assisted cooling coil index
4970 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag);
4971 0 : if (errFlag) {
4972 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4973 0 : errFlag = false;
4974 0 : errorsFound = true;
4975 : }
4976 :
4977 0 : this->m_coolingCoilAvailSched =
4978 0 : WaterCoils::GetWaterCoilAvailSched(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4979 0 : this->MaxCoolCoilFluidFlow =
4980 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4981 : // Get the Cooling Coil water Inlet Node number
4982 0 : this->CoolCoilFluidInletNode =
4983 0 : WaterCoils::GetCoilWaterInletNode(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4984 0 : if (errFlag) {
4985 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4986 0 : errFlag = false;
4987 0 : errorsFound = true;
4988 : }
4989 :
4990 : // Get the Cooling Coil Nodes
4991 : CoolingCoilInletNode =
4992 0 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4993 : CoolingCoilOutletNode =
4994 0 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4995 0 : if (errFlag) {
4996 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4997 0 : errFlag = false;
4998 0 : errorsFound = true;
4999 : }
5000 :
5001 0 : this->m_MaxCoolAirVolFlow =
5002 0 : HVACHXAssistedCoolingCoil::GetHXCoilAirFlowRate(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5003 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5004 0 : this->m_RequestAutoSize = true;
5005 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
5006 : }
5007 0 : if (errFlag) {
5008 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5009 0 : errFlag = false;
5010 0 : errorsFound = true;
5011 : }
5012 :
5013 0 : this->m_CondenserNodeNum = 0;
5014 :
5015 : // Push heating coil PLF curve index to DX coil
5016 0 : if (HeatingCoilPLFCurveIndex > 0) {
5017 : // get the actual index to the DX cooling coil object
5018 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
5019 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
5020 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
5021 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
5022 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
5023 : }
5024 : // VS coil issue here
5025 : }
5026 :
5027 0 : } // IF (IsNotOK) THEN
5028 235 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5029 225 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5030 14 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5031 14 : if (isNotOK) {
5032 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5033 0 : errorsFound = true;
5034 : } else {
5035 14 : this->m_CoolingCoilIndex =
5036 14 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5037 14 : if (errFlag) {
5038 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5039 0 : errorsFound = true;
5040 0 : errFlag = false;
5041 : } else {
5042 14 : auto &thisCoolCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex);
5043 14 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5044 14 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5045 14 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum;
5046 14 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5047 14 : this->m_NumOfSpeedCooling = thisCoolCoil.NumOfSpeeds;
5048 14 : if (this->m_NumOfSpeedCooling > 1) {
5049 12 : this->m_MultiOrVarSpeedCoolCoil = true;
5050 : }
5051 14 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5052 14 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
5053 10 : this->m_RequestAutoSize = true;
5054 : }
5055 14 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5056 14 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5057 10 : this->m_RequestAutoSize = true;
5058 : } else {
5059 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NumOfSpeeds) /
5060 4 : thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NormSpedLevel) *
5061 4 : thisCoolCoil.RatedAirVolFlowRate;
5062 : }
5063 14 : if (this->m_FanExists) { // Set fan info
5064 12 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
5065 12 : thisCoolCoil.supplyFanType = this->m_FanType;
5066 12 : thisCoolCoil.SupplyFanName = loc_m_FanName;
5067 : }
5068 : }
5069 : }
5070 :
5071 14 : if (this->m_HeatCoilExists) {
5072 12 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5073 9 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5074 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5075 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5076 5 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5077 4 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5078 8 : this->m_HeatPump = true;
5079 : }
5080 : }
5081 :
5082 235 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
5083 38 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5084 38 : if (isNotOK) {
5085 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5086 0 : errorsFound = true;
5087 : } else {
5088 38 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, input_data.cooling_coil_object_type);
5089 38 : if (errFlag) {
5090 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5091 0 : errorsFound = true;
5092 0 : errFlag = false;
5093 : } else {
5094 38 : auto const &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
5095 38 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
5096 38 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
5097 38 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
5098 38 : this->m_DesignCoolingCapacity = thisCoolCoil.MSRatedTotCap(thisCoolCoil.NumOfSpeeds);
5099 38 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
5100 2 : this->m_RequestAutoSize = true;
5101 : }
5102 38 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(1);
5103 38 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5104 2 : this->m_RequestAutoSize = true;
5105 : }
5106 : }
5107 : }
5108 :
5109 38 : if (this->m_HeatCoilExists) {
5110 38 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5111 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5112 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5113 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5114 38 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5115 33 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5116 5 : this->m_HeatPump = true;
5117 : }
5118 : }
5119 :
5120 183 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
5121 :
5122 20 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5123 20 : if (isNotOK) {
5124 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5125 0 : errorsFound = true;
5126 : } else { // mine data from Cooling coil object
5127 20 : this->m_CoolingCoilIndex =
5128 20 : WaterCoils::GetWaterCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5129 20 : if (errFlag) {
5130 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5131 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5132 0 : errorsFound = true;
5133 0 : errFlag = false;
5134 : } else {
5135 20 : auto const &thisCoolCoil = state.dataWaterCoils->WaterCoil(this->m_CoolingCoilIndex);
5136 20 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
5137 20 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
5138 20 : this->m_MaxCoolAirVolFlow = thisCoolCoil.DesAirVolFlowRate;
5139 : }
5140 20 : this->CoolCoilFluidInletNode = thisCoolCoil.WaterInletNodeNum;
5141 20 : this->MaxCoolCoilFluidFlow = thisCoolCoil.MaxWaterVolFlowRate;
5142 20 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
5143 20 : this->m_RequestAutoSize = true;
5144 20 : this->m_DesignCoolingCapacity = DataSizing::AutoSize; // water coils don't have a capacity field, need other logic?
5145 : }
5146 20 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5147 20 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5148 : }
5149 : }
5150 183 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5151 154 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5152 154 : if (isNotOK) {
5153 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5154 0 : errorsFound = true;
5155 : } else { // mine data from Cooling coil object
5156 154 : this->m_CoolingCoilIndex =
5157 154 : WaterToAirHeatPumpSimple::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5158 154 : if (errFlag) {
5159 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5160 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5161 0 : errorsFound = true;
5162 0 : errFlag = false;
5163 : } else {
5164 154 : auto const &thisCoolCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_CoolingCoilIndex);
5165 154 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5166 154 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5167 :
5168 : // this isn't likely to work on getInput calls but is what happened before
5169 154 : int CompanionHeatingCoil = thisCoolCoil.CompanionHeatingCoilNum;
5170 154 : if (CompanionHeatingCoil > 0) {
5171 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize &&
5172 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).WAHPPlantType ==
5173 0 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
5174 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
5175 0 : state.dataSize->DXCoolCap > 0) {
5176 : // Heating coil has not yet been sized, returning the temporary cooling capacity
5177 0 : this->m_DesignCoolingCapacity = state.dataSize->DXCoolCap;
5178 : }
5179 : }
5180 :
5181 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
5182 154 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5183 154 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5184 154 : this->m_RequestAutoSize = true;
5185 : }
5186 154 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5187 154 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5188 : }
5189 : }
5190 :
5191 154 : if (this->m_HeatCoilExists) {
5192 154 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5193 154 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5194 154 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5195 154 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5196 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5197 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5198 154 : this->m_HeatPump = true;
5199 : }
5200 : }
5201 :
5202 9 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
5203 5 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5204 5 : if (isNotOK) {
5205 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5206 0 : errorsFound = true;
5207 : } else { // mine data from Cooling coil object
5208 5 : this->m_CoolingCoilIndex =
5209 5 : WaterToAirHeatPump::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5210 5 : if (this->m_CoolingCoilIndex == 0) {
5211 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5212 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5213 0 : errorsFound = true;
5214 0 : errFlag = false;
5215 : } else {
5216 5 : auto const &thisCoolCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_CoolingCoilIndex);
5217 5 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5218 5 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingCapacity;
5219 5 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5220 5 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5221 : }
5222 : }
5223 :
5224 5 : if (this->m_HeatCoilExists) {
5225 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5226 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5227 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5228 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5229 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5230 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5231 5 : this->m_HeatPump = true;
5232 : }
5233 : }
5234 :
5235 4 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
5236 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5237 0 : if (isNotOK) {
5238 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5239 0 : errorsFound = true;
5240 : } else { // mine data from Cooling coil object
5241 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5242 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5243 0 : if (errFlag) {
5244 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5245 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5246 0 : errorsFound = true;
5247 0 : errFlag = false;
5248 : } else {
5249 0 : auto const &thisCoolCoil = state.dataUserDefinedComponents->UserCoil(this->m_CoolingCoilIndex);
5250 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5251 : // **** How to get this info ****
5252 : // UnitarySystem( UnitarySysNum ).DesignCoolingCapacity =
5253 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
5254 0 : CoolingCoilInletNode = thisCoolCoil.Air(1).InletNodeNum;
5255 0 : CoolingCoilOutletNode = thisCoolCoil.Air(1).OutletNodeNum;
5256 : }
5257 : }
5258 :
5259 4 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
5260 4 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5261 4 : if (isNotOK) {
5262 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5263 0 : errorsFound = true;
5264 : } else { // mine data from Cooling coil object
5265 4 : PackagedThermalStorageCoil::GetTESCoilIndex(
5266 4 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5267 4 : if (errFlag) {
5268 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5269 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5270 0 : errorsFound = true;
5271 0 : errFlag = false;
5272 : } else {
5273 4 : auto const &thisCoolCoil = state.dataPackagedThermalStorageCoil->TESCoil(this->m_CoolingCoilIndex);
5274 4 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5275 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedEvapAirVolFlowRate;
5276 4 : if (thisCoolCoil.CoolingOnlyModeIsAvailable) {
5277 4 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingOnlyRatedTotCap;
5278 0 : } else if (thisCoolCoil.CoolingAndChargeModeAvailable) {
5279 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndChargeRatedTotCap;
5280 0 : } else if (thisCoolCoil.CoolingAndDischargeModeAvailable) {
5281 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndDischargeRatedTotCap;
5282 : } else {
5283 0 : this->m_DesignCoolingCapacity = 0.0;
5284 : }
5285 4 : CoolingCoilInletNode = thisCoolCoil.EvapAirInletNodeNum;
5286 4 : CoolingCoilOutletNode = thisCoolCoil.EvapAirOutletNodeNum;
5287 : }
5288 : }
5289 :
5290 : } else { // IF(.NOT. lAlphaBlanks(16))THEN
5291 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5292 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iCoolingCoilTypeAlphaNum), Alphas(iCoolingCoilTypeAlphaNum)));
5293 0 : errorsFound = true;
5294 : }
5295 :
5296 762 : if (!input_data.dx_cooling_coil_system_sensor_node_name.empty()) { // used by CoilSystem:Cooling:DX
5297 596 : this->CoolCtrlNode = NodeInputManager::GetOnlySingleNode(state,
5298 298 : input_data.dx_cooling_coil_system_sensor_node_name,
5299 : errFlag,
5300 : objType,
5301 : thisObjectName,
5302 : DataLoopNode::NodeFluidType::Air,
5303 : DataLoopNode::ConnectionType::Sensor,
5304 : NodeInputManager::CompFluidStream::Primary,
5305 : DataLoopNode::ObjectIsParent);
5306 : } else {
5307 464 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
5308 95 : this->CoolCtrlNode = this->AirOutNode;
5309 : }
5310 464 : if (SetPointManager::NodeHasSPMCtrlVarType(state, CoolingCoilOutletNode, HVAC::CtrlVarType::Temp)) {
5311 43 : this->CoolCtrlNode = CoolingCoilOutletNode;
5312 : }
5313 : }
5314 :
5315 762 : this->CoolCoilInletNodeNum = CoolingCoilInletNode;
5316 762 : this->CoolCoilOutletNodeNum = CoolingCoilOutletNode;
5317 :
5318 : } else {
5319 1 : this->m_ValidASHRAECoolCoil = false;
5320 : }
5321 :
5322 763 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple &&
5323 154 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5324 154 : if (!input_data.heat_pump_coil_water_flow_mode.empty()) {
5325 153 : this->m_WaterCyclingMode =
5326 153 : static_cast<HVAC::WaterFlow>(getEnumValue(HVAC::waterFlowNamesUC, Util::makeUPPER(input_data.heat_pump_coil_water_flow_mode)));
5327 : } else {
5328 1 : this->m_WaterCyclingMode = HVAC::WaterFlow::Cycling;
5329 : }
5330 154 : WaterToAirHeatPumpSimple::SetSimpleWSHPData(
5331 154 : state, this->m_CoolingCoilIndex, errorsFound, this->m_WaterCyclingMode, _, this->m_HeatingCoilIndex);
5332 : }
5333 :
5334 763 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
5335 4 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5336 4 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, this->m_HeatingCoilIndex);
5337 : }
5338 :
5339 : // Add cooling coil to component sets array
5340 763 : if (this->m_CoolCoilExists && this->m_CoolCompNotSetYet) {
5341 762 : if (this->m_CoolingCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
5342 1448 : BranchNodeConnections::SetUpCompSets(state,
5343 : cCurrentModuleObject,
5344 : thisObjectName,
5345 : input_data.cooling_coil_object_type,
5346 : this->m_CoolingCoilName,
5347 724 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
5348 724 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
5349 : } else {
5350 38 : BranchNodeConnections::SetUpCompSets(state,
5351 : cCurrentModuleObject,
5352 : thisObjectName,
5353 : input_data.cooling_coil_object_type,
5354 : this->m_CoolingCoilName,
5355 : "UNDEFINED",
5356 : "UNDEFINED");
5357 : }
5358 762 : this->m_CoolCompNotSetYet = false;
5359 : }
5360 : // Run as 100% DOAS DX coil
5361 763 : if (!Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5362 757 : this->m_ISHundredPercentDOASDXCoil = false;
5363 : } else {
5364 6 : if (Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5365 6 : this->m_ISHundredPercentDOASDXCoil = true;
5366 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
5367 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5368 0 : ShowContinueError(state, "Variable DX Cooling Coil is not supported as 100% DOAS DX coil.");
5369 0 : ShowContinueError(state, "Variable DX Cooling Coil resets Use DOAS DX Cooling Coil = No and the simulation continues.");
5370 0 : this->m_ISHundredPercentDOASDXCoil = false;
5371 : }
5372 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "")) {
5373 0 : this->m_ISHundredPercentDOASDXCoil = false;
5374 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "No")) {
5375 0 : this->m_ISHundredPercentDOASDXCoil = false;
5376 : }
5377 : }
5378 :
5379 : // considered as as 100% DOAS DX cooling coil
5380 763 : if (this->m_ISHundredPercentDOASDXCoil) {
5381 : // set the system DX Coil application type to the child DX coil
5382 6 : if (!(this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5383 6 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
5384 6 : DXCoils::SetDXCoilTypeData(state, this->m_CoolingCoilName);
5385 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
5386 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].setToHundredPercentDOAS();
5387 : }
5388 : }
5389 : // DOAS DX Cooling Coil Leaving Minimum Air Temperature
5390 763 : this->DesignMinOutletTemp = input_data.minimum_supply_air_temperature;
5391 763 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp == DataSizing::AutoSize) {
5392 : // skip error for PTUnits
5393 175 : if (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater) {
5394 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5395 0 : ShowContinueError(state, "Invalid entry for Minimum Supply Air Temperature = AutoSize.");
5396 0 : ShowContinueError(state, "AutoSizing not allowed when Control Type = Load or Setpoint");
5397 0 : errorsFound = true;
5398 : }
5399 : }
5400 763 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp > 7.5) {
5401 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5402 0 : ShowContinueError(state, format("Invalid entry for Minimum Supply Air Temperature = {:.4R}", this->DesignMinOutletTemp));
5403 0 : ShowContinueError(state, "The minimum supply air temperature will be limited to 7.5C and the simulation continues.");
5404 0 : this->DesignMinOutletTemp = 7.5;
5405 : }
5406 :
5407 : // Get Latent Load Control flag
5408 763 : if (!input_data.latent_load_control.empty()) {
5409 763 : if (Util::SameString(input_data.latent_load_control, "SensibleOnlyLoadControl")) {
5410 745 : this->m_RunOnSensibleLoad = true;
5411 745 : this->m_RunOnLatentLoad = false;
5412 18 : } else if (Util::SameString(input_data.latent_load_control, "LatentOnlyLoadControl")) {
5413 0 : this->m_RunOnSensibleLoad = false;
5414 0 : this->m_RunOnLatentLoad = true;
5415 18 : } else if (Util::SameString(input_data.latent_load_control, "LatentOrSensibleLoadControl")) {
5416 9 : this->m_RunOnSensibleLoad = true;
5417 9 : this->m_RunOnLatentLoad = true;
5418 9 : } else if (Util::SameString(input_data.latent_load_control, "LatentWithSensibleLoadControl")) {
5419 9 : this->m_RunOnSensibleLoad = true;
5420 9 : this->m_RunOnLatentLoad = true;
5421 9 : this->m_RunOnLatentOnlyWithSensible = true;
5422 : }
5423 : }
5424 763 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
5425 24 : if (!this->m_RunOnLatentLoad && !this->m_RunOnLatentOnlyWithSensible && this->m_ControlType == UnitarySysCtrlType::Load) {
5426 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5427 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5428 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5429 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5430 0 : ShowContinueError(state, "Humidity/Moisture may not be controlled with these settings.");
5431 : }
5432 : } else {
5433 739 : if ((this->m_RunOnLatentLoad || this->m_RunOnLatentOnlyWithSensible) && this->m_ControlType == UnitarySysCtrlType::Load) {
5434 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5435 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5436 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5437 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5438 0 : ShowContinueError(state, "Humidity/Moisture will not be controlled with these settings.");
5439 0 : this->m_RunOnLatentLoad = false;
5440 0 : this->m_RunOnLatentOnlyWithSensible = false;
5441 : }
5442 : }
5443 : // Get reheat coil data if humidistat is used
5444 763 : this->m_SuppHeatCoilName = input_data.supplemental_heating_coil_name;
5445 763 : this->m_SuppHeatCoilTypeName = input_data.supplemental_heating_coil_object_type;
5446 :
5447 763 : if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Water")) {
5448 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
5449 763 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Steam")) {
5450 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
5451 1354 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Fuel") ||
5452 1134 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric") ||
5453 1897 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric:MultiStage") ||
5454 1302 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:DesuperHeater")) {
5455 225 : this->m_SuppHeatCoilType_Num =
5456 225 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5457 538 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:UserDefined")) {
5458 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_UserDefined;
5459 : }
5460 :
5461 763 : if (!this->m_SuppHeatCoilTypeName.empty() && !this->m_SuppHeatCoilName.empty()) {
5462 225 : errFlag = false;
5463 :
5464 225 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric ||
5465 5 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
5466 1 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
5467 :
5468 225 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5469 225 : if (isNotOK) {
5470 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5471 0 : errorsFound = true;
5472 :
5473 : } else { // mine data from reheat coil
5474 225 : this->m_SuppHeatCoilIndex =
5475 225 : HeatingCoils::GetHeatingCoilIndex(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5476 225 : if (errFlag) {
5477 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5478 0 : errorsFound = true;
5479 0 : errFlag = false;
5480 : } else {
5481 225 : auto const &thisSuppCoil = state.dataHeatingCoils->HeatingCoil(this->m_SuppHeatCoilIndex);
5482 225 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
5483 4 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.MSNominalCapacity(thisSuppCoil.NumOfStages);
5484 4 : this->m_NumOfSpeedSuppHeating = thisSuppCoil.NumOfStages;
5485 : } else {
5486 221 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.NominalCapacity;
5487 : }
5488 225 : if (this->m_DesignSuppHeatingCapacity == DataSizing::AutoSize) {
5489 207 : this->m_RequestAutoSize = true;
5490 : }
5491 225 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5492 225 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5493 : }
5494 : } // IF (IsNotOK) THEN
5495 :
5496 225 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5497 225 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5498 :
5499 225 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5500 :
5501 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5502 0 : if (isNotOK) {
5503 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5504 0 : errorsFound = true;
5505 : } else { // mine data from heating coil object
5506 0 : this->m_SuppHeatCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_SuppHeatCoilName, errFlag);
5507 0 : if (errFlag) {
5508 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5509 0 : errorsFound = true;
5510 0 : errFlag = false;
5511 : } else {
5512 0 : auto const &thisSuppCoil = state.dataWaterCoils->WaterCoil(this->m_SuppHeatCoilIndex);
5513 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.WaterInletNodeNum;
5514 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxWaterVolFlowRate;
5515 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5516 0 : this->m_RequestAutoSize = true;
5517 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize;
5518 : }
5519 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5520 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5521 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5522 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5523 : }
5524 : }
5525 :
5526 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5527 :
5528 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5529 0 : if (isNotOK) {
5530 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5531 0 : errorsFound = true;
5532 : } else { // mine data from heating coil object
5533 0 : this->m_SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_SuppHeatCoilName, errFlag);
5534 0 : if (errFlag) {
5535 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5536 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5537 0 : errorsFound = true;
5538 0 : errFlag = false;
5539 : } else {
5540 0 : auto const &thisSuppCoil = state.dataSteamCoils->SteamCoil(this->m_SuppHeatCoilIndex);
5541 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.SteamInletNodeNum;
5542 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxSteamVolFlowRate;
5543 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5544 0 : this->m_RequestAutoSize = true;
5545 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize; // not sure if steam coil needs this
5546 : }
5547 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
5548 0 : Real64 TempSteamIn = 100.0;
5549 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
5550 0 : this->m_MaxSuppCoilFluidFlow = this->m_MaxSuppCoilFluidFlow * SteamDensity;
5551 : }
5552 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5553 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5554 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5555 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5556 : }
5557 : }
5558 :
5559 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
5560 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5561 0 : if (isNotOK) {
5562 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5563 0 : errorsFound = true;
5564 : } else { // mine data from Heating coil object
5565 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5566 0 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilIndex, errFlag, cCurrentModuleObject);
5567 0 : if (errFlag) {
5568 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5569 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5570 0 : errorsFound = true;
5571 0 : errFlag = false;
5572 : } else {
5573 0 : auto const &thisSuppCoil = state.dataUserDefinedComponents->UserCoil(this->m_SuppHeatCoilIndex);
5574 0 : SupHeatCoilInletNode = thisSuppCoil.Air(1).InletNodeNum;
5575 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5576 0 : SupHeatCoilOutletNode = thisSuppCoil.Air(1).OutletNodeNum;
5577 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5578 : }
5579 : }
5580 :
5581 : } else { // Illegal reheating coil type
5582 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5583 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Type = {}", this->m_SuppHeatCoilTypeName));
5584 0 : errorsFound = true;
5585 : } // IF (this->SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
5586 :
5587 : } // IF(.NOT. lAlphaBlanks(iSuppHeatCoilTypeAlphaNum))THEN
5588 :
5589 763 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
5590 334 : this->SuppCtrlNode = this->AirOutNode;
5591 : }
5592 763 : if (SetPointManager::NodeHasSPMCtrlVarType(state, SupHeatCoilOutletNode, HVAC::CtrlVarType::Temp)) {
5593 28 : this->SuppCtrlNode = SupHeatCoilOutletNode;
5594 : }
5595 :
5596 : // Add supplemental heating coil to component sets array
5597 763 : if (this->m_SuppCoilExists && this->m_SuppCompNotSetYet) {
5598 450 : BranchNodeConnections::SetUpCompSets(state,
5599 : cCurrentModuleObject,
5600 : thisObjectName,
5601 : this->m_SuppHeatCoilTypeName,
5602 : this->m_SuppHeatCoilName,
5603 225 : state.dataLoopNodes->NodeID(SupHeatCoilInletNode),
5604 225 : state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
5605 225 : this->m_SuppCompNotSetYet = false;
5606 : }
5607 :
5608 763 : if (this->OAMixerExists) {
5609 : // Set up component set for OA mixer - use OA node and Mixed air node
5610 600 : BranchNodeConnections::SetUpCompSets(state,
5611 : this->UnitType,
5612 : this->Name,
5613 : input_data.oa_mixer_type,
5614 : input_data.oa_mixer_name,
5615 300 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[0]),
5616 300 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[3]));
5617 : }
5618 :
5619 : // set fan info for supplemental heating coils
5620 763 : if (this->m_SuppCoilExists && this->m_FanExists) {
5621 225 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
5622 225 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
5623 : }
5624 :
5625 : // Users may not provide SA flow input fields (below) and leave them blank. Check if other coil is AutoSized first to
5626 : // alleviate input requirements. check if coil has no air flow input (VolFlow = 0) and other coil isDataSizing::AutoSized. If so,
5627 : // use AutoSize for coil with 0 air flow rate. This means that the coils MUST mine the air flow rate if it exists
5628 763 : if (this->m_CoolCoilExists && this->m_HeatCoilExists) {
5629 444 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize && this->m_MaxHeatAirVolFlow == 0 && loc_m_HeatingSAFMethod == "") {
5630 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
5631 444 : } else if (this->m_MaxCoolAirVolFlow == 0 && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize && loc_m_CoolingSAFMethod == "") {
5632 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
5633 : }
5634 : }
5635 :
5636 : // translate DesignSpecification:ZoneHVAC:Sizing inputs
5637 : // UnitarySystem already has air flow scalable sizing, update locals
5638 : // UnitarySystem does not have capacity sizing, set inputs accordingly
5639 763 : if (this->m_HVACSizingIndex > 0) {
5640 0 : int zoneHVACIndex = this->m_HVACSizingIndex;
5641 0 : auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(zoneHVACIndex);
5642 0 : switch (zoneHVACSizing.CoolingSAFMethod) {
5643 0 : case DataSizing::None:
5644 0 : break; // do nothing?
5645 0 : case DataSizing::SupplyAirFlowRate:
5646 0 : loc_m_CoolingSAFMethod = "SupplyAirFlowRate";
5647 0 : loc_m_CoolingSAFMethod_SAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5648 0 : break;
5649 0 : case DataSizing::FlowPerFloorArea:
5650 0 : loc_m_CoolingSAFMethod = "FlowPerFloorArea";
5651 0 : loc_m_CoolingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxCoolAirVolFlow;
5652 0 : break;
5653 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5654 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5655 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5656 0 : break;
5657 0 : case DataSizing::FlowPerCoolingCapacity:
5658 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5659 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5660 0 : break;
5661 0 : default:
5662 : assert(true);
5663 : }
5664 :
5665 0 : switch (zoneHVACSizing.HeatingSAFMethod) {
5666 0 : case DataSizing::None:
5667 0 : break; // do nothing?
5668 0 : case DataSizing::SupplyAirFlowRate:
5669 0 : loc_m_HeatingSAFMethod = "SupplyAirFlowRate";
5670 0 : loc_m_HeatingSAFMethod_SAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5671 0 : break;
5672 0 : case DataSizing::FlowPerFloorArea:
5673 0 : loc_m_HeatingSAFMethod = "FlowPerFloorArea";
5674 0 : loc_m_HeatingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxHeatAirVolFlow;
5675 0 : break;
5676 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5677 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5678 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5679 0 : break;
5680 0 : case DataSizing::FlowPerHeatingCapacity:
5681 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5682 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5683 0 : break;
5684 0 : default:
5685 : assert(true);
5686 : }
5687 :
5688 0 : switch (zoneHVACSizing.NoCoolHeatSAFMethod) {
5689 0 : case DataSizing::None:
5690 0 : break; // do nothing?
5691 0 : case DataSizing::SupplyAirFlowRate:
5692 0 : loc_m_NoCoolHeatSAFMethod = "SupplyAirFlowRate";
5693 0 : loc_m_NoCoolHeatSAFMethod_SAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5694 0 : break;
5695 0 : case DataSizing::FlowPerFloorArea:
5696 0 : loc_m_NoCoolHeatSAFMethod = "FlowPerFloorArea";
5697 0 : loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5698 0 : break;
5699 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5700 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5701 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5702 0 : break;
5703 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5704 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5705 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5706 0 : break;
5707 0 : default:
5708 : assert(true);
5709 : }
5710 :
5711 0 : switch (zoneHVACSizing.CoolingCapMethod) {
5712 0 : case DataSizing::CoolingDesignCapacity:
5713 0 : this->m_CoolingCapMethod = DataSizing::CoolingDesignCapacity;
5714 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5715 0 : break;
5716 0 : case DataSizing::CapacityPerFloorArea:
5717 0 : this->m_CoolingCapMethod = DataSizing::CapacityPerFloorArea;
5718 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity * TotalFloorAreaOnAirLoop;
5719 0 : break;
5720 0 : case DataSizing::FractionOfAutosizedCoolingCapacity:
5721 0 : this->m_CoolingCapMethod = DataSizing::FractionOfAutosizedCoolingCapacity;
5722 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5723 0 : break;
5724 0 : default:
5725 : assert(true);
5726 : }
5727 :
5728 0 : switch (zoneHVACSizing.HeatingCapMethod) {
5729 0 : case DataSizing::HeatingDesignCapacity:
5730 0 : this->m_HeatingCapMethod = DataSizing::HeatingDesignCapacity;
5731 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5732 0 : break;
5733 0 : case DataSizing::CapacityPerFloorArea:
5734 0 : this->m_HeatingCapMethod = DataSizing::CapacityPerFloorArea;
5735 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity * TotalFloorAreaOnAirLoop;
5736 0 : break;
5737 0 : case DataSizing::FractionOfAutosizedHeatingCapacity:
5738 0 : this->m_HeatingCapMethod = DataSizing::FractionOfAutosizedHeatingCapacity;
5739 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5740 0 : break;
5741 0 : default:
5742 : assert(true);
5743 : }
5744 : }
5745 :
5746 : // Determine supply air flow rate sizing method for cooling mode
5747 763 : if (Util::SameString(loc_m_CoolingSAFMethod, "SupplyAirFlowRate")) {
5748 460 : this->m_CoolingSAFMethod = DataSizing::SupplyAirFlowRate;
5749 :
5750 460 : if (loc_m_CoolingSAFMethod_SAFlow != -999.0) {
5751 460 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlow;
5752 460 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5753 399 : this->m_RequestAutoSize = true;
5754 : } else {
5755 61 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5756 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5757 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5758 0 : ShowContinueError(
5759 : state,
5760 0 : format("Suspicious Cooling Supply Air Flow Rate = {:.7R} when cooling coil is present.", this->m_MaxCoolAirVolFlow));
5761 : }
5762 61 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5763 0 : errorsFound = true;
5764 : }
5765 : }
5766 :
5767 : } else {
5768 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5769 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5770 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate.");
5771 0 : errorsFound = true;
5772 : }
5773 303 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerFloorArea")) {
5774 :
5775 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerFloorArea;
5776 0 : if (loc_m_CoolingSAFMethod_SAFlowPerFloorArea != -999.0) {
5777 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlowPerFloorArea;
5778 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5779 0 : if (this->m_MaxCoolAirVolFlow <= 0.0001 && this->m_CoolCoilExists) {
5780 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5781 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5782 0 : ShowContinueError(
5783 : state,
5784 0 : format("Suspicious Cooling Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when cooling coil is present.",
5785 0 : this->m_MaxCoolAirVolFlow));
5786 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5787 0 : errorsFound = true;
5788 : }
5789 : }
5790 0 : this->m_MaxCoolAirVolFlow *= TotalFloorAreaOnAirLoop;
5791 0 : this->m_RequestAutoSize = true;
5792 : // AutoSized input is not allowed
5793 : } else {
5794 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5795 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5796 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Floor Area = Autosize");
5797 0 : errorsFound = true;
5798 : }
5799 : } else {
5800 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5801 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5802 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Floor Area.");
5803 0 : errorsFound = true;
5804 : }
5805 303 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FractionOfAutosizedCoolingValue")) {
5806 :
5807 0 : this->m_CoolingSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5808 0 : if (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5809 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow;
5810 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5811 0 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5812 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5813 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5814 0 : ShowContinueError(state,
5815 0 : format("Suspicious Cooling Fraction of Autosized Cooling Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5816 : "when cooling coil is present.",
5817 0 : this->m_MaxCoolAirVolFlow));
5818 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5819 0 : errorsFound = true;
5820 : }
5821 : }
5822 0 : this->m_RequestAutoSize = true;
5823 : // AutoSized input is not allowed
5824 : } else {
5825 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5826 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5827 0 : ShowContinueError(state, "Illegal Cooling Fraction of Autosized Cooling Supply Air Flow Rate = Autosize");
5828 0 : errorsFound = true;
5829 : }
5830 : } else {
5831 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5832 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5833 0 : ShowContinueError(state, "Blank field not allowed for Cooling Fraction of Autosized Cooling Supply Air Flow Rate.");
5834 0 : errorsFound = true;
5835 : }
5836 303 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerCoolingCapacity")) {
5837 :
5838 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerCoolingCapacity;
5839 0 : if (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity != -999.0) {
5840 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FlowPerCoolingCapacity;
5841 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5842 0 : if (this->m_MaxCoolAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5843 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5844 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5845 0 : ShowContinueError(state,
5846 0 : format("Suspicious Cooling Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5847 : "cooling coil is present.",
5848 0 : this->m_MaxCoolAirVolFlow));
5849 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5850 0 : errorsFound = true;
5851 : }
5852 : }
5853 0 : this->m_RequestAutoSize = true;
5854 : // AutoSized input is not allowed
5855 : } else {
5856 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5857 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5858 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Unit of Capacity = Autosize");
5859 0 : errorsFound = true;
5860 : }
5861 : } else {
5862 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5863 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5864 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Unit of Capacity.");
5865 0 : errorsFound = true;
5866 : }
5867 :
5868 303 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "None") || loc_m_CoolingSAFMethod == "") {
5869 303 : this->m_CoolingSAFMethod = DataSizing::None;
5870 303 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow == 0) {
5871 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5872 0 : if (this->m_HeatCoilExists) {
5873 0 : ShowContinueError(state, "Blank field not allowed for this coil type when heating coil air flow rate is not AutoSized.");
5874 : } else {
5875 0 : ShowContinueError(state, "Blank field not allowed for this type of cooling coil.");
5876 : }
5877 0 : errorsFound = true;
5878 : }
5879 : }
5880 :
5881 : // Determine supply air flow rate sizing method for heating mode
5882 763 : if (Util::SameString(loc_m_HeatingSAFMethod, "SupplyAirFlowRate")) {
5883 444 : this->m_HeatingSAFMethod = DataSizing::SupplyAirFlowRate;
5884 444 : if (loc_m_HeatingSAFMethod_SAFlow != -999.0) {
5885 444 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlow;
5886 444 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
5887 384 : this->m_RequestAutoSize = true;
5888 : } else {
5889 60 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5890 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5891 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5892 0 : ShowContinueError(
5893 : state,
5894 0 : format("Suspicious Heating Supply Air Flow Rate = {:.7R} when heating coil is present.", this->m_MaxHeatAirVolFlow));
5895 : }
5896 60 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5897 0 : errorsFound = true;
5898 : }
5899 : }
5900 : } else {
5901 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5902 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5903 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate.");
5904 0 : errorsFound = true;
5905 : }
5906 319 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerFloorArea")) {
5907 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerFloorArea;
5908 0 : if (loc_m_HeatingSAFMethod_SAFlowPerFloorArea != -999.0) {
5909 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlowPerFloorArea;
5910 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5911 0 : if (this->m_MaxHeatAirVolFlow <= 0.0001 && this->m_HeatCoilExists) {
5912 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5913 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5914 0 : ShowContinueError(
5915 : state,
5916 0 : format("Suspicious Heating Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when heating coil is present.",
5917 0 : this->m_MaxHeatAirVolFlow));
5918 : }
5919 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5920 0 : errorsFound = true;
5921 : }
5922 0 : this->m_MaxHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5923 0 : this->m_RequestAutoSize = true;
5924 : } else {
5925 : // AutoSized input is not allowed
5926 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5927 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5928 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Floor Area = Autosize");
5929 0 : errorsFound = true;
5930 : }
5931 : } else {
5932 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5933 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5934 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Floor Area.");
5935 0 : errorsFound = true;
5936 : }
5937 319 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FractionOfAutosizedHeatingValue")) {
5938 0 : this->m_HeatingSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5939 0 : if (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5940 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow;
5941 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5942 0 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5943 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5944 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5945 0 : ShowContinueError(state,
5946 0 : format("Suspicious Heating Fraction of Autosized Heating Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5947 : "when heating coil is present.",
5948 0 : this->m_MaxHeatAirVolFlow));
5949 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5950 0 : errorsFound = true;
5951 : }
5952 : }
5953 0 : this->m_RequestAutoSize = true;
5954 : // AutoSized input is not allowed
5955 : } else {
5956 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5957 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5958 0 : ShowContinueError(state, "Illegal input for Heating Fraction of Autosized Heating Supply Air Flow Rate = Autosize");
5959 0 : errorsFound = true;
5960 : }
5961 : } else {
5962 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5963 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5964 0 : ShowContinueError(state, "Blank field not allowed for Heating Fraction of Autosized Heating Supply Air Flow Rate");
5965 0 : errorsFound = true;
5966 : }
5967 319 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerHeatingCapacity")) {
5968 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerHeatingCapacity;
5969 0 : if (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity != -999.0) {
5970 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FlowPerHeatingCapacity;
5971 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5972 0 : if (this->m_MaxHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5973 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5974 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5975 0 : ShowContinueError(state,
5976 0 : format("Suspicious Heating Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5977 : "heating coil is present.",
5978 0 : this->m_MaxHeatAirVolFlow));
5979 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5980 0 : errorsFound = true;
5981 : }
5982 : }
5983 0 : this->m_RequestAutoSize = true;
5984 : // AutoSized input is not allowed
5985 : } else {
5986 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5987 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5988 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Unit of Capacity = Autosize");
5989 0 : errorsFound = true;
5990 : }
5991 : } else {
5992 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5993 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity");
5994 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Unit of Capacity");
5995 0 : errorsFound = true;
5996 : }
5997 319 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "None") || loc_m_HeatingSAFMethod == "") {
5998 319 : this->m_HeatingSAFMethod = DataSizing::None;
5999 319 : if (this->m_HeatCoilExists && this->m_MaxHeatAirVolFlow == 0) {
6000 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6001 0 : if (loc_m_HeatingSAFMethod == "") {
6002 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method is blank.");
6003 : } else {
6004 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = None.");
6005 : }
6006 0 : if (this->m_CoolCoilExists) {
6007 0 : ShowContinueError(state, "Blank field not allowed for this coil type when cooling coil air flow rate is not AutoSized.");
6008 : } else {
6009 0 : ShowContinueError(state, "Blank field not allowed for this type of heating coil.");
6010 : }
6011 0 : errorsFound = true;
6012 : }
6013 : }
6014 :
6015 : // Determine supply air flow rate sizing method when cooling or heating is not needed
6016 763 : if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "SupplyAirFlowRate")) {
6017 440 : this->m_NoCoolHeatSAFMethod = DataSizing::SupplyAirFlowRate;
6018 440 : if (loc_m_NoCoolHeatSAFMethod_SAFlow != -999.0) {
6019 440 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlow;
6020 440 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
6021 258 : this->m_RequestAutoSize = true;
6022 : } else {
6023 182 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6024 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6025 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
6026 0 : ShowContinueError(state, format("Illegal No Load Supply Air Flow Rate = {:.7R}", this->m_MaxNoCoolHeatAirVolFlow));
6027 0 : errorsFound = true;
6028 : }
6029 : }
6030 :
6031 : } else {
6032 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6033 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
6034 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate");
6035 0 : errorsFound = true;
6036 : }
6037 323 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerFloorArea")) {
6038 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerFloorArea;
6039 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea != -999.0) {
6040 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea;
6041 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6042 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.0001) {
6043 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6044 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6045 0 : ShowContinueError(
6046 : state,
6047 0 : format("Suspicious No Load Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2]", this->m_MaxNoCoolHeatAirVolFlow));
6048 : }
6049 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6050 0 : errorsFound = true;
6051 : }
6052 0 : this->m_MaxNoCoolHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
6053 0 : this->m_RequestAutoSize = true;
6054 : } else {
6055 : // AutoSized input is not allowed
6056 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6057 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6058 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Floor Area = Autosize");
6059 0 : errorsFound = true;
6060 : }
6061 : } else {
6062 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6063 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6064 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Floor Area");
6065 0 : errorsFound = true;
6066 : }
6067 323 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedCoolingValue")) {
6068 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
6069 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
6070 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow;
6071 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6072 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
6073 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6074 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
6075 0 : ShowContinueError(
6076 : state,
6077 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/m3].",
6078 0 : this->m_MaxNoCoolHeatAirVolFlow));
6079 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6080 0 : errorsFound = true;
6081 : }
6082 : }
6083 0 : this->m_RequestAutoSize = true;
6084 : // AutoSized input is not allowed
6085 : } else {
6086 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6087 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue");
6088 0 : ShowContinueError(state,
6089 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
6090 0 : errorsFound = true;
6091 : }
6092 : } else {
6093 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6094 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
6095 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
6096 0 : errorsFound = true;
6097 : }
6098 323 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedHeatingValue")) {
6099 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
6100 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
6101 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow;
6102 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6103 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
6104 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6105 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
6106 0 : ShowContinueError(
6107 : state,
6108 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/m3].",
6109 0 : this->m_MaxNoCoolHeatAirVolFlow));
6110 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6111 0 : errorsFound = true;
6112 : }
6113 : }
6114 0 : this->m_RequestAutoSize = true;
6115 : // AutoSized input is not allowed
6116 : } else {
6117 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6118 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
6119 0 : ShowContinueError(state,
6120 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
6121 0 : errorsFound = true;
6122 : }
6123 : } else {
6124 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6125 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
6126 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
6127 0 : errorsFound = true;
6128 : }
6129 323 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerCoolingCapacity")) {
6130 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerCoolingCapacity;
6131 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity != -999.0) {
6132 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity;
6133 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6134 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
6135 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6136 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6137 0 : ShowContinueError(
6138 : state,
6139 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/W].",
6140 0 : this->m_MaxNoCoolHeatAirVolFlow));
6141 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6142 0 : errorsFound = true;
6143 : }
6144 : }
6145 0 : this->m_RequestAutoSize = true;
6146 : // AutoSized input is not allowed
6147 : } else {
6148 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6149 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6150 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
6151 0 : errorsFound = true;
6152 : }
6153 : } else {
6154 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6155 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6156 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
6157 0 : errorsFound = true;
6158 : }
6159 323 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerHeatingCapacity")) {
6160 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerHeatingCapacity;
6161 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity != -999.0) {
6162 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity;
6163 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6164 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
6165 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6166 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6167 0 : ShowContinueError(
6168 : state,
6169 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/W].",
6170 0 : this->m_MaxNoCoolHeatAirVolFlow));
6171 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6172 0 : errorsFound = true;
6173 : }
6174 : }
6175 0 : this->m_RequestAutoSize = true;
6176 : // AutoSized input is not allowed
6177 : } else {
6178 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6179 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6180 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
6181 0 : errorsFound = true;
6182 : }
6183 : } else {
6184 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6185 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6186 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
6187 0 : errorsFound = true;
6188 : }
6189 323 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "None") || loc_m_NoCoolHeatSAFMethod == "") {
6190 323 : this->m_NoCoolHeatSAFMethod = DataSizing::None;
6191 323 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6192 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlow == -99999.0) { // no load air flow is autosized
6193 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6194 0 : this->m_RequestAutoSize = true;
6195 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == -999.0) { // no load air flow is blank
6196 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6197 0 : this->m_RequestAutoSize = true;
6198 0 : ShowWarningError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6199 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6200 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be blank.");
6201 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate has been set to AutoSize and the simulation continues.");
6202 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == 0.0) { // no load air flow for SZVAV cannot be 0
6203 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6204 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6205 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
6206 0 : errorsFound = true;
6207 : }
6208 : }
6209 : }
6210 763 : if (this->input_specs.no_load_supply_air_flow_rate_low_speed == "NO") {
6211 52 : this->m_useNoLoadLowSpeedAirFlow = false;
6212 : }
6213 :
6214 : // check supply air flow calculation method
6215 763 : if (this->m_FanExists) {
6216 460 : if (this->m_CoolCoilExists) {
6217 460 : if (loc_m_CoolingSAFMethod.empty()) {
6218 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6219 0 : ShowContinueError(state,
6220 : "Method used to determine the cooling supply air flow rate is not specified when cooling coil is present.");
6221 : // check if all cooling flow calc method fields are blank
6222 0 : if (((loc_m_CoolingSAFMethod_SAFlow == -999.0) && (loc_m_CoolingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6223 0 : (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow == -999.0) &&
6224 : (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity == -999.0))) {
6225 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate field is blank.");
6226 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Floor Area field is blank.");
6227 0 : ShowContinueError(state, "Cooling Fraction of Autosized Cooling Supply Air Flow Rate field is blank.");
6228 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Unit of Capacity field is blank.");
6229 0 : ShowContinueError(state,
6230 : "Blank field not allowed for all four cooling supply air flow rate calculation methods when "
6231 : "cooling coil is present.");
6232 : }
6233 : }
6234 : // set fan info for cooling coils
6235 460 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6236 460 : state, this->m_CoolingCoilName, input_data.cooling_coil_object_type, this->m_FanName, this->m_FanType, this->m_FanIndex);
6237 : }
6238 460 : if (this->m_HeatCoilExists) {
6239 444 : if (loc_m_HeatingSAFMethod.empty()) {
6240 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6241 0 : ShowContinueError(state,
6242 : "Method used to determine the heating supply air flow rate is not specified when heating coil is present.");
6243 : // check if all heating flow calc method fields are blank
6244 0 : if (((loc_m_HeatingSAFMethod_SAFlow == -999.0) && (loc_m_HeatingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6245 0 : (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow == -999.0) &&
6246 : (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity == -999.0))) {
6247 0 : ShowContinueError(state, "Heating Supply Air Flow Rate field is blank.");
6248 0 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Floor Area field is blank.");
6249 0 : ShowContinueError(state, "Heating Fraction of Autosized Heating Supply Air Flow Rate field is blank.");
6250 0 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Unit of Capacity field is blank.");
6251 0 : ShowContinueError(state,
6252 : "Blank field not allowed for all four heating supply air flow rate calculation methods when heating "
6253 : "coil is present.");
6254 : }
6255 : }
6256 : // set fan info for heating coils
6257 444 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6258 444 : state, this->m_HeatingCoilName, this->m_HeatingCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
6259 : }
6260 : }
6261 :
6262 : // Fan operating mode (cycling or constant) schedule. IF constant fan, then set AirFlowControl
6263 763 : if (this->m_fanOpModeSched != nullptr) {
6264 454 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6265 : // set fan operating mode to continuous so sizing can set VS coil data
6266 242 : this->m_FanOpMode = HVAC::FanOp::Continuous;
6267 : // set air flow control mode:
6268 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6269 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6270 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6271 242 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6272 39 : this->m_AirFlowControl = UseCompFlow::On;
6273 : } else {
6274 203 : this->m_AirFlowControl = UseCompFlow::Off;
6275 : }
6276 : }
6277 : }
6278 :
6279 763 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6280 4 : int numCoolingCoilModes = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getNumModes();
6281 4 : if (numCoolingCoilModes == 1) {
6282 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6283 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6284 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6285 0 : ShowContinueError(
6286 : state,
6287 0 : format("Cooling coil named: {} has only one mode", state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].name));
6288 0 : ShowFatalError(state, "Multimode cooling coil error causes program termination");
6289 : }
6290 763 : } else if (this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted &&
6291 756 : this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingTwoStageWHumControl &&
6292 747 : this->m_CoolingCoilType_Num != HVAC::CoilWater_CoolingHXAssisted && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6293 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6294 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6295 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6296 0 : if (this->m_SuppHeatCoilName == "" && this->m_SuppHeatCoilTypeName == "") {
6297 : } else {
6298 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
6299 0 : ShowContinueError(state, "Dehumidification control type is assumed to be None and the simulation continues.");
6300 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6301 : } else {
6302 0 : ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
6303 0 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
6304 : }
6305 : }
6306 : }
6307 :
6308 : // Check placement of cooling coil with respect to fan placement and dehumidification control type
6309 :
6310 763 : if (this->m_FanExists) {
6311 460 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6312 298 : if (FanOutletNode == HeatingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6313 23 : this->m_CoolingCoilUpstream = false;
6314 : }
6315 162 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) {
6316 162 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6317 0 : this->m_CoolingCoilUpstream = false;
6318 : }
6319 : }
6320 : } else {
6321 303 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6322 0 : this->m_CoolingCoilUpstream = false;
6323 : }
6324 303 : if (ZoneEquipmentFound) {
6325 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6326 0 : ShowContinueError(state, "ZoneHVAC equipment must contain a fan object.");
6327 0 : ShowContinueError(state, format("specified Supply Fan Object Type = {}", loc_fanType));
6328 0 : ShowContinueError(state, format("specified Supply Fan Name = {}", loc_m_FanName));
6329 0 : errorsFound = true;
6330 : }
6331 : }
6332 :
6333 : // check node connections
6334 763 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6335 :
6336 298 : int tmpAirInletNode = this->AirInNode;
6337 298 : if (this->OAMixerExists) {
6338 157 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6339 : }
6340 298 : if (FanInletNode != tmpAirInletNode) {
6341 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6342 0 : if (this->OAMixerExists) {
6343 0 : ShowContinueError(state,
6344 : "When a blow through fan is specified, the fan inlet node name must be the same as the outdoor "
6345 : "air mixer mixed air node name.");
6346 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6347 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6348 : } else {
6349 0 : ShowContinueError(state,
6350 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system "
6351 : "inlet node name.");
6352 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6353 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6354 : }
6355 0 : errorsFound = true;
6356 : }
6357 298 : if (this->m_CoolingCoilUpstream) {
6358 275 : if (FanOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6359 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6360 0 : ShowContinueError(state,
6361 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil "
6362 : "inlet node name.");
6363 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6364 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6365 0 : errorsFound = true;
6366 : }
6367 275 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6368 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6369 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6370 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6371 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6372 0 : errorsFound = true;
6373 : }
6374 275 : if (this->m_SuppCoilExists) {
6375 209 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6376 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6377 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6378 0 : ShowContinueError(state,
6379 0 : format("...Reheat coil outlet node name = {}" + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6380 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}" + state.dataLoopNodes->NodeID(this->AirOutNode)));
6381 0 : errorsFound = true;
6382 : }
6383 : } else { // IF((this->m_Humidistat ...
6384 : // Heating coil outlet node name must be the same as the Unitary system outlet node name
6385 66 : if (this->m_HeatCoilExists && HeatingCoilOutletNode != this->AirOutNode) {
6386 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6387 0 : ShowContinueError(state,
6388 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
6389 : "unitary system outlet node name.");
6390 0 : ShowContinueError(state,
6391 0 : format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6392 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6393 0 : errorsFound = true;
6394 : }
6395 : }
6396 : } else { // IF(this->CoolingCoilUpstream)THEN
6397 23 : if (FanOutletNode != HeatingCoilInletNode && this->m_FanExists && this->m_HeatCoilExists) {
6398 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6399 0 : ShowContinueError(state,
6400 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil "
6401 : "inlet node name.");
6402 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6403 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6404 0 : errorsFound = true;
6405 : }
6406 23 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6407 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6408 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6409 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6410 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6411 0 : errorsFound = true;
6412 : }
6413 23 : if (CoolingCoilOutletNode != this->AirOutNode && this->m_CoolCoilExists) {
6414 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6415 0 : ShowContinueError(state,
6416 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the unitary "
6417 : "system outlet node name.");
6418 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6419 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6420 0 : errorsFound = true;
6421 : }
6422 : }
6423 :
6424 465 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) { // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6425 :
6426 162 : int tmpAirInletNode = this->AirInNode;
6427 162 : if (this->OAMixerExists) {
6428 143 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6429 : }
6430 162 : if (this->m_CoolingCoilUpstream) {
6431 162 : if (CoolingCoilInletNode != tmpAirInletNode && CoolingCoilInletNode != 0 && this->m_FanExists) {
6432 0 : if (this->OAMixerExists) {
6433 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6434 0 : ShowContinueError(state,
6435 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the outdoor "
6436 : "air mixer mixed air node name.");
6437 0 : ShowContinueError(state,
6438 0 : format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6439 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6440 : } else {
6441 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6442 0 : ShowContinueError(state,
6443 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary "
6444 : "system inlet node name.");
6445 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6446 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6447 : }
6448 0 : errorsFound = true;
6449 : }
6450 162 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6451 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6452 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6453 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6454 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6455 0 : errorsFound = true;
6456 : }
6457 162 : if (HeatingCoilOutletNode != FanInletNode && this->m_HeatCoilExists && this->m_FanExists) {
6458 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6459 0 : ShowContinueError(state,
6460 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan "
6461 : "inlet node name.");
6462 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6463 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6464 0 : errorsFound = true;
6465 : }
6466 162 : if (this->m_SuppCoilExists) {
6467 16 : if (FanOutletNode != SupHeatCoilInletNode && this->m_FanExists) {
6468 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6469 0 : ShowContinueError(state,
6470 : "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
6471 : "inlet node name.");
6472 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6473 0 : ShowContinueError(state, format("...Reheat coil inlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
6474 0 : errorsFound = true;
6475 : }
6476 16 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6477 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6478 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6479 0 : ShowContinueError(state,
6480 0 : format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6481 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6482 0 : errorsFound = true;
6483 : }
6484 : } else {
6485 146 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6486 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6487 0 : ShowContinueError(state,
6488 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6489 : "outlet node name.");
6490 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6491 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6492 0 : errorsFound = true;
6493 : }
6494 : }
6495 : } else { // IF(this->CoolingCoilUpstream)THEN
6496 0 : if (HeatingCoilInletNode != tmpAirInletNode && HeatingCoilInletNode != 0 && this->m_FanExists) {
6497 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6498 0 : if (this->OAMixerExists) {
6499 0 : ShowContinueError(state,
6500 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6501 : "system mixer mixed air node name.");
6502 0 : ShowContinueError(state,
6503 0 : format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6504 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6505 : } else {
6506 0 : ShowContinueError(state,
6507 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6508 : "system inlet node name.");
6509 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6510 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6511 : }
6512 0 : errorsFound = true;
6513 : }
6514 0 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_HeatCoilExists && this->m_CoolCoilExists) {
6515 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6516 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6517 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6518 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6519 0 : errorsFound = true;
6520 : }
6521 0 : if (CoolingCoilOutletNode != FanInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6522 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6523 0 : ShowContinueError(state,
6524 : "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan "
6525 : "inlet node name.");
6526 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6527 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6528 0 : errorsFound = true;
6529 : }
6530 0 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6531 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6532 0 : ShowContinueError(state,
6533 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6534 : "outlet node name.");
6535 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6536 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6537 0 : errorsFound = true;
6538 : }
6539 : }
6540 : } // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6541 :
6542 : // Set the unitary system supplemental heater max outlet temperature
6543 : // this field will be 0 if the input is not specified (included) in the input file
6544 : // someone may use a default other than what we intended, allow it to be used
6545 : // so if this field is blank, and the input field is included, read the default, otherwise use 80
6546 : // if (!lNumericBlanks(iDesignMaxOutletTempNumericNum) && NumNumbers > (iDesignMaxOutletTempNumericNum - 1)) {
6547 763 : if (this->m_sysType == SysType::Unitary) {
6548 : // UnitarySystem has a single field for max outlet temp
6549 132 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6550 : } else {
6551 : // PTHP has a field for max outlet temp for supplemental heater and max outlet temp for SZVAV
6552 631 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6553 0 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6554 : } else {
6555 631 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature_from_supplemental_heater;
6556 : }
6557 : }
6558 763 : if (this->DesignMaxOutletTemp == DataSizing::AutoSize) {
6559 242 : this->m_RequestAutoSize = true;
6560 : }
6561 : //}
6562 :
6563 : // Set maximum Outdoor air temperature for supplemental heating coil operation
6564 : // this field will be 0 if the input is not specified (included) in the input file
6565 : // someone may use a default other than what we intended, allow it to be used
6566 : // so if this field is blank, and the input field is included, read the default, otherwise use 9999
6567 : // if (!lNumericBlanks(iMaxOATSuppHeatNumericNum) && NumNumbers > (iMaxOATSuppHeatNumericNum - 1)) {
6568 763 : this->m_MaxOATSuppHeat = input_data.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation;
6569 : // Can't let MaxOATSuppHeat default to 21C if using cool reheat since it would shut off supp heater when dehumidifying
6570 : // this may also allow supplemental heater to operate when in heating mode when it should not
6571 763 : if (this->m_MaxOATSuppHeat == 21.0 && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6572 13 : this->m_MaxOATSuppHeat = 999.0;
6573 : }
6574 763 : if (this->m_SuppCoilExists) {
6575 450 : OutputReportPredefined::PreDefTableEntry(
6576 225 : state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, this->m_HeatingCoilName, this->m_MaxOATSuppHeat);
6577 : }
6578 :
6579 763 : if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 &&
6580 60 : !this->m_RequestAutoSize) {
6581 13 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6582 750 : } else if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6583 49 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6584 701 : } else if (this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6585 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6586 : } else {
6587 701 : if (this->m_FanExists && this->m_DesignFanVolFlowRate == 0.0) {
6588 0 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
6589 : }
6590 : // need more of this type of warning when flow cannot be determined
6591 701 : if (this->m_MaxHeatAirVolFlow == 0.0 && this->m_HeatCoilExists) {
6592 0 : if (this->m_FanExists) {
6593 0 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6594 0 : if (this->m_MaxCoolAirVolFlow == 0.0) {
6595 0 : this->m_MaxHeatAirVolFlow = this->m_DesignFanVolFlowRate;
6596 : }
6597 : }
6598 0 : } else if (this->m_CoolCoilExists) {
6599 0 : this->m_MaxHeatAirVolFlow = this->m_MaxCoolAirVolFlow;
6600 : } else {
6601 0 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical &&
6602 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating &&
6603 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed) {
6604 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6605 0 : ShowContinueError(state,
6606 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6607 : "Supply Air Flow Rate Method");
6608 0 : errorsFound = true;
6609 : }
6610 : }
6611 701 : } else if (this->m_MaxHeatAirVolFlow == 0.0 && !this->m_FanExists && !this->m_CoolCoilExists) {
6612 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6613 0 : ShowContinueError(state,
6614 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6615 : "Supply Air Flow Rate Method");
6616 : }
6617 : }
6618 :
6619 763 : if (FanVolFlowRate != DataSizing::AutoSize && this->m_FanExists) {
6620 65 : if (FanVolFlowRate < this->m_MaxCoolAirVolFlow && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize && this->m_CoolCoilExists) {
6621 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6622 0 : ShowContinueError(
6623 : state,
6624 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
6625 : FanVolFlowRate,
6626 0 : this->m_FanName));
6627 0 : ShowContinueError(state, " The Cooling Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6628 0 : this->m_MaxCoolAirVolFlow = FanVolFlowRate;
6629 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6630 : }
6631 65 : if (FanVolFlowRate < this->m_MaxHeatAirVolFlow && this->m_MaxHeatAirVolFlow != DataSizing::AutoSize && this->m_HeatCoilExists) {
6632 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6633 0 : ShowContinueError(
6634 : state,
6635 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
6636 : FanVolFlowRate,
6637 0 : this->m_FanName));
6638 0 : ShowContinueError(state, " The Heating Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6639 0 : this->m_MaxHeatAirVolFlow = FanVolFlowRate;
6640 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6641 : }
6642 : }
6643 :
6644 763 : if (this->m_fanOpModeSched != nullptr) {
6645 454 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6646 : // set air flow control mode:
6647 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6648 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6649 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6650 242 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6651 39 : this->m_AirFlowControl = UseCompFlow::On;
6652 : } else {
6653 203 : this->m_AirFlowControl = UseCompFlow::Off;
6654 : }
6655 : }
6656 : }
6657 :
6658 : // Set minimum OAT for heat pump compressor operation in cooling mode
6659 : // get from coil module
6660 763 : errFlag = false;
6661 763 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6662 395 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6663 368 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6664 67 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6665 301 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6666 38 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6667 263 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6668 9 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6669 254 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6670 10 : this->m_MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6671 244 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
6672 : // already found in getInput
6673 : } else {
6674 191 : this->m_MinOATCompressorCooling = -1000.0;
6675 : }
6676 763 : if (errFlag) {
6677 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6678 0 : errorsFound = true;
6679 0 : errFlag = false;
6680 : }
6681 :
6682 : // Set minimum OAT for heat pump compressor operation in heating mode
6683 : // get from coil module
6684 763 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6685 3 : this->m_MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6686 760 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6687 54 : this->m_MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6688 : } else {
6689 706 : this->m_MinOATCompressorHeating = -1000.0;
6690 : }
6691 763 : if (errFlag) {
6692 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6693 0 : errorsFound = true;
6694 0 : errFlag = false;
6695 : }
6696 :
6697 : // Mine heatpump Outdoor condenser node from DX coil object
6698 763 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6699 395 : this->m_CondenserNodeNum =
6700 395 : DXCoils::GetCoilCondenserInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
6701 : // TODO: Should we add a block for the new DX Coil?
6702 368 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6703 10 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, this->m_CoolingCoilName, errFlag);
6704 358 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
6705 : // already filled
6706 : // UnitarySystem( UnitarySysNum ).CondenserNodeNum = GetDXCoilCondenserInletNode( "Coil:Cooling:DX:SingleSpeed",
6707 : // GetHXDXCoilName(state, CoolingCoilType, this->m_CoolingCoilName, errFlag ), errFlag );
6708 :
6709 : } else {
6710 355 : if (input_data.outdoor_dry_bulb_temperature_sensor_node_name != "") {
6711 292 : this->m_CondenserNodeNum = NodeInputManager::GetOnlySingleNode(state,
6712 146 : input_data.outdoor_dry_bulb_temperature_sensor_node_name,
6713 : errFlag,
6714 : objType,
6715 : thisObjectName,
6716 : DataLoopNode::NodeFluidType::Air,
6717 : DataLoopNode::ConnectionType::Inlet,
6718 : NodeInputManager::CompFluidStream::Primary,
6719 : DataLoopNode::ObjectIsParent);
6720 : } else {
6721 : // do nothing?
6722 : }
6723 : }
6724 763 : if (errFlag) {
6725 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6726 0 : errorsFound = true;
6727 0 : errFlag = false;
6728 : }
6729 :
6730 763 : this->m_AncillaryOnPower = input_data.ancillary_on_cycle_electric_power;
6731 763 : this->m_AncillaryOffPower = input_data.ancillary_off_cycle_electric_power;
6732 763 : this->m_MaxHROutletWaterTemp = input_data.maximum_temperature_for_heat_recovery;
6733 :
6734 763 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
6735 0 : this->m_HeatRecActive = true;
6736 0 : if (input_data.heat_recovery_water_inlet_node_name != "" && input_data.heat_recovery_water_outlet_node_name != "") {
6737 0 : this->m_HeatRecoveryInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6738 0 : input_data.heat_recovery_water_inlet_node_name,
6739 : errFlag,
6740 : objType,
6741 : thisObjectName,
6742 : DataLoopNode::NodeFluidType::Water,
6743 : DataLoopNode::ConnectionType::Inlet,
6744 : NodeInputManager::CompFluidStream::Tertiary,
6745 : DataLoopNode::ObjectIsNotParent);
6746 0 : this->m_HeatRecoveryOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6747 0 : input_data.heat_recovery_water_outlet_node_name,
6748 : errFlag,
6749 : objType,
6750 : thisObjectName,
6751 : DataLoopNode::NodeFluidType::Water,
6752 : DataLoopNode::ConnectionType::Outlet,
6753 : NodeInputManager::CompFluidStream::Tertiary,
6754 : DataLoopNode::ObjectIsNotParent);
6755 :
6756 0 : BranchNodeConnections::TestCompSet(state,
6757 : cCurrentModuleObject,
6758 : thisObjectName,
6759 0 : input_data.heat_recovery_water_inlet_node_name,
6760 0 : input_data.heat_recovery_water_outlet_node_name,
6761 : "Unitary System Heat Recovery Nodes");
6762 :
6763 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6764 0 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_CoolingCoilIndex);
6765 : }
6766 0 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6767 0 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_HeatingCoilIndex);
6768 : }
6769 0 : if (errFlag) {
6770 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6771 0 : errorsFound = true;
6772 : // errFlag = false; // not used after this point, uncomment if needed
6773 : }
6774 : } else {
6775 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6776 0 : ShowContinueError(state, format("Illegal Heat Recovery Water Inlet Node Name = {}", input_data.heat_recovery_water_inlet_node_name));
6777 0 : ShowContinueError(state,
6778 0 : format("Illegal Heat Recovery Water Outlet Node Name = {}", input_data.heat_recovery_water_outlet_node_name));
6779 0 : ShowContinueError(state,
6780 : "... heat recovery nodes must be specified when Design Heat Recovery Water Flow Rate"
6781 : " is greater than 0.");
6782 0 : ShowContinueError(state, format("... Design Heat Recovery Water Flow Rate = {:.7R}", this->m_DesignHRWaterVolumeFlow));
6783 0 : errorsFound = true;
6784 : }
6785 : }
6786 :
6787 763 : if (!this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) {
6788 :
6789 62 : if (this->m_DesignSpecMSHPIndex > -1) {
6790 :
6791 62 : this->m_NoLoadAirFlowRateRatio = this->m_CompPointerMSHP->noLoadAirFlowRateRatio;
6792 :
6793 62 : switch (this->m_HeatingCoilType_Num) {
6794 15 : case HVAC::CoilDX_MultiSpeedHeating:
6795 : case HVAC::Coil_HeatingElectric_MultiStage:
6796 : case HVAC::Coil_HeatingGas_MultiStage:
6797 : case HVAC::Coil_HeatingWaterToAirHPSimple:
6798 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
6799 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6800 15 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6801 15 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6802 15 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6803 15 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling < this->m_NumOfSpeedHeating) {
6804 0 : this->FullOutput.resize(this->m_NumOfSpeedHeating + 1);
6805 : }
6806 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple && this->m_NumOfSpeedHeating > 1) {
6807 1 : this->m_MultiSpeedHeatingCoil = true;
6808 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6809 : }
6810 65 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6811 50 : this->m_HeatMassFlowRate[i] = 0.0;
6812 50 : this->m_HeatVolumeFlowRate[i] = 0.0;
6813 50 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6814 : }
6815 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
6816 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6817 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_HeatingCoilName, errorsFound);
6818 1 : if (errorsFound) {
6819 0 : ShowSevereError(state,
6820 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_HeatingCoilName));
6821 : }
6822 1 : if (NumOfSpeed != this->m_NumOfSpeedHeating) {
6823 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_HeatingCoilName));
6824 0 : ShowContinueError(state,
6825 0 : format("... The number of heating coil speeds in the {} = {:.0R}",
6826 : MultispeedType,
6827 0 : double(this->m_NumOfSpeedHeating)));
6828 0 : ShowContinueError(
6829 : state,
6830 0 : format("... The number of heating coil speeds in Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6831 0 : double(NumOfSpeed)));
6832 0 : ShowContinueError(state, format("... The number of heating coil speeds in the {} will be used.", MultispeedType));
6833 : }
6834 1 : }
6835 15 : } break;
6836 : }
6837 62 : switch (this->m_CoolingCoilType_Num) {
6838 40 : case HVAC::CoilDX_MultiSpeedCooling:
6839 : case HVAC::Coil_CoolingWaterToAirHPSimple:
6840 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
6841 40 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6842 40 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6843 40 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6844 40 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6845 40 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > this->m_NumOfSpeedHeating) {
6846 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
6847 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
6848 : }
6849 40 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple && this->m_NumOfSpeedCooling > 1) {
6850 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6851 1 : this->m_DiscreteSpeedCoolingCoil = true;
6852 : }
6853 131 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6854 91 : this->m_CoolMassFlowRate[i] = 0.0;
6855 91 : this->m_CoolVolumeFlowRate[i] = 0.0;
6856 91 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6857 : }
6858 40 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
6859 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6860 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_CoolingCoilName, errorsFound);
6861 1 : if (errorsFound) {
6862 0 : ShowSevereError(state,
6863 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_CoolingCoilName));
6864 : }
6865 1 : if (NumOfSpeed != this->m_NumOfSpeedCooling) {
6866 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_CoolingCoilName));
6867 0 : ShowContinueError(state,
6868 0 : format("... The number of Cooling coil speeds in the {} = {:.0R}",
6869 : MultispeedType,
6870 0 : double(this->m_NumOfSpeedCooling)));
6871 0 : ShowContinueError(
6872 : state,
6873 0 : format("... The number of heating coil speeds in Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6874 0 : double(NumOfSpeed)));
6875 0 : ShowContinueError(state, format("... The number of Cooling coil speeds in the {} will be used.", MultispeedType));
6876 : }
6877 1 : }
6878 40 : } break;
6879 : }
6880 : } else {
6881 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6882 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6883 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6884 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6885 0 : errorsFound = true;
6886 : }
6887 701 : } else if (this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty()) {
6888 701 : if (this->m_FanType == HVAC::FanType::SystemModel) {
6889 41 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex));
6890 41 : assert(fanSystem != nullptr);
6891 41 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
6892 38 : if (fanSystem->numSpeeds > 1) {
6893 2 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6894 1 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6895 1 : this->m_sysType == SysType::PackagedWSHP) {
6896 1 : this->m_NumOfSpeedCooling = fanSystem->numSpeeds;
6897 1 : this->m_CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6898 1 : this->m_CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
6899 1 : this->m_MSCoolingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6900 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6901 1 : this->m_DiscreteSpeedCoolingCoil = true;
6902 1 : if (fanSystem->maxAirFlowRate > 0.0) {
6903 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6904 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6905 0 : this->m_CoolVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6906 0 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6907 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6908 : }
6909 : } else {
6910 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6911 0 : this->m_CoolMassFlowRate[i] = 0.0;
6912 0 : this->m_CoolVolumeFlowRate[i] = 0.0;
6913 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6914 : }
6915 : }
6916 : }
6917 : }
6918 2 : if ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6919 1 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6920 1 : this->m_sysType == SysType::PackagedWSHP) {
6921 1 : this->m_NumOfSpeedHeating = fanSystem->numSpeeds;
6922 1 : this->m_HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6923 1 : this->m_HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
6924 1 : this->m_MSHeatingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6925 1 : this->m_MultiSpeedHeatingCoil = true;
6926 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6927 1 : if (fanSystem->maxAirFlowRate > 0.0) {
6928 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
6929 0 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6930 0 : this->m_HeatVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6931 0 : this->m_HeatMassFlowRate[i] = this->m_HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6932 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6933 : }
6934 : } else {
6935 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6936 0 : this->m_HeatMassFlowRate[i] = 0.0;
6937 0 : this->m_HeatVolumeFlowRate[i] = 0.0;
6938 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6939 : }
6940 : }
6941 : }
6942 : }
6943 2 : if (((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6944 1 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6945 1 : this->m_sysType == SysType::PackagedWSHP) ||
6946 1 : ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6947 1 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6948 0 : this->m_sysType == SysType::PackagedWSHP)) {
6949 2 : ShowWarningError(state,
6950 2 : format("{} = {} with Fan:SystemModel is used in \"{}\"",
6951 : cCurrentModuleObject,
6952 1 : this->Name,
6953 1 : this->input_specs.supply_fan_name));
6954 1 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
6955 3 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
6956 : }
6957 : }
6958 : }
6959 : }
6960 0 : } else if ((this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) ||
6961 0 : (!this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty())) {
6962 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6963 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6964 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6965 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6966 0 : errorsFound = true;
6967 : }
6968 :
6969 763 : if (this->m_DiscreteSpeedCoolingCoil) {
6970 :
6971 76 : if (this->m_NumOfSpeedCooling == 0) {
6972 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6973 0 : ShowContinueError(state,
6974 0 : format("... Cooling coil object type requires valid {} for cooling to be specified with number of speeds > 0",
6975 : unitarySysHeatPumpPerformanceObjectType));
6976 0 : errorsFound = true;
6977 : }
6978 : }
6979 763 : if (this->m_MultiSpeedHeatingCoil) {
6980 :
6981 16 : if (this->m_DesignSpecMSHPIndex > -1) {
6982 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6983 : }
6984 :
6985 16 : if (this->m_NumOfSpeedHeating == 0) {
6986 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6987 0 : ShowContinueError(state,
6988 0 : format("... Heating coil object type requires valid {} for heating to be specified with number of speeds > 0",
6989 : unitarySysHeatPumpPerformanceObjectType));
6990 0 : errorsFound = true;
6991 : }
6992 : }
6993 :
6994 763 : if ((this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating &&
6995 13 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling)) ||
6996 751 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel &&
6997 79 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling))) {
6998 67 : if (this->m_DesignSpecMSHPIndex > -1) {
6999 53 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
7000 1 : this->m_SingleMode = 1;
7001 : }
7002 : }
7003 : } else {
7004 696 : if (this->m_DesignSpecMSHPIndex > -1) {
7005 9 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
7006 0 : ShowSevereError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7007 0 : ShowContinueError(state,
7008 : "In order to perform Single Mode Operation, the valid cooling coil type is Coil:Cooling:DX:MultiSpeed "
7009 : "or Coil:Cooling:DX and the valid heating is Coil:Heating:DX:MultiSpeed or Coil:Heating:Fuel.");
7010 0 : ShowContinueError(state,
7011 0 : format("The input cooling coil type = {} and the input heating coil type = {}",
7012 0 : input_data.cooling_coil_object_type,
7013 0 : this->m_HeatingCoilTypeName));
7014 : }
7015 : }
7016 : }
7017 :
7018 763 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
7019 10 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
7020 : }
7021 :
7022 763 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
7023 3 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_HeatingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
7024 : }
7025 :
7026 : // set global logicals that denote coil type
7027 763 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
7028 23 : this->m_MultiOrVarSpeedHeatCoil = true;
7029 : }
7030 763 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
7031 91 : this->m_MultiOrVarSpeedCoolCoil = true;
7032 : }
7033 :
7034 : // set global variables for multi-stage chilled and hot water coils
7035 763 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
7036 20 : if (this->m_DesignSpecMSHPIndex > -1) {
7037 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
7038 1 : if (this->m_NumOfSpeedCooling > 1) {
7039 1 : this->m_DiscreteSpeedCoolingCoil = true;
7040 1 : this->m_MultiOrVarSpeedCoolCoil = true;
7041 : }
7042 : }
7043 : }
7044 763 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
7045 : // designSpecIndex = this->m_DesignSpecMSHPIndex;
7046 9 : if (this->m_DesignSpecMSHPIndex > -1) {
7047 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
7048 1 : if (this->m_NumOfSpeedHeating > 1) {
7049 1 : this->m_MultiSpeedHeatingCoil = true;
7050 1 : this->m_MultiOrVarSpeedHeatCoil = true;
7051 : }
7052 : }
7053 : }
7054 : // zone coils are now simulated before sizing is complete, data will not be available but array is allocated
7055 763 : if (this->m_MultiOrVarSpeedCoolCoil) {
7056 158 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
7057 158 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
7058 158 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
7059 : }
7060 763 : if (this->m_MultiOrVarSpeedHeatCoil) {
7061 23 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
7062 23 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
7063 23 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
7064 : }
7065 :
7066 : // check for specific input requirements for ASHRAE90.1 model
7067 763 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
7068 :
7069 : // only allowed for water and DX cooling coils at this time
7070 0 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWater &&
7071 0 : this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterDetailed && this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingSingleSpeed) {
7072 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7073 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7074 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific cooling coil types.");
7075 0 : ShowContinueError(state,
7076 : "Valid cooling coil types are Coil:Cooling:Water, Coil:Cooling:Water:DetailedGeometry and "
7077 : "Coil:Cooling:DX:SingleSpeed.");
7078 0 : ShowContinueError(state,
7079 0 : format("The input cooling coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
7080 0 : input_data.cooling_coil_object_type));
7081 : }
7082 : // mark this coil as non-ASHRAE90 type
7083 0 : this->m_ValidASHRAECoolCoil = false;
7084 : }
7085 : // only allow for water, fuel, or electric at this time
7086 0 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWater &&
7087 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingGasOrOtherFuel && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingElectric &&
7088 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical) {
7089 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7090 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7091 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific heating coil types.");
7092 0 : ShowContinueError(state,
7093 : "Valid heating coil types are Coil:Heating:Water, Coil:Heating:Fuel, Coil:Heating:Electric and "
7094 : "Coil:Heating:DX:SingleSpeed.");
7095 0 : ShowContinueError(state,
7096 0 : format("The input heating coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
7097 0 : this->m_HeatingCoilTypeName));
7098 : }
7099 : // mark this coil as non-ASHRAE90 type
7100 0 : this->m_ValidASHRAEHeatCoil = false;
7101 : }
7102 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
7103 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7104 0 : ShowContinueError(state, format("Invalid entry for Dehumidification Control Type = {}", input_data.dehumidification_control_type));
7105 0 : ShowContinueError(state,
7106 : "ASHRAE90.1 control method does not support dehumidification at this time. Dehumidification control type is "
7107 : "assumed to be None.");
7108 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
7109 : }
7110 0 : if (this->m_RunOnLatentLoad) {
7111 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
7112 0 : ShowContinueError(state, format("Invalid entry for Latent Load Control: {}", input_data.latent_load_control));
7113 0 : ShowContinueError(state,
7114 : "ASHRAE90.1 control method does not support latent load control at this time. This input must be selected as "
7115 : "SensibleOnlyLoadControl.");
7116 0 : this->m_RunOnSensibleLoad = true;
7117 0 : this->m_RunOnLatentLoad = false;
7118 0 : this->m_RunOnLatentOnlyWithSensible = false;
7119 : }
7120 0 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) { // 0 min air flow not allowed for SZVAV
7121 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
7122 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
7123 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
7124 0 : errorsFound = true;
7125 : }
7126 : }
7127 763 : }
7128 :
7129 933 : void UnitarySys::getDXCoilSystemData(
7130 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7131 : {
7132 933 : std::string const cCurrentModuleObject = "CoilSystem:Cooling:DX";
7133 933 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7134 933 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7135 481 : auto &instancesValue = instances.value();
7136 481 : int numCoilSystemDX = 0;
7137 3098 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7138 :
7139 2617 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7140 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7141 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7142 2617 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7143 2021 : continue;
7144 : }
7145 :
7146 596 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7147 596 : UnitarySys thisSys;
7148 596 : if (sysNum == -1) {
7149 298 : ++state.dataUnitarySystems->numUnitarySystems;
7150 298 : auto const &thisObjName = instance.key();
7151 298 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7152 : } else {
7153 298 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7154 : }
7155 :
7156 : // get CoilSystem:Cooling:DX object inputs
7157 596 : auto const &fields = instance.value();
7158 596 : thisSys.input_specs.name = thisObjectName;
7159 596 : thisSys.input_specs.system_type = cCurrentModuleObject;
7160 1192 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7161 582 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7162 596 : }
7163 : thisSys.input_specs.air_inlet_node_name =
7164 1192 : Util::makeUPPER(fields.at("dx_cooling_coil_system_inlet_node_name").get<std::string>()); // required field
7165 : thisSys.input_specs.air_outlet_node_name =
7166 1192 : Util::makeUPPER(fields.at("dx_cooling_coil_system_outlet_node_name").get<std::string>()); // required field
7167 :
7168 : thisSys.input_specs.dx_cooling_coil_system_sensor_node_name =
7169 1192 : Util::makeUPPER(fields.at("dx_cooling_coil_system_sensor_node_name").get<std::string>()); // required field
7170 :
7171 : thisSys.input_specs.cooling_coil_object_type =
7172 1192 : Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>()); // required field
7173 1192 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>()); // required field
7174 : // min-fields = 7, begin optional inputs
7175 1192 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field
7176 : thisSys.input_specs.dehumidification_control_type =
7177 38 : it.value().get<std::string>(); // Don't capitalize this one, since it's an enum
7178 : } else {
7179 : // find default value
7180 558 : thisSys.input_specs.dehumidification_control_type = "None";
7181 596 : }
7182 1192 : std::string loc_RunOnSensLoad("");
7183 1192 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) { // not required field
7184 36 : loc_RunOnSensLoad = Util::makeUPPER(it.value().get<std::string>());
7185 : } else {
7186 : // find default value
7187 560 : loc_RunOnSensLoad = "YES";
7188 596 : }
7189 1192 : std::string loc_RunOnLatLoad("");
7190 1192 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) { // not required field
7191 36 : loc_RunOnLatLoad = Util::makeUPPER(it.value().get<std::string>());
7192 : } else {
7193 : // find default value
7194 560 : loc_RunOnLatLoad = "NO";
7195 596 : }
7196 596 : if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "NO") {
7197 582 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7198 14 : } else if (loc_RunOnSensLoad == "NO" && loc_RunOnLatLoad == "YES") {
7199 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7200 14 : } else if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "YES") {
7201 : // does DX system control on LatentOrSensibleLoadControl or LatentWithSensibleLoadControl?
7202 14 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7203 : }
7204 :
7205 1192 : if (auto it = fields.find("use_outdoor_air_dx_cooling_coil"); it != fields.end()) { // not required field
7206 12 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7207 : } else {
7208 : // find default value
7209 584 : thisSys.input_specs.use_doas_dx_cooling_coil = "NO";
7210 596 : }
7211 1192 : if (auto it = fields.find("outdoor_air_dx_cooling_coil_leaving_minimum_air_temperature"); it != fields.end()) { // not required field
7212 10 : thisSys.input_specs.minimum_supply_air_temperature = it.value().get<Real64>();
7213 596 : }
7214 : // set UnitarySystem specific inputs
7215 596 : thisSys.input_specs.control_type = "SETPOINT";
7216 :
7217 : // now translate to UnitarySystem
7218 596 : thisSys.UnitType = cCurrentModuleObject;
7219 596 : thisSys.m_sysType = SysType::CoilCoolingDX;
7220 596 : thisSys.AirloopEqType = SimAirServingZones::CompType::DXSystem;
7221 :
7222 : // TODO: figure out another way to set this next variable
7223 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7224 596 : thisSys.m_LastMode = CoolingMode;
7225 596 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7226 :
7227 596 : if (sysNum == -1) {
7228 298 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7229 298 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7230 : // zone equipment require a 1-n index for access to zone availability managers
7231 : // although not zone equipment, use same methodology
7232 298 : ++numCoilSystemDX;
7233 298 : thisSys.m_EquipCompNum = numCoilSystemDX;
7234 : } else {
7235 298 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7236 : }
7237 3098 : }
7238 : }
7239 933 : }
7240 :
7241 933 : void UnitarySys::getPackagedTerminalUnitData(
7242 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7243 : {
7244 933 : std::string cCurrentModuleObject = "ZoneHVAC:PackagedTerminalAirConditioner";
7245 933 : SysType sysTypeNum = SysType::PackagedAC;
7246 933 : DataZoneEquipment::ZoneEquipType zoneEqType = DataZoneEquipment::ZoneEquipType::Invalid;
7247 933 : int numPTAC = 0;
7248 933 : int numPTHP = 0;
7249 933 : int numPTWSHP = 0;
7250 933 : auto &ip = state.dataInputProcessing->inputProcessor;
7251 3732 : for (int getPTUnitType = 1; getPTUnitType <= 3; ++getPTUnitType) {
7252 2799 : if (getPTUnitType == 2) {
7253 933 : sysTypeNum = SysType::PackagedHP;
7254 933 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7255 933 : cCurrentModuleObject = "ZoneHVAC:PackagedTerminalHeatPump";
7256 1866 : } else if (getPTUnitType == 3) {
7257 933 : sysTypeNum = SysType::PackagedWSHP;
7258 933 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7259 933 : cCurrentModuleObject = "ZoneHVAC:WaterToAirHeatPump";
7260 : }
7261 2799 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7262 2799 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7263 392 : auto &instancesValue = instances.value();
7264 392 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
7265 22466 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7266 :
7267 22074 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7268 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7269 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7270 22074 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7271 21414 : continue;
7272 : }
7273 :
7274 660 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7275 660 : UnitarySys thisSys;
7276 660 : if (sysNum == -1) {
7277 330 : ++state.dataUnitarySystems->numUnitarySystems;
7278 330 : auto const &thisObjName = instance.key();
7279 330 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7280 : } else {
7281 330 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7282 : }
7283 :
7284 : // get PackagedTerminal unit object inputs
7285 660 : auto const &fields = instance.value();
7286 660 : thisSys.input_specs.name = thisObjectName;
7287 660 : thisSys.input_specs.system_type = cCurrentModuleObject;
7288 1320 : thisSys.input_specs.availability_schedule_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_schedule_name");
7289 1320 : thisSys.input_specs.air_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_inlet_node_name");
7290 1320 : thisSys.input_specs.air_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_outlet_node_name");
7291 :
7292 1320 : thisSys.input_specs.oa_mixer_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_object_type");
7293 1320 : thisSys.input_specs.oa_mixer_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_name");
7294 :
7295 660 : thisSys.input_specs.cooling_supply_air_flow_rate =
7296 1320 : ip->getRealFieldValue(fields, objectSchemaProps, "cooling_supply_air_flow_rate");
7297 660 : thisSys.input_specs.heating_supply_air_flow_rate =
7298 1320 : ip->getRealFieldValue(fields, objectSchemaProps, "heating_supply_air_flow_rate");
7299 660 : thisSys.input_specs.no_load_supply_air_flow_rate =
7300 1320 : ip->getRealFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate");
7301 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed =
7302 1320 : ip->getAlphaFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7303 1320 : thisSys.input_specs.cooling_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_outdoor_air_flow_rate");
7304 1320 : thisSys.input_specs.heating_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "heating_outdoor_air_flow_rate");
7305 1320 : thisSys.input_specs.no_load_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "no_load_outdoor_air_flow_rate");
7306 :
7307 1320 : thisSys.input_specs.supply_fan_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_object_type");
7308 1320 : thisSys.input_specs.supply_fan_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_name");
7309 1320 : thisSys.input_specs.heating_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_object_type");
7310 1320 : thisSys.input_specs.heating_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_name");
7311 1320 : thisSys.input_specs.cooling_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_object_type");
7312 1320 : thisSys.input_specs.cooling_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_name");
7313 :
7314 1320 : thisSys.input_specs.fan_placement = ip->getAlphaFieldValue(fields, objectSchemaProps, "fan_placement");
7315 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name =
7316 1320 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_operating_mode_schedule_name");
7317 660 : if (getPTUnitType > 1) {
7318 366 : thisSys.input_specs.maximum_supply_air_temperature_from_supplemental_heater =
7319 732 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_from_supplemental_heater");
7320 : thisSys.input_specs.supplemental_heating_coil_object_type =
7321 732 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_object_type");
7322 : thisSys.input_specs.supplemental_heating_coil_name =
7323 732 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_name");
7324 732 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = ip->getRealFieldValue(
7325 : fields, objectSchemaProps, "maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7326 366 : if (getPTUnitType == 2) {
7327 112 : thisSys.input_specs.heat_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "heating_convergence_tolerance");
7328 168 : thisSys.input_specs.cool_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_convergence_tolerance");
7329 310 : } else if (getPTUnitType == 3) {
7330 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name =
7331 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_dry_bulb_temperature_sensor_node_name");
7332 : thisSys.input_specs.heat_pump_coil_water_flow_mode =
7333 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "heat_pump_coil_water_flow_mode");
7334 310 : thisSys.input_specs.control_type = "LOAD";
7335 : }
7336 : }
7337 660 : if (getPTUnitType < 3) {
7338 700 : thisSys.input_specs.control_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "capacity_control_method");
7339 350 : if (thisSys.input_specs.control_type.empty() || thisSys.input_specs.control_type == "NONE") {
7340 350 : thisSys.input_specs.control_type = "LOAD";
7341 : }
7342 350 : thisSys.input_specs.minimum_supply_air_temperature =
7343 700 : ip->getRealFieldValue(fields, objectSchemaProps, "minimum_supply_air_temperature_in_cooling_mode");
7344 350 : thisSys.input_specs.maximum_supply_air_temperature =
7345 1050 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_in_heating_mode");
7346 : }
7347 :
7348 1320 : thisSys.input_specs.avail_manager_list_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_manager_list_name");
7349 : thisSys.input_specs.design_spec_zonehvac_sizing_object_name =
7350 1320 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_zonehvac_sizing_object_name");
7351 :
7352 660 : if (getPTUnitType == 3) {
7353 : thisSys.m_DesignSpecMultispeedHPType =
7354 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_type");
7355 : thisSys.m_DesignSpecMultispeedHPName =
7356 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_name");
7357 310 : if (!thisSys.m_DesignSpecMultispeedHPType.empty() && !thisSys.m_DesignSpecMultispeedHPName.empty()) {
7358 4 : DesignSpecMSHP thisDesignSpec;
7359 4 : thisSys.m_CompPointerMSHP =
7360 4 : thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, thisSys.m_DesignSpecMultispeedHPName);
7361 4 : thisSys.m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, thisSys.m_DesignSpecMultispeedHPName);
7362 4 : }
7363 : }
7364 :
7365 : // set UnitarySystem specific inputs
7366 660 : thisSys.input_specs.dehumidification_control_type = "None";
7367 660 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7368 660 : thisSys.input_specs.cooling_supply_air_flow_rate_method = "SupplyAirFlowRate";
7369 660 : thisSys.input_specs.heating_supply_air_flow_rate_method = "SupplyAirFlowRate";
7370 660 : thisSys.input_specs.no_load_supply_air_flow_rate_method = "SupplyAirFlowRate";
7371 :
7372 660 : thisSys.UnitType = cCurrentModuleObject;
7373 660 : thisSys.m_sysType = sysTypeNum;
7374 660 : thisSys.zoneEquipType = zoneEqType;
7375 :
7376 : // TODO: figure out another way to set this next variable
7377 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7378 660 : thisSys.m_LastMode = HeatingMode;
7379 660 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7380 :
7381 660 : if (sysNum == -1) {
7382 : // zone equipment require a 1-n index for access to zone availability managers
7383 330 : switch (getPTUnitType) {
7384 147 : case 1: // Excuse me?
7385 147 : ++numPTAC;
7386 147 : thisSys.m_EquipCompNum = numPTAC;
7387 147 : break;
7388 28 : case 2: // Baking powder?
7389 28 : ++numPTHP;
7390 28 : thisSys.m_EquipCompNum = numPTHP;
7391 28 : break;
7392 155 : case 3:
7393 155 : ++numPTWSHP;
7394 155 : thisSys.m_EquipCompNum = numPTWSHP;
7395 155 : break;
7396 330 : default:
7397 : assert(true);
7398 : }
7399 330 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7400 330 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7401 : } else {
7402 330 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7403 : }
7404 22466 : }
7405 : }
7406 2799 : }
7407 933 : }
7408 :
7409 933 : void UnitarySys::allocateUnitarySys(EnergyPlusData &state)
7410 : {
7411 933 : if (!state.dataUnitarySystems->unitarySys.empty()) {
7412 763 : return;
7413 : }
7414 170 : int numUnitarySystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:UnitarySystem");
7415 170 : int numCoilSystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:DX");
7416 170 : int numCoilSystemsWater = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:Water");
7417 170 : int numPackagedAC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalAirConditioner");
7418 170 : int numPackagedHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalHeatPump");
7419 170 : int numPackagedWSHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:WaterToAirHeatPump");
7420 170 : int numAllSystemTypes = numUnitarySystems + numCoilSystems + numCoilSystemsWater + numPackagedAC + numPackagedHP + numPackagedWSHP;
7421 933 : for (int sysCount = 0; sysCount < numAllSystemTypes; ++sysCount) {
7422 763 : UnitarySys thisSys;
7423 763 : state.dataUnitarySystems->unitarySys.push_back(thisSys);
7424 763 : }
7425 : }
7426 :
7427 933 : void UnitarySys::getCoilWaterSystemInputData(
7428 : EnergyPlusData &state, std::string_view CoilSysName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7429 : {
7430 :
7431 933 : std::string cCurrentModuleObject("CoilSystem:Cooling:Water");
7432 1273 : static const std::string routineName("getCoilWaterSystemInputData: ");
7433 933 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7434 933 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7435 8 : auto &instancesValue = instances.value();
7436 8 : int numCoilSystemWater = 0;
7437 16 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7438 :
7439 8 : auto const &fields = instance.value();
7440 8 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7441 8 : if (!Util::SameString(CoilSysName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7442 2 : continue;
7443 : }
7444 :
7445 6 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7446 6 : UnitarySys thisSys;
7447 6 : if (sysNum == -1) {
7448 3 : ++state.dataUnitarySystems->numUnitarySystems;
7449 3 : auto const &thisObjName = instance.key();
7450 3 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7451 : } else {
7452 3 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7453 : }
7454 :
7455 6 : thisSys.input_specs.name = thisObjectName;
7456 6 : thisSys.input_specs.system_type = cCurrentModuleObject;
7457 6 : thisSys.input_specs.control_type = "Setpoint";
7458 12 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>());
7459 12 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>());
7460 12 : std::string availScheduleName("");
7461 12 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field, has default value of Always On
7462 2 : availScheduleName = Util::makeUPPER(it.value().get<std::string>());
7463 6 : }
7464 6 : thisSys.input_specs.availability_schedule_name = availScheduleName;
7465 12 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>());
7466 6 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>());
7467 : // why is this cooling coil does not have a field for Design Air Vol Flow Rate
7468 : // set it "SupplyAirFlowRate" to avoid blank, which lead to fatal out during get input
7469 : static constexpr std::string_view loc_cooling_coil_object_type("COIL:COOLING:WATER:DETAILEDGEOMETRY");
7470 6 : if (Util::SameString(loc_cooling_coil_object_type, thisSys.input_specs.cooling_coil_object_type)) {
7471 0 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER("SupplyAirFlowRate");
7472 0 : thisSys.input_specs.cooling_supply_air_flow_rate = DataSizing::AutoSize;
7473 : }
7474 : // optional input fields
7475 6 : if (auto it = fields.find("minimum_air_to_water_temperature_offset");
7476 6 : it != fields.end()) { // not required field, has default value of 0.0
7477 6 : thisSys.m_minAirToWaterTempOffset = it.value().get<Real64>();
7478 6 : }
7479 12 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) {
7480 4 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7481 : } else {
7482 2 : thisSys.input_specs.dehumidification_control_type = "None";
7483 6 : }
7484 :
7485 6 : bool runOnSensibleLoad = true;
7486 12 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) {
7487 4 : runOnSensibleLoad = Util::SameString(it.value().get<std::string>(), "YES");
7488 6 : }
7489 6 : bool runOnLatentLoad = false;
7490 12 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) {
7491 4 : runOnLatentLoad = Util::SameString(it.value().get<std::string>(), "YES");
7492 6 : }
7493 :
7494 6 : if (runOnSensibleLoad && !runOnLatentLoad) {
7495 2 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7496 4 : } else if (!runOnSensibleLoad && runOnLatentLoad) {
7497 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7498 4 : } else if (runOnSensibleLoad && runOnLatentLoad) {
7499 4 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7500 : }
7501 :
7502 : // now translate to UnitarySystem
7503 6 : thisSys.UnitType = cCurrentModuleObject;
7504 6 : thisSys.m_sysType = SysType::CoilCoolingWater;
7505 6 : thisSys.AirloopEqType = SimAirServingZones::CompType::CoilSystemWater;
7506 6 : thisSys.input_specs.control_type = "Setpoint";
7507 6 : thisSys.m_CoolCoilExists = true; // is always true
7508 6 : thisSys.m_LastMode = CoolingMode;
7509 : // set water-side economizer flag
7510 6 : if (thisSys.m_minAirToWaterTempOffset > 0.0) {
7511 6 : thisSys.m_TemperatureOffsetControlActive = true;
7512 : }
7513 :
7514 : // heat recovery loop inputs
7515 12 : if (auto it = fields.find("minimum_water_loop_temperature_for_heat_recovery"); it != fields.end()) {
7516 2 : thisSys.m_minWaterLoopTempForHR = it.value().get<Real64>();
7517 6 : }
7518 12 : if (auto it = fields.find("economizer_lockout"); it != fields.end()) { // duplicate above as default
7519 0 : bool econoFlag = Util::SameString(it.value().get<std::string>(), "YES");
7520 0 : if (econoFlag) {
7521 0 : thisSys.m_waterSideEconomizerFlag = true;
7522 : }
7523 : } else {
7524 6 : thisSys.m_waterSideEconomizerFlag = true;
7525 6 : }
7526 6 : std::string HRWaterCoolingCoilName;
7527 12 : if (auto it = fields.find("companion_coil_used_for_heat_recovery"); it != fields.end()) {
7528 2 : HRWaterCoolingCoilName = Util::makeUPPER(it.value().get<std::string>());
7529 2 : thisSys.m_WaterHRPlantLoopModel = true;
7530 6 : }
7531 6 : if (thisSys.m_WaterHRPlantLoopModel) {
7532 2 : std::string const HRcoolingCoilType("COIL:COOLING:WATER");
7533 2 : bool errFound = false;
7534 2 : thisSys.m_HRcoolCoilAirInNode = WaterCoils::GetCoilInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7535 2 : thisSys.m_HRcoolCoilFluidInletNode =
7536 2 : WaterCoils::GetCoilWaterInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7537 2 : int HRCoilIndex = WaterCoils::GetWaterCoilIndex(state, Util::makeUPPER(HRcoolingCoilType), HRWaterCoolingCoilName, errFound);
7538 2 : bool heatRecoveryCoil = true; // use local here to highlight where this parameter is set
7539 2 : WaterCoils::SetWaterCoilData(state, HRCoilIndex, errFound, _, _, heatRecoveryCoil);
7540 2 : if (errFound) {
7541 0 : if (HRCoilIndex == 0) {
7542 0 : ShowContinueError(state, format("...cooling coil {} must be of type Coil:Cooling:Water.", HRWaterCoolingCoilName));
7543 : }
7544 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisObjectName));
7545 : }
7546 2 : errorsFound = errorsFound || errFound;
7547 2 : }
7548 : // end heat recovery loop inputs
7549 :
7550 6 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7551 :
7552 6 : if (sysNum == -1) {
7553 3 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7554 3 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7555 : // zone equipment require a 1-n index for access to zone availability managers
7556 : // although not zone equipment, use same methodology
7557 3 : ++numCoilSystemWater;
7558 3 : thisSys.m_EquipCompNum = numCoilSystemWater;
7559 : } else {
7560 3 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7561 : }
7562 16 : }
7563 :
7564 8 : if (errorsFound) {
7565 0 : ShowFatalError(
7566 : state,
7567 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", routineName, cCurrentModuleObject));
7568 : }
7569 : }
7570 933 : }
7571 :
7572 933 : void UnitarySys::getUnitarySystemInputData(
7573 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7574 : {
7575 :
7576 933 : std::string const cCurrentModuleObject = "AirLoopHVAC:UnitarySystem";
7577 1273 : static std::string const getUnitarySystemInput("getUnitarySystemInputData");
7578 933 : int zoneUnitaryNum = 0;
7579 933 : int airloopUnitaryNum = 0;
7580 :
7581 933 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7582 933 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end() && state.dataUnitarySystems->numUnitarySystems == 0) {
7583 0 : ShowSevereError(state, "getUnitarySystemInputData: did not find AirLoopHVAC:UnitarySystem object in input file. Check inputs");
7584 0 : errorsFound = true;
7585 933 : } else if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7586 223 : auto &instancesValue = instances.value();
7587 223 : auto const &objectSchemaProps = state.dataInputProcessing->inputProcessor->getObjectSchemaProps(state, cCurrentModuleObject);
7588 1256 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7589 :
7590 1033 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7591 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7592 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7593 1033 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7594 769 : continue;
7595 : }
7596 :
7597 264 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7598 264 : UnitarySys thisSys;
7599 264 : if (sysNum == -1) {
7600 132 : ++state.dataUnitarySystems->numUnitarySystems;
7601 132 : auto const &thisObjName = instance.key();
7602 132 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7603 : } else {
7604 132 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7605 : }
7606 :
7607 264 : auto const &fields = instance.value();
7608 264 : thisSys.UnitType = cCurrentModuleObject;
7609 264 : thisSys.m_sysType = SysType::Unitary;
7610 264 : thisSys.AirloopEqType = SimAirServingZones::CompType::UnitarySystemModel;
7611 :
7612 264 : thisSys.input_specs.name = thisObjectName;
7613 264 : thisSys.input_specs.system_type = cCurrentModuleObject;
7614 528 : thisSys.input_specs.control_type = fields.at("control_type").get<std::string>();
7615 528 : if (auto it = fields.find("controlling_zone_or_thermostat_location"); it != fields.end()) { // not required field
7616 248 : thisSys.input_specs.controlling_zone_or_thermostat_location = Util::makeUPPER(it.value().get<std::string>());
7617 264 : }
7618 528 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field, has default
7619 236 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7620 : } else {
7621 28 : thisSys.input_specs.dehumidification_control_type = "NONE"; // default value
7622 264 : }
7623 528 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7624 164 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7625 264 : }
7626 528 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>()); // required
7627 528 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>()); // required
7628 528 : if (auto it = fields.find("supply_fan_object_type"); it != fields.end()) { // not required field
7629 260 : thisSys.input_specs.supply_fan_object_type = Util::makeUPPER(it.value().get<std::string>());
7630 264 : }
7631 :
7632 528 : if (auto it = fields.find("supply_fan_name"); it != fields.end()) { // not required field
7633 260 : thisSys.input_specs.supply_fan_name = Util::makeUPPER(it.value().get<std::string>());
7634 264 : }
7635 528 : if (auto it = fields.find("fan_placement"); it != fields.end()) { // not required field
7636 260 : thisSys.input_specs.fan_placement = Util::makeUPPER(it.value().get<std::string>());
7637 264 : }
7638 528 : if (auto it = fields.find("supply_air_fan_operating_mode_schedule_name"); it != fields.end()) { // not required field
7639 250 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7640 264 : }
7641 528 : if (auto it = fields.find("heating_coil_object_type"); it != fields.end()) { // not required field
7642 230 : thisSys.input_specs.heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7643 230 : thisSys.m_HeatCoilExists = true;
7644 264 : }
7645 528 : if (auto it = fields.find("heating_coil_name"); it != fields.end()) { // not required field
7646 230 : thisSys.input_specs.heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7647 264 : }
7648 528 : if (auto it = fields.find("dx_heating_coil_sizing_ratio"); it != fields.end()) { // not required field, has default
7649 180 : thisSys.input_specs.dx_heating_coil_sizing_ratio = it.value().get<Real64>();
7650 264 : }
7651 528 : if (auto it = fields.find("cooling_coil_object_type"); it != fields.end()) { // not required field
7652 262 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7653 262 : thisSys.m_CoolCoilExists = true;
7654 264 : }
7655 528 : if (auto it = fields.find("cooling_coil_name"); it != fields.end()) { // not required field
7656 262 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(it.value().get<std::string>());
7657 264 : }
7658 528 : if (auto it = fields.find("use_doas_dx_cooling_coil"); it != fields.end()) { // not required field, has default
7659 78 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7660 : } else {
7661 186 : thisSys.input_specs.use_doas_dx_cooling_coil = "No";
7662 264 : }
7663 264 : if (auto it = fields.find("minimum_supply_air_temperature");
7664 264 : it != fields.end()) { // not required field, has default (2C), and autosizable
7665 78 : thisSys.input_specs.minimum_supply_air_temperature =
7666 156 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7667 156 : ? DataSizing::AutoSize
7668 78 : : it.value().get<Real64>();
7669 264 : }
7670 528 : if (auto it = fields.find("latent_load_control"); it != fields.end()) { // not required field, has default
7671 106 : thisSys.input_specs.latent_load_control = it.value().get<std::string>();
7672 : } else {
7673 158 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7674 264 : }
7675 528 : if (auto it = fields.find("supplemental_heating_coil_object_type"); it != fields.end()) { // not required field
7676 84 : thisSys.input_specs.supplemental_heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7677 264 : }
7678 528 : if (auto it = fields.find("supplemental_heating_coil_name"); it != fields.end()) { // not required field
7679 84 : thisSys.input_specs.supplemental_heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7680 264 : }
7681 528 : if (auto it = fields.find("cooling_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7682 260 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER(it.value().get<std::string>());
7683 264 : }
7684 528 : if (auto it = fields.find("cooling_supply_air_flow_rate"); it != fields.end()) { // not required field, autosizable
7685 260 : thisSys.input_specs.cooling_supply_air_flow_rate =
7686 752 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7687 752 : ? DataSizing::AutoSize
7688 28 : : it.value().get<Real64>();
7689 264 : }
7690 528 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7691 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7692 264 : }
7693 528 : if (auto it = fields.find("cooling_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7694 0 : thisSys.input_specs.cooling_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7695 264 : }
7696 528 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7697 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7698 264 : }
7699 528 : if (auto it = fields.find("heating_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7700 230 : thisSys.input_specs.heating_supply_air_flow_rate_method = it.value().get<std::string>();
7701 264 : }
7702 528 : if (auto it = fields.find("heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7703 228 : thisSys.input_specs.heating_supply_air_flow_rate =
7704 658 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7705 658 : ? DataSizing::AutoSize
7706 26 : : it.value().get<Real64>();
7707 264 : }
7708 528 : if (auto it = fields.find("heating_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7709 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7710 264 : }
7711 528 : if (auto it = fields.find("heating_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7712 0 : thisSys.input_specs.heating_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7713 264 : }
7714 528 : if (auto it = fields.find("heating_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7715 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7716 264 : }
7717 528 : if (auto it = fields.find("no_load_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7718 220 : thisSys.input_specs.no_load_supply_air_flow_rate_method = it.value().get<std::string>();
7719 264 : }
7720 528 : if (auto it = fields.find("no_load_supply_air_flow_rate"); it != fields.end()) { // not required field
7721 230 : thisSys.input_specs.no_load_supply_air_flow_rate =
7722 652 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7723 652 : ? DataSizing::AutoSize
7724 38 : : it.value().get<Real64>();
7725 264 : }
7726 528 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7727 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7728 264 : }
7729 528 : if (auto it = fields.find("no_load_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7730 0 : thisSys.input_specs.no_load_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7731 264 : }
7732 528 : if (auto it = fields.find("no_load_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7733 0 : thisSys.input_specs.no_load_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7734 264 : }
7735 264 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation");
7736 264 : it != fields.end()) { // not required field
7737 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation = it.value().get<Real64>();
7738 264 : }
7739 264 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation");
7740 264 : it != fields.end()) { // not required field
7741 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation = it.value().get<Real64>();
7742 264 : }
7743 792 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed = state.dataInputProcessing->inputProcessor->getAlphaFieldValue(
7744 264 : fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7745 792 : if (fields.find("maximum_supply_air_temperature") != fields.end()) { // not required field, has default of 80 C
7746 228 : auto const &obj = fields.at("maximum_supply_air_temperature");
7747 228 : thisSys.input_specs.maximum_supply_air_temperature =
7748 408 : (obj.type() == nlohmann::detail::value_t::string && Util::SameString(obj.get<std::string>(), "Autosize"))
7749 408 : ? DataSizing::AutoSize
7750 48 : : obj.get<Real64>();
7751 : }
7752 264 : if (auto it = fields.find("maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7753 264 : it != fields.end()) { // not required field, has default
7754 134 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = it.value().get<Real64>();
7755 264 : }
7756 528 : if (auto it = fields.find("outdoor_dry_bulb_temperature_sensor_node_name"); it != fields.end()) { // not required field
7757 12 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name = Util::makeUPPER(it.value().get<std::string>());
7758 264 : }
7759 528 : if (auto it = fields.find("ancillary_on_cycle_electric_power"); it != fields.end()) { // not required field, has default
7760 14 : thisSys.input_specs.ancillary_on_cycle_electric_power = it.value().get<Real64>();
7761 264 : }
7762 528 : if (auto it = fields.find("ancillary_off_cycle_electric_power"); it != fields.end()) { // not required field, has default
7763 14 : thisSys.input_specs.ancillary_off_cycle_electric_power = it.value().get<Real64>();
7764 264 : }
7765 528 : if (auto it = fields.find("design_heat_recovery_water_flow_rate"); it != fields.end()) { // not required field, has default
7766 0 : thisSys.input_specs.design_heat_recovery_water_flow_rate = it.value().get<Real64>();
7767 264 : }
7768 528 : if (auto it = fields.find("maximum_temperature_for_heat_recovery"); it != fields.end()) { // not required field, has default
7769 0 : thisSys.input_specs.maximum_temperature_for_heat_recovery = it.value().get<Real64>();
7770 264 : }
7771 528 : if (auto it = fields.find("heat_recovery_water_inlet_node_name"); it != fields.end()) { // not required field
7772 0 : thisSys.input_specs.heat_recovery_water_inlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7773 264 : }
7774 528 : if (auto it = fields.find("heat_recovery_water_outlet_node_name"); it != fields.end()) { // not required field
7775 0 : thisSys.input_specs.heat_recovery_water_outlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7776 264 : }
7777 528 : if (auto it = fields.find("design_specification_multispeed_object_type"); it != fields.end()) { // not required field
7778 120 : thisSys.input_specs.design_specification_multispeed_object_type = Util::makeUPPER(it.value().get<std::string>());
7779 264 : }
7780 528 : if (auto it = fields.find("design_specification_multispeed_object_name"); it != fields.end()) { // not required field
7781 120 : thisSys.input_specs.design_specification_multispeed_object_name = Util::makeUPPER(it.value().get<std::string>());
7782 264 : }
7783 :
7784 264 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7785 :
7786 264 : if (sysNum == -1) {
7787 132 : ++thisSys.m_UnitarySysNum;
7788 132 : if (ZoneEquipment) {
7789 : // zone equipment require a 1-n index for access to zone availability managers
7790 25 : ++zoneUnitaryNum;
7791 25 : thisSys.m_EquipCompNum = zoneUnitaryNum;
7792 : } else {
7793 : // zone equipment require a 1-n index for access to zone availability managers
7794 : // although not zone equipment, use same methodology
7795 : // keep OA system unitary equipment indexes separate?
7796 107 : ++airloopUnitaryNum;
7797 107 : thisSys.m_EquipCompNum = airloopUnitaryNum;
7798 : }
7799 132 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7800 132 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7801 : } else {
7802 132 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7803 : }
7804 1256 : }
7805 : }
7806 933 : }
7807 :
7808 127610 : void UnitarySys::calcUnitarySuppSystemToSP(EnergyPlusData &state, bool const FirstHVACIteration // True when first HVAC iteration
7809 : )
7810 : {
7811 :
7812 : // SUBROUTINE INFORMATION:
7813 : // AUTHOR Richard Raustad, FSEC
7814 : // DATE WRITTEN February 2013
7815 :
7816 : // PURPOSE OF THIS SUBROUTINE:
7817 : // This subroutine manages supplemental heater component simulation for setpoint based operation scheme.
7818 :
7819 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7820 : Real64 QActual;
7821 :
7822 127610 : std::string CompName = this->m_SuppHeatCoilName;
7823 127610 : int CoilType_Num = this->m_SuppHeatCoilType_Num;
7824 :
7825 127610 : if ((CoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel) || (CoilType_Num == HVAC::Coil_HeatingElectric)) {
7826 446850 : HeatingCoils::SimulateHeatingCoilComponents(state,
7827 : CompName,
7828 : FirstHVACIteration,
7829 178740 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7830 89370 : this->m_SuppHeatCoilIndex,
7831 : _,
7832 178740 : true,
7833 89370 : this->m_FanOpMode,
7834 89370 : this->m_SuppHeatPartLoadFrac);
7835 :
7836 38240 : } else if (CoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
7837 59614 : HeatingCoils::SimulateHeatingCoilComponents(state,
7838 : CompName,
7839 : FirstHVACIteration,
7840 : _,
7841 29807 : this->m_SuppHeatCoilIndex,
7842 : _,
7843 : _,
7844 29807 : this->m_FanOpMode,
7845 29807 : this->m_SuppHeatPartLoadFrac,
7846 29807 : this->m_SuppHeatingSpeedNum,
7847 29807 : this->m_SuppHeatingSpeedRatio);
7848 :
7849 8433 : } else if (CoilType_Num == HVAC::Coil_HeatingDesuperheater) {
7850 33732 : HeatingCoils::SimulateHeatingCoilComponents(state,
7851 : CompName,
7852 : FirstHVACIteration,
7853 16866 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7854 8433 : this->m_SuppHeatCoilIndex,
7855 : _,
7856 : _,
7857 8433 : this->m_FanOpMode,
7858 8433 : this->m_SuppHeatPartLoadFrac);
7859 :
7860 0 : } else if (CoilType_Num == HVAC::Coil_HeatingWater) {
7861 0 : WaterCoils::SimulateWaterCoilComponents(
7862 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, QActual, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
7863 :
7864 0 : } else if (CoilType_Num == HVAC::Coil_HeatingSteam) {
7865 0 : SteamCoils::SimulateSteamCoilComponents(state,
7866 : CompName,
7867 : FirstHVACIteration,
7868 0 : this->m_SuppHeatCoilIndex,
7869 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7870 : _,
7871 0 : this->m_FanOpMode,
7872 0 : this->m_SuppHeatPartLoadFrac);
7873 : }
7874 127610 : }
7875 :
7876 6054691 : void UnitarySys::controlUnitarySystemtoLoad(EnergyPlusData &state,
7877 : int const AirLoopNum, // Primary air loop number
7878 : bool const FirstHVACIteration, // True when first HVAC iteration
7879 : HVAC::CompressorOp &CompressorOn, // Determines if compressor is on or off
7880 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7881 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7882 : Real64 &sysOutputProvided, // system sensible output at supply air node
7883 : Real64 &latOutputProvided // system latent output at supply air node
7884 : )
7885 : {
7886 :
7887 : // SUBROUTINE INFORMATION:
7888 : // AUTHOR Richard Raustad, FSEC
7889 : // DATE WRITTEN February 2013
7890 6054691 : Real64 ZoneLoad = 0.0; // zone load (W)
7891 6054691 : Real64 SupHeaterLoad = 0.0; // additional heating required by supplemental heater (W)
7892 6054691 : Real64 OnOffAirFlowRatio = 1.0;
7893 6054691 : this->updateUnitarySystemControl(state,
7894 : AirLoopNum,
7895 : this->CoolCoilOutletNodeNum,
7896 : this->CoolCtrlNode,
7897 : OnOffAirFlowRatio,
7898 : FirstHVACIteration,
7899 : OAUCoilOutTemp,
7900 : ZoneLoad,
7901 : this->DesignMaxOutletTemp);
7902 :
7903 : // will not be running supplemental heater on this CALL (simulate with supplemental heater off)
7904 6054691 : Real64 FullSensibleOutput = 0.0;
7905 : // using furnace module logic
7906 : // first check to see if cycling fan with economizer can meet the load
7907 6054691 : if (AirLoopNum > 0) {
7908 2674018 : if (this->m_CoolCoilExists && this->m_HeatCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingAirToAirVariableSpeed &&
7909 2407210 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed && !FirstHVACIteration &&
7910 5546311 : this->m_FanOpMode == HVAC::FanOp::Cycling && state.dataUnitarySystems->CoolingLoad &&
7911 198275 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
7912 70406 : CompressorOn = HVAC::CompressorOp::Off;
7913 70406 : this->controlUnitarySystemOutput(
7914 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7915 70406 : if (this->m_CoolingPartLoadFrac >= 1.0 || this->m_HeatingPartLoadFrac >= 1.0 ||
7916 64120 : (this->m_CoolingPartLoadFrac <= 0.0 && this->m_HeatingPartLoadFrac <= 0.0)) {
7917 67826 : CompressorOn = HVAC::CompressorOp::On;
7918 67826 : this->controlUnitarySystemOutput(
7919 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7920 : }
7921 : } else {
7922 2603612 : CompressorOn = HVAC::CompressorOp::On;
7923 2603612 : this->controlUnitarySystemOutput(
7924 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7925 : }
7926 : } else {
7927 3380673 : CompressorOn = HVAC::CompressorOp::On;
7928 3380673 : this->controlUnitarySystemOutput(
7929 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7930 : }
7931 6786235 : if (state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate < HVAC::SmallMassFlow && this->m_sysType != SysType::PackagedAC &&
7932 6786235 : this->m_sysType != SysType::PackagedHP && this->m_sysType != SysType::PackagedWSHP) {
7933 578914 : state.dataUnitarySystems->CoolingLoad = false;
7934 578914 : state.dataUnitarySystems->HeatingLoad = false;
7935 578914 : state.dataUnitarySystems->MoistureLoad = 0.0;
7936 578914 : this->m_CoolingPartLoadFrac = 0.0;
7937 578914 : this->m_HeatingPartLoadFrac = 0.0;
7938 578914 : if (this->CoolCoilFluidInletNode > 0) {
7939 147610 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
7940 : }
7941 578914 : if (this->HeatCoilFluidInletNode > 0) {
7942 24 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = 0.0;
7943 : }
7944 578914 : this->setAverageAirFlow(state, this->m_CoolingPartLoadFrac, OnOffAirFlowRatio);
7945 : // anything else need to be reset here when system is shut down on low flow?
7946 : }
7947 6054691 : Real64 CoolPLR = this->m_CoolingPartLoadFrac;
7948 6054691 : Real64 HeatPLR = this->m_HeatingPartLoadFrac;
7949 6054691 : Real64 HeatCoilLoad = HeatPLR * this->m_DesignHeatingCapacity;
7950 :
7951 6054691 : if (this->CoolCoilFluidInletNode > 0) {
7952 393018 : PlantUtilities::SetComponentFlowRate(state,
7953 196509 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate,
7954 : this->CoolCoilFluidInletNode,
7955 : this->CoolCoilFluidOutletNodeNum,
7956 196509 : this->CoolCoilPlantLoc);
7957 : }
7958 6054691 : if (this->HeatCoilFluidInletNode > 0) {
7959 157188 : PlantUtilities::SetComponentFlowRate(state,
7960 78594 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate,
7961 : this->HeatCoilFluidInletNode,
7962 : this->HeatCoilFluidOutletNodeNum,
7963 78594 : this->HeatCoilPlantLoc);
7964 : }
7965 :
7966 9231900 : if (this->m_SuppCoilExists &&
7967 3177209 : (state.dataUnitarySystems->HeatingLoad || state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < 0.0)) {
7968 2643134 : if ((FullSensibleOutput < (state.dataUnitarySystems->QToHeatSetPt - HVAC::SmallLoad)) && !FirstHVACIteration) {
7969 254914 : SupHeaterLoad = max(0.0, state.dataUnitarySystems->QToHeatSetPt - FullSensibleOutput);
7970 254914 : this->m_SupHeaterLoad = 0.0;
7971 : // what does this line even do? I know we want the supplemental heater on only if there is a dehum load,
7972 : // but for HP's the supp heater should also run if the heating coil can't turn on
7973 : // (i.e., this line calc's a supp heater load, then next line also calc's it?)
7974 254914 : if (state.dataUnitarySystems->MoistureLoad < 0.0) {
7975 579 : this->m_SupHeaterLoad = SupHeaterLoad;
7976 : }
7977 : // so it look's like this next line should only be valid for HP's.
7978 254914 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7979 254914 : this->m_SuppHeatPartLoadFrac = min(1.0, SupHeaterLoad / this->m_DesignSuppHeatingCapacity);
7980 : }
7981 : } else {
7982 2388220 : SupHeaterLoad = 0.0;
7983 2388220 : this->m_SuppHeatPartLoadFrac = 0.0;
7984 : }
7985 : } else {
7986 3411557 : SupHeaterLoad = 0.0;
7987 3411557 : this->m_SuppHeatPartLoadFrac = 0.0;
7988 : }
7989 :
7990 6054691 : this->calcUnitarySystemToLoad(state,
7991 : AirLoopNum,
7992 : FirstHVACIteration,
7993 : CoolPLR,
7994 : HeatPLR,
7995 : OnOffAirFlowRatio,
7996 : sysOutputProvided,
7997 : latOutputProvided,
7998 : HXUnitOn,
7999 : HeatCoilLoad,
8000 : SupHeaterLoad,
8001 : CompressorOn);
8002 : // Why need this second run?
8003 : // check supplemental heating coil outlet temp based on maximum allowed
8004 6054691 : if (this->m_SuppCoilExists) {
8005 : // only need to test for high supply air temp if supplemental coil is operating
8006 3177209 : if (this->m_SuppHeatPartLoadFrac > 0.0) {
8007 254906 : this->calcUnitarySystemToLoad(state,
8008 : AirLoopNum,
8009 : FirstHVACIteration,
8010 : CoolPLR,
8011 : HeatPLR,
8012 : OnOffAirFlowRatio,
8013 : sysOutputProvided,
8014 : latOutputProvided,
8015 : HXUnitOn,
8016 : HeatCoilLoad,
8017 : SupHeaterLoad,
8018 : CompressorOn);
8019 254906 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
8020 : // multistage coil part load fraction already set in the calcUnitarySystemToLoad
8021 254906 : if (this->m_NumOfSpeedSuppHeating <= 1) {
8022 205404 : this->m_SuppHeatPartLoadFrac = SupHeaterLoad / this->m_DesignSuppHeatingCapacity;
8023 : }
8024 : } else {
8025 0 : this->m_SuppHeatPartLoadFrac = 0.0;
8026 : }
8027 : }
8028 : }
8029 :
8030 6054691 : if (this->m_SuppCoilFluidInletNode > 0) {
8031 0 : PlantUtilities::SetComponentFlowRate(state,
8032 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate,
8033 : this->m_SuppCoilFluidInletNode,
8034 : this->m_SuppCoilFluidOutletNodeNum,
8035 0 : this->m_SuppCoilPlantLoc);
8036 : }
8037 :
8038 6054691 : if (this->m_HeatRecActive) {
8039 0 : PlantUtilities::SetComponentFlowRate(state,
8040 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate,
8041 : this->m_HeatRecoveryInletNodeNum,
8042 : this->m_HeatRecoveryOutletNodeNum,
8043 0 : this->m_HRPlantLoc);
8044 : }
8045 6054691 : }
8046 :
8047 3680464 : void UnitarySys::controlUnitarySystemtoSP(EnergyPlusData &state,
8048 : int const AirLoopNum, // Primary air loop number
8049 : bool const FirstHVACIteration, // True when first HVAC iteration
8050 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
8051 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
8052 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8053 : Real64 &sysOutputProvided, // sensible output at supply air node
8054 : Real64 &latOutputProvided // latent output at supply air node
8055 : )
8056 : {
8057 :
8058 : // SUBROUTINE INFORMATION:
8059 : // AUTHOR Richard Raustad, FSEC
8060 : // DATE WRITTEN February 2013
8061 :
8062 : // PURPOSE OF THIS SUBROUTINE:
8063 : // This subroutine manages component simulation.
8064 :
8065 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8066 3680464 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
8067 3680464 : Real64 OnOffAirFlowRatio = 1.0; // Setpoint based coil control does not use this variable
8068 3680464 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
8069 3680464 : Real64 ZoneLoad = 0.0;
8070 3680464 : Real64 HeatCoilLoad = -999.0;
8071 :
8072 : // CALL the series of components that simulate a Unitary System
8073 3680464 : if (this->ATMixerExists) {
8074 : // There is an air terminal mixer
8075 0 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
8076 : // set the primary air inlet mass flow rate
8077 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
8078 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
8079 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
8080 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
8081 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
8082 : }
8083 : }
8084 3680464 : if (this->OAMixerExists) {
8085 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
8086 0 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
8087 : }
8088 3680464 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
8089 98727 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
8090 : }
8091 :
8092 3680464 : if (this->m_CoolingCoilUpstream) {
8093 :
8094 3680464 : if (this->m_CoolCoilExists) {
8095 3676380 : this->updateUnitarySystemControl(state,
8096 : AirLoopNum,
8097 : this->CoolCoilOutletNodeNum,
8098 : this->CoolCtrlNode,
8099 : OnOffAirFlowRatio,
8100 : FirstHVACIteration,
8101 : OAUCoilOutTemp,
8102 : ZoneLoad,
8103 : this->DesignMaxOutletTemp);
8104 3676380 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
8105 3676380 : PartLoadRatio = this->m_CoolingPartLoadFrac;
8106 3676380 : CompressorOn = HVAC::CompressorOp::Off;
8107 3676380 : if (PartLoadRatio > 0.0) {
8108 1223026 : CompressorOn = HVAC::CompressorOp::On;
8109 1223026 : this->m_LastMode = CoolingMode;
8110 : }
8111 3676380 : this->calcUnitaryCoolingSystem(
8112 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
8113 : }
8114 3680464 : if (this->m_HeatCoilExists) {
8115 102811 : this->updateUnitarySystemControl(state,
8116 : AirLoopNum,
8117 : this->HeatCoilOutletNodeNum,
8118 : this->HeatCtrlNode,
8119 : OnOffAirFlowRatio,
8120 : FirstHVACIteration,
8121 : OAUCoilOutTemp,
8122 : ZoneLoad,
8123 : this->DesignMaxOutletTemp);
8124 102811 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
8125 102811 : PartLoadRatio = this->m_HeatingPartLoadFrac;
8126 102811 : HVAC::CompressorOp CompressOn = HVAC::CompressorOp::Off;
8127 102811 : if (PartLoadRatio > 0.0) {
8128 28886 : CompressOn = HVAC::CompressorOp::On;
8129 28886 : this->m_LastMode = HeatingMode;
8130 : }
8131 102811 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressOn, OnOffAirFlowRatio, HeatCoilLoad);
8132 : }
8133 :
8134 : } else {
8135 :
8136 0 : if (this->m_HeatCoilExists) {
8137 0 : this->updateUnitarySystemControl(state,
8138 : AirLoopNum,
8139 : this->HeatCoilOutletNodeNum,
8140 : this->HeatCtrlNode,
8141 : OnOffAirFlowRatio,
8142 : FirstHVACIteration,
8143 : OAUCoilOutTemp,
8144 : ZoneLoad,
8145 : this->DesignMaxOutletTemp);
8146 0 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
8147 0 : PartLoadRatio = this->m_HeatingPartLoadFrac;
8148 0 : CompressorOn = HVAC::CompressorOp::Off;
8149 0 : if (PartLoadRatio > 0.0) {
8150 0 : CompressorOn = HVAC::CompressorOp::On;
8151 0 : this->m_LastMode = HeatingMode;
8152 : }
8153 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
8154 : }
8155 0 : if (this->m_CoolCoilExists) {
8156 0 : this->updateUnitarySystemControl(state,
8157 : AirLoopNum,
8158 : this->CoolCoilOutletNodeNum,
8159 : this->CoolCtrlNode,
8160 : OnOffAirFlowRatio,
8161 : FirstHVACIteration,
8162 : OAUCoilOutTemp,
8163 : ZoneLoad,
8164 : this->DesignMaxOutletTemp);
8165 0 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
8166 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
8167 0 : CompressorOn = HVAC::CompressorOp::Off;
8168 0 : if (PartLoadRatio > 0.0) {
8169 0 : CompressorOn = HVAC::CompressorOp::On;
8170 0 : this->m_LastMode = CoolingMode;
8171 : }
8172 0 : this->calcUnitaryCoolingSystem(
8173 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
8174 : }
8175 : }
8176 :
8177 3680464 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
8178 0 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
8179 : }
8180 :
8181 3680464 : if (this->m_SuppCoilExists) {
8182 98727 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
8183 98727 : this->updateUnitarySystemControl(state,
8184 : AirLoopNum,
8185 : this->SuppCoilOutletNodeNum,
8186 : this->SuppCtrlNode,
8187 : OnOffAirFlowRatio,
8188 : FirstHVACIteration,
8189 : OAUCoilOutTemp,
8190 : ZoneLoad,
8191 : this->DesignMaxOutletTemp);
8192 98727 : this->controlSuppHeatSystemToSP(state, AirLoopNum, FirstHVACIteration);
8193 98727 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
8194 98727 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
8195 : }
8196 :
8197 : // If there is a supply side air terminal mixer, calculate its output
8198 3680464 : if (this->ATMixerExists) {
8199 0 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
8200 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
8201 : }
8202 : }
8203 :
8204 3680464 : calculateCapacity(state, sysOutputProvided, latOutputProvided);
8205 3680464 : this->m_InitHeatPump = false;
8206 3680464 : }
8207 :
8208 9932609 : void UnitarySys::updateUnitarySystemControl(EnergyPlusData &state,
8209 : int const AirLoopNum, // number of the current air loop being simulated
8210 : int const OutNode, // coil outlet node number
8211 : int const ControlNode, // control node number
8212 : Real64 &OnOffAirFlowRatio,
8213 : bool const FirstHVACIteration,
8214 : Real64 const OAUCoilOutletTemp, // "ONLY" for zoneHVAC:OutdoorAirUnit
8215 : Real64 &ZoneLoad,
8216 : Real64 const MaxOutletTemp // limits heating coil outlet temp [C]
8217 : )
8218 : {
8219 :
8220 : // SUBROUTINE INFORMATION:
8221 : // AUTHOR Richard Raustad, FSEC
8222 : // DATE WRITTEN February 2013
8223 :
8224 : // PURPOSE OF THIS SUBROUTINE:
8225 : // This subroutine is for sizing unitary systems.
8226 :
8227 : // METHODOLOGY EMPLOYED:
8228 : // Either CALL the coil model to get the size or size coil.
8229 : // Current method is to use same methodology as is used in coil objects.
8230 : // Future changes will include a common sizing algorithm and push the calculated
8231 : // size to the coil object prior to first call (so the coil will not DataSizing::AutoSize).
8232 :
8233 : // These initializations are done every iteration
8234 :
8235 : {
8236 9932609 : state.dataUnitarySystems->MoistureLoad = 0.0;
8237 9932609 : this->LoadSHR = 0.0;
8238 9932609 : this->CoilSHR = 0.0;
8239 9932609 : switch (this->m_ControlType) {
8240 6054691 : case UnitarySysCtrlType::Load:
8241 : case UnitarySysCtrlType::CCMASHRAE: {
8242 6054691 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAirUnit
8243 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
8244 0 : ShowFatalError(state, "...Load based control is not allowed when used with ZoneHVAC:OutdoorAirUnit");
8245 : }
8246 :
8247 : // here we need to deal with sequenced zone equip
8248 6054691 : state.dataUnitarySystems->HeatingLoad = false;
8249 6054691 : state.dataUnitarySystems->CoolingLoad = false;
8250 6054691 : if (this->m_ZoneSequenceCoolingNum > 0 && this->m_ZoneSequenceHeatingNum > 0 && this->m_AirLoopEquipment) {
8251 : // air loop equipment uses sequenced variables
8252 2673915 : state.dataUnitarySystems->QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8253 2673915 : .SequencedOutputRequiredToCoolingSP(this->m_ZoneSequenceCoolingNum);
8254 2673915 : state.dataUnitarySystems->QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8255 2673915 : .SequencedOutputRequiredToHeatingSP(this->m_ZoneSequenceHeatingNum);
8256 3320297 : if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8257 646382 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8258 641938 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8259 641938 : state.dataUnitarySystems->HeatingLoad = true;
8260 2036421 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8261 4444 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleCool) {
8262 4444 : ZoneLoad = 0.0;
8263 3152144 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8264 1124611 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8265 1119796 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8266 1119796 : state.dataUnitarySystems->CoolingLoad = true;
8267 912552 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8268 4815 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleHeat) {
8269 4815 : ZoneLoad = 0.0;
8270 902922 : } else if (state.dataUnitarySystems->QToHeatSetPt <= 0.0 && state.dataUnitarySystems->QToCoolSetPt >= 0.0) {
8271 902922 : ZoneLoad = 0.0;
8272 : }
8273 5347830 : state.dataUnitarySystems->MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum)
8274 2673915 : .SequencedOutputRequiredToDehumidSP(this->m_ZoneSequenceCoolingNum);
8275 : } else {
8276 : // zone equipment uses Remaining* variables
8277 3380776 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired;
8278 6761552 : state.dataUnitarySystems->QToCoolSetPt =
8279 3380776 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToCoolSP;
8280 6761552 : state.dataUnitarySystems->QToHeatSetPt =
8281 3380776 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToHeatSP;
8282 6761552 : state.dataUnitarySystems->MoistureLoad =
8283 3380776 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum).RemainingOutputReqToDehumidSP;
8284 3380776 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
8285 2203384 : this->m_sysType == SysType::PackagedWSHP) {
8286 : // ZoneSysAvailManager is turning on sooner than PTUnit in UnitarySystem. Mimic PTUnit logic.
8287 4797231 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8288 1599740 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8289 1594739 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8290 2949568 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 &&
8291 1346816 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8292 1346486 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8293 : } else {
8294 256266 : ZoneLoad = 0.0;
8295 : }
8296 : }
8297 : }
8298 :
8299 8446911 : if (ZoneLoad < 0.0 && state.dataUnitarySystems->MoistureLoad <= 0.0 &&
8300 2392220 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8301 719055 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag)) {
8302 1196 : this->LoadSHR =
8303 1196 : ZoneLoad / (ZoneLoad + state.dataUnitarySystems->MoistureLoad *
8304 2392 : Psychrometrics::PsyHgAirFnWTdb(
8305 1196 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).airHumRat,
8306 1196 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).MAT));
8307 1196 : if (this->LoadSHR < 0.0) {
8308 0 : this->LoadSHR = 0.0;
8309 : }
8310 1196 : this->CoilSHR = this->LoadSHR;
8311 : }
8312 :
8313 6054691 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8314 193460 : Real64 H2OHtOfVap = Psychrometrics::PsyHfgAirFnWTdb(state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
8315 193460 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp);
8316 :
8317 : // positive MoistureLoad means no dehumidification load
8318 193460 : state.dataUnitarySystems->MoistureLoad = min(0.0, state.dataUnitarySystems->MoistureLoad * H2OHtOfVap);
8319 : } else {
8320 5861231 : state.dataUnitarySystems->MoistureLoad = 0.0;
8321 : }
8322 :
8323 6054691 : this->initLoadBasedControl(state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad);
8324 :
8325 : // *** the location of this EMS override looks suspect. If EMS is active the load will be changed but the CoolingLoad and HeatingLoad
8326 : // flags are not updated. suggest this be moved up above InitLoadBasedControl function on previous line so the EMS loads are used in
8327 : // that routine EMS override point
8328 6054691 : if (this->m_EMSOverrideSensZoneLoadRequest) {
8329 0 : ZoneLoad = this->m_EMSSensibleZoneLoadValue;
8330 : }
8331 6054691 : if (this->m_EMSOverrideMoistZoneLoadRequest) {
8332 0 : state.dataUnitarySystems->MoistureLoad = this->m_EMSMoistureZoneLoadValue;
8333 : }
8334 :
8335 6054691 : this->m_SimASHRAEModel = false; // flag used to invoke ASHRAE 90.1 model calculations
8336 : // allows non-ASHSRAE compliant coil types to be modeled using non-ASHAR90 method. Constant fan operating mode is required.
8337 6054691 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
8338 3228943 : if (state.dataUnitarySystems->CoolingLoad) {
8339 1492800 : if (this->m_ValidASHRAECoolCoil) {
8340 0 : this->m_SimASHRAEModel = true;
8341 : }
8342 1736143 : } else if (state.dataUnitarySystems->HeatingLoad) {
8343 1273910 : if (this->m_ValidASHRAEHeatCoil) {
8344 0 : this->m_SimASHRAEModel = true;
8345 : }
8346 : }
8347 : }
8348 6054691 : } break;
8349 3877918 : case UnitarySysCtrlType::Setpoint: {
8350 3877918 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAIRUNIT
8351 :
8352 74325 : if (ControlNode == 0) {
8353 0 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8354 74325 : } else if (ControlNode == OutNode) {
8355 74325 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8356 : }
8357 : // If the unitary system is an Outdoor Air Unit, the desired coil outlet humidity level is set to 1.0 (no dehum)
8358 74325 : this->m_DesiredOutletHumRat = 1.0;
8359 :
8360 : } else { // Not Outdoor Air Unit. Either airloop or zone equipment
8361 3803593 : Real64 humRatMaxSP = 1.0;
8362 3803593 : this->m_DesiredOutletHumRat = humRatMaxSP;
8363 3803593 : if (ControlNode == 0) {
8364 0 : this->m_DesiredOutletTemp = 0.0;
8365 0 : if (OutNode > 0) {
8366 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8367 0 : this->m_DesiredOutletHumRat = state.dataLoopNodes->Node(OutNode).HumRatMax;
8368 : }
8369 : }
8370 3803593 : } else if (ControlNode == OutNode) {
8371 3485748 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8372 28298 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8373 19909 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8374 : }
8375 84894 : this->frostControlSetPointLimit(state,
8376 28298 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8377 : humRatMaxSP,
8378 28298 : state.dataEnvrn->OutBaroPress,
8379 : this->DesignMinOutletTemp,
8380 : 1);
8381 : }
8382 3485748 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
8383 : // IF HumRatMax is zero, then there is no request from SetpointManager:SingleZone:Humidity:Maximum
8384 : // user might place temp SP at system outlet and HumRat set point at coil outlet
8385 3485748 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8386 208011 : if (state.dataLoopNodes->Node(this->AirOutNode).HumRatMax > 0.0) {
8387 203573 : humRatMaxSP = state.dataLoopNodes->Node(this->AirOutNode).HumRatMax;
8388 : }
8389 208011 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8390 172466 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8391 : }
8392 208011 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8393 59727 : this->frostControlSetPointLimit(state,
8394 19909 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8395 19909 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8396 19909 : state.dataEnvrn->OutBaroPress,
8397 : this->DesignMinOutletTemp,
8398 : 2);
8399 19909 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8400 : }
8401 208011 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8402 : }
8403 : } else {
8404 317845 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8405 15495 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8406 : }
8407 317845 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8408 0 : humRatMaxSP = state.dataLoopNodes->Node(OutNode).HumRatMax;
8409 : }
8410 317845 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8411 0 : this->frostControlSetPointLimit(state,
8412 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8413 : humRatMaxSP,
8414 0 : state.dataEnvrn->OutBaroPress,
8415 : this->DesignMinOutletTemp,
8416 : 1);
8417 : }
8418 317845 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint -
8419 317845 : (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(OutNode).Temp);
8420 317845 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8421 0 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8422 0 : this->frostControlSetPointLimit(state,
8423 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8424 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8425 0 : state.dataEnvrn->OutBaroPress,
8426 : this->DesignMinOutletTemp,
8427 : 2);
8428 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8429 : }
8430 0 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8431 : }
8432 : }
8433 : }
8434 3877918 : this->m_DesiredOutletTemp = min(this->m_DesiredOutletTemp, MaxOutletTemp);
8435 3877918 : } break;
8436 0 : default: {
8437 : // should never get here, only 3 control types
8438 0 : } break;
8439 : }
8440 : }
8441 9932609 : }
8442 37481 : void UnitarySys::controlUnitarySystemOutputEMS(EnergyPlusData &state,
8443 : int const AirLoopNum, // Index to air loop
8444 : bool const FirstHVACIteration, // True when first HVAC iteration
8445 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8446 : Real64 const ZoneLoad,
8447 : Real64 &FullSensibleOutput,
8448 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8449 : HVAC::CompressorOp CompressorOn)
8450 : {
8451 37481 : Real64 PartLoadRatio = 1.0;
8452 37481 : Real64 CoolPLR = 0.0;
8453 37481 : Real64 HeatPLR = 0.0;
8454 37481 : HVAC::CompressorOp CompressorONFlag = CompressorOn;
8455 37481 : Real64 HeatCoilLoad = 0.0;
8456 37481 : Real64 SupHeaterLoad = 0.0;
8457 : Real64 SensOutput; // sensible output
8458 : Real64 LatOutput; // latent output
8459 37481 : this->FanPartLoadRatio = 0.0;
8460 37481 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8461 :
8462 37481 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) {
8463 1520 : return;
8464 : }
8465 35961 : int SpeedNumEMS = ceil(this->m_EMSOverrideCoilSpeedNumValue);
8466 35961 : bool useMaxedSpeed = false;
8467 35961 : std::string useMaxedSpeedCoilName;
8468 35961 : if (state.dataUnitarySystems->HeatingLoad) {
8469 0 : if (SpeedNumEMS > this->m_NumOfSpeedHeating) {
8470 0 : SpeedNumEMS = this->m_NumOfSpeedHeating;
8471 0 : useMaxedSpeed = true;
8472 0 : useMaxedSpeedCoilName = this->m_HeatingCoilName;
8473 : }
8474 0 : this->m_HeatingSpeedNum = SpeedNumEMS;
8475 : } else {
8476 35961 : if (SpeedNumEMS > this->m_NumOfSpeedCooling) {
8477 0 : SpeedNumEMS = this->m_NumOfSpeedCooling;
8478 0 : useMaxedSpeed = true;
8479 0 : useMaxedSpeedCoilName = this->m_CoolingCoilName;
8480 : }
8481 35961 : this->m_CoolingSpeedNum = SpeedNumEMS;
8482 : }
8483 35961 : if (useMaxedSpeed) {
8484 0 : this->m_CoilSpeedErrIdx++;
8485 0 : ShowRecurringWarningErrorAtEnd(state,
8486 0 : "Wrong coil speed EMS override value, for unit=\"" + useMaxedSpeedCoilName +
8487 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
8488 0 : this->m_CoilSpeedErrIdx,
8489 0 : this->m_EMSOverrideCoilSpeedNumValue,
8490 0 : this->m_EMSOverrideCoilSpeedNumValue,
8491 : _,
8492 : "",
8493 : "");
8494 : }
8495 :
8496 35961 : if (state.dataUnitarySystems->HeatingLoad) {
8497 0 : CoolPLR = 0.0;
8498 0 : HeatPLR = 1.0;
8499 0 : this->m_HeatingCoilSensDemand = ZoneLoad;
8500 :
8501 0 : if (this->m_HeatingSpeedNum == 1) {
8502 0 : this->m_HeatingSpeedRatio = 0.0;
8503 0 : this->m_HeatingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8504 0 : if (useMaxedSpeed || this->m_HeatingCycRatio == 0) {
8505 0 : this->m_HeatingCycRatio = 1;
8506 : }
8507 : } else {
8508 0 : this->m_HeatingCycRatio = 1.0;
8509 0 : this->m_HeatingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8510 0 : if (useMaxedSpeed || this->m_HeatingSpeedRatio == 0) {
8511 0 : this->m_HeatingSpeedRatio = 1;
8512 : }
8513 : }
8514 : } else { // Cooling or moisture load
8515 35961 : HeatPLR = 0.0;
8516 35961 : CoolPLR = 1.0;
8517 35961 : if (state.dataUnitarySystems->CoolingLoad) {
8518 35961 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8519 : } else {
8520 0 : this->m_CoolingCoilSensDemand = 0.0;
8521 : }
8522 35961 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8523 :
8524 35961 : if (this->m_CoolingSpeedNum == 1) {
8525 17223 : this->m_CoolingSpeedRatio = 0.0;
8526 17223 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8527 17223 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
8528 17223 : this->m_CoolingCycRatio = 1;
8529 : }
8530 : } else {
8531 18738 : this->m_CoolingCycRatio = 1.0;
8532 18738 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8533 18738 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
8534 0 : this->m_CoolingSpeedRatio = 1;
8535 : }
8536 : }
8537 : }
8538 35961 : this->calcUnitarySystemToLoad(state,
8539 : AirLoopNum,
8540 : FirstHVACIteration,
8541 : CoolPLR,
8542 : HeatPLR,
8543 : OnOffAirFlowRatio,
8544 : SensOutput,
8545 : LatOutput,
8546 35961 : HXUnitOn,
8547 : HeatCoilLoad,
8548 : SupHeaterLoad,
8549 : CompressorONFlag);
8550 :
8551 35961 : FullSensibleOutput = SensOutput;
8552 :
8553 35961 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8554 : // no load
8555 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutput) {
8556 0 : return;
8557 : }
8558 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8559 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
8560 0 : return;
8561 : }
8562 : }
8563 35961 : HXUnitOn = true;
8564 35961 : this->calcUnitarySystemToLoad(state,
8565 : AirLoopNum,
8566 : FirstHVACIteration,
8567 : CoolPLR,
8568 : HeatPLR,
8569 : OnOffAirFlowRatio,
8570 : SensOutput,
8571 : LatOutput,
8572 35961 : HXUnitOn,
8573 : HeatCoilLoad,
8574 : SupHeaterLoad,
8575 : CompressorONFlag);
8576 35961 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
8577 : Real64 heatCoildT =
8578 35961 : (this->m_HeatCoilExists)
8579 35961 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
8580 35961 : : 0.0;
8581 : Real64 CoolingOnlySensibleOutput =
8582 35961 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
8583 35961 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
8584 35961 : heatCoildT);
8585 35961 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
8586 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
8587 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
8588 35961 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
8589 : // Heating mode and dehumidification is required
8590 : } else {
8591 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
8592 : // the heating coil pick up the load due to outdoor air.
8593 0 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
8594 : }
8595 35961 : }
8596 :
8597 6122517 : void UnitarySys::controlUnitarySystemOutput(EnergyPlusData &state,
8598 : int const AirLoopNum, // Index to air loop
8599 : bool const FirstHVACIteration, // True when first HVAC iteration
8600 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8601 : Real64 const ZoneLoad,
8602 : Real64 &FullSensibleOutput,
8603 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8604 : HVAC::CompressorOp CompressorOn)
8605 : {
8606 :
8607 : // SUBROUTINE INFORMATION:
8608 : // AUTHOR Richard Raustad, FSEC
8609 : // DATE WRITTEN February 2013
8610 :
8611 : // PURPOSE OF THIS SUBROUTINE:
8612 : // This subroutine determines operating PLR and calculates the load based system output.
8613 :
8614 : // SUBROUTINE PARAMETER DEFINITIONS:
8615 6122517 : int constexpr MaxIter = 100; // maximum number of iterations
8616 :
8617 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8618 : int SpeedNum; // multi-speed coil speed number
8619 : Real64 SensOutputOn; // sensible output at PLR = 1 [W]
8620 : Real64 LatOutputOn; // latent output at PLR = 1 [W]
8621 : Real64 TempLoad; // represents either a sensible or latent load [W]
8622 : Real64 TempSysOutput; // represents either a sensible or latent capacity [W]
8623 : Real64 TempSensOutput; // iterative sensible capacity [W]
8624 : Real64 TempLatOutput; // iterative latent capacity [W]
8625 : Real64 TempMinPLR; // iterative minimum PLR
8626 : Real64 TempMaxPLR; // iterative maximum PLR
8627 : Real64 CpAir; // specific heat of air [J/kg_C]
8628 : Real64 FullLoadAirOutletTemp; // saved full load outlet air temperature [C]
8629 : Real64 FullLoadAirOutletHumRat; // saved full load outlet air humidity ratio [kg/kg]
8630 :
8631 6122517 : std::string CompName = this->Name;
8632 6122517 : int OutletNode = this->AirOutNode;
8633 :
8634 6122517 : if (this->m_sysAvailSched->getCurrentVal() <= 0.0) {
8635 4494 : return;
8636 : }
8637 6118023 : if (this->m_EMSOverrideCoilSpeedNumOn) {
8638 37481 : this->controlUnitarySystemOutputEMS(
8639 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
8640 37481 : return;
8641 : }
8642 :
8643 6080542 : Real64 PartLoadRatio = 0.0; // Get no load result
8644 6080542 : this->m_EconoPartLoadRatio = 0;
8645 : // fan and coil PLR are disconnected when using ASHRAE model, don't confuse these for other models
8646 6080542 : this->FanPartLoadRatio = 0.0;
8647 6080542 : int SolFlag = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8648 6080542 : int SolFlagLat = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8649 6080542 : Real64 SensOutputOff = 0.0;
8650 6080542 : Real64 LatOutputOff = 0.0;
8651 6080542 : Real64 CoolPLR = 0.0;
8652 6080542 : Real64 HeatPLR = 0.0;
8653 6080542 : HVAC::CompressorOp CompressorONFlag = HVAC::CompressorOp::Off;
8654 6080542 : Real64 HeatCoilLoad = 0.0;
8655 6080542 : Real64 SupHeaterLoad = 0.0;
8656 :
8657 6080542 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8658 :
8659 6080542 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) {
8660 1051447 : return;
8661 : }
8662 :
8663 5029095 : this->calcUnitarySystemToLoad(state,
8664 : AirLoopNum,
8665 : FirstHVACIteration,
8666 : CoolPLR,
8667 : HeatPLR,
8668 : OnOffAirFlowRatio,
8669 : SensOutputOff,
8670 : LatOutputOff,
8671 5029095 : HXUnitOn,
8672 : HeatCoilLoad,
8673 : SupHeaterLoad,
8674 : CompressorONFlag);
8675 5029095 : FullSensibleOutput = SensOutputOff;
8676 :
8677 5029095 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8678 : // no load
8679 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutputOff) {
8680 0 : return;
8681 : }
8682 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8683 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
8684 0 : return;
8685 : }
8686 : }
8687 :
8688 : // determine if PLR=0 meets the load
8689 5029095 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8690 48933 : case HVAC::SetptType::SingleHeat: {
8691 48933 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8692 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8693 0 : return;
8694 : }
8695 48933 : if (!state.dataUnitarySystems->HeatingLoad &&
8696 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8697 0 : return;
8698 : }
8699 48933 : } break;
8700 53651 : case HVAC::SetptType::SingleCool: {
8701 53653 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8702 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8703 2 : return;
8704 : }
8705 53649 : if (!state.dataUnitarySystems->CoolingLoad &&
8706 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8707 0 : return;
8708 : }
8709 53649 : } break;
8710 4926511 : case HVAC::SetptType::SingleHeatCool:
8711 : case HVAC::SetptType::DualHeatCool: {
8712 4926552 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8713 41 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8714 41 : return;
8715 : }
8716 4938440 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8717 11970 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8718 9761 : return;
8719 : }
8720 4916709 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8721 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8722 0 : return;
8723 : }
8724 4916709 : } break;
8725 0 : default: {
8726 : // should never get here
8727 0 : } break;
8728 : }
8729 :
8730 5019291 : this->m_EconoSpeedNum = 0;
8731 5019291 : if (this->OAControllerEconomizerStagingType == HVAC::EconomizerStagingType::EconomizerFirst) {
8732 737912 : manageEconomizerStagingOperation(state, AirLoopNum, FirstHVACIteration, ZoneLoad);
8733 : }
8734 :
8735 : // if a variable speed unit, the SensOutputOff at SpeedNum=1 must be checked to see if it exceeds the ZoneLoad
8736 : // This is still no load but at the first speed above idle
8737 9728533 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating > 0) ||
8738 4709242 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling > 0)) {
8739 1908533 : if (this->m_Staged) {
8740 0 : if (state.dataUnitarySystems->HeatingLoad) {
8741 0 : this->m_HeatingSpeedNum = this->m_StageNum;
8742 : } else {
8743 0 : this->m_CoolingSpeedNum = std::abs(this->m_StageNum);
8744 : }
8745 : } else {
8746 1908533 : if (state.dataUnitarySystems->HeatingLoad) {
8747 310049 : this->m_HeatingSpeedNum = 1;
8748 : } else {
8749 1598484 : this->m_CoolingSpeedNum = 1;
8750 : }
8751 : }
8752 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8753 1908533 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8754 1908533 : this->calcUnitarySystemToLoad(state,
8755 : AirLoopNum,
8756 : FirstHVACIteration,
8757 : CoolPLR,
8758 : HeatPLR,
8759 : OnOffAirFlowRatio,
8760 : SensOutputOff,
8761 : LatOutputOff,
8762 1908533 : HXUnitOn,
8763 : HeatCoilLoad,
8764 : SupHeaterLoad,
8765 : CompressorONFlag);
8766 1908533 : FullSensibleOutput = SensOutputOff;
8767 :
8768 1908533 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8769 4496 : case HVAC::SetptType::SingleHeat: {
8770 4496 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8771 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8772 0 : return;
8773 : }
8774 4496 : if (!state.dataUnitarySystems->HeatingLoad &&
8775 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8776 0 : return;
8777 : }
8778 4496 : } break;
8779 39789 : case HVAC::SetptType::SingleCool: {
8780 39789 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8781 0 : this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
8782 0 : return;
8783 : }
8784 39789 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8785 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8786 0 : return;
8787 : }
8788 39789 : if (!state.dataUnitarySystems->CoolingLoad &&
8789 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8790 0 : return;
8791 : }
8792 39789 : } break;
8793 1864248 : case HVAC::SetptType::SingleHeatCool:
8794 : case HVAC::SetptType::DualHeatCool: {
8795 1870384 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8796 6136 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8797 6136 : return;
8798 : }
8799 2028477 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8800 170365 : this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
8801 169016 : return;
8802 : }
8803 1690445 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8804 1349 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8805 12 : return;
8806 : }
8807 1689084 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8808 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8809 0 : return;
8810 : }
8811 1689084 : } break;
8812 0 : default: {
8813 : // should never get here
8814 0 : } break;
8815 : }
8816 : }
8817 :
8818 4844127 : CompressorONFlag = CompressorOn;
8819 4844127 : PartLoadRatio = 1.0;
8820 4844127 : this->FanPartLoadRatio = 1.0;
8821 : // Get full load result for non-multistage economizer operations
8822 4844127 : if (this->m_EconoSpeedNum == 0) {
8823 4831917 : if (state.dataUnitarySystems->HeatingLoad) {
8824 2338813 : CoolPLR = 0.0;
8825 2338813 : HeatPLR = 1.0;
8826 2338813 : this->m_HeatingCoilSensDemand = ZoneLoad;
8827 2338813 : if (this->m_NumOfSpeedHeating > 0) {
8828 303913 : this->m_HeatingSpeedRatio = 1.0;
8829 303913 : this->m_HeatingCycRatio = 1.0;
8830 303913 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
8831 : }
8832 2338813 : if (this->m_Staged && this->m_StageNum > 0) {
8833 0 : if (this->m_NumOfSpeedHeating > 0) {
8834 0 : this->m_HeatingSpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8835 0 : this->m_HeatingSpeedRatio = 0.0;
8836 : }
8837 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8838 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8839 0 : this->calcUnitarySystemToLoad(state,
8840 : AirLoopNum,
8841 : FirstHVACIteration,
8842 : CoolPLR,
8843 : HeatPLR,
8844 : OnOffAirFlowRatio,
8845 : SensOutputOff,
8846 : LatOutputOff,
8847 0 : HXUnitOn,
8848 : HeatCoilLoad,
8849 : SupHeaterLoad,
8850 : CompressorONFlag);
8851 0 : if (SensOutputOff > ZoneLoad) {
8852 0 : return;
8853 : }
8854 0 : if (this->m_NumOfSpeedHeating > 0) {
8855 0 : this->m_HeatingSpeedRatio = 1.0;
8856 : }
8857 : }
8858 2493104 : } else if (state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < LatOutputOff) {
8859 2493104 : CoolPLR = 1.0;
8860 2493104 : HeatPLR = 0.0;
8861 2493104 : if (state.dataUnitarySystems->CoolingLoad) {
8862 2493104 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8863 : } else {
8864 0 : this->m_CoolingCoilSensDemand = 0.0;
8865 : }
8866 2493104 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8867 2493104 : if (this->m_NumOfSpeedCooling > 0) {
8868 1417246 : this->m_CoolingSpeedRatio = 1.0;
8869 1417246 : this->m_CoolingCycRatio = 1.0;
8870 1417246 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
8871 : }
8872 2493104 : if (this->m_Staged && this->m_StageNum < 0) {
8873 0 : if (this->m_NumOfSpeedCooling > 0) {
8874 0 : this->m_CoolingSpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8875 : }
8876 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8877 0 : this->m_CoolingSpeedRatio = 0.0;
8878 0 : this->calcUnitarySystemToLoad(state,
8879 : AirLoopNum,
8880 : FirstHVACIteration,
8881 : CoolPLR,
8882 : HeatPLR,
8883 : OnOffAirFlowRatio,
8884 : SensOutputOff,
8885 : LatOutputOff,
8886 0 : HXUnitOn,
8887 : HeatCoilLoad,
8888 : SupHeaterLoad,
8889 : CompressorONFlag);
8890 0 : if (SensOutputOff < ZoneLoad) {
8891 0 : return;
8892 : }
8893 0 : if (this->m_NumOfSpeedCooling > 0) {
8894 0 : this->m_CoolingSpeedRatio = 1.0;
8895 : }
8896 : }
8897 : } else {
8898 : // will return here when no cooling or heating load and MoistureLoad > LatOutputOff (i.e., PLR=0)
8899 0 : return;
8900 : }
8901 :
8902 4831917 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8903 :
8904 4831917 : this->calcUnitarySystemToLoad(state,
8905 : AirLoopNum,
8906 : FirstHVACIteration,
8907 : CoolPLR,
8908 : HeatPLR,
8909 : OnOffAirFlowRatio,
8910 : SensOutputOn,
8911 : LatOutputOn,
8912 4831917 : HXUnitOn,
8913 : HeatCoilLoad,
8914 : SupHeaterLoad,
8915 : CompressorONFlag);
8916 4831917 : FullSensibleOutput = SensOutputOn;
8917 4831917 : FullLoadAirOutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
8918 4831917 : FullLoadAirOutletHumRat = state.dataLoopNodes->Node(OutletNode).HumRat;
8919 :
8920 : // turn on HX if dehumidm_ControlType::Multimode
8921 69394 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < 0.0 &&
8922 4901311 : state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
8923 20914 : HXUnitOn = true;
8924 20914 : this->calcUnitarySystemToLoad(state,
8925 : AirLoopNum,
8926 : FirstHVACIteration,
8927 : CoolPLR,
8928 : HeatPLR,
8929 : OnOffAirFlowRatio,
8930 : SensOutputOn,
8931 : LatOutputOn,
8932 20914 : HXUnitOn,
8933 : HeatCoilLoad,
8934 : SupHeaterLoad,
8935 : CompressorONFlag);
8936 20914 : FullSensibleOutput = SensOutputOn;
8937 : }
8938 :
8939 : // test to see if full capacity is less than load, if so set to PLR=1 and RETURN if no moisture load
8940 7429672 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating <= 1) ||
8941 2597755 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling <= 1)) {
8942 3959569 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8943 44437 : case HVAC::SetptType::SingleHeat: {
8944 44437 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8945 8088 : this->m_HeatingPartLoadFrac = 1.0;
8946 8088 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
8947 8088 : return;
8948 : }
8949 : }
8950 36349 : if (!state.dataUnitarySystems->HeatingLoad &&
8951 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8952 0 : return;
8953 : }
8954 36349 : } break;
8955 42145 : case HVAC::SetptType::SingleCool: {
8956 42145 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8957 4953 : this->m_CoolingPartLoadFrac = 1.0;
8958 4953 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
8959 4953 : return;
8960 : }
8961 : }
8962 37192 : if (!state.dataUnitarySystems->CoolingLoad &&
8963 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8964 0 : return;
8965 : }
8966 37192 : } break;
8967 3872987 : case HVAC::SetptType::SingleHeatCool:
8968 : case HVAC::SetptType::DualHeatCool: {
8969 3872987 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8970 370517 : this->m_HeatingPartLoadFrac = 1.0;
8971 370517 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOn) {
8972 370517 : return;
8973 : }
8974 : }
8975 3502470 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8976 30925 : this->m_CoolingPartLoadFrac = 1.0;
8977 30925 : return;
8978 : }
8979 3471545 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8980 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8981 0 : return;
8982 : }
8983 3471545 : } break;
8984 0 : default: {
8985 : // no other choices for thermostat control
8986 0 : } break;
8987 : }
8988 : }
8989 : } else {
8990 : // define the sensible load to meet for operation with multi-stage economizer
8991 12210 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8992 : }
8993 : // will find speed for multispeed coils here and then RegulaFalsi on PLR at a fixed speed
8994 :
8995 : // Do the non-variable or non-multispeed coils have a NumOfSpeed = 0 ? We don't need to do this for single speed coils.
8996 : // Check to see which speed to meet the load
8997 4429644 : this->m_HeatingSpeedNum = 0;
8998 4429644 : this->m_CoolingSpeedNum = 0;
8999 4429644 : if (!this->m_Staged) {
9000 4429644 : if (state.dataUnitarySystems->HeatingLoad) {
9001 2213188 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
9002 317880 : CoolPLR = 0.0;
9003 317880 : HeatPLR = 1.0;
9004 317880 : if (SpeedNum == 1) {
9005 145361 : this->m_HeatingSpeedRatio = 0.0;
9006 : } else {
9007 172519 : this->m_HeatingSpeedRatio = 1.0;
9008 : }
9009 317880 : this->m_HeatingCycRatio = 1.0;
9010 317880 : this->m_HeatingSpeedNum = SpeedNum;
9011 317880 : this->calcUnitarySystemToLoad(state,
9012 : AirLoopNum,
9013 : FirstHVACIteration,
9014 : CoolPLR,
9015 : HeatPLR,
9016 : OnOffAirFlowRatio,
9017 : SensOutputOn,
9018 : LatOutputOn,
9019 317880 : HXUnitOn,
9020 : HeatCoilLoad,
9021 : SupHeaterLoad,
9022 : CompressorONFlag);
9023 317880 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9024 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9025 : }
9026 317880 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
9027 268032 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater && !this->m_MultiSpeedHeatingCoil)) {
9028 0 : this->m_HeatingSpeedRatio = 0.0;
9029 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
9030 0 : if (this->m_HeatingSpeedNum == 0) {
9031 0 : this->m_HeatingCycRatio = 0.0;
9032 0 : HeatPLR = 0.0;
9033 : } else {
9034 0 : this->m_HeatingCycRatio = 1.0;
9035 0 : HeatPLR = 1.0;
9036 : }
9037 0 : this->calcUnitarySystemToLoad(state,
9038 : AirLoopNum,
9039 : FirstHVACIteration,
9040 : CoolPLR,
9041 : HeatPLR,
9042 : OnOffAirFlowRatio,
9043 : SensOutputOff,
9044 : LatOutputOff,
9045 0 : HXUnitOn,
9046 : HeatCoilLoad,
9047 : SupHeaterLoad,
9048 : CompressorONFlag);
9049 0 : this->m_HeatingSpeedNum = SpeedNum;
9050 : }
9051 317880 : if (ZoneLoad <= SensOutputOn) {
9052 64900 : break;
9053 : }
9054 : }
9055 : } else { // Cooling or moisture load
9056 3275947 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9057 2182747 : CoolPLR = 1.0;
9058 2182747 : HeatPLR = 0.0;
9059 2182747 : if (SpeedNum == 1) {
9060 1409414 : this->m_CoolingSpeedRatio = 0.0;
9061 : } else {
9062 773333 : this->m_CoolingSpeedRatio = 1.0;
9063 : }
9064 2182747 : this->m_CoolingCycRatio = 1.0;
9065 2182747 : this->m_CoolingSpeedNum = SpeedNum;
9066 2182747 : this->calcUnitarySystemToLoad(state,
9067 : AirLoopNum,
9068 : FirstHVACIteration,
9069 : CoolPLR,
9070 : HeatPLR,
9071 : OnOffAirFlowRatio,
9072 : SensOutputOn,
9073 : LatOutputOn,
9074 2182747 : HXUnitOn,
9075 : HeatCoilLoad,
9076 : SupHeaterLoad,
9077 : CompressorONFlag);
9078 2182747 : if (state.dataGlobal->DoCoilDirectSolutions &&
9079 0 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
9080 0 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1))) {
9081 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9082 : }
9083 : // over specified logic? it has to be a water coil? what about other VS coil models?
9084 2182747 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9085 2170251 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9086 10198 : !this->m_DiscreteSpeedCoolingCoil)) {
9087 0 : this->m_CoolingSpeedRatio = 0.0;
9088 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9089 0 : if (this->m_CoolingSpeedNum == 0) {
9090 0 : this->m_CoolingCycRatio = 0.0;
9091 0 : CoolPLR = 0.0;
9092 : } else {
9093 0 : this->m_CoolingCycRatio = 1.0;
9094 0 : this->m_CoolingSpeedRatio = 0.0;
9095 0 : if (this->m_SingleMode == 1) {
9096 0 : CoolPLR = 1.0;
9097 : }
9098 : }
9099 :
9100 0 : this->calcUnitarySystemToLoad(state,
9101 : AirLoopNum,
9102 : FirstHVACIteration,
9103 : CoolPLR,
9104 : HeatPLR,
9105 : OnOffAirFlowRatio,
9106 : SensOutputOff,
9107 : LatOutputOff,
9108 0 : HXUnitOn,
9109 : HeatCoilLoad,
9110 : SupHeaterLoad,
9111 : CompressorONFlag);
9112 0 : this->m_CoolingSpeedNum = SpeedNum;
9113 : }
9114 2182747 : if (ZoneLoad >= SensOutputOn) {
9115 1376236 : break;
9116 : }
9117 : }
9118 : }
9119 : } else { // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
9120 : // Staged control
9121 0 : if (state.dataUnitarySystems->HeatingLoad) {
9122 0 : CoolPLR = 0.0;
9123 0 : HeatPLR = 1.0;
9124 0 : SpeedNum = this->m_StageNum;
9125 0 : if (SpeedNum == 1) {
9126 0 : this->m_HeatingSpeedRatio = 0.0;
9127 : } else {
9128 0 : this->m_HeatingSpeedRatio = 1.0;
9129 0 : SpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
9130 : }
9131 0 : this->m_HeatingCycRatio = 1.0;
9132 0 : this->m_HeatingSpeedNum = SpeedNum;
9133 0 : this->calcUnitarySystemToLoad(state,
9134 : AirLoopNum,
9135 : FirstHVACIteration,
9136 : CoolPLR,
9137 : HeatPLR,
9138 : OnOffAirFlowRatio,
9139 : SensOutputOn,
9140 : LatOutputOn,
9141 0 : HXUnitOn,
9142 : HeatCoilLoad,
9143 : SupHeaterLoad,
9144 : CompressorONFlag);
9145 0 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
9146 0 : this->m_HeatingSpeedRatio = 0.0;
9147 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
9148 0 : if (this->m_HeatingSpeedNum == 0) {
9149 0 : this->m_HeatingCycRatio = 0.0;
9150 0 : HeatPLR = 0.0;
9151 : } else {
9152 0 : this->m_HeatingCycRatio = 1.0;
9153 0 : HeatPLR = 1.0;
9154 : }
9155 0 : this->calcUnitarySystemToLoad(state,
9156 : AirLoopNum,
9157 : FirstHVACIteration,
9158 : CoolPLR,
9159 : HeatPLR,
9160 : OnOffAirFlowRatio,
9161 : SensOutputOff,
9162 : LatOutputOff,
9163 0 : HXUnitOn,
9164 : HeatCoilLoad,
9165 : SupHeaterLoad,
9166 : CompressorONFlag);
9167 0 : this->m_HeatingSpeedNum = SpeedNum;
9168 : }
9169 0 : if (ZoneLoad <= SensOutputOn) {
9170 : // EXIT ????????????
9171 : }
9172 : } else { // Cooling or moisture load
9173 0 : CoolPLR = 1.0;
9174 0 : HeatPLR = 0.0;
9175 0 : SpeedNum = std::abs(this->m_StageNum);
9176 0 : if (SpeedNum == 1) {
9177 0 : this->m_CoolingSpeedRatio = 0.0;
9178 : } else {
9179 0 : this->m_CoolingSpeedRatio = 1.0;
9180 0 : SpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
9181 : }
9182 0 : this->m_CoolingCycRatio = 1.0;
9183 0 : this->m_CoolingSpeedNum = SpeedNum;
9184 0 : this->calcUnitarySystemToLoad(state,
9185 : AirLoopNum,
9186 : FirstHVACIteration,
9187 : CoolPLR,
9188 : HeatPLR,
9189 : OnOffAirFlowRatio,
9190 : SensOutputOn,
9191 : LatOutputOn,
9192 0 : HXUnitOn,
9193 : HeatCoilLoad,
9194 : SupHeaterLoad,
9195 : CompressorONFlag);
9196 :
9197 0 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
9198 0 : this->m_CoolingSpeedRatio = 0.0;
9199 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9200 0 : if (this->m_CoolingSpeedNum == 0) {
9201 0 : this->m_CoolingCycRatio = 0.0;
9202 0 : CoolPLR = 0.0;
9203 : } else {
9204 0 : this->m_CoolingCycRatio = 1.0;
9205 0 : CoolPLR = 1.0;
9206 : }
9207 0 : this->calcUnitarySystemToLoad(state,
9208 : AirLoopNum,
9209 : FirstHVACIteration,
9210 : CoolPLR,
9211 : HeatPLR,
9212 : OnOffAirFlowRatio,
9213 : SensOutputOff,
9214 : LatOutputOff,
9215 0 : HXUnitOn,
9216 : HeatCoilLoad,
9217 : SupHeaterLoad,
9218 : CompressorONFlag);
9219 0 : this->m_CoolingSpeedNum = SpeedNum;
9220 : }
9221 0 : if (ZoneLoad >= SensOutputOn) {
9222 : // EXIT ???????????
9223 : }
9224 : }
9225 : } // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
9226 :
9227 4429644 : FullSensibleOutput = SensOutputOn;
9228 :
9229 4429644 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
9230 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
9231 : // if no load, or only a moisture load which can't be met at PLR=1, RETURN
9232 0 : return;
9233 : }
9234 :
9235 : // use the ASHRAE 90.1 method of reduced fan speed at low loads
9236 4429644 : if (this->m_SimASHRAEModel) {
9237 :
9238 : // check to make sure unit has the capacity to meet the load
9239 0 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
9240 0 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
9241 0 : UnitarySys &SZVAVModel(state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum]);
9242 0 : SZVAVModel::calcSZVAVModel(state,
9243 : SZVAVModel,
9244 : this->m_UnitarySysNum,
9245 : FirstHVACIteration,
9246 0 : state.dataUnitarySystems->CoolingLoad,
9247 0 : state.dataUnitarySystems->HeatingLoad,
9248 : ZoneLoad,
9249 : OnOffAirFlowRatio,
9250 0 : HXUnitOn,
9251 : AirLoopNum,
9252 : PartLoadRatio,
9253 : CompressorONFlag);
9254 : }
9255 :
9256 : } else { // not ASHRAE model
9257 :
9258 : // must test to see if load is bounded by capacity before calling RegulaFalsi
9259 6979541 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
9260 2549897 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
9261 6752263 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad > SensOutputOff) ||
9262 2436258 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad < SensOutputOff)) {
9263 : Real64 SensOutput;
9264 : Real64 LatOutput;
9265 5191641 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
9266 876973 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
9267 7754 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR > 0.0) {
9268 1164 : int CoilInletNode = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapInletNodeIndex;
9269 1164 : this->CoilSHR = 0.0;
9270 : Real64 LowSpeedCoilSen;
9271 : Real64 LowSpeedCoilLat;
9272 1164 : CoolPLR = 0.0;
9273 1164 : HeatPLR = 0.0;
9274 1164 : this->m_CoolingSpeedNum = 1;
9275 1164 : this->calcUnitarySystemToLoad(state,
9276 : AirLoopNum,
9277 : FirstHVACIteration,
9278 : CoolPLR,
9279 : HeatPLR,
9280 : OnOffAirFlowRatio,
9281 : SensOutputOff,
9282 : LatOutputOff,
9283 1164 : HXUnitOn,
9284 : HeatCoilLoad,
9285 : SupHeaterLoad,
9286 : CompressorONFlag);
9287 1164 : CoolPLR = 1.0;
9288 1164 : HeatPLR = 0.0;
9289 1164 : this->m_CoolingCycRatio = 1.0;
9290 1164 : this->m_CoolingSpeedRatio = 0.0;
9291 : // this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9292 1164 : this->calcUnitarySystemToLoad(state,
9293 : AirLoopNum,
9294 : FirstHVACIteration,
9295 : CoolPLR,
9296 : HeatPLR,
9297 : OnOffAirFlowRatio,
9298 : SensOutputOn,
9299 : LatOutputOn,
9300 1164 : HXUnitOn,
9301 : HeatCoilLoad,
9302 : SupHeaterLoad,
9303 : CompressorONFlag);
9304 1164 : Real64 ZoneLatLoad = ZoneLoad * (1.0 / this->LoadSHR - 1.0);
9305 1164 : Real64 SenPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9306 1164 : Real64 LatPLR = (ZoneLatLoad - LatOutputOff) / (LatOutputOn - LatOutputOff);
9307 1164 : Real64 totalRate = 0.0;
9308 1164 : Real64 sensRate = 0.0;
9309 1164 : Real64 latRate = 0.0;
9310 1164 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9311 1164 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9312 1164 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9313 1164 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9314 1164 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9315 : sensRate,
9316 : latRate,
9317 : totalRate);
9318 1164 : if (LatPLR > 1.0 || LatPLR < 0.0) {
9319 0 : this->CoilSHR = this->LoadSHR;
9320 : } else {
9321 1164 : Real64 coilSens = sensRate * SenPLR;
9322 1164 : Real64 coilLat = latRate * LatPLR;
9323 1164 : this->CoilSHR = coilSens / (coilSens + coilLat);
9324 : }
9325 1164 : if (this->m_NumOfSpeedCooling > 1) {
9326 0 : this->SpeedSHR[1] = this->CoilSHR;
9327 0 : LowSpeedCoilSen = sensRate;
9328 0 : LowSpeedCoilLat = latRate;
9329 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9330 0 : this->SpeedSHR[SpeedNum] = this->LoadSHR;
9331 : }
9332 : }
9333 1164 : if (this->CoilSHR < 0.0) {
9334 0 : this->CoilSHR = this->LoadSHR;
9335 : }
9336 1164 : if (this->m_NumOfSpeedCooling > 1 && ZoneLoad < SensOutputOn) {
9337 : Real64 SenSPR;
9338 : Real64 LatSPR;
9339 0 : this->FullOutput[1] = SensOutputOn;
9340 0 : this->FullLatOutput[1] = LatOutputOn;
9341 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9342 0 : this->CoilSHR = 0.0;
9343 0 : CoolPLR = 1.0;
9344 0 : HeatPLR = 0.0;
9345 0 : this->m_CoolingSpeedRatio = 1.0;
9346 0 : this->m_CoolingCycRatio = 1.0;
9347 0 : this->m_CoolingSpeedNum = SpeedNum;
9348 0 : this->calcUnitarySystemToLoad(state,
9349 : AirLoopNum,
9350 : FirstHVACIteration,
9351 : CoolPLR,
9352 : HeatPLR,
9353 : OnOffAirFlowRatio,
9354 0 : this->FullOutput[SpeedNum],
9355 0 : this->FullLatOutput[SpeedNum],
9356 0 : HXUnitOn,
9357 : HeatCoilLoad,
9358 : SupHeaterLoad,
9359 : CompressorONFlag);
9360 0 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9361 0 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9362 0 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9363 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9364 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9365 : sensRate,
9366 : latRate,
9367 : totalRate);
9368 0 : SenSPR =
9369 0 : (ZoneLoad - this->FullOutput[SpeedNum - 1]) / (this->FullOutput[SpeedNum] - this->FullOutput[SpeedNum - 1]);
9370 0 : LatSPR = (ZoneLatLoad - this->FullLatOutput[SpeedNum - 1]) /
9371 0 : (this->FullLatOutput[SpeedNum] - this->FullLatOutput[SpeedNum - 1]);
9372 0 : if (LatSPR > 1.0 || LatSPR < 0.0) {
9373 0 : this->CoilSHR = this->LoadSHR;
9374 : } else {
9375 0 : Real64 coilSens = sensRate * SenSPR + (1.0 - SenSPR) * LowSpeedCoilSen;
9376 0 : Real64 coilLat = latRate * LatSPR + (1.0 - LatSPR) * LowSpeedCoilLat;
9377 0 : this->CoilSHR = coilSens / (coilSens + coilLat);
9378 : }
9379 0 : this->SpeedSHR[SpeedNum] = this->CoilSHR;
9380 0 : LowSpeedCoilSen = sensRate;
9381 0 : LowSpeedCoilLat = latRate;
9382 : }
9383 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9384 0 : CoolPLR = 1.0;
9385 0 : HeatPLR = 0.0;
9386 0 : if (SpeedNum == 1) {
9387 0 : this->m_CoolingSpeedRatio = 0.0;
9388 : } else {
9389 0 : this->m_CoolingSpeedRatio = 1.0;
9390 : }
9391 0 : this->m_CoolingCycRatio = 1.0;
9392 0 : this->m_CoolingSpeedNum = SpeedNum;
9393 0 : this->calcUnitarySystemToLoad(state,
9394 : AirLoopNum,
9395 : FirstHVACIteration,
9396 : CoolPLR,
9397 : HeatPLR,
9398 : OnOffAirFlowRatio,
9399 : SensOutputOn,
9400 : LatOutputOn,
9401 0 : HXUnitOn,
9402 : HeatCoilLoad,
9403 : SupHeaterLoad,
9404 : CompressorONFlag);
9405 0 : if (ZoneLoad >= SensOutputOn) {
9406 0 : this->CoilSHR = this->SpeedSHR[SpeedNum];
9407 0 : break;
9408 : }
9409 : }
9410 : }
9411 : }
9412 : }
9413 4314668 : if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9414 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
9415 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9416 0 : HeatPLR = 0.0;
9417 0 : this->calcUnitarySystemToLoad(state,
9418 : AirLoopNum,
9419 : FirstHVACIteration,
9420 : CoolPLR,
9421 : HeatPLR,
9422 : OnOffAirFlowRatio,
9423 : SensOutput,
9424 : LatOutput,
9425 0 : HXUnitOn,
9426 : HeatCoilLoad,
9427 : SupHeaterLoad,
9428 : CompressorONFlag);
9429 0 : PartLoadRatio = CoolPLR;
9430 4314668 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9431 4314668 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1 &&
9432 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
9433 0 : HeatPLR = 0.0;
9434 0 : this->calcUnitarySystemToLoad(state,
9435 : AirLoopNum,
9436 : FirstHVACIteration,
9437 : 1.0,
9438 : HeatPLR,
9439 : OnOffAirFlowRatio,
9440 : SensOutputOn,
9441 : LatOutputOn,
9442 0 : HXUnitOn,
9443 : HeatCoilLoad,
9444 : SupHeaterLoad,
9445 : CompressorONFlag);
9446 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9447 0 : this->calcUnitarySystemToLoad(state,
9448 : AirLoopNum,
9449 : FirstHVACIteration,
9450 : CoolPLR,
9451 : HeatPLR,
9452 : OnOffAirFlowRatio,
9453 : SensOutput,
9454 : LatOutput,
9455 0 : HXUnitOn,
9456 : HeatCoilLoad,
9457 : SupHeaterLoad,
9458 : CompressorONFlag);
9459 0 : PartLoadRatio = CoolPLR;
9460 4314668 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9461 4314668 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1) {
9462 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9463 0 : HeatPLR = 0.0;
9464 0 : this->calcUnitarySystemToLoad(state,
9465 : AirLoopNum,
9466 : FirstHVACIteration,
9467 : CoolPLR,
9468 : HeatPLR,
9469 : OnOffAirFlowRatio,
9470 : SensOutput,
9471 : LatOutput,
9472 0 : HXUnitOn,
9473 : HeatCoilLoad,
9474 : SupHeaterLoad,
9475 : CompressorONFlag);
9476 0 : PartLoadRatio = CoolPLR;
9477 4314668 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9478 0 : (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
9479 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
9480 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel)) {
9481 0 : CoolPLR = 0.0;
9482 0 : HeatPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9483 0 : this->calcUnitarySystemToLoad(state,
9484 : AirLoopNum,
9485 : FirstHVACIteration,
9486 : CoolPLR,
9487 : HeatPLR,
9488 : OnOffAirFlowRatio,
9489 : SensOutput,
9490 : LatOutput,
9491 0 : HXUnitOn,
9492 : HeatCoilLoad,
9493 : SupHeaterLoad,
9494 : CompressorONFlag);
9495 0 : PartLoadRatio = HeatPLR;
9496 4314668 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9497 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9498 0 : CoolPLR = 0.0;
9499 0 : if (this->m_HeatingSpeedNum == 1) {
9500 0 : this->m_HeatingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_HeatingSpeedNum] - SensOutputOff);
9501 0 : HeatPLR = this->m_HeatingCycRatio;
9502 0 : this->m_HeatingSpeedRatio = 0.0;
9503 : } else {
9504 0 : this->m_HeatingCycRatio = 1.0;
9505 0 : this->m_HeatingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_HeatingSpeedNum - 1]) /
9506 0 : (this->FullOutput[this->m_HeatingSpeedNum] - this->FullOutput[this->m_HeatingSpeedNum - 1]);
9507 0 : HeatPLR = this->m_HeatingSpeedRatio;
9508 : }
9509 0 : this->calcUnitarySystemToLoad(state,
9510 : AirLoopNum,
9511 : FirstHVACIteration,
9512 : CoolPLR,
9513 : HeatPLR,
9514 : OnOffAirFlowRatio,
9515 : SensOutput,
9516 : LatOutput,
9517 0 : HXUnitOn,
9518 : HeatCoilLoad,
9519 : SupHeaterLoad,
9520 : CompressorONFlag);
9521 0 : PartLoadRatio = HeatPLR;
9522 4314668 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9523 4314668 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1) {
9524 0 : HeatPLR = 0.0;
9525 0 : if (this->m_CoolingSpeedNum == 1) {
9526 0 : this->m_CoolingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_CoolingSpeedNum] - SensOutputOff);
9527 0 : CoolPLR = this->m_CoolingCycRatio;
9528 0 : this->m_CoolingSpeedRatio = 0.0;
9529 : } else {
9530 0 : this->m_CoolingCycRatio = 1.0;
9531 0 : this->m_CoolingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_CoolingSpeedNum - 1]) /
9532 0 : (this->FullOutput[this->m_CoolingSpeedNum] - this->FullOutput[this->m_CoolingSpeedNum - 1]);
9533 0 : CoolPLR = this->m_CoolingSpeedRatio;
9534 : }
9535 0 : this->calcUnitarySystemToLoad(state,
9536 : AirLoopNum,
9537 : FirstHVACIteration,
9538 : CoolPLR,
9539 : HeatPLR,
9540 : OnOffAirFlowRatio,
9541 : SensOutput,
9542 : LatOutput,
9543 0 : HXUnitOn,
9544 : HeatCoilLoad,
9545 : SupHeaterLoad,
9546 : CompressorONFlag);
9547 0 : PartLoadRatio = CoolPLR;
9548 : } else {
9549 :
9550 4314668 : Real64 par6 = state.dataUnitarySystems->CoolingLoad ? 1.0 : 0.0;
9551 19445309 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9552 : Real64 const PartLoadRatio) {
9553 30261282 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9554 : PartLoadRatio,
9555 15130641 : this->m_UnitarySysNum,
9556 : FirstHVACIteration,
9557 : // par 3 not used?
9558 : CompressorONFlag,
9559 : ZoneLoad,
9560 : par6,
9561 : 1.0,
9562 : OnOffAirFlowRatio,
9563 : HXUnitOn,
9564 : // par 10 not used
9565 15130641 : AirLoopNum);
9566 4314668 : };
9567 : // Tolerance is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9568 4314668 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
9569 :
9570 4314668 : if (SolFlag == -1) {
9571 345 : if (state.dataUnitarySystems->HeatingLoad) {
9572 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9573 : // This does cause a problem when coil cannot turn on when OAT < min allowed or scheduled off
9574 : // If max iteration limit is exceeded, how do we know if the heating coil is operating?
9575 0 : TempMaxPLR = -0.1;
9576 0 : TempSensOutput = SensOutputOff;
9577 0 : while ((TempSensOutput - ZoneLoad) < 0.0 && TempMaxPLR < 1.0) {
9578 : // find upper limit of HeatingPLR
9579 0 : TempMaxPLR += 0.1;
9580 :
9581 : // SUBROUTINE SetSpeedVariables(UnitarySysNum, SensibleLoad, PartLoadRatio)
9582 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9583 0 : this->calcUnitarySystemToLoad(state,
9584 : AirLoopNum,
9585 : FirstHVACIteration,
9586 : CoolPLR,
9587 : TempMaxPLR,
9588 : OnOffAirFlowRatio,
9589 : TempSensOutput,
9590 : TempLatOutput,
9591 0 : HXUnitOn,
9592 : HeatCoilLoad,
9593 : SupHeaterLoad,
9594 : CompressorONFlag);
9595 : }
9596 0 : TempMinPLR = TempMaxPLR;
9597 0 : while ((TempSensOutput - ZoneLoad) > 0.0 && TempMinPLR > 0.0) {
9598 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9599 0 : TempMaxPLR = TempMinPLR;
9600 : // find minimum limit of HeatingPLR
9601 0 : TempMinPLR -= 0.01;
9602 0 : this->setSpeedVariables(state, true, TempMinPLR);
9603 0 : this->calcUnitarySystemToLoad(state,
9604 : AirLoopNum,
9605 : FirstHVACIteration,
9606 : CoolPLR,
9607 : TempMinPLR,
9608 : OnOffAirFlowRatio,
9609 : TempSensOutput,
9610 : TempLatOutput,
9611 0 : HXUnitOn,
9612 : HeatCoilLoad,
9613 : SupHeaterLoad,
9614 : CompressorONFlag);
9615 : }
9616 : // Now solve again with tighter PLR limits
9617 : auto f2 = // (AUTO_OK_LAMBDA)
9618 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9619 : Real64 const PartLoadRatio) {
9620 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9621 : PartLoadRatio,
9622 0 : this->m_UnitarySysNum,
9623 : FirstHVACIteration,
9624 : // par 3 not used?
9625 : CompressorONFlag,
9626 : ZoneLoad,
9627 : par6,
9628 : 1.0,
9629 : OnOffAirFlowRatio,
9630 : HXUnitOn,
9631 : // par 10 not used
9632 0 : AirLoopNum);
9633 0 : };
9634 0 : General::SolveRoot(state, this->m_HeatConvTol, MaxIter, SolFlag, HeatPLR, f2, TempMinPLR, TempMaxPLR);
9635 0 : this->calcUnitarySystemToLoad(state,
9636 : AirLoopNum,
9637 : FirstHVACIteration,
9638 : CoolPLR,
9639 : HeatPLR,
9640 : OnOffAirFlowRatio,
9641 : TempSensOutput,
9642 : TempLatOutput,
9643 0 : HXUnitOn,
9644 : HeatCoilLoad,
9645 : SupHeaterLoad,
9646 : CompressorONFlag);
9647 345 : } else if (state.dataUnitarySystems->CoolingLoad) {
9648 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9649 : // IF iteration limit is exceeded (SolFlag = -1), find tighter boundary of solution and repeat RegulaFalsi
9650 345 : TempMaxPLR = -0.1;
9651 345 : TempSysOutput = SensOutputOff;
9652 345 : TempLoad = ZoneLoad;
9653 1578 : while ((TempSysOutput - TempLoad) > 0.0 &&
9654 : TempMaxPLR < 0.95) { // avoid PLR > 1 by limiting TempMaxPLR to 1 (i.e., TempMaxPLR += 0.1)
9655 : // find upper limit of HeatingPLR
9656 1233 : TempMaxPLR += 0.1;
9657 1233 : if (TempMaxPLR > 0.95 && TempMaxPLR < 1.05) {
9658 0 : TempMaxPLR = 1.0; // enforce a perfect 1.0 at the top end
9659 : }
9660 1233 : this->setSpeedVariables(state, true, TempMaxPLR);
9661 1233 : this->calcUnitarySystemToLoad(state,
9662 : AirLoopNum,
9663 : FirstHVACIteration,
9664 : TempMaxPLR,
9665 : HeatPLR,
9666 : OnOffAirFlowRatio,
9667 : TempSensOutput,
9668 : TempLatOutput,
9669 1233 : HXUnitOn,
9670 : HeatCoilLoad,
9671 : SupHeaterLoad,
9672 : CompressorONFlag);
9673 1233 : TempSysOutput = TempSensOutput;
9674 : }
9675 345 : TempMinPLR = TempMaxPLR;
9676 2702 : while ((TempSysOutput - TempLoad) < 0.0 &&
9677 : TempMinPLR > 0.025) { // lower limit might be changed to 0.005 without adverse affect
9678 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9679 2357 : TempMaxPLR = TempMinPLR;
9680 : // find minimum limit of HeatingPLR
9681 2357 : TempMinPLR -= 0.01;
9682 2357 : this->setSpeedVariables(state, true, TempMinPLR);
9683 2357 : this->calcUnitarySystemToLoad(state,
9684 : AirLoopNum,
9685 : FirstHVACIteration,
9686 : TempMinPLR,
9687 : HeatPLR,
9688 : OnOffAirFlowRatio,
9689 : TempSensOutput,
9690 : TempLatOutput,
9691 2357 : HXUnitOn,
9692 : HeatCoilLoad,
9693 : SupHeaterLoad,
9694 : CompressorONFlag);
9695 2357 : TempSysOutput = TempSensOutput;
9696 : }
9697 : // Now solve again with tighter PLR limits
9698 : auto f2 = // (AUTO_OK_LAMBDA)
9699 2001 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9700 : Real64 const PartLoadRatio) {
9701 3312 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9702 : PartLoadRatio,
9703 1656 : this->m_UnitarySysNum,
9704 : FirstHVACIteration,
9705 : // par 3 not used?
9706 : CompressorONFlag,
9707 : ZoneLoad,
9708 : par6,
9709 : 1.0,
9710 : OnOffAirFlowRatio,
9711 : HXUnitOn,
9712 : // par 10 not used
9713 1656 : AirLoopNum);
9714 345 : };
9715 345 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, CoolPLR, f2, TempMinPLR, TempMaxPLR);
9716 345 : this->calcUnitarySystemToLoad(state,
9717 : AirLoopNum,
9718 : FirstHVACIteration,
9719 : CoolPLR,
9720 : HeatPLR,
9721 : OnOffAirFlowRatio,
9722 : TempSensOutput,
9723 : TempLatOutput,
9724 345 : HXUnitOn,
9725 : HeatCoilLoad,
9726 : SupHeaterLoad,
9727 : CompressorONFlag);
9728 : } // IF(HeatingLoad)THEN
9729 345 : if (SolFlag == -1) {
9730 29 : if (std::abs(ZoneLoad - TempSensOutput) > HVAC::SmallLoad) {
9731 29 : if (this->MaxIterIndex == 0) {
9732 5 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9733 10 : ShowContinueError(state, " Iteration limit exceeded in calculating system sensible part-load ratio.");
9734 10 : ShowContinueErrorTimeStamp(state,
9735 10 : format("Sensible load to be met = {:.2T} (watts), sensible output = {:.2T} "
9736 : "(watts), and the simulation continues.",
9737 : ZoneLoad,
9738 : TempSensOutput));
9739 : }
9740 232 : ShowRecurringWarningErrorAtEnd(state,
9741 58 : this->UnitType + " \"" + this->Name +
9742 : "\" - Iteration limit exceeded in calculating sensible part-load ratio error "
9743 : "continues. Sensible load statistics:",
9744 29 : this->MaxIterIndex,
9745 : ZoneLoad,
9746 : ZoneLoad);
9747 : }
9748 316 : } else if (SolFlag == -2) {
9749 202 : if (this->RegulaFalsiFailedIndex == 0) {
9750 4 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9751 8 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9752 8 : ShowContinueErrorTimeStamp(
9753 8 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9754 : }
9755 1616 : ShowRecurringWarningErrorAtEnd(
9756 : state,
9757 404 : this->UnitType + " \"" + this->Name +
9758 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9759 202 : this->RegulaFalsiFailedIndex,
9760 : ZoneLoad,
9761 : ZoneLoad);
9762 : }
9763 4314323 : } else if (SolFlag == -2) {
9764 656 : if (this->RegulaFalsiFailedIndex == 0) {
9765 8 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9766 16 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9767 16 : ShowContinueErrorTimeStamp(
9768 16 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9769 : }
9770 5248 : ShowRecurringWarningErrorAtEnd(
9771 : state,
9772 1312 : this->UnitType + " \"" + this->Name +
9773 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9774 656 : this->RegulaFalsiFailedIndex,
9775 : ZoneLoad,
9776 : ZoneLoad);
9777 : } // IF (SolFlag == -1) THEN
9778 : }
9779 : } else { // load is not bounded by capacity. Leave PLR=1 or turn off unit?
9780 1337 : this->m_CoolingPartLoadFrac = 0.0;
9781 1337 : this->m_HeatingPartLoadFrac = 0.0;
9782 1337 : CoolPLR = 0.0;
9783 1337 : HeatPLR = 0.0;
9784 1337 : PartLoadRatio = 0.0;
9785 : } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN
9786 : } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN
9787 : }
9788 :
9789 4429644 : if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) {
9790 145361 : if (this->m_HeatingSpeedNum == 1) {
9791 45829 : this->m_HeatingCycRatio = PartLoadRatio;
9792 45829 : this->m_HeatingSpeedRatio = 0.0;
9793 : } else {
9794 99532 : if (this->m_SingleMode == 0) {
9795 97522 : this->m_HeatingCycRatio = 1.0;
9796 97522 : this->m_HeatingSpeedRatio = PartLoadRatio;
9797 : } else {
9798 2010 : this->m_HeatingCycRatio = PartLoadRatio;
9799 2010 : this->m_HeatingSpeedRatio = 1.0;
9800 : }
9801 : }
9802 145361 : HeatPLR = PartLoadRatio;
9803 145361 : CoolPLR = 0.0;
9804 145361 : this->m_CoolingCycRatio = 0.0;
9805 145361 : this->m_CoolingSpeedRatio = 0.0;
9806 4284283 : } else if (state.dataUnitarySystems->CoolingLoad && (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil)) {
9807 821653 : if (this->m_CoolingSpeedNum == 1) {
9808 316697 : this->m_CoolingCycRatio = PartLoadRatio;
9809 316697 : this->m_CoolingSpeedRatio = 0.0;
9810 : } else {
9811 504956 : if (this->m_SingleMode == 0) {
9812 501908 : this->m_CoolingCycRatio = 1.0;
9813 501908 : this->m_CoolingSpeedRatio = PartLoadRatio;
9814 : } else {
9815 3048 : this->m_CoolingCycRatio = PartLoadRatio;
9816 3048 : this->m_CoolingSpeedRatio = 1.0;
9817 : }
9818 : }
9819 821653 : this->m_HeatingCycRatio = 0.0;
9820 821653 : this->m_HeatingSpeedRatio = 0.0;
9821 821653 : HeatPLR = 0.0;
9822 821653 : CoolPLR = PartLoadRatio;
9823 : } else {
9824 3462630 : HeatPLR = this->m_HeatingPartLoadFrac;
9825 3462630 : CoolPLR = this->m_CoolingPartLoadFrac;
9826 : }
9827 :
9828 4429644 : this->calcUnitarySystemToLoad(state,
9829 : AirLoopNum,
9830 : FirstHVACIteration,
9831 : CoolPLR,
9832 : HeatPLR,
9833 : OnOffAirFlowRatio,
9834 : TempSensOutput,
9835 : TempLatOutput,
9836 4429644 : HXUnitOn,
9837 : HeatCoilLoad,
9838 : SupHeaterLoad,
9839 : CompressorONFlag);
9840 :
9841 : // FullSensibleOutput is used to set supplemental heater PLR in calling routine
9842 : // OnOffAirFlowRatio is used to average air flow between ON and OFF state
9843 4429644 : FullSensibleOutput = TempSensOutput;
9844 4429644 : LatOutputOn = TempLatOutput;
9845 :
9846 : // RETURN if the moisture load is met
9847 4429644 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad >= TempLatOutput) {
9848 4394832 : return;
9849 : }
9850 : // Multimode does not meet the latent load, only the sensible load with or without HX active
9851 : // what if there is a heating load for a system using Multimode?
9852 34812 : if (!state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9853 0 : return;
9854 : }
9855 : // if HX was previously turned on return since sensible load is already met
9856 34812 : if (state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode && HXUnitOn) {
9857 20914 : return;
9858 : }
9859 : // IF(HeatingLoad .AND. UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)RETURN
9860 :
9861 13898 : if ((this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
9862 :
9863 : // find maximum latent output IF not already calculated
9864 13898 : if (state.dataUnitarySystems->HeatingLoad) {
9865 0 : CoolPLR = 1.0;
9866 0 : this->m_CoolingPartLoadFrac = 1.0;
9867 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9868 0 : this->m_CoolingSpeedRatio = 1.0;
9869 0 : this->m_CoolingCycRatio = 1.0;
9870 0 : if (this->m_CoolingSpeedNum > 0) {
9871 0 : this->m_HeatingPartLoadFrac = 0.0;
9872 0 : this->m_HeatingSpeedNum = 0;
9873 0 : HeatPLR = 0.0;
9874 0 : state.dataUnitarySystems->CoolingLoad = true;
9875 0 : state.dataUnitarySystems->HeatingLoad = false;
9876 0 : this->m_HeatingCoilSensDemand = 0.0;
9877 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9878 0 : this->calcUnitarySystemToLoad(state,
9879 : AirLoopNum,
9880 : FirstHVACIteration,
9881 : 0.0,
9882 : 0.0,
9883 : OnOffAirFlowRatio,
9884 : TempSensOutput,
9885 : TempLatOutput,
9886 0 : HXUnitOn,
9887 : HeatCoilLoad,
9888 : SupHeaterLoad,
9889 : CompressorONFlag);
9890 0 : this->calcUnitarySystemToLoad(state,
9891 : AirLoopNum,
9892 : FirstHVACIteration,
9893 : CoolPLR,
9894 : HeatPLR,
9895 : OnOffAirFlowRatio,
9896 : TempSensOutput,
9897 : LatOutputOn,
9898 0 : HXUnitOn,
9899 : HeatCoilLoad,
9900 : SupHeaterLoad,
9901 : CompressorONFlag);
9902 : } else {
9903 0 : this->m_HeatingCoilSensDemand = 0.0;
9904 0 : this->m_CoolingCoilLatentDemand = 0.0;
9905 0 : this->calcUnitarySystemToLoad(state,
9906 : AirLoopNum,
9907 : FirstHVACIteration,
9908 : 0.0,
9909 : 0.0,
9910 : OnOffAirFlowRatio,
9911 : TempSensOutput,
9912 : TempLatOutput,
9913 0 : HXUnitOn,
9914 : HeatCoilLoad,
9915 : SupHeaterLoad,
9916 : CompressorONFlag);
9917 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9918 0 : this->calcUnitarySystemToLoad(state,
9919 : AirLoopNum,
9920 : FirstHVACIteration,
9921 : CoolPLR,
9922 : HeatPLR,
9923 : OnOffAirFlowRatio,
9924 : TempSensOutput,
9925 : LatOutputOn,
9926 0 : HXUnitOn,
9927 : HeatCoilLoad,
9928 : SupHeaterLoad,
9929 : CompressorONFlag);
9930 : }
9931 : }
9932 :
9933 13898 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
9934 4700 : HXUnitOn = true;
9935 4700 : CoolPLR = 1.0;
9936 4700 : this->m_CoolingPartLoadFrac = 1.0;
9937 4700 : this->calcUnitarySystemToLoad(state,
9938 : AirLoopNum,
9939 : FirstHVACIteration,
9940 : CoolPLR,
9941 : HeatPLR,
9942 : OnOffAirFlowRatio,
9943 : TempSensOutput,
9944 : LatOutputOn,
9945 4700 : HXUnitOn,
9946 : HeatCoilLoad,
9947 : SupHeaterLoad,
9948 : CompressorONFlag);
9949 4700 : FullSensibleOutput = TempSensOutput;
9950 : }
9951 :
9952 13898 : if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
9953 9198 : HXUnitOn = true; // HX is needed to meet moisture load
9954 9198 : if (this->m_NumOfSpeedCooling > 0) {
9955 19461 : for (SpeedNum = this->m_CoolingSpeedNum; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9956 14636 : CoolPLR = 1.0;
9957 14636 : this->m_CoolingPartLoadFrac = CoolPLR;
9958 14636 : this->m_CoolingSpeedRatio = 1.0;
9959 14636 : this->m_CoolingCycRatio = 1.0;
9960 14636 : this->m_CoolingSpeedNum = SpeedNum;
9961 14636 : this->calcUnitarySystemToLoad(state,
9962 : AirLoopNum,
9963 : FirstHVACIteration,
9964 : CoolPLR,
9965 : HeatPLR,
9966 : OnOffAirFlowRatio,
9967 : SensOutputOn,
9968 : LatOutputOn,
9969 14636 : HXUnitOn,
9970 : HeatCoilLoad,
9971 : SupHeaterLoad,
9972 : CompressorONFlag);
9973 14636 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
9974 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9975 : }
9976 : // over specified logic? it has to be a water coil? what about other VS coil models?
9977 14636 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9978 14636 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
9979 14636 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9980 0 : !this->m_DiscreteSpeedCoolingCoil)) {
9981 0 : this->m_CoolingSpeedRatio = 0.0;
9982 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9983 0 : if (this->m_CoolingSpeedNum == 0) {
9984 0 : this->m_CoolingCycRatio = 0.0;
9985 0 : CoolPLR = 0.0;
9986 : } else {
9987 0 : this->m_CoolingCycRatio = 1.0;
9988 0 : this->m_CoolingSpeedRatio = 0.0;
9989 0 : if (this->m_SingleMode == 1) {
9990 0 : CoolPLR = 1.0;
9991 : }
9992 : }
9993 :
9994 0 : this->calcUnitarySystemToLoad(state,
9995 : AirLoopNum,
9996 : FirstHVACIteration,
9997 : CoolPLR,
9998 : HeatPLR,
9999 : OnOffAirFlowRatio,
10000 : SensOutputOn,
10001 : LatOutputOn,
10002 0 : HXUnitOn,
10003 : HeatCoilLoad,
10004 : SupHeaterLoad,
10005 : CompressorONFlag);
10006 0 : this->m_CoolingSpeedNum = SpeedNum;
10007 : }
10008 14636 : if (state.dataUnitarySystems->MoistureLoad >= LatOutputOn) {
10009 4373 : break;
10010 : }
10011 : }
10012 : } else {
10013 0 : CoolPLR = 1.0;
10014 0 : this->calcUnitarySystemToLoad(state,
10015 : AirLoopNum,
10016 : FirstHVACIteration,
10017 : CoolPLR,
10018 : HeatPLR,
10019 : OnOffAirFlowRatio,
10020 : SensOutputOn,
10021 : LatOutputOn,
10022 0 : HXUnitOn,
10023 : HeatCoilLoad,
10024 : SupHeaterLoad,
10025 : CompressorONFlag);
10026 0 : this->m_CoolingPartLoadFrac = CoolPLR;
10027 : }
10028 : }
10029 :
10030 27796 : if ((state.dataUnitarySystems->MoistureLoad < TempLatOutput) &&
10031 13898 : (state.dataUnitarySystems->MoistureLoad > LatOutputOn)) { // bounds check for RegulaFalsi
10032 :
10033 : // save heating PLR
10034 6137 : HeatPLR = this->m_HeatingPartLoadFrac;
10035 : Real64 par5;
10036 : Real64 par7;
10037 6137 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10038 1764 : par5 = ZoneLoad;
10039 1764 : par7 = 1.0;
10040 : } else {
10041 4373 : par5 = state.dataUnitarySystems->MoistureLoad;
10042 4373 : par7 = 0.0;
10043 : }
10044 : // Tolerance is fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
10045 29129 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, par5, par7, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
10046 : Real64 const PartLoadRatio) {
10047 45984 : return UnitarySys::calcUnitarySystemLoadResidual(state,
10048 : PartLoadRatio,
10049 22992 : this->m_UnitarySysNum,
10050 : FirstHVACIteration,
10051 : // par 3 not used?
10052 : CompressorONFlag,
10053 : par5,
10054 : 1.0,
10055 : par7,
10056 : OnOffAirFlowRatio,
10057 : HXUnitOn,
10058 : // par 10 not used
10059 22992 : AirLoopNum);
10060 6137 : };
10061 6137 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, PartLoadRatio, f, 0.0, 1.0);
10062 6137 : this->m_CoolingPartLoadFrac = PartLoadRatio;
10063 6137 : this->m_HeatingPartLoadFrac = HeatPLR;
10064 7761 : } else if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
10065 : // Logic below needs further look...what to do if the bounds check for RegulaFalsi fail?
10066 : // I'm not even sure if this should be done.
10067 : // It's wrong anyway, since there won't be a cooling load if multimode (see RETURN about 80 lines up).
10068 7761 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode) {
10069 4825 : this->m_CoolingPartLoadFrac = 1.0;
10070 : }
10071 : }
10072 : }
10073 :
10074 13898 : CoolPLR = this->m_CoolingPartLoadFrac;
10075 13898 : HeatPLR = this->m_HeatingPartLoadFrac;
10076 :
10077 13898 : this->calcUnitarySystemToLoad(state,
10078 : AirLoopNum,
10079 : FirstHVACIteration,
10080 : CoolPLR,
10081 : HeatPLR,
10082 : OnOffAirFlowRatio,
10083 : TempSensOutput,
10084 : TempLatOutput,
10085 13898 : HXUnitOn,
10086 : HeatCoilLoad,
10087 : SupHeaterLoad,
10088 : CompressorONFlag);
10089 :
10090 13898 : if (SolFlagLat == -1) {
10091 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
10092 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
10093 0 : TempMaxPLR = -0.1;
10094 0 : TempLatOutput = LatOutputOff;
10095 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
10096 : // find upper limit of HeatingPLR
10097 0 : TempMaxPLR += 0.1;
10098 0 : this->calcUnitarySystemToLoad(state,
10099 : AirLoopNum,
10100 : FirstHVACIteration,
10101 : TempMaxPLR,
10102 : HeatPLR,
10103 : OnOffAirFlowRatio,
10104 : TempSensOutput,
10105 : TempLatOutput,
10106 0 : HXUnitOn,
10107 : HeatCoilLoad,
10108 : SupHeaterLoad,
10109 : CompressorONFlag);
10110 : }
10111 0 : TempMinPLR = TempMaxPLR;
10112 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) < 0.0 && TempMinPLR > 0.0) {
10113 : // pull upper limit of HeatingPLR DOwn to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
10114 0 : TempMaxPLR = TempMinPLR;
10115 : // find minimum limit of HeatingPLR
10116 0 : TempMinPLR -= 0.01;
10117 0 : this->calcUnitarySystemToLoad(state,
10118 : AirLoopNum,
10119 : FirstHVACIteration,
10120 : TempMinPLR,
10121 : HeatPLR,
10122 : OnOffAirFlowRatio,
10123 : TempSensOutput,
10124 : TempLatOutput,
10125 0 : HXUnitOn,
10126 : HeatCoilLoad,
10127 : SupHeaterLoad,
10128 : CompressorONFlag);
10129 : }
10130 : // Now solve again with tighter PLR limits
10131 : Real64 par5;
10132 : Real64 par7;
10133 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10134 0 : par5 = ZoneLoad;
10135 0 : par7 = 1.0;
10136 : } else {
10137 0 : par5 = state.dataUnitarySystems->MoistureLoad;
10138 0 : par7 = 0.0;
10139 : }
10140 : // // Tolerance is fraction of load, M
10141 0 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, OnOffAirFlowRatio, HXUnitOn, AirLoopNum, par5, par7](
10142 : Real64 const PartLoadRatio) {
10143 : // TODO: The actual Par array being used here may have been altered through any of the sections above, and this line is not covered by
10144 : // a unit or integration test
10145 : // TODO: So I made some assumptions about the arguments. I'm not sure if ultimately this is even accessible, so maybe it doesn't
10146 : // matter.
10147 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
10148 : PartLoadRatio,
10149 0 : this->m_UnitarySysNum,
10150 : FirstHVACIteration,
10151 : // par 3 not used?
10152 : CompressorONFlag,
10153 : par5,
10154 : 1.0,
10155 : par7,
10156 : OnOffAirFlowRatio,
10157 : HXUnitOn,
10158 : // par 10 not used
10159 0 : AirLoopNum);
10160 0 : };
10161 0 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, CoolPLR, f, TempMinPLR, TempMaxPLR);
10162 0 : this->calcUnitarySystemToLoad(state,
10163 : AirLoopNum,
10164 : FirstHVACIteration,
10165 : CoolPLR,
10166 : HeatPLR,
10167 : OnOffAirFlowRatio,
10168 : TempSensOutput,
10169 : TempLatOutput,
10170 0 : HXUnitOn,
10171 : HeatCoilLoad,
10172 : SupHeaterLoad,
10173 : CompressorONFlag);
10174 0 : if (SolFlagLat == -1) {
10175 0 : if (std::abs(state.dataUnitarySystems->MoistureLoad - TempLatOutput) > HVAC::SmallLoad) {
10176 0 : if (this->warnIndex.m_LatMaxIterIndex == 0) {
10177 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
10178 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system Latent part-load ratio.");
10179 0 : ShowContinueErrorTimeStamp(
10180 : state,
10181 0 : format("Latent load to be met = {:.2T} (watts), Latent output = {:.2T} (watts), and the simulation continues.",
10182 0 : state.dataUnitarySystems->MoistureLoad,
10183 : TempLatOutput));
10184 : }
10185 0 : ShowRecurringWarningErrorAtEnd(
10186 : state,
10187 0 : this->UnitType + " \"" + this->Name +
10188 : "\" - Iteration limit exceeded in calculating Latent part-load ratio error continues. Latent load statistics:",
10189 0 : this->warnIndex.m_LatMaxIterIndex,
10190 0 : state.dataUnitarySystems->MoistureLoad,
10191 0 : state.dataUnitarySystems->MoistureLoad);
10192 : }
10193 0 : } else if (SolFlagLat == -2) {
10194 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
10195 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
10196 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
10197 0 : ShowContinueErrorTimeStamp(
10198 : state,
10199 0 : format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
10200 : }
10201 0 : ShowRecurringWarningErrorAtEnd(state,
10202 0 : this->UnitType + " \"" + this->Name +
10203 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
10204 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
10205 0 : state.dataUnitarySystems->MoistureLoad,
10206 0 : state.dataUnitarySystems->MoistureLoad);
10207 : }
10208 13898 : } else if (SolFlagLat == -2) {
10209 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
10210 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
10211 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
10212 0 : ShowContinueErrorTimeStamp(
10213 0 : state, format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
10214 : }
10215 0 : ShowRecurringWarningErrorAtEnd(state,
10216 0 : this->UnitType + " \"" + this->Name +
10217 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
10218 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
10219 0 : state.dataUnitarySystems->MoistureLoad,
10220 0 : state.dataUnitarySystems->MoistureLoad);
10221 : }
10222 :
10223 13898 : FullSensibleOutput = TempSensOutput;
10224 :
10225 13898 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
10226 : Real64 heatCoildT =
10227 13898 : (this->m_HeatCoilExists)
10228 13898 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
10229 13898 : : 0.0;
10230 : Real64 CoolingOnlySensibleOutput =
10231 13898 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
10232 13898 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
10233 13898 : heatCoildT);
10234 13898 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
10235 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
10236 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
10237 13193 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
10238 : // Heating mode and dehumidification is required
10239 : } else {
10240 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
10241 : // the heating coil pick up the load due to outdoor air.
10242 705 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
10243 : }
10244 6122517 : }
10245 :
10246 6054691 : void UnitarySys::initLoadBasedControl(EnergyPlusData &state,
10247 : int const AirLoopNum, // number of the current air loop being simulated
10248 : bool const FirstHVACIteration,
10249 : Real64 &OnOffAirFlowRatio,
10250 : Real64 &ZoneLoad)
10251 : {
10252 :
10253 : // SUBROUTINE INFORMATION:
10254 : // AUTHOR Richard Raustad, FSEC
10255 : // DATE WRITTEN February 2013
10256 :
10257 : // PURPOSE OF THIS SUBROUTINE:
10258 : // This subroutine is for initializations of the load controlled Unitary Systems.
10259 :
10260 : // METHODOLOGY EMPLOYED:
10261 : // Initialize mass flow rates and speed ratios. Calculate loads and adjust if necessary when using constant fan.
10262 :
10263 : // SUBROUTINE PARAMETER DEFINITIONS:
10264 : static constexpr std::string_view routineName("InitUnitarySystems");
10265 6054691 : Real64 QZnReq = 0.0;
10266 6054691 : Real64 QActual = 0.0;
10267 6054691 : Real64 SensOutputOff = 0.0;
10268 6054691 : Real64 LatOutputOff = 0.0;
10269 6054691 : Real64 HeatCoilLoad = 0.0;
10270 6054691 : Real64 SupHeaterLoad = 0.0;
10271 6054691 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
10272 :
10273 : // do the Begin Environment initializations
10274 6054691 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag2) {
10275 :
10276 2810 : bool errorsFound = false;
10277 : // set fluid-side hardware limits
10278 2810 : if (this->HeatCoilFluidInletNode > 0) {
10279 :
10280 62 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
10281 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10282 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
10283 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
10284 : Real64 CoilMaxVolFlowRate =
10285 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_HeatingCoilName, errorsFound);
10286 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10287 0 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
10288 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
10289 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
10290 : }
10291 : }
10292 : // IF steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10293 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
10294 0 : SteamCoils::SimulateSteamCoilComponents(state,
10295 : this->m_HeatingCoilName,
10296 : FirstHVACIteration,
10297 0 : this->m_HeatingCoilIndex,
10298 0 : 1.0,
10299 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10300 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, errorsFound);
10301 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10302 0 : Real64 TempSteamIn = 100.0;
10303 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10304 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10305 : }
10306 : }
10307 : }
10308 :
10309 62 : PlantUtilities::InitComponentNodes(
10310 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
10311 : }
10312 2810 : if (this->m_SuppCoilFluidInletNode > 0) {
10313 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
10314 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
10315 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10316 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
10317 : Real64 CoilMaxVolFlowRate =
10318 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_SuppHeatCoilName, errorsFound);
10319 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10320 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum)
10321 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
10322 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
10323 : }
10324 : }
10325 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
10326 0 : SteamCoils::SimulateSteamCoilComponents(state,
10327 : this->m_SuppHeatCoilName,
10328 : FirstHVACIteration,
10329 0 : this->m_SuppHeatCoilIndex,
10330 0 : 1.0,
10331 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10332 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, errorsFound);
10333 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10334 0 : Real64 TempSteamIn = 100.0;
10335 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10336 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10337 : }
10338 : }
10339 0 : PlantUtilities::InitComponentNodes(
10340 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
10341 : }
10342 : }
10343 2810 : this->m_MyEnvrnFlag2 = false;
10344 : }
10345 :
10346 6054691 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && this->m_MyCheckFlag) {
10347 3380776 : if (this->m_AirLoopEquipment) {
10348 103 : int zoneInlet = this->m_ZoneInletNode;
10349 103 : if (zoneInlet == 0) {
10350 0 : this->m_ThisSysInputShouldBeGotten = true; // need to find zone inlet node once data is available
10351 0 : this->m_MySizingCheckFlag = true; // need to resize after getInput is read in again
10352 0 : this->m_OKToPrintSizing = true; // hope first time back through finds the data, else multiple prints to the eio
10353 0 : this->m_airLoopReturnCounter += 1;
10354 0 : if (this->m_airLoopReturnCounter < 3) {
10355 0 : return;
10356 : }
10357 : }
10358 : // setup zone equipment sequence information based on finding matching air terminal
10359 103 : if (state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex > 0) {
10360 103 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex)
10361 103 : .getPrioritiesForInletNode(state, zoneInlet, this->m_ZoneSequenceCoolingNum, this->m_ZoneSequenceHeatingNum);
10362 : }
10363 103 : this->m_MyCheckFlag = false;
10364 103 : if (this->m_ZoneSequenceCoolingNum == 0 || this->m_ZoneSequenceHeatingNum == 0) {
10365 0 : ShowSevereError(state,
10366 0 : format("{} \"{}\": Airloop air terminal in the zone equipment list for zone = {} not it or is not allowed "
10367 : "Zone Equipment Cooling or Heating Sequence = 0.",
10368 0 : this->UnitType,
10369 0 : this->Name,
10370 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10371 0 : ShowFatalError(
10372 : state,
10373 0 : format("Subroutine InitLoadBasedControl: Errors it in getting {} input. Preceding condition(s) causes termination.",
10374 0 : this->UnitType));
10375 : }
10376 : }
10377 3380776 : if (this->m_ZoneInletNode == 0) {
10378 0 : ShowSevereError(state,
10379 0 : format("{} \"{}\": The zone inlet node in the controlled zone ({}) is not found.",
10380 0 : this->UnitType,
10381 0 : this->Name,
10382 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10383 0 : ShowFatalError(
10384 : state,
10385 0 : format("Subroutine InitLoadBasedControl: Errors found in getting {} input. Preceding condition(s) causes termination.",
10386 0 : this->UnitType));
10387 : }
10388 : }
10389 :
10390 : // What type of logic is this? Is the point to go through the main IF once? or every other time?
10391 : // RR: This was used with AirflowNetwork to calculate duct losses.
10392 : // RR: AFN counts the number of passes through airloop equipment (same logic in Furnaces and other modules) and resets the counter to 0 on
10393 : // BeginEnvrnFlag. RR: This has been changed in this module and AFN to use AirflowNetworkFanActivated if AirflowNetworkUnitarySystem is seen
10394 : // by AFN. RR: Search for AirflowNetworkFanActivated in this module to see usage. The following lines of code can probably be removed although
10395 : // it would require a AFN input file to test.
10396 6054691 : if (state.dataGlobal->BeginEnvrnFlag && m_initLoadBasedControlAirLoopPass) {
10397 2707 : m_airLoopPassCounter = 0;
10398 2707 : m_initLoadBasedControlAirLoopPass = false;
10399 : }
10400 6054691 : if (!state.dataGlobal->BeginEnvrnFlag) {
10401 6030819 : this->m_MyEnvrnFlag2 = true; // this does not appear to be needed, only initializes autosized coil fluid flow rates
10402 6030819 : m_initLoadBasedControlAirLoopPass = true;
10403 : }
10404 :
10405 6054691 : ++m_airLoopPassCounter;
10406 6054691 : if (m_airLoopPassCounter > 2) {
10407 3025192 : m_airLoopPassCounter = 1;
10408 : }
10409 :
10410 : // reset duct losses from previous iteration
10411 6054691 : if (FirstHVACIteration) {
10412 2241453 : this->m_SenLoadLoss = 0.0;
10413 2241453 : this->m_LatLoadLoss = 0.0;
10414 : }
10415 :
10416 : // Calculate air distribution losses
10417 6054691 : if (!FirstHVACIteration && state.afn->AirflowNetworkFanActivated) {
10418 9960 : Real64 DeltaMassRate = 0.0;
10419 9960 : Real64 TotalOutput = 0.0; // total output rate, {W}
10420 9960 : Real64 SensibleOutputDelta = 0.0; // delta sensible output rate, {W}
10421 9960 : Real64 LatentOutputDelta = 0.0; // delta latent output rate, {W}
10422 9960 : Real64 TotalOutputDelta = 0.0; // delta total output rate, {W}
10423 9960 : int ZoneInNode = this->m_ZoneInletNode;
10424 9960 : Real64 MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10425 19920 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
10426 9960 : this->m_sysType != SysType::PackagedWSHP) {
10427 9960 : DeltaMassRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate -
10428 9960 : state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10429 9960 : if (DeltaMassRate < 0.0) {
10430 0 : DeltaMassRate = 0.0;
10431 : }
10432 : } else {
10433 0 : MassFlowRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
10434 0 : DeltaMassRate = 0.0;
10435 : }
10436 39840 : CalcComponentSensibleLatentOutput(MassFlowRate,
10437 9960 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10438 9960 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10439 9960 : state.dataLoopNodes->Node(ZoneInNode).Temp,
10440 9960 : state.dataLoopNodes->Node(ZoneInNode).HumRat,
10441 9960 : this->m_SenLoadLoss,
10442 9960 : this->m_LatLoadLoss,
10443 : TotalOutput);
10444 39840 : CalcComponentSensibleLatentOutput(DeltaMassRate,
10445 9960 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10446 9960 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10447 9960 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
10448 9960 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
10449 : SensibleOutputDelta,
10450 : LatentOutputDelta,
10451 : TotalOutputDelta);
10452 9960 : this->m_SenLoadLoss = this->m_SenLoadLoss + SensibleOutputDelta;
10453 9960 : if (std::abs(this->m_SensibleLoadMet) > 0.0) {
10454 9960 : if (std::abs(this->m_SenLoadLoss / this->m_SensibleLoadMet) < 0.001) {
10455 0 : this->m_SenLoadLoss = 0.0;
10456 : }
10457 : }
10458 9960 : if (this->m_Humidistat) {
10459 0 : this->m_LatLoadLoss = this->m_LatLoadLoss + LatentOutputDelta;
10460 0 : if (std::abs(this->m_LatentLoadMet) > 0.0) {
10461 0 : if (std::abs(this->m_LatLoadLoss / this->m_LatentLoadMet) < 0.001) {
10462 0 : this->m_LatLoadLoss = 0.0;
10463 : }
10464 : }
10465 : }
10466 : }
10467 :
10468 6054691 : if (this->m_fanOpModeSched != nullptr) {
10469 6052183 : if (this->m_fanOpModeSched->getCurrentVal() == 0.0) {
10470 2823240 : this->m_FanOpMode = HVAC::FanOp::Cycling;
10471 : } else {
10472 3228943 : this->m_FanOpMode = HVAC::FanOp::Continuous;
10473 3228943 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10474 : }
10475 : }
10476 :
10477 : // System load calculation for cycling fan systems
10478 6054691 : if (this->ControlZoneMassFlowFrac > 0.0) {
10479 6054340 : QZnReq = ZoneLoad / this->ControlZoneMassFlowFrac;
10480 6054340 : state.dataUnitarySystems->MoistureLoad /= this->ControlZoneMassFlowFrac;
10481 6054340 : state.dataUnitarySystems->QToCoolSetPt /= this->ControlZoneMassFlowFrac;
10482 6054340 : state.dataUnitarySystems->QToHeatSetPt /= this->ControlZoneMassFlowFrac;
10483 6054340 : ZoneLoad = QZnReq;
10484 : } else {
10485 351 : QZnReq = ZoneLoad;
10486 351 : this->ControlZoneMassFlowFrac = 1.0;
10487 : }
10488 :
10489 6054691 : state.dataUnitarySystems->CoolingLoad = false;
10490 6054691 : state.dataUnitarySystems->HeatingLoad = false;
10491 6054691 : Real64 smallLoadTolerance = this->m_SmallLoadTolerance;
10492 6054691 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10493 3197491 : smallLoadTolerance = HVAC::SmallLoad;
10494 : }
10495 6054691 : if (QZnReq > smallLoadTolerance) { // no need to check deadband flag, QZnReq is correct.
10496 2116902 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
10497 2116902 : state.dataUnitarySystems->HeatingLoad = true;
10498 : }
10499 3937789 : } else if (QZnReq < -smallLoadTolerance) {
10500 2742872 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
10501 2742861 : state.dataUnitarySystems->CoolingLoad = true;
10502 : }
10503 : }
10504 :
10505 : // System load calculation for constant fan systems
10506 6054691 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10507 3228943 : bool HXUnitOn = false;
10508 3228943 : this->FanPartLoadRatio = 0.0; // sets fan to minimum for ASHRAE model
10509 3228943 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10510 : // the SpeedNum is set for PTUnits, might need to set this for all multi/var speed coils?
10511 1344464 : if (state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) {
10512 5991 : m_CoolingSpeedNum = 1;
10513 1338473 : } else if (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil) {
10514 1726 : m_HeatingSpeedNum = 1;
10515 : }
10516 : }
10517 3228943 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio,
10518 : 0.0); // CompOnMassFlow and CompOffMassFlow are scalar, reset to this system's values
10519 3228943 : this->calcUnitarySystemToLoad(state,
10520 : AirLoopNum,
10521 : FirstHVACIteration,
10522 : 0.0,
10523 : 0.0,
10524 : OnOffAirFlowRatio,
10525 : SensOutputOff,
10526 : LatOutputOff,
10527 : HXUnitOn,
10528 : HeatCoilLoad,
10529 : SupHeaterLoad,
10530 : CompressorOn);
10531 :
10532 3228943 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
10533 9143 : case HVAC::SetptType::SingleHeat: {
10534 9143 : state.dataUnitarySystems->CoolingLoad = false;
10535 : // No heating load and constant fan pushes zone below heating set point
10536 13873 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt <= 0.0 &&
10537 4730 : SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10538 156 : state.dataUnitarySystems->HeatingLoad = true;
10539 156 : state.dataUnitarySystems->CoolingLoad = false;
10540 156 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10541 : }
10542 9143 : } break;
10543 :
10544 8938 : case HVAC::SetptType::SingleCool: {
10545 8938 : state.dataUnitarySystems->HeatingLoad = false;
10546 : // No heating load and constant fan pushes zone above cooling set point
10547 9055 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
10548 117 : SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10549 70 : state.dataUnitarySystems->HeatingLoad = false;
10550 70 : state.dataUnitarySystems->CoolingLoad = true;
10551 70 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10552 : }
10553 8938 : } break;
10554 :
10555 0 : case HVAC::SetptType::SingleHeatCool: {
10556 : // zone temp above cooling and heating set point temps
10557 0 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10558 : // zone pushed below heating set point
10559 0 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10560 0 : state.dataUnitarySystems->HeatingLoad = true;
10561 0 : state.dataUnitarySystems->CoolingLoad = false;
10562 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10563 : }
10564 : // zone temp below heating set point temp
10565 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10566 : // zone pushed above cooling set point
10567 0 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10568 0 : state.dataUnitarySystems->HeatingLoad = false;
10569 0 : state.dataUnitarySystems->CoolingLoad = true;
10570 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10571 : }
10572 : }
10573 0 : } break;
10574 :
10575 3210862 : case HVAC::SetptType::DualHeatCool: {
10576 : // zone temp above cooling and heating set point temps
10577 3210862 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10578 : // zone pushed into deadband
10579 1572198 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10580 117837 : state.dataUnitarySystems->HeatingLoad = false;
10581 117837 : state.dataUnitarySystems->CoolingLoad = false;
10582 117837 : ZoneLoad = 0.0;
10583 : }
10584 : // zone pushed below heating set point
10585 1572198 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10586 34638 : state.dataUnitarySystems->HeatingLoad = true;
10587 34638 : state.dataUnitarySystems->CoolingLoad = false;
10588 34638 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10589 : }
10590 : // zone temp below heating set point temp
10591 1638664 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10592 : // zone pushed into deadband
10593 1034527 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt > HVAC::SmallLoad) {
10594 3366 : state.dataUnitarySystems->HeatingLoad = false;
10595 3366 : state.dataUnitarySystems->CoolingLoad = false;
10596 3366 : ZoneLoad = 0.0;
10597 : }
10598 : // zone pushed above cooling set point
10599 1034527 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10600 64 : state.dataUnitarySystems->HeatingLoad = false;
10601 64 : state.dataUnitarySystems->CoolingLoad = true;
10602 64 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10603 : }
10604 : // zone temp between set point temps
10605 604137 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10606 : // zone pushed below heating set point
10607 604137 : if (SensOutputOff < 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10608 213618 : state.dataUnitarySystems->HeatingLoad = true;
10609 213618 : state.dataUnitarySystems->CoolingLoad = false;
10610 213618 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10611 : // zone pushed above cooling set point
10612 390519 : } else if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10613 25739 : state.dataUnitarySystems->HeatingLoad = false;
10614 25739 : state.dataUnitarySystems->CoolingLoad = true;
10615 25739 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10616 : }
10617 : }
10618 3210862 : } break;
10619 :
10620 0 : default: {
10621 0 : } break;
10622 : } // switch
10623 :
10624 : // push iteration mode stack and set current mode
10625 3228943 : this->m_IterationMode[2] = this->m_IterationMode[1];
10626 3228943 : this->m_IterationMode[1] = this->m_IterationMode[0];
10627 3228943 : if (state.dataUnitarySystems->CoolingLoad) {
10628 1488801 : this->m_IterationMode[0] = CoolingMode;
10629 1740142 : } else if (state.dataUnitarySystems->HeatingLoad) {
10630 1290945 : this->m_IterationMode[0] = HeatingMode;
10631 : } else {
10632 449197 : this->m_IterationMode[0] = NoCoolHeat;
10633 : }
10634 : // IF small loads to meet or not converging, just shut down unit
10635 3228943 : if (std::abs(ZoneLoad) < smallLoadTolerance) {
10636 450466 : ZoneLoad = 0.0;
10637 450466 : state.dataUnitarySystems->CoolingLoad = false;
10638 450466 : state.dataUnitarySystems->HeatingLoad = false;
10639 2778477 : } else if (this->m_IterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 6)) {
10640 : // attempt to lock output (air flow) if oscillations are detected
10641 203889 : int OperatingMode = this->m_IterationMode[0]; // VS systems can take a few more iterations than single-speed systems
10642 203889 : int OperatingModeMinusOne = this->m_IterationMode[1];
10643 203889 : int OperatingModeMinusTwo = this->m_IterationMode[2];
10644 203889 : bool Oscillate = true;
10645 203889 : if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) {
10646 174124 : Oscillate = false;
10647 : }
10648 203889 : if (Oscillate) {
10649 29765 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10650 17998 : state.dataUnitarySystems->HeatingLoad = false;
10651 17998 : state.dataUnitarySystems->CoolingLoad = true;
10652 17998 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10653 11767 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0) {
10654 0 : state.dataUnitarySystems->HeatingLoad = true;
10655 0 : state.dataUnitarySystems->CoolingLoad = false;
10656 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10657 : } else {
10658 11767 : state.dataUnitarySystems->HeatingLoad = false;
10659 11767 : state.dataUnitarySystems->CoolingLoad = false;
10660 11767 : ZoneLoad = 0.0;
10661 : }
10662 : }
10663 : }
10664 : }
10665 :
10666 : // Determine the m_Staged status
10667 6054691 : if (allocated(state.dataZoneCtrls->StageZoneLogic) && this->m_DesignSpecMSHPIndex > -1) {
10668 0 : if (state.dataZoneCtrls->StageZoneLogic(this->ControlZoneNum)) {
10669 0 : this->m_Staged = true;
10670 0 : this->m_StageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).StageNum;
10671 : } else {
10672 0 : if (this->m_MyStagedFlag) {
10673 0 : ShowWarningError(state,
10674 : "ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to this UnitarySystem "
10675 : "object with UnitarySystemPerformance:Multispeed type = ");
10676 0 : ShowContinueError(state, format("{}. Please make correction. Simulation continues...", this->Name));
10677 0 : this->m_MyStagedFlag = false;
10678 : }
10679 : }
10680 : }
10681 :
10682 : // Staged control
10683 6054691 : if (this->m_Staged) {
10684 0 : if (this->m_StageNum == 0) {
10685 0 : state.dataUnitarySystems->HeatingLoad = false;
10686 0 : state.dataUnitarySystems->CoolingLoad = false;
10687 0 : QZnReq = 0.0;
10688 : } else {
10689 0 : QZnReq =
10690 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired / this->ControlZoneMassFlowFrac;
10691 0 : if (QZnReq > 0.0) {
10692 0 : state.dataUnitarySystems->HeatingLoad = true;
10693 0 : state.dataUnitarySystems->CoolingLoad = false;
10694 : } else {
10695 0 : state.dataUnitarySystems->HeatingLoad = false;
10696 0 : state.dataUnitarySystems->CoolingLoad = true;
10697 : }
10698 : }
10699 : }
10700 :
10701 6054691 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10702 117640 : if (state.dataUnitarySystems->HeatingLoad) {
10703 17088 : state.dataUnitarySystems->MoistureLoad = 0.0;
10704 : }
10705 : }
10706 :
10707 : // Check load control
10708 6054691 : if (this->m_RunOnLatentOnlyWithSensible && ZoneLoad == 0.0) {
10709 66859 : state.dataUnitarySystems->MoistureLoad = 0.0;
10710 : }
10711 6054691 : if (!this->m_RunOnSensibleLoad) {
10712 0 : ZoneLoad = 0.0;
10713 0 : state.dataUnitarySystems->CoolingLoad = false;
10714 0 : state.dataUnitarySystems->HeatingLoad = false;
10715 : }
10716 6054691 : if (!this->m_RunOnLatentLoad) {
10717 5861231 : state.dataUnitarySystems->MoistureLoad = 0.0;
10718 : }
10719 :
10720 : // Testing heat pump air to air with RH control with CoolReheat dehumidification control showed that when there was heating
10721 : // and moisture load, the cooling coil was turning on to meet the moisture load and reheat was then turning on to meet both
10722 : // heating load and excess cooling load caused by cooling coil. Adding the logic below caused the zone temperature,
10723 : // relative humidity, cooling/heating rate to line up for both the original and new file with unitary system object.
10724 :
10725 6054691 : if (this->m_SuppCoilExists) {
10726 3177209 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10727 39744 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolCoilExists) {
10728 5574 : state.dataUnitarySystems->HeatingLoad = false;
10729 5574 : state.dataUnitarySystems->CoolingLoad = true;
10730 : }
10731 : }
10732 : }
10733 :
10734 : // set report variables for predicted sensible and latent load
10735 6054691 : this->m_SensibleLoadPredicted = ZoneLoad;
10736 6054691 : this->m_MoistureLoadPredicted = state.dataUnitarySystems->MoistureLoad;
10737 : }
10738 :
10739 43925543 : void UnitarySys::setOnOffMassFlowRate(EnergyPlusData &state,
10740 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
10741 : Real64 const PartLoadRatio // coil part-load ratio
10742 : )
10743 : {
10744 :
10745 : // SUBROUTINE INFORMATION:
10746 : // AUTHOR Chandan Sharma
10747 : // DATE WRITTEN May 2013
10748 :
10749 : // PURPOSE OF THIS SUBROUTINE:
10750 : // This subroutine is for initializations of the components.
10751 :
10752 : // METHODOLOGY EMPLOYED:
10753 : // The unitarysystem may have alternate air flow rates
10754 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
10755 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
10756 : // based on PLR.
10757 :
10758 : // REFERENCES:
10759 : // Based on SetOnOffMassFlowRate by Richard Raustad
10760 :
10761 43925543 : int HeatSpeedNum = 0;
10762 43925543 : int CoolSpeedNum = 0;
10763 :
10764 43925543 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10765 43925543 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10766 43925543 : state.dataUnitarySystems->m_massFlow1 = 0.0;
10767 43925543 : state.dataUnitarySystems->m_massFlow2 = 0.0;
10768 43925543 : state.dataUnitarySystems->OACompOnMassFlow = 0.0;
10769 43925543 : state.dataUnitarySystems->OACompOffMassFlow = 0.0;
10770 :
10771 : // Set the compressor or coil ON mass flow rate
10772 43925543 : if (state.dataUnitarySystems->HeatingLoad) {
10773 :
10774 16633057 : this->m_LastMode = HeatingMode;
10775 :
10776 16633057 : if (this->m_MultiOrVarSpeedHeatCoil) {
10777 :
10778 3395783 : HeatSpeedNum = this->m_HeatingSpeedNum;
10779 :
10780 3395783 : if (HeatSpeedNum == 0) {
10781 894935 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10782 894935 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10783 2500848 : } else if (HeatSpeedNum == 1) {
10784 1718213 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10785 1718213 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10786 782635 : } else if (HeatSpeedNum > 1) {
10787 782635 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10788 782635 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10789 : }
10790 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10791 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10792 3395783 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10793 2452381 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10794 0 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10795 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10796 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10797 0 : if (CoolSpeedNum < 1) {
10798 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10799 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10800 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10801 0 : } else if (CoolSpeedNum == 1) {
10802 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10803 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10804 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10805 : } else {
10806 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10807 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10808 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10809 : }
10810 : } else {
10811 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10812 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10813 : }
10814 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10815 : } else {
10816 2452381 : if (HeatSpeedNum == 0) {
10817 731331 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10818 731331 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10819 1721050 : } else if (HeatSpeedNum == 1) {
10820 1411870 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10821 1411870 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatMassFlowRate[HeatSpeedNum];
10822 : } else {
10823 309180 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10824 309180 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10825 : }
10826 2452381 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10827 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10828 2452381 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10829 2425863 : this->m_sysType == SysType::PackagedWSHP) {
10830 26518 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10831 : }
10832 : }
10833 : } else { // cycling fan mode
10834 943402 : if (HeatSpeedNum <= 1) {
10835 469947 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10836 469947 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10837 : } else {
10838 473455 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10839 473455 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10840 : }
10841 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10842 943402 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10843 920422 : this->m_sysType == SysType::PackagedWSHP) {
10844 128196 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10845 : // does this assume OA flow <= min speed flow? without this there are SolveRoot failures.
10846 128196 : if (HeatSpeedNum > 1) {
10847 82125 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10848 : }
10849 : }
10850 : }
10851 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10852 : // If a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
10853 13238730 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10854 13238730 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && !this->m_DXHeatingCoil) {
10855 1456 : if (this->m_MultiOrVarSpeedCoolCoil) {
10856 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10857 0 : if (CoolSpeedNum < 1) {
10858 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10859 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10860 0 : } else if (CoolSpeedNum == 1) {
10861 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10862 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10863 : } else {
10864 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10865 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10866 : }
10867 : } else { // IF (MultiOrVarSpeedCoolCoil) THEN
10868 1456 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10869 1456 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10870 1456 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10871 1456 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10872 1456 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10873 : }
10874 : }
10875 1456 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10876 : } else { // Heating load but no moisture load
10877 13235818 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10878 7606659 : this->m_sysType == SysType::PackagedWSHP) {
10879 : // this was missing for heating mode where multi speed coils are used
10880 7577298 : if (this->m_MultiOrVarSpeedHeatCoil) {
10881 0 : if (HeatSpeedNum == 0) {
10882 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10883 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10884 0 : } else if (HeatSpeedNum == 1) {
10885 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10886 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10887 0 : } else if (HeatSpeedNum > 1) {
10888 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10889 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10890 : }
10891 : } else {
10892 7577298 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10893 7577298 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10894 7577298 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10895 : }
10896 7577298 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10897 2835975 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10898 2835975 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10899 2835975 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10900 : }
10901 : } else {
10902 5658520 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10903 5658520 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10904 5658520 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10905 5658520 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10906 4674392 : if (this->m_AirFlowControl == UseCompFlow::On) {
10907 126882 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10908 126882 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10909 126882 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10910 : } else {
10911 4547510 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10912 4547510 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10913 4547510 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10914 : }
10915 : }
10916 : }
10917 : }
10918 : }
10919 :
10920 : // If a cooling load exists, operate at the cooling mass flow rate
10921 27292486 : } else if (state.dataUnitarySystems->CoolingLoad) {
10922 :
10923 24287516 : this->m_LastMode = CoolingMode;
10924 :
10925 24287516 : if (this->m_MultiOrVarSpeedCoolCoil) {
10926 :
10927 12974110 : CoolSpeedNum = this->m_CoolingSpeedNum;
10928 :
10929 12974110 : if (CoolSpeedNum == 0) {
10930 3418088 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10931 3418088 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10932 3418088 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10933 9556022 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation; set system flow rate to economizer flow rate
10934 652193 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10935 652193 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10936 652193 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10937 8903829 : } else if (CoolSpeedNum > 0) {
10938 8903829 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10939 8903829 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10940 8903829 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10941 : }
10942 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10943 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10944 12974110 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10945 10448888 : if (CoolSpeedNum == 0) {
10946 2971245 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10947 2971245 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10948 2971245 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10949 7477643 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10950 125888 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10951 125888 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10952 125888 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10953 7351755 : } else if (CoolSpeedNum == 1) {
10954 3030938 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10955 3030938 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10956 3030938 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10957 : } else {
10958 4320817 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10959 4320817 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10960 4320817 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10961 : }
10962 : } else { // cycling fan mode
10963 2525222 : if (this->m_EconoSpeedNum == 0 && CoolSpeedNum == 0) { // multi-stage economizer operation
10964 286753 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10965 286753 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10966 2238469 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10967 686395 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
10968 686395 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum - 1];
10969 686395 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10970 1552074 : } else if (CoolSpeedNum == 0) {
10971 0 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10972 0 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10973 : } else {
10974 1552074 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10975 1552074 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10976 1552074 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10977 : }
10978 : }
10979 : } else {
10980 11313406 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10981 11313406 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10982 11313406 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10983 11313406 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10984 4526918 : if (this->m_AirFlowControl == UseCompFlow::On) {
10985 668628 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10986 668628 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10987 668628 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10988 : } else {
10989 3858290 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10990 3858290 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10991 3858290 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10992 : }
10993 : }
10994 : }
10995 :
10996 : } else { // No load
10997 : // If no load exists, set the compressor on mass flow rate.
10998 : // Set equal the mass flow rate when no heating or cooling is needed If no moisture load exists.
10999 : // If the user has set the off mass flow rate to 0, set according to the last operating mode.
11000 :
11001 3004970 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
11002 40580 : if (this->m_MultiOrVarSpeedCoolCoil) {
11003 40032 : CoolSpeedNum = this->m_CoolingSpeedNum;
11004 40032 : if (CoolSpeedNum < 1) {
11005 40032 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11006 40032 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11007 40032 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11008 0 : } else if (CoolSpeedNum == 1) {
11009 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
11010 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
11011 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11012 : } else {
11013 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
11014 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
11015 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11016 : }
11017 :
11018 40032 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11019 40032 : if (this->m_AirFlowControl == UseCompFlow::On) {
11020 0 : if (CoolSpeedNum <= 1) {
11021 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11022 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11023 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11024 : } else {
11025 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
11026 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
11027 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11028 : }
11029 : } else {
11030 40032 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11031 40032 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11032 40032 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11033 : }
11034 : }
11035 :
11036 : } else { // IF (MultiOrVarSpeedCoolCoil(UnitarySysNum)) THEN
11037 548 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
11038 548 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
11039 548 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11040 548 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11041 548 : if (this->m_AirFlowControl == UseCompFlow::On) {
11042 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
11043 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11044 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11045 : } else {
11046 548 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11047 548 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11048 548 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11049 : }
11050 : }
11051 : }
11052 :
11053 : } else { // No Moisture Load
11054 :
11055 2964390 : if (this->m_LastMode == HeatingMode) {
11056 : // this needs to be corrected to include UseCompressorOnFlow
11057 1510885 : if (this->m_MultiOrVarSpeedHeatCoil) {
11058 645228 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11059 645228 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11060 : } else {
11061 865657 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11062 865657 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
11063 : }
11064 : // this needs to happen regardless of system except maybe the CoilSystem objects
11065 : // do this only for PTUnit for the time being to reduce diffs for the PTUnit to UnitarySystem conversion
11066 1510885 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
11067 1471407 : this->m_sysType == SysType::PackagedWSHP) {
11068 115909 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11069 71195 : if (this->m_AirFlowControl == UseCompFlow::On) {
11070 5772 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11071 5772 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11072 5772 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11073 : }
11074 : }
11075 : }
11076 : } else {
11077 : // this needs to be corrected to include UseCompressorOnFlow
11078 1453505 : if (this->m_MultiOrVarSpeedCoolCoil) {
11079 1088424 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11080 1088424 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11081 : } else {
11082 365081 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11083 365081 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
11084 : }
11085 : }
11086 2964390 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11087 2964390 : if (state.dataUnitarySystems->CompOnMassFlow == 0.0) {
11088 226378 : if (this->m_LastMode == HeatingMode) {
11089 76437 : if (this->m_MultiOrVarSpeedHeatCoil) {
11090 3090 : HeatSpeedNum = this->m_HeatingSpeedNum;
11091 3090 : if (HeatSpeedNum == 0) {
11092 3080 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11093 3080 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11094 10 : } else if (HeatSpeedNum == 1) {
11095 10 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
11096 10 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
11097 0 : } else if (HeatSpeedNum > 1) {
11098 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
11099 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
11100 : }
11101 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
11102 73347 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
11103 73347 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
11104 : }
11105 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11106 149941 : if (this->m_MultiOrVarSpeedCoolCoil) {
11107 8686 : CoolSpeedNum = this->m_CoolingSpeedNum;
11108 8686 : if (CoolSpeedNum == 0) {
11109 8686 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11110 8686 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11111 0 : } else if (CoolSpeedNum == 1) {
11112 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
11113 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
11114 0 : } else if (CoolSpeedNum > 1) {
11115 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
11116 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
11117 : }
11118 : } else { // IF(MultiOrVarSpeedCoolCoil) THEN
11119 141255 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
11120 141255 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
11121 : } // IF(MultiOrVarSpeedCoolCoil) THEN
11122 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11123 : } // IF(CompOnMassFlow .EQ. 0.0d0)THEN
11124 :
11125 2964390 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11126 1915101 : if (this->m_AirFlowControl == UseCompFlow::On) {
11127 32428 : if (this->m_LastMode == HeatingMode) {
11128 8818 : if (this->m_MultiOrVarSpeedHeatCoil) {
11129 1614 : HeatSpeedNum = this->m_HeatingSpeedNum;
11130 1614 : if (HeatSpeedNum < 1) {
11131 1614 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11132 1614 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11133 1614 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11134 0 : } else if (HeatSpeedNum == 1) {
11135 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[1];
11136 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[1];
11137 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11138 : } else {
11139 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
11140 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
11141 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11142 : }
11143 : } else {
11144 : // this is a no load case, added if for PTUnit to correct this for PTUnit to UnitarySystem conversion
11145 : // the else is incorrect?
11146 7204 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
11147 1630 : this->m_sysType == SysType::PackagedWSHP) {
11148 5574 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11149 5574 : if (this->m_AirFlowControl == UseCompFlow::On) {
11150 5574 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11151 5574 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11152 5574 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11153 : }
11154 : }
11155 : } else {
11156 1630 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
11157 1630 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11158 1630 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11159 : }
11160 : }
11161 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11162 23610 : if (this->m_MultiOrVarSpeedCoolCoil) {
11163 5686 : CoolSpeedNum = this->m_CoolingSpeedNum;
11164 5686 : if (CoolSpeedNum < 1) {
11165 5666 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11166 5666 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11167 5666 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11168 20 : } else if (CoolSpeedNum == 1) {
11169 20 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
11170 20 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
11171 20 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11172 : } else {
11173 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
11174 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
11175 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11176 : }
11177 : } else {
11178 17924 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
11179 17924 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11180 17924 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11181 : }
11182 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11183 : } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
11184 1882673 : if (this->m_LastMode == HeatingMode) {
11185 893876 : if (this->m_MultiOrVarSpeedHeatCoil) {
11186 452788 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11187 452788 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11188 : } else {
11189 441088 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11190 441088 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11191 : }
11192 : } else {
11193 988797 : if (this->m_MultiOrVarSpeedCoolCoil) {
11194 796828 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11195 796828 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11196 : } else {
11197 191969 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11198 191969 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11199 : }
11200 : }
11201 1882673 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11202 : } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
11203 : } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN
11204 : } // ELSE ! No Moisture Load
11205 : } // No Heating/Cooling Load
11206 :
11207 43925543 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11208 26895691 : if (this->m_AirFlowControl == UseCompFlow::On &&
11209 1325634 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)) {
11210 881226 : if (this->m_LastMode == HeatingMode) {
11211 285939 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11212 : } else {
11213 595287 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11214 : }
11215 : }
11216 : }
11217 :
11218 43925543 : if (this->m_MultiSpeedHeatingCoil && (state.dataUnitarySystems->HeatingLoad && HeatSpeedNum == 1)) {
11219 1642669 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
11220 42282874 : } else if (this->m_DiscreteSpeedCoolingCoil && (state.dataUnitarySystems->CoolingLoad && CoolSpeedNum == 1)) {
11221 4255051 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
11222 : } else {
11223 38027823 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOffMassFlow; // these need to be set for multi-speed coils
11224 : }
11225 87851086 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
11226 43925543 : state.dataUnitarySystems->CompOnMassFlow; // doesn't hurt to set these if multi-speed coils are not used
11227 43925543 : state.dataHVACGlobal->MSUSEconoSpeedNum = this->m_EconoSpeedNum;
11228 :
11229 43925543 : state.dataUnitarySystems->m_massFlow1 = state.dataUnitarySystems->CompOnMassFlow;
11230 43925543 : state.dataUnitarySystems->m_massFlow2 = state.dataUnitarySystems->CompOffMassFlow;
11231 :
11232 : // Set the system mass flow rates
11233 43925543 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
11234 43925543 : }
11235 :
11236 75373805 : void UnitarySys::setAverageAirFlow(EnergyPlusData &state,
11237 : Real64 const PartLoadRatio, // unit part load ratio
11238 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
11239 : )
11240 : {
11241 :
11242 : // SUBROUTINE INFORMATION:
11243 : // AUTHOR Richard Raustad
11244 : // DATE WRITTEN July 2005
11245 :
11246 : // PURPOSE OF THIS SUBROUTINE:
11247 : // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
11248 : // Set OnOffAirFlowRatio to be used by DX coils
11249 :
11250 : // METHODOLOGY EMPLOYED:
11251 : // The air flow rate in cooling, heating, and no cooling or heating can be different.
11252 : // Calculate the air flow rate based on initializations.
11253 :
11254 75373805 : Real64 AverageUnitMassFlow = 0.0; // average supply air mass flow rate over time step
11255 75373805 : bool FanOn = false;
11256 :
11257 75373805 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
11258 75373805 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11259 :
11260 75373805 : Real64 FanPartLoadRatio = PartLoadRatio;
11261 75373805 : if (this->m_SimASHRAEModel) {
11262 0 : FanPartLoadRatio = this->FanPartLoadRatio;
11263 : }
11264 75373805 : if (this->m_EconoPartLoadRatio > 0) {
11265 621219 : FanPartLoadRatio = this->m_EconoPartLoadRatio;
11266 : }
11267 75373805 : int SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum, this->m_EconoSpeedNum);
11268 75373805 : int InletNode = this->AirInNode;
11269 :
11270 75373805 : if (SpeedNum > 1) {
11271 8955309 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11272 939470 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11273 7996524 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11274 6399683 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow +
11275 6399683 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow;
11276 : } else {
11277 1596841 : Real64 tempSpeedRatio = 0;
11278 1596841 : if (this->m_EconoPartLoadRatio > 0) {
11279 173349 : tempSpeedRatio = this->FanPartLoadRatio;
11280 : } else {
11281 1423492 : tempSpeedRatio = state.dataUnitarySystems->CoolingLoad ? this->m_CoolingSpeedRatio : this->m_HeatingSpeedRatio;
11282 : }
11283 1596841 : AverageUnitMassFlow = tempSpeedRatio * state.dataUnitarySystems->CompOnMassFlow +
11284 1596841 : (1.0 - tempSpeedRatio) * state.dataUnitarySystems->CompOffMassFlow;
11285 : }
11286 : } else {
11287 19315 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11288 : }
11289 : } else {
11290 67357966 : AverageUnitMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow) +
11291 67357966 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow);
11292 : }
11293 :
11294 75373805 : if (state.dataUnitarySystems->CompOffFlowRatio > 0.0) {
11295 45315208 : if (SpeedNum > 1) {
11296 8938146 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11297 931693 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11298 7994915 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio +
11299 7994915 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio;
11300 7994915 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11301 7994915 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11302 : } else {
11303 11538 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11304 11538 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11305 11538 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11306 : }
11307 : } else {
11308 37308755 : state.dataUnitarySystems->FanSpeedRatio = (FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio) +
11309 37308755 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio);
11310 37308755 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11311 37308755 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11312 : }
11313 : } else {
11314 30058597 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11315 30058597 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11316 30058597 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11317 : }
11318 :
11319 75373805 : if (!(state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating == 0)) {
11320 49070703 : if (this->m_SingleMode == 1) {
11321 76083 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11322 0 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11323 0 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11324 0 : state.dataUnitarySystems->m_runTimeFraction1 = 1.0;
11325 0 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11326 : } else {
11327 76083 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow;
11328 76083 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio;
11329 76083 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11330 76083 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11331 : }
11332 : }
11333 : }
11334 :
11335 75373805 : if (this->OAMixerExists) {
11336 40933198 : Real64 AverageOAMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->OACompOnMassFlow) +
11337 40933198 : ((1 - FanPartLoadRatio) * state.dataUnitarySystems->OACompOffMassFlow);
11338 :
11339 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = AverageOAMassFlow;
11340 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = AverageOAMassFlow;
11341 : // don't need to set relief node, delete them when working
11342 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = AverageOAMassFlow;
11343 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = AverageOAMassFlow;
11344 : }
11345 :
11346 : // BEGIN - refactor/move this to Init during FirstHVACIteration, need struct or module level global for turnFansOn and turnFansOff
11347 : // If the unitary system is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
11348 75373805 : FanOn = (this->m_FanExists) ? (this->m_fanAvailSched->getCurrentVal() > 0) : true;
11349 : // END - move this to Init during FirstHVACIteration
11350 :
11351 75373805 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && ((FanOn || state.dataHVACGlobal->TurnFansOn) && !state.dataHVACGlobal->TurnFansOff)) {
11352 74482121 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11353 : // set point based equipment should use VAV terminal units to set the flow.
11354 : // zone equipment needs to set flow since no other device regulates flow (ZoneHVAC /= AirLoopEquipment)
11355 22618 : if (!this->m_AirLoopEquipment) {
11356 0 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11357 0 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11358 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11359 : }
11360 22618 : if (AverageUnitMassFlow > 0.0) {
11361 22618 : OnOffAirFlowRatio = 1.0;
11362 : } else {
11363 0 : OnOffAirFlowRatio = 0.0;
11364 : }
11365 : } else {
11366 74459503 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11367 74459503 : if (!this->m_AirLoopEquipment) {
11368 43369493 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11369 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11370 : }
11371 74459503 : if (AverageUnitMassFlow > 0.0) {
11372 63385266 : if (SpeedNum > 1) {
11373 7960028 : OnOffAirFlowRatio = 1.0;
11374 : } else {
11375 55425238 : OnOffAirFlowRatio = state.dataUnitarySystems->CompOnMassFlow / AverageUnitMassFlow;
11376 : }
11377 : } else {
11378 11074237 : OnOffAirFlowRatio = 0.0;
11379 : }
11380 : }
11381 : } else {
11382 891684 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
11383 : // fan will turn on unless these are reset, or maybe one of them. Might be a better way when calling fan.
11384 891684 : state.dataUnitarySystems->m_massFlow1 = 0.0;
11385 891684 : state.dataUnitarySystems->m_massFlow2 = 0.0;
11386 891684 : OnOffAirFlowRatio = 1.0;
11387 891684 : if (this->OAMixerExists) {
11388 : // maybe can just set MaxAvail = 0?
11389 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = 0.0;
11390 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = 0.0;
11391 : // don't need to set relief node, delete then when working
11392 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = 0.0;
11393 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = 0.0;
11394 : }
11395 : }
11396 75373805 : }
11397 :
11398 43525978 : void UnitarySys::calcUnitarySystemToLoad(EnergyPlusData &state,
11399 : int const AirLoopNum, // index to air loop
11400 : bool const FirstHVACIteration, // True when first HVAC iteration
11401 : Real64 const CoolPLR, // operating cooling part-load ratio []
11402 : Real64 const HeatPLR, // operating cooling part-load ratio []
11403 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
11404 : Real64 &SensOutput, // sensible capacity (W)
11405 : Real64 &LatOutput, // latent capacity (W)
11406 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
11407 : Real64 HeatCoilLoad, // Adjusted load to heating coil when SAT exceeds max limit (W)
11408 : Real64 SuppCoilLoad, // Adjusted load to supp heating coil when SAT exceeds max limit (W)
11409 : HVAC::CompressorOp const CompressorOn // Determines if compressor is on or off
11410 : )
11411 : {
11412 :
11413 : // SUBROUTINE INFORMATION:
11414 : // AUTHOR Richard Raustad, FSEC
11415 : // DATE WRITTEN February 2013
11416 :
11417 : // PURPOSE OF THIS SUBROUTINE:
11418 : // This subroutine calculates the resulting performance of the unitary system given
11419 : // the operating PLR. System output is calculated with respect to zone condition.
11420 :
11421 43525978 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
11422 :
11423 43525978 : HVAC::CompressorOp CoolingCompOn = HVAC::CompressorOp::Off;
11424 43525978 : if (CoolPLR > 0) {
11425 15931127 : CoolingCompOn = CompressorOn;
11426 27594851 : } else if (CoolPLR == 0 && this->m_EconoSpeedNum > 0) { // turn compressor off for economizer calculations
11427 543879 : CoolingCompOn = HVAC::CompressorOp::Off;
11428 27050972 : } else if (this->m_CoolingSpeedNum > 1) { // for multispeed coils, comp is on IF speed > 1
11429 489853 : CoolingCompOn = HVAC::CompressorOp::On;
11430 : }
11431 :
11432 43525978 : HVAC::CompressorOp HeatingCompOn = HVAC::CompressorOp::Off;
11433 43525978 : if (HeatPLR > 0) {
11434 11775009 : HeatingCompOn = CompressorOn;
11435 11775009 : CoilCoolHeatRat = min(1.0, CoolPLR / HeatPLR);
11436 : }
11437 : // for multispeed coils, comp is on at PLR=0 IF speed > 1
11438 43525978 : if (this->m_HeatingSpeedNum > 1) {
11439 675739 : HeatingCompOn = HVAC::CompressorOp::On;
11440 : }
11441 :
11442 : // set the operating flow rate
11443 43525978 : if (this->m_NumOfSpeedCooling > 0 || this->m_NumOfSpeedHeating > 0) {
11444 27815872 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, max(CoolPLR, HeatPLR));
11445 : } else {
11446 15710106 : this->setAverageAirFlow(state, max(CoolPLR, HeatPLR), OnOffAirFlowRatio);
11447 : }
11448 :
11449 : // Call the series of components that simulate a Unitary System
11450 43525978 : if (this->ATMixerExists) {
11451 : // There is an air terminal mixer
11452 995259 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
11453 : // set the primary air inlet mass flow rate
11454 680709 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
11455 680709 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
11456 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
11457 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
11458 680709 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11459 : }
11460 : }
11461 43525978 : if (this->OAMixerExists) {
11462 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
11463 : // use of a blank std::string is not great here, but I'm not ready to change this API at the moment, so passing a static blank string is
11464 : // at least better than constructing a new string each time to call this function
11465 23591795 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
11466 : }
11467 :
11468 43525978 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
11469 30616368 : state.dataFans->fans(this->m_FanIndex)
11470 91849104 : ->simulate(state,
11471 : FirstHVACIteration,
11472 30616368 : state.dataUnitarySystems->FanSpeedRatio,
11473 : _, // Pressure rise
11474 : _, // Flow fraction
11475 30616368 : state.dataUnitarySystems->m_massFlow1,
11476 30616368 : state.dataUnitarySystems->m_runTimeFraction1,
11477 30616368 : state.dataUnitarySystems->m_massFlow2,
11478 30616368 : state.dataUnitarySystems->m_runTimeFraction2,
11479 : _);
11480 : }
11481 :
11482 43525978 : if (this->m_CoolingCoilUpstream) {
11483 :
11484 42280256 : if (this->m_CoolCoilExists) {
11485 42280256 : this->calcUnitaryCoolingSystem(
11486 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11487 : }
11488 42280256 : if (this->m_HeatCoilExists) {
11489 : // operate the heating coil without regard to coil outlet temperature
11490 41641482 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11491 41641482 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11492 719755 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11493 719755 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11494 719755 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11495 719755 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11496 719755 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11497 719755 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11498 719755 : HeatCoilLoad = MaxHeatCoilLoad;
11499 : }
11500 : }
11501 :
11502 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11503 42280256 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11504 3265888 : state.dataFans->fans(this->m_FanIndex)
11505 9797664 : ->simulate(state,
11506 : FirstHVACIteration,
11507 3265888 : state.dataUnitarySystems->FanSpeedRatio,
11508 : _, // Pressure rise
11509 : _, // Flow fraction
11510 3265888 : state.dataUnitarySystems->m_massFlow1,
11511 3265888 : state.dataUnitarySystems->m_runTimeFraction1,
11512 3265888 : state.dataUnitarySystems->m_massFlow2,
11513 3265888 : state.dataUnitarySystems->m_runTimeFraction2,
11514 : _);
11515 :
11516 3265888 : if (this->m_CoolCoilExists) {
11517 3265888 : this->calcUnitaryCoolingSystem(
11518 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11519 : }
11520 3265888 : if (this->m_HeatCoilExists) {
11521 3265330 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11522 3265330 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11523 23036 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11524 23036 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11525 23036 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11526 23036 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11527 23036 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11528 23036 : this->calcUnitaryHeatingSystem(
11529 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11530 : }
11531 : }
11532 : }
11533 :
11534 : } else {
11535 :
11536 1245722 : if (this->m_HeatCoilExists) {
11537 1245722 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11538 1245722 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11539 167072 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11540 167072 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11541 167072 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11542 167072 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11543 167072 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11544 167072 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11545 : }
11546 : }
11547 1245722 : if (this->m_CoolCoilExists) {
11548 1245722 : this->calcUnitaryCoolingSystem(
11549 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11550 : }
11551 :
11552 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11553 1245722 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11554 18379 : state.dataFans->fans(this->m_FanIndex)
11555 55137 : ->simulate(state,
11556 : FirstHVACIteration,
11557 18379 : state.dataUnitarySystems->FanSpeedRatio,
11558 : _, // Pressure rise
11559 : _, // Flow fraction
11560 18379 : state.dataUnitarySystems->m_massFlow1,
11561 18379 : state.dataUnitarySystems->m_runTimeFraction1,
11562 18379 : state.dataUnitarySystems->m_massFlow2,
11563 18379 : state.dataUnitarySystems->m_runTimeFraction2,
11564 : _);
11565 :
11566 18379 : if (this->m_HeatCoilExists) {
11567 18379 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11568 18379 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11569 8516 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11570 8516 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11571 8516 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11572 8516 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11573 8516 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11574 8516 : this->calcUnitaryHeatingSystem(
11575 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11576 : }
11577 : }
11578 18379 : if (this->m_CoolCoilExists) {
11579 18379 : this->calcUnitaryCoolingSystem(
11580 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11581 : }
11582 : }
11583 : }
11584 :
11585 43525978 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
11586 12909610 : state.dataFans->fans(this->m_FanIndex)
11587 38728830 : ->simulate(state,
11588 : FirstHVACIteration,
11589 12909610 : state.dataUnitarySystems->FanSpeedRatio,
11590 : _, // Pressure rise
11591 : _, // Flow fraction
11592 12909610 : state.dataUnitarySystems->m_massFlow1,
11593 12909610 : state.dataUnitarySystems->m_runTimeFraction1,
11594 12909610 : state.dataUnitarySystems->m_massFlow2,
11595 12909610 : state.dataUnitarySystems->m_runTimeFraction2,
11596 : _);
11597 : }
11598 43525978 : if (this->m_SuppCoilExists) {
11599 22073874 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, SuppCoilLoad);
11600 22078562 : if ((state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp) && this->m_SuppHeatPartLoadFrac > 0.0 &&
11601 4688 : !this->m_SimASHRAEModel) {
11602 : // EMS override will ignore this recalculation.
11603 4688 : Real64 MDotAir = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).MassFlowRate;
11604 4688 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).HumRat +
11605 4688 : state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).HumRat));
11606 4688 : Real64 HCDeltaT = max(0.0, this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).Temp);
11607 4688 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11608 4688 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, MaxHeatCoilLoad);
11609 4688 : SuppCoilLoad = MaxHeatCoilLoad;
11610 : }
11611 : }
11612 :
11613 : // If there is a supply side air terminal mixer, calculate its output
11614 43525978 : if (this->ATMixerExists) {
11615 995259 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11616 314550 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11617 : }
11618 : }
11619 :
11620 43525978 : calculateCapacity(state, SensOutput, LatOutput);
11621 43525978 : }
11622 :
11623 302026 : void UnitarySys::calcMultiStageSuppCoilStageByLoad(EnergyPlusData &state, Real64 const SuppHeatLoad, bool const FirstHVACIteration)
11624 : {
11625 302026 : if (SuppHeatLoad <= 0.0) {
11626 293002 : this->m_SuppHeatPartLoadFrac = 0.0;
11627 293002 : this->m_SuppHeatingSpeedRatio = 0.0;
11628 293002 : this->m_SuppHeatingCycRatio = 0.0;
11629 297458 : return;
11630 : }
11631 9024 : constexpr bool SuppHeatingCoilFlag(true);
11632 9024 : Real64 PartLoadFrac = 0.0;
11633 9024 : Real64 SpeedRatio = 0.0;
11634 9024 : Real64 CycRatio = 0.0;
11635 9024 : std::string CompName = this->m_SuppHeatCoilName;
11636 9024 : int CompIndex = this->m_SuppHeatCoilIndex;
11637 9024 : HVAC::FanOp fanOp = this->m_FanOpMode;
11638 9024 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
11639 9024 : int SpeedNum = 0;
11640 : // Get full load result
11641 9024 : PartLoadFrac = 1.0;
11642 9024 : CycRatio = 1.0;
11643 9024 : SpeedRatio = 1.0;
11644 9024 : int SolFla = 0;
11645 :
11646 : // SUBROUTINE PARAMETER DEFINITIONS:
11647 9024 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11648 9024 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
11649 :
11650 30680 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
11651 26224 : this->m_SuppHeatingSpeedNum = SpeedNum;
11652 26224 : HeatingCoils::SimulateHeatingCoilComponents(state,
11653 : CompName,
11654 : FirstHVACIteration,
11655 : SuppHeatLoad,
11656 : CompIndex,
11657 : QCoilActual,
11658 : SuppHeatingCoilFlag,
11659 : fanOp,
11660 : PartLoadFrac,
11661 : SpeedNum,
11662 : SpeedRatio);
11663 26224 : if (QCoilActual > SuppHeatLoad) {
11664 4568 : break;
11665 : }
11666 : }
11667 9024 : if (QCoilActual < SuppHeatLoad) {
11668 4456 : this->m_SuppHeatPartLoadFrac = 1.0;
11669 4456 : this->m_SuppHeatingSpeedRatio = 1.0;
11670 4456 : this->m_SuppHeatingCycRatio = 1.0;
11671 4456 : this->m_SuppHeatingSpeedNum = this->m_NumOfSpeedSuppHeating;
11672 4456 : return;
11673 : } else {
11674 :
11675 4568 : if (this->m_SuppHeatingSpeedNum > 1.0) {
11676 13692 : auto f = [&state, this, CycRatio, fanOp, SuppHeatLoad](Real64 const SpeedRatio) {
11677 : Real64 QActual;
11678 13692 : int CoilIndex = this->m_SuppHeatCoilIndex;
11679 13692 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11680 13692 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11681 13692 : return SuppHeatLoad - QActual;
11682 4564 : };
11683 :
11684 4564 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
11685 4564 : this->m_SuppHeatingCycRatio = CycRatio;
11686 4564 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11687 4564 : this->m_SuppHeatPartLoadFrac = SpeedRatio;
11688 4564 : PartLoadFrac = SpeedRatio;
11689 : } else {
11690 4 : SpeedRatio = 0.0;
11691 4 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11692 12 : auto f = [&state, this, SpeedRatio, fanOp, SuppHeatLoad](Real64 const CycRatio) {
11693 : Real64 QActual;
11694 12 : int CoilIndex = this->m_SuppHeatCoilIndex;
11695 12 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11696 12 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11697 12 : return SuppHeatLoad - QActual;
11698 4 : };
11699 :
11700 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
11701 4 : this->m_SuppHeatingCycRatio = CycRatio;
11702 4 : this->m_SuppHeatPartLoadFrac = CycRatio;
11703 4 : PartLoadFrac = CycRatio;
11704 : }
11705 : }
11706 9024 : }
11707 :
11708 47206442 : void UnitarySys::calculateCapacity(EnergyPlusData &state, Real64 &SensOutput, Real64 &LatOutput)
11709 : {
11710 :
11711 : // Check delta T (outlet to reference temp), IF positive use reference HumRat ELSE outlet humrat to calculate
11712 : // sensible capacity as MdotDeltaH at constant humidity ratio
11713 47206442 : int OutletNode = this->AirOutNode;
11714 47206442 : Real64 AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
11715 47206442 : Real64 RefTemp = 0.0;
11716 47206442 : Real64 RefHumRat = 0.0;
11717 47206442 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11718 3680464 : RefTemp = state.dataLoopNodes->Node(this->AirInNode).Temp;
11719 3680464 : RefHumRat = state.dataLoopNodes->Node(this->AirInNode).HumRat;
11720 : } else {
11721 43525978 : RefTemp = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp;
11722 43525978 : RefHumRat = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat;
11723 : }
11724 47206442 : Real64 SensibleOutput(0.0); // sensible output rate, {W}
11725 47206442 : Real64 LatentOutput(0.0); // latent output rate, {W}
11726 47206442 : Real64 TotalOutput(0.0); // total output rate, {W}
11727 : // calculate sensible load met
11728 47206442 : if (this->ATMixerExists) {
11729 995259 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11730 : // Air terminal supply side mixer
11731 314550 : int ATMixOutNode = this->ATMixerOutNode;
11732 314550 : CalcZoneSensibleLatentOutput(state.dataLoopNodes->Node(ATMixOutNode).MassFlowRate,
11733 314550 : state.dataLoopNodes->Node(ATMixOutNode).Temp,
11734 314550 : state.dataLoopNodes->Node(ATMixOutNode).HumRat,
11735 : RefTemp,
11736 : RefHumRat,
11737 : SensibleOutput,
11738 : LatentOutput,
11739 : TotalOutput);
11740 314550 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11741 314550 : if (this->m_Humidistat) {
11742 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11743 : } else {
11744 314550 : LatOutput = 0.0;
11745 : }
11746 : } else {
11747 : // Air terminal inlet side mixer
11748 1361418 : CalcZoneSensibleLatentOutput(AirMassFlow,
11749 680709 : state.dataLoopNodes->Node(OutletNode).Temp,
11750 680709 : state.dataLoopNodes->Node(OutletNode).HumRat,
11751 : RefTemp,
11752 : RefHumRat,
11753 : SensibleOutput,
11754 : LatentOutput,
11755 : TotalOutput);
11756 680709 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11757 680709 : if (this->m_Humidistat) {
11758 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11759 : } else {
11760 680709 : LatOutput = 0.0;
11761 : }
11762 : }
11763 : } else {
11764 : // Calculate sensible load met
11765 92422366 : CalcZoneSensibleLatentOutput(AirMassFlow,
11766 46211183 : state.dataLoopNodes->Node(OutletNode).Temp,
11767 46211183 : state.dataLoopNodes->Node(OutletNode).HumRat,
11768 : RefTemp,
11769 : RefHumRat,
11770 : SensibleOutput,
11771 : LatentOutput,
11772 : TotalOutput);
11773 46211183 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11774 46211183 : if (this->m_Humidistat) {
11775 1649021 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11776 : } else {
11777 44562162 : LatOutput = 0.0;
11778 : }
11779 : }
11780 47206442 : this->m_SensibleLoadMet = SensOutput;
11781 47206442 : this->m_LatentLoadMet = LatOutput;
11782 47206442 : }
11783 :
11784 50520320 : void UnitarySys::calcUnitaryCoolingSystem(EnergyPlusData &state,
11785 : int const AirLoopNum, // index to air loop
11786 : bool const FirstHVACIteration, // True when first HVAC iteration
11787 : Real64 const PartLoadRatio, // coil operating part-load ratio
11788 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11789 : Real64 const OnOffAirFlowRatio,
11790 : Real64 const CoilCoolHeatRat, // ratio of cooling to heating PLR for cycling fan RH control
11791 : bool const HXUnitOn // Flag to control HX for HXAssisted Cooling Coil
11792 : )
11793 : {
11794 :
11795 : // SUBROUTINE INFORMATION:
11796 : // AUTHOR Richard Raustad, FSEC
11797 : // DATE WRITTEN February 2013
11798 :
11799 : // PURPOSE OF THIS SUBROUTINE:
11800 : // This subroutine manages unitary cooling system component simulation.
11801 :
11802 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11803 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11804 : Real64 mdot; // water side flow rate (kg/s)
11805 : Real64 QActual; // actual coil output (W)
11806 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11807 :
11808 : // Simulate the coil component
11809 50520320 : std::string CompName = this->m_CoolingCoilName;
11810 50520320 : int CompIndex = this->m_CoolingCoilIndex;
11811 50520320 : Real64 CoilPLR = 1.0;
11812 50520320 : if (this->m_CondenserNodeNum != 0) {
11813 28994214 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11814 : // IF node is not connected to anything, pressure = default, use weather data
11815 28994214 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11816 2125 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11817 : } else {
11818 28992089 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11819 : }
11820 : } else {
11821 21526106 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11822 : }
11823 :
11824 50520320 : switch (this->m_CoolingCoilType_Num) {
11825 13151489 : case HVAC::CoilDX_CoolingSingleSpeed: { // Coil:Cooling:DX:SingleSpeed
11826 13151489 : DXCoils::SimDXCoil(state,
11827 : blankString,
11828 : CompressorOn,
11829 : FirstHVACIteration,
11830 : CompIndex,
11831 : this->m_FanOpMode,
11832 : PartLoadRatio,
11833 : OnOffAirFlowRatio,
11834 : CoilCoolHeatRat);
11835 13151489 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11836 13151489 : } break;
11837 10898513 : case HVAC::CoilDX_Cooling: { // CoilCoolingDX
11838 10898513 : bool const singleMode = (this->m_SingleMode == 1);
11839 10898513 : CoilPLR = 0.0;
11840 10898513 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11841 76796 : if (CompressorOn == HVAC::CompressorOp::On) {
11842 65028 : CoilPLR = (this->m_CoolingSpeedNum > 1) ? m_CoolingSpeedRatio : PartLoadRatio;
11843 : }
11844 : } else {
11845 10821717 : if (this->m_EMSOverrideCoilSpeedNumOn) {
11846 146884 : CoilPLR = this->m_CoolingSpeedRatio;
11847 : } else {
11848 10674833 : if (state.dataUnitarySystems->CoolingLoad) {
11849 7067224 : if (CompressorOn == HVAC::CompressorOp::Off) {
11850 2386437 : if (this->m_CoolingSpeedNum > 1) { // NOTE: Cooling speed 0 should behave the same as speed 1, but doesn't, and must be
11851 : // allowed to pass into the simulation code
11852 6381 : this->m_CoolingSpeedNum = 1; // Bypass mixed-speed calculations in called functions
11853 : }
11854 : } else {
11855 4680787 : if (singleMode) {
11856 26368 : CoilPLR = (this->m_CoolingSpeedNum == 1)
11857 26368 : ? PartLoadRatio
11858 : : 1.0; // singleMode allows cycling, but not part load operation at higher speeds
11859 : } else {
11860 4654419 : CoilPLR = PartLoadRatio;
11861 : }
11862 : }
11863 : }
11864 : }
11865 : }
11866 :
11867 10898513 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
11868 10898513 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
11869 76864 : coilMode = HVAC::CoilMode::SubcoolReheat;
11870 10821649 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
11871 0 : coilMode = HVAC::CoilMode::Enhanced;
11872 : }
11873 :
11874 10898513 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
11875 : state, coilMode, this->m_CoolingSpeedNum, CoilPLR, this->m_FanOpMode, singleMode, this->CoilSHR);
11876 :
11877 10898513 : if (this->m_CoolingSpeedNum > 1) {
11878 2964820 : if (this->m_SingleMode == 0) {
11879 2941524 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11880 : } else {
11881 23296 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11882 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11883 23296 : this->m_CoolingSpeedRatio = 1.0;
11884 : }
11885 : } else {
11886 7933693 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11887 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11888 7933693 : this->m_CoolingSpeedRatio = 0.0;
11889 : }
11890 10898513 : } break;
11891 30043 : case HVAC::CoilDX_CoolingHXAssisted:
11892 : case HVAC::CoilWater_CoolingHXAssisted: {
11893 30043 : if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
11894 : mdot =
11895 0 : min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxCoolCoilFluidFlow * PartLoadRatio);
11896 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11897 : }
11898 60086 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
11899 : blankString,
11900 : FirstHVACIteration,
11901 : CompressorOn,
11902 : PartLoadRatio,
11903 : CompIndex,
11904 : this->m_FanOpMode,
11905 : HXUnitOn,
11906 : OnOffAirFlowRatio,
11907 30043 : state.dataUnitarySystems->economizerFlag,
11908 : _,
11909 30043 : this->m_DehumidificationMode,
11910 30043 : 0.0); // this->CoilSHR);
11911 30043 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
11912 30043 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11913 : }
11914 30043 : } break;
11915 1072657 : case HVAC::CoilDX_CoolingTwoSpeed: { // Coil:Cooling:DX:TwoSpeed
11916 : // formerly (v3 and beyond)COIL:DX:MULTISPEED:COOLINGEMPIRICAL
11917 1072657 : DXCoils::SimDXCoilMultiSpeed(state, blankString, this->m_CoolingSpeedRatio, this->m_CoolingCycRatio, CompIndex);
11918 1072657 : if (this->m_CoolingSpeedRatio > 0.0) {
11919 351540 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingSpeedRatio : 0.0;
11920 : } else {
11921 721117 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11922 : }
11923 1072657 : } break;
11924 4382138 : case HVAC::CoilDX_MultiSpeedCooling: { // Coil:Cooling:DX:Multispeed
11925 4382138 : if (OutsideDryBulbTemp > this->m_MinOATCompressorCooling) {
11926 4382138 : DXCoils::SimDXCoilMultiSpeed(state,
11927 : CompName,
11928 : this->m_CoolingSpeedRatio,
11929 : this->m_CoolingCycRatio,
11930 : CompIndex,
11931 4382138 : this->m_CoolingSpeedNum,
11932 4382138 : this->m_FanOpMode,
11933 : CompressorOn,
11934 4382138 : this->m_SingleMode);
11935 4382138 : if (this->m_CoolingSpeedNum > 1) {
11936 894945 : if (this->m_SingleMode == 0) {
11937 894945 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11938 : } else {
11939 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11940 : }
11941 : } else {
11942 3487193 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11943 : }
11944 : } else {
11945 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 0.0, CompIndex, this->m_CoolingSpeedNum, this->m_FanOpMode, CompressorOn);
11946 0 : this->m_CoolCompPartLoadRatio = 0.0;
11947 : }
11948 4382138 : } break;
11949 48603 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
11950 : // formerly (v3 and beyond) COIL:DX:MULTIMODE:COOLINGEMPIRICAL
11951 48603 : DXCoils::SimDXCoilMultiMode(
11952 : state, CompName, CompressorOn, FirstHVACIteration, PartLoadRatio, this->m_DehumidificationMode, CompIndex, this->m_FanOpMode);
11953 48603 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11954 48603 : } break;
11955 0 : case HVAC::Coil_UserDefined: {
11956 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11957 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
11958 :
11959 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
11960 0 : } break;
11961 1364358 : case HVAC::Coil_CoolingWater:
11962 : case HVAC::Coil_CoolingWaterDetailed: {
11963 1364358 : if (this->CoolCoilWaterFlowRatio == 0.0) {
11964 1364358 : mdot = this->MaxCoolCoilFluidFlow * PartLoadRatio;
11965 : } else {
11966 0 : mdot = this->CoolCoilWaterFlowRatio * this->MaxCoolCoilFluidFlow;
11967 : }
11968 1364358 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11969 4093074 : WaterCoils::SimulateWaterCoilComponents(
11970 2728716 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11971 1364358 : } break;
11972 1821339 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
11973 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
11974 1821339 : if (this->m_CoolingSpeedNum > 1) {
11975 306991 : CoilPLR = 1.0;
11976 : } else {
11977 1514348 : CoilPLR = PartLoadRatio;
11978 : }
11979 1821339 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11980 : CompName,
11981 : CompIndex,
11982 : this->m_FanOpMode,
11983 : CompressorOn,
11984 : CoilPLR,
11985 : this->m_CoolingSpeedNum,
11986 : this->m_CoolingSpeedRatio,
11987 : this->m_CoolingCoilSensDemand,
11988 : this->m_CoolingCoilLatentDemand,
11989 : OnOffAirFlowRatio);
11990 1821339 : if (this->m_CoolingSpeedNum > 1) {
11991 306991 : this->m_CoolCompPartLoadRatio = 1.0;
11992 : } else {
11993 1514348 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11994 : }
11995 1821339 : } break;
11996 17305458 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
11997 :
11998 17305458 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11999 : blankString,
12000 17305458 : this->m_CoolingCoilIndex,
12001 : this->m_CoolingCoilSensDemand,
12002 : this->m_CoolingCoilLatentDemand,
12003 : this->m_FanOpMode,
12004 : CompressorOn,
12005 : PartLoadRatio,
12006 : FirstHVACIteration);
12007 17305458 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
12008 17305458 : } break;
12009 416870 : case HVAC::Coil_CoolingWaterToAirHP: {
12010 :
12011 416870 : WaterToAirHeatPump::SimWatertoAirHP(state,
12012 : blankString,
12013 416870 : this->m_CoolingCoilIndex,
12014 : this->MaxCoolAirMassFlow,
12015 : this->m_FanOpMode,
12016 : FirstHVACIteration,
12017 416870 : this->m_InitHeatPump,
12018 : this->m_CoolingCoilSensDemand,
12019 : this->m_CoolingCoilLatentDemand,
12020 : CompressorOn,
12021 : PartLoadRatio);
12022 :
12023 416870 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
12024 416870 : } break;
12025 28852 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
12026 28852 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, PartLoadRatio);
12027 28852 : } break;
12028 0 : default:
12029 0 : break;
12030 : }
12031 :
12032 50520320 : this->m_CoolingPartLoadFrac = PartLoadRatio;
12033 50520320 : }
12034 :
12035 47220986 : void UnitarySys::calcUnitaryHeatingSystem(EnergyPlusData &state,
12036 : int const AirLoopNum, // index to air loop
12037 : bool const FirstHVACIteration, // True when first HVAC iteration
12038 : Real64 const PartLoadRatio, // coil operating part-load ratio
12039 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
12040 : Real64 const OnOffAirFlowRatio, // ratio of on to off flow rate
12041 : Real64 HeatCoilLoad // adjusted heating coil load if outlet temp exceeds max (W)
12042 : )
12043 : {
12044 :
12045 : // SUBROUTINE INFORMATION:
12046 : // AUTHOR Richard Raustad, FSEC
12047 : // DATE WRITTEN February 2013
12048 :
12049 : // PURPOSE OF THIS SUBROUTINE:
12050 : // This subroutine manages unitary heating system component simulation.
12051 :
12052 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12053 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
12054 : Real64 mdot; // water side flow rate (kg/s)
12055 : Real64 QActual; // actual output of coil (W)
12056 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
12057 :
12058 47220986 : std::string CompName = this->m_HeatingCoilName;
12059 47220986 : Real64 dummy = 0.0;
12060 47220986 : Real64 HeatPLR = 1.0;
12061 47220986 : if (this->m_CondenserNodeNum != 0) {
12062 29527251 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
12063 : // IF node is not connected to anything, pressure = default, use weather data
12064 29527251 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12065 2219 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
12066 : } else {
12067 29525032 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12068 : }
12069 : } else {
12070 17693735 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
12071 : }
12072 :
12073 47220986 : switch (this->m_HeatingCoilType_Num) {
12074 2203590 : case HVAC::CoilDX_HeatingEmpirical: { // COIL:HEATING:DX:SINGLESPEED
12075 4407180 : DXCoils::SimDXCoil(
12076 2203590 : state, CompName, CompressorOn, FirstHVACIteration, this->m_HeatingCoilIndex, this->m_FanOpMode, PartLoadRatio, OnOffAirFlowRatio);
12077 2203590 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12078 2203590 : } break;
12079 0 : case HVAC::Coil_UserDefined: {
12080 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12081 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12082 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_HeatingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12083 0 : } break;
12084 20732195 : case HVAC::Coil_HeatingGasOrOtherFuel:
12085 : case HVAC::Coil_HeatingElectric: {
12086 20732195 : HeatCoilLoad = PartLoadRatio * m_DesignHeatingCapacity;
12087 82928780 : HeatingCoils::SimulateHeatingCoilComponents(
12088 62196585 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
12089 20732195 : } break;
12090 0 : case HVAC::Coil_HeatingDesuperheater: {
12091 0 : HeatingCoils::SimulateHeatingCoilComponents(
12092 0 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
12093 :
12094 0 : } break;
12095 4990992 : case HVAC::CoilDX_MultiSpeedHeating: {
12096 4990992 : if (OutsideDryBulbTemp > this->m_MinOATCompressorHeating) {
12097 4607858 : DXCoils::SimDXCoilMultiSpeed(state,
12098 : CompName,
12099 : this->m_HeatingSpeedRatio,
12100 : this->m_HeatingCycRatio,
12101 4607858 : this->m_HeatingCoilIndex,
12102 4607858 : this->m_HeatingSpeedNum,
12103 4607858 : this->m_FanOpMode,
12104 : CompressorOn,
12105 4607858 : this->m_SingleMode);
12106 4607858 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12107 : } else {
12108 766268 : DXCoils::SimDXCoilMultiSpeed(
12109 383134 : state, CompName, 0.0, 0.0, this->m_HeatingCoilIndex, this->m_HeatingSpeedNum, this->m_FanOpMode, CompressorOn);
12110 383134 : this->m_HeatCompPartLoadRatio = 0.0;
12111 : }
12112 4990992 : } break;
12113 0 : case HVAC::Coil_HeatingElectric_MultiStage:
12114 : case HVAC::Coil_HeatingGas_MultiStage: {
12115 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12116 : CompName,
12117 : FirstHVACIteration,
12118 : _,
12119 0 : 0,
12120 : _,
12121 : _,
12122 0 : this->m_FanOpMode,
12123 : PartLoadRatio,
12124 0 : this->m_HeatingSpeedNum,
12125 0 : this->m_HeatingSpeedRatio);
12126 : // This doesn't look right when it was at higher speed
12127 : // this->m_HeatingCycRatio = PartLoadRatio;
12128 0 : } break;
12129 1184720 : case HVAC::Coil_HeatingWater: {
12130 1184720 : if (this->HeatCoilWaterFlowRatio == 0.0) {
12131 1184720 : mdot = this->MaxHeatCoilFluidFlow * PartLoadRatio;
12132 : } else {
12133 0 : mdot = this->HeatCoilWaterFlowRatio * this->MaxHeatCoilFluidFlow;
12134 : }
12135 1184720 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
12136 3554160 : WaterCoils::SimulateWaterCoilComponents(
12137 2369440 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
12138 1184720 : } break;
12139 55178 : case HVAC::Coil_HeatingSteam: {
12140 : // this same CALL is made in the steam coil calc routine
12141 55178 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxHeatCoilFluidFlow * PartLoadRatio);
12142 55178 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
12143 : // tried this to resolve the PackagedTerminalAirConditioner steam spike issue, no help, but this is the correct way to do this
12144 55178 : PlantUtilities::SetComponentFlowRate(
12145 55178 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
12146 : } else {
12147 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
12148 : }
12149 220712 : SteamCoils::SimulateSteamCoilComponents(state,
12150 : CompName,
12151 : FirstHVACIteration,
12152 55178 : this->m_HeatingCoilIndex,
12153 110356 : this->m_DesignHeatingCapacity * PartLoadRatio,
12154 : _,
12155 55178 : this->m_FanOpMode,
12156 : PartLoadRatio);
12157 55178 : } break;
12158 331464 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
12159 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
12160 331464 : if (this->m_HeatingSpeedNum > 1) {
12161 106030 : HeatPLR = 1.0;
12162 106030 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
12163 44092 : this->m_HeatingSpeedRatio = PartLoadRatio;
12164 : }
12165 : } else {
12166 225434 : HeatPLR = PartLoadRatio;
12167 : }
12168 :
12169 331464 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12170 : CompName,
12171 331464 : this->m_HeatingCoilIndex,
12172 : this->m_FanOpMode,
12173 : CompressorOn,
12174 : HeatPLR,
12175 : this->m_HeatingSpeedNum,
12176 : this->m_HeatingSpeedRatio,
12177 : this->m_HeatingCoilSensDemand,
12178 : dummy,
12179 : OnOffAirFlowRatio);
12180 331464 : if (this->m_HeatingSpeedNum > 1) {
12181 106030 : this->m_HeatCompPartLoadRatio = 1.0;
12182 : } else {
12183 225434 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12184 : }
12185 331464 : } break;
12186 17305977 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
12187 :
12188 17305977 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12189 : blankString,
12190 17305977 : this->m_HeatingCoilIndex,
12191 : this->m_HeatingCoilSensDemand,
12192 : dummy,
12193 : this->m_FanOpMode,
12194 : CompressorOn,
12195 : PartLoadRatio,
12196 : FirstHVACIteration);
12197 17305977 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12198 17305977 : } break;
12199 416870 : case HVAC::Coil_HeatingWaterToAirHP: {
12200 :
12201 416870 : WaterToAirHeatPump::SimWatertoAirHP(state,
12202 : blankString,
12203 416870 : this->m_HeatingCoilIndex,
12204 : this->MaxHeatAirMassFlow,
12205 : this->m_FanOpMode,
12206 : FirstHVACIteration,
12207 416870 : this->m_InitHeatPump,
12208 : this->m_HeatingCoilSensDemand,
12209 : dummy,
12210 : CompressorOn,
12211 : PartLoadRatio);
12212 416870 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12213 416870 : } break;
12214 0 : default: {
12215 0 : ShowFatalError(
12216 0 : state, format("CalcUnitaryHeatingSystem: Invalid Unitary System coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
12217 0 : } break;
12218 : }
12219 :
12220 47220986 : this->m_HeatingPartLoadFrac = PartLoadRatio;
12221 47220986 : }
12222 :
12223 22078562 : void UnitarySys::calcUnitarySuppHeatingSystem(EnergyPlusData &state,
12224 : bool const FirstHVACIteration, // True when first HVAC iteration
12225 : Real64 const SuppCoilLoad // adjusted supp coil load when outlet temp exceeds max (W)
12226 : )
12227 : {
12228 :
12229 : // SUBROUTINE INFORMATION:
12230 : // AUTHOR Richard Raustad, FSEC
12231 : // DATE WRITTEN February 2013
12232 :
12233 : // PURPOSE OF THIS SUBROUTINE:
12234 : // This subroutine manages supplemental heater simulation.
12235 :
12236 : // SUBROUTINE PARAMETER DEFINITIONS:
12237 22078562 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12238 22078562 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12239 :
12240 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12241 : // std::string CompName; // Name of Unitary System object
12242 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
12243 : Real64 QActual; // actual coil output (W)
12244 : Real64 mdot; // water coil water mass flow rate (kg/s)
12245 22078562 : std::vector<Real64> Par; // Parameter array passed to solver
12246 : Real64 PartLoadFrac; // temporary PLR variable
12247 :
12248 22078562 : Par.resize(5);
12249 : // work is needed to figure out how to adjust other coil types if outlet temp exceeds maximum
12250 : // this works for gas and electric heating coils
12251 22078562 : std::string CompName = this->m_SuppHeatCoilName;
12252 34263781 : if (state.dataEnvrn->OutDryBulbTemp <= this->m_MaxOATSuppHeat ||
12253 12185219 : (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolingPartLoadFrac > 0.0)) {
12254 9977703 : SuppHeatCoilLoad = SuppCoilLoad;
12255 : //} else {
12256 : // SuppHeatCoilLoad = this->m_DesignSuppHeatingCapacity * PartLoadRatio;
12257 : //}
12258 : } else {
12259 12100859 : SuppHeatCoilLoad = 0.0;
12260 : }
12261 22078562 : switch (this->m_SuppHeatCoilType_Num) {
12262 22078562 : case HVAC::Coil_HeatingGasOrOtherFuel:
12263 : case HVAC::Coil_HeatingElectric:
12264 : case HVAC::Coil_HeatingElectric_MultiStage: {
12265 22078562 : switch (this->m_ControlType) {
12266 0 : case UnitarySysCtrlType::Setpoint: {
12267 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12268 : CompName,
12269 : FirstHVACIteration,
12270 : SuppHeatCoilLoad,
12271 0 : this->m_SuppHeatCoilIndex,
12272 : _,
12273 0 : true,
12274 0 : this->m_FanOpMode,
12275 0 : this->m_SuppHeatPartLoadFrac,
12276 0 : this->m_SuppHeatingSpeedNum,
12277 0 : this->m_SuppHeatingSpeedRatio);
12278 0 : } break;
12279 22078562 : default: {
12280 22078562 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
12281 461070 : if (SuppHeatCoilLoad > 0.0) {
12282 94464 : this->setEMSSuppCoilStagePLR(state);
12283 : } else {
12284 366606 : this->m_SuppHeatingSpeedRatio = 0.0;
12285 366606 : this->m_SuppHeatingCycRatio = 0.0;
12286 366606 : this->m_SuppHeatPartLoadFrac = 0.0;
12287 : }
12288 : } else {
12289 21617492 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
12290 302026 : this->calcMultiStageSuppCoilStageByLoad(state, SuppHeatCoilLoad, FirstHVACIteration);
12291 : }
12292 : }
12293 66235686 : HeatingCoils::SimulateHeatingCoilComponents(state,
12294 : CompName,
12295 : FirstHVACIteration,
12296 : SuppHeatCoilLoad,
12297 22078562 : this->m_SuppHeatCoilIndex,
12298 : _,
12299 44157124 : true,
12300 22078562 : this->m_FanOpMode,
12301 22078562 : this->m_SuppHeatPartLoadFrac,
12302 22078562 : this->m_SuppHeatingSpeedNum,
12303 22078562 : this->m_SuppHeatingSpeedRatio);
12304 22078562 : } break;
12305 : }
12306 22078562 : } break;
12307 0 : case HVAC::Coil_HeatingDesuperheater: {
12308 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12309 : CompName,
12310 : FirstHVACIteration,
12311 : SuppHeatCoilLoad,
12312 0 : this->m_SuppHeatCoilIndex,
12313 : _,
12314 0 : true,
12315 0 : this->m_FanOpMode,
12316 0 : this->m_SuppHeatPartLoadFrac);
12317 0 : } break;
12318 0 : case HVAC::Coil_HeatingWater: {
12319 : // see if HW coil has enough capacity to meet the load
12320 0 : if (SuppHeatCoilLoad > 0.0) {
12321 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->m_MaxSuppCoilFluidFlow);
12322 : } else {
12323 0 : mdot = 0.0;
12324 : }
12325 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12326 : // simulate water coil to find operating capacity
12327 0 : WaterCoils::SimulateWaterCoilComponents(state,
12328 : this->m_SuppHeatCoilName,
12329 : FirstHVACIteration,
12330 0 : this->m_SuppHeatCoilIndex,
12331 : QActual,
12332 0 : this->m_FanOpMode,
12333 0 : this->m_SuppHeatPartLoadFrac);
12334 0 : if (QActual > SuppHeatCoilLoad) {
12335 0 : auto f = [&state, this, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
12336 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12337 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
12338 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12339 0 : WaterCoils::SimulateWaterCoilComponents(
12340 0 : state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex, 0.0, this->m_FanOpMode, PartLoadFrac);
12341 0 : return SuppHeatCoilLoad;
12342 0 : };
12343 : int SolFla; // Flag of solver, num iterations if >0, else error index
12344 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12345 0 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
12346 : } else {
12347 0 : this->m_SuppHeatPartLoadFrac = (SuppHeatCoilLoad > 0.0) ? 1.0 : 0.0;
12348 : }
12349 0 : } break;
12350 0 : case HVAC::Coil_HeatingSteam: {
12351 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12352 0 : this->m_MaxSuppCoilFluidFlow * this->m_SuppHeatPartLoadFrac);
12353 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12354 0 : SteamCoils::SimulateSteamCoilComponents(
12355 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, SuppHeatCoilLoad, _, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
12356 0 : } break;
12357 0 : default:
12358 0 : break;
12359 : }
12360 22078562 : }
12361 :
12362 94464 : void UnitarySys::setEMSSuppCoilStagePLR(EnergyPlusData &state)
12363 : {
12364 94464 : bool useMaxedSpeed = false;
12365 94464 : int SpeedNumEMS = ceil(this->m_EMSOverrideSuppCoilSpeedNumValue);
12366 94464 : if (SpeedNumEMS > this->m_NumOfSpeedSuppHeating) {
12367 0 : SpeedNumEMS = this->m_NumOfSpeedSuppHeating;
12368 0 : useMaxedSpeed = true;
12369 : }
12370 94464 : this->m_SuppHeatingSpeedNum = SpeedNumEMS;
12371 94464 : if (useMaxedSpeed) {
12372 0 : this->m_CoilSpeedErrIdx++;
12373 0 : ShowRecurringWarningErrorAtEnd(state,
12374 0 : format("Wrong coil speed EMS override value, for unit=\"{}\". Exceeding maximum coil speed "
12375 : "level. Speed level is set to the maximum coil speed level allowed.",
12376 0 : this->m_SuppHeatCoilName),
12377 0 : this->m_CoilSpeedErrIdx,
12378 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12379 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12380 : _,
12381 : "",
12382 : "");
12383 : }
12384 94464 : if (this->m_SuppHeatingSpeedNum == 1) {
12385 16 : this->m_SuppHeatingSpeedRatio = 0.0;
12386 16 : this->m_SuppHeatingCycRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12387 16 : if (useMaxedSpeed || this->m_SuppHeatingCycRatio == 0) {
12388 16 : this->m_SuppHeatingCycRatio = 1;
12389 : }
12390 16 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingCycRatio;
12391 : } else {
12392 94448 : this->m_SuppHeatingCycRatio = 1.0;
12393 94448 : this->m_SuppHeatingSpeedRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12394 94448 : if (useMaxedSpeed || this->m_SuppHeatingSpeedRatio == 0) {
12395 0 : this->m_SuppHeatingSpeedRatio = 1;
12396 : }
12397 94448 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingSpeedRatio;
12398 : }
12399 94464 : }
12400 :
12401 3676380 : void UnitarySys::controlCoolingSystemToSP(EnergyPlusData &state,
12402 : int const AirLoopNum, // index to air loop
12403 : bool const FirstHVACIteration, // First HVAC iteration flag
12404 : bool &HXUnitOn, // flag to enable heat exchanger heat recovery
12405 : HVAC::CompressorOp &compressorOp // compressor on/off control
12406 : )
12407 : {
12408 : // SUBROUTINE INFORMATION:
12409 : // AUTHOR Richard Raustad, FSEC
12410 : // DATE WRITTEN February 2013
12411 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
12412 :
12413 : // PURPOSE OF THIS SUBROUTINE:
12414 : // Simulate the coil object at the required PLR.
12415 :
12416 : // METHODOLOGY EMPLOYED:
12417 : // Calculate operating PLR and adjust speed when using multispeed coils.
12418 : // Meet moisture load if required to do so.
12419 :
12420 : // SUBROUTINE PARAMETER DEFINITIONS:
12421 3676380 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12422 3676380 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12423 3676380 : Real64 constexpr HumRatAcc(1.e-6); // Accuracy of solver result
12424 :
12425 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12426 : Real64 ReqOutput; // Sensible capacity (outlet - inlet) required to meet load or setpoint temperature
12427 : // for variable speed or 2 speed compressors
12428 : Real64 OutletTempDXCoil; // Actual outlet temperature of the DX cooling coil
12429 : Real64 OutletHumRatLS; // Actual outlet humrat of the variable speed DX cooling coil at low speed
12430 : Real64 OutletHumRatHS; // Actual outlet humrat of the variable speed DX cooling coil at high speed
12431 : Real64 OutletHumRatDXCoil; // Actual outlet humidity ratio of the DX cooling coil
12432 : Real64 TempMinPLR; // Used to find latent PLR when max iterations exceeded
12433 : Real64 TempMaxPLR; // Used to find latent PLR when max iterations exceeded
12434 : Real64 TempOutletTempDXCoil; // Used to find latent PLR when max iterations exceeded
12435 : Real64 OutletTemp;
12436 : Real64 OutdoorDryBulb; // local variable for OutDryBulbTemp
12437 : Real64 maxPartLoadFrac; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
12438 :
12439 : // Set local variables
12440 : // Retrieve the load on the controlled zone
12441 3676380 : int OutletNode = this->CoolCoilOutletNodeNum;
12442 3676380 : int InletNode = this->CoolCoilInletNodeNum;
12443 3676380 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
12444 3676380 : Real64 DesOutHumRat = this->m_DesiredOutletHumRat;
12445 3676380 : int CoilType_Num = this->m_CoolingCoilType_Num;
12446 3676380 : Real64 LoopDXCoilMaxRTFSave = 0.0;
12447 3800876 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
12448 124496 : this->m_sysType != SysType::PackagedWSHP) {
12449 124496 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
12450 124496 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
12451 : }
12452 :
12453 3676380 : std::string CompName = this->m_CoolingCoilName;
12454 3676380 : HVAC::FanOp fanOp = this->m_FanOpMode;
12455 3676380 : Real64 SpeedRatio = 0.0;
12456 3676380 : Real64 CycRatio = 0.0;
12457 3676380 : Real64 PartLoadFrac = 0.0;
12458 3676380 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal;
12459 3676380 : Real64 dummy = 0.0;
12460 3676380 : Real64 SensLoad = 0.0;
12461 3676380 : int SolFla = 0;
12462 3676380 : int SolFlaLat = 0;
12463 3676380 : Real64 NoLoadTempOut = 0.0;
12464 3676380 : Real64 NoLoadHumRatOut = 0.0;
12465 : // #8849, FullLoadHumRatOut set only at max speed
12466 3676380 : Real64 FullLoadHumRatOut = 0.0;
12467 3676380 : Real64 FullOutput = 0.0; // Sensible capacity (outlet - inlet) when the compressor is on
12468 3676380 : Real64 OnOffAirFlowRatio = 0.0; // Autodesk:Init Patch to prevent use uninitialized in calls to SimVariableSpeedCoils
12469 3676380 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
12470 :
12471 3676380 : if (this->m_CondenserNodeNum != 0) {
12472 168360 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12473 : } else {
12474 3508020 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12475 : }
12476 :
12477 : // Check the dehumidification control type. IF it's multimode, turn off the HX to find the sensible PLR. Then check to
12478 : // see if the humidity load is met without the use of the HX. Always run the HX for the other modes.
12479 3676380 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode && this->m_CoolingCoilType_Num != HVAC::CoilDX_Cooling) {
12480 3565521 : HXUnitOn = true;
12481 : } else {
12482 110859 : HXUnitOn = false;
12483 : }
12484 :
12485 : // IF there is a fault of coil SAT Sensor
12486 3676380 : if (this->m_FaultyCoilSATFlag) {
12487 : // calculate the sensor offset using fault information
12488 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
12489 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
12490 : // update the DesOutTemp
12491 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
12492 : }
12493 :
12494 : // IF UnitarySystem is scheduled on and there is flow
12495 6993251 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && this->m_coolingCoilAvailSched->getCurrentVal() > 0.0 &&
12496 3316871 : (state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow)) {
12497 :
12498 2750022 : bool SensibleLoad = false;
12499 2750022 : bool LatentLoad = false;
12500 2750022 : bool unitSys = false;
12501 2750022 : Real64 tempHumRatAcc = HumRatAcc;
12502 2750022 : Real64 tempAcc = Acc;
12503 : // Determine if there is a sensible load on this system
12504 2750022 : if (this->m_sysType == SysType::CoilCoolingDX) {
12505 2571223 : if ((state.dataLoopNodes->Node(InletNode).Temp > state.dataLoopNodes->Node(this->CoolCtrlNode).TempSetPoint) &&
12506 3889599 : (state.dataLoopNodes->Node(InletNode).Temp > DesOutTemp) &&
12507 1318376 : (std::abs(state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp) > HVAC::TempControlTol)) {
12508 1135897 : SensibleLoad = true;
12509 : }
12510 2571223 : tempAcc = 0.0;
12511 2571223 : tempHumRatAcc = 0.0;
12512 : } else {
12513 178799 : unitSys = true;
12514 178799 : if (state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp > HVAC::TempControlTol) {
12515 154818 : SensibleLoad = true;
12516 : }
12517 : }
12518 :
12519 : // if a heat pump and other coil is on, disable this coil
12520 2750022 : if (this->m_HeatPump && this->m_HeatingPartLoadFrac > 0.0) {
12521 0 : SensibleLoad = false;
12522 : }
12523 :
12524 : // Determine if there is a latent load on this system - for future use to serve latent-only loads
12525 2750022 : if (this->m_sysType == SysType::CoilCoolingDX) {
12526 5120817 : if ((state.dataLoopNodes->Node(InletNode).HumRat > state.dataLoopNodes->Node(InletNode).HumRatMax) &&
12527 2549594 : (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat)) {
12528 11701 : LatentLoad = true;
12529 : }
12530 : } else {
12531 178799 : if (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat) {
12532 79431 : LatentLoad = true;
12533 : }
12534 : }
12535 :
12536 : // disable latent dehumidification if there is no sensible load and latent only is not allowed
12537 2750022 : if (this->m_RunOnLatentOnlyWithSensible && !SensibleLoad) {
12538 0 : LatentLoad = false;
12539 : }
12540 :
12541 : // disable compressor if OAT is below minimum outdoor temperature
12542 2750022 : if (OutdoorDryBulb < this->m_MinOATCompressorCooling) {
12543 0 : SensibleLoad = false;
12544 0 : LatentLoad = false;
12545 : }
12546 :
12547 : // activate heat recovery loop coil if scheduled on and there is air flow
12548 2750022 : if (this->m_WaterHRPlantLoopModel) {
12549 15820 : if (this->temperatureOffsetControlStatus == 1) {
12550 1 : PartLoadFrac = 1.0;
12551 1 : mdot = this->MaxCoolCoilFluidFlow;
12552 : }
12553 15820 : if (this->CoolCoilPlantLoc.loopNum > 0) {
12554 15820 : PlantUtilities::SetComponentFlowRate(
12555 15820 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12556 : }
12557 :
12558 47460 : WaterCoils::SimulateWaterCoilComponents(
12559 31640 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12560 15820 : SensibleLoad = false; // fall through remaining checks
12561 15820 : LatentLoad = false;
12562 2734202 : } else if (this->m_TemperatureOffsetControlActive) {
12563 : // disable waterside economizer if the condition is NOT favorable
12564 60192 : if (this->temperatureOffsetControlStatus == 0) {
12565 59696 : SensibleLoad = false;
12566 59696 : LatentLoad = false;
12567 59696 : HXUnitOn = false;
12568 : }
12569 : }
12570 :
12571 : // IF DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
12572 : // Multimode coil will switch to enhanced dehumidification IF available and needed, but it
12573 : // still runs to meet the sensible load. Multimode applies to Multimode or HXAssistedCooling coils.
12574 2750022 : if ((SensibleLoad && this->m_RunOnSensibleLoad) || (LatentLoad && this->m_RunOnLatentLoad)) {
12575 : // calculate sensible PLR, don't care IF latent is true here but need to guard for
12576 : // when LatentLoad=TRUE and SensibleLoad=FALSE
12577 1223025 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12578 3669075 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
12579 1223025 : state.dataLoopNodes->Node(OutletNode).HumRat,
12580 1223025 : state.dataLoopNodes->Node(InletNode).Temp,
12581 1223025 : state.dataLoopNodes->Node(InletNode).HumRat);
12582 :
12583 1223025 : PartLoadFrac = 0.0;
12584 1223025 : compressorOp = HVAC::CompressorOp::Off;
12585 :
12586 1223025 : if (this->m_EMSOverrideCoilSpeedNumOn && (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12587 36467 : this->m_CoolingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
12588 36467 : this->m_SpeedNum = this->m_CoolingSpeedNum;
12589 36467 : bool useMaxedSpeed = false;
12590 36467 : if (this->m_SpeedNum > this->m_NumOfSpeedCooling) {
12591 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
12592 0 : this->m_SpeedNum = this->m_NumOfSpeedCooling;
12593 0 : useMaxedSpeed = true;
12594 0 : if (this->m_CoilSpeedErrIdx == 0) {
12595 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12596 0 : ShowContinueError(state,
12597 : " Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.");
12598 : }
12599 0 : ShowRecurringWarningErrorAtEnd(
12600 : state,
12601 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12602 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
12603 0 : this->m_CoilSpeedErrIdx,
12604 0 : this->m_EMSOverrideCoilSpeedNumValue,
12605 0 : this->m_EMSOverrideCoilSpeedNumValue,
12606 : _,
12607 : "",
12608 : "");
12609 : }
12610 :
12611 36467 : if (this->m_SpeedNum < 0) {
12612 0 : this->m_CoolingSpeedNum = 0;
12613 0 : this->m_SpeedNum = 0;
12614 0 : if (this->m_CoilSpeedErrIdx == 0) {
12615 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12616 0 : ShowContinueError(state, " Input speed value is below zero. Speed level is set to zero.");
12617 : }
12618 0 : ShowRecurringWarningErrorAtEnd(state,
12619 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12620 : "\". Input speed value is below zero. Speed level is set to zero.",
12621 0 : this->m_CoilSpeedErrIdx,
12622 0 : this->m_EMSOverrideCoilSpeedNumValue,
12623 0 : this->m_EMSOverrideCoilSpeedNumValue,
12624 : _,
12625 : "",
12626 : "");
12627 : }
12628 :
12629 36467 : if (this->m_CoolingSpeedNum == 1) {
12630 3889 : SpeedRatio = this->m_CoolingSpeedRatio = 0.0;
12631 3889 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12632 3889 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
12633 3889 : CycRatio = this->m_CoolingCycRatio = 1;
12634 : } else {
12635 0 : CycRatio = this->m_CoolingCycRatio;
12636 : }
12637 3889 : PartLoadFrac = this->m_CoolingCycRatio;
12638 : } else {
12639 32578 : CycRatio = this->m_CoolingCycRatio = 1.0;
12640 32578 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12641 32578 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
12642 0 : SpeedRatio = this->m_CoolingSpeedRatio = 1;
12643 : } else {
12644 32578 : SpeedRatio = this->m_CoolingSpeedRatio;
12645 : }
12646 32578 : PartLoadFrac = this->m_CoolingSpeedRatio;
12647 : }
12648 36467 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12649 36467 : if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12650 0 : this->simMultiSpeedCoils(state,
12651 : AirLoopNum,
12652 : FirstHVACIteration,
12653 : compressorOp,
12654 : SensibleLoad,
12655 : LatentLoad,
12656 : PartLoadFrac,
12657 : CoolingCoil,
12658 : this->m_SpeedNum);
12659 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12660 0 : int SpeedNum = 0;
12661 0 : if (SpeedNum == this->m_NumOfSpeedCooling) { // should be using this->m_SpeedNum? Diffs?
12662 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12663 : }
12664 : } else {
12665 36467 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12666 36467 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12667 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12668 36467 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12669 0 : coilMode = HVAC::CoilMode::Enhanced;
12670 : }
12671 36467 : bool const singleMode = (this->m_SingleMode == 1);
12672 36467 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12673 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode);
12674 : }
12675 :
12676 1223025 : } else if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12677 709126 : this->m_CompPartLoadRatio = PartLoadFrac;
12678 :
12679 709126 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12680 :
12681 477432 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12682 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12683 :
12684 11618 : if (this->CoolCoilFluidInletNode > 0) {
12685 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
12686 : }
12687 :
12688 34854 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12689 : CompName,
12690 : FirstHVACIteration,
12691 : HVAC::CompressorOp::On,
12692 : PartLoadFrac,
12693 11618 : this->m_CoolingCoilIndex,
12694 : fanOp,
12695 : HXUnitOn,
12696 : _,
12697 11618 : state.dataUnitarySystems->economizerFlag,
12698 : _,
12699 11618 : this->m_DehumidificationMode,
12700 11618 : 0.0); // this->CoilSHR);
12701 11618 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
12702 11618 : this->m_CompPartLoadRatio = PartLoadFrac;
12703 : }
12704 465814 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12705 :
12706 401021 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, PartLoadFrac, this->m_CoolingCoilIndex);
12707 :
12708 64793 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12709 5179 : this->simMultiSpeedCoils(
12710 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, this->m_SpeedNum);
12711 :
12712 59614 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12713 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12714 :
12715 13133 : int SpeedNum = 0;
12716 13133 : this->m_CoolingCoilSensDemand = ReqOutput;
12717 13133 : VariableSpeedCoils::SimVariableSpeedCoils(
12718 13133 : state, "", this->m_CoolingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
12719 :
12720 59614 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
12721 :
12722 11039 : DXCoils::SimDXCoilMultiMode(
12723 11039 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12724 11039 : this->m_CompPartLoadRatio = PartLoadFrac;
12725 35442 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12726 : // SP control (tentatively) operates at constant air flow regardless of speed
12727 : // speed n uses MSHPMassFlowRateHigh and speed n-1 uses MSHPMassFlowRateLow
12728 28561 : state.dataHVACGlobal->MSHPMassFlowRateLow = this->m_DesignMassFlowRate;
12729 28561 : state.dataHVACGlobal->MSHPMassFlowRateHigh = this->m_DesignMassFlowRate;
12730 28561 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12731 28561 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12732 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12733 28561 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12734 0 : coilMode = HVAC::CoilMode::Enhanced;
12735 : }
12736 28561 : bool const singleMode = (this->m_SingleMode == 1);
12737 : // PartLoadFrac has not been set in this branch - so use m_CoolingSpeedRatio?
12738 28561 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12739 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12740 28561 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12741 6881 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12742 :
12743 1350 : WaterCoils::SimulateWaterCoilComponents(
12744 900 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12745 :
12746 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12747 :
12748 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12749 : blankString,
12750 0 : this->m_CoolingCoilIndex,
12751 : ReqOutput,
12752 : dummy,
12753 : fanOp,
12754 : HVAC::CompressorOp::Off,
12755 : PartLoadFrac,
12756 : FirstHVACIteration);
12757 0 : this->m_CoolingCoilSensDemand = 0.0;
12758 :
12759 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12760 :
12761 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12762 : blankString,
12763 0 : this->m_CoolingCoilIndex,
12764 : this->MaxCoolAirMassFlow,
12765 : fanOp,
12766 : FirstHVACIteration,
12767 0 : this->m_InitHeatPump,
12768 : ReqOutput,
12769 : dummy,
12770 : HVAC::CompressorOp::Off,
12771 : PartLoadFrac);
12772 :
12773 6431 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12774 :
12775 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12776 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12777 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12778 0 : if (CoolingActive) {
12779 0 : PartLoadFrac = 1.0;
12780 : }
12781 :
12782 6431 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12783 :
12784 6431 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12785 :
12786 : } else {
12787 : }
12788 :
12789 1223025 : NoLoadTempOut = state.dataLoopNodes->Node(OutletNode).Temp;
12790 1223025 : NoLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12791 :
12792 1223025 : Real64 NoOutput = 0.0; // CoilSystem:Cooling:DX
12793 1223025 : FullOutput = 0.0;
12794 1223025 : if (this->m_sysType == SysType::CoilCoolingDX) {
12795 1135897 : NoOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12796 1135897 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12797 1135897 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12798 1135897 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12799 2271794 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12800 1135897 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12801 : }
12802 :
12803 : // Changed logic to use temperature instead of load. The Psyc calcs can cause slight errors.
12804 : // For example it's possible that (NoOutput-ReqOutput) > Acc while (Node(OutletNode)%Temp-DesOutTemp) is not
12805 : // This can (and did) lead to RegulaFalsi errors
12806 :
12807 : // IF ((NoOutput-ReqOutput) .LT. Acc) THEN
12808 : // IF outlet temp at no load is lower than DesOutTemp (set point), do not operate the coil
12809 : // and if coolReheat, check hum rat as well
12810 1223025 : bool doIt = false; // CoilSystem:Cooling:DX
12811 1223025 : if (this->m_sysType == SysType::CoilCoolingDX) {
12812 1135897 : if ((NoOutput - ReqOutput) < Acc) {
12813 0 : PartLoadFrac = 0.0;
12814 : } else {
12815 1135897 : doIt = true;
12816 : }
12817 87128 : } else if (this->m_EMSOverrideCoilSpeedNumOn &&
12818 36467 : (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12819 : // do nothing, PartLoadFrac set above
12820 50661 : } else if (((NoLoadTempOut - DesOutTemp) < Acc) && ((NoLoadHumRatOut - DesOutHumRat) < HumRatAcc)) {
12821 0 : PartLoadFrac = 0.0;
12822 : } else { // need to turn on compressor to see if load is met
12823 50661 : doIt = true; // CoilSystem:Cooling:DX
12824 : } // CoilSystem:Cooling:DX
12825 1223025 : if (this->m_EMSOverrideCoilSpeedNumOn) {
12826 36467 : doIt = false;
12827 : }
12828 :
12829 1223025 : if (doIt) { // CoilSystem:Cooling:DX
12830 1186558 : PartLoadFrac = 1.0;
12831 1186558 : compressorOp = HVAC::CompressorOp::On;
12832 :
12833 1186558 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12834 :
12835 1418252 : DXCoils::SimDXCoil(
12836 709126 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12837 709126 : this->m_CompPartLoadRatio = PartLoadFrac;
12838 709126 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12839 :
12840 477432 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12841 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12842 :
12843 11618 : if (this->CoolCoilFluidInletNode > 0) {
12844 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = max(0.0, this->MaxCoolCoilFluidFlow);
12845 : }
12846 34854 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12847 : CompName,
12848 : FirstHVACIteration,
12849 : HVAC::CompressorOp::On,
12850 : PartLoadFrac,
12851 11618 : this->m_CoolingCoilIndex,
12852 : fanOp,
12853 : HXUnitOn,
12854 : _,
12855 11618 : state.dataUnitarySystems->economizerFlag,
12856 : _,
12857 11618 : this->m_DehumidificationMode,
12858 11618 : 0.0); // this->CoilSHR);
12859 :
12860 11618 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
12861 11618 : this->m_CompPartLoadRatio = PartLoadFrac;
12862 : }
12863 11618 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12864 :
12865 465814 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12866 :
12867 401021 : CycRatio = 1.0;
12868 752561 : for (int speedRatio = 0; speedRatio < this->m_NumOfSpeedCooling; ++speedRatio) {
12869 752561 : SpeedRatio = Real64(speedRatio);
12870 752561 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
12871 752561 : OutletTemp = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
12872 752561 : if (SpeedRatio == 1) {
12873 351540 : FullLoadHumRatOut = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
12874 351540 : break;
12875 : }
12876 401021 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12877 49481 : break;
12878 : }
12879 : }
12880 :
12881 64793 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12882 :
12883 5179 : CycRatio = 1.0;
12884 5179 : SpeedRatio = 0.0;
12885 15494 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12886 10337 : if (SpeedNum > 1) {
12887 5158 : CycRatio = 0.0;
12888 5158 : SpeedRatio = 1.0;
12889 : }
12890 10337 : this->m_CoolingSpeedNum = SpeedNum;
12891 10337 : this->simMultiSpeedCoils(
12892 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, SpeedNum);
12893 10337 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12894 10337 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12895 5158 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12896 : }
12897 10337 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12898 22 : break;
12899 : }
12900 : }
12901 :
12902 59614 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12903 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12904 :
12905 13133 : CycRatio = 1.0;
12906 13133 : SpeedRatio = 1.0;
12907 13133 : SensLoad = -1.0; // turns on coil
12908 13133 : this->m_CoolingSpeedRatio = SpeedRatio;
12909 13133 : this->m_CoolingPartLoadFrac = PartLoadFrac;
12910 17779 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12911 15962 : this->m_CoolingSpeedNum = SpeedNum;
12912 15962 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12913 : "",
12914 15962 : this->m_CoolingCoilIndex,
12915 : fanOp,
12916 : compressorOp,
12917 : CycRatio,
12918 : SpeedNum,
12919 : SpeedRatio,
12920 : SensLoad,
12921 : dummy,
12922 : OnOffAirFlowRatio);
12923 15962 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12924 15962 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12925 11101 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12926 : }
12927 15962 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12928 11316 : break;
12929 : }
12930 : }
12931 13133 : if (this->m_CoolingSpeedNum == 1) {
12932 11195 : CycRatio = 1.0;
12933 11195 : SpeedRatio = 0.0;
12934 : } else {
12935 1938 : CycRatio = 0.0;
12936 1938 : SpeedRatio = 1.0;
12937 : }
12938 :
12939 59614 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) { // Coil:Cooling:DX:TwoStageWithHumidityControlMode
12940 :
12941 11039 : DXCoils::SimDXCoilMultiMode(
12942 11039 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12943 11039 : this->m_CompPartLoadRatio = PartLoadFrac;
12944 :
12945 35442 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12946 28561 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12947 28561 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12948 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12949 28561 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12950 0 : coilMode = HVAC::CoilMode::Enhanced;
12951 : }
12952 28561 : this->m_CoolingSpeedRatio = 1.0;
12953 28561 : bool const singleMode = (this->m_SingleMode == 1);
12954 41070 : for (int speedNum = 1; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
12955 36799 : this->m_CoolingSpeedNum = speedNum;
12956 36799 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12957 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12958 36799 : if (speedNum == this->m_NumOfSpeedCooling) {
12959 23933 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12960 : }
12961 36799 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) {
12962 24290 : break;
12963 : }
12964 : }
12965 28561 : if (this->m_CoolingSpeedNum == 1) {
12966 20323 : this->m_CompPartLoadRatio = PartLoadFrac;
12967 20323 : this->m_CoolCompPartLoadRatio = PartLoadFrac; // why is the set only for a few?
12968 20323 : SpeedRatio = 0.0;
12969 : } else {
12970 8238 : SpeedRatio = PartLoadFrac;
12971 8238 : PartLoadFrac = 1.0;
12972 8238 : this->m_CompPartLoadRatio = 1.0;
12973 8238 : this->m_CoolCompPartLoadRatio = 1.0;
12974 : }
12975 6881 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12976 :
12977 450 : mdot = this->MaxCoolCoilFluidFlow;
12978 450 : PlantUtilities::SetComponentFlowRate(
12979 450 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12980 :
12981 1350 : WaterCoils::SimulateWaterCoilComponents(
12982 900 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12983 450 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12984 :
12985 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12986 :
12987 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12988 : blankString,
12989 0 : this->m_CoolingCoilIndex,
12990 : ReqOutput,
12991 : dummy,
12992 : fanOp,
12993 : HVAC::CompressorOp::On,
12994 : PartLoadFrac,
12995 : FirstHVACIteration);
12996 0 : this->m_CoolingCoilSensDemand = ReqOutput;
12997 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12998 :
12999 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
13000 :
13001 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
13002 : blankString,
13003 0 : this->m_CoolingCoilIndex,
13004 : this->MaxCoolAirMassFlow,
13005 : fanOp,
13006 : FirstHVACIteration,
13007 0 : this->m_InitHeatPump,
13008 : ReqOutput,
13009 : dummy,
13010 : HVAC::CompressorOp::Off,
13011 : PartLoadFrac);
13012 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13013 :
13014 6431 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13015 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
13016 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
13017 :
13018 0 : UserDefinedComponents::SimCoilUserDefined(
13019 0 : state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
13020 0 : if (CoolingActive) {
13021 0 : PartLoadFrac = 1.0;
13022 : }
13023 :
13024 6431 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13025 :
13026 : // TES coil simulated above with PLR=0. Operating mode is known here, no need to simulate again to determine operating
13027 : // mode.
13028 6431 : if (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13029 6431 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly) { // cannot cool
13030 5 : PartLoadFrac = 0.0;
13031 : } else {
13032 : // Get full load result
13033 6426 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
13034 : }
13035 :
13036 : } else {
13037 : }
13038 :
13039 1186558 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13040 1186558 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
13041 1186558 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
13042 2373116 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13043 1186558 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13044 1186558 : state.dataLoopNodes->Node(OutletNode).HumRat,
13045 1186558 : state.dataLoopNodes->Node(InletNode).Temp,
13046 1186558 : state.dataLoopNodes->Node(InletNode).HumRat);
13047 : }
13048 :
13049 : // IF ((FullOutput - ReqOutput) .GT. Acc) THEN ! old method
13050 : // IF ((Node(OutletNode)%Temp-DesOutTemp) .GT. Acc) THEN ! new method gets caught when temps are very close
13051 1223025 : if (this->m_sysType == SysType::CoilCoolingDX) {
13052 1135897 : if ((FullOutput - ReqOutput) > tempAcc) {
13053 172732 : PartLoadFrac = 1.0;
13054 172732 : doIt = false;
13055 : } else {
13056 963165 : doIt = true;
13057 : }
13058 : }
13059 1223025 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13060 36467 : doIt = false;
13061 : }
13062 :
13063 1223025 : if (doIt) {
13064 1013826 : if (unitSys && state.dataLoopNodes->Node(OutletNode).Temp > DesOutTemp - tempAcc) {
13065 18363 : PartLoadFrac = 1.0;
13066 18363 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13067 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13068 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13069 0 : PartLoadFrac = 0.0;
13070 : }
13071 995463 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13072 5389 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13073 5389 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13074 0 : PartLoadFrac = 0.0;
13075 995463 : } else if (!SensibleLoad) {
13076 0 : PartLoadFrac = 0.0;
13077 : } else {
13078 :
13079 995463 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13080 2509307 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadRatio) {
13081 2509307 : int CoilIndex = this->m_CoolingCoilIndex;
13082 2509307 : DXCoils::CalcDoe2DXCoil(state, CoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13083 2509307 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
13084 :
13085 2509307 : return DesOutTemp - OutletAirTemp;
13086 635341 : };
13087 635341 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13088 635341 : this->m_CompPartLoadRatio = PartLoadFrac;
13089 :
13090 360122 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) || (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) {
13091 :
13092 20351 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadFrac) {
13093 16855 : if (this->CoolCoilFluidInletNode > 0) {
13094 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = this->MaxCoolCoilFluidFlow * PartLoadFrac;
13095 : }
13096 33710 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(
13097 : state,
13098 16855 : this->m_CoolingCoilIndex,
13099 : FirstHVACIteration,
13100 : HVAC::CompressorOp::On,
13101 : PartLoadFrac,
13102 : HXUnitOn,
13103 : fanOp,
13104 : _,
13105 : _,
13106 16855 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13107 16855 : 0.0);
13108 16855 : return DesOutTemp - state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13109 3496 : };
13110 :
13111 3496 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13112 3496 : if (SolFla == -1) {
13113 :
13114 : // RegulaFalsi may not find sensible PLR when the latent degradation model is used.
13115 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13116 0 : TempMaxPLR = -0.1;
13117 0 : TempOutletTempDXCoil = state.dataLoopNodes->Node(InletNode).Temp;
13118 0 : while ((TempOutletTempDXCoil - DesOutTemp) > 0.0 && TempMaxPLR <= 1.0) {
13119 : // find upper limit of PLR
13120 0 : TempMaxPLR += 0.1;
13121 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13122 : CompName,
13123 : FirstHVACIteration,
13124 : HVAC::CompressorOp::On,
13125 : TempMaxPLR,
13126 0 : this->m_CoolingCoilIndex,
13127 : fanOp,
13128 : HXUnitOn,
13129 : _,
13130 0 : state.dataUnitarySystems->economizerFlag,
13131 : _,
13132 0 : this->m_DehumidificationMode,
13133 0 : 0.0); // this->CoilSHR);
13134 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13135 : }
13136 0 : TempMinPLR = TempMaxPLR;
13137 0 : while ((TempOutletTempDXCoil - DesOutTemp) < 0.0 && TempMinPLR >= 0.0) {
13138 : // pull upper limit of PLR DOwn to last valid limit (i.e. outlet temp still exceeds DesOutTemp)
13139 0 : TempMaxPLR = TempMinPLR;
13140 : // find minimum limit of PLR
13141 0 : TempMinPLR -= 0.01;
13142 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13143 : CompName,
13144 : FirstHVACIteration,
13145 : HVAC::CompressorOp::On,
13146 : TempMinPLR,
13147 0 : this->m_CoolingCoilIndex,
13148 : fanOp,
13149 : HXUnitOn,
13150 : _,
13151 0 : state.dataUnitarySystems->economizerFlag,
13152 : _,
13153 0 : this->m_DehumidificationMode,
13154 0 : 0.0); // this->CoilSHR);
13155 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13156 : }
13157 : // Relax boundary slightly to assure a solution can be found using RegulaFalsi (i.e. one boundary may
13158 : // be very near the desired result)
13159 0 : TempMinPLR = max(0.0, (TempMinPLR - 0.01));
13160 0 : TempMaxPLR = min(1.0, (TempMaxPLR + 0.01));
13161 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13162 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13163 0 : if (SolFla == -1) {
13164 0 : if (!state.dataGlobal->WarmupFlag) {
13165 0 : if (this->warnIndex.m_HXAssistedSensPLRIter < 1) {
13166 0 : ++this->warnIndex.m_HXAssistedSensPLRIter;
13167 0 : ShowWarningError(
13168 : state,
13169 0 : format("{} - Iteration limit exceeded calculating DX unit sensible part-load ratio for unit = {}",
13170 0 : this->UnitType,
13171 0 : this->Name));
13172 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13173 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13174 0 : ShowContinueErrorTimeStamp(
13175 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13176 : }
13177 0 : ShowRecurringWarningErrorAtEnd(state,
13178 0 : this->UnitType + " \"" + this->Name +
13179 : "\" - Iteration limit exceeded calculating sensible part-load ratio "
13180 : "error continues. Sensible PLR "
13181 : "statistics follow.",
13182 0 : this->warnIndex.m_HXAssistedSensPLRIterIndex,
13183 : PartLoadFrac,
13184 : PartLoadFrac);
13185 : }
13186 0 : } else if (SolFla == -2) {
13187 0 : PartLoadFrac = ReqOutput / FullOutput;
13188 0 : if (!state.dataGlobal->WarmupFlag) {
13189 0 : if (this->warnIndex.m_HXAssistedSensPLRFail < 1) {
13190 0 : ++this->warnIndex.m_HXAssistedSensPLRFail;
13191 0 : ShowWarningError(state,
13192 0 : format("{} - DX unit sensible part-load ratio calculation unexpectedly failed: "
13193 : "part-load ratio limits exceeded, for unit = {}",
13194 0 : this->UnitType,
13195 0 : this->Name));
13196 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13197 0 : ShowContinueErrorTimeStamp(
13198 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13199 : }
13200 0 : ShowRecurringWarningErrorAtEnd(state,
13201 0 : this->UnitType + " \"" + this->Name +
13202 : "\" - DX unit sensible part-load ratio calculation unexpectedly "
13203 : "failed error continues. Sensible PLR "
13204 : "statistics follow.",
13205 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex,
13206 : PartLoadFrac,
13207 : PartLoadFrac);
13208 : }
13209 : }
13210 3496 : } else if (SolFla == -2) {
13211 0 : PartLoadFrac = ReqOutput / FullOutput;
13212 0 : if (!state.dataGlobal->WarmupFlag) {
13213 0 : if (this->warnIndex.m_HXAssistedSensPLRFail2 < 1) {
13214 0 : ++this->warnIndex.m_HXAssistedSensPLRFail2;
13215 0 : ShowWarningError(state,
13216 0 : format("{} - DX unit sensible part-load ratio calculation failed: part-load ratio limits "
13217 : "exceeded, for unit = {}",
13218 0 : this->UnitType,
13219 0 : this->Name));
13220 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13221 0 : ShowContinueErrorTimeStamp(
13222 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13223 : }
13224 0 : ShowRecurringWarningErrorAtEnd(state,
13225 0 : this->UnitType + " \"" + this->Name +
13226 : "\" - DX unit sensible part-load ratio calculation failed error continues. "
13227 : "Sensible PLR statistics follow.",
13228 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex2,
13229 : PartLoadFrac,
13230 : PartLoadFrac);
13231 : }
13232 : }
13233 3496 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13234 3496 : this->m_CompPartLoadRatio = PartLoadFrac;
13235 : }
13236 :
13237 360122 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13238 311876 : this->m_CoolingSpeedRatio = SpeedRatio;
13239 311876 : if (SpeedRatio == 1.0) {
13240 1718066 : auto f = [&state, this, DesOutTemp](Real64 const SpeedRatio) {
13241 1718066 : int par1 = this->m_CoolingCoilIndex;
13242 1718066 : Real64 par2 = DesOutTemp;
13243 1718066 : int par3 = this->m_UnitarySysNum;
13244 : // 4-7 are not used for TwoSpeed coils, so these shouldn't matter at all
13245 1718066 : Real64 par4_CycRatio = 0.0;
13246 1718066 : int par5_SpeedNum = 0.0;
13247 1718066 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
13248 1718066 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13249 1718066 : return UnitarySys::DXCoilVarSpeedResidual(
13250 1718066 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13251 262395 : };
13252 262395 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13253 262395 : PartLoadFrac = SpeedRatio;
13254 : } else {
13255 183530 : auto f = [&state, this, DesOutTemp, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13256 : // several pars are not used in two speed coils, so these are just dummy values
13257 183530 : Real64 par4_SpeedRatio = 0.0;
13258 183530 : int par5_SpeedNum = 0.0;
13259 183530 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
13260 183530 : HVAC::CompressorOp par7_compressorOp = HVAC::CompressorOp::On;
13261 367060 : return UnitarySys::DXCoilCyclingResidual(state,
13262 : CycRatio,
13263 183530 : this->m_CoolingCoilIndex,
13264 : DesOutTemp,
13265 183530 : this->m_UnitarySysNum,
13266 : par4_SpeedRatio,
13267 : par5_SpeedNum,
13268 : par6_FanOpMode,
13269 : par7_compressorOp,
13270 : AirLoopNum,
13271 183530 : FirstHVACIteration);
13272 49481 : };
13273 49481 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13274 49481 : PartLoadFrac = CycRatio;
13275 : }
13276 :
13277 44750 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13278 :
13279 22 : if (this->m_CoolingSpeedNum > 1.0) {
13280 235 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
13281 235 : int par1 = this->m_CoolingCoilIndex;
13282 235 : Real64 par2 = DesOutTemp;
13283 235 : int par3 = this->m_UnitarySysNum;
13284 235 : Real64 par4_CycRatio = CycRatio;
13285 235 : int par5_SpeedNum = this->m_CoolingSpeedNum;
13286 235 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Cycling;
13287 235 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13288 235 : return UnitarySys::DXCoilVarSpeedResidual(
13289 235 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13290 1 : };
13291 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13292 1 : PartLoadFrac = SpeedRatio;
13293 : } else {
13294 21 : SpeedRatio = 0.0;
13295 21 : this->m_CoolingSpeedRatio = SpeedRatio;
13296 122 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13297 244 : return UnitarySys::DXCoilCyclingResidual(state,
13298 : CycRatio,
13299 122 : this->m_CoolingCoilIndex,
13300 : DesOutTemp,
13301 122 : this->m_UnitarySysNum,
13302 : SpeedRatio,
13303 122 : this->m_CoolingSpeedNum,
13304 : HVAC::FanOp::Cycling,
13305 : HVAC::CompressorOp::On,
13306 : AirLoopNum,
13307 122 : FirstHVACIteration);
13308 21 : };
13309 21 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13310 21 : PartLoadFrac = CycRatio;
13311 : }
13312 :
13313 44728 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13314 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13315 :
13316 11316 : CycRatio = 1.0;
13317 11316 : SpeedRatio = 1.0;
13318 :
13319 11316 : if (this->m_CoolingSpeedNum > 1.0) {
13320 8370 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
13321 8370 : int par1 = this->m_CoolingCoilIndex;
13322 8370 : Real64 par2 = DesOutTemp;
13323 8370 : int par3 = this->m_UnitarySysNum;
13324 8370 : Real64 par4_CycRatio = CycRatio;
13325 8370 : int par5_SpeedNum = this->m_CoolingSpeedNum;
13326 8370 : HVAC::FanOp par6_FanOpMode = this->m_FanOpMode;
13327 8370 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13328 8370 : return UnitarySys::DXCoilVarSpeedResidual(
13329 8370 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13330 1938 : };
13331 1938 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13332 1938 : this->m_CoolingCycRatio = CycRatio;
13333 1938 : this->m_CoolingSpeedRatio = SpeedRatio;
13334 1938 : this->m_CoolingPartLoadFrac = SpeedRatio;
13335 1938 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13336 1938 : PartLoadFrac = SpeedRatio;
13337 : } else {
13338 9378 : this->m_CoolingSpeedRatio = SpeedRatio;
13339 37415 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13340 74830 : return UnitarySys::DXCoilCyclingResidual(state,
13341 : CycRatio,
13342 37415 : this->m_CoolingCoilIndex,
13343 : DesOutTemp,
13344 37415 : this->m_UnitarySysNum,
13345 : SpeedRatio,
13346 37415 : this->m_CoolingSpeedNum,
13347 37415 : this->m_FanOpMode,
13348 : HVAC::CompressorOp::On,
13349 : AirLoopNum,
13350 37415 : FirstHVACIteration);
13351 9378 : };
13352 9378 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13353 9378 : SpeedRatio = 0.0;
13354 9378 : this->m_CoolingCycRatio = CycRatio;
13355 9378 : this->m_CoolingPartLoadFrac = CycRatio;
13356 9378 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13357 9378 : PartLoadFrac = CycRatio;
13358 : }
13359 :
13360 44728 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13361 14491 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13362 14491 : DXCoils::SimDXCoilMultiMode(
13363 14491 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13364 14491 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13365 3715 : };
13366 3715 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13367 3715 : this->m_CompPartLoadRatio = PartLoadFrac;
13368 29697 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13369 153185 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13370 153185 : bool const singleMode = this->m_SingleMode;
13371 153185 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13372 153185 : state, DehumidMode, this->m_CoolingSpeedNum, PartLoadRatio, fanOp, singleMode);
13373 : Real64 outletCondition =
13374 153185 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13375 153185 : return DesOutTemp - outletCondition;
13376 24290 : };
13377 :
13378 24290 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13379 24290 : if (this->m_CoolingSpeedNum == 1) {
13380 19105 : this->m_CompPartLoadRatio = PartLoadFrac;
13381 19105 : SpeedRatio = 0.0;
13382 : } else {
13383 5185 : SpeedRatio = PartLoadFrac;
13384 5185 : PartLoadFrac = 1.0;
13385 5185 : this->m_CompPartLoadRatio = 1.0;
13386 : }
13387 5407 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) {
13388 :
13389 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
13390 : maxPartLoadFrac =
13391 18 : min(1.0,
13392 18 : ((mdot / this->MaxCoolCoilFluidFlow) +
13393 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
13394 :
13395 72 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadRatio) {
13396 72 : Real64 mdot = min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13397 72 : this->MaxCoolCoilFluidFlow * PartLoadRatio);
13398 72 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
13399 144 : WaterCoils::SimulateWaterCoilComponents(
13400 72 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, _, _, PartLoadRatio);
13401 72 : return DesOutTemp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp;
13402 18 : };
13403 :
13404 18 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
13405 :
13406 5407 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13407 0 : this->m_CoolingCoilSensDemand = ReqOutput;
13408 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
13409 0 : return UnitarySys::coolWatertoAirHPTempResidual(
13410 0 : state, PartLoadRatio, this->m_UnitarySysNum, FirstHVACIteration, DesOutTemp, ReqOutput);
13411 0 : };
13412 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13413 5389 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13414 : // do nothing, user defined coil cannot be controlled
13415 :
13416 5389 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13417 21684 : auto f = [&state, this, DesOutTemp](Real64 const PartLoadRatio) {
13418 21684 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13419 43368 : PackagedThermalStorageCoil::SimTESCoil(state,
13420 : thisSys.m_CoolingCoilName,
13421 21684 : thisSys.m_CoolingCoilIndex,
13422 : thisSys.m_FanOpMode,
13423 21684 : thisSys.m_TESOpMode,
13424 : PartLoadRatio);
13425 21684 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp - DesOutTemp;
13426 5389 : };
13427 5389 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13428 : } else {
13429 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
13430 0 : ShowFatalError(state,
13431 0 : format("ControlCoolingSystemToSP: Invalid cooling coil type = {}", HVAC::cAllCoilTypes(CoilType_Num)));
13432 : }
13433 : }
13434 : }
13435 : }
13436 :
13437 : // IF system does not operate to meet sensible load, use no load humidity ratio to test against humidity setpoint,
13438 : // ELSE use operating humidity ratio to test against humidity setpoint
13439 2750022 : if (PartLoadFrac == 0.0) {
13440 1526996 : OutletHumRatDXCoil = NoLoadHumRatOut;
13441 : } else {
13442 1223026 : OutletHumRatDXCoil = state.dataLoopNodes->Node(OutletNode).HumRat;
13443 : }
13444 :
13445 : // IF humidity setpoint is not satisfied and humidity control type is MultiMode,
13446 : // then enable heat exchanger and run to meet sensible load
13447 :
13448 2750022 : if ((OutletHumRatDXCoil > (DesOutHumRat + tempHumRatAcc)) && (!unitSys || PartLoadFrac < 1.0) &&
13449 24876 : (this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
13450 :
13451 7528 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13452 : // pass
13453 7528 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
13454 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted,
13455 : // CoilSystem:Cooling:Water:HeatExchangerAssisted
13456 : // Determine required part load when heat exchanger is ON
13457 0 : HXUnitOn = true;
13458 0 : PartLoadFrac = 1.0;
13459 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13460 : CompName,
13461 : FirstHVACIteration,
13462 : HVAC::CompressorOp::On,
13463 : PartLoadFrac,
13464 0 : this->m_CoolingCoilIndex,
13465 : fanOp,
13466 : HXUnitOn,
13467 : _,
13468 0 : state.dataUnitarySystems->economizerFlag,
13469 : _,
13470 0 : this->m_DehumidificationMode,
13471 0 : 0.0); // this->CoilSHR);
13472 :
13473 0 : OutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13474 :
13475 : // FullOutput will be different than the FullOutput determined above during sensible PLR calculations
13476 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13477 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13478 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13479 0 : state.dataLoopNodes->Node(InletNode).Temp,
13480 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13481 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13482 :
13483 : // Check to see if the system can meet the load with the compressor off
13484 : // If NoOutput is lower than (more cooling than required) or very near the ReqOutput, do not run the compressor
13485 0 : if ((NoLoadTempOut - DesOutTemp) < Acc) {
13486 0 : PartLoadFrac = 0.0;
13487 : // OutletTempDXCoil is the full capacity outlet temperature at PartLoadFrac = 1 from the CALL above.
13488 : // if this temp is greater than or very near the desired outlet temp, then run the compressor at PartLoadFrac
13489 : // = 1.
13490 : // ELSEIF ((OutletTempDXCoil > DesOutTemp) .OR. ABS(OutletTempDXCoil - DesOutTemp) .LE. (Acc*2.0d0)) THEN
13491 0 : } else if (OutletTempDXCoil > DesOutTemp - (tempAcc * 2.0)) {
13492 0 : PartLoadFrac = 1.0;
13493 : } else {
13494 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadRatio) {
13495 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13496 :
13497 0 : if (thisSys.CoolCoilFluidInletNode > 0) {
13498 0 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = thisSys.MaxCoolCoilFluidFlow * PartLoadRatio;
13499 : }
13500 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13501 0 : this->m_CoolingCoilIndex,
13502 : FirstHVACIteration,
13503 : HVAC::CompressorOp::On,
13504 : PartLoadRatio,
13505 : HXUnitOn,
13506 : fanOp,
13507 : _,
13508 : _,
13509 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13510 0 : 0.0);
13511 0 : Real64 OutletAirTemp = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13512 0 : return DesOutTemp - OutletAirTemp;
13513 0 : };
13514 :
13515 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13516 : }
13517 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13518 :
13519 7528 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13520 :
13521 : // Get full load result
13522 7528 : PartLoadFrac = 1.0;
13523 7528 : DehumidMode = HVAC::CoilMode::Enhanced;
13524 7528 : this->m_DehumidificationMode = DehumidMode;
13525 7528 : DXCoils::SimDXCoilMultiMode(
13526 7528 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13527 7528 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13528 7528 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13529 7528 : state.dataLoopNodes->Node(OutletNode).HumRat,
13530 7528 : state.dataLoopNodes->Node(InletNode).Temp,
13531 7528 : state.dataLoopNodes->Node(InletNode).HumRat);
13532 7528 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13533 :
13534 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
13535 : // Check that this is the case; IF not set PartLoadFrac = 0.0 (off) and return
13536 : // Calculate the part load fraction
13537 7528 : if (FullOutput >= 0) {
13538 0 : PartLoadFrac = 0.0;
13539 : } else {
13540 7528 : OutletTempDXCoil = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13541 7528 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13542 : // If sensible load and setpoint cannot be met, set PLR = 1. if no sensible load and
13543 : // latent load exists and setpoint cannot be met, set PLR = 1.
13544 7528 : if ((OutletTempDXCoil > (DesOutTemp - (tempAcc * 2.0)) && SensibleLoad && this->m_RunOnSensibleLoad) ||
13545 589 : (OutletHumRatDXCoil >= (DesOutHumRat - (tempHumRatAcc * 2.0)) && !SensibleLoad && LatentLoad &&
13546 0 : this->m_RunOnLatentLoad)) {
13547 6939 : PartLoadFrac = 1.0;
13548 : // ELSEIF ((SensibleLoad .and. LatentLoad .AND. .NOT. UnitarySystem(UnitarySysNum)%RunOnLatentLoad
13549 : // .AND. &
13550 : // OutletHumRatDXCoil < DesOutHumRat)) THEN
13551 589 : } else if (!SensibleLoad && (OutletHumRatDXCoil < DesOutHumRat && LatentLoad && this->m_RunOnLatentLoad)) {
13552 0 : PartLoadFrac = ReqOutput / FullOutput;
13553 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13554 0 : DXCoils::SimDXCoilMultiMode(
13555 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13556 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13557 0 : };
13558 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13559 0 : } else { // must be a sensible load so find PLR
13560 589 : PartLoadFrac = ReqOutput / FullOutput;
13561 2310 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13562 2310 : DXCoils::SimDXCoilMultiMode(
13563 2310 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13564 2310 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13565 589 : };
13566 589 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13567 : }
13568 : }
13569 7528 : this->m_CompPartLoadRatio = PartLoadFrac;
13570 :
13571 0 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13572 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Enhanced;
13573 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
13574 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
13575 : }
13576 0 : if (this->m_CoolingSpeedNum == 0) {
13577 0 : this->m_CoolingSpeedNum = 1;
13578 : }
13579 0 : bool const singleMode = (this->m_SingleMode == 1);
13580 0 : PartLoadFrac = 1.0;
13581 0 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13582 0 : this->m_CoolingSpeedNum = speedNum;
13583 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13584 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13585 : // Cooling: break if outlet temp is lower than DesOutTemp or approaches DesOutTemp to within Acc from above
13586 0 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) {
13587 0 : break;
13588 : }
13589 : }
13590 :
13591 : // make sure outlet temp is below set point before calling SolveRoot
13592 : // Cooling: iterate only when outlet temp is below DesOutTemp by at least Acc
13593 0 : if ((DesOutTemp - state.dataLoopNodes->Node(OutletNode).Temp) > Acc) {
13594 :
13595 0 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadFrac) {
13596 0 : bool const singleMode = false;
13597 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13598 0 : state, HVAC::CoilMode::Enhanced, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13599 : Real64 outletCondition =
13600 0 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13601 :
13602 0 : return DesOutTemp - outletCondition;
13603 0 : };
13604 :
13605 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13606 : }
13607 0 : if (this->m_CoolingSpeedNum == 1) {
13608 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13609 0 : SpeedRatio = 0.0;
13610 : } else {
13611 0 : SpeedRatio = PartLoadFrac;
13612 0 : PartLoadFrac = 1.0;
13613 0 : this->m_CompPartLoadRatio = 1.0;
13614 : }
13615 :
13616 : } else {
13617 : }
13618 : } // END IF humidity ratio setpoint not met - Multimode humidity control
13619 :
13620 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13621 : // then overcool to meet moisture load
13622 2750022 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13623 : // pass
13624 2710093 : } else if ((OutletHumRatDXCoil > DesOutHumRat) && (!unitSys || PartLoadFrac < 1.0) && LatentLoad &&
13625 24533 : (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat)) {
13626 :
13627 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13628 : // do not run the compressor
13629 17348 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc) {
13630 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13631 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the DesOutHumRat,
13632 : // run the compressor at PartLoadFrac = 1.
13633 : // ELSEIF ((DesOutHumRat-FullLoadHumRatOut) .LT. HumRatAcc) THEN
13634 17348 : } else if (FullLoadHumRatOut > (DesOutHumRat - tempHumRatAcc)) {
13635 13054 : PartLoadFrac = 1.0;
13636 13054 : SpeedRatio = 1.0; // #8849, need to set properties of multi-speed/2-speed coils
13637 13054 : if (this->m_IsDXCoil) {
13638 13054 : this->m_CompPartLoadRatio = PartLoadFrac;
13639 : }
13640 : // ELSE find the PLR to meet the load
13641 :
13642 : } else {
13643 :
13644 4294 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13645 5232 : auto f = [&state, this, DesOutHumRat, fanOp](Real64 const PartLoadRatio) {
13646 5232 : DXCoils::CalcDoe2DXCoil(state, this->m_CoolingCoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13647 5232 : Real64 OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13648 5232 : return DesOutHumRat - OutletAirHumRat;
13649 546 : };
13650 546 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13651 546 : this->m_CompPartLoadRatio = PartLoadFrac;
13652 3748 : } else if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13653 :
13654 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13655 : // do not run the compressor
13656 918 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc * 2.0) {
13657 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13658 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the
13659 : // DesOutHumRat, run the compressor at PartLoadFrac = 1.
13660 918 : } else if ((DesOutHumRat - FullLoadHumRatOut) < tempHumRatAcc * 2.0) {
13661 6 : PartLoadFrac = 1.0;
13662 : // ELSE find the PLR to meet the load
13663 : } else {
13664 4955 : auto f = [&state, this, FirstHVACIteration, HXUnitOn, fanOp, DesOutHumRat](Real64 const PartLoadRatio) {
13665 8086 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13666 4043 : this->m_CoolingCoilIndex,
13667 : FirstHVACIteration,
13668 : HVAC::CompressorOp::On,
13669 : PartLoadRatio,
13670 : HXUnitOn,
13671 : fanOp,
13672 : _,
13673 4043 : state.dataUnitarySystems->economizerFlag,
13674 8086 : HVAC::CoilMode::Normal,
13675 4043 : 0.0);
13676 4043 : return DesOutHumRat - state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13677 912 : };
13678 912 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13679 912 : if (SolFla == -1) {
13680 :
13681 : // RegulaFalsi may not find latent PLR when the latent degradation model is used.
13682 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13683 0 : TempMaxPLR = -0.1;
13684 0 : while ((OutletHumRatDXCoil - DesOutHumRat) >= 0.0 && TempMaxPLR <= 1.0) {
13685 : // find upper limit of LatentPLR
13686 0 : TempMaxPLR += 0.1;
13687 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13688 : CompName,
13689 : FirstHVACIteration,
13690 : HVAC::CompressorOp::On,
13691 : TempMaxPLR,
13692 0 : this->m_CoolingCoilIndex,
13693 : fanOp,
13694 : HXUnitOn,
13695 : _,
13696 0 : state.dataUnitarySystems->economizerFlag,
13697 : _,
13698 0 : this->m_DehumidificationMode,
13699 0 : 0.0); // this->CoilSHR);
13700 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13701 : }
13702 0 : TempMaxPLR = min(1.0, TempMaxPLR + 0.1);
13703 0 : TempMinPLR = TempMaxPLR;
13704 0 : while ((OutletHumRatDXCoil - DesOutHumRat) <= 0.0 && TempMinPLR >= 0.0) {
13705 : // pull upper limit of LatentPLR DOwn to last valid limit (i.e. latent output still
13706 : // exceeds SystemMoisuterLoad)
13707 : // find minimum limit of Latent PLR
13708 0 : TempMinPLR -= 0.02;
13709 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13710 : CompName,
13711 : FirstHVACIteration,
13712 : HVAC::CompressorOp::On,
13713 : TempMinPLR,
13714 0 : this->m_CoolingCoilIndex,
13715 : fanOp,
13716 : HXUnitOn,
13717 : _,
13718 0 : state.dataUnitarySystems->economizerFlag,
13719 : _,
13720 0 : this->m_DehumidificationMode,
13721 0 : 0.0); // this->CoilSHR);
13722 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13723 : }
13724 0 : TempMinPLR = max(0.0, TempMinPLR - 0.1);
13725 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13726 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13727 0 : if (SolFla == -1) {
13728 0 : if (!state.dataGlobal->WarmupFlag) {
13729 0 : if (this->warnIndex.m_HXAssistedCRLatPLRIter < 1) {
13730 0 : ++this->warnIndex.m_HXAssistedCRLatPLRIter;
13731 0 : ShowWarningError(
13732 : state,
13733 0 : format("{} - Iteration limit exceeded calculating DX unit latent part-load ratio for unit = {}",
13734 0 : this->UnitType,
13735 0 : this->Name));
13736 0 : ShowContinueError(state, format("Estimated latent part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13737 0 : ShowContinueError(state, format("Calculated latent part-load ratio = {:.3R}", PartLoadFrac));
13738 0 : ShowContinueErrorTimeStamp(state,
13739 : "The calculated latent part-load ratio will be used and the simulation "
13740 : "continues. Occurrence info:");
13741 : }
13742 0 : ShowRecurringWarningErrorAtEnd(state,
13743 0 : this->UnitType + " \"" + this->Name +
13744 : "\" - Iteration limit exceeded calculating latent part-load ratio "
13745 : "error continues. Latent PLR "
13746 : "statistics follow.",
13747 0 : this->warnIndex.m_HXAssistedCRLatPLRIterIndex,
13748 : PartLoadFrac,
13749 : PartLoadFrac);
13750 : }
13751 :
13752 0 : } else if (SolFla == -2) {
13753 :
13754 0 : PartLoadFrac = ReqOutput / FullOutput;
13755 0 : if (!state.dataGlobal->WarmupFlag) {
13756 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail < 1) {
13757 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail;
13758 0 : ShowWarningError(state,
13759 0 : format("{} - DX unit latent part-load ratio calculation failed unexpectedly: part-load "
13760 : "ratio limits exceeded, for unit = {}",
13761 0 : this->UnitType,
13762 0 : this->Name));
13763 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13764 0 : ShowContinueErrorTimeStamp(
13765 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13766 : }
13767 0 : ShowRecurringWarningErrorAtEnd(state,
13768 0 : this->UnitType + " \"" + this->Name +
13769 : "\" - DX unit latent part-load ratio calculation failed "
13770 : "unexpectedly error continues. Latent PLR "
13771 : "statistics follow.",
13772 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex,
13773 : PartLoadFrac,
13774 : PartLoadFrac);
13775 : }
13776 : }
13777 912 : } else if (SolFla == -2) {
13778 0 : PartLoadFrac = ReqOutput / FullOutput;
13779 0 : if (!state.dataGlobal->WarmupFlag) {
13780 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail2 < 1) {
13781 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail2;
13782 0 : ShowWarningError(state,
13783 0 : format("{} - DX unit latent part-load ratio calculation failed: part-load ratio limits "
13784 : "exceeded, for unit = {}",
13785 0 : this->UnitType,
13786 0 : this->Name));
13787 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13788 0 : ShowContinueErrorTimeStamp(
13789 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13790 : }
13791 0 : ShowRecurringWarningErrorAtEnd(
13792 : state,
13793 0 : this->UnitType + " \"" + this->Name +
13794 : "\" - DX unit latent part-load ratio calculation failed error continues. Latent PLR statistics "
13795 : "follow.",
13796 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex2,
13797 : PartLoadFrac,
13798 : PartLoadFrac);
13799 : }
13800 : }
13801 : }
13802 918 : this->m_CompPartLoadRatio = PartLoadFrac;
13803 :
13804 2830 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13805 :
13806 : // Simulate MultiSpeed DX coil at sensible result
13807 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13808 :
13809 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13810 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13811 : // then overcool to meet moisture load
13812 :
13813 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13814 :
13815 0 : CycRatio = 0.0;
13816 0 : SpeedRatio = 0.0;
13817 :
13818 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13819 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13820 0 : if (OutletHumRatLS > DesOutHumRat) {
13821 0 : CycRatio = 1.0;
13822 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13823 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13824 0 : if (OutletHumRatHS < DesOutHumRat) {
13825 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13826 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13827 : SpeedRatio,
13828 0 : this->m_CoolingCoilIndex,
13829 : DesOutHumRat,
13830 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13831 : 0.0, // Real64 CycRatio,
13832 : 0, // int SpeedNum,
13833 : HVAC::FanOp::Invalid, // int FanOpMode,
13834 0 : HVAC::CompressorOp::On);
13835 0 : };
13836 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13837 : } else {
13838 0 : SpeedRatio = 1.0;
13839 : }
13840 0 : PartLoadFrac = SpeedRatio;
13841 : } else {
13842 0 : SpeedRatio = 0.0;
13843 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13844 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13845 : state,
13846 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13847 0 : this->m_CoolingCoilIndex,
13848 : DesOutHumRat,
13849 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13850 : 1.0, // Real64 CycRatio,
13851 0 : this->m_CoolingSpeedNum,
13852 0 : this->m_FanOpMode, // int FanOpMode,
13853 0 : HVAC::CompressorOp::On);
13854 0 : };
13855 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13856 0 : PartLoadFrac = CycRatio;
13857 : }
13858 : }
13859 :
13860 2830 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13861 :
13862 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13863 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13864 :
13865 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13866 : // then overcool to meet moisture load
13867 :
13868 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13869 :
13870 0 : CycRatio = 0.0;
13871 0 : SpeedRatio = 0.0;
13872 :
13873 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13874 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13875 0 : if (OutletHumRatLS > DesOutHumRat) {
13876 0 : CycRatio = 1.0;
13877 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13878 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13879 0 : if (OutletHumRatHS < DesOutHumRat) {
13880 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13881 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13882 : SpeedRatio,
13883 0 : this->m_CoolingCoilIndex,
13884 : DesOutHumRat,
13885 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13886 : 0.0, // Real64 CycRatio,
13887 : 0, // int SpeedNum,
13888 : HVAC::FanOp::Invalid, // int FanOpMode,
13889 0 : HVAC::CompressorOp::On);
13890 0 : };
13891 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13892 : } else {
13893 0 : SpeedRatio = 1.0;
13894 : }
13895 : } else {
13896 0 : SpeedRatio = 0.0;
13897 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13898 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13899 : state,
13900 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13901 0 : this->m_CoolingCoilIndex,
13902 : DesOutHumRat,
13903 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13904 : 0.0, // Real64 CycRatio,
13905 : 0,
13906 : HVAC::FanOp::Invalid, // int FanOpMode,
13907 0 : HVAC::CompressorOp::On);
13908 0 : };
13909 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13910 : }
13911 : }
13912 2830 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13913 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13914 968 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13915 : CompName,
13916 968 : this->m_CoolingCoilIndex,
13917 : this->m_FanOpMode,
13918 : HVAC::CompressorOp::On,
13919 : CycRatio,
13920 : this->m_CoolingSpeedNum,
13921 : SpeedRatio,
13922 : ReqOutput,
13923 : dummy,
13924 : OnOffAirFlowRatio);
13925 968 : OutletHumRatLS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13926 :
13927 968 : if (OutletHumRatLS > DesOutHumRat) {
13928 968 : CycRatio = 1.0;
13929 :
13930 968 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; ++speedNum) {
13931 968 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13932 : CompName,
13933 968 : this->m_CoolingCoilIndex,
13934 : this->m_FanOpMode,
13935 : HVAC::CompressorOp::On,
13936 : 1.0,
13937 : speedNum,
13938 : 1.0,
13939 : ReqOutput,
13940 : dummy,
13941 : OnOffAirFlowRatio);
13942 968 : OutletHumRatHS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13943 968 : if (OutletHumRatHS < DesOutHumRat || speedNum == this->m_NumOfSpeedCooling) {
13944 968 : this->m_CoolingSpeedNum = speedNum;
13945 968 : break;
13946 : }
13947 : }
13948 :
13949 968 : if (OutletHumRatHS < DesOutHumRat) {
13950 968 : if (this->m_CoolingSpeedNum == 1) {
13951 2904 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13952 5808 : return UnitarySys::DXCoilCyclingHumRatResidual(
13953 : state,
13954 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13955 2904 : this->m_CoolingCoilIndex,
13956 : DesOutHumRat,
13957 2904 : this->m_UnitarySysNum, // int UnitarySysNum,
13958 : 1.0, // Real64 CycRatio,
13959 2904 : this->m_CoolingSpeedNum,
13960 2904 : this->m_FanOpMode, // int FanOpMode,
13961 2904 : HVAC::CompressorOp::On);
13962 968 : };
13963 968 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13964 : } else {
13965 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13966 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13967 : SpeedRatio,
13968 0 : this->m_CoolingCoilIndex,
13969 : DesOutHumRat,
13970 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13971 : 1.0, // Real64 CycRatio,
13972 0 : this->m_CoolingSpeedNum,
13973 0 : this->m_FanOpMode, // int FanOpMode,
13974 0 : HVAC::CompressorOp::On);
13975 0 : };
13976 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13977 : }
13978 : } else {
13979 0 : if (this->m_CoolingSpeedNum == 1) {
13980 0 : CycRatio = 1.0;
13981 : } else {
13982 0 : SpeedRatio = 1.0;
13983 : }
13984 : }
13985 : } else {
13986 0 : SpeedRatio = 0.0;
13987 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13988 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13989 : SpeedRatio,
13990 0 : this->m_CoolingCoilIndex,
13991 : DesOutHumRat,
13992 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13993 : 0.0, // Real64 CycRatio,
13994 : 0, // int SpeedNum
13995 : HVAC::FanOp::Invalid, // int FanOpMode,
13996 0 : HVAC::CompressorOp::On);
13997 0 : };
13998 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13999 : }
14000 2830 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
14001 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
14002 0 : DXCoils::SimDXCoilMultiMode(
14003 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
14004 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
14005 0 : };
14006 0 : General::SolveRoot(state, Acc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14007 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14008 1862 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
14009 1858 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
14010 1858 : if (this->m_CoolingSpeedNum == 0) {
14011 0 : this->m_CoolingSpeedNum = 1;
14012 : }
14013 1858 : bool const singleMode = (this->m_SingleMode == 1);
14014 1858 : PartLoadFrac = 1.0;
14015 1858 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
14016 1858 : this->m_CoolingSpeedNum = speedNum;
14017 1858 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14018 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
14019 : // Cooling: break if outlet humrat is lower than DesOutHumRat or approaches DesOutHumRat to within HumRatAcc from above
14020 1858 : if ((state.dataLoopNodes->Node(OutletNode).HumRat - DesOutHumRat) < HumRatAcc) {
14021 1858 : break;
14022 : }
14023 : }
14024 : // make sure outlet HumRat is below set point before calling SolveRoot
14025 : // Cooling: iterate only when outlet humrat is below DesOutHumRat by at least HumRatAcc
14026 1858 : if ((DesOutHumRat - state.dataLoopNodes->Node(OutletNode).HumRat) > HumRatAcc) {
14027 :
14028 8853 : auto f = [&state,
14029 : this, // 0
14030 : DesOutHumRat, // 1
14031 : fanOp // 3
14032 : ](Real64 const PartLoadFrac) {
14033 8853 : bool const singleMode = false;
14034 8853 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14035 8853 : state, HVAC::CoilMode::Normal, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
14036 : Real64 outletCondition =
14037 8853 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex)
14038 8853 : .HumRat;
14039 8853 : return DesOutHumRat - outletCondition;
14040 1858 : };
14041 :
14042 1858 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14043 : }
14044 1858 : if (this->m_CoolingSpeedNum == 1) {
14045 1858 : this->m_CompPartLoadRatio = PartLoadFrac;
14046 1858 : SpeedRatio = 0.0;
14047 : } else {
14048 0 : SpeedRatio = PartLoadFrac;
14049 0 : PartLoadFrac = 1.0;
14050 0 : this->m_CompPartLoadRatio = 1.0;
14051 : }
14052 :
14053 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
14054 :
14055 32 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat](Real64 const PartLoadRatio) {
14056 32 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14057 32 : Real64 mdot = min(state.dataLoopNodes->Node(thisSys.CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14058 32 : thisSys.MaxCoolCoilFluidFlow * PartLoadRatio);
14059 32 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = mdot;
14060 64 : WaterCoils::SimulateWaterCoilComponents(
14061 32 : state, thisSys.m_CoolingCoilName, FirstHVACIteration, thisSys.m_CoolingCoilIndex, _, _, PartLoadRatio);
14062 32 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
14063 4 : };
14064 :
14065 4 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14066 :
14067 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
14068 :
14069 0 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat, ReqOutput](Real64 const PartLoadRatio) {
14070 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14071 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
14072 0 : Real64 dummy = 0.0;
14073 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
14074 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14075 : blankString,
14076 0 : thisSys.m_CoolingCoilIndex,
14077 : ReqOutput,
14078 : dummy,
14079 : thisSys.m_FanOpMode,
14080 : HVAC::CompressorOp::Off,
14081 : PartLoadRatio,
14082 : FirstHVACIteration);
14083 : } else {
14084 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14085 : blankString,
14086 0 : thisSys.m_CoolingCoilIndex,
14087 : thisSys.MaxCoolAirMassFlow,
14088 : thisSys.m_FanOpMode,
14089 : FirstHVACIteration,
14090 0 : thisSys.m_InitHeatPump,
14091 : ReqOutput,
14092 : dummy,
14093 : HVAC::CompressorOp::Off,
14094 : PartLoadRatio);
14095 : }
14096 0 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
14097 0 : };
14098 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14099 :
14100 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
14101 :
14102 0 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
14103 0 : (this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::Off &&
14104 0 : this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
14105 0 : auto f = [&state, this, DesOutHumRat](Real64 const PartLoadRatio) {
14106 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14107 0 : PackagedThermalStorageCoil::SimTESCoil(state,
14108 : thisSys.m_CoolingCoilName,
14109 0 : thisSys.m_CoolingCoilIndex,
14110 : thisSys.m_FanOpMode,
14111 0 : thisSys.m_TESOpMode,
14112 : PartLoadRatio);
14113 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat - DesOutHumRat;
14114 0 : };
14115 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14116 : }
14117 :
14118 : } else {
14119 : }
14120 : }
14121 : }
14122 : }
14123 3676380 : if (SolFla == -1) {
14124 4553 : if (!state.dataGlobal->WarmupFlag) {
14125 412 : if (this->warnIndex.m_SensPLRIter < 1) {
14126 1 : ++this->warnIndex.m_SensPLRIter;
14127 2 : ShowWarningError(state,
14128 2 : format("{} - Iteration limit exceeded calculating part-load ratio for unit = {}", this->UnitType, this->Name));
14129 1 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14130 1 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14131 3 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14132 : } else {
14133 3288 : ShowRecurringWarningErrorAtEnd(
14134 : state,
14135 822 : this->UnitType + " \"" + this->Name +
14136 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. Sensible PLR statistics follow.",
14137 411 : this->warnIndex.m_SensPLRIterIndex,
14138 : PartLoadFrac,
14139 : PartLoadFrac);
14140 : }
14141 : }
14142 3671827 : } else if (SolFla == -2) {
14143 0 : PartLoadFrac = ReqOutput / FullOutput;
14144 0 : if (!state.dataGlobal->WarmupFlag) {
14145 0 : if (this->warnIndex.m_SensPLRFail < 1) {
14146 0 : ++this->warnIndex.m_SensPLRFail;
14147 0 : ShowWarningError(state,
14148 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14149 0 : this->UnitType,
14150 0 : this->Name));
14151 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14152 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14153 : } else {
14154 0 : ShowRecurringWarningErrorAtEnd(
14155 : state,
14156 0 : this->UnitType + " \"" + this->Name +
14157 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14158 0 : this->warnIndex.m_SensPLRFailIndex,
14159 : PartLoadFrac,
14160 : PartLoadFrac);
14161 : }
14162 : }
14163 : }
14164 :
14165 3676380 : if (SolFlaLat == -1 && SolFla != -1) {
14166 0 : if (!state.dataGlobal->WarmupFlag) {
14167 0 : if (this->warnIndex.m_LatPLRIter < 1) {
14168 0 : ++this->warnIndex.m_LatPLRIter;
14169 0 : ShowWarningError(
14170 0 : state, format("{} - Iteration limit exceeded calculating latent part-load ratio for unit = {}", this->UnitType, this->Name));
14171 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14172 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14173 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14174 : }
14175 0 : ShowRecurringWarningErrorAtEnd(
14176 : state,
14177 0 : this->UnitType + " \"" + this->Name +
14178 : "\" - Iteration limit exceeded calculating latent part-load ratio error continues. Latent PLR statistics follow.",
14179 0 : this->warnIndex.m_LatPLRIterIndex,
14180 : PartLoadFrac,
14181 : PartLoadFrac);
14182 : }
14183 3676380 : } else if (SolFlaLat == -2 && SolFla != -2) {
14184 : // RegulaFalsi returns PLR = minPLR when a solution cannot be found, recalculate PartLoadFrac.
14185 0 : if (NoLoadHumRatOut - FullLoadHumRatOut != 0.0) {
14186 0 : PartLoadFrac = (NoLoadHumRatOut - DesOutHumRat) / (NoLoadHumRatOut - FullLoadHumRatOut);
14187 : } else {
14188 0 : PartLoadFrac = 1.0;
14189 : }
14190 0 : if (!state.dataGlobal->WarmupFlag) {
14191 0 : if (this->warnIndex.m_LatPLRFail < 1) {
14192 0 : ++this->warnIndex.m_LatPLRFail;
14193 0 : ShowWarningError(state,
14194 0 : format("{} - latent part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14195 0 : this->UnitType,
14196 0 : this->Name));
14197 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14198 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14199 : }
14200 0 : ShowRecurringWarningErrorAtEnd(state,
14201 0 : this->UnitType + " \"" + this->Name +
14202 : "\" - latent part-load ratio calculation failed error continues. Latent PLR statistics follow.",
14203 0 : this->warnIndex.m_LatPLRFailIndex,
14204 : PartLoadFrac,
14205 : PartLoadFrac);
14206 : }
14207 : }
14208 : // Set the final results
14209 :
14210 3676380 : if (PartLoadFrac > 1.0) {
14211 0 : PartLoadFrac = 1.0;
14212 3676380 : } else if (PartLoadFrac < 0.0) {
14213 0 : PartLoadFrac = 0.0;
14214 : }
14215 :
14216 3676380 : this->m_CoolingPartLoadFrac = PartLoadFrac;
14217 3676380 : this->m_CoolingSpeedRatio = SpeedRatio;
14218 3676380 : this->m_CoolingCycRatio = CycRatio;
14219 3676380 : this->m_DehumidificationMode = DehumidMode;
14220 :
14221 3800876 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14222 124496 : this->m_sysType != SysType::PackagedWSHP) {
14223 124496 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14224 124496 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14225 : }
14226 :
14227 3676380 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
14228 76032 : mdot = PartLoadFrac * this->MaxCoolCoilFluidFlow;
14229 76032 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
14230 : }
14231 3676380 : } // namespace UnitarySystems
14232 :
14233 102811 : void UnitarySys::controlHeatingSystemToSP(EnergyPlusData &state,
14234 : int const AirLoopNum, // index to air loop
14235 : bool const FirstHVACIteration, // First HVAC iteration flag
14236 : HVAC::CompressorOp &compressorOp, // compressor on/off control
14237 : Real64 &HeatCoilLoad // load met by heating coil
14238 : )
14239 : {
14240 : // SUBROUTINE INFORMATION:
14241 : // AUTHOR Richard Raustad, FSEC
14242 : // DATE WRITTEN February 2013
14243 :
14244 : // PURPOSE OF THIS SUBROUTINE:
14245 : // Simulate the coil object at the required PLR.
14246 :
14247 : // METHODOLOGY EMPLOYED:
14248 : // Calculate operating PLR and adjust speed when using multispeed coils.
14249 :
14250 : // SUBROUTINE PARAMETER DEFINITIONS:
14251 102811 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14252 102811 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14253 102811 : bool constexpr SuppHeatingCoilFlag(false);
14254 :
14255 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14256 102811 : Real64 FullOutput = 0; // Sensible capacity (outlet - inlet) when the compressor is on
14257 102811 : Real64 ReqOutput = 0; // Sensible capacity (outlet - inlet) required to meet load or set point temperature
14258 :
14259 102811 : Real64 OutdoorDryBulb = 0.0; // local variable for OutDryBulbTemp
14260 102811 : Real64 OutdoorHumRat = 0.0; // local variable for OutHumRat
14261 102811 : Real64 OutdoorPressure = 0.0; // local variable for OutBaroPress
14262 102811 : Real64 OutdoorWetBulb = 0.0; // local variable for OutWetBulbTemp
14263 102811 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14264 102811 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14265 :
14266 : // Set local variables
14267 : // Retrieve the load on the controlled zone
14268 102811 : int InletNode = this->HeatCoilInletNodeNum;
14269 102811 : int OutletNode = this->HeatCoilOutletNodeNum;
14270 102811 : std::string CompName = this->m_HeatingCoilName;
14271 102811 : int CompIndex = this->m_HeatingCoilIndex;
14272 102811 : HVAC::FanOp fanOp = this->m_FanOpMode;
14273 102811 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14274 :
14275 102811 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14276 102811 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14277 102811 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14278 0 : this->m_sysType != SysType::PackagedWSHP) {
14279 0 : LoopHeatingCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF;
14280 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
14281 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
14282 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
14283 : }
14284 :
14285 102811 : Real64 PartLoadFrac = 0.0;
14286 102811 : Real64 SpeedRatio = 0.0;
14287 102811 : Real64 CycRatio = 0.0;
14288 102811 : Real64 dummy = 0.0;
14289 102811 : int SolFla = 0;
14290 102811 : Real64 SensLoad = 0.0;
14291 102811 : Real64 OutletTemp = 0.0;
14292 :
14293 102811 : if (this->m_CondenserNodeNum != 0) {
14294 68625 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
14295 68625 : if (this->m_CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
14296 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14297 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14298 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14299 : } else {
14300 68625 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
14301 : // IF node is not connected to anything, pressure = default, use weather data
14302 68625 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
14303 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14304 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14305 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14306 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14307 : } else {
14308 68625 : OutdoorHumRat = state.dataLoopNodes->Node(this->m_CondenserNodeNum).HumRat;
14309 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
14310 68625 : OutdoorWetBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).OutAirWetBulb;
14311 : }
14312 : }
14313 : } else {
14314 34186 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14315 34186 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14316 34186 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14317 34186 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14318 : }
14319 :
14320 : // IF there is a fault of coil SAT Sensor
14321 102811 : if (this->m_FaultyCoilSATFlag) {
14322 : // calculate the sensor offset using fault information
14323 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14324 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14325 : // update the DesOutTemp
14326 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14327 : }
14328 :
14329 : // IF DXHeatingSystem is scheduled on and there is flow
14330 205598 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && this->m_heatingCoilAvailSched->getCurrentVal() > 0.0 &&
14331 102787 : state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow) {
14332 :
14333 102787 : bool SensibleLoad = false;
14334 : // Determine if there is a sensible load on this system
14335 102787 : if (DesOutTemp - state.dataLoopNodes->Node(InletNode).Temp > HVAC::TempControlTol) {
14336 30921 : SensibleLoad = true;
14337 : }
14338 : // if a heat pump and other coil is on, disable this coil
14339 102787 : if (this->m_HeatPump && this->m_CoolingPartLoadFrac > 0.0) {
14340 5179 : SensibleLoad = false;
14341 : }
14342 :
14343 : // disable compressor if OAT is below minimum outdoor temperature
14344 102787 : if (OutdoorDryBulb < this->m_MinOATCompressorHeating) {
14345 2050 : SensibleLoad = false;
14346 : }
14347 :
14348 : // IF DXHeatingSystem runs with a heating load then set PartLoadFrac on Heating System
14349 102787 : if (SensibleLoad) {
14350 :
14351 28886 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14352 86658 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
14353 28886 : state.dataLoopNodes->Node(InletNode).HumRat,
14354 28886 : state.dataLoopNodes->Node(InletNode).Temp,
14355 28886 : state.dataLoopNodes->Node(InletNode).HumRat);
14356 28886 : ReqOutput = max(0.0, ReqOutput);
14357 :
14358 : // Get no load result
14359 28886 : PartLoadFrac = 0.0;
14360 28886 : compressorOp = HVAC::CompressorOp::Off;
14361 :
14362 28886 : switch (this->m_HeatingCoilType_Num) {
14363 0 : case HVAC::CoilDX_HeatingEmpirical: {
14364 0 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, CompIndex, fanOp, PartLoadFrac);
14365 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14366 0 : } break;
14367 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
14368 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14369 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14370 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
14371 0 : if (HeatingActive) {
14372 0 : PartLoadFrac = 1.0;
14373 : }
14374 :
14375 0 : } break;
14376 2247 : case HVAC::CoilDX_MultiSpeedHeating:
14377 : case HVAC::Coil_HeatingElectric_MultiStage:
14378 : case HVAC::Coil_HeatingGas_MultiStage: {
14379 2247 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14380 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14381 0 : this->m_SpeedNum = this->m_HeatingSpeedNum;
14382 0 : bool useMaxedSpeed = false;
14383 0 : if (this->m_SpeedNum > this->m_NumOfSpeedHeating) {
14384 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14385 0 : this->m_SpeedNum = this->m_NumOfSpeedHeating;
14386 0 : this->m_CoilSpeedErrIdx++;
14387 0 : useMaxedSpeed = true;
14388 0 : ShowRecurringWarningErrorAtEnd(
14389 : state,
14390 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_HeatingCoilName +
14391 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
14392 0 : this->m_CoilSpeedErrIdx,
14393 0 : this->m_EMSOverrideCoilSpeedNumValue,
14394 0 : this->m_EMSOverrideCoilSpeedNumValue,
14395 : _,
14396 : "",
14397 : "");
14398 : }
14399 0 : if (this->m_HeatingSpeedNum == 1) {
14400 0 : this->m_HeatingSpeedRatio = 0.0;
14401 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14402 0 : this->m_HeatingCycRatio = CycRatio;
14403 0 : if (useMaxedSpeed || CycRatio == 0) {
14404 0 : this->m_HeatingCycRatio = 1;
14405 : } else {
14406 0 : this->m_HeatingCycRatio = CycRatio;
14407 : }
14408 : } else {
14409 0 : this->m_HeatingCycRatio = 1.0;
14410 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14411 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14412 0 : if (useMaxedSpeed || SpeedRatio == 0) {
14413 0 : this->m_HeatingSpeedRatio = 1;
14414 : } else {
14415 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14416 : }
14417 : }
14418 : }
14419 2247 : bool LatentLoad = false;
14420 2247 : this->simMultiSpeedCoils(
14421 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, this->m_SpeedNum);
14422 2247 : } break;
14423 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14424 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14425 0 : int SpeedNum = 0;
14426 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14427 0 : VariableSpeedCoils::SimVariableSpeedCoils(
14428 0 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14429 0 : } break;
14430 26639 : case HVAC::Coil_HeatingGasOrOtherFuel:
14431 : case HVAC::Coil_HeatingElectric:
14432 : case HVAC::Coil_HeatingDesuperheater: {
14433 26639 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, PartLoadFrac, CompIndex, _, _, fanOp);
14434 26639 : } break;
14435 0 : case HVAC::Coil_HeatingWater: {
14436 0 : WaterCoils::SimulateWaterCoilComponents(
14437 0 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14438 0 : } break;
14439 0 : case HVAC::Coil_HeatingSteam: {
14440 0 : SteamCoils::SimulateSteamCoilComponents(state,
14441 : CompName,
14442 : FirstHVACIteration,
14443 0 : this->m_HeatingCoilIndex,
14444 0 : 1.0,
14445 : _,
14446 0 : this->m_FanOpMode,
14447 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14448 0 : } break;
14449 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14450 0 : if (FirstHVACIteration) {
14451 0 : this->m_CompPartLoadRatio = 1;
14452 : }
14453 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14454 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::Off, PartLoadFrac, FirstHVACIteration);
14455 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14456 0 : this->m_HeatingCoilSensDemand = 0.0;
14457 0 : } break;
14458 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14459 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14460 : blankString,
14461 : CompIndex,
14462 : this->MaxHeatAirMassFlow,
14463 : fanOp,
14464 : FirstHVACIteration,
14465 0 : this->m_InitHeatPump,
14466 : ReqOutput,
14467 : dummy,
14468 : HVAC::CompressorOp::Off,
14469 : PartLoadFrac);
14470 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14471 0 : } break;
14472 0 : default:
14473 0 : break;
14474 : }
14475 :
14476 : // IF outlet temp at no load is within ACC of set point, do not run the coil
14477 :
14478 57772 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14479 28886 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14480 : // do nothing, coil is at the set point.
14481 28886 : } else if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) > Acc) { // IF outlet temp is above set point turn off coil
14482 0 : PartLoadFrac = 0.0;
14483 : } else { // ELSE get full load result
14484 :
14485 : // Get full load result
14486 28886 : PartLoadFrac = 1.0;
14487 28886 : compressorOp = HVAC::CompressorOp::On;
14488 :
14489 28886 : switch (this->m_HeatingCoilType_Num) {
14490 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14491 0 : DXCoils::SimDXCoil(
14492 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_HeatingCoilIndex, fanOp, PartLoadFrac);
14493 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14494 0 : } break;
14495 0 : case HVAC::Coil_UserDefined: {
14496 : // should never get here, coil cannot be controlled and has already been simulated
14497 0 : } break;
14498 2247 : case HVAC::CoilDX_MultiSpeedHeating: {
14499 2247 : CycRatio = 1.0;
14500 2247 : SpeedRatio = 0.0;
14501 2247 : int SpeedNum = 0;
14502 2247 : bool LatentLoad = false;
14503 2247 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14504 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14505 0 : SpeedNum = this->m_HeatingSpeedNum;
14506 0 : if (this->m_HeatingSpeedNum == 1) {
14507 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14508 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14509 0 : this->m_HeatingCycRatio = CycRatio;
14510 0 : if (CycRatio == 0) {
14511 0 : this->m_HeatingCycRatio = 1;
14512 : } else {
14513 0 : this->m_HeatingCycRatio = CycRatio;
14514 : }
14515 : } else {
14516 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14517 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14518 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14519 0 : if (SpeedRatio == 0) {
14520 0 : this->m_HeatingSpeedRatio = 1;
14521 : } else {
14522 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14523 : }
14524 : }
14525 0 : if (SpeedNum > this->m_NumOfSpeedHeating) {
14526 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14527 0 : SpeedNum = this->m_NumOfSpeedHeating;
14528 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14529 0 : if (this->m_HeatingSpeedNum == 1) {
14530 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14531 : } else {
14532 0 : this->m_HeatingSpeedRatio = SpeedRatio = 1.0;
14533 : }
14534 : }
14535 0 : this->simMultiSpeedCoils(
14536 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14537 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14538 : } else {
14539 6737 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14540 4492 : if (SpeedNum > 1) {
14541 2245 : CycRatio = 0.0;
14542 2245 : SpeedRatio = 1.0;
14543 : }
14544 4492 : this->m_HeatingSpeedNum = SpeedNum;
14545 4492 : this->simMultiSpeedCoils(state,
14546 : AirLoopNum,
14547 : FirstHVACIteration,
14548 : compressorOp,
14549 : SensibleLoad,
14550 : LatentLoad,
14551 : PartLoadFrac,
14552 : HeatingCoil,
14553 : SpeedNum);
14554 4492 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14555 4492 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14556 2 : break;
14557 : }
14558 : }
14559 : }
14560 2247 : } break;
14561 0 : case HVAC::Coil_HeatingElectric_MultiStage:
14562 : case HVAC::Coil_HeatingGas_MultiStage: {
14563 0 : bool LatentLoad = false;
14564 0 : CycRatio = 1.0;
14565 0 : SpeedRatio = 1.0;
14566 0 : SensLoad = 1.0; // turns on coil
14567 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14568 0 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14569 0 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14570 0 : this->m_HeatingSpeedNum = SpeedNum;
14571 0 : this->simMultiSpeedCoils(
14572 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14573 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14574 0 : SpeedRatio = double(SpeedNum) - 1.0;
14575 0 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14576 0 : break;
14577 : }
14578 : }
14579 0 : } break;
14580 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14581 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14582 0 : CycRatio = 1.0;
14583 0 : SpeedRatio = 1.0;
14584 0 : SensLoad = 1.0; // turns on coil
14585 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14586 0 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14587 0 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14588 0 : this->m_HeatingSpeedNum = SpeedNum;
14589 0 : VariableSpeedCoils::SimVariableSpeedCoils(
14590 0 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14591 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14592 0 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14593 0 : break;
14594 : }
14595 : }
14596 0 : } break;
14597 26639 : case HVAC::Coil_HeatingGasOrOtherFuel:
14598 : case HVAC::Coil_HeatingElectric: {
14599 53278 : HeatingCoils::SimulateHeatingCoilComponents(
14600 26639 : state, CompName, FirstHVACIteration, this->m_DesignHeatingCapacity, CompIndex, _, _, fanOp);
14601 26639 : } break;
14602 0 : case HVAC::Coil_HeatingDesuperheater: {
14603 0 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, ReqOutput, CompIndex, _, _, fanOp);
14604 0 : } break;
14605 0 : case HVAC::Coil_HeatingWater: {
14606 0 : mdot = this->MaxHeatCoilFluidFlow;
14607 0 : PlantUtilities::SetComponentFlowRate(
14608 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14609 :
14610 0 : WaterCoils::SimulateWaterCoilComponents(
14611 0 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14612 0 : } break;
14613 0 : case HVAC::Coil_HeatingSteam: {
14614 0 : mdot = this->MaxHeatCoilFluidFlow;
14615 0 : PlantUtilities::SetComponentFlowRate(
14616 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14617 :
14618 0 : SteamCoils::SimulateSteamCoilComponents(state,
14619 : CompName,
14620 : FirstHVACIteration,
14621 0 : this->m_HeatingCoilIndex,
14622 0 : 1.0,
14623 : _,
14624 0 : this->m_FanOpMode,
14625 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14626 0 : } break;
14627 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14628 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14629 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::On, PartLoadFrac, FirstHVACIteration);
14630 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14631 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14632 0 : } break;
14633 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14634 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14635 : blankString,
14636 : CompIndex,
14637 : this->MaxHeatAirMassFlow,
14638 : fanOp,
14639 : FirstHVACIteration,
14640 0 : this->m_InitHeatPump,
14641 : ReqOutput,
14642 : dummy,
14643 : HVAC::CompressorOp::Off,
14644 : PartLoadFrac);
14645 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14646 0 : } break;
14647 0 : default:
14648 0 : break;
14649 : }
14650 :
14651 28886 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14652 28886 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
14653 28886 : state.dataLoopNodes->Node(OutletNode).HumRat,
14654 28886 : state.dataLoopNodes->Node(InletNode).Temp,
14655 28886 : state.dataLoopNodes->Node(InletNode).HumRat);
14656 : // If the outlet temp is within ACC of set point,
14657 57772 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14658 28886 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14659 : // do nothing, coil is at set point
14660 28886 : } else if (state.dataLoopNodes->Node(OutletNode).Temp < (DesOutTemp - Acc)) { // IF outlet temp is below set point coil must be on
14661 7691 : PartLoadFrac = 1.0;
14662 : } else { // ELSE find the PLR to meet the set point
14663 :
14664 21195 : switch (this->m_HeatingCoilType_Num) {
14665 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14666 0 : auto f = [&state, CompIndex, DesOutTemp](Real64 const PartLoadFrac) {
14667 0 : DXCoils::CalcDXHeatingCoil(state, CompIndex, PartLoadFrac, HVAC::FanOp::Continuous, 1.0);
14668 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(CompIndex);
14669 0 : };
14670 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14671 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14672 0 : } break;
14673 2 : case HVAC::CoilDX_MultiSpeedHeating:
14674 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14675 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
14676 : case HVAC::Coil_HeatingElectric_MultiStage:
14677 : case HVAC::Coil_HeatingGas_MultiStage: {
14678 2 : if (this->m_HeatingSpeedNum > 1.0) {
14679 0 : auto f = [&state, this, DesOutTemp, CycRatio, fanOp](Real64 const SpeedRatio) {
14680 0 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14681 : SpeedRatio,
14682 0 : this->m_HeatingCoilIndex,
14683 : DesOutTemp,
14684 0 : this->m_UnitarySysNum,
14685 : CycRatio,
14686 0 : this->m_HeatingSpeedNum,
14687 : fanOp,
14688 : HVAC::CompressorOp::On,
14689 0 : false);
14690 0 : };
14691 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14692 0 : this->m_HeatingCycRatio = CycRatio;
14693 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14694 0 : this->m_HeatingPartLoadFrac = SpeedRatio;
14695 0 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14696 0 : PartLoadFrac = SpeedRatio;
14697 : } else {
14698 2 : SpeedRatio = 0.0;
14699 2 : this->m_HeatingSpeedRatio = SpeedRatio;
14700 6 : auto f = [&state, this, DesOutTemp, SpeedRatio, fanOp](Real64 const CycRatio) {
14701 12 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14702 : CycRatio,
14703 6 : this->m_HeatingCoilIndex,
14704 : DesOutTemp,
14705 6 : this->m_UnitarySysNum,
14706 : SpeedRatio,
14707 6 : this->m_HeatingSpeedNum,
14708 : fanOp,
14709 : HVAC::CompressorOp::On,
14710 6 : false);
14711 2 : };
14712 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14713 2 : this->m_HeatingCycRatio = CycRatio;
14714 2 : this->m_HeatingPartLoadFrac = CycRatio;
14715 2 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14716 2 : PartLoadFrac = CycRatio;
14717 : }
14718 2 : } break;
14719 21193 : case HVAC::Coil_HeatingGasOrOtherFuel: {
14720 63579 : HeatingCoils::SimulateHeatingCoilComponents(
14721 42386 : state, this->m_HeatingCoilName, FirstHVACIteration, ReqOutput, CompIndex, _, true, fanOp, PartLoadFrac);
14722 21193 : PartLoadFrac = ReqOutput / FullOutput;
14723 21193 : HeatCoilLoad = ReqOutput;
14724 21193 : } break;
14725 0 : case HVAC::Coil_HeatingElectric:
14726 : case HVAC::Coil_HeatingDesuperheater: {
14727 0 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14728 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, fanOp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14729 0 : return this->gasElecHeatingCoilResidual(state,
14730 : PartLoadFrac,
14731 0 : this->m_UnitarySysNum,
14732 : FirstHVACIteration,
14733 : DesOutTemp,
14734 : tmpSuppHeatingCoilFlag,
14735 : fanOp,
14736 0 : this->m_DesignHeatingCapacity);
14737 0 : };
14738 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14739 0 : } break;
14740 0 : case HVAC::Coil_HeatingWater: {
14741 :
14742 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14743 : maxPartLoadFrac =
14744 0 : min(1.0,
14745 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14746 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14747 :
14748 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const maxPartLoadFrac) {
14749 : Real64 OutletAirTemp; // Outlet air temperature [C]
14750 :
14751 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14752 0 : this->MaxHeatCoilFluidFlow * maxPartLoadFrac);
14753 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14754 0 : WaterCoils::SimulateWaterCoilComponents(state,
14755 0 : this->m_HeatingCoilName,
14756 : FirstHVACIteration,
14757 0 : this->m_HeatingCoilIndex,
14758 0 : 0.0, // QActual
14759 0 : this->m_FanOpMode,
14760 : maxPartLoadFrac);
14761 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14762 0 : return DesOutTemp - OutletAirTemp;
14763 0 : };
14764 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14765 0 : } break;
14766 0 : case HVAC::Coil_HeatingSteam: {
14767 :
14768 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14769 : maxPartLoadFrac =
14770 0 : min(1.0,
14771 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14772 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14773 :
14774 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14775 : Real64 OutletAirTemp; // Outlet air temperature [C]
14776 : Real64 mdot;
14777 :
14778 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14779 0 : this->MaxHeatCoilFluidFlow * PartLoadFrac);
14780 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14781 0 : SteamCoils::SimulateSteamCoilComponents(state,
14782 0 : this->m_HeatingCoilName,
14783 : FirstHVACIteration,
14784 0 : this->m_HeatingCoilIndex,
14785 0 : 1.0,
14786 : _,
14787 0 : this->m_FanOpMode,
14788 : PartLoadFrac);
14789 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp; // RR this should be supp coil
14790 0 : return DesOutTemp - OutletAirTemp;
14791 0 : };
14792 :
14793 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14794 0 : } break;
14795 0 : case HVAC::Coil_HeatingWaterToAirHPSimple:
14796 : case HVAC::Coil_HeatingWaterToAirHP: {
14797 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14798 :
14799 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
14800 : Real64 OutletAirTemp; // outlet air humidity ratio [kg/kg]
14801 : Real64 dummy;
14802 :
14803 0 : this->m_CompPartLoadRatio = PartLoadRatio;
14804 :
14805 0 : dummy = 0.0;
14806 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
14807 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14808 : blankString,
14809 0 : this->m_HeatingCoilIndex,
14810 : ReqOutput,
14811 : dummy,
14812 0 : this->m_FanOpMode,
14813 : HVAC::CompressorOp::On,
14814 : PartLoadRatio,
14815 : FirstHVACIteration);
14816 : } else {
14817 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14818 : blankString,
14819 0 : this->m_HeatingCoilIndex,
14820 0 : this->MaxHeatAirMassFlow,
14821 0 : this->m_FanOpMode,
14822 : FirstHVACIteration,
14823 0 : this->m_InitHeatPump,
14824 : ReqOutput,
14825 : dummy,
14826 : HVAC::CompressorOp::Off,
14827 : PartLoadRatio);
14828 : }
14829 :
14830 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14831 0 : return DesOutTemp - OutletAirTemp;
14832 0 : };
14833 :
14834 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14835 0 : } break;
14836 0 : case HVAC::Coil_UserDefined: {
14837 : // should never get here, user defined coil cannot be controlled and has already been simulated
14838 0 : } break;
14839 0 : default: {
14840 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
14841 0 : ShowFatalError(
14842 : state,
14843 0 : format("ControlHeatingSystemToSP: Invalid heating coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
14844 0 : } break;
14845 : }
14846 : }
14847 : }
14848 : }
14849 : }
14850 :
14851 102811 : if (PartLoadFrac > 1.0) {
14852 0 : PartLoadFrac = 1.0;
14853 102811 : } else if (PartLoadFrac < 0.0) {
14854 0 : PartLoadFrac = 0.0;
14855 : }
14856 :
14857 102811 : if (SolFla < 0) {
14858 0 : if (SolFla == -1) {
14859 0 : if (!state.dataGlobal->WarmupFlag) {
14860 0 : if (this->warnIndex.m_HeatCoilSensPLRIter < 1) {
14861 0 : ++this->warnIndex.m_HeatCoilSensPLRIter;
14862 0 : ShowWarningError(
14863 : state,
14864 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}", this->UnitType, this->Name));
14865 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14866 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14867 0 : ShowContinueErrorTimeStamp(state,
14868 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14869 : } else {
14870 0 : ShowRecurringWarningErrorAtEnd(state,
14871 0 : this->UnitType + " \"" + this->Name +
14872 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. "
14873 : "Sensible PLR statistics follow.",
14874 0 : this->warnIndex.m_HeatCoilSensPLRIterIndex,
14875 : PartLoadFrac,
14876 : PartLoadFrac);
14877 : }
14878 : }
14879 0 : } else if (SolFla == -2) {
14880 0 : PartLoadFrac = ReqOutput / FullOutput;
14881 0 : if (!state.dataGlobal->WarmupFlag) {
14882 0 : if (this->warnIndex.m_HeatCoilSensPLRFail < 1) {
14883 0 : ++this->warnIndex.m_HeatCoilSensPLRFail;
14884 0 : ShowWarningError(state,
14885 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14886 0 : this->UnitType,
14887 0 : this->Name));
14888 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14889 0 : ShowContinueErrorTimeStamp(state,
14890 : "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14891 : } else {
14892 0 : ShowRecurringWarningErrorAtEnd(
14893 : state,
14894 0 : this->UnitType + " \"" + this->Name +
14895 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14896 0 : this->warnIndex.m_HeatCoilSensPLRFailIndex,
14897 : PartLoadFrac,
14898 : PartLoadFrac);
14899 : }
14900 : }
14901 : }
14902 : }
14903 :
14904 : // Set the final results
14905 102811 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14906 102811 : this->m_HeatingSpeedRatio = SpeedRatio;
14907 102811 : this->m_HeatingCycRatio = CycRatio;
14908 102811 : HeatCoilLoad = ReqOutput;
14909 :
14910 102811 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14911 0 : this->m_sysType != SysType::PackagedWSHP) {
14912 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF =
14913 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14914 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14915 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14916 : }
14917 :
14918 102811 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
14919 0 : mdot = PartLoadFrac * this->MaxHeatCoilFluidFlow;
14920 0 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14921 : }
14922 102811 : }
14923 :
14924 98727 : void UnitarySys::controlSuppHeatSystemToSP(EnergyPlusData &state,
14925 : int const AirLoopNum, // index to air loop
14926 : bool const FirstHVACIteration // First HVAC iteration flag
14927 : )
14928 : {
14929 : // SUBROUTINE INFORMATION:
14930 : // AUTHOR Richard Raustad, FSEC
14931 : // DATE WRITTEN February 2013
14932 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
14933 :
14934 : // PURPOSE OF THIS SUBROUTINE:
14935 : // This subroutine updates the System outlet nodes.
14936 :
14937 : // METHODOLOGY EMPLOYED:
14938 : // Data is moved from the System data structure to the System outlet nodes.
14939 :
14940 : // SUBROUTINE PARAMETER DEFINITIONS:
14941 98727 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14942 98727 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14943 98727 : int constexpr SolveMaxIter(50);
14944 98727 : constexpr bool SuppHeatingCoilFlag(true);
14945 :
14946 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14947 98727 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
14948 98727 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14949 98727 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14950 98727 : Real64 PartLoadFrac = 0.0;
14951 98727 : Real64 SpeedRatio = 0.0;
14952 98727 : Real64 CycRatio = 0.0;
14953 :
14954 : // Set local variables
14955 98727 : auto &inletNode = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode);
14956 98727 : auto &outletNode = state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum);
14957 98727 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14958 98727 : std::string_view CompName = this->m_SuppHeatCoilName;
14959 :
14960 98727 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14961 98727 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14962 98727 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14963 0 : this->m_sysType != SysType::PackagedWSHP) {
14964 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14965 0 : LoopHeatingCoilMaxRTFSave = afnInfo.AFNLoopHeatingCoilMaxRTF;
14966 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = 0.0;
14967 0 : LoopDXCoilMaxRTFSave = afnInfo.AFNLoopDXCoilRTF;
14968 0 : afnInfo.AFNLoopDXCoilRTF = 0.0;
14969 : }
14970 :
14971 : // IF there is a fault of coil SAT Sensor
14972 98727 : if (this->m_FaultyCoilSATFlag) {
14973 : // calculate the sensor offset using fault information
14974 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14975 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14976 : // update the DesOutTemp
14977 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14978 : }
14979 :
14980 98727 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && (inletNode.MassFlowRate > HVAC::SmallAirVolFlow)) {
14981 :
14982 98709 : if (inletNode.Temp < (DesOutTemp - HVAC::TempControlTol)) {
14983 7681 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
14984 0 : this->setEMSSuppCoilStagePLR(state);
14985 : } else {
14986 : // Get no load result at PartLoadFrac = 0.0
14987 :
14988 7681 : switch (this->m_SuppHeatCoilType_Num) {
14989 5438 : case HVAC::Coil_HeatingGasOrOtherFuel:
14990 : case HVAC::Coil_HeatingElectric:
14991 : case HVAC::Coil_HeatingDesuperheater: {
14992 16314 : HeatingCoils::SimulateHeatingCoilComponents(state,
14993 : CompName,
14994 : FirstHVACIteration,
14995 : PartLoadFrac,
14996 5438 : this->m_SuppHeatCoilIndex,
14997 : QCoilActual,
14998 : SuppHeatingCoilFlag,
14999 5438 : this->m_FanOpMode,
15000 : PartLoadFrac); // QCoilReq=PartLoadFrac 0.0 for this call
15001 5438 : } break;
15002 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
15003 : // SpeedRatio = 0.0;
15004 8972 : HeatingCoils::SimulateHeatingCoilComponents(state,
15005 : CompName,
15006 : FirstHVACIteration,
15007 : DataLoopNode::SensedLoadFlagValue,
15008 2243 : this->m_SuppHeatCoilIndex,
15009 : QCoilActual,
15010 : SuppHeatingCoilFlag,
15011 2243 : this->m_FanOpMode,
15012 : PartLoadFrac,
15013 4486 : 0,
15014 : SpeedRatio);
15015 2243 : } break;
15016 0 : case HVAC::Coil_HeatingWater: {
15017 0 : WaterCoils::SimulateWaterCoilComponents(
15018 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
15019 0 : } break;
15020 0 : case HVAC::Coil_HeatingSteam: {
15021 0 : SteamCoils::SimulateSteamCoilComponents(state,
15022 : CompName,
15023 : FirstHVACIteration,
15024 0 : this->m_SuppHeatCoilIndex,
15025 0 : 1.0,
15026 : _,
15027 0 : this->m_FanOpMode,
15028 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
15029 0 : } break;
15030 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
15031 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
15032 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
15033 0 : UserDefinedComponents::SimCoilUserDefined(
15034 0 : state, CompName, this->m_SuppHeatCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
15035 0 : if (HeatingActive) {
15036 0 : PartLoadFrac = 1.0;
15037 : }
15038 0 : } break;
15039 0 : default:
15040 0 : break;
15041 : }
15042 :
15043 7681 : int SolFla = 0;
15044 : // If OutletTemp is within ACC of set point coil operation is not needed or UserDefined already met load.
15045 7681 : if (outletNode.Temp > (DesOutTemp - Acc) || this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
15046 : // do nothing, coil is at or above set point
15047 : } else {
15048 : // outlet temp too low, turn on coil
15049 : // Get full load result
15050 7681 : PartLoadFrac = 1.0;
15051 :
15052 7681 : switch (this->m_SuppHeatCoilType_Num) {
15053 5438 : case HVAC::Coil_HeatingGasOrOtherFuel:
15054 : case HVAC::Coil_HeatingElectric: {
15055 16314 : HeatingCoils::SimulateHeatingCoilComponents(state,
15056 : CompName,
15057 : FirstHVACIteration,
15058 5438 : this->m_DesignSuppHeatingCapacity,
15059 5438 : this->m_SuppHeatCoilIndex,
15060 : QCoilActual,
15061 : SuppHeatingCoilFlag,
15062 5438 : this->m_FanOpMode,
15063 : PartLoadFrac);
15064 5438 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
15065 5438 : PartLoadFrac = QCoilActual / this->m_DesignSuppHeatingCapacity;
15066 : }
15067 5438 : } break;
15068 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
15069 2243 : CycRatio = 1.0;
15070 2243 : SpeedRatio = 1.0;
15071 6336 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
15072 6336 : this->m_SuppHeatingSpeedNum = SpeedNum;
15073 19008 : HeatingCoils::SimulateHeatingCoilComponents(state,
15074 : CompName,
15075 : FirstHVACIteration,
15076 : DataLoopNode::SensedLoadFlagValue,
15077 6336 : this->m_SuppHeatCoilIndex,
15078 : QCoilActual,
15079 : SuppHeatingCoilFlag,
15080 6336 : this->m_FanOpMode,
15081 : PartLoadFrac,
15082 : SpeedNum,
15083 : SpeedRatio);
15084 6336 : if (outletNode.Temp > DesOutTemp) {
15085 2243 : break;
15086 : }
15087 : }
15088 2243 : } break;
15089 0 : case HVAC::Coil_HeatingDesuperheater: {
15090 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
15091 : CompName,
15092 : FirstHVACIteration,
15093 0 : this->m_DesignSuppHeatingCapacity,
15094 0 : this->m_SuppHeatCoilIndex,
15095 : _,
15096 : SuppHeatingCoilFlag,
15097 0 : this->m_FanOpMode);
15098 0 : } break;
15099 0 : case HVAC::Coil_HeatingWater: {
15100 0 : mdot = this->m_MaxSuppCoilFluidFlow;
15101 0 : PlantUtilities::SetComponentFlowRate(
15102 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15103 :
15104 0 : WaterCoils::SimulateWaterCoilComponents(
15105 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
15106 0 : } break;
15107 0 : case HVAC::Coil_HeatingSteam: {
15108 0 : mdot = this->m_MaxSuppCoilFluidFlow;
15109 0 : PlantUtilities::SetComponentFlowRate(
15110 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15111 :
15112 0 : SteamCoils::SimulateSteamCoilComponents(state,
15113 : CompName,
15114 : FirstHVACIteration,
15115 0 : this->m_SuppHeatCoilIndex,
15116 0 : 1.0,
15117 : _,
15118 0 : this->m_FanOpMode,
15119 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
15120 0 : } break;
15121 0 : case HVAC::Coil_UserDefined: {
15122 : // should never get here, coil has already been simulated
15123 0 : } break;
15124 0 : default:
15125 0 : break;
15126 : }
15127 :
15128 : // run the coil at PartLoadFrac = 1.
15129 7681 : if (outletNode.Temp < (DesOutTemp + Acc)) {
15130 0 : PartLoadFrac = 1.0; // these have already been set, leave as is for now
15131 0 : CycRatio = 1.0; // change to outletNode.Temp > and removed these vars and the "} else {"
15132 0 : SpeedRatio = 1.0;
15133 : } else {
15134 7681 : switch (this->m_SuppHeatCoilType_Num) {
15135 5438 : case HVAC::Coil_HeatingGasOrOtherFuel:
15136 : case HVAC::Coil_HeatingElectric:
15137 : case HVAC::Coil_HeatingDesuperheater: {
15138 5438 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
15139 16314 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
15140 32628 : return this->gasElecHeatingCoilResidual(state,
15141 : PartLoadFrac,
15142 16314 : this->m_UnitarySysNum,
15143 : FirstHVACIteration,
15144 : DesOutTemp,
15145 : tmpSuppHeatingCoilFlag,
15146 16314 : this->m_FanOpMode,
15147 16314 : this->m_DesignSuppHeatingCapacity);
15148 5438 : };
15149 5438 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
15150 5438 : } break;
15151 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
15152 2243 : if (this->m_SuppHeatingSpeedNum > 1) {
15153 6726 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
15154 13452 : return UnitarySys::heatingCoilVarSpeedResidual(state,
15155 : SpeedRatio,
15156 6726 : this->m_SuppHeatCoilIndex,
15157 : DesOutTemp,
15158 6726 : this->m_UnitarySysNum,
15159 : CycRatio,
15160 6726 : this->m_SuppHeatingSpeedNum,
15161 6726 : this->m_FanOpMode,
15162 : HVAC::CompressorOp::On,
15163 6726 : true);
15164 2242 : };
15165 2242 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
15166 2242 : PartLoadFrac = SpeedRatio;
15167 : } else {
15168 1 : SpeedRatio = 0.0;
15169 1 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
15170 3 : auto f = [&state, this, DesOutTemp, SpeedRatio](Real64 const CycRatio) {
15171 6 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
15172 : CycRatio,
15173 3 : this->m_SuppHeatCoilIndex,
15174 : DesOutTemp,
15175 3 : this->m_UnitarySysNum,
15176 : SpeedRatio,
15177 3 : this->m_SuppHeatingSpeedNum,
15178 3 : this->m_FanOpMode,
15179 : HVAC::CompressorOp::On,
15180 3 : true);
15181 1 : };
15182 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
15183 1 : PartLoadFrac = CycRatio;
15184 : }
15185 2243 : } break;
15186 0 : case HVAC::Coil_HeatingWater: {
15187 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
15188 : maxPartLoadFrac =
15189 0 : min(1.0,
15190 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
15191 : // max iteration limit (leave a little slop, 0.001)
15192 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
15193 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
15194 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
15195 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
15196 0 : WaterCoils::SimulateWaterCoilComponents(state,
15197 0 : this->m_SuppHeatCoilName,
15198 : FirstHVACIteration,
15199 0 : this->m_SuppHeatCoilIndex,
15200 0 : 0.0, // QActual
15201 0 : this->m_FanOpMode,
15202 : PartLoadFrac);
15203 :
15204 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
15205 0 : };
15206 :
15207 0 : General::SolveRoot(state, Acc, SolveMaxIter, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
15208 0 : } break;
15209 0 : case HVAC::Coil_HeatingSteam: {
15210 :
15211 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
15212 : maxPartLoadFrac =
15213 0 : min(1.0,
15214 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
15215 : // max iteration limit (leave a little slop, 0.001)
15216 :
15217 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
15218 : Real64 mdot;
15219 :
15220 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
15221 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
15222 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
15223 0 : SteamCoils::SimulateSteamCoilComponents(state,
15224 0 : this->m_SuppHeatCoilName,
15225 : FirstHVACIteration,
15226 0 : this->m_SuppHeatCoilIndex,
15227 0 : 1.0,
15228 : _,
15229 0 : this->m_FanOpMode,
15230 : PartLoadFrac);
15231 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
15232 0 : };
15233 :
15234 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
15235 0 : } break;
15236 0 : case HVAC::Coil_UserDefined: {
15237 : // do nothing, coil has already been simulated
15238 0 : } break;
15239 0 : default:
15240 0 : break;
15241 : }
15242 : }
15243 : } // IF (outletNode.Temp < (DesOutTemp + Acc)) THEN
15244 :
15245 7681 : if (PartLoadFrac > 1.0) {
15246 0 : PartLoadFrac = 1.0;
15247 7681 : } else if (PartLoadFrac < 0.0) {
15248 0 : PartLoadFrac = 0.0;
15249 : }
15250 :
15251 7681 : if (SolFla == -1) {
15252 0 : if (!state.dataGlobal->WarmupFlag) {
15253 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRIter < 1) {
15254 0 : Real64 ReqOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
15255 0 : DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15256 : Real64 FullOutput =
15257 0 : inletNode.MassFlowRate *
15258 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15259 :
15260 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRIter;
15261 0 : ShowWarningError(state,
15262 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}",
15263 0 : this->UnitType,
15264 0 : this->Name));
15265 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
15266 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
15267 0 : ShowContinueErrorTimeStamp(
15268 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
15269 : } else {
15270 0 : ShowRecurringWarningErrorAtEnd(state,
15271 0 : format("{} \"{}\" - Iteration limit exceeded calculating sensible part-load ratio "
15272 : "error continues. Sensible PLR statistics follow.",
15273 0 : this->UnitType,
15274 0 : this->Name),
15275 0 : this->warnIndex.m_SuppHeatCoilSensPLRIterIndex,
15276 : PartLoadFrac,
15277 : PartLoadFrac);
15278 : }
15279 : } // IF(.NOT. WarmupFlag)THEN
15280 7681 : } else if (SolFla == -2) {
15281 0 : Real64 ReqOutput = inletNode.MassFlowRate *
15282 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15283 0 : Real64 FullOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
15284 0 : outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15285 :
15286 0 : PartLoadFrac = ReqOutput / FullOutput;
15287 0 : if (!state.dataGlobal->WarmupFlag) {
15288 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRFail < 1) {
15289 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRFail;
15290 0 : ShowWarningError(
15291 : state,
15292 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
15293 0 : this->UnitType,
15294 0 : this->Name));
15295 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
15296 0 : ShowContinueErrorTimeStamp(
15297 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
15298 : } else {
15299 0 : ShowRecurringWarningErrorAtEnd(
15300 : state,
15301 0 : format("{} \"{}\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
15302 0 : this->UnitType,
15303 0 : this->Name),
15304 0 : this->warnIndex.m_SuppHeatCoilSensPLRFailIndex,
15305 : PartLoadFrac,
15306 : PartLoadFrac);
15307 : }
15308 : }
15309 : } // IF (SolFla == -1) THEN
15310 :
15311 7681 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
15312 7681 : this->m_SuppHeatingCycRatio = CycRatio;
15313 7681 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
15314 : } // IF (NOT EMS OVERRIDE) THEN
15315 :
15316 : } // IF SENSIBLE LOAD
15317 : } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. &
15318 :
15319 : // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel)
15320 98727 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15321 0 : this->m_sysType != SysType::PackagedWSHP) {
15322 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
15323 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = max(afnInfo.AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
15324 0 : afnInfo.AFNLoopDXCoilRTF = max(afnInfo.AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
15325 : }
15326 :
15327 98727 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
15328 0 : mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow;
15329 0 : PlantUtilities::SetComponentFlowRate(
15330 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15331 : }
15332 98727 : }
15333 :
15334 22255 : void UnitarySys::simMultiSpeedCoils(EnergyPlusData &state,
15335 : int const AirLoopNum, // Index to air loop
15336 : bool const FirstHVACIteration, // True when first HVAC iteration
15337 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
15338 : bool const SensibleLoad,
15339 : bool const LatentLoad,
15340 : Real64 const PartLoadFrac,
15341 : int const CoilType,
15342 : int const SpeedNumber)
15343 : {
15344 :
15345 : // SUBROUTINE INFORMATION:
15346 : // AUTHOR Chandan Sharma, FSEC
15347 : // DATE WRITTEN March 2013
15348 :
15349 : // PURPOSE OF THIS SUBROUTINE:
15350 : // This subroutine manages multispeed and variable speed cooling coil simulation.
15351 :
15352 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15353 22255 : std::string CompName; // Name of Unitary System object
15354 22255 : Real64 SensLoad = 0.0;
15355 22255 : Real64 LatLoad = 0.0;
15356 22255 : int CoilTypeNum = 0;
15357 22255 : int CompIndex = 0;
15358 22255 : Real64 SpeedRatio = 0.0;
15359 22255 : Real64 CycRatio = 0.0;
15360 22255 : Real64 dummy = 0.0;
15361 :
15362 22255 : if (CoilType == CoolingCoil) {
15363 :
15364 15516 : CompName = this->m_CoolingCoilName;
15365 15516 : CompIndex = this->m_CoolingCoilIndex;
15366 15516 : CoilTypeNum = this->m_CoolingCoilType_Num;
15367 15516 : if (SensibleLoad) {
15368 15516 : SensLoad = -1.0;
15369 15516 : state.dataUnitarySystems->CoolingLoad = true;
15370 15516 : state.dataUnitarySystems->HeatingLoad = false;
15371 : }
15372 15516 : if (LatentLoad) {
15373 0 : LatLoad = -1.0;
15374 : }
15375 :
15376 : } else {
15377 :
15378 6739 : CompName = this->m_HeatingCoilName;
15379 6739 : CompIndex = this->m_HeatingCoilIndex;
15380 6739 : CoilTypeNum = this->m_HeatingCoilType_Num;
15381 :
15382 6739 : if (SensibleLoad) {
15383 6739 : SensLoad = 1.0;
15384 6739 : state.dataUnitarySystems->CoolingLoad = false;
15385 6739 : state.dataUnitarySystems->HeatingLoad = true;
15386 : } else {
15387 0 : SensLoad = 0.0;
15388 0 : state.dataUnitarySystems->HeatingLoad = false;
15389 : }
15390 6739 : LatLoad = 0.0;
15391 : }
15392 :
15393 22255 : Real64 OnOffAirFlowRatio = 1.0;
15394 22255 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadFrac); // 1.0d0 = PartLoadRatio
15395 :
15396 22255 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
15397 :
15398 22255 : if ((CoilTypeNum == HVAC::CoilDX_MultiSpeedCooling) || (CoilTypeNum == HVAC::CoilDX_MultiSpeedHeating)) {
15399 22255 : DXCoils::SimDXCoilMultiSpeed(
15400 22255 : state, CompName, 0.0, PartLoadFrac, CompIndex, SpeedNumber, this->m_FanOpMode, HVAC::CompressorOp::On, this->m_SingleMode);
15401 :
15402 0 : } else if (CoilTypeNum == HVAC::CoilDX_Cooling) {
15403 0 : bool const singleMode = (this->m_SingleMode == 1);
15404 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
15405 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15406 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
15407 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
15408 0 : coilMode = HVAC::CoilMode::Enhanced;
15409 : }
15410 :
15411 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
15412 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode, this->CoilSHR);
15413 :
15414 0 : } else if (CoilTypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
15415 :
15416 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15417 : CompName,
15418 : CompIndex,
15419 : this->m_FanOpMode,
15420 : CompressorOn,
15421 : PartLoadFrac,
15422 : SpeedNumber,
15423 : this->m_CoolingSpeedRatio,
15424 : SensLoad,
15425 : dummy,
15426 : OnOffAirFlowRatio);
15427 :
15428 0 : } else if (CoilTypeNum == HVAC::Coil_HeatingAirToAirVariableSpeed) {
15429 :
15430 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15431 : CompName,
15432 : CompIndex,
15433 : this->m_FanOpMode,
15434 : CompressorOn,
15435 : PartLoadFrac,
15436 : SpeedNumber,
15437 : this->m_HeatingSpeedRatio,
15438 : SensLoad,
15439 : dummy,
15440 : OnOffAirFlowRatio);
15441 :
15442 0 : } else if (CoilTypeNum == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
15443 :
15444 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15445 : CompName,
15446 : CompIndex,
15447 : this->m_FanOpMode,
15448 : CompressorOn,
15449 : PartLoadFrac,
15450 : SpeedNumber,
15451 : this->m_CoolingSpeedRatio,
15452 : SensLoad,
15453 : dummy,
15454 : OnOffAirFlowRatio);
15455 :
15456 0 : } else if (CoilTypeNum == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
15457 :
15458 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15459 : CompName,
15460 : CompIndex,
15461 : this->m_FanOpMode,
15462 : CompressorOn,
15463 : PartLoadFrac,
15464 : SpeedNumber,
15465 : this->m_HeatingSpeedRatio,
15466 : SensLoad,
15467 : dummy,
15468 : OnOffAirFlowRatio);
15469 :
15470 0 : } else if ((CoilTypeNum == HVAC::Coil_HeatingElectric_MultiStage) || (CoilTypeNum == HVAC::Coil_HeatingGas_MultiStage)) {
15471 :
15472 0 : HeatingCoils::SimulateHeatingCoilComponents(
15473 0 : state, CompName, FirstHVACIteration, _, CompIndex, _, _, this->m_FanOpMode, PartLoadFrac, SpeedNumber, this->m_HeatingSpeedRatio);
15474 : } else {
15475 : }
15476 22255 : }
15477 :
15478 33695 : void UnitarySys::calcPassiveSystem(EnergyPlusData &state,
15479 : int const AirLoopNum, // index to air loop
15480 : bool const FirstHVACIteration // True when first HVAC iteration
15481 : )
15482 : {
15483 :
15484 : // SUBROUTINE INFORMATION:
15485 : // AUTHOR Richard Raustad, FSEC
15486 : // DATE WRITTEN February 2013
15487 :
15488 : // PURPOSE OF THIS SUBROUTINE:
15489 : // This subroutine calculates the set point based output of the unitary system.
15490 :
15491 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15492 33695 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
15493 33695 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off; // compressor control (0=off, 1=on)
15494 33695 : Real64 OnOffAirFlowRatio = 1.0;
15495 33695 : Real64 CoilCoolHeatRat = 1.0;
15496 33695 : Real64 HeatCoilLoad = 0.0;
15497 : // CALL the series of components that simulate a Unitary System
15498 33695 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
15499 28883 : state.dataFans->fans(this->m_FanIndex)
15500 86649 : ->simulate(state,
15501 : FirstHVACIteration,
15502 28883 : state.dataUnitarySystems->FanSpeedRatio,
15503 : _, // Pressure rise
15504 : _, // Flow fraction
15505 28883 : state.dataUnitarySystems->m_massFlow1,
15506 28883 : state.dataUnitarySystems->m_runTimeFraction1,
15507 28883 : state.dataUnitarySystems->m_massFlow2,
15508 28883 : state.dataUnitarySystems->m_runTimeFraction2,
15509 : _);
15510 : }
15511 :
15512 33695 : if (this->m_CoolingCoilUpstream) {
15513 :
15514 33695 : if (this->m_CoolCoilExists) {
15515 33695 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15516 33695 : CompressorOn = HVAC::CompressorOp::Off;
15517 33695 : if (PartLoadRatio > 0.0) {
15518 11417 : CompressorOn = HVAC::CompressorOp::On;
15519 : }
15520 33695 : bool HXUnitOn = false;
15521 33695 : this->calcUnitaryCoolingSystem(
15522 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15523 : }
15524 33695 : if (this->m_HeatCoilExists) {
15525 28883 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15526 28883 : CompressorOn = HVAC::CompressorOp::Off;
15527 28883 : if (PartLoadRatio > 0.0) {
15528 2 : CompressorOn = HVAC::CompressorOp::On;
15529 : }
15530 28883 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15531 : }
15532 :
15533 : } else {
15534 :
15535 0 : if (this->m_HeatCoilExists) {
15536 0 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15537 0 : CompressorOn = HVAC::CompressorOp::Off;
15538 0 : if (PartLoadRatio > 0.0) {
15539 0 : CompressorOn = HVAC::CompressorOp::On;
15540 : }
15541 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15542 : }
15543 0 : if (this->m_CoolCoilExists) {
15544 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15545 0 : CompressorOn = HVAC::CompressorOp::Off;
15546 0 : if (PartLoadRatio > 0.0) {
15547 0 : CompressorOn = HVAC::CompressorOp::On;
15548 : }
15549 0 : bool HXUnitOn = false;
15550 0 : this->calcUnitaryCoolingSystem(
15551 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15552 : }
15553 : }
15554 :
15555 33695 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
15556 0 : state.dataFans->fans(this->m_FanIndex)
15557 0 : ->simulate(state,
15558 : FirstHVACIteration,
15559 0 : state.dataUnitarySystems->FanSpeedRatio,
15560 : _, // Pressure rise
15561 : _, // Flow fraction
15562 0 : state.dataUnitarySystems->m_massFlow1,
15563 0 : state.dataUnitarySystems->m_runTimeFraction1,
15564 0 : state.dataUnitarySystems->m_massFlow2,
15565 0 : state.dataUnitarySystems->m_runTimeFraction2,
15566 : _);
15567 : }
15568 :
15569 : // CALL reheat coils next
15570 33695 : if (this->m_SuppCoilExists) {
15571 28883 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
15572 28883 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
15573 28883 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
15574 : }
15575 33695 : }
15576 :
15577 9735155 : void UnitarySys::reportUnitarySystem(EnergyPlusData &state, int const AirLoopNum)
15578 : {
15579 :
15580 : // SUBROUTINE INFORMATION:
15581 : // AUTHOR Chandan Sharma
15582 : // DATE WRITTEN July 2013
15583 :
15584 : // PURPOSE OF THIS SUBROUTINE:
15585 : // This subroutine updates the report variable for the coils.
15586 :
15587 9735155 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15588 :
15589 9735155 : Real64 SensibleOutput = 0.0; // sensible output rate, {W}
15590 9735155 : Real64 LatentOutput = 0.0; // latent output rate, {W}
15591 9735155 : Real64 TotalOutput = 0.0; // total output rate, {W}
15592 9735155 : Real64 QTotUnitOut = 0.0;
15593 9735155 : Real64 QSensUnitOut = 0.0;
15594 9735155 : this->m_PartLoadFrac = 0.0;
15595 9735155 : this->m_CompPartLoadRatio = 0.0;
15596 9735155 : this->m_CycRatio = 0.0;
15597 9735155 : this->m_SpeedRatio = 0.0;
15598 9735155 : this->FanPartLoadRatio = 0.0;
15599 9735155 : this->m_TotalAuxElecPower = 0.0;
15600 9735155 : this->m_HeatingAuxElecConsumption = 0.0;
15601 9735155 : this->m_CoolingAuxElecConsumption = 0.0;
15602 9735155 : this->m_ElecPower = 0.0;
15603 9735155 : this->m_ElecPowerConsumption = 0.0;
15604 :
15605 9735155 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
15606 9735155 : switch (this->m_ControlType) {
15607 : // Noticed that these are calculated differently.
15608 : // That doesn't make sense except that NodeNumOfControlledZone = 0 for set point control because the control zone name is not required.
15609 3680464 : case UnitarySysCtrlType::Setpoint: {
15610 3680464 : if (this->AirOutNode > 0) {
15611 3680464 : int InletNode = this->AirInNode;
15612 14721856 : CalcComponentSensibleLatentOutput(AirMassFlow,
15613 3680464 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15614 3680464 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15615 3680464 : state.dataLoopNodes->Node(InletNode).Temp,
15616 3680464 : state.dataLoopNodes->Node(InletNode).HumRat,
15617 : SensibleOutput,
15618 : LatentOutput,
15619 : TotalOutput);
15620 3680464 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15621 3680464 : QTotUnitOut = TotalOutput;
15622 : }
15623 3680464 : } break;
15624 6054691 : default: {
15625 6054691 : if (this->AirOutNode > 0 && this->NodeNumOfControlledZone > 0) {
15626 : // PTUnit uses old style method of calculating delivered capacity.
15627 : // Also PTUnit always uses inlet node data, which is good when inlet is connected to zone return node
15628 6054691 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15629 3197491 : Real64 SpecHumOut = state.dataLoopNodes->Node(this->AirOutNode).HumRat;
15630 3197491 : Real64 SpecHumIn = state.dataLoopNodes->Node(this->AirInNode).HumRat;
15631 3197491 : LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s (dehumid = negative)
15632 3197491 : SensibleOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirOutNode).Temp,
15633 3197491 : state.dataLoopNodes->Node(this->AirInNode).HumRat) -
15634 3197491 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirInNode).Temp,
15635 3197491 : state.dataLoopNodes->Node(this->AirInNode).HumRat));
15636 3197491 : TotalOutput =
15637 3197491 : AirMassFlow * (state.dataLoopNodes->Node(this->AirOutNode).Enthalpy - state.dataLoopNodes->Node(this->AirInNode).Enthalpy);
15638 3197491 : } else {
15639 : // air loop systems don't use the Sensible capacity, zone equipment uses this to adjust RemainingOutputRequired
15640 11428800 : CalcZoneSensibleLatentOutput(AirMassFlow,
15641 2857200 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15642 2857200 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15643 2857200 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
15644 2857200 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
15645 : SensibleOutput,
15646 : LatentOutput,
15647 : TotalOutput);
15648 : }
15649 6054691 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15650 6054691 : QTotUnitOut = TotalOutput;
15651 : }
15652 6054691 : } break;
15653 : }
15654 :
15655 : // set the system part-load ratio report variable
15656 9735155 : this->m_PartLoadFrac = max(this->m_CoolingPartLoadFrac, this->m_HeatingPartLoadFrac);
15657 : // set the compressor part-load ratio report variable
15658 9735155 : this->m_CompPartLoadRatio = max(this->m_CoolCompPartLoadRatio, this->m_HeatCompPartLoadRatio);
15659 :
15660 : // logic difference in PTUnit *Rate reporting vs UnitarySystem. Use PTUnit more compact method for 9093.
15661 9735155 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15662 : // Issue 9093.
15663 : // PTHP reports these differently, seems this is correct. Can't change this now, need an issue to resolve
15664 3197491 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15665 3197491 : this->m_TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
15666 3197491 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15667 3197491 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15668 3197491 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15669 3197491 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15670 : } else {
15671 6537664 : if (state.dataUnitarySystems->HeatingLoad) {
15672 1053098 : if (QTotUnitOut > 0.0) { // heating
15673 577595 : this->m_TotCoolEnergyRate = 0.0;
15674 577595 : this->m_SensCoolEnergyRate = 0.0;
15675 577595 : this->m_LatCoolEnergyRate = 0.0;
15676 577595 : this->m_TotHeatEnergyRate = QTotUnitOut;
15677 577595 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15678 577595 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15679 : } else {
15680 475503 : this->m_TotCoolEnergyRate = std::abs(QTotUnitOut);
15681 475503 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15682 475503 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15683 475503 : this->m_TotHeatEnergyRate = 0.0;
15684 475503 : this->m_SensHeatEnergyRate = 0.0;
15685 475503 : this->m_LatHeatEnergyRate = 0.0;
15686 : }
15687 : } else {
15688 5484566 : if (QTotUnitOut <= 0.0) { // cooling
15689 5267947 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15690 5267947 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15691 5267947 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15692 5267947 : this->m_TotHeatEnergyRate = 0.0;
15693 5267947 : this->m_SensHeatEnergyRate = 0.0;
15694 5267947 : this->m_LatHeatEnergyRate = 0.0;
15695 : } else {
15696 216619 : this->m_TotCoolEnergyRate = 0.0;
15697 216619 : this->m_SensCoolEnergyRate = 0.0;
15698 216619 : this->m_LatCoolEnergyRate = 0.0;
15699 216619 : this->m_TotHeatEnergyRate = QTotUnitOut;
15700 216619 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15701 216619 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15702 : }
15703 : }
15704 : }
15705 :
15706 9735155 : this->m_TotHeatEnergy = m_TotHeatEnergyRate * ReportingConstant;
15707 9735155 : this->m_TotCoolEnergy = m_TotCoolEnergyRate * ReportingConstant;
15708 9735155 : this->m_SensHeatEnergy = m_SensHeatEnergyRate * ReportingConstant;
15709 9735155 : this->m_SensCoolEnergy = m_SensCoolEnergyRate * ReportingConstant;
15710 9735155 : this->m_LatHeatEnergy = m_LatHeatEnergyRate * ReportingConstant;
15711 9735155 : this->m_LatCoolEnergy = m_LatCoolEnergyRate * ReportingConstant;
15712 :
15713 9735155 : if (this->m_FanExists && this->AirOutNode > 0) {
15714 6153418 : if (state.dataUnitarySystems->CompOnMassFlow > 0.0) {
15715 5918315 : this->FanPartLoadRatio = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate / state.dataUnitarySystems->CompOnMassFlow;
15716 : }
15717 6153418 : if (AirLoopNum > 0) {
15718 2772745 : if (this->m_FanOpMode == HVAC::FanOp::Cycling) {
15719 845084 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = this->FanPartLoadRatio;
15720 : } else {
15721 1927661 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0;
15722 : }
15723 : }
15724 : }
15725 :
15726 9735155 : Real64 locFanElecPower = (this->m_FanIndex == 0) ? 0.0 : state.dataFans->fans(this->m_FanIndex)->totalPower;
15727 :
15728 9735155 : Real64 elecCoolingPower = 0.0;
15729 9735155 : Real64 elecHeatingPower = 0.0;
15730 9735155 : Real64 suppHeatingPower = 0.0;
15731 9735155 : Real64 defrostElecPower = 0.0;
15732 :
15733 9735155 : switch (this->m_CoolingCoilType_Num) {
15734 1072657 : case HVAC::CoilDX_CoolingTwoSpeed: {
15735 : // need to make sure these are 0 for non-variable speed coils (or not report these variables)
15736 1072657 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15737 1072657 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15738 1072657 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15739 : // see :setSpeedVariables
15740 1072657 : if (state.dataUnitarySystems->CoolingLoad && this->m_SpeedNum <= 1) {
15741 17035 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15742 17035 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15743 : }
15744 1072657 : if (this->m_LastMode == CoolingMode) {
15745 1072657 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15746 : }
15747 1072657 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15748 1072657 : } break;
15749 674543 : case HVAC::CoilDX_MultiSpeedCooling: {
15750 674543 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15751 674543 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15752 674543 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15753 :
15754 674543 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15755 674543 : if (state.dataUnitarySystems->CoolingLoad) {
15756 189345 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15757 189345 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15758 : }
15759 674543 : if (this->m_LastMode == CoolingMode) {
15760 260440 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15761 : }
15762 674543 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15763 674543 : } break;
15764 272541 : case HVAC::Coil_CoolingWater:
15765 : case HVAC::Coil_CoolingWaterDetailed: {
15766 272541 : if (this->m_DiscreteSpeedCoolingCoil) {
15767 14902 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15768 14902 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15769 14902 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15770 14902 : if (state.dataUnitarySystems->CoolingLoad) {
15771 : // if discrete, the coil cycles on and off
15772 5174 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15773 5174 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15774 : }
15775 14902 : if (this->m_LastMode == CoolingMode) {
15776 7212 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15777 : }
15778 : } else {
15779 257639 : if (state.dataUnitarySystems->CoolingLoad) {
15780 : // if not discrete, the coil runs the entire time step.
15781 20954 : this->m_TotalAuxElecPower =
15782 20954 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15783 20954 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15784 : }
15785 257639 : if (this->m_LastMode == CoolingMode) {
15786 106945 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15787 : }
15788 : }
15789 272541 : this->m_ElecPower = locFanElecPower;
15790 272541 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15791 272541 : } break;
15792 : // May not need
15793 2033898 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
15794 2033898 : if (this->m_NumOfSpeedCooling > 1) {
15795 7334 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15796 7334 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15797 7334 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15798 : }
15799 2033898 : if (state.dataUnitarySystems->CoolingLoad) {
15800 1038182 : this->m_TotalAuxElecPower =
15801 1038182 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15802 1038182 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15803 : }
15804 2033898 : if (this->m_LastMode == CoolingMode) {
15805 1196484 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15806 : }
15807 2033898 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15808 2033898 : } break;
15809 1621822 : case HVAC::CoilDX_Cooling: {
15810 1621822 : if (this->m_NumOfSpeedCooling > 1) {
15811 1493165 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15812 1493165 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15813 1493165 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15814 :
15815 1493165 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15816 1493165 : if (state.dataUnitarySystems->CoolingLoad) {
15817 663343 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15818 663343 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15819 : }
15820 1493165 : if (this->m_LastMode == CoolingMode) {
15821 999684 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15822 : }
15823 1493165 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15824 : } else {
15825 128657 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15826 8766 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR == 0.0) {
15827 2324 : this->LoadSHR = 1.0;
15828 2324 : this->CoilSHR = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].performance.NormalSHR;
15829 : }
15830 : }
15831 128657 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15832 128657 : if (state.dataUnitarySystems->CoolingLoad) {
15833 41816 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15834 41816 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15835 : }
15836 128657 : if (this->m_LastMode == CoolingMode) {
15837 68815 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15838 : }
15839 128657 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15840 : }
15841 1621822 : } break;
15842 28852 : case HVAC::Coil_UserDefined:
15843 : case HVAC::CoilWater_CoolingHXAssisted:
15844 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
15845 28852 : if (state.dataUnitarySystems->CoolingLoad) {
15846 0 : this->m_TotalAuxElecPower =
15847 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15848 0 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15849 : }
15850 28852 : if (this->m_LastMode == CoolingMode) {
15851 28852 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15852 : }
15853 : // these coil types do not consume electricity or report electricity at the plant
15854 28852 : } break;
15855 4030842 : default: { // all other DX cooling coils
15856 4030842 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15857 4030842 : if (state.dataUnitarySystems->CoolingLoad) {
15858 817139 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15859 817139 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15860 : }
15861 4030842 : if (this->m_LastMode == CoolingMode) {
15862 3150638 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15863 : }
15864 4030842 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15865 4030842 : } break;
15866 : }
15867 :
15868 9735155 : switch (this->m_HeatingCoilType_Num) {
15869 791927 : case HVAC::CoilDX_MultiSpeedHeating: {
15870 791927 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15871 791927 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15872 791927 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15873 :
15874 791927 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15875 791927 : if (state.dataUnitarySystems->HeatingLoad) {
15876 287845 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15877 287845 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15878 : }
15879 791927 : if (this->m_LastMode == HeatingMode) {
15880 453247 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15881 : }
15882 791927 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15883 791927 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15884 791927 : } break;
15885 0 : case HVAC::Coil_HeatingGas_MultiStage:
15886 : case HVAC::Coil_HeatingElectric_MultiStage: {
15887 0 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15888 0 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15889 :
15890 0 : if (state.dataUnitarySystems->HeatingLoad) {
15891 0 : this->m_TotalAuxElecPower =
15892 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15893 0 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15894 : }
15895 0 : if (this->m_LastMode == HeatingMode) {
15896 0 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15897 : }
15898 :
15899 0 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15900 0 : } break;
15901 2384231 : case HVAC::CoilDX_HeatingEmpirical:
15902 : case HVAC::Coil_HeatingWaterToAirHP:
15903 : case HVAC::Coil_HeatingWaterToAirHPSimple:
15904 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15905 2384231 : if (this->m_NumOfSpeedHeating > 1) {
15906 27128 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15907 27128 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15908 27128 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15909 : }
15910 2384231 : if (state.dataUnitarySystems->HeatingLoad) {
15911 908323 : this->m_TotalAuxElecPower =
15912 908323 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15913 908323 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15914 : }
15915 2384231 : if (this->m_LastMode == HeatingMode) {
15916 969393 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15917 : }
15918 2384231 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15919 2384231 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15920 2384231 : } break;
15921 8895 : case HVAC::Coil_HeatingAirToAirVariableSpeed: {
15922 8895 : if (state.dataUnitarySystems->HeatingLoad) {
15923 3402 : this->m_TotalAuxElecPower =
15924 3402 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15925 3402 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15926 : }
15927 8895 : if (this->m_LastMode == HeatingMode) {
15928 4130 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15929 : }
15930 :
15931 8895 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15932 8895 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15933 8895 : } break;
15934 78594 : case HVAC::Coil_UserDefined:
15935 : case HVAC::Coil_HeatingWater:
15936 : case HVAC::Coil_HeatingSteam:
15937 : case HVAC::Coil_HeatingDesuperheater: {
15938 78594 : if (state.dataUnitarySystems->HeatingLoad) {
15939 34626 : this->m_TotalAuxElecPower =
15940 34626 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15941 34626 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15942 : }
15943 78594 : if (this->m_LastMode == HeatingMode) {
15944 40278 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15945 : }
15946 78594 : } break;
15947 6471508 : default: {
15948 6471508 : if (this->m_HeatCoilExists) {
15949 2732620 : if (state.dataUnitarySystems->HeatingLoad) {
15950 : // if discrete, the coil cycles on and off
15951 982103 : this->m_TotalAuxElecPower =
15952 982103 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15953 982103 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15954 : }
15955 2732620 : if (this->m_LastMode == HeatingMode) {
15956 1230167 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15957 : }
15958 2732620 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15959 : }
15960 6471508 : } break;
15961 : }
15962 :
15963 9735155 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
15964 4540482 : this->m_TotalAuxElecPower = this->m_AncillaryOffPower;
15965 : }
15966 :
15967 9735155 : if (this->m_SuppCoilExists) {
15968 3275936 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
15969 1067750 : suppHeatingPower = state.dataHVACGlobal->SuppHeatingCoilPower;
15970 : }
15971 : }
15972 :
15973 9735155 : this->m_ElecPower = locFanElecPower + elecCoolingPower + elecHeatingPower + suppHeatingPower + defrostElecPower + this->m_TotalAuxElecPower;
15974 9735155 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15975 :
15976 9872931 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15977 137776 : this->m_sysType != SysType::PackagedWSHP) {
15978 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataUnitarySystems->CompOnMassFlow;
15979 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataUnitarySystems->CompOffMassFlow;
15980 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = this->m_FanOpMode;
15981 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = this->FanPartLoadRatio;
15982 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopCompCycRatio = this->m_CycRatio;
15983 : }
15984 9735155 : if (this->m_FirstPass) {
15985 1114 : if (AirLoopNum > -1) {
15986 1106 : if (!state.dataGlobal->SysSizingCalc) {
15987 :
15988 755 : int const CurOASysNum = state.dataSize->CurOASysNum;
15989 755 : if (CurOASysNum > 0) {
15990 2 : auto &thisOASysEqSizing = state.dataSize->OASysEqSizing(CurOASysNum);
15991 2 : thisOASysEqSizing.AirFlow = false;
15992 2 : thisOASysEqSizing.CoolingAirFlow = false;
15993 2 : thisOASysEqSizing.HeatingAirFlow = false;
15994 2 : thisOASysEqSizing.Capacity = false;
15995 2 : thisOASysEqSizing.CoolingCapacity = false;
15996 2 : thisOASysEqSizing.HeatingCapacity = false;
15997 2 : this->m_FirstPass = false;
15998 753 : } else if (state.dataSize->CurSysNum > 0) {
15999 402 : if (state.dataSize->CurSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
16000 402 : state.dataAirLoop->AirLoopControlInfo(state.dataSize->CurSysNum).UnitarySysSimulating = false;
16001 : }
16002 402 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
16003 351 : } else if (state.dataSize->CurZoneEqNum > 0) {
16004 351 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
16005 : } else {
16006 0 : this->m_FirstPass = false;
16007 : }
16008 : }
16009 : } else {
16010 8 : this->m_FirstPass = false;
16011 : }
16012 : // reset the global system type flags
16013 1114 : state.dataSize->ZoneEqDXCoil = false;
16014 : }
16015 :
16016 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
16017 9735155 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
16018 9735155 : state.dataSize->ZoneEqUnitarySys = false;
16019 9735155 : }
16020 :
16021 0 : void UnitarySys::unitarySystemHeatRecovery(EnergyPlusData &state)
16022 : {
16023 :
16024 : // SUBROUTINE INFORMATION:
16025 : // AUTHOR: Chandan Sharma
16026 : // DATE WRITTEN: May 2013
16027 :
16028 : // PURPOSE OF THIS SUBROUTINE:
16029 : // Calculate the heat recovered from UnitarySystem
16030 :
16031 : // SUBROUTINE PARAMETER DEFINITIONS:
16032 : static constexpr std::string_view routineName("UnitarySystemHeatRecovery");
16033 :
16034 0 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
16035 :
16036 0 : Real64 HeatRecInletTemp = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).Temp;
16037 0 : Real64 HeatRecOutletTemp = 0.0;
16038 0 : Real64 HeatRecMassFlowRate = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate;
16039 :
16040 0 : Real64 QHeatRec = state.dataHVACGlobal->MSHPWasteHeat;
16041 :
16042 0 : if (HeatRecMassFlowRate > 0.0) {
16043 :
16044 0 : Real64 CpHeatRec = state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).glycol->getSpecificHeat(state, HeatRecInletTemp, routineName);
16045 :
16046 0 : HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + HeatRecInletTemp;
16047 : // coil model should be handling max outlet water temp (via limit to heat transfer) since heat rejection needs to be accounted for by the
16048 : // coil
16049 0 : if (HeatRecOutletTemp > this->m_MaxHROutletWaterTemp) {
16050 0 : HeatRecOutletTemp = max(HeatRecInletTemp, this->m_MaxHROutletWaterTemp);
16051 0 : QHeatRec = HeatRecMassFlowRate * CpHeatRec * (HeatRecOutletTemp - HeatRecInletTemp);
16052 : }
16053 : } else {
16054 0 : HeatRecOutletTemp = HeatRecInletTemp;
16055 0 : QHeatRec = 0.0;
16056 : }
16057 :
16058 0 : PlantUtilities::SafeCopyPlantNode(state, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
16059 :
16060 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).Temp = HeatRecOutletTemp;
16061 :
16062 0 : this->m_HeatRecoveryRate = QHeatRec;
16063 0 : this->m_HeatRecoveryEnergy = this->m_HeatRecoveryRate * ReportingConstant;
16064 0 : this->m_HeatRecoveryInletTemp = HeatRecInletTemp;
16065 0 : this->m_HeatRecoveryOutletTemp = HeatRecOutletTemp;
16066 0 : this->m_HeatRecoveryMassFlowRate = HeatRecMassFlowRate;
16067 0 : }
16068 :
16069 15155289 : Real64 UnitarySys::calcUnitarySystemLoadResidual(EnergyPlusData &state,
16070 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
16071 : int UnitarySysNum,
16072 : bool FirstHVACIteration,
16073 : // par 3 not used?
16074 : HVAC::CompressorOp compressorOp,
16075 : Real64 LoadToBeMet,
16076 : Real64 coolHeatFlag, // make bool?
16077 : Real64 SensibleLoad,
16078 : Real64 OnOffAirFlowRatio,
16079 : bool HXUnitOn,
16080 : // par 10 not used
16081 : int AirLoopNum)
16082 : {
16083 :
16084 : // FUNCTION INFORMATION:
16085 : // AUTHOR Richard Raustad, FSEC
16086 : // DATE WRITTEN February 2013
16087 :
16088 : // PURPOSE OF THIS SUBROUTINE:
16089 : // To calculate the part-load ratio for the unitary system
16090 :
16091 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16092 : Real64 SensOutput; // sensible output of system
16093 : Real64 LatOutput; // latent output of system
16094 15155289 : Real64 HeatCoilLoad = 0.0;
16095 15155289 : Real64 SupHeaterLoad = 0.0;
16096 15155289 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16097 15155289 : Real64 CoolPLR = coolHeatFlag == 1.0 ? PartLoadRatio : 0.0;
16098 15155289 : Real64 HeatPLR = coolHeatFlag == 1.0 ? 0.0 : PartLoadRatio;
16099 15155289 : thisSys.setSpeedVariables(state, SensibleLoad, PartLoadRatio);
16100 15155289 : thisSys.calcUnitarySystemToLoad(state,
16101 : AirLoopNum,
16102 : FirstHVACIteration,
16103 : CoolPLR,
16104 : HeatPLR,
16105 : OnOffAirFlowRatio,
16106 : SensOutput,
16107 : LatOutput,
16108 : HXUnitOn,
16109 : HeatCoilLoad,
16110 : SupHeaterLoad,
16111 : compressorOp);
16112 : // Calculate residual based on output calculation flag
16113 15155289 : Real64 baselineLoad = SensibleLoad == 1.0 ? SensOutput : LatOutput;
16114 15155289 : Real64 divisor = std::abs(LoadToBeMet) == 0.0 ? 100.0 : LoadToBeMet;
16115 15155289 : return (baselineLoad - LoadToBeMet) / divisor;
16116 : }
16117 :
16118 1726671 : Real64 UnitarySys::DXCoilVarSpeedResidual(EnergyPlusData &state,
16119 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16120 : int CoilIndex,
16121 : Real64 DesOutTemp,
16122 : int UnitarySysNum,
16123 : Real64 CycRatio,
16124 : int SpeedNum,
16125 : HVAC::FanOp const fanOp,
16126 : HVAC::CompressorOp compressorOp)
16127 : {
16128 : // FUNCTION INFORMATION:
16129 : // AUTHOR Fred Buhl
16130 : // DATE WRITTEN September 2002
16131 :
16132 : // PURPOSE OF THIS FUNCTION:
16133 : // Calculates residual function (desired outlet temp - actual outlet temp).
16134 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16135 :
16136 : // METHODOLOGY EMPLOYED:
16137 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given compressor speed
16138 : // and calculates the residual as defined above
16139 :
16140 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16141 1726671 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16142 :
16143 : Real64 dummy;
16144 : Real64 OnOffAirFlowRatio;
16145 : Real64 SensLoad;
16146 :
16147 1726671 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16148 1726671 : switch (thisSys.m_CoolingCoilType_Num) {
16149 1718066 : case HVAC::CoilDX_CoolingTwoSpeed: {
16150 1718066 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
16151 1718066 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16152 1718066 : } break;
16153 235 : case HVAC::CoilDX_MultiSpeedCooling: {
16154 235 : OnOffAirFlowRatio = 1.0;
16155 235 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16156 235 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16157 235 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16158 235 : } break;
16159 8370 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16160 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16161 8370 : dummy = 0.0;
16162 8370 : SensLoad = -1.0;
16163 8370 : OnOffAirFlowRatio = 1.0;
16164 8370 : VariableSpeedCoils::SimVariableSpeedCoils(
16165 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16166 :
16167 8370 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16168 8370 : } break;
16169 0 : default: {
16170 0 : assert(false);
16171 : } break;
16172 : }
16173 1726671 : return DesOutTemp - OutletAirTemp;
16174 : }
16175 :
16176 6726 : Real64 UnitarySys::heatingCoilVarSpeedResidual(EnergyPlusData &state,
16177 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16178 : int CoilIndex,
16179 : Real64 DesOutTemp,
16180 : int UnitarySysNum,
16181 : Real64 CycRatio,
16182 : int SpeedNum,
16183 : HVAC::FanOp const fanOp,
16184 : HVAC::CompressorOp compressorOp,
16185 : bool SuppHeat
16186 :
16187 : )
16188 : {
16189 : // FUNCTION INFORMATION:
16190 : // AUTHOR Fred Buhl
16191 : // DATE WRITTEN September 2002
16192 :
16193 : // PURPOSE OF THIS FUNCTION:
16194 : // Calculates residual function (desired outlet temp - actual outlet temp).
16195 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16196 :
16197 : // METHODOLOGY EMPLOYED:
16198 : // Calls calc routines of multi Speed or variable Coil to get outlet temperature at the given compressor speed
16199 : // and calculates the residual as defined above
16200 :
16201 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16202 6726 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16203 : Real64 OnOffAirFlowRatio;
16204 : Real64 SensLoad;
16205 : Real64 LatLoad;
16206 : Real64 QActual;
16207 :
16208 6726 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16209 :
16210 6726 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16211 6726 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16212 6726 : if (SuppHeat) {
16213 6726 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16214 6726 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16215 : }
16216 :
16217 6726 : switch (heatCoilType) {
16218 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16219 0 : OnOffAirFlowRatio = 1.0;
16220 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16221 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16222 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16223 0 : } break;
16224 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16225 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16226 0 : OnOffAirFlowRatio = 1.0;
16227 0 : SensLoad = 1.0;
16228 0 : LatLoad = -1.0;
16229 : // can't call only the calc routine with these coil types since Init sets air flow rate based on speed num and cycling ratio
16230 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16231 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16232 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16233 0 : } break;
16234 6726 : case HVAC::Coil_HeatingElectric_MultiStage: {
16235 6726 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16236 6726 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16237 6726 : } break;
16238 0 : case HVAC::Coil_HeatingGas_MultiStage: {
16239 0 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16240 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16241 0 : } break;
16242 0 : default: {
16243 0 : assert(false);
16244 : } break;
16245 : }
16246 6726 : return DesOutTemp - OutletAirTemp;
16247 : }
16248 :
16249 0 : Real64 UnitarySys::DXCoilVarSpeedHumRatResidual(EnergyPlusData &state,
16250 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16251 : int CoilIndex,
16252 : Real64 DesOutHumRat,
16253 : int UnitarySysNum,
16254 : Real64 CycRatio,
16255 : int SpeedNum,
16256 : HVAC::FanOp const fanOp,
16257 : HVAC::CompressorOp compressorOp)
16258 : {
16259 : // FUNCTION INFORMATION:
16260 : // AUTHOR Richard Raustad
16261 : // DATE WRITTEN January 2008
16262 :
16263 : // PURPOSE OF THIS FUNCTION:
16264 : // Calculates residual function (desired outlet humrat - actual outlet humrat).
16265 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16266 :
16267 : // METHODOLOGY EMPLOYED:
16268 : // Calls calc routines of multi speed or variable speed coils to get outlet humidity ratio at the given compressor speed
16269 : // and calculates the residual as defined above
16270 :
16271 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16272 0 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio
16273 : Real64 SensLoad;
16274 : Real64 LatLoad;
16275 : Real64 OnOffAirFlowRatio;
16276 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16277 0 : switch (thisSys.m_CoolingCoilType_Num) {
16278 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16279 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
16280 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16281 0 : } break;
16282 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16283 0 : OnOffAirFlowRatio = 1.0;
16284 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16285 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16286 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16287 0 : } break;
16288 0 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16289 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16290 0 : SensLoad = -1.0;
16291 0 : LatLoad = 0.0;
16292 0 : OnOffAirFlowRatio = 1.0;
16293 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16294 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16295 0 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16296 0 : } break;
16297 0 : default: {
16298 0 : assert(false);
16299 : } break;
16300 : }
16301 0 : return DesOutHumRat - OutletAirHumRat;
16302 : }
16303 :
16304 221067 : Real64 UnitarySys::DXCoilCyclingResidual(EnergyPlusData &state,
16305 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16306 : int CoilIndex,
16307 : Real64 DesOutTemp,
16308 : int UnitarySysNum,
16309 : Real64 SpeedRatio,
16310 : int SpeedNum,
16311 : HVAC::FanOp const fanOp,
16312 : HVAC::CompressorOp compressorOp,
16313 : int AirloopNum,
16314 : bool FirstHVACIteration
16315 :
16316 : )
16317 : {
16318 : // FUNCTION INFORMATION:
16319 : // AUTHOR Fred Buhl
16320 : // DATE WRITTEN September 2002
16321 :
16322 : // PURPOSE OF THIS FUNCTION:
16323 : // Calculates residual function (desired outlet temp - actual outlet temp)
16324 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16325 :
16326 : // METHODOLOGY EMPLOYED:
16327 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16328 : // and calculates the residual as defined above
16329 :
16330 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16331 221067 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16332 : Real64 OnOffAirFlowRatio;
16333 :
16334 221067 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16335 221067 : switch (thisSys.m_CoolingCoilType_Num) {
16336 183530 : case HVAC::CoilDX_CoolingTwoSpeed: {
16337 183530 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16338 0 : thisSys.m_CoolingCycRatio = CycRatio;
16339 0 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16340 0 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16341 : } else {
16342 183530 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16343 : }
16344 183530 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16345 183530 : } break;
16346 122 : case HVAC::CoilDX_MultiSpeedCooling: {
16347 122 : OnOffAirFlowRatio = 1.0;
16348 122 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16349 122 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16350 122 : thisSys.m_CoolingCycRatio = CycRatio;
16351 122 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16352 122 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16353 : } else {
16354 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16355 : }
16356 122 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16357 122 : } break;
16358 37415 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16359 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16360 37415 : if (CycRatio == 0.0) {
16361 9378 : compressorOp = HVAC::CompressorOp::Off;
16362 : }
16363 37415 : Real64 dummy = 0.0;
16364 37415 : OnOffAirFlowRatio = 1.0;
16365 37415 : Real64 SensLoad = -1.0;
16366 37415 : VariableSpeedCoils::SimVariableSpeedCoils(
16367 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16368 37415 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16369 37415 : } break;
16370 0 : default: {
16371 0 : assert(false);
16372 : } break;
16373 : }
16374 221067 : return DesOutTemp - OutletAirTemp;
16375 : }
16376 :
16377 2904 : Real64 UnitarySys::DXCoilCyclingHumRatResidual(EnergyPlusData &state,
16378 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16379 : int CoilIndex,
16380 : Real64 DesOutHumRat,
16381 : int UnitarySysNum,
16382 : Real64 SpeedRatio,
16383 : int SpeedNum,
16384 : HVAC::FanOp const fanOp,
16385 : HVAC::CompressorOp compressorOp)
16386 : {
16387 :
16388 : // FUNCTION INFORMATION:
16389 : // AUTHOR Fred Buhl
16390 : // DATE WRITTEN September 2002
16391 :
16392 : // PURPOSE OF THIS FUNCTION:
16393 : // Calculates residual function (desired outlet temp - actual outlet temp)
16394 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16395 :
16396 : // METHODOLOGY EMPLOYED:
16397 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given cycling ratio
16398 : // and calculates the residual as defined above
16399 :
16400 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16401 2904 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio [kg/kg]
16402 : Real64 SensLoad;
16403 : Real64 LatLoad;
16404 : Real64 OnOffAirFlowRatio;
16405 :
16406 2904 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16407 2904 : switch (thisSys.m_CoolingCoilType_Num) {
16408 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16409 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16410 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16411 0 : } break;
16412 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16413 0 : OnOffAirFlowRatio = 1.0;
16414 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16415 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16416 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16417 0 : } break;
16418 2904 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16419 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16420 2904 : SensLoad = -1.0;
16421 2904 : LatLoad = 0.0;
16422 2904 : OnOffAirFlowRatio = 1.0;
16423 2904 : VariableSpeedCoils::SimVariableSpeedCoils(
16424 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16425 2904 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16426 2904 : } break;
16427 0 : default: {
16428 0 : assert(false);
16429 : } break;
16430 : }
16431 2904 : return DesOutHumRat - OutletAirHumRat;
16432 : }
16433 :
16434 9 : Real64 UnitarySys::heatingCoilVarSpeedCycResidual(EnergyPlusData &state,
16435 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16436 : int CoilIndex,
16437 : Real64 DesOutTemp,
16438 : int UnitarySysNum,
16439 : Real64 SpeedRatio,
16440 : int SpeedNum,
16441 : HVAC::FanOp const fanOp,
16442 : HVAC::CompressorOp compressorOp,
16443 : bool SuppHeat)
16444 : {
16445 :
16446 : // FUNCTION INFORMATION:
16447 : // AUTHOR Fred Buhl
16448 : // DATE WRITTEN September 2002
16449 :
16450 : // PURPOSE OF THIS FUNCTION:
16451 : // Calculates residual function (desired outlet temp - actual outlet temp)
16452 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16453 :
16454 : // METHODOLOGY EMPLOYED:
16455 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16456 : // and calculates the residual as defined above
16457 :
16458 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16459 9 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16460 : Real64 SensLoad;
16461 : Real64 LatLoad;
16462 : Real64 OnOffAirFlowRatio;
16463 : Real64 QActual;
16464 :
16465 9 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16466 :
16467 9 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16468 9 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16469 9 : if (SuppHeat) {
16470 3 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16471 3 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16472 : }
16473 :
16474 9 : switch (heatCoilType) {
16475 6 : case HVAC::CoilDX_MultiSpeedHeating: {
16476 6 : OnOffAirFlowRatio = 1.0;
16477 6 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16478 6 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16479 6 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16480 6 : } break;
16481 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16482 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16483 0 : if (CycRatio == 0.0) {
16484 0 : compressorOp = HVAC::CompressorOp::Off;
16485 : }
16486 0 : SensLoad = -1.0;
16487 0 : LatLoad = 0.0;
16488 0 : OnOffAirFlowRatio = 1.0;
16489 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16490 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16491 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16492 0 : } break;
16493 3 : case HVAC::Coil_HeatingElectric_MultiStage: {
16494 3 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16495 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16496 3 : } break;
16497 0 : case HVAC::Coil_HeatingGas_MultiStage: {
16498 0 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16499 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16500 0 : } break;
16501 0 : default: {
16502 0 : assert(false);
16503 : } break;
16504 : }
16505 :
16506 9 : return DesOutTemp - OutletAirTemp;
16507 : }
16508 :
16509 16314 : Real64 UnitarySys::gasElecHeatingCoilResidual(EnergyPlusData &state,
16510 : Real64 const PartLoadFrac, // Compressor cycling ratio (1.0 is continuous, 0.0 is off)
16511 : int UnitarySysNum,
16512 : bool FirstHVACIteration,
16513 : Real64 desTemp,
16514 : bool SuppHeatingCoilFlag,
16515 : HVAC::FanOp const fanOp,
16516 : Real64 HeatingLoadArg)
16517 : {
16518 :
16519 : // FUNCTION INFORMATION:
16520 : // AUTHOR Chandan Sharma, FSEC
16521 : // DATE WRITTEN February 2013
16522 :
16523 : // PURPOSE OF THIS FUNCTION:
16524 : // Calculates residual function (desired outlet temp - actual outlet temp)
16525 : // hot water Coil output depends on the part load ratio which is being varied to zero the residual.
16526 :
16527 : // METHODOLOGY EMPLOYED:
16528 : // Calls SimulateHeatingCoilComponents to get outlet temperature at the given part load ratio
16529 : // and calculates the residual as defined above
16530 :
16531 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16532 16314 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16533 16314 : Real64 HeatingLoad = HeatingLoadArg * PartLoadFrac;
16534 : // heating coils using set point control pass DataLoopNode::SensedLoadFlagValue as QCoilReq to indicate temperature control
16535 16314 : if (!SuppHeatingCoilFlag) {
16536 0 : HeatingCoils::SimulateHeatingCoilComponents(
16537 0 : state, thisSys.m_HeatingCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_HeatingCoilIndex, _, _, fanOp, PartLoadFrac);
16538 0 : return desTemp - state.dataLoopNodes->Node(thisSys.HeatCoilOutletNodeNum).Temp;
16539 : } else {
16540 65256 : HeatingCoils::SimulateHeatingCoilComponents(
16541 48942 : state, thisSys.m_SuppHeatCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_SuppHeatCoilIndex, _, true, fanOp, PartLoadFrac);
16542 16314 : return desTemp - state.dataLoopNodes->Node(thisSys.SuppCoilOutletNodeNum).Temp;
16543 : }
16544 : }
16545 :
16546 0 : Real64 UnitarySys::coolWatertoAirHPTempResidual(EnergyPlusData &state,
16547 : Real64 const PartLoadRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16548 : int UnitarySysNum,
16549 : bool FirstHVACIteration,
16550 : Real64 DesOutTemp,
16551 : Real64 ReqOutput)
16552 : {
16553 :
16554 : // FUNCTION INFORMATION:
16555 : // AUTHOR Chandan Sharma, FSEC
16556 : // DATE WRITTEN January 2013
16557 :
16558 : // PURPOSE OF THIS FUNCTION:
16559 : // Calculates residual function (desired outlet temp - actual outlet temp)
16560 : // Cool water coil output depends on the part load ratio which is being varied to zero the residual.
16561 :
16562 : // METHODOLOGY EMPLOYED:
16563 : // Calls SimWatertoAirHP or SimWatertoAirHPSimple to get outlet humidity ratio at the given cycling ratio
16564 : // and calculates the residual as defined above
16565 :
16566 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16567 :
16568 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
16569 :
16570 0 : Real64 dummy = 0.0;
16571 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
16572 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
16573 : blankString,
16574 0 : thisSys.m_CoolingCoilIndex,
16575 : ReqOutput,
16576 : dummy,
16577 : thisSys.m_FanOpMode,
16578 : HVAC::CompressorOp::On,
16579 : PartLoadRatio,
16580 : FirstHVACIteration);
16581 : } else {
16582 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
16583 : blankString,
16584 0 : thisSys.m_CoolingCoilIndex,
16585 : thisSys.MaxCoolAirMassFlow,
16586 : thisSys.m_FanOpMode,
16587 : FirstHVACIteration,
16588 0 : thisSys.m_InitHeatPump,
16589 : ReqOutput,
16590 : dummy,
16591 : HVAC::CompressorOp::Off,
16592 : PartLoadRatio);
16593 : }
16594 0 : return DesOutTemp - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16595 : }
16596 :
16597 0 : Real64 UnitarySys::calcUnitarySystemWaterFlowResidual(EnergyPlusData &state,
16598 : Real64 const PartLoadRatio, // coil part load ratio
16599 : int UnitarySysNum,
16600 : bool FirstHVACIteration,
16601 : Real64 QZnReq,
16602 : int AirControlNode,
16603 : Real64 OnOffAirFlowRat,
16604 : int AirLoopNum,
16605 : int WaterControlNode,
16606 : Real64 highWaterMdot,
16607 : Real64 lowSpeedRatio,
16608 : Real64 airMdot,
16609 : Real64 par13_SATempTarget,
16610 : Real64 systemMaxAirFlowRate,
16611 : Real64 par15_LoadType,
16612 : Real64 par16_IterationMethod)
16613 : {
16614 :
16615 : // FUNCTION INFORMATION:
16616 : // AUTHOR Richard Raustad, FSEC
16617 : // DATE WRITTEN January 2017
16618 :
16619 : // PURPOSE OF THIS SUBROUTINE:
16620 : // To calculate the part-load ratio for the UnitarySystem coil with varying part load ratio
16621 :
16622 : // METHODOLOGY EMPLOYED:
16623 : // Use SolveRoot to CALL this Function to converge on a solution
16624 :
16625 0 : Real64 HeatCoilLoad = 0.0;
16626 0 : Real64 SupHeaterLoad = 0.0;
16627 :
16628 : // Convert parameters to usable variables
16629 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16630 0 : Real64 SATempTarget = 0.0;
16631 0 : bool LoadIsTarget = false;
16632 0 : if (par13_SATempTarget == 0.0) {
16633 0 : LoadIsTarget = true;
16634 : } else {
16635 0 : SATempTarget = par13_SATempTarget;
16636 : }
16637 0 : bool iterateOnAirOnly = (par16_IterationMethod > 1.0);
16638 0 : bool coolingLoad = (par15_LoadType > 0.0);
16639 :
16640 0 : bool HXUnitOn = true;
16641 :
16642 0 : if (iterateOnAirOnly) {
16643 :
16644 : // set air flow rate bounded by low speed and high speed air flow rates
16645 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
16646 : // FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model
16647 : // FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem
16648 0 : thisSys.FanPartLoadRatio = PartLoadRatio;
16649 : // if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot;
16650 :
16651 : } else {
16652 :
16653 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot;
16654 0 : if (lowSpeedRatio != 1.0) {
16655 : // division by zero when lowSpeedRatio == 1.0
16656 0 : thisSys.FanPartLoadRatio =
16657 0 : max(0.0, ((airMdot - (systemMaxAirFlowRate * lowSpeedRatio)) / ((1.0 - lowSpeedRatio) * systemMaxAirFlowRate)));
16658 : } else {
16659 0 : thisSys.FanPartLoadRatio = 1.0;
16660 : }
16661 0 : if (WaterControlNode > 0) {
16662 0 : Real64 waterMdot = highWaterMdot * PartLoadRatio;
16663 0 : state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot;
16664 : }
16665 : }
16666 :
16667 0 : Real64 coolingPLR = 0.0;
16668 0 : Real64 heatingPLR = 0.0;
16669 :
16670 0 : if (WaterControlNode > 0 && WaterControlNode == thisSys.CoolCoilFluidInletNode) {
16671 : // cooling load using water cooling coil
16672 0 : coolingPLR = PartLoadRatio;
16673 0 : thisSys.m_CoolingPartLoadFrac = PartLoadRatio;
16674 0 : if (thisSys.MaxCoolCoilFluidFlow > 0.0) {
16675 0 : thisSys.CoolCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxCoolCoilFluidFlow;
16676 : }
16677 0 : } else if (WaterControlNode > 0 && WaterControlNode == thisSys.HeatCoilFluidInletNode) {
16678 : // heating load using water heating coil
16679 0 : heatingPLR = PartLoadRatio;
16680 0 : thisSys.m_HeatingPartLoadFrac = PartLoadRatio;
16681 0 : if (thisSys.MaxHeatCoilFluidFlow > 0.0) {
16682 0 : thisSys.HeatCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxHeatCoilFluidFlow;
16683 : }
16684 0 : } else if (coolingLoad) { // non-water coil with cooling load
16685 0 : coolingPLR = PartLoadRatio;
16686 0 : thisSys.m_CoolingPartLoadFrac = coolingPLR;
16687 : } else { // must be non-water coil with heating load
16688 0 : heatingPLR = PartLoadRatio;
16689 0 : thisSys.m_HeatingPartLoadFrac = heatingPLR;
16690 : }
16691 :
16692 0 : Real64 SensOutput = 0.0;
16693 0 : Real64 LatOutput = 0.0;
16694 0 : thisSys.calcUnitarySystemToLoad(state,
16695 : AirLoopNum,
16696 : FirstHVACIteration,
16697 : coolingPLR,
16698 : heatingPLR,
16699 : OnOffAirFlowRat,
16700 : SensOutput,
16701 : LatOutput,
16702 : HXUnitOn,
16703 : HeatCoilLoad,
16704 : SupHeaterLoad,
16705 : HVAC::CompressorOp::On);
16706 :
16707 0 : if (LoadIsTarget) {
16708 : // Calculate residual based on output magnitude
16709 0 : if (std::abs(QZnReq) <= 100.0) {
16710 0 : return (SensOutput - QZnReq) / 100.0;
16711 : } else {
16712 0 : return (SensOutput - QZnReq) / QZnReq;
16713 : }
16714 : } else {
16715 : // Calculate residual based on outlet temperature
16716 0 : return (state.dataLoopNodes->Node(thisSys.AirOutNode).Temp - SATempTarget) * 10.0;
16717 : }
16718 : }
16719 :
16720 15158879 : void UnitarySys::setSpeedVariables(EnergyPlusData &state,
16721 : bool const SensibleLoad, // True when meeting a sensible load (not a moisture load)
16722 : Real64 const PartLoadRatio // operating PLR
16723 : )
16724 : {
16725 :
16726 : // SUBROUTINE INFORMATION:
16727 : // AUTHOR Richard Raustad, FSEC
16728 : // DATE WRITTEN February 2013
16729 :
16730 : // PURPOSE OF THIS SUBROUTINE:
16731 : // This subroutine determines operating PLR and calculates the load based system output.
16732 :
16733 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16734 15158879 : Real64 OnOffAirFlowRatio = 0.0; // compressor on to average flow rate
16735 :
16736 15158879 : if (state.dataUnitarySystems->HeatingLoad && SensibleLoad) {
16737 6579425 : this->m_CoolingSpeedRatio = 0.0;
16738 6579425 : this->m_CoolingCycRatio = 0.0;
16739 6579425 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
16740 288741 : if (this->m_HeatingSpeedNum <= 1) {
16741 151293 : this->m_HeatingSpeedRatio = 0.0;
16742 151293 : this->m_HeatingCycRatio = PartLoadRatio;
16743 151293 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16744 : } else {
16745 137448 : if (this->m_SingleMode == 0) {
16746 137448 : this->m_HeatingSpeedRatio = PartLoadRatio;
16747 137448 : this->m_HeatingCycRatio = 1.0;
16748 : } else {
16749 0 : this->m_HeatingSpeedRatio = 1.0;
16750 0 : this->m_HeatingCycRatio = PartLoadRatio;
16751 : }
16752 : }
16753 6290684 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
16754 3720354 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
16755 2652450 : this->m_CompPartLoadRatio = PartLoadRatio;
16756 2652450 : this->m_HeatingSpeedNum = 0;
16757 : }
16758 : } else {
16759 8579454 : this->m_HeatingSpeedRatio = 0.0;
16760 8579454 : this->m_HeatingCycRatio = 0.0;
16761 8579454 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
16762 2748312 : if (this->m_CoolingSpeedNum <= 1) {
16763 1187437 : this->m_CoolingSpeedRatio = 0.0;
16764 1187437 : this->m_CoolingCycRatio = PartLoadRatio;
16765 1187437 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16766 : } else {
16767 1560875 : if (this->m_SingleMode == 0) {
16768 1551731 : this->m_CoolingSpeedRatio = PartLoadRatio;
16769 1551731 : this->m_CoolingCycRatio = 1.0;
16770 : } else {
16771 9144 : this->m_CoolingSpeedRatio = 1.0;
16772 9144 : this->m_CoolingCycRatio = PartLoadRatio;
16773 : }
16774 : }
16775 5831142 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
16776 2545251 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
16777 3341331 : this->m_CompPartLoadRatio = PartLoadRatio;
16778 3341331 : this->m_CoolingSpeedNum = 0;
16779 2489811 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
16780 0 : if (this->m_CoolingSpeedNum == 1) {
16781 0 : this->m_CoolingSpeedRatio = 0.0;
16782 0 : this->m_CoolingCycRatio = PartLoadRatio;
16783 : } else {
16784 0 : this->m_CoolingSpeedRatio = PartLoadRatio;
16785 0 : this->m_CoolingCycRatio = 1.0;
16786 : }
16787 : } else {
16788 2489811 : this->m_CoolingSpeedNum = 0;
16789 : }
16790 : }
16791 15158879 : OnOffAirFlowRatio = 1.0;
16792 15158879 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
16793 15158879 : }
16794 :
16795 16 : void UnitarySys::checkUnitarySysCoilInOASysExists(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum)
16796 : {
16797 :
16798 : // SUBROUTINE INFORMATION:
16799 : // AUTHOR Chandan Sharma
16800 : // DATE WRITTEN April 2013
16801 :
16802 : // PURPOSE OF THIS SUBROUTINE:
16803 : // After making sure get input is done, checks if the Coil System DX coil is in the
16804 : // OA System. IF exists then the DX cooling coil is 100% DOAS DX coil.
16805 : // METHODOLOGY EMPLOYED:
16806 : // Based on CheckDXCoolingCoilInOASysExists by Bereket Nigusse
16807 :
16808 : // SUBROUTINE PARAMETER DEFINITIONS:
16809 : static constexpr std::string_view RoutineName("CheckUnitarySysCoilInOASysExists: "); // include trailing blank space
16810 :
16811 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16812 16 : if (state.dataUnitarySystems->getInputOnceFlag) {
16813 2 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16814 2 : state.dataUnitarySystems->getInputOnceFlag = false;
16815 : }
16816 :
16817 16 : if (state.dataUnitarySystems->numUnitarySystems > 0) {
16818 16 : bool UnitarySysFound = false;
16819 40 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16820 40 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16821 16 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten) {
16822 8 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16823 : }
16824 16 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ISHundredPercentDOASDXCoil) {
16825 0 : if (!(state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
16826 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num ==
16827 : HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
16828 0 : DXCoils::SetDXCoilTypeData(state, state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilName);
16829 : }
16830 : }
16831 16 : UnitarySysFound = true;
16832 16 : break;
16833 : }
16834 : }
16835 16 : if (!UnitarySysFound) {
16836 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16837 : }
16838 : } else {
16839 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16840 : }
16841 16 : }
16842 :
16843 221 : void UnitarySys::getUnitarySysHeatCoolCoil(EnergyPlusData &state,
16844 : std::string_view UnitarySysName, // Name of Unitary System object
16845 : bool &CoolingCoil, // Cooling coil exists
16846 : bool &HeatingCoil, // Heating coil exists
16847 : int const ZoneOAUnitNum // index to zone OA unit
16848 : )
16849 : {
16850 :
16851 : // FUNCTION INFORMATION:
16852 : // AUTHOR Chandan Sharma
16853 : // DATE WRITTEN April 2013
16854 :
16855 : // PURPOSE OF THIS FUNCTION:
16856 : // Determined weather Unitary system has heating or cooling coils
16857 :
16858 221 : if (state.dataUnitarySystems->getInputOnceFlag) {
16859 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16860 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16861 : }
16862 :
16863 930 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16864 930 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16865 221 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten) {
16866 111 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16867 : }
16868 441 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolCoilExists &&
16869 220 : !state.dataUnitarySystems->unitarySys[UnitarySysNum].m_WaterHRPlantLoopModel) {
16870 220 : CoolingCoil = true;
16871 : }
16872 225 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_HeatCoilExists ||
16873 4 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_SuppCoilExists) {
16874 217 : HeatingCoil = true;
16875 : }
16876 221 : break;
16877 : }
16878 : }
16879 221 : }
16880 :
16881 0 : int UnitarySys::getAirInNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16882 : {
16883 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16884 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16885 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16886 : }
16887 0 : int airNode = 0;
16888 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16889 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16890 0 : airNode = this->AirInNode;
16891 0 : break;
16892 : }
16893 : }
16894 0 : if (airNode == 0) {
16895 0 : errFlag = true;
16896 : }
16897 0 : return airNode;
16898 : }
16899 :
16900 6 : int getZoneEqIndex(EnergyPlusData &state, std::string const &UnitarySysName, DataZoneEquipment::ZoneEquipType zoneEquipType, int const OAUnitNum)
16901 : {
16902 :
16903 6 : if (state.dataUnitarySystems->getInputOnceFlag) {
16904 0 : UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, true, OAUnitNum);
16905 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16906 : }
16907 :
16908 6 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16909 6 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16910 6 : if (zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner ||
16911 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump ||
16912 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir ||
16913 : zoneEquipType == DataZoneEquipment::ZoneEquipType::UnitarySystem) {
16914 6 : return UnitarySysNum;
16915 : }
16916 : }
16917 : }
16918 0 : return -1;
16919 : }
16920 :
16921 0 : int UnitarySys::getAirOutNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16922 : {
16923 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16924 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16925 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16926 : }
16927 0 : int airNode = 0;
16928 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16929 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16930 0 : airNode = this->AirOutNode;
16931 0 : break;
16932 : }
16933 : }
16934 0 : if (airNode == 0) {
16935 0 : errFlag = true;
16936 : }
16937 0 : return airNode;
16938 : }
16939 :
16940 167266 : int UnitarySys::getAirOutletNode()
16941 : {
16942 167266 : return this->AirOutNode;
16943 : }
16944 :
16945 167266 : int UnitarySys::getMixerOANode()
16946 : {
16947 167266 : return this->m_OAMixerNodes[0];
16948 : }
16949 :
16950 167266 : int UnitarySys::getMixerMixNode()
16951 : {
16952 167266 : return this->m_OAMixerNodes[3];
16953 : }
16954 :
16955 167266 : int UnitarySys::getMixerRetNode()
16956 : {
16957 167266 : return this->m_OAMixerNodes[2];
16958 : }
16959 :
16960 351 : int UnitarySys::getEquipIndex()
16961 : {
16962 351 : return this->m_EquipCompNum;
16963 : }
16964 :
16965 3 : bool searchZoneInletNodes(EnergyPlusData &state, int nodeToFind, int &ZoneEquipConfigIndex, int &InletNodeIndex)
16966 : {
16967 13 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16968 23 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++ZoneInletNum) {
16969 13 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(ZoneInletNum) == nodeToFind) {
16970 3 : ZoneEquipConfigIndex = ControlledZoneNum;
16971 3 : InletNodeIndex = ZoneInletNum;
16972 3 : return true;
16973 : }
16974 : }
16975 : }
16976 0 : return false;
16977 : }
16978 :
16979 348 : bool searchZoneInletNodesByEquipmentIndex(EnergyPlusData &state, int nodeToFind, int zoneEquipmentIndex)
16980 : {
16981 399 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).NumInletNodes; ++ZoneInletNum) {
16982 399 : if (state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).InletNode(ZoneInletNum) == nodeToFind) {
16983 348 : return true;
16984 : }
16985 : }
16986 0 : return false;
16987 : }
16988 :
16989 206 : bool searchZoneInletNodeAirLoopNum(EnergyPlusData &state, int airLoopNumToFind, int ZoneEquipConfigIndex, int &InletNodeIndex)
16990 : {
16991 206 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).NumInletNodes; ++ZoneInletNum) {
16992 206 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).InletNodeAirLoopNum(ZoneInletNum) == airLoopNumToFind) {
16993 206 : InletNodeIndex = ZoneInletNum;
16994 206 : return true;
16995 : }
16996 : }
16997 0 : return false;
16998 : }
16999 :
17000 351 : bool searchExhaustNodes(EnergyPlusData &state, const int nodeToFind, int &ZoneEquipConfigIndex, int &ExhaustNodeIndex)
17001 : {
17002 12998 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
17003 25353 : for (int ZoneExhNum = 1; ZoneExhNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes; ++ZoneExhNum) {
17004 12706 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum) == nodeToFind) {
17005 348 : ZoneEquipConfigIndex = ControlledZoneNum;
17006 348 : ExhaustNodeIndex = ZoneExhNum;
17007 348 : return true;
17008 : }
17009 : }
17010 : }
17011 3 : return false;
17012 : }
17013 :
17014 351 : void UnitarySys::setSystemParams(EnergyPlusData &state, Real64 &TotalFloorAreaOnAirLoop, const std::string &thisObjectName)
17015 : {
17016 351 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum);
17017 351 : this->NodeNumOfControlledZone = zoneEquipConfig.ZoneNode;
17018 351 : TotalFloorAreaOnAirLoop = state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
17019 351 : this->m_AirLoopEquipment = false;
17020 351 : if (zoneEquipConfig.EquipListIndex == 0) {
17021 0 : return;
17022 : }
17023 :
17024 351 : auto &zoneEquipList = state.dataZoneEquip->ZoneEquipList(zoneEquipConfig.EquipListIndex);
17025 890 : for (int EquipNum = 1; EquipNum <= zoneEquipList.NumOfEquipTypes; ++EquipNum) {
17026 581 : if ((zoneEquipList.EquipType(EquipNum) != DataZoneEquipment::ZoneEquipType::UnitarySystem) ||
17027 21 : zoneEquipList.EquipName(EquipNum) != thisObjectName) {
17028 539 : continue;
17029 : }
17030 21 : this->m_ZoneSequenceCoolingNum = zoneEquipList.CoolingPriority(EquipNum);
17031 21 : this->m_ZoneSequenceHeatingNum = zoneEquipList.HeatingPriority(EquipNum);
17032 21 : break;
17033 : }
17034 : }
17035 :
17036 412 : bool searchTotalComponents(EnergyPlusData &state,
17037 : SimAirServingZones::CompType compTypeToFind,
17038 : std::string_view objectNameToFind,
17039 : int &compIndex,
17040 : int &branchIndex,
17041 : int &airLoopIndex)
17042 : {
17043 1219 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
17044 2016 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
17045 4595 : for (int CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
17046 : ++CompNum) {
17047 3788 : if (compTypeToFind != state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num) {
17048 2635 : continue;
17049 : }
17050 1153 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
17051 : objectNameToFind)) {
17052 402 : compIndex = CompNum;
17053 402 : branchIndex = BranchNum;
17054 402 : airLoopIndex = AirLoopNum;
17055 402 : return true;
17056 : }
17057 : }
17058 : }
17059 : }
17060 10 : return false;
17061 : }
17062 :
17063 16 : bool getUnitarySystemNodeNumber(EnergyPlusData &state, int const nodeNumber)
17064 : {
17065 16 : for (int unitarySysIndex = 0; unitarySysIndex <= state.dataUnitarySystems->numUnitarySystems - 1; ++unitarySysIndex) {
17066 0 : auto &unitarySys = state.dataUnitarySystems->unitarySys[unitarySysIndex];
17067 :
17068 0 : int FanInletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->inletNodeNum;
17069 0 : int FanOutletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->outletNodeNum;
17070 :
17071 0 : bool noUnitarySysOutdoorAir = false;
17072 0 : if (unitarySys.m_CoolOutAirVolFlow == 0 && unitarySys.m_HeatOutAirVolFlow == 0 && unitarySys.m_NoCoolHeatOutAirVolFlow == 0) {
17073 0 : noUnitarySysOutdoorAir = true;
17074 : }
17075 :
17076 0 : if (unitarySys.m_sysType == UnitarySys::SysType::PackagedWSHP || unitarySys.m_sysType == UnitarySys::SysType::PackagedAC ||
17077 0 : unitarySys.m_sysType == UnitarySys::SysType::PackagedHP) {
17078 0 : if (noUnitarySysOutdoorAir && (nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex ||
17079 0 : nodeNumber == unitarySys.AirInNode || nodeNumber == unitarySys.m_OAMixerNodes[0] ||
17080 0 : nodeNumber == unitarySys.m_OAMixerNodes[1] || nodeNumber == unitarySys.m_OAMixerNodes[2]) ||
17081 0 : nodeNumber == unitarySys.m_OAMixerNodes[3] || nodeNumber == unitarySys.CoolCoilOutletNodeNum ||
17082 0 : nodeNumber == unitarySys.HeatCoilOutletNodeNum) {
17083 0 : return true;
17084 : }
17085 : }
17086 : }
17087 16 : return false;
17088 : }
17089 :
17090 170 : void setupAllOutputVars(EnergyPlusData &state, int const numAllSystemTypes)
17091 : {
17092 : // setup reports only once
17093 : // all report variable are set up here after all systems are allocated.
17094 : // UnitarySystem now models other equipment types, any new reports may be setup here.
17095 170 : if (numAllSystemTypes == state.dataUnitarySystems->numUnitarySystems) {
17096 933 : for (int sysNum = 0; sysNum < state.dataUnitarySystems->numUnitarySystems; ++sysNum) {
17097 763 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_sysType) {
17098 132 : case UnitarySys::SysType::Unitary:
17099 : // Setup Report variables for the Unitary System that are not reported in the components themselves
17100 264 : SetupOutputVariable(state,
17101 : "Unitary System Part Load Ratio",
17102 : Constant::Units::None,
17103 132 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17104 : OutputProcessor::TimeStepType::System,
17105 : OutputProcessor::StoreType::Average,
17106 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17107 264 : SetupOutputVariable(state,
17108 : "Unitary System Total Cooling Rate",
17109 : Constant::Units::W,
17110 132 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17111 : OutputProcessor::TimeStepType::System,
17112 : OutputProcessor::StoreType::Average,
17113 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17114 264 : SetupOutputVariable(state,
17115 : "Unitary System Sensible Cooling Rate",
17116 : Constant::Units::W,
17117 132 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17118 : OutputProcessor::TimeStepType::System,
17119 : OutputProcessor::StoreType::Average,
17120 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17121 264 : SetupOutputVariable(state,
17122 : "Unitary System Latent Cooling Rate",
17123 : Constant::Units::W,
17124 132 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17125 : OutputProcessor::TimeStepType::System,
17126 : OutputProcessor::StoreType::Average,
17127 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17128 264 : SetupOutputVariable(state,
17129 : "Unitary System Total Heating Rate",
17130 : Constant::Units::W,
17131 132 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17132 : OutputProcessor::TimeStepType::System,
17133 : OutputProcessor::StoreType::Average,
17134 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17135 264 : SetupOutputVariable(state,
17136 : "Unitary System Sensible Heating Rate",
17137 : Constant::Units::W,
17138 132 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17139 : OutputProcessor::TimeStepType::System,
17140 : OutputProcessor::StoreType::Average,
17141 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17142 264 : SetupOutputVariable(state,
17143 : "Unitary System Latent Heating Rate",
17144 : Constant::Units::W,
17145 132 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17146 : OutputProcessor::TimeStepType::System,
17147 : OutputProcessor::StoreType::Average,
17148 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17149 264 : SetupOutputVariable(state,
17150 : "Unitary System Ancillary Electricity Rate",
17151 : Constant::Units::W,
17152 132 : state.dataUnitarySystems->unitarySys[sysNum].m_TotalAuxElecPower,
17153 : OutputProcessor::TimeStepType::System,
17154 : OutputProcessor::StoreType::Average,
17155 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17156 132 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolCoilExists) {
17157 262 : SetupOutputVariable(state,
17158 : "Unitary System Cooling Ancillary Electricity Energy",
17159 : Constant::Units::J,
17160 131 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingAuxElecConsumption,
17161 : OutputProcessor::TimeStepType::System,
17162 : OutputProcessor::StoreType::Sum,
17163 131 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17164 : Constant::eResource::Electricity,
17165 : OutputProcessor::Group::HVAC,
17166 : OutputProcessor::EndUseCat::Cooling);
17167 : }
17168 149 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatCoilExists ||
17169 17 : state.dataUnitarySystems->unitarySys[sysNum].m_SuppCoilExists) {
17170 230 : SetupOutputVariable(state,
17171 : "Unitary System Heating Ancillary Electricity Energy",
17172 : Constant::Units::J,
17173 115 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingAuxElecConsumption,
17174 : OutputProcessor::TimeStepType::System,
17175 : OutputProcessor::StoreType::Sum,
17176 115 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17177 : Constant::eResource::Electricity,
17178 : OutputProcessor::Group::HVAC,
17179 : OutputProcessor::EndUseCat::Heating);
17180 : }
17181 :
17182 264 : SetupOutputVariable(state,
17183 : "Unitary System Electricity Rate",
17184 : Constant::Units::W,
17185 132 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17186 : OutputProcessor::TimeStepType::System,
17187 : OutputProcessor::StoreType::Average,
17188 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17189 264 : SetupOutputVariable(state,
17190 : "Unitary System Electricity Energy",
17191 : Constant::Units::J,
17192 132 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17193 : OutputProcessor::TimeStepType::System,
17194 : OutputProcessor::StoreType::Sum,
17195 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17196 :
17197 : // report predicted load as determined by Unitary System for load control only
17198 132 : if (state.dataUnitarySystems->unitarySys[sysNum].m_ControlType != UnitarySys::UnitarySysCtrlType::Setpoint) {
17199 248 : SetupOutputVariable(state,
17200 : "Unitary System Predicted Sensible Load to Setpoint Heat Transfer Rate",
17201 : Constant::Units::W,
17202 124 : state.dataUnitarySystems->unitarySys[sysNum].m_SensibleLoadPredicted,
17203 : OutputProcessor::TimeStepType::System,
17204 : OutputProcessor::StoreType::Average,
17205 124 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17206 248 : SetupOutputVariable(state,
17207 : "Unitary System Predicted Moisture Load to Setpoint Heat Transfer Rate",
17208 : Constant::Units::W,
17209 124 : state.dataUnitarySystems->unitarySys[sysNum].m_MoistureLoadPredicted,
17210 : OutputProcessor::TimeStepType::System,
17211 : OutputProcessor::StoreType::Average,
17212 124 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17213 : }
17214 :
17215 : // IF(UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)THEN
17216 264 : SetupOutputVariable(state,
17217 : "Unitary System Dehumidification Induced Heating Demand Rate",
17218 : Constant::Units::W,
17219 132 : state.dataUnitarySystems->unitarySys[sysNum].m_DehumidInducedHeatingDemandRate,
17220 : OutputProcessor::TimeStepType::System,
17221 : OutputProcessor::StoreType::Average,
17222 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17223 : // END IF
17224 :
17225 132 : if (state.dataUnitarySystems->unitarySys[sysNum].m_FanExists) {
17226 260 : SetupOutputVariable(state,
17227 : "Unitary System Fan Part Load Ratio",
17228 : Constant::Units::None,
17229 130 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17230 : OutputProcessor::TimeStepType::System,
17231 : OutputProcessor::StoreType::Average,
17232 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17233 : }
17234 :
17235 264 : SetupOutputVariable(state,
17236 : "Unitary System Compressor Part Load Ratio",
17237 : Constant::Units::None,
17238 132 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17239 : OutputProcessor::TimeStepType::System,
17240 : OutputProcessor::StoreType::Average,
17241 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17242 :
17243 132 : SetupOutputVariable(state,
17244 : "Unitary System Frost Control Status",
17245 : Constant::Units::None,
17246 132 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17247 : OutputProcessor::TimeStepType::System,
17248 : OutputProcessor::StoreType::Average,
17249 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17250 :
17251 132 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num) {
17252 90 : case HVAC::CoilDX_MultiSpeedCooling:
17253 : case HVAC::CoilDX_Cooling: {
17254 90 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecActive) {
17255 0 : SetupOutputVariable(state,
17256 : "Unitary System Heat Recovery Rate",
17257 : Constant::Units::W,
17258 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryRate,
17259 : OutputProcessor::TimeStepType::System,
17260 : OutputProcessor::StoreType::Average,
17261 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17262 0 : SetupOutputVariable(state,
17263 : "Unitary System Heat Recovery Inlet Temperature",
17264 : Constant::Units::C,
17265 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryInletTemp,
17266 : OutputProcessor::TimeStepType::System,
17267 : OutputProcessor::StoreType::Average,
17268 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17269 0 : SetupOutputVariable(state,
17270 : "Unitary System Heat Recovery Outlet Temperature",
17271 : Constant::Units::C,
17272 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryOutletTemp,
17273 : OutputProcessor::TimeStepType::System,
17274 : OutputProcessor::StoreType::Average,
17275 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17276 0 : SetupOutputVariable(state,
17277 : "Unitary System Heat Recovery Fluid Mass Flow Rate",
17278 : Constant::Units::kg_s,
17279 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryMassFlowRate,
17280 : OutputProcessor::TimeStepType::System,
17281 : OutputProcessor::StoreType::Average,
17282 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17283 0 : SetupOutputVariable(state,
17284 : "Unitary System Heat Recovery Energy",
17285 : Constant::Units::J,
17286 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryEnergy,
17287 : OutputProcessor::TimeStepType::System,
17288 : OutputProcessor::StoreType::Sum,
17289 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17290 : }
17291 90 : } break;
17292 10 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
17293 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit:
17294 : case HVAC::Coil_CoolingWaterToAirHPSimple:
17295 : case HVAC::Coil_CoolingWaterToAirHP: {
17296 20 : SetupOutputVariable(state,
17297 : "Unitary System Requested Sensible Cooling Rate",
17298 : Constant::Units::W,
17299 10 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilSensDemand,
17300 : OutputProcessor::TimeStepType::System,
17301 : OutputProcessor::StoreType::Average,
17302 10 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17303 20 : SetupOutputVariable(state,
17304 : "Unitary System Requested Latent Cooling Rate",
17305 : Constant::Units::W,
17306 10 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilLatentDemand,
17307 : OutputProcessor::TimeStepType::System,
17308 : OutputProcessor::StoreType::Average,
17309 10 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17310 10 : } break;
17311 32 : default:
17312 32 : break;
17313 : }
17314 :
17315 132 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex >= 0) {
17316 184 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
17317 52 : state.dataCoilCoolingDX->coilCoolingDXs[state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex]
17318 52 : .SubcoolReheatFlag) {
17319 2 : SetupOutputVariable(state,
17320 : "Unitary System Zone Load Sensible Heat Ratio",
17321 : Constant::Units::None,
17322 1 : state.dataUnitarySystems->unitarySys[sysNum].LoadSHR,
17323 : OutputProcessor::TimeStepType::System,
17324 : OutputProcessor::StoreType::Average,
17325 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17326 2 : SetupOutputVariable(state,
17327 : "Unitary System Cooling Coil Load Sensible Heat Ratio",
17328 : Constant::Units::None,
17329 1 : state.dataUnitarySystems->unitarySys[sysNum].CoilSHR,
17330 : OutputProcessor::TimeStepType::System,
17331 : OutputProcessor::StoreType::Average,
17332 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17333 : }
17334 : }
17335 :
17336 132 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num) {
17337 8 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
17338 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
17339 : case HVAC::Coil_HeatingWaterToAirHPSimple:
17340 : case HVAC::Coil_HeatingWaterToAirHP: {
17341 16 : SetupOutputVariable(state,
17342 : "Unitary System Requested Heating Rate",
17343 : Constant::Units::W,
17344 8 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilSensDemand,
17345 : OutputProcessor::TimeStepType::System,
17346 : OutputProcessor::StoreType::Average,
17347 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17348 8 : } break;
17349 124 : default:
17350 124 : break;
17351 : }
17352 :
17353 132 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17354 94 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
17355 94 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
17356 42 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17357 267 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
17358 41 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
17359 182 : SetupOutputVariable(state,
17360 : "Unitary System DX Coil Cycling Ratio",
17361 : Constant::Units::None,
17362 91 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17363 : OutputProcessor::TimeStepType::System,
17364 : OutputProcessor::StoreType::Average,
17365 91 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17366 182 : SetupOutputVariable(state,
17367 : "Unitary System DX Coil Speed Ratio",
17368 : Constant::Units::None,
17369 91 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17370 : OutputProcessor::TimeStepType::System,
17371 : OutputProcessor::StoreType::Average,
17372 91 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17373 91 : SetupOutputVariable(state,
17374 : "Unitary System DX Coil Speed Level",
17375 : Constant::Units::None,
17376 91 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17377 : OutputProcessor::TimeStepType::System,
17378 : OutputProcessor::StoreType::Average,
17379 91 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17380 : }
17381 :
17382 132 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
17383 115 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
17384 263 : state.dataUnitarySystems->unitarySys[sysNum].m_DiscreteSpeedCoolingCoil) ||
17385 131 : (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWater &&
17386 1 : state.dataUnitarySystems->unitarySys[sysNum].m_MultiSpeedHeatingCoil)) {
17387 2 : SetupOutputVariable(state,
17388 : "Unitary System Water Coil Cycling Ratio",
17389 : Constant::Units::None,
17390 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17391 : OutputProcessor::TimeStepType::System,
17392 : OutputProcessor::StoreType::Average,
17393 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17394 2 : SetupOutputVariable(state,
17395 : "Unitary System Water Coil Speed Ratio",
17396 : Constant::Units::None,
17397 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17398 : OutputProcessor::TimeStepType::System,
17399 : OutputProcessor::StoreType::Average,
17400 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17401 1 : SetupOutputVariable(state,
17402 : "Unitary System Water Coil Speed Level",
17403 : Constant::Units::None,
17404 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17405 : OutputProcessor::TimeStepType::System,
17406 : OutputProcessor::StoreType::Average,
17407 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17408 : }
17409 :
17410 132 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
17411 96 : SetupEMSActuator(state,
17412 : "UnitarySystem",
17413 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17414 : "Autosized Supply Air Flow Rate",
17415 : "[m3/s]",
17416 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideOn,
17417 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideValue);
17418 96 : SetupEMSActuator(state,
17419 : "UnitarySystem",
17420 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17421 : "Autosized Supply Air Flow Rate During Cooling Operation",
17422 : "[m3/s]",
17423 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideOn,
17424 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideValue);
17425 96 : SetupEMSActuator(state,
17426 : "UnitarySystem",
17427 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17428 : "Autosized Supply Air Flow Rate During Heating Operation",
17429 : "[m3/s]",
17430 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideOn,
17431 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideValue);
17432 96 : SetupEMSActuator(state,
17433 : "UnitarySystem",
17434 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17435 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
17436 : "[m3/s]",
17437 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideOn,
17438 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideValue);
17439 48 : SetupEMSInternalVariable(state,
17440 : "Unitary System Control Zone Mass Flow Fraction",
17441 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17442 : "[]",
17443 48 : state.dataUnitarySystems->unitarySys[sysNum].ControlZoneMassFlowFrac);
17444 48 : SetupEMSInternalVariable(state,
17445 : "Unitary HVAC Design Heating Capacity",
17446 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17447 : "[W]",
17448 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignHeatingCapacity);
17449 48 : SetupEMSInternalVariable(state,
17450 : "Unitary HVAC Design Cooling Capacity",
17451 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17452 : "[W]",
17453 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignCoolingCapacity);
17454 96 : SetupEMSActuator(state,
17455 : "Unitary HVAC",
17456 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17457 : "Sensible Load Request",
17458 : "[W]",
17459 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSensZoneLoadRequest,
17460 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSSensibleZoneLoadValue);
17461 96 : SetupEMSActuator(state,
17462 : "Unitary HVAC",
17463 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17464 : "Moisture Load Request",
17465 : "[W]",
17466 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideMoistZoneLoadRequest,
17467 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSMoistureZoneLoadValue);
17468 48 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17469 58 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17470 10 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
17471 90 : SetupEMSActuator(state,
17472 : "Coil Speed Control",
17473 45 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17474 : "Unitary System DX Coil Speed Value",
17475 : "[]",
17476 45 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumOn,
17477 45 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumValue);
17478 : }
17479 96 : SetupEMSActuator(state,
17480 : "Coil Speed Control",
17481 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17482 : "Unitary System Supplemental Coil Stage Level",
17483 : "[]",
17484 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumOn,
17485 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumValue);
17486 : }
17487 : bool anyEMSRan;
17488 132 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
17489 763 : break;
17490 298 : case UnitarySys::SysType::CoilCoolingDX:
17491 : // Setup Report variables for the DXCoolingSystem that is not reported in the components themselves
17492 298 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
17493 134 : SetupOutputVariable(state,
17494 : "Coil System Cycling Ratio",
17495 : Constant::Units::None,
17496 67 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17497 : OutputProcessor::TimeStepType::System,
17498 : OutputProcessor::StoreType::Average,
17499 67 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17500 134 : SetupOutputVariable(state,
17501 : "Coil System Compressor Speed Ratio",
17502 : Constant::Units::None,
17503 67 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17504 : OutputProcessor::TimeStepType::System,
17505 : OutputProcessor::StoreType::Average,
17506 67 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17507 231 : } else if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
17508 4 : SetupOutputVariable(state,
17509 : "Coil System Cycling Ratio",
17510 : Constant::Units::None,
17511 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17512 : OutputProcessor::TimeStepType::System,
17513 : OutputProcessor::StoreType::Average,
17514 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17515 4 : SetupOutputVariable(state,
17516 : "Coil System Compressor Speed Ratio",
17517 : Constant::Units::None,
17518 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17519 : OutputProcessor::TimeStepType::System,
17520 : OutputProcessor::StoreType::Average,
17521 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17522 2 : SetupOutputVariable(state,
17523 : "Coil System Compressor Speed Number",
17524 : Constant::Units::None,
17525 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedNum,
17526 : OutputProcessor::TimeStepType::System,
17527 : OutputProcessor::StoreType::Average,
17528 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17529 : } else {
17530 458 : SetupOutputVariable(state,
17531 : "Coil System Part Load Ratio",
17532 : Constant::Units::None,
17533 229 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingPartLoadFrac,
17534 : OutputProcessor::TimeStepType::System,
17535 : OutputProcessor::StoreType::Average,
17536 229 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17537 : }
17538 298 : SetupOutputVariable(state,
17539 : "Coil System Frost Control Status",
17540 : Constant::Units::None,
17541 298 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17542 : OutputProcessor::TimeStepType::System,
17543 : OutputProcessor::StoreType::Average,
17544 298 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17545 298 : break;
17546 3 : case UnitarySys::SysType::CoilCoolingWater:
17547 : // Setup Report variables for the CoilSystemWater
17548 6 : SetupOutputVariable(state,
17549 : "Coil System Water Part Load Ratio",
17550 : Constant::Units::None,
17551 3 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17552 : OutputProcessor::TimeStepType::System,
17553 : OutputProcessor::StoreType::Average,
17554 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17555 6 : SetupOutputVariable(state,
17556 : "Coil System Water Total Cooling Rate",
17557 : Constant::Units::W,
17558 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17559 : OutputProcessor::TimeStepType::System,
17560 : OutputProcessor::StoreType::Average,
17561 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17562 6 : SetupOutputVariable(state,
17563 : "Coil System Water Sensible Cooling Rate",
17564 : Constant::Units::W,
17565 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17566 : OutputProcessor::TimeStepType::System,
17567 : OutputProcessor::StoreType::Average,
17568 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17569 6 : SetupOutputVariable(state,
17570 : "Coil System Water Latent Cooling Rate",
17571 : Constant::Units::W,
17572 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17573 : OutputProcessor::TimeStepType::System,
17574 : OutputProcessor::StoreType::Average,
17575 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17576 :
17577 3 : if (state.dataUnitarySystems->unitarySys[sysNum].m_TemperatureOffsetControlActive) {
17578 3 : SetupOutputVariable(state,
17579 : "Coil System Water Control Status",
17580 : Constant::Units::None,
17581 3 : state.dataUnitarySystems->unitarySys[sysNum].temperatureOffsetControlStatus,
17582 : OutputProcessor::TimeStepType::System,
17583 : OutputProcessor::StoreType::Average,
17584 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17585 : }
17586 3 : break;
17587 147 : case UnitarySys::SysType::PackagedAC:
17588 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalAirConditioner'
17589 294 : SetupOutputVariable(state,
17590 : "Zone Packaged Terminal Air Conditioner Total Heating Rate",
17591 : Constant::Units::W,
17592 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17593 : OutputProcessor::TimeStepType::System,
17594 : OutputProcessor::StoreType::Average,
17595 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17596 294 : SetupOutputVariable(state,
17597 : "Zone Packaged Terminal Air Conditioner Total Heating Energy",
17598 : Constant::Units::J,
17599 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17600 : OutputProcessor::TimeStepType::System,
17601 : OutputProcessor::StoreType::Sum,
17602 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17603 294 : SetupOutputVariable(state,
17604 : "Zone Packaged Terminal Air Conditioner Total Cooling Rate",
17605 : Constant::Units::W,
17606 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17607 : OutputProcessor::TimeStepType::System,
17608 : OutputProcessor::StoreType::Average,
17609 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17610 294 : SetupOutputVariable(state,
17611 : "Zone Packaged Terminal Air Conditioner Total Cooling Energy",
17612 : Constant::Units::J,
17613 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17614 : OutputProcessor::TimeStepType::System,
17615 : OutputProcessor::StoreType::Sum,
17616 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17617 294 : SetupOutputVariable(state,
17618 : "Zone Packaged Terminal Air Conditioner Sensible Heating Rate",
17619 : Constant::Units::W,
17620 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17621 : OutputProcessor::TimeStepType::System,
17622 : OutputProcessor::StoreType::Average,
17623 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17624 294 : SetupOutputVariable(state,
17625 : "Zone Packaged Terminal Air Conditioner Sensible Heating Energy",
17626 : Constant::Units::J,
17627 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17628 : OutputProcessor::TimeStepType::System,
17629 : OutputProcessor::StoreType::Sum,
17630 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17631 294 : SetupOutputVariable(state,
17632 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Rate",
17633 : Constant::Units::W,
17634 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17635 : OutputProcessor::TimeStepType::System,
17636 : OutputProcessor::StoreType::Average,
17637 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17638 294 : SetupOutputVariable(state,
17639 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Energy",
17640 : Constant::Units::J,
17641 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17642 : OutputProcessor::TimeStepType::System,
17643 : OutputProcessor::StoreType::Sum,
17644 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17645 294 : SetupOutputVariable(state,
17646 : "Zone Packaged Terminal Air Conditioner Latent Heating Rate",
17647 : Constant::Units::W,
17648 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17649 : OutputProcessor::TimeStepType::System,
17650 : OutputProcessor::StoreType::Average,
17651 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17652 294 : SetupOutputVariable(state,
17653 : "Zone Packaged Terminal Air Conditioner Latent Heating Energy",
17654 : Constant::Units::J,
17655 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17656 : OutputProcessor::TimeStepType::System,
17657 : OutputProcessor::StoreType::Sum,
17658 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17659 294 : SetupOutputVariable(state,
17660 : "Zone Packaged Terminal Air Conditioner Latent Cooling Rate",
17661 : Constant::Units::W,
17662 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17663 : OutputProcessor::TimeStepType::System,
17664 : OutputProcessor::StoreType::Average,
17665 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17666 294 : SetupOutputVariable(state,
17667 : "Zone Packaged Terminal Air Conditioner Latent Cooling Energy",
17668 : Constant::Units::J,
17669 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17670 : OutputProcessor::TimeStepType::System,
17671 : OutputProcessor::StoreType::Sum,
17672 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17673 294 : SetupOutputVariable(state,
17674 : "Zone Packaged Terminal Air Conditioner Electricity Rate",
17675 : Constant::Units::W,
17676 147 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17677 : OutputProcessor::TimeStepType::System,
17678 : OutputProcessor::StoreType::Average,
17679 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17680 294 : SetupOutputVariable(state,
17681 : "Zone Packaged Terminal Air Conditioner Electricity Energy",
17682 : Constant::Units::J,
17683 147 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17684 : OutputProcessor::TimeStepType::System,
17685 : OutputProcessor::StoreType::Sum,
17686 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17687 294 : SetupOutputVariable(state,
17688 : "Zone Packaged Terminal Air Conditioner Fan Part Load Ratio",
17689 : Constant::Units::None,
17690 147 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17691 : OutputProcessor::TimeStepType::System,
17692 : OutputProcessor::StoreType::Average,
17693 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17694 294 : SetupOutputVariable(state,
17695 : "Zone Packaged Terminal Air Conditioner Compressor Part Load Ratio",
17696 : Constant::Units::None,
17697 147 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17698 : OutputProcessor::TimeStepType::System,
17699 : OutputProcessor::StoreType::Average,
17700 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17701 147 : SetupOutputVariable(state,
17702 : "Zone Packaged Terminal Air Conditioner Fan Availability Status",
17703 : Constant::Units::None,
17704 147 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17705 : OutputProcessor::TimeStepType::System,
17706 : OutputProcessor::StoreType::Average,
17707 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17708 147 : break;
17709 28 : case UnitarySys::SysType::PackagedHP:
17710 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalHeatPump'
17711 56 : SetupOutputVariable(state,
17712 : "Zone Packaged Terminal Heat Pump Total Heating Rate",
17713 : Constant::Units::W,
17714 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17715 : OutputProcessor::TimeStepType::System,
17716 : OutputProcessor::StoreType::Average,
17717 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17718 56 : SetupOutputVariable(state,
17719 : "Zone Packaged Terminal Heat Pump Total Heating Energy",
17720 : Constant::Units::J,
17721 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17722 : OutputProcessor::TimeStepType::System,
17723 : OutputProcessor::StoreType::Sum,
17724 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17725 56 : SetupOutputVariable(state,
17726 : "Zone Packaged Terminal Heat Pump Total Cooling Rate",
17727 : Constant::Units::W,
17728 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17729 : OutputProcessor::TimeStepType::System,
17730 : OutputProcessor::StoreType::Average,
17731 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17732 56 : SetupOutputVariable(state,
17733 : "Zone Packaged Terminal Heat Pump Total Cooling Energy",
17734 : Constant::Units::J,
17735 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17736 : OutputProcessor::TimeStepType::System,
17737 : OutputProcessor::StoreType::Sum,
17738 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17739 56 : SetupOutputVariable(state,
17740 : "Zone Packaged Terminal Heat Pump Sensible Heating Rate",
17741 : Constant::Units::W,
17742 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17743 : OutputProcessor::TimeStepType::System,
17744 : OutputProcessor::StoreType::Average,
17745 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17746 56 : SetupOutputVariable(state,
17747 : "Zone Packaged Terminal Heat Pump Sensible Heating Energy",
17748 : Constant::Units::J,
17749 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17750 : OutputProcessor::TimeStepType::System,
17751 : OutputProcessor::StoreType::Sum,
17752 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17753 56 : SetupOutputVariable(state,
17754 : "Zone Packaged Terminal Heat Pump Sensible Cooling Rate",
17755 : Constant::Units::W,
17756 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17757 : OutputProcessor::TimeStepType::System,
17758 : OutputProcessor::StoreType::Average,
17759 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17760 56 : SetupOutputVariable(state,
17761 : "Zone Packaged Terminal Heat Pump Sensible Cooling Energy",
17762 : Constant::Units::J,
17763 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17764 : OutputProcessor::TimeStepType::System,
17765 : OutputProcessor::StoreType::Sum,
17766 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17767 56 : SetupOutputVariable(state,
17768 : "Zone Packaged Terminal Heat Pump Latent Heating Rate",
17769 : Constant::Units::W,
17770 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17771 : OutputProcessor::TimeStepType::System,
17772 : OutputProcessor::StoreType::Average,
17773 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17774 56 : SetupOutputVariable(state,
17775 : "Zone Packaged Terminal Heat Pump Latent Heating Energy",
17776 : Constant::Units::J,
17777 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17778 : OutputProcessor::TimeStepType::System,
17779 : OutputProcessor::StoreType::Sum,
17780 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17781 56 : SetupOutputVariable(state,
17782 : "Zone Packaged Terminal Heat Pump Latent Cooling Rate",
17783 : Constant::Units::W,
17784 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17785 : OutputProcessor::TimeStepType::System,
17786 : OutputProcessor::StoreType::Average,
17787 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17788 56 : SetupOutputVariable(state,
17789 : "Zone Packaged Terminal Heat Pump Latent Cooling Energy",
17790 : Constant::Units::J,
17791 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17792 : OutputProcessor::TimeStepType::System,
17793 : OutputProcessor::StoreType::Sum,
17794 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17795 56 : SetupOutputVariable(state,
17796 : "Zone Packaged Terminal Heat Pump Electricity Rate",
17797 : Constant::Units::W,
17798 28 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17799 : OutputProcessor::TimeStepType::System,
17800 : OutputProcessor::StoreType::Average,
17801 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17802 56 : SetupOutputVariable(state,
17803 : "Zone Packaged Terminal Heat Pump Electricity Energy",
17804 : Constant::Units::J,
17805 28 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17806 : OutputProcessor::TimeStepType::System,
17807 : OutputProcessor::StoreType::Sum,
17808 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17809 56 : SetupOutputVariable(state,
17810 : "Zone Packaged Terminal Heat Pump Fan Part Load Ratio",
17811 : Constant::Units::None,
17812 28 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17813 : OutputProcessor::TimeStepType::System,
17814 : OutputProcessor::StoreType::Average,
17815 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17816 56 : SetupOutputVariable(state,
17817 : "Zone Packaged Terminal Heat Pump Compressor Part Load Ratio",
17818 : Constant::Units::None,
17819 28 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17820 : OutputProcessor::TimeStepType::System,
17821 : OutputProcessor::StoreType::Average,
17822 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17823 28 : SetupOutputVariable(state,
17824 : "Zone Packaged Terminal Heat Pump Fan Availability Status",
17825 : Constant::Units::None,
17826 28 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17827 : OutputProcessor::TimeStepType::System,
17828 : OutputProcessor::StoreType::Average,
17829 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17830 28 : break;
17831 155 : case UnitarySys::SysType::PackagedWSHP:
17832 : // CurrentModuleObject = 'ZoneHVAC:WaterToAirHeatPump'
17833 310 : SetupOutputVariable(state,
17834 : "Zone Water to Air Heat Pump Total Heating Rate",
17835 : Constant::Units::W,
17836 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17837 : OutputProcessor::TimeStepType::System,
17838 : OutputProcessor::StoreType::Average,
17839 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17840 310 : SetupOutputVariable(state,
17841 : "Zone Water to Air Heat Pump Total Heating Energy",
17842 : Constant::Units::J,
17843 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17844 : OutputProcessor::TimeStepType::System,
17845 : OutputProcessor::StoreType::Sum,
17846 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17847 310 : SetupOutputVariable(state,
17848 : "Zone Water to Air Heat Pump Total Cooling Rate",
17849 : Constant::Units::W,
17850 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17851 : OutputProcessor::TimeStepType::System,
17852 : OutputProcessor::StoreType::Average,
17853 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17854 310 : SetupOutputVariable(state,
17855 : "Zone Water to Air Heat Pump Total Cooling Energy",
17856 : Constant::Units::J,
17857 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17858 : OutputProcessor::TimeStepType::System,
17859 : OutputProcessor::StoreType::Sum,
17860 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17861 310 : SetupOutputVariable(state,
17862 : "Zone Water to Air Heat Pump Sensible Heating Rate",
17863 : Constant::Units::W,
17864 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17865 : OutputProcessor::TimeStepType::System,
17866 : OutputProcessor::StoreType::Average,
17867 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17868 310 : SetupOutputVariable(state,
17869 : "Zone Water to Air Heat Pump Sensible Heating Energy",
17870 : Constant::Units::J,
17871 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17872 : OutputProcessor::TimeStepType::System,
17873 : OutputProcessor::StoreType::Sum,
17874 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17875 310 : SetupOutputVariable(state,
17876 : "Zone Water to Air Heat Pump Sensible Cooling Rate",
17877 : Constant::Units::W,
17878 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17879 : OutputProcessor::TimeStepType::System,
17880 : OutputProcessor::StoreType::Average,
17881 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17882 310 : SetupOutputVariable(state,
17883 : "Zone Water to Air Heat Pump Sensible Cooling Energy",
17884 : Constant::Units::J,
17885 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17886 : OutputProcessor::TimeStepType::System,
17887 : OutputProcessor::StoreType::Sum,
17888 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17889 310 : SetupOutputVariable(state,
17890 : "Zone Water to Air Heat Pump Latent Heating Rate",
17891 : Constant::Units::W,
17892 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17893 : OutputProcessor::TimeStepType::System,
17894 : OutputProcessor::StoreType::Average,
17895 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17896 310 : SetupOutputVariable(state,
17897 : "Zone Water to Air Heat Pump Latent Heating Energy",
17898 : Constant::Units::J,
17899 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17900 : OutputProcessor::TimeStepType::System,
17901 : OutputProcessor::StoreType::Sum,
17902 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17903 310 : SetupOutputVariable(state,
17904 : "Zone Water to Air Heat Pump Latent Cooling Rate",
17905 : Constant::Units::W,
17906 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17907 : OutputProcessor::TimeStepType::System,
17908 : OutputProcessor::StoreType::Average,
17909 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17910 310 : SetupOutputVariable(state,
17911 : "Zone Water to Air Heat Pump Latent Cooling Energy",
17912 : Constant::Units::J,
17913 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17914 : OutputProcessor::TimeStepType::System,
17915 : OutputProcessor::StoreType::Sum,
17916 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17917 310 : SetupOutputVariable(state,
17918 : "Zone Water to Air Heat Pump Electricity Rate",
17919 : Constant::Units::W,
17920 155 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17921 : OutputProcessor::TimeStepType::System,
17922 : OutputProcessor::StoreType::Average,
17923 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17924 310 : SetupOutputVariable(state,
17925 : "Zone Water to Air Heat Pump Electricity Energy",
17926 : Constant::Units::J,
17927 155 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17928 : OutputProcessor::TimeStepType::System,
17929 : OutputProcessor::StoreType::Sum,
17930 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17931 310 : SetupOutputVariable(state,
17932 : "Zone Water to Air Heat Pump Fan Part Load Ratio",
17933 : Constant::Units::None,
17934 155 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17935 : OutputProcessor::TimeStepType::System,
17936 : OutputProcessor::StoreType::Average,
17937 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17938 310 : SetupOutputVariable(state,
17939 : "Zone Water to Air Heat Pump Compressor Part Load Ratio",
17940 : Constant::Units::None,
17941 155 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17942 : OutputProcessor::TimeStepType::System,
17943 : OutputProcessor::StoreType::Average,
17944 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17945 155 : SetupOutputVariable(state,
17946 : "Zone Water to Air Heat Pump Fan Availability Status",
17947 : Constant::Units::None,
17948 155 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17949 : OutputProcessor::TimeStepType::System,
17950 : OutputProcessor::StoreType::Average,
17951 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17952 155 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
17953 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
17954 310 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedCooling > 1) ||
17955 153 : ((state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
17956 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
17957 153 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedHeating > 1)) {
17958 4 : SetupOutputVariable(state,
17959 : "Unitary System Water Coil Multispeed Fan Cycling Ratio",
17960 : Constant::Units::None,
17961 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17962 : OutputProcessor::TimeStepType::System,
17963 : OutputProcessor::StoreType::Average,
17964 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17965 4 : SetupOutputVariable(state,
17966 : "Unitary System Water Coil Multispeed Fan Speed Ratio",
17967 : Constant::Units::None,
17968 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17969 : OutputProcessor::TimeStepType::System,
17970 : OutputProcessor::StoreType::Average,
17971 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17972 2 : SetupOutputVariable(state,
17973 : "Unitary System Water Coil Multispeed Fan Speed Level",
17974 : Constant::Units::None,
17975 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17976 : OutputProcessor::TimeStepType::System,
17977 : OutputProcessor::StoreType::Average,
17978 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17979 : }
17980 155 : break;
17981 0 : default:
17982 0 : ShowFatalError(state,
17983 : "setupAllOutputVar: Developer error. All report variables must be set up here after all systems are read in.");
17984 : }
17985 : }
17986 170 : state.dataUnitarySystems->setupOutputOnce = false;
17987 : } else {
17988 0 : ShowSevereError(state,
17989 : "setupAllOutputVar: Developer error. Should never get here. Remove when comfortable that UnitarySys::allocateUnitarySys "
17990 : "is working as expected.");
17991 0 : ShowFatalError(state, "setupAllOutputVar: Developer error. Conflict in number of UnitarySystems.");
17992 : }
17993 170 : }
17994 :
17995 61 : void isWaterCoilHeatRecoveryType(EnergyPlusData const &state, int const waterCoilNodeNum, bool &nodeNotFound)
17996 : {
17997 61 : if (!nodeNotFound) {
17998 60 : return;
17999 : }
18000 1 : nodeNotFound = std::none_of(
18001 2 : state.dataUnitarySystems->unitarySys.cbegin(), state.dataUnitarySystems->unitarySys.cend(), [waterCoilNodeNum](auto const &us) {
18002 1 : return us.m_WaterHRPlantLoopModel && us.m_HRcoolCoilFluidInletNode == waterCoilNodeNum;
18003 : });
18004 : }
18005 :
18006 470139 : Real64 UnitarySys::getFanDeltaTemp(EnergyPlusData &state, bool const firstHVACIteration, Real64 const massFlowRate, Real64 const airFlowRatio)
18007 : {
18008 470139 : int FanInletNode = 0;
18009 470139 : int FanOutletNode = 0;
18010 :
18011 470139 : auto *fan = state.dataFans->fans(this->m_FanIndex);
18012 470139 : FanInletNode = fan->inletNodeNum;
18013 470139 : FanOutletNode = fan->outletNodeNum;
18014 470139 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = massFlowRate;
18015 470139 : fan->simulate(state, firstHVACIteration, airFlowRatio, _, airFlowRatio, _, _, _);
18016 470139 : return state.dataLoopNodes->Node(FanOutletNode).Temp - state.dataLoopNodes->Node(FanInletNode).Temp;
18017 : }
18018 :
18019 175588 : void UnitarySys::setEconomizerStagingOperationSpeed(EnergyPlusData &state, bool const firstHVACIteration, Real64 const zoneLoad)
18020 : {
18021 175588 : this->m_LowSpeedEconOutput = 0;
18022 175588 : this->m_LowSpeedEconRuntime = 0;
18023 175588 : this->m_EconoPartLoadRatio = 0;
18024 175588 : this->m_EconoSpeedNum = 0;
18025 175588 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
18026 175588 : Real64 mixedTempAtMinOA = 0;
18027 175588 : Real64 highSpeedEconMassFlowRate = 0;
18028 175588 : Real64 highSpeedFanDT = 0;
18029 175588 : Real64 econClgOutput = 0;
18030 175588 : Real64 lowSpeedEconMassFlowRate = 0;
18031 175588 : Real64 lowSpeedFanDT = 0;
18032 175588 : Real64 highSpeedEconRuntime = 0;
18033 175588 : Real64 econClgOutputMinOA = 0;
18034 : // determine outdoor air properties
18035 : using Psychrometrics::PsyCpAirFnW;
18036 175588 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
18037 175588 : Real64 outdoorAirTemp = state.dataLoopNodes->Node(outdoorAirController.InletNode).Temp;
18038 175588 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
18039 : // iterate through the unitary system's cooling speed to see at which
18040 : // air flow rate the load can be met at 100% outdoor air fraction
18041 284768 : for (int clgSpd = 1; clgSpd <= this->m_NumOfSpeedCooling; ++clgSpd) {
18042 : // calculations for "high speed" refer to operation at the current
18043 : // cooling speed, "clgSpd", and "low speed" is "clgSpd -1"
18044 284768 : highSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd];
18045 : // determine air temperature difference for across the fan at this air flow rate
18046 284768 : highSpeedFanDT = this->getFanDeltaTemp(state,
18047 : firstHVACIteration,
18048 : highSpeedEconMassFlowRate,
18049 284768 : highSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18050 284768 : econClgOutput = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + highSpeedFanDT));
18051 : // check if economizer alone can meet the load, or if we have reached the maximum cooling speed
18052 284768 : if (econClgOutput > std::abs(zoneLoad) || clgSpd == this->m_NumOfSpeedCooling) {
18053 : // low speed economizer operation is handled through normal process (i.e., no staging operation)
18054 175588 : if (clgSpd > 1) {
18055 : // check that the system output at the minimum outdoor air flow rate doesn't "overcool" at this speed
18056 84835 : mixedTempAtMinOA = 0;
18057 84835 : if (highSpeedEconMassFlowRate - outdoorAirController.MinOA > 0) {
18058 84835 : mixedTempAtMinOA =
18059 84835 : (outdoorAirTemp * outdoorAirController.MinOA + state.dataLoopNodes->Node(outdoorAirController.RetNode).Temp *
18060 84835 : (highSpeedEconMassFlowRate - outdoorAirController.MinOA)) /
18061 : highSpeedEconMassFlowRate;
18062 : } else {
18063 0 : mixedTempAtMinOA = outdoorAirTemp;
18064 : }
18065 84835 : econClgOutputMinOA = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (mixedTempAtMinOA + highSpeedFanDT));
18066 84835 : if (econClgOutputMinOA < std::abs(zoneLoad)) {
18067 75052 : highSpeedEconRuntime = 1.0;
18068 : } else {
18069 : // if running at this speed would "overcool", we run partly at the lower speed and partly at this speed
18070 9783 : lowSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd - 1];
18071 9783 : lowSpeedFanDT = this->getFanDeltaTemp(state,
18072 : firstHVACIteration,
18073 : lowSpeedEconMassFlowRate,
18074 9783 : lowSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18075 9783 : this->m_LowSpeedEconOutput = cpAir * lowSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + lowSpeedFanDT));
18076 : // determine this speed's runtime
18077 9783 : highSpeedEconRuntime = (std::abs(zoneLoad) - this->m_LowSpeedEconOutput) / (econClgOutput - this->m_LowSpeedEconOutput);
18078 : }
18079 : } else {
18080 90753 : highSpeedEconRuntime = 1.0;
18081 : }
18082 : // set economizer air flow "speed"
18083 175588 : this->m_EconoSpeedNum = clgSpd;
18084 : // set economizer PLR, a.k.a the system fan part load ratio, and runtime at each speed
18085 175588 : this->m_EconoPartLoadRatio = highSpeedEconRuntime;
18086 175588 : this->m_LowSpeedEconRuntime = 1 - highSpeedEconRuntime;
18087 175588 : break;
18088 : }
18089 : }
18090 175588 : }
18091 :
18092 175588 : void UnitarySys::calcMixedTempAirSPforEconomizerStagingOperation(EnergyPlusData &state,
18093 : int const airLoopNum,
18094 : bool const firstHVACIteration,
18095 : Real64 const zoneLoad)
18096 : {
18097 175588 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
18098 : using Psychrometrics::PsyCpAirFnW;
18099 175588 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
18100 175588 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
18101 : // determine and set new air loop mixed air flow rate
18102 175588 : Real64 mixedAirFlowRate = this->m_EconoPartLoadRatio * this->m_CoolMassFlowRate[this->m_EconoSpeedNum] +
18103 175588 : this->m_LowSpeedEconRuntime * this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
18104 175588 : if (airLoopNum > 0) {
18105 : // request fixed mixed flow rate
18106 175588 : state.dataAirLoop->AirLoopControlInfo(airLoopNum).LoopFlowRateSet = true;
18107 175588 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac = mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
18108 : // adjust mixed air flow rate for rated air flow rate adjustment (variable speed coils only)
18109 175588 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac *=
18110 175588 : this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling] / state.dataAirLoop->AirLoopFlow(airLoopNum).DesSupply;
18111 : }
18112 : // determine air temperature difference across fan based on new mixed air flow rate
18113 175588 : int mixedAirNode = outdoorAirController.MixNode;
18114 175588 : Real64 fanDTAtMixedAirFlowRate = this->getFanDeltaTemp(
18115 175588 : state, firstHVACIteration, mixedAirFlowRate, mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18116 : // determine new mixed air setpoint
18117 175588 : Real64 newMixedAirSP = zoneTemp - std::abs(zoneLoad) / (cpAir * mixedAirFlowRate);
18118 175588 : state.dataLoopNodes->Node(mixedAirNode).TempSetPoint = newMixedAirSP - fanDTAtMixedAirFlowRate;
18119 175588 : }
18120 :
18121 : void
18122 737912 : UnitarySys::manageEconomizerStagingOperation(EnergyPlusData &state, int const airLoopNum, bool const firstHVACIteration, Real64 const zoneLoad)
18123 : {
18124 737912 : if (airLoopNum > 0) {
18125 961520 : if (state.dataAirLoop->AirLoopControlInfo(airLoopNum).EconoActive == true && state.dataGlobal->WarmupFlag == false &&
18126 223608 : state.dataUnitarySystems->CoolingLoad) {
18127 175588 : this->setEconomizerStagingOperationSpeed(state, firstHVACIteration, zoneLoad);
18128 :
18129 : // adjustments are only needed when economizer speed is greater than the lowest speed
18130 175588 : if (this->m_EconoSpeedNum > 0) {
18131 175588 : this->calcMixedTempAirSPforEconomizerStagingOperation(state, airLoopNum, firstHVACIteration, zoneLoad);
18132 :
18133 : // recalculate the outdoor air fraction to meet the new mixed air setpoint at the new mixed air flow rate
18134 351176 : MixedAir::ManageOutsideAirSystem(
18135 175588 : state, state.dataAirLoop->OutsideAirSys(this->OASysIndex).Name, firstHVACIteration, airLoopNum, this->OASysIndex);
18136 : }
18137 : }
18138 : }
18139 737912 : }
18140 :
18141 : } // namespace UnitarySystems
18142 : } // namespace EnergyPlus
|