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 8987089 : 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 8987089 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
131 :
132 : // Obtains and Allocates unitary system related parameters from input file
133 8987089 : if (this->m_ThisSysInputShouldBeGotten) {
134 615 : getUnitarySystemInput(state, Name, ZoneEquipment, ZoneOAUnitNum);
135 : }
136 8987089 : CompIndex = this->m_EquipCompNum;
137 8987089 : state.dataUnitarySystems->FanSpeedRatio = 1.0;
138 8987089 : this->initUnitarySystems(state, AirLoopNum, FirstHVACIteration, OAUCoilOutTemp);
139 8987089 : 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 8987089 : 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 8987089 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
148 2616596 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = this->m_DesignMassFlowRate;
149 : }
150 :
151 8987089 : bool HXUnitOn = false;
152 8987089 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
153 2989820 : this->controlUnitarySystemtoSP(
154 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
155 : } else {
156 5997269 : this->controlUnitarySystemtoLoad(
157 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
158 : }
159 :
160 : // Report the current output
161 8987089 : this->reportUnitarySystem(state, AirLoopNum);
162 :
163 : // CoolActive = false; // set in call from ZoneEquipmentManager
164 8987089 : if (this->m_CoolingPartLoadFrac * double(CompressorOn) > 0.0) {
165 3539271 : CoolActive = true;
166 : }
167 : // HeatActive = false; // set in call from ZoneEquipmentManager
168 8987089 : if (this->m_HeatingPartLoadFrac * double(CompressorOn) > 0.0 || this->m_SuppHeatPartLoadFrac * double(CompressorOn) > 0.0) {
169 2217449 : HeatActive = true;
170 : }
171 :
172 : // set econo lockout flag
173 : // If the system is not an equipment of Outdoor air unit
174 8987089 : if (AirLoopNum > 0 && !state.dataAirLoop->AirLoopControlInfo.empty() && this->m_AirLoopEquipment) {
175 :
176 5532091 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor =
177 6170732 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor &&
178 638641 : (this->m_HeatCompPartLoadRatio > 0.0 || this->m_SpeedRatio > 0.0 || this->m_CycRatio > 0.0);
179 :
180 5532091 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating =
181 6244081 : HeatActive && (state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor ||
182 711990 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithHeating);
183 : }
184 :
185 : // Calculate heat recovery
186 8987089 : 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 8987089 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
195 2616596 : 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 736 : HVACSystemData *UnitarySys::factory(
325 : EnergyPlusData &state, HVAC::UnitarySysType const type, std::string const &objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
326 : {
327 736 : if (state.dataUnitarySystems->getInputOnceFlag) {
328 163 : UnitarySys::getUnitarySystemInput(state, objectName, ZoneEquipment, ZoneOAUnitNum);
329 163 : state.dataUnitarySystems->getInputOnceFlag = false;
330 : }
331 736 : int sysNum = -1;
332 12780 : for (auto &sys : state.dataUnitarySystems->unitarySys) {
333 12780 : ++sysNum;
334 12780 : if (Util::SameString(sys.Name, objectName) && type == HVAC::UnitarySysType::Unitary_AnyCoilType) {
335 736 : state.dataUnitarySystems->unitarySys[sysNum].m_UnitarySysNum = sysNum;
336 736 : return &sys;
337 : }
338 1472 : }
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 2944 : 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 2944 : int index = -1;
370 76680 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->unitarySys.size(); ++loop) {
371 75208 : UnitarySys *thisUnitarySysObjec = &state.dataUnitarySystems->unitarySys[loop];
372 75208 : if (Util::SameString(objectName, thisUnitarySysObjec->Name)) {
373 1472 : index = loop;
374 1472 : break;
375 : }
376 : }
377 2944 : return index;
378 : }
379 :
380 8987089 : 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 21645441 : if (this->m_IsZoneEquipment &&
386 12184580 : (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 8987089 : if (!state.dataGlobal->SysSizingCalc && this->m_MySizingCheckFlag && !this->m_ThisSysInputShouldBeGotten) {
416 731 : if (AirLoopNum > 0) {
417 372 : if (this->m_FanExists && (this->m_CoolCoilExists && (this->m_HeatCoilExists || this->m_SuppCoilExists))) {
418 105 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
419 : }
420 372 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
421 372 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
422 49 : 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 372 : if (!this->m_FanExists) {
426 266 : if (state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanType != HVAC::FanType::Invalid) {
427 263 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
428 263 : if (this->m_CoolCoilExists) {
429 262 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
430 : state,
431 262 : this->m_CoolingCoilName,
432 262 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
433 262 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
434 262 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
435 : primaryAirSystems.supFanNum);
436 : }
437 263 : 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 263 : 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 731 : this->sizeSystem(state, FirstHVACIteration, AirLoopNum);
459 731 : this->m_MySizingCheckFlag = false;
460 731 : if (AirLoopNum > 0) {
461 372 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = this->m_FanOpMode;
462 372 : 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 8987089 : if (this->m_MyFanFlag) { // should include " && !this->m_MySizingCheckFlag"
473 1758 : if (this->m_ActualFanVolFlowRate != DataSizing::AutoSize) {
474 731 : if (this->m_ActualFanVolFlowRate > 0.0) {
475 731 : this->m_HeatingFanSpeedRatio = this->m_MaxHeatAirVolFlow / this->m_ActualFanVolFlowRate;
476 731 : this->m_CoolingFanSpeedRatio = this->m_MaxCoolAirVolFlow / this->m_ActualFanVolFlowRate;
477 731 : this->m_NoHeatCoolSpeedRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
478 731 : 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 731 : if (this->m_MultiOrVarSpeedHeatCoil || this->m_MultiOrVarSpeedCoolCoil) {
507 137 : if (this->m_MultiOrVarSpeedCoolCoil) {
508 137 : int NumSpeeds = this->m_NumOfSpeedCooling;
509 137 : if (this->m_MSCoolingSpeedRatio.empty()) {
510 0 : this->m_MSCoolingSpeedRatio.resize(NumSpeeds + 1);
511 : }
512 137 : if (this->m_CoolVolumeFlowRate.empty()) {
513 0 : this->m_CoolVolumeFlowRate.resize(NumSpeeds + 1);
514 : }
515 524 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
516 387 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
517 : }
518 : }
519 137 : 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 137 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
532 : }
533 : }
534 731 : this->m_MyFanFlag = false;
535 : } else {
536 1027 : if (this->m_FanExists) {
537 1027 : 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 8987089 : if (this->m_MyPlantScanFlag && !state.dataPlnt->PlantLoop.empty()) {
545 514 : 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 514 : DataPlant::PlantEquipmentType TypeOfCoilWaterCooling{DataPlant::PlantEquipmentType::Invalid};
562 514 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed ||
563 494 : 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 514 : DataPlant::PlantEquipmentType TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::Invalid;
619 514 : 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 514 : this->m_MyPlantScanFlag = false;
676 8986575 : } else if (this->m_MyPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
677 217 : this->m_MyPlantScanFlag = false;
678 : }
679 :
680 : // Scan Supplemental hot water and steam heating coil plant components for one time initializations
681 8987089 : if (this->m_MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
682 731 : 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 731 : } 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 731 : this->m_MySuppCoilPlantScanFlag = false;
745 :
746 8986358 : } else if (this->m_MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
747 0 : this->m_MySuppCoilPlantScanFlag = false;
748 : }
749 :
750 : // do the Begin Environment initializations
751 8987089 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag) {
752 4301 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
753 4301 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
754 4301 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
755 4301 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
756 4301 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
757 4301 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
758 4301 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
759 4301 : 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 4301 : this->m_CompPartLoadRatio = 0.0;
765 4301 : this->m_CoolingCoilSensDemand = 0.0;
766 4301 : this->m_CoolingCoilLatentDemand = 0.0;
767 4301 : this->m_HeatingCoilSensDemand = 0.0;
768 4301 : this->m_SenLoadLoss = 0.0;
769 4301 : if (this->m_Humidistat) {
770 153 : this->m_LatLoadLoss = 0.0;
771 : }
772 :
773 4301 : 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 4301 : 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 4301 : 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 4301 : 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 4301 : this->m_MyEnvrnFlag = false;
876 : }
877 :
878 8987089 : if (!state.dataGlobal->BeginEnvrnFlag) {
879 8947376 : this->m_MyEnvrnFlag = true;
880 : }
881 :
882 : // Init maximum available Heat Recovery flow rate
883 8987089 : 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 8987089 : if (FirstHVACIteration || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
905 3831101 : if (FirstHVACIteration) {
906 3690080 : this->m_IterationCounter = 0;
907 3690080 : 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 3690080 : 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 3690080 : 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 3831101 : 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 3831101 : 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 3831101 : 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 3831101 : 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 3831101 : 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 8987089 : this->m_IterationCounter += 1;
1042 :
1043 8987089 : if (this->m_MySetPointCheckFlag) {
1044 4617 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACGlobal->DoSetPointTest) {
1045 731 : bool e = false;
1046 731 : if (this->m_CoolCoilExists) {
1047 730 : e = this->checkNodeSetPoint(state, AirLoopNum, this->CoolCtrlNode, CoolingCoil, OAUCoilOutTemp);
1048 : }
1049 731 : if (this->m_HeatCoilExists) {
1050 442 : e = this->checkNodeSetPoint(state, AirLoopNum, this->HeatCtrlNode, HeatingCoil, OAUCoilOutTemp) || e;
1051 : }
1052 731 : if (this->m_SuppCoilExists) {
1053 227 : e = this->checkNodeSetPoint(state, AirLoopNum, this->SuppCtrlNode, SuppHeatCoil, OAUCoilOutTemp) || e;
1054 : }
1055 731 : if (e) {
1056 0 : ShowFatalError(state, "Previous errors cause termination.");
1057 : }
1058 731 : this->m_MySetPointCheckFlag = false;
1059 : }
1060 : }
1061 :
1062 8987089 : if (m_setFaultModelInput) {
1063 1751725 : if ((!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
1064 :
1065 : // check FaultsManager if connection exists
1066 726 : FaultsManager::SetFaultyCoilSATSensor(state, this->UnitType, this->Name, this->m_FaultyCoilSATFlag, this->m_FaultyCoilSATIndex);
1067 726 : 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 726 : m_setFaultModelInput = false;
1081 : }
1082 : }
1083 :
1084 : // re-set water-side economizer flags each time step
1085 8987089 : 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 8987089 : if (AirLoopNum > 0) {
1096 5532091 : 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 5456059 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1108 : }
1109 : // get OA controller info
1110 5532091 : this->OASysIndex = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).OASysNum;
1111 5532091 : if (this->OASysIndex > 0) {
1112 5277274 : this->OAControllerIndex = state.dataAirLoop->OutsideAirSys(this->OASysIndex).OAControllerIndex;
1113 5277274 : if (this->OAControllerIndex > 0) {
1114 5277274 : this->OAControllerEconomizerStagingType = state.dataMixedAir->OAController(this->OAControllerIndex).EconomizerStagingType;
1115 : }
1116 : }
1117 : }
1118 :
1119 8987089 : this->m_CoolingPartLoadFrac = 0.0;
1120 8987089 : this->m_HeatingPartLoadFrac = 0.0;
1121 8987089 : this->m_SuppHeatPartLoadFrac = 0.0;
1122 8987089 : this->m_CoolingCycRatio = 0.0;
1123 8987089 : this->m_CoolingSpeedRatio = 0.0;
1124 8987089 : this->m_CoolingSpeedNum = 0;
1125 8987089 : this->m_HeatingCycRatio = 0.0;
1126 8987089 : this->m_HeatingSpeedRatio = 0.0;
1127 8987089 : this->m_HeatingSpeedNum = 0;
1128 8987089 : this->m_SuppHeatingSpeedNum = 0;
1129 8987089 : this->m_HeatingCoilSensDemand = 0.0;
1130 8987089 : this->m_CoolingCoilSensDemand = 0.0;
1131 8987089 : this->m_CoolingCoilLatentDemand = 0.0;
1132 8987089 : this->m_DehumidInducedHeatingDemandRate = 0.0;
1133 8987089 : this->CoolCoilWaterFlowRatio = 0.0;
1134 8987089 : this->HeatCoilWaterFlowRatio = 0.0;
1135 :
1136 : // water/steam coil initialization
1137 8987089 : if (this->CoolCoilFluidInletNode > 0) {
1138 272541 : Real64 mdot = 0.0;
1139 272541 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
1140 : }
1141 8987089 : if (this->HeatCoilFluidInletNode > 0) {
1142 78594 : Real64 mdot = 0.0;
1143 78594 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
1144 : }
1145 8987089 : 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 8987089 : this->m_InitHeatPump = true;
1152 8987089 : state.dataUnitarySystems->m_massFlow1 = 0.0;
1153 8987089 : state.dataUnitarySystems->m_massFlow2 = 0.0;
1154 8987089 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
1155 8987089 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
1156 8987089 : 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 8987089 : }
1165 :
1166 1399 : 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 1399 : bool SetPointErrorFlag = false;
1182 :
1183 1399 : if (ControlNode == 0) {
1184 925 : 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 925 : return SetPointErrorFlag;
1202 : }
1203 :
1204 474 : 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 466 : 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 976 : if ((this->m_DehumidControlType_Num != DehumCtrlType::None) &&
1232 44 : (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) &&
1233 510 : 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 474 : 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 901 : void UnitarySys::getUnitarySystemInput(EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
1298 : {
1299 :
1300 901 : bool errorsFound(false);
1301 901 : UnitarySys::allocateUnitarySys(state);
1302 :
1303 901 : UnitarySys::getDXCoilSystemData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1304 901 : UnitarySys::getCoilWaterSystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1305 901 : UnitarySys::getPackagedTerminalUnitData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1306 901 : UnitarySys::getUnitarySystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1307 :
1308 901 : 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 1802 : if (int(state.dataUnitarySystems->unitarySys.size()) == state.dataUnitarySystems->numUnitarySystems &&
1314 901 : state.dataZoneEquip->ZoneEquipInputsFilled) {
1315 866 : if (state.dataUnitarySystems->setupOutputOnce) {
1316 165 : setupAllOutputVars(state, state.dataUnitarySystems->numUnitarySystems);
1317 : }
1318 : }
1319 901 : }
1320 :
1321 731 : 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 731 : 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 731 : Real64 SumOfMassFlowRateMax(0.0); // the sum of zone inlet mass flow rates
1359 : Real64 minNoLoadFlow; // used for sizing MaxNoCoolHeatVolFlow for SingleZoneVAV method
1360 731 : 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 731 : DataSizing::ZoneEqSizingData *select_EqSizing = nullptr;
1366 :
1367 731 : auto &OASysEqSizing = state.dataSize->OASysEqSizing;
1368 :
1369 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
1370 731 : if (state.dataSize->CurOASysNum > 0) {
1371 2 : select_EqSizing = &OASysEqSizing(state.dataSize->CurOASysNum);
1372 729 : } else if (state.dataSize->CurSysNum > 0) {
1373 370 : 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 370 : select_EqSizing->AirFlow = false;
1378 370 : select_EqSizing->CoolingAirFlow = false;
1379 370 : select_EqSizing->HeatingAirFlow = false;
1380 370 : select_EqSizing->AirVolFlow = 0.0;
1381 370 : select_EqSizing->CoolingAirVolFlow = 0.0;
1382 370 : select_EqSizing->HeatingAirVolFlow = 0.0;
1383 370 : select_EqSizing->Capacity = false;
1384 370 : select_EqSizing->CoolingCapacity = false;
1385 370 : select_EqSizing->HeatingCapacity = false;
1386 370 : select_EqSizing->DesCoolingLoad = 0.0;
1387 370 : select_EqSizing->DesHeatingLoad = 0.0;
1388 370 : 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 731 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
1403 :
1404 : // coil sizing requires this information to check proper flow/capacity limits (#8761)
1405 731 : if (this->m_ISHundredPercentDOASDXCoil) {
1406 6 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::DOAS; // uses 100% DX coil flow limits
1407 : } else {
1408 725 : 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 731 : state.dataSize->DataCoolCoilType = this->m_CoolingCoilType_Num;
1412 731 : state.dataSize->DataCoolCoilIndex = this->m_CoolingCoilIndex;
1413 :
1414 : bool anyEMSRan;
1415 731 : 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 1146 : if (((state.dataSize->CurOASysNum > 0 || state.dataSize->CurSysNum > 0) && state.dataSize->SysSizingRunDone) ||
1420 415 : (state.dataSize->CurZoneEqNum > 0 && state.dataSize->ZoneSizingRunDone)) {
1421 675 : HardSizeNoDesRun = false;
1422 : } else {
1423 56 : HardSizeNoDesRun = true;
1424 : }
1425 731 : std::string SizingString;
1426 731 : std::string CompName = this->Name;
1427 731 : std::string CompType = this->UnitType;
1428 731 : int CoolingSAFlowMethod = this->m_CoolingSAFMethod;
1429 731 : 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 731 : state.dataSize->UnitaryHeatCap = 0.0;
1433 731 : state.dataSize->SuppHeatCap = 0.0;
1434 731 : bool TempCoolingLoad = state.dataUnitarySystems->CoolingLoad;
1435 731 : bool TempHeatingLoad = state.dataUnitarySystems->HeatingLoad;
1436 731 : state.dataUnitarySystems->CoolingLoad = true;
1437 731 : state.dataUnitarySystems->HeatingLoad = false;
1438 731 : state.dataSize->ZoneCoolingOnlyFan = false;
1439 731 : state.dataSize->ZoneHeatingOnlyFan = false;
1440 731 : bool IsAutoSize = false;
1441 731 : Real64 SysCoolingFlow = 0.0;
1442 731 : Real64 SysHeatingFlow = 0.0;
1443 731 : Real64 CoolCapAtPeak = 0.0;
1444 731 : Real64 HeatCapAtPeak = 0.0;
1445 :
1446 731 : if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0 && this->m_FanExists) {
1447 106 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum = this->m_FanIndex;
1448 106 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanType = this->m_FanType;
1449 106 : state.dataSize->DataFanType = this->m_FanType;
1450 106 : state.dataSize->DataFanIndex = this->m_FanIndex;
1451 :
1452 106 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanPlace = this->m_FanPlace;
1453 625 : } 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 731 : 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 731 : Real64 coolingCapacityMultiplier = 1.0;
1464 731 : Real64 heatingCapacityMultiplier = 1.0;
1465 731 : 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 731 : bool SizingDesRunThisZone = false;
1478 731 : 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 731 : 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 731 : bool coolingAirFlowIsAutosized = this->m_MaxCoolAirVolFlow == DataSizing::AutoSize;
1512 731 : bool heatingAirFlowIsAutosized = this->m_MaxHeatAirVolFlow == DataSizing::AutoSize;
1513 731 : if (this->m_CoolCoilExists) {
1514 730 : if (!this->m_HeatCoilExists) {
1515 289 : state.dataSize->ZoneCoolingOnlyFan = true;
1516 : }
1517 730 : TempSize = this->m_MaxCoolAirVolFlow;
1518 730 : 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 730 : if (this->m_sysType == SysType::Unitary) {
1523 128 : state.dataSize->CurDuctType = HVAC::AirDuctType::Cooling;
1524 : }
1525 730 : bool errorsFound = false;
1526 730 : if ((CoolingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (CoolingSAFlowMethod == DataSizing::None)) {
1527 730 : CoolingAirFlowSizer sizingCoolingAirFlow;
1528 730 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1529 730 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1530 730 : } 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 730 : state.dataSize->CurDuctType = SaveCurDuctType;
1581 730 : EqSizing.CoolingAirFlow = true;
1582 730 : EqSizing.CoolingAirVolFlow = SysCoolingFlow;
1583 :
1584 : // Cooling airflow should be known at this point. Now find DataSizing::AutoSized design cooling capacity.
1585 730 : if (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity < 0.0) {
1586 578 : SizingMethod = HVAC::CoolingCapacitySizing;
1587 578 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1588 578 : TempSize = DataSizing::AutoSize;
1589 : // could probably move this up outside the IF and delete then next group below in the else
1590 578 : 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 352 : case HVAC::CoilDX_CoolingSingleSpeed:
1597 : case HVAC::CoilDX_MultiSpeedCooling:
1598 : case HVAC::CoilDX_CoolingTwoSpeed:
1599 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
1600 352 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1601 352 : state.dataSize->DataIsDXCoil = true;
1602 352 : } 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 1156 : CoolingCapacitySizer sizerCoolingCapacity;
1616 578 : sizerCoolingCapacity.overrideSizingString(SizingString);
1617 578 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1618 578 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1619 578 : 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 578 : if (this->m_HVACSizingIndex <= 0) {
1622 578 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1623 : }
1624 : // CoilSystem does not size the cooling coil (#8761)
1625 578 : if ((this->m_sysType == SysType::Unitary) || (this->m_sysType == SysType::PackagedAC) || (this->m_sysType == SysType::PackagedHP) ||
1626 384 : (this->m_sysType == SysType::PackagedWSHP)) {
1627 349 : EqSizing.CoolingCapacity = true;
1628 349 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1629 : }
1630 730 : } else if (!HardSizeNoDesRun && (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1631 : // corrected code for #8756
1632 81 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1633 5 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1634 5 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1635 76 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1636 76 : state.dataSize->DataIsDXCoil = true;
1637 : }
1638 81 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
1639 3 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1640 3 : state.dataSize->DataIsDXCoil = true;
1641 : }
1642 81 : 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 81 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) {
1649 47 : state.dataSize->DataIsDXCoil = false;
1650 : }
1651 81 : SizingMethod = HVAC::CoolingCapacitySizing;
1652 81 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1653 81 : if (this->m_CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
1654 81 : (this->m_CoolingCapMethod == DataSizing::CoolingDesignCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1655 0 : TempSize = this->m_DesignCoolingCapacity;
1656 : } else {
1657 81 : TempSize = DataSizing::AutoSize;
1658 : }
1659 81 : CoolingCapacitySizer sizerCoolingCapacity;
1660 81 : sizerCoolingCapacity.overrideSizingString(SizingString);
1661 81 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1662 81 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1663 81 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1664 81 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1665 81 : EqSizing.CoolingCapacity = true;
1666 81 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1667 81 : } 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 730 : state.dataSize->DataIsDXCoil = false;
1674 730 : state.dataSize->DataTotCapCurveIndex = 0;
1675 730 : state.dataSize->DataFlowUsedForSizing = 0.0;
1676 : }
1677 :
1678 : // STEP 2: find the DataSizing::AutoSized heating air flow rate and capacity
1679 731 : if (this->m_HeatCoilExists) {
1680 442 : if (!this->m_CoolCoilExists) {
1681 1 : state.dataSize->ZoneHeatingOnlyFan = true;
1682 : }
1683 442 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1684 442 : SizingMethod = HVAC::HeatingAirflowSizing;
1685 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1686 442 : TempSize = this->m_MaxHeatAirVolFlow;
1687 442 : SaveCurDuctType = state.dataSize->CurDuctType;
1688 442 : state.dataSize->CurDuctType = HVAC::AirDuctType::Heating;
1689 442 : if ((HeatingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (HeatingSAFlowMethod == DataSizing::None)) {
1690 442 : bool errorsFound = false;
1691 442 : HeatingAirFlowSizer sizingHeatingAirFlow;
1692 442 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1693 442 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1694 442 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1695 442 : } 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 442 : state.dataSize->CurDuctType = SaveCurDuctType;
1747 442 : EqSizing.HeatingAirFlow = true;
1748 442 : EqSizing.HeatingAirVolFlow = SysHeatingFlow;
1749 :
1750 : // Heating airflow should be known at this point. Now find DataSizing::AutoSized design heating capacity.
1751 442 : if (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
1752 412 : SizingMethod = HVAC::HeatingCapacitySizing;
1753 412 : if (m_sysType == SysType::Unitary || m_sysType == SysType::CoilCoolingDX || m_sysType == SysType::CoilCoolingWater) {
1754 97 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1755 : }
1756 412 : TempSize = DataSizing::AutoSize;
1757 412 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1758 412 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1759 47 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1760 47 : state.dataSize->DataIsDXCoil = true;
1761 : }
1762 : // should have VS coil capFT here also
1763 412 : 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 412 : if (this->m_sysType == SysType::PackagedHP) {
1770 22 : state.dataSize->DataIsDXCoil = false;
1771 : }
1772 412 : if (state.dataSize->CurSysNum > 0) {
1773 91 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1774 : false; // set to false to allow calculation of actual heating capacity
1775 : }
1776 412 : bool errorsFound = false;
1777 412 : HeatingCapacitySizer sizerHeatingCapacity;
1778 412 : sizerHeatingCapacity.overrideSizingString(SizingString);
1779 412 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1780 412 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1781 412 : if (state.dataSize->CurSysNum > 0) {
1782 91 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1783 : }
1784 412 : EqSizing.HeatingCapacity = true;
1785 412 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1786 412 : } 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 442 : state.dataSize->DataIsDXCoil = false;
1821 442 : state.dataSize->DataTotCapCurveIndex = 0;
1822 442 : state.dataSize->DataFlowUsedForSizing = 0.0;
1823 442 : if (this->m_sysType == SysType::PackagedAC) {
1824 147 : EqSizing.HeatingCapacity = false;
1825 : }
1826 : }
1827 :
1828 731 : bool isWSVarSpeedCoolCoil = this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
1829 731 : bool isWSVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
1830 731 : bool isVarSpeedCoolCoil = this->m_HeatingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed;
1831 731 : bool isVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed;
1832 :
1833 731 : Real64 saveRawHeatingCapacity = HeatCapAtPeak;
1834 :
1835 : // STEP 3A: Find VS cooling coil air flow to capacity ratio and adjust design air flow
1836 1067 : 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 731 : if ((!isWSVarSpeedHeatCoil &&
1871 727 : (((this->m_sysType == SysType::PackagedAC && !isVarSpeedCoolCoil) && (this->m_sysType == SysType::PackagedHP && !isVarSpeedHeatCoil)) ||
1872 727 : (this->m_sysType == SysType::Unitary && this->m_HeatPump))) ||
1873 695 : (this->m_sysType == SysType::Unitary &&
1874 93 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
1875 59 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
1876 58 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling))) {
1877 99 : EqSizing.CoolingAirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1878 99 : 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 731 : 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 703 : } else if (this->m_HeatPump && (state.dataSize->CurZoneEqNum == 0 || !isWSVarSpeedCoolCoil)) {
1888 190 : EqSizing.AirFlow = true;
1889 190 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1890 190 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit &&
1891 189 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1892 189 : EqSizing.Capacity = true;
1893 189 : EqSizing.DesCoolingLoad = max(EqSizing.DesCoolingLoad, EqSizing.DesHeatingLoad);
1894 189 : EqSizing.DesHeatingLoad = EqSizing.DesCoolingLoad;
1895 189 : state.dataSize->DXCoolCap = EqSizing.DesCoolingLoad;
1896 : }
1897 513 : } 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 731 : if (this->m_OKToPrintSizing) {
1908 731 : if (this->m_sysType != SysType::CoilCoolingDX && this->m_sysType != SysType::CoilCoolingWater) {
1909 459 : PrintFlag = true;
1910 : }
1911 : }
1912 : // STEP 5: report system parameters (e.g., air flow rates, capacities, etc.)
1913 731 : if (this->m_FanExists) {
1914 457 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1915 330 : PrintFlag = false;
1916 : }
1917 :
1918 457 : EqSizing.SystemAirFlow = true;
1919 457 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1920 457 : if (this->m_DesignFanVolFlowRate <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1921 392 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
1922 : }
1923 457 : state.dataSize->DataEMSOverrideON = this->m_DesignFanVolFlowRateEMSOverrideOn;
1924 457 : state.dataSize->DataEMSOverride = this->m_DesignFanVolFlowRateEMSOverrideValue;
1925 :
1926 457 : bool errorsFound = false;
1927 457 : SystemAirFlowSizer sizerSystemAirFlow;
1928 457 : std::string sizingString = "Supply Air Flow Rate [m3/s]";
1929 457 : sizerSystemAirFlow.overrideSizingString(sizingString);
1930 457 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1931 457 : this->m_DesignFanVolFlowRate = sizerSystemAirFlow.size(state, this->m_DesignFanVolFlowRate, errorsFound);
1932 :
1933 457 : state.dataSize->DataEMSOverrideON = false;
1934 457 : EqSizing.SystemAirFlow = false;
1935 :
1936 457 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1937 330 : PrintFlag = true;
1938 : }
1939 457 : }
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 731 : if (this->m_HeatCoilExists && !this->m_CoolCoilExists) {
1944 1 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
1945 0 : this->m_MaxCoolAirVolFlow = EqSizing.HeatingAirVolFlow;
1946 : }
1947 730 : } else if (this->m_CoolCoilExists && !this->m_HeatCoilExists) {
1948 289 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
1949 0 : this->m_MaxHeatAirVolFlow = EqSizing.CoolingAirVolFlow;
1950 : }
1951 289 : 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 731 : 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 401 : if (this->m_HeatCoilExists) {
2015 :
2016 112 : SizingMethod = HVAC::HeatingAirflowSizing;
2017 112 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2018 99 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
2019 : }
2020 112 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
2021 112 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2022 2 : EqSizing.AirFlow = false;
2023 : }
2024 112 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
2025 112 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
2026 112 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
2027 112 : TempSize = this->m_MaxHeatAirVolFlow;
2028 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2029 112 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
2030 112 : bool errorsFound = false;
2031 112 : HeatingAirFlowSizer sizingHeatingAirFlow;
2032 112 : sizingHeatingAirFlow.overrideSizingString(SizingString);
2033 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2034 112 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2035 112 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
2036 112 : state.dataSize->DataEMSOverrideON = false;
2037 112 : state.dataSize->DataConstantUsedForSizing = 0.0;
2038 112 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2039 2 : EqSizing.AirFlow = saveEqSizingAirFlow;
2040 : }
2041 112 : }
2042 :
2043 401 : if (this->m_CoolCoilExists) {
2044 :
2045 400 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2046 340 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
2047 : }
2048 400 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
2049 400 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
2050 400 : TempSize = this->m_MaxCoolAirVolFlow;
2051 400 : bool errorsFound = false;
2052 400 : CoolingAirFlowSizer sizingCoolingAirFlow;
2053 400 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
2054 400 : if (state.dataGlobal->isEpJSON) {
2055 3 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
2056 : }
2057 400 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
2058 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2059 400 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2060 400 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
2061 400 : state.dataSize->DataEMSOverrideON = false;
2062 400 : state.dataSize->DataConstantUsedForSizing = 0.0;
2063 400 : }
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 731 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2069 231 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2070 231 : if (this->m_ActualFanVolFlowRate > 0.0) {
2071 0 : this->m_DesignFanVolFlowRate = this->m_ActualFanVolFlowRate;
2072 : }
2073 231 : 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 731 : if (!this->m_FanExists) {
2079 274 : this->m_ActualFanVolFlowRate = this->m_DesignFanVolFlowRate;
2080 : }
2081 :
2082 731 : if (this->m_CoolCoilExists || this->m_HeatCoilExists || this->m_SuppCoilExists) {
2083 731 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2084 : // set no load air flow ratio local var
2085 731 : Real64 NoLoadCoolingAirFlowRateRatio = 1.0;
2086 731 : Real64 NoLoadHeatingAirFlowRateRatio = 1.0;
2087 731 : if (MSHPIndex > -1) {
2088 57 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling > 0) {
2089 57 : 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 33 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0]);
2095 : }
2096 : }
2097 57 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating > 0) {
2098 57 : 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 33 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0]);
2104 : }
2105 : }
2106 57 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio > 0.0) {
2107 57 : this->m_NoLoadAirFlowRateRatio = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2108 : } else {
2109 0 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2110 : }
2111 : } else {
2112 674 : if ((this->m_CoolCoilExists || this->m_HeatCoilExists) && this->m_useNoLoadLowSpeedAirFlow) {
2113 653 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2114 644 : 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 653 : } 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 635 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2140 : // RatedAirVolFlowRate(1) = high speed, RatedAirVolFlowRate2= low speed
2141 49 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1);
2142 51 : if (MaxSpeedFlowRate > 0.0 &&
2143 2 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 != DataSizing::AutoSize) {
2144 2 : NoLoadCoolingAirFlowRateRatio =
2145 2 : 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 47 : NoLoadCoolingAirFlowRateRatio = 0.5;
2148 : }
2149 586 : } 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 586 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2161 : NoLoadCoolingAirFlowRateRatio =
2162 17 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].performance->evapAirFlowFraction(state);
2163 : }
2164 653 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
2165 650 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2166 : Real64 MaxSpeedFlowRate =
2167 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2168 3 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2169 3 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) >
2170 : 0.0) { // these are the air flow at speed fields, and could be 0
2171 3 : NoLoadHeatingAirFlowRateRatio =
2172 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2173 : } else {
2174 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2175 : }
2176 653 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
2177 : // MSRatedAirVolFlowRate
2178 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex)
2179 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2180 0 : if (MaxSpeedFlowRate > 0.0 &&
2181 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2182 0 : NoLoadHeatingAirFlowRateRatio =
2183 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2184 : } else { // if any flow rates are autosized use the ratio of number of speeds
2185 0 : NoLoadHeatingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
2186 : }
2187 : }
2188 653 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2189 : }
2190 : }
2191 731 : if (this->m_NoCoolHeatSAFMethod <= DataSizing::SupplyAirFlowRate && this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
2192 0 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
2193 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2194 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
2195 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
2196 0 : minNoLoadFlow = 0.6667; // TODO: Should this have a Coil:Cooling:DX block?
2197 : } else {
2198 0 : if (this->m_NoLoadAirFlowRateRatio < 1.0) {
2199 0 : minNoLoadFlow = this->m_NoLoadAirFlowRateRatio;
2200 : } else {
2201 0 : minNoLoadFlow = 0.5;
2202 : }
2203 : }
2204 0 : if (this->m_MaxCoolAirVolFlow >= this->m_MaxHeatAirVolFlow) {
2205 0 : state.dataSize->DataFractionUsedForSizing =
2206 0 : min(minNoLoadFlow, (this->m_MaxHeatAirVolFlow / this->m_MaxCoolAirVolFlow) - 0.01);
2207 : } else {
2208 0 : state.dataSize->DataFractionUsedForSizing =
2209 0 : min(minNoLoadFlow, (this->m_MaxCoolAirVolFlow / this->m_MaxHeatAirVolFlow) - 0.01);
2210 : }
2211 : } else {
2212 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2213 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2214 : }
2215 731 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
2216 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.CoolingAirVolFlow;
2217 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2218 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2219 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2220 731 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
2221 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.HeatingAirVolFlow;
2222 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2223 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2224 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2225 731 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerCoolingCapacity) {
2226 0 : if (EqSizing.DesCoolingLoad <= 0.0) {
2227 : // water coils not sizing yet
2228 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2229 0 : WaterCoils::SimulateWaterCoilComponents(
2230 0 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2231 0 : EqSizing.DesCoolingLoad = WaterCoils::GetWaterCoilCapacity(
2232 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
2233 : }
2234 : }
2235 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesCoolingLoad;
2236 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2237 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2238 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2239 731 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerHeatingCapacity) {
2240 0 : if (EqSizing.DesHeatingLoad <= 0.0) {
2241 : // water coil not sizing yet
2242 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2243 0 : WaterCoils::SimulateWaterCoilComponents(
2244 0 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2245 0 : EqSizing.DesHeatingLoad = WaterCoils::GetWaterCoilCapacity(
2246 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
2247 : }
2248 : }
2249 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesHeatingLoad;
2250 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2251 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2252 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2253 : } else {
2254 731 : state.dataSize->DataFractionUsedForSizing = this->m_NoLoadAirFlowRateRatio;
2255 : }
2256 :
2257 731 : FieldNum = 11; // N11 , \field No Load Supply Air Flow Rate
2258 731 : state.dataSize->DataEMSOverrideON = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideOn;
2259 731 : state.dataSize->DataEMSOverride = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideValue;
2260 731 : TempSize = this->m_MaxNoCoolHeatAirVolFlow;
2261 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2262 731 : SizingString = "No Load Supply Air Flow Rate [m3/s]";
2263 731 : bool errorsFound = false;
2264 731 : SystemAirFlowSizer sizerSystemAirFlow;
2265 731 : sizerSystemAirFlow.overrideSizingString(SizingString);
2266 731 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2267 731 : this->m_MaxNoCoolHeatAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
2268 731 : state.dataSize->DataEMSOverrideON = false;
2269 731 : state.dataSize->DataConstantUsedForSizing = 0.0;
2270 731 : state.dataSize->DataFractionUsedForSizing = 0.0;
2271 731 : }
2272 :
2273 731 : if (this->m_MaxCoolAirVolFlow > 0.0) {
2274 730 : this->LowSpeedCoolFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxCoolAirVolFlow;
2275 : }
2276 731 : if (this->m_MaxHeatAirVolFlow > 0.0) {
2277 442 : this->LowSpeedHeatFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxHeatAirVolFlow;
2278 : }
2279 :
2280 731 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for use in component sizing
2281 34 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
2282 : }
2283 :
2284 731 : if (this->OAMixerExists) {
2285 300 : IsAutoSize = false;
2286 300 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
2287 110 : IsAutoSize = true;
2288 : }
2289 300 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2290 0 : if (this->m_CoolOutAirVolFlow > 0.0) {
2291 0 : BaseSizer::reportSizerOutput(state,
2292 : this->UnitType,
2293 : this->Name,
2294 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2295 : this->m_CoolOutAirVolFlow);
2296 : }
2297 : } else {
2298 300 : CheckZoneSizing(state, this->UnitType, this->Name);
2299 300 : Real64 CoolOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2300 300 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2301 3 : CoolOutAirVolFlowDes = 0.0;
2302 : }
2303 300 : if (IsAutoSize) {
2304 110 : this->m_CoolOutAirVolFlow = CoolOutAirVolFlowDes;
2305 110 : BaseSizer::reportSizerOutput(
2306 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]", CoolOutAirVolFlowDes);
2307 : } else {
2308 190 : if (this->m_CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2309 47 : Real64 CoolOutAirVolFlowUser = this->m_CoolOutAirVolFlow;
2310 47 : BaseSizer::reportSizerOutput(state,
2311 : this->UnitType,
2312 : this->Name,
2313 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2314 : CoolOutAirVolFlowDes,
2315 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2316 : CoolOutAirVolFlowUser);
2317 47 : if (state.dataGlobal->DisplayExtraWarnings) {
2318 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
2319 0 : state.dataSize->AutoVsHardSizingThreshold) {
2320 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2321 0 : ShowContinueError(
2322 : state,
2323 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
2324 0 : ShowContinueError(state,
2325 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
2326 : CoolOutAirVolFlowDes));
2327 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2328 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2329 : }
2330 : }
2331 : }
2332 : }
2333 : }
2334 :
2335 300 : IsAutoSize = false;
2336 300 : if (this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
2337 110 : IsAutoSize = true;
2338 : }
2339 300 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2340 0 : if (this->m_HeatOutAirVolFlow > 0.0) {
2341 0 : BaseSizer::reportSizerOutput(state,
2342 : this->UnitType,
2343 : this->Name,
2344 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2345 : this->m_HeatOutAirVolFlow);
2346 : }
2347 : } else {
2348 300 : CheckZoneSizing(state, this->UnitType, this->Name);
2349 300 : Real64 HeatOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2350 300 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2351 3 : HeatOutAirVolFlowDes = 0.0;
2352 : }
2353 300 : if (IsAutoSize) {
2354 110 : this->m_HeatOutAirVolFlow = HeatOutAirVolFlowDes;
2355 110 : BaseSizer::reportSizerOutput(
2356 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]", HeatOutAirVolFlowDes);
2357 : } else {
2358 190 : if (this->m_HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2359 47 : Real64 HeatOutAirVolFlowUser = this->m_HeatOutAirVolFlow;
2360 47 : BaseSizer::reportSizerOutput(state,
2361 : this->UnitType,
2362 : this->Name,
2363 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
2364 : HeatOutAirVolFlowDes,
2365 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2366 : HeatOutAirVolFlowUser);
2367 47 : if (state.dataGlobal->DisplayExtraWarnings) {
2368 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
2369 0 : state.dataSize->AutoVsHardSizingThreshold) {
2370 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2371 0 : ShowContinueError(
2372 : state,
2373 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
2374 0 : ShowContinueError(state,
2375 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
2376 : HeatOutAirVolFlowDes));
2377 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2378 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2379 : }
2380 : }
2381 : }
2382 : }
2383 : }
2384 :
2385 300 : IsAutoSize = false;
2386 300 : if (this->m_NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
2387 110 : IsAutoSize = true;
2388 : }
2389 300 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2390 0 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0) {
2391 0 : BaseSizer::reportSizerOutput(state,
2392 : this->UnitType,
2393 : this->Name,
2394 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2395 : this->m_NoCoolHeatOutAirVolFlow);
2396 : }
2397 : } else {
2398 300 : CheckZoneSizing(state, this->UnitType, this->Name);
2399 : Real64 NoCoolHeatOutAirVolFlowDes =
2400 300 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, this->m_MaxNoCoolHeatAirVolFlow);
2401 300 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2402 100 : NoCoolHeatOutAirVolFlowDes = 0.0;
2403 : }
2404 300 : if (IsAutoSize) {
2405 110 : this->m_NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
2406 110 : BaseSizer::reportSizerOutput(state,
2407 : this->UnitType,
2408 : this->Name,
2409 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2410 : NoCoolHeatOutAirVolFlowDes);
2411 : } else {
2412 190 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2413 39 : Real64 NoCoolHeatOutAirVolFlowUser = this->m_NoCoolHeatOutAirVolFlow;
2414 39 : BaseSizer::reportSizerOutput(state,
2415 : this->UnitType,
2416 : this->Name,
2417 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2418 : NoCoolHeatOutAirVolFlowDes,
2419 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2420 : NoCoolHeatOutAirVolFlowUser);
2421 39 : if (state.dataGlobal->DisplayExtraWarnings) {
2422 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
2423 0 : state.dataSize->AutoVsHardSizingThreshold) {
2424 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2425 0 : ShowContinueError(state,
2426 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2427 : NoCoolHeatOutAirVolFlowUser));
2428 0 : ShowContinueError(
2429 : state,
2430 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2431 : NoCoolHeatOutAirVolFlowDes));
2432 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2433 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2434 : }
2435 : }
2436 : }
2437 : }
2438 : }
2439 : }
2440 731 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2441 183 : PrintFlag = false;
2442 : }
2443 :
2444 731 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2445 330 : if (this->m_AirFlowControl == UseCompFlow::On) {
2446 21 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2447 21 : this->m_NoLoadAirFlowRateRatio = 1.0;
2448 : }
2449 330 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2450 324 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2451 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
2452 6 : if (this->m_AirFlowControl == UseCompFlow::On) {
2453 2 : Real64 airFlowAdjustmentRatio = 1.0;
2454 2 : if (!coolingAirFlowIsAutosized) {
2455 2 : airFlowAdjustmentRatio =
2456 2 : this->m_MaxCoolAirVolFlow /
2457 2 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2458 2 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2459 : }
2460 2 : this->m_MaxNoCoolHeatAirVolFlow =
2461 2 : airFlowAdjustmentRatio * state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1);
2462 : }
2463 : }
2464 6 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2465 3 : if (this->m_AirFlowControl == UseCompFlow::On) {
2466 1 : Real64 airFlowAdjustmentRatio = 1.0;
2467 1 : if (!heatingAirFlowIsAutosized) {
2468 1 : airFlowAdjustmentRatio =
2469 1 : this->m_MaxHeatAirVolFlow /
2470 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2471 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2472 : }
2473 1 : if (this->m_CoolCoilExists) {
2474 1 : this->m_MaxNoCoolHeatAirVolFlow =
2475 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2476 : airFlowAdjustmentRatio *
2477 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1));
2478 : } else {
2479 0 : this->m_MaxNoCoolHeatAirVolFlow =
2480 0 : airFlowAdjustmentRatio *
2481 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1);
2482 : }
2483 : }
2484 : }
2485 : }
2486 : }
2487 :
2488 : // Change the Volume Flow Rates to Mass Flow Rates
2489 731 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
2490 731 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
2491 731 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2492 731 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2493 731 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2494 731 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2495 731 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2496 :
2497 : // initialize multi-speed coils
2498 731 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) ||
2499 727 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
2500 15 : if (this->m_NumOfSpeedCooling > 0) {
2501 15 : if (this->m_CoolVolumeFlowRate.empty()) {
2502 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2503 : }
2504 15 : if (this->m_CoolMassFlowRate.empty()) {
2505 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2506 : }
2507 15 : if (this->m_MSCoolingSpeedRatio.empty()) {
2508 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2509 : }
2510 : }
2511 :
2512 15 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2513 15 : if (MSHPIndex > -1) {
2514 16 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1; --Iter) {
2515 14 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2516 14 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2517 14 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2518 : }
2519 : }
2520 : }
2521 :
2522 15 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2523 : blankString,
2524 15 : this->m_CoolingCoilIndex,
2525 : HVAC::FanOp::Invalid, // Invalid instead of off?
2526 : HVAC::CompressorOp::Off,
2527 : 0.0,
2528 : 1,
2529 : 0.0,
2530 : 0.0,
2531 : 0.0,
2532 : 0.0); // conduct the sizing operation in the VS WSHP
2533 15 : if (this->m_NumOfSpeedCooling != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds) {
2534 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2535 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2536 0 : ShowFatalError(state,
2537 0 : format("Cooling coil = {}: {}",
2538 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).VarSpeedCoilType,
2539 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).Name));
2540 : }
2541 15 : state.dataSize->DXCoolCap = VariableSpeedCoils::GetCoilCapacityVariableSpeed(
2542 15 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
2543 15 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2544 15 : if (this->m_DXHeatingCoil) {
2545 9 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2546 : }
2547 :
2548 127 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2549 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2550 112 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2551 160 : this->m_MSCoolingSpeedRatio[Iter] =
2552 80 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2553 80 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedCooling);
2554 80 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * this->m_MSCoolingSpeedRatio[Iter];
2555 80 : this->m_CoolMassFlowRate[Iter] = this->MaxCoolAirMassFlow * this->m_MSCoolingSpeedRatio[Iter];
2556 : } else {
2557 64 : this->m_CoolVolumeFlowRate[Iter] =
2558 32 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter);
2559 32 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2560 : // this is divided by the system max air flow, not the cooling coil max air flow, doesn't seem correct
2561 32 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2562 : }
2563 : }
2564 :
2565 15 : if (MSHPIndex > -1) {
2566 2 : this->m_MaxNoCoolHeatAirVolFlow =
2567 2 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2568 2 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2569 2 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2570 13 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2571 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2572 : }
2573 :
2574 716 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
2575 : // mine data from heat exchanger assisted cooling coil
2576 : // Get DX heat exchanger assisted cooling coil index
2577 3 : int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilType_Num;
2578 3 : if (childCCType_Num == HVAC::CoilDX_Cooling) {
2579 0 : int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilIndex;
2580 0 : if (childCCIndex < 0) {
2581 0 : ShowWarningError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
2582 0 : ShowFatalError(state, "No cooling coil = Coil:Cooling:DX found.");
2583 0 : ErrFound = true;
2584 : }
2585 0 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
2586 0 : this->m_NumOfSpeedCooling = newCoil.performance->numSpeeds();
2587 0 : if (this->m_NumOfSpeedCooling > 0) {
2588 0 : if (this->m_CoolVolumeFlowRate.empty()) {
2589 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2590 : }
2591 0 : if (this->m_CoolMassFlowRate.empty()) {
2592 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2593 : }
2594 0 : if (this->m_MSCoolingSpeedRatio.empty()) {
2595 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2596 : }
2597 : }
2598 :
2599 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2600 0 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2601 0 : if (MSHPIndex > -1) {
2602 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2603 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2604 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2605 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2606 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2607 : }
2608 : }
2609 : }
2610 :
2611 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2612 0 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance->numSpeeds()) {
2613 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2614 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2615 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2616 : }
2617 :
2618 : // Use discrete/continuous control algorithm regardless of number of speeds
2619 0 : if (newCoil.performance->capControlMethod == CoilCoolingDXPerformanceBase::CapControlMethod::DISCRETE) {
2620 0 : this->m_DiscreteSpeedCoolingCoil = true;
2621 0 : } else if (newCoil.performance->capControlMethod == CoilCoolingDXPerformanceBase::CapControlMethod::CONTINUOUS) {
2622 0 : this->m_ContSpeedCoolingCoil = true;
2623 : }
2624 :
2625 0 : newCoil.size(state);
2626 0 : if (MSHPIndex == -1) {
2627 0 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2628 0 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance->evapAirFlowRateAtSpeedIndex(state, Iter - 1);
2629 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2630 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2631 0 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2632 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2633 : } else {
2634 0 : this->m_MSCoolingSpeedRatio[Iter] =
2635 0 : this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2636 : }
2637 : }
2638 : }
2639 :
2640 0 : state.dataSize->DXCoolCap = newCoil.performance->ratedGrossTotalCap();
2641 0 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2642 0 : if (this->m_HeatPump) {
2643 0 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2644 : }
2645 :
2646 0 : if (MSHPIndex > -1) {
2647 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2648 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2649 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2650 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2651 : }
2652 0 : this->m_CoolVolumeFlowRate[Iter] =
2653 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2654 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2655 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2656 : }
2657 0 : this->m_MaxNoCoolHeatAirVolFlow =
2658 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2659 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2660 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2661 0 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2662 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2663 : }
2664 : }
2665 713 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2666 54 : if (this->m_NumOfSpeedCooling > 0) {
2667 54 : if (this->m_CoolVolumeFlowRate.empty()) {
2668 17 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2669 : }
2670 54 : if (this->m_CoolMassFlowRate.empty()) {
2671 17 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2672 : }
2673 54 : if (this->m_MSCoolingSpeedRatio.empty()) {
2674 17 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2675 : }
2676 : }
2677 :
2678 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2679 54 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2680 54 : if (MSHPIndex > -1) {
2681 86 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2682 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2683 66 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2684 62 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2685 62 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2686 : }
2687 : }
2688 : }
2689 :
2690 : // mine capacity from Coil:Cooling:DX object
2691 54 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
2692 : // TODO: Determine operating mode based on dehumdification stuff, using normalMode for now
2693 54 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance->numSpeeds()) {
2694 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2695 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2696 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2697 : }
2698 :
2699 : // Use discrete/continuous control algorithm regardless of number of speeds
2700 54 : if (newCoil.performance->capControlMethod == CoilCoolingDXPerformanceBase::CapControlMethod::DISCRETE) {
2701 52 : this->m_DiscreteSpeedCoolingCoil = true;
2702 2 : } else if (newCoil.performance->capControlMethod == CoilCoolingDXPerformanceBase::CapControlMethod::CONTINUOUS) {
2703 2 : this->m_ContSpeedCoolingCoil = true;
2704 : }
2705 :
2706 54 : newCoil.size(state);
2707 54 : if (MSHPIndex == -1) {
2708 : // Gotta loop backwards since we may try to access the last element when there are no fans
2709 85 : for (Iter = this->m_NumOfSpeedCooling; Iter >= 1; --Iter) {
2710 51 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance->evapAirFlowRateAtSpeedIndex(state, Iter - 1);
2711 51 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2712 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2713 51 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2714 49 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2715 : } else {
2716 2 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2717 : }
2718 : }
2719 : }
2720 :
2721 54 : state.dataSize->DXCoolCap = newCoil.performance->ratedGrossTotalCap();
2722 54 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2723 54 : if (this->m_HeatPump) {
2724 20 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2725 : }
2726 :
2727 54 : if (MSHPIndex > -1) {
2728 86 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2729 66 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2730 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2731 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2732 : }
2733 132 : this->m_CoolVolumeFlowRate[Iter] =
2734 66 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2735 66 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2736 66 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2737 : }
2738 20 : this->m_MaxNoCoolHeatAirVolFlow =
2739 20 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2740 20 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2741 20 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2742 34 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2743 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2744 : }
2745 :
2746 659 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2747 82 : if (this->m_NumOfSpeedCooling > 0) {
2748 82 : if (this->m_CoolVolumeFlowRate.empty()) {
2749 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2750 : }
2751 82 : if (this->m_CoolMassFlowRate.empty()) {
2752 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2753 : }
2754 82 : if (this->m_MSCoolingSpeedRatio.empty()) {
2755 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2756 : }
2757 : }
2758 :
2759 : // 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
2760 : // system ran prior to this one)
2761 164 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
2762 164 : EqSizing.CoolingAirVolFlow *
2763 82 : state.dataEnvrn->StdRhoAir; // doesn't matter what this value is since only coil size is needed and CompressorOn = 0 here
2764 82 : DXCoils::SimDXCoilMultiSpeed(state, blankString, 1.0, 1.0, this->m_CoolingCoilIndex, 0, HVAC::FanOp::Invalid, HVAC::CompressorOp::Off);
2765 82 : if (!HardSizeNoDesRun && EqSizing.Capacity) {
2766 : // do nothing, the vars EqSizing.DesCoolingLoad and DataSizing::DXCoolCap are already set earlier and the values could be max of the
2767 : // cooling and heating autosized values. Thus resetting them here to user specified value may not be the design size used else where
2768 : } else {
2769 154 : state.dataSize->DXCoolCap =
2770 77 : DXCoils::GetCoilCapacityByIndexType(state, this->m_CoolingCoilIndex, this->m_CoolingCoilType_Num, ErrFound);
2771 77 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2772 : }
2773 82 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2774 :
2775 82 : if (MSHPIndex > -1) {
2776 : // use reverse order since we divide by CoolVolumeFlowRate(max)
2777 102 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2778 69 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2779 7 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2780 7 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2781 : }
2782 138 : this->m_CoolVolumeFlowRate[Iter] =
2783 69 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2784 69 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2785 69 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2786 : }
2787 33 : this->m_MaxNoCoolHeatAirVolFlow =
2788 33 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2789 33 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2790 33 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2791 49 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2792 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2793 : } else {
2794 147 : for (Iter = this->m_NumOfSpeedCooling; Iter > 0; --Iter) {
2795 98 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * Iter / this->m_NumOfSpeedCooling;
2796 98 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2797 98 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2798 : }
2799 49 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2800 49 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2801 : }
2802 577 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2803 20 : if (this->m_NumOfSpeedCooling > 0) {
2804 1 : if (this->m_CoolVolumeFlowRate.empty()) {
2805 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2806 : }
2807 1 : if (this->m_CoolMassFlowRate.empty()) {
2808 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2809 : }
2810 1 : if (this->m_MSCoolingSpeedRatio.empty()) {
2811 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2812 : }
2813 : }
2814 20 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2815 :
2816 20 : if (MSHPIndex > -1) {
2817 5 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2818 4 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2819 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2820 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2821 : }
2822 8 : this->m_CoolVolumeFlowRate[Iter] =
2823 4 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2824 4 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2825 4 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2826 : }
2827 1 : this->m_MaxNoCoolHeatAirVolFlow =
2828 1 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2829 1 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2830 1 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2831 19 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2832 19 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2833 : }
2834 : }
2835 :
2836 731 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2837 718 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2838 13 : if (this->m_NumOfSpeedHeating > 0) {
2839 13 : if (this->m_HeatVolumeFlowRate.empty()) {
2840 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2841 : }
2842 13 : if (this->m_HeatMassFlowRate.empty()) {
2843 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2844 : }
2845 13 : if (this->m_MSHeatingSpeedRatio.empty()) {
2846 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2847 : }
2848 : }
2849 :
2850 13 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2851 :
2852 13 : if (MSHPIndex > -1) {
2853 : // use reverse order since we divide by HeatVolumeFlowRate(max)
2854 51 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2855 38 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2856 26 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint &&
2857 0 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2858 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage)) {
2859 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2860 : } else {
2861 26 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2862 26 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2863 : }
2864 : } else {
2865 12 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2866 12 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2867 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] < 1.0 &&
2868 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
2869 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2870 0 : ShowContinueError(
2871 0 : state, format("Design specification object = {}", state.dataUnitarySystems->designSpecMSHP[MSHPIndex].name));
2872 0 : ShowContinueError(state,
2873 : "When control type = SetPointBased the outlet air temperature must change with coil capacity, if "
2874 : "air flow also changes outlet air temperature will be relatively constant.");
2875 0 : ShowContinueError(
2876 : state,
2877 0 : format("Speed {} Supply Air Flow Ratio During Heating Operation will be set = 1.0 and the simulation continues",
2878 : Iter));
2879 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2880 : }
2881 : }
2882 : }
2883 76 : this->m_HeatVolumeFlowRate[Iter] =
2884 38 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2885 38 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2886 38 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2887 : }
2888 13 : if (this->m_CoolCoilExists) {
2889 13 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2890 13 : this->m_MaxNoCoolHeatAirVolFlow =
2891 13 : min(this->m_MaxNoCoolHeatAirVolFlow,
2892 13 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2893 13 : this->MaxNoCoolHeatAirMassFlow =
2894 13 : min(this->MaxNoCoolHeatAirMassFlow,
2895 13 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2896 13 : this->m_NoLoadAirFlowRateRatio =
2897 13 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2898 : } else {
2899 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2900 : }
2901 0 : } else if (MSHPIndex > -1) {
2902 0 : this->m_MaxNoCoolHeatAirVolFlow =
2903 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2904 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2905 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2906 : } else {
2907 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2908 : }
2909 : }
2910 718 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
2911 714 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2912 7 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2913 7 : if (MSHPIndex > -1) {
2914 11 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2915 10 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2916 10 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2917 10 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2918 : }
2919 : }
2920 : }
2921 :
2922 7 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2923 : blankString,
2924 7 : this->m_HeatingCoilIndex,
2925 : HVAC::FanOp::Invalid,
2926 : HVAC::CompressorOp::Off,
2927 : 0.0,
2928 : 1,
2929 : 0.0,
2930 : 0.0,
2931 : 0.0,
2932 : 0.0); // conduct the sizing operation in the VS WSHP
2933 :
2934 7 : if (this->m_NumOfSpeedHeating != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds) {
2935 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2936 0 : ShowContinueError(state, "Number of heating speeds does not match coil object.");
2937 0 : ShowFatalError(state,
2938 0 : format("Heating coil = {}: {}",
2939 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).VarSpeedCoilType,
2940 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).Name));
2941 : }
2942 :
2943 7 : if (this->m_NumOfSpeedHeating > 0) {
2944 7 : if (this->m_HeatVolumeFlowRate.empty()) {
2945 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2946 : }
2947 7 : if (this->m_HeatMassFlowRate.empty()) {
2948 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2949 : }
2950 7 : if (this->m_MSHeatingSpeedRatio.empty()) {
2951 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2952 : }
2953 : }
2954 :
2955 77 : for (Iter = this->m_NumOfSpeedHeating; Iter >= 1; --Iter) {
2956 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2957 70 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2958 : // SpeedRatio is only used in OnOff fan and should represent the ratio of flow to fan max flow
2959 100 : this->m_MSHeatingSpeedRatio[Iter] =
2960 50 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2961 50 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedHeating);
2962 50 : this->m_HeatVolumeFlowRate[Iter] = this->m_MaxHeatAirVolFlow * this->m_MSHeatingSpeedRatio[Iter];
2963 50 : this->m_HeatMassFlowRate[Iter] = this->MaxHeatAirMassFlow * this->m_MSHeatingSpeedRatio[Iter];
2964 : } else {
2965 40 : this->m_HeatVolumeFlowRate[Iter] =
2966 20 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter);
2967 20 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2968 20 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2969 : // this is divided by the system max air flow, not the heating coil max air flow
2970 20 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2971 : } else {
2972 : // if there is no fan this doesn't matter? Should calculate SpeedRatio in fan model? and get rid of SpeedRatio variable?
2973 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_HeatVolumeFlowRate[this->m_NumOfSpeedHeating];
2974 : }
2975 : }
2976 : }
2977 :
2978 7 : if (this->m_CoolCoilExists && this->m_NumOfSpeedHeating > 0) {
2979 14 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2980 1 : this->m_MaxNoCoolHeatAirVolFlow =
2981 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2982 1 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2983 1 : this->MaxNoCoolHeatAirMassFlow =
2984 1 : min(this->MaxNoCoolHeatAirMassFlow,
2985 1 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2986 1 : this->m_NoLoadAirFlowRateRatio =
2987 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2988 6 : } else if (this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2989 0 : this->m_MaxNoCoolHeatAirVolFlow =
2990 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2991 0 : this->MaxNoCoolHeatAirMassFlow =
2992 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2993 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2994 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2995 6 : } else if (!this->m_CoolVolumeFlowRate.empty()) {
2996 : // what the heck is this next line? should be min of min cooling and min heating flow rates?
2997 : // this is calculated above so likely not even needed here, just have to be sure it's always calculated
2998 6 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
2999 6 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
3000 3 : this->m_sysType == SysType::PackagedWSHP) {
3001 4 : if (!this->m_MultiOrVarSpeedCoolCoil && !this->m_MultiOrVarSpeedHeatCoil) {
3002 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3003 : }
3004 4 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
3005 : } else {
3006 : // this should be min of min cooling and min heating flow rates?
3007 2 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
3008 : }
3009 6 : this->m_NoLoadAirFlowRateRatio =
3010 6 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
3011 : } else {
3012 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
3013 : }
3014 0 : } else if (MSHPIndex > -1) {
3015 0 : this->m_MaxNoCoolHeatAirVolFlow =
3016 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3017 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
3018 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
3019 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3020 : } else {
3021 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
3022 : }
3023 : }
3024 731 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3025 : // pass air flow rate to zone water coil
3026 9 : if (state.dataSize->CurZoneEqNum > 0) {
3027 7 : WaterCoils::SetCoilDesFlow(state,
3028 7 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
3029 7 : this->m_HeatingCoilName,
3030 : this->m_MaxHeatAirVolFlow,
3031 7 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
3032 : }
3033 :
3034 9 : if (this->m_NumOfSpeedHeating > 0) {
3035 1 : if (this->m_HeatVolumeFlowRate.empty()) {
3036 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
3037 : }
3038 1 : if (this->m_HeatMassFlowRate.empty()) {
3039 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
3040 : }
3041 1 : if (this->m_MSHeatingSpeedRatio.empty()) {
3042 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
3043 : }
3044 : }
3045 :
3046 9 : MSHPIndex = this->m_DesignSpecMSHPIndex;
3047 9 : if (MSHPIndex > -1) {
3048 5 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
3049 4 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
3050 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
3051 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
3052 : }
3053 8 : this->m_HeatVolumeFlowRate[Iter] =
3054 4 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
3055 4 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
3056 4 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
3057 : }
3058 1 : if (this->m_CoolCoilExists) {
3059 1 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > 0) {
3060 0 : this->m_MaxNoCoolHeatAirVolFlow =
3061 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
3062 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
3063 0 : this->MaxNoCoolHeatAirMassFlow =
3064 0 : min(this->MaxNoCoolHeatAirMassFlow,
3065 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
3066 0 : this->m_NoLoadAirFlowRateRatio =
3067 0 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
3068 : } else {
3069 1 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
3070 1 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
3071 1 : this->m_NoLoadAirFlowRateRatio =
3072 1 : min(this->m_NoLoadAirFlowRateRatio, (this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate));
3073 : }
3074 : } else {
3075 0 : this->m_MaxNoCoolHeatAirVolFlow =
3076 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3077 0 : this->MaxNoCoolHeatAirMassFlow =
3078 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3079 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
3080 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3081 : }
3082 : }
3083 : }
3084 :
3085 : // Not sure if this may be needed for special cases
3086 731 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow < 0.0) {
3087 0 : if (!state.dataSize->SysSizingRunDone) {
3088 0 : int BranchNum = BranchInputManager::GetAirBranchIndex(state, "AirloopHVAC:UnitarySystem", this->Name);
3089 0 : BranchFanFlow = 0.0;
3090 0 : if (BranchNum > 0.0) {
3091 0 : std::string FanType = "";
3092 0 : std::string FanName = "";
3093 0 : BranchInputManager::GetBranchFanTypeName(state, BranchNum, FanType, FanName, ErrFound);
3094 0 : if (!ErrFound) {
3095 0 : BranchFanFlow = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
3096 : }
3097 0 : }
3098 0 : if (BranchFanFlow > 0.0) {
3099 0 : this->m_MaxCoolAirVolFlow = BranchFanFlow;
3100 : } else {
3101 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3102 0 : if (SystemFlow > 0.0) {
3103 0 : this->m_MaxCoolAirVolFlow = SystemFlow;
3104 : } else {
3105 : // what do I do?
3106 : }
3107 : }
3108 : }
3109 : }
3110 :
3111 : // why is this here?
3112 731 : this->m_SenLoadLoss = 0.0;
3113 731 : if (this->m_Humidistat) {
3114 25 : this->m_LatLoadLoss = 0.0;
3115 : }
3116 :
3117 731 : switch (this->m_sysType) {
3118 175 : case SysType::PackagedAC:
3119 : case SysType::PackagedHP:
3120 175 : PrintFlag = false;
3121 175 : break;
3122 556 : default:
3123 556 : break;
3124 : }
3125 731 : if (this->m_CoolCoilExists) {
3126 730 : SizingMethod = HVAC::CoolingCapacitySizing;
3127 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3128 730 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
3129 40 : WaterCoils::SimulateWaterCoilComponents(
3130 40 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3131 20 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3132 40 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
3133 20 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3134 20 : state.dataSize->DataFractionUsedForSizing = 1.0;
3135 20 : SizingMethod = HVAC::AutoCalculateSizing;
3136 20 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3137 710 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
3138 : std::string HXCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(
3139 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3140 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
3141 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound, true);
3142 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(
3143 0 : state, blankString, true, HVAC::CompressorOp::On, 1.0, this->m_CoolingCoilIndex, HVAC::FanOp::Cycling, false, 1.0, false);
3144 0 : state.dataSize->DataConstantUsedForSizing =
3145 0 : WaterCoils::GetWaterCoilCapacity(state, Util::makeUPPER(HVAC::cAllCoilTypes(ActualCoolCoilType)), HXCoilName, ErrFound);
3146 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3147 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3148 0 : SizingMethod = HVAC::AutoCalculateSizing;
3149 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3150 710 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3151 154 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3152 : blankString,
3153 154 : this->m_CoolingCoilIndex,
3154 : this->m_CoolingCoilSensDemand,
3155 : this->m_CoolingCoilLatentDemand,
3156 : HVAC::FanOp::Invalid,
3157 : HVAC::CompressorOp::Off,
3158 : 0.0,
3159 : FirstHVACIteration);
3160 154 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3161 154 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3162 154 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3163 154 : state.dataSize->DataFractionUsedForSizing = 1.0;
3164 154 : SizingMethod = HVAC::AutoCalculateSizing;
3165 154 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3166 154 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
3167 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3168 : }
3169 : // airflow sizing with multispeed fan
3170 308 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3171 154 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3172 154 : if (this->m_NumOfSpeedCooling > 1) {
3173 2 : int FanIndex = this->m_FanIndex;
3174 6 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
3175 4 : if (this->m_DesignSpecMSHPIndex > -1) {
3176 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] ==
3177 : DataSizing::AutoSize) {
3178 2 : this->m_CoolVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedCooling) * AirFlowRate;
3179 : } else {
3180 0 : this->m_CoolVolumeFlowRate[i] =
3181 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
3182 : }
3183 : } else {
3184 2 : this->m_CoolVolumeFlowRate[i] =
3185 2 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3186 : }
3187 4 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3188 : }
3189 : }
3190 556 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
3191 5 : WaterToAirHeatPump::SimWatertoAirHP(state,
3192 : blankString,
3193 5 : this->m_CoolingCoilIndex,
3194 : this->MaxCoolAirMassFlow,
3195 : this->m_FanOpMode,
3196 : FirstHVACIteration,
3197 5 : this->m_InitHeatPump,
3198 : 0.0,
3199 : 0.0,
3200 : HVAC::CompressorOp::Off,
3201 : 0.0);
3202 10 : state.dataSize->DataConstantUsedForSizing =
3203 5 : WaterToAirHeatPump::GetCoilCapacity(state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3204 5 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3205 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
3206 5 : SizingMethod = HVAC::AutoCalculateSizing;
3207 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
3208 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3209 5 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3210 : }
3211 551 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
3212 4 : PackagedThermalStorageCoil::SimTESCoil(
3213 4 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, 0.0);
3214 4 : PackagedThermalStorageCoil::GetTESCoilCoolingCapacity(
3215 4 : state, this->m_CoolingCoilName, state.dataSize->DataConstantUsedForSizing, ErrFound, CompType);
3216 4 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3217 4 : state.dataSize->DataFractionUsedForSizing = 1.0;
3218 4 : SizingMethod = HVAC::AutoCalculateSizing;
3219 : }
3220 :
3221 730 : TempSize = this->m_DesignCoolingCapacity;
3222 730 : state.dataSize->DataFlowUsedForSizing = this->m_MaxCoolAirVolFlow;
3223 730 : SizingString = "Nominal Cooling Capacity [W]";
3224 730 : bool errorsFound = false;
3225 730 : CoolingCapacitySizer sizerCoolingCapacity;
3226 730 : sizerCoolingCapacity.overrideSizingString(SizingString);
3227 730 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3228 730 : this->m_DesignCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
3229 730 : state.dataSize->DataConstantUsedForSizing = 0.0;
3230 730 : state.dataSize->DataFractionUsedForSizing = 0.0;
3231 730 : state.dataSize->DataFlowUsedForSizing = 0.0;
3232 730 : }
3233 :
3234 731 : if (this->m_HeatCoilExists) {
3235 442 : SizingMethod = HVAC::HeatingCapacitySizing;
3236 :
3237 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3238 442 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3239 18 : WaterCoils::SimulateWaterCoilComponents(
3240 18 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3241 9 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3242 18 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
3243 9 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3244 9 : state.dataSize->DataFractionUsedForSizing = 1.0;
3245 9 : SizingMethod = HVAC::AutoCalculateSizing;
3246 9 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3247 433 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3248 154 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3249 : blankString,
3250 154 : this->m_HeatingCoilIndex,
3251 : this->m_HeatingCoilSensDemand,
3252 : dummy,
3253 : HVAC::FanOp::Invalid, // Invalid instead of off?
3254 : HVAC::CompressorOp::Off,
3255 : 0.0,
3256 : FirstHVACIteration);
3257 154 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3258 154 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3259 154 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3260 154 : state.dataSize->DataFractionUsedForSizing = 1.0;
3261 154 : SizingMethod = HVAC::AutoCalculateSizing;
3262 154 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3263 154 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3264 : // adjusted cooling coil capacity
3265 154 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3266 : blankString,
3267 154 : this->m_CoolingCoilIndex,
3268 : this->m_CoolingCoilSensDemand,
3269 : this->m_CoolingCoilLatentDemand,
3270 : HVAC::FanOp::Invalid, // Invalid instead of off?
3271 : HVAC::CompressorOp::Off,
3272 : 0.0,
3273 : FirstHVACIteration);
3274 154 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3275 154 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3276 154 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3277 : }
3278 154 : state.dataSize->DataFractionUsedForSizing = 1.0;
3279 154 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3280 : // airflow sizing with multispeed fan
3281 308 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3282 154 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3283 154 : if (this->m_NumOfSpeedHeating > 1) {
3284 2 : int FanIndex = this->m_FanIndex;
3285 6 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
3286 4 : if (this->m_DesignSpecMSHPIndex > -1) {
3287 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] ==
3288 : DataSizing::AutoSize) {
3289 2 : this->m_HeatVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedHeating) * AirFlowRate;
3290 : } else {
3291 0 : this->m_HeatVolumeFlowRate[i] =
3292 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
3293 : }
3294 : } else {
3295 2 : this->m_HeatVolumeFlowRate[i] =
3296 2 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3297 : }
3298 4 : this->m_HeatMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3299 : }
3300 : }
3301 : }
3302 :
3303 442 : TempSize = this->m_DesignHeatingCapacity;
3304 442 : SizingString = "Nominal Heating Capacity [W]";
3305 442 : if (state.dataSize->CurSysNum > 0) {
3306 106 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
3307 : false; // set to false to allow calculation of parent object heating capacity
3308 : }
3309 442 : bool errorsFound = false;
3310 442 : HeatingCapacitySizer sizerHeatingCapacity;
3311 442 : sizerHeatingCapacity.overrideSizingString(SizingString);
3312 442 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3313 442 : TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3314 442 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3315 154 : state.dataSize->DXCoolCap = TempSize;
3316 : }
3317 442 : if (state.dataSize->CurSysNum > 0) {
3318 106 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
3319 : }
3320 442 : this->m_DesignHeatingCapacity = TempSize;
3321 442 : state.dataSize->DataConstantUsedForSizing = 0.0;
3322 442 : state.dataSize->DataFractionUsedForSizing = 0.0;
3323 442 : state.dataSize->DataHeatSizeRatio = 1.0;
3324 442 : }
3325 :
3326 731 : if (!HardSizeNoDesRun && (EqSizing.Capacity && EqSizing.DesHeatingLoad > 0.0)) {
3327 : // vars EqSizing.DesHeatingLoad is already set earlier and supplemental heating coil should
3328 : // be sized to design value instead of user specified value if HardSizeNoDesRun is false
3329 183 : state.dataSize->UnitaryHeatCap = EqSizing.DesHeatingLoad;
3330 :
3331 : } else {
3332 548 : state.dataSize->UnitaryHeatCap = this->m_DesignHeatingCapacity;
3333 : }
3334 :
3335 731 : if (this->m_sysType == SysType::PackagedWSHP) {
3336 155 : PrintFlag = true;
3337 : }
3338 :
3339 731 : if ((this->m_HeatCoilExists || this->m_SuppCoilExists) && this->m_ControlType != UnitarySysCtrlType::CCMASHRAE) {
3340 442 : TempSize = this->DesignMaxOutletTemp;
3341 442 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
3342 442 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3343 183 : PrintFlag = true;
3344 183 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
3345 183 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
3346 183 : }
3347 442 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3348 442 : this->DesignMaxOutletTemp = sizerMaxHeaterOutTemp.size(state, TempSize, ErrFound);
3349 442 : }
3350 :
3351 731 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3352 183 : PrintFlag = false;
3353 : }
3354 :
3355 731 : if (this->m_SuppCoilExists) {
3356 227 : switch (this->m_sysType) {
3357 183 : case SysType::PackagedWSHP:
3358 : case SysType::PackagedHP:
3359 183 : if (this->m_HVACSizingIndex <= 0) {
3360 183 : EqSizing.HeatingCapacity = false; // ensure PTHP supplemental heating coil sizes to load
3361 : }
3362 183 : break;
3363 44 : default:
3364 44 : break;
3365 : }
3366 :
3367 227 : TempSize = this->m_DesignSuppHeatingCapacity;
3368 227 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
3369 227 : if (TempSize == DataSizing::AutoSize) {
3370 209 : IsAutoSize = true;
3371 209 : if (this->m_sysType == SysType::Unitary) {
3372 31 : PrintFlag = false;
3373 : }
3374 209 : bool errorsFound = false;
3375 209 : HeatingCapacitySizer sizerHeatingCapacity;
3376 209 : sizerHeatingCapacity.overrideSizingString(SizingString);
3377 209 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3378 209 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3379 209 : }
3380 : // logic here isn't accurate. Replicating temporarily to minimize diffs in AutoSizingLibrary refactor
3381 227 : TempSize = this->m_DesignSuppHeatingCapacity;
3382 :
3383 227 : if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && IsAutoSize) {
3384 2 : state.dataSize->DataConstantUsedForSizing = max(this->m_DesignSuppHeatingCapacity, this->m_DesignCoolingCapacity);
3385 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3386 2 : TempSize = DataSizing::AutoSize;
3387 : // pass design size to supplemental heater
3388 2 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3389 225 : } else if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
3390 4 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3391 : } else {
3392 221 : if (state.dataSize->CurZoneEqNum > 0) {
3393 184 : state.dataSize->SuppHeatCap = saveRawHeatingCapacity;
3394 : } else {
3395 37 : state.dataSize->SuppHeatCap = this->m_DesignHeatingCapacity;
3396 : }
3397 : }
3398 :
3399 227 : if (this->m_OKToPrintSizing &&
3400 227 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3401 44 : PrintFlag = true;
3402 : }
3403 227 : state.dataSize->DataCoilIsSuppHeater = true;
3404 227 : bool errorsFound = false;
3405 227 : HeatingCapacitySizer sizerHeatingCapacity;
3406 227 : sizerHeatingCapacity.overrideSizingString(SizingString);
3407 227 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3408 227 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3409 227 : state.dataSize->DataConstantUsedForSizing = 0.0;
3410 227 : state.dataSize->DataFractionUsedForSizing = 0.0;
3411 227 : state.dataSize->DataCoilIsSuppHeater = false;
3412 : }
3413 :
3414 : // register plant flow rate. Not sure this has ever been tested.
3415 731 : if (this->m_HeatRecActive) {
3416 0 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->m_HeatRecoveryInletNodeNum, this->m_DesignHRWaterVolumeFlow);
3417 : }
3418 :
3419 : // Set flow rate for unitary system with no fan
3420 731 : if (state.dataSize->CurOASysNum == 0 && state.dataSize->CurZoneEqNum == 0 && this->m_DesignFanVolFlowRate <= 0.0) {
3421 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3422 0 : if (SystemFlow > 0.0) {
3423 0 : this->m_DesignFanVolFlowRate = SystemFlow;
3424 : } else {
3425 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3426 : }
3427 0 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
3428 : }
3429 :
3430 : // Moved from InitLoadBasedControl
3431 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
3432 731 : if (this->m_AirLoopEquipment && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
3433 100 : int NumAirLoopZones = 0; // number of zone inlet nodes in an air loop
3434 100 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
3435 100 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = true;
3436 100 : NumAirLoopZones =
3437 100 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
3438 222 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3439 : // zone inlet nodes for cooling
3440 122 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
3441 122 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
3442 : // the data structure for the zones inlet nodes has not been filled
3443 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3444 : }
3445 : }
3446 : // zone inlet nodes for heating
3447 122 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
3448 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
3449 : // the data structure for the zones inlet nodes has not been filled
3450 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3451 : }
3452 : }
3453 : }
3454 : }
3455 100 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady) {
3456 100 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
3457 222 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3458 122 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
3459 122 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3460 122 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == this->ControlZoneNum) {
3461 100 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
3462 100 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3463 : }
3464 : }
3465 100 : if (SumOfMassFlowRateMax != 0.0) {
3466 100 : if (state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
3467 100 : this->ControlZoneMassFlowFrac =
3468 100 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
3469 : } else {
3470 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3471 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
3472 0 : this->ControlZoneMassFlowFrac = 1.0;
3473 : }
3474 100 : this->m_SmallLoadTolerance = 5.0 / this->ControlZoneMassFlowFrac; // adjust 5W load tolerance by control zone fraction
3475 100 : BaseSizer::reportSizerOutput(state,
3476 : this->UnitType,
3477 : this->Name,
3478 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
3479 : this->ControlZoneMassFlowFrac);
3480 : }
3481 : }
3482 100 : } else {
3483 631 : this->ControlZoneMassFlowFrac = 1.0;
3484 : }
3485 :
3486 : // should only report for those that allow SZVAV inputs, e.g., control type == CCMASHRAE
3487 731 : PrintFlag = true;
3488 :
3489 731 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3490 0 : bool SizingDesRunThisSys = false;
3491 0 : state.dataSize->DataZoneUsedForSizing = this->ControlZoneNum;
3492 0 : CheckThisZoneForSizing(state, state.dataSize->DataZoneUsedForSizing, SizingDesRunThisSys);
3493 :
3494 0 : capacityMultiplier = 0.5; // one-half of design zone load
3495 0 : if (SizingDesRunThisSys) {
3496 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesCoolLoad * capacityMultiplier;
3497 : } else {
3498 0 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignCoolingCapacity * capacityMultiplier;
3499 : }
3500 0 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3501 0 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3502 0 : ASHRAEMinSATCoolingSizer sizerASHRAEMinSATCooling;
3503 0 : std::string stringOverride = "Minimum Supply Air Temperature [C]";
3504 0 : if (state.dataGlobal->isEpJSON) {
3505 0 : stringOverride = "minimum_supply_air_temperature [C]";
3506 : }
3507 0 : sizerASHRAEMinSATCooling.overrideSizingString(stringOverride);
3508 0 : sizerASHRAEMinSATCooling.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3509 0 : this->DesignMinOutletTemp = sizerASHRAEMinSATCooling.size(state, this->DesignMinOutletTemp, ErrFound);
3510 :
3511 0 : if (SizingDesRunThisSys) {
3512 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesHeatLoad * capacityMultiplier;
3513 : } else {
3514 0 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignHeatingCapacity * capacityMultiplier;
3515 : }
3516 0 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3517 0 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3518 0 : ASHRAEMaxSATHeatingSizer sizerASHRAEMaxSATHeating;
3519 0 : stringOverride = "Maximum Supply Air Temperature [C]";
3520 0 : if (state.dataGlobal->isEpJSON) {
3521 0 : stringOverride = "maximum_supply_air_temperature [C]";
3522 : }
3523 0 : sizerASHRAEMaxSATHeating.overrideSizingString(stringOverride);
3524 0 : sizerASHRAEMaxSATHeating.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3525 0 : this->DesignMaxOutletTemp = sizerASHRAEMaxSATHeating.size(state, this->DesignMaxOutletTemp, ErrFound);
3526 :
3527 0 : state.dataSize->DataCapacityUsedForSizing = 0.0; // reset so other routines don't use this inadvertently
3528 0 : state.dataSize->DataFlowUsedForSizing = 0.0;
3529 0 : state.dataSize->DataZoneUsedForSizing = 0;
3530 :
3531 : // check that MaxNoCoolHeatAirVolFlow is less than both MaxCoolAirVolFlow and MaxHeatAirVolFlow
3532 0 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3533 0 : if (this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxCoolAirVolFlow || this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxHeatAirVolFlow) {
3534 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3535 0 : ShowContinueError(
3536 : state,
3537 : " For SingleZoneVAV control the No Load Supply Air Flow Rate must be less than both the cooling and heating supply "
3538 : "air flow rates.");
3539 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow) - 0.01;
3540 0 : ShowContinueError(
3541 : state,
3542 0 : format(" The SingleZoneVAV control No Load Supply Air Flow Rate is reset to {:.5T} and the simulation continues.",
3543 0 : this->m_MaxNoCoolHeatAirVolFlow));
3544 : }
3545 : }
3546 0 : }
3547 :
3548 731 : state.dataUnitarySystems->CoolingLoad = TempCoolingLoad;
3549 731 : state.dataUnitarySystems->HeatingLoad = TempHeatingLoad;
3550 : // if (++NumUnitarySystemsSized == NumUnitarySystem)
3551 : // UnitarySystemNumericFields.deallocate(); // remove temporary array for field names at end of sizing
3552 731 : } // namespace UnitarySystems
3553 :
3554 1472 : void UnitarySys::processInputSpec(EnergyPlusData &state,
3555 : const UnitarySysInputSpec &input_data,
3556 : int sysNum,
3557 : bool &errorsFound,
3558 : bool const ZoneEquipment,
3559 : int const ZoneOAUnitNum)
3560 : {
3561 : static constexpr std::string_view routineName = "UnitarySys::processInputSpec";
3562 :
3563 : using namespace OutputReportPredefined;
3564 :
3565 : static constexpr std::string_view unitarySysHeatPumpPerformanceObjectType("UnitarySystemPerformance:Multispeed");
3566 :
3567 1472 : std::string const &cCurrentModuleObject = input_data.system_type;
3568 : DataLoopNode::ConnectionObjectType objType = static_cast<DataLoopNode::ConnectionObjectType>(
3569 1472 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(input_data.system_type)));
3570 1472 : std::string const &thisObjectName = input_data.name;
3571 :
3572 1472 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisObjectName};
3573 :
3574 1472 : this->Name = Util::makeUPPER(thisObjectName);
3575 1472 : sysNum = getUnitarySystemIndex(state, thisObjectName);
3576 1472 : this->m_UnitarySysNum = sysNum;
3577 :
3578 1472 : if (ZoneEquipment) {
3579 732 : this->m_IsZoneEquipment = true;
3580 : }
3581 1472 : if (state.dataUnitarySystems->getInputOnceFlag) {
3582 1472 : this->AirInNode = NodeInputManager::GetOnlySingleNode(state,
3583 736 : input_data.air_inlet_node_name,
3584 : errorsFound,
3585 : objType,
3586 : thisObjectName,
3587 : DataLoopNode::NodeFluidType::Air,
3588 : DataLoopNode::ConnectionType::Inlet,
3589 : NodeInputManager::CompFluidStream::Primary,
3590 : DataLoopNode::ObjectIsParent);
3591 : } else {
3592 736 : this->AirInNode = Util::FindItemInList(input_data.air_inlet_node_name, state.dataLoopNodes->NodeID);
3593 : }
3594 :
3595 1472 : if (state.dataUnitarySystems->getInputOnceFlag) {
3596 1472 : this->AirOutNode = NodeInputManager::GetOnlySingleNode(state,
3597 736 : input_data.air_outlet_node_name,
3598 : errorsFound,
3599 : objType,
3600 : thisObjectName,
3601 : DataLoopNode::NodeFluidType::Air,
3602 : DataLoopNode::ConnectionType::Outlet,
3603 : NodeInputManager::CompFluidStream::Primary,
3604 : DataLoopNode::ObjectIsParent);
3605 : } else {
3606 736 : this->AirOutNode = Util::FindItemInList(input_data.air_outlet_node_name, state.dataLoopNodes->NodeID);
3607 : }
3608 :
3609 : // need to read in all information needed to SetupOutputVariable in setupAllOutputVars
3610 : // as soon as all systems are read in, regardless if all information is available, reports will be set up.
3611 : // make sure we have all the information needed to process reports (see IF blocks in setupAllOutputVars).
3612 : // all coil types, which comps exist, control type, heat recovery active, cooling coil index.
3613 1472 : bool errFlag = false;
3614 1472 : bool PrintMessage = false;
3615 :
3616 1472 : if (!input_data.design_specification_multispeed_object_type.empty() && !input_data.design_specification_multispeed_object_name.empty()) {
3617 120 : this->m_DesignSpecMultispeedHPType = input_data.design_specification_multispeed_object_type;
3618 120 : this->m_DesignSpecMultispeedHPName = input_data.design_specification_multispeed_object_name;
3619 120 : DesignSpecMSHP thisDesignSpec;
3620 120 : this->m_CompPointerMSHP = thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, this->m_DesignSpecMultispeedHPName);
3621 120 : this->m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, this->m_DesignSpecMultispeedHPName);
3622 120 : }
3623 :
3624 : // these are needed for call from GetOASysNumHeat(Cool)ingCoils
3625 1472 : this->m_HeatingCoilName = input_data.heating_coil_name;
3626 1472 : this->m_HeatingCoilTypeName = input_data.heating_coil_object_type;
3627 1472 : if (!this->m_HeatingCoilTypeName.empty()) {
3628 894 : this->m_HeatCoilExists = true;
3629 : }
3630 1472 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num == 0) {
3631 447 : if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:VariableSpeed")) {
3632 3 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingAirToAirVariableSpeed;
3633 444 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:MultiSpeed")) {
3634 13 : this->m_HeatingCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
3635 431 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Water")) {
3636 9 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWater;
3637 9 : if (this->m_DesignSpecMSHPIndex > -1) {
3638 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
3639 1 : if (this->m_NumOfSpeedHeating > 1) {
3640 1 : this->m_MultiSpeedHeatingCoil = true;
3641 1 : this->m_MultiOrVarSpeedHeatCoil = true;
3642 : }
3643 : }
3644 422 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Steam")) {
3645 2 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
3646 420 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:EquationFit")) {
3647 154 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPSimple;
3648 266 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation")) {
3649 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHP;
3650 261 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3651 4 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
3652 257 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric:MultiStage")) {
3653 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingElectric_MultiStage;
3654 257 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Gas:MultiStage")) {
3655 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingGas_MultiStage;
3656 435 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Fuel") ||
3657 435 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric") ||
3658 300 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Desuperheater")) {
3659 214 : this->m_HeatingCoilType_Num =
3660 214 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
3661 43 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:UserDefined")) {
3662 0 : this->m_HeatingCoilType_Num = HVAC::Coil_UserDefined;
3663 43 : } else if (this->m_HeatCoilExists) {
3664 43 : this->m_HeatingCoilType_Num =
3665 43 : DXCoils::GetCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag, PrintMessage);
3666 : }
3667 :
3668 447 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
3669 434 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
3670 434 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
3671 13 : this->m_MultiSpeedHeatingCoil = true;
3672 434 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
3673 430 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
3674 7 : this->m_VarSpeedHeatingCoil = true;
3675 : }
3676 : }
3677 :
3678 1472 : this->m_CoolingCoilName = input_data.cooling_coil_name;
3679 1472 : if (!input_data.cooling_coil_object_type.empty()) { // not required field
3680 1470 : this->m_CoolCoilExists = true;
3681 : }
3682 : // Find the type of coil. do not print message since this may not be the correct coil type.
3683 1472 : errFlag = false;
3684 1472 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num == 0) {
3685 735 : if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:VariableSpeed")) {
3686 11 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
3687 724 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:MultiSpeed")) {
3688 38 : this->m_CoolingCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3689 686 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water")) {
3690 20 : this->m_IsDXCoil = false;
3691 20 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3692 20 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3693 20 : if (this->m_DesignSpecMSHPIndex > -1) {
3694 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3695 1 : if (this->m_NumOfSpeedCooling > 1) {
3696 1 : this->m_DiscreteSpeedCoolingCoil = true;
3697 1 : this->m_MultiOrVarSpeedCoolCoil = true;
3698 : }
3699 : }
3700 666 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water:DetailedGeometry")) {
3701 0 : this->m_IsDXCoil = false;
3702 0 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterDetailed;
3703 0 : if (this->m_DesignSpecMSHPIndex > -1) {
3704 0 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3705 0 : if (this->m_NumOfSpeedCooling > 1) {
3706 0 : this->m_DiscreteSpeedCoolingCoil = true;
3707 0 : this->m_MultiOrVarSpeedCoolCoil = true;
3708 : }
3709 : }
3710 666 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
3711 9 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
3712 657 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
3713 3 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3714 3 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3715 654 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
3716 0 : this->m_IsDXCoil = false;
3717 0 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3718 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3719 654 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:EquationFit")) {
3720 154 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPSimple;
3721 500 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation")) {
3722 5 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHP;
3723 495 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3724 4 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
3725 491 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed")) {
3726 384 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
3727 107 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoSpeed")) {
3728 49 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
3729 58 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:UserDefined")) {
3730 0 : this->m_IsDXCoil = false;
3731 0 : this->m_CoolingCoilType_Num = HVAC::Coil_UserDefined;
3732 58 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed:ThermalStorage")) {
3733 4 : this->m_CoolingCoilType_Num = HVAC::CoilDX_PackagedThermalStorageCooling;
3734 54 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX")) { // CoilCoolingDX
3735 54 : this->m_CoolingCoilType_Num = HVAC::CoilDX_Cooling;
3736 54 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
3737 54 : if (this->m_CoolingCoilIndex == -1) {
3738 0 : ShowFatalError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
3739 : } else {
3740 : // set variable speed coil flag as necessary
3741 54 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
3742 54 : this->m_NumOfSpeedCooling = newCoil.performance->numSpeeds();
3743 54 : if (this->m_NumOfSpeedCooling > 1) {
3744 37 : if (newCoil.performance->capControlMethod == CoilCoolingDXPerformanceBase::CapControlMethod::DISCRETE) {
3745 36 : this->m_DiscreteSpeedCoolingCoil = true;
3746 1 : } else if (newCoil.performance->capControlMethod == CoilCoolingDXPerformanceBase::CapControlMethod::CONTINUOUS) {
3747 1 : this->m_ContSpeedCoolingCoil = true;
3748 : }
3749 37 : this->m_MultiOrVarSpeedCoolCoil = true;
3750 : }
3751 : }
3752 : }
3753 :
3754 735 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
3755 38 : this->m_DiscreteSpeedCoolingCoil = true;
3756 697 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
3757 693 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
3758 15 : this->m_ContSpeedCoolingCoil = true;
3759 : }
3760 : }
3761 :
3762 1472 : if (!input_data.supplemental_heating_coil_object_type.empty()) {
3763 454 : this->m_SuppCoilExists = true;
3764 : }
3765 :
3766 1472 : if (!input_data.supply_fan_object_type.empty() && !input_data.supply_fan_name.empty()) {
3767 924 : this->m_FanExists = true;
3768 : }
3769 :
3770 : constexpr static std::array<std::string_view, static_cast<int>(UnitarySysCtrlType::Num)> UnitarySysCtrlTypeNamesUC = {
3771 : "NONE", "LOAD", "SETPOINT", "SINGLEZONEVAV"};
3772 1472 : this->m_ControlType = static_cast<UnitarySysCtrlType>(getEnumValue(UnitarySysCtrlTypeNamesUC, Util::makeUPPER(input_data.control_type)));
3773 1472 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3774 0 : this->m_ValidASHRAECoolCoil = true;
3775 0 : this->m_ValidASHRAEHeatCoil = true;
3776 : }
3777 :
3778 1472 : this->m_DesignHRWaterVolumeFlow = input_data.design_heat_recovery_water_flow_rate;
3779 1472 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
3780 0 : this->m_HeatRecActive = true;
3781 : }
3782 :
3783 1472 : errFlag = false;
3784 1472 : if (!input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) {
3785 600 : this->OAMixerIndex = MixedAir::GetOAMixerIndex(state, input_data.oa_mixer_name);
3786 600 : ValidateComponent(state, input_data.oa_mixer_type, input_data.oa_mixer_name, errFlag, cCurrentModuleObject);
3787 600 : if (errFlag) {
3788 0 : ShowContinueError(state, format("specified in {} = \"{}\".", cCurrentModuleObject, input_data.oa_mixer_name));
3789 0 : errorsFound = true;
3790 0 : errFlag = false;
3791 : } else {
3792 600 : this->OAMixerExists = true;
3793 : // OANodeNums = outside air mixer node numbers, OANodeNums(4) = outside air mixer mixed air node
3794 600 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, input_data.oa_mixer_name, errFlag);
3795 600 : if (errFlag) {
3796 0 : ShowContinueError(state, format("that was specified in {} = {}", cCurrentModuleObject, input_data.oa_mixer_name));
3797 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
3798 0 : errorsFound = true;
3799 0 : errFlag = false;
3800 : } else {
3801 600 : this->m_OAMixerNodes[0] = OANodeNums(1); // inlet
3802 600 : this->m_OAMixerNodes[1] = OANodeNums(2); // relief
3803 600 : this->m_OAMixerNodes[2] = OANodeNums(3); // return
3804 600 : this->m_OAMixerNodes[3] = OANodeNums(4); // mixed
3805 : }
3806 600 : }
3807 1744 : } else if ((input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) ||
3808 872 : (!input_data.oa_mixer_type.empty() && input_data.oa_mixer_name.empty())) {
3809 0 : ShowSevereError(state, format("Missing one of {} Outdoor Air Mixer inputs.", cCurrentModuleObject));
3810 0 : ShowContinueError(state, format("..OutdoorAir:Mixer type = {}", input_data.oa_mixer_type));
3811 0 : ShowContinueError(state, format("..OutdoorAir:Mixer name = {}", input_data.oa_mixer_name));
3812 0 : errorsFound = true;
3813 : }
3814 1472 : this->m_HeatConvTol = input_data.heat_conv_tol;
3815 1472 : this->m_CoolConvTol = input_data.cool_conv_tol;
3816 :
3817 : // Early calls to ATMixer don't have enough info to pass GetInput. Need to get the data next time through.
3818 1472 : if (sysNum == -1 || !state.dataZoneEquip->ZoneEquipInputsFilled) {
3819 736 : return;
3820 : }
3821 :
3822 736 : this->m_CoolOutAirVolFlow = input_data.cooling_oa_flow_rate;
3823 736 : this->m_HeatOutAirVolFlow = input_data.heating_oa_flow_rate;
3824 736 : this->m_NoCoolHeatOutAirVolFlow = input_data.no_load_oa_flow_rate;
3825 :
3826 736 : if (ZoneEquipment) {
3827 351 : this->m_OKToPrintSizing = true;
3828 : }
3829 :
3830 736 : this->m_IterationMode.resize(3);
3831 :
3832 736 : std::string loc_m_CoolingSAFMethod = input_data.cooling_supply_air_flow_rate_method;
3833 736 : Real64 loc_m_CoolingSAFMethod_SAFlow = input_data.cooling_supply_air_flow_rate;
3834 736 : Real64 loc_m_CoolingSAFMethod_SAFlowPerFloorArea = input_data.cooling_supply_air_flow_rate_per_floor_area;
3835 736 : Real64 loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.cooling_fraction_of_autosized_cooling_supply_air_flow_rate;
3836 736 : Real64 loc_m_CoolingSAFMethod_FlowPerCoolingCapacity = input_data.cooling_supply_air_flow_rate_per_unit_of_capacity;
3837 736 : std::string loc_m_HeatingSAFMethod = input_data.heating_supply_air_flow_rate_method;
3838 736 : Real64 loc_m_HeatingSAFMethod_SAFlow = input_data.heating_supply_air_flow_rate;
3839 736 : Real64 loc_m_HeatingSAFMethod_SAFlowPerFloorArea = input_data.heating_supply_air_flow_rate_per_floor_area;
3840 736 : Real64 loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.heating_fraction_of_autosized_heating_supply_air_flow_rate;
3841 736 : Real64 loc_m_HeatingSAFMethod_FlowPerHeatingCapacity = input_data.heating_supply_air_flow_rate_per_unit_of_capacity;
3842 736 : std::string loc_m_NoCoolHeatSAFMethod = input_data.no_load_supply_air_flow_rate_method;
3843 736 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlow = input_data.no_load_supply_air_flow_rate;
3844 736 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = input_data.no_load_supply_air_flow_rate_per_floor_area;
3845 736 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.no_load_fraction_of_autosized_cooling_supply_air_flow_rate;
3846 736 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.no_load_fraction_of_autosized_heating_supply_air_flow_rate;
3847 736 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity =
3848 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation;
3849 736 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity =
3850 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation;
3851 :
3852 736 : int FanInletNode = 0;
3853 736 : int FanOutletNode = 0;
3854 736 : Real64 FanVolFlowRate = 0.0;
3855 736 : int CoolingCoilInletNode = 0;
3856 736 : int CoolingCoilOutletNode = 0;
3857 736 : int HeatingCoilInletNode = 0;
3858 736 : int HeatingCoilOutletNode = 0;
3859 736 : int SupHeatCoilInletNode = 0;
3860 736 : int SupHeatCoilOutletNode = 0;
3861 :
3862 736 : bool isNotOK = false;
3863 :
3864 736 : if (input_data.availability_schedule_name.empty()) {
3865 86 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3866 650 : } else if ((this->m_sysAvailSched = Sched::GetSchedule(state, input_data.availability_schedule_name)) == nullptr) {
3867 0 : ShowWarningItemNotFound(state,
3868 : eoh,
3869 : "Availability Schedule Name",
3870 : input_data.availability_schedule_name,
3871 : "Set the default as Always On. Simulation continues.");
3872 0 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3873 : }
3874 :
3875 736 : if (!input_data.controlling_zone_or_thermostat_location.empty()) { // not required field
3876 126 : this->ControlZoneNum = Util::FindItemInList(input_data.controlling_zone_or_thermostat_location, state.dataHeatBal->Zone);
3877 610 : } else if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3878 330 : if (this->m_sysType == SysType::Unitary) {
3879 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3880 0 : ShowContinueError(state, "Controlling Zone or Thermostat Location cannot be blank when Control Type = Load or SingleZoneVAV");
3881 0 : errorsFound = true;
3882 : }
3883 : }
3884 :
3885 : // check that control zone name is valid for load based control
3886 736 : if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3887 : // bypass this error for PTUnits
3888 456 : if (this->ControlZoneNum == 0 &&
3889 330 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3890 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3891 0 : ShowContinueError(state, "When Control Type = Load or SingleZoneVAV");
3892 0 : ShowContinueError(state,
3893 0 : format(" Controlling Zone or Thermostat Location must be a valid zone name, zone name = {}",
3894 0 : input_data.controlling_zone_or_thermostat_location));
3895 0 : errorsFound = true;
3896 : }
3897 : }
3898 :
3899 736 : if (Util::SameString(input_data.dehumidification_control_type, "None")) {
3900 712 : this->m_DehumidControlType_Num = DehumCtrlType::None;
3901 712 : this->m_Humidistat = false;
3902 24 : } else if (Util::SameString(input_data.dehumidification_control_type, "CoolReheat")) {
3903 13 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
3904 13 : this->m_Humidistat = true;
3905 11 : } else if (Util::SameString(input_data.dehumidification_control_type, "Multimode")) {
3906 11 : this->m_DehumidControlType_Num = DehumCtrlType::Multimode;
3907 11 : this->m_Humidistat = true;
3908 : }
3909 736 : if (this->m_Humidistat && this->m_ControlType == UnitarySysCtrlType::Load) {
3910 9 : bool AirNodeFound = false;
3911 42 : for (int HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
3912 33 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != this->ControlZoneNum) {
3913 24 : continue;
3914 : }
3915 9 : AirNodeFound = true;
3916 : }
3917 9 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3918 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3919 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
3920 0 : ShowContinueError(
3921 0 : state, format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3922 0 : errorsFound = true;
3923 : }
3924 : }
3925 :
3926 736 : Real64 TotalFloorAreaOnAirLoop = 0.0;
3927 736 : int AirLoopNumber = 0;
3928 736 : bool AirNodeFound = false;
3929 736 : bool AirLoopFound = false;
3930 736 : bool OASysFound = false;
3931 736 : bool ZoneEquipmentFound = false;
3932 736 : bool ZoneInletNodeFound = false;
3933 :
3934 : // Get AirTerminal mixer data
3935 736 : SingleDuct::GetATMixer(state,
3936 : thisObjectName,
3937 736 : this->m_ATMixerName,
3938 736 : this->m_ATMixerIndex,
3939 736 : this->ATMixerType,
3940 736 : this->m_ATMixerPriNode,
3941 736 : this->m_ATMixerSecNode,
3942 736 : this->ATMixerOutNode,
3943 : this->AirOutNode);
3944 736 : if (this->ATMixerType == HVAC::MixerType::InletSide || this->ATMixerType == HVAC::MixerType::SupplySide) {
3945 34 : this->ATMixerExists = true;
3946 : }
3947 : // check that heat pump doesn't have local outside air and DOA
3948 736 : if (this->ATMixerExists && this->m_OAMixerNodes[0] > 0 &&
3949 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)) {
3950 0 : ShowSevereError(state,
3951 0 : format("{} = \"{}\". System has local as well as central outdoor air specified", cCurrentModuleObject, this->Name));
3952 0 : errorsFound = true;
3953 : }
3954 :
3955 : // if part of ZoneHVAC:OutdoorAirUnit bypass most checks for connection to air loop or OASystem
3956 736 : if (ZoneOAUnitNum > 0) {
3957 8 : OASysFound = true;
3958 : }
3959 :
3960 736 : if (ZoneEquipment) {
3961 351 : int ControlledZoneNum = 0;
3962 351 : int ZoneExhNum = 0;
3963 351 : bool ZoneExhaustNodeFound = false;
3964 351 : bool InducedNodeFound = false;
3965 :
3966 351 : if (!this->ATMixerExists) {
3967 317 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3968 317 : if (ZoneExhaustNodeFound) {
3969 316 : ZoneEquipmentFound = true;
3970 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3971 : // this should be zoneExhaustNode
3972 316 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum);
3973 316 : this->ControlZoneNum = ControlledZoneNum;
3974 316 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3975 316 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3976 : } else { // find if the inlet node is an induced node from zone plenum
3977 1 : int ZoneInletNum = 0;
3978 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3979 1 : if (ZoneInletNodeFound) {
3980 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3981 : this->AirInNode,
3982 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3983 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3984 1 : if (InducedNodeFound) {
3985 1 : this->m_ZoneInletNode = this->AirOutNode;
3986 1 : ZoneEquipmentFound = true;
3987 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3988 : }
3989 : }
3990 : }
3991 34 : } else if (this->ATMixerType == HVAC::MixerType::InletSide) {
3992 21 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->m_ATMixerSecNode, ControlledZoneNum, ZoneExhNum);
3993 21 : if (ZoneExhaustNodeFound) {
3994 20 : ZoneEquipmentFound = true;
3995 20 : this->m_ZoneInletNode = this->AirOutNode;
3996 20 : this->ControlZoneNum = ControlledZoneNum;
3997 20 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3998 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3999 20 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
4000 : } else {
4001 1 : int ZoneInletNum = 0;
4002 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
4003 1 : if (ZoneInletNodeFound) {
4004 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
4005 : this->m_ATMixerSecNode,
4006 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
4007 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
4008 1 : if (InducedNodeFound) {
4009 1 : this->m_ZoneInletNode = this->AirOutNode;
4010 1 : ZoneEquipmentFound = true;
4011 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4012 : }
4013 : }
4014 : }
4015 13 : } else if (this->ATMixerType == HVAC::MixerType::SupplySide) {
4016 13 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
4017 13 : if (ZoneExhaustNodeFound) {
4018 12 : ZoneEquipmentFound = true;
4019 12 : this->m_ZoneInletNode = this->ATMixerOutNode;
4020 12 : this->ControlZoneNum = ControlledZoneNum;
4021 12 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4022 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
4023 12 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->ATMixerOutNode, this->ControlZoneNum);
4024 : } else {
4025 1 : int ZoneInletNum = 0;
4026 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->ATMixerOutNode, this->ControlZoneNum, ZoneInletNum);
4027 1 : if (ZoneInletNodeFound) {
4028 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
4029 : this->AirInNode,
4030 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
4031 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
4032 1 : if (InducedNodeFound) {
4033 1 : this->m_ZoneInletNode = this->ATMixerOutNode;
4034 1 : ZoneEquipmentFound = true;
4035 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4036 : }
4037 : }
4038 : }
4039 : }
4040 351 : if (!ZoneExhaustNodeFound && !InducedNodeFound) {
4041 : // Exhaust Node was not found
4042 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4043 0 : ShowContinueError(state,
4044 0 : format("Incorrect or misspelled Air Inlet Node Name or Exhaust Node Name or Induced Node Name. = {}",
4045 0 : input_data.air_inlet_node_name));
4046 0 : ShowContinueError(
4047 : state,
4048 0 : format("Air Inlet Node {} name does not match any controlled zone exhaust node name. Check ZoneHVAC:EquipmentConnections "
4049 : "object inputs.",
4050 0 : input_data.air_inlet_node_name));
4051 0 : ShowContinueError(state, "or Induced Air Outlet Node Name specified in AirLoopHVAC:ReturnPlenum object.");
4052 0 : errorsFound = true;
4053 351 : } else if (!ZoneInletNodeFound) {
4054 0 : bool ZoneInletNodeExists = false;
4055 0 : int InletControlledZoneNum = 0;
4056 0 : int ZoneInletNum = 0;
4057 0 : ZoneInletNodeExists = searchZoneInletNodes(state, this->AirOutNode, InletControlledZoneNum, ZoneInletNum);
4058 0 : if (!ZoneInletNodeExists) {
4059 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4060 0 : ShowContinueError(state, format("Incorrect or misspelled Air Outlet Node Name = {}", input_data.air_outlet_node_name));
4061 0 : ShowContinueError(state,
4062 : "Node name does not match any controlled zone inlet node name. Check ZoneHVAC:EquipmentConnections "
4063 : "object inputs.");
4064 0 : errorsFound = true;
4065 : }
4066 : }
4067 : } else {
4068 : // check if the UnitarySystem is connected to an air loop
4069 :
4070 : int compIndex;
4071 : int branchIndex;
4072 385 : AirLoopFound = searchTotalComponents(state, this->AirloopEqType, thisObjectName, compIndex, branchIndex, AirLoopNumber);
4073 385 : if (AirLoopFound && (this->ControlZoneNum > 0)) {
4074 : // Find the controlled zone number for the specified thermostat location
4075 105 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
4076 :
4077 : // Determine if system is on air loop served by the thermostat location specified
4078 105 : int ZoneInletNum = 0;
4079 105 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
4080 105 : if (ZoneInletNodeFound) {
4081 105 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
4082 105 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
4083 : }
4084 :
4085 1071 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4086 966 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4087 861 : continue;
4088 : }
4089 105 : AirNodeFound = true;
4090 : }
4091 105 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4092 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4093 0 : continue;
4094 : }
4095 0 : AirNodeFound = true;
4096 : }
4097 105 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4098 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4099 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4100 0 : ShowContinueError(
4101 : state,
4102 0 : format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
4103 0 : errorsFound = true;
4104 : }
4105 :
4106 105 : if (this->ControlZoneNum > 0) {
4107 : // Find the controlled zone number for the specified thermostat location
4108 105 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
4109 :
4110 : // Determine if system is on air loop served by the thermostat location specified
4111 105 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
4112 105 : if (ZoneInletNodeFound) {
4113 105 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
4114 105 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
4115 : }
4116 :
4117 : // if (this->m_ZoneInletNode == 0) AirLoopFound = false;
4118 1071 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4119 966 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4120 861 : continue;
4121 : }
4122 105 : AirNodeFound = true;
4123 : }
4124 105 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4125 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4126 0 : continue;
4127 : }
4128 0 : AirNodeFound = true;
4129 : }
4130 105 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4131 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4132 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4133 0 : ShowContinueError(state,
4134 0 : format("specified Controlling Zone or Thermostat Location name = {}",
4135 0 : input_data.controlling_zone_or_thermostat_location));
4136 0 : errorsFound = true;
4137 : }
4138 : }
4139 : }
4140 :
4141 : // check if the UnitarySystem is connected to an outside air system
4142 385 : if (!AirLoopFound && state.dataAirLoop->NumOASystems > 0) {
4143 4 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
4144 2 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
4145 4 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum), thisObjectName) ||
4146 2 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject)) {
4147 0 : continue;
4148 : }
4149 2 : AirLoopNumber = OASysNum;
4150 2 : OASysFound = true;
4151 2 : break;
4152 : }
4153 : }
4154 : }
4155 : }
4156 :
4157 736 : if (AirLoopNumber == 0 && !ZoneEquipmentFound &&
4158 8 : (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE)) {
4159 0 : std::string_view zoneName = input_data.controlling_zone_or_thermostat_location;
4160 0 : if (zoneName.empty() && this->ControlZoneNum > 0) {
4161 0 : zoneName = state.dataHeatBal->Zone(this->ControlZoneNum).Name;
4162 : }
4163 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4164 0 : ShowContinueError(state, "Did not find proper connections for AirLoopHVAC or ZoneHVAC system.");
4165 0 : ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}", zoneName));
4166 0 : if (!AirNodeFound && !ZoneEquipmentFound) {
4167 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4168 0 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
4169 : // ShowContinueError(state, format("specified {} = {}", cAlphaFields(iControlZoneAlphaNum), Alphas(iControlZoneAlphaNum)));
4170 0 : ShowContinueError(state,
4171 : "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
4172 : }
4173 0 : errorsFound = true;
4174 : }
4175 :
4176 736 : if (!AirLoopFound && !ZoneEquipmentFound && !OASysFound) {
4177 : // Unsuccessful attempt to get all input data.
4178 0 : return;
4179 736 : } else if (ZoneEquipmentFound || OASysFound ||
4180 375 : (AirLoopFound && (this->m_ZoneInletNode > 0 || this->m_ControlType == UnitarySysCtrlType::Setpoint))) {
4181 736 : this->m_OKToPrintSizing = true;
4182 736 : this->m_ThisSysInputShouldBeGotten = false;
4183 : }
4184 :
4185 736 : this->m_AvailManagerListName = input_data.avail_manager_list_name;
4186 :
4187 736 : if (!input_data.design_spec_zonehvac_sizing_object_name.empty()) {
4188 0 : this->m_HVACSizingIndex = Util::FindItemInList(input_data.design_spec_zonehvac_sizing_object_name, state.dataSize->ZoneHVACSizing);
4189 0 : if (this->m_HVACSizingIndex == 0) {
4190 0 : ShowSevereError(
4191 : state,
4192 0 : format("Design Specification ZoneHVAC Sizing Object Name = {} not found.", input_data.design_spec_zonehvac_sizing_object_name));
4193 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, this->Name));
4194 0 : errorsFound = true;
4195 : }
4196 : }
4197 :
4198 736 : if (!ZoneEquipment) {
4199 1155 : BranchNodeConnections::TestCompSet(state,
4200 : cCurrentModuleObject,
4201 770 : Util::makeUPPER(thisObjectName),
4202 385 : input_data.air_inlet_node_name,
4203 385 : input_data.air_outlet_node_name,
4204 : "Air Nodes");
4205 : }
4206 :
4207 736 : std::string const &loc_fanType = input_data.supply_fan_object_type;
4208 736 : std::string const &loc_m_FanName = input_data.supply_fan_name;
4209 :
4210 736 : if (!loc_m_FanName.empty() && !loc_fanType.empty()) {
4211 462 : this->m_FanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(loc_fanType)));
4212 :
4213 462 : this->m_FanIndex = Fans::GetFanIndex(state, loc_m_FanName);
4214 462 : if (this->m_FanIndex == 0) {
4215 0 : ShowSevereItemNotFound(state, eoh, "fan_name", loc_m_FanName);
4216 0 : errorsFound = true;
4217 : } else {
4218 462 : auto const *fan = state.dataFans->fans(this->m_FanIndex);
4219 462 : FanVolFlowRate = fan->maxAirFlowRate;
4220 462 : if (FanVolFlowRate == DataSizing::AutoSize) {
4221 397 : this->m_RequestAutoSize = true;
4222 : }
4223 462 : this->m_ActualFanVolFlowRate = FanVolFlowRate;
4224 462 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
4225 462 : FanInletNode = fan->inletNodeNum;
4226 462 : FanOutletNode = fan->outletNodeNum;
4227 462 : this->m_fanAvailSched = fan->availSched;
4228 : }
4229 :
4230 462 : this->m_FanExists = true;
4231 462 : this->m_FanName = loc_m_FanName;
4232 274 : } else if (!loc_m_FanName.empty() || !loc_fanType.empty()) {
4233 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4234 0 : ShowContinueError(state, format("Invalid Fan Type or Name: Fan Name = {}, Fan Type = {}", loc_m_FanName, loc_fanType));
4235 0 : errorsFound = true;
4236 : }
4237 :
4238 : // Add fan to component sets array
4239 736 : if (this->m_FanExists && this->m_FanCompNotSetYet) {
4240 924 : BranchNodeConnections::SetUpCompSets(state,
4241 : cCurrentModuleObject,
4242 : thisObjectName,
4243 : loc_fanType,
4244 : loc_m_FanName,
4245 462 : state.dataLoopNodes->NodeID(FanInletNode),
4246 462 : state.dataLoopNodes->NodeID(FanOutletNode));
4247 462 : this->m_FanCompNotSetYet = false;
4248 : }
4249 :
4250 736 : this->m_FanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Util::makeUPPER(input_data.fan_placement)));
4251 736 : if (this->m_FanPlace == HVAC::FanPlace::Invalid && this->m_FanExists) {
4252 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4253 0 : ShowContinueError(state, format("Illegal Fan Placement = {}", input_data.fan_placement));
4254 0 : errorsFound = true;
4255 : }
4256 :
4257 736 : if (input_data.supply_air_fan_operating_mode_schedule_name.empty()) {
4258 280 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4259 : // Fan operating mode must be constant fan so that the coil outlet temp is proportional to PLR
4260 : // Cycling fan always outputs the full load outlet air temp so should not be used with set point based control
4261 279 : this->m_FanOpMode = HVAC::FanOp::Continuous;
4262 : } else {
4263 1 : this->m_FanOpMode = HVAC::FanOp::Cycling;
4264 1 : if (this->m_FanType != HVAC::FanType::OnOff && this->m_FanType != HVAC::FanType::SystemModel && this->m_FanExists) {
4265 0 : ShowSevereEmptyField(state,
4266 : eoh,
4267 : "Fan Operating Mode Schedule Name",
4268 : "Fan type must be Fan:OnOff or Fan:SystemModel when Supply Air Fan Operating Mode Schedule Name is blank.");
4269 0 : errorsFound = true;
4270 : }
4271 : }
4272 456 : } else if ((this->m_fanOpModeSched = Sched::GetSchedule(state, input_data.supply_air_fan_operating_mode_schedule_name)) == nullptr) {
4273 0 : ShowSevereItemNotFound(state, eoh, "Fan Operating Mode Schedule Name", input_data.supply_air_fan_operating_mode_schedule_name);
4274 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iFanSchedAlphaNum), Alphas(iFanSchedAlphaNum)));
4275 0 : errorsFound = true;
4276 460 : } else if ((this->m_ControlType == UnitarySysCtrlType::Setpoint || this->m_FanType == HVAC::FanType::Constant) &&
4277 4 : !this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
4278 0 : Sched::ShowSevereBadMinMax(state,
4279 : eoh,
4280 : "Supply Air Fan Operating Mode Schedule Name",
4281 : input_data.supply_air_fan_operating_mode_schedule_name,
4282 : Clusive::Ex,
4283 : 0.0,
4284 : Clusive::In,
4285 : 1.0);
4286 0 : errorsFound = true;
4287 : }
4288 :
4289 736 : PrintMessage = true;
4290 : // Get coil data
4291 736 : this->m_HeatingSizingRatio = input_data.dx_heating_coil_sizing_ratio;
4292 736 : int HeatingCoilPLFCurveIndex = 0;
4293 736 : if (!this->m_HeatingCoilTypeName.empty()) {
4294 447 : PrintMessage = false;
4295 : } else {
4296 289 : this->m_ValidASHRAEHeatCoil = false;
4297 : }
4298 :
4299 736 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4300 :
4301 43 : this->m_DXHeatingCoil = true;
4302 :
4303 43 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4304 43 : if (isNotOK) {
4305 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4306 0 : errorsFound = true;
4307 :
4308 : } else { // mine data from DX heating coil
4309 :
4310 : // Get DX heating coil index
4311 43 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4312 43 : if (errFlag) {
4313 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4314 0 : errorsFound = true;
4315 0 : errFlag = false;
4316 : } else {
4317 43 : auto &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4318 43 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4319 43 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedTotCap(1);
4320 43 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4321 37 : this->m_RequestAutoSize = true;
4322 : }
4323 43 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate(1);
4324 43 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4325 37 : this->m_RequestAutoSize = true;
4326 : }
4327 43 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4328 43 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4329 43 : thisHeatCoil.HeatSizeRatio = this->m_HeatingSizingRatio;
4330 : }
4331 : }
4332 :
4333 693 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4334 690 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
4335 :
4336 7 : this->m_DXHeatingCoil = true;
4337 :
4338 7 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4339 7 : if (isNotOK) {
4340 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4341 0 : errorsFound = true;
4342 : } else {
4343 7 : this->m_HeatingCoilIndex =
4344 7 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4345 7 : if (errFlag) {
4346 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4347 0 : errorsFound = true;
4348 0 : errFlag = false;
4349 : } else {
4350 7 : auto const &thisHeatCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex);
4351 7 : this->m_NumOfSpeedHeating = thisHeatCoil.NumOfSpeeds;
4352 7 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4353 7 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4354 7 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4355 5 : this->m_RequestAutoSize = true;
4356 : } else {
4357 2 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NumOfSpeeds) /
4358 2 : thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NormSpedLevel) * thisHeatCoil.RatedAirVolFlowRate;
4359 : }
4360 7 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4361 7 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4362 7 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4363 7 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4364 5 : this->m_RequestAutoSize = true;
4365 : }
4366 : }
4367 : }
4368 693 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
4369 13 : this->m_DXHeatingCoil = true;
4370 13 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4371 13 : if (isNotOK) {
4372 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4373 0 : errorsFound = true;
4374 : } else {
4375 13 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, this->m_HeatingCoilTypeName);
4376 13 : if (errFlag) {
4377 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4378 0 : errorsFound = true;
4379 0 : errFlag = false;
4380 : } else {
4381 13 : auto const &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4382 13 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4383 13 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(1);
4384 13 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4385 8 : this->m_RequestAutoSize = true;
4386 : }
4387 13 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4388 13 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4389 13 : this->m_DesignHeatingCapacity = thisHeatCoil.MSRatedTotCap(thisHeatCoil.NumOfSpeeds);
4390 : }
4391 : }
4392 673 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
4393 673 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
4394 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4395 0 : if (isNotOK) {
4396 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4397 0 : errorsFound = true;
4398 : } else {
4399 0 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4400 0 : if (errFlag) {
4401 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4402 0 : errorsFound = true;
4403 0 : errFlag = false;
4404 : } else {
4405 0 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4406 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4407 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4408 0 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4409 0 : this->m_DesignHeatingCapacity = thisHeatCoil.MSNominalCapacity(thisHeatCoil.NumOfStages);
4410 0 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4411 0 : this->m_RequestAutoSize = true;
4412 : }
4413 : }
4414 : }
4415 673 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
4416 459 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
4417 214 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4418 214 : if (isNotOK) {
4419 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4420 0 : errorsFound = true;
4421 : } else { // mine data from heating coil
4422 214 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4423 214 : if (errFlag) {
4424 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4425 0 : errorsFound = true;
4426 0 : errFlag = false;
4427 : } else {
4428 214 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4429 214 : this->m_DesignHeatingCapacity = thisHeatCoil.NominalCapacity;
4430 214 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4431 209 : this->m_RequestAutoSize = true;
4432 : }
4433 214 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4434 214 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4435 214 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4436 214 : HeatingCoilPLFCurveIndex = thisHeatCoil.PLFCurveIndex;
4437 : // These heating coil types do not have an air flow input field
4438 214 : if (this->m_RequestAutoSize) {
4439 209 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4440 : }
4441 : }
4442 : } // IF (IsNotOK) THEN
4443 :
4444 673 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
4445 9 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4446 9 : if (isNotOK) {
4447 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4448 0 : errorsFound = true;
4449 : } else { // mine data from heating coil object
4450 9 : this->m_HeatingCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_HeatingCoilName, errFlag);
4451 9 : if (errFlag) {
4452 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4453 0 : errorsFound = true;
4454 0 : errFlag = false;
4455 : } else {
4456 9 : auto const &thisHeatCoil = state.dataWaterCoils->WaterCoil(this->m_HeatingCoilIndex);
4457 9 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4458 9 : this->HeatCoilFluidInletNode = thisHeatCoil.WaterInletNodeNum;
4459 9 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxWaterVolFlowRate;
4460 9 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4461 9 : this->m_RequestAutoSize = true;
4462 9 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4463 : }
4464 9 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4465 9 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4466 : }
4467 : }
4468 :
4469 450 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
4470 2 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4471 2 : if (isNotOK) {
4472 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4473 0 : errorsFound = true;
4474 : } else { // mine data from heating coil object
4475 2 : this->m_HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_HeatingCoilName, errFlag);
4476 2 : if (errFlag) {
4477 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4478 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4479 0 : errorsFound = true;
4480 0 : errFlag = false;
4481 : } else {
4482 2 : auto const &thisHeatCoil = state.dataSteamCoils->SteamCoil(this->m_HeatingCoilIndex);
4483 2 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4484 2 : this->HeatCoilFluidInletNode = thisHeatCoil.SteamInletNodeNum;
4485 2 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxSteamVolFlowRate;
4486 2 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4487 0 : this->m_RequestAutoSize = true;
4488 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4489 : }
4490 2 : if (this->MaxHeatCoilFluidFlow > 0.0) {
4491 2 : Real64 TempSteamIn = 100.0;
4492 2 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
4493 2 : this->MaxHeatCoilFluidFlow *= SteamDensity;
4494 2 : errFlag = false;
4495 : }
4496 2 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4497 2 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4498 2 : if (this->m_RequestAutoSize) {
4499 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4500 : }
4501 : }
4502 : }
4503 :
4504 448 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
4505 154 : this->m_DXHeatingCoil = true;
4506 154 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4507 154 : if (isNotOK) {
4508 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4509 0 : errorsFound = true;
4510 : } else { // mine data from heating coil object
4511 154 : this->m_HeatingCoilIndex =
4512 154 : WaterToAirHeatPumpSimple::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4513 154 : if (errFlag) {
4514 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4515 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4516 0 : errorsFound = true;
4517 0 : errFlag = false;
4518 : } else {
4519 154 : auto const &thisHeatCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_HeatingCoilIndex);
4520 154 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4521 154 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4522 154 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4523 154 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4524 154 : this->m_RequestAutoSize = true;
4525 : }
4526 154 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4527 154 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4528 : }
4529 : }
4530 :
4531 294 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
4532 5 : this->m_DXHeatingCoil = true;
4533 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4534 5 : if (isNotOK) {
4535 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4536 0 : errorsFound = true;
4537 : } else { // mine data from heating coil object
4538 5 : this->m_HeatingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4539 5 : if (errFlag) {
4540 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4541 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4542 0 : errorsFound = true;
4543 0 : errFlag = false;
4544 : } else {
4545 5 : auto const &thisHeatCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_HeatingCoilIndex);
4546 5 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4547 5 : this->m_DesignHeatingCapacity = thisHeatCoil.HeatingCapacity;
4548 5 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4549 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4550 : }
4551 : }
4552 :
4553 289 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
4554 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4555 0 : if (isNotOK) {
4556 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4557 0 : errorsFound = true;
4558 : } else { // mine data from Heating coil object
4559 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
4560 0 : state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, cCurrentModuleObject);
4561 0 : if (errFlag) {
4562 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4563 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4564 0 : errorsFound = true;
4565 0 : errFlag = false;
4566 : } else {
4567 0 : auto const &thisHeatCoil = state.dataUserDefinedComponents->UserCoil(this->m_HeatingCoilIndex);
4568 0 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4569 : // **** How to get this info ****
4570 : // UnitarySystem( UnitarySysNum ).DesignHeatingCapacity =
4571 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
4572 0 : HeatingCoilInletNode = thisHeatCoil.Air(1).InletNodeNum;
4573 0 : HeatingCoilOutletNode = thisHeatCoil.Air(1).OutletNodeNum;
4574 : }
4575 : }
4576 :
4577 289 : } else if (this->m_HeatCoilExists) {
4578 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4579 0 : ShowContinueError(state, format("Illegal Heating Coil Object Type = {}", this->m_HeatingCoilTypeName));
4580 0 : errorsFound = true;
4581 : } // IF (this->m_HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
4582 :
4583 : // coil outlet node set point has priority, IF not exist, then use system outlet node
4584 736 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
4585 305 : this->HeatCtrlNode = this->AirOutNode;
4586 : }
4587 736 : if (SetPointManager::NodeHasSPMCtrlVarType(state, HeatingCoilOutletNode, HVAC::CtrlVarType::Temp)) {
4588 60 : this->HeatCtrlNode = HeatingCoilOutletNode;
4589 : }
4590 :
4591 736 : this->HeatCoilInletNodeNum = HeatingCoilInletNode;
4592 736 : this->HeatCoilOutletNodeNum = HeatingCoilOutletNode;
4593 :
4594 : // Add heating coil to component sets array
4595 736 : if (this->m_HeatCoilExists && this->m_HeatCompNotSetYet) {
4596 447 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
4597 868 : BranchNodeConnections::SetUpCompSets(state,
4598 : cCurrentModuleObject,
4599 : thisObjectName,
4600 : this->m_HeatingCoilTypeName,
4601 : this->m_HeatingCoilName,
4602 434 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
4603 434 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4604 : } else {
4605 13 : BranchNodeConnections::SetUpCompSets(
4606 : state, cCurrentModuleObject, thisObjectName, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, "UNDEFINED", "UNDEFINED");
4607 : }
4608 447 : this->m_HeatCompNotSetYet = false;
4609 : }
4610 :
4611 : // Get Cooling Coil Information IF available
4612 736 : if (!input_data.cooling_coil_object_type.empty() && !this->m_CoolingCoilName.empty()) {
4613 :
4614 735 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4615 433 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4616 433 : if (isNotOK) {
4617 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4618 0 : errorsFound = true;
4619 :
4620 : } else { // mine data from DX cooling coil
4621 :
4622 433 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4623 49 : this->m_NumOfSpeedCooling = 2;
4624 49 : this->m_MultiOrVarSpeedCoolCoil = true;
4625 : } else {
4626 384 : this->m_NumOfSpeedCooling = 1;
4627 384 : this->m_MultiOrVarSpeedCoolCoil = false;
4628 : }
4629 :
4630 : // Get DX cooling coil index
4631 433 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4632 433 : if (isNotOK) {
4633 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4634 0 : errorsFound = true;
4635 : } else {
4636 433 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
4637 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
4638 : }
4639 433 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4640 433 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4641 433 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(1);
4642 433 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4643 344 : this->m_RequestAutoSize = true;
4644 : }
4645 433 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4646 433 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4647 341 : this->m_RequestAutoSize = true;
4648 : }
4649 433 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4650 433 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4651 433 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4652 :
4653 433 : if (this->m_FanExists) {
4654 181 : thisCoolCoil.SupplyFanName = this->m_FanName;
4655 181 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4656 181 : thisCoolCoil.supplyFanType = this->m_FanType;
4657 181 : if (this->m_FanType != HVAC::FanType::Invalid) {
4658 181 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
4659 : state,
4660 181 : thisCoolCoil.Name,
4661 181 : thisCoolCoil.DXCoilType,
4662 181 : state.dataFans->fans(thisCoolCoil.SupplyFanIndex)->Name,
4663 : this->m_FanType,
4664 : thisCoolCoil.SupplyFanIndex);
4665 : }
4666 : }
4667 433 : if (this->m_HeatCoilExists) {
4668 180 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4669 180 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4670 180 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4671 180 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4672 180 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4673 180 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4674 28 : this->m_HeatPump = true;
4675 : }
4676 : }
4677 :
4678 : // Push heating coil PLF curve index to DX coil
4679 433 : if (HeatingCoilPLFCurveIndex > 0) {
4680 2 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4681 : }
4682 : }
4683 : } // IF (IsNotOK) THEN
4684 :
4685 735 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
4686 54 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4687 54 : if (isNotOK) {
4688 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4689 0 : errorsFound = true;
4690 :
4691 : } else {
4692 : // // call CoilCoolingDX constructor
4693 54 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
4694 54 : if (this->m_CoolingCoilIndex == -1) {
4695 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4696 0 : errorsFound = true;
4697 : } else {
4698 :
4699 : // mine data from coil object
4700 : // TODO: Need to check for autosize on these I guess
4701 54 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
4702 54 : this->m_DesignCoolingCapacity = newCoil.performance->ratedGrossTotalCap();
4703 54 : this->m_MaxCoolAirVolFlow = newCoil.performance->ratedEvapAirFlowRate(state);
4704 54 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4705 50 : this->m_RequestAutoSize = true;
4706 : }
4707 54 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4708 50 : this->m_RequestAutoSize = true;
4709 : }
4710 54 : this->m_coolingCoilAvailSched = newCoil.availSched;
4711 54 : CoolingCoilInletNode = newCoil.evapInletNodeIndex;
4712 54 : CoolingCoilOutletNode = newCoil.evapOutletNodeIndex;
4713 54 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4714 54 : this->m_NumOfSpeedCooling = newCoil.performance->numSpeeds();
4715 54 : this->m_MinOATCompressorCooling = newCoil.performance->minOutdoorDrybulb;
4716 54 : newCoil.supplyFanName = this->m_FanName;
4717 54 : newCoil.supplyFanIndex = this->m_FanIndex;
4718 54 : newCoil.supplyFanType = this->m_FanType;
4719 54 : if (newCoil.subcoolReheatFlag) {
4720 1 : this->m_Humidistat = true;
4721 1 : if (this->m_NumOfSpeedCooling > 1) {
4722 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4723 0 : this->FullLatOutput.resize(this->m_NumOfSpeedCooling + 1);
4724 0 : this->SpeedSHR.resize(this->m_NumOfSpeedCooling + 1);
4725 : }
4726 1 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4727 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4728 0 : ShowContinueError(state,
4729 : "Setpoint control is not available for SubcoolReheat cooling coil. Load control is forced. "
4730 : "Simulation continues.");
4731 0 : this->m_ControlType = UnitarySysCtrlType::Load;
4732 : }
4733 : }
4734 54 : newCoil.setData(this->m_FanIndex, this->m_FanType, this->m_FanName, this->m_SuppCoilPlantLoc.loopNum);
4735 :
4736 : // Push heating coil PLF curve index to DX coil
4737 : // if ( HeatingCoilPLFCurveIndex > 0 ) {
4738 : // SetDXCoolingCoilData( UnitarySystem( UnitarySysNum ).CoolingCoilIndex, ErrorsFound,
4739 : // HeatingCoilPLFCurveIndex );
4740 : // }
4741 : }
4742 :
4743 54 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > 1) {
4744 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4745 : }
4746 :
4747 54 : if (this->m_HeatCoilExists) {
4748 52 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4749 52 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4750 52 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4751 52 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4752 52 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4753 45 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4754 20 : this->m_HeatPump = true;
4755 : }
4756 : }
4757 : }
4758 :
4759 248 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
4760 9 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4761 9 : if (isNotOK) {
4762 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4763 0 : errorsFound = true;
4764 :
4765 : } else { // mine data from DX cooling coil
4766 :
4767 : // Get DX cooling coil index
4768 9 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4769 9 : if (isNotOK) {
4770 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4771 0 : errorsFound = true;
4772 : } else {
4773 9 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4774 9 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4775 9 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(thisCoolCoil.NumCapacityStages);
4776 9 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4777 6 : this->m_RequestAutoSize = true;
4778 : }
4779 9 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4780 9 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4781 6 : this->m_RequestAutoSize = true;
4782 : }
4783 9 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4784 9 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4785 9 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4786 :
4787 : // Push heating coil PLF curve index to DX coil
4788 9 : if (HeatingCoilPLFCurveIndex > 0) {
4789 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4790 : }
4791 :
4792 9 : if (this->m_HeatCoilExists) {
4793 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4794 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4795 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4796 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4797 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4798 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4799 0 : this->m_HeatPump = true;
4800 : }
4801 : }
4802 : }
4803 : } // IF (IsNotOK) THEN
4804 :
4805 239 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
4806 3 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4807 3 : if (isNotOK) {
4808 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4809 0 : errorsFound = true;
4810 :
4811 : } else { // mine data from heat exchanger assisted cooling coil
4812 :
4813 : // Get DX heat exchanger assisted cooling coil index
4814 3 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4815 3 : if (isNotOK) {
4816 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4817 0 : errorsFound = true;
4818 : }
4819 :
4820 : std::string ChildCoolingCoilName =
4821 3 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4822 : std::string ChildCoolingCoilType =
4823 3 : HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4824 3 : if (isNotOK) {
4825 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4826 0 : errorsFound = true;
4827 : }
4828 :
4829 3 : if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
4830 :
4831 0 : int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
4832 0 : if (childCCIndex < 0) {
4833 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4834 0 : errorsFound = true;
4835 : }
4836 :
4837 0 : auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
4838 0 : this->m_coolingCoilAvailSched = newCoil.availSched;
4839 :
4840 : // thisSys.m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4841 : // Get Coil:Cooling:DX coil air flow rate. Later fields will overwrite this IF input field is present
4842 0 : this->m_MaxCoolAirVolFlow = newCoil.performance->ratedEvapAirFlowRate(state);
4843 : // if (thisSys.m_DesignCoolingCapacity == DataSizing::AutoSize) thisSys.m_RequestAutoSize = true;
4844 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4845 0 : this->m_RequestAutoSize = true;
4846 : }
4847 :
4848 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4849 0 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4850 :
4851 3 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) {
4852 :
4853 2 : this->m_coolingCoilAvailSched = DXCoils::GetDXCoilAvailSched(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4854 2 : if (isNotOK) {
4855 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4856 0 : errorsFound = true;
4857 : }
4858 :
4859 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
4860 2 : this->m_MaxCoolAirVolFlow = DXCoils::GetDXCoilAirFlow(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4861 2 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4862 2 : this->m_RequestAutoSize = true;
4863 : }
4864 2 : if (errFlag) {
4865 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4866 0 : errFlag = false;
4867 0 : errorsFound = true;
4868 : }
4869 :
4870 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4871 2 : this->m_CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(
4872 : state,
4873 : "COIL:COOLING:DX:SINGLESPEED",
4874 4 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag),
4875 : errFlag);
4876 :
4877 2 : if (errFlag) {
4878 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4879 0 : errFlag = false;
4880 0 : errorsFound = true;
4881 : }
4882 :
4883 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED")) {
4884 1 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4885 1 : this->m_MaxCoolAirVolFlow =
4886 1 : VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4887 1 : if (errFlag) {
4888 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4889 0 : errFlag = false;
4890 0 : errorsFound = true;
4891 : }
4892 1 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, ChildCoolingCoilName, errFlag);
4893 1 : if (errFlag) {
4894 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4895 0 : errFlag = false;
4896 0 : errorsFound = true;
4897 : }
4898 : }
4899 :
4900 : // Get DX cooling coil capacity
4901 3 : this->m_DesignCoolingCapacity =
4902 3 : HVACHXAssistedCoolingCoil::GetCoilCapacity(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4903 3 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4904 3 : this->m_RequestAutoSize = true;
4905 : }
4906 3 : if (errFlag) {
4907 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4908 0 : errFlag = false;
4909 0 : errorsFound = true;
4910 : }
4911 :
4912 : // Get the Cooling Coil Nodes
4913 : CoolingCoilInletNode =
4914 3 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4915 : CoolingCoilOutletNode =
4916 3 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4917 3 : if (errFlag) {
4918 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4919 0 : errFlag = false;
4920 0 : errorsFound = true;
4921 : }
4922 :
4923 : // Push heating coil PLF curve index to DX coil
4924 3 : if (HeatingCoilPLFCurveIndex > 0) {
4925 : // get the actual index to the DX cooling coil object
4926 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4927 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4928 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4929 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4930 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4931 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4932 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4933 : }
4934 : // what could we do for VS coil here? odd thing here
4935 : }
4936 :
4937 3 : if (this->m_HeatCoilExists) {
4938 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4939 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4940 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4941 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4942 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4943 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4944 0 : this->m_HeatPump = true;
4945 : }
4946 : }
4947 :
4948 3 : } // IF (IsNotOK) THEN
4949 236 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
4950 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4951 0 : if (isNotOK) {
4952 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4953 0 : errorsFound = true;
4954 :
4955 : } else { // mine data from heat exchanger assisted cooling coil
4956 :
4957 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4958 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4959 : std::string HXCoilName =
4960 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4961 :
4962 0 : if (errFlag) {
4963 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4964 0 : errFlag = false;
4965 0 : errorsFound = true;
4966 : }
4967 :
4968 : // Get DX heat exchanger assisted cooling coil index
4969 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag);
4970 0 : if (errFlag) {
4971 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4972 0 : errFlag = false;
4973 0 : errorsFound = true;
4974 : }
4975 :
4976 0 : this->m_coolingCoilAvailSched =
4977 0 : WaterCoils::GetWaterCoilAvailSched(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4978 0 : this->MaxCoolCoilFluidFlow =
4979 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4980 : // Get the Cooling Coil water Inlet Node number
4981 0 : this->CoolCoilFluidInletNode =
4982 0 : WaterCoils::GetCoilWaterInletNode(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4983 0 : if (errFlag) {
4984 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4985 0 : errFlag = false;
4986 0 : errorsFound = true;
4987 : }
4988 :
4989 : // Get the Cooling Coil Nodes
4990 : CoolingCoilInletNode =
4991 0 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4992 : CoolingCoilOutletNode =
4993 0 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4994 0 : if (errFlag) {
4995 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4996 0 : errFlag = false;
4997 0 : errorsFound = true;
4998 : }
4999 :
5000 0 : this->m_MaxCoolAirVolFlow =
5001 0 : HVACHXAssistedCoolingCoil::GetHXCoilAirFlowRate(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5002 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5003 0 : this->m_RequestAutoSize = true;
5004 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
5005 : }
5006 0 : if (errFlag) {
5007 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5008 0 : errFlag = false;
5009 0 : errorsFound = true;
5010 : }
5011 :
5012 0 : this->m_CondenserNodeNum = 0;
5013 :
5014 : // Push heating coil PLF curve index to DX coil
5015 0 : if (HeatingCoilPLFCurveIndex > 0) {
5016 : // get the actual index to the DX cooling coil object
5017 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
5018 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
5019 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
5020 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
5021 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
5022 : }
5023 : // VS coil issue here
5024 : }
5025 :
5026 0 : } // IF (IsNotOK) THEN
5027 236 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5028 225 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5029 15 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5030 15 : if (isNotOK) {
5031 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5032 0 : errorsFound = true;
5033 : } else {
5034 15 : this->m_CoolingCoilIndex =
5035 15 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5036 15 : if (errFlag) {
5037 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5038 0 : errorsFound = true;
5039 0 : errFlag = false;
5040 : } else {
5041 15 : auto &thisCoolCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex);
5042 15 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5043 15 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5044 15 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum;
5045 15 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5046 15 : this->m_NumOfSpeedCooling = thisCoolCoil.NumOfSpeeds;
5047 15 : if (this->m_NumOfSpeedCooling > 1) {
5048 13 : this->m_MultiOrVarSpeedCoolCoil = true;
5049 : }
5050 15 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5051 15 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
5052 10 : this->m_RequestAutoSize = true;
5053 : }
5054 15 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5055 15 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5056 10 : this->m_RequestAutoSize = true;
5057 : } else {
5058 5 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NumOfSpeeds) /
5059 5 : thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NormSpedLevel) *
5060 5 : thisCoolCoil.RatedAirVolFlowRate;
5061 : }
5062 15 : if (this->m_FanExists) { // Set fan info
5063 13 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
5064 13 : thisCoolCoil.supplyFanType = this->m_FanType;
5065 13 : thisCoolCoil.SupplyFanName = loc_m_FanName;
5066 : }
5067 : }
5068 : }
5069 :
5070 15 : if (this->m_HeatCoilExists) {
5071 13 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5072 10 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5073 6 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5074 6 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5075 6 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5076 5 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5077 9 : this->m_HeatPump = true;
5078 : }
5079 : }
5080 :
5081 236 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
5082 38 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5083 38 : if (isNotOK) {
5084 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5085 0 : errorsFound = true;
5086 : } else {
5087 38 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, input_data.cooling_coil_object_type);
5088 38 : if (errFlag) {
5089 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5090 0 : errorsFound = true;
5091 0 : errFlag = false;
5092 : } else {
5093 38 : auto const &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
5094 38 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
5095 38 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
5096 38 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
5097 38 : this->m_DesignCoolingCapacity = thisCoolCoil.MSRatedTotCap(thisCoolCoil.NumOfSpeeds);
5098 38 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
5099 2 : this->m_RequestAutoSize = true;
5100 : }
5101 38 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(1);
5102 38 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5103 2 : this->m_RequestAutoSize = true;
5104 : }
5105 : }
5106 : }
5107 :
5108 38 : if (this->m_HeatCoilExists) {
5109 38 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5110 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5111 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5112 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5113 38 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5114 33 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5115 5 : this->m_HeatPump = true;
5116 : }
5117 : }
5118 :
5119 183 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
5120 :
5121 20 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5122 20 : if (isNotOK) {
5123 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5124 0 : errorsFound = true;
5125 : } else { // mine data from Cooling coil object
5126 20 : this->m_CoolingCoilIndex =
5127 20 : WaterCoils::GetWaterCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5128 20 : if (errFlag) {
5129 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5130 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5131 0 : errorsFound = true;
5132 0 : errFlag = false;
5133 : } else {
5134 20 : auto const &thisCoolCoil = state.dataWaterCoils->WaterCoil(this->m_CoolingCoilIndex);
5135 20 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
5136 20 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
5137 20 : this->m_MaxCoolAirVolFlow = thisCoolCoil.DesAirVolFlowRate;
5138 : }
5139 20 : this->CoolCoilFluidInletNode = thisCoolCoil.WaterInletNodeNum;
5140 20 : this->MaxCoolCoilFluidFlow = thisCoolCoil.MaxWaterVolFlowRate;
5141 20 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
5142 20 : this->m_RequestAutoSize = true;
5143 20 : this->m_DesignCoolingCapacity = DataSizing::AutoSize; // water coils don't have a capacity field, need other logic?
5144 : }
5145 20 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5146 20 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5147 : }
5148 : }
5149 183 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5150 154 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5151 154 : if (isNotOK) {
5152 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5153 0 : errorsFound = true;
5154 : } else { // mine data from Cooling coil object
5155 154 : this->m_CoolingCoilIndex =
5156 154 : WaterToAirHeatPumpSimple::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5157 154 : if (errFlag) {
5158 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5159 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5160 0 : errorsFound = true;
5161 0 : errFlag = false;
5162 : } else {
5163 154 : auto const &thisCoolCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_CoolingCoilIndex);
5164 154 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5165 154 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5166 :
5167 : // this isn't likely to work on getInput calls but is what happened before
5168 154 : int CompanionHeatingCoil = thisCoolCoil.CompanionHeatingCoilNum;
5169 154 : if (CompanionHeatingCoil > 0) {
5170 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize &&
5171 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).WAHPPlantType ==
5172 0 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
5173 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
5174 0 : state.dataSize->DXCoolCap > 0) {
5175 : // Heating coil has not yet been sized, returning the temporary cooling capacity
5176 0 : this->m_DesignCoolingCapacity = state.dataSize->DXCoolCap;
5177 : }
5178 : }
5179 :
5180 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
5181 154 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5182 154 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5183 154 : this->m_RequestAutoSize = true;
5184 : }
5185 154 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5186 154 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5187 : }
5188 : }
5189 :
5190 154 : if (this->m_HeatCoilExists) {
5191 154 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5192 154 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5193 154 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5194 154 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5195 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5196 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5197 154 : this->m_HeatPump = true;
5198 : }
5199 : }
5200 :
5201 9 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
5202 5 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5203 5 : if (isNotOK) {
5204 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5205 0 : errorsFound = true;
5206 : } else { // mine data from Cooling coil object
5207 5 : this->m_CoolingCoilIndex =
5208 5 : WaterToAirHeatPump::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5209 5 : if (this->m_CoolingCoilIndex == 0) {
5210 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5211 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5212 0 : errorsFound = true;
5213 0 : errFlag = false;
5214 : } else {
5215 5 : auto const &thisCoolCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_CoolingCoilIndex);
5216 5 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5217 5 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingCapacity;
5218 5 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5219 5 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5220 : }
5221 : }
5222 :
5223 5 : if (this->m_HeatCoilExists) {
5224 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5225 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5226 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5227 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5228 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5229 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5230 5 : this->m_HeatPump = true;
5231 : }
5232 : }
5233 :
5234 4 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
5235 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5236 0 : if (isNotOK) {
5237 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5238 0 : errorsFound = true;
5239 : } else { // mine data from Cooling coil object
5240 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5241 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5242 0 : if (errFlag) {
5243 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5244 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5245 0 : errorsFound = true;
5246 0 : errFlag = false;
5247 : } else {
5248 0 : auto const &thisCoolCoil = state.dataUserDefinedComponents->UserCoil(this->m_CoolingCoilIndex);
5249 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5250 : // **** How to get this info ****
5251 : // UnitarySystem( UnitarySysNum ).DesignCoolingCapacity =
5252 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
5253 0 : CoolingCoilInletNode = thisCoolCoil.Air(1).InletNodeNum;
5254 0 : CoolingCoilOutletNode = thisCoolCoil.Air(1).OutletNodeNum;
5255 : }
5256 : }
5257 :
5258 4 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
5259 4 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5260 4 : if (isNotOK) {
5261 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5262 0 : errorsFound = true;
5263 : } else { // mine data from Cooling coil object
5264 4 : PackagedThermalStorageCoil::GetTESCoilIndex(
5265 4 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5266 4 : if (errFlag) {
5267 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5268 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5269 0 : errorsFound = true;
5270 0 : errFlag = false;
5271 : } else {
5272 4 : auto const &thisCoolCoil = state.dataPackagedThermalStorageCoil->TESCoil(this->m_CoolingCoilIndex);
5273 4 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5274 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedEvapAirVolFlowRate;
5275 4 : if (thisCoolCoil.CoolingOnlyModeIsAvailable) {
5276 4 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingOnlyRatedTotCap;
5277 0 : } else if (thisCoolCoil.CoolingAndChargeModeAvailable) {
5278 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndChargeRatedTotCap;
5279 0 : } else if (thisCoolCoil.CoolingAndDischargeModeAvailable) {
5280 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndDischargeRatedTotCap;
5281 : } else {
5282 0 : this->m_DesignCoolingCapacity = 0.0;
5283 : }
5284 4 : CoolingCoilInletNode = thisCoolCoil.EvapAirInletNodeNum;
5285 4 : CoolingCoilOutletNode = thisCoolCoil.EvapAirOutletNodeNum;
5286 : }
5287 : }
5288 :
5289 : } else { // IF(.NOT. lAlphaBlanks(16))THEN
5290 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5291 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iCoolingCoilTypeAlphaNum), Alphas(iCoolingCoilTypeAlphaNum)));
5292 0 : errorsFound = true;
5293 : }
5294 :
5295 735 : if (!input_data.dx_cooling_coil_system_sensor_node_name.empty()) { // used by CoilSystem:Cooling:DX
5296 538 : this->CoolCtrlNode = NodeInputManager::GetOnlySingleNode(state,
5297 269 : input_data.dx_cooling_coil_system_sensor_node_name,
5298 : errFlag,
5299 : objType,
5300 : thisObjectName,
5301 : DataLoopNode::NodeFluidType::Air,
5302 : DataLoopNode::ConnectionType::Sensor,
5303 : NodeInputManager::CompFluidStream::Primary,
5304 : DataLoopNode::ObjectIsParent);
5305 : } else {
5306 466 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
5307 95 : this->CoolCtrlNode = this->AirOutNode;
5308 : }
5309 466 : if (SetPointManager::NodeHasSPMCtrlVarType(state, CoolingCoilOutletNode, HVAC::CtrlVarType::Temp)) {
5310 43 : this->CoolCtrlNode = CoolingCoilOutletNode;
5311 : }
5312 : }
5313 :
5314 735 : this->CoolCoilInletNodeNum = CoolingCoilInletNode;
5315 735 : this->CoolCoilOutletNodeNum = CoolingCoilOutletNode;
5316 :
5317 : } else {
5318 1 : this->m_ValidASHRAECoolCoil = false;
5319 : }
5320 :
5321 736 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple &&
5322 154 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5323 154 : if (!input_data.heat_pump_coil_water_flow_mode.empty()) {
5324 153 : this->m_WaterCyclingMode =
5325 153 : static_cast<HVAC::WaterFlow>(getEnumValue(HVAC::waterFlowNamesUC, Util::makeUPPER(input_data.heat_pump_coil_water_flow_mode)));
5326 : } else {
5327 1 : this->m_WaterCyclingMode = HVAC::WaterFlow::Cycling;
5328 : }
5329 154 : WaterToAirHeatPumpSimple::SetSimpleWSHPData(
5330 154 : state, this->m_CoolingCoilIndex, errorsFound, this->m_WaterCyclingMode, _, this->m_HeatingCoilIndex);
5331 : }
5332 :
5333 736 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
5334 4 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5335 4 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, this->m_HeatingCoilIndex);
5336 : }
5337 :
5338 : // Add cooling coil to component sets array
5339 736 : if (this->m_CoolCoilExists && this->m_CoolCompNotSetYet) {
5340 735 : if (this->m_CoolingCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
5341 1394 : BranchNodeConnections::SetUpCompSets(state,
5342 : cCurrentModuleObject,
5343 : thisObjectName,
5344 : input_data.cooling_coil_object_type,
5345 : this->m_CoolingCoilName,
5346 697 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
5347 697 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
5348 : } else {
5349 38 : BranchNodeConnections::SetUpCompSets(state,
5350 : cCurrentModuleObject,
5351 : thisObjectName,
5352 : input_data.cooling_coil_object_type,
5353 : this->m_CoolingCoilName,
5354 : "UNDEFINED",
5355 : "UNDEFINED");
5356 : }
5357 735 : this->m_CoolCompNotSetYet = false;
5358 : }
5359 : // Run as 100% DOAS DX coil
5360 736 : if (!Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5361 730 : this->m_ISHundredPercentDOASDXCoil = false;
5362 : } else {
5363 6 : if (Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5364 6 : this->m_ISHundredPercentDOASDXCoil = true;
5365 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
5366 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5367 0 : ShowContinueError(state, "Variable DX Cooling Coil is not supported as 100% DOAS DX coil.");
5368 0 : ShowContinueError(state, "Variable DX Cooling Coil resets Use DOAS DX Cooling Coil = No and the simulation continues.");
5369 0 : this->m_ISHundredPercentDOASDXCoil = false;
5370 : }
5371 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "")) {
5372 0 : this->m_ISHundredPercentDOASDXCoil = false;
5373 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "No")) {
5374 0 : this->m_ISHundredPercentDOASDXCoil = false;
5375 : }
5376 : }
5377 :
5378 : // considered as as 100% DOAS DX cooling coil
5379 736 : if (this->m_ISHundredPercentDOASDXCoil) {
5380 : // set the system DX Coil application type to the child DX coil
5381 6 : if (!(this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5382 6 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
5383 6 : DXCoils::SetDXCoilTypeData(state, this->m_CoolingCoilName);
5384 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
5385 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].setToHundredPercentDOAS();
5386 : }
5387 : }
5388 : // DOAS DX Cooling Coil Leaving Minimum Air Temperature
5389 736 : this->DesignMinOutletTemp = input_data.minimum_supply_air_temperature;
5390 736 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp == DataSizing::AutoSize) {
5391 : // skip error for PTUnits
5392 175 : if (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater) {
5393 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5394 0 : ShowContinueError(state, "Invalid entry for Minimum Supply Air Temperature = AutoSize.");
5395 0 : ShowContinueError(state, "AutoSizing not allowed when Control Type = Load or Setpoint");
5396 0 : errorsFound = true;
5397 : }
5398 : }
5399 736 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp > 7.5) {
5400 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5401 0 : ShowContinueError(state, format("Invalid entry for Minimum Supply Air Temperature = {:.4R}", this->DesignMinOutletTemp));
5402 0 : ShowContinueError(state, "The minimum supply air temperature will be limited to 7.5C and the simulation continues.");
5403 0 : this->DesignMinOutletTemp = 7.5;
5404 : }
5405 :
5406 : // Get Latent Load Control flag
5407 736 : if (!input_data.latent_load_control.empty()) {
5408 736 : if (Util::SameString(input_data.latent_load_control, "SensibleOnlyLoadControl")) {
5409 718 : this->m_RunOnSensibleLoad = true;
5410 718 : this->m_RunOnLatentLoad = false;
5411 18 : } else if (Util::SameString(input_data.latent_load_control, "LatentOnlyLoadControl")) {
5412 0 : this->m_RunOnSensibleLoad = false;
5413 0 : this->m_RunOnLatentLoad = true;
5414 18 : } else if (Util::SameString(input_data.latent_load_control, "LatentOrSensibleLoadControl")) {
5415 9 : this->m_RunOnSensibleLoad = true;
5416 9 : this->m_RunOnLatentLoad = true;
5417 9 : } else if (Util::SameString(input_data.latent_load_control, "LatentWithSensibleLoadControl")) {
5418 9 : this->m_RunOnSensibleLoad = true;
5419 9 : this->m_RunOnLatentLoad = true;
5420 9 : this->m_RunOnLatentOnlyWithSensible = true;
5421 : }
5422 : }
5423 736 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
5424 24 : if (!this->m_RunOnLatentLoad && !this->m_RunOnLatentOnlyWithSensible && this->m_ControlType == UnitarySysCtrlType::Load) {
5425 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5426 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5427 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5428 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5429 0 : ShowContinueError(state, "Humidity/Moisture may not be controlled with these settings.");
5430 : }
5431 : } else {
5432 712 : if ((this->m_RunOnLatentLoad || this->m_RunOnLatentOnlyWithSensible) && this->m_ControlType == UnitarySysCtrlType::Load) {
5433 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5434 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5435 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5436 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5437 0 : ShowContinueError(state, "Humidity/Moisture will not be controlled with these settings.");
5438 0 : this->m_RunOnLatentLoad = false;
5439 0 : this->m_RunOnLatentOnlyWithSensible = false;
5440 : }
5441 : }
5442 : // Get reheat coil data if humidistat is used
5443 736 : this->m_SuppHeatCoilName = input_data.supplemental_heating_coil_name;
5444 736 : this->m_SuppHeatCoilTypeName = input_data.supplemental_heating_coil_object_type;
5445 :
5446 736 : if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Water")) {
5447 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
5448 736 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Steam")) {
5449 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
5450 1298 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Fuel") ||
5451 1076 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric") ||
5452 1812 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric:MultiStage") ||
5453 1246 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:DesuperHeater")) {
5454 227 : this->m_SuppHeatCoilType_Num =
5455 227 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5456 509 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:UserDefined")) {
5457 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_UserDefined;
5458 : }
5459 :
5460 736 : if (!this->m_SuppHeatCoilTypeName.empty() && !this->m_SuppHeatCoilName.empty()) {
5461 227 : errFlag = false;
5462 :
5463 227 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric ||
5464 5 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
5465 1 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
5466 :
5467 227 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5468 227 : if (isNotOK) {
5469 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5470 0 : errorsFound = true;
5471 :
5472 : } else { // mine data from reheat coil
5473 227 : this->m_SuppHeatCoilIndex =
5474 227 : HeatingCoils::GetHeatingCoilIndex(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5475 227 : if (errFlag) {
5476 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5477 0 : errorsFound = true;
5478 0 : errFlag = false;
5479 : } else {
5480 227 : auto const &thisSuppCoil = state.dataHeatingCoils->HeatingCoil(this->m_SuppHeatCoilIndex);
5481 227 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
5482 4 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.MSNominalCapacity(thisSuppCoil.NumOfStages);
5483 4 : this->m_NumOfSpeedSuppHeating = thisSuppCoil.NumOfStages;
5484 : } else {
5485 223 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.NominalCapacity;
5486 : }
5487 227 : if (this->m_DesignSuppHeatingCapacity == DataSizing::AutoSize) {
5488 209 : this->m_RequestAutoSize = true;
5489 : }
5490 227 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5491 227 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5492 : }
5493 : } // IF (IsNotOK) THEN
5494 :
5495 227 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5496 227 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5497 :
5498 227 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5499 :
5500 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5501 0 : if (isNotOK) {
5502 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5503 0 : errorsFound = true;
5504 : } else { // mine data from heating coil object
5505 0 : this->m_SuppHeatCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_SuppHeatCoilName, errFlag);
5506 0 : if (errFlag) {
5507 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5508 0 : errorsFound = true;
5509 0 : errFlag = false;
5510 : } else {
5511 0 : auto const &thisSuppCoil = state.dataWaterCoils->WaterCoil(this->m_SuppHeatCoilIndex);
5512 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.WaterInletNodeNum;
5513 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxWaterVolFlowRate;
5514 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5515 0 : this->m_RequestAutoSize = true;
5516 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize;
5517 : }
5518 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5519 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5520 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5521 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5522 : }
5523 : }
5524 :
5525 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5526 :
5527 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5528 0 : if (isNotOK) {
5529 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5530 0 : errorsFound = true;
5531 : } else { // mine data from heating coil object
5532 0 : this->m_SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_SuppHeatCoilName, errFlag);
5533 0 : if (errFlag) {
5534 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5535 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5536 0 : errorsFound = true;
5537 0 : errFlag = false;
5538 : } else {
5539 0 : auto const &thisSuppCoil = state.dataSteamCoils->SteamCoil(this->m_SuppHeatCoilIndex);
5540 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.SteamInletNodeNum;
5541 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxSteamVolFlowRate;
5542 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5543 0 : this->m_RequestAutoSize = true;
5544 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize; // not sure if steam coil needs this
5545 : }
5546 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
5547 0 : Real64 TempSteamIn = 100.0;
5548 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
5549 0 : this->m_MaxSuppCoilFluidFlow = this->m_MaxSuppCoilFluidFlow * SteamDensity;
5550 : }
5551 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5552 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5553 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5554 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5555 : }
5556 : }
5557 :
5558 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
5559 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5560 0 : if (isNotOK) {
5561 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5562 0 : errorsFound = true;
5563 : } else { // mine data from Heating coil object
5564 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5565 0 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilIndex, errFlag, cCurrentModuleObject);
5566 0 : if (errFlag) {
5567 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5568 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5569 0 : errorsFound = true;
5570 0 : errFlag = false;
5571 : } else {
5572 0 : auto const &thisSuppCoil = state.dataUserDefinedComponents->UserCoil(this->m_SuppHeatCoilIndex);
5573 0 : SupHeatCoilInletNode = thisSuppCoil.Air(1).InletNodeNum;
5574 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5575 0 : SupHeatCoilOutletNode = thisSuppCoil.Air(1).OutletNodeNum;
5576 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5577 : }
5578 : }
5579 :
5580 : } else { // Illegal reheating coil type
5581 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5582 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Type = {}", this->m_SuppHeatCoilTypeName));
5583 0 : errorsFound = true;
5584 : } // IF (this->SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
5585 :
5586 : } // IF(.NOT. lAlphaBlanks(iSuppHeatCoilTypeAlphaNum))THEN
5587 :
5588 736 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
5589 305 : this->SuppCtrlNode = this->AirOutNode;
5590 : }
5591 736 : if (SetPointManager::NodeHasSPMCtrlVarType(state, SupHeatCoilOutletNode, HVAC::CtrlVarType::Temp)) {
5592 28 : this->SuppCtrlNode = SupHeatCoilOutletNode;
5593 : }
5594 :
5595 : // Add supplemental heating coil to component sets array
5596 736 : if (this->m_SuppCoilExists && this->m_SuppCompNotSetYet) {
5597 454 : BranchNodeConnections::SetUpCompSets(state,
5598 : cCurrentModuleObject,
5599 : thisObjectName,
5600 : this->m_SuppHeatCoilTypeName,
5601 : this->m_SuppHeatCoilName,
5602 227 : state.dataLoopNodes->NodeID(SupHeatCoilInletNode),
5603 227 : state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
5604 227 : this->m_SuppCompNotSetYet = false;
5605 : }
5606 :
5607 736 : if (this->OAMixerExists) {
5608 : // Set up component set for OA mixer - use OA node and Mixed air node
5609 600 : BranchNodeConnections::SetUpCompSets(state,
5610 : this->UnitType,
5611 : this->Name,
5612 : input_data.oa_mixer_type,
5613 : input_data.oa_mixer_name,
5614 300 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[0]),
5615 300 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[3]));
5616 : }
5617 :
5618 : // set fan info for supplemental heating coils
5619 736 : if (this->m_SuppCoilExists && this->m_FanExists) {
5620 227 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
5621 227 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
5622 : }
5623 :
5624 : // Users may not provide SA flow input fields (below) and leave them blank. Check if other coil is AutoSized first to
5625 : // alleviate input requirements. check if coil has no air flow input (VolFlow = 0) and other coil isDataSizing::AutoSized. If so,
5626 : // use AutoSize for coil with 0 air flow rate. This means that the coils MUST mine the air flow rate if it exists
5627 736 : if (this->m_CoolCoilExists && this->m_HeatCoilExists) {
5628 446 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize && this->m_MaxHeatAirVolFlow == 0 && loc_m_HeatingSAFMethod == "") {
5629 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
5630 446 : } else if (this->m_MaxCoolAirVolFlow == 0 && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize && loc_m_CoolingSAFMethod == "") {
5631 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
5632 : }
5633 : }
5634 :
5635 : // translate DesignSpecification:ZoneHVAC:Sizing inputs
5636 : // UnitarySystem already has air flow scalable sizing, update locals
5637 : // UnitarySystem does not have capacity sizing, set inputs accordingly
5638 736 : if (this->m_HVACSizingIndex > 0) {
5639 0 : int zoneHVACIndex = this->m_HVACSizingIndex;
5640 0 : auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(zoneHVACIndex);
5641 0 : switch (zoneHVACSizing.CoolingSAFMethod) {
5642 0 : case DataSizing::None:
5643 0 : break; // do nothing?
5644 0 : case DataSizing::SupplyAirFlowRate:
5645 0 : loc_m_CoolingSAFMethod = "SupplyAirFlowRate";
5646 0 : loc_m_CoolingSAFMethod_SAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5647 0 : break;
5648 0 : case DataSizing::FlowPerFloorArea:
5649 0 : loc_m_CoolingSAFMethod = "FlowPerFloorArea";
5650 0 : loc_m_CoolingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxCoolAirVolFlow;
5651 0 : break;
5652 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5653 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5654 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5655 0 : break;
5656 0 : case DataSizing::FlowPerCoolingCapacity:
5657 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5658 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5659 0 : break;
5660 0 : default:
5661 : assert(true);
5662 : }
5663 :
5664 0 : switch (zoneHVACSizing.HeatingSAFMethod) {
5665 0 : case DataSizing::None:
5666 0 : break; // do nothing?
5667 0 : case DataSizing::SupplyAirFlowRate:
5668 0 : loc_m_HeatingSAFMethod = "SupplyAirFlowRate";
5669 0 : loc_m_HeatingSAFMethod_SAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5670 0 : break;
5671 0 : case DataSizing::FlowPerFloorArea:
5672 0 : loc_m_HeatingSAFMethod = "FlowPerFloorArea";
5673 0 : loc_m_HeatingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxHeatAirVolFlow;
5674 0 : break;
5675 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5676 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5677 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5678 0 : break;
5679 0 : case DataSizing::FlowPerHeatingCapacity:
5680 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5681 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5682 0 : break;
5683 0 : default:
5684 : assert(true);
5685 : }
5686 :
5687 0 : switch (zoneHVACSizing.NoCoolHeatSAFMethod) {
5688 0 : case DataSizing::None:
5689 0 : break; // do nothing?
5690 0 : case DataSizing::SupplyAirFlowRate:
5691 0 : loc_m_NoCoolHeatSAFMethod = "SupplyAirFlowRate";
5692 0 : loc_m_NoCoolHeatSAFMethod_SAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5693 0 : break;
5694 0 : case DataSizing::FlowPerFloorArea:
5695 0 : loc_m_NoCoolHeatSAFMethod = "FlowPerFloorArea";
5696 0 : loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5697 0 : break;
5698 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5699 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5700 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5701 0 : break;
5702 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5703 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5704 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5705 0 : break;
5706 0 : default:
5707 : assert(true);
5708 : }
5709 :
5710 0 : switch (zoneHVACSizing.CoolingCapMethod) {
5711 0 : case DataSizing::CoolingDesignCapacity:
5712 0 : this->m_CoolingCapMethod = DataSizing::CoolingDesignCapacity;
5713 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5714 0 : break;
5715 0 : case DataSizing::CapacityPerFloorArea:
5716 0 : this->m_CoolingCapMethod = DataSizing::CapacityPerFloorArea;
5717 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity * TotalFloorAreaOnAirLoop;
5718 0 : break;
5719 0 : case DataSizing::FractionOfAutosizedCoolingCapacity:
5720 0 : this->m_CoolingCapMethod = DataSizing::FractionOfAutosizedCoolingCapacity;
5721 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5722 0 : break;
5723 0 : default:
5724 : assert(true);
5725 : }
5726 :
5727 0 : switch (zoneHVACSizing.HeatingCapMethod) {
5728 0 : case DataSizing::HeatingDesignCapacity:
5729 0 : this->m_HeatingCapMethod = DataSizing::HeatingDesignCapacity;
5730 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5731 0 : break;
5732 0 : case DataSizing::CapacityPerFloorArea:
5733 0 : this->m_HeatingCapMethod = DataSizing::CapacityPerFloorArea;
5734 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity * TotalFloorAreaOnAirLoop;
5735 0 : break;
5736 0 : case DataSizing::FractionOfAutosizedHeatingCapacity:
5737 0 : this->m_HeatingCapMethod = DataSizing::FractionOfAutosizedHeatingCapacity;
5738 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5739 0 : break;
5740 0 : default:
5741 : assert(true);
5742 : }
5743 : }
5744 :
5745 : // Determine supply air flow rate sizing method for cooling mode
5746 736 : if (Util::SameString(loc_m_CoolingSAFMethod, "SupplyAirFlowRate")) {
5747 462 : this->m_CoolingSAFMethod = DataSizing::SupplyAirFlowRate;
5748 :
5749 462 : if (loc_m_CoolingSAFMethod_SAFlow != -999.0) {
5750 462 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlow;
5751 462 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5752 401 : this->m_RequestAutoSize = true;
5753 : } else {
5754 61 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5755 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5756 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5757 0 : ShowContinueError(
5758 : state,
5759 0 : format("Suspicious Cooling Supply Air Flow Rate = {:.7R} when cooling coil is present.", this->m_MaxCoolAirVolFlow));
5760 : }
5761 61 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5762 0 : errorsFound = true;
5763 : }
5764 : }
5765 :
5766 : } else {
5767 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5768 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5769 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate.");
5770 0 : errorsFound = true;
5771 : }
5772 274 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerFloorArea")) {
5773 :
5774 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerFloorArea;
5775 0 : if (loc_m_CoolingSAFMethod_SAFlowPerFloorArea != -999.0) {
5776 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlowPerFloorArea;
5777 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5778 0 : if (this->m_MaxCoolAirVolFlow <= 0.0001 && this->m_CoolCoilExists) {
5779 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5780 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5781 0 : ShowContinueError(
5782 : state,
5783 0 : format("Suspicious Cooling Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when cooling coil is present.",
5784 0 : this->m_MaxCoolAirVolFlow));
5785 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5786 0 : errorsFound = true;
5787 : }
5788 : }
5789 0 : this->m_MaxCoolAirVolFlow *= TotalFloorAreaOnAirLoop;
5790 0 : this->m_RequestAutoSize = true;
5791 : // AutoSized input is not allowed
5792 : } else {
5793 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5794 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5795 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Floor Area = Autosize");
5796 0 : errorsFound = true;
5797 : }
5798 : } else {
5799 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5800 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5801 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Floor Area.");
5802 0 : errorsFound = true;
5803 : }
5804 274 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FractionOfAutosizedCoolingValue")) {
5805 :
5806 0 : this->m_CoolingSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5807 0 : if (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5808 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow;
5809 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5810 0 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5811 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5812 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5813 0 : ShowContinueError(state,
5814 0 : format("Suspicious Cooling Fraction of Autosized Cooling Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5815 : "when cooling coil is present.",
5816 0 : this->m_MaxCoolAirVolFlow));
5817 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5818 0 : errorsFound = true;
5819 : }
5820 : }
5821 0 : this->m_RequestAutoSize = true;
5822 : // AutoSized input is not allowed
5823 : } else {
5824 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5825 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5826 0 : ShowContinueError(state, "Illegal Cooling Fraction of Autosized Cooling Supply Air Flow Rate = Autosize");
5827 0 : errorsFound = true;
5828 : }
5829 : } else {
5830 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5831 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5832 0 : ShowContinueError(state, "Blank field not allowed for Cooling Fraction of Autosized Cooling Supply Air Flow Rate.");
5833 0 : errorsFound = true;
5834 : }
5835 274 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerCoolingCapacity")) {
5836 :
5837 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerCoolingCapacity;
5838 0 : if (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity != -999.0) {
5839 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FlowPerCoolingCapacity;
5840 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5841 0 : if (this->m_MaxCoolAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5842 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5843 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5844 0 : ShowContinueError(state,
5845 0 : format("Suspicious Cooling Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5846 : "cooling coil is present.",
5847 0 : this->m_MaxCoolAirVolFlow));
5848 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5849 0 : errorsFound = true;
5850 : }
5851 : }
5852 0 : this->m_RequestAutoSize = true;
5853 : // AutoSized input is not allowed
5854 : } else {
5855 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5856 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5857 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Unit of Capacity = Autosize");
5858 0 : errorsFound = true;
5859 : }
5860 : } else {
5861 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5862 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5863 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Unit of Capacity.");
5864 0 : errorsFound = true;
5865 : }
5866 :
5867 274 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "None") || loc_m_CoolingSAFMethod == "") {
5868 274 : this->m_CoolingSAFMethod = DataSizing::None;
5869 274 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow == 0) {
5870 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5871 0 : if (this->m_HeatCoilExists) {
5872 0 : ShowContinueError(state, "Blank field not allowed for this coil type when heating coil air flow rate is not AutoSized.");
5873 : } else {
5874 0 : ShowContinueError(state, "Blank field not allowed for this type of cooling coil.");
5875 : }
5876 0 : errorsFound = true;
5877 : }
5878 : }
5879 :
5880 : // Determine supply air flow rate sizing method for heating mode
5881 736 : if (Util::SameString(loc_m_HeatingSAFMethod, "SupplyAirFlowRate")) {
5882 446 : this->m_HeatingSAFMethod = DataSizing::SupplyAirFlowRate;
5883 446 : if (loc_m_HeatingSAFMethod_SAFlow != -999.0) {
5884 446 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlow;
5885 446 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
5886 386 : this->m_RequestAutoSize = true;
5887 : } else {
5888 60 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5889 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5890 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5891 0 : ShowContinueError(
5892 : state,
5893 0 : format("Suspicious Heating Supply Air Flow Rate = {:.7R} when heating coil is present.", this->m_MaxHeatAirVolFlow));
5894 : }
5895 60 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5896 0 : errorsFound = true;
5897 : }
5898 : }
5899 : } else {
5900 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5901 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5902 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate.");
5903 0 : errorsFound = true;
5904 : }
5905 290 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerFloorArea")) {
5906 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerFloorArea;
5907 0 : if (loc_m_HeatingSAFMethod_SAFlowPerFloorArea != -999.0) {
5908 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlowPerFloorArea;
5909 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5910 0 : if (this->m_MaxHeatAirVolFlow <= 0.0001 && this->m_HeatCoilExists) {
5911 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5912 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5913 0 : ShowContinueError(
5914 : state,
5915 0 : format("Suspicious Heating Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when heating coil is present.",
5916 0 : this->m_MaxHeatAirVolFlow));
5917 : }
5918 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5919 0 : errorsFound = true;
5920 : }
5921 0 : this->m_MaxHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5922 0 : this->m_RequestAutoSize = true;
5923 : } else {
5924 : // AutoSized input is not allowed
5925 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5926 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5927 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Floor Area = Autosize");
5928 0 : errorsFound = true;
5929 : }
5930 : } else {
5931 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5932 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5933 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Floor Area.");
5934 0 : errorsFound = true;
5935 : }
5936 290 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FractionOfAutosizedHeatingValue")) {
5937 0 : this->m_HeatingSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5938 0 : if (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5939 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow;
5940 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5941 0 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5942 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5943 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5944 0 : ShowContinueError(state,
5945 0 : format("Suspicious Heating Fraction of Autosized Heating Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5946 : "when heating coil is present.",
5947 0 : this->m_MaxHeatAirVolFlow));
5948 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5949 0 : errorsFound = true;
5950 : }
5951 : }
5952 0 : this->m_RequestAutoSize = true;
5953 : // AutoSized input is not allowed
5954 : } else {
5955 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5956 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5957 0 : ShowContinueError(state, "Illegal input for Heating Fraction of Autosized Heating Supply Air Flow Rate = Autosize");
5958 0 : errorsFound = true;
5959 : }
5960 : } else {
5961 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5962 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5963 0 : ShowContinueError(state, "Blank field not allowed for Heating Fraction of Autosized Heating Supply Air Flow Rate");
5964 0 : errorsFound = true;
5965 : }
5966 290 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerHeatingCapacity")) {
5967 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerHeatingCapacity;
5968 0 : if (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity != -999.0) {
5969 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FlowPerHeatingCapacity;
5970 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5971 0 : if (this->m_MaxHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5972 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5973 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5974 0 : ShowContinueError(state,
5975 0 : format("Suspicious Heating Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5976 : "heating coil is present.",
5977 0 : this->m_MaxHeatAirVolFlow));
5978 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5979 0 : errorsFound = true;
5980 : }
5981 : }
5982 0 : this->m_RequestAutoSize = true;
5983 : // AutoSized input is not allowed
5984 : } else {
5985 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5986 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5987 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Unit of Capacity = Autosize");
5988 0 : errorsFound = true;
5989 : }
5990 : } else {
5991 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5992 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity");
5993 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Unit of Capacity");
5994 0 : errorsFound = true;
5995 : }
5996 290 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "None") || loc_m_HeatingSAFMethod == "") {
5997 290 : this->m_HeatingSAFMethod = DataSizing::None;
5998 290 : if (this->m_HeatCoilExists && this->m_MaxHeatAirVolFlow == 0) {
5999 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6000 0 : if (loc_m_HeatingSAFMethod == "") {
6001 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method is blank.");
6002 : } else {
6003 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = None.");
6004 : }
6005 0 : if (this->m_CoolCoilExists) {
6006 0 : ShowContinueError(state, "Blank field not allowed for this coil type when cooling coil air flow rate is not AutoSized.");
6007 : } else {
6008 0 : ShowContinueError(state, "Blank field not allowed for this type of heating coil.");
6009 : }
6010 0 : errorsFound = true;
6011 : }
6012 : }
6013 :
6014 : // Determine supply air flow rate sizing method when cooling or heating is not needed
6015 736 : if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "SupplyAirFlowRate")) {
6016 442 : this->m_NoCoolHeatSAFMethod = DataSizing::SupplyAirFlowRate;
6017 442 : if (loc_m_NoCoolHeatSAFMethod_SAFlow != -999.0) {
6018 442 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlow;
6019 442 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
6020 260 : this->m_RequestAutoSize = true;
6021 : } else {
6022 182 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6023 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6024 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
6025 0 : ShowContinueError(state, format("Illegal No Load Supply Air Flow Rate = {:.7R}", this->m_MaxNoCoolHeatAirVolFlow));
6026 0 : errorsFound = true;
6027 : }
6028 : }
6029 :
6030 : } else {
6031 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6032 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
6033 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate");
6034 0 : errorsFound = true;
6035 : }
6036 294 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerFloorArea")) {
6037 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerFloorArea;
6038 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea != -999.0) {
6039 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea;
6040 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6041 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.0001) {
6042 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6043 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6044 0 : ShowContinueError(
6045 : state,
6046 0 : format("Suspicious No Load Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2]", this->m_MaxNoCoolHeatAirVolFlow));
6047 : }
6048 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6049 0 : errorsFound = true;
6050 : }
6051 0 : this->m_MaxNoCoolHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
6052 0 : this->m_RequestAutoSize = true;
6053 : } else {
6054 : // AutoSized input is not allowed
6055 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6056 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6057 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Floor Area = Autosize");
6058 0 : errorsFound = true;
6059 : }
6060 : } else {
6061 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6062 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6063 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Floor Area");
6064 0 : errorsFound = true;
6065 : }
6066 294 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedCoolingValue")) {
6067 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
6068 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
6069 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow;
6070 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6071 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
6072 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6073 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
6074 0 : ShowContinueError(
6075 : state,
6076 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/m3].",
6077 0 : this->m_MaxNoCoolHeatAirVolFlow));
6078 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6079 0 : errorsFound = true;
6080 : }
6081 : }
6082 0 : this->m_RequestAutoSize = true;
6083 : // AutoSized input is not allowed
6084 : } else {
6085 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6086 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue");
6087 0 : ShowContinueError(state,
6088 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
6089 0 : errorsFound = true;
6090 : }
6091 : } else {
6092 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6093 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
6094 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
6095 0 : errorsFound = true;
6096 : }
6097 294 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedHeatingValue")) {
6098 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
6099 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
6100 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow;
6101 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6102 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
6103 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6104 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
6105 0 : ShowContinueError(
6106 : state,
6107 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/m3].",
6108 0 : this->m_MaxNoCoolHeatAirVolFlow));
6109 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6110 0 : errorsFound = true;
6111 : }
6112 : }
6113 0 : this->m_RequestAutoSize = true;
6114 : // AutoSized input is not allowed
6115 : } else {
6116 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6117 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
6118 0 : ShowContinueError(state,
6119 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
6120 0 : errorsFound = true;
6121 : }
6122 : } else {
6123 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6124 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
6125 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
6126 0 : errorsFound = true;
6127 : }
6128 294 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerCoolingCapacity")) {
6129 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerCoolingCapacity;
6130 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity != -999.0) {
6131 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity;
6132 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6133 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
6134 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6135 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6136 0 : ShowContinueError(
6137 : state,
6138 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/W].",
6139 0 : this->m_MaxNoCoolHeatAirVolFlow));
6140 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6141 0 : errorsFound = true;
6142 : }
6143 : }
6144 0 : this->m_RequestAutoSize = true;
6145 : // AutoSized input is not allowed
6146 : } else {
6147 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6148 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6149 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
6150 0 : errorsFound = true;
6151 : }
6152 : } else {
6153 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6154 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6155 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
6156 0 : errorsFound = true;
6157 : }
6158 294 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerHeatingCapacity")) {
6159 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerHeatingCapacity;
6160 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity != -999.0) {
6161 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity;
6162 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6163 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
6164 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6165 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6166 0 : ShowContinueError(
6167 : state,
6168 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/W].",
6169 0 : this->m_MaxNoCoolHeatAirVolFlow));
6170 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6171 0 : errorsFound = true;
6172 : }
6173 : }
6174 0 : this->m_RequestAutoSize = true;
6175 : // AutoSized input is not allowed
6176 : } else {
6177 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6178 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6179 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
6180 0 : errorsFound = true;
6181 : }
6182 : } else {
6183 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6184 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6185 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
6186 0 : errorsFound = true;
6187 : }
6188 294 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "None") || loc_m_NoCoolHeatSAFMethod == "") {
6189 294 : this->m_NoCoolHeatSAFMethod = DataSizing::None;
6190 294 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6191 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlow == -99999.0) { // no load air flow is autosized
6192 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6193 0 : this->m_RequestAutoSize = true;
6194 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == -999.0) { // no load air flow is blank
6195 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6196 0 : this->m_RequestAutoSize = true;
6197 0 : ShowWarningError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6198 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6199 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be blank.");
6200 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate has been set to AutoSize and the simulation continues.");
6201 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == 0.0) { // no load air flow for SZVAV cannot be 0
6202 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6203 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6204 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
6205 0 : errorsFound = true;
6206 : }
6207 : }
6208 : }
6209 736 : if (this->input_specs.no_load_supply_air_flow_rate_low_speed == "NO") {
6210 54 : this->m_useNoLoadLowSpeedAirFlow = false;
6211 : }
6212 :
6213 : // check supply air flow calculation method
6214 736 : if (this->m_FanExists) {
6215 462 : if (this->m_CoolCoilExists) {
6216 462 : if (loc_m_CoolingSAFMethod.empty()) {
6217 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6218 0 : ShowContinueError(state,
6219 : "Method used to determine the cooling supply air flow rate is not specified when cooling coil is present.");
6220 : // check if all cooling flow calc method fields are blank
6221 0 : if (((loc_m_CoolingSAFMethod_SAFlow == -999.0) && (loc_m_CoolingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6222 0 : (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow == -999.0) &&
6223 : (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity == -999.0))) {
6224 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate field is blank.");
6225 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Floor Area field is blank.");
6226 0 : ShowContinueError(state, "Cooling Fraction of Autosized Cooling Supply Air Flow Rate field is blank.");
6227 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Unit of Capacity field is blank.");
6228 0 : ShowContinueError(state,
6229 : "Blank field not allowed for all four cooling supply air flow rate calculation methods when "
6230 : "cooling coil is present.");
6231 : }
6232 : }
6233 : // set fan info for cooling coils
6234 462 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6235 462 : state, this->m_CoolingCoilName, input_data.cooling_coil_object_type, this->m_FanName, this->m_FanType, this->m_FanIndex);
6236 : }
6237 462 : if (this->m_HeatCoilExists) {
6238 446 : if (loc_m_HeatingSAFMethod.empty()) {
6239 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6240 0 : ShowContinueError(state,
6241 : "Method used to determine the heating supply air flow rate is not specified when heating coil is present.");
6242 : // check if all heating flow calc method fields are blank
6243 0 : if (((loc_m_HeatingSAFMethod_SAFlow == -999.0) && (loc_m_HeatingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6244 0 : (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow == -999.0) &&
6245 : (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity == -999.0))) {
6246 0 : ShowContinueError(state, "Heating Supply Air Flow Rate field is blank.");
6247 0 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Floor Area field is blank.");
6248 0 : ShowContinueError(state, "Heating Fraction of Autosized Heating Supply Air Flow Rate field is blank.");
6249 0 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Unit of Capacity field is blank.");
6250 0 : ShowContinueError(state,
6251 : "Blank field not allowed for all four heating supply air flow rate calculation methods when heating "
6252 : "coil is present.");
6253 : }
6254 : }
6255 : // set fan info for heating coils
6256 446 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6257 446 : state, this->m_HeatingCoilName, this->m_HeatingCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
6258 : }
6259 : }
6260 :
6261 : // Fan operating mode (cycling or constant) schedule. IF constant fan, then set AirFlowControl
6262 736 : if (this->m_fanOpModeSched != nullptr) {
6263 456 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6264 : // set fan operating mode to continuous so sizing can set VS coil data
6265 242 : this->m_FanOpMode = HVAC::FanOp::Continuous;
6266 : // set air flow control mode:
6267 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6268 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6269 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6270 242 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6271 39 : this->m_AirFlowControl = UseCompFlow::On;
6272 : } else {
6273 203 : this->m_AirFlowControl = UseCompFlow::Off;
6274 : }
6275 : }
6276 : }
6277 :
6278 736 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6279 4 : int numCoolingCoilModes = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getNumModes();
6280 4 : if (numCoolingCoilModes == 1) {
6281 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6282 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6283 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6284 0 : ShowContinueError(
6285 : state,
6286 0 : format("Cooling coil named: {} has only one mode", state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].name));
6287 0 : ShowFatalError(state, "Multimode cooling coil error causes program termination");
6288 : }
6289 736 : } else if (this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted &&
6290 729 : this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingTwoStageWHumControl &&
6291 720 : this->m_CoolingCoilType_Num != HVAC::CoilWater_CoolingHXAssisted && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6292 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6293 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6294 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6295 0 : if (this->m_SuppHeatCoilName == "" && this->m_SuppHeatCoilTypeName == "") {
6296 : } else {
6297 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
6298 0 : ShowContinueError(state, "Dehumidification control type is assumed to be None and the simulation continues.");
6299 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6300 : } else {
6301 0 : ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
6302 0 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
6303 : }
6304 : }
6305 : }
6306 :
6307 : // Check placement of cooling coil with respect to fan placement and dehumidification control type
6308 :
6309 736 : if (this->m_FanExists) {
6310 462 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6311 300 : if (FanOutletNode == HeatingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6312 23 : this->m_CoolingCoilUpstream = false;
6313 : }
6314 162 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) {
6315 162 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6316 0 : this->m_CoolingCoilUpstream = false;
6317 : }
6318 : }
6319 : } else {
6320 274 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6321 0 : this->m_CoolingCoilUpstream = false;
6322 : }
6323 274 : if (ZoneEquipmentFound) {
6324 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6325 0 : ShowContinueError(state, "ZoneHVAC equipment must contain a fan object.");
6326 0 : ShowContinueError(state, format("specified Supply Fan Object Type = {}", loc_fanType));
6327 0 : ShowContinueError(state, format("specified Supply Fan Name = {}", loc_m_FanName));
6328 0 : errorsFound = true;
6329 : }
6330 : }
6331 :
6332 : // check node connections
6333 736 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6334 :
6335 300 : int tmpAirInletNode = this->AirInNode;
6336 300 : if (this->OAMixerExists) {
6337 157 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6338 : }
6339 300 : if (FanInletNode != tmpAirInletNode) {
6340 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6341 0 : if (this->OAMixerExists) {
6342 0 : ShowContinueError(state,
6343 : "When a blow through fan is specified, the fan inlet node name must be the same as the outdoor "
6344 : "air mixer mixed air node name.");
6345 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6346 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6347 : } else {
6348 0 : ShowContinueError(state,
6349 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system "
6350 : "inlet node name.");
6351 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6352 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6353 : }
6354 0 : errorsFound = true;
6355 : }
6356 300 : if (this->m_CoolingCoilUpstream) {
6357 277 : if (FanOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6358 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6359 0 : ShowContinueError(state,
6360 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil "
6361 : "inlet node name.");
6362 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6363 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6364 0 : errorsFound = true;
6365 : }
6366 277 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6367 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6368 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6369 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6370 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6371 0 : errorsFound = true;
6372 : }
6373 277 : if (this->m_SuppCoilExists) {
6374 211 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6375 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6376 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6377 0 : ShowContinueError(state,
6378 0 : format("...Reheat coil outlet node name = {}" + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6379 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}" + state.dataLoopNodes->NodeID(this->AirOutNode)));
6380 0 : errorsFound = true;
6381 : }
6382 : } else { // IF((this->m_Humidistat ...
6383 : // Heating coil outlet node name must be the same as the Unitary system outlet node name
6384 66 : if (this->m_HeatCoilExists && HeatingCoilOutletNode != this->AirOutNode) {
6385 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6386 0 : ShowContinueError(state,
6387 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
6388 : "unitary system outlet node name.");
6389 0 : ShowContinueError(state,
6390 0 : format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6391 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6392 0 : errorsFound = true;
6393 : }
6394 : }
6395 : } else { // IF(this->CoolingCoilUpstream)THEN
6396 23 : if (FanOutletNode != HeatingCoilInletNode && this->m_FanExists && this->m_HeatCoilExists) {
6397 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6398 0 : ShowContinueError(state,
6399 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil "
6400 : "inlet node name.");
6401 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6402 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6403 0 : errorsFound = true;
6404 : }
6405 23 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6406 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6407 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6408 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6409 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6410 0 : errorsFound = true;
6411 : }
6412 23 : if (CoolingCoilOutletNode != this->AirOutNode && this->m_CoolCoilExists) {
6413 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6414 0 : ShowContinueError(state,
6415 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the unitary "
6416 : "system outlet node name.");
6417 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6418 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6419 0 : errorsFound = true;
6420 : }
6421 : }
6422 :
6423 436 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) { // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6424 :
6425 162 : int tmpAirInletNode = this->AirInNode;
6426 162 : if (this->OAMixerExists) {
6427 143 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6428 : }
6429 162 : if (this->m_CoolingCoilUpstream) {
6430 162 : if (CoolingCoilInletNode != tmpAirInletNode && CoolingCoilInletNode != 0 && this->m_FanExists) {
6431 0 : if (this->OAMixerExists) {
6432 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6433 0 : ShowContinueError(state,
6434 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the outdoor "
6435 : "air mixer mixed air node name.");
6436 0 : ShowContinueError(state,
6437 0 : format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6438 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6439 : } else {
6440 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6441 0 : ShowContinueError(state,
6442 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary "
6443 : "system inlet node name.");
6444 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6445 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6446 : }
6447 0 : errorsFound = true;
6448 : }
6449 162 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6450 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6451 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6452 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6453 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6454 0 : errorsFound = true;
6455 : }
6456 162 : if (HeatingCoilOutletNode != FanInletNode && this->m_HeatCoilExists && this->m_FanExists) {
6457 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6458 0 : ShowContinueError(state,
6459 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan "
6460 : "inlet node name.");
6461 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6462 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6463 0 : errorsFound = true;
6464 : }
6465 162 : if (this->m_SuppCoilExists) {
6466 16 : if (FanOutletNode != SupHeatCoilInletNode && this->m_FanExists) {
6467 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6468 0 : ShowContinueError(state,
6469 : "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
6470 : "inlet node name.");
6471 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6472 0 : ShowContinueError(state, format("...Reheat coil inlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
6473 0 : errorsFound = true;
6474 : }
6475 16 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6476 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6477 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6478 0 : ShowContinueError(state,
6479 0 : format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6480 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6481 0 : errorsFound = true;
6482 : }
6483 : } else {
6484 146 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6485 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6486 0 : ShowContinueError(state,
6487 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6488 : "outlet node name.");
6489 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6490 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6491 0 : errorsFound = true;
6492 : }
6493 : }
6494 : } else { // IF(this->CoolingCoilUpstream)THEN
6495 0 : if (HeatingCoilInletNode != tmpAirInletNode && HeatingCoilInletNode != 0 && this->m_FanExists) {
6496 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6497 0 : if (this->OAMixerExists) {
6498 0 : ShowContinueError(state,
6499 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6500 : "system mixer mixed air node name.");
6501 0 : ShowContinueError(state,
6502 0 : format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6503 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6504 : } else {
6505 0 : ShowContinueError(state,
6506 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6507 : "system inlet node name.");
6508 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6509 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6510 : }
6511 0 : errorsFound = true;
6512 : }
6513 0 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_HeatCoilExists && this->m_CoolCoilExists) {
6514 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6515 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6516 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6517 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6518 0 : errorsFound = true;
6519 : }
6520 0 : if (CoolingCoilOutletNode != FanInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6521 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6522 0 : ShowContinueError(state,
6523 : "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan "
6524 : "inlet node name.");
6525 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6526 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6527 0 : errorsFound = true;
6528 : }
6529 0 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6530 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6531 0 : ShowContinueError(state,
6532 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6533 : "outlet node name.");
6534 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6535 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6536 0 : errorsFound = true;
6537 : }
6538 : }
6539 : } // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6540 :
6541 : // Set the unitary system supplemental heater max outlet temperature
6542 : // this field will be 0 if the input is not specified (included) in the input file
6543 : // someone may use a default other than what we intended, allow it to be used
6544 : // so if this field is blank, and the input field is included, read the default, otherwise use 80
6545 : // if (!lNumericBlanks(iDesignMaxOutletTempNumericNum) && NumNumbers > (iDesignMaxOutletTempNumericNum - 1)) {
6546 736 : if (this->m_sysType == SysType::Unitary) {
6547 : // UnitarySystem has a single field for max outlet temp
6548 134 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6549 : } else {
6550 : // PTHP has a field for max outlet temp for supplemental heater and max outlet temp for SZVAV
6551 602 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6552 0 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6553 : } else {
6554 602 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature_from_supplemental_heater;
6555 : }
6556 : }
6557 736 : if (this->DesignMaxOutletTemp == DataSizing::AutoSize) {
6558 244 : this->m_RequestAutoSize = true;
6559 : }
6560 : //}
6561 :
6562 : // Set maximum Outdoor air temperature for supplemental heating coil operation
6563 : // this field will be 0 if the input is not specified (included) in the input file
6564 : // someone may use a default other than what we intended, allow it to be used
6565 : // so if this field is blank, and the input field is included, read the default, otherwise use 9999
6566 : // if (!lNumericBlanks(iMaxOATSuppHeatNumericNum) && NumNumbers > (iMaxOATSuppHeatNumericNum - 1)) {
6567 736 : this->m_MaxOATSuppHeat = input_data.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation;
6568 : // Can't let MaxOATSuppHeat default to 21C if using cool reheat since it would shut off supp heater when dehumidifying
6569 : // this may also allow supplemental heater to operate when in heating mode when it should not
6570 736 : if (this->m_MaxOATSuppHeat == 21.0 && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6571 13 : this->m_MaxOATSuppHeat = 999.0;
6572 : }
6573 736 : if (this->m_SuppCoilExists) {
6574 454 : OutputReportPredefined::PreDefTableEntry(
6575 227 : state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, this->m_HeatingCoilName, this->m_MaxOATSuppHeat);
6576 : }
6577 :
6578 736 : if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 &&
6579 60 : !this->m_RequestAutoSize) {
6580 13 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6581 723 : } else if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6582 44 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6583 679 : } else if (this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6584 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6585 : } else {
6586 679 : if (this->m_FanExists && this->m_DesignFanVolFlowRate == 0.0) {
6587 0 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
6588 : }
6589 : // need more of this type of warning when flow cannot be determined
6590 679 : if (this->m_MaxHeatAirVolFlow == 0.0 && this->m_HeatCoilExists) {
6591 0 : if (this->m_FanExists) {
6592 0 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6593 0 : if (this->m_MaxCoolAirVolFlow == 0.0) {
6594 0 : this->m_MaxHeatAirVolFlow = this->m_DesignFanVolFlowRate;
6595 : }
6596 : }
6597 0 : } else if (this->m_CoolCoilExists) {
6598 0 : this->m_MaxHeatAirVolFlow = this->m_MaxCoolAirVolFlow;
6599 : } else {
6600 0 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical &&
6601 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating &&
6602 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed) {
6603 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6604 0 : ShowContinueError(state,
6605 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6606 : "Supply Air Flow Rate Method");
6607 0 : errorsFound = true;
6608 : }
6609 : }
6610 679 : } else if (this->m_MaxHeatAirVolFlow == 0.0 && !this->m_FanExists && !this->m_CoolCoilExists) {
6611 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6612 0 : ShowContinueError(state,
6613 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6614 : "Supply Air Flow Rate Method");
6615 : }
6616 : }
6617 :
6618 736 : if (FanVolFlowRate != DataSizing::AutoSize && this->m_FanExists) {
6619 65 : if (FanVolFlowRate < this->m_MaxCoolAirVolFlow && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize && this->m_CoolCoilExists) {
6620 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6621 0 : ShowContinueError(
6622 : state,
6623 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
6624 : FanVolFlowRate,
6625 0 : this->m_FanName));
6626 0 : ShowContinueError(state, " The Cooling Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6627 0 : this->m_MaxCoolAirVolFlow = FanVolFlowRate;
6628 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6629 : }
6630 65 : if (FanVolFlowRate < this->m_MaxHeatAirVolFlow && this->m_MaxHeatAirVolFlow != DataSizing::AutoSize && this->m_HeatCoilExists) {
6631 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6632 0 : ShowContinueError(
6633 : state,
6634 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
6635 : FanVolFlowRate,
6636 0 : this->m_FanName));
6637 0 : ShowContinueError(state, " The Heating Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6638 0 : this->m_MaxHeatAirVolFlow = FanVolFlowRate;
6639 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6640 : }
6641 : }
6642 :
6643 736 : if (this->m_fanOpModeSched != nullptr) {
6644 456 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6645 : // set air flow control mode:
6646 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6647 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6648 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6649 242 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6650 39 : this->m_AirFlowControl = UseCompFlow::On;
6651 : } else {
6652 203 : this->m_AirFlowControl = UseCompFlow::Off;
6653 : }
6654 : }
6655 : }
6656 :
6657 : // Set minimum OAT for heat pump compressor operation in cooling mode
6658 : // get from coil module
6659 736 : errFlag = false;
6660 736 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6661 384 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6662 352 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6663 49 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6664 303 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6665 38 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6666 265 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6667 9 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6668 256 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6669 11 : this->m_MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6670 245 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
6671 : // already found in getInput
6672 : } else {
6673 191 : this->m_MinOATCompressorCooling = -1000.0;
6674 : }
6675 736 : if (errFlag) {
6676 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6677 0 : errorsFound = true;
6678 0 : errFlag = false;
6679 : }
6680 :
6681 : // Set minimum OAT for heat pump compressor operation in heating mode
6682 : // get from coil module
6683 736 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6684 3 : this->m_MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6685 733 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6686 56 : this->m_MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6687 : } else {
6688 677 : this->m_MinOATCompressorHeating = -1000.0;
6689 : }
6690 736 : if (errFlag) {
6691 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6692 0 : errorsFound = true;
6693 0 : errFlag = false;
6694 : }
6695 :
6696 : // Mine heatpump Outdoor condenser node from DX coil object
6697 736 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6698 384 : this->m_CondenserNodeNum =
6699 384 : DXCoils::GetCoilCondenserInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
6700 : // TODO: Should we add a block for the new DX Coil?
6701 352 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6702 11 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, this->m_CoolingCoilName, errFlag);
6703 341 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
6704 : // already filled
6705 : // UnitarySystem( UnitarySysNum ).CondenserNodeNum = GetDXCoilCondenserInletNode( "Coil:Cooling:DX:SingleSpeed",
6706 : // GetHXDXCoilName(state, CoolingCoilType, this->m_CoolingCoilName, errFlag ), errFlag );
6707 :
6708 : } else {
6709 338 : if (input_data.outdoor_dry_bulb_temperature_sensor_node_name != "") {
6710 292 : this->m_CondenserNodeNum = NodeInputManager::GetOnlySingleNode(state,
6711 146 : input_data.outdoor_dry_bulb_temperature_sensor_node_name,
6712 : errFlag,
6713 : objType,
6714 : thisObjectName,
6715 : DataLoopNode::NodeFluidType::Air,
6716 : DataLoopNode::ConnectionType::Inlet,
6717 : NodeInputManager::CompFluidStream::Primary,
6718 : DataLoopNode::ObjectIsParent);
6719 : } else {
6720 : // do nothing?
6721 : }
6722 : }
6723 736 : if (errFlag) {
6724 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6725 0 : errorsFound = true;
6726 0 : errFlag = false;
6727 : }
6728 :
6729 736 : this->m_AncillaryOnPower = input_data.ancillary_on_cycle_electric_power;
6730 736 : this->m_AncillaryOffPower = input_data.ancillary_off_cycle_electric_power;
6731 736 : this->m_MaxHROutletWaterTemp = input_data.maximum_temperature_for_heat_recovery;
6732 :
6733 736 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
6734 0 : this->m_HeatRecActive = true;
6735 0 : if (input_data.heat_recovery_water_inlet_node_name != "" && input_data.heat_recovery_water_outlet_node_name != "") {
6736 0 : this->m_HeatRecoveryInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6737 0 : input_data.heat_recovery_water_inlet_node_name,
6738 : errFlag,
6739 : objType,
6740 : thisObjectName,
6741 : DataLoopNode::NodeFluidType::Water,
6742 : DataLoopNode::ConnectionType::Inlet,
6743 : NodeInputManager::CompFluidStream::Tertiary,
6744 : DataLoopNode::ObjectIsNotParent);
6745 0 : this->m_HeatRecoveryOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6746 0 : input_data.heat_recovery_water_outlet_node_name,
6747 : errFlag,
6748 : objType,
6749 : thisObjectName,
6750 : DataLoopNode::NodeFluidType::Water,
6751 : DataLoopNode::ConnectionType::Outlet,
6752 : NodeInputManager::CompFluidStream::Tertiary,
6753 : DataLoopNode::ObjectIsNotParent);
6754 :
6755 0 : BranchNodeConnections::TestCompSet(state,
6756 : cCurrentModuleObject,
6757 : thisObjectName,
6758 0 : input_data.heat_recovery_water_inlet_node_name,
6759 0 : input_data.heat_recovery_water_outlet_node_name,
6760 : "Unitary System Heat Recovery Nodes");
6761 :
6762 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6763 0 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_CoolingCoilIndex);
6764 : }
6765 0 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6766 0 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_HeatingCoilIndex);
6767 : }
6768 0 : if (errFlag) {
6769 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6770 0 : errorsFound = true;
6771 : // errFlag = false; // not used after this point, uncomment if needed
6772 : }
6773 : } else {
6774 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6775 0 : ShowContinueError(state, format("Illegal Heat Recovery Water Inlet Node Name = {}", input_data.heat_recovery_water_inlet_node_name));
6776 0 : ShowContinueError(state,
6777 0 : format("Illegal Heat Recovery Water Outlet Node Name = {}", input_data.heat_recovery_water_outlet_node_name));
6778 0 : ShowContinueError(state,
6779 : "... heat recovery nodes must be specified when Design Heat Recovery Water Flow Rate"
6780 : " is greater than 0.");
6781 0 : ShowContinueError(state, format("... Design Heat Recovery Water Flow Rate = {:.7R}", this->m_DesignHRWaterVolumeFlow));
6782 0 : errorsFound = true;
6783 : }
6784 : }
6785 :
6786 736 : if (!this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) {
6787 :
6788 62 : if (this->m_DesignSpecMSHPIndex > -1) {
6789 :
6790 62 : this->m_NoLoadAirFlowRateRatio = this->m_CompPointerMSHP->noLoadAirFlowRateRatio;
6791 :
6792 62 : switch (this->m_HeatingCoilType_Num) {
6793 15 : case HVAC::CoilDX_MultiSpeedHeating:
6794 : case HVAC::Coil_HeatingElectric_MultiStage:
6795 : case HVAC::Coil_HeatingGas_MultiStage:
6796 : case HVAC::Coil_HeatingWaterToAirHPSimple:
6797 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
6798 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6799 15 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6800 15 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6801 15 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6802 15 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling < this->m_NumOfSpeedHeating) {
6803 0 : this->FullOutput.resize(this->m_NumOfSpeedHeating + 1);
6804 : }
6805 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple && this->m_NumOfSpeedHeating > 1) {
6806 1 : this->m_MultiSpeedHeatingCoil = true;
6807 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6808 : }
6809 65 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6810 50 : this->m_HeatMassFlowRate[i] = 0.0;
6811 50 : this->m_HeatVolumeFlowRate[i] = 0.0;
6812 50 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6813 : }
6814 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
6815 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6816 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_HeatingCoilName, errorsFound);
6817 1 : if (errorsFound) {
6818 0 : ShowSevereError(state,
6819 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_HeatingCoilName));
6820 : }
6821 1 : if (NumOfSpeed != this->m_NumOfSpeedHeating) {
6822 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_HeatingCoilName));
6823 0 : ShowContinueError(state,
6824 0 : format("... The number of heating coil speeds in the {} = {:.0R}",
6825 : MultispeedType,
6826 0 : double(this->m_NumOfSpeedHeating)));
6827 0 : ShowContinueError(
6828 : state,
6829 0 : format("... The number of heating coil speeds in Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6830 0 : double(NumOfSpeed)));
6831 0 : ShowContinueError(state, format("... The number of heating coil speeds in the {} will be used.", MultispeedType));
6832 : }
6833 1 : }
6834 15 : } break;
6835 : }
6836 62 : switch (this->m_CoolingCoilType_Num) {
6837 40 : case HVAC::CoilDX_MultiSpeedCooling:
6838 : case HVAC::Coil_CoolingWaterToAirHPSimple:
6839 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
6840 40 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6841 40 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6842 40 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6843 40 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6844 40 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > this->m_NumOfSpeedHeating) {
6845 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
6846 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
6847 : }
6848 40 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple && this->m_NumOfSpeedCooling > 1) {
6849 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6850 1 : this->m_DiscreteSpeedCoolingCoil = true;
6851 : }
6852 131 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6853 91 : this->m_CoolMassFlowRate[i] = 0.0;
6854 91 : this->m_CoolVolumeFlowRate[i] = 0.0;
6855 91 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6856 : }
6857 40 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
6858 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6859 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_CoolingCoilName, errorsFound);
6860 1 : if (errorsFound) {
6861 0 : ShowSevereError(state,
6862 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_CoolingCoilName));
6863 : }
6864 1 : if (NumOfSpeed != this->m_NumOfSpeedCooling) {
6865 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_CoolingCoilName));
6866 0 : ShowContinueError(state,
6867 0 : format("... The number of Cooling coil speeds in the {} = {:.0R}",
6868 : MultispeedType,
6869 0 : double(this->m_NumOfSpeedCooling)));
6870 0 : ShowContinueError(
6871 : state,
6872 0 : format("... The number of heating coil speeds in Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6873 0 : double(NumOfSpeed)));
6874 0 : ShowContinueError(state, format("... The number of Cooling coil speeds in the {} will be used.", MultispeedType));
6875 : }
6876 1 : }
6877 40 : } break;
6878 : }
6879 : } else {
6880 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6881 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6882 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6883 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6884 0 : errorsFound = true;
6885 : }
6886 674 : } else if (this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty()) {
6887 674 : if (this->m_FanType == HVAC::FanType::SystemModel) {
6888 43 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex));
6889 43 : assert(fanSystem != nullptr);
6890 43 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
6891 40 : if (fanSystem->numSpeeds > 1) {
6892 2 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6893 1 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6894 1 : this->m_sysType == SysType::PackagedWSHP) {
6895 1 : this->m_NumOfSpeedCooling = fanSystem->numSpeeds;
6896 1 : this->m_CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6897 1 : this->m_CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
6898 1 : this->m_MSCoolingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6899 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6900 1 : this->m_DiscreteSpeedCoolingCoil = true;
6901 1 : if (fanSystem->maxAirFlowRate > 0.0) {
6902 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6903 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6904 0 : this->m_CoolVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6905 0 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6906 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6907 : }
6908 : } else {
6909 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6910 0 : this->m_CoolMassFlowRate[i] = 0.0;
6911 0 : this->m_CoolVolumeFlowRate[i] = 0.0;
6912 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6913 : }
6914 : }
6915 : }
6916 : }
6917 2 : if ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6918 1 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6919 1 : this->m_sysType == SysType::PackagedWSHP) {
6920 1 : this->m_NumOfSpeedHeating = fanSystem->numSpeeds;
6921 1 : this->m_HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6922 1 : this->m_HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
6923 1 : this->m_MSHeatingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6924 1 : this->m_MultiSpeedHeatingCoil = true;
6925 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6926 1 : if (fanSystem->maxAirFlowRate > 0.0) {
6927 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
6928 0 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6929 0 : this->m_HeatVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6930 0 : this->m_HeatMassFlowRate[i] = this->m_HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6931 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6932 : }
6933 : } else {
6934 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6935 0 : this->m_HeatMassFlowRate[i] = 0.0;
6936 0 : this->m_HeatVolumeFlowRate[i] = 0.0;
6937 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6938 : }
6939 : }
6940 : }
6941 : }
6942 2 : if (((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6943 1 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6944 1 : this->m_sysType == SysType::PackagedWSHP) ||
6945 1 : ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6946 1 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6947 0 : this->m_sysType == SysType::PackagedWSHP)) {
6948 2 : ShowWarningError(state,
6949 2 : format("{} = {} with Fan:SystemModel is used in \"{}\"",
6950 : cCurrentModuleObject,
6951 1 : this->Name,
6952 1 : this->input_specs.supply_fan_name));
6953 1 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
6954 3 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
6955 : }
6956 : }
6957 : }
6958 : }
6959 0 : } else if ((this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) ||
6960 0 : (!this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty())) {
6961 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6962 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6963 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6964 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6965 0 : errorsFound = true;
6966 : }
6967 :
6968 736 : if (this->m_DiscreteSpeedCoolingCoil) {
6969 :
6970 77 : if (this->m_NumOfSpeedCooling == 0) {
6971 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6972 0 : ShowContinueError(state,
6973 0 : format("... Cooling coil object type requires valid {} for cooling to be specified with number of speeds > 0",
6974 : unitarySysHeatPumpPerformanceObjectType));
6975 0 : errorsFound = true;
6976 : }
6977 : }
6978 736 : if (this->m_MultiSpeedHeatingCoil) {
6979 :
6980 16 : if (this->m_DesignSpecMSHPIndex > -1) {
6981 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6982 : }
6983 :
6984 16 : if (this->m_NumOfSpeedHeating == 0) {
6985 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6986 0 : ShowContinueError(state,
6987 0 : format("... Heating coil object type requires valid {} for heating to be specified with number of speeds > 0",
6988 : unitarySysHeatPumpPerformanceObjectType));
6989 0 : errorsFound = true;
6990 : }
6991 : }
6992 :
6993 736 : if ((this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating &&
6994 13 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling)) ||
6995 724 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel &&
6996 79 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling))) {
6997 67 : if (this->m_DesignSpecMSHPIndex > -1) {
6998 53 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
6999 1 : this->m_SingleMode = 1;
7000 : }
7001 : }
7002 : } else {
7003 669 : if (this->m_DesignSpecMSHPIndex > -1) {
7004 9 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
7005 0 : ShowSevereError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7006 0 : ShowContinueError(state,
7007 : "In order to perform Single Mode Operation, the valid cooling coil type is Coil:Cooling:DX:MultiSpeed "
7008 : "or Coil:Cooling:DX and the valid heating is Coil:Heating:DX:MultiSpeed or Coil:Heating:Fuel.");
7009 0 : ShowContinueError(state,
7010 0 : format("The input cooling coil type = {} and the input heating coil type = {}",
7011 0 : input_data.cooling_coil_object_type,
7012 0 : this->m_HeatingCoilTypeName));
7013 : }
7014 : }
7015 : }
7016 :
7017 736 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
7018 11 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
7019 : }
7020 :
7021 736 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
7022 3 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_HeatingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
7023 : }
7024 :
7025 : // set global logicals that denote coil type
7026 736 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
7027 23 : this->m_MultiOrVarSpeedHeatCoil = true;
7028 : }
7029 736 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
7030 93 : this->m_MultiOrVarSpeedCoolCoil = true;
7031 : }
7032 :
7033 : // set global variables for multi-stage chilled and hot water coils
7034 736 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
7035 20 : if (this->m_DesignSpecMSHPIndex > -1) {
7036 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
7037 1 : if (this->m_NumOfSpeedCooling > 1) {
7038 1 : this->m_DiscreteSpeedCoolingCoil = true;
7039 1 : this->m_MultiOrVarSpeedCoolCoil = true;
7040 : }
7041 : }
7042 : }
7043 736 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
7044 : // designSpecIndex = this->m_DesignSpecMSHPIndex;
7045 9 : if (this->m_DesignSpecMSHPIndex > -1) {
7046 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
7047 1 : if (this->m_NumOfSpeedHeating > 1) {
7048 1 : this->m_MultiSpeedHeatingCoil = true;
7049 1 : this->m_MultiOrVarSpeedHeatCoil = true;
7050 : }
7051 : }
7052 : }
7053 : // zone coils are now simulated before sizing is complete, data will not be available but array is allocated
7054 736 : if (this->m_MultiOrVarSpeedCoolCoil) {
7055 142 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
7056 142 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
7057 142 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
7058 : }
7059 736 : if (this->m_MultiOrVarSpeedHeatCoil) {
7060 23 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
7061 23 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
7062 23 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
7063 : }
7064 :
7065 : // check for specific input requirements for ASHRAE90.1 model
7066 736 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
7067 :
7068 : // only allowed for water and DX cooling coils at this time
7069 0 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWater &&
7070 0 : this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterDetailed && this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingSingleSpeed) {
7071 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7072 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7073 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific cooling coil types.");
7074 0 : ShowContinueError(state,
7075 : "Valid cooling coil types are Coil:Cooling:Water, Coil:Cooling:Water:DetailedGeometry and "
7076 : "Coil:Cooling:DX:SingleSpeed.");
7077 0 : ShowContinueError(state,
7078 0 : format("The input cooling coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
7079 0 : input_data.cooling_coil_object_type));
7080 : }
7081 : // mark this coil as non-ASHRAE90 type
7082 0 : this->m_ValidASHRAECoolCoil = false;
7083 : }
7084 : // only allow for water, fuel, or electric at this time
7085 0 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWater &&
7086 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingGasOrOtherFuel && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingElectric &&
7087 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical) {
7088 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7089 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7090 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific heating coil types.");
7091 0 : ShowContinueError(state,
7092 : "Valid heating coil types are Coil:Heating:Water, Coil:Heating:Fuel, Coil:Heating:Electric and "
7093 : "Coil:Heating:DX:SingleSpeed.");
7094 0 : ShowContinueError(state,
7095 0 : format("The input heating coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
7096 0 : this->m_HeatingCoilTypeName));
7097 : }
7098 : // mark this coil as non-ASHRAE90 type
7099 0 : this->m_ValidASHRAEHeatCoil = false;
7100 : }
7101 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
7102 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7103 0 : ShowContinueError(state, format("Invalid entry for Dehumidification Control Type = {}", input_data.dehumidification_control_type));
7104 0 : ShowContinueError(state,
7105 : "ASHRAE90.1 control method does not support dehumidification at this time. Dehumidification control type is "
7106 : "assumed to be None.");
7107 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
7108 : }
7109 0 : if (this->m_RunOnLatentLoad) {
7110 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
7111 0 : ShowContinueError(state, format("Invalid entry for Latent Load Control: {}", input_data.latent_load_control));
7112 0 : ShowContinueError(state,
7113 : "ASHRAE90.1 control method does not support latent load control at this time. This input must be selected as "
7114 : "SensibleOnlyLoadControl.");
7115 0 : this->m_RunOnSensibleLoad = true;
7116 0 : this->m_RunOnLatentLoad = false;
7117 0 : this->m_RunOnLatentOnlyWithSensible = false;
7118 : }
7119 0 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) { // 0 min air flow not allowed for SZVAV
7120 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
7121 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
7122 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
7123 0 : errorsFound = true;
7124 : }
7125 : }
7126 736 : }
7127 :
7128 901 : void UnitarySys::getDXCoilSystemData(
7129 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7130 : {
7131 901 : std::string const cCurrentModuleObject = "CoilSystem:Cooling:DX";
7132 901 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7133 901 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7134 445 : auto &instancesValue = instances.value();
7135 445 : int numCoilSystemDX = 0;
7136 2886 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7137 :
7138 2441 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7139 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7140 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7141 2441 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7142 1903 : continue;
7143 : }
7144 :
7145 538 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7146 538 : UnitarySys thisSys;
7147 538 : if (sysNum == -1) {
7148 269 : ++state.dataUnitarySystems->numUnitarySystems;
7149 269 : auto const &thisObjName = instance.key();
7150 269 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7151 : } else {
7152 269 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7153 : }
7154 :
7155 : // get CoilSystem:Cooling:DX object inputs
7156 538 : auto const &fields = instance.value();
7157 538 : thisSys.input_specs.name = thisObjectName;
7158 538 : thisSys.input_specs.system_type = cCurrentModuleObject;
7159 1076 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7160 524 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7161 538 : }
7162 : thisSys.input_specs.air_inlet_node_name =
7163 1076 : Util::makeUPPER(fields.at("dx_cooling_coil_system_inlet_node_name").get<std::string>()); // required field
7164 : thisSys.input_specs.air_outlet_node_name =
7165 1076 : Util::makeUPPER(fields.at("dx_cooling_coil_system_outlet_node_name").get<std::string>()); // required field
7166 :
7167 : thisSys.input_specs.dx_cooling_coil_system_sensor_node_name =
7168 1076 : Util::makeUPPER(fields.at("dx_cooling_coil_system_sensor_node_name").get<std::string>()); // required field
7169 :
7170 : thisSys.input_specs.cooling_coil_object_type =
7171 1076 : Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>()); // required field
7172 1076 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>()); // required field
7173 : // min-fields = 7, begin optional inputs
7174 1076 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field
7175 : thisSys.input_specs.dehumidification_control_type =
7176 38 : it.value().get<std::string>(); // Don't capitalize this one, since it's an enum
7177 : } else {
7178 : // find default value
7179 500 : thisSys.input_specs.dehumidification_control_type = "None";
7180 538 : }
7181 1076 : std::string loc_RunOnSensLoad("");
7182 1076 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) { // not required field
7183 36 : loc_RunOnSensLoad = Util::makeUPPER(it.value().get<std::string>());
7184 : } else {
7185 : // find default value
7186 502 : loc_RunOnSensLoad = "YES";
7187 538 : }
7188 1076 : std::string loc_RunOnLatLoad("");
7189 1076 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) { // not required field
7190 36 : loc_RunOnLatLoad = Util::makeUPPER(it.value().get<std::string>());
7191 : } else {
7192 : // find default value
7193 502 : loc_RunOnLatLoad = "NO";
7194 538 : }
7195 538 : if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "NO") {
7196 524 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7197 14 : } else if (loc_RunOnSensLoad == "NO" && loc_RunOnLatLoad == "YES") {
7198 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7199 14 : } else if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "YES") {
7200 : // does DX system control on LatentOrSensibleLoadControl or LatentWithSensibleLoadControl?
7201 14 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7202 : }
7203 :
7204 1076 : if (auto it = fields.find("use_outdoor_air_dx_cooling_coil"); it != fields.end()) { // not required field
7205 12 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7206 : } else {
7207 : // find default value
7208 526 : thisSys.input_specs.use_doas_dx_cooling_coil = "NO";
7209 538 : }
7210 1076 : if (auto it = fields.find("outdoor_air_dx_cooling_coil_leaving_minimum_air_temperature"); it != fields.end()) { // not required field
7211 10 : thisSys.input_specs.minimum_supply_air_temperature = it.value().get<Real64>();
7212 538 : }
7213 : // set UnitarySystem specific inputs
7214 538 : thisSys.input_specs.control_type = "SETPOINT";
7215 :
7216 : // now translate to UnitarySystem
7217 538 : thisSys.UnitType = cCurrentModuleObject;
7218 538 : thisSys.m_sysType = SysType::CoilCoolingDX;
7219 538 : thisSys.AirloopEqType = SimAirServingZones::CompType::DXSystem;
7220 :
7221 : // TODO: figure out another way to set this next variable
7222 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7223 538 : thisSys.m_LastMode = CoolingMode;
7224 538 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7225 :
7226 538 : if (sysNum == -1) {
7227 269 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7228 269 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7229 : // zone equipment require a 1-n index for access to zone availability managers
7230 : // although not zone equipment, use same methodology
7231 269 : ++numCoilSystemDX;
7232 269 : thisSys.m_EquipCompNum = numCoilSystemDX;
7233 : } else {
7234 269 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7235 : }
7236 2886 : }
7237 : }
7238 901 : }
7239 :
7240 901 : void UnitarySys::getPackagedTerminalUnitData(
7241 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7242 : {
7243 901 : std::string cCurrentModuleObject = "ZoneHVAC:PackagedTerminalAirConditioner";
7244 901 : SysType sysTypeNum = SysType::PackagedAC;
7245 901 : DataZoneEquipment::ZoneEquipType zoneEqType = DataZoneEquipment::ZoneEquipType::Invalid;
7246 901 : int numPTAC = 0;
7247 901 : int numPTHP = 0;
7248 901 : int numPTWSHP = 0;
7249 901 : auto &ip = state.dataInputProcessing->inputProcessor;
7250 3604 : for (int getPTUnitType = 1; getPTUnitType <= 3; ++getPTUnitType) {
7251 2703 : if (getPTUnitType == 2) {
7252 901 : sysTypeNum = SysType::PackagedHP;
7253 901 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7254 901 : cCurrentModuleObject = "ZoneHVAC:PackagedTerminalHeatPump";
7255 1802 : } else if (getPTUnitType == 3) {
7256 901 : sysTypeNum = SysType::PackagedWSHP;
7257 901 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7258 901 : cCurrentModuleObject = "ZoneHVAC:WaterToAirHeatPump";
7259 : }
7260 2703 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7261 2703 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7262 392 : auto &instancesValue = instances.value();
7263 392 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
7264 22466 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7265 :
7266 22074 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7267 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7268 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7269 22074 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7270 21414 : continue;
7271 : }
7272 :
7273 660 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7274 660 : UnitarySys thisSys;
7275 660 : if (sysNum == -1) {
7276 330 : ++state.dataUnitarySystems->numUnitarySystems;
7277 330 : auto const &thisObjName = instance.key();
7278 330 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7279 : } else {
7280 330 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7281 : }
7282 :
7283 : // get PackagedTerminal unit object inputs
7284 660 : auto const &fields = instance.value();
7285 660 : thisSys.input_specs.name = thisObjectName;
7286 660 : thisSys.input_specs.system_type = cCurrentModuleObject;
7287 1320 : thisSys.input_specs.availability_schedule_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_schedule_name");
7288 1320 : thisSys.input_specs.air_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_inlet_node_name");
7289 1320 : thisSys.input_specs.air_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_outlet_node_name");
7290 :
7291 1320 : thisSys.input_specs.oa_mixer_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_object_type");
7292 1320 : thisSys.input_specs.oa_mixer_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_name");
7293 :
7294 660 : thisSys.input_specs.cooling_supply_air_flow_rate =
7295 1320 : ip->getRealFieldValue(fields, objectSchemaProps, "cooling_supply_air_flow_rate");
7296 660 : thisSys.input_specs.heating_supply_air_flow_rate =
7297 1320 : ip->getRealFieldValue(fields, objectSchemaProps, "heating_supply_air_flow_rate");
7298 660 : thisSys.input_specs.no_load_supply_air_flow_rate =
7299 1320 : ip->getRealFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate");
7300 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed =
7301 1320 : ip->getAlphaFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7302 1320 : thisSys.input_specs.cooling_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_outdoor_air_flow_rate");
7303 1320 : thisSys.input_specs.heating_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "heating_outdoor_air_flow_rate");
7304 1320 : thisSys.input_specs.no_load_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "no_load_outdoor_air_flow_rate");
7305 :
7306 1320 : thisSys.input_specs.supply_fan_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_object_type");
7307 1320 : thisSys.input_specs.supply_fan_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_name");
7308 1320 : thisSys.input_specs.heating_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_object_type");
7309 1320 : thisSys.input_specs.heating_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_name");
7310 1320 : thisSys.input_specs.cooling_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_object_type");
7311 1320 : thisSys.input_specs.cooling_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_name");
7312 :
7313 1320 : thisSys.input_specs.fan_placement = ip->getAlphaFieldValue(fields, objectSchemaProps, "fan_placement");
7314 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name =
7315 1320 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_operating_mode_schedule_name");
7316 660 : if (getPTUnitType > 1) {
7317 366 : thisSys.input_specs.maximum_supply_air_temperature_from_supplemental_heater =
7318 732 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_from_supplemental_heater");
7319 : thisSys.input_specs.supplemental_heating_coil_object_type =
7320 732 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_object_type");
7321 : thisSys.input_specs.supplemental_heating_coil_name =
7322 732 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_name");
7323 732 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = ip->getRealFieldValue(
7324 : fields, objectSchemaProps, "maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7325 366 : if (getPTUnitType == 2) {
7326 112 : thisSys.input_specs.heat_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "heating_convergence_tolerance");
7327 168 : thisSys.input_specs.cool_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_convergence_tolerance");
7328 310 : } else if (getPTUnitType == 3) {
7329 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name =
7330 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_dry_bulb_temperature_sensor_node_name");
7331 : thisSys.input_specs.heat_pump_coil_water_flow_mode =
7332 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "heat_pump_coil_water_flow_mode");
7333 310 : thisSys.input_specs.control_type = "LOAD";
7334 : }
7335 : }
7336 660 : if (getPTUnitType < 3) {
7337 700 : thisSys.input_specs.control_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "capacity_control_method");
7338 350 : if (thisSys.input_specs.control_type.empty() || thisSys.input_specs.control_type == "NONE") {
7339 350 : thisSys.input_specs.control_type = "LOAD";
7340 : }
7341 350 : thisSys.input_specs.minimum_supply_air_temperature =
7342 700 : ip->getRealFieldValue(fields, objectSchemaProps, "minimum_supply_air_temperature_in_cooling_mode");
7343 350 : thisSys.input_specs.maximum_supply_air_temperature =
7344 1050 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_in_heating_mode");
7345 : }
7346 :
7347 1320 : thisSys.input_specs.avail_manager_list_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_manager_list_name");
7348 : thisSys.input_specs.design_spec_zonehvac_sizing_object_name =
7349 1320 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_zonehvac_sizing_object_name");
7350 :
7351 660 : if (getPTUnitType == 3) {
7352 : thisSys.m_DesignSpecMultispeedHPType =
7353 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_type");
7354 : thisSys.m_DesignSpecMultispeedHPName =
7355 620 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_name");
7356 310 : if (!thisSys.m_DesignSpecMultispeedHPType.empty() && !thisSys.m_DesignSpecMultispeedHPName.empty()) {
7357 4 : DesignSpecMSHP thisDesignSpec;
7358 4 : thisSys.m_CompPointerMSHP =
7359 4 : thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, thisSys.m_DesignSpecMultispeedHPName);
7360 4 : thisSys.m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, thisSys.m_DesignSpecMultispeedHPName);
7361 4 : }
7362 : }
7363 :
7364 : // set UnitarySystem specific inputs
7365 660 : thisSys.input_specs.dehumidification_control_type = "None";
7366 660 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7367 660 : thisSys.input_specs.cooling_supply_air_flow_rate_method = "SupplyAirFlowRate";
7368 660 : thisSys.input_specs.heating_supply_air_flow_rate_method = "SupplyAirFlowRate";
7369 660 : thisSys.input_specs.no_load_supply_air_flow_rate_method = "SupplyAirFlowRate";
7370 :
7371 660 : thisSys.UnitType = cCurrentModuleObject;
7372 660 : thisSys.m_sysType = sysTypeNum;
7373 660 : thisSys.zoneEquipType = zoneEqType;
7374 :
7375 : // TODO: figure out another way to set this next variable
7376 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7377 660 : thisSys.m_LastMode = HeatingMode;
7378 660 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7379 :
7380 660 : if (sysNum == -1) {
7381 : // zone equipment require a 1-n index for access to zone availability managers
7382 330 : switch (getPTUnitType) {
7383 147 : case 1: // Excuse me?
7384 147 : ++numPTAC;
7385 147 : thisSys.m_EquipCompNum = numPTAC;
7386 147 : break;
7387 28 : case 2: // Baking powder?
7388 28 : ++numPTHP;
7389 28 : thisSys.m_EquipCompNum = numPTHP;
7390 28 : break;
7391 155 : case 3:
7392 155 : ++numPTWSHP;
7393 155 : thisSys.m_EquipCompNum = numPTWSHP;
7394 155 : break;
7395 330 : default:
7396 : assert(true);
7397 : }
7398 330 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7399 330 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7400 : } else {
7401 330 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7402 : }
7403 22466 : }
7404 : }
7405 2703 : }
7406 901 : }
7407 :
7408 901 : void UnitarySys::allocateUnitarySys(EnergyPlusData &state)
7409 : {
7410 901 : if (!state.dataUnitarySystems->unitarySys.empty()) {
7411 736 : return;
7412 : }
7413 165 : int numUnitarySystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:UnitarySystem");
7414 165 : int numCoilSystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:DX");
7415 165 : int numCoilSystemsWater = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:Water");
7416 165 : int numPackagedAC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalAirConditioner");
7417 165 : int numPackagedHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalHeatPump");
7418 165 : int numPackagedWSHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:WaterToAirHeatPump");
7419 165 : int numAllSystemTypes = numUnitarySystems + numCoilSystems + numCoilSystemsWater + numPackagedAC + numPackagedHP + numPackagedWSHP;
7420 901 : for (int sysCount = 0; sysCount < numAllSystemTypes; ++sysCount) {
7421 736 : UnitarySys thisSys;
7422 736 : state.dataUnitarySystems->unitarySys.push_back(thisSys);
7423 736 : }
7424 : }
7425 :
7426 901 : void UnitarySys::getCoilWaterSystemInputData(
7427 : EnergyPlusData &state, std::string_view CoilSysName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7428 : {
7429 :
7430 901 : std::string cCurrentModuleObject("CoilSystem:Cooling:Water");
7431 1231 : static const std::string routineName("getCoilWaterSystemInputData: ");
7432 901 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7433 901 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7434 8 : auto &instancesValue = instances.value();
7435 8 : int numCoilSystemWater = 0;
7436 16 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7437 :
7438 8 : auto const &fields = instance.value();
7439 8 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7440 8 : if (!Util::SameString(CoilSysName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7441 2 : continue;
7442 : }
7443 :
7444 6 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7445 6 : UnitarySys thisSys;
7446 6 : if (sysNum == -1) {
7447 3 : ++state.dataUnitarySystems->numUnitarySystems;
7448 3 : auto const &thisObjName = instance.key();
7449 3 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7450 : } else {
7451 3 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7452 : }
7453 :
7454 6 : thisSys.input_specs.name = thisObjectName;
7455 6 : thisSys.input_specs.system_type = cCurrentModuleObject;
7456 6 : thisSys.input_specs.control_type = "Setpoint";
7457 12 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>());
7458 12 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>());
7459 12 : std::string availScheduleName("");
7460 12 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field, has default value of Always On
7461 2 : availScheduleName = Util::makeUPPER(it.value().get<std::string>());
7462 6 : }
7463 6 : thisSys.input_specs.availability_schedule_name = availScheduleName;
7464 12 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>());
7465 6 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>());
7466 : // why is this cooling coil does not have a field for Design Air Vol Flow Rate
7467 : // set it "SupplyAirFlowRate" to avoid blank, which lead to fatal out during get input
7468 : static constexpr std::string_view loc_cooling_coil_object_type("COIL:COOLING:WATER:DETAILEDGEOMETRY");
7469 6 : if (Util::SameString(loc_cooling_coil_object_type, thisSys.input_specs.cooling_coil_object_type)) {
7470 0 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER("SupplyAirFlowRate");
7471 0 : thisSys.input_specs.cooling_supply_air_flow_rate = DataSizing::AutoSize;
7472 : }
7473 : // optional input fields
7474 6 : if (auto it = fields.find("minimum_air_to_water_temperature_offset");
7475 6 : it != fields.end()) { // not required field, has default value of 0.0
7476 6 : thisSys.m_minAirToWaterTempOffset = it.value().get<Real64>();
7477 6 : }
7478 12 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) {
7479 4 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7480 : } else {
7481 2 : thisSys.input_specs.dehumidification_control_type = "None";
7482 6 : }
7483 :
7484 6 : bool runOnSensibleLoad = true;
7485 12 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) {
7486 4 : runOnSensibleLoad = Util::SameString(it.value().get<std::string>(), "YES");
7487 6 : }
7488 6 : bool runOnLatentLoad = false;
7489 12 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) {
7490 4 : runOnLatentLoad = Util::SameString(it.value().get<std::string>(), "YES");
7491 6 : }
7492 :
7493 6 : if (runOnSensibleLoad && !runOnLatentLoad) {
7494 2 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7495 4 : } else if (!runOnSensibleLoad && runOnLatentLoad) {
7496 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7497 4 : } else if (runOnSensibleLoad && runOnLatentLoad) {
7498 4 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7499 : }
7500 :
7501 : // now translate to UnitarySystem
7502 6 : thisSys.UnitType = cCurrentModuleObject;
7503 6 : thisSys.m_sysType = SysType::CoilCoolingWater;
7504 6 : thisSys.AirloopEqType = SimAirServingZones::CompType::CoilSystemWater;
7505 6 : thisSys.input_specs.control_type = "Setpoint";
7506 6 : thisSys.m_CoolCoilExists = true; // is always true
7507 6 : thisSys.m_LastMode = CoolingMode;
7508 : // set water-side economizer flag
7509 6 : if (thisSys.m_minAirToWaterTempOffset > 0.0) {
7510 6 : thisSys.m_TemperatureOffsetControlActive = true;
7511 : }
7512 :
7513 : // heat recovery loop inputs
7514 12 : if (auto it = fields.find("minimum_water_loop_temperature_for_heat_recovery"); it != fields.end()) {
7515 2 : thisSys.m_minWaterLoopTempForHR = it.value().get<Real64>();
7516 6 : }
7517 12 : if (auto it = fields.find("economizer_lockout"); it != fields.end()) { // duplicate above as default
7518 0 : bool econoFlag = Util::SameString(it.value().get<std::string>(), "YES");
7519 0 : if (econoFlag) {
7520 0 : thisSys.m_waterSideEconomizerFlag = true;
7521 : }
7522 : } else {
7523 6 : thisSys.m_waterSideEconomizerFlag = true;
7524 6 : }
7525 6 : std::string HRWaterCoolingCoilName;
7526 12 : if (auto it = fields.find("companion_coil_used_for_heat_recovery"); it != fields.end()) {
7527 2 : HRWaterCoolingCoilName = Util::makeUPPER(it.value().get<std::string>());
7528 2 : thisSys.m_WaterHRPlantLoopModel = true;
7529 6 : }
7530 6 : if (thisSys.m_WaterHRPlantLoopModel) {
7531 2 : std::string const HRcoolingCoilType("COIL:COOLING:WATER");
7532 2 : bool errFound = false;
7533 2 : thisSys.m_HRcoolCoilAirInNode = WaterCoils::GetCoilInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7534 2 : thisSys.m_HRcoolCoilFluidInletNode =
7535 2 : WaterCoils::GetCoilWaterInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7536 2 : int HRCoilIndex = WaterCoils::GetWaterCoilIndex(state, Util::makeUPPER(HRcoolingCoilType), HRWaterCoolingCoilName, errFound);
7537 2 : bool heatRecoveryCoil = true; // use local here to highlight where this parameter is set
7538 2 : WaterCoils::SetWaterCoilData(state, HRCoilIndex, errFound, _, _, heatRecoveryCoil);
7539 2 : if (errFound) {
7540 0 : if (HRCoilIndex == 0) {
7541 0 : ShowContinueError(state, format("...cooling coil {} must be of type Coil:Cooling:Water.", HRWaterCoolingCoilName));
7542 : }
7543 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisObjectName));
7544 : }
7545 2 : errorsFound = errorsFound || errFound;
7546 2 : }
7547 : // end heat recovery loop inputs
7548 :
7549 6 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7550 :
7551 6 : if (sysNum == -1) {
7552 3 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7553 3 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7554 : // zone equipment require a 1-n index for access to zone availability managers
7555 : // although not zone equipment, use same methodology
7556 3 : ++numCoilSystemWater;
7557 3 : thisSys.m_EquipCompNum = numCoilSystemWater;
7558 : } else {
7559 3 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7560 : }
7561 16 : }
7562 :
7563 8 : if (errorsFound) {
7564 0 : ShowFatalError(
7565 : state,
7566 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", routineName, cCurrentModuleObject));
7567 : }
7568 : }
7569 901 : }
7570 :
7571 901 : void UnitarySys::getUnitarySystemInputData(
7572 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7573 : {
7574 :
7575 901 : std::string const cCurrentModuleObject = "AirLoopHVAC:UnitarySystem";
7576 1231 : static std::string const getUnitarySystemInput("getUnitarySystemInputData");
7577 901 : int zoneUnitaryNum = 0;
7578 901 : int airloopUnitaryNum = 0;
7579 :
7580 901 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7581 901 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end() && state.dataUnitarySystems->numUnitarySystems == 0) {
7582 0 : ShowSevereError(state, "getUnitarySystemInputData: did not find AirLoopHVAC:UnitarySystem object in input file. Check inputs");
7583 0 : errorsFound = true;
7584 901 : } else if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7585 227 : auto &instancesValue = instances.value();
7586 227 : auto const &objectSchemaProps = state.dataInputProcessing->inputProcessor->getObjectSchemaProps(state, cCurrentModuleObject);
7587 1264 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7588 :
7589 1037 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7590 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7591 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7592 1037 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7593 769 : continue;
7594 : }
7595 :
7596 268 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7597 268 : UnitarySys thisSys;
7598 268 : if (sysNum == -1) {
7599 134 : ++state.dataUnitarySystems->numUnitarySystems;
7600 134 : auto const &thisObjName = instance.key();
7601 134 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7602 : } else {
7603 134 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7604 : }
7605 :
7606 268 : auto const &fields = instance.value();
7607 268 : thisSys.UnitType = cCurrentModuleObject;
7608 268 : thisSys.m_sysType = SysType::Unitary;
7609 268 : thisSys.AirloopEqType = SimAirServingZones::CompType::UnitarySystemModel;
7610 :
7611 268 : thisSys.input_specs.name = thisObjectName;
7612 268 : thisSys.input_specs.system_type = cCurrentModuleObject;
7613 536 : thisSys.input_specs.control_type = fields.at("control_type").get<std::string>();
7614 536 : if (auto it = fields.find("controlling_zone_or_thermostat_location"); it != fields.end()) { // not required field
7615 252 : thisSys.input_specs.controlling_zone_or_thermostat_location = Util::makeUPPER(it.value().get<std::string>());
7616 268 : }
7617 536 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field, has default
7618 236 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7619 : } else {
7620 32 : thisSys.input_specs.dehumidification_control_type = "NONE"; // default value
7621 268 : }
7622 536 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7623 168 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7624 268 : }
7625 536 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>()); // required
7626 536 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>()); // required
7627 536 : if (auto it = fields.find("supply_fan_object_type"); it != fields.end()) { // not required field
7628 264 : thisSys.input_specs.supply_fan_object_type = Util::makeUPPER(it.value().get<std::string>());
7629 268 : }
7630 :
7631 536 : if (auto it = fields.find("supply_fan_name"); it != fields.end()) { // not required field
7632 264 : thisSys.input_specs.supply_fan_name = Util::makeUPPER(it.value().get<std::string>());
7633 268 : }
7634 536 : if (auto it = fields.find("fan_placement"); it != fields.end()) { // not required field
7635 264 : thisSys.input_specs.fan_placement = Util::makeUPPER(it.value().get<std::string>());
7636 268 : }
7637 536 : if (auto it = fields.find("supply_air_fan_operating_mode_schedule_name"); it != fields.end()) { // not required field
7638 254 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7639 268 : }
7640 536 : if (auto it = fields.find("heating_coil_object_type"); it != fields.end()) { // not required field
7641 234 : thisSys.input_specs.heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7642 234 : thisSys.m_HeatCoilExists = true;
7643 268 : }
7644 536 : if (auto it = fields.find("heating_coil_name"); it != fields.end()) { // not required field
7645 234 : thisSys.input_specs.heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7646 268 : }
7647 536 : if (auto it = fields.find("dx_heating_coil_sizing_ratio"); it != fields.end()) { // not required field, has default
7648 180 : thisSys.input_specs.dx_heating_coil_sizing_ratio = it.value().get<Real64>();
7649 268 : }
7650 536 : if (auto it = fields.find("cooling_coil_object_type"); it != fields.end()) { // not required field
7651 266 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7652 266 : thisSys.m_CoolCoilExists = true;
7653 268 : }
7654 536 : if (auto it = fields.find("cooling_coil_name"); it != fields.end()) { // not required field
7655 266 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(it.value().get<std::string>());
7656 268 : }
7657 536 : if (auto it = fields.find("use_doas_dx_cooling_coil"); it != fields.end()) { // not required field, has default
7658 78 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7659 : } else {
7660 190 : thisSys.input_specs.use_doas_dx_cooling_coil = "No";
7661 268 : }
7662 268 : if (auto it = fields.find("minimum_supply_air_temperature");
7663 268 : it != fields.end()) { // not required field, has default (2C), and autosizable
7664 78 : thisSys.input_specs.minimum_supply_air_temperature =
7665 156 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7666 156 : ? DataSizing::AutoSize
7667 78 : : it.value().get<Real64>();
7668 268 : }
7669 536 : if (auto it = fields.find("latent_load_control"); it != fields.end()) { // not required field, has default
7670 106 : thisSys.input_specs.latent_load_control = it.value().get<std::string>();
7671 : } else {
7672 162 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7673 268 : }
7674 536 : if (auto it = fields.find("supplemental_heating_coil_object_type"); it != fields.end()) { // not required field
7675 88 : thisSys.input_specs.supplemental_heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7676 268 : }
7677 536 : if (auto it = fields.find("supplemental_heating_coil_name"); it != fields.end()) { // not required field
7678 88 : thisSys.input_specs.supplemental_heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7679 268 : }
7680 536 : if (auto it = fields.find("cooling_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7681 264 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER(it.value().get<std::string>());
7682 268 : }
7683 536 : if (auto it = fields.find("cooling_supply_air_flow_rate"); it != fields.end()) { // not required field, autosizable
7684 264 : thisSys.input_specs.cooling_supply_air_flow_rate =
7685 764 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7686 764 : ? DataSizing::AutoSize
7687 28 : : it.value().get<Real64>();
7688 268 : }
7689 536 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7690 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7691 268 : }
7692 536 : if (auto it = fields.find("cooling_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7693 0 : thisSys.input_specs.cooling_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7694 268 : }
7695 536 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7696 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7697 268 : }
7698 536 : if (auto it = fields.find("heating_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7699 234 : thisSys.input_specs.heating_supply_air_flow_rate_method = it.value().get<std::string>();
7700 268 : }
7701 536 : if (auto it = fields.find("heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7702 232 : thisSys.input_specs.heating_supply_air_flow_rate =
7703 670 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7704 670 : ? DataSizing::AutoSize
7705 26 : : it.value().get<Real64>();
7706 268 : }
7707 536 : if (auto it = fields.find("heating_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7708 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7709 268 : }
7710 536 : if (auto it = fields.find("heating_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7711 0 : thisSys.input_specs.heating_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7712 268 : }
7713 536 : if (auto it = fields.find("heating_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7714 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7715 268 : }
7716 536 : if (auto it = fields.find("no_load_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7717 224 : thisSys.input_specs.no_load_supply_air_flow_rate_method = it.value().get<std::string>();
7718 268 : }
7719 536 : if (auto it = fields.find("no_load_supply_air_flow_rate"); it != fields.end()) { // not required field
7720 234 : thisSys.input_specs.no_load_supply_air_flow_rate =
7721 664 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7722 664 : ? DataSizing::AutoSize
7723 38 : : it.value().get<Real64>();
7724 268 : }
7725 536 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7726 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7727 268 : }
7728 536 : if (auto it = fields.find("no_load_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7729 0 : thisSys.input_specs.no_load_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7730 268 : }
7731 536 : if (auto it = fields.find("no_load_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7732 0 : thisSys.input_specs.no_load_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7733 268 : }
7734 268 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation");
7735 268 : it != fields.end()) { // not required field
7736 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation = it.value().get<Real64>();
7737 268 : }
7738 268 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation");
7739 268 : it != fields.end()) { // not required field
7740 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation = it.value().get<Real64>();
7741 268 : }
7742 804 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed = state.dataInputProcessing->inputProcessor->getAlphaFieldValue(
7743 268 : fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7744 804 : if (fields.find("maximum_supply_air_temperature") != fields.end()) { // not required field, has default of 80 C
7745 232 : auto const &obj = fields.at("maximum_supply_air_temperature");
7746 232 : thisSys.input_specs.maximum_supply_air_temperature =
7747 416 : (obj.type() == nlohmann::detail::value_t::string && Util::SameString(obj.get<std::string>(), "Autosize"))
7748 416 : ? DataSizing::AutoSize
7749 48 : : obj.get<Real64>();
7750 : }
7751 268 : if (auto it = fields.find("maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7752 268 : it != fields.end()) { // not required field, has default
7753 138 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = it.value().get<Real64>();
7754 268 : }
7755 536 : if (auto it = fields.find("outdoor_dry_bulb_temperature_sensor_node_name"); it != fields.end()) { // not required field
7756 12 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name = Util::makeUPPER(it.value().get<std::string>());
7757 268 : }
7758 536 : if (auto it = fields.find("ancillary_on_cycle_electric_power"); it != fields.end()) { // not required field, has default
7759 14 : thisSys.input_specs.ancillary_on_cycle_electric_power = it.value().get<Real64>();
7760 268 : }
7761 536 : if (auto it = fields.find("ancillary_off_cycle_electric_power"); it != fields.end()) { // not required field, has default
7762 14 : thisSys.input_specs.ancillary_off_cycle_electric_power = it.value().get<Real64>();
7763 268 : }
7764 536 : if (auto it = fields.find("design_heat_recovery_water_flow_rate"); it != fields.end()) { // not required field, has default
7765 0 : thisSys.input_specs.design_heat_recovery_water_flow_rate = it.value().get<Real64>();
7766 268 : }
7767 536 : if (auto it = fields.find("maximum_temperature_for_heat_recovery"); it != fields.end()) { // not required field, has default
7768 0 : thisSys.input_specs.maximum_temperature_for_heat_recovery = it.value().get<Real64>();
7769 268 : }
7770 536 : if (auto it = fields.find("heat_recovery_water_inlet_node_name"); it != fields.end()) { // not required field
7771 0 : thisSys.input_specs.heat_recovery_water_inlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7772 268 : }
7773 536 : if (auto it = fields.find("heat_recovery_water_outlet_node_name"); it != fields.end()) { // not required field
7774 0 : thisSys.input_specs.heat_recovery_water_outlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7775 268 : }
7776 536 : if (auto it = fields.find("design_specification_multispeed_object_type"); it != fields.end()) { // not required field
7777 120 : thisSys.input_specs.design_specification_multispeed_object_type = Util::makeUPPER(it.value().get<std::string>());
7778 268 : }
7779 536 : if (auto it = fields.find("design_specification_multispeed_object_name"); it != fields.end()) { // not required field
7780 120 : thisSys.input_specs.design_specification_multispeed_object_name = Util::makeUPPER(it.value().get<std::string>());
7781 268 : }
7782 :
7783 268 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7784 :
7785 268 : if (sysNum == -1) {
7786 134 : ++thisSys.m_UnitarySysNum;
7787 134 : if (ZoneEquipment) {
7788 : // zone equipment require a 1-n index for access to zone availability managers
7789 25 : ++zoneUnitaryNum;
7790 25 : thisSys.m_EquipCompNum = zoneUnitaryNum;
7791 : } else {
7792 : // zone equipment require a 1-n index for access to zone availability managers
7793 : // although not zone equipment, use same methodology
7794 : // keep OA system unitary equipment indexes separate?
7795 109 : ++airloopUnitaryNum;
7796 109 : thisSys.m_EquipCompNum = airloopUnitaryNum;
7797 : }
7798 134 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7799 134 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7800 : } else {
7801 134 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7802 : }
7803 1264 : }
7804 : }
7805 901 : }
7806 :
7807 127610 : void UnitarySys::calcUnitarySuppSystemToSP(EnergyPlusData &state, bool const FirstHVACIteration // True when first HVAC iteration
7808 : )
7809 : {
7810 :
7811 : // SUBROUTINE INFORMATION:
7812 : // AUTHOR Richard Raustad, FSEC
7813 : // DATE WRITTEN February 2013
7814 :
7815 : // PURPOSE OF THIS SUBROUTINE:
7816 : // This subroutine manages supplemental heater component simulation for setpoint based operation scheme.
7817 :
7818 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7819 : Real64 QActual;
7820 :
7821 127610 : std::string CompName = this->m_SuppHeatCoilName;
7822 127610 : int CoilType_Num = this->m_SuppHeatCoilType_Num;
7823 :
7824 127610 : if ((CoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel) || (CoilType_Num == HVAC::Coil_HeatingElectric)) {
7825 446850 : HeatingCoils::SimulateHeatingCoilComponents(state,
7826 : CompName,
7827 : FirstHVACIteration,
7828 178740 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7829 89370 : this->m_SuppHeatCoilIndex,
7830 : _,
7831 178740 : true,
7832 89370 : this->m_FanOpMode,
7833 89370 : this->m_SuppHeatPartLoadFrac);
7834 :
7835 38240 : } else if (CoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
7836 59614 : HeatingCoils::SimulateHeatingCoilComponents(state,
7837 : CompName,
7838 : FirstHVACIteration,
7839 : _,
7840 29807 : this->m_SuppHeatCoilIndex,
7841 : _,
7842 : _,
7843 29807 : this->m_FanOpMode,
7844 29807 : this->m_SuppHeatPartLoadFrac,
7845 29807 : this->m_SuppHeatingSpeedNum,
7846 29807 : this->m_SuppHeatingSpeedRatio);
7847 :
7848 8433 : } else if (CoilType_Num == HVAC::Coil_HeatingDesuperheater) {
7849 33732 : HeatingCoils::SimulateHeatingCoilComponents(state,
7850 : CompName,
7851 : FirstHVACIteration,
7852 16866 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7853 8433 : this->m_SuppHeatCoilIndex,
7854 : _,
7855 : _,
7856 8433 : this->m_FanOpMode,
7857 8433 : this->m_SuppHeatPartLoadFrac);
7858 :
7859 0 : } else if (CoilType_Num == HVAC::Coil_HeatingWater) {
7860 0 : WaterCoils::SimulateWaterCoilComponents(
7861 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, QActual, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
7862 :
7863 0 : } else if (CoilType_Num == HVAC::Coil_HeatingSteam) {
7864 0 : SteamCoils::SimulateSteamCoilComponents(state,
7865 : CompName,
7866 : FirstHVACIteration,
7867 0 : this->m_SuppHeatCoilIndex,
7868 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7869 : _,
7870 0 : this->m_FanOpMode,
7871 0 : this->m_SuppHeatPartLoadFrac);
7872 : }
7873 127610 : }
7874 :
7875 5997269 : void UnitarySys::controlUnitarySystemtoLoad(EnergyPlusData &state,
7876 : int const AirLoopNum, // Primary air loop number
7877 : bool const FirstHVACIteration, // True when first HVAC iteration
7878 : HVAC::CompressorOp &CompressorOn, // Determines if compressor is on or off
7879 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7880 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7881 : Real64 &sysOutputProvided, // system sensible output at supply air node
7882 : Real64 &latOutputProvided // system latent output at supply air node
7883 : )
7884 : {
7885 :
7886 : // SUBROUTINE INFORMATION:
7887 : // AUTHOR Richard Raustad, FSEC
7888 : // DATE WRITTEN February 2013
7889 5997269 : Real64 ZoneLoad = 0.0; // zone load (W)
7890 5997269 : Real64 SupHeaterLoad = 0.0; // additional heating required by supplemental heater (W)
7891 5997269 : Real64 OnOffAirFlowRatio = 1.0;
7892 5997269 : this->updateUnitarySystemControl(state,
7893 : AirLoopNum,
7894 : this->CoolCoilOutletNodeNum,
7895 : this->CoolCtrlNode,
7896 : OnOffAirFlowRatio,
7897 : FirstHVACIteration,
7898 : OAUCoilOutTemp,
7899 : ZoneLoad,
7900 : this->DesignMaxOutletTemp);
7901 :
7902 : // will not be running supplemental heater on this CALL (simulate with supplemental heater off)
7903 5997269 : Real64 FullSensibleOutput = 0.0;
7904 : // using furnace module logic
7905 : // first check to see if cycling fan with economizer can meet the load
7906 5997269 : if (AirLoopNum > 0) {
7907 2616596 : if (this->m_CoolCoilExists && this->m_HeatCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingAirToAirVariableSpeed &&
7908 2344676 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed && !FirstHVACIteration &&
7909 5425422 : this->m_FanOpMode == HVAC::FanOp::Cycling && state.dataUnitarySystems->CoolingLoad &&
7910 192230 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
7911 67783 : CompressorOn = HVAC::CompressorOp::Off;
7912 67783 : this->controlUnitarySystemOutput(
7913 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7914 67783 : if (this->m_CoolingPartLoadFrac >= 1.0 || this->m_HeatingPartLoadFrac >= 1.0 ||
7915 63029 : (this->m_CoolingPartLoadFrac <= 0.0 && this->m_HeatingPartLoadFrac <= 0.0)) {
7916 66051 : CompressorOn = HVAC::CompressorOp::On;
7917 66051 : this->controlUnitarySystemOutput(
7918 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7919 : }
7920 : } else {
7921 2548813 : CompressorOn = HVAC::CompressorOp::On;
7922 2548813 : this->controlUnitarySystemOutput(
7923 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7924 : }
7925 : } else {
7926 3380673 : CompressorOn = HVAC::CompressorOp::On;
7927 3380673 : this->controlUnitarySystemOutput(
7928 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7929 : }
7930 6714958 : if (state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate < HVAC::SmallMassFlow && this->m_sysType != SysType::PackagedAC &&
7931 6714958 : this->m_sysType != SysType::PackagedHP && this->m_sysType != SysType::PackagedWSHP) {
7932 565059 : state.dataUnitarySystems->CoolingLoad = false;
7933 565059 : state.dataUnitarySystems->HeatingLoad = false;
7934 565059 : state.dataUnitarySystems->MoistureLoad = 0.0;
7935 565059 : this->m_CoolingPartLoadFrac = 0.0;
7936 565059 : this->m_HeatingPartLoadFrac = 0.0;
7937 565059 : if (this->CoolCoilFluidInletNode > 0) {
7938 147610 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
7939 : }
7940 565059 : if (this->HeatCoilFluidInletNode > 0) {
7941 24 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = 0.0;
7942 : }
7943 565059 : this->setAverageAirFlow(state, this->m_CoolingPartLoadFrac, OnOffAirFlowRatio);
7944 : // anything else need to be reset here when system is shut down on low flow?
7945 : }
7946 5997269 : Real64 CoolPLR = this->m_CoolingPartLoadFrac;
7947 5997269 : Real64 HeatPLR = this->m_HeatingPartLoadFrac;
7948 5997269 : Real64 HeatCoilLoad = HeatPLR * this->m_DesignHeatingCapacity;
7949 :
7950 5997269 : if (this->CoolCoilFluidInletNode > 0) {
7951 393018 : PlantUtilities::SetComponentFlowRate(state,
7952 196509 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate,
7953 : this->CoolCoilFluidInletNode,
7954 : this->CoolCoilFluidOutletNodeNum,
7955 196509 : this->CoolCoilPlantLoc);
7956 : }
7957 5997269 : if (this->HeatCoilFluidInletNode > 0) {
7958 157188 : PlantUtilities::SetComponentFlowRate(state,
7959 78594 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate,
7960 : this->HeatCoilFluidInletNode,
7961 : this->HeatCoilFluidOutletNodeNum,
7962 78594 : this->HeatCoilPlantLoc);
7963 : }
7964 :
7965 9184702 : if (this->m_SuppCoilExists &&
7966 3187433 : (state.dataUnitarySystems->HeatingLoad || state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < 0.0)) {
7967 2653238 : if ((FullSensibleOutput < (state.dataUnitarySystems->QToHeatSetPt - HVAC::SmallLoad)) && !FirstHVACIteration) {
7968 256954 : SupHeaterLoad = max(0.0, state.dataUnitarySystems->QToHeatSetPt - FullSensibleOutput);
7969 256954 : this->m_SupHeaterLoad = 0.0;
7970 : // what does this line even do? I know we want the supplemental heater on only if there is a dehum load,
7971 : // but for HP's the supp heater should also run if the heating coil can't turn on
7972 : // (i.e., this line calc's a supp heater load, then next line also calc's it?)
7973 256954 : if (state.dataUnitarySystems->MoistureLoad < 0.0) {
7974 579 : this->m_SupHeaterLoad = SupHeaterLoad;
7975 : }
7976 : // so it look's like this next line should only be valid for HP's.
7977 256954 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7978 256954 : this->m_SuppHeatPartLoadFrac = min(1.0, SupHeaterLoad / this->m_DesignSuppHeatingCapacity);
7979 : }
7980 : } else {
7981 2396284 : SupHeaterLoad = 0.0;
7982 2396284 : this->m_SuppHeatPartLoadFrac = 0.0;
7983 : }
7984 : } else {
7985 3344031 : SupHeaterLoad = 0.0;
7986 3344031 : this->m_SuppHeatPartLoadFrac = 0.0;
7987 : }
7988 :
7989 5997269 : this->calcUnitarySystemToLoad(state,
7990 : AirLoopNum,
7991 : FirstHVACIteration,
7992 : CoolPLR,
7993 : HeatPLR,
7994 : OnOffAirFlowRatio,
7995 : sysOutputProvided,
7996 : latOutputProvided,
7997 : HXUnitOn,
7998 : HeatCoilLoad,
7999 : SupHeaterLoad,
8000 : CompressorOn);
8001 : // Why need this second run?
8002 : // check supplemental heating coil outlet temp based on maximum allowed
8003 5997269 : if (this->m_SuppCoilExists) {
8004 : // only need to test for high supply air temp if supplemental coil is operating
8005 3187433 : if (this->m_SuppHeatPartLoadFrac > 0.0) {
8006 256946 : this->calcUnitarySystemToLoad(state,
8007 : AirLoopNum,
8008 : FirstHVACIteration,
8009 : CoolPLR,
8010 : HeatPLR,
8011 : OnOffAirFlowRatio,
8012 : sysOutputProvided,
8013 : latOutputProvided,
8014 : HXUnitOn,
8015 : HeatCoilLoad,
8016 : SupHeaterLoad,
8017 : CompressorOn);
8018 256946 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
8019 : // multistage coil part load fraction already set in the calcUnitarySystemToLoad
8020 256946 : if (this->m_NumOfSpeedSuppHeating <= 1) {
8021 207444 : this->m_SuppHeatPartLoadFrac = SupHeaterLoad / this->m_DesignSuppHeatingCapacity;
8022 : }
8023 : } else {
8024 0 : this->m_SuppHeatPartLoadFrac = 0.0;
8025 : }
8026 : }
8027 : }
8028 :
8029 5997269 : if (this->m_SuppCoilFluidInletNode > 0) {
8030 0 : PlantUtilities::SetComponentFlowRate(state,
8031 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate,
8032 : this->m_SuppCoilFluidInletNode,
8033 : this->m_SuppCoilFluidOutletNodeNum,
8034 0 : this->m_SuppCoilPlantLoc);
8035 : }
8036 :
8037 5997269 : if (this->m_HeatRecActive) {
8038 0 : PlantUtilities::SetComponentFlowRate(state,
8039 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate,
8040 : this->m_HeatRecoveryInletNodeNum,
8041 : this->m_HeatRecoveryOutletNodeNum,
8042 0 : this->m_HRPlantLoc);
8043 : }
8044 5997269 : }
8045 :
8046 2989820 : void UnitarySys::controlUnitarySystemtoSP(EnergyPlusData &state,
8047 : int const AirLoopNum, // Primary air loop number
8048 : bool const FirstHVACIteration, // True when first HVAC iteration
8049 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
8050 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
8051 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8052 : Real64 &sysOutputProvided, // sensible output at supply air node
8053 : Real64 &latOutputProvided // latent output at supply air node
8054 : )
8055 : {
8056 :
8057 : // SUBROUTINE INFORMATION:
8058 : // AUTHOR Richard Raustad, FSEC
8059 : // DATE WRITTEN February 2013
8060 :
8061 : // PURPOSE OF THIS SUBROUTINE:
8062 : // This subroutine manages component simulation.
8063 :
8064 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8065 2989820 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
8066 2989820 : Real64 OnOffAirFlowRatio = 1.0; // Setpoint based coil control does not use this variable
8067 2989820 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
8068 2989820 : Real64 ZoneLoad = 0.0;
8069 2989820 : Real64 HeatCoilLoad = -999.0;
8070 :
8071 : // CALL the series of components that simulate a Unitary System
8072 2989820 : if (this->ATMixerExists) {
8073 : // There is an air terminal mixer
8074 0 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
8075 : // set the primary air inlet mass flow rate
8076 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
8077 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
8078 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
8079 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
8080 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
8081 : }
8082 : }
8083 2989820 : if (this->OAMixerExists) {
8084 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
8085 0 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
8086 : }
8087 2989820 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
8088 98727 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
8089 : }
8090 :
8091 2989820 : if (this->m_CoolingCoilUpstream) {
8092 :
8093 2989820 : if (this->m_CoolCoilExists) {
8094 2985736 : this->updateUnitarySystemControl(state,
8095 : AirLoopNum,
8096 : this->CoolCoilOutletNodeNum,
8097 : this->CoolCtrlNode,
8098 : OnOffAirFlowRatio,
8099 : FirstHVACIteration,
8100 : OAUCoilOutTemp,
8101 : ZoneLoad,
8102 : this->DesignMaxOutletTemp);
8103 2985736 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
8104 2985736 : PartLoadRatio = this->m_CoolingPartLoadFrac;
8105 2985736 : CompressorOn = HVAC::CompressorOp::Off;
8106 2985736 : if (PartLoadRatio > 0.0) {
8107 1036200 : CompressorOn = HVAC::CompressorOp::On;
8108 1036200 : this->m_LastMode = CoolingMode;
8109 : }
8110 2985736 : this->calcUnitaryCoolingSystem(
8111 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
8112 : }
8113 2989820 : if (this->m_HeatCoilExists) {
8114 102811 : this->updateUnitarySystemControl(state,
8115 : AirLoopNum,
8116 : this->HeatCoilOutletNodeNum,
8117 : this->HeatCtrlNode,
8118 : OnOffAirFlowRatio,
8119 : FirstHVACIteration,
8120 : OAUCoilOutTemp,
8121 : ZoneLoad,
8122 : this->DesignMaxOutletTemp);
8123 102811 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
8124 102811 : PartLoadRatio = this->m_HeatingPartLoadFrac;
8125 102811 : HVAC::CompressorOp CompressOn = HVAC::CompressorOp::Off;
8126 102811 : if (PartLoadRatio > 0.0) {
8127 28886 : CompressOn = HVAC::CompressorOp::On;
8128 28886 : this->m_LastMode = HeatingMode;
8129 : }
8130 102811 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressOn, OnOffAirFlowRatio, HeatCoilLoad);
8131 : }
8132 :
8133 : } else {
8134 :
8135 0 : if (this->m_HeatCoilExists) {
8136 0 : this->updateUnitarySystemControl(state,
8137 : AirLoopNum,
8138 : this->HeatCoilOutletNodeNum,
8139 : this->HeatCtrlNode,
8140 : OnOffAirFlowRatio,
8141 : FirstHVACIteration,
8142 : OAUCoilOutTemp,
8143 : ZoneLoad,
8144 : this->DesignMaxOutletTemp);
8145 0 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
8146 0 : PartLoadRatio = this->m_HeatingPartLoadFrac;
8147 0 : CompressorOn = HVAC::CompressorOp::Off;
8148 0 : if (PartLoadRatio > 0.0) {
8149 0 : CompressorOn = HVAC::CompressorOp::On;
8150 0 : this->m_LastMode = HeatingMode;
8151 : }
8152 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
8153 : }
8154 0 : if (this->m_CoolCoilExists) {
8155 0 : this->updateUnitarySystemControl(state,
8156 : AirLoopNum,
8157 : this->CoolCoilOutletNodeNum,
8158 : this->CoolCtrlNode,
8159 : OnOffAirFlowRatio,
8160 : FirstHVACIteration,
8161 : OAUCoilOutTemp,
8162 : ZoneLoad,
8163 : this->DesignMaxOutletTemp);
8164 0 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
8165 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
8166 0 : CompressorOn = HVAC::CompressorOp::Off;
8167 0 : if (PartLoadRatio > 0.0) {
8168 0 : CompressorOn = HVAC::CompressorOp::On;
8169 0 : this->m_LastMode = CoolingMode;
8170 : }
8171 0 : this->calcUnitaryCoolingSystem(
8172 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
8173 : }
8174 : }
8175 :
8176 2989820 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
8177 0 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
8178 : }
8179 :
8180 2989820 : if (this->m_SuppCoilExists) {
8181 98727 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
8182 98727 : this->updateUnitarySystemControl(state,
8183 : AirLoopNum,
8184 : this->SuppCoilOutletNodeNum,
8185 : this->SuppCtrlNode,
8186 : OnOffAirFlowRatio,
8187 : FirstHVACIteration,
8188 : OAUCoilOutTemp,
8189 : ZoneLoad,
8190 : this->DesignMaxOutletTemp);
8191 98727 : this->controlSuppHeatSystemToSP(state, AirLoopNum, FirstHVACIteration);
8192 98727 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
8193 98727 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
8194 : }
8195 :
8196 : // If there is a supply side air terminal mixer, calculate its output
8197 2989820 : if (this->ATMixerExists) {
8198 0 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
8199 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
8200 : }
8201 : }
8202 :
8203 2989820 : calculateCapacity(state, sysOutputProvided, latOutputProvided);
8204 2989820 : this->m_InitHeatPump = false;
8205 2989820 : }
8206 :
8207 9184543 : void UnitarySys::updateUnitarySystemControl(EnergyPlusData &state,
8208 : int const AirLoopNum, // number of the current air loop being simulated
8209 : int const OutNode, // coil outlet node number
8210 : int const ControlNode, // control node number
8211 : Real64 &OnOffAirFlowRatio,
8212 : bool const FirstHVACIteration,
8213 : Real64 const OAUCoilOutletTemp, // "ONLY" for zoneHVAC:OutdoorAirUnit
8214 : Real64 &ZoneLoad,
8215 : Real64 const MaxOutletTemp // limits heating coil outlet temp [C]
8216 : )
8217 : {
8218 :
8219 : // SUBROUTINE INFORMATION:
8220 : // AUTHOR Richard Raustad, FSEC
8221 : // DATE WRITTEN February 2013
8222 :
8223 : // PURPOSE OF THIS SUBROUTINE:
8224 : // This subroutine is for sizing unitary systems.
8225 :
8226 : // METHODOLOGY EMPLOYED:
8227 : // Either CALL the coil model to get the size or size coil.
8228 : // Current method is to use same methodology as is used in coil objects.
8229 : // Future changes will include a common sizing algorithm and push the calculated
8230 : // size to the coil object prior to first call (so the coil will not DataSizing::AutoSize).
8231 :
8232 : // These initializations are done every iteration
8233 :
8234 : {
8235 9184543 : state.dataUnitarySystems->MoistureLoad = 0.0;
8236 9184543 : this->LoadSHR = 0.0;
8237 9184543 : this->CoilSHR = 0.0;
8238 9184543 : switch (this->m_ControlType) {
8239 5997269 : case UnitarySysCtrlType::Load:
8240 : case UnitarySysCtrlType::CCMASHRAE: {
8241 5997269 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAirUnit
8242 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
8243 0 : ShowFatalError(state, "...Load based control is not allowed when used with ZoneHVAC:OutdoorAirUnit");
8244 : }
8245 :
8246 : // here we need to deal with sequenced zone equip
8247 5997269 : state.dataUnitarySystems->HeatingLoad = false;
8248 5997269 : state.dataUnitarySystems->CoolingLoad = false;
8249 5997269 : if (this->m_ZoneSequenceCoolingNum > 0 && this->m_ZoneSequenceHeatingNum > 0 && this->m_AirLoopEquipment) {
8250 : // air loop equipment uses sequenced variables
8251 2616496 : state.dataUnitarySystems->QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8252 2616496 : .SequencedOutputRequiredToCoolingSP(this->m_ZoneSequenceCoolingNum);
8253 2616496 : state.dataUnitarySystems->QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8254 2616496 : .SequencedOutputRequiredToHeatingSP(this->m_ZoneSequenceHeatingNum);
8255 3238606 : if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8256 622110 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8257 617654 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8258 617654 : state.dataUnitarySystems->HeatingLoad = true;
8259 2003298 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8260 4456 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleCool) {
8261 4456 : ZoneLoad = 0.0;
8262 3097289 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8263 1102903 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8264 1097982 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8265 1097982 : state.dataUnitarySystems->CoolingLoad = true;
8266 901325 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8267 4921 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleHeat) {
8268 4921 : ZoneLoad = 0.0;
8269 891483 : } else if (state.dataUnitarySystems->QToHeatSetPt <= 0.0 && state.dataUnitarySystems->QToCoolSetPt >= 0.0) {
8270 891483 : ZoneLoad = 0.0;
8271 : }
8272 5232992 : state.dataUnitarySystems->MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum)
8273 2616496 : .SequencedOutputRequiredToDehumidSP(this->m_ZoneSequenceCoolingNum);
8274 : } else {
8275 : // zone equipment uses Remaining* variables
8276 3380773 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired;
8277 6761546 : state.dataUnitarySystems->QToCoolSetPt =
8278 3380773 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToCoolSP;
8279 6761546 : state.dataUnitarySystems->QToHeatSetPt =
8280 3380773 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToHeatSP;
8281 6761546 : state.dataUnitarySystems->MoistureLoad =
8282 3380773 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum).RemainingOutputReqToDehumidSP;
8283 3380773 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
8284 2203381 : this->m_sysType == SysType::PackagedWSHP) {
8285 : // ZoneSysAvailManager is turning on sooner than PTUnit in UnitarySystem. Mimic PTUnit logic.
8286 4797231 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8287 1599740 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8288 1594739 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8289 2949568 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 &&
8290 1346816 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8291 1346486 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8292 : } else {
8293 256266 : ZoneLoad = 0.0;
8294 : }
8295 : }
8296 : }
8297 :
8298 8367677 : if (ZoneLoad < 0.0 && state.dataUnitarySystems->MoistureLoad <= 0.0 &&
8299 2370408 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8300 722098 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag)) {
8301 1196 : this->LoadSHR =
8302 1196 : ZoneLoad / (ZoneLoad + state.dataUnitarySystems->MoistureLoad *
8303 2392 : Psychrometrics::PsyHgAirFnWTdb(
8304 1196 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).airHumRat,
8305 1196 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).MAT));
8306 1196 : if (this->LoadSHR < 0.0) {
8307 0 : this->LoadSHR = 0.0;
8308 : }
8309 1196 : this->CoilSHR = this->LoadSHR;
8310 : }
8311 :
8312 5997269 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8313 193460 : Real64 H2OHtOfVap = Psychrometrics::PsyHfgAirFnWTdb(state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
8314 193460 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp);
8315 :
8316 : // positive MoistureLoad means no dehumidification load
8317 193460 : state.dataUnitarySystems->MoistureLoad = min(0.0, state.dataUnitarySystems->MoistureLoad * H2OHtOfVap);
8318 : } else {
8319 5803809 : state.dataUnitarySystems->MoistureLoad = 0.0;
8320 : }
8321 :
8322 5997269 : this->initLoadBasedControl(state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad);
8323 :
8324 : // *** the location of this EMS override looks suspect. If EMS is active the load will be changed but the CoolingLoad and HeatingLoad
8325 : // flags are not updated. suggest this be moved up above InitLoadBasedControl function on previous line so the EMS loads are used in
8326 : // that routine EMS override point
8327 5997269 : if (this->m_EMSOverrideSensZoneLoadRequest) {
8328 0 : ZoneLoad = this->m_EMSSensibleZoneLoadValue;
8329 : }
8330 5997269 : if (this->m_EMSOverrideMoistZoneLoadRequest) {
8331 0 : state.dataUnitarySystems->MoistureLoad = this->m_EMSMoistureZoneLoadValue;
8332 : }
8333 :
8334 5997269 : this->m_SimASHRAEModel = false; // flag used to invoke ASHRAE 90.1 model calculations
8335 : // allows non-ASHSRAE compliant coil types to be modeled using non-ASHAR90 method. Constant fan operating mode is required.
8336 5997269 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
8337 3192548 : if (state.dataUnitarySystems->CoolingLoad) {
8338 1474300 : if (this->m_ValidASHRAECoolCoil) {
8339 0 : this->m_SimASHRAEModel = true;
8340 : }
8341 1718248 : } else if (state.dataUnitarySystems->HeatingLoad) {
8342 1257218 : if (this->m_ValidASHRAEHeatCoil) {
8343 0 : this->m_SimASHRAEModel = true;
8344 : }
8345 : }
8346 : }
8347 5997269 : } break;
8348 3187274 : case UnitarySysCtrlType::Setpoint: {
8349 3187274 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAIRUNIT
8350 :
8351 74325 : if (ControlNode == 0) {
8352 0 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8353 74325 : } else if (ControlNode == OutNode) {
8354 74325 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8355 : }
8356 : // If the unitary system is an Outdoor Air Unit, the desired coil outlet humidity level is set to 1.0 (no dehum)
8357 74325 : this->m_DesiredOutletHumRat = 1.0;
8358 :
8359 : } else { // Not Outdoor Air Unit. Either airloop or zone equipment
8360 3112949 : Real64 humRatMaxSP = 1.0;
8361 3112949 : this->m_DesiredOutletHumRat = humRatMaxSP;
8362 3112949 : if (ControlNode == 0) {
8363 0 : this->m_DesiredOutletTemp = 0.0;
8364 0 : if (OutNode > 0) {
8365 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8366 0 : this->m_DesiredOutletHumRat = state.dataLoopNodes->Node(OutNode).HumRatMax;
8367 : }
8368 : }
8369 3112949 : } else if (ControlNode == OutNode) {
8370 2795104 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8371 28298 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8372 19909 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8373 : }
8374 84894 : this->frostControlSetPointLimit(state,
8375 28298 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8376 : humRatMaxSP,
8377 28298 : state.dataEnvrn->OutBaroPress,
8378 : this->DesignMinOutletTemp,
8379 : 1);
8380 : }
8381 2795104 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
8382 : // IF HumRatMax is zero, then there is no request from SetpointManager:SingleZone:Humidity:Maximum
8383 : // user might place temp SP at system outlet and HumRat set point at coil outlet
8384 2795104 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8385 208011 : if (state.dataLoopNodes->Node(this->AirOutNode).HumRatMax > 0.0) {
8386 203573 : humRatMaxSP = state.dataLoopNodes->Node(this->AirOutNode).HumRatMax;
8387 : }
8388 208011 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8389 172466 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8390 : }
8391 208011 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8392 59727 : this->frostControlSetPointLimit(state,
8393 19909 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8394 19909 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8395 19909 : state.dataEnvrn->OutBaroPress,
8396 : this->DesignMinOutletTemp,
8397 : 2);
8398 19909 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8399 : }
8400 208011 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8401 : }
8402 : } else {
8403 317845 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8404 15495 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8405 : }
8406 317845 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8407 0 : humRatMaxSP = state.dataLoopNodes->Node(OutNode).HumRatMax;
8408 : }
8409 317845 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8410 0 : this->frostControlSetPointLimit(state,
8411 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8412 : humRatMaxSP,
8413 0 : state.dataEnvrn->OutBaroPress,
8414 : this->DesignMinOutletTemp,
8415 : 1);
8416 : }
8417 317845 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint -
8418 317845 : (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(OutNode).Temp);
8419 317845 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8420 0 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8421 0 : this->frostControlSetPointLimit(state,
8422 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8423 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8424 0 : state.dataEnvrn->OutBaroPress,
8425 : this->DesignMinOutletTemp,
8426 : 2);
8427 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8428 : }
8429 0 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8430 : }
8431 : }
8432 : }
8433 3187274 : this->m_DesiredOutletTemp = min(this->m_DesiredOutletTemp, MaxOutletTemp);
8434 3187274 : } break;
8435 0 : default: {
8436 : // should never get here, only 3 control types
8437 0 : } break;
8438 : }
8439 : }
8440 9184543 : }
8441 37481 : void UnitarySys::controlUnitarySystemOutputEMS(EnergyPlusData &state,
8442 : int const AirLoopNum, // Index to air loop
8443 : bool const FirstHVACIteration, // True when first HVAC iteration
8444 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8445 : Real64 const ZoneLoad,
8446 : Real64 &FullSensibleOutput,
8447 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8448 : HVAC::CompressorOp CompressorOn)
8449 : {
8450 37481 : Real64 PartLoadRatio = 1.0;
8451 37481 : Real64 CoolPLR = 0.0;
8452 37481 : Real64 HeatPLR = 0.0;
8453 37481 : HVAC::CompressorOp CompressorONFlag = CompressorOn;
8454 37481 : Real64 HeatCoilLoad = 0.0;
8455 37481 : Real64 SupHeaterLoad = 0.0;
8456 : Real64 SensOutput; // sensible output
8457 : Real64 LatOutput; // latent output
8458 37481 : this->FanPartLoadRatio = 0.0;
8459 37481 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8460 :
8461 37481 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) {
8462 1520 : return;
8463 : }
8464 35961 : int SpeedNumEMS = ceil(this->m_EMSOverrideCoilSpeedNumValue);
8465 35961 : bool useMaxedSpeed = false;
8466 35961 : std::string useMaxedSpeedCoilName;
8467 35961 : if (state.dataUnitarySystems->HeatingLoad) {
8468 0 : if (SpeedNumEMS > this->m_NumOfSpeedHeating) {
8469 0 : SpeedNumEMS = this->m_NumOfSpeedHeating;
8470 0 : useMaxedSpeed = true;
8471 0 : useMaxedSpeedCoilName = this->m_HeatingCoilName;
8472 : }
8473 0 : this->m_HeatingSpeedNum = SpeedNumEMS;
8474 : } else {
8475 35961 : if (SpeedNumEMS > this->m_NumOfSpeedCooling) {
8476 0 : SpeedNumEMS = this->m_NumOfSpeedCooling;
8477 0 : useMaxedSpeed = true;
8478 0 : useMaxedSpeedCoilName = this->m_CoolingCoilName;
8479 : }
8480 35961 : this->m_CoolingSpeedNum = SpeedNumEMS;
8481 : }
8482 35961 : if (useMaxedSpeed) {
8483 0 : this->m_CoilSpeedErrIdx++;
8484 0 : ShowRecurringWarningErrorAtEnd(state,
8485 0 : "Wrong coil speed EMS override value, for unit=\"" + useMaxedSpeedCoilName +
8486 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
8487 0 : this->m_CoilSpeedErrIdx,
8488 0 : this->m_EMSOverrideCoilSpeedNumValue,
8489 0 : this->m_EMSOverrideCoilSpeedNumValue,
8490 : _,
8491 : "",
8492 : "");
8493 : }
8494 :
8495 35961 : if (state.dataUnitarySystems->HeatingLoad) {
8496 0 : CoolPLR = 0.0;
8497 0 : HeatPLR = 1.0;
8498 0 : this->m_HeatingCoilSensDemand = ZoneLoad;
8499 :
8500 0 : if (this->m_HeatingSpeedNum == 1) {
8501 0 : this->m_HeatingSpeedRatio = 0.0;
8502 0 : this->m_HeatingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8503 0 : if (useMaxedSpeed || this->m_HeatingCycRatio == 0) {
8504 0 : this->m_HeatingCycRatio = 1;
8505 : }
8506 : } else {
8507 0 : this->m_HeatingCycRatio = 1.0;
8508 0 : this->m_HeatingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8509 0 : if (useMaxedSpeed || this->m_HeatingSpeedRatio == 0) {
8510 0 : this->m_HeatingSpeedRatio = 1;
8511 : }
8512 : }
8513 : } else { // Cooling or moisture load
8514 35961 : HeatPLR = 0.0;
8515 35961 : CoolPLR = 1.0;
8516 35961 : if (state.dataUnitarySystems->CoolingLoad) {
8517 35961 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8518 : } else {
8519 0 : this->m_CoolingCoilSensDemand = 0.0;
8520 : }
8521 35961 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8522 :
8523 35961 : if (this->m_CoolingSpeedNum == 1) {
8524 17223 : this->m_CoolingSpeedRatio = 0.0;
8525 17223 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8526 17223 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
8527 17223 : this->m_CoolingCycRatio = 1;
8528 : }
8529 : } else {
8530 18738 : this->m_CoolingCycRatio = 1.0;
8531 18738 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8532 18738 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
8533 0 : this->m_CoolingSpeedRatio = 1;
8534 : }
8535 : }
8536 : }
8537 35961 : this->calcUnitarySystemToLoad(state,
8538 : AirLoopNum,
8539 : FirstHVACIteration,
8540 : CoolPLR,
8541 : HeatPLR,
8542 : OnOffAirFlowRatio,
8543 : SensOutput,
8544 : LatOutput,
8545 35961 : HXUnitOn,
8546 : HeatCoilLoad,
8547 : SupHeaterLoad,
8548 : CompressorONFlag);
8549 :
8550 35961 : FullSensibleOutput = SensOutput;
8551 :
8552 35961 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8553 : // no load
8554 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutput) {
8555 0 : return;
8556 : }
8557 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8558 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
8559 0 : return;
8560 : }
8561 : }
8562 35961 : HXUnitOn = true;
8563 35961 : this->calcUnitarySystemToLoad(state,
8564 : AirLoopNum,
8565 : FirstHVACIteration,
8566 : CoolPLR,
8567 : HeatPLR,
8568 : OnOffAirFlowRatio,
8569 : SensOutput,
8570 : LatOutput,
8571 35961 : HXUnitOn,
8572 : HeatCoilLoad,
8573 : SupHeaterLoad,
8574 : CompressorONFlag);
8575 35961 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
8576 : Real64 heatCoildT =
8577 35961 : (this->m_HeatCoilExists)
8578 35961 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
8579 35961 : : 0.0;
8580 : Real64 CoolingOnlySensibleOutput =
8581 35961 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
8582 35961 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
8583 35961 : heatCoildT);
8584 35961 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
8585 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
8586 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
8587 35961 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
8588 : // Heating mode and dehumidification is required
8589 : } else {
8590 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
8591 : // the heating coil pick up the load due to outdoor air.
8592 0 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
8593 : }
8594 35961 : }
8595 :
8596 6063320 : void UnitarySys::controlUnitarySystemOutput(EnergyPlusData &state,
8597 : int const AirLoopNum, // Index to air loop
8598 : bool const FirstHVACIteration, // True when first HVAC iteration
8599 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8600 : Real64 const ZoneLoad,
8601 : Real64 &FullSensibleOutput,
8602 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8603 : HVAC::CompressorOp CompressorOn)
8604 : {
8605 :
8606 : // SUBROUTINE INFORMATION:
8607 : // AUTHOR Richard Raustad, FSEC
8608 : // DATE WRITTEN February 2013
8609 :
8610 : // PURPOSE OF THIS SUBROUTINE:
8611 : // This subroutine determines operating PLR and calculates the load based system output.
8612 :
8613 : // SUBROUTINE PARAMETER DEFINITIONS:
8614 6063320 : int constexpr MaxIter = 100; // maximum number of iterations
8615 :
8616 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8617 : int SpeedNum; // multi-speed coil speed number
8618 : Real64 SensOutputOn; // sensible output at PLR = 1 [W]
8619 : Real64 LatOutputOn; // latent output at PLR = 1 [W]
8620 : Real64 TempLoad; // represents either a sensible or latent load [W]
8621 : Real64 TempSysOutput; // represents either a sensible or latent capacity [W]
8622 : Real64 TempSensOutput; // iterative sensible capacity [W]
8623 : Real64 TempLatOutput; // iterative latent capacity [W]
8624 : Real64 TempMinPLR; // iterative minimum PLR
8625 : Real64 TempMaxPLR; // iterative maximum PLR
8626 : Real64 CpAir; // specific heat of air [J/kg_C]
8627 : Real64 FullLoadAirOutletTemp; // saved full load outlet air temperature [C]
8628 : Real64 FullLoadAirOutletHumRat; // saved full load outlet air humidity ratio [kg/kg]
8629 :
8630 6063320 : std::string CompName = this->Name;
8631 6063320 : int OutletNode = this->AirOutNode;
8632 :
8633 6063320 : if (this->m_sysAvailSched->getCurrentVal() <= 0.0) {
8634 4506 : return;
8635 : }
8636 6058814 : if (this->m_EMSOverrideCoilSpeedNumOn) {
8637 37481 : this->controlUnitarySystemOutputEMS(
8638 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
8639 37481 : return;
8640 : }
8641 :
8642 6021333 : Real64 PartLoadRatio = 0.0; // Get no load result
8643 6021333 : this->m_EconoPartLoadRatio = 0;
8644 : // fan and coil PLR are disconnected when using ASHRAE model, don't confuse these for other models
8645 6021333 : this->FanPartLoadRatio = 0.0;
8646 6021333 : int SolFlag = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8647 6021333 : int SolFlagLat = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8648 6021333 : Real64 SensOutputOff = 0.0;
8649 6021333 : Real64 LatOutputOff = 0.0;
8650 6021333 : Real64 CoolPLR = 0.0;
8651 6021333 : Real64 HeatPLR = 0.0;
8652 6021333 : HVAC::CompressorOp CompressorONFlag = HVAC::CompressorOp::Off;
8653 6021333 : Real64 HeatCoilLoad = 0.0;
8654 6021333 : Real64 SupHeaterLoad = 0.0;
8655 :
8656 6021333 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8657 :
8658 6021333 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) {
8659 1043389 : return;
8660 : }
8661 :
8662 4977944 : this->calcUnitarySystemToLoad(state,
8663 : AirLoopNum,
8664 : FirstHVACIteration,
8665 : CoolPLR,
8666 : HeatPLR,
8667 : OnOffAirFlowRatio,
8668 : SensOutputOff,
8669 : LatOutputOff,
8670 4977944 : HXUnitOn,
8671 : HeatCoilLoad,
8672 : SupHeaterLoad,
8673 : CompressorONFlag);
8674 4977944 : FullSensibleOutput = SensOutputOff;
8675 :
8676 4977944 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8677 : // no load
8678 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutputOff) {
8679 0 : return;
8680 : }
8681 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8682 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
8683 0 : return;
8684 : }
8685 : }
8686 :
8687 : // determine if PLR=0 meets the load
8688 4977944 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8689 52953 : case HVAC::SetptType::SingleHeat: {
8690 52953 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8691 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8692 0 : return;
8693 : }
8694 52953 : if (!state.dataUnitarySystems->HeatingLoad &&
8695 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8696 0 : return;
8697 : }
8698 52953 : } break;
8699 59735 : case HVAC::SetptType::SingleCool: {
8700 59737 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8701 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8702 2 : return;
8703 : }
8704 59733 : if (!state.dataUnitarySystems->CoolingLoad &&
8705 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8706 0 : return;
8707 : }
8708 59733 : } break;
8709 4865256 : case HVAC::SetptType::SingleHeatCool:
8710 : case HVAC::SetptType::DualHeatCool: {
8711 4865297 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8712 41 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8713 41 : return;
8714 : }
8715 4875398 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8716 10183 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8717 7974 : return;
8718 : }
8719 4857241 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8720 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8721 0 : return;
8722 : }
8723 4857241 : } break;
8724 0 : default: {
8725 : // should never get here
8726 0 : } break;
8727 : }
8728 :
8729 4969927 : this->m_EconoSpeedNum = 0;
8730 4969927 : if (this->OAControllerEconomizerStagingType == HVAC::EconomizerStagingType::EconomizerFirst) {
8731 737912 : manageEconomizerStagingOperation(state, AirLoopNum, FirstHVACIteration, ZoneLoad);
8732 : }
8733 :
8734 : // if a variable speed unit, the SensOutputOff at SpeedNum=1 must be checked to see if it exceeds the ZoneLoad
8735 : // This is still no load but at the first speed above idle
8736 9629805 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating > 0) ||
8737 4659878 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling > 0)) {
8738 1886761 : if (this->m_Staged) {
8739 0 : if (state.dataUnitarySystems->HeatingLoad) {
8740 0 : this->m_HeatingSpeedNum = this->m_StageNum;
8741 : } else {
8742 0 : this->m_CoolingSpeedNum = std::abs(this->m_StageNum);
8743 : }
8744 : } else {
8745 1886761 : if (state.dataUnitarySystems->HeatingLoad) {
8746 310049 : this->m_HeatingSpeedNum = 1;
8747 : } else {
8748 1576712 : this->m_CoolingSpeedNum = 1;
8749 : }
8750 : }
8751 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8752 1886761 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8753 1886761 : this->calcUnitarySystemToLoad(state,
8754 : AirLoopNum,
8755 : FirstHVACIteration,
8756 : CoolPLR,
8757 : HeatPLR,
8758 : OnOffAirFlowRatio,
8759 : SensOutputOff,
8760 : LatOutputOff,
8761 1886761 : HXUnitOn,
8762 : HeatCoilLoad,
8763 : SupHeaterLoad,
8764 : CompressorONFlag);
8765 1886761 : FullSensibleOutput = SensOutputOff;
8766 :
8767 1886761 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8768 4496 : case HVAC::SetptType::SingleHeat: {
8769 4496 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8770 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8771 0 : return;
8772 : }
8773 4496 : if (!state.dataUnitarySystems->HeatingLoad &&
8774 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8775 0 : return;
8776 : }
8777 4496 : } break;
8778 45873 : case HVAC::SetptType::SingleCool: {
8779 45873 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8780 0 : this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
8781 0 : return;
8782 : }
8783 45873 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8784 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8785 0 : return;
8786 : }
8787 45873 : if (!state.dataUnitarySystems->CoolingLoad &&
8788 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8789 0 : return;
8790 : }
8791 45873 : } break;
8792 1836392 : case HVAC::SetptType::SingleHeatCool:
8793 : case HVAC::SetptType::DualHeatCool: {
8794 1842528 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8795 6136 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8796 6136 : return;
8797 : }
8798 2000621 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8799 170365 : this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
8800 169016 : return;
8801 : }
8802 1662589 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8803 1349 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8804 12 : return;
8805 : }
8806 1661228 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8807 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8808 0 : return;
8809 : }
8810 1661228 : } break;
8811 0 : default: {
8812 : // should never get here
8813 0 : } break;
8814 : }
8815 : }
8816 :
8817 4794763 : CompressorONFlag = CompressorOn;
8818 4794763 : PartLoadRatio = 1.0;
8819 4794763 : this->FanPartLoadRatio = 1.0;
8820 : // Get full load result for non-multistage economizer operations
8821 4794763 : if (this->m_EconoSpeedNum == 0) {
8822 4782553 : if (state.dataUnitarySystems->HeatingLoad) {
8823 2311221 : CoolPLR = 0.0;
8824 2311221 : HeatPLR = 1.0;
8825 2311221 : this->m_HeatingCoilSensDemand = ZoneLoad;
8826 2311221 : if (this->m_NumOfSpeedHeating > 0) {
8827 303913 : this->m_HeatingSpeedRatio = 1.0;
8828 303913 : this->m_HeatingCycRatio = 1.0;
8829 303913 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
8830 : }
8831 2311221 : if (this->m_Staged && this->m_StageNum > 0) {
8832 0 : if (this->m_NumOfSpeedHeating > 0) {
8833 0 : this->m_HeatingSpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8834 0 : this->m_HeatingSpeedRatio = 0.0;
8835 : }
8836 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8837 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8838 0 : this->calcUnitarySystemToLoad(state,
8839 : AirLoopNum,
8840 : FirstHVACIteration,
8841 : CoolPLR,
8842 : HeatPLR,
8843 : OnOffAirFlowRatio,
8844 : SensOutputOff,
8845 : LatOutputOff,
8846 0 : HXUnitOn,
8847 : HeatCoilLoad,
8848 : SupHeaterLoad,
8849 : CompressorONFlag);
8850 0 : if (SensOutputOff > ZoneLoad) {
8851 0 : return;
8852 : }
8853 0 : if (this->m_NumOfSpeedHeating > 0) {
8854 0 : this->m_HeatingSpeedRatio = 1.0;
8855 : }
8856 : }
8857 2471332 : } else if (state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < LatOutputOff) {
8858 2471332 : CoolPLR = 1.0;
8859 2471332 : HeatPLR = 0.0;
8860 2471332 : if (state.dataUnitarySystems->CoolingLoad) {
8861 2471332 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8862 : } else {
8863 0 : this->m_CoolingCoilSensDemand = 0.0;
8864 : }
8865 2471332 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8866 2471332 : if (this->m_NumOfSpeedCooling > 0) {
8867 1395474 : this->m_CoolingSpeedRatio = 1.0;
8868 1395474 : this->m_CoolingCycRatio = 1.0;
8869 1395474 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
8870 : }
8871 2471332 : if (this->m_Staged && this->m_StageNum < 0) {
8872 0 : if (this->m_NumOfSpeedCooling > 0) {
8873 0 : this->m_CoolingSpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8874 : }
8875 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8876 0 : this->m_CoolingSpeedRatio = 0.0;
8877 0 : this->calcUnitarySystemToLoad(state,
8878 : AirLoopNum,
8879 : FirstHVACIteration,
8880 : CoolPLR,
8881 : HeatPLR,
8882 : OnOffAirFlowRatio,
8883 : SensOutputOff,
8884 : LatOutputOff,
8885 0 : HXUnitOn,
8886 : HeatCoilLoad,
8887 : SupHeaterLoad,
8888 : CompressorONFlag);
8889 0 : if (SensOutputOff < ZoneLoad) {
8890 0 : return;
8891 : }
8892 0 : if (this->m_NumOfSpeedCooling > 0) {
8893 0 : this->m_CoolingSpeedRatio = 1.0;
8894 : }
8895 : }
8896 : } else {
8897 : // will return here when no cooling or heating load and MoistureLoad > LatOutputOff (i.e., PLR=0)
8898 0 : return;
8899 : }
8900 :
8901 4782553 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8902 :
8903 4782553 : this->calcUnitarySystemToLoad(state,
8904 : AirLoopNum,
8905 : FirstHVACIteration,
8906 : CoolPLR,
8907 : HeatPLR,
8908 : OnOffAirFlowRatio,
8909 : SensOutputOn,
8910 : LatOutputOn,
8911 4782553 : HXUnitOn,
8912 : HeatCoilLoad,
8913 : SupHeaterLoad,
8914 : CompressorONFlag);
8915 4782553 : FullSensibleOutput = SensOutputOn;
8916 4782553 : FullLoadAirOutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
8917 4782553 : FullLoadAirOutletHumRat = state.dataLoopNodes->Node(OutletNode).HumRat;
8918 :
8919 : // turn on HX if dehumidm_ControlType::Multimode
8920 69394 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < 0.0 &&
8921 4851947 : state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
8922 20914 : HXUnitOn = true;
8923 20914 : this->calcUnitarySystemToLoad(state,
8924 : AirLoopNum,
8925 : FirstHVACIteration,
8926 : CoolPLR,
8927 : HeatPLR,
8928 : OnOffAirFlowRatio,
8929 : SensOutputOn,
8930 : LatOutputOn,
8931 20914 : HXUnitOn,
8932 : HeatCoilLoad,
8933 : SupHeaterLoad,
8934 : CompressorONFlag);
8935 20914 : FullSensibleOutput = SensOutputOn;
8936 : }
8937 :
8938 : // test to see if full capacity is less than load, if so set to PLR=1 and RETURN if no moisture load
8939 7358536 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating <= 1) ||
8940 2575983 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling <= 1)) {
8941 3931977 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8942 48457 : case HVAC::SetptType::SingleHeat: {
8943 48457 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8944 12108 : this->m_HeatingPartLoadFrac = 1.0;
8945 12108 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
8946 12108 : return;
8947 : }
8948 : }
8949 36349 : if (!state.dataUnitarySystems->HeatingLoad &&
8950 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8951 0 : return;
8952 : }
8953 36349 : } break;
8954 42145 : case HVAC::SetptType::SingleCool: {
8955 42145 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8956 4953 : this->m_CoolingPartLoadFrac = 1.0;
8957 4953 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
8958 4953 : return;
8959 : }
8960 : }
8961 37192 : if (!state.dataUnitarySystems->CoolingLoad &&
8962 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8963 0 : return;
8964 : }
8965 37192 : } break;
8966 3841375 : case HVAC::SetptType::SingleHeatCool:
8967 : case HVAC::SetptType::DualHeatCool: {
8968 3841375 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8969 365420 : this->m_HeatingPartLoadFrac = 1.0;
8970 365420 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOn) {
8971 365420 : return;
8972 : }
8973 : }
8974 3475955 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8975 30925 : this->m_CoolingPartLoadFrac = 1.0;
8976 30925 : return;
8977 : }
8978 3445030 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8979 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8980 0 : return;
8981 : }
8982 3445030 : } break;
8983 0 : default: {
8984 : // no other choices for thermostat control
8985 0 : } break;
8986 : }
8987 : }
8988 : } else {
8989 : // define the sensible load to meet for operation with multi-stage economizer
8990 12210 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8991 : }
8992 : // will find speed for multispeed coils here and then RegulaFalsi on PLR at a fixed speed
8993 :
8994 : // Do the non-variable or non-multispeed coils have a NumOfSpeed = 0 ? We don't need to do this for single speed coils.
8995 : // Check to see which speed to meet the load
8996 4381357 : this->m_HeatingSpeedNum = 0;
8997 4381357 : this->m_CoolingSpeedNum = 0;
8998 4381357 : if (!this->m_Staged) {
8999 4381357 : if (state.dataUnitarySystems->HeatingLoad) {
9000 2186673 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
9001 317880 : CoolPLR = 0.0;
9002 317880 : HeatPLR = 1.0;
9003 317880 : if (SpeedNum == 1) {
9004 145361 : this->m_HeatingSpeedRatio = 0.0;
9005 : } else {
9006 172519 : this->m_HeatingSpeedRatio = 1.0;
9007 : }
9008 317880 : this->m_HeatingCycRatio = 1.0;
9009 317880 : this->m_HeatingSpeedNum = SpeedNum;
9010 317880 : this->calcUnitarySystemToLoad(state,
9011 : AirLoopNum,
9012 : FirstHVACIteration,
9013 : CoolPLR,
9014 : HeatPLR,
9015 : OnOffAirFlowRatio,
9016 : SensOutputOn,
9017 : LatOutputOn,
9018 317880 : HXUnitOn,
9019 : HeatCoilLoad,
9020 : SupHeaterLoad,
9021 : CompressorONFlag);
9022 317880 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9023 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9024 : }
9025 317880 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
9026 268032 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater && !this->m_MultiSpeedHeatingCoil)) {
9027 0 : this->m_HeatingSpeedRatio = 0.0;
9028 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
9029 0 : if (this->m_HeatingSpeedNum == 0) {
9030 0 : this->m_HeatingCycRatio = 0.0;
9031 0 : HeatPLR = 0.0;
9032 : } else {
9033 0 : this->m_HeatingCycRatio = 1.0;
9034 0 : HeatPLR = 1.0;
9035 : }
9036 0 : this->calcUnitarySystemToLoad(state,
9037 : AirLoopNum,
9038 : FirstHVACIteration,
9039 : CoolPLR,
9040 : HeatPLR,
9041 : OnOffAirFlowRatio,
9042 : SensOutputOff,
9043 : LatOutputOff,
9044 0 : HXUnitOn,
9045 : HeatCoilLoad,
9046 : SupHeaterLoad,
9047 : CompressorONFlag);
9048 0 : this->m_HeatingSpeedNum = SpeedNum;
9049 : }
9050 317880 : if (ZoneLoad <= SensOutputOn) {
9051 64900 : break;
9052 : }
9053 : }
9054 : } else { // Cooling or moisture load
9055 3228819 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9056 2142113 : CoolPLR = 1.0;
9057 2142113 : HeatPLR = 0.0;
9058 2142113 : if (SpeedNum == 1) {
9059 1387642 : this->m_CoolingSpeedRatio = 0.0;
9060 : } else {
9061 754471 : this->m_CoolingSpeedRatio = 1.0;
9062 : }
9063 2142113 : this->m_CoolingCycRatio = 1.0;
9064 2142113 : this->m_CoolingSpeedNum = SpeedNum;
9065 2142113 : this->calcUnitarySystemToLoad(state,
9066 : AirLoopNum,
9067 : FirstHVACIteration,
9068 : CoolPLR,
9069 : HeatPLR,
9070 : OnOffAirFlowRatio,
9071 : SensOutputOn,
9072 : LatOutputOn,
9073 2142113 : HXUnitOn,
9074 : HeatCoilLoad,
9075 : SupHeaterLoad,
9076 : CompressorONFlag);
9077 2142113 : if (state.dataGlobal->DoCoilDirectSolutions &&
9078 0 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
9079 0 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1))) {
9080 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9081 : }
9082 : // over specified logic? it has to be a water coil? what about other VS coil models?
9083 2142113 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9084 2129617 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9085 10198 : !this->m_DiscreteSpeedCoolingCoil)) {
9086 0 : this->m_CoolingSpeedRatio = 0.0;
9087 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9088 0 : if (this->m_CoolingSpeedNum == 0) {
9089 0 : this->m_CoolingCycRatio = 0.0;
9090 0 : CoolPLR = 0.0;
9091 : } else {
9092 0 : this->m_CoolingCycRatio = 1.0;
9093 0 : this->m_CoolingSpeedRatio = 0.0;
9094 0 : if (this->m_SingleMode == 1) {
9095 0 : CoolPLR = 1.0;
9096 : }
9097 : }
9098 :
9099 0 : this->calcUnitarySystemToLoad(state,
9100 : AirLoopNum,
9101 : FirstHVACIteration,
9102 : CoolPLR,
9103 : HeatPLR,
9104 : OnOffAirFlowRatio,
9105 : SensOutputOff,
9106 : LatOutputOff,
9107 0 : HXUnitOn,
9108 : HeatCoilLoad,
9109 : SupHeaterLoad,
9110 : CompressorONFlag);
9111 0 : this->m_CoolingSpeedNum = SpeedNum;
9112 : }
9113 2142113 : if (ZoneLoad >= SensOutputOn) {
9114 1360958 : break;
9115 : }
9116 : }
9117 : }
9118 : } else { // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
9119 : // Staged control
9120 0 : if (state.dataUnitarySystems->HeatingLoad) {
9121 0 : CoolPLR = 0.0;
9122 0 : HeatPLR = 1.0;
9123 0 : SpeedNum = this->m_StageNum;
9124 0 : if (SpeedNum == 1) {
9125 0 : this->m_HeatingSpeedRatio = 0.0;
9126 : } else {
9127 0 : this->m_HeatingSpeedRatio = 1.0;
9128 0 : SpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
9129 : }
9130 0 : this->m_HeatingCycRatio = 1.0;
9131 0 : this->m_HeatingSpeedNum = SpeedNum;
9132 0 : this->calcUnitarySystemToLoad(state,
9133 : AirLoopNum,
9134 : FirstHVACIteration,
9135 : CoolPLR,
9136 : HeatPLR,
9137 : OnOffAirFlowRatio,
9138 : SensOutputOn,
9139 : LatOutputOn,
9140 0 : HXUnitOn,
9141 : HeatCoilLoad,
9142 : SupHeaterLoad,
9143 : CompressorONFlag);
9144 0 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
9145 0 : this->m_HeatingSpeedRatio = 0.0;
9146 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
9147 0 : if (this->m_HeatingSpeedNum == 0) {
9148 0 : this->m_HeatingCycRatio = 0.0;
9149 0 : HeatPLR = 0.0;
9150 : } else {
9151 0 : this->m_HeatingCycRatio = 1.0;
9152 0 : HeatPLR = 1.0;
9153 : }
9154 0 : this->calcUnitarySystemToLoad(state,
9155 : AirLoopNum,
9156 : FirstHVACIteration,
9157 : CoolPLR,
9158 : HeatPLR,
9159 : OnOffAirFlowRatio,
9160 : SensOutputOff,
9161 : LatOutputOff,
9162 0 : HXUnitOn,
9163 : HeatCoilLoad,
9164 : SupHeaterLoad,
9165 : CompressorONFlag);
9166 0 : this->m_HeatingSpeedNum = SpeedNum;
9167 : }
9168 0 : if (ZoneLoad <= SensOutputOn) {
9169 : // EXIT ????????????
9170 : }
9171 : } else { // Cooling or moisture load
9172 0 : CoolPLR = 1.0;
9173 0 : HeatPLR = 0.0;
9174 0 : SpeedNum = std::abs(this->m_StageNum);
9175 0 : if (SpeedNum == 1) {
9176 0 : this->m_CoolingSpeedRatio = 0.0;
9177 : } else {
9178 0 : this->m_CoolingSpeedRatio = 1.0;
9179 0 : SpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
9180 : }
9181 0 : this->m_CoolingCycRatio = 1.0;
9182 0 : this->m_CoolingSpeedNum = SpeedNum;
9183 0 : this->calcUnitarySystemToLoad(state,
9184 : AirLoopNum,
9185 : FirstHVACIteration,
9186 : CoolPLR,
9187 : HeatPLR,
9188 : OnOffAirFlowRatio,
9189 : SensOutputOn,
9190 : LatOutputOn,
9191 0 : HXUnitOn,
9192 : HeatCoilLoad,
9193 : SupHeaterLoad,
9194 : CompressorONFlag);
9195 :
9196 0 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
9197 0 : this->m_CoolingSpeedRatio = 0.0;
9198 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9199 0 : if (this->m_CoolingSpeedNum == 0) {
9200 0 : this->m_CoolingCycRatio = 0.0;
9201 0 : CoolPLR = 0.0;
9202 : } else {
9203 0 : this->m_CoolingCycRatio = 1.0;
9204 0 : CoolPLR = 1.0;
9205 : }
9206 0 : this->calcUnitarySystemToLoad(state,
9207 : AirLoopNum,
9208 : FirstHVACIteration,
9209 : CoolPLR,
9210 : HeatPLR,
9211 : OnOffAirFlowRatio,
9212 : SensOutputOff,
9213 : LatOutputOff,
9214 0 : HXUnitOn,
9215 : HeatCoilLoad,
9216 : SupHeaterLoad,
9217 : CompressorONFlag);
9218 0 : this->m_CoolingSpeedNum = SpeedNum;
9219 : }
9220 0 : if (ZoneLoad >= SensOutputOn) {
9221 : // EXIT ???????????
9222 : }
9223 : }
9224 : } // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
9225 :
9226 4381357 : FullSensibleOutput = SensOutputOn;
9227 :
9228 4381357 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
9229 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
9230 : // if no load, or only a moisture load which can't be met at PLR=1, RETURN
9231 0 : return;
9232 : }
9233 :
9234 : // use the ASHRAE 90.1 method of reduced fan speed at low loads
9235 4381357 : if (this->m_SimASHRAEModel) {
9236 :
9237 : // check to make sure unit has the capacity to meet the load
9238 0 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
9239 0 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
9240 0 : UnitarySys &SZVAVModel(state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum]);
9241 0 : SZVAVModel::calcSZVAVModel(state,
9242 : SZVAVModel,
9243 : this->m_UnitarySysNum,
9244 : FirstHVACIteration,
9245 0 : state.dataUnitarySystems->CoolingLoad,
9246 0 : state.dataUnitarySystems->HeatingLoad,
9247 : ZoneLoad,
9248 : OnOffAirFlowRatio,
9249 0 : HXUnitOn,
9250 : AirLoopNum,
9251 : PartLoadRatio,
9252 : CompressorONFlag);
9253 : }
9254 :
9255 : } else { // not ASHRAE model
9256 :
9257 : // must test to see if load is bounded by capacity before calling RegulaFalsi
9258 6909482 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
9259 2528125 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
9260 6695192 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad > SensOutputOff) ||
9261 2420980 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad < SensOutputOff)) {
9262 : Real64 SensOutput;
9263 : Real64 LatOutput;
9264 5152890 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
9265 880015 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
9266 7754 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR > 0.0) {
9267 1164 : int CoilInletNode = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapInletNodeIndex;
9268 1164 : this->CoilSHR = 0.0;
9269 : Real64 LowSpeedCoilSen;
9270 : Real64 LowSpeedCoilLat;
9271 1164 : CoolPLR = 0.0;
9272 1164 : HeatPLR = 0.0;
9273 1164 : this->m_CoolingSpeedNum = 1;
9274 1164 : this->calcUnitarySystemToLoad(state,
9275 : AirLoopNum,
9276 : FirstHVACIteration,
9277 : CoolPLR,
9278 : HeatPLR,
9279 : OnOffAirFlowRatio,
9280 : SensOutputOff,
9281 : LatOutputOff,
9282 1164 : HXUnitOn,
9283 : HeatCoilLoad,
9284 : SupHeaterLoad,
9285 : CompressorONFlag);
9286 1164 : CoolPLR = 1.0;
9287 1164 : HeatPLR = 0.0;
9288 1164 : this->m_CoolingCycRatio = 1.0;
9289 1164 : this->m_CoolingSpeedRatio = 0.0;
9290 : // this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9291 1164 : this->calcUnitarySystemToLoad(state,
9292 : AirLoopNum,
9293 : FirstHVACIteration,
9294 : CoolPLR,
9295 : HeatPLR,
9296 : OnOffAirFlowRatio,
9297 : SensOutputOn,
9298 : LatOutputOn,
9299 1164 : HXUnitOn,
9300 : HeatCoilLoad,
9301 : SupHeaterLoad,
9302 : CompressorONFlag);
9303 1164 : Real64 ZoneLatLoad = ZoneLoad * (1.0 / this->LoadSHR - 1.0);
9304 1164 : Real64 SenPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9305 1164 : Real64 LatPLR = (ZoneLatLoad - LatOutputOff) / (LatOutputOn - LatOutputOff);
9306 1164 : Real64 totalRate = 0.0;
9307 1164 : Real64 sensRate = 0.0;
9308 1164 : Real64 latRate = 0.0;
9309 1164 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9310 1164 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9311 1164 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9312 1164 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9313 1164 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9314 : sensRate,
9315 : latRate,
9316 : totalRate);
9317 1164 : if (LatPLR > 1.0 || LatPLR < 0.0) {
9318 0 : this->CoilSHR = this->LoadSHR;
9319 : } else {
9320 1164 : Real64 coilSens = sensRate * SenPLR;
9321 1164 : Real64 coilLat = latRate * LatPLR;
9322 1164 : this->CoilSHR = coilSens / (coilSens + coilLat);
9323 : }
9324 1164 : if (this->m_NumOfSpeedCooling > 1) {
9325 0 : this->SpeedSHR[1] = this->CoilSHR;
9326 0 : LowSpeedCoilSen = sensRate;
9327 0 : LowSpeedCoilLat = latRate;
9328 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9329 0 : this->SpeedSHR[SpeedNum] = this->LoadSHR;
9330 : }
9331 : }
9332 1164 : if (this->CoilSHR < 0.0) {
9333 0 : this->CoilSHR = this->LoadSHR;
9334 : }
9335 1164 : if (this->m_NumOfSpeedCooling > 1 && ZoneLoad < SensOutputOn) {
9336 : Real64 SenSPR;
9337 : Real64 LatSPR;
9338 0 : this->FullOutput[1] = SensOutputOn;
9339 0 : this->FullLatOutput[1] = LatOutputOn;
9340 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9341 0 : this->CoilSHR = 0.0;
9342 0 : CoolPLR = 1.0;
9343 0 : HeatPLR = 0.0;
9344 0 : this->m_CoolingSpeedRatio = 1.0;
9345 0 : this->m_CoolingCycRatio = 1.0;
9346 0 : this->m_CoolingSpeedNum = SpeedNum;
9347 0 : this->calcUnitarySystemToLoad(state,
9348 : AirLoopNum,
9349 : FirstHVACIteration,
9350 : CoolPLR,
9351 : HeatPLR,
9352 : OnOffAirFlowRatio,
9353 0 : this->FullOutput[SpeedNum],
9354 0 : this->FullLatOutput[SpeedNum],
9355 0 : HXUnitOn,
9356 : HeatCoilLoad,
9357 : SupHeaterLoad,
9358 : CompressorONFlag);
9359 0 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9360 0 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9361 0 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9362 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9363 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9364 : sensRate,
9365 : latRate,
9366 : totalRate);
9367 0 : SenSPR =
9368 0 : (ZoneLoad - this->FullOutput[SpeedNum - 1]) / (this->FullOutput[SpeedNum] - this->FullOutput[SpeedNum - 1]);
9369 0 : LatSPR = (ZoneLatLoad - this->FullLatOutput[SpeedNum - 1]) /
9370 0 : (this->FullLatOutput[SpeedNum] - this->FullLatOutput[SpeedNum - 1]);
9371 0 : if (LatSPR > 1.0 || LatSPR < 0.0) {
9372 0 : this->CoilSHR = this->LoadSHR;
9373 : } else {
9374 0 : Real64 coilSens = sensRate * SenSPR + (1.0 - SenSPR) * LowSpeedCoilSen;
9375 0 : Real64 coilLat = latRate * LatSPR + (1.0 - LatSPR) * LowSpeedCoilLat;
9376 0 : this->CoilSHR = coilSens / (coilSens + coilLat);
9377 : }
9378 0 : this->SpeedSHR[SpeedNum] = this->CoilSHR;
9379 0 : LowSpeedCoilSen = sensRate;
9380 0 : LowSpeedCoilLat = latRate;
9381 : }
9382 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9383 0 : CoolPLR = 1.0;
9384 0 : HeatPLR = 0.0;
9385 0 : if (SpeedNum == 1) {
9386 0 : this->m_CoolingSpeedRatio = 0.0;
9387 : } else {
9388 0 : this->m_CoolingSpeedRatio = 1.0;
9389 : }
9390 0 : this->m_CoolingCycRatio = 1.0;
9391 0 : this->m_CoolingSpeedNum = SpeedNum;
9392 0 : this->calcUnitarySystemToLoad(state,
9393 : AirLoopNum,
9394 : FirstHVACIteration,
9395 : CoolPLR,
9396 : HeatPLR,
9397 : OnOffAirFlowRatio,
9398 : SensOutputOn,
9399 : LatOutputOn,
9400 0 : HXUnitOn,
9401 : HeatCoilLoad,
9402 : SupHeaterLoad,
9403 : CompressorONFlag);
9404 0 : if (ZoneLoad >= SensOutputOn) {
9405 0 : this->CoilSHR = this->SpeedSHR[SpeedNum];
9406 0 : break;
9407 : }
9408 : }
9409 : }
9410 : }
9411 : }
9412 4272875 : if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9413 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
9414 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9415 0 : HeatPLR = 0.0;
9416 0 : this->calcUnitarySystemToLoad(state,
9417 : AirLoopNum,
9418 : FirstHVACIteration,
9419 : CoolPLR,
9420 : HeatPLR,
9421 : OnOffAirFlowRatio,
9422 : SensOutput,
9423 : LatOutput,
9424 0 : HXUnitOn,
9425 : HeatCoilLoad,
9426 : SupHeaterLoad,
9427 : CompressorONFlag);
9428 0 : PartLoadRatio = CoolPLR;
9429 4272875 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9430 4272875 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1 &&
9431 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
9432 0 : HeatPLR = 0.0;
9433 0 : this->calcUnitarySystemToLoad(state,
9434 : AirLoopNum,
9435 : FirstHVACIteration,
9436 : 1.0,
9437 : HeatPLR,
9438 : OnOffAirFlowRatio,
9439 : SensOutputOn,
9440 : LatOutputOn,
9441 0 : HXUnitOn,
9442 : HeatCoilLoad,
9443 : SupHeaterLoad,
9444 : CompressorONFlag);
9445 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9446 0 : this->calcUnitarySystemToLoad(state,
9447 : AirLoopNum,
9448 : FirstHVACIteration,
9449 : CoolPLR,
9450 : HeatPLR,
9451 : OnOffAirFlowRatio,
9452 : SensOutput,
9453 : LatOutput,
9454 0 : HXUnitOn,
9455 : HeatCoilLoad,
9456 : SupHeaterLoad,
9457 : CompressorONFlag);
9458 0 : PartLoadRatio = CoolPLR;
9459 4272875 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9460 4272875 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1) {
9461 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9462 0 : HeatPLR = 0.0;
9463 0 : this->calcUnitarySystemToLoad(state,
9464 : AirLoopNum,
9465 : FirstHVACIteration,
9466 : CoolPLR,
9467 : HeatPLR,
9468 : OnOffAirFlowRatio,
9469 : SensOutput,
9470 : LatOutput,
9471 0 : HXUnitOn,
9472 : HeatCoilLoad,
9473 : SupHeaterLoad,
9474 : CompressorONFlag);
9475 0 : PartLoadRatio = CoolPLR;
9476 4272875 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9477 0 : (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
9478 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
9479 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel)) {
9480 0 : CoolPLR = 0.0;
9481 0 : HeatPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9482 0 : this->calcUnitarySystemToLoad(state,
9483 : AirLoopNum,
9484 : FirstHVACIteration,
9485 : CoolPLR,
9486 : HeatPLR,
9487 : OnOffAirFlowRatio,
9488 : SensOutput,
9489 : LatOutput,
9490 0 : HXUnitOn,
9491 : HeatCoilLoad,
9492 : SupHeaterLoad,
9493 : CompressorONFlag);
9494 0 : PartLoadRatio = HeatPLR;
9495 4272875 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9496 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9497 0 : CoolPLR = 0.0;
9498 0 : if (this->m_HeatingSpeedNum == 1) {
9499 0 : this->m_HeatingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_HeatingSpeedNum] - SensOutputOff);
9500 0 : HeatPLR = this->m_HeatingCycRatio;
9501 0 : this->m_HeatingSpeedRatio = 0.0;
9502 : } else {
9503 0 : this->m_HeatingCycRatio = 1.0;
9504 0 : this->m_HeatingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_HeatingSpeedNum - 1]) /
9505 0 : (this->FullOutput[this->m_HeatingSpeedNum] - this->FullOutput[this->m_HeatingSpeedNum - 1]);
9506 0 : HeatPLR = this->m_HeatingSpeedRatio;
9507 : }
9508 0 : this->calcUnitarySystemToLoad(state,
9509 : AirLoopNum,
9510 : FirstHVACIteration,
9511 : CoolPLR,
9512 : HeatPLR,
9513 : OnOffAirFlowRatio,
9514 : SensOutput,
9515 : LatOutput,
9516 0 : HXUnitOn,
9517 : HeatCoilLoad,
9518 : SupHeaterLoad,
9519 : CompressorONFlag);
9520 0 : PartLoadRatio = HeatPLR;
9521 4272875 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9522 4272875 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1) {
9523 0 : HeatPLR = 0.0;
9524 0 : if (this->m_CoolingSpeedNum == 1) {
9525 0 : this->m_CoolingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_CoolingSpeedNum] - SensOutputOff);
9526 0 : CoolPLR = this->m_CoolingCycRatio;
9527 0 : this->m_CoolingSpeedRatio = 0.0;
9528 : } else {
9529 0 : this->m_CoolingCycRatio = 1.0;
9530 0 : this->m_CoolingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_CoolingSpeedNum - 1]) /
9531 0 : (this->FullOutput[this->m_CoolingSpeedNum] - this->FullOutput[this->m_CoolingSpeedNum - 1]);
9532 0 : CoolPLR = this->m_CoolingSpeedRatio;
9533 : }
9534 0 : this->calcUnitarySystemToLoad(state,
9535 : AirLoopNum,
9536 : FirstHVACIteration,
9537 : CoolPLR,
9538 : HeatPLR,
9539 : OnOffAirFlowRatio,
9540 : SensOutput,
9541 : LatOutput,
9542 0 : HXUnitOn,
9543 : HeatCoilLoad,
9544 : SupHeaterLoad,
9545 : CompressorONFlag);
9546 0 : PartLoadRatio = CoolPLR;
9547 : } else {
9548 :
9549 4272875 : Real64 par6 = state.dataUnitarySystems->CoolingLoad ? 1.0 : 0.0;
9550 19273421 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9551 : Real64 const PartLoadRatio) {
9552 30001092 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9553 : PartLoadRatio,
9554 15000546 : this->m_UnitarySysNum,
9555 : FirstHVACIteration,
9556 : // par 3 not used?
9557 : CompressorONFlag,
9558 : ZoneLoad,
9559 : par6,
9560 : 1.0,
9561 : OnOffAirFlowRatio,
9562 : HXUnitOn,
9563 : // par 10 not used
9564 15000546 : AirLoopNum);
9565 4272875 : };
9566 : // Tolerance is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9567 4272875 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
9568 :
9569 4272875 : if (SolFlag == -1) {
9570 245 : if (state.dataUnitarySystems->HeatingLoad) {
9571 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9572 : // This does cause a problem when coil cannot turn on when OAT < min allowed or scheduled off
9573 : // If max iteration limit is exceeded, how do we know if the heating coil is operating?
9574 0 : TempMaxPLR = -0.1;
9575 0 : TempSensOutput = SensOutputOff;
9576 0 : while ((TempSensOutput - ZoneLoad) < 0.0 && TempMaxPLR < 1.0) {
9577 : // find upper limit of HeatingPLR
9578 0 : TempMaxPLR += 0.1;
9579 :
9580 : // SUBROUTINE SetSpeedVariables(UnitarySysNum, SensibleLoad, PartLoadRatio)
9581 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9582 0 : this->calcUnitarySystemToLoad(state,
9583 : AirLoopNum,
9584 : FirstHVACIteration,
9585 : CoolPLR,
9586 : TempMaxPLR,
9587 : OnOffAirFlowRatio,
9588 : TempSensOutput,
9589 : TempLatOutput,
9590 0 : HXUnitOn,
9591 : HeatCoilLoad,
9592 : SupHeaterLoad,
9593 : CompressorONFlag);
9594 : }
9595 0 : TempMinPLR = TempMaxPLR;
9596 0 : while ((TempSensOutput - ZoneLoad) > 0.0 && TempMinPLR > 0.0) {
9597 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9598 0 : TempMaxPLR = TempMinPLR;
9599 : // find minimum limit of HeatingPLR
9600 0 : TempMinPLR -= 0.01;
9601 0 : this->setSpeedVariables(state, true, TempMinPLR);
9602 0 : this->calcUnitarySystemToLoad(state,
9603 : AirLoopNum,
9604 : FirstHVACIteration,
9605 : CoolPLR,
9606 : TempMinPLR,
9607 : OnOffAirFlowRatio,
9608 : TempSensOutput,
9609 : TempLatOutput,
9610 0 : HXUnitOn,
9611 : HeatCoilLoad,
9612 : SupHeaterLoad,
9613 : CompressorONFlag);
9614 : }
9615 : // Now solve again with tighter PLR limits
9616 : auto f2 = // (AUTO_OK_LAMBDA)
9617 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9618 : Real64 const PartLoadRatio) {
9619 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9620 : PartLoadRatio,
9621 0 : this->m_UnitarySysNum,
9622 : FirstHVACIteration,
9623 : // par 3 not used?
9624 : CompressorONFlag,
9625 : ZoneLoad,
9626 : par6,
9627 : 1.0,
9628 : OnOffAirFlowRatio,
9629 : HXUnitOn,
9630 : // par 10 not used
9631 0 : AirLoopNum);
9632 0 : };
9633 0 : General::SolveRoot(state, this->m_HeatConvTol, MaxIter, SolFlag, HeatPLR, f2, TempMinPLR, TempMaxPLR);
9634 0 : this->calcUnitarySystemToLoad(state,
9635 : AirLoopNum,
9636 : FirstHVACIteration,
9637 : CoolPLR,
9638 : HeatPLR,
9639 : OnOffAirFlowRatio,
9640 : TempSensOutput,
9641 : TempLatOutput,
9642 0 : HXUnitOn,
9643 : HeatCoilLoad,
9644 : SupHeaterLoad,
9645 : CompressorONFlag);
9646 245 : } else if (state.dataUnitarySystems->CoolingLoad) {
9647 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9648 : // IF iteration limit is exceeded (SolFlag = -1), find tighter boundary of solution and repeat RegulaFalsi
9649 245 : TempMaxPLR = -0.1;
9650 245 : TempSysOutput = SensOutputOff;
9651 245 : TempLoad = ZoneLoad;
9652 851 : while ((TempSysOutput - TempLoad) > 0.0 &&
9653 : TempMaxPLR < 0.95) { // avoid PLR > 1 by limiting TempMaxPLR to 1 (i.e., TempMaxPLR += 0.1)
9654 : // find upper limit of HeatingPLR
9655 606 : TempMaxPLR += 0.1;
9656 606 : if (TempMaxPLR > 0.95 && TempMaxPLR < 1.05) {
9657 0 : TempMaxPLR = 1.0; // enforce a perfect 1.0 at the top end
9658 : }
9659 606 : this->setSpeedVariables(state, true, TempMaxPLR);
9660 606 : this->calcUnitarySystemToLoad(state,
9661 : AirLoopNum,
9662 : FirstHVACIteration,
9663 : TempMaxPLR,
9664 : HeatPLR,
9665 : OnOffAirFlowRatio,
9666 : TempSensOutput,
9667 : TempLatOutput,
9668 606 : HXUnitOn,
9669 : HeatCoilLoad,
9670 : SupHeaterLoad,
9671 : CompressorONFlag);
9672 606 : TempSysOutput = TempSensOutput;
9673 : }
9674 245 : TempMinPLR = TempMaxPLR;
9675 2081 : while ((TempSysOutput - TempLoad) < 0.0 &&
9676 : TempMinPLR > 0.025) { // lower limit might be changed to 0.005 without adverse affect
9677 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9678 1836 : TempMaxPLR = TempMinPLR;
9679 : // find minimum limit of HeatingPLR
9680 1836 : TempMinPLR -= 0.01;
9681 1836 : this->setSpeedVariables(state, true, TempMinPLR);
9682 1836 : this->calcUnitarySystemToLoad(state,
9683 : AirLoopNum,
9684 : FirstHVACIteration,
9685 : TempMinPLR,
9686 : HeatPLR,
9687 : OnOffAirFlowRatio,
9688 : TempSensOutput,
9689 : TempLatOutput,
9690 1836 : HXUnitOn,
9691 : HeatCoilLoad,
9692 : SupHeaterLoad,
9693 : CompressorONFlag);
9694 1836 : TempSysOutput = TempSensOutput;
9695 : }
9696 : // Now solve again with tighter PLR limits
9697 : auto f2 = // (AUTO_OK_LAMBDA)
9698 1129 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9699 : Real64 const PartLoadRatio) {
9700 1768 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9701 : PartLoadRatio,
9702 884 : this->m_UnitarySysNum,
9703 : FirstHVACIteration,
9704 : // par 3 not used?
9705 : CompressorONFlag,
9706 : ZoneLoad,
9707 : par6,
9708 : 1.0,
9709 : OnOffAirFlowRatio,
9710 : HXUnitOn,
9711 : // par 10 not used
9712 884 : AirLoopNum);
9713 245 : };
9714 245 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, CoolPLR, f2, TempMinPLR, TempMaxPLR);
9715 245 : this->calcUnitarySystemToLoad(state,
9716 : AirLoopNum,
9717 : FirstHVACIteration,
9718 : CoolPLR,
9719 : HeatPLR,
9720 : OnOffAirFlowRatio,
9721 : TempSensOutput,
9722 : TempLatOutput,
9723 245 : HXUnitOn,
9724 : HeatCoilLoad,
9725 : SupHeaterLoad,
9726 : CompressorONFlag);
9727 : } // IF(HeatingLoad)THEN
9728 245 : if (SolFlag == -1) {
9729 13 : if (std::abs(ZoneLoad - TempSensOutput) > HVAC::SmallLoad) {
9730 13 : if (this->MaxIterIndex == 0) {
9731 3 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9732 6 : ShowContinueError(state, " Iteration limit exceeded in calculating system sensible part-load ratio.");
9733 6 : ShowContinueErrorTimeStamp(state,
9734 6 : format("Sensible load to be met = {:.2T} (watts), sensible output = {:.2T} "
9735 : "(watts), and the simulation continues.",
9736 : ZoneLoad,
9737 : TempSensOutput));
9738 : }
9739 104 : ShowRecurringWarningErrorAtEnd(state,
9740 26 : this->UnitType + " \"" + this->Name +
9741 : "\" - Iteration limit exceeded in calculating sensible part-load ratio error "
9742 : "continues. Sensible load statistics:",
9743 13 : this->MaxIterIndex,
9744 : ZoneLoad,
9745 : ZoneLoad);
9746 : }
9747 232 : } else if (SolFlag == -2) {
9748 202 : if (this->RegulaFalsiFailedIndex == 0) {
9749 4 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9750 8 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9751 8 : ShowContinueErrorTimeStamp(
9752 8 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9753 : }
9754 1616 : ShowRecurringWarningErrorAtEnd(
9755 : state,
9756 404 : this->UnitType + " \"" + this->Name +
9757 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9758 202 : this->RegulaFalsiFailedIndex,
9759 : ZoneLoad,
9760 : ZoneLoad);
9761 : }
9762 4272630 : } else if (SolFlag == -2) {
9763 413 : if (this->RegulaFalsiFailedIndex == 0) {
9764 4 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9765 8 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9766 8 : ShowContinueErrorTimeStamp(
9767 8 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9768 : }
9769 3304 : ShowRecurringWarningErrorAtEnd(
9770 : state,
9771 826 : this->UnitType + " \"" + this->Name +
9772 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9773 413 : this->RegulaFalsiFailedIndex,
9774 : ZoneLoad,
9775 : ZoneLoad);
9776 : } // IF (SolFlag == -1) THEN
9777 : }
9778 : } else { // load is not bounded by capacity. Leave PLR=1 or turn off unit?
9779 1337 : this->m_CoolingPartLoadFrac = 0.0;
9780 1337 : this->m_HeatingPartLoadFrac = 0.0;
9781 1337 : CoolPLR = 0.0;
9782 1337 : HeatPLR = 0.0;
9783 1337 : PartLoadRatio = 0.0;
9784 : } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN
9785 : } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN
9786 : }
9787 :
9788 4381357 : if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) {
9789 145361 : if (this->m_HeatingSpeedNum == 1) {
9790 45829 : this->m_HeatingCycRatio = PartLoadRatio;
9791 45829 : this->m_HeatingSpeedRatio = 0.0;
9792 : } else {
9793 99532 : if (this->m_SingleMode == 0) {
9794 97522 : this->m_HeatingCycRatio = 1.0;
9795 97522 : this->m_HeatingSpeedRatio = PartLoadRatio;
9796 : } else {
9797 2010 : this->m_HeatingCycRatio = PartLoadRatio;
9798 2010 : this->m_HeatingSpeedRatio = 1.0;
9799 : }
9800 : }
9801 145361 : HeatPLR = PartLoadRatio;
9802 145361 : CoolPLR = 0.0;
9803 145361 : this->m_CoolingCycRatio = 0.0;
9804 145361 : this->m_CoolingSpeedRatio = 0.0;
9805 4235996 : } else if (state.dataUnitarySystems->CoolingLoad && (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil)) {
9806 799881 : if (this->m_CoolingSpeedNum == 1) {
9807 313787 : this->m_CoolingCycRatio = PartLoadRatio;
9808 313787 : this->m_CoolingSpeedRatio = 0.0;
9809 : } else {
9810 486094 : if (this->m_SingleMode == 0) {
9811 483046 : this->m_CoolingCycRatio = 1.0;
9812 483046 : this->m_CoolingSpeedRatio = PartLoadRatio;
9813 : } else {
9814 3048 : this->m_CoolingCycRatio = PartLoadRatio;
9815 3048 : this->m_CoolingSpeedRatio = 1.0;
9816 : }
9817 : }
9818 799881 : this->m_HeatingCycRatio = 0.0;
9819 799881 : this->m_HeatingSpeedRatio = 0.0;
9820 799881 : HeatPLR = 0.0;
9821 799881 : CoolPLR = PartLoadRatio;
9822 : } else {
9823 3436115 : HeatPLR = this->m_HeatingPartLoadFrac;
9824 3436115 : CoolPLR = this->m_CoolingPartLoadFrac;
9825 : }
9826 :
9827 4381357 : this->calcUnitarySystemToLoad(state,
9828 : AirLoopNum,
9829 : FirstHVACIteration,
9830 : CoolPLR,
9831 : HeatPLR,
9832 : OnOffAirFlowRatio,
9833 : TempSensOutput,
9834 : TempLatOutput,
9835 4381357 : HXUnitOn,
9836 : HeatCoilLoad,
9837 : SupHeaterLoad,
9838 : CompressorONFlag);
9839 :
9840 : // FullSensibleOutput is used to set supplemental heater PLR in calling routine
9841 : // OnOffAirFlowRatio is used to average air flow between ON and OFF state
9842 4381357 : FullSensibleOutput = TempSensOutput;
9843 4381357 : LatOutputOn = TempLatOutput;
9844 :
9845 : // RETURN if the moisture load is met
9846 4381357 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad >= TempLatOutput) {
9847 4346545 : return;
9848 : }
9849 : // Multimode does not meet the latent load, only the sensible load with or without HX active
9850 : // what if there is a heating load for a system using Multimode?
9851 34812 : if (!state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9852 0 : return;
9853 : }
9854 : // if HX was previously turned on return since sensible load is already met
9855 34812 : if (state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode && HXUnitOn) {
9856 20914 : return;
9857 : }
9858 : // IF(HeatingLoad .AND. UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)RETURN
9859 :
9860 13898 : if ((this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
9861 :
9862 : // find maximum latent output IF not already calculated
9863 13898 : if (state.dataUnitarySystems->HeatingLoad) {
9864 0 : CoolPLR = 1.0;
9865 0 : this->m_CoolingPartLoadFrac = 1.0;
9866 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9867 0 : this->m_CoolingSpeedRatio = 1.0;
9868 0 : this->m_CoolingCycRatio = 1.0;
9869 0 : if (this->m_CoolingSpeedNum > 0) {
9870 0 : this->m_HeatingPartLoadFrac = 0.0;
9871 0 : this->m_HeatingSpeedNum = 0;
9872 0 : HeatPLR = 0.0;
9873 0 : state.dataUnitarySystems->CoolingLoad = true;
9874 0 : state.dataUnitarySystems->HeatingLoad = false;
9875 0 : this->m_HeatingCoilSensDemand = 0.0;
9876 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9877 0 : this->calcUnitarySystemToLoad(state,
9878 : AirLoopNum,
9879 : FirstHVACIteration,
9880 : 0.0,
9881 : 0.0,
9882 : OnOffAirFlowRatio,
9883 : TempSensOutput,
9884 : TempLatOutput,
9885 0 : HXUnitOn,
9886 : HeatCoilLoad,
9887 : SupHeaterLoad,
9888 : CompressorONFlag);
9889 0 : this->calcUnitarySystemToLoad(state,
9890 : AirLoopNum,
9891 : FirstHVACIteration,
9892 : CoolPLR,
9893 : HeatPLR,
9894 : OnOffAirFlowRatio,
9895 : TempSensOutput,
9896 : LatOutputOn,
9897 0 : HXUnitOn,
9898 : HeatCoilLoad,
9899 : SupHeaterLoad,
9900 : CompressorONFlag);
9901 : } else {
9902 0 : this->m_HeatingCoilSensDemand = 0.0;
9903 0 : this->m_CoolingCoilLatentDemand = 0.0;
9904 0 : this->calcUnitarySystemToLoad(state,
9905 : AirLoopNum,
9906 : FirstHVACIteration,
9907 : 0.0,
9908 : 0.0,
9909 : OnOffAirFlowRatio,
9910 : TempSensOutput,
9911 : TempLatOutput,
9912 0 : HXUnitOn,
9913 : HeatCoilLoad,
9914 : SupHeaterLoad,
9915 : CompressorONFlag);
9916 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9917 0 : this->calcUnitarySystemToLoad(state,
9918 : AirLoopNum,
9919 : FirstHVACIteration,
9920 : CoolPLR,
9921 : HeatPLR,
9922 : OnOffAirFlowRatio,
9923 : TempSensOutput,
9924 : LatOutputOn,
9925 0 : HXUnitOn,
9926 : HeatCoilLoad,
9927 : SupHeaterLoad,
9928 : CompressorONFlag);
9929 : }
9930 : }
9931 :
9932 13898 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
9933 4700 : HXUnitOn = true;
9934 4700 : CoolPLR = 1.0;
9935 4700 : this->m_CoolingPartLoadFrac = 1.0;
9936 4700 : this->calcUnitarySystemToLoad(state,
9937 : AirLoopNum,
9938 : FirstHVACIteration,
9939 : CoolPLR,
9940 : HeatPLR,
9941 : OnOffAirFlowRatio,
9942 : TempSensOutput,
9943 : LatOutputOn,
9944 4700 : HXUnitOn,
9945 : HeatCoilLoad,
9946 : SupHeaterLoad,
9947 : CompressorONFlag);
9948 4700 : FullSensibleOutput = TempSensOutput;
9949 : }
9950 :
9951 13898 : if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
9952 9198 : HXUnitOn = true; // HX is needed to meet moisture load
9953 9198 : if (this->m_NumOfSpeedCooling > 0) {
9954 19461 : for (SpeedNum = this->m_CoolingSpeedNum; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9955 14636 : CoolPLR = 1.0;
9956 14636 : this->m_CoolingPartLoadFrac = CoolPLR;
9957 14636 : this->m_CoolingSpeedRatio = 1.0;
9958 14636 : this->m_CoolingCycRatio = 1.0;
9959 14636 : this->m_CoolingSpeedNum = SpeedNum;
9960 14636 : this->calcUnitarySystemToLoad(state,
9961 : AirLoopNum,
9962 : FirstHVACIteration,
9963 : CoolPLR,
9964 : HeatPLR,
9965 : OnOffAirFlowRatio,
9966 : SensOutputOn,
9967 : LatOutputOn,
9968 14636 : HXUnitOn,
9969 : HeatCoilLoad,
9970 : SupHeaterLoad,
9971 : CompressorONFlag);
9972 14636 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
9973 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9974 : }
9975 : // over specified logic? it has to be a water coil? what about other VS coil models?
9976 14636 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9977 14636 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
9978 14636 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9979 0 : !this->m_DiscreteSpeedCoolingCoil)) {
9980 0 : this->m_CoolingSpeedRatio = 0.0;
9981 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9982 0 : if (this->m_CoolingSpeedNum == 0) {
9983 0 : this->m_CoolingCycRatio = 0.0;
9984 0 : CoolPLR = 0.0;
9985 : } else {
9986 0 : this->m_CoolingCycRatio = 1.0;
9987 0 : this->m_CoolingSpeedRatio = 0.0;
9988 0 : if (this->m_SingleMode == 1) {
9989 0 : CoolPLR = 1.0;
9990 : }
9991 : }
9992 :
9993 0 : this->calcUnitarySystemToLoad(state,
9994 : AirLoopNum,
9995 : FirstHVACIteration,
9996 : CoolPLR,
9997 : HeatPLR,
9998 : OnOffAirFlowRatio,
9999 : SensOutputOn,
10000 : LatOutputOn,
10001 0 : HXUnitOn,
10002 : HeatCoilLoad,
10003 : SupHeaterLoad,
10004 : CompressorONFlag);
10005 0 : this->m_CoolingSpeedNum = SpeedNum;
10006 : }
10007 14636 : if (state.dataUnitarySystems->MoistureLoad >= LatOutputOn) {
10008 4373 : break;
10009 : }
10010 : }
10011 : } else {
10012 0 : CoolPLR = 1.0;
10013 0 : this->calcUnitarySystemToLoad(state,
10014 : AirLoopNum,
10015 : FirstHVACIteration,
10016 : CoolPLR,
10017 : HeatPLR,
10018 : OnOffAirFlowRatio,
10019 : SensOutputOn,
10020 : LatOutputOn,
10021 0 : HXUnitOn,
10022 : HeatCoilLoad,
10023 : SupHeaterLoad,
10024 : CompressorONFlag);
10025 0 : this->m_CoolingPartLoadFrac = CoolPLR;
10026 : }
10027 : }
10028 :
10029 27796 : if ((state.dataUnitarySystems->MoistureLoad < TempLatOutput) &&
10030 13898 : (state.dataUnitarySystems->MoistureLoad > LatOutputOn)) { // bounds check for RegulaFalsi
10031 :
10032 : // save heating PLR
10033 6137 : HeatPLR = this->m_HeatingPartLoadFrac;
10034 : Real64 par5;
10035 : Real64 par7;
10036 6137 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10037 1764 : par5 = ZoneLoad;
10038 1764 : par7 = 1.0;
10039 : } else {
10040 4373 : par5 = state.dataUnitarySystems->MoistureLoad;
10041 4373 : par7 = 0.0;
10042 : }
10043 : // Tolerance is fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
10044 29129 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, par5, par7, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
10045 : Real64 const PartLoadRatio) {
10046 45984 : return UnitarySys::calcUnitarySystemLoadResidual(state,
10047 : PartLoadRatio,
10048 22992 : this->m_UnitarySysNum,
10049 : FirstHVACIteration,
10050 : // par 3 not used?
10051 : CompressorONFlag,
10052 : par5,
10053 : 1.0,
10054 : par7,
10055 : OnOffAirFlowRatio,
10056 : HXUnitOn,
10057 : // par 10 not used
10058 22992 : AirLoopNum);
10059 6137 : };
10060 6137 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, PartLoadRatio, f, 0.0, 1.0);
10061 6137 : this->m_CoolingPartLoadFrac = PartLoadRatio;
10062 6137 : this->m_HeatingPartLoadFrac = HeatPLR;
10063 7761 : } else if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
10064 : // Logic below needs further look...what to do if the bounds check for RegulaFalsi fail?
10065 : // I'm not even sure if this should be done.
10066 : // It's wrong anyway, since there won't be a cooling load if multimode (see RETURN about 80 lines up).
10067 7761 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode) {
10068 4825 : this->m_CoolingPartLoadFrac = 1.0;
10069 : }
10070 : }
10071 : }
10072 :
10073 13898 : CoolPLR = this->m_CoolingPartLoadFrac;
10074 13898 : HeatPLR = this->m_HeatingPartLoadFrac;
10075 :
10076 13898 : this->calcUnitarySystemToLoad(state,
10077 : AirLoopNum,
10078 : FirstHVACIteration,
10079 : CoolPLR,
10080 : HeatPLR,
10081 : OnOffAirFlowRatio,
10082 : TempSensOutput,
10083 : TempLatOutput,
10084 13898 : HXUnitOn,
10085 : HeatCoilLoad,
10086 : SupHeaterLoad,
10087 : CompressorONFlag);
10088 :
10089 13898 : if (SolFlagLat == -1) {
10090 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
10091 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
10092 0 : TempMaxPLR = -0.1;
10093 0 : TempLatOutput = LatOutputOff;
10094 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
10095 : // find upper limit of HeatingPLR
10096 0 : TempMaxPLR += 0.1;
10097 0 : this->calcUnitarySystemToLoad(state,
10098 : AirLoopNum,
10099 : FirstHVACIteration,
10100 : TempMaxPLR,
10101 : HeatPLR,
10102 : OnOffAirFlowRatio,
10103 : TempSensOutput,
10104 : TempLatOutput,
10105 0 : HXUnitOn,
10106 : HeatCoilLoad,
10107 : SupHeaterLoad,
10108 : CompressorONFlag);
10109 : }
10110 0 : TempMinPLR = TempMaxPLR;
10111 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) < 0.0 && TempMinPLR > 0.0) {
10112 : // pull upper limit of HeatingPLR DOwn to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
10113 0 : TempMaxPLR = TempMinPLR;
10114 : // find minimum limit of HeatingPLR
10115 0 : TempMinPLR -= 0.01;
10116 0 : this->calcUnitarySystemToLoad(state,
10117 : AirLoopNum,
10118 : FirstHVACIteration,
10119 : TempMinPLR,
10120 : HeatPLR,
10121 : OnOffAirFlowRatio,
10122 : TempSensOutput,
10123 : TempLatOutput,
10124 0 : HXUnitOn,
10125 : HeatCoilLoad,
10126 : SupHeaterLoad,
10127 : CompressorONFlag);
10128 : }
10129 : // Now solve again with tighter PLR limits
10130 : Real64 par5;
10131 : Real64 par7;
10132 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10133 0 : par5 = ZoneLoad;
10134 0 : par7 = 1.0;
10135 : } else {
10136 0 : par5 = state.dataUnitarySystems->MoistureLoad;
10137 0 : par7 = 0.0;
10138 : }
10139 : // // Tolerance is fraction of load, M
10140 0 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, OnOffAirFlowRatio, HXUnitOn, AirLoopNum, par5, par7](
10141 : Real64 const PartLoadRatio) {
10142 : // 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
10143 : // a unit or integration test
10144 : // TODO: So I made some assumptions about the arguments. I'm not sure if ultimately this is even accessible, so maybe it doesn't
10145 : // matter.
10146 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
10147 : PartLoadRatio,
10148 0 : this->m_UnitarySysNum,
10149 : FirstHVACIteration,
10150 : // par 3 not used?
10151 : CompressorONFlag,
10152 : par5,
10153 : 1.0,
10154 : par7,
10155 : OnOffAirFlowRatio,
10156 : HXUnitOn,
10157 : // par 10 not used
10158 0 : AirLoopNum);
10159 0 : };
10160 0 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, CoolPLR, f, TempMinPLR, TempMaxPLR);
10161 0 : this->calcUnitarySystemToLoad(state,
10162 : AirLoopNum,
10163 : FirstHVACIteration,
10164 : CoolPLR,
10165 : HeatPLR,
10166 : OnOffAirFlowRatio,
10167 : TempSensOutput,
10168 : TempLatOutput,
10169 0 : HXUnitOn,
10170 : HeatCoilLoad,
10171 : SupHeaterLoad,
10172 : CompressorONFlag);
10173 0 : if (SolFlagLat == -1) {
10174 0 : if (std::abs(state.dataUnitarySystems->MoistureLoad - TempLatOutput) > HVAC::SmallLoad) {
10175 0 : if (this->warnIndex.m_LatMaxIterIndex == 0) {
10176 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
10177 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system Latent part-load ratio.");
10178 0 : ShowContinueErrorTimeStamp(
10179 : state,
10180 0 : format("Latent load to be met = {:.2T} (watts), Latent output = {:.2T} (watts), and the simulation continues.",
10181 0 : state.dataUnitarySystems->MoistureLoad,
10182 : TempLatOutput));
10183 : }
10184 0 : ShowRecurringWarningErrorAtEnd(
10185 : state,
10186 0 : this->UnitType + " \"" + this->Name +
10187 : "\" - Iteration limit exceeded in calculating Latent part-load ratio error continues. Latent load statistics:",
10188 0 : this->warnIndex.m_LatMaxIterIndex,
10189 0 : state.dataUnitarySystems->MoistureLoad,
10190 0 : state.dataUnitarySystems->MoistureLoad);
10191 : }
10192 0 : } else if (SolFlagLat == -2) {
10193 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
10194 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
10195 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
10196 0 : ShowContinueErrorTimeStamp(
10197 : state,
10198 0 : format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
10199 : }
10200 0 : ShowRecurringWarningErrorAtEnd(state,
10201 0 : this->UnitType + " \"" + this->Name +
10202 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
10203 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
10204 0 : state.dataUnitarySystems->MoistureLoad,
10205 0 : state.dataUnitarySystems->MoistureLoad);
10206 : }
10207 13898 : } else if (SolFlagLat == -2) {
10208 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
10209 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
10210 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
10211 0 : ShowContinueErrorTimeStamp(
10212 0 : state, format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
10213 : }
10214 0 : ShowRecurringWarningErrorAtEnd(state,
10215 0 : this->UnitType + " \"" + this->Name +
10216 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
10217 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
10218 0 : state.dataUnitarySystems->MoistureLoad,
10219 0 : state.dataUnitarySystems->MoistureLoad);
10220 : }
10221 :
10222 13898 : FullSensibleOutput = TempSensOutput;
10223 :
10224 13898 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
10225 : Real64 heatCoildT =
10226 13898 : (this->m_HeatCoilExists)
10227 13898 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
10228 13898 : : 0.0;
10229 : Real64 CoolingOnlySensibleOutput =
10230 13898 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
10231 13898 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
10232 13898 : heatCoildT);
10233 13898 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
10234 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
10235 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
10236 13193 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
10237 : // Heating mode and dehumidification is required
10238 : } else {
10239 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
10240 : // the heating coil pick up the load due to outdoor air.
10241 705 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
10242 : }
10243 6063320 : }
10244 :
10245 5997269 : void UnitarySys::initLoadBasedControl(EnergyPlusData &state,
10246 : int const AirLoopNum, // number of the current air loop being simulated
10247 : bool const FirstHVACIteration,
10248 : Real64 &OnOffAirFlowRatio,
10249 : Real64 &ZoneLoad)
10250 : {
10251 :
10252 : // SUBROUTINE INFORMATION:
10253 : // AUTHOR Richard Raustad, FSEC
10254 : // DATE WRITTEN February 2013
10255 :
10256 : // PURPOSE OF THIS SUBROUTINE:
10257 : // This subroutine is for initializations of the load controlled Unitary Systems.
10258 :
10259 : // METHODOLOGY EMPLOYED:
10260 : // Initialize mass flow rates and speed ratios. Calculate loads and adjust if necessary when using constant fan.
10261 :
10262 : // SUBROUTINE PARAMETER DEFINITIONS:
10263 : static constexpr std::string_view routineName("InitUnitarySystems");
10264 5997269 : Real64 QZnReq = 0.0;
10265 5997269 : Real64 QActual = 0.0;
10266 5997269 : Real64 SensOutputOff = 0.0;
10267 5997269 : Real64 LatOutputOff = 0.0;
10268 5997269 : Real64 HeatCoilLoad = 0.0;
10269 5997269 : Real64 SupHeaterLoad = 0.0;
10270 5997269 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
10271 :
10272 : // do the Begin Environment initializations
10273 5997269 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag2) {
10274 :
10275 2785 : bool errorsFound = false;
10276 : // set fluid-side hardware limits
10277 2785 : if (this->HeatCoilFluidInletNode > 0) {
10278 :
10279 62 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
10280 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10281 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
10282 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
10283 : Real64 CoilMaxVolFlowRate =
10284 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_HeatingCoilName, errorsFound);
10285 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10286 0 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
10287 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
10288 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
10289 : }
10290 : }
10291 : // IF steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10292 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
10293 0 : SteamCoils::SimulateSteamCoilComponents(state,
10294 : this->m_HeatingCoilName,
10295 : FirstHVACIteration,
10296 0 : this->m_HeatingCoilIndex,
10297 0 : 1.0,
10298 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10299 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, errorsFound);
10300 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10301 0 : Real64 TempSteamIn = 100.0;
10302 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10303 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10304 : }
10305 : }
10306 : }
10307 :
10308 62 : PlantUtilities::InitComponentNodes(
10309 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
10310 : }
10311 2785 : if (this->m_SuppCoilFluidInletNode > 0) {
10312 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
10313 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
10314 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10315 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
10316 : Real64 CoilMaxVolFlowRate =
10317 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_SuppHeatCoilName, errorsFound);
10318 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10319 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum)
10320 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
10321 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
10322 : }
10323 : }
10324 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
10325 0 : SteamCoils::SimulateSteamCoilComponents(state,
10326 : this->m_SuppHeatCoilName,
10327 : FirstHVACIteration,
10328 0 : this->m_SuppHeatCoilIndex,
10329 0 : 1.0,
10330 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10331 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, errorsFound);
10332 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10333 0 : Real64 TempSteamIn = 100.0;
10334 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10335 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10336 : }
10337 : }
10338 0 : PlantUtilities::InitComponentNodes(
10339 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
10340 : }
10341 : }
10342 2785 : this->m_MyEnvrnFlag2 = false;
10343 : }
10344 :
10345 5997269 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && this->m_MyCheckFlag) {
10346 3380773 : if (this->m_AirLoopEquipment) {
10347 100 : int zoneInlet = this->m_ZoneInletNode;
10348 100 : if (zoneInlet == 0) {
10349 0 : this->m_ThisSysInputShouldBeGotten = true; // need to find zone inlet node once data is available
10350 0 : this->m_MySizingCheckFlag = true; // need to resize after getInput is read in again
10351 0 : this->m_OKToPrintSizing = true; // hope first time back through finds the data, else multiple prints to the eio
10352 0 : this->m_airLoopReturnCounter += 1;
10353 0 : if (this->m_airLoopReturnCounter < 3) {
10354 0 : return;
10355 : }
10356 : }
10357 : // setup zone equipment sequence information based on finding matching air terminal
10358 100 : if (state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex > 0) {
10359 100 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex)
10360 100 : .getPrioritiesForInletNode(state, zoneInlet, this->m_ZoneSequenceCoolingNum, this->m_ZoneSequenceHeatingNum);
10361 : }
10362 100 : this->m_MyCheckFlag = false;
10363 100 : if (this->m_ZoneSequenceCoolingNum == 0 || this->m_ZoneSequenceHeatingNum == 0) {
10364 0 : ShowSevereError(state,
10365 0 : format("{} \"{}\": Airloop air terminal in the zone equipment list for zone = {} not it or is not allowed "
10366 : "Zone Equipment Cooling or Heating Sequence = 0.",
10367 0 : this->UnitType,
10368 0 : this->Name,
10369 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10370 0 : ShowFatalError(
10371 : state,
10372 0 : format("Subroutine InitLoadBasedControl: Errors it in getting {} input. Preceding condition(s) causes termination.",
10373 0 : this->UnitType));
10374 : }
10375 : }
10376 3380773 : if (this->m_ZoneInletNode == 0) {
10377 0 : ShowSevereError(state,
10378 0 : format("{} \"{}\": The zone inlet node in the controlled zone ({}) is not found.",
10379 0 : this->UnitType,
10380 0 : this->Name,
10381 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10382 0 : ShowFatalError(
10383 : state,
10384 0 : format("Subroutine InitLoadBasedControl: Errors found in getting {} input. Preceding condition(s) causes termination.",
10385 0 : this->UnitType));
10386 : }
10387 : }
10388 :
10389 : // What type of logic is this? Is the point to go through the main IF once? or every other time?
10390 : // RR: This was used with AirflowNetwork to calculate duct losses.
10391 : // RR: AFN counts the number of passes through airloop equipment (same logic in Furnaces and other modules) and resets the counter to 0 on
10392 : // BeginEnvrnFlag. RR: This has been changed in this module and AFN to use AirflowNetworkFanActivated if AirflowNetworkUnitarySystem is seen
10393 : // by AFN. RR: Search for AirflowNetworkFanActivated in this module to see usage. The following lines of code can probably be removed although
10394 : // it would require a AFN input file to test.
10395 5997269 : if (state.dataGlobal->BeginEnvrnFlag && m_initLoadBasedControlAirLoopPass) {
10396 2685 : m_airLoopPassCounter = 0;
10397 2685 : m_initLoadBasedControlAirLoopPass = false;
10398 : }
10399 5997269 : if (!state.dataGlobal->BeginEnvrnFlag) {
10400 5973503 : this->m_MyEnvrnFlag2 = true; // this does not appear to be needed, only initializes autosized coil fluid flow rates
10401 5973503 : m_initLoadBasedControlAirLoopPass = true;
10402 : }
10403 :
10404 5997269 : ++m_airLoopPassCounter;
10405 5997269 : if (m_airLoopPassCounter > 2) {
10406 2996507 : m_airLoopPassCounter = 1;
10407 : }
10408 :
10409 : // reset duct losses from previous iteration
10410 5997269 : if (FirstHVACIteration) {
10411 2238276 : this->m_SenLoadLoss = 0.0;
10412 2238276 : this->m_LatLoadLoss = 0.0;
10413 : }
10414 :
10415 : // Calculate air distribution losses
10416 5997269 : if (!FirstHVACIteration && state.afn->AirflowNetworkFanActivated) {
10417 9960 : Real64 DeltaMassRate = 0.0;
10418 9960 : Real64 TotalOutput = 0.0; // total output rate, {W}
10419 9960 : Real64 SensibleOutputDelta = 0.0; // delta sensible output rate, {W}
10420 9960 : Real64 LatentOutputDelta = 0.0; // delta latent output rate, {W}
10421 9960 : Real64 TotalOutputDelta = 0.0; // delta total output rate, {W}
10422 9960 : int ZoneInNode = this->m_ZoneInletNode;
10423 9960 : Real64 MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10424 19920 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
10425 9960 : this->m_sysType != SysType::PackagedWSHP) {
10426 9960 : DeltaMassRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate -
10427 9960 : state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10428 9960 : if (DeltaMassRate < 0.0) {
10429 0 : DeltaMassRate = 0.0;
10430 : }
10431 : } else {
10432 0 : MassFlowRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
10433 0 : DeltaMassRate = 0.0;
10434 : }
10435 39840 : CalcComponentSensibleLatentOutput(MassFlowRate,
10436 9960 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10437 9960 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10438 9960 : state.dataLoopNodes->Node(ZoneInNode).Temp,
10439 9960 : state.dataLoopNodes->Node(ZoneInNode).HumRat,
10440 9960 : this->m_SenLoadLoss,
10441 9960 : this->m_LatLoadLoss,
10442 : TotalOutput);
10443 39840 : CalcComponentSensibleLatentOutput(DeltaMassRate,
10444 9960 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10445 9960 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10446 9960 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
10447 9960 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
10448 : SensibleOutputDelta,
10449 : LatentOutputDelta,
10450 : TotalOutputDelta);
10451 9960 : this->m_SenLoadLoss = this->m_SenLoadLoss + SensibleOutputDelta;
10452 9960 : if (std::abs(this->m_SensibleLoadMet) > 0.0) {
10453 9960 : if (std::abs(this->m_SenLoadLoss / this->m_SensibleLoadMet) < 0.001) {
10454 0 : this->m_SenLoadLoss = 0.0;
10455 : }
10456 : }
10457 9960 : if (this->m_Humidistat) {
10458 0 : this->m_LatLoadLoss = this->m_LatLoadLoss + LatentOutputDelta;
10459 0 : if (std::abs(this->m_LatentLoadMet) > 0.0) {
10460 0 : if (std::abs(this->m_LatLoadLoss / this->m_LatentLoadMet) < 0.001) {
10461 0 : this->m_LatLoadLoss = 0.0;
10462 : }
10463 : }
10464 : }
10465 : }
10466 :
10467 5997269 : if (this->m_fanOpModeSched != nullptr) {
10468 5994761 : if (this->m_fanOpModeSched->getCurrentVal() == 0.0) {
10469 2802213 : this->m_FanOpMode = HVAC::FanOp::Cycling;
10470 : } else {
10471 3192548 : this->m_FanOpMode = HVAC::FanOp::Continuous;
10472 3192548 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10473 : }
10474 : }
10475 :
10476 : // System load calculation for cycling fan systems
10477 5997269 : if (this->ControlZoneMassFlowFrac > 0.0) {
10478 5996918 : QZnReq = ZoneLoad / this->ControlZoneMassFlowFrac;
10479 5996918 : state.dataUnitarySystems->MoistureLoad /= this->ControlZoneMassFlowFrac;
10480 5996918 : state.dataUnitarySystems->QToCoolSetPt /= this->ControlZoneMassFlowFrac;
10481 5996918 : state.dataUnitarySystems->QToHeatSetPt /= this->ControlZoneMassFlowFrac;
10482 5996918 : ZoneLoad = QZnReq;
10483 : } else {
10484 351 : QZnReq = ZoneLoad;
10485 351 : this->ControlZoneMassFlowFrac = 1.0;
10486 : }
10487 :
10488 5997269 : state.dataUnitarySystems->CoolingLoad = false;
10489 5997269 : state.dataUnitarySystems->HeatingLoad = false;
10490 5997269 : Real64 smallLoadTolerance = this->m_SmallLoadTolerance;
10491 5997269 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10492 3197491 : smallLoadTolerance = HVAC::SmallLoad;
10493 : }
10494 5997269 : if (QZnReq > smallLoadTolerance) { // no need to check deadband flag, QZnReq is correct.
10495 2092618 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
10496 2092618 : state.dataUnitarySystems->HeatingLoad = true;
10497 : }
10498 3904651 : } else if (QZnReq < -smallLoadTolerance) {
10499 2721060 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
10500 2721047 : state.dataUnitarySystems->CoolingLoad = true;
10501 : }
10502 : }
10503 :
10504 : // System load calculation for constant fan systems
10505 5997269 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10506 3192548 : bool HXUnitOn = false;
10507 3192548 : this->FanPartLoadRatio = 0.0; // sets fan to minimum for ASHRAE model
10508 3192548 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10509 : // the SpeedNum is set for PTUnits, might need to set this for all multi/var speed coils?
10510 1344464 : if (state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) {
10511 5991 : m_CoolingSpeedNum = 1;
10512 1338473 : } else if (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil) {
10513 1726 : m_HeatingSpeedNum = 1;
10514 : }
10515 : }
10516 3192548 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio,
10517 : 0.0); // CompOnMassFlow and CompOffMassFlow are scalar, reset to this system's values
10518 3192548 : this->calcUnitarySystemToLoad(state,
10519 : AirLoopNum,
10520 : FirstHVACIteration,
10521 : 0.0,
10522 : 0.0,
10523 : OnOffAirFlowRatio,
10524 : SensOutputOff,
10525 : LatOutputOff,
10526 : HXUnitOn,
10527 : HeatCoilLoad,
10528 : SupHeaterLoad,
10529 : CompressorOn);
10530 :
10531 3192548 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
10532 9143 : case HVAC::SetptType::SingleHeat: {
10533 9143 : state.dataUnitarySystems->CoolingLoad = false;
10534 : // No heating load and constant fan pushes zone below heating set point
10535 13873 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt <= 0.0 &&
10536 4730 : SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10537 156 : state.dataUnitarySystems->HeatingLoad = true;
10538 156 : state.dataUnitarySystems->CoolingLoad = false;
10539 156 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10540 : }
10541 9143 : } break;
10542 :
10543 8938 : case HVAC::SetptType::SingleCool: {
10544 8938 : state.dataUnitarySystems->HeatingLoad = false;
10545 : // No heating load and constant fan pushes zone above cooling set point
10546 9055 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
10547 117 : SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10548 70 : state.dataUnitarySystems->HeatingLoad = false;
10549 70 : state.dataUnitarySystems->CoolingLoad = true;
10550 70 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10551 : }
10552 8938 : } break;
10553 :
10554 0 : case HVAC::SetptType::SingleHeatCool: {
10555 : // zone temp above cooling and heating set point temps
10556 0 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10557 : // zone pushed below heating set point
10558 0 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10559 0 : state.dataUnitarySystems->HeatingLoad = true;
10560 0 : state.dataUnitarySystems->CoolingLoad = false;
10561 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10562 : }
10563 : // zone temp below heating set point temp
10564 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10565 : // zone pushed above cooling set point
10566 0 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10567 0 : state.dataUnitarySystems->HeatingLoad = false;
10568 0 : state.dataUnitarySystems->CoolingLoad = true;
10569 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10570 : }
10571 : }
10572 0 : } break;
10573 :
10574 3174467 : case HVAC::SetptType::DualHeatCool: {
10575 : // zone temp above cooling and heating set point temps
10576 3174467 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10577 : // zone pushed into deadband
10578 1553668 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10579 117807 : state.dataUnitarySystems->HeatingLoad = false;
10580 117807 : state.dataUnitarySystems->CoolingLoad = false;
10581 117807 : ZoneLoad = 0.0;
10582 : }
10583 : // zone pushed below heating set point
10584 1553668 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10585 34638 : state.dataUnitarySystems->HeatingLoad = true;
10586 34638 : state.dataUnitarySystems->CoolingLoad = false;
10587 34638 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10588 : }
10589 : // zone temp below heating set point temp
10590 1620799 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10591 : // zone pushed into deadband
10592 1021143 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt > HVAC::SmallLoad) {
10593 3288 : state.dataUnitarySystems->HeatingLoad = false;
10594 3288 : state.dataUnitarySystems->CoolingLoad = false;
10595 3288 : ZoneLoad = 0.0;
10596 : }
10597 : // zone pushed above cooling set point
10598 1021143 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10599 64 : state.dataUnitarySystems->HeatingLoad = false;
10600 64 : state.dataUnitarySystems->CoolingLoad = true;
10601 64 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10602 : }
10603 : // zone temp between set point temps
10604 599656 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10605 : // zone pushed below heating set point
10606 599656 : if (SensOutputOff < 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10607 210232 : state.dataUnitarySystems->HeatingLoad = true;
10608 210232 : state.dataUnitarySystems->CoolingLoad = false;
10609 210232 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10610 : // zone pushed above cooling set point
10611 389424 : } else if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10612 25739 : state.dataUnitarySystems->HeatingLoad = false;
10613 25739 : state.dataUnitarySystems->CoolingLoad = true;
10614 25739 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10615 : }
10616 : }
10617 3174467 : } break;
10618 :
10619 0 : default: {
10620 0 : } break;
10621 : } // switch
10622 :
10623 : // push iteration mode stack and set current mode
10624 3192548 : this->m_IterationMode[2] = this->m_IterationMode[1];
10625 3192548 : this->m_IterationMode[1] = this->m_IterationMode[0];
10626 3192548 : if (state.dataUnitarySystems->CoolingLoad) {
10627 1470301 : this->m_IterationMode[0] = CoolingMode;
10628 1722247 : } else if (state.dataUnitarySystems->HeatingLoad) {
10629 1274253 : this->m_IterationMode[0] = HeatingMode;
10630 : } else {
10631 447994 : this->m_IterationMode[0] = NoCoolHeat;
10632 : }
10633 : // IF small loads to meet or not converging, just shut down unit
10634 3192548 : if (std::abs(ZoneLoad) < smallLoadTolerance) {
10635 449263 : ZoneLoad = 0.0;
10636 449263 : state.dataUnitarySystems->CoolingLoad = false;
10637 449263 : state.dataUnitarySystems->HeatingLoad = false;
10638 2743285 : } else if (this->m_IterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 6)) {
10639 : // attempt to lock output (air flow) if oscillations are detected
10640 200631 : int OperatingMode = this->m_IterationMode[0]; // VS systems can take a few more iterations than single-speed systems
10641 200631 : int OperatingModeMinusOne = this->m_IterationMode[1];
10642 200631 : int OperatingModeMinusTwo = this->m_IterationMode[2];
10643 200631 : bool Oscillate = true;
10644 200631 : if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) {
10645 170866 : Oscillate = false;
10646 : }
10647 200631 : if (Oscillate) {
10648 29765 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10649 17998 : state.dataUnitarySystems->HeatingLoad = false;
10650 17998 : state.dataUnitarySystems->CoolingLoad = true;
10651 17998 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10652 11767 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0) {
10653 0 : state.dataUnitarySystems->HeatingLoad = true;
10654 0 : state.dataUnitarySystems->CoolingLoad = false;
10655 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10656 : } else {
10657 11767 : state.dataUnitarySystems->HeatingLoad = false;
10658 11767 : state.dataUnitarySystems->CoolingLoad = false;
10659 11767 : ZoneLoad = 0.0;
10660 : }
10661 : }
10662 : }
10663 : }
10664 :
10665 : // Determine the m_Staged status
10666 5997269 : if (allocated(state.dataZoneCtrls->StageZoneLogic) && this->m_DesignSpecMSHPIndex > -1) {
10667 0 : if (state.dataZoneCtrls->StageZoneLogic(this->ControlZoneNum)) {
10668 0 : this->m_Staged = true;
10669 0 : this->m_StageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).StageNum;
10670 : } else {
10671 0 : if (this->m_MyStagedFlag) {
10672 0 : ShowWarningError(state,
10673 : "ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to this UnitarySystem "
10674 : "object with UnitarySystemPerformance:Multispeed type = ");
10675 0 : ShowContinueError(state, format("{}. Please make correction. Simulation continues...", this->Name));
10676 0 : this->m_MyStagedFlag = false;
10677 : }
10678 : }
10679 : }
10680 :
10681 : // Staged control
10682 5997269 : if (this->m_Staged) {
10683 0 : if (this->m_StageNum == 0) {
10684 0 : state.dataUnitarySystems->HeatingLoad = false;
10685 0 : state.dataUnitarySystems->CoolingLoad = false;
10686 0 : QZnReq = 0.0;
10687 : } else {
10688 0 : QZnReq =
10689 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired / this->ControlZoneMassFlowFrac;
10690 0 : if (QZnReq > 0.0) {
10691 0 : state.dataUnitarySystems->HeatingLoad = true;
10692 0 : state.dataUnitarySystems->CoolingLoad = false;
10693 : } else {
10694 0 : state.dataUnitarySystems->HeatingLoad = false;
10695 0 : state.dataUnitarySystems->CoolingLoad = true;
10696 : }
10697 : }
10698 : }
10699 :
10700 5997269 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10701 117640 : if (state.dataUnitarySystems->HeatingLoad) {
10702 17088 : state.dataUnitarySystems->MoistureLoad = 0.0;
10703 : }
10704 : }
10705 :
10706 : // Check load control
10707 5997269 : if (this->m_RunOnLatentOnlyWithSensible && ZoneLoad == 0.0) {
10708 66859 : state.dataUnitarySystems->MoistureLoad = 0.0;
10709 : }
10710 5997269 : if (!this->m_RunOnSensibleLoad) {
10711 0 : ZoneLoad = 0.0;
10712 0 : state.dataUnitarySystems->CoolingLoad = false;
10713 0 : state.dataUnitarySystems->HeatingLoad = false;
10714 : }
10715 5997269 : if (!this->m_RunOnLatentLoad) {
10716 5803809 : state.dataUnitarySystems->MoistureLoad = 0.0;
10717 : }
10718 :
10719 : // Testing heat pump air to air with RH control with CoolReheat dehumidification control showed that when there was heating
10720 : // and moisture load, the cooling coil was turning on to meet the moisture load and reheat was then turning on to meet both
10721 : // heating load and excess cooling load caused by cooling coil. Adding the logic below caused the zone temperature,
10722 : // relative humidity, cooling/heating rate to line up for both the original and new file with unitary system object.
10723 :
10724 5997269 : if (this->m_SuppCoilExists) {
10725 3187433 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10726 39744 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolCoilExists) {
10727 5574 : state.dataUnitarySystems->HeatingLoad = false;
10728 5574 : state.dataUnitarySystems->CoolingLoad = true;
10729 : }
10730 : }
10731 : }
10732 :
10733 : // set report variables for predicted sensible and latent load
10734 5997269 : this->m_SensibleLoadPredicted = ZoneLoad;
10735 5997269 : this->m_MoistureLoadPredicted = state.dataUnitarySystems->MoistureLoad;
10736 : }
10737 :
10738 43323703 : void UnitarySys::setOnOffMassFlowRate(EnergyPlusData &state,
10739 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
10740 : Real64 const PartLoadRatio // coil part-load ratio
10741 : )
10742 : {
10743 :
10744 : // SUBROUTINE INFORMATION:
10745 : // AUTHOR Chandan Sharma
10746 : // DATE WRITTEN May 2013
10747 :
10748 : // PURPOSE OF THIS SUBROUTINE:
10749 : // This subroutine is for initializations of the components.
10750 :
10751 : // METHODOLOGY EMPLOYED:
10752 : // The unitarysystem may have alternate air flow rates
10753 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
10754 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
10755 : // based on PLR.
10756 :
10757 : // REFERENCES:
10758 : // Based on SetOnOffMassFlowRate by Richard Raustad
10759 :
10760 43323703 : int HeatSpeedNum = 0;
10761 43323703 : int CoolSpeedNum = 0;
10762 :
10763 43323703 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10764 43323703 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10765 43323703 : state.dataUnitarySystems->m_massFlow1 = 0.0;
10766 43323703 : state.dataUnitarySystems->m_massFlow2 = 0.0;
10767 43323703 : state.dataUnitarySystems->OACompOnMassFlow = 0.0;
10768 43323703 : state.dataUnitarySystems->OACompOffMassFlow = 0.0;
10769 :
10770 : // Set the compressor or coil ON mass flow rate
10771 43323703 : if (state.dataUnitarySystems->HeatingLoad) {
10772 :
10773 16368169 : this->m_LastMode = HeatingMode;
10774 :
10775 16368169 : if (this->m_MultiOrVarSpeedHeatCoil) {
10776 :
10777 3395783 : HeatSpeedNum = this->m_HeatingSpeedNum;
10778 :
10779 3395783 : if (HeatSpeedNum == 0) {
10780 894935 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10781 894935 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10782 2500848 : } else if (HeatSpeedNum == 1) {
10783 1718213 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10784 1718213 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10785 782635 : } else if (HeatSpeedNum > 1) {
10786 782635 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10787 782635 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10788 : }
10789 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10790 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10791 3395783 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10792 2452381 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10793 0 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10794 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10795 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10796 0 : if (CoolSpeedNum < 1) {
10797 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10798 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10799 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10800 0 : } else if (CoolSpeedNum == 1) {
10801 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10802 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10803 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10804 : } else {
10805 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10806 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10807 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10808 : }
10809 : } else {
10810 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10811 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10812 : }
10813 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10814 : } else {
10815 2452381 : if (HeatSpeedNum == 0) {
10816 731331 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10817 731331 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10818 1721050 : } else if (HeatSpeedNum == 1) {
10819 1411870 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10820 1411870 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatMassFlowRate[HeatSpeedNum];
10821 : } else {
10822 309180 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10823 309180 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10824 : }
10825 2452381 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10826 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10827 2452381 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10828 2425863 : this->m_sysType == SysType::PackagedWSHP) {
10829 26518 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10830 : }
10831 : }
10832 : } else { // cycling fan mode
10833 943402 : if (HeatSpeedNum <= 1) {
10834 469947 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10835 469947 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10836 : } else {
10837 473455 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10838 473455 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10839 : }
10840 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10841 943402 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10842 920422 : this->m_sysType == SysType::PackagedWSHP) {
10843 128196 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10844 : // does this assume OA flow <= min speed flow? without this there are SolveRoot failures.
10845 128196 : if (HeatSpeedNum > 1) {
10846 82125 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10847 : }
10848 : }
10849 : }
10850 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10851 : // If a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
10852 12973842 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10853 12973842 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && !this->m_DXHeatingCoil) {
10854 1456 : if (this->m_MultiOrVarSpeedCoolCoil) {
10855 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10856 0 : if (CoolSpeedNum < 1) {
10857 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10858 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10859 0 : } else if (CoolSpeedNum == 1) {
10860 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10861 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10862 : } else {
10863 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10864 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10865 : }
10866 : } else { // IF (MultiOrVarSpeedCoolCoil) THEN
10867 1456 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10868 1456 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10869 1456 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10870 1456 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10871 1456 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10872 : }
10873 : }
10874 1456 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10875 : } else { // Heating load but no moisture load
10876 12970930 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10877 7341771 : this->m_sysType == SysType::PackagedWSHP) {
10878 : // this was missing for heating mode where multi speed coils are used
10879 7577298 : if (this->m_MultiOrVarSpeedHeatCoil) {
10880 0 : if (HeatSpeedNum == 0) {
10881 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10882 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10883 0 : } else if (HeatSpeedNum == 1) {
10884 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10885 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10886 0 : } else if (HeatSpeedNum > 1) {
10887 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10888 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10889 : }
10890 : } else {
10891 7577298 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10892 7577298 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10893 7577298 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10894 : }
10895 7577298 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10896 2835975 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10897 2835975 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10898 2835975 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10899 : }
10900 : } else {
10901 5393632 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10902 5393632 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10903 5393632 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10904 5393632 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10905 4497396 : if (this->m_AirFlowControl == UseCompFlow::On) {
10906 126882 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10907 126882 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10908 126882 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10909 : } else {
10910 4370514 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10911 4370514 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10912 4370514 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10913 : }
10914 : }
10915 : }
10916 : }
10917 : }
10918 :
10919 : // If a cooling load exists, operate at the cooling mass flow rate
10920 26955534 : } else if (state.dataUnitarySystems->CoolingLoad) {
10921 :
10922 23982847 : this->m_LastMode = CoolingMode;
10923 :
10924 23982847 : if (this->m_MultiOrVarSpeedCoolCoil) {
10925 :
10926 12669441 : CoolSpeedNum = this->m_CoolingSpeedNum;
10927 :
10928 12669441 : if (CoolSpeedNum == 0) {
10929 3337448 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10930 3337448 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10931 3337448 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10932 9331993 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation; set system flow rate to economizer flow rate
10933 652193 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10934 652193 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10935 652193 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10936 8679800 : } else if (CoolSpeedNum > 0) {
10937 8679800 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10938 8679800 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10939 8679800 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10940 : }
10941 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10942 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10943 12669441 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10944 10181620 : if (CoolSpeedNum == 0) {
10945 2897173 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10946 2897173 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10947 2897173 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10948 7284447 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10949 125888 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10950 125888 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10951 125888 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10952 7158559 : } else if (CoolSpeedNum == 1) {
10953 2944855 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10954 2944855 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10955 2944855 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10956 : } else {
10957 4213704 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10958 4213704 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10959 4213704 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10960 : }
10961 : } else { // cycling fan mode
10962 2487821 : if (this->m_EconoSpeedNum == 0 && CoolSpeedNum == 0) { // multi-stage economizer operation
10963 280185 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10964 280185 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10965 2207636 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10966 686395 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
10967 686395 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum - 1];
10968 686395 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10969 1521241 : } else if (CoolSpeedNum == 0) {
10970 0 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10971 0 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10972 : } else {
10973 1521241 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10974 1521241 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10975 1521241 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10976 : }
10977 : }
10978 : } else {
10979 11313406 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10980 11313406 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10981 11313406 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10982 11313406 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10983 4526918 : if (this->m_AirFlowControl == UseCompFlow::On) {
10984 668628 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10985 668628 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10986 668628 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10987 : } else {
10988 3858290 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10989 3858290 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10990 3858290 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10991 : }
10992 : }
10993 : }
10994 :
10995 : } else { // No load
10996 : // If no load exists, set the compressor on mass flow rate.
10997 : // Set equal the mass flow rate when no heating or cooling is needed If no moisture load exists.
10998 : // If the user has set the off mass flow rate to 0, set according to the last operating mode.
10999 :
11000 2972687 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
11001 40580 : if (this->m_MultiOrVarSpeedCoolCoil) {
11002 40032 : CoolSpeedNum = this->m_CoolingSpeedNum;
11003 40032 : if (CoolSpeedNum < 1) {
11004 40032 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11005 40032 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11006 40032 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11007 0 : } else if (CoolSpeedNum == 1) {
11008 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
11009 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
11010 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11011 : } else {
11012 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
11013 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
11014 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11015 : }
11016 :
11017 40032 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11018 40032 : if (this->m_AirFlowControl == UseCompFlow::On) {
11019 0 : if (CoolSpeedNum <= 1) {
11020 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11021 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11022 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11023 : } else {
11024 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
11025 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
11026 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11027 : }
11028 : } else {
11029 40032 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11030 40032 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11031 40032 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11032 : }
11033 : }
11034 :
11035 : } else { // IF (MultiOrVarSpeedCoolCoil(UnitarySysNum)) THEN
11036 548 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
11037 548 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
11038 548 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11039 548 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11040 548 : if (this->m_AirFlowControl == UseCompFlow::On) {
11041 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
11042 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11043 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11044 : } else {
11045 548 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11046 548 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11047 548 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11048 : }
11049 : }
11050 : }
11051 :
11052 : } else { // No Moisture Load
11053 :
11054 2932107 : if (this->m_LastMode == HeatingMode) {
11055 : // this needs to be corrected to include UseCompressorOnFlow
11056 1487901 : if (this->m_MultiOrVarSpeedHeatCoil) {
11057 645228 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11058 645228 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11059 : } else {
11060 842673 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11061 842673 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
11062 : }
11063 : // this needs to happen regardless of system except maybe the CoilSystem objects
11064 : // do this only for PTUnit for the time being to reduce diffs for the PTUnit to UnitarySystem conversion
11065 1487901 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
11066 1448423 : this->m_sysType == SysType::PackagedWSHP) {
11067 115909 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11068 71195 : if (this->m_AirFlowControl == UseCompFlow::On) {
11069 5772 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11070 5772 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11071 5772 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11072 : }
11073 : }
11074 : }
11075 : } else {
11076 : // this needs to be corrected to include UseCompressorOnFlow
11077 1444206 : if (this->m_MultiOrVarSpeedCoolCoil) {
11078 1079125 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11079 1079125 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11080 : } else {
11081 365081 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11082 365081 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
11083 : }
11084 : }
11085 2932107 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11086 2932107 : if (state.dataUnitarySystems->CompOnMassFlow == 0.0) {
11087 226378 : if (this->m_LastMode == HeatingMode) {
11088 76437 : if (this->m_MultiOrVarSpeedHeatCoil) {
11089 3090 : HeatSpeedNum = this->m_HeatingSpeedNum;
11090 3090 : if (HeatSpeedNum == 0) {
11091 3080 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11092 3080 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11093 10 : } else if (HeatSpeedNum == 1) {
11094 10 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
11095 10 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
11096 0 : } else if (HeatSpeedNum > 1) {
11097 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
11098 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
11099 : }
11100 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
11101 73347 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
11102 73347 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
11103 : }
11104 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11105 149941 : if (this->m_MultiOrVarSpeedCoolCoil) {
11106 8686 : CoolSpeedNum = this->m_CoolingSpeedNum;
11107 8686 : if (CoolSpeedNum == 0) {
11108 8686 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11109 8686 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11110 0 : } else if (CoolSpeedNum == 1) {
11111 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
11112 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
11113 0 : } else if (CoolSpeedNum > 1) {
11114 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
11115 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
11116 : }
11117 : } else { // IF(MultiOrVarSpeedCoolCoil) THEN
11118 141255 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
11119 141255 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
11120 : } // IF(MultiOrVarSpeedCoolCoil) THEN
11121 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11122 : } // IF(CompOnMassFlow .EQ. 0.0d0)THEN
11123 :
11124 2932107 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11125 1903733 : if (this->m_AirFlowControl == UseCompFlow::On) {
11126 32428 : if (this->m_LastMode == HeatingMode) {
11127 8818 : if (this->m_MultiOrVarSpeedHeatCoil) {
11128 1614 : HeatSpeedNum = this->m_HeatingSpeedNum;
11129 1614 : if (HeatSpeedNum < 1) {
11130 1614 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11131 1614 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11132 1614 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11133 0 : } else if (HeatSpeedNum == 1) {
11134 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[1];
11135 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[1];
11136 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11137 : } else {
11138 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
11139 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
11140 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11141 : }
11142 : } else {
11143 : // this is a no load case, added if for PTUnit to correct this for PTUnit to UnitarySystem conversion
11144 : // the else is incorrect?
11145 7204 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
11146 1630 : this->m_sysType == SysType::PackagedWSHP) {
11147 5574 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11148 5574 : if (this->m_AirFlowControl == UseCompFlow::On) {
11149 5574 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11150 5574 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11151 5574 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11152 : }
11153 : }
11154 : } else {
11155 1630 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
11156 1630 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11157 1630 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11158 : }
11159 : }
11160 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11161 23610 : if (this->m_MultiOrVarSpeedCoolCoil) {
11162 5686 : CoolSpeedNum = this->m_CoolingSpeedNum;
11163 5686 : if (CoolSpeedNum < 1) {
11164 5666 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11165 5666 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11166 5666 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11167 20 : } else if (CoolSpeedNum == 1) {
11168 20 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
11169 20 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
11170 20 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11171 : } else {
11172 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
11173 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
11174 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11175 : }
11176 : } else {
11177 17924 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
11178 17924 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11179 17924 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11180 : }
11181 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11182 : } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
11183 1871305 : if (this->m_LastMode == HeatingMode) {
11184 884134 : if (this->m_MultiOrVarSpeedHeatCoil) {
11185 452788 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11186 452788 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11187 : } else {
11188 431346 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11189 431346 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11190 : }
11191 : } else {
11192 987171 : if (this->m_MultiOrVarSpeedCoolCoil) {
11193 795202 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11194 795202 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11195 : } else {
11196 191969 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11197 191969 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11198 : }
11199 : }
11200 1871305 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11201 : } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
11202 : } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN
11203 : } // ELSE ! No Moisture Load
11204 : } // No Heating/Cooling Load
11205 :
11206 43323703 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11207 26440059 : if (this->m_AirFlowControl == UseCompFlow::On &&
11208 1325634 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)) {
11209 881226 : if (this->m_LastMode == HeatingMode) {
11210 285939 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11211 : } else {
11212 595287 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11213 : }
11214 : }
11215 : }
11216 :
11217 43323703 : if (this->m_MultiSpeedHeatingCoil && (state.dataUnitarySystems->HeatingLoad && HeatSpeedNum == 1)) {
11218 1642669 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
11219 41681034 : } else if (this->m_DiscreteSpeedCoolingCoil && (state.dataUnitarySystems->CoolingLoad && CoolSpeedNum == 1)) {
11220 4143359 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
11221 : } else {
11222 37537675 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOffMassFlow; // these need to be set for multi-speed coils
11223 : }
11224 86647406 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
11225 43323703 : state.dataUnitarySystems->CompOnMassFlow; // doesn't hurt to set these if multi-speed coils are not used
11226 43323703 : state.dataHVACGlobal->MSUSEconoSpeedNum = this->m_EconoSpeedNum;
11227 :
11228 43323703 : state.dataUnitarySystems->m_massFlow1 = state.dataUnitarySystems->CompOnMassFlow;
11229 43323703 : state.dataUnitarySystems->m_massFlow2 = state.dataUnitarySystems->CompOffMassFlow;
11230 :
11231 : // Set the system mass flow rates
11232 43323703 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
11233 43323703 : }
11234 :
11235 74626095 : void UnitarySys::setAverageAirFlow(EnergyPlusData &state,
11236 : Real64 const PartLoadRatio, // unit part load ratio
11237 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
11238 : )
11239 : {
11240 :
11241 : // SUBROUTINE INFORMATION:
11242 : // AUTHOR Richard Raustad
11243 : // DATE WRITTEN July 2005
11244 :
11245 : // PURPOSE OF THIS SUBROUTINE:
11246 : // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
11247 : // Set OnOffAirFlowRatio to be used by DX coils
11248 :
11249 : // METHODOLOGY EMPLOYED:
11250 : // The air flow rate in cooling, heating, and no cooling or heating can be different.
11251 : // Calculate the air flow rate based on initializations.
11252 :
11253 74626095 : Real64 AverageUnitMassFlow = 0.0; // average supply air mass flow rate over time step
11254 74626095 : bool FanOn = false;
11255 :
11256 74626095 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
11257 74626095 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11258 :
11259 74626095 : Real64 FanPartLoadRatio = PartLoadRatio;
11260 74626095 : if (this->m_SimASHRAEModel) {
11261 0 : FanPartLoadRatio = this->FanPartLoadRatio;
11262 : }
11263 74626095 : if (this->m_EconoPartLoadRatio > 0) {
11264 621219 : FanPartLoadRatio = this->m_EconoPartLoadRatio;
11265 : }
11266 74626095 : int SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum, this->m_EconoSpeedNum);
11267 74626095 : int InletNode = this->AirInNode;
11268 :
11269 74626095 : if (SpeedNum > 1) {
11270 8768522 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11271 932816 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11272 7823045 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11273 6259954 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow +
11274 6259954 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow;
11275 : } else {
11276 1563091 : Real64 tempSpeedRatio = 0;
11277 1563091 : if (this->m_EconoPartLoadRatio > 0) {
11278 173349 : tempSpeedRatio = this->FanPartLoadRatio;
11279 : } else {
11280 1389742 : tempSpeedRatio = state.dataUnitarySystems->CoolingLoad ? this->m_CoolingSpeedRatio : this->m_HeatingSpeedRatio;
11281 : }
11282 1563091 : AverageUnitMassFlow = tempSpeedRatio * state.dataUnitarySystems->CompOnMassFlow +
11283 1563091 : (1.0 - tempSpeedRatio) * state.dataUnitarySystems->CompOffMassFlow;
11284 : }
11285 : } else {
11286 12661 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11287 : }
11288 : } else {
11289 66790389 : AverageUnitMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow) +
11290 66790389 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow);
11291 : }
11292 :
11293 74626095 : if (state.dataUnitarySystems->CompOffFlowRatio > 0.0) {
11294 44721150 : if (SpeedNum > 1) {
11295 8758013 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11296 928366 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11297 7821436 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio +
11298 7821436 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio;
11299 7821436 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11300 7821436 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11301 : } else {
11302 8211 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11303 8211 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11304 8211 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11305 : }
11306 : } else {
11307 36891503 : state.dataUnitarySystems->FanSpeedRatio = (FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio) +
11308 36891503 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio);
11309 36891503 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11310 36891503 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11311 : }
11312 : } else {
11313 29904945 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11314 29904945 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11315 29904945 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11316 : }
11317 :
11318 74626095 : if (!(state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating == 0)) {
11319 48667426 : if (this->m_SingleMode == 1) {
11320 76083 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11321 0 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11322 0 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11323 0 : state.dataUnitarySystems->m_runTimeFraction1 = 1.0;
11324 0 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11325 : } else {
11326 76083 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow;
11327 76083 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio;
11328 76083 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11329 76083 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11330 : }
11331 : }
11332 : }
11333 :
11334 74626095 : if (this->OAMixerExists) {
11335 40933198 : Real64 AverageOAMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->OACompOnMassFlow) +
11336 40933198 : ((1 - FanPartLoadRatio) * state.dataUnitarySystems->OACompOffMassFlow);
11337 :
11338 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = AverageOAMassFlow;
11339 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = AverageOAMassFlow;
11340 : // don't need to set relief node, delete them when working
11341 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = AverageOAMassFlow;
11342 40933198 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = AverageOAMassFlow;
11343 : }
11344 :
11345 : // BEGIN - refactor/move this to Init during FirstHVACIteration, need struct or module level global for turnFansOn and turnFansOff
11346 : // If the unitary system is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
11347 74626095 : FanOn = (this->m_FanExists) ? (this->m_fanAvailSched->getCurrentVal() > 0) : true;
11348 : // END - move this to Init during FirstHVACIteration
11349 :
11350 74626095 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && ((FanOn || state.dataHVACGlobal->TurnFansOn) && !state.dataHVACGlobal->TurnFansOff)) {
11351 73814094 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11352 : // set point based equipment should use VAV terminal units to set the flow.
11353 : // zone equipment needs to set flow since no other device regulates flow (ZoneHVAC /= AirLoopEquipment)
11354 22618 : if (!this->m_AirLoopEquipment) {
11355 0 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11356 0 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11357 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11358 : }
11359 22618 : if (AverageUnitMassFlow > 0.0) {
11360 22618 : OnOffAirFlowRatio = 1.0;
11361 : } else {
11362 0 : OnOffAirFlowRatio = 0.0;
11363 : }
11364 : } else {
11365 73791476 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11366 73791476 : if (!this->m_AirLoopEquipment) {
11367 43369493 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11368 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11369 : }
11370 73791476 : if (AverageUnitMassFlow > 0.0) {
11371 62745381 : if (SpeedNum > 1) {
11372 7799857 : OnOffAirFlowRatio = 1.0;
11373 : } else {
11374 54945524 : OnOffAirFlowRatio = state.dataUnitarySystems->CompOnMassFlow / AverageUnitMassFlow;
11375 : }
11376 : } else {
11377 11046095 : OnOffAirFlowRatio = 0.0;
11378 : }
11379 : }
11380 : } else {
11381 812001 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
11382 : // fan will turn on unless these are reset, or maybe one of them. Might be a better way when calling fan.
11383 812001 : state.dataUnitarySystems->m_massFlow1 = 0.0;
11384 812001 : state.dataUnitarySystems->m_massFlow2 = 0.0;
11385 812001 : OnOffAirFlowRatio = 1.0;
11386 812001 : if (this->OAMixerExists) {
11387 : // maybe can just set MaxAvail = 0?
11388 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = 0.0;
11389 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = 0.0;
11390 : // don't need to set relief node, delete then when working
11391 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = 0.0;
11392 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = 0.0;
11393 : }
11394 : }
11395 74626095 : }
11396 :
11397 43090878 : void UnitarySys::calcUnitarySystemToLoad(EnergyPlusData &state,
11398 : int const AirLoopNum, // index to air loop
11399 : bool const FirstHVACIteration, // True when first HVAC iteration
11400 : Real64 const CoolPLR, // operating cooling part-load ratio []
11401 : Real64 const HeatPLR, // operating cooling part-load ratio []
11402 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
11403 : Real64 &SensOutput, // sensible capacity (W)
11404 : Real64 &LatOutput, // latent capacity (W)
11405 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
11406 : Real64 HeatCoilLoad, // Adjusted load to heating coil when SAT exceeds max limit (W)
11407 : Real64 SuppCoilLoad, // Adjusted load to supp heating coil when SAT exceeds max limit (W)
11408 : HVAC::CompressorOp const CompressorOn // Determines if compressor is on or off
11409 : )
11410 : {
11411 :
11412 : // SUBROUTINE INFORMATION:
11413 : // AUTHOR Richard Raustad, FSEC
11414 : // DATE WRITTEN February 2013
11415 :
11416 : // PURPOSE OF THIS SUBROUTINE:
11417 : // This subroutine calculates the resulting performance of the unitary system given
11418 : // the operating PLR. System output is calculated with respect to zone condition.
11419 :
11420 43090878 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
11421 :
11422 43090878 : HVAC::CompressorOp CoolingCompOn = HVAC::CompressorOp::Off;
11423 43090878 : if (CoolPLR > 0) {
11424 15793360 : CoolingCompOn = CompressorOn;
11425 27297518 : } else if (CoolPLR == 0 && this->m_EconoSpeedNum > 0) { // turn compressor off for economizer calculations
11426 543879 : CoolingCompOn = HVAC::CompressorOp::Off;
11427 26753639 : } else if (this->m_CoolingSpeedNum > 1) { // for multispeed coils, comp is on IF speed > 1
11428 470365 : CoolingCompOn = HVAC::CompressorOp::On;
11429 : }
11430 :
11431 43090878 : HVAC::CompressorOp HeatingCompOn = HVAC::CompressorOp::Off;
11432 43090878 : if (HeatPLR > 0) {
11433 11646180 : HeatingCompOn = CompressorOn;
11434 11646180 : CoilCoolHeatRat = min(1.0, CoolPLR / HeatPLR);
11435 : }
11436 : // for multispeed coils, comp is on at PLR=0 IF speed > 1
11437 43090878 : if (this->m_HeatingSpeedNum > 1) {
11438 675739 : HeatingCompOn = HVAC::CompressorOp::On;
11439 : }
11440 :
11441 : // set the operating flow rate
11442 43090878 : if (this->m_NumOfSpeedCooling > 0 || this->m_NumOfSpeedHeating > 0) {
11443 27380772 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, max(CoolPLR, HeatPLR));
11444 : } else {
11445 15710106 : this->setAverageAirFlow(state, max(CoolPLR, HeatPLR), OnOffAirFlowRatio);
11446 : }
11447 :
11448 : // Call the series of components that simulate a Unitary System
11449 43090878 : if (this->ATMixerExists) {
11450 : // There is an air terminal mixer
11451 995259 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
11452 : // set the primary air inlet mass flow rate
11453 680709 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
11454 680709 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
11455 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
11456 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
11457 680709 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11458 : }
11459 : }
11460 43090878 : if (this->OAMixerExists) {
11461 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
11462 : // 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
11463 : // at least better than constructing a new string each time to call this function
11464 23591795 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
11465 : }
11466 :
11467 43090878 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
11468 30686182 : state.dataFans->fans(this->m_FanIndex)
11469 92058546 : ->simulate(state,
11470 : FirstHVACIteration,
11471 30686182 : state.dataUnitarySystems->FanSpeedRatio,
11472 : _, // Pressure rise
11473 : _, // Flow fraction
11474 30686182 : state.dataUnitarySystems->m_massFlow1,
11475 30686182 : state.dataUnitarySystems->m_runTimeFraction1,
11476 30686182 : state.dataUnitarySystems->m_massFlow2,
11477 30686182 : state.dataUnitarySystems->m_runTimeFraction2,
11478 : _);
11479 : }
11480 :
11481 43090878 : if (this->m_CoolingCoilUpstream) {
11482 :
11483 41845156 : if (this->m_CoolCoilExists) {
11484 41845156 : this->calcUnitaryCoolingSystem(
11485 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11486 : }
11487 41845156 : if (this->m_HeatCoilExists) {
11488 : // operate the heating coil without regard to coil outlet temperature
11489 41206382 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11490 41206382 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11491 651899 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11492 651899 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11493 651899 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11494 651899 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11495 651899 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11496 651899 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11497 651899 : HeatCoilLoad = MaxHeatCoilLoad;
11498 : }
11499 : }
11500 :
11501 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11502 41845156 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11503 3275242 : state.dataFans->fans(this->m_FanIndex)
11504 9825726 : ->simulate(state,
11505 : FirstHVACIteration,
11506 3275242 : state.dataUnitarySystems->FanSpeedRatio,
11507 : _, // Pressure rise
11508 : _, // Flow fraction
11509 3275242 : state.dataUnitarySystems->m_massFlow1,
11510 3275242 : state.dataUnitarySystems->m_runTimeFraction1,
11511 3275242 : state.dataUnitarySystems->m_massFlow2,
11512 3275242 : state.dataUnitarySystems->m_runTimeFraction2,
11513 : _);
11514 :
11515 3275242 : if (this->m_CoolCoilExists) {
11516 3275242 : this->calcUnitaryCoolingSystem(
11517 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11518 : }
11519 3275242 : if (this->m_HeatCoilExists) {
11520 3274684 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11521 3274684 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11522 23036 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11523 23036 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11524 23036 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11525 23036 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11526 23036 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11527 23036 : this->calcUnitaryHeatingSystem(
11528 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11529 : }
11530 : }
11531 : }
11532 :
11533 : } else {
11534 :
11535 1245722 : if (this->m_HeatCoilExists) {
11536 1245722 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11537 1245722 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11538 167072 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11539 167072 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11540 167072 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11541 167072 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11542 167072 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11543 167072 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11544 : }
11545 : }
11546 1245722 : if (this->m_CoolCoilExists) {
11547 1245722 : this->calcUnitaryCoolingSystem(
11548 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11549 : }
11550 :
11551 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11552 1245722 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11553 18379 : state.dataFans->fans(this->m_FanIndex)
11554 55137 : ->simulate(state,
11555 : FirstHVACIteration,
11556 18379 : state.dataUnitarySystems->FanSpeedRatio,
11557 : _, // Pressure rise
11558 : _, // Flow fraction
11559 18379 : state.dataUnitarySystems->m_massFlow1,
11560 18379 : state.dataUnitarySystems->m_runTimeFraction1,
11561 18379 : state.dataUnitarySystems->m_massFlow2,
11562 18379 : state.dataUnitarySystems->m_runTimeFraction2,
11563 : _);
11564 :
11565 18379 : if (this->m_HeatCoilExists) {
11566 18379 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11567 18379 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11568 8516 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11569 8516 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11570 8516 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11571 8516 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11572 8516 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11573 8516 : this->calcUnitaryHeatingSystem(
11574 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11575 : }
11576 : }
11577 18379 : if (this->m_CoolCoilExists) {
11578 18379 : this->calcUnitaryCoolingSystem(
11579 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11580 : }
11581 : }
11582 : }
11583 :
11584 43090878 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
11585 12404696 : state.dataFans->fans(this->m_FanIndex)
11586 37214088 : ->simulate(state,
11587 : FirstHVACIteration,
11588 12404696 : state.dataUnitarySystems->FanSpeedRatio,
11589 : _, // Pressure rise
11590 : _, // Flow fraction
11591 12404696 : state.dataUnitarySystems->m_massFlow1,
11592 12404696 : state.dataUnitarySystems->m_runTimeFraction1,
11593 12404696 : state.dataUnitarySystems->m_massFlow2,
11594 12404696 : state.dataUnitarySystems->m_runTimeFraction2,
11595 : _);
11596 : }
11597 43090878 : if (this->m_SuppCoilExists) {
11598 22143688 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, SuppCoilLoad);
11599 22148376 : if ((state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp) && this->m_SuppHeatPartLoadFrac > 0.0 &&
11600 4688 : !this->m_SimASHRAEModel) {
11601 : // EMS override will ignore this recalculation.
11602 4688 : Real64 MDotAir = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).MassFlowRate;
11603 4688 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).HumRat +
11604 4688 : state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).HumRat));
11605 4688 : Real64 HCDeltaT = max(0.0, this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).Temp);
11606 4688 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11607 4688 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, MaxHeatCoilLoad);
11608 4688 : SuppCoilLoad = MaxHeatCoilLoad;
11609 : }
11610 : }
11611 :
11612 : // If there is a supply side air terminal mixer, calculate its output
11613 43090878 : if (this->ATMixerExists) {
11614 995259 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11615 314550 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11616 : }
11617 : }
11618 :
11619 43090878 : calculateCapacity(state, SensOutput, LatOutput);
11620 43090878 : }
11621 :
11622 302026 : void UnitarySys::calcMultiStageSuppCoilStageByLoad(EnergyPlusData &state, Real64 const SuppHeatLoad, bool const FirstHVACIteration)
11623 : {
11624 302026 : if (SuppHeatLoad <= 0.0) {
11625 293002 : this->m_SuppHeatPartLoadFrac = 0.0;
11626 293002 : this->m_SuppHeatingSpeedRatio = 0.0;
11627 293002 : this->m_SuppHeatingCycRatio = 0.0;
11628 297458 : return;
11629 : }
11630 9024 : constexpr bool SuppHeatingCoilFlag(true);
11631 9024 : Real64 PartLoadFrac = 0.0;
11632 9024 : Real64 SpeedRatio = 0.0;
11633 9024 : Real64 CycRatio = 0.0;
11634 9024 : std::string CompName = this->m_SuppHeatCoilName;
11635 9024 : int CompIndex = this->m_SuppHeatCoilIndex;
11636 9024 : HVAC::FanOp fanOp = this->m_FanOpMode;
11637 9024 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
11638 9024 : int SpeedNum = 0;
11639 : // Get full load result
11640 9024 : PartLoadFrac = 1.0;
11641 9024 : CycRatio = 1.0;
11642 9024 : SpeedRatio = 1.0;
11643 9024 : int SolFla = 0;
11644 :
11645 : // SUBROUTINE PARAMETER DEFINITIONS:
11646 9024 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11647 9024 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
11648 :
11649 30680 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
11650 26224 : this->m_SuppHeatingSpeedNum = SpeedNum;
11651 26224 : HeatingCoils::SimulateHeatingCoilComponents(state,
11652 : CompName,
11653 : FirstHVACIteration,
11654 : SuppHeatLoad,
11655 : CompIndex,
11656 : QCoilActual,
11657 : SuppHeatingCoilFlag,
11658 : fanOp,
11659 : PartLoadFrac,
11660 : SpeedNum,
11661 : SpeedRatio);
11662 26224 : if (QCoilActual > SuppHeatLoad) {
11663 4568 : break;
11664 : }
11665 : }
11666 9024 : if (QCoilActual < SuppHeatLoad) {
11667 4456 : this->m_SuppHeatPartLoadFrac = 1.0;
11668 4456 : this->m_SuppHeatingSpeedRatio = 1.0;
11669 4456 : this->m_SuppHeatingCycRatio = 1.0;
11670 4456 : this->m_SuppHeatingSpeedNum = this->m_NumOfSpeedSuppHeating;
11671 4456 : return;
11672 : } else {
11673 :
11674 4568 : if (this->m_SuppHeatingSpeedNum > 1.0) {
11675 13692 : auto f = [&state, this, CycRatio, fanOp, SuppHeatLoad](Real64 const SpeedRatio) {
11676 : Real64 QActual;
11677 13692 : int CoilIndex = this->m_SuppHeatCoilIndex;
11678 13692 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11679 13692 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11680 13692 : return SuppHeatLoad - QActual;
11681 4564 : };
11682 :
11683 4564 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
11684 4564 : this->m_SuppHeatingCycRatio = CycRatio;
11685 4564 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11686 4564 : this->m_SuppHeatPartLoadFrac = SpeedRatio;
11687 4564 : PartLoadFrac = SpeedRatio;
11688 : } else {
11689 4 : SpeedRatio = 0.0;
11690 4 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11691 12 : auto f = [&state, this, SpeedRatio, fanOp, SuppHeatLoad](Real64 const CycRatio) {
11692 : Real64 QActual;
11693 12 : int CoilIndex = this->m_SuppHeatCoilIndex;
11694 12 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11695 12 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11696 12 : return SuppHeatLoad - QActual;
11697 4 : };
11698 :
11699 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
11700 4 : this->m_SuppHeatingCycRatio = CycRatio;
11701 4 : this->m_SuppHeatPartLoadFrac = CycRatio;
11702 4 : PartLoadFrac = CycRatio;
11703 : }
11704 : }
11705 9024 : }
11706 :
11707 46080698 : void UnitarySys::calculateCapacity(EnergyPlusData &state, Real64 &SensOutput, Real64 &LatOutput)
11708 : {
11709 :
11710 : // Check delta T (outlet to reference temp), IF positive use reference HumRat ELSE outlet humrat to calculate
11711 : // sensible capacity as MdotDeltaH at constant humidity ratio
11712 46080698 : int OutletNode = this->AirOutNode;
11713 46080698 : Real64 AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
11714 46080698 : Real64 RefTemp = 0.0;
11715 46080698 : Real64 RefHumRat = 0.0;
11716 46080698 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11717 2989820 : RefTemp = state.dataLoopNodes->Node(this->AirInNode).Temp;
11718 2989820 : RefHumRat = state.dataLoopNodes->Node(this->AirInNode).HumRat;
11719 : } else {
11720 43090878 : RefTemp = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp;
11721 43090878 : RefHumRat = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat;
11722 : }
11723 46080698 : Real64 SensibleOutput(0.0); // sensible output rate, {W}
11724 46080698 : Real64 LatentOutput(0.0); // latent output rate, {W}
11725 46080698 : Real64 TotalOutput(0.0); // total output rate, {W}
11726 : // calculate sensible load met
11727 46080698 : if (this->ATMixerExists) {
11728 995259 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11729 : // Air terminal supply side mixer
11730 314550 : int ATMixOutNode = this->ATMixerOutNode;
11731 314550 : CalcZoneSensibleLatentOutput(state.dataLoopNodes->Node(ATMixOutNode).MassFlowRate,
11732 314550 : state.dataLoopNodes->Node(ATMixOutNode).Temp,
11733 314550 : state.dataLoopNodes->Node(ATMixOutNode).HumRat,
11734 : RefTemp,
11735 : RefHumRat,
11736 : SensibleOutput,
11737 : LatentOutput,
11738 : TotalOutput);
11739 314550 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11740 314550 : if (this->m_Humidistat) {
11741 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11742 : } else {
11743 314550 : LatOutput = 0.0;
11744 : }
11745 : } else {
11746 : // Air terminal inlet side mixer
11747 1361418 : CalcZoneSensibleLatentOutput(AirMassFlow,
11748 680709 : state.dataLoopNodes->Node(OutletNode).Temp,
11749 680709 : state.dataLoopNodes->Node(OutletNode).HumRat,
11750 : RefTemp,
11751 : RefHumRat,
11752 : SensibleOutput,
11753 : LatentOutput,
11754 : TotalOutput);
11755 680709 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11756 680709 : if (this->m_Humidistat) {
11757 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11758 : } else {
11759 680709 : LatOutput = 0.0;
11760 : }
11761 : }
11762 : } else {
11763 : // Calculate sensible load met
11764 90170878 : CalcZoneSensibleLatentOutput(AirMassFlow,
11765 45085439 : state.dataLoopNodes->Node(OutletNode).Temp,
11766 45085439 : state.dataLoopNodes->Node(OutletNode).HumRat,
11767 : RefTemp,
11768 : RefHumRat,
11769 : SensibleOutput,
11770 : LatentOutput,
11771 : TotalOutput);
11772 45085439 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11773 45085439 : if (this->m_Humidistat) {
11774 1649021 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11775 : } else {
11776 43436418 : LatOutput = 0.0;
11777 : }
11778 : }
11779 46080698 : this->m_SensibleLoadMet = SensOutput;
11780 46080698 : this->m_LatentLoadMet = LatOutput;
11781 46080698 : }
11782 :
11783 49403930 : void UnitarySys::calcUnitaryCoolingSystem(EnergyPlusData &state,
11784 : int const AirLoopNum, // index to air loop
11785 : bool const FirstHVACIteration, // True when first HVAC iteration
11786 : Real64 const PartLoadRatio, // coil operating part-load ratio
11787 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11788 : Real64 const OnOffAirFlowRatio,
11789 : Real64 const CoilCoolHeatRat, // ratio of cooling to heating PLR for cycling fan RH control
11790 : bool const HXUnitOn // Flag to control HX for HXAssisted Cooling Coil
11791 : )
11792 : {
11793 :
11794 : // SUBROUTINE INFORMATION:
11795 : // AUTHOR Richard Raustad, FSEC
11796 : // DATE WRITTEN February 2013
11797 :
11798 : // PURPOSE OF THIS SUBROUTINE:
11799 : // This subroutine manages unitary cooling system component simulation.
11800 :
11801 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11802 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11803 : Real64 mdot; // water side flow rate (kg/s)
11804 : Real64 QActual; // actual coil output (W)
11805 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11806 :
11807 : // Simulate the coil component
11808 49403930 : std::string CompName = this->m_CoolingCoilName;
11809 49403930 : int CompIndex = this->m_CoolingCoilIndex;
11810 49403930 : Real64 CoilPLR = 1.0;
11811 49403930 : if (this->m_CondenserNodeNum != 0) {
11812 29029327 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11813 : // IF node is not connected to anything, pressure = default, use weather data
11814 29029327 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11815 2125 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11816 : } else {
11817 29027202 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11818 : }
11819 : } else {
11820 20374603 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11821 : }
11822 :
11823 49403930 : switch (this->m_CoolingCoilType_Num) {
11824 12805917 : case HVAC::CoilDX_CoolingSingleSpeed: { // Coil:Cooling:DX:SingleSpeed
11825 12805917 : DXCoils::SimDXCoil(state,
11826 : blankString,
11827 : CompressorOn,
11828 : FirstHVACIteration,
11829 : CompIndex,
11830 : this->m_FanOpMode,
11831 : PartLoadRatio,
11832 : OnOffAirFlowRatio,
11833 : CoilCoolHeatRat);
11834 12805917 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11835 12805917 : } break;
11836 10933626 : case HVAC::CoilDX_Cooling: { // CoilCoolingDX
11837 10933626 : bool const singleMode = (this->m_SingleMode == 1);
11838 10933626 : CoilPLR = 0.0;
11839 10933626 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11840 76796 : if (CompressorOn == HVAC::CompressorOp::On) {
11841 65028 : CoilPLR = (this->m_CoolingSpeedNum > 1) ? m_CoolingSpeedRatio : PartLoadRatio;
11842 : }
11843 : } else {
11844 10856830 : if (this->m_EMSOverrideCoilSpeedNumOn) {
11845 146884 : CoilPLR = this->m_CoolingSpeedRatio;
11846 : } else {
11847 10709946 : if (state.dataUnitarySystems->CoolingLoad) {
11848 7095242 : if (CompressorOn == HVAC::CompressorOp::Off) {
11849 2395236 : if (this->m_CoolingSpeedNum > 1) { // NOTE: Cooling speed 0 should behave the same as speed 1, but doesn't, and must be
11850 : // allowed to pass into the simulation code
11851 6381 : this->m_CoolingSpeedNum = 1; // Bypass mixed-speed calculations in called functions
11852 : }
11853 : } else {
11854 4700006 : if (singleMode) {
11855 26368 : CoilPLR = (this->m_CoolingSpeedNum == 1)
11856 26368 : ? PartLoadRatio
11857 : : 1.0; // singleMode allows cycling, but not part load operation at higher speeds
11858 : } else {
11859 4673638 : CoilPLR = PartLoadRatio;
11860 : }
11861 : }
11862 : }
11863 : }
11864 : }
11865 :
11866 10933626 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
11867 10933626 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
11868 76864 : coilMode = HVAC::CoilMode::SubcoolReheat;
11869 10856762 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
11870 0 : coilMode = HVAC::CoilMode::Enhanced;
11871 : }
11872 10933626 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
11873 : state, coilMode, this->m_CoolingSpeedNum, CoilPLR, this->m_FanOpMode, singleMode, this->CoilSHR);
11874 :
11875 10933626 : if (this->m_CoolingSpeedNum > 1) {
11876 2970137 : if (!singleMode) {
11877 2946841 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11878 : } else {
11879 23296 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11880 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11881 23296 : this->m_CoolingSpeedRatio = 1.0;
11882 : }
11883 : } else {
11884 7963489 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11885 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11886 7963489 : this->m_CoolingSpeedRatio = 0.0;
11887 : }
11888 10933626 : } break;
11889 30043 : case HVAC::CoilDX_CoolingHXAssisted:
11890 : case HVAC::CoilWater_CoolingHXAssisted: {
11891 30043 : if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
11892 : mdot =
11893 0 : min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxCoolCoilFluidFlow * PartLoadRatio);
11894 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11895 : }
11896 60086 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
11897 : blankString,
11898 : FirstHVACIteration,
11899 : CompressorOn,
11900 : PartLoadRatio,
11901 : CompIndex,
11902 : this->m_FanOpMode,
11903 : HXUnitOn,
11904 : OnOffAirFlowRatio,
11905 30043 : state.dataUnitarySystems->economizerFlag,
11906 : _,
11907 30043 : this->m_DehumidificationMode,
11908 30043 : 0.0); // this->CoilSHR);
11909 30043 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
11910 30043 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11911 : }
11912 30043 : } break;
11913 727585 : case HVAC::CoilDX_CoolingTwoSpeed: { // Coil:Cooling:DX:TwoSpeed
11914 : // formerly (v3 and beyond)COIL:DX:MULTISPEED:COOLINGEMPIRICAL
11915 727585 : DXCoils::SimDXCoilMultiSpeed(state, blankString, this->m_CoolingSpeedRatio, this->m_CoolingCycRatio, CompIndex);
11916 727585 : if (this->m_CoolingSpeedRatio > 0.0) {
11917 259924 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingSpeedRatio : 0.0;
11918 : } else {
11919 467661 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11920 : }
11921 727585 : } break;
11922 3877224 : case HVAC::CoilDX_MultiSpeedCooling: { // Coil:Cooling:DX:Multispeed
11923 3877224 : if (OutsideDryBulbTemp > this->m_MinOATCompressorCooling) {
11924 3877224 : DXCoils::SimDXCoilMultiSpeed(state,
11925 : CompName,
11926 : this->m_CoolingSpeedRatio,
11927 : this->m_CoolingCycRatio,
11928 : CompIndex,
11929 3877224 : this->m_CoolingSpeedNum,
11930 3877224 : this->m_FanOpMode,
11931 : CompressorOn,
11932 3877224 : this->m_SingleMode);
11933 3877224 : if (this->m_CoolingSpeedNum > 1) {
11934 769905 : if (this->m_SingleMode == 0) {
11935 769905 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11936 : } else {
11937 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11938 : }
11939 : } else {
11940 3107319 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11941 : }
11942 : } else {
11943 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 0.0, CompIndex, this->m_CoolingSpeedNum, this->m_FanOpMode, CompressorOn);
11944 0 : this->m_CoolCompPartLoadRatio = 0.0;
11945 : }
11946 3877224 : } break;
11947 48603 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
11948 : // formerly (v3 and beyond) COIL:DX:MULTIMODE:COOLINGEMPIRICAL
11949 48603 : DXCoils::SimDXCoilMultiMode(
11950 : state, CompName, CompressorOn, FirstHVACIteration, PartLoadRatio, this->m_DehumidificationMode, CompIndex, this->m_FanOpMode);
11951 48603 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11952 48603 : } break;
11953 0 : case HVAC::Coil_UserDefined: {
11954 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11955 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
11956 :
11957 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
11958 0 : } break;
11959 1364358 : case HVAC::Coil_CoolingWater:
11960 : case HVAC::Coil_CoolingWaterDetailed: {
11961 1364358 : if (this->CoolCoilWaterFlowRatio == 0.0) {
11962 1364358 : mdot = this->MaxCoolCoilFluidFlow * PartLoadRatio;
11963 : } else {
11964 0 : mdot = this->CoolCoilWaterFlowRatio * this->MaxCoolCoilFluidFlow;
11965 : }
11966 1364358 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11967 4093074 : WaterCoils::SimulateWaterCoilComponents(
11968 2728716 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11969 1364358 : } break;
11970 1865394 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
11971 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
11972 1865394 : if (this->m_CoolingSpeedNum > 1) {
11973 310033 : CoilPLR = 1.0;
11974 : } else {
11975 1555361 : CoilPLR = PartLoadRatio;
11976 : }
11977 1865394 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11978 : CompName,
11979 : CompIndex,
11980 : this->m_FanOpMode,
11981 : CompressorOn,
11982 : CoilPLR,
11983 : this->m_CoolingSpeedNum,
11984 : this->m_CoolingSpeedRatio,
11985 : this->m_CoolingCoilSensDemand,
11986 : this->m_CoolingCoilLatentDemand,
11987 : OnOffAirFlowRatio);
11988 1865394 : if (this->m_CoolingSpeedNum > 1) {
11989 310033 : this->m_CoolCompPartLoadRatio = 1.0;
11990 : } else {
11991 1555361 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11992 : }
11993 1865394 : } break;
11994 17305458 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
11995 :
11996 17305458 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11997 : blankString,
11998 17305458 : this->m_CoolingCoilIndex,
11999 : this->m_CoolingCoilSensDemand,
12000 : this->m_CoolingCoilLatentDemand,
12001 : this->m_FanOpMode,
12002 : CompressorOn,
12003 : PartLoadRatio,
12004 : FirstHVACIteration);
12005 17305458 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
12006 17305458 : } break;
12007 416870 : case HVAC::Coil_CoolingWaterToAirHP: {
12008 :
12009 416870 : WaterToAirHeatPump::SimWatertoAirHP(state,
12010 : blankString,
12011 416870 : this->m_CoolingCoilIndex,
12012 : this->MaxCoolAirMassFlow,
12013 : this->m_FanOpMode,
12014 : FirstHVACIteration,
12015 416870 : this->m_InitHeatPump,
12016 : this->m_CoolingCoilSensDemand,
12017 : this->m_CoolingCoilLatentDemand,
12018 : CompressorOn,
12019 : PartLoadRatio);
12020 :
12021 416870 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
12022 416870 : } break;
12023 28852 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
12024 28852 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, PartLoadRatio);
12025 28852 : } break;
12026 0 : default:
12027 0 : break;
12028 : }
12029 :
12030 49403930 : this->m_CoolingPartLoadFrac = PartLoadRatio;
12031 49403930 : }
12032 :
12033 46727384 : void UnitarySys::calcUnitaryHeatingSystem(EnergyPlusData &state,
12034 : int const AirLoopNum, // index to air loop
12035 : bool const FirstHVACIteration, // True when first HVAC iteration
12036 : Real64 const PartLoadRatio, // coil operating part-load ratio
12037 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
12038 : Real64 const OnOffAirFlowRatio, // ratio of on to off flow rate
12039 : Real64 HeatCoilLoad // adjusted heating coil load if outlet temp exceeds max (W)
12040 : )
12041 : {
12042 :
12043 : // SUBROUTINE INFORMATION:
12044 : // AUTHOR Richard Raustad, FSEC
12045 : // DATE WRITTEN February 2013
12046 :
12047 : // PURPOSE OF THIS SUBROUTINE:
12048 : // This subroutine manages unitary heating system component simulation.
12049 :
12050 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12051 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
12052 : Real64 mdot; // water side flow rate (kg/s)
12053 : Real64 QActual; // actual output of coil (W)
12054 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
12055 :
12056 46727384 : std::string CompName = this->m_HeatingCoilName;
12057 46727384 : Real64 dummy = 0.0;
12058 46727384 : Real64 HeatPLR = 1.0;
12059 46727384 : if (this->m_CondenserNodeNum != 0) {
12060 29562364 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
12061 : // IF node is not connected to anything, pressure = default, use weather data
12062 29562364 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12063 2219 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
12064 : } else {
12065 29560145 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12066 : }
12067 : } else {
12068 17165020 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
12069 : }
12070 :
12071 46727384 : switch (this->m_HeatingCoilType_Num) {
12072 2282758 : case HVAC::CoilDX_HeatingEmpirical: { // COIL:HEATING:DX:SINGLESPEED
12073 4565516 : DXCoils::SimDXCoil(
12074 2282758 : state, CompName, CompressorOn, FirstHVACIteration, this->m_HeatingCoilIndex, this->m_FanOpMode, PartLoadRatio, OnOffAirFlowRatio);
12075 2282758 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12076 2282758 : } break;
12077 0 : case HVAC::Coil_UserDefined: {
12078 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12079 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12080 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_HeatingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12081 0 : } break;
12082 20159425 : case HVAC::Coil_HeatingGasOrOtherFuel:
12083 : case HVAC::Coil_HeatingElectric: {
12084 20159425 : HeatCoilLoad = PartLoadRatio * m_DesignHeatingCapacity;
12085 80637700 : HeatingCoils::SimulateHeatingCoilComponents(
12086 60478275 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
12087 20159425 : } break;
12088 0 : case HVAC::Coil_HeatingDesuperheater: {
12089 0 : HeatingCoils::SimulateHeatingCoilComponents(
12090 0 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
12091 :
12092 0 : } break;
12093 4990992 : case HVAC::CoilDX_MultiSpeedHeating: {
12094 4990992 : if (OutsideDryBulbTemp > this->m_MinOATCompressorHeating) {
12095 4607858 : DXCoils::SimDXCoilMultiSpeed(state,
12096 : CompName,
12097 : this->m_HeatingSpeedRatio,
12098 : this->m_HeatingCycRatio,
12099 4607858 : this->m_HeatingCoilIndex,
12100 4607858 : this->m_HeatingSpeedNum,
12101 4607858 : this->m_FanOpMode,
12102 : CompressorOn,
12103 4607858 : this->m_SingleMode);
12104 4607858 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12105 : } else {
12106 766268 : DXCoils::SimDXCoilMultiSpeed(
12107 383134 : state, CompName, 0.0, 0.0, this->m_HeatingCoilIndex, this->m_HeatingSpeedNum, this->m_FanOpMode, CompressorOn);
12108 383134 : this->m_HeatCompPartLoadRatio = 0.0;
12109 : }
12110 4990992 : } break;
12111 0 : case HVAC::Coil_HeatingElectric_MultiStage:
12112 : case HVAC::Coil_HeatingGas_MultiStage: {
12113 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12114 : CompName,
12115 : FirstHVACIteration,
12116 : _,
12117 0 : 0,
12118 : _,
12119 : _,
12120 0 : this->m_FanOpMode,
12121 : PartLoadRatio,
12122 0 : this->m_HeatingSpeedNum,
12123 0 : this->m_HeatingSpeedRatio);
12124 : // This doesn't look right when it was at higher speed
12125 : // this->m_HeatingCycRatio = PartLoadRatio;
12126 0 : } break;
12127 1184720 : case HVAC::Coil_HeatingWater: {
12128 1184720 : if (this->HeatCoilWaterFlowRatio == 0.0) {
12129 1184720 : mdot = this->MaxHeatCoilFluidFlow * PartLoadRatio;
12130 : } else {
12131 0 : mdot = this->HeatCoilWaterFlowRatio * this->MaxHeatCoilFluidFlow;
12132 : }
12133 1184720 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
12134 3554160 : WaterCoils::SimulateWaterCoilComponents(
12135 2369440 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
12136 1184720 : } break;
12137 55178 : case HVAC::Coil_HeatingSteam: {
12138 : // this same CALL is made in the steam coil calc routine
12139 55178 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxHeatCoilFluidFlow * PartLoadRatio);
12140 55178 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
12141 : // tried this to resolve the PackagedTerminalAirConditioner steam spike issue, no help, but this is the correct way to do this
12142 55178 : PlantUtilities::SetComponentFlowRate(
12143 55178 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
12144 : } else {
12145 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
12146 : }
12147 220712 : SteamCoils::SimulateSteamCoilComponents(state,
12148 : CompName,
12149 : FirstHVACIteration,
12150 55178 : this->m_HeatingCoilIndex,
12151 110356 : this->m_DesignHeatingCapacity * PartLoadRatio,
12152 : _,
12153 55178 : this->m_FanOpMode,
12154 : PartLoadRatio);
12155 55178 : } break;
12156 331464 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
12157 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
12158 331464 : if (this->m_HeatingSpeedNum > 1) {
12159 106030 : HeatPLR = 1.0;
12160 106030 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
12161 44092 : this->m_HeatingSpeedRatio = PartLoadRatio;
12162 : }
12163 : } else {
12164 225434 : HeatPLR = PartLoadRatio;
12165 : }
12166 :
12167 331464 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12168 : CompName,
12169 331464 : this->m_HeatingCoilIndex,
12170 : this->m_FanOpMode,
12171 : CompressorOn,
12172 : HeatPLR,
12173 : this->m_HeatingSpeedNum,
12174 : this->m_HeatingSpeedRatio,
12175 : this->m_HeatingCoilSensDemand,
12176 : dummy,
12177 : OnOffAirFlowRatio);
12178 331464 : if (this->m_HeatingSpeedNum > 1) {
12179 106030 : this->m_HeatCompPartLoadRatio = 1.0;
12180 : } else {
12181 225434 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12182 : }
12183 331464 : } break;
12184 17305977 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
12185 :
12186 17305977 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12187 : blankString,
12188 17305977 : this->m_HeatingCoilIndex,
12189 : this->m_HeatingCoilSensDemand,
12190 : dummy,
12191 : this->m_FanOpMode,
12192 : CompressorOn,
12193 : PartLoadRatio,
12194 : FirstHVACIteration);
12195 17305977 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12196 17305977 : } break;
12197 416870 : case HVAC::Coil_HeatingWaterToAirHP: {
12198 :
12199 416870 : WaterToAirHeatPump::SimWatertoAirHP(state,
12200 : blankString,
12201 416870 : this->m_HeatingCoilIndex,
12202 : this->MaxHeatAirMassFlow,
12203 : this->m_FanOpMode,
12204 : FirstHVACIteration,
12205 416870 : this->m_InitHeatPump,
12206 : this->m_HeatingCoilSensDemand,
12207 : dummy,
12208 : CompressorOn,
12209 : PartLoadRatio);
12210 416870 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12211 416870 : } break;
12212 0 : default: {
12213 0 : ShowFatalError(
12214 0 : state, format("CalcUnitaryHeatingSystem: Invalid Unitary System coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
12215 0 : } break;
12216 : }
12217 :
12218 46727384 : this->m_HeatingPartLoadFrac = PartLoadRatio;
12219 46727384 : }
12220 :
12221 22148376 : void UnitarySys::calcUnitarySuppHeatingSystem(EnergyPlusData &state,
12222 : bool const FirstHVACIteration, // True when first HVAC iteration
12223 : Real64 const SuppCoilLoad // adjusted supp coil load when outlet temp exceeds max (W)
12224 : )
12225 : {
12226 :
12227 : // SUBROUTINE INFORMATION:
12228 : // AUTHOR Richard Raustad, FSEC
12229 : // DATE WRITTEN February 2013
12230 :
12231 : // PURPOSE OF THIS SUBROUTINE:
12232 : // This subroutine manages supplemental heater simulation.
12233 :
12234 : // SUBROUTINE PARAMETER DEFINITIONS:
12235 22148376 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12236 22148376 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12237 :
12238 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12239 : // std::string CompName; // Name of Unitary System object
12240 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
12241 : Real64 QActual; // actual coil output (W)
12242 : Real64 mdot; // water coil water mass flow rate (kg/s)
12243 22148376 : std::vector<Real64> Par; // Parameter array passed to solver
12244 : Real64 PartLoadFrac; // temporary PLR variable
12245 :
12246 22148376 : Par.resize(5);
12247 : // work is needed to figure out how to adjust other coil types if outlet temp exceeds maximum
12248 : // this works for gas and electric heating coils
12249 22148376 : std::string CompName = this->m_SuppHeatCoilName;
12250 34385022 : if (state.dataEnvrn->OutDryBulbTemp <= this->m_MaxOATSuppHeat ||
12251 12236646 : (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolingPartLoadFrac > 0.0)) {
12252 9996090 : SuppHeatCoilLoad = SuppCoilLoad;
12253 : //} else {
12254 : // SuppHeatCoilLoad = this->m_DesignSuppHeatingCapacity * PartLoadRatio;
12255 : //}
12256 : } else {
12257 12152286 : SuppHeatCoilLoad = 0.0;
12258 : }
12259 22148376 : switch (this->m_SuppHeatCoilType_Num) {
12260 22148376 : case HVAC::Coil_HeatingGasOrOtherFuel:
12261 : case HVAC::Coil_HeatingElectric:
12262 : case HVAC::Coil_HeatingElectric_MultiStage: {
12263 22148376 : switch (this->m_ControlType) {
12264 0 : case UnitarySysCtrlType::Setpoint: {
12265 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12266 : CompName,
12267 : FirstHVACIteration,
12268 : SuppHeatCoilLoad,
12269 0 : this->m_SuppHeatCoilIndex,
12270 : _,
12271 0 : true,
12272 0 : this->m_FanOpMode,
12273 0 : this->m_SuppHeatPartLoadFrac,
12274 0 : this->m_SuppHeatingSpeedNum,
12275 0 : this->m_SuppHeatingSpeedRatio);
12276 0 : } break;
12277 22148376 : default: {
12278 22148376 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
12279 461070 : if (SuppHeatCoilLoad > 0.0) {
12280 94464 : this->setEMSSuppCoilStagePLR(state);
12281 : } else {
12282 366606 : this->m_SuppHeatingSpeedRatio = 0.0;
12283 366606 : this->m_SuppHeatingCycRatio = 0.0;
12284 366606 : this->m_SuppHeatPartLoadFrac = 0.0;
12285 : }
12286 : } else {
12287 21687306 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
12288 302026 : this->calcMultiStageSuppCoilStageByLoad(state, SuppHeatCoilLoad, FirstHVACIteration);
12289 : }
12290 : }
12291 66445128 : HeatingCoils::SimulateHeatingCoilComponents(state,
12292 : CompName,
12293 : FirstHVACIteration,
12294 : SuppHeatCoilLoad,
12295 22148376 : this->m_SuppHeatCoilIndex,
12296 : _,
12297 44296752 : true,
12298 22148376 : this->m_FanOpMode,
12299 22148376 : this->m_SuppHeatPartLoadFrac,
12300 22148376 : this->m_SuppHeatingSpeedNum,
12301 22148376 : this->m_SuppHeatingSpeedRatio);
12302 22148376 : } break;
12303 : }
12304 22148376 : } break;
12305 0 : case HVAC::Coil_HeatingDesuperheater: {
12306 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12307 : CompName,
12308 : FirstHVACIteration,
12309 : SuppHeatCoilLoad,
12310 0 : this->m_SuppHeatCoilIndex,
12311 : _,
12312 0 : true,
12313 0 : this->m_FanOpMode,
12314 0 : this->m_SuppHeatPartLoadFrac);
12315 0 : } break;
12316 0 : case HVAC::Coil_HeatingWater: {
12317 : // see if HW coil has enough capacity to meet the load
12318 0 : if (SuppHeatCoilLoad > 0.0) {
12319 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->m_MaxSuppCoilFluidFlow);
12320 : } else {
12321 0 : mdot = 0.0;
12322 : }
12323 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12324 : // simulate water coil to find operating capacity
12325 0 : WaterCoils::SimulateWaterCoilComponents(state,
12326 : this->m_SuppHeatCoilName,
12327 : FirstHVACIteration,
12328 0 : this->m_SuppHeatCoilIndex,
12329 : QActual,
12330 0 : this->m_FanOpMode,
12331 0 : this->m_SuppHeatPartLoadFrac);
12332 0 : if (QActual > SuppHeatCoilLoad) {
12333 0 : auto f = [&state, this, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
12334 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12335 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
12336 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12337 0 : WaterCoils::SimulateWaterCoilComponents(
12338 0 : state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex, 0.0, this->m_FanOpMode, PartLoadFrac);
12339 0 : return SuppHeatCoilLoad;
12340 0 : };
12341 : int SolFla; // Flag of solver, num iterations if >0, else error index
12342 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12343 0 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
12344 : } else {
12345 0 : this->m_SuppHeatPartLoadFrac = (SuppHeatCoilLoad > 0.0) ? 1.0 : 0.0;
12346 : }
12347 0 : } break;
12348 0 : case HVAC::Coil_HeatingSteam: {
12349 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12350 0 : this->m_MaxSuppCoilFluidFlow * this->m_SuppHeatPartLoadFrac);
12351 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12352 0 : SteamCoils::SimulateSteamCoilComponents(
12353 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, SuppHeatCoilLoad, _, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
12354 0 : } break;
12355 0 : default:
12356 0 : break;
12357 : }
12358 22148376 : }
12359 :
12360 94464 : void UnitarySys::setEMSSuppCoilStagePLR(EnergyPlusData &state)
12361 : {
12362 94464 : bool useMaxedSpeed = false;
12363 94464 : int SpeedNumEMS = ceil(this->m_EMSOverrideSuppCoilSpeedNumValue);
12364 94464 : if (SpeedNumEMS > this->m_NumOfSpeedSuppHeating) {
12365 0 : SpeedNumEMS = this->m_NumOfSpeedSuppHeating;
12366 0 : useMaxedSpeed = true;
12367 : }
12368 94464 : this->m_SuppHeatingSpeedNum = SpeedNumEMS;
12369 94464 : if (useMaxedSpeed) {
12370 0 : this->m_CoilSpeedErrIdx++;
12371 0 : ShowRecurringWarningErrorAtEnd(state,
12372 0 : format("Wrong coil speed EMS override value, for unit=\"{}\". Exceeding maximum coil speed "
12373 : "level. Speed level is set to the maximum coil speed level allowed.",
12374 0 : this->m_SuppHeatCoilName),
12375 0 : this->m_CoilSpeedErrIdx,
12376 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12377 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12378 : _,
12379 : "",
12380 : "");
12381 : }
12382 94464 : if (this->m_SuppHeatingSpeedNum == 1) {
12383 16 : this->m_SuppHeatingSpeedRatio = 0.0;
12384 16 : this->m_SuppHeatingCycRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12385 16 : if (useMaxedSpeed || this->m_SuppHeatingCycRatio == 0) {
12386 16 : this->m_SuppHeatingCycRatio = 1;
12387 : }
12388 16 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingCycRatio;
12389 : } else {
12390 94448 : this->m_SuppHeatingCycRatio = 1.0;
12391 94448 : this->m_SuppHeatingSpeedRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12392 94448 : if (useMaxedSpeed || this->m_SuppHeatingSpeedRatio == 0) {
12393 0 : this->m_SuppHeatingSpeedRatio = 1;
12394 : }
12395 94448 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingSpeedRatio;
12396 : }
12397 94464 : }
12398 :
12399 2985736 : void UnitarySys::controlCoolingSystemToSP(EnergyPlusData &state,
12400 : int const AirLoopNum, // index to air loop
12401 : bool const FirstHVACIteration, // First HVAC iteration flag
12402 : bool &HXUnitOn, // flag to enable heat exchanger heat recovery
12403 : HVAC::CompressorOp &compressorOp // compressor on/off control
12404 : )
12405 : {
12406 : // SUBROUTINE INFORMATION:
12407 : // AUTHOR Richard Raustad, FSEC
12408 : // DATE WRITTEN February 2013
12409 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
12410 :
12411 : // PURPOSE OF THIS SUBROUTINE:
12412 : // Simulate the coil object at the required PLR.
12413 :
12414 : // METHODOLOGY EMPLOYED:
12415 : // Calculate operating PLR and adjust speed when using multispeed coils.
12416 : // Meet moisture load if required to do so.
12417 :
12418 : // SUBROUTINE PARAMETER DEFINITIONS:
12419 2985736 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12420 2985736 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12421 2985736 : Real64 constexpr HumRatAcc(1.e-6); // Accuracy of solver result
12422 :
12423 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12424 : Real64 ReqOutput; // Sensible capacity (outlet - inlet) required to meet load or setpoint temperature
12425 : // for variable speed or 2 speed compressors
12426 : Real64 OutletTempDXCoil; // Actual outlet temperature of the DX cooling coil
12427 : Real64 OutletHumRatLS; // Actual outlet humrat of the variable speed DX cooling coil at low speed
12428 : Real64 OutletHumRatHS; // Actual outlet humrat of the variable speed DX cooling coil at high speed
12429 : Real64 OutletHumRatDXCoil; // Actual outlet humidity ratio of the DX cooling coil
12430 : Real64 TempMinPLR; // Used to find latent PLR when max iterations exceeded
12431 : Real64 TempMaxPLR; // Used to find latent PLR when max iterations exceeded
12432 : Real64 TempOutletTempDXCoil; // Used to find latent PLR when max iterations exceeded
12433 : Real64 OutletTemp;
12434 : Real64 OutdoorDryBulb; // local variable for OutDryBulbTemp
12435 : Real64 maxPartLoadFrac; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
12436 :
12437 : // Set local variables
12438 : // Retrieve the load on the controlled zone
12439 2985736 : int OutletNode = this->CoolCoilOutletNodeNum;
12440 2985736 : int InletNode = this->CoolCoilInletNodeNum;
12441 2985736 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
12442 2985736 : Real64 DesOutHumRat = this->m_DesiredOutletHumRat;
12443 2985736 : int CoilType_Num = this->m_CoolingCoilType_Num;
12444 2985736 : Real64 LoopDXCoilMaxRTFSave = 0.0;
12445 3110232 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
12446 124496 : this->m_sysType != SysType::PackagedWSHP) {
12447 124496 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
12448 124496 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
12449 : }
12450 :
12451 2985736 : std::string CompName = this->m_CoolingCoilName;
12452 2985736 : HVAC::FanOp fanOp = this->m_FanOpMode;
12453 2985736 : Real64 SpeedRatio = 0.0;
12454 2985736 : Real64 CycRatio = 0.0;
12455 2985736 : Real64 PartLoadFrac = 0.0;
12456 2985736 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal;
12457 2985736 : Real64 dummy = 0.0;
12458 2985736 : Real64 SensLoad = 0.0;
12459 2985736 : int SolFla = 0;
12460 2985736 : int SolFlaLat = 0;
12461 2985736 : Real64 NoLoadTempOut = 0.0;
12462 2985736 : Real64 NoLoadHumRatOut = 0.0;
12463 : // #8849, FullLoadHumRatOut set only at max speed
12464 2985736 : Real64 FullLoadHumRatOut = 0.0;
12465 2985736 : Real64 FullOutput = 0.0; // Sensible capacity (outlet - inlet) when the compressor is on
12466 2985736 : Real64 OnOffAirFlowRatio = 0.0; // Autodesk:Init Patch to prevent use uninitialized in calls to SimVariableSpeedCoils
12467 2985736 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
12468 :
12469 2985736 : if (this->m_CondenserNodeNum != 0) {
12470 168360 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12471 : } else {
12472 2817376 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12473 : }
12474 :
12475 : // Check the dehumidification control type. IF it's multimode, turn off the HX to find the sensible PLR. Then check to
12476 : // see if the humidity load is met without the use of the HX. Always run the HX for the other modes.
12477 2985736 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode && this->m_CoolingCoilType_Num != HVAC::CoilDX_Cooling) {
12478 2874877 : HXUnitOn = true;
12479 : } else {
12480 110859 : HXUnitOn = false;
12481 : }
12482 :
12483 : // IF there is a fault of coil SAT Sensor
12484 2985736 : if (this->m_FaultyCoilSATFlag) {
12485 : // calculate the sensor offset using fault information
12486 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
12487 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
12488 : // update the DesOutTemp
12489 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
12490 : }
12491 :
12492 : // IF UnitarySystem is scheduled on and there is flow
12493 5611963 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && this->m_coolingCoilAvailSched->getCurrentVal() > 0.0 &&
12494 2626227 : (state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow)) {
12495 :
12496 2224607 : bool SensibleLoad = false;
12497 2224607 : bool LatentLoad = false;
12498 2224607 : bool unitSys = false;
12499 2224607 : Real64 tempHumRatAcc = HumRatAcc;
12500 2224607 : Real64 tempAcc = Acc;
12501 : // Determine if there is a sensible load on this system
12502 2224607 : if (this->m_sysType == SysType::CoilCoolingDX) {
12503 2045808 : if ((state.dataLoopNodes->Node(InletNode).Temp > state.dataLoopNodes->Node(this->CoolCtrlNode).TempSetPoint) &&
12504 3111144 : (state.dataLoopNodes->Node(InletNode).Temp > DesOutTemp) &&
12505 1065336 : (std::abs(state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp) > HVAC::TempControlTol)) {
12506 949071 : SensibleLoad = true;
12507 : }
12508 2045808 : tempAcc = 0.0;
12509 2045808 : tempHumRatAcc = 0.0;
12510 : } else {
12511 178799 : unitSys = true;
12512 178799 : if (state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp > HVAC::TempControlTol) {
12513 154818 : SensibleLoad = true;
12514 : }
12515 : }
12516 :
12517 : // if a heat pump and other coil is on, disable this coil
12518 2224607 : if (this->m_HeatPump && this->m_HeatingPartLoadFrac > 0.0) {
12519 0 : SensibleLoad = false;
12520 : }
12521 :
12522 : // Determine if there is a latent load on this system - for future use to serve latent-only loads
12523 2224607 : if (this->m_sysType == SysType::CoilCoolingDX) {
12524 4069987 : if ((state.dataLoopNodes->Node(InletNode).HumRat > state.dataLoopNodes->Node(InletNode).HumRatMax) &&
12525 2024179 : (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat)) {
12526 11701 : LatentLoad = true;
12527 : }
12528 : } else {
12529 178799 : if (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat) {
12530 79431 : LatentLoad = true;
12531 : }
12532 : }
12533 :
12534 : // disable latent dehumidification if there is no sensible load and latent only is not allowed
12535 2224607 : if (this->m_RunOnLatentOnlyWithSensible && !SensibleLoad) {
12536 0 : LatentLoad = false;
12537 : }
12538 :
12539 : // disable compressor if OAT is below minimum outdoor temperature
12540 2224607 : if (OutdoorDryBulb < this->m_MinOATCompressorCooling) {
12541 0 : SensibleLoad = false;
12542 0 : LatentLoad = false;
12543 : }
12544 :
12545 : // activate heat recovery loop coil if scheduled on and there is air flow
12546 2224607 : if (this->m_WaterHRPlantLoopModel) {
12547 15820 : if (this->temperatureOffsetControlStatus == 1) {
12548 1 : PartLoadFrac = 1.0;
12549 1 : mdot = this->MaxCoolCoilFluidFlow;
12550 : }
12551 15820 : if (this->CoolCoilPlantLoc.loopNum > 0) {
12552 15820 : PlantUtilities::SetComponentFlowRate(
12553 15820 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12554 : }
12555 :
12556 47460 : WaterCoils::SimulateWaterCoilComponents(
12557 31640 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12558 15820 : SensibleLoad = false; // fall through remaining checks
12559 15820 : LatentLoad = false;
12560 2208787 : } else if (this->m_TemperatureOffsetControlActive) {
12561 : // disable waterside economizer if the condition is NOT favorable
12562 60192 : if (this->temperatureOffsetControlStatus == 0) {
12563 59696 : SensibleLoad = false;
12564 59696 : LatentLoad = false;
12565 59696 : HXUnitOn = false;
12566 : }
12567 : }
12568 :
12569 : // IF DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
12570 : // Multimode coil will switch to enhanced dehumidification IF available and needed, but it
12571 : // still runs to meet the sensible load. Multimode applies to Multimode or HXAssistedCooling coils.
12572 2224607 : if ((SensibleLoad && this->m_RunOnSensibleLoad) || (LatentLoad && this->m_RunOnLatentLoad)) {
12573 : // calculate sensible PLR, don't care IF latent is true here but need to guard for
12574 : // when LatentLoad=TRUE and SensibleLoad=FALSE
12575 1036199 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12576 3108597 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
12577 1036199 : state.dataLoopNodes->Node(OutletNode).HumRat,
12578 1036199 : state.dataLoopNodes->Node(InletNode).Temp,
12579 1036199 : state.dataLoopNodes->Node(InletNode).HumRat);
12580 :
12581 1036199 : PartLoadFrac = 0.0;
12582 1036199 : compressorOp = HVAC::CompressorOp::Off;
12583 :
12584 1036199 : if (this->m_EMSOverrideCoilSpeedNumOn && (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12585 36467 : this->m_CoolingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
12586 36467 : this->m_SpeedNum = this->m_CoolingSpeedNum;
12587 36467 : bool useMaxedSpeed = false;
12588 36467 : if (this->m_SpeedNum > this->m_NumOfSpeedCooling) {
12589 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
12590 0 : this->m_SpeedNum = this->m_NumOfSpeedCooling;
12591 0 : useMaxedSpeed = true;
12592 0 : if (this->m_CoilSpeedErrIdx == 0) {
12593 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12594 0 : ShowContinueError(state,
12595 : " Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.");
12596 : }
12597 0 : ShowRecurringWarningErrorAtEnd(
12598 : state,
12599 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12600 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
12601 0 : this->m_CoilSpeedErrIdx,
12602 0 : this->m_EMSOverrideCoilSpeedNumValue,
12603 0 : this->m_EMSOverrideCoilSpeedNumValue,
12604 : _,
12605 : "",
12606 : "");
12607 : }
12608 :
12609 36467 : if (this->m_SpeedNum < 0) {
12610 0 : this->m_CoolingSpeedNum = 0;
12611 0 : this->m_SpeedNum = 0;
12612 0 : if (this->m_CoilSpeedErrIdx == 0) {
12613 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12614 0 : ShowContinueError(state, " Input speed value is below zero. Speed level is set to zero.");
12615 : }
12616 0 : ShowRecurringWarningErrorAtEnd(state,
12617 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12618 : "\". Input speed value is below zero. Speed level is set to zero.",
12619 0 : this->m_CoilSpeedErrIdx,
12620 0 : this->m_EMSOverrideCoilSpeedNumValue,
12621 0 : this->m_EMSOverrideCoilSpeedNumValue,
12622 : _,
12623 : "",
12624 : "");
12625 : }
12626 :
12627 36467 : if (this->m_CoolingSpeedNum == 1) {
12628 3889 : SpeedRatio = this->m_CoolingSpeedRatio = 0.0;
12629 3889 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12630 3889 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
12631 3889 : CycRatio = this->m_CoolingCycRatio = 1;
12632 : } else {
12633 0 : CycRatio = this->m_CoolingCycRatio;
12634 : }
12635 3889 : PartLoadFrac = this->m_CoolingCycRatio;
12636 : } else {
12637 32578 : CycRatio = this->m_CoolingCycRatio = 1.0;
12638 32578 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12639 32578 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
12640 0 : SpeedRatio = this->m_CoolingSpeedRatio = 1;
12641 : } else {
12642 32578 : SpeedRatio = this->m_CoolingSpeedRatio;
12643 : }
12644 32578 : PartLoadFrac = this->m_CoolingSpeedRatio;
12645 : }
12646 36467 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12647 36467 : if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12648 0 : this->simMultiSpeedCoils(state,
12649 : AirLoopNum,
12650 : FirstHVACIteration,
12651 : compressorOp,
12652 : SensibleLoad,
12653 : LatentLoad,
12654 : PartLoadFrac,
12655 : CoolingCoil,
12656 : this->m_SpeedNum);
12657 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12658 0 : int SpeedNum = 0;
12659 0 : if (SpeedNum == this->m_NumOfSpeedCooling) { // should be using this->m_SpeedNum? Diffs?
12660 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12661 : }
12662 : } else {
12663 36467 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12664 36467 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
12665 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12666 36467 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12667 0 : coilMode = HVAC::CoilMode::Enhanced;
12668 : }
12669 36467 : bool const singleMode = (this->m_SingleMode == 1);
12670 36467 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12671 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode);
12672 : }
12673 :
12674 1036199 : } else if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12675 628553 : this->m_CompPartLoadRatio = PartLoadFrac;
12676 :
12677 628553 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12678 :
12679 371179 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12680 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12681 :
12682 11618 : if (this->CoolCoilFluidInletNode > 0) {
12683 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
12684 : }
12685 :
12686 34854 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12687 : CompName,
12688 : FirstHVACIteration,
12689 : HVAC::CompressorOp::On,
12690 : PartLoadFrac,
12691 11618 : this->m_CoolingCoilIndex,
12692 : fanOp,
12693 : HXUnitOn,
12694 : _,
12695 11618 : state.dataUnitarySystems->economizerFlag,
12696 : _,
12697 11618 : this->m_DehumidificationMode,
12698 11618 : 0.0); // this->CoilSHR);
12699 11618 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
12700 11618 : this->m_CompPartLoadRatio = PartLoadFrac;
12701 : }
12702 359561 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12703 :
12704 294768 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, PartLoadFrac, this->m_CoolingCoilIndex);
12705 :
12706 64793 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12707 5179 : this->simMultiSpeedCoils(
12708 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, this->m_SpeedNum);
12709 :
12710 59614 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12711 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12712 :
12713 13133 : int SpeedNum = 0;
12714 13133 : this->m_CoolingCoilSensDemand = ReqOutput;
12715 13133 : VariableSpeedCoils::SimVariableSpeedCoils(
12716 13133 : state, "", this->m_CoolingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
12717 :
12718 59614 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
12719 :
12720 11039 : DXCoils::SimDXCoilMultiMode(
12721 11039 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12722 11039 : this->m_CompPartLoadRatio = PartLoadFrac;
12723 35442 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12724 : // SP control (tentatively) operates at constant air flow regardless of speed
12725 : // speed n uses MSHPMassFlowRateHigh and speed n-1 uses MSHPMassFlowRateLow
12726 28561 : state.dataHVACGlobal->MSHPMassFlowRateLow = this->m_DesignMassFlowRate;
12727 28561 : state.dataHVACGlobal->MSHPMassFlowRateHigh = this->m_DesignMassFlowRate;
12728 28561 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12729 28561 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
12730 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12731 28561 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12732 0 : coilMode = HVAC::CoilMode::Enhanced;
12733 : }
12734 28561 : bool const singleMode = (this->m_SingleMode == 1);
12735 : // PartLoadFrac has not been set in this branch - so use m_CoolingSpeedRatio?
12736 28561 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12737 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12738 28561 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12739 6881 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12740 :
12741 1350 : WaterCoils::SimulateWaterCoilComponents(
12742 900 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12743 :
12744 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12745 :
12746 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12747 : blankString,
12748 0 : this->m_CoolingCoilIndex,
12749 : ReqOutput,
12750 : dummy,
12751 : fanOp,
12752 : HVAC::CompressorOp::Off,
12753 : PartLoadFrac,
12754 : FirstHVACIteration);
12755 0 : this->m_CoolingCoilSensDemand = 0.0;
12756 :
12757 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12758 :
12759 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12760 : blankString,
12761 0 : this->m_CoolingCoilIndex,
12762 : this->MaxCoolAirMassFlow,
12763 : fanOp,
12764 : FirstHVACIteration,
12765 0 : this->m_InitHeatPump,
12766 : ReqOutput,
12767 : dummy,
12768 : HVAC::CompressorOp::Off,
12769 : PartLoadFrac);
12770 :
12771 6431 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12772 :
12773 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12774 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12775 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12776 0 : if (CoolingActive) {
12777 0 : PartLoadFrac = 1.0;
12778 : }
12779 :
12780 6431 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12781 :
12782 6431 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12783 :
12784 : } else {
12785 : }
12786 :
12787 1036199 : NoLoadTempOut = state.dataLoopNodes->Node(OutletNode).Temp;
12788 1036199 : NoLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12789 :
12790 1036199 : Real64 NoOutput = 0.0; // CoilSystem:Cooling:DX
12791 1036199 : FullOutput = 0.0;
12792 1036199 : if (this->m_sysType == SysType::CoilCoolingDX) {
12793 949071 : NoOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12794 949071 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12795 949071 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12796 949071 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12797 1898142 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12798 949071 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12799 : }
12800 :
12801 : // Changed logic to use temperature instead of load. The Psyc calcs can cause slight errors.
12802 : // For example it's possible that (NoOutput-ReqOutput) > Acc while (Node(OutletNode)%Temp-DesOutTemp) is not
12803 : // This can (and did) lead to RegulaFalsi errors
12804 :
12805 : // IF ((NoOutput-ReqOutput) .LT. Acc) THEN
12806 : // IF outlet temp at no load is lower than DesOutTemp (set point), do not operate the coil
12807 : // and if coolReheat, check hum rat as well
12808 1036199 : bool doIt = false; // CoilSystem:Cooling:DX
12809 1036199 : if (this->m_sysType == SysType::CoilCoolingDX) {
12810 949071 : if ((NoOutput - ReqOutput) < Acc) {
12811 0 : PartLoadFrac = 0.0;
12812 : } else {
12813 949071 : doIt = true;
12814 : }
12815 87128 : } else if (this->m_EMSOverrideCoilSpeedNumOn &&
12816 36467 : (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12817 : // do nothing, PartLoadFrac set above
12818 50661 : } else if (((NoLoadTempOut - DesOutTemp) < Acc) && ((NoLoadHumRatOut - DesOutHumRat) < HumRatAcc)) {
12819 0 : PartLoadFrac = 0.0;
12820 : } else { // need to turn on compressor to see if load is met
12821 50661 : doIt = true; // CoilSystem:Cooling:DX
12822 : } // CoilSystem:Cooling:DX
12823 1036199 : if (this->m_EMSOverrideCoilSpeedNumOn) {
12824 36467 : doIt = false;
12825 : }
12826 :
12827 1036199 : if (doIt) { // CoilSystem:Cooling:DX
12828 999732 : PartLoadFrac = 1.0;
12829 999732 : compressorOp = HVAC::CompressorOp::On;
12830 :
12831 999732 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12832 :
12833 1257106 : DXCoils::SimDXCoil(
12834 628553 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12835 628553 : this->m_CompPartLoadRatio = PartLoadFrac;
12836 628553 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12837 :
12838 371179 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12839 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12840 :
12841 11618 : if (this->CoolCoilFluidInletNode > 0) {
12842 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = max(0.0, this->MaxCoolCoilFluidFlow);
12843 : }
12844 34854 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12845 : CompName,
12846 : FirstHVACIteration,
12847 : HVAC::CompressorOp::On,
12848 : PartLoadFrac,
12849 11618 : this->m_CoolingCoilIndex,
12850 : fanOp,
12851 : HXUnitOn,
12852 : _,
12853 11618 : state.dataUnitarySystems->economizerFlag,
12854 : _,
12855 11618 : this->m_DehumidificationMode,
12856 11618 : 0.0); // this->CoilSHR);
12857 :
12858 11618 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
12859 11618 : this->m_CompPartLoadRatio = PartLoadFrac;
12860 : }
12861 11618 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12862 :
12863 359561 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12864 :
12865 294768 : CycRatio = 1.0;
12866 554692 : for (int speedRatio = 0; speedRatio < this->m_NumOfSpeedCooling; ++speedRatio) {
12867 554692 : SpeedRatio = Real64(speedRatio);
12868 554692 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
12869 554692 : OutletTemp = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
12870 554692 : if (SpeedRatio == 1) {
12871 259924 : FullLoadHumRatOut = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
12872 259924 : break;
12873 : }
12874 294768 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12875 34844 : break;
12876 : }
12877 : }
12878 :
12879 64793 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12880 :
12881 5179 : CycRatio = 1.0;
12882 5179 : SpeedRatio = 0.0;
12883 15494 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12884 10337 : if (SpeedNum > 1) {
12885 5158 : CycRatio = 0.0;
12886 5158 : SpeedRatio = 1.0;
12887 : }
12888 10337 : this->m_CoolingSpeedNum = SpeedNum;
12889 10337 : this->simMultiSpeedCoils(
12890 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, SpeedNum);
12891 10337 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12892 10337 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12893 5158 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12894 : }
12895 10337 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12896 22 : break;
12897 : }
12898 : }
12899 :
12900 59614 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12901 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12902 :
12903 13133 : CycRatio = 1.0;
12904 13133 : SpeedRatio = 1.0;
12905 13133 : SensLoad = -1.0; // turns on coil
12906 13133 : this->m_CoolingSpeedRatio = SpeedRatio;
12907 13133 : this->m_CoolingPartLoadFrac = PartLoadFrac;
12908 17779 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12909 15962 : this->m_CoolingSpeedNum = SpeedNum;
12910 15962 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12911 : "",
12912 15962 : this->m_CoolingCoilIndex,
12913 : fanOp,
12914 : compressorOp,
12915 : CycRatio,
12916 : SpeedNum,
12917 : SpeedRatio,
12918 : SensLoad,
12919 : dummy,
12920 : OnOffAirFlowRatio);
12921 15962 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12922 15962 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12923 11101 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12924 : }
12925 15962 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12926 11316 : break;
12927 : }
12928 : }
12929 13133 : if (this->m_CoolingSpeedNum == 1) {
12930 11195 : CycRatio = 1.0;
12931 11195 : SpeedRatio = 0.0;
12932 : } else {
12933 1938 : CycRatio = 0.0;
12934 1938 : SpeedRatio = 1.0;
12935 : }
12936 :
12937 59614 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) { // Coil:Cooling:DX:TwoStageWithHumidityControlMode
12938 :
12939 11039 : DXCoils::SimDXCoilMultiMode(
12940 11039 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12941 11039 : this->m_CompPartLoadRatio = PartLoadFrac;
12942 :
12943 35442 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12944 28561 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12945 28561 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
12946 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12947 28561 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12948 0 : coilMode = HVAC::CoilMode::Enhanced;
12949 : }
12950 28561 : this->m_CoolingSpeedRatio = 1.0;
12951 28561 : bool const singleMode = (this->m_SingleMode == 1);
12952 41070 : for (int speedNum = 1; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
12953 36799 : this->m_CoolingSpeedNum = speedNum;
12954 36799 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12955 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12956 36799 : if (speedNum == this->m_NumOfSpeedCooling) {
12957 23933 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12958 : }
12959 36799 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) {
12960 24290 : break;
12961 : }
12962 : }
12963 28561 : if (this->m_CoolingSpeedNum == 1) {
12964 20323 : this->m_CompPartLoadRatio = PartLoadFrac;
12965 20323 : this->m_CoolCompPartLoadRatio = PartLoadFrac; // why is the set only for a few?
12966 20323 : SpeedRatio = 0.0;
12967 : } else {
12968 8238 : SpeedRatio = PartLoadFrac;
12969 8238 : PartLoadFrac = 1.0;
12970 8238 : this->m_CompPartLoadRatio = 1.0;
12971 8238 : this->m_CoolCompPartLoadRatio = 1.0;
12972 : }
12973 6881 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12974 :
12975 450 : mdot = this->MaxCoolCoilFluidFlow;
12976 450 : PlantUtilities::SetComponentFlowRate(
12977 450 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12978 :
12979 1350 : WaterCoils::SimulateWaterCoilComponents(
12980 900 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12981 450 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12982 :
12983 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12984 :
12985 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12986 : blankString,
12987 0 : this->m_CoolingCoilIndex,
12988 : ReqOutput,
12989 : dummy,
12990 : fanOp,
12991 : HVAC::CompressorOp::On,
12992 : PartLoadFrac,
12993 : FirstHVACIteration);
12994 0 : this->m_CoolingCoilSensDemand = ReqOutput;
12995 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12996 :
12997 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12998 :
12999 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
13000 : blankString,
13001 0 : this->m_CoolingCoilIndex,
13002 : this->MaxCoolAirMassFlow,
13003 : fanOp,
13004 : FirstHVACIteration,
13005 0 : this->m_InitHeatPump,
13006 : ReqOutput,
13007 : dummy,
13008 : HVAC::CompressorOp::Off,
13009 : PartLoadFrac);
13010 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13011 :
13012 6431 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13013 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
13014 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
13015 :
13016 0 : UserDefinedComponents::SimCoilUserDefined(
13017 0 : state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
13018 0 : if (CoolingActive) {
13019 0 : PartLoadFrac = 1.0;
13020 : }
13021 :
13022 6431 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13023 :
13024 : // TES coil simulated above with PLR=0. Operating mode is known here, no need to simulate again to determine operating
13025 : // mode.
13026 6431 : if (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13027 6431 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly) { // cannot cool
13028 5 : PartLoadFrac = 0.0;
13029 : } else {
13030 : // Get full load result
13031 6426 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
13032 : }
13033 :
13034 : } else {
13035 : }
13036 :
13037 999732 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13038 999732 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
13039 999732 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
13040 1999464 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13041 999732 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13042 999732 : state.dataLoopNodes->Node(OutletNode).HumRat,
13043 999732 : state.dataLoopNodes->Node(InletNode).Temp,
13044 999732 : state.dataLoopNodes->Node(InletNode).HumRat);
13045 : }
13046 :
13047 : // IF ((FullOutput - ReqOutput) .GT. Acc) THEN ! old method
13048 : // IF ((Node(OutletNode)%Temp-DesOutTemp) .GT. Acc) THEN ! new method gets caught when temps are very close
13049 1036199 : if (this->m_sysType == SysType::CoilCoolingDX) {
13050 949071 : if ((FullOutput - ReqOutput) > tempAcc) {
13051 117856 : PartLoadFrac = 1.0;
13052 117856 : doIt = false;
13053 : } else {
13054 831215 : doIt = true;
13055 : }
13056 : }
13057 1036199 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13058 36467 : doIt = false;
13059 : }
13060 :
13061 1036199 : if (doIt) {
13062 881876 : if (unitSys && state.dataLoopNodes->Node(OutletNode).Temp > DesOutTemp - tempAcc) {
13063 18363 : PartLoadFrac = 1.0;
13064 18363 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13065 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13066 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13067 0 : PartLoadFrac = 0.0;
13068 : }
13069 863513 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13070 5389 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13071 5389 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13072 0 : PartLoadFrac = 0.0;
13073 863513 : } else if (!SensibleLoad) {
13074 0 : PartLoadFrac = 0.0;
13075 : } else {
13076 :
13077 863513 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13078 2274968 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadRatio) {
13079 2274968 : int CoilIndex = this->m_CoolingCoilIndex;
13080 2274968 : DXCoils::CalcDoe2DXCoil(state, CoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13081 2274968 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
13082 :
13083 2274968 : return DesOutTemp - OutletAirTemp;
13084 577982 : };
13085 577982 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13086 577982 : this->m_CompPartLoadRatio = PartLoadFrac;
13087 :
13088 285531 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) || (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) {
13089 :
13090 20351 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadFrac) {
13091 16855 : if (this->CoolCoilFluidInletNode > 0) {
13092 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = this->MaxCoolCoilFluidFlow * PartLoadFrac;
13093 : }
13094 33710 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(
13095 : state,
13096 16855 : this->m_CoolingCoilIndex,
13097 : FirstHVACIteration,
13098 : HVAC::CompressorOp::On,
13099 : PartLoadFrac,
13100 : HXUnitOn,
13101 : fanOp,
13102 : _,
13103 : _,
13104 16855 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13105 16855 : 0.0);
13106 16855 : return DesOutTemp - state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13107 3496 : };
13108 :
13109 3496 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13110 3496 : if (SolFla == -1) {
13111 :
13112 : // RegulaFalsi may not find sensible PLR when the latent degradation model is used.
13113 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13114 0 : TempMaxPLR = -0.1;
13115 0 : TempOutletTempDXCoil = state.dataLoopNodes->Node(InletNode).Temp;
13116 0 : while ((TempOutletTempDXCoil - DesOutTemp) > 0.0 && TempMaxPLR <= 1.0) {
13117 : // find upper limit of PLR
13118 0 : TempMaxPLR += 0.1;
13119 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13120 : CompName,
13121 : FirstHVACIteration,
13122 : HVAC::CompressorOp::On,
13123 : TempMaxPLR,
13124 0 : this->m_CoolingCoilIndex,
13125 : fanOp,
13126 : HXUnitOn,
13127 : _,
13128 0 : state.dataUnitarySystems->economizerFlag,
13129 : _,
13130 0 : this->m_DehumidificationMode,
13131 0 : 0.0); // this->CoilSHR);
13132 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13133 : }
13134 0 : TempMinPLR = TempMaxPLR;
13135 0 : while ((TempOutletTempDXCoil - DesOutTemp) < 0.0 && TempMinPLR >= 0.0) {
13136 : // pull upper limit of PLR DOwn to last valid limit (i.e. outlet temp still exceeds DesOutTemp)
13137 0 : TempMaxPLR = TempMinPLR;
13138 : // find minimum limit of PLR
13139 0 : TempMinPLR -= 0.01;
13140 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13141 : CompName,
13142 : FirstHVACIteration,
13143 : HVAC::CompressorOp::On,
13144 : TempMinPLR,
13145 0 : this->m_CoolingCoilIndex,
13146 : fanOp,
13147 : HXUnitOn,
13148 : _,
13149 0 : state.dataUnitarySystems->economizerFlag,
13150 : _,
13151 0 : this->m_DehumidificationMode,
13152 0 : 0.0); // this->CoilSHR);
13153 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13154 : }
13155 : // Relax boundary slightly to assure a solution can be found using RegulaFalsi (i.e. one boundary may
13156 : // be very near the desired result)
13157 0 : TempMinPLR = max(0.0, (TempMinPLR - 0.01));
13158 0 : TempMaxPLR = min(1.0, (TempMaxPLR + 0.01));
13159 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13160 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13161 0 : if (SolFla == -1) {
13162 0 : if (!state.dataGlobal->WarmupFlag) {
13163 0 : if (this->warnIndex.m_HXAssistedSensPLRIter < 1) {
13164 0 : ++this->warnIndex.m_HXAssistedSensPLRIter;
13165 0 : ShowWarningError(
13166 : state,
13167 0 : format("{} - Iteration limit exceeded calculating DX unit sensible part-load ratio for unit = {}",
13168 0 : this->UnitType,
13169 0 : this->Name));
13170 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13171 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13172 0 : ShowContinueErrorTimeStamp(
13173 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13174 : }
13175 0 : ShowRecurringWarningErrorAtEnd(state,
13176 0 : this->UnitType + " \"" + this->Name +
13177 : "\" - Iteration limit exceeded calculating sensible part-load ratio "
13178 : "error continues. Sensible PLR "
13179 : "statistics follow.",
13180 0 : this->warnIndex.m_HXAssistedSensPLRIterIndex,
13181 : PartLoadFrac,
13182 : PartLoadFrac);
13183 : }
13184 0 : } else if (SolFla == -2) {
13185 0 : PartLoadFrac = ReqOutput / FullOutput;
13186 0 : if (!state.dataGlobal->WarmupFlag) {
13187 0 : if (this->warnIndex.m_HXAssistedSensPLRFail < 1) {
13188 0 : ++this->warnIndex.m_HXAssistedSensPLRFail;
13189 0 : ShowWarningError(state,
13190 0 : format("{} - DX unit sensible part-load ratio calculation unexpectedly failed: "
13191 : "part-load ratio limits exceeded, for unit = {}",
13192 0 : this->UnitType,
13193 0 : this->Name));
13194 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13195 0 : ShowContinueErrorTimeStamp(
13196 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13197 : }
13198 0 : ShowRecurringWarningErrorAtEnd(state,
13199 0 : this->UnitType + " \"" + this->Name +
13200 : "\" - DX unit sensible part-load ratio calculation unexpectedly "
13201 : "failed error continues. Sensible PLR "
13202 : "statistics follow.",
13203 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex,
13204 : PartLoadFrac,
13205 : PartLoadFrac);
13206 : }
13207 : }
13208 3496 : } else if (SolFla == -2) {
13209 0 : PartLoadFrac = ReqOutput / FullOutput;
13210 0 : if (!state.dataGlobal->WarmupFlag) {
13211 0 : if (this->warnIndex.m_HXAssistedSensPLRFail2 < 1) {
13212 0 : ++this->warnIndex.m_HXAssistedSensPLRFail2;
13213 0 : ShowWarningError(state,
13214 0 : format("{} - DX unit sensible part-load ratio calculation failed: part-load ratio limits "
13215 : "exceeded, for unit = {}",
13216 0 : this->UnitType,
13217 0 : this->Name));
13218 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13219 0 : ShowContinueErrorTimeStamp(
13220 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13221 : }
13222 0 : ShowRecurringWarningErrorAtEnd(state,
13223 0 : this->UnitType + " \"" + this->Name +
13224 : "\" - DX unit sensible part-load ratio calculation failed error continues. "
13225 : "Sensible PLR statistics follow.",
13226 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex2,
13227 : PartLoadFrac,
13228 : PartLoadFrac);
13229 : }
13230 : }
13231 3496 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13232 3496 : this->m_CompPartLoadRatio = PartLoadFrac;
13233 : }
13234 :
13235 285531 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13236 237285 : this->m_CoolingSpeedRatio = SpeedRatio;
13237 237285 : if (SpeedRatio == 1.0) {
13238 1298319 : auto f = [&state, this, DesOutTemp](Real64 const SpeedRatio) {
13239 1298319 : int par1 = this->m_CoolingCoilIndex;
13240 1298319 : Real64 par2 = DesOutTemp;
13241 1298319 : int par3 = this->m_UnitarySysNum;
13242 : // 4-7 are not used for TwoSpeed coils, so these shouldn't matter at all
13243 1298319 : Real64 par4_CycRatio = 0.0;
13244 1298319 : int par5_SpeedNum = 0.0;
13245 1298319 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
13246 1298319 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13247 1298319 : return UnitarySys::DXCoilVarSpeedResidual(
13248 1298319 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13249 202441 : };
13250 202441 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13251 202441 : PartLoadFrac = SpeedRatio;
13252 : } else {
13253 129646 : auto f = [&state, this, DesOutTemp, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13254 : // several pars are not used in two speed coils, so these are just dummy values
13255 129646 : Real64 par4_SpeedRatio = 0.0;
13256 129646 : int par5_SpeedNum = 0.0;
13257 129646 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
13258 129646 : HVAC::CompressorOp par7_compressorOp = HVAC::CompressorOp::On;
13259 259292 : return UnitarySys::DXCoilCyclingResidual(state,
13260 : CycRatio,
13261 129646 : this->m_CoolingCoilIndex,
13262 : DesOutTemp,
13263 129646 : this->m_UnitarySysNum,
13264 : par4_SpeedRatio,
13265 : par5_SpeedNum,
13266 : par6_FanOpMode,
13267 : par7_compressorOp,
13268 : AirLoopNum,
13269 129646 : FirstHVACIteration);
13270 34844 : };
13271 34844 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13272 34844 : PartLoadFrac = CycRatio;
13273 : }
13274 :
13275 44750 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13276 :
13277 22 : if (this->m_CoolingSpeedNum > 1.0) {
13278 235 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
13279 235 : int par1 = this->m_CoolingCoilIndex;
13280 235 : Real64 par2 = DesOutTemp;
13281 235 : int par3 = this->m_UnitarySysNum;
13282 235 : Real64 par4_CycRatio = CycRatio;
13283 235 : int par5_SpeedNum = this->m_CoolingSpeedNum;
13284 235 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Cycling;
13285 235 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13286 235 : return UnitarySys::DXCoilVarSpeedResidual(
13287 235 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13288 1 : };
13289 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13290 1 : PartLoadFrac = SpeedRatio;
13291 : } else {
13292 21 : SpeedRatio = 0.0;
13293 21 : this->m_CoolingSpeedRatio = SpeedRatio;
13294 122 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13295 244 : return UnitarySys::DXCoilCyclingResidual(state,
13296 : CycRatio,
13297 122 : this->m_CoolingCoilIndex,
13298 : DesOutTemp,
13299 122 : this->m_UnitarySysNum,
13300 : SpeedRatio,
13301 122 : this->m_CoolingSpeedNum,
13302 : HVAC::FanOp::Cycling,
13303 : HVAC::CompressorOp::On,
13304 : AirLoopNum,
13305 122 : FirstHVACIteration);
13306 21 : };
13307 21 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13308 21 : PartLoadFrac = CycRatio;
13309 : }
13310 :
13311 44728 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13312 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13313 :
13314 11316 : CycRatio = 1.0;
13315 11316 : SpeedRatio = 1.0;
13316 :
13317 11316 : if (this->m_CoolingSpeedNum > 1.0) {
13318 8370 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
13319 8370 : int par1 = this->m_CoolingCoilIndex;
13320 8370 : Real64 par2 = DesOutTemp;
13321 8370 : int par3 = this->m_UnitarySysNum;
13322 8370 : Real64 par4_CycRatio = CycRatio;
13323 8370 : int par5_SpeedNum = this->m_CoolingSpeedNum;
13324 8370 : HVAC::FanOp par6_FanOpMode = this->m_FanOpMode;
13325 8370 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13326 8370 : return UnitarySys::DXCoilVarSpeedResidual(
13327 8370 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13328 1938 : };
13329 1938 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13330 1938 : this->m_CoolingCycRatio = CycRatio;
13331 1938 : this->m_CoolingSpeedRatio = SpeedRatio;
13332 1938 : this->m_CoolingPartLoadFrac = SpeedRatio;
13333 1938 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13334 1938 : PartLoadFrac = SpeedRatio;
13335 : } else {
13336 9378 : this->m_CoolingSpeedRatio = SpeedRatio;
13337 37415 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13338 74830 : return UnitarySys::DXCoilCyclingResidual(state,
13339 : CycRatio,
13340 37415 : this->m_CoolingCoilIndex,
13341 : DesOutTemp,
13342 37415 : this->m_UnitarySysNum,
13343 : SpeedRatio,
13344 37415 : this->m_CoolingSpeedNum,
13345 37415 : this->m_FanOpMode,
13346 : HVAC::CompressorOp::On,
13347 : AirLoopNum,
13348 37415 : FirstHVACIteration);
13349 9378 : };
13350 9378 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13351 9378 : SpeedRatio = 0.0;
13352 9378 : this->m_CoolingCycRatio = CycRatio;
13353 9378 : this->m_CoolingPartLoadFrac = CycRatio;
13354 9378 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13355 9378 : PartLoadFrac = CycRatio;
13356 : }
13357 :
13358 44728 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13359 14491 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13360 14491 : DXCoils::SimDXCoilMultiMode(
13361 14491 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13362 14491 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13363 3715 : };
13364 3715 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13365 3715 : this->m_CompPartLoadRatio = PartLoadFrac;
13366 29697 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13367 153185 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13368 153185 : bool const singleMode = this->m_SingleMode;
13369 153185 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13370 153185 : state, DehumidMode, this->m_CoolingSpeedNum, PartLoadRatio, fanOp, singleMode);
13371 : Real64 outletCondition =
13372 153185 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13373 153185 : return DesOutTemp - outletCondition;
13374 24290 : };
13375 :
13376 24290 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13377 24290 : if (this->m_CoolingSpeedNum == 1) {
13378 19105 : this->m_CompPartLoadRatio = PartLoadFrac;
13379 19105 : SpeedRatio = 0.0;
13380 : } else {
13381 5185 : SpeedRatio = PartLoadFrac;
13382 5185 : PartLoadFrac = 1.0;
13383 5185 : this->m_CompPartLoadRatio = 1.0;
13384 : }
13385 5407 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) {
13386 :
13387 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
13388 : maxPartLoadFrac =
13389 18 : min(1.0,
13390 18 : ((mdot / this->MaxCoolCoilFluidFlow) +
13391 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
13392 :
13393 72 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadRatio) {
13394 72 : Real64 mdot = min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13395 72 : this->MaxCoolCoilFluidFlow * PartLoadRatio);
13396 72 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
13397 144 : WaterCoils::SimulateWaterCoilComponents(
13398 72 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, _, _, PartLoadRatio);
13399 72 : return DesOutTemp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp;
13400 18 : };
13401 :
13402 18 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
13403 :
13404 5407 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13405 0 : this->m_CoolingCoilSensDemand = ReqOutput;
13406 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
13407 0 : return UnitarySys::coolWatertoAirHPTempResidual(
13408 0 : state, PartLoadRatio, this->m_UnitarySysNum, FirstHVACIteration, DesOutTemp, ReqOutput);
13409 0 : };
13410 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13411 5389 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13412 : // do nothing, user defined coil cannot be controlled
13413 :
13414 5389 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13415 21684 : auto f = [&state, this, DesOutTemp](Real64 const PartLoadRatio) {
13416 21684 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13417 43368 : PackagedThermalStorageCoil::SimTESCoil(state,
13418 : thisSys.m_CoolingCoilName,
13419 21684 : thisSys.m_CoolingCoilIndex,
13420 : thisSys.m_FanOpMode,
13421 21684 : thisSys.m_TESOpMode,
13422 : PartLoadRatio);
13423 21684 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp - DesOutTemp;
13424 5389 : };
13425 5389 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13426 : } else {
13427 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
13428 0 : ShowFatalError(state,
13429 0 : format("ControlCoolingSystemToSP: Invalid cooling coil type = {}", HVAC::cAllCoilTypes(CoilType_Num)));
13430 : }
13431 : }
13432 : }
13433 : }
13434 :
13435 : // IF system does not operate to meet sensible load, use no load humidity ratio to test against humidity setpoint,
13436 : // ELSE use operating humidity ratio to test against humidity setpoint
13437 2224607 : if (PartLoadFrac == 0.0) {
13438 1188407 : OutletHumRatDXCoil = NoLoadHumRatOut;
13439 : } else {
13440 1036200 : OutletHumRatDXCoil = state.dataLoopNodes->Node(OutletNode).HumRat;
13441 : }
13442 :
13443 : // IF humidity setpoint is not satisfied and humidity control type is MultiMode,
13444 : // then enable heat exchanger and run to meet sensible load
13445 :
13446 2224607 : if ((OutletHumRatDXCoil > (DesOutHumRat + tempHumRatAcc)) && (!unitSys || PartLoadFrac < 1.0) &&
13447 24876 : (this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
13448 :
13449 7528 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13450 : // pass
13451 7528 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
13452 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted,
13453 : // CoilSystem:Cooling:Water:HeatExchangerAssisted
13454 : // Determine required part load when heat exchanger is ON
13455 0 : HXUnitOn = true;
13456 0 : PartLoadFrac = 1.0;
13457 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13458 : CompName,
13459 : FirstHVACIteration,
13460 : HVAC::CompressorOp::On,
13461 : PartLoadFrac,
13462 0 : this->m_CoolingCoilIndex,
13463 : fanOp,
13464 : HXUnitOn,
13465 : _,
13466 0 : state.dataUnitarySystems->economizerFlag,
13467 : _,
13468 0 : this->m_DehumidificationMode,
13469 0 : 0.0); // this->CoilSHR);
13470 :
13471 0 : OutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13472 :
13473 : // FullOutput will be different than the FullOutput determined above during sensible PLR calculations
13474 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13475 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13476 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13477 0 : state.dataLoopNodes->Node(InletNode).Temp,
13478 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13479 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13480 :
13481 : // Check to see if the system can meet the load with the compressor off
13482 : // If NoOutput is lower than (more cooling than required) or very near the ReqOutput, do not run the compressor
13483 0 : if ((NoLoadTempOut - DesOutTemp) < Acc) {
13484 0 : PartLoadFrac = 0.0;
13485 : // OutletTempDXCoil is the full capacity outlet temperature at PartLoadFrac = 1 from the CALL above.
13486 : // if this temp is greater than or very near the desired outlet temp, then run the compressor at PartLoadFrac
13487 : // = 1.
13488 : // ELSEIF ((OutletTempDXCoil > DesOutTemp) .OR. ABS(OutletTempDXCoil - DesOutTemp) .LE. (Acc*2.0d0)) THEN
13489 0 : } else if (OutletTempDXCoil > DesOutTemp - (tempAcc * 2.0)) {
13490 0 : PartLoadFrac = 1.0;
13491 : } else {
13492 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadRatio) {
13493 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13494 :
13495 0 : if (thisSys.CoolCoilFluidInletNode > 0) {
13496 0 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = thisSys.MaxCoolCoilFluidFlow * PartLoadRatio;
13497 : }
13498 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13499 0 : this->m_CoolingCoilIndex,
13500 : FirstHVACIteration,
13501 : HVAC::CompressorOp::On,
13502 : PartLoadRatio,
13503 : HXUnitOn,
13504 : fanOp,
13505 : _,
13506 : _,
13507 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13508 0 : 0.0);
13509 0 : Real64 OutletAirTemp = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13510 0 : return DesOutTemp - OutletAirTemp;
13511 0 : };
13512 :
13513 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13514 : }
13515 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13516 :
13517 7528 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13518 :
13519 : // Get full load result
13520 7528 : PartLoadFrac = 1.0;
13521 7528 : DehumidMode = HVAC::CoilMode::Enhanced;
13522 7528 : this->m_DehumidificationMode = DehumidMode;
13523 7528 : DXCoils::SimDXCoilMultiMode(
13524 7528 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13525 7528 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13526 7528 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13527 7528 : state.dataLoopNodes->Node(OutletNode).HumRat,
13528 7528 : state.dataLoopNodes->Node(InletNode).Temp,
13529 7528 : state.dataLoopNodes->Node(InletNode).HumRat);
13530 7528 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13531 :
13532 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
13533 : // Check that this is the case; IF not set PartLoadFrac = 0.0 (off) and return
13534 : // Calculate the part load fraction
13535 7528 : if (FullOutput >= 0) {
13536 0 : PartLoadFrac = 0.0;
13537 : } else {
13538 7528 : OutletTempDXCoil = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13539 7528 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13540 : // If sensible load and setpoint cannot be met, set PLR = 1. if no sensible load and
13541 : // latent load exists and setpoint cannot be met, set PLR = 1.
13542 7528 : if ((OutletTempDXCoil > (DesOutTemp - (tempAcc * 2.0)) && SensibleLoad && this->m_RunOnSensibleLoad) ||
13543 589 : (OutletHumRatDXCoil >= (DesOutHumRat - (tempHumRatAcc * 2.0)) && !SensibleLoad && LatentLoad &&
13544 0 : this->m_RunOnLatentLoad)) {
13545 6939 : PartLoadFrac = 1.0;
13546 : // ELSEIF ((SensibleLoad .and. LatentLoad .AND. .NOT. UnitarySystem(UnitarySysNum)%RunOnLatentLoad
13547 : // .AND. &
13548 : // OutletHumRatDXCoil < DesOutHumRat)) THEN
13549 589 : } else if (!SensibleLoad && (OutletHumRatDXCoil < DesOutHumRat && LatentLoad && this->m_RunOnLatentLoad)) {
13550 0 : PartLoadFrac = ReqOutput / FullOutput;
13551 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13552 0 : DXCoils::SimDXCoilMultiMode(
13553 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13554 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13555 0 : };
13556 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13557 0 : } else { // must be a sensible load so find PLR
13558 589 : PartLoadFrac = ReqOutput / FullOutput;
13559 2310 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13560 2310 : DXCoils::SimDXCoilMultiMode(
13561 2310 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13562 2310 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13563 589 : };
13564 589 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13565 : }
13566 : }
13567 7528 : this->m_CompPartLoadRatio = PartLoadFrac;
13568 :
13569 0 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13570 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Enhanced;
13571 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
13572 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
13573 : }
13574 0 : if (this->m_CoolingSpeedNum == 0) {
13575 0 : this->m_CoolingSpeedNum = 1;
13576 : }
13577 0 : bool const singleMode = (this->m_SingleMode == 1);
13578 0 : PartLoadFrac = 1.0;
13579 0 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13580 0 : this->m_CoolingSpeedNum = speedNum;
13581 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13582 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13583 : // Cooling: break if outlet temp is lower than DesOutTemp or approaches DesOutTemp to within Acc from above
13584 0 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) {
13585 0 : break;
13586 : }
13587 : }
13588 :
13589 : // make sure outlet temp is below set point before calling SolveRoot
13590 : // Cooling: iterate only when outlet temp is below DesOutTemp by at least Acc
13591 0 : if ((DesOutTemp - state.dataLoopNodes->Node(OutletNode).Temp) > Acc) {
13592 :
13593 0 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadFrac) {
13594 0 : bool const singleMode = false;
13595 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13596 0 : state, HVAC::CoilMode::Enhanced, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13597 : Real64 outletCondition =
13598 0 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13599 :
13600 0 : return DesOutTemp - outletCondition;
13601 0 : };
13602 :
13603 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13604 : }
13605 0 : if (this->m_CoolingSpeedNum == 1) {
13606 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13607 0 : SpeedRatio = 0.0;
13608 : } else {
13609 0 : SpeedRatio = PartLoadFrac;
13610 0 : PartLoadFrac = 1.0;
13611 0 : this->m_CompPartLoadRatio = 1.0;
13612 : }
13613 :
13614 : } else {
13615 : }
13616 : } // END IF humidity ratio setpoint not met - Multimode humidity control
13617 :
13618 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13619 : // then overcool to meet moisture load
13620 2224607 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13621 : // pass
13622 2184678 : } else if ((OutletHumRatDXCoil > DesOutHumRat) && (!unitSys || PartLoadFrac < 1.0) && LatentLoad &&
13623 24533 : (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat)) {
13624 :
13625 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13626 : // do not run the compressor
13627 17348 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc) {
13628 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13629 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the DesOutHumRat,
13630 : // run the compressor at PartLoadFrac = 1.
13631 : // ELSEIF ((DesOutHumRat-FullLoadHumRatOut) .LT. HumRatAcc) THEN
13632 17348 : } else if (FullLoadHumRatOut > (DesOutHumRat - tempHumRatAcc)) {
13633 13054 : PartLoadFrac = 1.0;
13634 13054 : SpeedRatio = 1.0; // #8849, need to set properties of multi-speed/2-speed coils
13635 13054 : if (this->m_IsDXCoil) {
13636 13054 : this->m_CompPartLoadRatio = PartLoadFrac;
13637 : }
13638 : // ELSE find the PLR to meet the load
13639 :
13640 : } else {
13641 :
13642 4294 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13643 5232 : auto f = [&state, this, DesOutHumRat, fanOp](Real64 const PartLoadRatio) {
13644 5232 : DXCoils::CalcDoe2DXCoil(state, this->m_CoolingCoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13645 5232 : Real64 OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13646 5232 : return DesOutHumRat - OutletAirHumRat;
13647 546 : };
13648 546 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13649 546 : this->m_CompPartLoadRatio = PartLoadFrac;
13650 3748 : } else if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13651 :
13652 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13653 : // do not run the compressor
13654 918 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc * 2.0) {
13655 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13656 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the
13657 : // DesOutHumRat, run the compressor at PartLoadFrac = 1.
13658 918 : } else if ((DesOutHumRat - FullLoadHumRatOut) < tempHumRatAcc * 2.0) {
13659 6 : PartLoadFrac = 1.0;
13660 : // ELSE find the PLR to meet the load
13661 : } else {
13662 4955 : auto f = [&state, this, FirstHVACIteration, HXUnitOn, fanOp, DesOutHumRat](Real64 const PartLoadRatio) {
13663 8086 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13664 4043 : this->m_CoolingCoilIndex,
13665 : FirstHVACIteration,
13666 : HVAC::CompressorOp::On,
13667 : PartLoadRatio,
13668 : HXUnitOn,
13669 : fanOp,
13670 : _,
13671 4043 : state.dataUnitarySystems->economizerFlag,
13672 8086 : HVAC::CoilMode::Normal,
13673 4043 : 0.0);
13674 4043 : return DesOutHumRat - state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13675 912 : };
13676 912 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13677 912 : if (SolFla == -1) {
13678 :
13679 : // RegulaFalsi may not find latent PLR when the latent degradation model is used.
13680 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13681 0 : TempMaxPLR = -0.1;
13682 0 : while ((OutletHumRatDXCoil - DesOutHumRat) >= 0.0 && TempMaxPLR <= 1.0) {
13683 : // find upper limit of LatentPLR
13684 0 : TempMaxPLR += 0.1;
13685 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13686 : CompName,
13687 : FirstHVACIteration,
13688 : HVAC::CompressorOp::On,
13689 : TempMaxPLR,
13690 0 : this->m_CoolingCoilIndex,
13691 : fanOp,
13692 : HXUnitOn,
13693 : _,
13694 0 : state.dataUnitarySystems->economizerFlag,
13695 : _,
13696 0 : this->m_DehumidificationMode,
13697 0 : 0.0); // this->CoilSHR);
13698 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13699 : }
13700 0 : TempMaxPLR = min(1.0, TempMaxPLR + 0.1);
13701 0 : TempMinPLR = TempMaxPLR;
13702 0 : while ((OutletHumRatDXCoil - DesOutHumRat) <= 0.0 && TempMinPLR >= 0.0) {
13703 : // pull upper limit of LatentPLR DOwn to last valid limit (i.e. latent output still
13704 : // exceeds SystemMoisuterLoad)
13705 : // find minimum limit of Latent PLR
13706 0 : TempMinPLR -= 0.02;
13707 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13708 : CompName,
13709 : FirstHVACIteration,
13710 : HVAC::CompressorOp::On,
13711 : TempMinPLR,
13712 0 : this->m_CoolingCoilIndex,
13713 : fanOp,
13714 : HXUnitOn,
13715 : _,
13716 0 : state.dataUnitarySystems->economizerFlag,
13717 : _,
13718 0 : this->m_DehumidificationMode,
13719 0 : 0.0); // this->CoilSHR);
13720 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13721 : }
13722 0 : TempMinPLR = max(0.0, TempMinPLR - 0.1);
13723 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13724 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13725 0 : if (SolFla == -1) {
13726 0 : if (!state.dataGlobal->WarmupFlag) {
13727 0 : if (this->warnIndex.m_HXAssistedCRLatPLRIter < 1) {
13728 0 : ++this->warnIndex.m_HXAssistedCRLatPLRIter;
13729 0 : ShowWarningError(
13730 : state,
13731 0 : format("{} - Iteration limit exceeded calculating DX unit latent part-load ratio for unit = {}",
13732 0 : this->UnitType,
13733 0 : this->Name));
13734 0 : ShowContinueError(state, format("Estimated latent part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13735 0 : ShowContinueError(state, format("Calculated latent part-load ratio = {:.3R}", PartLoadFrac));
13736 0 : ShowContinueErrorTimeStamp(state,
13737 : "The calculated latent part-load ratio will be used and the simulation "
13738 : "continues. Occurrence info:");
13739 : }
13740 0 : ShowRecurringWarningErrorAtEnd(state,
13741 0 : this->UnitType + " \"" + this->Name +
13742 : "\" - Iteration limit exceeded calculating latent part-load ratio "
13743 : "error continues. Latent PLR "
13744 : "statistics follow.",
13745 0 : this->warnIndex.m_HXAssistedCRLatPLRIterIndex,
13746 : PartLoadFrac,
13747 : PartLoadFrac);
13748 : }
13749 :
13750 0 : } else if (SolFla == -2) {
13751 :
13752 0 : PartLoadFrac = ReqOutput / FullOutput;
13753 0 : if (!state.dataGlobal->WarmupFlag) {
13754 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail < 1) {
13755 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail;
13756 0 : ShowWarningError(state,
13757 0 : format("{} - DX unit latent part-load ratio calculation failed unexpectedly: part-load "
13758 : "ratio limits exceeded, for unit = {}",
13759 0 : this->UnitType,
13760 0 : this->Name));
13761 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13762 0 : ShowContinueErrorTimeStamp(
13763 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13764 : }
13765 0 : ShowRecurringWarningErrorAtEnd(state,
13766 0 : this->UnitType + " \"" + this->Name +
13767 : "\" - DX unit latent part-load ratio calculation failed "
13768 : "unexpectedly error continues. Latent PLR "
13769 : "statistics follow.",
13770 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex,
13771 : PartLoadFrac,
13772 : PartLoadFrac);
13773 : }
13774 : }
13775 912 : } else if (SolFla == -2) {
13776 0 : PartLoadFrac = ReqOutput / FullOutput;
13777 0 : if (!state.dataGlobal->WarmupFlag) {
13778 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail2 < 1) {
13779 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail2;
13780 0 : ShowWarningError(state,
13781 0 : format("{} - DX unit latent part-load ratio calculation failed: part-load ratio limits "
13782 : "exceeded, for unit = {}",
13783 0 : this->UnitType,
13784 0 : this->Name));
13785 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13786 0 : ShowContinueErrorTimeStamp(
13787 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13788 : }
13789 0 : ShowRecurringWarningErrorAtEnd(
13790 : state,
13791 0 : this->UnitType + " \"" + this->Name +
13792 : "\" - DX unit latent part-load ratio calculation failed error continues. Latent PLR statistics "
13793 : "follow.",
13794 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex2,
13795 : PartLoadFrac,
13796 : PartLoadFrac);
13797 : }
13798 : }
13799 : }
13800 918 : this->m_CompPartLoadRatio = PartLoadFrac;
13801 :
13802 2830 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13803 :
13804 : // Simulate MultiSpeed DX coil at sensible result
13805 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13806 :
13807 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13808 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13809 : // then overcool to meet moisture load
13810 :
13811 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13812 :
13813 0 : CycRatio = 0.0;
13814 0 : SpeedRatio = 0.0;
13815 :
13816 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13817 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13818 0 : if (OutletHumRatLS > DesOutHumRat) {
13819 0 : CycRatio = 1.0;
13820 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13821 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13822 0 : if (OutletHumRatHS < DesOutHumRat) {
13823 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13824 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13825 : SpeedRatio,
13826 0 : this->m_CoolingCoilIndex,
13827 : DesOutHumRat,
13828 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13829 : 0.0, // Real64 CycRatio,
13830 : 0, // int SpeedNum,
13831 : HVAC::FanOp::Invalid, // int FanOpMode,
13832 0 : HVAC::CompressorOp::On);
13833 0 : };
13834 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13835 : } else {
13836 0 : SpeedRatio = 1.0;
13837 : }
13838 0 : PartLoadFrac = SpeedRatio;
13839 : } else {
13840 0 : SpeedRatio = 0.0;
13841 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13842 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13843 : state,
13844 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13845 0 : this->m_CoolingCoilIndex,
13846 : DesOutHumRat,
13847 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13848 : 1.0, // Real64 CycRatio,
13849 0 : this->m_CoolingSpeedNum,
13850 0 : this->m_FanOpMode, // int FanOpMode,
13851 0 : HVAC::CompressorOp::On);
13852 0 : };
13853 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13854 0 : PartLoadFrac = CycRatio;
13855 : }
13856 : }
13857 :
13858 2830 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13859 :
13860 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13861 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13862 :
13863 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13864 : // then overcool to meet moisture load
13865 :
13866 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13867 :
13868 0 : CycRatio = 0.0;
13869 0 : SpeedRatio = 0.0;
13870 :
13871 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13872 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13873 0 : if (OutletHumRatLS > DesOutHumRat) {
13874 0 : CycRatio = 1.0;
13875 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13876 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13877 0 : if (OutletHumRatHS < DesOutHumRat) {
13878 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13879 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13880 : SpeedRatio,
13881 0 : this->m_CoolingCoilIndex,
13882 : DesOutHumRat,
13883 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13884 : 0.0, // Real64 CycRatio,
13885 : 0, // int SpeedNum,
13886 : HVAC::FanOp::Invalid, // int FanOpMode,
13887 0 : HVAC::CompressorOp::On);
13888 0 : };
13889 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13890 : } else {
13891 0 : SpeedRatio = 1.0;
13892 : }
13893 : } else {
13894 0 : SpeedRatio = 0.0;
13895 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13896 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13897 : state,
13898 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13899 0 : this->m_CoolingCoilIndex,
13900 : DesOutHumRat,
13901 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13902 : 0.0, // Real64 CycRatio,
13903 : 0,
13904 : HVAC::FanOp::Invalid, // int FanOpMode,
13905 0 : HVAC::CompressorOp::On);
13906 0 : };
13907 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13908 : }
13909 : }
13910 2830 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13911 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13912 968 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13913 : CompName,
13914 968 : this->m_CoolingCoilIndex,
13915 : this->m_FanOpMode,
13916 : HVAC::CompressorOp::On,
13917 : CycRatio,
13918 : this->m_CoolingSpeedNum,
13919 : SpeedRatio,
13920 : ReqOutput,
13921 : dummy,
13922 : OnOffAirFlowRatio);
13923 968 : OutletHumRatLS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13924 :
13925 968 : if (OutletHumRatLS > DesOutHumRat) {
13926 968 : CycRatio = 1.0;
13927 :
13928 968 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; ++speedNum) {
13929 968 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13930 : CompName,
13931 968 : this->m_CoolingCoilIndex,
13932 : this->m_FanOpMode,
13933 : HVAC::CompressorOp::On,
13934 : 1.0,
13935 : speedNum,
13936 : 1.0,
13937 : ReqOutput,
13938 : dummy,
13939 : OnOffAirFlowRatio);
13940 968 : OutletHumRatHS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13941 968 : if (OutletHumRatHS < DesOutHumRat || speedNum == this->m_NumOfSpeedCooling) {
13942 968 : this->m_CoolingSpeedNum = speedNum;
13943 968 : break;
13944 : }
13945 : }
13946 :
13947 968 : if (OutletHumRatHS < DesOutHumRat) {
13948 968 : if (this->m_CoolingSpeedNum == 1) {
13949 2904 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13950 5808 : return UnitarySys::DXCoilCyclingHumRatResidual(
13951 : state,
13952 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13953 2904 : this->m_CoolingCoilIndex,
13954 : DesOutHumRat,
13955 2904 : this->m_UnitarySysNum, // int UnitarySysNum,
13956 : 1.0, // Real64 CycRatio,
13957 2904 : this->m_CoolingSpeedNum,
13958 2904 : this->m_FanOpMode, // int FanOpMode,
13959 2904 : HVAC::CompressorOp::On);
13960 968 : };
13961 968 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13962 : } else {
13963 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13964 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13965 : SpeedRatio,
13966 0 : this->m_CoolingCoilIndex,
13967 : DesOutHumRat,
13968 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13969 : 1.0, // Real64 CycRatio,
13970 0 : this->m_CoolingSpeedNum,
13971 0 : this->m_FanOpMode, // int FanOpMode,
13972 0 : HVAC::CompressorOp::On);
13973 0 : };
13974 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13975 : }
13976 : } else {
13977 0 : if (this->m_CoolingSpeedNum == 1) {
13978 0 : CycRatio = 1.0;
13979 : } else {
13980 0 : SpeedRatio = 1.0;
13981 : }
13982 : }
13983 : } else {
13984 0 : SpeedRatio = 0.0;
13985 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13986 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13987 : SpeedRatio,
13988 0 : this->m_CoolingCoilIndex,
13989 : DesOutHumRat,
13990 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13991 : 0.0, // Real64 CycRatio,
13992 : 0, // int SpeedNum
13993 : HVAC::FanOp::Invalid, // int FanOpMode,
13994 0 : HVAC::CompressorOp::On);
13995 0 : };
13996 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13997 : }
13998 2830 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13999 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
14000 0 : DXCoils::SimDXCoilMultiMode(
14001 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
14002 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
14003 0 : };
14004 0 : General::SolveRoot(state, Acc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14005 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14006 1862 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
14007 1858 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
14008 1858 : if (this->m_CoolingSpeedNum == 0) {
14009 0 : this->m_CoolingSpeedNum = 1;
14010 : }
14011 1858 : bool const singleMode = (this->m_SingleMode == 1);
14012 1858 : PartLoadFrac = 1.0;
14013 1858 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
14014 1858 : this->m_CoolingSpeedNum = speedNum;
14015 1858 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14016 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
14017 : // Cooling: break if outlet humrat is lower than DesOutHumRat or approaches DesOutHumRat to within HumRatAcc from above
14018 1858 : if ((state.dataLoopNodes->Node(OutletNode).HumRat - DesOutHumRat) < HumRatAcc) {
14019 1858 : break;
14020 : }
14021 : }
14022 : // make sure outlet HumRat is below set point before calling SolveRoot
14023 : // Cooling: iterate only when outlet humrat is below DesOutHumRat by at least HumRatAcc
14024 1858 : if ((DesOutHumRat - state.dataLoopNodes->Node(OutletNode).HumRat) > HumRatAcc) {
14025 :
14026 8853 : auto f = [&state,
14027 : this, // 0
14028 : DesOutHumRat, // 1
14029 : fanOp // 3
14030 : ](Real64 const PartLoadFrac) {
14031 8853 : bool const singleMode = false;
14032 8853 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14033 8853 : state, HVAC::CoilMode::Normal, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
14034 : Real64 outletCondition =
14035 8853 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex)
14036 8853 : .HumRat;
14037 8853 : return DesOutHumRat - outletCondition;
14038 1858 : };
14039 :
14040 1858 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14041 : }
14042 1858 : if (this->m_CoolingSpeedNum == 1) {
14043 1858 : this->m_CompPartLoadRatio = PartLoadFrac;
14044 1858 : SpeedRatio = 0.0;
14045 : } else {
14046 0 : SpeedRatio = PartLoadFrac;
14047 0 : PartLoadFrac = 1.0;
14048 0 : this->m_CompPartLoadRatio = 1.0;
14049 : }
14050 :
14051 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
14052 :
14053 32 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat](Real64 const PartLoadRatio) {
14054 32 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14055 32 : Real64 mdot = min(state.dataLoopNodes->Node(thisSys.CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14056 32 : thisSys.MaxCoolCoilFluidFlow * PartLoadRatio);
14057 32 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = mdot;
14058 64 : WaterCoils::SimulateWaterCoilComponents(
14059 32 : state, thisSys.m_CoolingCoilName, FirstHVACIteration, thisSys.m_CoolingCoilIndex, _, _, PartLoadRatio);
14060 32 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
14061 4 : };
14062 :
14063 4 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14064 :
14065 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
14066 :
14067 0 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat, ReqOutput](Real64 const PartLoadRatio) {
14068 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14069 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
14070 0 : Real64 dummy = 0.0;
14071 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
14072 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14073 : blankString,
14074 0 : thisSys.m_CoolingCoilIndex,
14075 : ReqOutput,
14076 : dummy,
14077 : thisSys.m_FanOpMode,
14078 : HVAC::CompressorOp::Off,
14079 : PartLoadRatio,
14080 : FirstHVACIteration);
14081 : } else {
14082 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14083 : blankString,
14084 0 : thisSys.m_CoolingCoilIndex,
14085 : thisSys.MaxCoolAirMassFlow,
14086 : thisSys.m_FanOpMode,
14087 : FirstHVACIteration,
14088 0 : thisSys.m_InitHeatPump,
14089 : ReqOutput,
14090 : dummy,
14091 : HVAC::CompressorOp::Off,
14092 : PartLoadRatio);
14093 : }
14094 0 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
14095 0 : };
14096 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14097 :
14098 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
14099 :
14100 0 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
14101 0 : (this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::Off &&
14102 0 : this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
14103 0 : auto f = [&state, this, DesOutHumRat](Real64 const PartLoadRatio) {
14104 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14105 0 : PackagedThermalStorageCoil::SimTESCoil(state,
14106 : thisSys.m_CoolingCoilName,
14107 0 : thisSys.m_CoolingCoilIndex,
14108 : thisSys.m_FanOpMode,
14109 0 : thisSys.m_TESOpMode,
14110 : PartLoadRatio);
14111 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat - DesOutHumRat;
14112 0 : };
14113 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14114 : }
14115 :
14116 : } else {
14117 : }
14118 : }
14119 : }
14120 : }
14121 2985736 : if (SolFla == -1) {
14122 4553 : if (!state.dataGlobal->WarmupFlag) {
14123 412 : if (this->warnIndex.m_SensPLRIter < 1) {
14124 1 : ++this->warnIndex.m_SensPLRIter;
14125 2 : ShowWarningError(state,
14126 2 : format("{} - Iteration limit exceeded calculating part-load ratio for unit = {}", this->UnitType, this->Name));
14127 1 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14128 1 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14129 3 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14130 : } else {
14131 3288 : ShowRecurringWarningErrorAtEnd(
14132 : state,
14133 822 : this->UnitType + " \"" + this->Name +
14134 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. Sensible PLR statistics follow.",
14135 411 : this->warnIndex.m_SensPLRIterIndex,
14136 : PartLoadFrac,
14137 : PartLoadFrac);
14138 : }
14139 : }
14140 2981183 : } else if (SolFla == -2) {
14141 0 : PartLoadFrac = ReqOutput / FullOutput;
14142 0 : if (!state.dataGlobal->WarmupFlag) {
14143 0 : if (this->warnIndex.m_SensPLRFail < 1) {
14144 0 : ++this->warnIndex.m_SensPLRFail;
14145 0 : ShowWarningError(state,
14146 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14147 0 : this->UnitType,
14148 0 : this->Name));
14149 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14150 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14151 : } else {
14152 0 : ShowRecurringWarningErrorAtEnd(
14153 : state,
14154 0 : this->UnitType + " \"" + this->Name +
14155 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14156 0 : this->warnIndex.m_SensPLRFailIndex,
14157 : PartLoadFrac,
14158 : PartLoadFrac);
14159 : }
14160 : }
14161 : }
14162 :
14163 2985736 : if (SolFlaLat == -1 && SolFla != -1) {
14164 0 : if (!state.dataGlobal->WarmupFlag) {
14165 0 : if (this->warnIndex.m_LatPLRIter < 1) {
14166 0 : ++this->warnIndex.m_LatPLRIter;
14167 0 : ShowWarningError(
14168 0 : state, format("{} - Iteration limit exceeded calculating latent part-load ratio for unit = {}", this->UnitType, this->Name));
14169 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14170 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14171 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14172 : }
14173 0 : ShowRecurringWarningErrorAtEnd(
14174 : state,
14175 0 : this->UnitType + " \"" + this->Name +
14176 : "\" - Iteration limit exceeded calculating latent part-load ratio error continues. Latent PLR statistics follow.",
14177 0 : this->warnIndex.m_LatPLRIterIndex,
14178 : PartLoadFrac,
14179 : PartLoadFrac);
14180 : }
14181 2985736 : } else if (SolFlaLat == -2 && SolFla != -2) {
14182 : // RegulaFalsi returns PLR = minPLR when a solution cannot be found, recalculate PartLoadFrac.
14183 0 : if (NoLoadHumRatOut - FullLoadHumRatOut != 0.0) {
14184 0 : PartLoadFrac = (NoLoadHumRatOut - DesOutHumRat) / (NoLoadHumRatOut - FullLoadHumRatOut);
14185 : } else {
14186 0 : PartLoadFrac = 1.0;
14187 : }
14188 0 : if (!state.dataGlobal->WarmupFlag) {
14189 0 : if (this->warnIndex.m_LatPLRFail < 1) {
14190 0 : ++this->warnIndex.m_LatPLRFail;
14191 0 : ShowWarningError(state,
14192 0 : format("{} - latent part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14193 0 : this->UnitType,
14194 0 : this->Name));
14195 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14196 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14197 : }
14198 0 : ShowRecurringWarningErrorAtEnd(state,
14199 0 : this->UnitType + " \"" + this->Name +
14200 : "\" - latent part-load ratio calculation failed error continues. Latent PLR statistics follow.",
14201 0 : this->warnIndex.m_LatPLRFailIndex,
14202 : PartLoadFrac,
14203 : PartLoadFrac);
14204 : }
14205 : }
14206 : // Set the final results
14207 :
14208 2985736 : if (PartLoadFrac > 1.0) {
14209 0 : PartLoadFrac = 1.0;
14210 2985736 : } else if (PartLoadFrac < 0.0) {
14211 0 : PartLoadFrac = 0.0;
14212 : }
14213 :
14214 2985736 : this->m_CoolingPartLoadFrac = PartLoadFrac;
14215 2985736 : this->m_CoolingSpeedRatio = SpeedRatio;
14216 2985736 : this->m_CoolingCycRatio = CycRatio;
14217 2985736 : this->m_DehumidificationMode = DehumidMode;
14218 :
14219 3110232 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14220 124496 : this->m_sysType != SysType::PackagedWSHP) {
14221 124496 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14222 124496 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14223 : }
14224 :
14225 2985736 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
14226 76032 : mdot = PartLoadFrac * this->MaxCoolCoilFluidFlow;
14227 76032 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
14228 : }
14229 2985736 : } // namespace UnitarySystems
14230 :
14231 102811 : void UnitarySys::controlHeatingSystemToSP(EnergyPlusData &state,
14232 : int const AirLoopNum, // index to air loop
14233 : bool const FirstHVACIteration, // First HVAC iteration flag
14234 : HVAC::CompressorOp &compressorOp, // compressor on/off control
14235 : Real64 &HeatCoilLoad // load met by heating coil
14236 : )
14237 : {
14238 : // SUBROUTINE INFORMATION:
14239 : // AUTHOR Richard Raustad, FSEC
14240 : // DATE WRITTEN February 2013
14241 :
14242 : // PURPOSE OF THIS SUBROUTINE:
14243 : // Simulate the coil object at the required PLR.
14244 :
14245 : // METHODOLOGY EMPLOYED:
14246 : // Calculate operating PLR and adjust speed when using multispeed coils.
14247 :
14248 : // SUBROUTINE PARAMETER DEFINITIONS:
14249 102811 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14250 102811 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14251 102811 : bool constexpr SuppHeatingCoilFlag(false);
14252 :
14253 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14254 102811 : Real64 FullOutput = 0; // Sensible capacity (outlet - inlet) when the compressor is on
14255 102811 : Real64 ReqOutput = 0; // Sensible capacity (outlet - inlet) required to meet load or set point temperature
14256 :
14257 102811 : Real64 OutdoorDryBulb = 0.0; // local variable for OutDryBulbTemp
14258 102811 : Real64 OutdoorHumRat = 0.0; // local variable for OutHumRat
14259 102811 : Real64 OutdoorPressure = 0.0; // local variable for OutBaroPress
14260 102811 : Real64 OutdoorWetBulb = 0.0; // local variable for OutWetBulbTemp
14261 102811 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14262 102811 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14263 :
14264 : // Set local variables
14265 : // Retrieve the load on the controlled zone
14266 102811 : int InletNode = this->HeatCoilInletNodeNum;
14267 102811 : int OutletNode = this->HeatCoilOutletNodeNum;
14268 102811 : std::string CompName = this->m_HeatingCoilName;
14269 102811 : int CompIndex = this->m_HeatingCoilIndex;
14270 102811 : HVAC::FanOp fanOp = this->m_FanOpMode;
14271 102811 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14272 :
14273 102811 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14274 102811 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14275 102811 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14276 0 : this->m_sysType != SysType::PackagedWSHP) {
14277 0 : LoopHeatingCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF;
14278 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
14279 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
14280 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
14281 : }
14282 :
14283 102811 : Real64 PartLoadFrac = 0.0;
14284 102811 : Real64 SpeedRatio = 0.0;
14285 102811 : Real64 CycRatio = 0.0;
14286 102811 : Real64 dummy = 0.0;
14287 102811 : int SolFla = 0;
14288 102811 : Real64 SensLoad = 0.0;
14289 102811 : Real64 OutletTemp = 0.0;
14290 :
14291 102811 : if (this->m_CondenserNodeNum != 0) {
14292 68625 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
14293 68625 : if (this->m_CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
14294 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14295 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14296 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14297 : } else {
14298 68625 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
14299 : // IF node is not connected to anything, pressure = default, use weather data
14300 68625 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
14301 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14302 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14303 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14304 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14305 : } else {
14306 68625 : OutdoorHumRat = state.dataLoopNodes->Node(this->m_CondenserNodeNum).HumRat;
14307 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
14308 68625 : OutdoorWetBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).OutAirWetBulb;
14309 : }
14310 : }
14311 : } else {
14312 34186 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14313 34186 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14314 34186 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14315 34186 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14316 : }
14317 :
14318 : // IF there is a fault of coil SAT Sensor
14319 102811 : if (this->m_FaultyCoilSATFlag) {
14320 : // calculate the sensor offset using fault information
14321 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14322 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14323 : // update the DesOutTemp
14324 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14325 : }
14326 :
14327 : // IF DXHeatingSystem is scheduled on and there is flow
14328 205598 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && this->m_heatingCoilAvailSched->getCurrentVal() > 0.0 &&
14329 102787 : state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow) {
14330 :
14331 102787 : bool SensibleLoad = false;
14332 : // Determine if there is a sensible load on this system
14333 102787 : if (DesOutTemp - state.dataLoopNodes->Node(InletNode).Temp > HVAC::TempControlTol) {
14334 30921 : SensibleLoad = true;
14335 : }
14336 : // if a heat pump and other coil is on, disable this coil
14337 102787 : if (this->m_HeatPump && this->m_CoolingPartLoadFrac > 0.0) {
14338 5179 : SensibleLoad = false;
14339 : }
14340 :
14341 : // disable compressor if OAT is below minimum outdoor temperature
14342 102787 : if (OutdoorDryBulb < this->m_MinOATCompressorHeating) {
14343 2050 : SensibleLoad = false;
14344 : }
14345 :
14346 : // IF DXHeatingSystem runs with a heating load then set PartLoadFrac on Heating System
14347 102787 : if (SensibleLoad) {
14348 :
14349 28886 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14350 86658 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
14351 28886 : state.dataLoopNodes->Node(InletNode).HumRat,
14352 28886 : state.dataLoopNodes->Node(InletNode).Temp,
14353 28886 : state.dataLoopNodes->Node(InletNode).HumRat);
14354 28886 : ReqOutput = max(0.0, ReqOutput);
14355 :
14356 : // Get no load result
14357 28886 : PartLoadFrac = 0.0;
14358 28886 : compressorOp = HVAC::CompressorOp::Off;
14359 :
14360 28886 : switch (this->m_HeatingCoilType_Num) {
14361 0 : case HVAC::CoilDX_HeatingEmpirical: {
14362 0 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, CompIndex, fanOp, PartLoadFrac);
14363 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14364 0 : } break;
14365 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
14366 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14367 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14368 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
14369 0 : if (HeatingActive) {
14370 0 : PartLoadFrac = 1.0;
14371 : }
14372 :
14373 0 : } break;
14374 2247 : case HVAC::CoilDX_MultiSpeedHeating:
14375 : case HVAC::Coil_HeatingElectric_MultiStage:
14376 : case HVAC::Coil_HeatingGas_MultiStage: {
14377 2247 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14378 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14379 0 : this->m_SpeedNum = this->m_HeatingSpeedNum;
14380 0 : bool useMaxedSpeed = false;
14381 0 : if (this->m_SpeedNum > this->m_NumOfSpeedHeating) {
14382 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14383 0 : this->m_SpeedNum = this->m_NumOfSpeedHeating;
14384 0 : this->m_CoilSpeedErrIdx++;
14385 0 : useMaxedSpeed = true;
14386 0 : ShowRecurringWarningErrorAtEnd(
14387 : state,
14388 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_HeatingCoilName +
14389 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
14390 0 : this->m_CoilSpeedErrIdx,
14391 0 : this->m_EMSOverrideCoilSpeedNumValue,
14392 0 : this->m_EMSOverrideCoilSpeedNumValue,
14393 : _,
14394 : "",
14395 : "");
14396 : }
14397 0 : if (this->m_HeatingSpeedNum == 1) {
14398 0 : this->m_HeatingSpeedRatio = 0.0;
14399 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14400 0 : this->m_HeatingCycRatio = CycRatio;
14401 0 : if (useMaxedSpeed || CycRatio == 0) {
14402 0 : this->m_HeatingCycRatio = 1;
14403 : } else {
14404 0 : this->m_HeatingCycRatio = CycRatio;
14405 : }
14406 : } else {
14407 0 : this->m_HeatingCycRatio = 1.0;
14408 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14409 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14410 0 : if (useMaxedSpeed || SpeedRatio == 0) {
14411 0 : this->m_HeatingSpeedRatio = 1;
14412 : } else {
14413 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14414 : }
14415 : }
14416 : }
14417 2247 : bool LatentLoad = false;
14418 2247 : this->simMultiSpeedCoils(
14419 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, this->m_SpeedNum);
14420 2247 : } break;
14421 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14422 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14423 0 : int SpeedNum = 0;
14424 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14425 0 : VariableSpeedCoils::SimVariableSpeedCoils(
14426 0 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14427 0 : } break;
14428 26639 : case HVAC::Coil_HeatingGasOrOtherFuel:
14429 : case HVAC::Coil_HeatingElectric:
14430 : case HVAC::Coil_HeatingDesuperheater: {
14431 26639 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, PartLoadFrac, CompIndex, _, _, fanOp);
14432 26639 : } break;
14433 0 : case HVAC::Coil_HeatingWater: {
14434 0 : WaterCoils::SimulateWaterCoilComponents(
14435 0 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14436 0 : } break;
14437 0 : case HVAC::Coil_HeatingSteam: {
14438 0 : SteamCoils::SimulateSteamCoilComponents(state,
14439 : CompName,
14440 : FirstHVACIteration,
14441 0 : this->m_HeatingCoilIndex,
14442 0 : 1.0,
14443 : _,
14444 0 : this->m_FanOpMode,
14445 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14446 0 : } break;
14447 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14448 0 : if (FirstHVACIteration) {
14449 0 : this->m_CompPartLoadRatio = 1;
14450 : }
14451 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14452 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::Off, PartLoadFrac, FirstHVACIteration);
14453 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14454 0 : this->m_HeatingCoilSensDemand = 0.0;
14455 0 : } break;
14456 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14457 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14458 : blankString,
14459 : CompIndex,
14460 : this->MaxHeatAirMassFlow,
14461 : fanOp,
14462 : FirstHVACIteration,
14463 0 : this->m_InitHeatPump,
14464 : ReqOutput,
14465 : dummy,
14466 : HVAC::CompressorOp::Off,
14467 : PartLoadFrac);
14468 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14469 0 : } break;
14470 0 : default:
14471 0 : break;
14472 : }
14473 :
14474 : // IF outlet temp at no load is within ACC of set point, do not run the coil
14475 :
14476 57772 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14477 28886 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14478 : // do nothing, coil is at the set point.
14479 28886 : } else if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) > Acc) { // IF outlet temp is above set point turn off coil
14480 0 : PartLoadFrac = 0.0;
14481 : } else { // ELSE get full load result
14482 :
14483 : // Get full load result
14484 28886 : PartLoadFrac = 1.0;
14485 28886 : compressorOp = HVAC::CompressorOp::On;
14486 :
14487 28886 : switch (this->m_HeatingCoilType_Num) {
14488 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14489 0 : DXCoils::SimDXCoil(
14490 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_HeatingCoilIndex, fanOp, PartLoadFrac);
14491 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14492 0 : } break;
14493 0 : case HVAC::Coil_UserDefined: {
14494 : // should never get here, coil cannot be controlled and has already been simulated
14495 0 : } break;
14496 2247 : case HVAC::CoilDX_MultiSpeedHeating: {
14497 2247 : CycRatio = 1.0;
14498 2247 : SpeedRatio = 0.0;
14499 2247 : int SpeedNum = 0;
14500 2247 : bool LatentLoad = false;
14501 2247 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14502 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14503 0 : SpeedNum = this->m_HeatingSpeedNum;
14504 0 : if (this->m_HeatingSpeedNum == 1) {
14505 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14506 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14507 0 : this->m_HeatingCycRatio = CycRatio;
14508 0 : if (CycRatio == 0) {
14509 0 : this->m_HeatingCycRatio = 1;
14510 : } else {
14511 0 : this->m_HeatingCycRatio = CycRatio;
14512 : }
14513 : } else {
14514 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14515 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14516 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14517 0 : if (SpeedRatio == 0) {
14518 0 : this->m_HeatingSpeedRatio = 1;
14519 : } else {
14520 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14521 : }
14522 : }
14523 0 : if (SpeedNum > this->m_NumOfSpeedHeating) {
14524 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14525 0 : SpeedNum = this->m_NumOfSpeedHeating;
14526 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14527 0 : if (this->m_HeatingSpeedNum == 1) {
14528 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14529 : } else {
14530 0 : this->m_HeatingSpeedRatio = SpeedRatio = 1.0;
14531 : }
14532 : }
14533 0 : this->simMultiSpeedCoils(
14534 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14535 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14536 : } else {
14537 6737 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14538 4492 : if (SpeedNum > 1) {
14539 2245 : CycRatio = 0.0;
14540 2245 : SpeedRatio = 1.0;
14541 : }
14542 4492 : this->m_HeatingSpeedNum = SpeedNum;
14543 4492 : this->simMultiSpeedCoils(state,
14544 : AirLoopNum,
14545 : FirstHVACIteration,
14546 : compressorOp,
14547 : SensibleLoad,
14548 : LatentLoad,
14549 : PartLoadFrac,
14550 : HeatingCoil,
14551 : SpeedNum);
14552 4492 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14553 4492 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14554 2 : break;
14555 : }
14556 : }
14557 : }
14558 2247 : } break;
14559 0 : case HVAC::Coil_HeatingElectric_MultiStage:
14560 : case HVAC::Coil_HeatingGas_MultiStage: {
14561 0 : bool LatentLoad = false;
14562 0 : CycRatio = 1.0;
14563 0 : SpeedRatio = 1.0;
14564 0 : SensLoad = 1.0; // turns on coil
14565 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14566 0 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14567 0 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14568 0 : this->m_HeatingSpeedNum = SpeedNum;
14569 0 : this->simMultiSpeedCoils(
14570 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14571 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14572 0 : SpeedRatio = double(SpeedNum) - 1.0;
14573 0 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14574 0 : break;
14575 : }
14576 : }
14577 0 : } break;
14578 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14579 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14580 0 : CycRatio = 1.0;
14581 0 : SpeedRatio = 1.0;
14582 0 : SensLoad = 1.0; // turns on coil
14583 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14584 0 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14585 0 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14586 0 : this->m_HeatingSpeedNum = SpeedNum;
14587 0 : VariableSpeedCoils::SimVariableSpeedCoils(
14588 0 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14589 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14590 0 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14591 0 : break;
14592 : }
14593 : }
14594 0 : } break;
14595 26639 : case HVAC::Coil_HeatingGasOrOtherFuel:
14596 : case HVAC::Coil_HeatingElectric: {
14597 53278 : HeatingCoils::SimulateHeatingCoilComponents(
14598 26639 : state, CompName, FirstHVACIteration, this->m_DesignHeatingCapacity, CompIndex, _, _, fanOp);
14599 26639 : } break;
14600 0 : case HVAC::Coil_HeatingDesuperheater: {
14601 0 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, ReqOutput, CompIndex, _, _, fanOp);
14602 0 : } break;
14603 0 : case HVAC::Coil_HeatingWater: {
14604 0 : mdot = this->MaxHeatCoilFluidFlow;
14605 0 : PlantUtilities::SetComponentFlowRate(
14606 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14607 :
14608 0 : WaterCoils::SimulateWaterCoilComponents(
14609 0 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14610 0 : } break;
14611 0 : case HVAC::Coil_HeatingSteam: {
14612 0 : mdot = this->MaxHeatCoilFluidFlow;
14613 0 : PlantUtilities::SetComponentFlowRate(
14614 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14615 :
14616 0 : SteamCoils::SimulateSteamCoilComponents(state,
14617 : CompName,
14618 : FirstHVACIteration,
14619 0 : this->m_HeatingCoilIndex,
14620 0 : 1.0,
14621 : _,
14622 0 : this->m_FanOpMode,
14623 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14624 0 : } break;
14625 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14626 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14627 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::On, PartLoadFrac, FirstHVACIteration);
14628 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14629 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14630 0 : } break;
14631 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14632 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14633 : blankString,
14634 : CompIndex,
14635 : this->MaxHeatAirMassFlow,
14636 : fanOp,
14637 : FirstHVACIteration,
14638 0 : this->m_InitHeatPump,
14639 : ReqOutput,
14640 : dummy,
14641 : HVAC::CompressorOp::Off,
14642 : PartLoadFrac);
14643 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14644 0 : } break;
14645 0 : default:
14646 0 : break;
14647 : }
14648 :
14649 28886 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14650 28886 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
14651 28886 : state.dataLoopNodes->Node(OutletNode).HumRat,
14652 28886 : state.dataLoopNodes->Node(InletNode).Temp,
14653 28886 : state.dataLoopNodes->Node(InletNode).HumRat);
14654 : // If the outlet temp is within ACC of set point,
14655 57772 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14656 28886 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14657 : // do nothing, coil is at set point
14658 28886 : } else if (state.dataLoopNodes->Node(OutletNode).Temp < (DesOutTemp - Acc)) { // IF outlet temp is below set point coil must be on
14659 7691 : PartLoadFrac = 1.0;
14660 : } else { // ELSE find the PLR to meet the set point
14661 :
14662 21195 : switch (this->m_HeatingCoilType_Num) {
14663 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14664 0 : auto f = [&state, CompIndex, DesOutTemp](Real64 const PartLoadFrac) {
14665 0 : DXCoils::CalcDXHeatingCoil(state, CompIndex, PartLoadFrac, HVAC::FanOp::Continuous, 1.0);
14666 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(CompIndex);
14667 0 : };
14668 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14669 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14670 0 : } break;
14671 2 : case HVAC::CoilDX_MultiSpeedHeating:
14672 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14673 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
14674 : case HVAC::Coil_HeatingElectric_MultiStage:
14675 : case HVAC::Coil_HeatingGas_MultiStage: {
14676 2 : if (this->m_HeatingSpeedNum > 1.0) {
14677 0 : auto f = [&state, this, DesOutTemp, CycRatio, fanOp](Real64 const SpeedRatio) {
14678 0 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14679 : SpeedRatio,
14680 0 : this->m_HeatingCoilIndex,
14681 : DesOutTemp,
14682 0 : this->m_UnitarySysNum,
14683 : CycRatio,
14684 0 : this->m_HeatingSpeedNum,
14685 : fanOp,
14686 : HVAC::CompressorOp::On,
14687 0 : false);
14688 0 : };
14689 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14690 0 : this->m_HeatingCycRatio = CycRatio;
14691 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14692 0 : this->m_HeatingPartLoadFrac = SpeedRatio;
14693 0 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14694 0 : PartLoadFrac = SpeedRatio;
14695 : } else {
14696 2 : SpeedRatio = 0.0;
14697 2 : this->m_HeatingSpeedRatio = SpeedRatio;
14698 6 : auto f = [&state, this, DesOutTemp, SpeedRatio, fanOp](Real64 const CycRatio) {
14699 12 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14700 : CycRatio,
14701 6 : this->m_HeatingCoilIndex,
14702 : DesOutTemp,
14703 6 : this->m_UnitarySysNum,
14704 : SpeedRatio,
14705 6 : this->m_HeatingSpeedNum,
14706 : fanOp,
14707 : HVAC::CompressorOp::On,
14708 6 : false);
14709 2 : };
14710 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14711 2 : this->m_HeatingCycRatio = CycRatio;
14712 2 : this->m_HeatingPartLoadFrac = CycRatio;
14713 2 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14714 2 : PartLoadFrac = CycRatio;
14715 : }
14716 2 : } break;
14717 21193 : case HVAC::Coil_HeatingGasOrOtherFuel: {
14718 63579 : HeatingCoils::SimulateHeatingCoilComponents(
14719 42386 : state, this->m_HeatingCoilName, FirstHVACIteration, ReqOutput, CompIndex, _, true, fanOp, PartLoadFrac);
14720 21193 : PartLoadFrac = ReqOutput / FullOutput;
14721 21193 : HeatCoilLoad = ReqOutput;
14722 21193 : } break;
14723 0 : case HVAC::Coil_HeatingElectric:
14724 : case HVAC::Coil_HeatingDesuperheater: {
14725 0 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14726 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, fanOp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14727 0 : return this->gasElecHeatingCoilResidual(state,
14728 : PartLoadFrac,
14729 0 : this->m_UnitarySysNum,
14730 : FirstHVACIteration,
14731 : DesOutTemp,
14732 : tmpSuppHeatingCoilFlag,
14733 : fanOp,
14734 0 : this->m_DesignHeatingCapacity);
14735 0 : };
14736 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14737 0 : } break;
14738 0 : case HVAC::Coil_HeatingWater: {
14739 :
14740 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14741 : maxPartLoadFrac =
14742 0 : min(1.0,
14743 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14744 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14745 :
14746 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const maxPartLoadFrac) {
14747 : Real64 OutletAirTemp; // Outlet air temperature [C]
14748 :
14749 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14750 0 : this->MaxHeatCoilFluidFlow * maxPartLoadFrac);
14751 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14752 0 : WaterCoils::SimulateWaterCoilComponents(state,
14753 0 : this->m_HeatingCoilName,
14754 : FirstHVACIteration,
14755 0 : this->m_HeatingCoilIndex,
14756 0 : 0.0, // QActual
14757 0 : this->m_FanOpMode,
14758 : maxPartLoadFrac);
14759 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14760 0 : return DesOutTemp - OutletAirTemp;
14761 0 : };
14762 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14763 0 : } break;
14764 0 : case HVAC::Coil_HeatingSteam: {
14765 :
14766 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14767 : maxPartLoadFrac =
14768 0 : min(1.0,
14769 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14770 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14771 :
14772 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14773 : Real64 OutletAirTemp; // Outlet air temperature [C]
14774 : Real64 mdot;
14775 :
14776 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14777 0 : this->MaxHeatCoilFluidFlow * PartLoadFrac);
14778 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14779 0 : SteamCoils::SimulateSteamCoilComponents(state,
14780 0 : this->m_HeatingCoilName,
14781 : FirstHVACIteration,
14782 0 : this->m_HeatingCoilIndex,
14783 0 : 1.0,
14784 : _,
14785 0 : this->m_FanOpMode,
14786 : PartLoadFrac);
14787 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp; // RR this should be supp coil
14788 0 : return DesOutTemp - OutletAirTemp;
14789 0 : };
14790 :
14791 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14792 0 : } break;
14793 0 : case HVAC::Coil_HeatingWaterToAirHPSimple:
14794 : case HVAC::Coil_HeatingWaterToAirHP: {
14795 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14796 :
14797 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
14798 : Real64 OutletAirTemp; // outlet air humidity ratio [kg/kg]
14799 : Real64 dummy;
14800 :
14801 0 : this->m_CompPartLoadRatio = PartLoadRatio;
14802 :
14803 0 : dummy = 0.0;
14804 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
14805 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14806 : blankString,
14807 0 : this->m_HeatingCoilIndex,
14808 : ReqOutput,
14809 : dummy,
14810 0 : this->m_FanOpMode,
14811 : HVAC::CompressorOp::On,
14812 : PartLoadRatio,
14813 : FirstHVACIteration);
14814 : } else {
14815 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14816 : blankString,
14817 0 : this->m_HeatingCoilIndex,
14818 0 : this->MaxHeatAirMassFlow,
14819 0 : this->m_FanOpMode,
14820 : FirstHVACIteration,
14821 0 : this->m_InitHeatPump,
14822 : ReqOutput,
14823 : dummy,
14824 : HVAC::CompressorOp::Off,
14825 : PartLoadRatio);
14826 : }
14827 :
14828 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14829 0 : return DesOutTemp - OutletAirTemp;
14830 0 : };
14831 :
14832 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14833 0 : } break;
14834 0 : case HVAC::Coil_UserDefined: {
14835 : // should never get here, user defined coil cannot be controlled and has already been simulated
14836 0 : } break;
14837 0 : default: {
14838 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
14839 0 : ShowFatalError(
14840 : state,
14841 0 : format("ControlHeatingSystemToSP: Invalid heating coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
14842 0 : } break;
14843 : }
14844 : }
14845 : }
14846 : }
14847 : }
14848 :
14849 102811 : if (PartLoadFrac > 1.0) {
14850 0 : PartLoadFrac = 1.0;
14851 102811 : } else if (PartLoadFrac < 0.0) {
14852 0 : PartLoadFrac = 0.0;
14853 : }
14854 :
14855 102811 : if (SolFla < 0) {
14856 0 : if (SolFla == -1) {
14857 0 : if (!state.dataGlobal->WarmupFlag) {
14858 0 : if (this->warnIndex.m_HeatCoilSensPLRIter < 1) {
14859 0 : ++this->warnIndex.m_HeatCoilSensPLRIter;
14860 0 : ShowWarningError(
14861 : state,
14862 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}", this->UnitType, this->Name));
14863 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14864 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14865 0 : ShowContinueErrorTimeStamp(state,
14866 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14867 : } else {
14868 0 : ShowRecurringWarningErrorAtEnd(state,
14869 0 : this->UnitType + " \"" + this->Name +
14870 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. "
14871 : "Sensible PLR statistics follow.",
14872 0 : this->warnIndex.m_HeatCoilSensPLRIterIndex,
14873 : PartLoadFrac,
14874 : PartLoadFrac);
14875 : }
14876 : }
14877 0 : } else if (SolFla == -2) {
14878 0 : PartLoadFrac = ReqOutput / FullOutput;
14879 0 : if (!state.dataGlobal->WarmupFlag) {
14880 0 : if (this->warnIndex.m_HeatCoilSensPLRFail < 1) {
14881 0 : ++this->warnIndex.m_HeatCoilSensPLRFail;
14882 0 : ShowWarningError(state,
14883 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14884 0 : this->UnitType,
14885 0 : this->Name));
14886 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14887 0 : ShowContinueErrorTimeStamp(state,
14888 : "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14889 : } else {
14890 0 : ShowRecurringWarningErrorAtEnd(
14891 : state,
14892 0 : this->UnitType + " \"" + this->Name +
14893 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14894 0 : this->warnIndex.m_HeatCoilSensPLRFailIndex,
14895 : PartLoadFrac,
14896 : PartLoadFrac);
14897 : }
14898 : }
14899 : }
14900 : }
14901 :
14902 : // Set the final results
14903 102811 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14904 102811 : this->m_HeatingSpeedRatio = SpeedRatio;
14905 102811 : this->m_HeatingCycRatio = CycRatio;
14906 102811 : HeatCoilLoad = ReqOutput;
14907 :
14908 102811 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14909 0 : this->m_sysType != SysType::PackagedWSHP) {
14910 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF =
14911 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14912 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14913 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14914 : }
14915 :
14916 102811 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
14917 0 : mdot = PartLoadFrac * this->MaxHeatCoilFluidFlow;
14918 0 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14919 : }
14920 102811 : }
14921 :
14922 98727 : void UnitarySys::controlSuppHeatSystemToSP(EnergyPlusData &state,
14923 : int const AirLoopNum, // index to air loop
14924 : bool const FirstHVACIteration // First HVAC iteration flag
14925 : )
14926 : {
14927 : // SUBROUTINE INFORMATION:
14928 : // AUTHOR Richard Raustad, FSEC
14929 : // DATE WRITTEN February 2013
14930 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
14931 :
14932 : // PURPOSE OF THIS SUBROUTINE:
14933 : // This subroutine updates the System outlet nodes.
14934 :
14935 : // METHODOLOGY EMPLOYED:
14936 : // Data is moved from the System data structure to the System outlet nodes.
14937 :
14938 : // SUBROUTINE PARAMETER DEFINITIONS:
14939 98727 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14940 98727 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14941 98727 : int constexpr SolveMaxIter(50);
14942 98727 : constexpr bool SuppHeatingCoilFlag(true);
14943 :
14944 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14945 98727 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
14946 98727 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14947 98727 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14948 98727 : Real64 PartLoadFrac = 0.0;
14949 98727 : Real64 SpeedRatio = 0.0;
14950 98727 : Real64 CycRatio = 0.0;
14951 :
14952 : // Set local variables
14953 98727 : auto &inletNode = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode);
14954 98727 : auto &outletNode = state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum);
14955 98727 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14956 98727 : std::string_view CompName = this->m_SuppHeatCoilName;
14957 :
14958 98727 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14959 98727 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14960 98727 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14961 0 : this->m_sysType != SysType::PackagedWSHP) {
14962 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14963 0 : LoopHeatingCoilMaxRTFSave = afnInfo.AFNLoopHeatingCoilMaxRTF;
14964 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = 0.0;
14965 0 : LoopDXCoilMaxRTFSave = afnInfo.AFNLoopDXCoilRTF;
14966 0 : afnInfo.AFNLoopDXCoilRTF = 0.0;
14967 : }
14968 :
14969 : // IF there is a fault of coil SAT Sensor
14970 98727 : if (this->m_FaultyCoilSATFlag) {
14971 : // calculate the sensor offset using fault information
14972 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14973 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14974 : // update the DesOutTemp
14975 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14976 : }
14977 :
14978 98727 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && (inletNode.MassFlowRate > HVAC::SmallAirVolFlow)) {
14979 :
14980 98709 : if (inletNode.Temp < (DesOutTemp - HVAC::TempControlTol)) {
14981 7681 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
14982 0 : this->setEMSSuppCoilStagePLR(state);
14983 : } else {
14984 : // Get no load result at PartLoadFrac = 0.0
14985 :
14986 7681 : switch (this->m_SuppHeatCoilType_Num) {
14987 5438 : case HVAC::Coil_HeatingGasOrOtherFuel:
14988 : case HVAC::Coil_HeatingElectric:
14989 : case HVAC::Coil_HeatingDesuperheater: {
14990 16314 : HeatingCoils::SimulateHeatingCoilComponents(state,
14991 : CompName,
14992 : FirstHVACIteration,
14993 : PartLoadFrac,
14994 5438 : this->m_SuppHeatCoilIndex,
14995 : QCoilActual,
14996 : SuppHeatingCoilFlag,
14997 5438 : this->m_FanOpMode,
14998 : PartLoadFrac); // QCoilReq=PartLoadFrac 0.0 for this call
14999 5438 : } break;
15000 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
15001 : // SpeedRatio = 0.0;
15002 8972 : HeatingCoils::SimulateHeatingCoilComponents(state,
15003 : CompName,
15004 : FirstHVACIteration,
15005 : DataLoopNode::SensedLoadFlagValue,
15006 2243 : this->m_SuppHeatCoilIndex,
15007 : QCoilActual,
15008 : SuppHeatingCoilFlag,
15009 2243 : this->m_FanOpMode,
15010 : PartLoadFrac,
15011 4486 : 0,
15012 : SpeedRatio);
15013 2243 : } break;
15014 0 : case HVAC::Coil_HeatingWater: {
15015 0 : WaterCoils::SimulateWaterCoilComponents(
15016 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
15017 0 : } break;
15018 0 : case HVAC::Coil_HeatingSteam: {
15019 0 : SteamCoils::SimulateSteamCoilComponents(state,
15020 : CompName,
15021 : FirstHVACIteration,
15022 0 : this->m_SuppHeatCoilIndex,
15023 0 : 1.0,
15024 : _,
15025 0 : this->m_FanOpMode,
15026 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
15027 0 : } break;
15028 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
15029 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
15030 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
15031 0 : UserDefinedComponents::SimCoilUserDefined(
15032 0 : state, CompName, this->m_SuppHeatCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
15033 0 : if (HeatingActive) {
15034 0 : PartLoadFrac = 1.0;
15035 : }
15036 0 : } break;
15037 0 : default:
15038 0 : break;
15039 : }
15040 :
15041 7681 : int SolFla = 0;
15042 : // If OutletTemp is within ACC of set point coil operation is not needed or UserDefined already met load.
15043 7681 : if (outletNode.Temp > (DesOutTemp - Acc) || this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
15044 : // do nothing, coil is at or above set point
15045 : } else {
15046 : // outlet temp too low, turn on coil
15047 : // Get full load result
15048 7681 : PartLoadFrac = 1.0;
15049 :
15050 7681 : switch (this->m_SuppHeatCoilType_Num) {
15051 5438 : case HVAC::Coil_HeatingGasOrOtherFuel:
15052 : case HVAC::Coil_HeatingElectric: {
15053 16314 : HeatingCoils::SimulateHeatingCoilComponents(state,
15054 : CompName,
15055 : FirstHVACIteration,
15056 5438 : this->m_DesignSuppHeatingCapacity,
15057 5438 : this->m_SuppHeatCoilIndex,
15058 : QCoilActual,
15059 : SuppHeatingCoilFlag,
15060 5438 : this->m_FanOpMode,
15061 : PartLoadFrac);
15062 5438 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
15063 5438 : PartLoadFrac = QCoilActual / this->m_DesignSuppHeatingCapacity;
15064 : }
15065 5438 : } break;
15066 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
15067 2243 : CycRatio = 1.0;
15068 2243 : SpeedRatio = 1.0;
15069 6336 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
15070 6336 : this->m_SuppHeatingSpeedNum = SpeedNum;
15071 19008 : HeatingCoils::SimulateHeatingCoilComponents(state,
15072 : CompName,
15073 : FirstHVACIteration,
15074 : DataLoopNode::SensedLoadFlagValue,
15075 6336 : this->m_SuppHeatCoilIndex,
15076 : QCoilActual,
15077 : SuppHeatingCoilFlag,
15078 6336 : this->m_FanOpMode,
15079 : PartLoadFrac,
15080 : SpeedNum,
15081 : SpeedRatio);
15082 6336 : if (outletNode.Temp > DesOutTemp) {
15083 2243 : break;
15084 : }
15085 : }
15086 2243 : } break;
15087 0 : case HVAC::Coil_HeatingDesuperheater: {
15088 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
15089 : CompName,
15090 : FirstHVACIteration,
15091 0 : this->m_DesignSuppHeatingCapacity,
15092 0 : this->m_SuppHeatCoilIndex,
15093 : _,
15094 : SuppHeatingCoilFlag,
15095 0 : this->m_FanOpMode);
15096 0 : } break;
15097 0 : case HVAC::Coil_HeatingWater: {
15098 0 : mdot = this->m_MaxSuppCoilFluidFlow;
15099 0 : PlantUtilities::SetComponentFlowRate(
15100 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15101 :
15102 0 : WaterCoils::SimulateWaterCoilComponents(
15103 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
15104 0 : } break;
15105 0 : case HVAC::Coil_HeatingSteam: {
15106 0 : mdot = this->m_MaxSuppCoilFluidFlow;
15107 0 : PlantUtilities::SetComponentFlowRate(
15108 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15109 :
15110 0 : SteamCoils::SimulateSteamCoilComponents(state,
15111 : CompName,
15112 : FirstHVACIteration,
15113 0 : this->m_SuppHeatCoilIndex,
15114 0 : 1.0,
15115 : _,
15116 0 : this->m_FanOpMode,
15117 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
15118 0 : } break;
15119 0 : case HVAC::Coil_UserDefined: {
15120 : // should never get here, coil has already been simulated
15121 0 : } break;
15122 0 : default:
15123 0 : break;
15124 : }
15125 :
15126 : // run the coil at PartLoadFrac = 1.
15127 7681 : if (outletNode.Temp < (DesOutTemp + Acc)) {
15128 0 : PartLoadFrac = 1.0; // these have already been set, leave as is for now
15129 0 : CycRatio = 1.0; // change to outletNode.Temp > and removed these vars and the "} else {"
15130 0 : SpeedRatio = 1.0;
15131 : } else {
15132 7681 : switch (this->m_SuppHeatCoilType_Num) {
15133 5438 : case HVAC::Coil_HeatingGasOrOtherFuel:
15134 : case HVAC::Coil_HeatingElectric:
15135 : case HVAC::Coil_HeatingDesuperheater: {
15136 5438 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
15137 16314 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
15138 32628 : return this->gasElecHeatingCoilResidual(state,
15139 : PartLoadFrac,
15140 16314 : this->m_UnitarySysNum,
15141 : FirstHVACIteration,
15142 : DesOutTemp,
15143 : tmpSuppHeatingCoilFlag,
15144 16314 : this->m_FanOpMode,
15145 16314 : this->m_DesignSuppHeatingCapacity);
15146 5438 : };
15147 5438 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
15148 5438 : } break;
15149 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
15150 2243 : if (this->m_SuppHeatingSpeedNum > 1) {
15151 6726 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
15152 13452 : return UnitarySys::heatingCoilVarSpeedResidual(state,
15153 : SpeedRatio,
15154 6726 : this->m_SuppHeatCoilIndex,
15155 : DesOutTemp,
15156 6726 : this->m_UnitarySysNum,
15157 : CycRatio,
15158 6726 : this->m_SuppHeatingSpeedNum,
15159 6726 : this->m_FanOpMode,
15160 : HVAC::CompressorOp::On,
15161 6726 : true);
15162 2242 : };
15163 2242 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
15164 2242 : PartLoadFrac = SpeedRatio;
15165 : } else {
15166 1 : SpeedRatio = 0.0;
15167 1 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
15168 3 : auto f = [&state, this, DesOutTemp, SpeedRatio](Real64 const CycRatio) {
15169 6 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
15170 : CycRatio,
15171 3 : this->m_SuppHeatCoilIndex,
15172 : DesOutTemp,
15173 3 : this->m_UnitarySysNum,
15174 : SpeedRatio,
15175 3 : this->m_SuppHeatingSpeedNum,
15176 3 : this->m_FanOpMode,
15177 : HVAC::CompressorOp::On,
15178 3 : true);
15179 1 : };
15180 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
15181 1 : PartLoadFrac = CycRatio;
15182 : }
15183 2243 : } break;
15184 0 : case HVAC::Coil_HeatingWater: {
15185 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
15186 : maxPartLoadFrac =
15187 0 : min(1.0,
15188 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
15189 : // max iteration limit (leave a little slop, 0.001)
15190 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
15191 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
15192 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
15193 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
15194 0 : WaterCoils::SimulateWaterCoilComponents(state,
15195 0 : this->m_SuppHeatCoilName,
15196 : FirstHVACIteration,
15197 0 : this->m_SuppHeatCoilIndex,
15198 0 : 0.0, // QActual
15199 0 : this->m_FanOpMode,
15200 : PartLoadFrac);
15201 :
15202 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
15203 0 : };
15204 :
15205 0 : General::SolveRoot(state, Acc, SolveMaxIter, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
15206 0 : } break;
15207 0 : case HVAC::Coil_HeatingSteam: {
15208 :
15209 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
15210 : maxPartLoadFrac =
15211 0 : min(1.0,
15212 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
15213 : // max iteration limit (leave a little slop, 0.001)
15214 :
15215 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
15216 : Real64 mdot;
15217 :
15218 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
15219 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
15220 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
15221 0 : SteamCoils::SimulateSteamCoilComponents(state,
15222 0 : this->m_SuppHeatCoilName,
15223 : FirstHVACIteration,
15224 0 : this->m_SuppHeatCoilIndex,
15225 0 : 1.0,
15226 : _,
15227 0 : this->m_FanOpMode,
15228 : PartLoadFrac);
15229 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
15230 0 : };
15231 :
15232 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
15233 0 : } break;
15234 0 : case HVAC::Coil_UserDefined: {
15235 : // do nothing, coil has already been simulated
15236 0 : } break;
15237 0 : default:
15238 0 : break;
15239 : }
15240 : }
15241 : } // IF (outletNode.Temp < (DesOutTemp + Acc)) THEN
15242 :
15243 7681 : if (PartLoadFrac > 1.0) {
15244 0 : PartLoadFrac = 1.0;
15245 7681 : } else if (PartLoadFrac < 0.0) {
15246 0 : PartLoadFrac = 0.0;
15247 : }
15248 :
15249 7681 : if (SolFla == -1) {
15250 0 : if (!state.dataGlobal->WarmupFlag) {
15251 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRIter < 1) {
15252 0 : Real64 ReqOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
15253 0 : DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15254 : Real64 FullOutput =
15255 0 : inletNode.MassFlowRate *
15256 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15257 :
15258 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRIter;
15259 0 : ShowWarningError(state,
15260 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}",
15261 0 : this->UnitType,
15262 0 : this->Name));
15263 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
15264 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
15265 0 : ShowContinueErrorTimeStamp(
15266 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
15267 : } else {
15268 0 : ShowRecurringWarningErrorAtEnd(state,
15269 0 : format("{} \"{}\" - Iteration limit exceeded calculating sensible part-load ratio "
15270 : "error continues. Sensible PLR statistics follow.",
15271 0 : this->UnitType,
15272 0 : this->Name),
15273 0 : this->warnIndex.m_SuppHeatCoilSensPLRIterIndex,
15274 : PartLoadFrac,
15275 : PartLoadFrac);
15276 : }
15277 : } // IF(.NOT. WarmupFlag)THEN
15278 7681 : } else if (SolFla == -2) {
15279 0 : Real64 ReqOutput = inletNode.MassFlowRate *
15280 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15281 0 : Real64 FullOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
15282 0 : outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15283 :
15284 0 : PartLoadFrac = ReqOutput / FullOutput;
15285 0 : if (!state.dataGlobal->WarmupFlag) {
15286 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRFail < 1) {
15287 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRFail;
15288 0 : ShowWarningError(
15289 : state,
15290 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
15291 0 : this->UnitType,
15292 0 : this->Name));
15293 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
15294 0 : ShowContinueErrorTimeStamp(
15295 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
15296 : } else {
15297 0 : ShowRecurringWarningErrorAtEnd(
15298 : state,
15299 0 : format("{} \"{}\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
15300 0 : this->UnitType,
15301 0 : this->Name),
15302 0 : this->warnIndex.m_SuppHeatCoilSensPLRFailIndex,
15303 : PartLoadFrac,
15304 : PartLoadFrac);
15305 : }
15306 : }
15307 : } // IF (SolFla == -1) THEN
15308 :
15309 7681 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
15310 7681 : this->m_SuppHeatingCycRatio = CycRatio;
15311 7681 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
15312 : } // IF (NOT EMS OVERRIDE) THEN
15313 :
15314 : } // IF SENSIBLE LOAD
15315 : } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. &
15316 :
15317 : // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel)
15318 98727 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15319 0 : this->m_sysType != SysType::PackagedWSHP) {
15320 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
15321 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = max(afnInfo.AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
15322 0 : afnInfo.AFNLoopDXCoilRTF = max(afnInfo.AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
15323 : }
15324 :
15325 98727 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
15326 0 : mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow;
15327 0 : PlantUtilities::SetComponentFlowRate(
15328 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15329 : }
15330 98727 : }
15331 :
15332 22255 : void UnitarySys::simMultiSpeedCoils(EnergyPlusData &state,
15333 : int const AirLoopNum, // Index to air loop
15334 : bool const FirstHVACIteration, // True when first HVAC iteration
15335 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
15336 : bool const SensibleLoad,
15337 : bool const LatentLoad,
15338 : Real64 const PartLoadFrac,
15339 : int const CoilType,
15340 : int const SpeedNumber)
15341 : {
15342 :
15343 : // SUBROUTINE INFORMATION:
15344 : // AUTHOR Chandan Sharma, FSEC
15345 : // DATE WRITTEN March 2013
15346 :
15347 : // PURPOSE OF THIS SUBROUTINE:
15348 : // This subroutine manages multispeed and variable speed cooling coil simulation.
15349 :
15350 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15351 22255 : std::string CompName; // Name of Unitary System object
15352 22255 : Real64 SensLoad = 0.0;
15353 22255 : Real64 LatLoad = 0.0;
15354 22255 : int CoilTypeNum = 0;
15355 22255 : int CompIndex = 0;
15356 22255 : Real64 SpeedRatio = 0.0;
15357 22255 : Real64 CycRatio = 0.0;
15358 22255 : Real64 dummy = 0.0;
15359 :
15360 22255 : if (CoilType == CoolingCoil) {
15361 :
15362 15516 : CompName = this->m_CoolingCoilName;
15363 15516 : CompIndex = this->m_CoolingCoilIndex;
15364 15516 : CoilTypeNum = this->m_CoolingCoilType_Num;
15365 15516 : if (SensibleLoad) {
15366 15516 : SensLoad = -1.0;
15367 15516 : state.dataUnitarySystems->CoolingLoad = true;
15368 15516 : state.dataUnitarySystems->HeatingLoad = false;
15369 : }
15370 15516 : if (LatentLoad) {
15371 0 : LatLoad = -1.0;
15372 : }
15373 :
15374 : } else {
15375 :
15376 6739 : CompName = this->m_HeatingCoilName;
15377 6739 : CompIndex = this->m_HeatingCoilIndex;
15378 6739 : CoilTypeNum = this->m_HeatingCoilType_Num;
15379 :
15380 6739 : if (SensibleLoad) {
15381 6739 : SensLoad = 1.0;
15382 6739 : state.dataUnitarySystems->CoolingLoad = false;
15383 6739 : state.dataUnitarySystems->HeatingLoad = true;
15384 : } else {
15385 0 : SensLoad = 0.0;
15386 0 : state.dataUnitarySystems->HeatingLoad = false;
15387 : }
15388 6739 : LatLoad = 0.0;
15389 : }
15390 :
15391 22255 : Real64 OnOffAirFlowRatio = 1.0;
15392 22255 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadFrac); // 1.0d0 = PartLoadRatio
15393 :
15394 22255 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
15395 :
15396 22255 : if ((CoilTypeNum == HVAC::CoilDX_MultiSpeedCooling) || (CoilTypeNum == HVAC::CoilDX_MultiSpeedHeating)) {
15397 22255 : DXCoils::SimDXCoilMultiSpeed(
15398 22255 : state, CompName, 0.0, PartLoadFrac, CompIndex, SpeedNumber, this->m_FanOpMode, HVAC::CompressorOp::On, this->m_SingleMode);
15399 :
15400 0 : } else if (CoilTypeNum == HVAC::CoilDX_Cooling) {
15401 0 : bool const singleMode = (this->m_SingleMode == 1);
15402 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
15403 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
15404 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
15405 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
15406 0 : coilMode = HVAC::CoilMode::Enhanced;
15407 : }
15408 :
15409 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
15410 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode, this->CoilSHR);
15411 :
15412 0 : } else if (CoilTypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
15413 :
15414 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15415 : CompName,
15416 : CompIndex,
15417 : this->m_FanOpMode,
15418 : CompressorOn,
15419 : PartLoadFrac,
15420 : SpeedNumber,
15421 : this->m_CoolingSpeedRatio,
15422 : SensLoad,
15423 : dummy,
15424 : OnOffAirFlowRatio);
15425 :
15426 0 : } else if (CoilTypeNum == HVAC::Coil_HeatingAirToAirVariableSpeed) {
15427 :
15428 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15429 : CompName,
15430 : CompIndex,
15431 : this->m_FanOpMode,
15432 : CompressorOn,
15433 : PartLoadFrac,
15434 : SpeedNumber,
15435 : this->m_HeatingSpeedRatio,
15436 : SensLoad,
15437 : dummy,
15438 : OnOffAirFlowRatio);
15439 :
15440 0 : } else if (CoilTypeNum == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
15441 :
15442 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15443 : CompName,
15444 : CompIndex,
15445 : this->m_FanOpMode,
15446 : CompressorOn,
15447 : PartLoadFrac,
15448 : SpeedNumber,
15449 : this->m_CoolingSpeedRatio,
15450 : SensLoad,
15451 : dummy,
15452 : OnOffAirFlowRatio);
15453 :
15454 0 : } else if (CoilTypeNum == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
15455 :
15456 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15457 : CompName,
15458 : CompIndex,
15459 : this->m_FanOpMode,
15460 : CompressorOn,
15461 : PartLoadFrac,
15462 : SpeedNumber,
15463 : this->m_HeatingSpeedRatio,
15464 : SensLoad,
15465 : dummy,
15466 : OnOffAirFlowRatio);
15467 :
15468 0 : } else if ((CoilTypeNum == HVAC::Coil_HeatingElectric_MultiStage) || (CoilTypeNum == HVAC::Coil_HeatingGas_MultiStage)) {
15469 :
15470 0 : HeatingCoils::SimulateHeatingCoilComponents(
15471 0 : state, CompName, FirstHVACIteration, _, CompIndex, _, _, this->m_FanOpMode, PartLoadFrac, SpeedNumber, this->m_HeatingSpeedRatio);
15472 : } else {
15473 : }
15474 22255 : }
15475 :
15476 33695 : void UnitarySys::calcPassiveSystem(EnergyPlusData &state,
15477 : int const AirLoopNum, // index to air loop
15478 : bool const FirstHVACIteration // True when first HVAC iteration
15479 : )
15480 : {
15481 :
15482 : // SUBROUTINE INFORMATION:
15483 : // AUTHOR Richard Raustad, FSEC
15484 : // DATE WRITTEN February 2013
15485 :
15486 : // PURPOSE OF THIS SUBROUTINE:
15487 : // This subroutine calculates the set point based output of the unitary system.
15488 :
15489 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15490 33695 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
15491 33695 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off; // compressor control (0=off, 1=on)
15492 33695 : Real64 OnOffAirFlowRatio = 1.0;
15493 33695 : Real64 CoilCoolHeatRat = 1.0;
15494 33695 : Real64 HeatCoilLoad = 0.0;
15495 : // CALL the series of components that simulate a Unitary System
15496 33695 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
15497 28883 : state.dataFans->fans(this->m_FanIndex)
15498 86649 : ->simulate(state,
15499 : FirstHVACIteration,
15500 28883 : state.dataUnitarySystems->FanSpeedRatio,
15501 : _, // Pressure rise
15502 : _, // Flow fraction
15503 28883 : state.dataUnitarySystems->m_massFlow1,
15504 28883 : state.dataUnitarySystems->m_runTimeFraction1,
15505 28883 : state.dataUnitarySystems->m_massFlow2,
15506 28883 : state.dataUnitarySystems->m_runTimeFraction2,
15507 : _);
15508 : }
15509 :
15510 33695 : if (this->m_CoolingCoilUpstream) {
15511 :
15512 33695 : if (this->m_CoolCoilExists) {
15513 33695 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15514 33695 : CompressorOn = HVAC::CompressorOp::Off;
15515 33695 : if (PartLoadRatio > 0.0) {
15516 11417 : CompressorOn = HVAC::CompressorOp::On;
15517 : }
15518 33695 : bool HXUnitOn = false;
15519 33695 : this->calcUnitaryCoolingSystem(
15520 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15521 : }
15522 33695 : if (this->m_HeatCoilExists) {
15523 28883 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15524 28883 : CompressorOn = HVAC::CompressorOp::Off;
15525 28883 : if (PartLoadRatio > 0.0) {
15526 2 : CompressorOn = HVAC::CompressorOp::On;
15527 : }
15528 28883 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15529 : }
15530 :
15531 : } else {
15532 :
15533 0 : if (this->m_HeatCoilExists) {
15534 0 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15535 0 : CompressorOn = HVAC::CompressorOp::Off;
15536 0 : if (PartLoadRatio > 0.0) {
15537 0 : CompressorOn = HVAC::CompressorOp::On;
15538 : }
15539 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15540 : }
15541 0 : if (this->m_CoolCoilExists) {
15542 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15543 0 : CompressorOn = HVAC::CompressorOp::Off;
15544 0 : if (PartLoadRatio > 0.0) {
15545 0 : CompressorOn = HVAC::CompressorOp::On;
15546 : }
15547 0 : bool HXUnitOn = false;
15548 0 : this->calcUnitaryCoolingSystem(
15549 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15550 : }
15551 : }
15552 :
15553 33695 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
15554 0 : state.dataFans->fans(this->m_FanIndex)
15555 0 : ->simulate(state,
15556 : FirstHVACIteration,
15557 0 : state.dataUnitarySystems->FanSpeedRatio,
15558 : _, // Pressure rise
15559 : _, // Flow fraction
15560 0 : state.dataUnitarySystems->m_massFlow1,
15561 0 : state.dataUnitarySystems->m_runTimeFraction1,
15562 0 : state.dataUnitarySystems->m_massFlow2,
15563 0 : state.dataUnitarySystems->m_runTimeFraction2,
15564 : _);
15565 : }
15566 :
15567 : // CALL reheat coils next
15568 33695 : if (this->m_SuppCoilExists) {
15569 28883 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
15570 28883 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
15571 28883 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
15572 : }
15573 33695 : }
15574 :
15575 8987089 : void UnitarySys::reportUnitarySystem(EnergyPlusData &state, int const AirLoopNum)
15576 : {
15577 :
15578 : // SUBROUTINE INFORMATION:
15579 : // AUTHOR Chandan Sharma
15580 : // DATE WRITTEN July 2013
15581 :
15582 : // PURPOSE OF THIS SUBROUTINE:
15583 : // This subroutine updates the report variable for the coils.
15584 :
15585 8987089 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15586 :
15587 8987089 : Real64 SensibleOutput = 0.0; // sensible output rate, {W}
15588 8987089 : Real64 LatentOutput = 0.0; // latent output rate, {W}
15589 8987089 : Real64 TotalOutput = 0.0; // total output rate, {W}
15590 8987089 : Real64 QTotUnitOut = 0.0;
15591 8987089 : Real64 QSensUnitOut = 0.0;
15592 8987089 : this->m_PartLoadFrac = 0.0;
15593 8987089 : this->m_CompPartLoadRatio = 0.0;
15594 8987089 : this->m_CycRatio = 0.0;
15595 8987089 : this->m_SpeedRatio = 0.0;
15596 8987089 : this->FanPartLoadRatio = 0.0;
15597 8987089 : this->m_TotalAuxElecPower = 0.0;
15598 8987089 : this->m_HeatingAuxElecConsumption = 0.0;
15599 8987089 : this->m_CoolingAuxElecConsumption = 0.0;
15600 8987089 : this->m_ElecPower = 0.0;
15601 8987089 : this->m_ElecPowerConsumption = 0.0;
15602 :
15603 8987089 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
15604 8987089 : switch (this->m_ControlType) {
15605 : // Noticed that these are calculated differently.
15606 : // That doesn't make sense except that NodeNumOfControlledZone = 0 for set point control because the control zone name is not required.
15607 2989820 : case UnitarySysCtrlType::Setpoint: {
15608 2989820 : if (this->AirOutNode > 0) {
15609 2989820 : int InletNode = this->AirInNode;
15610 11959280 : CalcComponentSensibleLatentOutput(AirMassFlow,
15611 2989820 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15612 2989820 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15613 2989820 : state.dataLoopNodes->Node(InletNode).Temp,
15614 2989820 : state.dataLoopNodes->Node(InletNode).HumRat,
15615 : SensibleOutput,
15616 : LatentOutput,
15617 : TotalOutput);
15618 2989820 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15619 2989820 : QTotUnitOut = TotalOutput;
15620 : }
15621 2989820 : } break;
15622 5997269 : default: {
15623 5997269 : if (this->AirOutNode > 0 && this->NodeNumOfControlledZone > 0) {
15624 : // PTUnit uses old style method of calculating delivered capacity.
15625 : // Also PTUnit always uses inlet node data, which is good when inlet is connected to zone return node
15626 5997269 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15627 3197491 : Real64 SpecHumOut = state.dataLoopNodes->Node(this->AirOutNode).HumRat;
15628 3197491 : Real64 SpecHumIn = state.dataLoopNodes->Node(this->AirInNode).HumRat;
15629 3197491 : LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s (dehumid = negative)
15630 3197491 : SensibleOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirOutNode).Temp,
15631 3197491 : state.dataLoopNodes->Node(this->AirInNode).HumRat) -
15632 3197491 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirInNode).Temp,
15633 3197491 : state.dataLoopNodes->Node(this->AirInNode).HumRat));
15634 3197491 : TotalOutput =
15635 3197491 : AirMassFlow * (state.dataLoopNodes->Node(this->AirOutNode).Enthalpy - state.dataLoopNodes->Node(this->AirInNode).Enthalpy);
15636 3197491 : } else {
15637 : // air loop systems don't use the Sensible capacity, zone equipment uses this to adjust RemainingOutputRequired
15638 11199112 : CalcZoneSensibleLatentOutput(AirMassFlow,
15639 2799778 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15640 2799778 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15641 2799778 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
15642 2799778 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
15643 : SensibleOutput,
15644 : LatentOutput,
15645 : TotalOutput);
15646 : }
15647 5997269 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15648 5997269 : QTotUnitOut = TotalOutput;
15649 : }
15650 5997269 : } break;
15651 : }
15652 :
15653 : // set the system part-load ratio report variable
15654 8987089 : this->m_PartLoadFrac = max(this->m_CoolingPartLoadFrac, this->m_HeatingPartLoadFrac);
15655 : // set the compressor part-load ratio report variable
15656 8987089 : this->m_CompPartLoadRatio = max(this->m_CoolCompPartLoadRatio, this->m_HeatCompPartLoadRatio);
15657 :
15658 : // logic difference in PTUnit *Rate reporting vs UnitarySystem. Use PTUnit more compact method for 9093.
15659 8987089 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15660 : // Issue 9093.
15661 : // PTHP reports these differently, seems this is correct. Can't change this now, need an issue to resolve
15662 3197491 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15663 3197491 : this->m_TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
15664 3197491 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15665 3197491 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15666 3197491 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15667 3197491 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15668 : } else {
15669 5789598 : if (state.dataUnitarySystems->HeatingLoad) {
15670 1029396 : if (QTotUnitOut > 0.0) { // heating
15671 555269 : this->m_TotCoolEnergyRate = 0.0;
15672 555269 : this->m_SensCoolEnergyRate = 0.0;
15673 555269 : this->m_LatCoolEnergyRate = 0.0;
15674 555269 : this->m_TotHeatEnergyRate = QTotUnitOut;
15675 555269 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15676 555269 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15677 : } else {
15678 474127 : this->m_TotCoolEnergyRate = std::abs(QTotUnitOut);
15679 474127 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15680 474127 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15681 474127 : this->m_TotHeatEnergyRate = 0.0;
15682 474127 : this->m_SensHeatEnergyRate = 0.0;
15683 474127 : this->m_LatHeatEnergyRate = 0.0;
15684 : }
15685 : } else {
15686 4760202 : if (QTotUnitOut <= 0.0) { // cooling
15687 4544308 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15688 4544308 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15689 4544308 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15690 4544308 : this->m_TotHeatEnergyRate = 0.0;
15691 4544308 : this->m_SensHeatEnergyRate = 0.0;
15692 4544308 : this->m_LatHeatEnergyRate = 0.0;
15693 : } else {
15694 215894 : this->m_TotCoolEnergyRate = 0.0;
15695 215894 : this->m_SensCoolEnergyRate = 0.0;
15696 215894 : this->m_LatCoolEnergyRate = 0.0;
15697 215894 : this->m_TotHeatEnergyRate = QTotUnitOut;
15698 215894 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15699 215894 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15700 : }
15701 : }
15702 : }
15703 :
15704 8987089 : this->m_TotHeatEnergy = m_TotHeatEnergyRate * ReportingConstant;
15705 8987089 : this->m_TotCoolEnergy = m_TotCoolEnergyRate * ReportingConstant;
15706 8987089 : this->m_SensHeatEnergy = m_SensHeatEnergyRate * ReportingConstant;
15707 8987089 : this->m_SensCoolEnergy = m_SensCoolEnergyRate * ReportingConstant;
15708 8987089 : this->m_LatHeatEnergy = m_LatHeatEnergyRate * ReportingConstant;
15709 8987089 : this->m_LatCoolEnergy = m_LatCoolEnergyRate * ReportingConstant;
15710 :
15711 8987089 : if (this->m_FanExists && this->AirOutNode > 0) {
15712 6095996 : if (state.dataUnitarySystems->CompOnMassFlow > 0.0) {
15713 5860893 : this->FanPartLoadRatio = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate / state.dataUnitarySystems->CompOnMassFlow;
15714 : }
15715 6095996 : if (AirLoopNum > 0) {
15716 2715323 : if (this->m_FanOpMode == HVAC::FanOp::Cycling) {
15717 824057 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = this->FanPartLoadRatio;
15718 : } else {
15719 1891266 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0;
15720 : }
15721 : }
15722 : }
15723 :
15724 8987089 : Real64 locFanElecPower = (this->m_FanIndex == 0) ? 0.0 : state.dataFans->fans(this->m_FanIndex)->totalPower;
15725 :
15726 8987089 : Real64 elecCoolingPower = 0.0;
15727 8987089 : Real64 elecHeatingPower = 0.0;
15728 8987089 : Real64 suppHeatingPower = 0.0;
15729 8987089 : Real64 defrostElecPower = 0.0;
15730 :
15731 8987089 : switch (this->m_CoolingCoilType_Num) {
15732 727585 : case HVAC::CoilDX_CoolingTwoSpeed: {
15733 : // need to make sure these are 0 for non-variable speed coils (or not report these variables)
15734 727585 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15735 727585 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15736 727585 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15737 : // see :setSpeedVariables
15738 727585 : if (state.dataUnitarySystems->CoolingLoad && this->m_SpeedNum <= 1) {
15739 17035 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15740 17035 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15741 : }
15742 727585 : if (this->m_LastMode == CoolingMode) {
15743 727585 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15744 : }
15745 727585 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15746 727585 : } break;
15747 606897 : case HVAC::CoilDX_MultiSpeedCooling: {
15748 606897 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15749 606897 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15750 606897 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15751 :
15752 606897 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15753 606897 : if (state.dataUnitarySystems->CoolingLoad) {
15754 164804 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15755 164804 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15756 : }
15757 606897 : if (this->m_LastMode == CoolingMode) {
15758 230111 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15759 : }
15760 606897 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15761 606897 : } break;
15762 272541 : case HVAC::Coil_CoolingWater:
15763 : case HVAC::Coil_CoolingWaterDetailed: {
15764 272541 : if (this->m_DiscreteSpeedCoolingCoil) {
15765 14902 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15766 14902 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15767 14902 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15768 14902 : if (state.dataUnitarySystems->CoolingLoad) {
15769 : // if discrete, the coil cycles on and off
15770 5174 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15771 5174 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15772 : }
15773 14902 : if (this->m_LastMode == CoolingMode) {
15774 7212 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15775 : }
15776 : } else {
15777 257639 : if (state.dataUnitarySystems->CoolingLoad) {
15778 : // if not discrete, the coil runs the entire time step.
15779 20954 : this->m_TotalAuxElecPower =
15780 20954 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15781 20954 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15782 : }
15783 257639 : if (this->m_LastMode == CoolingMode) {
15784 106945 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15785 : }
15786 : }
15787 272541 : this->m_ElecPower = locFanElecPower;
15788 272541 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15789 272541 : } break;
15790 : // May not need
15791 2033898 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
15792 2033898 : if (this->m_NumOfSpeedCooling > 1) {
15793 7334 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15794 7334 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15795 7334 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15796 : }
15797 2033898 : if (state.dataUnitarySystems->CoolingLoad) {
15798 1038182 : this->m_TotalAuxElecPower =
15799 1038182 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15800 1038182 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15801 : }
15802 2033898 : if (this->m_LastMode == CoolingMode) {
15803 1196484 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15804 : }
15805 2033898 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15806 2033898 : } break;
15807 1626934 : case HVAC::CoilDX_Cooling: {
15808 1626934 : if (this->m_NumOfSpeedCooling > 1) {
15809 1498277 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15810 1498277 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15811 1498277 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15812 :
15813 1498277 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15814 1498277 : if (state.dataUnitarySystems->CoolingLoad) {
15815 666385 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15816 666385 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15817 : }
15818 1498277 : if (this->m_LastMode == CoolingMode) {
15819 1002780 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15820 : }
15821 1498277 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15822 : } else {
15823 128657 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].subcoolReheatFlag) {
15824 8766 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR == 0.0) {
15825 2324 : this->LoadSHR = 1.0;
15826 2324 : this->CoilSHR = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].performance->NormalSHR;
15827 : }
15828 : }
15829 128657 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15830 128657 : if (state.dataUnitarySystems->CoolingLoad) {
15831 41816 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15832 41816 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15833 : }
15834 128657 : if (this->m_LastMode == CoolingMode) {
15835 68815 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15836 : }
15837 128657 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15838 : }
15839 1626934 : } break;
15840 28852 : case HVAC::Coil_UserDefined:
15841 : case HVAC::CoilWater_CoolingHXAssisted:
15842 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
15843 28852 : if (state.dataUnitarySystems->CoolingLoad) {
15844 0 : this->m_TotalAuxElecPower =
15845 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15846 0 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15847 : }
15848 28852 : if (this->m_LastMode == CoolingMode) {
15849 28852 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15850 : }
15851 : // these coil types do not consume electricity or report electricity at the plant
15852 28852 : } break;
15853 3690382 : default: { // all other DX cooling coils
15854 3690382 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15855 3690382 : if (state.dataUnitarySystems->CoolingLoad) {
15856 820181 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15857 820181 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15858 : }
15859 3690382 : if (this->m_LastMode == CoolingMode) {
15860 2808162 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15861 : }
15862 3690382 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15863 3690382 : } break;
15864 : }
15865 :
15866 8987089 : switch (this->m_HeatingCoilType_Num) {
15867 791927 : case HVAC::CoilDX_MultiSpeedHeating: {
15868 791927 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15869 791927 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15870 791927 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15871 :
15872 791927 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15873 791927 : if (state.dataUnitarySystems->HeatingLoad) {
15874 287845 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15875 287845 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15876 : }
15877 791927 : if (this->m_LastMode == HeatingMode) {
15878 453247 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15879 : }
15880 791927 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15881 791927 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15882 791927 : } break;
15883 0 : case HVAC::Coil_HeatingGas_MultiStage:
15884 : case HVAC::Coil_HeatingElectric_MultiStage: {
15885 0 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15886 0 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15887 :
15888 0 : if (state.dataUnitarySystems->HeatingLoad) {
15889 0 : this->m_TotalAuxElecPower =
15890 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15891 0 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15892 : }
15893 0 : if (this->m_LastMode == HeatingMode) {
15894 0 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15895 : }
15896 :
15897 0 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15898 0 : } break;
15899 2394455 : case HVAC::CoilDX_HeatingEmpirical:
15900 : case HVAC::Coil_HeatingWaterToAirHP:
15901 : case HVAC::Coil_HeatingWaterToAirHPSimple:
15902 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15903 2394455 : if (this->m_NumOfSpeedHeating > 1) {
15904 27128 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15905 27128 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15906 27128 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15907 : }
15908 2394455 : if (state.dataUnitarySystems->HeatingLoad) {
15909 912343 : this->m_TotalAuxElecPower =
15910 912343 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15911 912343 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15912 : }
15913 2394455 : if (this->m_LastMode == HeatingMode) {
15914 973413 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15915 : }
15916 2394455 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15917 2394455 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15918 2394455 : } break;
15919 8895 : case HVAC::Coil_HeatingAirToAirVariableSpeed: {
15920 8895 : if (state.dataUnitarySystems->HeatingLoad) {
15921 3402 : this->m_TotalAuxElecPower =
15922 3402 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15923 3402 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15924 : }
15925 8895 : if (this->m_LastMode == HeatingMode) {
15926 4130 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15927 : }
15928 :
15929 8895 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15930 8895 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15931 8895 : } break;
15932 78594 : case HVAC::Coil_UserDefined:
15933 : case HVAC::Coil_HeatingWater:
15934 : case HVAC::Coil_HeatingSteam:
15935 : case HVAC::Coil_HeatingDesuperheater: {
15936 78594 : if (state.dataUnitarySystems->HeatingLoad) {
15937 34626 : this->m_TotalAuxElecPower =
15938 34626 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15939 34626 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15940 : }
15941 78594 : if (this->m_LastMode == HeatingMode) {
15942 40278 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15943 : }
15944 78594 : } break;
15945 5713218 : default: {
15946 5713218 : if (this->m_HeatCoilExists) {
15947 2664974 : if (state.dataUnitarySystems->HeatingLoad) {
15948 : // if discrete, the coil cycles on and off
15949 954381 : this->m_TotalAuxElecPower =
15950 954381 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15951 954381 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15952 : }
15953 2664974 : if (this->m_LastMode == HeatingMode) {
15954 1193096 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15955 : }
15956 2664974 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15957 : }
15958 5713218 : } break;
15959 : }
15960 :
15961 8987089 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
15962 3834575 : this->m_TotalAuxElecPower = this->m_AncillaryOffPower;
15963 : }
15964 :
15965 8987089 : if (this->m_SuppCoilExists) {
15966 3286160 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
15967 1067750 : suppHeatingPower = state.dataHVACGlobal->SuppHeatingCoilPower;
15968 : }
15969 : }
15970 :
15971 8987089 : this->m_ElecPower = locFanElecPower + elecCoolingPower + elecHeatingPower + suppHeatingPower + defrostElecPower + this->m_TotalAuxElecPower;
15972 8987089 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15973 :
15974 9124865 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15975 137776 : this->m_sysType != SysType::PackagedWSHP) {
15976 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataUnitarySystems->CompOnMassFlow;
15977 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataUnitarySystems->CompOffMassFlow;
15978 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = this->m_FanOpMode;
15979 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = this->FanPartLoadRatio;
15980 137776 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopCompCycRatio = this->m_CycRatio;
15981 : }
15982 8987089 : if (this->m_FirstPass) {
15983 1082 : if (AirLoopNum > -1) {
15984 1074 : if (!state.dataGlobal->SysSizingCalc) {
15985 :
15986 723 : int const CurOASysNum = state.dataSize->CurOASysNum;
15987 723 : if (CurOASysNum > 0) {
15988 2 : auto &thisOASysEqSizing = state.dataSize->OASysEqSizing(CurOASysNum);
15989 2 : thisOASysEqSizing.AirFlow = false;
15990 2 : thisOASysEqSizing.CoolingAirFlow = false;
15991 2 : thisOASysEqSizing.HeatingAirFlow = false;
15992 2 : thisOASysEqSizing.Capacity = false;
15993 2 : thisOASysEqSizing.CoolingCapacity = false;
15994 2 : thisOASysEqSizing.HeatingCapacity = false;
15995 2 : this->m_FirstPass = false;
15996 721 : } else if (state.dataSize->CurSysNum > 0) {
15997 370 : if (state.dataSize->CurSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
15998 370 : state.dataAirLoop->AirLoopControlInfo(state.dataSize->CurSysNum).UnitarySysSimulating = false;
15999 : }
16000 370 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
16001 351 : } else if (state.dataSize->CurZoneEqNum > 0) {
16002 351 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
16003 : } else {
16004 0 : this->m_FirstPass = false;
16005 : }
16006 : }
16007 : } else {
16008 8 : this->m_FirstPass = false;
16009 : }
16010 : // reset the global system type flags
16011 1082 : state.dataSize->ZoneEqDXCoil = false;
16012 : }
16013 :
16014 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
16015 8987089 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
16016 8987089 : state.dataSize->ZoneEqUnitarySys = false;
16017 8987089 : }
16018 :
16019 0 : void UnitarySys::unitarySystemHeatRecovery(EnergyPlusData &state)
16020 : {
16021 :
16022 : // SUBROUTINE INFORMATION:
16023 : // AUTHOR: Chandan Sharma
16024 : // DATE WRITTEN: May 2013
16025 :
16026 : // PURPOSE OF THIS SUBROUTINE:
16027 : // Calculate the heat recovered from UnitarySystem
16028 :
16029 : // SUBROUTINE PARAMETER DEFINITIONS:
16030 : static constexpr std::string_view routineName("UnitarySystemHeatRecovery");
16031 :
16032 0 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
16033 :
16034 0 : Real64 HeatRecInletTemp = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).Temp;
16035 0 : Real64 HeatRecOutletTemp = 0.0;
16036 0 : Real64 HeatRecMassFlowRate = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate;
16037 :
16038 0 : Real64 QHeatRec = state.dataHVACGlobal->MSHPWasteHeat;
16039 :
16040 0 : if (HeatRecMassFlowRate > 0.0) {
16041 :
16042 0 : Real64 CpHeatRec = state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).glycol->getSpecificHeat(state, HeatRecInletTemp, routineName);
16043 :
16044 0 : HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + HeatRecInletTemp;
16045 : // coil model should be handling max outlet water temp (via limit to heat transfer) since heat rejection needs to be accounted for by the
16046 : // coil
16047 0 : if (HeatRecOutletTemp > this->m_MaxHROutletWaterTemp) {
16048 0 : HeatRecOutletTemp = max(HeatRecInletTemp, this->m_MaxHROutletWaterTemp);
16049 0 : QHeatRec = HeatRecMassFlowRate * CpHeatRec * (HeatRecOutletTemp - HeatRecInletTemp);
16050 : }
16051 : } else {
16052 0 : HeatRecOutletTemp = HeatRecInletTemp;
16053 0 : QHeatRec = 0.0;
16054 : }
16055 :
16056 0 : PlantUtilities::SafeCopyPlantNode(state, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
16057 :
16058 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).Temp = HeatRecOutletTemp;
16059 :
16060 0 : this->m_HeatRecoveryRate = QHeatRec;
16061 0 : this->m_HeatRecoveryEnergy = this->m_HeatRecoveryRate * ReportingConstant;
16062 0 : this->m_HeatRecoveryInletTemp = HeatRecInletTemp;
16063 0 : this->m_HeatRecoveryOutletTemp = HeatRecOutletTemp;
16064 0 : this->m_HeatRecoveryMassFlowRate = HeatRecMassFlowRate;
16065 0 : }
16066 :
16067 15024422 : Real64 UnitarySys::calcUnitarySystemLoadResidual(EnergyPlusData &state,
16068 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
16069 : int UnitarySysNum,
16070 : bool FirstHVACIteration,
16071 : // par 3 not used?
16072 : HVAC::CompressorOp compressorOp,
16073 : Real64 LoadToBeMet,
16074 : Real64 coolHeatFlag, // make bool?
16075 : Real64 SensibleLoad,
16076 : Real64 OnOffAirFlowRatio,
16077 : bool HXUnitOn,
16078 : // par 10 not used
16079 : int AirLoopNum)
16080 : {
16081 :
16082 : // FUNCTION INFORMATION:
16083 : // AUTHOR Richard Raustad, FSEC
16084 : // DATE WRITTEN February 2013
16085 :
16086 : // PURPOSE OF THIS SUBROUTINE:
16087 : // To calculate the part-load ratio for the unitary system
16088 :
16089 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16090 : Real64 SensOutput; // sensible output of system
16091 : Real64 LatOutput; // latent output of system
16092 15024422 : Real64 HeatCoilLoad = 0.0;
16093 15024422 : Real64 SupHeaterLoad = 0.0;
16094 15024422 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16095 15024422 : Real64 CoolPLR = coolHeatFlag == 1.0 ? PartLoadRatio : 0.0;
16096 15024422 : Real64 HeatPLR = coolHeatFlag == 1.0 ? 0.0 : PartLoadRatio;
16097 15024422 : thisSys.setSpeedVariables(state, SensibleLoad, PartLoadRatio);
16098 15024422 : thisSys.calcUnitarySystemToLoad(state,
16099 : AirLoopNum,
16100 : FirstHVACIteration,
16101 : CoolPLR,
16102 : HeatPLR,
16103 : OnOffAirFlowRatio,
16104 : SensOutput,
16105 : LatOutput,
16106 : HXUnitOn,
16107 : HeatCoilLoad,
16108 : SupHeaterLoad,
16109 : compressorOp);
16110 : // Calculate residual based on output calculation flag
16111 15024422 : Real64 baselineLoad = SensibleLoad == 1.0 ? SensOutput : LatOutput;
16112 15024422 : Real64 divisor = std::abs(LoadToBeMet) == 0.0 ? 100.0 : LoadToBeMet;
16113 15024422 : return (baselineLoad - LoadToBeMet) / divisor;
16114 : }
16115 :
16116 1306924 : Real64 UnitarySys::DXCoilVarSpeedResidual(EnergyPlusData &state,
16117 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16118 : int CoilIndex,
16119 : Real64 DesOutTemp,
16120 : int UnitarySysNum,
16121 : Real64 CycRatio,
16122 : int SpeedNum,
16123 : HVAC::FanOp const fanOp,
16124 : HVAC::CompressorOp compressorOp)
16125 : {
16126 : // FUNCTION INFORMATION:
16127 : // AUTHOR Fred Buhl
16128 : // DATE WRITTEN September 2002
16129 :
16130 : // PURPOSE OF THIS FUNCTION:
16131 : // Calculates residual function (desired outlet temp - actual outlet temp).
16132 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16133 :
16134 : // METHODOLOGY EMPLOYED:
16135 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given compressor speed
16136 : // and calculates the residual as defined above
16137 :
16138 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16139 1306924 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16140 :
16141 : Real64 dummy;
16142 : Real64 OnOffAirFlowRatio;
16143 : Real64 SensLoad;
16144 :
16145 1306924 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16146 1306924 : switch (thisSys.m_CoolingCoilType_Num) {
16147 1298319 : case HVAC::CoilDX_CoolingTwoSpeed: {
16148 1298319 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
16149 1298319 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16150 1298319 : } break;
16151 235 : case HVAC::CoilDX_MultiSpeedCooling: {
16152 235 : OnOffAirFlowRatio = 1.0;
16153 235 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16154 235 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16155 235 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16156 235 : } break;
16157 8370 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16158 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16159 8370 : dummy = 0.0;
16160 8370 : SensLoad = -1.0;
16161 8370 : OnOffAirFlowRatio = 1.0;
16162 8370 : VariableSpeedCoils::SimVariableSpeedCoils(
16163 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16164 :
16165 8370 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16166 8370 : } break;
16167 0 : default: {
16168 0 : assert(false);
16169 : } break;
16170 : }
16171 1306924 : return DesOutTemp - OutletAirTemp;
16172 : }
16173 :
16174 6726 : Real64 UnitarySys::heatingCoilVarSpeedResidual(EnergyPlusData &state,
16175 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16176 : int CoilIndex,
16177 : Real64 DesOutTemp,
16178 : int UnitarySysNum,
16179 : Real64 CycRatio,
16180 : int SpeedNum,
16181 : HVAC::FanOp const fanOp,
16182 : HVAC::CompressorOp compressorOp,
16183 : bool SuppHeat
16184 :
16185 : )
16186 : {
16187 : // FUNCTION INFORMATION:
16188 : // AUTHOR Fred Buhl
16189 : // DATE WRITTEN September 2002
16190 :
16191 : // PURPOSE OF THIS FUNCTION:
16192 : // Calculates residual function (desired outlet temp - actual outlet temp).
16193 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16194 :
16195 : // METHODOLOGY EMPLOYED:
16196 : // Calls calc routines of multi Speed or variable Coil to get outlet temperature at the given compressor speed
16197 : // and calculates the residual as defined above
16198 :
16199 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16200 6726 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16201 : Real64 OnOffAirFlowRatio;
16202 : Real64 SensLoad;
16203 : Real64 LatLoad;
16204 : Real64 QActual;
16205 :
16206 6726 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16207 :
16208 6726 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16209 6726 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16210 6726 : if (SuppHeat) {
16211 6726 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16212 6726 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16213 : }
16214 :
16215 6726 : switch (heatCoilType) {
16216 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16217 0 : OnOffAirFlowRatio = 1.0;
16218 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16219 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16220 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16221 0 : } break;
16222 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16223 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16224 0 : OnOffAirFlowRatio = 1.0;
16225 0 : SensLoad = 1.0;
16226 0 : LatLoad = -1.0;
16227 : // can't call only the calc routine with these coil types since Init sets air flow rate based on speed num and cycling ratio
16228 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16229 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16230 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16231 0 : } break;
16232 6726 : case HVAC::Coil_HeatingElectric_MultiStage: {
16233 6726 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16234 6726 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16235 6726 : } break;
16236 0 : case HVAC::Coil_HeatingGas_MultiStage: {
16237 0 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16238 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16239 0 : } break;
16240 0 : default: {
16241 0 : assert(false);
16242 : } break;
16243 : }
16244 6726 : return DesOutTemp - OutletAirTemp;
16245 : }
16246 :
16247 0 : Real64 UnitarySys::DXCoilVarSpeedHumRatResidual(EnergyPlusData &state,
16248 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16249 : int CoilIndex,
16250 : Real64 DesOutHumRat,
16251 : int UnitarySysNum,
16252 : Real64 CycRatio,
16253 : int SpeedNum,
16254 : HVAC::FanOp const fanOp,
16255 : HVAC::CompressorOp compressorOp)
16256 : {
16257 : // FUNCTION INFORMATION:
16258 : // AUTHOR Richard Raustad
16259 : // DATE WRITTEN January 2008
16260 :
16261 : // PURPOSE OF THIS FUNCTION:
16262 : // Calculates residual function (desired outlet humrat - actual outlet humrat).
16263 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16264 :
16265 : // METHODOLOGY EMPLOYED:
16266 : // Calls calc routines of multi speed or variable speed coils to get outlet humidity ratio at the given compressor speed
16267 : // and calculates the residual as defined above
16268 :
16269 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16270 0 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio
16271 : Real64 SensLoad;
16272 : Real64 LatLoad;
16273 : Real64 OnOffAirFlowRatio;
16274 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16275 0 : switch (thisSys.m_CoolingCoilType_Num) {
16276 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16277 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
16278 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16279 0 : } break;
16280 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16281 0 : OnOffAirFlowRatio = 1.0;
16282 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16283 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16284 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16285 0 : } break;
16286 0 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16287 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16288 0 : SensLoad = -1.0;
16289 0 : LatLoad = 0.0;
16290 0 : OnOffAirFlowRatio = 1.0;
16291 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16292 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16293 0 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16294 0 : } break;
16295 0 : default: {
16296 0 : assert(false);
16297 : } break;
16298 : }
16299 0 : return DesOutHumRat - OutletAirHumRat;
16300 : }
16301 :
16302 167183 : Real64 UnitarySys::DXCoilCyclingResidual(EnergyPlusData &state,
16303 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16304 : int CoilIndex,
16305 : Real64 DesOutTemp,
16306 : int UnitarySysNum,
16307 : Real64 SpeedRatio,
16308 : int SpeedNum,
16309 : HVAC::FanOp const fanOp,
16310 : HVAC::CompressorOp compressorOp,
16311 : int AirloopNum,
16312 : bool FirstHVACIteration
16313 :
16314 : )
16315 : {
16316 : // FUNCTION INFORMATION:
16317 : // AUTHOR Fred Buhl
16318 : // DATE WRITTEN September 2002
16319 :
16320 : // PURPOSE OF THIS FUNCTION:
16321 : // Calculates residual function (desired outlet temp - actual outlet temp)
16322 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16323 :
16324 : // METHODOLOGY EMPLOYED:
16325 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16326 : // and calculates the residual as defined above
16327 :
16328 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16329 167183 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16330 : Real64 OnOffAirFlowRatio;
16331 :
16332 167183 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16333 167183 : switch (thisSys.m_CoolingCoilType_Num) {
16334 129646 : case HVAC::CoilDX_CoolingTwoSpeed: {
16335 129646 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16336 0 : thisSys.m_CoolingCycRatio = CycRatio;
16337 0 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16338 0 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16339 : } else {
16340 129646 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16341 : }
16342 129646 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16343 129646 : } break;
16344 122 : case HVAC::CoilDX_MultiSpeedCooling: {
16345 122 : OnOffAirFlowRatio = 1.0;
16346 122 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16347 122 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16348 122 : thisSys.m_CoolingCycRatio = CycRatio;
16349 122 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16350 122 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16351 : } else {
16352 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16353 : }
16354 122 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16355 122 : } break;
16356 37415 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16357 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16358 37415 : if (CycRatio == 0.0) {
16359 9378 : compressorOp = HVAC::CompressorOp::Off;
16360 : }
16361 37415 : Real64 dummy = 0.0;
16362 37415 : OnOffAirFlowRatio = 1.0;
16363 37415 : Real64 SensLoad = -1.0;
16364 37415 : VariableSpeedCoils::SimVariableSpeedCoils(
16365 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16366 37415 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16367 37415 : } break;
16368 0 : default: {
16369 0 : assert(false);
16370 : } break;
16371 : }
16372 167183 : return DesOutTemp - OutletAirTemp;
16373 : }
16374 :
16375 2904 : Real64 UnitarySys::DXCoilCyclingHumRatResidual(EnergyPlusData &state,
16376 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16377 : int CoilIndex,
16378 : Real64 DesOutHumRat,
16379 : int UnitarySysNum,
16380 : Real64 SpeedRatio,
16381 : int SpeedNum,
16382 : HVAC::FanOp const fanOp,
16383 : HVAC::CompressorOp compressorOp)
16384 : {
16385 :
16386 : // FUNCTION INFORMATION:
16387 : // AUTHOR Fred Buhl
16388 : // DATE WRITTEN September 2002
16389 :
16390 : // PURPOSE OF THIS FUNCTION:
16391 : // Calculates residual function (desired outlet temp - actual outlet temp)
16392 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16393 :
16394 : // METHODOLOGY EMPLOYED:
16395 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given cycling ratio
16396 : // and calculates the residual as defined above
16397 :
16398 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16399 2904 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio [kg/kg]
16400 : Real64 SensLoad;
16401 : Real64 LatLoad;
16402 : Real64 OnOffAirFlowRatio;
16403 :
16404 2904 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16405 2904 : switch (thisSys.m_CoolingCoilType_Num) {
16406 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16407 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16408 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16409 0 : } break;
16410 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16411 0 : OnOffAirFlowRatio = 1.0;
16412 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16413 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16414 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16415 0 : } break;
16416 2904 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16417 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16418 2904 : SensLoad = -1.0;
16419 2904 : LatLoad = 0.0;
16420 2904 : OnOffAirFlowRatio = 1.0;
16421 2904 : VariableSpeedCoils::SimVariableSpeedCoils(
16422 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16423 2904 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16424 2904 : } break;
16425 0 : default: {
16426 0 : assert(false);
16427 : } break;
16428 : }
16429 2904 : return DesOutHumRat - OutletAirHumRat;
16430 : }
16431 :
16432 9 : Real64 UnitarySys::heatingCoilVarSpeedCycResidual(EnergyPlusData &state,
16433 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16434 : int CoilIndex,
16435 : Real64 DesOutTemp,
16436 : int UnitarySysNum,
16437 : Real64 SpeedRatio,
16438 : int SpeedNum,
16439 : HVAC::FanOp const fanOp,
16440 : HVAC::CompressorOp compressorOp,
16441 : bool SuppHeat)
16442 : {
16443 :
16444 : // FUNCTION INFORMATION:
16445 : // AUTHOR Fred Buhl
16446 : // DATE WRITTEN September 2002
16447 :
16448 : // PURPOSE OF THIS FUNCTION:
16449 : // Calculates residual function (desired outlet temp - actual outlet temp)
16450 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16451 :
16452 : // METHODOLOGY EMPLOYED:
16453 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16454 : // and calculates the residual as defined above
16455 :
16456 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16457 9 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16458 : Real64 SensLoad;
16459 : Real64 LatLoad;
16460 : Real64 OnOffAirFlowRatio;
16461 : Real64 QActual;
16462 :
16463 9 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16464 :
16465 9 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16466 9 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16467 9 : if (SuppHeat) {
16468 3 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16469 3 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16470 : }
16471 :
16472 9 : switch (heatCoilType) {
16473 6 : case HVAC::CoilDX_MultiSpeedHeating: {
16474 6 : OnOffAirFlowRatio = 1.0;
16475 6 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16476 6 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16477 6 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16478 6 : } break;
16479 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16480 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16481 0 : if (CycRatio == 0.0) {
16482 0 : compressorOp = HVAC::CompressorOp::Off;
16483 : }
16484 0 : SensLoad = -1.0;
16485 0 : LatLoad = 0.0;
16486 0 : OnOffAirFlowRatio = 1.0;
16487 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16488 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16489 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16490 0 : } break;
16491 3 : case HVAC::Coil_HeatingElectric_MultiStage: {
16492 3 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16493 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16494 3 : } break;
16495 0 : case HVAC::Coil_HeatingGas_MultiStage: {
16496 0 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16497 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16498 0 : } break;
16499 0 : default: {
16500 0 : assert(false);
16501 : } break;
16502 : }
16503 :
16504 9 : return DesOutTemp - OutletAirTemp;
16505 : }
16506 :
16507 16314 : Real64 UnitarySys::gasElecHeatingCoilResidual(EnergyPlusData &state,
16508 : Real64 const PartLoadFrac, // Compressor cycling ratio (1.0 is continuous, 0.0 is off)
16509 : int UnitarySysNum,
16510 : bool FirstHVACIteration,
16511 : Real64 desTemp,
16512 : bool SuppHeatingCoilFlag,
16513 : HVAC::FanOp const fanOp,
16514 : Real64 HeatingLoadArg)
16515 : {
16516 :
16517 : // FUNCTION INFORMATION:
16518 : // AUTHOR Chandan Sharma, FSEC
16519 : // DATE WRITTEN February 2013
16520 :
16521 : // PURPOSE OF THIS FUNCTION:
16522 : // Calculates residual function (desired outlet temp - actual outlet temp)
16523 : // hot water Coil output depends on the part load ratio which is being varied to zero the residual.
16524 :
16525 : // METHODOLOGY EMPLOYED:
16526 : // Calls SimulateHeatingCoilComponents to get outlet temperature at the given part load ratio
16527 : // and calculates the residual as defined above
16528 :
16529 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16530 16314 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16531 16314 : Real64 HeatingLoad = HeatingLoadArg * PartLoadFrac;
16532 : // heating coils using set point control pass DataLoopNode::SensedLoadFlagValue as QCoilReq to indicate temperature control
16533 16314 : if (!SuppHeatingCoilFlag) {
16534 0 : HeatingCoils::SimulateHeatingCoilComponents(
16535 0 : state, thisSys.m_HeatingCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_HeatingCoilIndex, _, _, fanOp, PartLoadFrac);
16536 0 : return desTemp - state.dataLoopNodes->Node(thisSys.HeatCoilOutletNodeNum).Temp;
16537 : } else {
16538 65256 : HeatingCoils::SimulateHeatingCoilComponents(
16539 48942 : state, thisSys.m_SuppHeatCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_SuppHeatCoilIndex, _, true, fanOp, PartLoadFrac);
16540 16314 : return desTemp - state.dataLoopNodes->Node(thisSys.SuppCoilOutletNodeNum).Temp;
16541 : }
16542 : }
16543 :
16544 0 : Real64 UnitarySys::coolWatertoAirHPTempResidual(EnergyPlusData &state,
16545 : Real64 const PartLoadRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16546 : int UnitarySysNum,
16547 : bool FirstHVACIteration,
16548 : Real64 DesOutTemp,
16549 : Real64 ReqOutput)
16550 : {
16551 :
16552 : // FUNCTION INFORMATION:
16553 : // AUTHOR Chandan Sharma, FSEC
16554 : // DATE WRITTEN January 2013
16555 :
16556 : // PURPOSE OF THIS FUNCTION:
16557 : // Calculates residual function (desired outlet temp - actual outlet temp)
16558 : // Cool water coil output depends on the part load ratio which is being varied to zero the residual.
16559 :
16560 : // METHODOLOGY EMPLOYED:
16561 : // Calls SimWatertoAirHP or SimWatertoAirHPSimple to get outlet humidity ratio at the given cycling ratio
16562 : // and calculates the residual as defined above
16563 :
16564 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16565 :
16566 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
16567 :
16568 0 : Real64 dummy = 0.0;
16569 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
16570 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
16571 : blankString,
16572 0 : thisSys.m_CoolingCoilIndex,
16573 : ReqOutput,
16574 : dummy,
16575 : thisSys.m_FanOpMode,
16576 : HVAC::CompressorOp::On,
16577 : PartLoadRatio,
16578 : FirstHVACIteration);
16579 : } else {
16580 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
16581 : blankString,
16582 0 : thisSys.m_CoolingCoilIndex,
16583 : thisSys.MaxCoolAirMassFlow,
16584 : thisSys.m_FanOpMode,
16585 : FirstHVACIteration,
16586 0 : thisSys.m_InitHeatPump,
16587 : ReqOutput,
16588 : dummy,
16589 : HVAC::CompressorOp::Off,
16590 : PartLoadRatio);
16591 : }
16592 0 : return DesOutTemp - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16593 : }
16594 :
16595 0 : Real64 UnitarySys::calcUnitarySystemWaterFlowResidual(EnergyPlusData &state,
16596 : Real64 const PartLoadRatio, // coil part load ratio
16597 : int UnitarySysNum,
16598 : bool FirstHVACIteration,
16599 : Real64 QZnReq,
16600 : int AirControlNode,
16601 : Real64 OnOffAirFlowRat,
16602 : int AirLoopNum,
16603 : int WaterControlNode,
16604 : Real64 highWaterMdot,
16605 : Real64 lowSpeedRatio,
16606 : Real64 airMdot,
16607 : Real64 par13_SATempTarget,
16608 : Real64 systemMaxAirFlowRate,
16609 : Real64 par15_LoadType,
16610 : Real64 par16_IterationMethod)
16611 : {
16612 :
16613 : // FUNCTION INFORMATION:
16614 : // AUTHOR Richard Raustad, FSEC
16615 : // DATE WRITTEN January 2017
16616 :
16617 : // PURPOSE OF THIS SUBROUTINE:
16618 : // To calculate the part-load ratio for the UnitarySystem coil with varying part load ratio
16619 :
16620 : // METHODOLOGY EMPLOYED:
16621 : // Use SolveRoot to CALL this Function to converge on a solution
16622 :
16623 0 : Real64 HeatCoilLoad = 0.0;
16624 0 : Real64 SupHeaterLoad = 0.0;
16625 :
16626 : // Convert parameters to usable variables
16627 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16628 0 : Real64 SATempTarget = 0.0;
16629 0 : bool LoadIsTarget = false;
16630 0 : if (par13_SATempTarget == 0.0) {
16631 0 : LoadIsTarget = true;
16632 : } else {
16633 0 : SATempTarget = par13_SATempTarget;
16634 : }
16635 0 : bool iterateOnAirOnly = (par16_IterationMethod > 1.0);
16636 0 : bool coolingLoad = (par15_LoadType > 0.0);
16637 :
16638 0 : bool HXUnitOn = true;
16639 :
16640 0 : if (iterateOnAirOnly) {
16641 :
16642 : // set air flow rate bounded by low speed and high speed air flow rates
16643 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
16644 : // FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model
16645 : // FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem
16646 0 : thisSys.FanPartLoadRatio = PartLoadRatio;
16647 : // if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot;
16648 :
16649 : } else {
16650 :
16651 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot;
16652 0 : if (lowSpeedRatio != 1.0) {
16653 : // division by zero when lowSpeedRatio == 1.0
16654 0 : thisSys.FanPartLoadRatio =
16655 0 : max(0.0, ((airMdot - (systemMaxAirFlowRate * lowSpeedRatio)) / ((1.0 - lowSpeedRatio) * systemMaxAirFlowRate)));
16656 : } else {
16657 0 : thisSys.FanPartLoadRatio = 1.0;
16658 : }
16659 0 : if (WaterControlNode > 0) {
16660 0 : Real64 waterMdot = highWaterMdot * PartLoadRatio;
16661 0 : state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot;
16662 : }
16663 : }
16664 :
16665 0 : Real64 coolingPLR = 0.0;
16666 0 : Real64 heatingPLR = 0.0;
16667 :
16668 0 : if (WaterControlNode > 0 && WaterControlNode == thisSys.CoolCoilFluidInletNode) {
16669 : // cooling load using water cooling coil
16670 0 : coolingPLR = PartLoadRatio;
16671 0 : thisSys.m_CoolingPartLoadFrac = PartLoadRatio;
16672 0 : if (thisSys.MaxCoolCoilFluidFlow > 0.0) {
16673 0 : thisSys.CoolCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxCoolCoilFluidFlow;
16674 : }
16675 0 : } else if (WaterControlNode > 0 && WaterControlNode == thisSys.HeatCoilFluidInletNode) {
16676 : // heating load using water heating coil
16677 0 : heatingPLR = PartLoadRatio;
16678 0 : thisSys.m_HeatingPartLoadFrac = PartLoadRatio;
16679 0 : if (thisSys.MaxHeatCoilFluidFlow > 0.0) {
16680 0 : thisSys.HeatCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxHeatCoilFluidFlow;
16681 : }
16682 0 : } else if (coolingLoad) { // non-water coil with cooling load
16683 0 : coolingPLR = PartLoadRatio;
16684 0 : thisSys.m_CoolingPartLoadFrac = coolingPLR;
16685 : } else { // must be non-water coil with heating load
16686 0 : heatingPLR = PartLoadRatio;
16687 0 : thisSys.m_HeatingPartLoadFrac = heatingPLR;
16688 : }
16689 :
16690 0 : Real64 SensOutput = 0.0;
16691 0 : Real64 LatOutput = 0.0;
16692 0 : thisSys.calcUnitarySystemToLoad(state,
16693 : AirLoopNum,
16694 : FirstHVACIteration,
16695 : coolingPLR,
16696 : heatingPLR,
16697 : OnOffAirFlowRat,
16698 : SensOutput,
16699 : LatOutput,
16700 : HXUnitOn,
16701 : HeatCoilLoad,
16702 : SupHeaterLoad,
16703 : HVAC::CompressorOp::On);
16704 :
16705 0 : if (LoadIsTarget) {
16706 : // Calculate residual based on output magnitude
16707 0 : if (std::abs(QZnReq) <= 100.0) {
16708 0 : return (SensOutput - QZnReq) / 100.0;
16709 : } else {
16710 0 : return (SensOutput - QZnReq) / QZnReq;
16711 : }
16712 : } else {
16713 : // Calculate residual based on outlet temperature
16714 0 : return (state.dataLoopNodes->Node(thisSys.AirOutNode).Temp - SATempTarget) * 10.0;
16715 : }
16716 : }
16717 :
16718 15026864 : void UnitarySys::setSpeedVariables(EnergyPlusData &state,
16719 : bool const SensibleLoad, // True when meeting a sensible load (not a moisture load)
16720 : Real64 const PartLoadRatio // operating PLR
16721 : )
16722 : {
16723 :
16724 : // SUBROUTINE INFORMATION:
16725 : // AUTHOR Richard Raustad, FSEC
16726 : // DATE WRITTEN February 2013
16727 :
16728 : // PURPOSE OF THIS SUBROUTINE:
16729 : // This subroutine determines operating PLR and calculates the load based system output.
16730 :
16731 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16732 15026864 : Real64 OnOffAirFlowRatio = 0.0; // compressor on to average flow rate
16733 :
16734 15026864 : if (state.dataUnitarySystems->HeatingLoad && SensibleLoad) {
16735 6499880 : this->m_CoolingSpeedRatio = 0.0;
16736 6499880 : this->m_CoolingCycRatio = 0.0;
16737 6499880 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
16738 288741 : if (this->m_HeatingSpeedNum <= 1) {
16739 151293 : this->m_HeatingSpeedRatio = 0.0;
16740 151293 : this->m_HeatingCycRatio = PartLoadRatio;
16741 151293 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16742 : } else {
16743 137448 : if (this->m_SingleMode == 0) {
16744 137448 : this->m_HeatingSpeedRatio = PartLoadRatio;
16745 137448 : this->m_HeatingCycRatio = 1.0;
16746 : } else {
16747 0 : this->m_HeatingSpeedRatio = 1.0;
16748 0 : this->m_HeatingCycRatio = PartLoadRatio;
16749 : }
16750 : }
16751 6211139 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
16752 3640809 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
16753 2652450 : this->m_CompPartLoadRatio = PartLoadRatio;
16754 2652450 : this->m_HeatingSpeedNum = 0;
16755 : }
16756 : } else {
16757 8526984 : this->m_HeatingSpeedRatio = 0.0;
16758 8526984 : this->m_HeatingCycRatio = 0.0;
16759 8526984 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
16760 2695842 : if (this->m_CoolingSpeedNum <= 1) {
16761 1171545 : this->m_CoolingSpeedRatio = 0.0;
16762 1171545 : this->m_CoolingCycRatio = PartLoadRatio;
16763 1171545 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16764 : } else {
16765 1524297 : if (this->m_SingleMode == 0) {
16766 1515153 : this->m_CoolingSpeedRatio = PartLoadRatio;
16767 1515153 : this->m_CoolingCycRatio = 1.0;
16768 : } else {
16769 9144 : this->m_CoolingSpeedRatio = 1.0;
16770 9144 : this->m_CoolingCycRatio = PartLoadRatio;
16771 : }
16772 : }
16773 5831142 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
16774 2545251 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
16775 3341331 : this->m_CompPartLoadRatio = PartLoadRatio;
16776 3341331 : this->m_CoolingSpeedNum = 0;
16777 2489811 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
16778 0 : if (this->m_CoolingSpeedNum == 1) {
16779 0 : this->m_CoolingSpeedRatio = 0.0;
16780 0 : this->m_CoolingCycRatio = PartLoadRatio;
16781 : } else {
16782 0 : this->m_CoolingSpeedRatio = PartLoadRatio;
16783 0 : this->m_CoolingCycRatio = 1.0;
16784 : }
16785 : } else {
16786 2489811 : this->m_CoolingSpeedNum = 0;
16787 : }
16788 : }
16789 15026864 : OnOffAirFlowRatio = 1.0;
16790 15026864 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
16791 15026864 : }
16792 :
16793 16 : void UnitarySys::checkUnitarySysCoilInOASysExists(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum)
16794 : {
16795 :
16796 : // SUBROUTINE INFORMATION:
16797 : // AUTHOR Chandan Sharma
16798 : // DATE WRITTEN April 2013
16799 :
16800 : // PURPOSE OF THIS SUBROUTINE:
16801 : // After making sure get input is done, checks if the Coil System DX coil is in the
16802 : // OA System. IF exists then the DX cooling coil is 100% DOAS DX coil.
16803 : // METHODOLOGY EMPLOYED:
16804 : // Based on CheckDXCoolingCoilInOASysExists by Bereket Nigusse
16805 :
16806 : // SUBROUTINE PARAMETER DEFINITIONS:
16807 : static constexpr std::string_view RoutineName("CheckUnitarySysCoilInOASysExists: "); // include trailing blank space
16808 :
16809 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16810 16 : if (state.dataUnitarySystems->getInputOnceFlag) {
16811 2 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16812 2 : state.dataUnitarySystems->getInputOnceFlag = false;
16813 : }
16814 :
16815 16 : if (state.dataUnitarySystems->numUnitarySystems > 0) {
16816 16 : bool UnitarySysFound = false;
16817 40 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16818 40 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16819 16 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten) {
16820 8 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16821 : }
16822 16 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ISHundredPercentDOASDXCoil) {
16823 0 : if (!(state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
16824 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num ==
16825 : HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
16826 0 : DXCoils::SetDXCoilTypeData(state, state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilName);
16827 : }
16828 : }
16829 16 : UnitarySysFound = true;
16830 16 : break;
16831 : }
16832 : }
16833 16 : if (!UnitarySysFound) {
16834 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16835 : }
16836 : } else {
16837 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16838 : }
16839 16 : }
16840 :
16841 225 : void UnitarySys::getUnitarySysHeatCoolCoil(EnergyPlusData &state,
16842 : std::string_view UnitarySysName, // Name of Unitary System object
16843 : bool &CoolingCoil, // Cooling coil exists
16844 : bool &HeatingCoil, // Heating coil exists
16845 : int const ZoneOAUnitNum // index to zone OA unit
16846 : )
16847 : {
16848 :
16849 : // FUNCTION INFORMATION:
16850 : // AUTHOR Chandan Sharma
16851 : // DATE WRITTEN April 2013
16852 :
16853 : // PURPOSE OF THIS FUNCTION:
16854 : // Determined weather Unitary system has heating or cooling coils
16855 :
16856 225 : if (state.dataUnitarySystems->getInputOnceFlag) {
16857 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16858 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16859 : }
16860 :
16861 934 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16862 934 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16863 225 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten) {
16864 113 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16865 : }
16866 449 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolCoilExists &&
16867 224 : !state.dataUnitarySystems->unitarySys[UnitarySysNum].m_WaterHRPlantLoopModel) {
16868 224 : CoolingCoil = true;
16869 : }
16870 229 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_HeatCoilExists ||
16871 4 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_SuppCoilExists) {
16872 221 : HeatingCoil = true;
16873 : }
16874 225 : break;
16875 : }
16876 : }
16877 225 : }
16878 :
16879 0 : int UnitarySys::getAirInNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16880 : {
16881 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16882 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16883 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16884 : }
16885 0 : int airNode = 0;
16886 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16887 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16888 0 : airNode = this->AirInNode;
16889 0 : break;
16890 : }
16891 : }
16892 0 : if (airNode == 0) {
16893 0 : errFlag = true;
16894 : }
16895 0 : return airNode;
16896 : }
16897 :
16898 6 : int getZoneEqIndex(EnergyPlusData &state, std::string const &UnitarySysName, DataZoneEquipment::ZoneEquipType zoneEquipType, int const OAUnitNum)
16899 : {
16900 :
16901 6 : if (state.dataUnitarySystems->getInputOnceFlag) {
16902 0 : UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, true, OAUnitNum);
16903 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16904 : }
16905 :
16906 6 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16907 6 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16908 6 : if (zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner ||
16909 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump ||
16910 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir ||
16911 : zoneEquipType == DataZoneEquipment::ZoneEquipType::UnitarySystem) {
16912 6 : return UnitarySysNum;
16913 : }
16914 : }
16915 : }
16916 0 : return -1;
16917 : }
16918 :
16919 0 : int UnitarySys::getAirOutNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16920 : {
16921 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16922 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16923 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16924 : }
16925 0 : int airNode = 0;
16926 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16927 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16928 0 : airNode = this->AirOutNode;
16929 0 : break;
16930 : }
16931 : }
16932 0 : if (airNode == 0) {
16933 0 : errFlag = true;
16934 : }
16935 0 : return airNode;
16936 : }
16937 :
16938 167266 : int UnitarySys::getAirOutletNode()
16939 : {
16940 167266 : return this->AirOutNode;
16941 : }
16942 :
16943 167266 : int UnitarySys::getMixerOANode()
16944 : {
16945 167266 : return this->m_OAMixerNodes[0];
16946 : }
16947 :
16948 167266 : int UnitarySys::getMixerMixNode()
16949 : {
16950 167266 : return this->m_OAMixerNodes[3];
16951 : }
16952 :
16953 167266 : int UnitarySys::getMixerRetNode()
16954 : {
16955 167266 : return this->m_OAMixerNodes[2];
16956 : }
16957 :
16958 351 : int UnitarySys::getEquipIndex()
16959 : {
16960 351 : return this->m_EquipCompNum;
16961 : }
16962 :
16963 3 : bool searchZoneInletNodes(EnergyPlusData &state, int nodeToFind, int &ZoneEquipConfigIndex, int &InletNodeIndex)
16964 : {
16965 13 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16966 23 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++ZoneInletNum) {
16967 13 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(ZoneInletNum) == nodeToFind) {
16968 3 : ZoneEquipConfigIndex = ControlledZoneNum;
16969 3 : InletNodeIndex = ZoneInletNum;
16970 3 : return true;
16971 : }
16972 : }
16973 : }
16974 0 : return false;
16975 : }
16976 :
16977 348 : bool searchZoneInletNodesByEquipmentIndex(EnergyPlusData &state, int nodeToFind, int zoneEquipmentIndex)
16978 : {
16979 399 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).NumInletNodes; ++ZoneInletNum) {
16980 399 : if (state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).InletNode(ZoneInletNum) == nodeToFind) {
16981 348 : return true;
16982 : }
16983 : }
16984 0 : return false;
16985 : }
16986 :
16987 210 : bool searchZoneInletNodeAirLoopNum(EnergyPlusData &state, int airLoopNumToFind, int ZoneEquipConfigIndex, int &InletNodeIndex)
16988 : {
16989 210 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).NumInletNodes; ++ZoneInletNum) {
16990 210 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).InletNodeAirLoopNum(ZoneInletNum) == airLoopNumToFind) {
16991 210 : InletNodeIndex = ZoneInletNum;
16992 210 : return true;
16993 : }
16994 : }
16995 0 : return false;
16996 : }
16997 :
16998 351 : bool searchExhaustNodes(EnergyPlusData &state, const int nodeToFind, int &ZoneEquipConfigIndex, int &ExhaustNodeIndex)
16999 : {
17000 12998 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
17001 25353 : for (int ZoneExhNum = 1; ZoneExhNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes; ++ZoneExhNum) {
17002 12706 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum) == nodeToFind) {
17003 348 : ZoneEquipConfigIndex = ControlledZoneNum;
17004 348 : ExhaustNodeIndex = ZoneExhNum;
17005 348 : return true;
17006 : }
17007 : }
17008 : }
17009 3 : return false;
17010 : }
17011 :
17012 351 : void UnitarySys::setSystemParams(EnergyPlusData &state, Real64 &TotalFloorAreaOnAirLoop, const std::string &thisObjectName)
17013 : {
17014 351 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum);
17015 351 : this->NodeNumOfControlledZone = zoneEquipConfig.ZoneNode;
17016 351 : TotalFloorAreaOnAirLoop = state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
17017 351 : this->m_AirLoopEquipment = false;
17018 351 : if (zoneEquipConfig.EquipListIndex == 0) {
17019 0 : return;
17020 : }
17021 :
17022 351 : auto &zoneEquipList = state.dataZoneEquip->ZoneEquipList(zoneEquipConfig.EquipListIndex);
17023 890 : for (int EquipNum = 1; EquipNum <= zoneEquipList.NumOfEquipTypes; ++EquipNum) {
17024 581 : if ((zoneEquipList.EquipType(EquipNum) != DataZoneEquipment::ZoneEquipType::UnitarySystem) ||
17025 21 : zoneEquipList.EquipName(EquipNum) != thisObjectName) {
17026 539 : continue;
17027 : }
17028 21 : this->m_ZoneSequenceCoolingNum = zoneEquipList.CoolingPriority(EquipNum);
17029 21 : this->m_ZoneSequenceHeatingNum = zoneEquipList.HeatingPriority(EquipNum);
17030 21 : break;
17031 : }
17032 : }
17033 :
17034 385 : bool searchTotalComponents(EnergyPlusData &state,
17035 : SimAirServingZones::CompType compTypeToFind,
17036 : std::string_view objectNameToFind,
17037 : int &compIndex,
17038 : int &branchIndex,
17039 : int &airLoopIndex)
17040 : {
17041 1113 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
17042 1831 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
17043 4146 : for (int CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
17044 : ++CompNum) {
17045 3418 : if (compTypeToFind != state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num) {
17046 2351 : continue;
17047 : }
17048 1067 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
17049 : objectNameToFind)) {
17050 375 : compIndex = CompNum;
17051 375 : branchIndex = BranchNum;
17052 375 : airLoopIndex = AirLoopNum;
17053 375 : return true;
17054 : }
17055 : }
17056 : }
17057 : }
17058 10 : return false;
17059 : }
17060 :
17061 0 : bool getUnitarySystemNodeNumber(EnergyPlusData &state, int const nodeNumber)
17062 : {
17063 0 : for (int unitarySysIndex = 0; unitarySysIndex <= state.dataUnitarySystems->numUnitarySystems - 1; ++unitarySysIndex) {
17064 0 : auto &unitarySys = state.dataUnitarySystems->unitarySys[unitarySysIndex];
17065 :
17066 0 : int FanInletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->inletNodeNum;
17067 0 : int FanOutletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->outletNodeNum;
17068 :
17069 0 : bool noUnitarySysOutdoorAir = false;
17070 0 : if (unitarySys.m_CoolOutAirVolFlow == 0 && unitarySys.m_HeatOutAirVolFlow == 0 && unitarySys.m_NoCoolHeatOutAirVolFlow == 0) {
17071 0 : noUnitarySysOutdoorAir = true;
17072 : }
17073 :
17074 0 : if (unitarySys.m_sysType == UnitarySys::SysType::PackagedWSHP || unitarySys.m_sysType == UnitarySys::SysType::PackagedAC ||
17075 0 : unitarySys.m_sysType == UnitarySys::SysType::PackagedHP) {
17076 0 : if (noUnitarySysOutdoorAir && (nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex ||
17077 0 : nodeNumber == unitarySys.AirInNode || nodeNumber == unitarySys.m_OAMixerNodes[0] ||
17078 0 : nodeNumber == unitarySys.m_OAMixerNodes[1] || nodeNumber == unitarySys.m_OAMixerNodes[2]) ||
17079 0 : nodeNumber == unitarySys.m_OAMixerNodes[3] || nodeNumber == unitarySys.CoolCoilOutletNodeNum ||
17080 0 : nodeNumber == unitarySys.HeatCoilOutletNodeNum) {
17081 0 : return true;
17082 : }
17083 : }
17084 : }
17085 0 : return false;
17086 : }
17087 :
17088 165 : void setupAllOutputVars(EnergyPlusData &state, int const numAllSystemTypes)
17089 : {
17090 : // setup reports only once
17091 : // all report variable are set up here after all systems are allocated.
17092 : // UnitarySystem now models other equipment types, any new reports may be setup here.
17093 165 : if (numAllSystemTypes == state.dataUnitarySystems->numUnitarySystems) {
17094 901 : for (int sysNum = 0; sysNum < state.dataUnitarySystems->numUnitarySystems; ++sysNum) {
17095 736 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_sysType) {
17096 134 : case UnitarySys::SysType::Unitary:
17097 : // Setup Report variables for the Unitary System that are not reported in the components themselves
17098 268 : SetupOutputVariable(state,
17099 : "Unitary System Part Load Ratio",
17100 : Constant::Units::None,
17101 134 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17102 : OutputProcessor::TimeStepType::System,
17103 : OutputProcessor::StoreType::Average,
17104 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17105 268 : SetupOutputVariable(state,
17106 : "Unitary System Total Cooling Rate",
17107 : Constant::Units::W,
17108 134 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17109 : OutputProcessor::TimeStepType::System,
17110 : OutputProcessor::StoreType::Average,
17111 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17112 268 : SetupOutputVariable(state,
17113 : "Unitary System Sensible Cooling Rate",
17114 : Constant::Units::W,
17115 134 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17116 : OutputProcessor::TimeStepType::System,
17117 : OutputProcessor::StoreType::Average,
17118 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17119 268 : SetupOutputVariable(state,
17120 : "Unitary System Latent Cooling Rate",
17121 : Constant::Units::W,
17122 134 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17123 : OutputProcessor::TimeStepType::System,
17124 : OutputProcessor::StoreType::Average,
17125 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17126 268 : SetupOutputVariable(state,
17127 : "Unitary System Total Heating Rate",
17128 : Constant::Units::W,
17129 134 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17130 : OutputProcessor::TimeStepType::System,
17131 : OutputProcessor::StoreType::Average,
17132 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17133 268 : SetupOutputVariable(state,
17134 : "Unitary System Sensible Heating Rate",
17135 : Constant::Units::W,
17136 134 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17137 : OutputProcessor::TimeStepType::System,
17138 : OutputProcessor::StoreType::Average,
17139 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17140 268 : SetupOutputVariable(state,
17141 : "Unitary System Latent Heating Rate",
17142 : Constant::Units::W,
17143 134 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17144 : OutputProcessor::TimeStepType::System,
17145 : OutputProcessor::StoreType::Average,
17146 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17147 268 : SetupOutputVariable(state,
17148 : "Unitary System Ancillary Electricity Rate",
17149 : Constant::Units::W,
17150 134 : state.dataUnitarySystems->unitarySys[sysNum].m_TotalAuxElecPower,
17151 : OutputProcessor::TimeStepType::System,
17152 : OutputProcessor::StoreType::Average,
17153 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17154 134 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolCoilExists) {
17155 266 : SetupOutputVariable(state,
17156 : "Unitary System Cooling Ancillary Electricity Energy",
17157 : Constant::Units::J,
17158 133 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingAuxElecConsumption,
17159 : OutputProcessor::TimeStepType::System,
17160 : OutputProcessor::StoreType::Sum,
17161 133 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17162 : Constant::eResource::Electricity,
17163 : OutputProcessor::Group::HVAC,
17164 : OutputProcessor::EndUseCat::Cooling);
17165 : }
17166 151 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatCoilExists ||
17167 17 : state.dataUnitarySystems->unitarySys[sysNum].m_SuppCoilExists) {
17168 234 : SetupOutputVariable(state,
17169 : "Unitary System Heating Ancillary Electricity Energy",
17170 : Constant::Units::J,
17171 117 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingAuxElecConsumption,
17172 : OutputProcessor::TimeStepType::System,
17173 : OutputProcessor::StoreType::Sum,
17174 117 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17175 : Constant::eResource::Electricity,
17176 : OutputProcessor::Group::HVAC,
17177 : OutputProcessor::EndUseCat::Heating);
17178 : }
17179 :
17180 268 : SetupOutputVariable(state,
17181 : "Unitary System Electricity Rate",
17182 : Constant::Units::W,
17183 134 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17184 : OutputProcessor::TimeStepType::System,
17185 : OutputProcessor::StoreType::Average,
17186 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17187 268 : SetupOutputVariable(state,
17188 : "Unitary System Electricity Energy",
17189 : Constant::Units::J,
17190 134 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17191 : OutputProcessor::TimeStepType::System,
17192 : OutputProcessor::StoreType::Sum,
17193 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17194 :
17195 : // report predicted load as determined by Unitary System for load control only
17196 134 : if (state.dataUnitarySystems->unitarySys[sysNum].m_ControlType != UnitarySys::UnitarySysCtrlType::Setpoint) {
17197 252 : SetupOutputVariable(state,
17198 : "Unitary System Predicted Sensible Load to Setpoint Heat Transfer Rate",
17199 : Constant::Units::W,
17200 126 : state.dataUnitarySystems->unitarySys[sysNum].m_SensibleLoadPredicted,
17201 : OutputProcessor::TimeStepType::System,
17202 : OutputProcessor::StoreType::Average,
17203 126 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17204 252 : SetupOutputVariable(state,
17205 : "Unitary System Predicted Moisture Load to Setpoint Heat Transfer Rate",
17206 : Constant::Units::W,
17207 126 : state.dataUnitarySystems->unitarySys[sysNum].m_MoistureLoadPredicted,
17208 : OutputProcessor::TimeStepType::System,
17209 : OutputProcessor::StoreType::Average,
17210 126 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17211 : }
17212 :
17213 : // IF(UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)THEN
17214 268 : SetupOutputVariable(state,
17215 : "Unitary System Dehumidification Induced Heating Demand Rate",
17216 : Constant::Units::W,
17217 134 : state.dataUnitarySystems->unitarySys[sysNum].m_DehumidInducedHeatingDemandRate,
17218 : OutputProcessor::TimeStepType::System,
17219 : OutputProcessor::StoreType::Average,
17220 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17221 : // END IF
17222 :
17223 134 : if (state.dataUnitarySystems->unitarySys[sysNum].m_FanExists) {
17224 264 : SetupOutputVariable(state,
17225 : "Unitary System Fan Part Load Ratio",
17226 : Constant::Units::None,
17227 132 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17228 : OutputProcessor::TimeStepType::System,
17229 : OutputProcessor::StoreType::Average,
17230 132 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17231 : }
17232 :
17233 268 : SetupOutputVariable(state,
17234 : "Unitary System Compressor Part Load Ratio",
17235 : Constant::Units::None,
17236 134 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17237 : OutputProcessor::TimeStepType::System,
17238 : OutputProcessor::StoreType::Average,
17239 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17240 :
17241 134 : SetupOutputVariable(state,
17242 : "Unitary System Frost Control Status",
17243 : Constant::Units::None,
17244 134 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17245 : OutputProcessor::TimeStepType::System,
17246 : OutputProcessor::StoreType::Average,
17247 134 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17248 :
17249 134 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num) {
17250 91 : case HVAC::CoilDX_MultiSpeedCooling:
17251 : case HVAC::CoilDX_Cooling: {
17252 91 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecActive) {
17253 0 : SetupOutputVariable(state,
17254 : "Unitary System Heat Recovery Rate",
17255 : Constant::Units::W,
17256 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryRate,
17257 : OutputProcessor::TimeStepType::System,
17258 : OutputProcessor::StoreType::Average,
17259 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17260 0 : SetupOutputVariable(state,
17261 : "Unitary System Heat Recovery Inlet Temperature",
17262 : Constant::Units::C,
17263 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryInletTemp,
17264 : OutputProcessor::TimeStepType::System,
17265 : OutputProcessor::StoreType::Average,
17266 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17267 0 : SetupOutputVariable(state,
17268 : "Unitary System Heat Recovery Outlet Temperature",
17269 : Constant::Units::C,
17270 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryOutletTemp,
17271 : OutputProcessor::TimeStepType::System,
17272 : OutputProcessor::StoreType::Average,
17273 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17274 0 : SetupOutputVariable(state,
17275 : "Unitary System Heat Recovery Fluid Mass Flow Rate",
17276 : Constant::Units::kg_s,
17277 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryMassFlowRate,
17278 : OutputProcessor::TimeStepType::System,
17279 : OutputProcessor::StoreType::Average,
17280 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17281 0 : SetupOutputVariable(state,
17282 : "Unitary System Heat Recovery Energy",
17283 : Constant::Units::J,
17284 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryEnergy,
17285 : OutputProcessor::TimeStepType::System,
17286 : OutputProcessor::StoreType::Sum,
17287 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17288 : }
17289 91 : } break;
17290 11 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
17291 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit:
17292 : case HVAC::Coil_CoolingWaterToAirHPSimple:
17293 : case HVAC::Coil_CoolingWaterToAirHP: {
17294 22 : SetupOutputVariable(state,
17295 : "Unitary System Requested Sensible Cooling Rate",
17296 : Constant::Units::W,
17297 11 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilSensDemand,
17298 : OutputProcessor::TimeStepType::System,
17299 : OutputProcessor::StoreType::Average,
17300 11 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17301 22 : SetupOutputVariable(state,
17302 : "Unitary System Requested Latent Cooling Rate",
17303 : Constant::Units::W,
17304 11 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilLatentDemand,
17305 : OutputProcessor::TimeStepType::System,
17306 : OutputProcessor::StoreType::Average,
17307 11 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17308 11 : } break;
17309 32 : default:
17310 32 : break;
17311 : }
17312 :
17313 134 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex >= 0) {
17314 187 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
17315 53 : state.dataCoilCoolingDX->coilCoolingDXs[state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex]
17316 53 : .subcoolReheatFlag) {
17317 2 : SetupOutputVariable(state,
17318 : "Unitary System Zone Load Sensible Heat Ratio",
17319 : Constant::Units::None,
17320 1 : state.dataUnitarySystems->unitarySys[sysNum].LoadSHR,
17321 : OutputProcessor::TimeStepType::System,
17322 : OutputProcessor::StoreType::Average,
17323 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17324 2 : SetupOutputVariable(state,
17325 : "Unitary System Cooling Coil Load Sensible Heat Ratio",
17326 : Constant::Units::None,
17327 1 : state.dataUnitarySystems->unitarySys[sysNum].CoilSHR,
17328 : OutputProcessor::TimeStepType::System,
17329 : OutputProcessor::StoreType::Average,
17330 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17331 : }
17332 : }
17333 :
17334 134 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num) {
17335 8 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
17336 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
17337 : case HVAC::Coil_HeatingWaterToAirHPSimple:
17338 : case HVAC::Coil_HeatingWaterToAirHP: {
17339 16 : SetupOutputVariable(state,
17340 : "Unitary System Requested Heating Rate",
17341 : Constant::Units::W,
17342 8 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilSensDemand,
17343 : OutputProcessor::TimeStepType::System,
17344 : OutputProcessor::StoreType::Average,
17345 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17346 8 : } break;
17347 126 : default:
17348 126 : break;
17349 : }
17350 :
17351 134 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17352 96 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
17353 96 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
17354 43 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17355 272 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
17356 42 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
17357 184 : SetupOutputVariable(state,
17358 : "Unitary System DX Coil Cycling Ratio",
17359 : Constant::Units::None,
17360 92 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17361 : OutputProcessor::TimeStepType::System,
17362 : OutputProcessor::StoreType::Average,
17363 92 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17364 184 : SetupOutputVariable(state,
17365 : "Unitary System DX Coil Speed Ratio",
17366 : Constant::Units::None,
17367 92 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17368 : OutputProcessor::TimeStepType::System,
17369 : OutputProcessor::StoreType::Average,
17370 92 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17371 92 : SetupOutputVariable(state,
17372 : "Unitary System DX Coil Speed Level",
17373 : Constant::Units::None,
17374 92 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17375 : OutputProcessor::TimeStepType::System,
17376 : OutputProcessor::StoreType::Average,
17377 92 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17378 : }
17379 :
17380 134 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
17381 117 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
17382 267 : state.dataUnitarySystems->unitarySys[sysNum].m_DiscreteSpeedCoolingCoil) ||
17383 133 : (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWater &&
17384 1 : state.dataUnitarySystems->unitarySys[sysNum].m_MultiSpeedHeatingCoil)) {
17385 2 : SetupOutputVariable(state,
17386 : "Unitary System Water Coil Cycling Ratio",
17387 : Constant::Units::None,
17388 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17389 : OutputProcessor::TimeStepType::System,
17390 : OutputProcessor::StoreType::Average,
17391 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17392 2 : SetupOutputVariable(state,
17393 : "Unitary System Water Coil Speed Ratio",
17394 : Constant::Units::None,
17395 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17396 : OutputProcessor::TimeStepType::System,
17397 : OutputProcessor::StoreType::Average,
17398 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17399 1 : SetupOutputVariable(state,
17400 : "Unitary System Water Coil Speed Level",
17401 : Constant::Units::None,
17402 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17403 : OutputProcessor::TimeStepType::System,
17404 : OutputProcessor::StoreType::Average,
17405 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17406 : }
17407 :
17408 134 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
17409 96 : SetupEMSActuator(state,
17410 : "UnitarySystem",
17411 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17412 : "Autosized Supply Air Flow Rate",
17413 : "[m3/s]",
17414 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideOn,
17415 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideValue);
17416 96 : SetupEMSActuator(state,
17417 : "UnitarySystem",
17418 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17419 : "Autosized Supply Air Flow Rate During Cooling Operation",
17420 : "[m3/s]",
17421 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideOn,
17422 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideValue);
17423 96 : SetupEMSActuator(state,
17424 : "UnitarySystem",
17425 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17426 : "Autosized Supply Air Flow Rate During Heating Operation",
17427 : "[m3/s]",
17428 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideOn,
17429 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideValue);
17430 96 : SetupEMSActuator(state,
17431 : "UnitarySystem",
17432 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17433 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
17434 : "[m3/s]",
17435 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideOn,
17436 48 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideValue);
17437 48 : SetupEMSInternalVariable(state,
17438 : "Unitary System Control Zone Mass Flow Fraction",
17439 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17440 : "[]",
17441 48 : state.dataUnitarySystems->unitarySys[sysNum].ControlZoneMassFlowFrac);
17442 48 : SetupEMSInternalVariable(state,
17443 : "Unitary HVAC Design Heating Capacity",
17444 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17445 : "[W]",
17446 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignHeatingCapacity);
17447 48 : SetupEMSInternalVariable(state,
17448 : "Unitary HVAC Design Cooling Capacity",
17449 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17450 : "[W]",
17451 48 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignCoolingCapacity);
17452 96 : SetupEMSActuator(state,
17453 : "Unitary HVAC",
17454 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17455 : "Sensible Load Request",
17456 : "[W]",
17457 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSensZoneLoadRequest,
17458 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSSensibleZoneLoadValue);
17459 96 : SetupEMSActuator(state,
17460 : "Unitary HVAC",
17461 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17462 : "Moisture Load Request",
17463 : "[W]",
17464 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideMoistZoneLoadRequest,
17465 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSMoistureZoneLoadValue);
17466 48 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17467 58 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17468 10 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
17469 90 : SetupEMSActuator(state,
17470 : "Coil Speed Control",
17471 45 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17472 : "Unitary System DX Coil Speed Value",
17473 : "[]",
17474 45 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumOn,
17475 45 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumValue);
17476 : }
17477 96 : SetupEMSActuator(state,
17478 : "Coil Speed Control",
17479 48 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17480 : "Unitary System Supplemental Coil Stage Level",
17481 : "[]",
17482 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumOn,
17483 48 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumValue);
17484 : }
17485 : bool anyEMSRan;
17486 134 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
17487 736 : break;
17488 269 : case UnitarySys::SysType::CoilCoolingDX:
17489 : // Setup Report variables for the DXCoolingSystem that is not reported in the components themselves
17490 269 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
17491 98 : SetupOutputVariable(state,
17492 : "Coil System Cycling Ratio",
17493 : Constant::Units::None,
17494 49 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17495 : OutputProcessor::TimeStepType::System,
17496 : OutputProcessor::StoreType::Average,
17497 49 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17498 98 : SetupOutputVariable(state,
17499 : "Coil System Compressor Speed Ratio",
17500 : Constant::Units::None,
17501 49 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17502 : OutputProcessor::TimeStepType::System,
17503 : OutputProcessor::StoreType::Average,
17504 49 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17505 220 : } else if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
17506 4 : SetupOutputVariable(state,
17507 : "Coil System Cycling Ratio",
17508 : Constant::Units::None,
17509 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17510 : OutputProcessor::TimeStepType::System,
17511 : OutputProcessor::StoreType::Average,
17512 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17513 4 : SetupOutputVariable(state,
17514 : "Coil System Compressor Speed Ratio",
17515 : Constant::Units::None,
17516 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17517 : OutputProcessor::TimeStepType::System,
17518 : OutputProcessor::StoreType::Average,
17519 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17520 2 : SetupOutputVariable(state,
17521 : "Coil System Compressor Speed Number",
17522 : Constant::Units::None,
17523 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedNum,
17524 : OutputProcessor::TimeStepType::System,
17525 : OutputProcessor::StoreType::Average,
17526 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17527 : } else {
17528 436 : SetupOutputVariable(state,
17529 : "Coil System Part Load Ratio",
17530 : Constant::Units::None,
17531 218 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingPartLoadFrac,
17532 : OutputProcessor::TimeStepType::System,
17533 : OutputProcessor::StoreType::Average,
17534 218 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17535 : }
17536 269 : SetupOutputVariable(state,
17537 : "Coil System Frost Control Status",
17538 : Constant::Units::None,
17539 269 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17540 : OutputProcessor::TimeStepType::System,
17541 : OutputProcessor::StoreType::Average,
17542 269 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17543 269 : break;
17544 3 : case UnitarySys::SysType::CoilCoolingWater:
17545 : // Setup Report variables for the CoilSystemWater
17546 6 : SetupOutputVariable(state,
17547 : "Coil System Water Part Load Ratio",
17548 : Constant::Units::None,
17549 3 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17550 : OutputProcessor::TimeStepType::System,
17551 : OutputProcessor::StoreType::Average,
17552 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17553 6 : SetupOutputVariable(state,
17554 : "Coil System Water Total Cooling Rate",
17555 : Constant::Units::W,
17556 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17557 : OutputProcessor::TimeStepType::System,
17558 : OutputProcessor::StoreType::Average,
17559 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17560 6 : SetupOutputVariable(state,
17561 : "Coil System Water Sensible Cooling Rate",
17562 : Constant::Units::W,
17563 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17564 : OutputProcessor::TimeStepType::System,
17565 : OutputProcessor::StoreType::Average,
17566 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17567 6 : SetupOutputVariable(state,
17568 : "Coil System Water Latent Cooling Rate",
17569 : Constant::Units::W,
17570 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17571 : OutputProcessor::TimeStepType::System,
17572 : OutputProcessor::StoreType::Average,
17573 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17574 :
17575 3 : if (state.dataUnitarySystems->unitarySys[sysNum].m_TemperatureOffsetControlActive) {
17576 3 : SetupOutputVariable(state,
17577 : "Coil System Water Control Status",
17578 : Constant::Units::None,
17579 3 : state.dataUnitarySystems->unitarySys[sysNum].temperatureOffsetControlStatus,
17580 : OutputProcessor::TimeStepType::System,
17581 : OutputProcessor::StoreType::Average,
17582 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17583 : }
17584 3 : break;
17585 147 : case UnitarySys::SysType::PackagedAC:
17586 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalAirConditioner'
17587 294 : SetupOutputVariable(state,
17588 : "Zone Packaged Terminal Air Conditioner Total Heating Rate",
17589 : Constant::Units::W,
17590 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17591 : OutputProcessor::TimeStepType::System,
17592 : OutputProcessor::StoreType::Average,
17593 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17594 294 : SetupOutputVariable(state,
17595 : "Zone Packaged Terminal Air Conditioner Total Heating Energy",
17596 : Constant::Units::J,
17597 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17598 : OutputProcessor::TimeStepType::System,
17599 : OutputProcessor::StoreType::Sum,
17600 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17601 294 : SetupOutputVariable(state,
17602 : "Zone Packaged Terminal Air Conditioner Total Cooling Rate",
17603 : Constant::Units::W,
17604 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17605 : OutputProcessor::TimeStepType::System,
17606 : OutputProcessor::StoreType::Average,
17607 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17608 294 : SetupOutputVariable(state,
17609 : "Zone Packaged Terminal Air Conditioner Total Cooling Energy",
17610 : Constant::Units::J,
17611 147 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17612 : OutputProcessor::TimeStepType::System,
17613 : OutputProcessor::StoreType::Sum,
17614 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17615 294 : SetupOutputVariable(state,
17616 : "Zone Packaged Terminal Air Conditioner Sensible Heating Rate",
17617 : Constant::Units::W,
17618 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17619 : OutputProcessor::TimeStepType::System,
17620 : OutputProcessor::StoreType::Average,
17621 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17622 294 : SetupOutputVariable(state,
17623 : "Zone Packaged Terminal Air Conditioner Sensible Heating Energy",
17624 : Constant::Units::J,
17625 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17626 : OutputProcessor::TimeStepType::System,
17627 : OutputProcessor::StoreType::Sum,
17628 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17629 294 : SetupOutputVariable(state,
17630 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Rate",
17631 : Constant::Units::W,
17632 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17633 : OutputProcessor::TimeStepType::System,
17634 : OutputProcessor::StoreType::Average,
17635 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17636 294 : SetupOutputVariable(state,
17637 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Energy",
17638 : Constant::Units::J,
17639 147 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17640 : OutputProcessor::TimeStepType::System,
17641 : OutputProcessor::StoreType::Sum,
17642 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17643 294 : SetupOutputVariable(state,
17644 : "Zone Packaged Terminal Air Conditioner Latent Heating Rate",
17645 : Constant::Units::W,
17646 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17647 : OutputProcessor::TimeStepType::System,
17648 : OutputProcessor::StoreType::Average,
17649 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17650 294 : SetupOutputVariable(state,
17651 : "Zone Packaged Terminal Air Conditioner Latent Heating Energy",
17652 : Constant::Units::J,
17653 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17654 : OutputProcessor::TimeStepType::System,
17655 : OutputProcessor::StoreType::Sum,
17656 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17657 294 : SetupOutputVariable(state,
17658 : "Zone Packaged Terminal Air Conditioner Latent Cooling Rate",
17659 : Constant::Units::W,
17660 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17661 : OutputProcessor::TimeStepType::System,
17662 : OutputProcessor::StoreType::Average,
17663 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17664 294 : SetupOutputVariable(state,
17665 : "Zone Packaged Terminal Air Conditioner Latent Cooling Energy",
17666 : Constant::Units::J,
17667 147 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17668 : OutputProcessor::TimeStepType::System,
17669 : OutputProcessor::StoreType::Sum,
17670 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17671 294 : SetupOutputVariable(state,
17672 : "Zone Packaged Terminal Air Conditioner Electricity Rate",
17673 : Constant::Units::W,
17674 147 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17675 : OutputProcessor::TimeStepType::System,
17676 : OutputProcessor::StoreType::Average,
17677 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17678 294 : SetupOutputVariable(state,
17679 : "Zone Packaged Terminal Air Conditioner Electricity Energy",
17680 : Constant::Units::J,
17681 147 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17682 : OutputProcessor::TimeStepType::System,
17683 : OutputProcessor::StoreType::Sum,
17684 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17685 294 : SetupOutputVariable(state,
17686 : "Zone Packaged Terminal Air Conditioner Fan Part Load Ratio",
17687 : Constant::Units::None,
17688 147 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17689 : OutputProcessor::TimeStepType::System,
17690 : OutputProcessor::StoreType::Average,
17691 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17692 294 : SetupOutputVariable(state,
17693 : "Zone Packaged Terminal Air Conditioner Compressor Part Load Ratio",
17694 : Constant::Units::None,
17695 147 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17696 : OutputProcessor::TimeStepType::System,
17697 : OutputProcessor::StoreType::Average,
17698 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17699 147 : SetupOutputVariable(state,
17700 : "Zone Packaged Terminal Air Conditioner Fan Availability Status",
17701 : Constant::Units::None,
17702 147 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17703 : OutputProcessor::TimeStepType::System,
17704 : OutputProcessor::StoreType::Average,
17705 147 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17706 147 : break;
17707 28 : case UnitarySys::SysType::PackagedHP:
17708 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalHeatPump'
17709 56 : SetupOutputVariable(state,
17710 : "Zone Packaged Terminal Heat Pump Total Heating Rate",
17711 : Constant::Units::W,
17712 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17713 : OutputProcessor::TimeStepType::System,
17714 : OutputProcessor::StoreType::Average,
17715 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17716 56 : SetupOutputVariable(state,
17717 : "Zone Packaged Terminal Heat Pump Total Heating Energy",
17718 : Constant::Units::J,
17719 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17720 : OutputProcessor::TimeStepType::System,
17721 : OutputProcessor::StoreType::Sum,
17722 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17723 56 : SetupOutputVariable(state,
17724 : "Zone Packaged Terminal Heat Pump Total Cooling Rate",
17725 : Constant::Units::W,
17726 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17727 : OutputProcessor::TimeStepType::System,
17728 : OutputProcessor::StoreType::Average,
17729 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17730 56 : SetupOutputVariable(state,
17731 : "Zone Packaged Terminal Heat Pump Total Cooling Energy",
17732 : Constant::Units::J,
17733 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17734 : OutputProcessor::TimeStepType::System,
17735 : OutputProcessor::StoreType::Sum,
17736 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17737 56 : SetupOutputVariable(state,
17738 : "Zone Packaged Terminal Heat Pump Sensible Heating Rate",
17739 : Constant::Units::W,
17740 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17741 : OutputProcessor::TimeStepType::System,
17742 : OutputProcessor::StoreType::Average,
17743 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17744 56 : SetupOutputVariable(state,
17745 : "Zone Packaged Terminal Heat Pump Sensible Heating Energy",
17746 : Constant::Units::J,
17747 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17748 : OutputProcessor::TimeStepType::System,
17749 : OutputProcessor::StoreType::Sum,
17750 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17751 56 : SetupOutputVariable(state,
17752 : "Zone Packaged Terminal Heat Pump Sensible Cooling Rate",
17753 : Constant::Units::W,
17754 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17755 : OutputProcessor::TimeStepType::System,
17756 : OutputProcessor::StoreType::Average,
17757 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17758 56 : SetupOutputVariable(state,
17759 : "Zone Packaged Terminal Heat Pump Sensible Cooling Energy",
17760 : Constant::Units::J,
17761 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17762 : OutputProcessor::TimeStepType::System,
17763 : OutputProcessor::StoreType::Sum,
17764 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17765 56 : SetupOutputVariable(state,
17766 : "Zone Packaged Terminal Heat Pump Latent Heating Rate",
17767 : Constant::Units::W,
17768 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17769 : OutputProcessor::TimeStepType::System,
17770 : OutputProcessor::StoreType::Average,
17771 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17772 56 : SetupOutputVariable(state,
17773 : "Zone Packaged Terminal Heat Pump Latent Heating Energy",
17774 : Constant::Units::J,
17775 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17776 : OutputProcessor::TimeStepType::System,
17777 : OutputProcessor::StoreType::Sum,
17778 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17779 56 : SetupOutputVariable(state,
17780 : "Zone Packaged Terminal Heat Pump Latent Cooling Rate",
17781 : Constant::Units::W,
17782 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17783 : OutputProcessor::TimeStepType::System,
17784 : OutputProcessor::StoreType::Average,
17785 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17786 56 : SetupOutputVariable(state,
17787 : "Zone Packaged Terminal Heat Pump Latent Cooling Energy",
17788 : Constant::Units::J,
17789 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17790 : OutputProcessor::TimeStepType::System,
17791 : OutputProcessor::StoreType::Sum,
17792 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17793 56 : SetupOutputVariable(state,
17794 : "Zone Packaged Terminal Heat Pump Electricity Rate",
17795 : Constant::Units::W,
17796 28 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17797 : OutputProcessor::TimeStepType::System,
17798 : OutputProcessor::StoreType::Average,
17799 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17800 56 : SetupOutputVariable(state,
17801 : "Zone Packaged Terminal Heat Pump Electricity Energy",
17802 : Constant::Units::J,
17803 28 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17804 : OutputProcessor::TimeStepType::System,
17805 : OutputProcessor::StoreType::Sum,
17806 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17807 56 : SetupOutputVariable(state,
17808 : "Zone Packaged Terminal Heat Pump Fan Part Load Ratio",
17809 : Constant::Units::None,
17810 28 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17811 : OutputProcessor::TimeStepType::System,
17812 : OutputProcessor::StoreType::Average,
17813 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17814 56 : SetupOutputVariable(state,
17815 : "Zone Packaged Terminal Heat Pump Compressor Part Load Ratio",
17816 : Constant::Units::None,
17817 28 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17818 : OutputProcessor::TimeStepType::System,
17819 : OutputProcessor::StoreType::Average,
17820 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17821 28 : SetupOutputVariable(state,
17822 : "Zone Packaged Terminal Heat Pump Fan Availability Status",
17823 : Constant::Units::None,
17824 28 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17825 : OutputProcessor::TimeStepType::System,
17826 : OutputProcessor::StoreType::Average,
17827 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17828 28 : break;
17829 155 : case UnitarySys::SysType::PackagedWSHP:
17830 : // CurrentModuleObject = 'ZoneHVAC:WaterToAirHeatPump'
17831 310 : SetupOutputVariable(state,
17832 : "Zone Water to Air Heat Pump Total Heating Rate",
17833 : Constant::Units::W,
17834 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17835 : OutputProcessor::TimeStepType::System,
17836 : OutputProcessor::StoreType::Average,
17837 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17838 310 : SetupOutputVariable(state,
17839 : "Zone Water to Air Heat Pump Total Heating Energy",
17840 : Constant::Units::J,
17841 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17842 : OutputProcessor::TimeStepType::System,
17843 : OutputProcessor::StoreType::Sum,
17844 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17845 310 : SetupOutputVariable(state,
17846 : "Zone Water to Air Heat Pump Total Cooling Rate",
17847 : Constant::Units::W,
17848 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17849 : OutputProcessor::TimeStepType::System,
17850 : OutputProcessor::StoreType::Average,
17851 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17852 310 : SetupOutputVariable(state,
17853 : "Zone Water to Air Heat Pump Total Cooling Energy",
17854 : Constant::Units::J,
17855 155 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17856 : OutputProcessor::TimeStepType::System,
17857 : OutputProcessor::StoreType::Sum,
17858 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17859 310 : SetupOutputVariable(state,
17860 : "Zone Water to Air Heat Pump Sensible Heating Rate",
17861 : Constant::Units::W,
17862 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17863 : OutputProcessor::TimeStepType::System,
17864 : OutputProcessor::StoreType::Average,
17865 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17866 310 : SetupOutputVariable(state,
17867 : "Zone Water to Air Heat Pump Sensible Heating Energy",
17868 : Constant::Units::J,
17869 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17870 : OutputProcessor::TimeStepType::System,
17871 : OutputProcessor::StoreType::Sum,
17872 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17873 310 : SetupOutputVariable(state,
17874 : "Zone Water to Air Heat Pump Sensible Cooling Rate",
17875 : Constant::Units::W,
17876 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17877 : OutputProcessor::TimeStepType::System,
17878 : OutputProcessor::StoreType::Average,
17879 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17880 310 : SetupOutputVariable(state,
17881 : "Zone Water to Air Heat Pump Sensible Cooling Energy",
17882 : Constant::Units::J,
17883 155 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17884 : OutputProcessor::TimeStepType::System,
17885 : OutputProcessor::StoreType::Sum,
17886 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17887 310 : SetupOutputVariable(state,
17888 : "Zone Water to Air Heat Pump Latent Heating Rate",
17889 : Constant::Units::W,
17890 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17891 : OutputProcessor::TimeStepType::System,
17892 : OutputProcessor::StoreType::Average,
17893 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17894 310 : SetupOutputVariable(state,
17895 : "Zone Water to Air Heat Pump Latent Heating Energy",
17896 : Constant::Units::J,
17897 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17898 : OutputProcessor::TimeStepType::System,
17899 : OutputProcessor::StoreType::Sum,
17900 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17901 310 : SetupOutputVariable(state,
17902 : "Zone Water to Air Heat Pump Latent Cooling Rate",
17903 : Constant::Units::W,
17904 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17905 : OutputProcessor::TimeStepType::System,
17906 : OutputProcessor::StoreType::Average,
17907 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17908 310 : SetupOutputVariable(state,
17909 : "Zone Water to Air Heat Pump Latent Cooling Energy",
17910 : Constant::Units::J,
17911 155 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17912 : OutputProcessor::TimeStepType::System,
17913 : OutputProcessor::StoreType::Sum,
17914 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17915 310 : SetupOutputVariable(state,
17916 : "Zone Water to Air Heat Pump Electricity Rate",
17917 : Constant::Units::W,
17918 155 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17919 : OutputProcessor::TimeStepType::System,
17920 : OutputProcessor::StoreType::Average,
17921 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17922 310 : SetupOutputVariable(state,
17923 : "Zone Water to Air Heat Pump Electricity Energy",
17924 : Constant::Units::J,
17925 155 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17926 : OutputProcessor::TimeStepType::System,
17927 : OutputProcessor::StoreType::Sum,
17928 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17929 310 : SetupOutputVariable(state,
17930 : "Zone Water to Air Heat Pump Fan Part Load Ratio",
17931 : Constant::Units::None,
17932 155 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17933 : OutputProcessor::TimeStepType::System,
17934 : OutputProcessor::StoreType::Average,
17935 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17936 310 : SetupOutputVariable(state,
17937 : "Zone Water to Air Heat Pump Compressor Part Load Ratio",
17938 : Constant::Units::None,
17939 155 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17940 : OutputProcessor::TimeStepType::System,
17941 : OutputProcessor::StoreType::Average,
17942 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17943 155 : SetupOutputVariable(state,
17944 : "Zone Water to Air Heat Pump Fan Availability Status",
17945 : Constant::Units::None,
17946 155 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17947 : OutputProcessor::TimeStepType::System,
17948 : OutputProcessor::StoreType::Average,
17949 155 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17950 155 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
17951 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
17952 310 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedCooling > 1) ||
17953 153 : ((state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
17954 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
17955 153 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedHeating > 1)) {
17956 4 : SetupOutputVariable(state,
17957 : "Unitary System Water Coil Multispeed Fan Cycling Ratio",
17958 : Constant::Units::None,
17959 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17960 : OutputProcessor::TimeStepType::System,
17961 : OutputProcessor::StoreType::Average,
17962 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17963 4 : SetupOutputVariable(state,
17964 : "Unitary System Water Coil Multispeed Fan Speed Ratio",
17965 : Constant::Units::None,
17966 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17967 : OutputProcessor::TimeStepType::System,
17968 : OutputProcessor::StoreType::Average,
17969 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17970 2 : SetupOutputVariable(state,
17971 : "Unitary System Water Coil Multispeed Fan Speed Level",
17972 : Constant::Units::None,
17973 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17974 : OutputProcessor::TimeStepType::System,
17975 : OutputProcessor::StoreType::Average,
17976 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17977 : }
17978 155 : break;
17979 0 : default:
17980 0 : ShowFatalError(state,
17981 : "setupAllOutputVar: Developer error. All report variables must be set up here after all systems are read in.");
17982 : }
17983 : }
17984 165 : state.dataUnitarySystems->setupOutputOnce = false;
17985 : } else {
17986 0 : ShowSevereError(state,
17987 : "setupAllOutputVar: Developer error. Should never get here. Remove when comfortable that UnitarySys::allocateUnitarySys "
17988 : "is working as expected.");
17989 0 : ShowFatalError(state, "setupAllOutputVar: Developer error. Conflict in number of UnitarySystems.");
17990 : }
17991 165 : }
17992 :
17993 61 : void isWaterCoilHeatRecoveryType(EnergyPlusData const &state, int const waterCoilNodeNum, bool &nodeNotFound)
17994 : {
17995 61 : if (!nodeNotFound) {
17996 60 : return;
17997 : }
17998 1 : nodeNotFound = std::none_of(
17999 2 : state.dataUnitarySystems->unitarySys.cbegin(), state.dataUnitarySystems->unitarySys.cend(), [waterCoilNodeNum](auto const &us) {
18000 1 : return us.m_WaterHRPlantLoopModel && us.m_HRcoolCoilFluidInletNode == waterCoilNodeNum;
18001 : });
18002 : }
18003 :
18004 470139 : Real64 UnitarySys::getFanDeltaTemp(EnergyPlusData &state, bool const firstHVACIteration, Real64 const massFlowRate, Real64 const airFlowRatio)
18005 : {
18006 470139 : int FanInletNode = 0;
18007 470139 : int FanOutletNode = 0;
18008 :
18009 470139 : auto *fan = state.dataFans->fans(this->m_FanIndex);
18010 470139 : FanInletNode = fan->inletNodeNum;
18011 470139 : FanOutletNode = fan->outletNodeNum;
18012 470139 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = massFlowRate;
18013 470139 : fan->simulate(state, firstHVACIteration, airFlowRatio, _, airFlowRatio, _, _, _);
18014 470139 : return state.dataLoopNodes->Node(FanOutletNode).Temp - state.dataLoopNodes->Node(FanInletNode).Temp;
18015 : }
18016 :
18017 175588 : void UnitarySys::setEconomizerStagingOperationSpeed(EnergyPlusData &state, bool const firstHVACIteration, Real64 const zoneLoad)
18018 : {
18019 175588 : this->m_LowSpeedEconOutput = 0;
18020 175588 : this->m_LowSpeedEconRuntime = 0;
18021 175588 : this->m_EconoPartLoadRatio = 0;
18022 175588 : this->m_EconoSpeedNum = 0;
18023 175588 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
18024 175588 : Real64 mixedTempAtMinOA = 0;
18025 175588 : Real64 highSpeedEconMassFlowRate = 0;
18026 175588 : Real64 highSpeedFanDT = 0;
18027 175588 : Real64 econClgOutput = 0;
18028 175588 : Real64 lowSpeedEconMassFlowRate = 0;
18029 175588 : Real64 lowSpeedFanDT = 0;
18030 175588 : Real64 highSpeedEconRuntime = 0;
18031 175588 : Real64 econClgOutputMinOA = 0;
18032 : // determine outdoor air properties
18033 : using Psychrometrics::PsyCpAirFnW;
18034 175588 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
18035 175588 : Real64 outdoorAirTemp = state.dataLoopNodes->Node(outdoorAirController.InletNode).Temp;
18036 175588 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
18037 : // iterate through the unitary system's cooling speed to see at which
18038 : // air flow rate the load can be met at 100% outdoor air fraction
18039 284768 : for (int clgSpd = 1; clgSpd <= this->m_NumOfSpeedCooling; ++clgSpd) {
18040 : // calculations for "high speed" refer to operation at the current
18041 : // cooling speed, "clgSpd", and "low speed" is "clgSpd -1"
18042 284768 : highSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd];
18043 : // determine air temperature difference for across the fan at this air flow rate
18044 284768 : highSpeedFanDT = this->getFanDeltaTemp(state,
18045 : firstHVACIteration,
18046 : highSpeedEconMassFlowRate,
18047 284768 : highSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18048 284768 : econClgOutput = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + highSpeedFanDT));
18049 : // check if economizer alone can meet the load, or if we have reached the maximum cooling speed
18050 284768 : if (econClgOutput > std::abs(zoneLoad) || clgSpd == this->m_NumOfSpeedCooling) {
18051 : // low speed economizer operation is handled through normal process (i.e., no staging operation)
18052 175588 : if (clgSpd > 1) {
18053 : // check that the system output at the minimum outdoor air flow rate doesn't "overcool" at this speed
18054 84835 : mixedTempAtMinOA = 0;
18055 84835 : if (highSpeedEconMassFlowRate - outdoorAirController.MinOA > 0) {
18056 84835 : mixedTempAtMinOA =
18057 84835 : (outdoorAirTemp * outdoorAirController.MinOA + state.dataLoopNodes->Node(outdoorAirController.RetNode).Temp *
18058 84835 : (highSpeedEconMassFlowRate - outdoorAirController.MinOA)) /
18059 : highSpeedEconMassFlowRate;
18060 : } else {
18061 0 : mixedTempAtMinOA = outdoorAirTemp;
18062 : }
18063 84835 : econClgOutputMinOA = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (mixedTempAtMinOA + highSpeedFanDT));
18064 84835 : if (econClgOutputMinOA < std::abs(zoneLoad)) {
18065 75052 : highSpeedEconRuntime = 1.0;
18066 : } else {
18067 : // if running at this speed would "overcool", we run partly at the lower speed and partly at this speed
18068 9783 : lowSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd - 1];
18069 9783 : lowSpeedFanDT = this->getFanDeltaTemp(state,
18070 : firstHVACIteration,
18071 : lowSpeedEconMassFlowRate,
18072 9783 : lowSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18073 9783 : this->m_LowSpeedEconOutput = cpAir * lowSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + lowSpeedFanDT));
18074 : // determine this speed's runtime
18075 9783 : highSpeedEconRuntime = (std::abs(zoneLoad) - this->m_LowSpeedEconOutput) / (econClgOutput - this->m_LowSpeedEconOutput);
18076 : }
18077 : } else {
18078 90753 : highSpeedEconRuntime = 1.0;
18079 : }
18080 : // set economizer air flow "speed"
18081 175588 : this->m_EconoSpeedNum = clgSpd;
18082 : // set economizer PLR, a.k.a the system fan part load ratio, and runtime at each speed
18083 175588 : this->m_EconoPartLoadRatio = highSpeedEconRuntime;
18084 175588 : this->m_LowSpeedEconRuntime = 1 - highSpeedEconRuntime;
18085 175588 : break;
18086 : }
18087 : }
18088 175588 : }
18089 :
18090 175588 : void UnitarySys::calcMixedTempAirSPforEconomizerStagingOperation(EnergyPlusData &state,
18091 : int const airLoopNum,
18092 : bool const firstHVACIteration,
18093 : Real64 const zoneLoad)
18094 : {
18095 175588 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
18096 : using Psychrometrics::PsyCpAirFnW;
18097 175588 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
18098 175588 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
18099 : // determine and set new air loop mixed air flow rate
18100 175588 : Real64 mixedAirFlowRate = this->m_EconoPartLoadRatio * this->m_CoolMassFlowRate[this->m_EconoSpeedNum] +
18101 175588 : this->m_LowSpeedEconRuntime * this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
18102 175588 : if (airLoopNum > 0) {
18103 : // request fixed mixed flow rate
18104 175588 : state.dataAirLoop->AirLoopControlInfo(airLoopNum).LoopFlowRateSet = true;
18105 175588 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac = mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
18106 : // adjust mixed air flow rate for rated air flow rate adjustment (variable speed coils only)
18107 175588 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac *=
18108 175588 : this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling] / state.dataAirLoop->AirLoopFlow(airLoopNum).DesSupply;
18109 : }
18110 : // determine air temperature difference across fan based on new mixed air flow rate
18111 175588 : int mixedAirNode = outdoorAirController.MixNode;
18112 175588 : Real64 fanDTAtMixedAirFlowRate = this->getFanDeltaTemp(
18113 175588 : state, firstHVACIteration, mixedAirFlowRate, mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18114 : // determine new mixed air setpoint
18115 175588 : Real64 newMixedAirSP = zoneTemp - std::abs(zoneLoad) / (cpAir * mixedAirFlowRate);
18116 175588 : state.dataLoopNodes->Node(mixedAirNode).TempSetPoint = newMixedAirSP - fanDTAtMixedAirFlowRate;
18117 175588 : }
18118 :
18119 : void
18120 737912 : UnitarySys::manageEconomizerStagingOperation(EnergyPlusData &state, int const airLoopNum, bool const firstHVACIteration, Real64 const zoneLoad)
18121 : {
18122 737912 : if (airLoopNum > 0) {
18123 961520 : if (state.dataAirLoop->AirLoopControlInfo(airLoopNum).EconoActive == true && state.dataGlobal->WarmupFlag == false &&
18124 223608 : state.dataUnitarySystems->CoolingLoad) {
18125 175588 : this->setEconomizerStagingOperationSpeed(state, firstHVACIteration, zoneLoad);
18126 :
18127 : // adjustments are only needed when economizer speed is greater than the lowest speed
18128 175588 : if (this->m_EconoSpeedNum > 0) {
18129 175588 : this->calcMixedTempAirSPforEconomizerStagingOperation(state, airLoopNum, firstHVACIteration, zoneLoad);
18130 :
18131 : // recalculate the outdoor air fraction to meet the new mixed air setpoint at the new mixed air flow rate
18132 351176 : MixedAir::ManageOutsideAirSystem(
18133 175588 : state, state.dataAirLoop->OutsideAirSys(this->OASysIndex).Name, firstHVACIteration, airLoopNum, this->OASysIndex);
18134 : }
18135 : }
18136 : }
18137 737912 : }
18138 :
18139 : } // namespace UnitarySystems
18140 : } // namespace EnergyPlus
|