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 72352 : 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 72352 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
131 :
132 : // Obtains and Allocates unitary system related parameters from input file
133 72352 : if (this->m_ThisSysInputShouldBeGotten) {
134 27 : getUnitarySystemInput(state, Name, ZoneEquipment, ZoneOAUnitNum);
135 : }
136 72352 : CompIndex = this->m_EquipCompNum;
137 72352 : state.dataUnitarySystems->FanSpeedRatio = 1.0;
138 72352 : this->initUnitarySystems(state, AirLoopNum, FirstHVACIteration, OAUCoilOutTemp);
139 72352 : 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 72352 : 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 72352 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
148 8 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = this->m_DesignMassFlowRate;
149 : }
150 :
151 72352 : bool HXUnitOn = false;
152 72352 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
153 65316 : this->controlUnitarySystemtoSP(
154 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
155 : } else {
156 7036 : this->controlUnitarySystemtoLoad(
157 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
158 : }
159 :
160 : // Report the current output
161 72352 : this->reportUnitarySystem(state, AirLoopNum);
162 :
163 : // CoolActive = false; // set in call from ZoneEquipmentManager
164 72352 : if (this->m_CoolingPartLoadFrac * double(CompressorOn) > 0.0) {
165 26303 : CoolActive = true;
166 : }
167 : // HeatActive = false; // set in call from ZoneEquipmentManager
168 72352 : if (this->m_HeatingPartLoadFrac * double(CompressorOn) > 0.0 || this->m_SuppHeatPartLoadFrac * double(CompressorOn) > 0.0) {
169 2777 : HeatActive = true;
170 : }
171 :
172 : // set econo lockout flag
173 : // If the system is not an equipment of Outdoor air unit
174 72352 : if (AirLoopNum > 0 && !state.dataAirLoop->AirLoopControlInfo.empty() && this->m_AirLoopEquipment) {
175 :
176 50710 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor =
177 50710 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor &&
178 0 : (this->m_HeatCompPartLoadRatio > 0.0 || this->m_SpeedRatio > 0.0 || this->m_CycRatio > 0.0);
179 :
180 50710 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating =
181 50714 : HeatActive && (state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor ||
182 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithHeating);
183 : }
184 :
185 : // Calculate heat recovery
186 72352 : if (this->m_HeatRecActive) {
187 1 : 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 72352 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
195 8 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = tempMassFlowRateMaxAvail;
196 : }
197 : }
198 :
199 49 : DesignSpecMSHP *DesignSpecMSHP::factory(EnergyPlusData &state, HVAC::UnitarySysType type, std::string const &objectName)
200 : {
201 :
202 49 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
203 22 : DesignSpecMSHP::getDesignSpecMSHP(state);
204 22 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
205 : }
206 51 : for (auto &dSpec : state.dataUnitarySystems->designSpecMSHP) {
207 49 : if (Util::SameString(dSpec.name, objectName) && dSpec.m_type == type) {
208 47 : return &dSpec;
209 : }
210 96 : }
211 2 : ShowSevereError(state, format("Design Specification MultiSpeed Heat Pump factory: Error getting inputs for system named: {}", objectName));
212 2 : 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 1 : errorsFound = true;
233 : } else {
234 21 : int designSpecNum = 0;
235 21 : auto &instancesValue = instances.value();
236 43 : 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 22 : int TotalArgs = 0;
240 22 : int NumAlphas = 0;
241 22 : int NumNumbers = 0;
242 22 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
243 22 : int IOStatus = 0;
244 22 : Array1D_string Alphas(NumAlphas);
245 22 : Array1D<Real64> Numbers(NumNumbers, 0.0);
246 22 : Array1D_bool lNumericBlanks(NumNumbers, true);
247 22 : Array1D_bool lAlphaBlanks(NumAlphas, true);
248 22 : Array1D_string cAlphaFields(NumAlphas);
249 22 : Array1D_string cNumericFields(NumNumbers);
250 22 : 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 22 : auto const &fields = instance.value();
265 22 : std::string const &thisObjectName = instance.key();
266 22 : DesignSpecMSHP thisDesignSpec;
267 :
268 22 : thisDesignSpec.name = Util::makeUPPER(thisObjectName);
269 44 : thisDesignSpec.numOfSpeedHeating = fields.at("number_of_speeds_for_heating").get<int>(); // required field
270 22 : thisDesignSpec.numOfSpeedCooling = fields.at("number_of_speeds_for_cooling").get<int>(); // required field
271 22 : int maxSpeeds = max(thisDesignSpec.numOfSpeedHeating, thisDesignSpec.numOfSpeedCooling);
272 22 : thisDesignSpec.m_type = HVAC::UnitarySysType::Furnace_HeatOnly; // add global int value for factory
273 :
274 44 : if (auto it = fields.find("single_mode_operation"); it != fields.end()) { // not required field
275 22 : std::string loc_m_SingleModeOp = Util::makeUPPER(it.value().get<std::string>());
276 22 : if (Util::SameString(loc_m_SingleModeOp, "Yes")) {
277 1 : thisDesignSpec.m_SingleModeFlag = true;
278 : }
279 44 : }
280 :
281 44 : if (auto it = fields.find("no_load_supply_air_flow_rate_ratio"); it != fields.end()) { // not required field
282 7 : thisDesignSpec.noLoadAirFlowRateRatio = it.value().get<Real64>();
283 22 : }
284 :
285 22 : thisDesignSpec.heatingVolFlowRatio.resize(maxSpeeds + 1);
286 22 : thisDesignSpec.coolingVolFlowRatio.resize(maxSpeeds + 1);
287 :
288 22 : auto speedFlowRatios = fields.find("flow_ratios");
289 22 : if (speedFlowRatios != fields.end()) {
290 22 : auto &flowRatioArray = speedFlowRatios.value();
291 22 : int numSpeedInputs = flowRatioArray.size();
292 22 : if (numSpeedInputs >= maxSpeeds) {
293 22 : int speedNum = -1;
294 105 : for (auto const &flowRatio : flowRatioArray) {
295 83 : speedNum += 1;
296 83 : if (speedNum < (maxSpeeds + 1)) {
297 76 : auto &cobj = flowRatio.at("cooling_speed_supply_air_flow_ratio");
298 76 : thisDesignSpec.coolingVolFlowRatio[speedNum] =
299 118 : (cobj.type() == nlohmann::detail::value_t::string && Util::SameString(cobj.get<std::string>(), "Autosize"))
300 118 : ? DataSizing::AutoSize
301 34 : : cobj.get<Real64>();
302 :
303 76 : auto &hobj = flowRatio.at("heating_speed_supply_air_flow_ratio");
304 76 : thisDesignSpec.heatingVolFlowRatio[speedNum] =
305 118 : (hobj.type() == nlohmann::detail::value_t::string && Util::SameString(hobj.get<std::string>(), "Autosize"))
306 118 : ? DataSizing::AutoSize
307 34 : : hobj.get<Real64>();
308 : }
309 22 : }
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 22 : state.dataUnitarySystems->designSpecMSHP.push_back(thisDesignSpec);
320 43 : }
321 : }
322 22 : } // namespace UnitarySystems
323 :
324 133 : HVACSystemData *UnitarySys::factory(
325 : EnergyPlusData &state, HVAC::UnitarySysType const type, std::string const &objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
326 : {
327 133 : if (state.dataUnitarySystems->getInputOnceFlag) {
328 91 : UnitarySys::getUnitarySystemInput(state, objectName, ZoneEquipment, ZoneOAUnitNum);
329 91 : state.dataUnitarySystems->getInputOnceFlag = false;
330 : }
331 133 : int sysNum = -1;
332 152 : for (auto &sys : state.dataUnitarySystems->unitarySys) {
333 152 : ++sysNum;
334 152 : if (Util::SameString(sys.Name, objectName) && type == HVAC::UnitarySysType::Unitary_AnyCoilType) {
335 133 : state.dataUnitarySystems->unitarySys[sysNum].m_UnitarySysNum = sysNum;
336 133 : return &sys;
337 : }
338 266 : }
339 0 : ShowFatalError(state, format("UnitarySystem factory: Error getting inputs for system named: {}", objectName));
340 0 : return nullptr;
341 : }
342 :
343 49 : 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 49 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
349 0 : DesignSpecMSHP::getDesignSpecMSHP(state);
350 0 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
351 : }
352 49 : int index = -1;
353 51 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->designSpecMSHP.size(); ++loop) {
354 49 : DesignSpecMSHP *thisDesignSpecMSHPObjec = &state.dataUnitarySystems->designSpecMSHP[loop];
355 49 : if (Util::SameString(objectName, thisDesignSpecMSHPObjec->name)) {
356 47 : index = loop;
357 47 : return index;
358 : }
359 : }
360 2 : ShowSevereError(state, format("getDesignSpecMSHPIndex: did not find UnitarySystemPerformance:Multispeed name ={}. Check inputs", objectName));
361 2 : return index;
362 : }
363 :
364 406 : 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 406 : int index = -1;
370 705 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->unitarySys.size(); ++loop) {
371 503 : UnitarySys *thisUnitarySysObjec = &state.dataUnitarySystems->unitarySys[loop];
372 503 : if (Util::SameString(objectName, thisUnitarySysObjec->Name)) {
373 204 : index = loop;
374 204 : break;
375 : }
376 : }
377 406 : return index;
378 : }
379 :
380 72365 : 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 151809 : if (this->m_IsZoneEquipment &&
386 79345 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
387 6980 : !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 6966 : DataZoneEquipment::ZoneEquipType thisObjectType = DataZoneEquipment::ZoneEquipType::Invalid;
392 6966 : switch (this->m_sysType) {
393 18 : case SysType::PackagedAC:
394 18 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
395 18 : break;
396 0 : case SysType::PackagedHP:
397 0 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump;
398 0 : break;
399 6948 : case SysType::PackagedWSHP:
400 6948 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir;
401 6948 : break;
402 0 : default:
403 0 : break;
404 : }
405 6966 : if (this->m_ZoneCompFlag) {
406 8 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).AvailManagerListName = this->m_AvailManagerListName;
407 8 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).ZoneNum = this->ControlZoneNum;
408 8 : this->m_ZoneCompFlag = false;
409 : }
410 6966 : 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 72365 : if (!state.dataGlobal->SysSizingCalc && this->m_MySizingCheckFlag && !this->m_ThisSysInputShouldBeGotten) {
416 53 : if (AirLoopNum > 0) {
417 18 : if (this->m_FanExists && (this->m_CoolCoilExists && (this->m_HeatCoilExists || this->m_SuppCoilExists))) {
418 1 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
419 : }
420 18 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
421 18 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
422 2 : 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 18 : if (!this->m_FanExists) {
426 17 : if (state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanType != HVAC::FanType::Invalid) {
427 15 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
428 15 : if (this->m_CoolCoilExists) {
429 15 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
430 : state,
431 15 : this->m_CoolingCoilName,
432 15 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
433 15 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
434 15 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
435 : primaryAirSystems.supFanNum);
436 : }
437 15 : if (this->m_HeatCoilExists) {
438 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
439 : state,
440 0 : this->m_HeatingCoilName,
441 0 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
442 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
443 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
444 : primaryAirSystems.supFanNum);
445 : }
446 15 : 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 53 : this->sizeSystem(state, FirstHVACIteration, AirLoopNum);
459 53 : this->m_MySizingCheckFlag = false;
460 53 : if (AirLoopNum > 0) {
461 18 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = this->m_FanOpMode;
462 18 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).cycFanSched = this->m_fanOpModeSched;
463 35 : } else if (AirLoopNum < 0) {
464 1 : 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 72365 : if (this->m_MyFanFlag) { // should include " && !this->m_MySizingCheckFlag"
473 98 : if (this->m_ActualFanVolFlowRate != DataSizing::AutoSize) {
474 57 : if (this->m_ActualFanVolFlowRate > 0.0) {
475 57 : this->m_HeatingFanSpeedRatio = this->m_MaxHeatAirVolFlow / this->m_ActualFanVolFlowRate;
476 57 : this->m_CoolingFanSpeedRatio = this->m_MaxCoolAirVolFlow / this->m_ActualFanVolFlowRate;
477 57 : this->m_NoHeatCoolSpeedRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
478 57 : if (this->m_FanExists && !this->m_MultiOrVarSpeedHeatCoil && !this->m_MultiOrVarSpeedCoolCoil) {
479 21 : bool fanHasPowerSpeedRatioCurve = false;
480 21 : if (this->m_FanType == HVAC::FanType::SystemModel) {
481 1 : if (dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex))->powerModFuncFlowFracCurveNum > 0) {
482 0 : fanHasPowerSpeedRatioCurve = true;
483 : }
484 : } else {
485 20 : if (dynamic_cast<Fans::FanComponent *>(state.dataFans->fans(this->m_FanIndex))->powerRatioAtSpeedRatioCurveNum > 0) {
486 0 : fanHasPowerSpeedRatioCurve = true;
487 : }
488 : }
489 21 : if (fanHasPowerSpeedRatioCurve) {
490 :
491 0 : if (this->m_ActualFanVolFlowRate == this->m_MaxHeatAirVolFlow &&
492 0 : this->m_ActualFanVolFlowRate == this->m_MaxCoolAirVolFlow &&
493 0 : this->m_ActualFanVolFlowRate == this->m_MaxNoCoolHeatAirVolFlow) {
494 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
495 0 : ShowContinueError(
496 0 : state, format("...For fan type and name = {} \"{}\"", HVAC::fanTypeNames[(int)this->m_FanType], this->m_FanName));
497 0 : 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 0 : ShowContinueError(state,
501 0 : format("...Fan volumetric flow rate = {:.5R} m3/s.", this->m_ActualFanVolFlowRate));
502 0 : ShowContinueError(state, format("...Unitary system volumetric flow rate = {:.5R} m3/s.", this->m_MaxHeatAirVolFlow));
503 : }
504 : }
505 : }
506 57 : if (this->m_MultiOrVarSpeedHeatCoil || this->m_MultiOrVarSpeedCoolCoil) {
507 20 : if (this->m_MultiOrVarSpeedCoolCoil) {
508 14 : int NumSpeeds = this->m_NumOfSpeedCooling;
509 14 : if (this->m_MSCoolingSpeedRatio.empty()) {
510 0 : this->m_MSCoolingSpeedRatio.resize(NumSpeeds + 1);
511 : }
512 14 : if (this->m_CoolVolumeFlowRate.empty()) {
513 0 : this->m_CoolVolumeFlowRate.resize(NumSpeeds + 1);
514 : }
515 77 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
516 63 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
517 : }
518 : }
519 20 : if (this->m_MultiOrVarSpeedHeatCoil) {
520 12 : int NumSpeeds = this->m_NumOfSpeedHeating;
521 12 : if (this->m_MSHeatingSpeedRatio.empty()) {
522 0 : this->m_MSHeatingSpeedRatio.resize(NumSpeeds + 1);
523 : }
524 12 : if (this->m_HeatVolumeFlowRate.empty()) {
525 0 : this->m_HeatVolumeFlowRate.resize(NumSpeeds + 1);
526 : }
527 61 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
528 49 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
529 : }
530 : }
531 20 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
532 : }
533 : }
534 57 : this->m_MyFanFlag = false;
535 : } else {
536 41 : if (this->m_FanExists) {
537 41 : 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 72365 : if (this->m_MyPlantScanFlag && !state.dataPlnt->PlantLoop.empty()) {
545 28 : 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 28 : DataPlant::PlantEquipmentType TypeOfCoilWaterCooling{DataPlant::PlantEquipmentType::Invalid};
562 28 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed ||
563 22 : this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
564 12 : std::string CoolingCoilType = "";
565 6 : std::string CoolingCoilName = "";
566 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
567 6 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
568 6 : CoolingCoilType = "Coil:Cooling:Water";
569 6 : 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 6 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
594 12 : PlantUtilities::ScanPlantLoopsForObject(state,
595 : CoolingCoilName,
596 : TypeOfCoilWaterCooling,
597 6 : this->CoolCoilPlantLoc,
598 6 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
599 : _,
600 : _,
601 : _,
602 : _,
603 : _);
604 6 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
605 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
606 : }
607 6 : this->MaxCoolCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
608 6 : state, CoolingCoilType, CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
609 :
610 6 : if (this->MaxCoolCoilFluidFlow > 0.0) {
611 : Real64 rho =
612 6 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
613 6 : this->MaxCoolCoilFluidFlow *= rho;
614 : }
615 : // fill outlet node for coil
616 6 : this->CoolCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->CoolCoilPlantLoc).NodeNumOut;
617 6 : }
618 28 : DataPlant::PlantEquipmentType TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::Invalid;
619 28 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
620 2 : std::string HeatingCoilType = "";
621 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
622 2 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
623 2 : 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 2 : WaterCoils::SetCoilDesFlow(state,
628 2 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
629 2 : this->m_HeatingCoilName,
630 : this->m_MaxHeatAirVolFlow,
631 2 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
632 : } else {
633 0 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
634 0 : HeatingCoilType = "Coil:Heating:Steam";
635 : }
636 2 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
637 4 : PlantUtilities::ScanPlantLoopsForObject(state,
638 : this->m_HeatingCoilName,
639 : TypeOfCoilWaterHeating,
640 2 : this->HeatCoilPlantLoc,
641 2 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
642 : _,
643 : _,
644 : _,
645 : _,
646 : _);
647 2 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
648 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
649 : }
650 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
651 2 : this->MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
652 2 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
653 :
654 2 : 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 0 : this->MaxHeatCoilFluidFlow =
664 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
665 0 : if (this->MaxHeatCoilFluidFlow > 0.0) {
666 0 : Real64 TempSteamIn = 100.0;
667 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
668 0 : this->MaxHeatCoilFluidFlow *= SteamDensity;
669 : }
670 : }
671 : // fill outlet node for coil
672 2 : this->HeatCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->HeatCoilPlantLoc).NodeNumOut;
673 2 : }
674 :
675 28 : this->m_MyPlantScanFlag = false;
676 72337 : } else if (this->m_MyPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
677 41 : this->m_MyPlantScanFlag = false;
678 : }
679 :
680 : // Scan Supplemental hot water and steam heating coil plant components for one time initializations
681 72365 : if (this->m_MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
682 42 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
683 1 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
684 2 : PlantUtilities::ScanPlantLoopsForObject(state,
685 : this->m_SuppHeatCoilName,
686 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
687 1 : this->m_SuppCoilPlantLoc,
688 1 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
689 : _,
690 : _,
691 : _,
692 : _,
693 : _);
694 1 : WaterCoils::SetCoilDesFlow(state,
695 1 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
696 1 : this->m_SuppHeatCoilName,
697 : this->m_MaxHeatAirVolFlow,
698 1 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
699 :
700 1 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
701 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
702 : }
703 1 : this->m_MaxSuppCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
704 1 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
705 :
706 1 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
707 : Real64 rho =
708 1 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
709 1 : this->m_MaxSuppCoilFluidFlow =
710 1 : WaterCoils::GetCoilMaxWaterFlowRate(
711 2 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
712 : rho;
713 : }
714 : // fill outlet node for coil
715 1 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
716 :
717 41 : } 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 42 : this->m_MySuppCoilPlantScanFlag = false;
745 :
746 72323 : } else if (this->m_MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
747 27 : this->m_MySuppCoilPlantScanFlag = false;
748 : }
749 :
750 : // do the Begin Environment initializations
751 72365 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag) {
752 107 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
753 107 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
754 107 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
755 107 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
756 107 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
757 107 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
758 107 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
759 107 : if (this->OAMixerExists) {
760 2 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMax = max(this->m_CoolOutAirMassFlow, this->m_HeatOutAirMassFlow);
761 2 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMin = 0.0;
762 2 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMinAvail = 0.0;
763 : }
764 107 : this->m_CompPartLoadRatio = 0.0;
765 107 : this->m_CoolingCoilSensDemand = 0.0;
766 107 : this->m_CoolingCoilLatentDemand = 0.0;
767 107 : this->m_HeatingCoilSensDemand = 0.0;
768 107 : this->m_SenLoadLoss = 0.0;
769 107 : if (this->m_Humidistat) {
770 4 : this->m_LatLoadLoss = 0.0;
771 : }
772 :
773 107 : 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 107 : if (this->CoolCoilFluidInletNode > 0) {
784 :
785 3 : 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 0 : std::string CoolingCoilType = "";
788 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
789 0 : CoolingCoilType = "Coil:Cooling:Water";
790 : } else {
791 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
792 : }
793 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex);
794 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
795 0 : state, CoolingCoilType, this->m_CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
796 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
797 0 : Real64 rho = state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum)
798 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
799 0 : this->MaxCoolCoilFluidFlow = CoilMaxVolFlowRate * rho;
800 : }
801 0 : }
802 :
803 3 : PlantUtilities::InitComponentNodes(
804 : state, 0.0, this->MaxCoolCoilFluidFlow, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum);
805 : }
806 107 : if (this->HeatCoilFluidInletNode > 0) {
807 :
808 2 : 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 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
811 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
812 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
813 0 : state, "Coil:Heating:Water", this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
814 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
815 0 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
816 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
817 0 : 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 0 : 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 2 : PlantUtilities::InitComponentNodes(
840 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
841 : }
842 107 : if (this->m_SuppCoilFluidInletNode > 0) {
843 1 : 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 107 : this->m_MyEnvrnFlag = false;
876 : }
877 :
878 72365 : if (!state.dataGlobal->BeginEnvrnFlag) {
879 71622 : this->m_MyEnvrnFlag = true;
880 : }
881 :
882 : // Init maximum available Heat Recovery flow rate
883 72365 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
884 1 : Real64 mdotHR = 0.0;
885 1 : if (this->m_sysAvailSched->getCurrentVal() > 0.0) {
886 1 : if (FirstHVACIteration) {
887 1 : 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 1 : mdotHR = min(state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).MassFlowRateMaxAvail, mdotHR);
900 1 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate = mdotHR;
901 : }
902 :
903 : // get operating capacity of water and steam coil
904 72365 : if (FirstHVACIteration || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
905 35871 : if (FirstHVACIteration) {
906 35859 : this->m_IterationCounter = 0;
907 35859 : 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 35859 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint && this->m_sysType == SysType::Unitary && this->m_FanExists) {
911 1 : if (this->m_sysAvailSched->getCurrentVal() > 0.0) {
912 1 : if (this->m_LastMode == CoolingMode) {
913 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
914 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
915 : } else {
916 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxCoolAirMassFlow;
917 : }
918 1 : } else if (this->m_LastMode == HeatingMode) {
919 0 : if (this->m_MultiOrVarSpeedHeatCoil) {
920 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_HeatMassFlowRate[this->m_NumOfSpeedHeating];
921 : } else {
922 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxHeatAirMassFlow;
923 : }
924 : } else {
925 1 : if (this->m_MultiOrVarSpeedCoolCoil) {
926 1 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
927 : } else {
928 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
929 : }
930 : }
931 : } else {
932 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = 0.0;
933 : }
934 : }
935 35859 : if (this->m_WaterHRPlantLoopModel) {
936 : // initialize loop water temp on FirstHVACIteration
937 2 : Real64 airInTemp = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp;
938 2 : Real64 companionAirInTemp = state.dataLoopNodes->Node(this->m_HRcoolCoilAirInNode).Temp;
939 2 : Real64 oneHalfAirDeltaT = (companionAirInTemp - airInTemp) / 2.0;
940 2 : Real64 initialLoopTemp = airInTemp + oneHalfAirDeltaT;
941 2 : if (initialLoopTemp > this->m_minWaterLoopTempForHR && std::abs(oneHalfAirDeltaT) > this->m_minAirToWaterTempOffset) {
942 2 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp = initialLoopTemp;
943 2 : this->temperatureOffsetControlStatus = 1;
944 : } else {
945 0 : this->temperatureOffsetControlStatus = 0;
946 : }
947 : }
948 : }
949 35871 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
950 :
951 : // set water-side mass flow rates
952 13 : Real64 mdot = this->MaxCoolCoilFluidFlow;
953 13 : PlantUtilities::SetComponentFlowRate(
954 13 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
955 : // simulate water coil to find operating capacity
956 26 : WaterCoils::SimulateWaterCoilComponents(state,
957 : this->m_CoolingCoilName,
958 : FirstHVACIteration,
959 13 : this->m_CoolingCoilIndex,
960 13 : state.dataUnitarySystems->initUnitarySystemsQActual);
961 13 : this->m_DesignCoolingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
962 :
963 : } // from IF(UnitarySystem(UnitarySysNum)%CoolingCoilType_Num == Coil_CoolingWater .OR. Coil_CoolingWaterDetailed
964 35871 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
965 :
966 : // set water-side mass flow rates
967 1 : Real64 mdot = this->MaxHeatCoilFluidFlow;
968 1 : PlantUtilities::SetComponentFlowRate(
969 1 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
970 : // simulate water coil to find operating capacity
971 2 : WaterCoils::SimulateWaterCoilComponents(state,
972 : this->m_HeatingCoilName,
973 : FirstHVACIteration,
974 1 : this->m_HeatingCoilIndex,
975 1 : state.dataUnitarySystems->initUnitarySystemsQActual);
976 1 : this->m_DesignHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
977 :
978 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingWater) THEN
979 :
980 35871 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
981 :
982 : // set water-side mass flow rates
983 0 : Real64 mdot = this->MaxHeatCoilFluidFlow;
984 0 : PlantUtilities::SetComponentFlowRate(
985 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
986 : // simulate steam coil to find operating capacity
987 0 : SteamCoils::SimulateSteamCoilComponents(
988 : state,
989 : this->m_HeatingCoilName,
990 : FirstHVACIteration,
991 0 : this->m_HeatingCoilIndex,
992 0 : 1.0,
993 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
994 0 : this->m_DesignHeatingCapacity = SteamCoils::GetCoilCapacity(state,
995 0 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
996 0 : this->m_HeatingCoilName,
997 0 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
998 :
999 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
1000 35871 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
1001 :
1002 : // set steam-side mass flow rates
1003 1 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
1004 1 : PlantUtilities::SetComponentFlowRate(
1005 1 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1006 : // simulate water coil to find operating capacity
1007 1 : 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 2 : WaterCoils::SimulateWaterCoilComponents(state,
1010 : this->m_SuppHeatCoilName,
1011 : FirstHVACIteration,
1012 1 : this->m_SuppHeatCoilIndex,
1013 1 : state.dataUnitarySystems->initUnitarySystemsQActual);
1014 1 : 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 35871 : 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 72365 : this->m_IterationCounter += 1;
1042 :
1043 72365 : if (this->m_MySetPointCheckFlag) {
1044 183 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACGlobal->DoSetPointTest) {
1045 33 : bool e = false;
1046 33 : if (this->m_CoolCoilExists) {
1047 24 : e = this->checkNodeSetPoint(state, AirLoopNum, this->CoolCtrlNode, CoolingCoil, OAUCoilOutTemp);
1048 : }
1049 33 : if (this->m_HeatCoilExists) {
1050 13 : e = this->checkNodeSetPoint(state, AirLoopNum, this->HeatCtrlNode, HeatingCoil, OAUCoilOutTemp) || e;
1051 : }
1052 33 : if (this->m_SuppCoilExists) {
1053 5 : e = this->checkNodeSetPoint(state, AirLoopNum, this->SuppCtrlNode, SuppHeatCoil, OAUCoilOutTemp) || e;
1054 : }
1055 33 : if (e) {
1056 0 : ShowFatalError(state, "Previous errors cause termination.");
1057 : }
1058 33 : this->m_MySetPointCheckFlag = false;
1059 : }
1060 : }
1061 :
1062 72365 : if (m_setFaultModelInput) {
1063 34487 : if ((!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
1064 :
1065 : // check FaultsManager if connection exists
1066 64 : FaultsManager::SetFaultyCoilSATSensor(state, this->UnitType, this->Name, this->m_FaultyCoilSATFlag, this->m_FaultyCoilSATIndex);
1067 64 : 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 64 : m_setFaultModelInput = false;
1081 : }
1082 : }
1083 :
1084 : // re-set water-side economizer flags each time step
1085 72365 : if (this->m_TemperatureOffsetControlActive && !this->m_WaterHRPlantLoopModel) {
1086 5 : if (state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp >
1087 5 : (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 2 : this->temperatureOffsetControlStatus = 0;
1090 : } else {
1091 : // enable coilsystem waterside economizer mode
1092 3 : this->temperatureOffsetControlStatus = 1;
1093 : }
1094 : }
1095 72365 : if (AirLoopNum > 0) {
1096 50720 : if (this->m_sysType == SysType::CoilCoolingWater) {
1097 7 : if (this->m_waterSideEconomizerFlag) { // CoilSystem:Cooling:Water has an input for economizer lockout
1098 7 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1099 7 : if (state.dataUnitarySystems->economizerFlag) {
1100 : // user input economizer lockout will disable heat recovery loop AND water economizer
1101 2 : this->temperatureOffsetControlStatus = 0;
1102 : }
1103 : } else {
1104 0 : state.dataUnitarySystems->economizerFlag = false;
1105 : }
1106 : } else {
1107 50713 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1108 : }
1109 : // get OA controller info
1110 50720 : this->OASysIndex = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).OASysNum;
1111 50720 : if (this->OASysIndex > 0) {
1112 50696 : this->OAControllerIndex = state.dataAirLoop->OutsideAirSys(this->OASysIndex).OAControllerIndex;
1113 50696 : if (this->OAControllerIndex > 0) {
1114 50696 : this->OAControllerEconomizerStagingType = state.dataMixedAir->OAController(this->OAControllerIndex).EconomizerStagingType;
1115 : }
1116 : }
1117 : }
1118 :
1119 72365 : this->m_CoolingPartLoadFrac = 0.0;
1120 72365 : this->m_HeatingPartLoadFrac = 0.0;
1121 72365 : this->m_SuppHeatPartLoadFrac = 0.0;
1122 72365 : this->m_CoolingCycRatio = 0.0;
1123 72365 : this->m_CoolingSpeedRatio = 0.0;
1124 72365 : this->m_CoolingSpeedNum = 0;
1125 72365 : this->m_HeatingCycRatio = 0.0;
1126 72365 : this->m_HeatingSpeedRatio = 0.0;
1127 72365 : this->m_HeatingSpeedNum = 0;
1128 72365 : this->m_SuppHeatingSpeedNum = 0;
1129 72365 : this->m_HeatingCoilSensDemand = 0.0;
1130 72365 : this->m_CoolingCoilSensDemand = 0.0;
1131 72365 : this->m_CoolingCoilLatentDemand = 0.0;
1132 72365 : this->m_DehumidInducedHeatingDemandRate = 0.0;
1133 72365 : this->CoolCoilWaterFlowRatio = 0.0;
1134 72365 : this->HeatCoilWaterFlowRatio = 0.0;
1135 :
1136 : // water/steam coil initialization
1137 72365 : if (this->CoolCoilFluidInletNode > 0) {
1138 28 : Real64 mdot = 0.0;
1139 28 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
1140 : }
1141 72365 : if (this->HeatCoilFluidInletNode > 0) {
1142 15 : Real64 mdot = 0.0;
1143 15 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
1144 : }
1145 72365 : if (this->m_SuppCoilFluidInletNode > 0) {
1146 4 : Real64 mdot = 0.0;
1147 4 : PlantUtilities::SetComponentFlowRate(
1148 4 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1149 : }
1150 :
1151 72365 : this->m_InitHeatPump = true;
1152 72365 : state.dataUnitarySystems->m_massFlow1 = 0.0;
1153 72365 : state.dataUnitarySystems->m_massFlow2 = 0.0;
1154 72365 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
1155 72365 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
1156 72365 : 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 6980 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
1160 6980 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
1161 6980 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
1162 6980 : state.dataHVACGlobal->DefrostElecPower = 0.0;
1163 : }
1164 72365 : }
1165 :
1166 45 : 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 45 : bool SetPointErrorFlag = false;
1182 :
1183 45 : if (ControlNode == 0) {
1184 8 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1185 1 : int coilOutNode = this->CoolCoilOutletNodeNum;
1186 1 : if (CoilType == HeatingCoil) {
1187 1 : coilOutNode = this->HeatCoilOutletNodeNum;
1188 : }
1189 1 : if (CoilType == SuppHeatCoil) {
1190 0 : coilOutNode = this->SuppCoilOutletNodeNum;
1191 : }
1192 :
1193 1 : ShowSevereError(state, format("checkNodeSetPoint: Missing {} set point in {} = {}", coilTypes[CoilType], this->UnitType, this->Name));
1194 2 : ShowContinueError(state,
1195 3 : format("...Setpoint is required at system air outlet node = {} or {} coil air outlet node = {}",
1196 1 : state.dataLoopNodes->NodeID(this->AirOutNode),
1197 1 : coilTypes[CoilType],
1198 1 : state.dataLoopNodes->NodeID(coilOutNode)));
1199 1 : SetPointErrorFlag = true;
1200 : }
1201 8 : return SetPointErrorFlag;
1202 : }
1203 :
1204 37 : if (AirLoopNum == -1) { // Outdoor Air Unit
1205 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint = OAUCoilOutTemp; // Set the coil outlet temperature
1206 0 : 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 37 : 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 75 : if ((this->m_DehumidControlType_Num != DehumCtrlType::None) &&
1232 1 : (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) &&
1233 38 : 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 37 : return SetPointErrorFlag; // these later errors will also cause a fatal error
1253 : }
1254 :
1255 0 : 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 0 : int constexpr RunOnSensible(1); // identifier for temperature (sensible load) control
1275 0 : int constexpr RunOnLatent(2); // identifier for humidity (latent load) control
1276 : static constexpr std::string_view routineName("FrostControlSetPointLimit");
1277 :
1278 0 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate;
1279 0 : if (ControlMode == RunOnSensible && AirMassFlow > HVAC::SmallAirVolFlow &&
1280 0 : TempSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp) {
1281 0 : if (TempSetPoint < TfrostControl) {
1282 0 : TempSetPoint = TfrostControl;
1283 0 : this->m_FrostControlStatus = 1;
1284 : }
1285 0 : } else if (ControlMode == RunOnLatent && AirMassFlow > HVAC::SmallAirVolFlow &&
1286 0 : HumRatSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat) {
1287 0 : Real64 HumRatioSat = Psychrometrics::PsyWFnTdpPb(state, TfrostControl, BaroPress, routineName);
1288 0 : if (HumRatioSat > HumRatSetPoint) {
1289 0 : HumRatSetPoint = HumRatioSat;
1290 0 : this->m_FrostControlStatus = 2;
1291 : }
1292 : } else {
1293 0 : this->m_FrostControlStatus = 0;
1294 : }
1295 0 : }
1296 :
1297 136 : void UnitarySys::getUnitarySystemInput(EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
1298 : {
1299 :
1300 136 : bool errorsFound(false);
1301 136 : UnitarySys::allocateUnitarySys(state);
1302 :
1303 136 : UnitarySys::getDXCoilSystemData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1304 136 : UnitarySys::getCoilWaterSystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1305 136 : UnitarySys::getPackagedTerminalUnitData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1306 136 : UnitarySys::getUnitarySystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1307 :
1308 136 : 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 272 : if (int(state.dataUnitarySystems->unitarySys.size()) == state.dataUnitarySystems->numUnitarySystems &&
1314 136 : state.dataZoneEquip->ZoneEquipInputsFilled) {
1315 71 : if (state.dataUnitarySystems->setupOutputOnce) {
1316 45 : setupAllOutputVars(state, state.dataUnitarySystems->numUnitarySystems);
1317 : }
1318 : }
1319 136 : }
1320 :
1321 86 : 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 86 : 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 86 : Real64 SumOfMassFlowRateMax(0.0); // the sum of zone inlet mass flow rates
1359 : Real64 minNoLoadFlow; // used for sizing MaxNoCoolHeatVolFlow for SingleZoneVAV method
1360 86 : 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 86 : DataSizing::ZoneEqSizingData *select_EqSizing = nullptr;
1366 :
1367 86 : auto &OASysEqSizing = state.dataSize->OASysEqSizing;
1368 :
1369 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
1370 86 : if (state.dataSize->CurOASysNum > 0) {
1371 4 : select_EqSizing = &OASysEqSizing(state.dataSize->CurOASysNum);
1372 82 : } else if (state.dataSize->CurSysNum > 0) {
1373 20 : 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 20 : select_EqSizing->AirFlow = false;
1378 20 : select_EqSizing->CoolingAirFlow = false;
1379 20 : select_EqSizing->HeatingAirFlow = false;
1380 20 : select_EqSizing->AirVolFlow = 0.0;
1381 20 : select_EqSizing->CoolingAirVolFlow = 0.0;
1382 20 : select_EqSizing->HeatingAirVolFlow = 0.0;
1383 20 : select_EqSizing->Capacity = false;
1384 20 : select_EqSizing->CoolingCapacity = false;
1385 20 : select_EqSizing->HeatingCapacity = false;
1386 20 : select_EqSizing->DesCoolingLoad = 0.0;
1387 20 : select_EqSizing->DesHeatingLoad = 0.0;
1388 20 : select_EqSizing->OAVolFlow = 0.0; // UnitarySys doesn't have OA
1389 62 : } else if (state.dataSize->CurZoneEqNum > 0) {
1390 62 : select_EqSizing = &state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
1391 62 : state.dataSize->ZoneEqUnitarySys = true;
1392 : // UnitarySystem never set this flag. Probably should for zone equipment.
1393 62 : if ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
1394 8 : this->m_IsDXCoil) {
1395 8 : state.dataSize->ZoneEqDXCoil = true;
1396 : }
1397 :
1398 : } else {
1399 0 : assert(false);
1400 : }
1401 : // Object Data, points to specific array
1402 86 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
1403 :
1404 : // coil sizing requires this information to check proper flow/capacity limits (#8761)
1405 86 : if (this->m_ISHundredPercentDOASDXCoil) {
1406 0 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::DOAS; // uses 100% DX coil flow limits
1407 : } else {
1408 86 : 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 86 : state.dataSize->DataCoolCoilType = this->m_CoolingCoilType_Num;
1412 86 : state.dataSize->DataCoolCoilIndex = this->m_CoolingCoilIndex;
1413 :
1414 : bool anyEMSRan;
1415 86 : 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 152 : if (((state.dataSize->CurOASysNum > 0 || state.dataSize->CurSysNum > 0) && state.dataSize->SysSizingRunDone) ||
1420 66 : (state.dataSize->CurZoneEqNum > 0 && state.dataSize->ZoneSizingRunDone)) {
1421 71 : HardSizeNoDesRun = false;
1422 : } else {
1423 15 : HardSizeNoDesRun = true;
1424 : }
1425 86 : std::string SizingString;
1426 86 : std::string CompName = this->Name;
1427 86 : std::string CompType = this->UnitType;
1428 86 : int CoolingSAFlowMethod = this->m_CoolingSAFMethod;
1429 86 : 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 86 : state.dataSize->UnitaryHeatCap = 0.0;
1433 86 : state.dataSize->SuppHeatCap = 0.0;
1434 86 : bool TempCoolingLoad = state.dataUnitarySystems->CoolingLoad;
1435 86 : bool TempHeatingLoad = state.dataUnitarySystems->HeatingLoad;
1436 86 : state.dataUnitarySystems->CoolingLoad = true;
1437 86 : state.dataUnitarySystems->HeatingLoad = false;
1438 86 : state.dataSize->ZoneCoolingOnlyFan = false;
1439 86 : state.dataSize->ZoneHeatingOnlyFan = false;
1440 86 : bool IsAutoSize = false;
1441 86 : Real64 SysCoolingFlow = 0.0;
1442 86 : Real64 SysHeatingFlow = 0.0;
1443 86 : Real64 CoolCapAtPeak = 0.0;
1444 86 : Real64 HeatCapAtPeak = 0.0;
1445 :
1446 86 : if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0 && this->m_FanExists) {
1447 4 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum = this->m_FanIndex;
1448 4 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanType = this->m_FanType;
1449 4 : state.dataSize->DataFanType = this->m_FanType;
1450 4 : state.dataSize->DataFanIndex = this->m_FanIndex;
1451 :
1452 4 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanPlace = this->m_FanPlace;
1453 82 : } else if (state.dataSize->CurZoneEqNum > 0 && this->m_FanExists) {
1454 59 : state.dataSize->DataFanType = this->m_FanType;
1455 59 : state.dataSize->DataFanIndex = this->m_FanIndex;
1456 59 : state.dataSize->DataFanPlacement = this->m_FanPlace;
1457 : }
1458 :
1459 86 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for scalable capacity sizing
1460 6 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
1461 : }
1462 :
1463 86 : Real64 coolingCapacityMultiplier = 1.0;
1464 86 : Real64 heatingCapacityMultiplier = 1.0;
1465 86 : 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 86 : bool SizingDesRunThisZone = false;
1478 86 : if (this->OAMixerExists) {
1479 1 : if (state.dataSize->CurZoneEqNum > 0) {
1480 1 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1481 1 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize || this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
1482 0 : CheckZoneSizing(state, this->UnitType, this->Name);
1483 : }
1484 : // initialize OA flow for sizing other inputs (e.g., capacity)
1485 1 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
1486 0 : EqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
1487 : } else {
1488 1 : EqSizing.OAVolFlow = this->m_CoolOutAirVolFlow;
1489 : }
1490 1 : if (this->m_HeatOutAirVolFlow != DataSizing::AutoSize) {
1491 1 : EqSizing.OAVolFlow = max(EqSizing.OAVolFlow, this->m_HeatOutAirVolFlow);
1492 : }
1493 : }
1494 : }
1495 :
1496 86 : 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 86 : bool coolingAirFlowIsAutosized = this->m_MaxCoolAirVolFlow == DataSizing::AutoSize;
1512 86 : bool heatingAirFlowIsAutosized = this->m_MaxHeatAirVolFlow == DataSizing::AutoSize;
1513 86 : if (this->m_CoolCoilExists) {
1514 68 : if (!this->m_HeatCoilExists) {
1515 34 : state.dataSize->ZoneCoolingOnlyFan = true;
1516 : }
1517 68 : TempSize = this->m_MaxCoolAirVolFlow;
1518 68 : 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 68 : if (this->m_sysType == SysType::Unitary) {
1523 41 : state.dataSize->CurDuctType = HVAC::AirDuctType::Cooling;
1524 : }
1525 68 : bool errorsFound = false;
1526 68 : if ((CoolingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (CoolingSAFlowMethod == DataSizing::None)) {
1527 57 : CoolingAirFlowSizer sizingCoolingAirFlow;
1528 57 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1529 57 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1530 68 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1531 2 : CoolingAirFlowSizer sizingCoolingAirFlow;
1532 2 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1533 2 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1534 2 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1535 11 : } else if (CoolingSAFlowMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
1536 5 : TempSize = DataSizing::AutoSize;
1537 5 : CoolingAirFlowSizer sizingCoolingAirFlow;
1538 5 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1539 5 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1540 5 : SysCoolingFlow *= this->m_MaxCoolAirVolFlow;
1541 5 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1542 9 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerCoolingCapacity) {
1543 4 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
1544 4 : TempSize = DataSizing::AutoSize;
1545 4 : CoolingAirFlowSizer sizingCoolingAirFlow;
1546 4 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1547 4 : state.dataSize->DataFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1548 4 : SizingMethod = HVAC::CoolingCapacitySizing;
1549 4 : 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 4 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
1554 4 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1555 3 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1556 3 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1557 1 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1558 1 : state.dataSize->DataIsDXCoil = true;
1559 : }
1560 4 : CoolingCapacitySizer sizerCoolingCapacity;
1561 4 : sizerCoolingCapacity.overrideSizingString(SizingString);
1562 4 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1563 4 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1564 4 : SysCoolingFlow = CoolCapAtPeak * this->m_MaxCoolAirVolFlow;
1565 4 : state.dataSize->DataTotCapCurveIndex = 0;
1566 4 : EqSizing.CoolingCapacity = true;
1567 4 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1568 4 : } else {
1569 0 : SysCoolingFlow = this->m_DesignCoolingCapacity * this->m_MaxCoolAirVolFlow;
1570 0 : CoolCapAtPeak = this->m_DesignCoolingCapacity;
1571 0 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1572 : }
1573 4 : 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 68 : state.dataSize->CurDuctType = SaveCurDuctType;
1581 68 : EqSizing.CoolingAirFlow = true;
1582 68 : EqSizing.CoolingAirVolFlow = SysCoolingFlow;
1583 :
1584 : // Cooling airflow should be known at this point. Now find DataSizing::AutoSized design cooling capacity.
1585 68 : if (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity < 0.0) {
1586 46 : SizingMethod = HVAC::CoolingCapacitySizing;
1587 46 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1588 46 : TempSize = DataSizing::AutoSize;
1589 : // could probably move this up outside the IF and delete then next group below in the else
1590 46 : switch (this->m_CoolingCoilType_Num) {
1591 3 : case HVAC::CoilDX_Cooling: {
1592 6 : state.dataSize->DataTotCapCurveIndex =
1593 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1594 3 : state.dataSize->DataIsDXCoil = true;
1595 3 : } break;
1596 22 : case HVAC::CoilDX_CoolingSingleSpeed:
1597 : case HVAC::CoilDX_MultiSpeedCooling:
1598 : case HVAC::CoilDX_CoolingTwoSpeed:
1599 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
1600 22 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1601 22 : state.dataSize->DataIsDXCoil = true;
1602 22 : } break;
1603 2 : case HVAC::Coil_CoolingAirToAirVariableSpeed: {
1604 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1605 2 : state.dataSize->DataIsDXCoil = true;
1606 2 : } break;
1607 2 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
1608 2 : 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 2 : } break;
1612 17 : default: {
1613 17 : } break;
1614 : }
1615 92 : CoolingCapacitySizer sizerCoolingCapacity;
1616 46 : sizerCoolingCapacity.overrideSizingString(SizingString);
1617 46 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1618 46 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1619 46 : 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 46 : if (this->m_HVACSizingIndex <= 0) {
1622 46 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1623 : }
1624 : // CoilSystem does not size the cooling coil (#8761)
1625 46 : if ((this->m_sysType == SysType::Unitary) || (this->m_sysType == SysType::PackagedAC) || (this->m_sysType == SysType::PackagedHP) ||
1626 18 : (this->m_sysType == SysType::PackagedWSHP)) {
1627 30 : EqSizing.CoolingCapacity = true;
1628 30 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1629 : }
1630 68 : } else if (!HardSizeNoDesRun && (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1631 : // corrected code for #8756
1632 1 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1633 1 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1634 1 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1635 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1636 0 : state.dataSize->DataIsDXCoil = true;
1637 : }
1638 1 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
1639 0 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1640 0 : state.dataSize->DataIsDXCoil = true;
1641 : }
1642 1 : 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 1 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) {
1649 0 : state.dataSize->DataIsDXCoil = false;
1650 : }
1651 1 : SizingMethod = HVAC::CoolingCapacitySizing;
1652 1 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1653 1 : if (this->m_CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
1654 1 : (this->m_CoolingCapMethod == DataSizing::CoolingDesignCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1655 0 : TempSize = this->m_DesignCoolingCapacity;
1656 : } else {
1657 1 : TempSize = DataSizing::AutoSize;
1658 : }
1659 1 : CoolingCapacitySizer sizerCoolingCapacity;
1660 1 : sizerCoolingCapacity.overrideSizingString(SizingString);
1661 1 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1662 1 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1663 1 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1664 1 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1665 1 : EqSizing.CoolingCapacity = true;
1666 1 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1667 1 : } else {
1668 : // something seems missing here based on multiple conditional if above
1669 21 : if (this->m_DesignCoolingCapacity != DataSizing::AutoSize) {
1670 17 : CoolCapAtPeak = this->m_DesignCoolingCapacity;
1671 : }
1672 : }
1673 68 : state.dataSize->DataIsDXCoil = false;
1674 68 : state.dataSize->DataTotCapCurveIndex = 0;
1675 68 : state.dataSize->DataFlowUsedForSizing = 0.0;
1676 : }
1677 :
1678 : // STEP 2: find the DataSizing::AutoSized heating air flow rate and capacity
1679 86 : if (this->m_HeatCoilExists) {
1680 52 : if (!this->m_CoolCoilExists) {
1681 18 : state.dataSize->ZoneHeatingOnlyFan = true;
1682 : }
1683 52 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1684 52 : SizingMethod = HVAC::HeatingAirflowSizing;
1685 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1686 52 : TempSize = this->m_MaxHeatAirVolFlow;
1687 52 : SaveCurDuctType = state.dataSize->CurDuctType;
1688 52 : state.dataSize->CurDuctType = HVAC::AirDuctType::Heating;
1689 52 : if ((HeatingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (HeatingSAFlowMethod == DataSizing::None)) {
1690 43 : bool errorsFound = false;
1691 43 : HeatingAirFlowSizer sizingHeatingAirFlow;
1692 43 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1693 43 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1694 43 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1695 52 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1696 2 : bool errorsFound = false;
1697 2 : HeatingAirFlowSizer sizingHeatingAirFlow;
1698 2 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1699 2 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1700 2 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1701 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1702 9 : } else if (HeatingSAFlowMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
1703 3 : TempSize = DataSizing::AutoSize;
1704 3 : bool errorsFound = false;
1705 3 : HeatingAirFlowSizer sizingHeatingAirFlow;
1706 3 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1707 3 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1708 3 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1709 3 : SysHeatingFlow *= this->m_MaxHeatAirVolFlow;
1710 3 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1711 7 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerHeatingCapacity) {
1712 4 : TempSize = DataSizing::AutoSize;
1713 4 : bool errorsFound = false;
1714 4 : HeatingAirFlowSizer sizingHeatingAirFlow;
1715 4 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1716 4 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1717 4 : state.dataSize->DataFlowUsedForSizing = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1718 4 : SizingMethod = HVAC::HeatingCapacitySizing;
1719 4 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
1720 4 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1721 4 : 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 4 : 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 4 : HeatingCapacitySizer sizerHeatingCapacity;
1730 4 : sizerHeatingCapacity.overrideSizingString(SizingString);
1731 4 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1732 4 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1733 4 : if (state.dataSize->CurSysNum > 0) {
1734 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1735 : }
1736 4 : SysHeatingFlow = HeatCapAtPeak * this->m_MaxHeatAirVolFlow;
1737 4 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1738 4 : EqSizing.HeatingCapacity = true;
1739 4 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1740 4 : } 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 52 : state.dataSize->CurDuctType = SaveCurDuctType;
1747 52 : EqSizing.HeatingAirFlow = true;
1748 52 : EqSizing.HeatingAirVolFlow = SysHeatingFlow;
1749 :
1750 : // Heating airflow should be known at this point. Now find DataSizing::AutoSized design heating capacity.
1751 52 : if (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
1752 26 : SizingMethod = HVAC::HeatingCapacitySizing;
1753 26 : if (m_sysType == SysType::Unitary || m_sysType == SysType::CoilCoolingDX || m_sysType == SysType::CoilCoolingWater) {
1754 24 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1755 : }
1756 26 : TempSize = DataSizing::AutoSize;
1757 26 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1758 26 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1759 1 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1760 1 : state.dataSize->DataIsDXCoil = true;
1761 : }
1762 : // should have VS coil capFT here also
1763 26 : if (this->m_sysType == SysType::PackagedWSHP && this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1764 1 : 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 26 : if (this->m_sysType == SysType::PackagedHP) {
1770 0 : state.dataSize->DataIsDXCoil = false;
1771 : }
1772 26 : if (state.dataSize->CurSysNum > 0) {
1773 2 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1774 : false; // set to false to allow calculation of actual heating capacity
1775 : }
1776 26 : bool errorsFound = false;
1777 26 : HeatingCapacitySizer sizerHeatingCapacity;
1778 26 : sizerHeatingCapacity.overrideSizingString(SizingString);
1779 26 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1780 26 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1781 26 : if (state.dataSize->CurSysNum > 0) {
1782 2 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1783 : }
1784 26 : EqSizing.HeatingCapacity = true;
1785 26 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1786 26 : } else {
1787 26 : if (!HardSizeNoDesRun &&
1788 10 : (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity != DataSizing::AutoSize)) {
1789 : // should have other DX heating coil types here
1790 10 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1791 0 : SizingMethod = HVAC::HeatingCapacitySizing;
1792 0 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1793 0 : TempSize = DataSizing::AutoSize;
1794 0 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1795 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1796 0 : state.dataSize->DataIsDXCoil = true;
1797 0 : if (state.dataSize->CurSysNum > 0) {
1798 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1799 : false; // set to false to allow calculation of actual heating capacity
1800 : }
1801 0 : bool errorsFound = false;
1802 0 : HeatingCapacitySizer sizerHeatingCapacity;
1803 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
1804 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1805 0 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1806 0 : if (state.dataSize->CurSysNum > 0) {
1807 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1808 : }
1809 0 : EqSizing.HeatingCapacity = true;
1810 0 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1811 0 : }
1812 10 : } else {
1813 : // something seems missing here based on multiple conditional if above
1814 16 : if (this->m_DesignHeatingCapacity != DataSizing::AutoSize) {
1815 12 : HeatCapAtPeak = this->m_DesignHeatingCapacity;
1816 : }
1817 : }
1818 : }
1819 : // if ( ! UnitarySystem( UnitarySysNum ).CoolCoilExists )DXCoolCap = HeatCapAtPeak;
1820 52 : state.dataSize->DataIsDXCoil = false;
1821 52 : state.dataSize->DataTotCapCurveIndex = 0;
1822 52 : state.dataSize->DataFlowUsedForSizing = 0.0;
1823 52 : if (this->m_sysType == SysType::PackagedAC) {
1824 6 : EqSizing.HeatingCapacity = false;
1825 : }
1826 : }
1827 :
1828 86 : bool isWSVarSpeedCoolCoil = this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
1829 86 : bool isWSVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
1830 86 : bool isVarSpeedCoolCoil = this->m_HeatingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed;
1831 86 : bool isVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed;
1832 :
1833 86 : Real64 saveRawHeatingCapacity = HeatCapAtPeak;
1834 :
1835 : // STEP 3A: Find VS cooling coil air flow to capacity ratio and adjust design air flow
1836 122 : if (EqSizing.DesCoolingLoad > 0.0 && state.dataSize->CurZoneEqNum > 0 &&
1837 36 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
1838 35 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1839 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed))) {
1840 1 : Real64 coolingToHeatingCapRatio = 1.0;
1841 1 : if ((isWSVarSpeedCoolCoil && this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) ||
1842 0 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1843 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
1844 1 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NormSpedLevel;
1845 : Real64 coolingAirFlowToCapacityRatio =
1846 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1847 1 : EqSizing.CoolingAirVolFlow = EqSizing.DesCoolingLoad * coolingAirFlowToCapacityRatio;
1848 1 : if (EqSizing.DesHeatingLoad > 0.0) {
1849 1 : coolingToHeatingCapRatio = EqSizing.DesCoolingLoad / EqSizing.DesHeatingLoad;
1850 : }
1851 : }
1852 1 : if (((isWSVarSpeedHeatCoil || isVarSpeedHeatCoil) && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) ||
1853 0 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1854 0 : this->m_CoolingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed)) {
1855 1 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
1856 : Real64 heatingAirFlowToCapacityRatio =
1857 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1858 1 : EqSizing.DesHeatingLoad *= coolingToHeatingCapRatio;
1859 1 : 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 86 : if ((!isWSVarSpeedHeatCoil &&
1871 85 : (((this->m_sysType == SysType::PackagedAC && !isVarSpeedCoolCoil) && (this->m_sysType == SysType::PackagedHP && !isVarSpeedHeatCoil)) ||
1872 85 : (this->m_sysType == SysType::Unitary && this->m_HeatPump))) ||
1873 82 : (this->m_sysType == SysType::Unitary &&
1874 55 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
1875 49 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
1876 47 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling))) {
1877 16 : EqSizing.CoolingAirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1878 16 : 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 86 : 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 0 : EqSizing.HeatingCapacity = false;
1887 86 : } else if (this->m_HeatPump && (state.dataSize->CurZoneEqNum == 0 || !isWSVarSpeedCoolCoil)) {
1888 5 : EqSizing.AirFlow = true;
1889 5 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1890 5 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit &&
1891 5 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1892 5 : EqSizing.Capacity = true;
1893 5 : EqSizing.DesCoolingLoad = max(EqSizing.DesCoolingLoad, EqSizing.DesHeatingLoad);
1894 5 : EqSizing.DesHeatingLoad = EqSizing.DesCoolingLoad;
1895 5 : state.dataSize->DXCoolCap = EqSizing.DesCoolingLoad;
1896 : }
1897 81 : } else if (!this->m_CoolCoilExists && state.dataSize->CurZoneEqNum > 0) {
1898 18 : 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 86 : if (this->m_OKToPrintSizing) {
1908 62 : if (this->m_sysType != SysType::CoilCoolingDX && this->m_sysType != SysType::CoilCoolingWater) {
1909 43 : PrintFlag = true;
1910 : }
1911 : }
1912 : // STEP 5: report system parameters (e.g., air flow rates, capacities, etc.)
1913 86 : if (this->m_FanExists) {
1914 63 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1915 8 : PrintFlag = false;
1916 : }
1917 :
1918 63 : EqSizing.SystemAirFlow = true;
1919 63 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1920 63 : if (this->m_DesignFanVolFlowRate <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1921 45 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
1922 : }
1923 63 : state.dataSize->DataEMSOverrideON = this->m_DesignFanVolFlowRateEMSOverrideOn;
1924 63 : state.dataSize->DataEMSOverride = this->m_DesignFanVolFlowRateEMSOverrideValue;
1925 :
1926 63 : bool errorsFound = false;
1927 63 : SystemAirFlowSizer sizerSystemAirFlow;
1928 63 : std::string sizingString = "Supply Air Flow Rate [m3/s]";
1929 63 : sizerSystemAirFlow.overrideSizingString(sizingString);
1930 63 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1931 63 : this->m_DesignFanVolFlowRate = sizerSystemAirFlow.size(state, this->m_DesignFanVolFlowRate, errorsFound);
1932 :
1933 63 : state.dataSize->DataEMSOverrideON = false;
1934 63 : EqSizing.SystemAirFlow = false;
1935 :
1936 63 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1937 8 : PrintFlag = true;
1938 : }
1939 63 : }
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 86 : if (this->m_HeatCoilExists && !this->m_CoolCoilExists) {
1944 18 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
1945 5 : this->m_MaxCoolAirVolFlow = EqSizing.HeatingAirVolFlow;
1946 : }
1947 68 : } else if (this->m_CoolCoilExists && !this->m_HeatCoilExists) {
1948 34 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
1949 8 : this->m_MaxHeatAirVolFlow = EqSizing.CoolingAirVolFlow;
1950 : }
1951 34 : 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 86 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1957 8 : if (this->m_CoolCoilExists) {
1958 : // allow design size to report
1959 8 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
1960 6 : EqSizing.CoolingAirFlow = false;
1961 : }
1962 8 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1963 2 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1964 : }
1965 8 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
1966 8 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
1967 8 : TempSize = this->m_MaxCoolAirVolFlow;
1968 8 : bool errorsFound = false;
1969 8 : CoolingAirFlowSizer sizingCoolingAirFlow;
1970 8 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
1971 8 : if (state.dataGlobal->isEpJSON) {
1972 0 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
1973 : }
1974 8 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1975 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1976 8 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1977 8 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1978 8 : state.dataSize->DataEMSOverrideON = false;
1979 8 : state.dataSize->DataConstantUsedForSizing = 0.0;
1980 8 : }
1981 8 : if (this->m_HeatCoilExists) {
1982 : // allow design size to report
1983 8 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
1984 6 : EqSizing.HeatingAirFlow = false;
1985 : }
1986 8 : SizingMethod = HVAC::HeatingAirflowSizing;
1987 8 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1988 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1989 : }
1990 8 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
1991 8 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1992 1 : EqSizing.AirFlow = false;
1993 : }
1994 8 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1995 8 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
1996 8 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
1997 8 : TempSize = this->m_MaxHeatAirVolFlow;
1998 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1999 8 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
2000 8 : bool errorsFound = false;
2001 8 : HeatingAirFlowSizer sizingHeatingAirFlow;
2002 8 : sizingHeatingAirFlow.overrideSizingString(SizingString);
2003 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2004 8 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2005 8 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
2006 8 : state.dataSize->DataEMSOverrideON = false;
2007 8 : state.dataSize->DataConstantUsedForSizing = 0.0;
2008 8 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2009 1 : EqSizing.AirFlow = saveEqSizingAirFlow;
2010 : }
2011 8 : }
2012 :
2013 8 : } else {
2014 78 : if (this->m_HeatCoilExists) {
2015 :
2016 44 : SizingMethod = HVAC::HeatingAirflowSizing;
2017 44 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2018 36 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
2019 : }
2020 44 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
2021 44 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2022 0 : EqSizing.AirFlow = false;
2023 : }
2024 44 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
2025 44 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
2026 44 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
2027 44 : TempSize = this->m_MaxHeatAirVolFlow;
2028 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2029 44 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
2030 44 : bool errorsFound = false;
2031 44 : HeatingAirFlowSizer sizingHeatingAirFlow;
2032 44 : sizingHeatingAirFlow.overrideSizingString(SizingString);
2033 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2034 44 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2035 44 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
2036 44 : state.dataSize->DataEMSOverrideON = false;
2037 44 : state.dataSize->DataConstantUsedForSizing = 0.0;
2038 44 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2039 0 : EqSizing.AirFlow = saveEqSizingAirFlow;
2040 : }
2041 44 : }
2042 :
2043 78 : if (this->m_CoolCoilExists) {
2044 :
2045 60 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2046 47 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
2047 : }
2048 60 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
2049 60 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
2050 60 : TempSize = this->m_MaxCoolAirVolFlow;
2051 60 : bool errorsFound = false;
2052 60 : CoolingAirFlowSizer sizingCoolingAirFlow;
2053 60 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
2054 60 : if (state.dataGlobal->isEpJSON) {
2055 0 : stringOverride = "cooling_supply_air_flow_rate [m3/s]";
2056 : }
2057 60 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
2058 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2059 60 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2060 60 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
2061 60 : state.dataSize->DataEMSOverrideON = false;
2062 60 : state.dataSize->DataConstantUsedForSizing = 0.0;
2063 60 : }
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 86 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2069 22 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2070 22 : if (this->m_ActualFanVolFlowRate > 0.0) {
2071 0 : this->m_DesignFanVolFlowRate = this->m_ActualFanVolFlowRate;
2072 : }
2073 22 : 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 86 : if (!this->m_FanExists) {
2079 23 : this->m_ActualFanVolFlowRate = this->m_DesignFanVolFlowRate;
2080 : }
2081 :
2082 86 : if (this->m_CoolCoilExists || this->m_HeatCoilExists || this->m_SuppCoilExists) {
2083 86 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2084 : // set no load air flow ratio local var
2085 86 : Real64 NoLoadCoolingAirFlowRateRatio = 1.0;
2086 86 : Real64 NoLoadHeatingAirFlowRateRatio = 1.0;
2087 86 : if (MSHPIndex > -1) {
2088 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling > 0) {
2089 18 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0] == DataSizing::AutoSize) {
2090 : NoLoadCoolingAirFlowRateRatio =
2091 6 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling));
2092 : } else {
2093 : NoLoadCoolingAirFlowRateRatio =
2094 12 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0]);
2095 : }
2096 : }
2097 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating > 0) {
2098 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0] == DataSizing::AutoSize) {
2099 : NoLoadHeatingAirFlowRateRatio =
2100 8 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating));
2101 : } else {
2102 : NoLoadHeatingAirFlowRateRatio =
2103 11 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0]);
2104 : }
2105 : }
2106 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio > 0.0) {
2107 13 : this->m_NoLoadAirFlowRateRatio = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2108 : } else {
2109 6 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2110 : }
2111 : } else {
2112 67 : if ((this->m_CoolCoilExists || this->m_HeatCoilExists) && this->m_useNoLoadLowSpeedAirFlow) {
2113 65 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2114 62 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
2115 : Real64 MaxSpeedFlowRate =
2116 4 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2117 4 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2118 4 : 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 3 : NoLoadCoolingAirFlowRateRatio =
2121 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2122 : } else {
2123 1 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2124 : }
2125 65 : } 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 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2131 0 : .RatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages);
2132 0 : if (MaxSpeedFlowRate > 0.0 &&
2133 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2134 0 : NoLoadCoolingAirFlowRateRatio =
2135 0 : 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 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages;
2138 : }
2139 61 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2140 : // RatedAirVolFlowRate(1) = high speed, RatedAirVolFlowRate2= low speed
2141 3 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1);
2142 3 : if (MaxSpeedFlowRate > 0.0 &&
2143 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 != DataSizing::AutoSize) {
2144 0 : NoLoadCoolingAirFlowRateRatio =
2145 0 : 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 3 : NoLoadCoolingAirFlowRateRatio = 0.5;
2148 : }
2149 58 : } 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 58 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2161 4 : NoLoadCoolingAirFlowRateRatio = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex]
2162 2 : .performance.normalMode.speeds[0]
2163 : .original_input_specs.evaporator_air_flow_fraction;
2164 : }
2165 65 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
2166 64 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2167 : Real64 MaxSpeedFlowRate =
2168 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2169 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2170 1 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) >
2171 : 0.0) { // these are the air flow at speed fields, and could be 0
2172 1 : NoLoadHeatingAirFlowRateRatio =
2173 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2174 : } else {
2175 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2176 : }
2177 65 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
2178 : // MSRatedAirVolFlowRate
2179 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex)
2180 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2181 0 : if (MaxSpeedFlowRate > 0.0 &&
2182 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2183 0 : NoLoadHeatingAirFlowRateRatio =
2184 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2185 : } else { // if any flow rates are autosized use the ratio of number of speeds
2186 0 : NoLoadHeatingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
2187 : }
2188 : }
2189 65 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2190 : }
2191 : }
2192 86 : if (this->m_NoCoolHeatSAFMethod <= DataSizing::SupplyAirFlowRate && this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
2193 2 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
2194 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2195 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
2196 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
2197 0 : minNoLoadFlow = 0.6667; // TODO: Should this have a Coil:Cooling:DX block?
2198 : } else {
2199 0 : if (this->m_NoLoadAirFlowRateRatio < 1.0) {
2200 0 : minNoLoadFlow = this->m_NoLoadAirFlowRateRatio;
2201 : } else {
2202 0 : minNoLoadFlow = 0.5;
2203 : }
2204 : }
2205 0 : if (this->m_MaxCoolAirVolFlow >= this->m_MaxHeatAirVolFlow) {
2206 0 : state.dataSize->DataFractionUsedForSizing =
2207 0 : min(minNoLoadFlow, (this->m_MaxHeatAirVolFlow / this->m_MaxCoolAirVolFlow) - 0.01);
2208 : } else {
2209 0 : state.dataSize->DataFractionUsedForSizing =
2210 0 : min(minNoLoadFlow, (this->m_MaxCoolAirVolFlow / this->m_MaxHeatAirVolFlow) - 0.01);
2211 : }
2212 : } else {
2213 2 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2214 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
2215 : }
2216 84 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
2217 1 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.CoolingAirVolFlow;
2218 1 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2219 1 : state.dataSize->DataFractionUsedForSizing = 1.0;
2220 1 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2221 83 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
2222 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.HeatingAirVolFlow;
2223 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2224 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2225 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2226 83 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerCoolingCapacity) {
2227 1 : if (EqSizing.DesCoolingLoad <= 0.0) {
2228 : // water coils not sizing yet
2229 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2230 0 : WaterCoils::SimulateWaterCoilComponents(
2231 0 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2232 0 : EqSizing.DesCoolingLoad = WaterCoils::GetWaterCoilCapacity(
2233 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
2234 : }
2235 : }
2236 1 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesCoolingLoad;
2237 1 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2238 1 : state.dataSize->DataFractionUsedForSizing = 1.0;
2239 1 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2240 82 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerHeatingCapacity) {
2241 0 : if (EqSizing.DesHeatingLoad <= 0.0) {
2242 : // water coil not sizing yet
2243 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2244 0 : WaterCoils::SimulateWaterCoilComponents(
2245 0 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2246 0 : EqSizing.DesHeatingLoad = WaterCoils::GetWaterCoilCapacity(
2247 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
2248 : }
2249 : }
2250 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesHeatingLoad;
2251 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2252 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2253 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2254 : } else {
2255 82 : state.dataSize->DataFractionUsedForSizing = this->m_NoLoadAirFlowRateRatio;
2256 : }
2257 :
2258 86 : FieldNum = 11; // N11 , \field No Load Supply Air Flow Rate
2259 86 : state.dataSize->DataEMSOverrideON = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideOn;
2260 86 : state.dataSize->DataEMSOverride = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideValue;
2261 86 : TempSize = this->m_MaxNoCoolHeatAirVolFlow;
2262 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2263 86 : SizingString = "No Load Supply Air Flow Rate [m3/s]";
2264 86 : bool errorsFound = false;
2265 86 : SystemAirFlowSizer sizerSystemAirFlow;
2266 86 : sizerSystemAirFlow.overrideSizingString(SizingString);
2267 86 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2268 86 : this->m_MaxNoCoolHeatAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
2269 86 : state.dataSize->DataEMSOverrideON = false;
2270 86 : state.dataSize->DataConstantUsedForSizing = 0.0;
2271 86 : state.dataSize->DataFractionUsedForSizing = 0.0;
2272 86 : }
2273 :
2274 86 : if (this->m_MaxCoolAirVolFlow > 0.0) {
2275 73 : this->LowSpeedCoolFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxCoolAirVolFlow;
2276 : }
2277 86 : if (this->m_MaxHeatAirVolFlow > 0.0) {
2278 62 : this->LowSpeedHeatFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxHeatAirVolFlow;
2279 : }
2280 :
2281 86 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for use in component sizing
2282 6 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
2283 : }
2284 :
2285 86 : if (this->OAMixerExists) {
2286 1 : IsAutoSize = false;
2287 1 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
2288 0 : IsAutoSize = true;
2289 : }
2290 1 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2291 1 : if (this->m_CoolOutAirVolFlow > 0.0) {
2292 1 : BaseSizer::reportSizerOutput(state,
2293 : this->UnitType,
2294 : this->Name,
2295 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2296 : this->m_CoolOutAirVolFlow);
2297 : }
2298 : } else {
2299 0 : CheckZoneSizing(state, this->UnitType, this->Name);
2300 0 : Real64 CoolOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2301 0 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2302 0 : CoolOutAirVolFlowDes = 0.0;
2303 : }
2304 0 : if (IsAutoSize) {
2305 0 : this->m_CoolOutAirVolFlow = CoolOutAirVolFlowDes;
2306 0 : BaseSizer::reportSizerOutput(
2307 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]", CoolOutAirVolFlowDes);
2308 : } else {
2309 0 : if (this->m_CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2310 0 : Real64 CoolOutAirVolFlowUser = this->m_CoolOutAirVolFlow;
2311 0 : BaseSizer::reportSizerOutput(state,
2312 : this->UnitType,
2313 : this->Name,
2314 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2315 : CoolOutAirVolFlowDes,
2316 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2317 : CoolOutAirVolFlowUser);
2318 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2319 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
2320 0 : state.dataSize->AutoVsHardSizingThreshold) {
2321 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2322 0 : ShowContinueError(
2323 : state,
2324 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
2325 0 : ShowContinueError(state,
2326 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
2327 : CoolOutAirVolFlowDes));
2328 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2329 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2330 : }
2331 : }
2332 : }
2333 : }
2334 : }
2335 :
2336 1 : IsAutoSize = false;
2337 1 : if (this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
2338 0 : IsAutoSize = true;
2339 : }
2340 1 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2341 1 : if (this->m_HeatOutAirVolFlow > 0.0) {
2342 1 : BaseSizer::reportSizerOutput(state,
2343 : this->UnitType,
2344 : this->Name,
2345 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2346 : this->m_HeatOutAirVolFlow);
2347 : }
2348 : } else {
2349 0 : CheckZoneSizing(state, this->UnitType, this->Name);
2350 0 : Real64 HeatOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2351 0 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2352 0 : HeatOutAirVolFlowDes = 0.0;
2353 : }
2354 0 : if (IsAutoSize) {
2355 0 : this->m_HeatOutAirVolFlow = HeatOutAirVolFlowDes;
2356 0 : BaseSizer::reportSizerOutput(
2357 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]", HeatOutAirVolFlowDes);
2358 : } else {
2359 0 : if (this->m_HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2360 0 : Real64 HeatOutAirVolFlowUser = this->m_HeatOutAirVolFlow;
2361 0 : BaseSizer::reportSizerOutput(state,
2362 : this->UnitType,
2363 : this->Name,
2364 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
2365 : HeatOutAirVolFlowDes,
2366 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2367 : HeatOutAirVolFlowUser);
2368 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2369 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
2370 0 : state.dataSize->AutoVsHardSizingThreshold) {
2371 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2372 0 : ShowContinueError(
2373 : state,
2374 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
2375 0 : ShowContinueError(state,
2376 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
2377 : HeatOutAirVolFlowDes));
2378 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2379 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2380 : }
2381 : }
2382 : }
2383 : }
2384 : }
2385 :
2386 1 : IsAutoSize = false;
2387 1 : if (this->m_NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
2388 0 : IsAutoSize = true;
2389 : }
2390 1 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2391 1 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0) {
2392 1 : BaseSizer::reportSizerOutput(state,
2393 : this->UnitType,
2394 : this->Name,
2395 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2396 : this->m_NoCoolHeatOutAirVolFlow);
2397 : }
2398 : } else {
2399 0 : CheckZoneSizing(state, this->UnitType, this->Name);
2400 : Real64 NoCoolHeatOutAirVolFlowDes =
2401 0 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, this->m_MaxNoCoolHeatAirVolFlow);
2402 0 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2403 0 : NoCoolHeatOutAirVolFlowDes = 0.0;
2404 : }
2405 0 : if (IsAutoSize) {
2406 0 : this->m_NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
2407 0 : BaseSizer::reportSizerOutput(state,
2408 : this->UnitType,
2409 : this->Name,
2410 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2411 : NoCoolHeatOutAirVolFlowDes);
2412 : } else {
2413 0 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2414 0 : Real64 NoCoolHeatOutAirVolFlowUser = this->m_NoCoolHeatOutAirVolFlow;
2415 0 : BaseSizer::reportSizerOutput(state,
2416 : this->UnitType,
2417 : this->Name,
2418 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2419 : NoCoolHeatOutAirVolFlowDes,
2420 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2421 : NoCoolHeatOutAirVolFlowUser);
2422 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2423 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
2424 0 : state.dataSize->AutoVsHardSizingThreshold) {
2425 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2426 0 : ShowContinueError(state,
2427 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2428 : NoCoolHeatOutAirVolFlowUser));
2429 0 : ShowContinueError(
2430 : state,
2431 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2432 : NoCoolHeatOutAirVolFlowDes));
2433 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2434 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2435 : }
2436 : }
2437 : }
2438 : }
2439 : }
2440 : }
2441 86 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2442 2 : PrintFlag = false;
2443 : }
2444 :
2445 86 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2446 8 : if (this->m_AirFlowControl == UseCompFlow::On) {
2447 3 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2448 3 : this->m_NoLoadAirFlowRateRatio = 1.0;
2449 : }
2450 8 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2451 8 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2452 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
2453 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
2454 0 : Real64 airFlowAdjustmentRatio = 1.0;
2455 0 : if (!coolingAirFlowIsAutosized) {
2456 0 : airFlowAdjustmentRatio =
2457 0 : this->m_MaxCoolAirVolFlow /
2458 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2459 0 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2460 : }
2461 0 : this->m_MaxNoCoolHeatAirVolFlow =
2462 0 : airFlowAdjustmentRatio * state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1);
2463 : }
2464 : }
2465 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2466 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
2467 0 : Real64 airFlowAdjustmentRatio = 1.0;
2468 0 : if (!heatingAirFlowIsAutosized) {
2469 0 : airFlowAdjustmentRatio =
2470 0 : this->m_MaxHeatAirVolFlow /
2471 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2472 0 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2473 : }
2474 0 : if (this->m_CoolCoilExists) {
2475 0 : this->m_MaxNoCoolHeatAirVolFlow =
2476 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
2477 : airFlowAdjustmentRatio *
2478 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1));
2479 : } else {
2480 0 : this->m_MaxNoCoolHeatAirVolFlow =
2481 0 : airFlowAdjustmentRatio *
2482 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1);
2483 : }
2484 : }
2485 : }
2486 : }
2487 : }
2488 :
2489 : // Change the Volume Flow Rates to Mass Flow Rates
2490 86 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
2491 86 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
2492 86 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2493 86 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2494 86 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2495 86 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2496 86 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2497 :
2498 : // initialize multi-speed coils
2499 86 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) ||
2500 84 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
2501 6 : if (this->m_NumOfSpeedCooling > 0) {
2502 6 : if (this->m_CoolVolumeFlowRate.empty()) {
2503 1 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2504 : }
2505 6 : if (this->m_CoolMassFlowRate.empty()) {
2506 1 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2507 : }
2508 6 : if (this->m_MSCoolingSpeedRatio.empty()) {
2509 1 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2510 : }
2511 : }
2512 :
2513 6 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2514 6 : if (MSHPIndex > -1) {
2515 22 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1; --Iter) {
2516 20 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2517 10 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2518 10 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2519 : }
2520 : }
2521 : }
2522 :
2523 6 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2524 : blankString,
2525 6 : this->m_CoolingCoilIndex,
2526 : HVAC::FanOp::Invalid, // Invalid instead of off?
2527 : HVAC::CompressorOp::Off,
2528 : 0.0,
2529 : 1,
2530 : 0.0,
2531 : 0.0,
2532 : 0.0,
2533 : 0.0); // conduct the sizing operation in the VS WSHP
2534 6 : if (this->m_NumOfSpeedCooling != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds) {
2535 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2536 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2537 0 : ShowFatalError(state,
2538 0 : format("Cooling coil = {}: {}",
2539 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).VarSpeedCoilType,
2540 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).Name));
2541 : }
2542 6 : state.dataSize->DXCoolCap = VariableSpeedCoils::GetCoilCapacityVariableSpeed(
2543 6 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
2544 6 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2545 6 : if (this->m_DXHeatingCoil) {
2546 3 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2547 : }
2548 :
2549 61 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2550 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2551 55 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2552 20 : this->m_MSCoolingSpeedRatio[Iter] =
2553 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2554 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedCooling);
2555 10 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * this->m_MSCoolingSpeedRatio[Iter];
2556 10 : this->m_CoolMassFlowRate[Iter] = this->MaxCoolAirMassFlow * this->m_MSCoolingSpeedRatio[Iter];
2557 : } else {
2558 90 : this->m_CoolVolumeFlowRate[Iter] =
2559 45 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter);
2560 45 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2561 : // this is divided by the system max air flow, not the cooling coil max air flow, doesn't seem correct
2562 45 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2563 : }
2564 : }
2565 :
2566 6 : if (MSHPIndex > -1) {
2567 2 : this->m_MaxNoCoolHeatAirVolFlow =
2568 2 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2569 2 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2570 2 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2571 4 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2572 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2573 : }
2574 :
2575 80 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
2576 : // mine data from heat exchanger assisted cooling coil
2577 : // Get DX heat exchanger assisted cooling coil index
2578 1 : int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilType_Num;
2579 1 : if (childCCType_Num == HVAC::CoilDX_Cooling) {
2580 0 : int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilIndex;
2581 0 : if (childCCIndex < 0) {
2582 0 : ShowWarningError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
2583 0 : ShowFatalError(state, "No cooling coil = Coil:Cooling:DX found.");
2584 0 : ErrFound = true;
2585 : }
2586 0 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
2587 0 : this->m_NumOfSpeedCooling = newCoil.performance.normalMode.speeds.size();
2588 0 : if (this->m_NumOfSpeedCooling > 0) {
2589 0 : if (this->m_CoolVolumeFlowRate.empty()) {
2590 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2591 : }
2592 0 : if (this->m_CoolMassFlowRate.empty()) {
2593 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2594 : }
2595 0 : if (this->m_MSCoolingSpeedRatio.empty()) {
2596 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2597 : }
2598 : }
2599 :
2600 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2601 0 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2602 0 : if (MSHPIndex > -1) {
2603 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2604 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2605 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2606 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2607 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2608 : }
2609 : }
2610 : }
2611 :
2612 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2613 0 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2614 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2615 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2616 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2617 : }
2618 :
2619 : // Use discrete/continuous control algorithm regardless of number of speeds
2620 0 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2621 0 : this->m_DiscreteSpeedCoolingCoil = true;
2622 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2623 0 : this->m_ContSpeedCoolingCoil = true;
2624 : }
2625 :
2626 0 : newCoil.size(state);
2627 0 : if (MSHPIndex == -1) {
2628 0 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2629 0 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2630 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2631 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2632 0 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2633 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2634 : } else {
2635 0 : this->m_MSCoolingSpeedRatio[Iter] =
2636 0 : this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2637 : }
2638 : }
2639 : }
2640 :
2641 0 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2642 0 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2643 0 : if (this->m_HeatPump) {
2644 0 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2645 : }
2646 :
2647 0 : if (MSHPIndex > -1) {
2648 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2649 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2650 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2651 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2652 : }
2653 0 : this->m_CoolVolumeFlowRate[Iter] =
2654 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2655 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2656 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2657 : }
2658 0 : this->m_MaxNoCoolHeatAirVolFlow =
2659 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2660 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2661 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2662 0 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2663 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2664 : }
2665 : }
2666 79 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2667 6 : if (this->m_NumOfSpeedCooling > 0) {
2668 6 : if (this->m_CoolVolumeFlowRate.empty()) {
2669 1 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2670 : }
2671 6 : if (this->m_CoolMassFlowRate.empty()) {
2672 1 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2673 : }
2674 6 : if (this->m_MSCoolingSpeedRatio.empty()) {
2675 1 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2676 : }
2677 : }
2678 :
2679 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2680 6 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2681 6 : if (MSHPIndex > -1) {
2682 9 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2683 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2684 6 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2685 4 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2686 4 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2687 : }
2688 : }
2689 : }
2690 :
2691 : // mine capacity from Coil:Cooling:DX object
2692 6 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
2693 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2694 6 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2695 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2696 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2697 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2698 : }
2699 :
2700 : // Use discrete/continuous control algorithm regardless of number of speeds
2701 6 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2702 6 : this->m_DiscreteSpeedCoolingCoil = true;
2703 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2704 0 : this->m_ContSpeedCoolingCoil = true;
2705 : }
2706 :
2707 6 : newCoil.size(state);
2708 6 : if (MSHPIndex == -1) {
2709 : // Gotta loop backwards since we may try to access the last element when there are no fans
2710 8 : for (Iter = this->m_NumOfSpeedCooling; Iter >= 1; --Iter) {
2711 5 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2712 5 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2713 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2714 5 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2715 1 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2716 : } else {
2717 4 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2718 : }
2719 : }
2720 : }
2721 :
2722 6 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2723 6 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2724 6 : if (this->m_HeatPump) {
2725 0 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2726 : }
2727 :
2728 6 : if (MSHPIndex > -1) {
2729 9 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2730 6 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2731 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2732 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2733 : }
2734 12 : this->m_CoolVolumeFlowRate[Iter] =
2735 6 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2736 6 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2737 6 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2738 : }
2739 3 : this->m_MaxNoCoolHeatAirVolFlow =
2740 3 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2741 3 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2742 3 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2743 3 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2744 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2745 : }
2746 :
2747 73 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2748 8 : if (this->m_NumOfSpeedCooling > 0) {
2749 8 : if (this->m_CoolVolumeFlowRate.empty()) {
2750 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2751 : }
2752 8 : if (this->m_CoolMassFlowRate.empty()) {
2753 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2754 : }
2755 8 : if (this->m_MSCoolingSpeedRatio.empty()) {
2756 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2757 : }
2758 : }
2759 :
2760 : // set the multi-speed high flow rate variable in case a non-zero air flow rate resides on the coil inlet during sizing (e.g., upstream
2761 : // system ran prior to this one)
2762 16 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
2763 16 : EqSizing.CoolingAirVolFlow *
2764 8 : state.dataEnvrn->StdRhoAir; // doesn't matter what this value is since only coil size is needed and CompressorOn = 0 here
2765 8 : DXCoils::SimDXCoilMultiSpeed(state, blankString, 1.0, 1.0, this->m_CoolingCoilIndex, 0, HVAC::FanOp::Invalid, HVAC::CompressorOp::Off);
2766 8 : if (!HardSizeNoDesRun && EqSizing.Capacity) {
2767 : // do nothing, the vars EqSizing.DesCoolingLoad and DataSizing::DXCoolCap are already set earlier and the values could be max of the
2768 : // cooling and heating autosized values. Thus resetting them here to user specified value may not be the design size used else where
2769 : } else {
2770 14 : state.dataSize->DXCoolCap =
2771 7 : DXCoils::GetCoilCapacityByIndexType(state, this->m_CoolingCoilIndex, this->m_CoolingCoilType_Num, ErrFound);
2772 7 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2773 : }
2774 8 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2775 :
2776 8 : if (MSHPIndex > -1) {
2777 : // use reverse order since we divide by CoolVolumeFlowRate(max)
2778 16 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2779 11 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2780 8 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2781 8 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2782 : }
2783 22 : this->m_CoolVolumeFlowRate[Iter] =
2784 11 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2785 11 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2786 11 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2787 : }
2788 5 : this->m_MaxNoCoolHeatAirVolFlow =
2789 5 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2790 5 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2791 5 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2792 3 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2793 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2794 : } else {
2795 9 : for (Iter = this->m_NumOfSpeedCooling; Iter > 0; --Iter) {
2796 6 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * Iter / this->m_NumOfSpeedCooling;
2797 6 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2798 6 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2799 : }
2800 3 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2801 3 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2802 : }
2803 65 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2804 7 : if (this->m_NumOfSpeedCooling > 0) {
2805 0 : if (this->m_CoolVolumeFlowRate.empty()) {
2806 0 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2807 : }
2808 0 : if (this->m_CoolMassFlowRate.empty()) {
2809 0 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2810 : }
2811 0 : if (this->m_MSCoolingSpeedRatio.empty()) {
2812 0 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2813 : }
2814 : }
2815 7 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2816 :
2817 7 : if (MSHPIndex > -1) {
2818 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2819 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2820 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2821 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2822 : }
2823 0 : this->m_CoolVolumeFlowRate[Iter] =
2824 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2825 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2826 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2827 : }
2828 0 : this->m_MaxNoCoolHeatAirVolFlow =
2829 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2830 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2831 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2832 7 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2833 7 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2834 : }
2835 : }
2836 :
2837 86 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2838 80 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2839 9 : if (this->m_NumOfSpeedHeating > 0) {
2840 9 : if (this->m_HeatVolumeFlowRate.empty()) {
2841 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2842 : }
2843 9 : if (this->m_HeatMassFlowRate.empty()) {
2844 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2845 : }
2846 9 : if (this->m_MSHeatingSpeedRatio.empty()) {
2847 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2848 : }
2849 : }
2850 :
2851 9 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2852 :
2853 9 : if (MSHPIndex > -1) {
2854 : // use reverse order since we divide by HeatVolumeFlowRate(max)
2855 28 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2856 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2857 4 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint &&
2858 0 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2859 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage)) {
2860 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2861 : } else {
2862 4 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2863 4 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2864 : }
2865 : } else {
2866 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2867 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2868 15 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] < 1.0 &&
2869 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
2870 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2871 0 : ShowContinueError(
2872 0 : state, format("Design specification object = {}", state.dataUnitarySystems->designSpecMSHP[MSHPIndex].name));
2873 0 : ShowContinueError(state,
2874 : "When control type = SetPointBased the outlet air temperature must change with coil capacity, if "
2875 : "air flow also changes outlet air temperature will be relatively constant.");
2876 0 : ShowContinueError(
2877 : state,
2878 0 : format("Speed {} Supply Air Flow Ratio During Heating Operation will be set = 1.0 and the simulation continues",
2879 : Iter));
2880 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2881 : }
2882 : }
2883 : }
2884 38 : this->m_HeatVolumeFlowRate[Iter] =
2885 19 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2886 19 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2887 19 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2888 : }
2889 9 : if (this->m_CoolCoilExists) {
2890 1 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2891 1 : this->m_MaxNoCoolHeatAirVolFlow =
2892 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2893 1 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2894 1 : this->MaxNoCoolHeatAirMassFlow =
2895 1 : min(this->MaxNoCoolHeatAirMassFlow,
2896 1 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2897 1 : this->m_NoLoadAirFlowRateRatio =
2898 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2899 : } else {
2900 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2901 : }
2902 8 : } else if (MSHPIndex > -1) {
2903 8 : this->m_MaxNoCoolHeatAirVolFlow =
2904 8 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2905 8 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2906 8 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2907 : } else {
2908 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2909 : }
2910 : }
2911 77 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
2912 76 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2913 4 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2914 4 : if (MSHPIndex > -1) {
2915 33 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2916 30 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2917 20 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2918 20 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2919 : }
2920 : }
2921 : }
2922 :
2923 4 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2924 : blankString,
2925 4 : this->m_HeatingCoilIndex,
2926 : HVAC::FanOp::Invalid,
2927 : HVAC::CompressorOp::Off,
2928 : 0.0,
2929 : 1,
2930 : 0.0,
2931 : 0.0,
2932 : 0.0,
2933 : 0.0); // conduct the sizing operation in the VS WSHP
2934 :
2935 4 : if (this->m_NumOfSpeedHeating != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds) {
2936 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2937 0 : ShowContinueError(state, "Number of heating speeds does not match coil object.");
2938 0 : ShowFatalError(state,
2939 0 : format("Heating coil = {}: {}",
2940 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).VarSpeedCoilType,
2941 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).Name));
2942 : }
2943 :
2944 4 : if (this->m_NumOfSpeedHeating > 0) {
2945 4 : if (this->m_HeatVolumeFlowRate.empty()) {
2946 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2947 : }
2948 4 : if (this->m_HeatMassFlowRate.empty()) {
2949 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2950 : }
2951 4 : if (this->m_MSHeatingSpeedRatio.empty()) {
2952 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2953 : }
2954 : }
2955 :
2956 39 : for (Iter = this->m_NumOfSpeedHeating; Iter >= 1; --Iter) {
2957 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2958 35 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2959 : // SpeedRatio is only used in OnOff fan and should represent the ratio of flow to fan max flow
2960 20 : this->m_MSHeatingSpeedRatio[Iter] =
2961 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2962 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedHeating);
2963 10 : this->m_HeatVolumeFlowRate[Iter] = this->m_MaxHeatAirVolFlow * this->m_MSHeatingSpeedRatio[Iter];
2964 10 : this->m_HeatMassFlowRate[Iter] = this->MaxHeatAirMassFlow * this->m_MSHeatingSpeedRatio[Iter];
2965 : } else {
2966 50 : this->m_HeatVolumeFlowRate[Iter] =
2967 25 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter);
2968 25 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2969 25 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2970 : // this is divided by the system max air flow, not the heating coil max air flow
2971 25 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2972 : } else {
2973 : // if there is no fan this doesn't matter? Should calculate SpeedRatio in fan model? and get rid of SpeedRatio variable?
2974 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_HeatVolumeFlowRate[this->m_NumOfSpeedHeating];
2975 : }
2976 : }
2977 : }
2978 :
2979 4 : if (this->m_CoolCoilExists && this->m_NumOfSpeedHeating > 0) {
2980 8 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2981 3 : this->m_MaxNoCoolHeatAirVolFlow =
2982 3 : min(this->m_MaxNoCoolHeatAirVolFlow,
2983 3 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2984 3 : this->MaxNoCoolHeatAirMassFlow =
2985 3 : min(this->MaxNoCoolHeatAirMassFlow,
2986 3 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2987 3 : this->m_NoLoadAirFlowRateRatio =
2988 3 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2989 1 : } else if (this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2990 0 : this->m_MaxNoCoolHeatAirVolFlow =
2991 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2992 0 : this->MaxNoCoolHeatAirMassFlow =
2993 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2994 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2995 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2996 1 : } else if (!this->m_CoolVolumeFlowRate.empty()) {
2997 : // what the heck is this next line? should be min of min cooling and min heating flow rates?
2998 : // this is calculated above so likely not even needed here, just have to be sure it's always calculated
2999 1 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
3000 1 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
3001 1 : this->m_sysType == SysType::PackagedWSHP) {
3002 0 : if (!this->m_MultiOrVarSpeedCoolCoil && !this->m_MultiOrVarSpeedHeatCoil) {
3003 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3004 : }
3005 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
3006 : } else {
3007 : // this should be min of min cooling and min heating flow rates?
3008 1 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
3009 : }
3010 1 : this->m_NoLoadAirFlowRateRatio =
3011 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
3012 : } else {
3013 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
3014 : }
3015 0 : } else if (MSHPIndex > -1) {
3016 0 : this->m_MaxNoCoolHeatAirVolFlow =
3017 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3018 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
3019 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
3020 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3021 : } else {
3022 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
3023 : }
3024 : }
3025 86 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3026 : // pass air flow rate to zone water coil
3027 6 : if (state.dataSize->CurZoneEqNum > 0) {
3028 4 : WaterCoils::SetCoilDesFlow(state,
3029 4 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
3030 4 : this->m_HeatingCoilName,
3031 : this->m_MaxHeatAirVolFlow,
3032 4 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
3033 : }
3034 :
3035 6 : if (this->m_NumOfSpeedHeating > 0) {
3036 0 : if (this->m_HeatVolumeFlowRate.empty()) {
3037 0 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
3038 : }
3039 0 : if (this->m_HeatMassFlowRate.empty()) {
3040 0 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
3041 : }
3042 0 : if (this->m_MSHeatingSpeedRatio.empty()) {
3043 0 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
3044 : }
3045 : }
3046 :
3047 6 : MSHPIndex = this->m_DesignSpecMSHPIndex;
3048 6 : if (MSHPIndex > -1) {
3049 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
3050 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
3051 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
3052 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
3053 : }
3054 0 : this->m_HeatVolumeFlowRate[Iter] =
3055 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
3056 0 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
3057 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
3058 : }
3059 0 : if (this->m_CoolCoilExists) {
3060 0 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > 0) {
3061 0 : this->m_MaxNoCoolHeatAirVolFlow =
3062 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
3063 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
3064 0 : this->MaxNoCoolHeatAirMassFlow =
3065 0 : min(this->MaxNoCoolHeatAirMassFlow,
3066 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
3067 0 : this->m_NoLoadAirFlowRateRatio =
3068 0 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
3069 : } else {
3070 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
3071 0 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
3072 0 : this->m_NoLoadAirFlowRateRatio =
3073 0 : min(this->m_NoLoadAirFlowRateRatio, (this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate));
3074 : }
3075 : } else {
3076 0 : this->m_MaxNoCoolHeatAirVolFlow =
3077 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3078 0 : this->MaxNoCoolHeatAirMassFlow =
3079 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3080 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
3081 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
3082 : }
3083 : }
3084 : }
3085 :
3086 : // Not sure if this may be needed for special cases
3087 86 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow < 0.0) {
3088 0 : if (!state.dataSize->SysSizingRunDone) {
3089 0 : int BranchNum = BranchInputManager::GetAirBranchIndex(state, "AirloopHVAC:UnitarySystem", this->Name);
3090 0 : BranchFanFlow = 0.0;
3091 0 : if (BranchNum > 0.0) {
3092 0 : std::string FanType = "";
3093 0 : std::string FanName = "";
3094 0 : BranchInputManager::GetBranchFanTypeName(state, BranchNum, FanType, FanName, ErrFound);
3095 0 : if (!ErrFound) {
3096 0 : BranchFanFlow = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
3097 : }
3098 0 : }
3099 0 : if (BranchFanFlow > 0.0) {
3100 0 : this->m_MaxCoolAirVolFlow = BranchFanFlow;
3101 : } else {
3102 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3103 0 : if (SystemFlow > 0.0) {
3104 0 : this->m_MaxCoolAirVolFlow = SystemFlow;
3105 : } else {
3106 : // what do I do?
3107 : }
3108 : }
3109 : }
3110 : }
3111 :
3112 : // why is this here?
3113 86 : this->m_SenLoadLoss = 0.0;
3114 86 : if (this->m_Humidistat) {
3115 3 : this->m_LatLoadLoss = 0.0;
3116 : }
3117 :
3118 86 : switch (this->m_sysType) {
3119 6 : case SysType::PackagedAC:
3120 : case SysType::PackagedHP:
3121 6 : PrintFlag = false;
3122 6 : break;
3123 80 : default:
3124 80 : break;
3125 : }
3126 86 : if (this->m_CoolCoilExists) {
3127 68 : SizingMethod = HVAC::CoolingCapacitySizing;
3128 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3129 68 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
3130 14 : WaterCoils::SimulateWaterCoilComponents(
3131 14 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3132 7 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3133 14 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
3134 7 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3135 7 : state.dataSize->DataFractionUsedForSizing = 1.0;
3136 7 : SizingMethod = HVAC::AutoCalculateSizing;
3137 7 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3138 61 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
3139 : std::string HXCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(
3140 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3141 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
3142 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound, true);
3143 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(
3144 0 : state, blankString, true, HVAC::CompressorOp::On, 1.0, this->m_CoolingCoilIndex, HVAC::FanOp::Cycling, false, 1.0, false);
3145 0 : state.dataSize->DataConstantUsedForSizing =
3146 0 : WaterCoils::GetWaterCoilCapacity(state, Util::makeUPPER(HVAC::cAllCoilTypes(ActualCoolCoilType)), HXCoilName, ErrFound);
3147 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3148 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3149 0 : SizingMethod = HVAC::AutoCalculateSizing;
3150 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3151 61 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3152 2 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3153 : blankString,
3154 2 : this->m_CoolingCoilIndex,
3155 : this->m_CoolingCoilSensDemand,
3156 : this->m_CoolingCoilLatentDemand,
3157 : HVAC::FanOp::Invalid,
3158 : HVAC::CompressorOp::Off,
3159 : 0.0,
3160 : FirstHVACIteration);
3161 2 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3162 2 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3163 2 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3164 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3165 2 : SizingMethod = HVAC::AutoCalculateSizing;
3166 2 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3167 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
3168 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3169 : }
3170 : // airflow sizing with multispeed fan
3171 4 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3172 2 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3173 2 : if (this->m_NumOfSpeedCooling > 1) {
3174 1 : int FanIndex = this->m_FanIndex;
3175 3 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
3176 2 : if (this->m_DesignSpecMSHPIndex > -1) {
3177 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] ==
3178 : DataSizing::AutoSize) {
3179 2 : this->m_CoolVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedCooling) * AirFlowRate;
3180 : } else {
3181 0 : this->m_CoolVolumeFlowRate[i] =
3182 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
3183 : }
3184 : } else {
3185 0 : this->m_CoolVolumeFlowRate[i] =
3186 0 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3187 : }
3188 2 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3189 : }
3190 : }
3191 59 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
3192 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
3193 : blankString,
3194 0 : this->m_CoolingCoilIndex,
3195 : this->MaxCoolAirMassFlow,
3196 : this->m_FanOpMode,
3197 : FirstHVACIteration,
3198 0 : this->m_InitHeatPump,
3199 : 0.0,
3200 : 0.0,
3201 : HVAC::CompressorOp::Off,
3202 : 0.0);
3203 0 : state.dataSize->DataConstantUsedForSizing =
3204 0 : WaterToAirHeatPump::GetCoilCapacity(state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3205 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3206 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3207 0 : SizingMethod = HVAC::AutoCalculateSizing;
3208 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
3209 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3210 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3211 : }
3212 59 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
3213 0 : PackagedThermalStorageCoil::SimTESCoil(
3214 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, 0.0);
3215 0 : PackagedThermalStorageCoil::GetTESCoilCoolingCapacity(
3216 0 : state, this->m_CoolingCoilName, state.dataSize->DataConstantUsedForSizing, ErrFound, CompType);
3217 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3218 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3219 0 : SizingMethod = HVAC::AutoCalculateSizing;
3220 : }
3221 :
3222 68 : TempSize = this->m_DesignCoolingCapacity;
3223 68 : state.dataSize->DataFlowUsedForSizing = this->m_MaxCoolAirVolFlow;
3224 68 : SizingString = "Nominal Cooling Capacity [W]";
3225 68 : bool errorsFound = false;
3226 68 : CoolingCapacitySizer sizerCoolingCapacity;
3227 68 : sizerCoolingCapacity.overrideSizingString(SizingString);
3228 68 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3229 68 : this->m_DesignCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
3230 68 : state.dataSize->DataConstantUsedForSizing = 0.0;
3231 68 : state.dataSize->DataFractionUsedForSizing = 0.0;
3232 68 : state.dataSize->DataFlowUsedForSizing = 0.0;
3233 68 : }
3234 :
3235 86 : if (this->m_HeatCoilExists) {
3236 52 : SizingMethod = HVAC::HeatingCapacitySizing;
3237 :
3238 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3239 52 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3240 12 : WaterCoils::SimulateWaterCoilComponents(
3241 12 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3242 6 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3243 12 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
3244 6 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3245 6 : state.dataSize->DataFractionUsedForSizing = 1.0;
3246 6 : SizingMethod = HVAC::AutoCalculateSizing;
3247 6 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3248 46 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3249 2 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3250 : blankString,
3251 2 : this->m_HeatingCoilIndex,
3252 : this->m_HeatingCoilSensDemand,
3253 : dummy,
3254 : HVAC::FanOp::Invalid, // Invalid instead of off?
3255 : HVAC::CompressorOp::Off,
3256 : 0.0,
3257 : FirstHVACIteration);
3258 2 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3259 2 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3260 2 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3261 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3262 2 : SizingMethod = HVAC::AutoCalculateSizing;
3263 2 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3264 2 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3265 : // adjusted cooling coil capacity
3266 2 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3267 : blankString,
3268 2 : this->m_CoolingCoilIndex,
3269 : this->m_CoolingCoilSensDemand,
3270 : this->m_CoolingCoilLatentDemand,
3271 : HVAC::FanOp::Invalid, // Invalid instead of off?
3272 : HVAC::CompressorOp::Off,
3273 : 0.0,
3274 : FirstHVACIteration);
3275 2 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3276 2 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3277 2 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3278 : }
3279 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3280 2 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3281 : // airflow sizing with multispeed fan
3282 4 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3283 2 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3284 2 : if (this->m_NumOfSpeedHeating > 1) {
3285 1 : int FanIndex = this->m_FanIndex;
3286 3 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
3287 2 : if (this->m_DesignSpecMSHPIndex > -1) {
3288 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] ==
3289 : DataSizing::AutoSize) {
3290 2 : this->m_HeatVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedHeating) * AirFlowRate;
3291 : } else {
3292 0 : this->m_HeatVolumeFlowRate[i] =
3293 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
3294 : }
3295 : } else {
3296 0 : this->m_HeatVolumeFlowRate[i] =
3297 0 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3298 : }
3299 2 : this->m_HeatMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3300 : }
3301 : }
3302 : }
3303 :
3304 52 : TempSize = this->m_DesignHeatingCapacity;
3305 52 : SizingString = "Nominal Heating Capacity [W]";
3306 52 : if (state.dataSize->CurSysNum > 0) {
3307 3 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
3308 : false; // set to false to allow calculation of parent object heating capacity
3309 : }
3310 52 : bool errorsFound = false;
3311 52 : HeatingCapacitySizer sizerHeatingCapacity;
3312 52 : sizerHeatingCapacity.overrideSizingString(SizingString);
3313 52 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3314 52 : TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3315 52 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3316 2 : state.dataSize->DXCoolCap = TempSize;
3317 : }
3318 52 : if (state.dataSize->CurSysNum > 0) {
3319 3 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
3320 : }
3321 52 : this->m_DesignHeatingCapacity = TempSize;
3322 52 : state.dataSize->DataConstantUsedForSizing = 0.0;
3323 52 : state.dataSize->DataFractionUsedForSizing = 0.0;
3324 52 : state.dataSize->DataHeatSizeRatio = 1.0;
3325 52 : }
3326 :
3327 86 : if (!HardSizeNoDesRun && (EqSizing.Capacity && EqSizing.DesHeatingLoad > 0.0)) {
3328 : // vars EqSizing.DesHeatingLoad is already set earlier and supplemental heating coil should
3329 : // be sized to design value instead of user specified value if HardSizeNoDesRun is false
3330 4 : state.dataSize->UnitaryHeatCap = EqSizing.DesHeatingLoad;
3331 :
3332 : } else {
3333 82 : state.dataSize->UnitaryHeatCap = this->m_DesignHeatingCapacity;
3334 : }
3335 :
3336 86 : if (this->m_sysType == SysType::PackagedWSHP) {
3337 2 : PrintFlag = true;
3338 : }
3339 :
3340 86 : if ((this->m_HeatCoilExists || this->m_SuppCoilExists) && this->m_ControlType != UnitarySysCtrlType::CCMASHRAE) {
3341 50 : TempSize = this->DesignMaxOutletTemp;
3342 50 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
3343 50 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3344 2 : PrintFlag = true;
3345 2 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
3346 2 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
3347 2 : }
3348 50 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3349 50 : this->DesignMaxOutletTemp = sizerMaxHeaterOutTemp.size(state, TempSize, ErrFound);
3350 50 : }
3351 :
3352 86 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3353 2 : PrintFlag = false;
3354 : }
3355 :
3356 86 : if (this->m_SuppCoilExists) {
3357 13 : switch (this->m_sysType) {
3358 2 : case SysType::PackagedWSHP:
3359 : case SysType::PackagedHP:
3360 2 : if (this->m_HVACSizingIndex <= 0) {
3361 2 : EqSizing.HeatingCapacity = false; // ensure PTHP supplemental heating coil sizes to load
3362 : }
3363 2 : break;
3364 11 : default:
3365 11 : break;
3366 : }
3367 :
3368 13 : TempSize = this->m_DesignSuppHeatingCapacity;
3369 13 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
3370 13 : if (TempSize == DataSizing::AutoSize) {
3371 5 : IsAutoSize = true;
3372 5 : if (this->m_sysType == SysType::Unitary) {
3373 3 : PrintFlag = false;
3374 : }
3375 5 : bool errorsFound = false;
3376 5 : HeatingCapacitySizer sizerHeatingCapacity;
3377 5 : sizerHeatingCapacity.overrideSizingString(SizingString);
3378 5 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3379 5 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3380 5 : }
3381 : // logic here isn't accurate. Replicating temporarily to minimize diffs in AutoSizingLibrary refactor
3382 13 : TempSize = this->m_DesignSuppHeatingCapacity;
3383 :
3384 13 : if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && IsAutoSize) {
3385 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_DesignSuppHeatingCapacity, this->m_DesignCoolingCapacity);
3386 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3387 0 : TempSize = DataSizing::AutoSize;
3388 : // pass design size to supplemental heater
3389 0 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3390 13 : } else if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
3391 0 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3392 : } else {
3393 13 : if (state.dataSize->CurZoneEqNum > 0) {
3394 13 : state.dataSize->SuppHeatCap = saveRawHeatingCapacity;
3395 : } else {
3396 0 : state.dataSize->SuppHeatCap = this->m_DesignHeatingCapacity;
3397 : }
3398 : }
3399 :
3400 13 : if (this->m_OKToPrintSizing &&
3401 13 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3402 11 : PrintFlag = true;
3403 : }
3404 13 : state.dataSize->DataCoilIsSuppHeater = true;
3405 13 : bool errorsFound = false;
3406 13 : HeatingCapacitySizer sizerHeatingCapacity;
3407 13 : sizerHeatingCapacity.overrideSizingString(SizingString);
3408 13 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3409 13 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3410 13 : state.dataSize->DataConstantUsedForSizing = 0.0;
3411 13 : state.dataSize->DataFractionUsedForSizing = 0.0;
3412 13 : state.dataSize->DataCoilIsSuppHeater = false;
3413 : }
3414 :
3415 : // register plant flow rate. Not sure this has ever been tested.
3416 86 : if (this->m_HeatRecActive) {
3417 2 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->m_HeatRecoveryInletNodeNum, this->m_DesignHRWaterVolumeFlow);
3418 : }
3419 :
3420 : // Set flow rate for unitary system with no fan
3421 86 : if (state.dataSize->CurOASysNum == 0 && state.dataSize->CurZoneEqNum == 0 && this->m_DesignFanVolFlowRate <= 0.0) {
3422 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3423 0 : if (SystemFlow > 0.0) {
3424 0 : this->m_DesignFanVolFlowRate = SystemFlow;
3425 : } else {
3426 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3427 : }
3428 0 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
3429 : }
3430 :
3431 : // Moved from InitLoadBasedControl
3432 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
3433 86 : if (this->m_AirLoopEquipment && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
3434 25 : int NumAirLoopZones = 0; // number of zone inlet nodes in an air loop
3435 25 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
3436 1 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = true;
3437 1 : NumAirLoopZones =
3438 1 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
3439 1 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3440 : // zone inlet nodes for cooling
3441 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
3442 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
3443 : // the data structure for the zones inlet nodes has not been filled
3444 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3445 : }
3446 : }
3447 : // zone inlet nodes for heating
3448 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
3449 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
3450 : // the data structure for the zones inlet nodes has not been filled
3451 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3452 : }
3453 : }
3454 : }
3455 : }
3456 25 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady) {
3457 1 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
3458 1 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3459 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
3460 0 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3461 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == this->ControlZoneNum) {
3462 0 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
3463 0 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3464 : }
3465 : }
3466 1 : if (SumOfMassFlowRateMax != 0.0) {
3467 0 : if (state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
3468 0 : this->ControlZoneMassFlowFrac =
3469 0 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
3470 : } else {
3471 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3472 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
3473 0 : this->ControlZoneMassFlowFrac = 1.0;
3474 : }
3475 0 : this->m_SmallLoadTolerance = 5.0 / this->ControlZoneMassFlowFrac; // adjust 5W load tolerance by control zone fraction
3476 0 : BaseSizer::reportSizerOutput(state,
3477 : this->UnitType,
3478 : this->Name,
3479 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
3480 : this->ControlZoneMassFlowFrac);
3481 : }
3482 : }
3483 25 : } else {
3484 61 : this->ControlZoneMassFlowFrac = 1.0;
3485 : }
3486 :
3487 : // should only report for those that allow SZVAV inputs, e.g., control type == CCMASHRAE
3488 86 : PrintFlag = true;
3489 :
3490 86 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3491 2 : bool SizingDesRunThisSys = false;
3492 2 : state.dataSize->DataZoneUsedForSizing = this->ControlZoneNum;
3493 2 : CheckThisZoneForSizing(state, state.dataSize->DataZoneUsedForSizing, SizingDesRunThisSys);
3494 :
3495 2 : capacityMultiplier = 0.5; // one-half of design zone load
3496 2 : if (SizingDesRunThisSys) {
3497 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesCoolLoad * capacityMultiplier;
3498 : } else {
3499 2 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignCoolingCapacity * capacityMultiplier;
3500 : }
3501 2 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3502 2 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3503 2 : ASHRAEMinSATCoolingSizer sizerASHRAEMinSATCooling;
3504 2 : std::string stringOverride = "Minimum Supply Air Temperature [C]";
3505 2 : if (state.dataGlobal->isEpJSON) {
3506 0 : stringOverride = "minimum_supply_air_temperature [C]";
3507 : }
3508 2 : sizerASHRAEMinSATCooling.overrideSizingString(stringOverride);
3509 2 : sizerASHRAEMinSATCooling.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3510 2 : this->DesignMinOutletTemp = sizerASHRAEMinSATCooling.size(state, this->DesignMinOutletTemp, ErrFound);
3511 :
3512 2 : if (SizingDesRunThisSys) {
3513 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesHeatLoad * capacityMultiplier;
3514 : } else {
3515 2 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignHeatingCapacity * capacityMultiplier;
3516 : }
3517 2 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3518 2 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3519 2 : ASHRAEMaxSATHeatingSizer sizerASHRAEMaxSATHeating;
3520 2 : stringOverride = "Maximum Supply Air Temperature [C]";
3521 2 : if (state.dataGlobal->isEpJSON) {
3522 0 : stringOverride = "maximum_supply_air_temperature [C]";
3523 : }
3524 2 : sizerASHRAEMaxSATHeating.overrideSizingString(stringOverride);
3525 2 : sizerASHRAEMaxSATHeating.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3526 2 : this->DesignMaxOutletTemp = sizerASHRAEMaxSATHeating.size(state, this->DesignMaxOutletTemp, ErrFound);
3527 :
3528 2 : state.dataSize->DataCapacityUsedForSizing = 0.0; // reset so other routines don't use this inadvertently
3529 2 : state.dataSize->DataFlowUsedForSizing = 0.0;
3530 2 : state.dataSize->DataZoneUsedForSizing = 0;
3531 :
3532 : // check that MaxNoCoolHeatAirVolFlow is less than both MaxCoolAirVolFlow and MaxHeatAirVolFlow
3533 2 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3534 2 : if (this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxCoolAirVolFlow || this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxHeatAirVolFlow) {
3535 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3536 0 : ShowContinueError(
3537 : state,
3538 : " For SingleZoneVAV control the No Load Supply Air Flow Rate must be less than both the cooling and heating supply "
3539 : "air flow rates.");
3540 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow) - 0.01;
3541 0 : ShowContinueError(
3542 : state,
3543 0 : format(" The SingleZoneVAV control No Load Supply Air Flow Rate is reset to {:.5T} and the simulation continues.",
3544 0 : this->m_MaxNoCoolHeatAirVolFlow));
3545 : }
3546 : }
3547 2 : }
3548 :
3549 86 : state.dataUnitarySystems->CoolingLoad = TempCoolingLoad;
3550 86 : state.dataUnitarySystems->HeatingLoad = TempHeatingLoad;
3551 : // if (++NumUnitarySystemsSized == NumUnitarySystem)
3552 : // UnitarySystemNumericFields.deallocate(); // remove temporary array for field names at end of sizing
3553 86 : } // namespace UnitarySystems
3554 :
3555 203 : void UnitarySys::processInputSpec(EnergyPlusData &state,
3556 : const UnitarySysInputSpec &input_data,
3557 : int sysNum,
3558 : bool &errorsFound,
3559 : bool const ZoneEquipment,
3560 : int const ZoneOAUnitNum)
3561 : {
3562 : static constexpr std::string_view routineName = "UnitarySys::processInputSpec";
3563 :
3564 : using namespace OutputReportPredefined;
3565 :
3566 : static constexpr std::string_view unitarySysHeatPumpPerformanceObjectType("UnitarySystemPerformance:Multispeed");
3567 :
3568 203 : std::string const &cCurrentModuleObject = input_data.system_type;
3569 : DataLoopNode::ConnectionObjectType objType = static_cast<DataLoopNode::ConnectionObjectType>(
3570 203 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(input_data.system_type)));
3571 203 : std::string const &thisObjectName = input_data.name;
3572 :
3573 203 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisObjectName};
3574 :
3575 203 : this->Name = Util::makeUPPER(thisObjectName);
3576 203 : sysNum = getUnitarySystemIndex(state, thisObjectName);
3577 203 : this->m_UnitarySysNum = sysNum;
3578 :
3579 203 : if (ZoneEquipment) {
3580 142 : this->m_IsZoneEquipment = true;
3581 : }
3582 203 : if (state.dataUnitarySystems->getInputOnceFlag) {
3583 208 : this->AirInNode = NodeInputManager::GetOnlySingleNode(state,
3584 104 : input_data.air_inlet_node_name,
3585 : errorsFound,
3586 : objType,
3587 : thisObjectName,
3588 : DataLoopNode::NodeFluidType::Air,
3589 : DataLoopNode::ConnectionType::Inlet,
3590 : NodeInputManager::CompFluidStream::Primary,
3591 : DataLoopNode::ObjectIsParent);
3592 : } else {
3593 99 : this->AirInNode = Util::FindItemInList(input_data.air_inlet_node_name, state.dataLoopNodes->NodeID);
3594 : }
3595 :
3596 203 : if (state.dataUnitarySystems->getInputOnceFlag) {
3597 208 : this->AirOutNode = NodeInputManager::GetOnlySingleNode(state,
3598 104 : input_data.air_outlet_node_name,
3599 : errorsFound,
3600 : objType,
3601 : thisObjectName,
3602 : DataLoopNode::NodeFluidType::Air,
3603 : DataLoopNode::ConnectionType::Outlet,
3604 : NodeInputManager::CompFluidStream::Primary,
3605 : DataLoopNode::ObjectIsParent);
3606 : } else {
3607 99 : this->AirOutNode = Util::FindItemInList(input_data.air_outlet_node_name, state.dataLoopNodes->NodeID);
3608 : }
3609 :
3610 : // need to read in all information needed to SetupOutputVariable in setupAllOutputVars
3611 : // as soon as all systems are read in, regardless if all information is available, reports will be set up.
3612 : // make sure we have all the information needed to process reports (see IF blocks in setupAllOutputVars).
3613 : // all coil types, which comps exist, control type, heat recovery active, cooling coil index.
3614 203 : bool errFlag = false;
3615 203 : bool PrintMessage = false;
3616 :
3617 203 : if (!input_data.design_specification_multispeed_object_type.empty() && !input_data.design_specification_multispeed_object_name.empty()) {
3618 45 : this->m_DesignSpecMultispeedHPType = input_data.design_specification_multispeed_object_type;
3619 45 : this->m_DesignSpecMultispeedHPName = input_data.design_specification_multispeed_object_name;
3620 45 : DesignSpecMSHP thisDesignSpec;
3621 45 : this->m_CompPointerMSHP = thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, this->m_DesignSpecMultispeedHPName);
3622 45 : this->m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, this->m_DesignSpecMultispeedHPName);
3623 45 : }
3624 :
3625 : // these are needed for call from GetOASysNumHeat(Cool)ingCoils
3626 203 : this->m_HeatingCoilName = input_data.heating_coil_name;
3627 203 : this->m_HeatingCoilTypeName = input_data.heating_coil_object_type;
3628 203 : if (!this->m_HeatingCoilTypeName.empty()) {
3629 130 : this->m_HeatCoilExists = true;
3630 : }
3631 203 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num == 0) {
3632 64 : if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:VariableSpeed")) {
3633 4 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingAirToAirVariableSpeed;
3634 60 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:MultiSpeed")) {
3635 3 : this->m_HeatingCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
3636 57 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Water")) {
3637 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWater;
3638 5 : if (this->m_DesignSpecMSHPIndex > -1) {
3639 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
3640 1 : if (this->m_NumOfSpeedHeating > 1) {
3641 0 : this->m_MultiSpeedHeatingCoil = true;
3642 0 : this->m_MultiOrVarSpeedHeatCoil = true;
3643 : }
3644 : }
3645 52 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Steam")) {
3646 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
3647 52 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:EquationFit")) {
3648 2 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPSimple;
3649 50 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation")) {
3650 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHP;
3651 50 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3652 1 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
3653 49 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric:MultiStage")) {
3654 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingElectric_MultiStage;
3655 44 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Gas:MultiStage")) {
3656 3 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingGas_MultiStage;
3657 55 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Fuel") ||
3658 55 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric") ||
3659 46 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Desuperheater")) {
3660 37 : this->m_HeatingCoilType_Num =
3661 37 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
3662 4 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:UserDefined")) {
3663 0 : this->m_HeatingCoilType_Num = HVAC::Coil_UserDefined;
3664 4 : } else if (this->m_HeatCoilExists) {
3665 4 : this->m_HeatingCoilType_Num =
3666 4 : DXCoils::GetCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag, PrintMessage);
3667 : }
3668 :
3669 64 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
3670 61 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
3671 56 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
3672 11 : this->m_MultiSpeedHeatingCoil = true;
3673 53 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
3674 52 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
3675 5 : this->m_VarSpeedHeatingCoil = true;
3676 : }
3677 : }
3678 :
3679 203 : this->m_CoolingCoilName = input_data.cooling_coil_name;
3680 203 : if (!input_data.cooling_coil_object_type.empty()) { // not required field
3681 170 : this->m_CoolCoilExists = true;
3682 : }
3683 : // Find the type of coil. do not print message since this may not be the correct coil type.
3684 203 : errFlag = false;
3685 203 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num == 0) {
3686 86 : if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:VariableSpeed")) {
3687 7 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
3688 79 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:MultiSpeed")) {
3689 8 : this->m_CoolingCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3690 71 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water")) {
3691 11 : this->m_IsDXCoil = false;
3692 11 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3693 11 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3694 11 : if (this->m_DesignSpecMSHPIndex > -1) {
3695 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3696 1 : if (this->m_NumOfSpeedCooling > 1) {
3697 1 : this->m_DiscreteSpeedCoolingCoil = true;
3698 1 : this->m_MultiOrVarSpeedCoolCoil = true;
3699 : }
3700 : }
3701 60 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water:DetailedGeometry")) {
3702 1 : this->m_IsDXCoil = false;
3703 1 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterDetailed;
3704 1 : if (this->m_DesignSpecMSHPIndex > -1) {
3705 0 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3706 0 : if (this->m_NumOfSpeedCooling > 1) {
3707 0 : this->m_DiscreteSpeedCoolingCoil = true;
3708 0 : this->m_MultiOrVarSpeedCoolCoil = true;
3709 : }
3710 : }
3711 59 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
3712 0 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
3713 59 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
3714 2 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3715 2 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3716 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
3717 0 : this->m_IsDXCoil = false;
3718 0 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3719 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3720 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:EquationFit")) {
3721 2 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPSimple;
3722 55 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation")) {
3723 0 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHP;
3724 55 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3725 1 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
3726 54 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed")) {
3727 45 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
3728 9 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoSpeed")) {
3729 3 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
3730 6 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:UserDefined")) {
3731 0 : this->m_IsDXCoil = false;
3732 0 : this->m_CoolingCoilType_Num = HVAC::Coil_UserDefined;
3733 6 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed:ThermalStorage")) {
3734 0 : this->m_CoolingCoilType_Num = HVAC::CoilDX_PackagedThermalStorageCooling;
3735 6 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX")) { // CoilCoolingDX
3736 6 : this->m_CoolingCoilType_Num = HVAC::CoilDX_Cooling;
3737 6 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
3738 6 : if (this->m_CoolingCoilIndex == -1) {
3739 0 : ShowFatalError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
3740 : } else {
3741 : // set variable speed coil flag as necessary
3742 6 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
3743 6 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
3744 6 : if (this->m_NumOfSpeedCooling > 1) {
3745 5 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
3746 5 : this->m_DiscreteSpeedCoolingCoil = true;
3747 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
3748 0 : this->m_ContSpeedCoolingCoil = true;
3749 : }
3750 5 : this->m_MultiOrVarSpeedCoolCoil = true;
3751 : }
3752 : }
3753 : }
3754 :
3755 86 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
3756 8 : this->m_DiscreteSpeedCoolingCoil = true;
3757 78 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
3758 77 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
3759 8 : this->m_ContSpeedCoolingCoil = true;
3760 : }
3761 : }
3762 :
3763 203 : if (!input_data.supplemental_heating_coil_object_type.empty()) {
3764 53 : this->m_SuppCoilExists = true;
3765 : }
3766 :
3767 203 : if (!input_data.supply_fan_object_type.empty() && !input_data.supply_fan_name.empty()) {
3768 142 : this->m_FanExists = true;
3769 : }
3770 :
3771 : constexpr static std::array<std::string_view, static_cast<int>(UnitarySysCtrlType::Num)> UnitarySysCtrlTypeNamesUC = {
3772 : "NONE", "LOAD", "SETPOINT", "SINGLEZONEVAV"};
3773 203 : this->m_ControlType = static_cast<UnitarySysCtrlType>(getEnumValue(UnitarySysCtrlTypeNamesUC, Util::makeUPPER(input_data.control_type)));
3774 203 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3775 8 : this->m_ValidASHRAECoolCoil = true;
3776 8 : this->m_ValidASHRAEHeatCoil = true;
3777 : }
3778 :
3779 203 : this->m_DesignHRWaterVolumeFlow = input_data.design_heat_recovery_water_flow_rate;
3780 203 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
3781 9 : this->m_HeatRecActive = true;
3782 : }
3783 :
3784 203 : errFlag = false;
3785 203 : if (!input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) {
3786 13 : this->OAMixerIndex = MixedAir::GetOAMixerIndex(state, input_data.oa_mixer_name);
3787 13 : ValidateComponent(state, input_data.oa_mixer_type, input_data.oa_mixer_name, errFlag, cCurrentModuleObject);
3788 13 : if (errFlag) {
3789 0 : ShowContinueError(state, format("specified in {} = \"{}\".", cCurrentModuleObject, input_data.oa_mixer_name));
3790 0 : errorsFound = true;
3791 0 : errFlag = false;
3792 : } else {
3793 13 : this->OAMixerExists = true;
3794 : // OANodeNums = outside air mixer node numbers, OANodeNums(4) = outside air mixer mixed air node
3795 13 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, input_data.oa_mixer_name, errFlag);
3796 13 : if (errFlag) {
3797 0 : ShowContinueError(state, format("that was specified in {} = {}", cCurrentModuleObject, input_data.oa_mixer_name));
3798 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
3799 0 : errorsFound = true;
3800 0 : errFlag = false;
3801 : } else {
3802 13 : this->m_OAMixerNodes[0] = OANodeNums(1); // inlet
3803 13 : this->m_OAMixerNodes[1] = OANodeNums(2); // relief
3804 13 : this->m_OAMixerNodes[2] = OANodeNums(3); // return
3805 13 : this->m_OAMixerNodes[3] = OANodeNums(4); // mixed
3806 : }
3807 13 : }
3808 380 : } else if ((input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) ||
3809 190 : (!input_data.oa_mixer_type.empty() && input_data.oa_mixer_name.empty())) {
3810 0 : ShowSevereError(state, format("Missing one of {} Outdoor Air Mixer inputs.", cCurrentModuleObject));
3811 0 : ShowContinueError(state, format("..OutdoorAir:Mixer type = {}", input_data.oa_mixer_type));
3812 0 : ShowContinueError(state, format("..OutdoorAir:Mixer name = {}", input_data.oa_mixer_name));
3813 0 : errorsFound = true;
3814 : }
3815 203 : this->m_HeatConvTol = input_data.heat_conv_tol;
3816 203 : this->m_CoolConvTol = input_data.cool_conv_tol;
3817 :
3818 : // Early calls to ATMixer don't have enough info to pass GetInput. Need to get the data next time through.
3819 203 : if (sysNum == -1 || !state.dataZoneEquip->ZoneEquipInputsFilled) {
3820 103 : return;
3821 : }
3822 :
3823 102 : this->m_CoolOutAirVolFlow = input_data.cooling_oa_flow_rate;
3824 102 : this->m_HeatOutAirVolFlow = input_data.heating_oa_flow_rate;
3825 102 : this->m_NoCoolHeatOutAirVolFlow = input_data.no_load_oa_flow_rate;
3826 :
3827 102 : if (ZoneEquipment) {
3828 72 : this->m_OKToPrintSizing = true;
3829 : }
3830 :
3831 102 : this->m_IterationMode.resize(3);
3832 :
3833 102 : std::string loc_m_CoolingSAFMethod = input_data.cooling_supply_air_flow_rate_method;
3834 102 : Real64 loc_m_CoolingSAFMethod_SAFlow = input_data.cooling_supply_air_flow_rate;
3835 102 : Real64 loc_m_CoolingSAFMethod_SAFlowPerFloorArea = input_data.cooling_supply_air_flow_rate_per_floor_area;
3836 102 : Real64 loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.cooling_fraction_of_autosized_cooling_supply_air_flow_rate;
3837 102 : Real64 loc_m_CoolingSAFMethod_FlowPerCoolingCapacity = input_data.cooling_supply_air_flow_rate_per_unit_of_capacity;
3838 102 : std::string loc_m_HeatingSAFMethod = input_data.heating_supply_air_flow_rate_method;
3839 102 : Real64 loc_m_HeatingSAFMethod_SAFlow = input_data.heating_supply_air_flow_rate;
3840 102 : Real64 loc_m_HeatingSAFMethod_SAFlowPerFloorArea = input_data.heating_supply_air_flow_rate_per_floor_area;
3841 102 : Real64 loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.heating_fraction_of_autosized_heating_supply_air_flow_rate;
3842 102 : Real64 loc_m_HeatingSAFMethod_FlowPerHeatingCapacity = input_data.heating_supply_air_flow_rate_per_unit_of_capacity;
3843 102 : std::string loc_m_NoCoolHeatSAFMethod = input_data.no_load_supply_air_flow_rate_method;
3844 102 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlow = input_data.no_load_supply_air_flow_rate;
3845 102 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = input_data.no_load_supply_air_flow_rate_per_floor_area;
3846 102 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.no_load_fraction_of_autosized_cooling_supply_air_flow_rate;
3847 102 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.no_load_fraction_of_autosized_heating_supply_air_flow_rate;
3848 102 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity =
3849 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation;
3850 102 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity =
3851 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation;
3852 :
3853 102 : int FanInletNode = 0;
3854 102 : int FanOutletNode = 0;
3855 102 : Real64 FanVolFlowRate = 0.0;
3856 102 : int CoolingCoilInletNode = 0;
3857 102 : int CoolingCoilOutletNode = 0;
3858 102 : int HeatingCoilInletNode = 0;
3859 102 : int HeatingCoilOutletNode = 0;
3860 102 : int SupHeatCoilInletNode = 0;
3861 102 : int SupHeatCoilOutletNode = 0;
3862 :
3863 102 : bool isNotOK = false;
3864 :
3865 102 : if (input_data.availability_schedule_name.empty()) {
3866 22 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3867 80 : } else if ((this->m_sysAvailSched = Sched::GetSchedule(state, input_data.availability_schedule_name)) == nullptr) {
3868 1 : ShowWarningItemNotFound(state,
3869 : eoh,
3870 : "Availability Schedule Name",
3871 : input_data.availability_schedule_name,
3872 : "Set the default as Always On. Simulation continues.");
3873 1 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3874 : }
3875 :
3876 102 : if (!input_data.controlling_zone_or_thermostat_location.empty()) { // not required field
3877 52 : this->ControlZoneNum = Util::FindItemInList(input_data.controlling_zone_or_thermostat_location, state.dataHeatBal->Zone);
3878 50 : } else if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3879 20 : if (this->m_sysType == SysType::Unitary) {
3880 1 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3881 2 : ShowContinueError(state, "Controlling Zone or Thermostat Location cannot be blank when Control Type = Load or SingleZoneVAV");
3882 1 : errorsFound = true;
3883 : }
3884 : }
3885 :
3886 : // check that control zone name is valid for load based control
3887 102 : if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3888 : // bypass this error for PTUnits
3889 55 : if (this->ControlZoneNum == 0 &&
3890 22 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3891 3 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3892 6 : ShowContinueError(state, "When Control Type = Load or SingleZoneVAV");
3893 6 : ShowContinueError(state,
3894 6 : format(" Controlling Zone or Thermostat Location must be a valid zone name, zone name = {}",
3895 3 : input_data.controlling_zone_or_thermostat_location));
3896 3 : errorsFound = true;
3897 : }
3898 : }
3899 :
3900 102 : if (Util::SameString(input_data.dehumidification_control_type, "None")) {
3901 96 : this->m_DehumidControlType_Num = DehumCtrlType::None;
3902 96 : this->m_Humidistat = false;
3903 6 : } else if (Util::SameString(input_data.dehumidification_control_type, "CoolReheat")) {
3904 6 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
3905 6 : this->m_Humidistat = true;
3906 0 : } else if (Util::SameString(input_data.dehumidification_control_type, "Multimode")) {
3907 0 : this->m_DehumidControlType_Num = DehumCtrlType::Multimode;
3908 0 : this->m_Humidistat = true;
3909 : }
3910 102 : if (this->m_Humidistat && this->m_ControlType == UnitarySysCtrlType::Load) {
3911 1 : bool AirNodeFound = false;
3912 2 : for (int HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
3913 1 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != this->ControlZoneNum) {
3914 0 : continue;
3915 : }
3916 1 : AirNodeFound = true;
3917 : }
3918 1 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3919 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3920 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
3921 0 : ShowContinueError(
3922 0 : state, format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3923 0 : errorsFound = true;
3924 : }
3925 : }
3926 :
3927 102 : Real64 TotalFloorAreaOnAirLoop = 0.0;
3928 102 : int AirLoopNumber = 0;
3929 102 : bool AirNodeFound = false;
3930 102 : bool AirLoopFound = false;
3931 102 : bool OASysFound = false;
3932 102 : bool ZoneEquipmentFound = false;
3933 102 : bool ZoneInletNodeFound = false;
3934 :
3935 : // Get AirTerminal mixer data
3936 102 : SingleDuct::GetATMixer(state,
3937 : thisObjectName,
3938 102 : this->m_ATMixerName,
3939 102 : this->m_ATMixerIndex,
3940 102 : this->ATMixerType,
3941 102 : this->m_ATMixerPriNode,
3942 102 : this->m_ATMixerSecNode,
3943 102 : this->ATMixerOutNode,
3944 : this->AirOutNode);
3945 102 : if (this->ATMixerType == HVAC::MixerType::InletSide || this->ATMixerType == HVAC::MixerType::SupplySide) {
3946 13 : this->ATMixerExists = true;
3947 : }
3948 : // check that heat pump doesn't have local outside air and DOA
3949 102 : if (this->ATMixerExists && this->m_OAMixerNodes[0] > 0 &&
3950 0 : (input_data.cooling_oa_flow_rate != 0.0 || input_data.heating_oa_flow_rate != 0.0 || input_data.no_load_oa_flow_rate != 0.0)) {
3951 0 : ShowSevereError(state,
3952 0 : format("{} = \"{}\". System has local as well as central outdoor air specified", cCurrentModuleObject, this->Name));
3953 0 : errorsFound = true;
3954 : }
3955 :
3956 : // if part of ZoneHVAC:OutdoorAirUnit bypass most checks for connection to air loop or OASystem
3957 102 : if (ZoneOAUnitNum > 0) {
3958 1 : OASysFound = true;
3959 : }
3960 :
3961 102 : if (ZoneEquipment) {
3962 72 : int ControlledZoneNum = 0;
3963 72 : int ZoneExhNum = 0;
3964 72 : bool ZoneExhaustNodeFound = false;
3965 72 : bool InducedNodeFound = false;
3966 :
3967 72 : if (!this->ATMixerExists) {
3968 59 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3969 59 : if (ZoneExhaustNodeFound) {
3970 55 : ZoneEquipmentFound = true;
3971 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3972 : // this should be zoneExhaustNode
3973 55 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum);
3974 55 : this->ControlZoneNum = ControlledZoneNum;
3975 55 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3976 55 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3977 : } else { // find if the inlet node is an induced node from zone plenum
3978 4 : int ZoneInletNum = 0;
3979 4 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3980 4 : if (ZoneInletNodeFound) {
3981 6 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3982 : this->AirInNode,
3983 3 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3984 3 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3985 3 : if (InducedNodeFound) {
3986 2 : this->m_ZoneInletNode = this->AirOutNode;
3987 2 : ZoneEquipmentFound = true;
3988 2 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3989 : }
3990 : }
3991 : }
3992 13 : } else if (this->ATMixerType == HVAC::MixerType::InletSide) {
3993 8 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->m_ATMixerSecNode, ControlledZoneNum, ZoneExhNum);
3994 8 : if (ZoneExhaustNodeFound) {
3995 7 : ZoneEquipmentFound = true;
3996 7 : this->m_ZoneInletNode = this->AirOutNode;
3997 7 : this->ControlZoneNum = ControlledZoneNum;
3998 7 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3999 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
4000 7 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
4001 : } else {
4002 1 : int ZoneInletNum = 0;
4003 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
4004 1 : if (ZoneInletNodeFound) {
4005 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
4006 : this->m_ATMixerSecNode,
4007 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
4008 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
4009 1 : if (InducedNodeFound) {
4010 1 : this->m_ZoneInletNode = this->AirOutNode;
4011 1 : ZoneEquipmentFound = true;
4012 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4013 : }
4014 : }
4015 : }
4016 5 : } else if (this->ATMixerType == HVAC::MixerType::SupplySide) {
4017 5 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
4018 5 : if (ZoneExhaustNodeFound) {
4019 4 : ZoneEquipmentFound = true;
4020 4 : this->m_ZoneInletNode = this->ATMixerOutNode;
4021 4 : this->ControlZoneNum = ControlledZoneNum;
4022 4 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4023 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
4024 4 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->ATMixerOutNode, this->ControlZoneNum);
4025 : } else {
4026 1 : int ZoneInletNum = 0;
4027 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->ATMixerOutNode, this->ControlZoneNum, ZoneInletNum);
4028 1 : if (ZoneInletNodeFound) {
4029 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
4030 : this->AirInNode,
4031 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
4032 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
4033 1 : if (InducedNodeFound) {
4034 1 : this->m_ZoneInletNode = this->ATMixerOutNode;
4035 1 : ZoneEquipmentFound = true;
4036 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
4037 : }
4038 : }
4039 : }
4040 : }
4041 72 : if (!ZoneExhaustNodeFound && !InducedNodeFound) {
4042 : // Exhaust Node was not found
4043 2 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4044 4 : ShowContinueError(state,
4045 4 : format("Incorrect or misspelled Air Inlet Node Name or Exhaust Node Name or Induced Node Name. = {}",
4046 2 : input_data.air_inlet_node_name));
4047 4 : ShowContinueError(
4048 : state,
4049 4 : format("Air Inlet Node {} name does not match any controlled zone exhaust node name. Check ZoneHVAC:EquipmentConnections "
4050 : "object inputs.",
4051 2 : input_data.air_inlet_node_name));
4052 4 : ShowContinueError(state, "or Induced Air Outlet Node Name specified in AirLoopHVAC:ReturnPlenum object.");
4053 2 : errorsFound = true;
4054 70 : } else if (!ZoneInletNodeFound) {
4055 0 : bool ZoneInletNodeExists = false;
4056 0 : int InletControlledZoneNum = 0;
4057 0 : int ZoneInletNum = 0;
4058 0 : ZoneInletNodeExists = searchZoneInletNodes(state, this->AirOutNode, InletControlledZoneNum, ZoneInletNum);
4059 0 : if (!ZoneInletNodeExists) {
4060 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4061 0 : ShowContinueError(state, format("Incorrect or misspelled Air Outlet Node Name = {}", input_data.air_outlet_node_name));
4062 0 : ShowContinueError(state,
4063 : "Node name does not match any controlled zone inlet node name. Check ZoneHVAC:EquipmentConnections "
4064 : "object inputs.");
4065 0 : errorsFound = true;
4066 : }
4067 : }
4068 : } else {
4069 : // check if the UnitarySystem is connected to an air loop
4070 :
4071 : int compIndex;
4072 : int branchIndex;
4073 30 : AirLoopFound = searchTotalComponents(state, this->AirloopEqType, thisObjectName, compIndex, branchIndex, AirLoopNumber);
4074 30 : if (AirLoopFound && (this->ControlZoneNum > 0)) {
4075 : // Find the controlled zone number for the specified thermostat location
4076 2 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
4077 :
4078 : // Determine if system is on air loop served by the thermostat location specified
4079 2 : int ZoneInletNum = 0;
4080 2 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
4081 2 : if (ZoneInletNodeFound) {
4082 2 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
4083 2 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
4084 : }
4085 :
4086 4 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4087 2 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4088 0 : continue;
4089 : }
4090 2 : AirNodeFound = true;
4091 : }
4092 2 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4093 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4094 0 : continue;
4095 : }
4096 0 : AirNodeFound = true;
4097 : }
4098 2 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4099 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4100 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4101 0 : ShowContinueError(
4102 : state,
4103 0 : format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
4104 0 : errorsFound = true;
4105 : }
4106 :
4107 2 : if (this->ControlZoneNum > 0) {
4108 : // Find the controlled zone number for the specified thermostat location
4109 2 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
4110 :
4111 : // Determine if system is on air loop served by the thermostat location specified
4112 2 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
4113 2 : if (ZoneInletNodeFound) {
4114 2 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
4115 2 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
4116 : }
4117 :
4118 : // if (this->m_ZoneInletNode == 0) AirLoopFound = false;
4119 4 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4120 2 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4121 0 : continue;
4122 : }
4123 2 : AirNodeFound = true;
4124 : }
4125 2 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4126 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) {
4127 0 : continue;
4128 : }
4129 0 : AirNodeFound = true;
4130 : }
4131 2 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4132 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4133 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4134 0 : ShowContinueError(state,
4135 0 : format("specified Controlling Zone or Thermostat Location name = {}",
4136 0 : input_data.controlling_zone_or_thermostat_location));
4137 0 : errorsFound = true;
4138 : }
4139 : }
4140 : }
4141 :
4142 : // check if the UnitarySystem is connected to an outside air system
4143 30 : if (!AirLoopFound && state.dataAirLoop->NumOASystems > 0) {
4144 10 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
4145 12 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
4146 14 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum), thisObjectName) ||
4147 4 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject)) {
4148 6 : continue;
4149 : }
4150 4 : AirLoopNumber = OASysNum;
4151 4 : OASysFound = true;
4152 4 : break;
4153 : }
4154 : }
4155 : }
4156 : }
4157 :
4158 102 : if (AirLoopNumber == 0 && !ZoneEquipmentFound &&
4159 3 : (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE)) {
4160 2 : std::string_view zoneName = input_data.controlling_zone_or_thermostat_location;
4161 2 : if (zoneName.empty() && this->ControlZoneNum > 0) {
4162 1 : zoneName = state.dataHeatBal->Zone(this->ControlZoneNum).Name;
4163 : }
4164 2 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4165 4 : ShowContinueError(state, "Did not find proper connections for AirLoopHVAC or ZoneHVAC system.");
4166 2 : ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}", zoneName));
4167 2 : if (!AirNodeFound && !ZoneEquipmentFound) {
4168 2 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4169 4 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
4170 : // ShowContinueError(state, format("specified {} = {}", cAlphaFields(iControlZoneAlphaNum), Alphas(iControlZoneAlphaNum)));
4171 6 : ShowContinueError(state,
4172 : "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
4173 : }
4174 2 : errorsFound = true;
4175 : }
4176 :
4177 102 : if (!AirLoopFound && !ZoneEquipmentFound && !OASysFound) {
4178 : // Unsuccessful attempt to get all input data.
4179 2 : return;
4180 100 : } else if (ZoneEquipmentFound || OASysFound ||
4181 25 : (AirLoopFound && (this->m_ZoneInletNode > 0 || this->m_ControlType == UnitarySysCtrlType::Setpoint))) {
4182 100 : this->m_OKToPrintSizing = true;
4183 100 : this->m_ThisSysInputShouldBeGotten = false;
4184 : }
4185 :
4186 100 : this->m_AvailManagerListName = input_data.avail_manager_list_name;
4187 :
4188 100 : if (!input_data.design_spec_zonehvac_sizing_object_name.empty()) {
4189 0 : this->m_HVACSizingIndex = Util::FindItemInList(input_data.design_spec_zonehvac_sizing_object_name, state.dataSize->ZoneHVACSizing);
4190 0 : if (this->m_HVACSizingIndex == 0) {
4191 0 : ShowSevereError(
4192 : state,
4193 0 : format("Design Specification ZoneHVAC Sizing Object Name = {} not found.", input_data.design_spec_zonehvac_sizing_object_name));
4194 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, this->Name));
4195 0 : errorsFound = true;
4196 : }
4197 : }
4198 :
4199 100 : if (!ZoneEquipment) {
4200 90 : BranchNodeConnections::TestCompSet(state,
4201 : cCurrentModuleObject,
4202 60 : Util::makeUPPER(thisObjectName),
4203 30 : input_data.air_inlet_node_name,
4204 30 : input_data.air_outlet_node_name,
4205 : "Air Nodes");
4206 : }
4207 :
4208 100 : std::string const &loc_fanType = input_data.supply_fan_object_type;
4209 100 : std::string const &loc_m_FanName = input_data.supply_fan_name;
4210 :
4211 100 : if (!loc_m_FanName.empty() && !loc_fanType.empty()) {
4212 71 : this->m_FanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(loc_fanType)));
4213 :
4214 71 : this->m_FanIndex = Fans::GetFanIndex(state, loc_m_FanName);
4215 71 : if (this->m_FanIndex == 0) {
4216 0 : ShowSevereItemNotFound(state, eoh, "fan_name", loc_m_FanName);
4217 0 : errorsFound = true;
4218 : } else {
4219 71 : auto const *fan = state.dataFans->fans(this->m_FanIndex);
4220 71 : FanVolFlowRate = fan->maxAirFlowRate;
4221 71 : if (FanVolFlowRate == DataSizing::AutoSize) {
4222 35 : this->m_RequestAutoSize = true;
4223 : }
4224 71 : this->m_ActualFanVolFlowRate = FanVolFlowRate;
4225 71 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
4226 71 : FanInletNode = fan->inletNodeNum;
4227 71 : FanOutletNode = fan->outletNodeNum;
4228 71 : this->m_fanAvailSched = fan->availSched;
4229 : }
4230 :
4231 71 : this->m_FanExists = true;
4232 71 : this->m_FanName = loc_m_FanName;
4233 29 : } else if (!loc_m_FanName.empty() || !loc_fanType.empty()) {
4234 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4235 0 : ShowContinueError(state, format("Invalid Fan Type or Name: Fan Name = {}, Fan Type = {}", loc_m_FanName, loc_fanType));
4236 0 : errorsFound = true;
4237 : }
4238 :
4239 : // Add fan to component sets array
4240 100 : if (this->m_FanExists && this->m_FanCompNotSetYet) {
4241 134 : BranchNodeConnections::SetUpCompSets(state,
4242 : cCurrentModuleObject,
4243 : thisObjectName,
4244 : loc_fanType,
4245 : loc_m_FanName,
4246 67 : state.dataLoopNodes->NodeID(FanInletNode),
4247 67 : state.dataLoopNodes->NodeID(FanOutletNode));
4248 67 : this->m_FanCompNotSetYet = false;
4249 : }
4250 :
4251 100 : this->m_FanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Util::makeUPPER(input_data.fan_placement)));
4252 100 : if (this->m_FanPlace == HVAC::FanPlace::Invalid && this->m_FanExists) {
4253 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4254 0 : ShowContinueError(state, format("Illegal Fan Placement = {}", input_data.fan_placement));
4255 0 : errorsFound = true;
4256 : }
4257 :
4258 100 : if (input_data.supply_air_fan_operating_mode_schedule_name.empty()) {
4259 56 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4260 : // Fan operating mode must be constant fan so that the coil outlet temp is proportional to PLR
4261 : // Cycling fan always outputs the full load outlet air temp so should not be used with set point based control
4262 43 : this->m_FanOpMode = HVAC::FanOp::Continuous;
4263 : } else {
4264 13 : this->m_FanOpMode = HVAC::FanOp::Cycling;
4265 13 : if (this->m_FanType != HVAC::FanType::OnOff && this->m_FanType != HVAC::FanType::SystemModel && this->m_FanExists) {
4266 0 : ShowSevereEmptyField(state,
4267 : eoh,
4268 : "Fan Operating Mode Schedule Name",
4269 : "Fan type must be Fan:OnOff or Fan:SystemModel when Supply Air Fan Operating Mode Schedule Name is blank.");
4270 0 : errorsFound = true;
4271 : }
4272 : }
4273 44 : } else if ((this->m_fanOpModeSched = Sched::GetSchedule(state, input_data.supply_air_fan_operating_mode_schedule_name)) == nullptr) {
4274 0 : ShowSevereItemNotFound(state, eoh, "Fan Operating Mode Schedule Name", input_data.supply_air_fan_operating_mode_schedule_name);
4275 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iFanSchedAlphaNum), Alphas(iFanSchedAlphaNum)));
4276 0 : errorsFound = true;
4277 52 : } else if ((this->m_ControlType == UnitarySysCtrlType::Setpoint || this->m_FanType == HVAC::FanType::Constant) &&
4278 8 : !this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
4279 1 : Sched::ShowSevereBadMinMax(state,
4280 : eoh,
4281 : "Supply Air Fan Operating Mode Schedule Name",
4282 : input_data.supply_air_fan_operating_mode_schedule_name,
4283 : Clusive::Ex,
4284 : 0.0,
4285 : Clusive::In,
4286 : 1.0);
4287 1 : errorsFound = true;
4288 : }
4289 :
4290 100 : PrintMessage = true;
4291 : // Get coil data
4292 100 : this->m_HeatingSizingRatio = input_data.dx_heating_coil_sizing_ratio;
4293 100 : int HeatingCoilPLFCurveIndex = 0;
4294 100 : if (!this->m_HeatingCoilTypeName.empty()) {
4295 65 : PrintMessage = false;
4296 : } else {
4297 35 : this->m_ValidASHRAEHeatCoil = false;
4298 : }
4299 :
4300 100 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4301 :
4302 3 : this->m_DXHeatingCoil = true;
4303 :
4304 3 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4305 3 : if (isNotOK) {
4306 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4307 0 : errorsFound = true;
4308 :
4309 : } else { // mine data from DX heating coil
4310 :
4311 : // Get DX heating coil index
4312 3 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4313 3 : if (errFlag) {
4314 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4315 0 : errorsFound = true;
4316 0 : errFlag = false;
4317 : } else {
4318 3 : auto &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4319 3 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4320 3 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedTotCap(1);
4321 3 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4322 0 : this->m_RequestAutoSize = true;
4323 : }
4324 3 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate(1);
4325 3 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4326 0 : this->m_RequestAutoSize = true;
4327 : }
4328 3 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4329 3 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4330 3 : thisHeatCoil.HeatSizeRatio = this->m_HeatingSizingRatio;
4331 : }
4332 : }
4333 :
4334 97 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4335 92 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
4336 :
4337 6 : this->m_DXHeatingCoil = true;
4338 :
4339 6 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4340 6 : if (isNotOK) {
4341 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4342 0 : errorsFound = true;
4343 : } else {
4344 6 : this->m_HeatingCoilIndex =
4345 6 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4346 6 : if (errFlag) {
4347 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4348 0 : errorsFound = true;
4349 0 : errFlag = false;
4350 : } else {
4351 6 : auto const &thisHeatCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex);
4352 6 : this->m_NumOfSpeedHeating = thisHeatCoil.NumOfSpeeds;
4353 6 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4354 6 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4355 6 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4356 3 : this->m_RequestAutoSize = true;
4357 : } else {
4358 3 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NumOfSpeeds) /
4359 3 : thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NormSpedLevel) * thisHeatCoil.RatedAirVolFlowRate;
4360 : }
4361 6 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4362 6 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4363 6 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4364 6 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4365 6 : this->m_RequestAutoSize = true;
4366 : }
4367 : }
4368 : }
4369 97 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
4370 5 : this->m_DXHeatingCoil = true;
4371 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4372 5 : if (isNotOK) {
4373 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4374 0 : errorsFound = true;
4375 : } else {
4376 5 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, this->m_HeatingCoilTypeName);
4377 5 : if (errFlag) {
4378 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4379 0 : errorsFound = true;
4380 0 : errFlag = false;
4381 : } else {
4382 5 : auto const &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4383 5 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4384 5 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(1);
4385 5 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4386 2 : this->m_RequestAutoSize = true;
4387 : }
4388 5 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4389 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4390 5 : this->m_DesignHeatingCapacity = thisHeatCoil.MSRatedTotCap(thisHeatCoil.NumOfSpeeds);
4391 : }
4392 : }
4393 86 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
4394 81 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
4395 8 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4396 8 : if (isNotOK) {
4397 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4398 0 : errorsFound = true;
4399 : } else {
4400 8 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4401 8 : if (errFlag) {
4402 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4403 0 : errorsFound = true;
4404 0 : errFlag = false;
4405 : } else {
4406 8 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4407 8 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4408 8 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4409 8 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4410 8 : this->m_DesignHeatingCapacity = thisHeatCoil.MSNominalCapacity(thisHeatCoil.NumOfStages);
4411 8 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4412 1 : this->m_RequestAutoSize = true;
4413 : }
4414 : }
4415 : }
4416 86 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
4417 43 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
4418 36 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4419 36 : if (isNotOK) {
4420 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4421 0 : errorsFound = true;
4422 : } else { // mine data from heating coil
4423 36 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4424 36 : if (errFlag) {
4425 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4426 0 : errorsFound = true;
4427 0 : errFlag = false;
4428 : } else {
4429 36 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4430 36 : this->m_DesignHeatingCapacity = thisHeatCoil.NominalCapacity;
4431 36 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
4432 10 : this->m_RequestAutoSize = true;
4433 : }
4434 36 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4435 36 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4436 36 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4437 36 : HeatingCoilPLFCurveIndex = thisHeatCoil.PLFCurveIndex;
4438 : // These heating coil types do not have an air flow input field
4439 36 : if (this->m_RequestAutoSize) {
4440 11 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4441 : }
4442 : }
4443 : } // IF (IsNotOK) THEN
4444 :
4445 78 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
4446 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4447 5 : if (isNotOK) {
4448 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4449 0 : errorsFound = true;
4450 : } else { // mine data from heating coil object
4451 5 : this->m_HeatingCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_HeatingCoilName, errFlag);
4452 5 : if (errFlag) {
4453 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4454 0 : errorsFound = true;
4455 0 : errFlag = false;
4456 : } else {
4457 5 : auto const &thisHeatCoil = state.dataWaterCoils->WaterCoil(this->m_HeatingCoilIndex);
4458 5 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4459 5 : this->HeatCoilFluidInletNode = thisHeatCoil.WaterInletNodeNum;
4460 5 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxWaterVolFlowRate;
4461 5 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4462 3 : this->m_RequestAutoSize = true;
4463 3 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4464 : }
4465 5 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4466 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4467 : }
4468 : }
4469 :
4470 37 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
4471 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4472 0 : if (isNotOK) {
4473 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4474 0 : errorsFound = true;
4475 : } else { // mine data from heating coil object
4476 0 : this->m_HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_HeatingCoilName, errFlag);
4477 0 : if (errFlag) {
4478 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4479 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4480 0 : errorsFound = true;
4481 0 : errFlag = false;
4482 : } else {
4483 0 : auto const &thisHeatCoil = state.dataSteamCoils->SteamCoil(this->m_HeatingCoilIndex);
4484 0 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4485 0 : this->HeatCoilFluidInletNode = thisHeatCoil.SteamInletNodeNum;
4486 0 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxSteamVolFlowRate;
4487 0 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4488 0 : this->m_RequestAutoSize = true;
4489 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4490 : }
4491 0 : if (this->MaxHeatCoilFluidFlow > 0.0) {
4492 0 : Real64 TempSteamIn = 100.0;
4493 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
4494 0 : this->MaxHeatCoilFluidFlow *= SteamDensity;
4495 0 : errFlag = false;
4496 : }
4497 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4498 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4499 0 : if (this->m_RequestAutoSize) {
4500 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4501 : }
4502 : }
4503 : }
4504 :
4505 37 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
4506 2 : this->m_DXHeatingCoil = true;
4507 2 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4508 2 : if (isNotOK) {
4509 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4510 0 : errorsFound = true;
4511 : } else { // mine data from heating coil object
4512 2 : this->m_HeatingCoilIndex =
4513 2 : WaterToAirHeatPumpSimple::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4514 2 : if (errFlag) {
4515 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4516 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4517 0 : errorsFound = true;
4518 0 : errFlag = false;
4519 : } else {
4520 2 : auto const &thisHeatCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_HeatingCoilIndex);
4521 2 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4522 2 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4523 2 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4524 2 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4525 1 : this->m_RequestAutoSize = true;
4526 : }
4527 2 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4528 2 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4529 : }
4530 : }
4531 :
4532 35 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
4533 0 : this->m_DXHeatingCoil = true;
4534 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4535 0 : if (isNotOK) {
4536 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4537 0 : errorsFound = true;
4538 : } else { // mine data from heating coil object
4539 0 : this->m_HeatingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4540 0 : if (errFlag) {
4541 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4542 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4543 0 : errorsFound = true;
4544 0 : errFlag = false;
4545 : } else {
4546 0 : auto const &thisHeatCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_HeatingCoilIndex);
4547 0 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4548 0 : this->m_DesignHeatingCapacity = thisHeatCoil.HeatingCapacity;
4549 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4550 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4551 : }
4552 : }
4553 :
4554 35 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
4555 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4556 0 : if (isNotOK) {
4557 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4558 0 : errorsFound = true;
4559 : } else { // mine data from Heating coil object
4560 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
4561 0 : state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, cCurrentModuleObject);
4562 0 : if (errFlag) {
4563 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4564 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4565 0 : errorsFound = true;
4566 0 : errFlag = false;
4567 : } else {
4568 0 : auto const &thisHeatCoil = state.dataUserDefinedComponents->UserCoil(this->m_HeatingCoilIndex);
4569 0 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4570 : // **** How to get this info ****
4571 : // UnitarySystem( UnitarySysNum ).DesignHeatingCapacity =
4572 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
4573 0 : HeatingCoilInletNode = thisHeatCoil.Air(1).InletNodeNum;
4574 0 : HeatingCoilOutletNode = thisHeatCoil.Air(1).OutletNodeNum;
4575 : }
4576 : }
4577 :
4578 35 : } else if (this->m_HeatCoilExists) {
4579 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4580 0 : ShowContinueError(state, format("Illegal Heating Coil Object Type = {}", this->m_HeatingCoilTypeName));
4581 0 : errorsFound = true;
4582 : } // IF (this->m_HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
4583 :
4584 : // coil outlet node set point has priority, IF not exist, then use system outlet node
4585 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
4586 33 : this->HeatCtrlNode = this->AirOutNode;
4587 : }
4588 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, HeatingCoilOutletNode, HVAC::CtrlVarType::Temp)) {
4589 11 : this->HeatCtrlNode = HeatingCoilOutletNode;
4590 : }
4591 :
4592 100 : this->HeatCoilInletNodeNum = HeatingCoilInletNode;
4593 100 : this->HeatCoilOutletNodeNum = HeatingCoilOutletNode;
4594 :
4595 : // Add heating coil to component sets array
4596 100 : if (this->m_HeatCoilExists && this->m_HeatCompNotSetYet) {
4597 61 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
4598 116 : BranchNodeConnections::SetUpCompSets(state,
4599 : cCurrentModuleObject,
4600 : thisObjectName,
4601 : this->m_HeatingCoilTypeName,
4602 : this->m_HeatingCoilName,
4603 58 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
4604 58 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4605 : } else {
4606 3 : BranchNodeConnections::SetUpCompSets(
4607 : state, cCurrentModuleObject, thisObjectName, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, "UNDEFINED", "UNDEFINED");
4608 : }
4609 61 : this->m_HeatCompNotSetYet = false;
4610 : }
4611 :
4612 : // Get Cooling Coil Information IF available
4613 100 : if (!input_data.cooling_coil_object_type.empty() && !this->m_CoolingCoilName.empty()) {
4614 :
4615 83 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4616 44 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4617 44 : if (isNotOK) {
4618 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4619 0 : errorsFound = true;
4620 :
4621 : } else { // mine data from DX cooling coil
4622 :
4623 44 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4624 3 : this->m_NumOfSpeedCooling = 2;
4625 3 : this->m_MultiOrVarSpeedCoolCoil = true;
4626 : } else {
4627 41 : this->m_NumOfSpeedCooling = 1;
4628 41 : this->m_MultiOrVarSpeedCoolCoil = false;
4629 : }
4630 :
4631 : // Get DX cooling coil index
4632 44 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4633 44 : if (isNotOK) {
4634 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4635 0 : errorsFound = true;
4636 : } else {
4637 44 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
4638 1 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
4639 : }
4640 44 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4641 44 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4642 44 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(1);
4643 44 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4644 19 : this->m_RequestAutoSize = true;
4645 : }
4646 44 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4647 44 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4648 19 : this->m_RequestAutoSize = true;
4649 : }
4650 44 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4651 44 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4652 44 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4653 :
4654 44 : if (this->m_FanExists) {
4655 26 : thisCoolCoil.SupplyFanName = this->m_FanName;
4656 26 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4657 26 : thisCoolCoil.supplyFanType = this->m_FanType;
4658 26 : if (this->m_FanType != HVAC::FanType::Invalid) {
4659 26 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
4660 : state,
4661 26 : thisCoolCoil.Name,
4662 26 : thisCoolCoil.DXCoilType,
4663 26 : state.dataFans->fans(thisCoolCoil.SupplyFanIndex)->Name,
4664 : this->m_FanType,
4665 : thisCoolCoil.SupplyFanIndex);
4666 : }
4667 : }
4668 44 : if (this->m_HeatCoilExists) {
4669 24 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4670 23 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4671 23 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4672 23 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4673 23 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4674 23 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4675 4 : this->m_HeatPump = true;
4676 : }
4677 : }
4678 :
4679 : // Push heating coil PLF curve index to DX coil
4680 44 : if (HeatingCoilPLFCurveIndex > 0) {
4681 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4682 : }
4683 : }
4684 : } // IF (IsNotOK) THEN
4685 :
4686 83 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
4687 6 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4688 6 : if (isNotOK) {
4689 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4690 0 : errorsFound = true;
4691 :
4692 : } else {
4693 : // // call CoilCoolingDX constructor
4694 6 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
4695 6 : if (this->m_CoolingCoilIndex == -1) {
4696 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4697 0 : errorsFound = true;
4698 : } else {
4699 :
4700 : // mine data from coil object
4701 : // TODO: Need to check for autosize on these I guess
4702 6 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
4703 6 : this->m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4704 6 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4705 6 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4706 4 : this->m_RequestAutoSize = true;
4707 : }
4708 6 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4709 4 : this->m_RequestAutoSize = true;
4710 : }
4711 6 : this->m_coolingCoilAvailSched = newCoil.availSched;
4712 6 : CoolingCoilInletNode = newCoil.evapInletNodeIndex;
4713 6 : CoolingCoilOutletNode = newCoil.evapOutletNodeIndex;
4714 6 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4715 6 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
4716 6 : this->m_MinOATCompressorCooling = newCoil.performance.minOutdoorDrybulb;
4717 6 : newCoil.supplyFanName = this->m_FanName;
4718 6 : newCoil.supplyFanIndex = this->m_FanIndex;
4719 6 : newCoil.supplyFanType = this->m_FanType;
4720 6 : if (newCoil.SubcoolReheatFlag) {
4721 1 : this->m_Humidistat = true;
4722 1 : if (this->m_NumOfSpeedCooling > 1) {
4723 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4724 0 : this->FullLatOutput.resize(this->m_NumOfSpeedCooling + 1);
4725 0 : this->SpeedSHR.resize(this->m_NumOfSpeedCooling + 1);
4726 : }
4727 1 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4728 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4729 0 : ShowContinueError(state,
4730 : "Setpoint control is not available for SubcoolReheat cooling coil. Load control is forced. "
4731 : "Simulation continues.");
4732 0 : this->m_ControlType = UnitarySysCtrlType::Load;
4733 : }
4734 : }
4735 6 : newCoil.setData(this->m_FanIndex, this->m_FanType, this->m_FanName, this->m_SuppCoilPlantLoc.loopNum);
4736 :
4737 : // Push heating coil PLF curve index to DX coil
4738 : // if ( HeatingCoilPLFCurveIndex > 0 ) {
4739 : // SetDXCoolingCoilData( UnitarySystem( UnitarySysNum ).CoolingCoilIndex, ErrorsFound,
4740 : // HeatingCoilPLFCurveIndex );
4741 : // }
4742 : }
4743 :
4744 6 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > 1) {
4745 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4746 : }
4747 :
4748 6 : if (this->m_HeatCoilExists) {
4749 3 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4750 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4751 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4752 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4753 3 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4754 3 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4755 0 : this->m_HeatPump = true;
4756 : }
4757 : }
4758 : }
4759 :
4760 33 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
4761 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4762 0 : if (isNotOK) {
4763 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4764 0 : errorsFound = true;
4765 :
4766 : } else { // mine data from DX cooling coil
4767 :
4768 : // Get DX cooling coil index
4769 0 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4770 0 : if (isNotOK) {
4771 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4772 0 : errorsFound = true;
4773 : } else {
4774 0 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4775 0 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4776 0 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(thisCoolCoil.NumCapacityStages);
4777 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4778 0 : this->m_RequestAutoSize = true;
4779 : }
4780 0 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4781 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4782 0 : this->m_RequestAutoSize = true;
4783 : }
4784 0 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4785 0 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4786 0 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4787 :
4788 : // Push heating coil PLF curve index to DX coil
4789 0 : if (HeatingCoilPLFCurveIndex > 0) {
4790 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4791 : }
4792 :
4793 0 : if (this->m_HeatCoilExists) {
4794 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4795 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4796 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4797 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4798 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4799 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4800 0 : this->m_HeatPump = true;
4801 : }
4802 : }
4803 : }
4804 : } // IF (IsNotOK) THEN
4805 :
4806 33 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
4807 2 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4808 2 : if (isNotOK) {
4809 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4810 0 : errorsFound = true;
4811 :
4812 : } else { // mine data from heat exchanger assisted cooling coil
4813 :
4814 : // Get DX heat exchanger assisted cooling coil index
4815 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4816 2 : if (isNotOK) {
4817 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4818 0 : errorsFound = true;
4819 : }
4820 :
4821 : std::string ChildCoolingCoilName =
4822 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4823 : std::string ChildCoolingCoilType =
4824 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4825 2 : if (isNotOK) {
4826 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4827 0 : errorsFound = true;
4828 : }
4829 :
4830 2 : if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
4831 :
4832 1 : int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
4833 1 : if (childCCIndex < 0) {
4834 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4835 0 : errorsFound = true;
4836 : }
4837 :
4838 1 : auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
4839 1 : this->m_coolingCoilAvailSched = newCoil.availSched;
4840 :
4841 : // thisSys.m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4842 : // Get Coil:Cooling:DX coil air flow rate. Later fields will overwrite this IF input field is present
4843 1 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4844 : // if (thisSys.m_DesignCoolingCapacity == DataSizing::AutoSize) thisSys.m_RequestAutoSize = true;
4845 1 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4846 1 : this->m_RequestAutoSize = true;
4847 : }
4848 :
4849 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4850 1 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4851 :
4852 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) {
4853 :
4854 0 : this->m_coolingCoilAvailSched = DXCoils::GetDXCoilAvailSched(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4855 0 : if (isNotOK) {
4856 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4857 0 : errorsFound = true;
4858 : }
4859 :
4860 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
4861 0 : this->m_MaxCoolAirVolFlow = DXCoils::GetDXCoilAirFlow(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4862 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4863 0 : this->m_RequestAutoSize = true;
4864 : }
4865 0 : if (errFlag) {
4866 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4867 0 : errFlag = false;
4868 0 : errorsFound = true;
4869 : }
4870 :
4871 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4872 0 : this->m_CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(
4873 : state,
4874 : "COIL:COOLING:DX:SINGLESPEED",
4875 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag),
4876 : errFlag);
4877 :
4878 0 : if (errFlag) {
4879 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4880 0 : errFlag = false;
4881 0 : errorsFound = true;
4882 : }
4883 :
4884 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED")) {
4885 1 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4886 1 : this->m_MaxCoolAirVolFlow =
4887 1 : VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4888 1 : if (errFlag) {
4889 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4890 0 : errFlag = false;
4891 0 : errorsFound = true;
4892 : }
4893 1 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, ChildCoolingCoilName, errFlag);
4894 1 : if (errFlag) {
4895 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4896 0 : errFlag = false;
4897 0 : errorsFound = true;
4898 : }
4899 : }
4900 :
4901 : // Get DX cooling coil capacity
4902 2 : this->m_DesignCoolingCapacity =
4903 2 : HVACHXAssistedCoolingCoil::GetCoilCapacity(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4904 2 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
4905 1 : this->m_RequestAutoSize = true;
4906 : }
4907 2 : if (errFlag) {
4908 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4909 0 : errFlag = false;
4910 0 : errorsFound = true;
4911 : }
4912 :
4913 : // Get the Cooling Coil Nodes
4914 : CoolingCoilInletNode =
4915 2 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4916 : CoolingCoilOutletNode =
4917 2 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4918 2 : if (errFlag) {
4919 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4920 0 : errFlag = false;
4921 0 : errorsFound = true;
4922 : }
4923 :
4924 : // Push heating coil PLF curve index to DX coil
4925 2 : if (HeatingCoilPLFCurveIndex > 0) {
4926 : // get the actual index to the DX cooling coil object
4927 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4928 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4929 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4930 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4931 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4932 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4933 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4934 : }
4935 : // what could we do for VS coil here? odd thing here
4936 : }
4937 :
4938 2 : if (this->m_HeatCoilExists) {
4939 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4940 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4941 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4942 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4943 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4944 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4945 0 : this->m_HeatPump = true;
4946 : }
4947 : }
4948 :
4949 2 : } // IF (IsNotOK) THEN
4950 31 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
4951 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4952 0 : if (isNotOK) {
4953 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4954 0 : errorsFound = true;
4955 :
4956 : } else { // mine data from heat exchanger assisted cooling coil
4957 :
4958 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4959 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4960 : std::string HXCoilName =
4961 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4962 :
4963 0 : if (errFlag) {
4964 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4965 0 : errFlag = false;
4966 0 : errorsFound = true;
4967 : }
4968 :
4969 : // Get DX heat exchanger assisted cooling coil index
4970 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag);
4971 0 : if (errFlag) {
4972 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4973 0 : errFlag = false;
4974 0 : errorsFound = true;
4975 : }
4976 :
4977 0 : this->m_coolingCoilAvailSched =
4978 0 : WaterCoils::GetWaterCoilAvailSched(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4979 0 : this->MaxCoolCoilFluidFlow =
4980 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4981 : // Get the Cooling Coil water Inlet Node number
4982 0 : this->CoolCoilFluidInletNode =
4983 0 : WaterCoils::GetCoilWaterInletNode(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4984 0 : if (errFlag) {
4985 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4986 0 : errFlag = false;
4987 0 : errorsFound = true;
4988 : }
4989 :
4990 : // Get the Cooling Coil Nodes
4991 : CoolingCoilInletNode =
4992 0 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4993 : CoolingCoilOutletNode =
4994 0 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4995 0 : if (errFlag) {
4996 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4997 0 : errFlag = false;
4998 0 : errorsFound = true;
4999 : }
5000 :
5001 0 : this->m_MaxCoolAirVolFlow =
5002 0 : HVACHXAssistedCoolingCoil::GetHXCoilAirFlowRate(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5003 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5004 0 : this->m_RequestAutoSize = true;
5005 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
5006 : }
5007 0 : if (errFlag) {
5008 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5009 0 : errFlag = false;
5010 0 : errorsFound = true;
5011 : }
5012 :
5013 0 : this->m_CondenserNodeNum = 0;
5014 :
5015 : // Push heating coil PLF curve index to DX coil
5016 0 : if (HeatingCoilPLFCurveIndex > 0) {
5017 : // get the actual index to the DX cooling coil object
5018 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
5019 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
5020 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
5021 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
5022 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
5023 : }
5024 : // VS coil issue here
5025 : }
5026 :
5027 0 : } // IF (IsNotOK) THEN
5028 31 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5029 25 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5030 7 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5031 7 : if (isNotOK) {
5032 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5033 0 : errorsFound = true;
5034 : } else {
5035 7 : this->m_CoolingCoilIndex =
5036 7 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5037 7 : if (errFlag) {
5038 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5039 0 : errorsFound = true;
5040 0 : errFlag = false;
5041 : } else {
5042 7 : auto &thisCoolCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex);
5043 7 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5044 7 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5045 7 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum;
5046 7 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5047 7 : this->m_NumOfSpeedCooling = thisCoolCoil.NumOfSpeeds;
5048 7 : if (this->m_NumOfSpeedCooling > 1) {
5049 7 : this->m_MultiOrVarSpeedCoolCoil = true;
5050 : }
5051 7 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5052 7 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
5053 3 : this->m_RequestAutoSize = true;
5054 : }
5055 7 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5056 7 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5057 3 : this->m_RequestAutoSize = true;
5058 : } else {
5059 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NumOfSpeeds) /
5060 4 : thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NormSpedLevel) *
5061 4 : thisCoolCoil.RatedAirVolFlowRate;
5062 : }
5063 7 : if (this->m_FanExists) { // Set fan info
5064 5 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
5065 5 : thisCoolCoil.supplyFanType = this->m_FanType;
5066 5 : thisCoolCoil.SupplyFanName = loc_m_FanName;
5067 : }
5068 : }
5069 : }
5070 :
5071 7 : if (this->m_HeatCoilExists) {
5072 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5073 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5074 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5075 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5076 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5077 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5078 3 : this->m_HeatPump = true;
5079 : }
5080 : }
5081 :
5082 31 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
5083 10 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5084 10 : if (isNotOK) {
5085 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5086 0 : errorsFound = true;
5087 : } else {
5088 10 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, input_data.cooling_coil_object_type);
5089 10 : if (errFlag) {
5090 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5091 0 : errorsFound = true;
5092 0 : errFlag = false;
5093 : } else {
5094 10 : auto const &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
5095 10 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
5096 10 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
5097 10 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
5098 10 : this->m_DesignCoolingCapacity = thisCoolCoil.MSRatedTotCap(thisCoolCoil.NumOfSpeeds);
5099 10 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
5100 8 : this->m_RequestAutoSize = true;
5101 : }
5102 10 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(1);
5103 10 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5104 8 : this->m_RequestAutoSize = true;
5105 : }
5106 : }
5107 : }
5108 :
5109 10 : if (this->m_HeatCoilExists) {
5110 7 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5111 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5112 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5113 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5114 5 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5115 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5116 5 : this->m_HeatPump = true;
5117 : }
5118 : }
5119 :
5120 14 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
5121 :
5122 12 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5123 12 : if (isNotOK) {
5124 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5125 0 : errorsFound = true;
5126 : } else { // mine data from Cooling coil object
5127 12 : this->m_CoolingCoilIndex =
5128 12 : WaterCoils::GetWaterCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5129 12 : if (errFlag) {
5130 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5131 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5132 0 : errorsFound = true;
5133 0 : errFlag = false;
5134 : } else {
5135 12 : auto const &thisCoolCoil = state.dataWaterCoils->WaterCoil(this->m_CoolingCoilIndex);
5136 12 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
5137 12 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
5138 11 : this->m_MaxCoolAirVolFlow = thisCoolCoil.DesAirVolFlowRate;
5139 : }
5140 12 : this->CoolCoilFluidInletNode = thisCoolCoil.WaterInletNodeNum;
5141 12 : this->MaxCoolCoilFluidFlow = thisCoolCoil.MaxWaterVolFlowRate;
5142 12 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
5143 4 : this->m_RequestAutoSize = true;
5144 4 : this->m_DesignCoolingCapacity = DataSizing::AutoSize; // water coils don't have a capacity field, need other logic?
5145 : }
5146 12 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5147 12 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5148 : }
5149 : }
5150 14 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5151 2 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5152 2 : if (isNotOK) {
5153 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5154 0 : errorsFound = true;
5155 : } else { // mine data from Cooling coil object
5156 2 : this->m_CoolingCoilIndex =
5157 2 : WaterToAirHeatPumpSimple::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5158 2 : if (errFlag) {
5159 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5160 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5161 0 : errorsFound = true;
5162 0 : errFlag = false;
5163 : } else {
5164 2 : auto const &thisCoolCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_CoolingCoilIndex);
5165 2 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5166 2 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5167 :
5168 : // this isn't likely to work on getInput calls but is what happened before
5169 2 : int CompanionHeatingCoil = thisCoolCoil.CompanionHeatingCoilNum;
5170 2 : if (CompanionHeatingCoil > 0) {
5171 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize &&
5172 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).WAHPPlantType ==
5173 0 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
5174 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
5175 0 : state.dataSize->DXCoolCap > 0) {
5176 : // Heating coil has not yet been sized, returning the temporary cooling capacity
5177 0 : this->m_DesignCoolingCapacity = state.dataSize->DXCoolCap;
5178 : }
5179 : }
5180 :
5181 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
5182 2 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5183 2 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5184 1 : this->m_RequestAutoSize = true;
5185 : }
5186 2 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5187 2 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5188 : }
5189 : }
5190 :
5191 2 : if (this->m_HeatCoilExists) {
5192 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5193 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5194 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5195 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5196 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5197 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5198 2 : this->m_HeatPump = true;
5199 : }
5200 : }
5201 :
5202 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
5203 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5204 0 : if (isNotOK) {
5205 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5206 0 : errorsFound = true;
5207 : } else { // mine data from Cooling coil object
5208 0 : this->m_CoolingCoilIndex =
5209 0 : WaterToAirHeatPump::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5210 0 : if (this->m_CoolingCoilIndex == 0) {
5211 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5212 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5213 0 : errorsFound = true;
5214 0 : errFlag = false;
5215 : } else {
5216 0 : auto const &thisCoolCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_CoolingCoilIndex);
5217 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5218 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingCapacity;
5219 0 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5220 0 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5221 : }
5222 : }
5223 :
5224 0 : if (this->m_HeatCoilExists) {
5225 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5226 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5227 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5228 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5229 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5230 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5231 0 : this->m_HeatPump = true;
5232 : }
5233 : }
5234 :
5235 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
5236 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5237 0 : if (isNotOK) {
5238 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5239 0 : errorsFound = true;
5240 : } else { // mine data from Cooling coil object
5241 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5242 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5243 0 : if (errFlag) {
5244 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5245 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5246 0 : errorsFound = true;
5247 0 : errFlag = false;
5248 : } else {
5249 0 : auto const &thisCoolCoil = state.dataUserDefinedComponents->UserCoil(this->m_CoolingCoilIndex);
5250 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5251 : // **** How to get this info ****
5252 : // UnitarySystem( UnitarySysNum ).DesignCoolingCapacity =
5253 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
5254 0 : CoolingCoilInletNode = thisCoolCoil.Air(1).InletNodeNum;
5255 0 : CoolingCoilOutletNode = thisCoolCoil.Air(1).OutletNodeNum;
5256 : }
5257 : }
5258 :
5259 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
5260 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5261 0 : if (isNotOK) {
5262 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5263 0 : errorsFound = true;
5264 : } else { // mine data from Cooling coil object
5265 0 : PackagedThermalStorageCoil::GetTESCoilIndex(
5266 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5267 0 : if (errFlag) {
5268 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5269 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5270 0 : errorsFound = true;
5271 0 : errFlag = false;
5272 : } else {
5273 0 : auto const &thisCoolCoil = state.dataPackagedThermalStorageCoil->TESCoil(this->m_CoolingCoilIndex);
5274 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5275 0 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedEvapAirVolFlowRate;
5276 0 : if (thisCoolCoil.CoolingOnlyModeIsAvailable) {
5277 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingOnlyRatedTotCap;
5278 0 : } else if (thisCoolCoil.CoolingAndChargeModeAvailable) {
5279 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndChargeRatedTotCap;
5280 0 : } else if (thisCoolCoil.CoolingAndDischargeModeAvailable) {
5281 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndDischargeRatedTotCap;
5282 : } else {
5283 0 : this->m_DesignCoolingCapacity = 0.0;
5284 : }
5285 0 : CoolingCoilInletNode = thisCoolCoil.EvapAirInletNodeNum;
5286 0 : CoolingCoilOutletNode = thisCoolCoil.EvapAirOutletNodeNum;
5287 : }
5288 : }
5289 :
5290 : } else { // IF(.NOT. lAlphaBlanks(16))THEN
5291 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5292 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iCoolingCoilTypeAlphaNum), Alphas(iCoolingCoilTypeAlphaNum)));
5293 0 : errorsFound = true;
5294 : }
5295 :
5296 83 : if (!input_data.dx_cooling_coil_system_sensor_node_name.empty()) { // used by CoilSystem:Cooling:DX
5297 42 : this->CoolCtrlNode = NodeInputManager::GetOnlySingleNode(state,
5298 21 : input_data.dx_cooling_coil_system_sensor_node_name,
5299 : errFlag,
5300 : objType,
5301 : thisObjectName,
5302 : DataLoopNode::NodeFluidType::Air,
5303 : DataLoopNode::ConnectionType::Sensor,
5304 : NodeInputManager::CompFluidStream::Primary,
5305 : DataLoopNode::ObjectIsParent);
5306 : } else {
5307 62 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
5308 9 : this->CoolCtrlNode = this->AirOutNode;
5309 : }
5310 62 : if (SetPointManager::NodeHasSPMCtrlVarType(state, CoolingCoilOutletNode, HVAC::CtrlVarType::Temp)) {
5311 8 : this->CoolCtrlNode = CoolingCoilOutletNode;
5312 : }
5313 : }
5314 :
5315 83 : this->CoolCoilInletNodeNum = CoolingCoilInletNode;
5316 83 : this->CoolCoilOutletNodeNum = CoolingCoilOutletNode;
5317 :
5318 : } else {
5319 17 : this->m_ValidASHRAECoolCoil = false;
5320 : }
5321 :
5322 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple &&
5323 2 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5324 2 : if (!input_data.heat_pump_coil_water_flow_mode.empty()) {
5325 1 : this->m_WaterCyclingMode =
5326 1 : static_cast<HVAC::WaterFlow>(getEnumValue(HVAC::waterFlowNamesUC, Util::makeUPPER(input_data.heat_pump_coil_water_flow_mode)));
5327 : } else {
5328 1 : this->m_WaterCyclingMode = HVAC::WaterFlow::Cycling;
5329 : }
5330 2 : WaterToAirHeatPumpSimple::SetSimpleWSHPData(
5331 2 : state, this->m_CoolingCoilIndex, errorsFound, this->m_WaterCyclingMode, _, this->m_HeatingCoilIndex);
5332 : }
5333 :
5334 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
5335 1 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5336 1 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, this->m_HeatingCoilIndex);
5337 : }
5338 :
5339 : // Add cooling coil to component sets array
5340 100 : if (this->m_CoolCoilExists && this->m_CoolCompNotSetYet) {
5341 80 : if (this->m_CoolingCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
5342 144 : BranchNodeConnections::SetUpCompSets(state,
5343 : cCurrentModuleObject,
5344 : thisObjectName,
5345 : input_data.cooling_coil_object_type,
5346 : this->m_CoolingCoilName,
5347 72 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
5348 72 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
5349 : } else {
5350 8 : BranchNodeConnections::SetUpCompSets(state,
5351 : cCurrentModuleObject,
5352 : thisObjectName,
5353 : input_data.cooling_coil_object_type,
5354 : this->m_CoolingCoilName,
5355 : "UNDEFINED",
5356 : "UNDEFINED");
5357 : }
5358 80 : this->m_CoolCompNotSetYet = false;
5359 : }
5360 : // Run as 100% DOAS DX coil
5361 100 : if (!Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5362 100 : this->m_ISHundredPercentDOASDXCoil = false;
5363 : } else {
5364 0 : if (Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5365 0 : this->m_ISHundredPercentDOASDXCoil = true;
5366 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
5367 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5368 0 : ShowContinueError(state, "Variable DX Cooling Coil is not supported as 100% DOAS DX coil.");
5369 0 : ShowContinueError(state, "Variable DX Cooling Coil resets Use DOAS DX Cooling Coil = No and the simulation continues.");
5370 0 : this->m_ISHundredPercentDOASDXCoil = false;
5371 : }
5372 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "")) {
5373 0 : this->m_ISHundredPercentDOASDXCoil = false;
5374 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "No")) {
5375 0 : this->m_ISHundredPercentDOASDXCoil = false;
5376 : }
5377 : }
5378 :
5379 : // considered as as 100% DOAS DX cooling coil
5380 100 : if (this->m_ISHundredPercentDOASDXCoil) {
5381 : // set the system DX Coil application type to the child DX coil
5382 0 : if (!(this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5383 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
5384 0 : DXCoils::SetDXCoilTypeData(state, this->m_CoolingCoilName);
5385 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
5386 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].setToHundredPercentDOAS();
5387 : }
5388 : }
5389 : // DOAS DX Cooling Coil Leaving Minimum Air Temperature
5390 100 : this->DesignMinOutletTemp = input_data.minimum_supply_air_temperature;
5391 100 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp == DataSizing::AutoSize) {
5392 : // skip error for PTUnits
5393 15 : if (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater) {
5394 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5395 0 : ShowContinueError(state, "Invalid entry for Minimum Supply Air Temperature = AutoSize.");
5396 0 : ShowContinueError(state, "AutoSizing not allowed when Control Type = Load or Setpoint");
5397 0 : errorsFound = true;
5398 : }
5399 : }
5400 100 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp > 7.5) {
5401 5 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5402 5 : ShowContinueError(state, format("Invalid entry for Minimum Supply Air Temperature = {:.4R}", this->DesignMinOutletTemp));
5403 10 : ShowContinueError(state, "The minimum supply air temperature will be limited to 7.5C and the simulation continues.");
5404 5 : this->DesignMinOutletTemp = 7.5;
5405 : }
5406 :
5407 : // Get Latent Load Control flag
5408 100 : if (!input_data.latent_load_control.empty()) {
5409 100 : if (Util::SameString(input_data.latent_load_control, "SensibleOnlyLoadControl")) {
5410 95 : this->m_RunOnSensibleLoad = true;
5411 95 : this->m_RunOnLatentLoad = false;
5412 5 : } else if (Util::SameString(input_data.latent_load_control, "LatentOnlyLoadControl")) {
5413 0 : this->m_RunOnSensibleLoad = false;
5414 0 : this->m_RunOnLatentLoad = true;
5415 5 : } else if (Util::SameString(input_data.latent_load_control, "LatentOrSensibleLoadControl")) {
5416 5 : this->m_RunOnSensibleLoad = true;
5417 5 : this->m_RunOnLatentLoad = true;
5418 0 : } else if (Util::SameString(input_data.latent_load_control, "LatentWithSensibleLoadControl")) {
5419 0 : this->m_RunOnSensibleLoad = true;
5420 0 : this->m_RunOnLatentLoad = true;
5421 0 : this->m_RunOnLatentOnlyWithSensible = true;
5422 : }
5423 : }
5424 100 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
5425 6 : if (!this->m_RunOnLatentLoad && !this->m_RunOnLatentOnlyWithSensible && this->m_ControlType == UnitarySysCtrlType::Load) {
5426 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5427 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5428 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5429 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5430 0 : ShowContinueError(state, "Humidity/Moisture may not be controlled with these settings.");
5431 : }
5432 : } else {
5433 94 : if ((this->m_RunOnLatentLoad || this->m_RunOnLatentOnlyWithSensible) && this->m_ControlType == UnitarySysCtrlType::Load) {
5434 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5435 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5436 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5437 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5438 0 : ShowContinueError(state, "Humidity/Moisture will not be controlled with these settings.");
5439 0 : this->m_RunOnLatentLoad = false;
5440 0 : this->m_RunOnLatentOnlyWithSensible = false;
5441 : }
5442 : }
5443 : // Get reheat coil data if humidistat is used
5444 100 : this->m_SuppHeatCoilName = input_data.supplemental_heating_coil_name;
5445 100 : this->m_SuppHeatCoilTypeName = input_data.supplemental_heating_coil_object_type;
5446 :
5447 100 : if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Water")) {
5448 1 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
5449 99 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Steam")) {
5450 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
5451 177 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Fuel") ||
5452 155 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric") ||
5453 254 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric:MultiStage") ||
5454 172 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:DesuperHeater")) {
5455 26 : this->m_SuppHeatCoilType_Num =
5456 26 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5457 73 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:UserDefined")) {
5458 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_UserDefined;
5459 : }
5460 :
5461 100 : if (!this->m_SuppHeatCoilTypeName.empty() && !this->m_SuppHeatCoilName.empty()) {
5462 27 : errFlag = false;
5463 :
5464 27 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric ||
5465 5 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
5466 1 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
5467 :
5468 26 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5469 26 : if (isNotOK) {
5470 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5471 0 : errorsFound = true;
5472 :
5473 : } else { // mine data from reheat coil
5474 26 : this->m_SuppHeatCoilIndex =
5475 26 : HeatingCoils::GetHeatingCoilIndex(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5476 26 : if (errFlag) {
5477 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5478 0 : errorsFound = true;
5479 0 : errFlag = false;
5480 : } else {
5481 26 : auto const &thisSuppCoil = state.dataHeatingCoils->HeatingCoil(this->m_SuppHeatCoilIndex);
5482 26 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
5483 4 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.MSNominalCapacity(thisSuppCoil.NumOfStages);
5484 4 : this->m_NumOfSpeedSuppHeating = thisSuppCoil.NumOfStages;
5485 : } else {
5486 22 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.NominalCapacity;
5487 : }
5488 26 : if (this->m_DesignSuppHeatingCapacity == DataSizing::AutoSize) {
5489 5 : this->m_RequestAutoSize = true;
5490 : }
5491 26 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5492 26 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5493 : }
5494 : } // IF (IsNotOK) THEN
5495 :
5496 26 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5497 26 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5498 :
5499 27 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5500 :
5501 1 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5502 1 : if (isNotOK) {
5503 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5504 0 : errorsFound = true;
5505 : } else { // mine data from heating coil object
5506 1 : this->m_SuppHeatCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_SuppHeatCoilName, errFlag);
5507 1 : if (errFlag) {
5508 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5509 0 : errorsFound = true;
5510 0 : errFlag = false;
5511 : } else {
5512 1 : auto const &thisSuppCoil = state.dataWaterCoils->WaterCoil(this->m_SuppHeatCoilIndex);
5513 1 : this->m_SuppCoilFluidInletNode = thisSuppCoil.WaterInletNodeNum;
5514 1 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxWaterVolFlowRate;
5515 1 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5516 0 : this->m_RequestAutoSize = true;
5517 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize;
5518 : }
5519 1 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5520 1 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5521 1 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5522 1 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5523 : }
5524 : }
5525 :
5526 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5527 :
5528 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5529 0 : if (isNotOK) {
5530 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5531 0 : errorsFound = true;
5532 : } else { // mine data from heating coil object
5533 0 : this->m_SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_SuppHeatCoilName, errFlag);
5534 0 : if (errFlag) {
5535 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5536 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5537 0 : errorsFound = true;
5538 0 : errFlag = false;
5539 : } else {
5540 0 : auto const &thisSuppCoil = state.dataSteamCoils->SteamCoil(this->m_SuppHeatCoilIndex);
5541 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.SteamInletNodeNum;
5542 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxSteamVolFlowRate;
5543 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5544 0 : this->m_RequestAutoSize = true;
5545 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize; // not sure if steam coil needs this
5546 : }
5547 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
5548 0 : Real64 TempSteamIn = 100.0;
5549 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
5550 0 : this->m_MaxSuppCoilFluidFlow = this->m_MaxSuppCoilFluidFlow * SteamDensity;
5551 : }
5552 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5553 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5554 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5555 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5556 : }
5557 : }
5558 :
5559 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
5560 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5561 0 : if (isNotOK) {
5562 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5563 0 : errorsFound = true;
5564 : } else { // mine data from Heating coil object
5565 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5566 0 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilIndex, errFlag, cCurrentModuleObject);
5567 0 : if (errFlag) {
5568 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5569 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5570 0 : errorsFound = true;
5571 0 : errFlag = false;
5572 : } else {
5573 0 : auto const &thisSuppCoil = state.dataUserDefinedComponents->UserCoil(this->m_SuppHeatCoilIndex);
5574 0 : SupHeatCoilInletNode = thisSuppCoil.Air(1).InletNodeNum;
5575 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5576 0 : SupHeatCoilOutletNode = thisSuppCoil.Air(1).OutletNodeNum;
5577 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5578 : }
5579 : }
5580 :
5581 : } else { // Illegal reheating coil type
5582 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5583 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Type = {}", this->m_SuppHeatCoilTypeName));
5584 0 : errorsFound = true;
5585 : } // IF (this->SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
5586 :
5587 : } // IF(.NOT. lAlphaBlanks(iSuppHeatCoilTypeAlphaNum))THEN
5588 :
5589 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) {
5590 33 : this->SuppCtrlNode = this->AirOutNode;
5591 : }
5592 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, SupHeatCoilOutletNode, HVAC::CtrlVarType::Temp)) {
5593 3 : this->SuppCtrlNode = SupHeatCoilOutletNode;
5594 : }
5595 :
5596 : // Add supplemental heating coil to component sets array
5597 100 : if (this->m_SuppCoilExists && this->m_SuppCompNotSetYet) {
5598 50 : BranchNodeConnections::SetUpCompSets(state,
5599 : cCurrentModuleObject,
5600 : thisObjectName,
5601 : this->m_SuppHeatCoilTypeName,
5602 : this->m_SuppHeatCoilName,
5603 25 : state.dataLoopNodes->NodeID(SupHeatCoilInletNode),
5604 25 : state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
5605 25 : this->m_SuppCompNotSetYet = false;
5606 : }
5607 :
5608 100 : if (this->OAMixerExists) {
5609 : // Set up component set for OA mixer - use OA node and Mixed air node
5610 12 : BranchNodeConnections::SetUpCompSets(state,
5611 : this->UnitType,
5612 : this->Name,
5613 : input_data.oa_mixer_type,
5614 : input_data.oa_mixer_name,
5615 6 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[0]),
5616 6 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[3]));
5617 : }
5618 :
5619 : // set fan info for supplemental heating coils
5620 100 : if (this->m_SuppCoilExists && this->m_FanExists) {
5621 27 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
5622 27 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
5623 : }
5624 :
5625 : // Users may not provide SA flow input fields (below) and leave them blank. Check if other coil is AutoSized first to
5626 : // alleviate input requirements. check if coil has no air flow input (VolFlow = 0) and other coil isDataSizing::AutoSized. If so,
5627 : // use AutoSize for coil with 0 air flow rate. This means that the coils MUST mine the air flow rate if it exists
5628 100 : if (this->m_CoolCoilExists && this->m_HeatCoilExists) {
5629 48 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize && this->m_MaxHeatAirVolFlow == 0 && loc_m_HeatingSAFMethod == "") {
5630 3 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
5631 45 : } else if (this->m_MaxCoolAirVolFlow == 0 && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize && loc_m_CoolingSAFMethod == "") {
5632 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
5633 : }
5634 : }
5635 :
5636 : // translate DesignSpecification:ZoneHVAC:Sizing inputs
5637 : // UnitarySystem already has air flow scalable sizing, update locals
5638 : // UnitarySystem does not have capacity sizing, set inputs accordingly
5639 100 : if (this->m_HVACSizingIndex > 0) {
5640 0 : int zoneHVACIndex = this->m_HVACSizingIndex;
5641 0 : auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(zoneHVACIndex);
5642 0 : switch (zoneHVACSizing.CoolingSAFMethod) {
5643 0 : case DataSizing::None:
5644 0 : break; // do nothing?
5645 0 : case DataSizing::SupplyAirFlowRate:
5646 0 : loc_m_CoolingSAFMethod = "SupplyAirFlowRate";
5647 0 : loc_m_CoolingSAFMethod_SAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5648 0 : break;
5649 0 : case DataSizing::FlowPerFloorArea:
5650 0 : loc_m_CoolingSAFMethod = "FlowPerFloorArea";
5651 0 : loc_m_CoolingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxCoolAirVolFlow;
5652 0 : break;
5653 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5654 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5655 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5656 0 : break;
5657 0 : case DataSizing::FlowPerCoolingCapacity:
5658 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5659 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5660 0 : break;
5661 0 : default:
5662 : assert(true);
5663 : }
5664 :
5665 0 : switch (zoneHVACSizing.HeatingSAFMethod) {
5666 0 : case DataSizing::None:
5667 0 : break; // do nothing?
5668 0 : case DataSizing::SupplyAirFlowRate:
5669 0 : loc_m_HeatingSAFMethod = "SupplyAirFlowRate";
5670 0 : loc_m_HeatingSAFMethod_SAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5671 0 : break;
5672 0 : case DataSizing::FlowPerFloorArea:
5673 0 : loc_m_HeatingSAFMethod = "FlowPerFloorArea";
5674 0 : loc_m_HeatingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxHeatAirVolFlow;
5675 0 : break;
5676 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5677 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5678 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5679 0 : break;
5680 0 : case DataSizing::FlowPerHeatingCapacity:
5681 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5682 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5683 0 : break;
5684 0 : default:
5685 : assert(true);
5686 : }
5687 :
5688 0 : switch (zoneHVACSizing.NoCoolHeatSAFMethod) {
5689 0 : case DataSizing::None:
5690 0 : break; // do nothing?
5691 0 : case DataSizing::SupplyAirFlowRate:
5692 0 : loc_m_NoCoolHeatSAFMethod = "SupplyAirFlowRate";
5693 0 : loc_m_NoCoolHeatSAFMethod_SAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5694 0 : break;
5695 0 : case DataSizing::FlowPerFloorArea:
5696 0 : loc_m_NoCoolHeatSAFMethod = "FlowPerFloorArea";
5697 0 : loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5698 0 : break;
5699 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5700 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5701 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5702 0 : break;
5703 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5704 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5705 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5706 0 : break;
5707 0 : default:
5708 : assert(true);
5709 : }
5710 :
5711 0 : switch (zoneHVACSizing.CoolingCapMethod) {
5712 0 : case DataSizing::CoolingDesignCapacity:
5713 0 : this->m_CoolingCapMethod = DataSizing::CoolingDesignCapacity;
5714 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5715 0 : break;
5716 0 : case DataSizing::CapacityPerFloorArea:
5717 0 : this->m_CoolingCapMethod = DataSizing::CapacityPerFloorArea;
5718 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity * TotalFloorAreaOnAirLoop;
5719 0 : break;
5720 0 : case DataSizing::FractionOfAutosizedCoolingCapacity:
5721 0 : this->m_CoolingCapMethod = DataSizing::FractionOfAutosizedCoolingCapacity;
5722 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5723 0 : break;
5724 0 : default:
5725 : assert(true);
5726 : }
5727 :
5728 0 : switch (zoneHVACSizing.HeatingCapMethod) {
5729 0 : case DataSizing::HeatingDesignCapacity:
5730 0 : this->m_HeatingCapMethod = DataSizing::HeatingDesignCapacity;
5731 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5732 0 : break;
5733 0 : case DataSizing::CapacityPerFloorArea:
5734 0 : this->m_HeatingCapMethod = DataSizing::CapacityPerFloorArea;
5735 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity * TotalFloorAreaOnAirLoop;
5736 0 : break;
5737 0 : case DataSizing::FractionOfAutosizedHeatingCapacity:
5738 0 : this->m_HeatingCapMethod = DataSizing::FractionOfAutosizedHeatingCapacity;
5739 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5740 0 : break;
5741 0 : default:
5742 : assert(true);
5743 : }
5744 : }
5745 :
5746 : // Determine supply air flow rate sizing method for cooling mode
5747 100 : if (Util::SameString(loc_m_CoolingSAFMethod, "SupplyAirFlowRate")) {
5748 43 : this->m_CoolingSAFMethod = DataSizing::SupplyAirFlowRate;
5749 :
5750 43 : if (loc_m_CoolingSAFMethod_SAFlow != -999.0) {
5751 43 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlow;
5752 43 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5753 11 : this->m_RequestAutoSize = true;
5754 : } else {
5755 32 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5756 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5757 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5758 0 : ShowContinueError(
5759 : state,
5760 0 : format("Suspicious Cooling Supply Air Flow Rate = {:.7R} when cooling coil is present.", this->m_MaxCoolAirVolFlow));
5761 : }
5762 32 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5763 0 : errorsFound = true;
5764 : }
5765 : }
5766 :
5767 : } else {
5768 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5769 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5770 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate.");
5771 0 : errorsFound = true;
5772 : }
5773 57 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerFloorArea")) {
5774 :
5775 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerFloorArea;
5776 0 : if (loc_m_CoolingSAFMethod_SAFlowPerFloorArea != -999.0) {
5777 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlowPerFloorArea;
5778 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5779 0 : if (this->m_MaxCoolAirVolFlow <= 0.0001 && this->m_CoolCoilExists) {
5780 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5781 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5782 0 : ShowContinueError(
5783 : state,
5784 0 : format("Suspicious Cooling Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when cooling coil is present.",
5785 0 : this->m_MaxCoolAirVolFlow));
5786 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5787 0 : errorsFound = true;
5788 : }
5789 : }
5790 0 : this->m_MaxCoolAirVolFlow *= TotalFloorAreaOnAirLoop;
5791 0 : this->m_RequestAutoSize = true;
5792 : // AutoSized input is not allowed
5793 : } else {
5794 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5795 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5796 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Floor Area = Autosize");
5797 0 : errorsFound = true;
5798 : }
5799 : } else {
5800 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5801 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5802 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Floor Area.");
5803 0 : errorsFound = true;
5804 : }
5805 57 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FractionOfAutosizedCoolingValue")) {
5806 :
5807 1 : this->m_CoolingSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5808 1 : if (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5809 1 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow;
5810 1 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5811 1 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5812 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5813 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5814 0 : ShowContinueError(state,
5815 0 : format("Suspicious Cooling Fraction of Autosized Cooling Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5816 : "when cooling coil is present.",
5817 0 : this->m_MaxCoolAirVolFlow));
5818 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5819 0 : errorsFound = true;
5820 : }
5821 : }
5822 1 : this->m_RequestAutoSize = true;
5823 : // AutoSized input is not allowed
5824 : } else {
5825 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5826 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5827 0 : ShowContinueError(state, "Illegal Cooling Fraction of Autosized Cooling Supply Air Flow Rate = Autosize");
5828 0 : errorsFound = true;
5829 : }
5830 : } else {
5831 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5832 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5833 0 : ShowContinueError(state, "Blank field not allowed for Cooling Fraction of Autosized Cooling Supply Air Flow Rate.");
5834 0 : errorsFound = true;
5835 : }
5836 56 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerCoolingCapacity")) {
5837 :
5838 4 : this->m_CoolingSAFMethod = DataSizing::FlowPerCoolingCapacity;
5839 4 : if (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity != -999.0) {
5840 4 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FlowPerCoolingCapacity;
5841 4 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5842 4 : if (this->m_MaxCoolAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5843 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5844 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5845 0 : ShowContinueError(state,
5846 0 : format("Suspicious Cooling Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5847 : "cooling coil is present.",
5848 0 : this->m_MaxCoolAirVolFlow));
5849 0 : if (this->m_MaxCoolAirVolFlow < 0.0) {
5850 0 : errorsFound = true;
5851 : }
5852 : }
5853 4 : this->m_RequestAutoSize = true;
5854 : // AutoSized input is not allowed
5855 : } else {
5856 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5857 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5858 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Unit of Capacity = Autosize");
5859 0 : errorsFound = true;
5860 : }
5861 : } else {
5862 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5863 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5864 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Unit of Capacity.");
5865 0 : errorsFound = true;
5866 : }
5867 :
5868 52 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "None") || loc_m_CoolingSAFMethod == "") {
5869 52 : this->m_CoolingSAFMethod = DataSizing::None;
5870 52 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow == 0) {
5871 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5872 0 : if (this->m_HeatCoilExists) {
5873 0 : ShowContinueError(state, "Blank field not allowed for this coil type when heating coil air flow rate is not AutoSized.");
5874 : } else {
5875 0 : ShowContinueError(state, "Blank field not allowed for this type of cooling coil.");
5876 : }
5877 0 : errorsFound = true;
5878 : }
5879 : }
5880 :
5881 : // Determine supply air flow rate sizing method for heating mode
5882 100 : if (Util::SameString(loc_m_HeatingSAFMethod, "SupplyAirFlowRate")) {
5883 60 : this->m_HeatingSAFMethod = DataSizing::SupplyAirFlowRate;
5884 60 : if (loc_m_HeatingSAFMethod_SAFlow != -999.0) {
5885 60 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlow;
5886 60 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
5887 28 : this->m_RequestAutoSize = true;
5888 : } else {
5889 32 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5890 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5891 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5892 0 : ShowContinueError(
5893 : state,
5894 0 : format("Suspicious Heating Supply Air Flow Rate = {:.7R} when heating coil is present.", this->m_MaxHeatAirVolFlow));
5895 : }
5896 32 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5897 0 : errorsFound = true;
5898 : }
5899 : }
5900 : } else {
5901 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5902 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5903 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate.");
5904 0 : errorsFound = true;
5905 : }
5906 40 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerFloorArea")) {
5907 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerFloorArea;
5908 0 : if (loc_m_HeatingSAFMethod_SAFlowPerFloorArea != -999.0) {
5909 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlowPerFloorArea;
5910 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5911 0 : if (this->m_MaxHeatAirVolFlow <= 0.0001 && this->m_HeatCoilExists) {
5912 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5913 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5914 0 : ShowContinueError(
5915 : state,
5916 0 : format("Suspicious Heating Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when heating coil is present.",
5917 0 : this->m_MaxHeatAirVolFlow));
5918 : }
5919 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5920 0 : errorsFound = true;
5921 : }
5922 0 : this->m_MaxHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5923 0 : this->m_RequestAutoSize = true;
5924 : } else {
5925 : // AutoSized input is not allowed
5926 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5927 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5928 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Floor Area = Autosize");
5929 0 : errorsFound = true;
5930 : }
5931 : } else {
5932 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5933 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5934 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Floor Area.");
5935 0 : errorsFound = true;
5936 : }
5937 40 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FractionOfAutosizedHeatingValue")) {
5938 1 : this->m_HeatingSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5939 1 : if (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5940 1 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow;
5941 1 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5942 1 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5943 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5944 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5945 0 : ShowContinueError(state,
5946 0 : format("Suspicious Heating Fraction of Autosized Heating Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5947 : "when heating coil is present.",
5948 0 : this->m_MaxHeatAirVolFlow));
5949 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5950 0 : errorsFound = true;
5951 : }
5952 : }
5953 1 : this->m_RequestAutoSize = true;
5954 : // AutoSized input is not allowed
5955 : } else {
5956 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5957 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5958 0 : ShowContinueError(state, "Illegal input for Heating Fraction of Autosized Heating Supply Air Flow Rate = Autosize");
5959 0 : errorsFound = true;
5960 : }
5961 : } else {
5962 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5963 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5964 0 : ShowContinueError(state, "Blank field not allowed for Heating Fraction of Autosized Heating Supply Air Flow Rate");
5965 0 : errorsFound = true;
5966 : }
5967 39 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerHeatingCapacity")) {
5968 4 : this->m_HeatingSAFMethod = DataSizing::FlowPerHeatingCapacity;
5969 4 : if (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity != -999.0) {
5970 4 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FlowPerHeatingCapacity;
5971 4 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5972 4 : if (this->m_MaxHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5973 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5974 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5975 0 : ShowContinueError(state,
5976 0 : format("Suspicious Heating Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5977 : "heating coil is present.",
5978 0 : this->m_MaxHeatAirVolFlow));
5979 0 : if (this->m_MaxHeatAirVolFlow < 0.0) {
5980 0 : errorsFound = true;
5981 : }
5982 : }
5983 4 : this->m_RequestAutoSize = true;
5984 : // AutoSized input is not allowed
5985 : } else {
5986 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5987 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5988 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Unit of Capacity = Autosize");
5989 0 : errorsFound = true;
5990 : }
5991 : } else {
5992 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5993 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity");
5994 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Unit of Capacity");
5995 0 : errorsFound = true;
5996 : }
5997 35 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "None") || loc_m_HeatingSAFMethod == "") {
5998 35 : this->m_HeatingSAFMethod = DataSizing::None;
5999 35 : if (this->m_HeatCoilExists && this->m_MaxHeatAirVolFlow == 0) {
6000 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6001 1 : if (loc_m_HeatingSAFMethod == "") {
6002 3 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method is blank.");
6003 : } else {
6004 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = None.");
6005 : }
6006 1 : if (this->m_CoolCoilExists) {
6007 3 : ShowContinueError(state, "Blank field not allowed for this coil type when cooling coil air flow rate is not AutoSized.");
6008 : } else {
6009 0 : ShowContinueError(state, "Blank field not allowed for this type of heating coil.");
6010 : }
6011 1 : errorsFound = true;
6012 : }
6013 : }
6014 :
6015 : // Determine supply air flow rate sizing method when cooling or heating is not needed
6016 100 : if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "SupplyAirFlowRate")) {
6017 44 : this->m_NoCoolHeatSAFMethod = DataSizing::SupplyAirFlowRate;
6018 44 : if (loc_m_NoCoolHeatSAFMethod_SAFlow != -999.0) {
6019 44 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlow;
6020 44 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
6021 7 : this->m_RequestAutoSize = true;
6022 : } else {
6023 37 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6024 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6025 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
6026 0 : ShowContinueError(state, format("Illegal No Load Supply Air Flow Rate = {:.7R}", this->m_MaxNoCoolHeatAirVolFlow));
6027 0 : errorsFound = true;
6028 : }
6029 : }
6030 :
6031 : } else {
6032 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6033 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
6034 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate");
6035 0 : errorsFound = true;
6036 : }
6037 56 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerFloorArea")) {
6038 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerFloorArea;
6039 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea != -999.0) {
6040 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea;
6041 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6042 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.0001) {
6043 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6044 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6045 0 : ShowContinueError(
6046 : state,
6047 0 : format("Suspicious No Load Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2]", this->m_MaxNoCoolHeatAirVolFlow));
6048 : }
6049 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6050 0 : errorsFound = true;
6051 : }
6052 0 : this->m_MaxNoCoolHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
6053 0 : this->m_RequestAutoSize = true;
6054 : } else {
6055 : // AutoSized input is not allowed
6056 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6057 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6058 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Floor Area = Autosize");
6059 0 : errorsFound = true;
6060 : }
6061 : } else {
6062 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6063 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
6064 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Floor Area");
6065 0 : errorsFound = true;
6066 : }
6067 56 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedCoolingValue")) {
6068 1 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
6069 1 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
6070 1 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow;
6071 1 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6072 1 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
6073 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6074 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
6075 0 : ShowContinueError(
6076 : state,
6077 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/m3].",
6078 0 : this->m_MaxNoCoolHeatAirVolFlow));
6079 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6080 0 : errorsFound = true;
6081 : }
6082 : }
6083 1 : this->m_RequestAutoSize = true;
6084 : // AutoSized input is not allowed
6085 : } else {
6086 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6087 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue");
6088 0 : ShowContinueError(state,
6089 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
6090 0 : errorsFound = true;
6091 : }
6092 : } else {
6093 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6094 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
6095 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
6096 0 : errorsFound = true;
6097 : }
6098 55 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedHeatingValue")) {
6099 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
6100 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
6101 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow;
6102 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6103 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
6104 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6105 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
6106 0 : ShowContinueError(
6107 : state,
6108 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/m3].",
6109 0 : this->m_MaxNoCoolHeatAirVolFlow));
6110 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6111 0 : errorsFound = true;
6112 : }
6113 : }
6114 0 : this->m_RequestAutoSize = true;
6115 : // AutoSized input is not allowed
6116 : } else {
6117 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6118 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
6119 0 : ShowContinueError(state,
6120 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
6121 0 : errorsFound = true;
6122 : }
6123 : } else {
6124 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6125 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
6126 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
6127 0 : errorsFound = true;
6128 : }
6129 55 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerCoolingCapacity")) {
6130 2 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerCoolingCapacity;
6131 2 : if (loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity != -999.0) {
6132 2 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity;
6133 2 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6134 2 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
6135 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6136 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6137 0 : ShowContinueError(
6138 : state,
6139 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/W].",
6140 0 : this->m_MaxNoCoolHeatAirVolFlow));
6141 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6142 0 : errorsFound = true;
6143 : }
6144 : }
6145 2 : this->m_RequestAutoSize = true;
6146 : // AutoSized input is not allowed
6147 : } else {
6148 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6149 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6150 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
6151 0 : errorsFound = true;
6152 : }
6153 : } else {
6154 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6155 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
6156 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
6157 0 : errorsFound = true;
6158 : }
6159 53 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerHeatingCapacity")) {
6160 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerHeatingCapacity;
6161 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity != -999.0) {
6162 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity;
6163 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
6164 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
6165 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6166 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6167 0 : ShowContinueError(
6168 : state,
6169 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/W].",
6170 0 : this->m_MaxNoCoolHeatAirVolFlow));
6171 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
6172 0 : errorsFound = true;
6173 : }
6174 : }
6175 0 : this->m_RequestAutoSize = true;
6176 : // AutoSized input is not allowed
6177 : } else {
6178 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6179 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6180 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
6181 0 : errorsFound = true;
6182 : }
6183 : } else {
6184 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6185 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
6186 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
6187 0 : errorsFound = true;
6188 : }
6189 53 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "None") || loc_m_NoCoolHeatSAFMethod == "") {
6190 53 : this->m_NoCoolHeatSAFMethod = DataSizing::None;
6191 53 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6192 1 : if (loc_m_NoCoolHeatSAFMethod_SAFlow == -99999.0) { // no load air flow is autosized
6193 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6194 0 : this->m_RequestAutoSize = true;
6195 1 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == -999.0) { // no load air flow is blank
6196 1 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6197 1 : this->m_RequestAutoSize = true;
6198 1 : ShowWarningError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6199 1 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6200 2 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be blank.");
6201 3 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate has been set to AutoSize and the simulation continues.");
6202 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == 0.0) { // no load air flow for SZVAV cannot be 0
6203 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6204 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6205 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
6206 0 : errorsFound = true;
6207 : }
6208 : }
6209 : }
6210 100 : if (this->input_specs.no_load_supply_air_flow_rate_low_speed == "NO") {
6211 6 : this->m_useNoLoadLowSpeedAirFlow = false;
6212 : }
6213 :
6214 : // check supply air flow calculation method
6215 100 : if (this->m_FanExists) {
6216 71 : if (this->m_CoolCoilExists) {
6217 54 : if (loc_m_CoolingSAFMethod.empty()) {
6218 9 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6219 18 : ShowContinueError(state,
6220 : "Method used to determine the cooling supply air flow rate is not specified when cooling coil is present.");
6221 : // check if all cooling flow calc method fields are blank
6222 9 : if (((loc_m_CoolingSAFMethod_SAFlow == -999.0) && (loc_m_CoolingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6223 2 : (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow == -999.0) &&
6224 : (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity == -999.0))) {
6225 4 : ShowContinueError(state, "Cooling Supply Air Flow Rate field is blank.");
6226 4 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Floor Area field is blank.");
6227 4 : ShowContinueError(state, "Cooling Fraction of Autosized Cooling Supply Air Flow Rate field is blank.");
6228 4 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Unit of Capacity field is blank.");
6229 6 : ShowContinueError(state,
6230 : "Blank field not allowed for all four cooling supply air flow rate calculation methods when "
6231 : "cooling coil is present.");
6232 : }
6233 : }
6234 : // set fan info for cooling coils
6235 54 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6236 54 : state, this->m_CoolingCoilName, input_data.cooling_coil_object_type, this->m_FanName, this->m_FanType, this->m_FanIndex);
6237 : }
6238 71 : if (this->m_HeatCoilExists) {
6239 65 : if (loc_m_HeatingSAFMethod.empty()) {
6240 5 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6241 10 : ShowContinueError(state,
6242 : "Method used to determine the heating supply air flow rate is not specified when heating coil is present.");
6243 : // check if all heating flow calc method fields are blank
6244 5 : if (((loc_m_HeatingSAFMethod_SAFlow == -999.0) && (loc_m_HeatingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6245 2 : (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow == -999.0) &&
6246 : (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity == -999.0))) {
6247 4 : ShowContinueError(state, "Heating Supply Air Flow Rate field is blank.");
6248 4 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Floor Area field is blank.");
6249 4 : ShowContinueError(state, "Heating Fraction of Autosized Heating Supply Air Flow Rate field is blank.");
6250 4 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Unit of Capacity field is blank.");
6251 6 : ShowContinueError(state,
6252 : "Blank field not allowed for all four heating supply air flow rate calculation methods when heating "
6253 : "coil is present.");
6254 : }
6255 : }
6256 : // set fan info for heating coils
6257 65 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6258 65 : state, this->m_HeatingCoilName, this->m_HeatingCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
6259 : }
6260 : }
6261 :
6262 : // Fan operating mode (cycling or constant) schedule. IF constant fan, then set AirFlowControl
6263 100 : if (this->m_fanOpModeSched != nullptr) {
6264 44 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6265 : // set fan operating mode to continuous so sizing can set VS coil data
6266 31 : this->m_FanOpMode = HVAC::FanOp::Continuous;
6267 : // set air flow control mode:
6268 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6269 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6270 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6271 31 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6272 10 : this->m_AirFlowControl = UseCompFlow::On;
6273 : } else {
6274 21 : this->m_AirFlowControl = UseCompFlow::Off;
6275 : }
6276 : }
6277 : }
6278 :
6279 100 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6280 0 : int numCoolingCoilModes = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getNumModes();
6281 0 : if (numCoolingCoilModes == 1) {
6282 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6283 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6284 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6285 0 : ShowContinueError(
6286 : state,
6287 0 : format("Cooling coil named: {} has only one mode", state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].name));
6288 0 : ShowFatalError(state, "Multimode cooling coil error causes program termination");
6289 : }
6290 100 : } else if (this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted &&
6291 98 : this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingTwoStageWHumControl &&
6292 98 : this->m_CoolingCoilType_Num != HVAC::CoilWater_CoolingHXAssisted && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6293 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6294 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6295 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6296 0 : if (this->m_SuppHeatCoilName == "" && this->m_SuppHeatCoilTypeName == "") {
6297 : } else {
6298 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
6299 0 : ShowContinueError(state, "Dehumidification control type is assumed to be None and the simulation continues.");
6300 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6301 : } else {
6302 0 : ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
6303 0 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
6304 : }
6305 : }
6306 : }
6307 :
6308 : // Check placement of cooling coil with respect to fan placement and dehumidification control type
6309 :
6310 100 : if (this->m_FanExists) {
6311 71 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6312 65 : if (FanOutletNode == HeatingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6313 17 : this->m_CoolingCoilUpstream = false;
6314 : }
6315 6 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) {
6316 6 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6317 0 : this->m_CoolingCoilUpstream = false;
6318 : }
6319 : }
6320 : } else {
6321 29 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6322 0 : this->m_CoolingCoilUpstream = false;
6323 : }
6324 29 : if (ZoneEquipmentFound) {
6325 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6326 2 : ShowContinueError(state, "ZoneHVAC equipment must contain a fan object.");
6327 1 : ShowContinueError(state, format("specified Supply Fan Object Type = {}", loc_fanType));
6328 1 : ShowContinueError(state, format("specified Supply Fan Name = {}", loc_m_FanName));
6329 1 : errorsFound = true;
6330 : }
6331 : }
6332 :
6333 : // check node connections
6334 100 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6335 :
6336 65 : int tmpAirInletNode = this->AirInNode;
6337 65 : if (this->OAMixerExists) {
6338 5 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6339 : }
6340 65 : if (FanInletNode != tmpAirInletNode) {
6341 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6342 0 : if (this->OAMixerExists) {
6343 0 : ShowContinueError(state,
6344 : "When a blow through fan is specified, the fan inlet node name must be the same as the outdoor "
6345 : "air mixer mixed air node name.");
6346 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6347 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6348 : } else {
6349 0 : ShowContinueError(state,
6350 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system "
6351 : "inlet node name.");
6352 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6353 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6354 : }
6355 0 : errorsFound = true;
6356 : }
6357 65 : if (this->m_CoolingCoilUpstream) {
6358 48 : if (FanOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6359 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6360 0 : ShowContinueError(state,
6361 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil "
6362 : "inlet node name.");
6363 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6364 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6365 0 : errorsFound = true;
6366 : }
6367 48 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6368 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6369 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6370 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6371 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6372 0 : errorsFound = true;
6373 : }
6374 48 : if (this->m_SuppCoilExists) {
6375 21 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6376 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6377 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6378 0 : ShowContinueError(state,
6379 0 : format("...Reheat coil outlet node name = {}" + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6380 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}" + state.dataLoopNodes->NodeID(this->AirOutNode)));
6381 0 : errorsFound = true;
6382 : }
6383 : } else { // IF((this->m_Humidistat ...
6384 : // Heating coil outlet node name must be the same as the Unitary system outlet node name
6385 27 : if (this->m_HeatCoilExists && HeatingCoilOutletNode != this->AirOutNode) {
6386 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6387 0 : ShowContinueError(state,
6388 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
6389 : "unitary system outlet node name.");
6390 0 : ShowContinueError(state,
6391 0 : format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6392 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6393 0 : errorsFound = true;
6394 : }
6395 : }
6396 : } else { // IF(this->CoolingCoilUpstream)THEN
6397 17 : if (FanOutletNode != HeatingCoilInletNode && this->m_FanExists && this->m_HeatCoilExists) {
6398 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6399 0 : ShowContinueError(state,
6400 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil "
6401 : "inlet node name.");
6402 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6403 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6404 0 : errorsFound = true;
6405 : }
6406 17 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6407 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6408 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6409 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6410 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6411 0 : errorsFound = true;
6412 : }
6413 17 : if (CoolingCoilOutletNode != this->AirOutNode && this->m_CoolCoilExists) {
6414 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6415 0 : ShowContinueError(state,
6416 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the unitary "
6417 : "system outlet node name.");
6418 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6419 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6420 0 : errorsFound = true;
6421 : }
6422 : }
6423 :
6424 35 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) { // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6425 :
6426 6 : int tmpAirInletNode = this->AirInNode;
6427 6 : if (this->OAMixerExists) {
6428 1 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6429 : }
6430 6 : if (this->m_CoolingCoilUpstream) {
6431 6 : if (CoolingCoilInletNode != tmpAirInletNode && CoolingCoilInletNode != 0 && this->m_FanExists) {
6432 0 : if (this->OAMixerExists) {
6433 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6434 0 : ShowContinueError(state,
6435 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the outdoor "
6436 : "air mixer mixed air node name.");
6437 0 : ShowContinueError(state,
6438 0 : format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6439 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6440 : } else {
6441 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6442 0 : ShowContinueError(state,
6443 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary "
6444 : "system inlet node name.");
6445 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6446 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6447 : }
6448 0 : errorsFound = true;
6449 : }
6450 6 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6451 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6452 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6453 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6454 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6455 0 : errorsFound = true;
6456 : }
6457 6 : if (HeatingCoilOutletNode != FanInletNode && this->m_HeatCoilExists && this->m_FanExists) {
6458 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6459 0 : ShowContinueError(state,
6460 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan "
6461 : "inlet node name.");
6462 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6463 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6464 0 : errorsFound = true;
6465 : }
6466 6 : if (this->m_SuppCoilExists) {
6467 2 : if (FanOutletNode != SupHeatCoilInletNode && this->m_FanExists) {
6468 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6469 0 : ShowContinueError(state,
6470 : "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
6471 : "inlet node name.");
6472 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6473 0 : ShowContinueError(state, format("...Reheat coil inlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
6474 0 : errorsFound = true;
6475 : }
6476 2 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6477 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6478 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6479 0 : ShowContinueError(state,
6480 0 : format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6481 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6482 0 : errorsFound = true;
6483 : }
6484 : } else {
6485 4 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6486 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6487 0 : ShowContinueError(state,
6488 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6489 : "outlet node name.");
6490 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6491 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6492 0 : errorsFound = true;
6493 : }
6494 : }
6495 : } else { // IF(this->CoolingCoilUpstream)THEN
6496 0 : if (HeatingCoilInletNode != tmpAirInletNode && HeatingCoilInletNode != 0 && this->m_FanExists) {
6497 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6498 0 : if (this->OAMixerExists) {
6499 0 : ShowContinueError(state,
6500 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6501 : "system mixer mixed air node name.");
6502 0 : ShowContinueError(state,
6503 0 : format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6504 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6505 : } else {
6506 0 : ShowContinueError(state,
6507 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6508 : "system inlet node name.");
6509 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6510 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6511 : }
6512 0 : errorsFound = true;
6513 : }
6514 0 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_HeatCoilExists && this->m_CoolCoilExists) {
6515 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6516 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6517 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6518 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6519 0 : errorsFound = true;
6520 : }
6521 0 : if (CoolingCoilOutletNode != FanInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6522 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6523 0 : ShowContinueError(state,
6524 : "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan "
6525 : "inlet node name.");
6526 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6527 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6528 0 : errorsFound = true;
6529 : }
6530 0 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6531 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6532 0 : ShowContinueError(state,
6533 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6534 : "outlet node name.");
6535 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6536 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6537 0 : errorsFound = true;
6538 : }
6539 : }
6540 : } // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6541 :
6542 : // Set the unitary system supplemental heater max outlet temperature
6543 : // this field will be 0 if the input is not specified (included) in the input file
6544 : // someone may use a default other than what we intended, allow it to be used
6545 : // so if this field is blank, and the input field is included, read the default, otherwise use 80
6546 : // if (!lNumericBlanks(iDesignMaxOutletTempNumericNum) && NumNumbers > (iDesignMaxOutletTempNumericNum - 1)) {
6547 100 : if (this->m_sysType == SysType::Unitary) {
6548 : // UnitarySystem has a single field for max outlet temp
6549 55 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6550 : } else {
6551 : // PTHP has a field for max outlet temp for supplemental heater and max outlet temp for SZVAV
6552 45 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6553 1 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6554 : } else {
6555 44 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature_from_supplemental_heater;
6556 : }
6557 : }
6558 100 : if (this->DesignMaxOutletTemp == DataSizing::AutoSize) {
6559 5 : this->m_RequestAutoSize = true;
6560 : }
6561 : //}
6562 :
6563 : // Set maximum Outdoor air temperature for supplemental heating coil operation
6564 : // this field will be 0 if the input is not specified (included) in the input file
6565 : // someone may use a default other than what we intended, allow it to be used
6566 : // so if this field is blank, and the input field is included, read the default, otherwise use 9999
6567 : // if (!lNumericBlanks(iMaxOATSuppHeatNumericNum) && NumNumbers > (iMaxOATSuppHeatNumericNum - 1)) {
6568 100 : this->m_MaxOATSuppHeat = input_data.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation;
6569 : // Can't let MaxOATSuppHeat default to 21C if using cool reheat since it would shut off supp heater when dehumidifying
6570 : // this may also allow supplemental heater to operate when in heating mode when it should not
6571 100 : if (this->m_MaxOATSuppHeat == 21.0 && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6572 6 : this->m_MaxOATSuppHeat = 999.0;
6573 : }
6574 100 : if (this->m_SuppCoilExists) {
6575 54 : OutputReportPredefined::PreDefTableEntry(
6576 27 : state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, this->m_HeatingCoilName, this->m_MaxOATSuppHeat);
6577 : }
6578 :
6579 100 : if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 &&
6580 37 : !this->m_RequestAutoSize) {
6581 28 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6582 72 : } else if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6583 11 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6584 61 : } else if (this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6585 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6586 : } else {
6587 61 : if (this->m_FanExists && this->m_DesignFanVolFlowRate == 0.0) {
6588 0 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
6589 : }
6590 : // need more of this type of warning when flow cannot be determined
6591 61 : if (this->m_MaxHeatAirVolFlow == 0.0 && this->m_HeatCoilExists) {
6592 0 : if (this->m_FanExists) {
6593 0 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6594 0 : if (this->m_MaxCoolAirVolFlow == 0.0) {
6595 0 : this->m_MaxHeatAirVolFlow = this->m_DesignFanVolFlowRate;
6596 : }
6597 : }
6598 0 : } else if (this->m_CoolCoilExists) {
6599 0 : this->m_MaxHeatAirVolFlow = this->m_MaxCoolAirVolFlow;
6600 : } else {
6601 0 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical &&
6602 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating &&
6603 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed) {
6604 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6605 0 : ShowContinueError(state,
6606 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6607 : "Supply Air Flow Rate Method");
6608 0 : errorsFound = true;
6609 : }
6610 : }
6611 61 : } else if (this->m_MaxHeatAirVolFlow == 0.0 && !this->m_FanExists && !this->m_CoolCoilExists) {
6612 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6613 0 : ShowContinueError(state,
6614 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6615 : "Supply Air Flow Rate Method");
6616 : }
6617 : }
6618 :
6619 100 : if (FanVolFlowRate != DataSizing::AutoSize && this->m_FanExists) {
6620 36 : if (FanVolFlowRate < this->m_MaxCoolAirVolFlow && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize && this->m_CoolCoilExists) {
6621 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6622 0 : ShowContinueError(
6623 : state,
6624 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
6625 : FanVolFlowRate,
6626 0 : this->m_FanName));
6627 0 : ShowContinueError(state, " The Cooling Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6628 0 : this->m_MaxCoolAirVolFlow = FanVolFlowRate;
6629 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6630 : }
6631 36 : if (FanVolFlowRate < this->m_MaxHeatAirVolFlow && this->m_MaxHeatAirVolFlow != DataSizing::AutoSize && this->m_HeatCoilExists) {
6632 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6633 0 : ShowContinueError(
6634 : state,
6635 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
6636 : FanVolFlowRate,
6637 0 : this->m_FanName));
6638 0 : ShowContinueError(state, " The Heating Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6639 0 : this->m_MaxHeatAirVolFlow = FanVolFlowRate;
6640 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6641 : }
6642 : }
6643 :
6644 100 : if (this->m_fanOpModeSched != nullptr) {
6645 44 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6646 : // set air flow control mode:
6647 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6648 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6649 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6650 31 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6651 10 : this->m_AirFlowControl = UseCompFlow::On;
6652 : } else {
6653 21 : this->m_AirFlowControl = UseCompFlow::Off;
6654 : }
6655 : }
6656 : }
6657 :
6658 : // Set minimum OAT for heat pump compressor operation in cooling mode
6659 : // get from coil module
6660 100 : errFlag = false;
6661 100 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6662 41 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6663 59 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6664 3 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6665 56 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6666 10 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6667 46 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6668 0 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6669 46 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6670 6 : this->m_MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6671 40 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
6672 : // already found in getInput
6673 : } else {
6674 34 : this->m_MinOATCompressorCooling = -1000.0;
6675 : }
6676 100 : if (errFlag) {
6677 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6678 0 : errorsFound = true;
6679 0 : errFlag = false;
6680 : }
6681 :
6682 : // Set minimum OAT for heat pump compressor operation in heating mode
6683 : // get from coil module
6684 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6685 5 : this->m_MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6686 95 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6687 8 : this->m_MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6688 : } else {
6689 87 : this->m_MinOATCompressorHeating = -1000.0;
6690 : }
6691 100 : if (errFlag) {
6692 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6693 0 : errorsFound = true;
6694 0 : errFlag = false;
6695 : }
6696 :
6697 : // Mine heatpump Outdoor condenser node from DX coil object
6698 100 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6699 41 : this->m_CondenserNodeNum =
6700 41 : DXCoils::GetCoilCondenserInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
6701 : // TODO: Should we add a block for the new DX Coil?
6702 59 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6703 6 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, this->m_CoolingCoilName, errFlag);
6704 53 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
6705 : // already filled
6706 : // UnitarySystem( UnitarySysNum ).CondenserNodeNum = GetDXCoilCondenserInletNode( "Coil:Cooling:DX:SingleSpeed",
6707 : // GetHXDXCoilName(state, CoolingCoilType, this->m_CoolingCoilName, errFlag ), errFlag );
6708 :
6709 : } else {
6710 51 : if (input_data.outdoor_dry_bulb_temperature_sensor_node_name != "") {
6711 2 : this->m_CondenserNodeNum = NodeInputManager::GetOnlySingleNode(state,
6712 1 : input_data.outdoor_dry_bulb_temperature_sensor_node_name,
6713 : errFlag,
6714 : objType,
6715 : thisObjectName,
6716 : DataLoopNode::NodeFluidType::Air,
6717 : DataLoopNode::ConnectionType::Inlet,
6718 : NodeInputManager::CompFluidStream::Primary,
6719 : DataLoopNode::ObjectIsParent);
6720 : } else {
6721 : // do nothing?
6722 : }
6723 : }
6724 100 : if (errFlag) {
6725 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6726 0 : errorsFound = true;
6727 0 : errFlag = false;
6728 : }
6729 :
6730 100 : this->m_AncillaryOnPower = input_data.ancillary_on_cycle_electric_power;
6731 100 : this->m_AncillaryOffPower = input_data.ancillary_off_cycle_electric_power;
6732 100 : this->m_MaxHROutletWaterTemp = input_data.maximum_temperature_for_heat_recovery;
6733 :
6734 100 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
6735 5 : this->m_HeatRecActive = true;
6736 5 : if (input_data.heat_recovery_water_inlet_node_name != "" && input_data.heat_recovery_water_outlet_node_name != "") {
6737 5 : this->m_HeatRecoveryInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6738 5 : input_data.heat_recovery_water_inlet_node_name,
6739 : errFlag,
6740 : objType,
6741 : thisObjectName,
6742 : DataLoopNode::NodeFluidType::Water,
6743 : DataLoopNode::ConnectionType::Inlet,
6744 : NodeInputManager::CompFluidStream::Tertiary,
6745 : DataLoopNode::ObjectIsNotParent);
6746 10 : this->m_HeatRecoveryOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6747 5 : input_data.heat_recovery_water_outlet_node_name,
6748 : errFlag,
6749 : objType,
6750 : thisObjectName,
6751 : DataLoopNode::NodeFluidType::Water,
6752 : DataLoopNode::ConnectionType::Outlet,
6753 : NodeInputManager::CompFluidStream::Tertiary,
6754 : DataLoopNode::ObjectIsNotParent);
6755 :
6756 10 : BranchNodeConnections::TestCompSet(state,
6757 : cCurrentModuleObject,
6758 : thisObjectName,
6759 5 : input_data.heat_recovery_water_inlet_node_name,
6760 5 : input_data.heat_recovery_water_outlet_node_name,
6761 : "Unitary System Heat Recovery Nodes");
6762 :
6763 5 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6764 2 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_CoolingCoilIndex);
6765 : }
6766 5 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6767 2 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_HeatingCoilIndex);
6768 : }
6769 5 : if (errFlag) {
6770 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6771 0 : errorsFound = true;
6772 : // errFlag = false; // not used after this point, uncomment if needed
6773 : }
6774 : } else {
6775 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6776 0 : ShowContinueError(state, format("Illegal Heat Recovery Water Inlet Node Name = {}", input_data.heat_recovery_water_inlet_node_name));
6777 0 : ShowContinueError(state,
6778 0 : format("Illegal Heat Recovery Water Outlet Node Name = {}", input_data.heat_recovery_water_outlet_node_name));
6779 0 : ShowContinueError(state,
6780 : "... heat recovery nodes must be specified when Design Heat Recovery Water Flow Rate"
6781 : " is greater than 0.");
6782 0 : ShowContinueError(state, format("... Design Heat Recovery Water Flow Rate = {:.7R}", this->m_DesignHRWaterVolumeFlow));
6783 0 : errorsFound = true;
6784 : }
6785 : }
6786 :
6787 100 : if (!this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) {
6788 :
6789 26 : if (this->m_DesignSpecMSHPIndex > -1) {
6790 :
6791 25 : this->m_NoLoadAirFlowRateRatio = this->m_CompPointerMSHP->noLoadAirFlowRateRatio;
6792 :
6793 25 : switch (this->m_HeatingCoilType_Num) {
6794 15 : case HVAC::CoilDX_MultiSpeedHeating:
6795 : case HVAC::Coil_HeatingElectric_MultiStage:
6796 : case HVAC::Coil_HeatingGas_MultiStage:
6797 : case HVAC::Coil_HeatingWaterToAirHPSimple:
6798 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
6799 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6800 15 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6801 15 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6802 15 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6803 15 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling < this->m_NumOfSpeedHeating) {
6804 0 : this->FullOutput.resize(this->m_NumOfSpeedHeating + 1);
6805 : }
6806 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple && this->m_NumOfSpeedHeating > 1) {
6807 1 : this->m_MultiSpeedHeatingCoil = true;
6808 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6809 : }
6810 62 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6811 47 : this->m_HeatMassFlowRate[i] = 0.0;
6812 47 : this->m_HeatVolumeFlowRate[i] = 0.0;
6813 47 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6814 : }
6815 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
6816 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6817 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_HeatingCoilName, errorsFound);
6818 1 : if (errorsFound) {
6819 0 : ShowSevereError(state,
6820 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_HeatingCoilName));
6821 : }
6822 1 : if (NumOfSpeed != this->m_NumOfSpeedHeating) {
6823 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_HeatingCoilName));
6824 0 : ShowContinueError(state,
6825 0 : format("... The number of heating coil speeds in the {} = {:.0R}",
6826 : MultispeedType,
6827 0 : double(this->m_NumOfSpeedHeating)));
6828 0 : ShowContinueError(
6829 : state,
6830 0 : format("... The number of heating coil speeds in Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6831 0 : double(NumOfSpeed)));
6832 0 : ShowContinueError(state, format("... The number of heating coil speeds in the {} will be used.", MultispeedType));
6833 : }
6834 1 : }
6835 15 : } break;
6836 : }
6837 25 : switch (this->m_CoolingCoilType_Num) {
6838 12 : case HVAC::CoilDX_MultiSpeedCooling:
6839 : case HVAC::Coil_CoolingWaterToAirHPSimple:
6840 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
6841 12 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6842 12 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6843 12 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6844 12 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6845 12 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > this->m_NumOfSpeedHeating) {
6846 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
6847 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
6848 : }
6849 12 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple && this->m_NumOfSpeedCooling > 1) {
6850 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6851 1 : this->m_DiscreteSpeedCoolingCoil = true;
6852 : }
6853 51 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6854 39 : this->m_CoolMassFlowRate[i] = 0.0;
6855 39 : this->m_CoolVolumeFlowRate[i] = 0.0;
6856 39 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6857 : }
6858 12 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
6859 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6860 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_CoolingCoilName, errorsFound);
6861 1 : if (errorsFound) {
6862 0 : ShowSevereError(state,
6863 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_CoolingCoilName));
6864 : }
6865 1 : if (NumOfSpeed != this->m_NumOfSpeedCooling) {
6866 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_CoolingCoilName));
6867 0 : ShowContinueError(state,
6868 0 : format("... The number of Cooling coil speeds in the {} = {:.0R}",
6869 : MultispeedType,
6870 0 : double(this->m_NumOfSpeedCooling)));
6871 0 : ShowContinueError(
6872 : state,
6873 0 : format("... The number of heating coil speeds in Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6874 0 : double(NumOfSpeed)));
6875 0 : ShowContinueError(state, format("... The number of Cooling coil speeds in the {} will be used.", MultispeedType));
6876 : }
6877 1 : }
6878 12 : } break;
6879 : }
6880 : } else {
6881 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6882 2 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6883 1 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6884 1 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6885 1 : errorsFound = true;
6886 : }
6887 74 : } else if (this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty()) {
6888 74 : if (this->m_FanType == HVAC::FanType::SystemModel) {
6889 1 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex));
6890 1 : assert(fanSystem != nullptr);
6891 1 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
6892 1 : if (fanSystem->numSpeeds > 1) {
6893 0 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6894 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6895 0 : this->m_sysType == SysType::PackagedWSHP) {
6896 0 : this->m_NumOfSpeedCooling = fanSystem->numSpeeds;
6897 0 : this->m_CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6898 0 : this->m_CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
6899 0 : this->m_MSCoolingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6900 0 : this->m_MultiOrVarSpeedCoolCoil = true;
6901 0 : this->m_DiscreteSpeedCoolingCoil = true;
6902 0 : if (fanSystem->maxAirFlowRate > 0.0) {
6903 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6904 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6905 0 : this->m_CoolVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6906 0 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6907 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6908 : }
6909 : } else {
6910 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6911 0 : this->m_CoolMassFlowRate[i] = 0.0;
6912 0 : this->m_CoolVolumeFlowRate[i] = 0.0;
6913 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6914 : }
6915 : }
6916 : }
6917 : }
6918 0 : if ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6919 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6920 0 : this->m_sysType == SysType::PackagedWSHP) {
6921 0 : this->m_NumOfSpeedHeating = fanSystem->numSpeeds;
6922 0 : this->m_HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6923 0 : this->m_HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
6924 0 : this->m_MSHeatingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6925 0 : this->m_MultiSpeedHeatingCoil = true;
6926 0 : this->m_MultiOrVarSpeedHeatCoil = true;
6927 0 : if (fanSystem->maxAirFlowRate > 0.0) {
6928 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
6929 0 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6930 0 : this->m_HeatVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6931 0 : this->m_HeatMassFlowRate[i] = this->m_HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6932 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6933 : }
6934 : } else {
6935 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6936 0 : this->m_HeatMassFlowRate[i] = 0.0;
6937 0 : this->m_HeatVolumeFlowRate[i] = 0.0;
6938 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6939 : }
6940 : }
6941 : }
6942 : }
6943 0 : if (((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6944 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6945 0 : this->m_sysType == SysType::PackagedWSHP) ||
6946 0 : ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6947 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6948 0 : this->m_sysType == SysType::PackagedWSHP)) {
6949 0 : ShowWarningError(state,
6950 0 : format("{} = {} with Fan:SystemModel is used in \"{}\"",
6951 : cCurrentModuleObject,
6952 0 : this->Name,
6953 0 : this->input_specs.supply_fan_name));
6954 0 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
6955 0 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
6956 : }
6957 : }
6958 : }
6959 : }
6960 0 : } else if ((this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) ||
6961 0 : (!this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty())) {
6962 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6963 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6964 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6965 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6966 0 : errorsFound = true;
6967 : }
6968 :
6969 100 : if (this->m_DiscreteSpeedCoolingCoil) {
6970 :
6971 17 : if (this->m_NumOfSpeedCooling == 0) {
6972 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6973 0 : ShowContinueError(state,
6974 0 : format("... Cooling coil object type requires valid {} for cooling to be specified with number of speeds > 0",
6975 : unitarySysHeatPumpPerformanceObjectType));
6976 0 : errorsFound = true;
6977 : }
6978 : }
6979 100 : if (this->m_MultiSpeedHeatingCoil) {
6980 :
6981 14 : if (this->m_DesignSpecMSHPIndex > -1) {
6982 14 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6983 : }
6984 :
6985 14 : if (this->m_NumOfSpeedHeating == 0) {
6986 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6987 0 : ShowContinueError(state,
6988 0 : format("... Heating coil object type requires valid {} for heating to be specified with number of speeds > 0",
6989 : unitarySysHeatPumpPerformanceObjectType));
6990 0 : errorsFound = true;
6991 : }
6992 : }
6993 :
6994 100 : if ((this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating &&
6995 5 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling)) ||
6996 97 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel &&
6997 28 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling))) {
6998 6 : if (this->m_DesignSpecMSHPIndex > -1) {
6999 5 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
7000 1 : this->m_SingleMode = 1;
7001 : }
7002 : }
7003 : } else {
7004 94 : if (this->m_DesignSpecMSHPIndex > -1) {
7005 20 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
7006 0 : ShowSevereError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7007 0 : ShowContinueError(state,
7008 : "In order to perform Single Mode Operation, the valid cooling coil type is Coil:Cooling:DX:MultiSpeed "
7009 : "or Coil:Cooling:DX and the valid heating is Coil:Heating:DX:MultiSpeed or Coil:Heating:Fuel.");
7010 0 : ShowContinueError(state,
7011 0 : format("The input cooling coil type = {} and the input heating coil type = {}",
7012 0 : input_data.cooling_coil_object_type,
7013 0 : this->m_HeatingCoilTypeName));
7014 : }
7015 : }
7016 : }
7017 :
7018 100 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
7019 6 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
7020 : }
7021 :
7022 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
7023 5 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_HeatingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
7024 : }
7025 :
7026 : // set global logicals that denote coil type
7027 100 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
7028 20 : this->m_MultiOrVarSpeedHeatCoil = true;
7029 : }
7030 100 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
7031 24 : this->m_MultiOrVarSpeedCoolCoil = true;
7032 : }
7033 :
7034 : // set global variables for multi-stage chilled and hot water coils
7035 100 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
7036 12 : if (this->m_DesignSpecMSHPIndex > -1) {
7037 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
7038 1 : if (this->m_NumOfSpeedCooling > 1) {
7039 1 : this->m_DiscreteSpeedCoolingCoil = true;
7040 1 : this->m_MultiOrVarSpeedCoolCoil = true;
7041 : }
7042 : }
7043 : }
7044 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
7045 : // designSpecIndex = this->m_DesignSpecMSHPIndex;
7046 5 : if (this->m_DesignSpecMSHPIndex > -1) {
7047 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
7048 1 : if (this->m_NumOfSpeedHeating > 1) {
7049 0 : this->m_MultiSpeedHeatingCoil = true;
7050 0 : this->m_MultiOrVarSpeedHeatCoil = true;
7051 : }
7052 : }
7053 : }
7054 : // zone coils are now simulated before sizing is complete, data will not be available but array is allocated
7055 100 : if (this->m_MultiOrVarSpeedCoolCoil) {
7056 27 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
7057 27 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
7058 27 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
7059 : }
7060 100 : if (this->m_MultiOrVarSpeedHeatCoil) {
7061 20 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
7062 20 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
7063 20 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
7064 : }
7065 :
7066 : // check for specific input requirements for ASHRAE90.1 model
7067 100 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
7068 :
7069 : // only allowed for water and DX cooling coils at this time
7070 4 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWater &&
7071 3 : this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterDetailed && this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingSingleSpeed) {
7072 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7073 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7074 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific cooling coil types.");
7075 0 : ShowContinueError(state,
7076 : "Valid cooling coil types are Coil:Cooling:Water, Coil:Cooling:Water:DetailedGeometry and "
7077 : "Coil:Cooling:DX:SingleSpeed.");
7078 0 : ShowContinueError(state,
7079 0 : format("The input cooling coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
7080 0 : input_data.cooling_coil_object_type));
7081 : }
7082 : // mark this coil as non-ASHRAE90 type
7083 0 : this->m_ValidASHRAECoolCoil = false;
7084 : }
7085 : // only allow for water, fuel, or electric at this time
7086 4 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWater &&
7087 3 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingGasOrOtherFuel && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingElectric &&
7088 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical) {
7089 0 : if (state.dataGlobal->DisplayExtraWarnings) {
7090 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7091 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific heating coil types.");
7092 0 : ShowContinueError(state,
7093 : "Valid heating coil types are Coil:Heating:Water, Coil:Heating:Fuel, Coil:Heating:Electric and "
7094 : "Coil:Heating:DX:SingleSpeed.");
7095 0 : ShowContinueError(state,
7096 0 : format("The input heating coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
7097 0 : this->m_HeatingCoilTypeName));
7098 : }
7099 : // mark this coil as non-ASHRAE90 type
7100 0 : this->m_ValidASHRAEHeatCoil = false;
7101 : }
7102 4 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
7103 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
7104 0 : ShowContinueError(state, format("Invalid entry for Dehumidification Control Type = {}", input_data.dehumidification_control_type));
7105 0 : ShowContinueError(state,
7106 : "ASHRAE90.1 control method does not support dehumidification at this time. Dehumidification control type is "
7107 : "assumed to be None.");
7108 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
7109 : }
7110 4 : if (this->m_RunOnLatentLoad) {
7111 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
7112 0 : ShowContinueError(state, format("Invalid entry for Latent Load Control: {}", input_data.latent_load_control));
7113 0 : ShowContinueError(state,
7114 : "ASHRAE90.1 control method does not support latent load control at this time. This input must be selected as "
7115 : "SensibleOnlyLoadControl.");
7116 0 : this->m_RunOnSensibleLoad = true;
7117 0 : this->m_RunOnLatentLoad = false;
7118 0 : this->m_RunOnLatentOnlyWithSensible = false;
7119 : }
7120 4 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) { // 0 min air flow not allowed for SZVAV
7121 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
7122 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
7123 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
7124 0 : errorsFound = true;
7125 : }
7126 : }
7127 106 : }
7128 :
7129 136 : void UnitarySys::getDXCoilSystemData(
7130 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7131 : {
7132 136 : std::string const cCurrentModuleObject = "CoilSystem:Cooling:DX";
7133 136 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7134 136 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7135 42 : auto &instancesValue = instances.value();
7136 42 : int numCoilSystemDX = 0;
7137 93 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7138 :
7139 51 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7140 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7141 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7142 51 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7143 6 : continue;
7144 : }
7145 :
7146 45 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7147 45 : UnitarySys thisSys;
7148 45 : if (sysNum == -1) {
7149 24 : ++state.dataUnitarySystems->numUnitarySystems;
7150 24 : auto const &thisObjName = instance.key();
7151 24 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7152 : } else {
7153 21 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7154 : }
7155 :
7156 : // get CoilSystem:Cooling:DX object inputs
7157 45 : auto const &fields = instance.value();
7158 45 : thisSys.input_specs.name = thisObjectName;
7159 45 : thisSys.input_specs.system_type = cCurrentModuleObject;
7160 90 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7161 45 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7162 45 : }
7163 : thisSys.input_specs.air_inlet_node_name =
7164 90 : Util::makeUPPER(fields.at("dx_cooling_coil_system_inlet_node_name").get<std::string>()); // required field
7165 : thisSys.input_specs.air_outlet_node_name =
7166 90 : Util::makeUPPER(fields.at("dx_cooling_coil_system_outlet_node_name").get<std::string>()); // required field
7167 :
7168 : thisSys.input_specs.dx_cooling_coil_system_sensor_node_name =
7169 90 : Util::makeUPPER(fields.at("dx_cooling_coil_system_sensor_node_name").get<std::string>()); // required field
7170 :
7171 : thisSys.input_specs.cooling_coil_object_type =
7172 90 : Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>()); // required field
7173 90 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>()); // required field
7174 : // min-fields = 7, begin optional inputs
7175 90 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field
7176 : thisSys.input_specs.dehumidification_control_type =
7177 11 : it.value().get<std::string>(); // Don't capitalize this one, since it's an enum
7178 : } else {
7179 : // find default value
7180 34 : thisSys.input_specs.dehumidification_control_type = "None";
7181 45 : }
7182 90 : std::string loc_RunOnSensLoad("");
7183 90 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) { // not required field
7184 11 : loc_RunOnSensLoad = Util::makeUPPER(it.value().get<std::string>());
7185 : } else {
7186 : // find default value
7187 34 : loc_RunOnSensLoad = "YES";
7188 45 : }
7189 90 : std::string loc_RunOnLatLoad("");
7190 90 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) { // not required field
7191 11 : loc_RunOnLatLoad = Util::makeUPPER(it.value().get<std::string>());
7192 : } else {
7193 : // find default value
7194 34 : loc_RunOnLatLoad = "NO";
7195 45 : }
7196 45 : if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "NO") {
7197 41 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7198 4 : } else if (loc_RunOnSensLoad == "NO" && loc_RunOnLatLoad == "YES") {
7199 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7200 4 : } else if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "YES") {
7201 : // does DX system control on LatentOrSensibleLoadControl or LatentWithSensibleLoadControl?
7202 4 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7203 : }
7204 :
7205 90 : if (auto it = fields.find("use_outdoor_air_dx_cooling_coil"); it != fields.end()) { // not required field
7206 7 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7207 : } else {
7208 : // find default value
7209 38 : thisSys.input_specs.use_doas_dx_cooling_coil = "NO";
7210 45 : }
7211 90 : if (auto it = fields.find("outdoor_air_dx_cooling_coil_leaving_minimum_air_temperature"); it != fields.end()) { // not required field
7212 0 : thisSys.input_specs.minimum_supply_air_temperature = it.value().get<Real64>();
7213 45 : }
7214 : // set UnitarySystem specific inputs
7215 45 : thisSys.input_specs.control_type = "SETPOINT";
7216 :
7217 : // now translate to UnitarySystem
7218 45 : thisSys.UnitType = cCurrentModuleObject;
7219 45 : thisSys.m_sysType = SysType::CoilCoolingDX;
7220 45 : thisSys.AirloopEqType = SimAirServingZones::CompType::DXSystem;
7221 :
7222 : // TODO: figure out another way to set this next variable
7223 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7224 45 : thisSys.m_LastMode = CoolingMode;
7225 45 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7226 :
7227 45 : if (sysNum == -1) {
7228 24 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7229 24 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7230 : // zone equipment require a 1-n index for access to zone availability managers
7231 : // although not zone equipment, use same methodology
7232 24 : ++numCoilSystemDX;
7233 24 : thisSys.m_EquipCompNum = numCoilSystemDX;
7234 : } else {
7235 21 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7236 : }
7237 93 : }
7238 : }
7239 136 : }
7240 :
7241 136 : void UnitarySys::getPackagedTerminalUnitData(
7242 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7243 : {
7244 136 : std::string cCurrentModuleObject = "ZoneHVAC:PackagedTerminalAirConditioner";
7245 136 : SysType sysTypeNum = SysType::PackagedAC;
7246 136 : DataZoneEquipment::ZoneEquipType zoneEqType = DataZoneEquipment::ZoneEquipType::Invalid;
7247 136 : int numPTAC = 0;
7248 136 : int numPTHP = 0;
7249 136 : int numPTWSHP = 0;
7250 136 : auto &ip = state.dataInputProcessing->inputProcessor;
7251 544 : for (int getPTUnitType = 1; getPTUnitType <= 3; ++getPTUnitType) {
7252 408 : if (getPTUnitType == 2) {
7253 136 : sysTypeNum = SysType::PackagedHP;
7254 136 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7255 136 : cCurrentModuleObject = "ZoneHVAC:PackagedTerminalHeatPump";
7256 272 : } else if (getPTUnitType == 3) {
7257 136 : sysTypeNum = SysType::PackagedWSHP;
7258 136 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7259 136 : cCurrentModuleObject = "ZoneHVAC:WaterToAirHeatPump";
7260 : }
7261 408 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7262 408 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7263 30 : auto &instancesValue = instances.value();
7264 30 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
7265 87 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7266 :
7267 57 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7268 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7269 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7270 57 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7271 22 : continue;
7272 : }
7273 :
7274 35 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7275 35 : UnitarySys thisSys;
7276 35 : if (sysNum == -1) {
7277 18 : ++state.dataUnitarySystems->numUnitarySystems;
7278 18 : auto const &thisObjName = instance.key();
7279 18 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7280 : } else {
7281 17 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7282 : }
7283 :
7284 : // get PackagedTerminal unit object inputs
7285 35 : auto const &fields = instance.value();
7286 35 : thisSys.input_specs.name = thisObjectName;
7287 35 : thisSys.input_specs.system_type = cCurrentModuleObject;
7288 70 : thisSys.input_specs.availability_schedule_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_schedule_name");
7289 70 : thisSys.input_specs.air_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_inlet_node_name");
7290 70 : thisSys.input_specs.air_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_outlet_node_name");
7291 :
7292 70 : thisSys.input_specs.oa_mixer_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_object_type");
7293 70 : thisSys.input_specs.oa_mixer_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_name");
7294 :
7295 35 : thisSys.input_specs.cooling_supply_air_flow_rate =
7296 70 : ip->getRealFieldValue(fields, objectSchemaProps, "cooling_supply_air_flow_rate");
7297 35 : thisSys.input_specs.heating_supply_air_flow_rate =
7298 70 : ip->getRealFieldValue(fields, objectSchemaProps, "heating_supply_air_flow_rate");
7299 35 : thisSys.input_specs.no_load_supply_air_flow_rate =
7300 70 : ip->getRealFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate");
7301 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed =
7302 70 : ip->getAlphaFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7303 70 : thisSys.input_specs.cooling_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_outdoor_air_flow_rate");
7304 70 : thisSys.input_specs.heating_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "heating_outdoor_air_flow_rate");
7305 70 : thisSys.input_specs.no_load_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "no_load_outdoor_air_flow_rate");
7306 :
7307 70 : thisSys.input_specs.supply_fan_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_object_type");
7308 70 : thisSys.input_specs.supply_fan_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_name");
7309 70 : thisSys.input_specs.heating_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_object_type");
7310 70 : thisSys.input_specs.heating_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_name");
7311 70 : thisSys.input_specs.cooling_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_object_type");
7312 70 : thisSys.input_specs.cooling_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_name");
7313 :
7314 70 : thisSys.input_specs.fan_placement = ip->getAlphaFieldValue(fields, objectSchemaProps, "fan_placement");
7315 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name =
7316 70 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_operating_mode_schedule_name");
7317 35 : if (getPTUnitType > 1) {
7318 10 : thisSys.input_specs.maximum_supply_air_temperature_from_supplemental_heater =
7319 20 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_from_supplemental_heater");
7320 : thisSys.input_specs.supplemental_heating_coil_object_type =
7321 20 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_object_type");
7322 : thisSys.input_specs.supplemental_heating_coil_name =
7323 20 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_name");
7324 20 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = ip->getRealFieldValue(
7325 : fields, objectSchemaProps, "maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7326 10 : if (getPTUnitType == 2) {
7327 12 : thisSys.input_specs.heat_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "heating_convergence_tolerance");
7328 18 : thisSys.input_specs.cool_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_convergence_tolerance");
7329 4 : } else if (getPTUnitType == 3) {
7330 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name =
7331 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_dry_bulb_temperature_sensor_node_name");
7332 : thisSys.input_specs.heat_pump_coil_water_flow_mode =
7333 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "heat_pump_coil_water_flow_mode");
7334 4 : thisSys.input_specs.control_type = "LOAD";
7335 : }
7336 : }
7337 35 : if (getPTUnitType < 3) {
7338 62 : thisSys.input_specs.control_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "capacity_control_method");
7339 31 : if (thisSys.input_specs.control_type.empty() || thisSys.input_specs.control_type == "NONE") {
7340 29 : thisSys.input_specs.control_type = "LOAD";
7341 : }
7342 31 : thisSys.input_specs.minimum_supply_air_temperature =
7343 62 : ip->getRealFieldValue(fields, objectSchemaProps, "minimum_supply_air_temperature_in_cooling_mode");
7344 31 : thisSys.input_specs.maximum_supply_air_temperature =
7345 93 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_in_heating_mode");
7346 : }
7347 :
7348 70 : thisSys.input_specs.avail_manager_list_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_manager_list_name");
7349 : thisSys.input_specs.design_spec_zonehvac_sizing_object_name =
7350 70 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_zonehvac_sizing_object_name");
7351 :
7352 35 : if (getPTUnitType == 3) {
7353 : thisSys.m_DesignSpecMultispeedHPType =
7354 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_type");
7355 : thisSys.m_DesignSpecMultispeedHPName =
7356 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_name");
7357 4 : if (!thisSys.m_DesignSpecMultispeedHPType.empty() && !thisSys.m_DesignSpecMultispeedHPName.empty()) {
7358 4 : DesignSpecMSHP thisDesignSpec;
7359 4 : thisSys.m_CompPointerMSHP =
7360 4 : thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, thisSys.m_DesignSpecMultispeedHPName);
7361 4 : thisSys.m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, thisSys.m_DesignSpecMultispeedHPName);
7362 4 : }
7363 : }
7364 :
7365 : // set UnitarySystem specific inputs
7366 35 : thisSys.input_specs.dehumidification_control_type = "None";
7367 35 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7368 35 : thisSys.input_specs.cooling_supply_air_flow_rate_method = "SupplyAirFlowRate";
7369 35 : thisSys.input_specs.heating_supply_air_flow_rate_method = "SupplyAirFlowRate";
7370 35 : thisSys.input_specs.no_load_supply_air_flow_rate_method = "SupplyAirFlowRate";
7371 :
7372 35 : thisSys.UnitType = cCurrentModuleObject;
7373 35 : thisSys.m_sysType = sysTypeNum;
7374 35 : thisSys.zoneEquipType = zoneEqType;
7375 :
7376 : // TODO: figure out another way to set this next variable
7377 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7378 35 : thisSys.m_LastMode = HeatingMode;
7379 35 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7380 :
7381 35 : if (sysNum == -1) {
7382 : // zone equipment require a 1-n index for access to zone availability managers
7383 18 : switch (getPTUnitType) {
7384 13 : case 1: // Excuse me?
7385 13 : ++numPTAC;
7386 13 : thisSys.m_EquipCompNum = numPTAC;
7387 13 : break;
7388 3 : case 2: // Baking powder?
7389 3 : ++numPTHP;
7390 3 : thisSys.m_EquipCompNum = numPTHP;
7391 3 : break;
7392 2 : case 3:
7393 2 : ++numPTWSHP;
7394 2 : thisSys.m_EquipCompNum = numPTWSHP;
7395 2 : break;
7396 18 : default:
7397 : assert(true);
7398 : }
7399 18 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7400 18 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7401 : } else {
7402 17 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7403 : }
7404 87 : }
7405 : }
7406 408 : }
7407 136 : }
7408 :
7409 136 : void UnitarySys::allocateUnitarySys(EnergyPlusData &state)
7410 : {
7411 136 : if (!state.dataUnitarySystems->unitarySys.empty()) {
7412 44 : return;
7413 : }
7414 92 : int numUnitarySystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:UnitarySystem");
7415 92 : int numCoilSystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:DX");
7416 92 : int numCoilSystemsWater = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:Water");
7417 92 : int numPackagedAC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalAirConditioner");
7418 92 : int numPackagedHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalHeatPump");
7419 92 : int numPackagedWSHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:WaterToAirHeatPump");
7420 92 : int numAllSystemTypes = numUnitarySystems + numCoilSystems + numCoilSystemsWater + numPackagedAC + numPackagedHP + numPackagedWSHP;
7421 193 : for (int sysCount = 0; sysCount < numAllSystemTypes; ++sysCount) {
7422 101 : UnitarySys thisSys;
7423 101 : state.dataUnitarySystems->unitarySys.push_back(thisSys);
7424 101 : }
7425 : }
7426 :
7427 142 : void UnitarySys::getCoilWaterSystemInputData(
7428 : EnergyPlusData &state, std::string_view CoilSysName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7429 : {
7430 :
7431 142 : std::string cCurrentModuleObject("CoilSystem:Cooling:Water");
7432 326 : static const std::string routineName("getCoilWaterSystemInputData: ");
7433 142 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7434 142 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7435 12 : auto &instancesValue = instances.value();
7436 12 : int numCoilSystemWater = 0;
7437 24 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7438 :
7439 12 : auto const &fields = instance.value();
7440 12 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7441 12 : if (!Util::SameString(CoilSysName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7442 0 : continue;
7443 : }
7444 :
7445 12 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7446 12 : UnitarySys thisSys;
7447 12 : if (sysNum == -1) {
7448 6 : ++state.dataUnitarySystems->numUnitarySystems;
7449 6 : auto const &thisObjName = instance.key();
7450 6 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7451 : } else {
7452 6 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7453 : }
7454 :
7455 12 : thisSys.input_specs.name = thisObjectName;
7456 12 : thisSys.input_specs.system_type = cCurrentModuleObject;
7457 12 : thisSys.input_specs.control_type = "Setpoint";
7458 24 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>());
7459 24 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>());
7460 24 : std::string availScheduleName("");
7461 24 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field, has default value of Always On
7462 0 : availScheduleName = Util::makeUPPER(it.value().get<std::string>());
7463 12 : }
7464 12 : thisSys.input_specs.availability_schedule_name = availScheduleName;
7465 24 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>());
7466 12 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>());
7467 : // why is this cooling coil does not have a field for Design Air Vol Flow Rate
7468 : // set it "SupplyAirFlowRate" to avoid blank, which lead to fatal out during get input
7469 : static constexpr std::string_view loc_cooling_coil_object_type("COIL:COOLING:WATER:DETAILEDGEOMETRY");
7470 12 : if (Util::SameString(loc_cooling_coil_object_type, thisSys.input_specs.cooling_coil_object_type)) {
7471 2 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER("SupplyAirFlowRate");
7472 2 : thisSys.input_specs.cooling_supply_air_flow_rate = DataSizing::AutoSize;
7473 : }
7474 : // optional input fields
7475 12 : if (auto it = fields.find("minimum_air_to_water_temperature_offset");
7476 12 : it != fields.end()) { // not required field, has default value of 0.0
7477 12 : thisSys.m_minAirToWaterTempOffset = it.value().get<Real64>();
7478 12 : }
7479 24 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) {
7480 12 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7481 : } else {
7482 0 : thisSys.input_specs.dehumidification_control_type = "None";
7483 12 : }
7484 :
7485 12 : bool runOnSensibleLoad = true;
7486 24 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) {
7487 12 : runOnSensibleLoad = Util::SameString(it.value().get<std::string>(), "YES");
7488 12 : }
7489 12 : bool runOnLatentLoad = false;
7490 24 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) {
7491 12 : runOnLatentLoad = Util::SameString(it.value().get<std::string>(), "YES");
7492 12 : }
7493 :
7494 12 : if (runOnSensibleLoad && !runOnLatentLoad) {
7495 10 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7496 2 : } else if (!runOnSensibleLoad && runOnLatentLoad) {
7497 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7498 2 : } else if (runOnSensibleLoad && runOnLatentLoad) {
7499 2 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7500 : }
7501 :
7502 : // now translate to UnitarySystem
7503 12 : thisSys.UnitType = cCurrentModuleObject;
7504 12 : thisSys.m_sysType = SysType::CoilCoolingWater;
7505 12 : thisSys.AirloopEqType = SimAirServingZones::CompType::CoilSystemWater;
7506 12 : thisSys.input_specs.control_type = "Setpoint";
7507 12 : thisSys.m_CoolCoilExists = true; // is always true
7508 12 : thisSys.m_LastMode = CoolingMode;
7509 : // set water-side economizer flag
7510 12 : if (thisSys.m_minAirToWaterTempOffset > 0.0) {
7511 12 : thisSys.m_TemperatureOffsetControlActive = true;
7512 : }
7513 :
7514 : // heat recovery loop inputs
7515 24 : if (auto it = fields.find("minimum_water_loop_temperature_for_heat_recovery"); it != fields.end()) {
7516 0 : thisSys.m_minWaterLoopTempForHR = it.value().get<Real64>();
7517 12 : }
7518 24 : if (auto it = fields.find("economizer_lockout"); it != fields.end()) { // duplicate above as default
7519 0 : bool econoFlag = Util::SameString(it.value().get<std::string>(), "YES");
7520 0 : if (econoFlag) {
7521 0 : thisSys.m_waterSideEconomizerFlag = true;
7522 : }
7523 : } else {
7524 12 : thisSys.m_waterSideEconomizerFlag = true;
7525 12 : }
7526 12 : std::string HRWaterCoolingCoilName;
7527 24 : if (auto it = fields.find("companion_coil_used_for_heat_recovery"); it != fields.end()) {
7528 2 : HRWaterCoolingCoilName = Util::makeUPPER(it.value().get<std::string>());
7529 2 : thisSys.m_WaterHRPlantLoopModel = true;
7530 12 : }
7531 12 : if (thisSys.m_WaterHRPlantLoopModel) {
7532 2 : std::string const HRcoolingCoilType("COIL:COOLING:WATER");
7533 2 : bool errFound = false;
7534 2 : thisSys.m_HRcoolCoilAirInNode = WaterCoils::GetCoilInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7535 2 : thisSys.m_HRcoolCoilFluidInletNode =
7536 2 : WaterCoils::GetCoilWaterInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7537 2 : int HRCoilIndex = WaterCoils::GetWaterCoilIndex(state, Util::makeUPPER(HRcoolingCoilType), HRWaterCoolingCoilName, errFound);
7538 2 : bool heatRecoveryCoil = true; // use local here to highlight where this parameter is set
7539 2 : WaterCoils::SetWaterCoilData(state, HRCoilIndex, errFound, _, _, heatRecoveryCoil);
7540 2 : if (errFound) {
7541 0 : if (HRCoilIndex == 0) {
7542 0 : ShowContinueError(state, format("...cooling coil {} must be of type Coil:Cooling:Water.", HRWaterCoolingCoilName));
7543 : }
7544 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisObjectName));
7545 : }
7546 2 : errorsFound = errorsFound || errFound;
7547 2 : }
7548 : // end heat recovery loop inputs
7549 :
7550 12 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7551 :
7552 12 : if (sysNum == -1) {
7553 6 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7554 6 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7555 : // zone equipment require a 1-n index for access to zone availability managers
7556 : // although not zone equipment, use same methodology
7557 6 : ++numCoilSystemWater;
7558 6 : thisSys.m_EquipCompNum = numCoilSystemWater;
7559 : } else {
7560 6 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7561 : }
7562 24 : }
7563 :
7564 12 : if (errorsFound) {
7565 0 : ShowFatalError(
7566 : state,
7567 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", routineName, cCurrentModuleObject));
7568 : }
7569 : }
7570 142 : }
7571 :
7572 186 : void UnitarySys::getUnitarySystemInputData(
7573 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7574 : {
7575 :
7576 186 : std::string const cCurrentModuleObject = "AirLoopHVAC:UnitarySystem";
7577 372 : static std::string const getUnitarySystemInput("getUnitarySystemInputData");
7578 186 : int zoneUnitaryNum = 0;
7579 186 : int airloopUnitaryNum = 0;
7580 :
7581 186 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7582 186 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end() && state.dataUnitarySystems->numUnitarySystems == 0) {
7583 0 : ShowSevereError(state, "getUnitarySystemInputData: did not find AirLoopHVAC:UnitarySystem object in input file. Check inputs");
7584 0 : errorsFound = true;
7585 186 : } else if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7586 111 : auto &instancesValue = instances.value();
7587 111 : auto const &objectSchemaProps = state.dataInputProcessing->inputProcessor->getObjectSchemaProps(state, cCurrentModuleObject);
7588 222 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7589 :
7590 111 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7591 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7592 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7593 111 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) {
7594 2 : continue;
7595 : }
7596 :
7597 109 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7598 109 : UnitarySys thisSys;
7599 109 : if (sysNum == -1) {
7600 53 : ++state.dataUnitarySystems->numUnitarySystems;
7601 53 : auto const &thisObjName = instance.key();
7602 53 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7603 : } else {
7604 56 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7605 : }
7606 :
7607 109 : auto const &fields = instance.value();
7608 109 : thisSys.UnitType = cCurrentModuleObject;
7609 109 : thisSys.m_sysType = SysType::Unitary;
7610 109 : thisSys.AirloopEqType = SimAirServingZones::CompType::UnitarySystemModel;
7611 :
7612 109 : thisSys.input_specs.name = thisObjectName;
7613 109 : thisSys.input_specs.system_type = cCurrentModuleObject;
7614 218 : thisSys.input_specs.control_type = fields.at("control_type").get<std::string>();
7615 218 : if (auto it = fields.find("controlling_zone_or_thermostat_location"); it != fields.end()) { // not required field
7616 101 : thisSys.input_specs.controlling_zone_or_thermostat_location = Util::makeUPPER(it.value().get<std::string>());
7617 109 : }
7618 218 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field, has default
7619 108 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7620 : } else {
7621 1 : thisSys.input_specs.dehumidification_control_type = "NONE"; // default value
7622 109 : }
7623 218 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7624 83 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7625 109 : }
7626 218 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>()); // required
7627 218 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>()); // required
7628 218 : if (auto it = fields.find("supply_fan_object_type"); it != fields.end()) { // not required field
7629 105 : thisSys.input_specs.supply_fan_object_type = Util::makeUPPER(it.value().get<std::string>());
7630 109 : }
7631 :
7632 218 : if (auto it = fields.find("supply_fan_name"); it != fields.end()) { // not required field
7633 105 : thisSys.input_specs.supply_fan_name = Util::makeUPPER(it.value().get<std::string>());
7634 109 : }
7635 218 : if (auto it = fields.find("fan_placement"); it != fields.end()) { // not required field
7636 105 : thisSys.input_specs.fan_placement = Util::makeUPPER(it.value().get<std::string>());
7637 109 : }
7638 218 : if (auto it = fields.find("supply_air_fan_operating_mode_schedule_name"); it != fields.end()) { // not required field
7639 53 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7640 109 : }
7641 218 : if (auto it = fields.find("heating_coil_object_type"); it != fields.end()) { // not required field
7642 93 : thisSys.input_specs.heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7643 93 : thisSys.m_HeatCoilExists = true;
7644 109 : }
7645 218 : if (auto it = fields.find("heating_coil_name"); it != fields.end()) { // not required field
7646 93 : thisSys.input_specs.heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7647 109 : }
7648 218 : if (auto it = fields.find("dx_heating_coil_sizing_ratio"); it != fields.end()) { // not required field, has default
7649 19 : thisSys.input_specs.dx_heating_coil_sizing_ratio = it.value().get<Real64>();
7650 109 : }
7651 218 : if (auto it = fields.find("cooling_coil_object_type"); it != fields.end()) { // not required field
7652 76 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7653 76 : thisSys.m_CoolCoilExists = true;
7654 109 : }
7655 218 : if (auto it = fields.find("cooling_coil_name"); it != fields.end()) { // not required field
7656 76 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(it.value().get<std::string>());
7657 109 : }
7658 218 : if (auto it = fields.find("use_doas_dx_cooling_coil"); it != fields.end()) { // not required field, has default
7659 57 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7660 : } else {
7661 52 : thisSys.input_specs.use_doas_dx_cooling_coil = "No";
7662 109 : }
7663 109 : if (auto it = fields.find("minimum_supply_air_temperature");
7664 109 : it != fields.end()) { // not required field, has default (2C), and autosizable
7665 66 : thisSys.input_specs.minimum_supply_air_temperature =
7666 134 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7667 134 : ? DataSizing::AutoSize
7668 64 : : it.value().get<Real64>();
7669 109 : }
7670 218 : if (auto it = fields.find("latent_load_control"); it != fields.end()) { // not required field, has default
7671 58 : thisSys.input_specs.latent_load_control = it.value().get<std::string>();
7672 : } else {
7673 51 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7674 109 : }
7675 218 : if (auto it = fields.find("supplemental_heating_coil_object_type"); it != fields.end()) { // not required field
7676 43 : thisSys.input_specs.supplemental_heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7677 109 : }
7678 218 : if (auto it = fields.find("supplemental_heating_coil_name"); it != fields.end()) { // not required field
7679 43 : thisSys.input_specs.supplemental_heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7680 109 : }
7681 218 : if (auto it = fields.find("cooling_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7682 61 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER(it.value().get<std::string>());
7683 109 : }
7684 218 : if (auto it = fields.find("cooling_supply_air_flow_rate"); it != fields.end()) { // not required field, autosizable
7685 94 : thisSys.input_specs.cooling_supply_air_flow_rate =
7686 249 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7687 249 : ? DataSizing::AutoSize
7688 33 : : it.value().get<Real64>();
7689 109 : }
7690 218 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7691 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7692 109 : }
7693 218 : if (auto it = fields.find("cooling_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7694 2 : thisSys.input_specs.cooling_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7695 109 : }
7696 218 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7697 9 : thisSys.input_specs.cooling_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7698 109 : }
7699 218 : if (auto it = fields.find("heating_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7700 93 : thisSys.input_specs.heating_supply_air_flow_rate_method = it.value().get<std::string>();
7701 109 : }
7702 218 : if (auto it = fields.find("heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7703 97 : thisSys.input_specs.heating_supply_air_flow_rate =
7704 258 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7705 258 : ? DataSizing::AutoSize
7706 33 : : it.value().get<Real64>();
7707 109 : }
7708 218 : if (auto it = fields.find("heating_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7709 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7710 109 : }
7711 218 : if (auto it = fields.find("heating_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7712 2 : thisSys.input_specs.heating_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7713 109 : }
7714 218 : if (auto it = fields.find("heating_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7715 6 : thisSys.input_specs.heating_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7716 109 : }
7717 218 : if (auto it = fields.find("no_load_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7718 61 : thisSys.input_specs.no_load_supply_air_flow_rate_method = it.value().get<std::string>();
7719 109 : }
7720 218 : if (auto it = fields.find("no_load_supply_air_flow_rate"); it != fields.end()) { // not required field
7721 92 : thisSys.input_specs.no_load_supply_air_flow_rate =
7722 239 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7723 239 : ? DataSizing::AutoSize
7724 37 : : it.value().get<Real64>();
7725 109 : }
7726 218 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7727 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7728 109 : }
7729 218 : if (auto it = fields.find("no_load_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7730 2 : thisSys.input_specs.no_load_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7731 109 : }
7732 218 : if (auto it = fields.find("no_load_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7733 0 : thisSys.input_specs.no_load_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7734 109 : }
7735 109 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation");
7736 109 : it != fields.end()) { // not required field
7737 4 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation = it.value().get<Real64>();
7738 109 : }
7739 109 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation");
7740 109 : it != fields.end()) { // not required field
7741 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation = it.value().get<Real64>();
7742 109 : }
7743 327 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed = state.dataInputProcessing->inputProcessor->getAlphaFieldValue(
7744 109 : fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7745 327 : if (fields.find("maximum_supply_air_temperature") != fields.end()) { // not required field, has default of 80 C
7746 106 : auto const &obj = fields.at("maximum_supply_air_temperature");
7747 106 : thisSys.input_specs.maximum_supply_air_temperature =
7748 117 : (obj.type() == nlohmann::detail::value_t::string && Util::SameString(obj.get<std::string>(), "Autosize"))
7749 117 : ? DataSizing::AutoSize
7750 95 : : obj.get<Real64>();
7751 : }
7752 109 : if (auto it = fields.find("maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7753 109 : it != fields.end()) { // not required field, has default
7754 31 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = it.value().get<Real64>();
7755 109 : }
7756 218 : if (auto it = fields.find("outdoor_dry_bulb_temperature_sensor_node_name"); it != fields.end()) { // not required field
7757 2 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name = Util::makeUPPER(it.value().get<std::string>());
7758 109 : }
7759 218 : if (auto it = fields.find("ancillary_on_cycle_electric_power"); it != fields.end()) { // not required field, has default
7760 8 : thisSys.input_specs.ancillary_on_cycle_electric_power = it.value().get<Real64>();
7761 109 : }
7762 218 : if (auto it = fields.find("ancillary_off_cycle_electric_power"); it != fields.end()) { // not required field, has default
7763 8 : thisSys.input_specs.ancillary_off_cycle_electric_power = it.value().get<Real64>();
7764 109 : }
7765 218 : if (auto it = fields.find("design_heat_recovery_water_flow_rate"); it != fields.end()) { // not required field, has default
7766 9 : thisSys.input_specs.design_heat_recovery_water_flow_rate = it.value().get<Real64>();
7767 109 : }
7768 218 : if (auto it = fields.find("maximum_temperature_for_heat_recovery"); it != fields.end()) { // not required field, has default
7769 13 : thisSys.input_specs.maximum_temperature_for_heat_recovery = it.value().get<Real64>();
7770 109 : }
7771 218 : if (auto it = fields.find("heat_recovery_water_inlet_node_name"); it != fields.end()) { // not required field
7772 9 : thisSys.input_specs.heat_recovery_water_inlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7773 109 : }
7774 218 : if (auto it = fields.find("heat_recovery_water_outlet_node_name"); it != fields.end()) { // not required field
7775 9 : thisSys.input_specs.heat_recovery_water_outlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7776 109 : }
7777 218 : if (auto it = fields.find("design_specification_multispeed_object_type"); it != fields.end()) { // not required field
7778 45 : thisSys.input_specs.design_specification_multispeed_object_type = Util::makeUPPER(it.value().get<std::string>());
7779 109 : }
7780 218 : if (auto it = fields.find("design_specification_multispeed_object_name"); it != fields.end()) { // not required field
7781 45 : thisSys.input_specs.design_specification_multispeed_object_name = Util::makeUPPER(it.value().get<std::string>());
7782 109 : }
7783 :
7784 109 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7785 :
7786 109 : if (sysNum == -1) {
7787 53 : ++thisSys.m_UnitarySysNum;
7788 53 : if (ZoneEquipment) {
7789 : // zone equipment require a 1-n index for access to zone availability managers
7790 49 : ++zoneUnitaryNum;
7791 49 : thisSys.m_EquipCompNum = zoneUnitaryNum;
7792 : } else {
7793 : // zone equipment require a 1-n index for access to zone availability managers
7794 : // although not zone equipment, use same methodology
7795 : // keep OA system unitary equipment indexes separate?
7796 4 : ++airloopUnitaryNum;
7797 4 : thisSys.m_EquipCompNum = airloopUnitaryNum;
7798 : }
7799 53 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7800 53 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7801 : } else {
7802 56 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7803 : }
7804 222 : }
7805 : }
7806 186 : }
7807 :
7808 26 : void UnitarySys::calcUnitarySuppSystemToSP(EnergyPlusData &state, bool const FirstHVACIteration // True when first HVAC iteration
7809 : )
7810 : {
7811 :
7812 : // SUBROUTINE INFORMATION:
7813 : // AUTHOR Richard Raustad, FSEC
7814 : // DATE WRITTEN February 2013
7815 :
7816 : // PURPOSE OF THIS SUBROUTINE:
7817 : // This subroutine manages supplemental heater component simulation for setpoint based operation scheme.
7818 :
7819 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7820 : Real64 QActual;
7821 :
7822 26 : std::string CompName = this->m_SuppHeatCoilName;
7823 26 : int CoilType_Num = this->m_SuppHeatCoilType_Num;
7824 :
7825 26 : if ((CoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel) || (CoilType_Num == HVAC::Coil_HeatingElectric)) {
7826 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
7827 : CompName,
7828 : FirstHVACIteration,
7829 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7830 0 : this->m_SuppHeatCoilIndex,
7831 : _,
7832 0 : true,
7833 0 : this->m_FanOpMode,
7834 0 : this->m_SuppHeatPartLoadFrac);
7835 :
7836 26 : } else if (CoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
7837 44 : HeatingCoils::SimulateHeatingCoilComponents(state,
7838 : CompName,
7839 : FirstHVACIteration,
7840 : _,
7841 22 : this->m_SuppHeatCoilIndex,
7842 : _,
7843 : _,
7844 22 : this->m_FanOpMode,
7845 22 : this->m_SuppHeatPartLoadFrac,
7846 22 : this->m_SuppHeatingSpeedNum,
7847 22 : this->m_SuppHeatingSpeedRatio);
7848 :
7849 4 : } else if (CoilType_Num == HVAC::Coil_HeatingDesuperheater) {
7850 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
7851 : CompName,
7852 : FirstHVACIteration,
7853 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7854 0 : this->m_SuppHeatCoilIndex,
7855 : _,
7856 : _,
7857 0 : this->m_FanOpMode,
7858 0 : this->m_SuppHeatPartLoadFrac);
7859 :
7860 4 : } else if (CoilType_Num == HVAC::Coil_HeatingWater) {
7861 8 : WaterCoils::SimulateWaterCoilComponents(
7862 8 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, QActual, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
7863 :
7864 0 : } else if (CoilType_Num == HVAC::Coil_HeatingSteam) {
7865 0 : SteamCoils::SimulateSteamCoilComponents(state,
7866 : CompName,
7867 : FirstHVACIteration,
7868 0 : this->m_SuppHeatCoilIndex,
7869 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7870 : _,
7871 0 : this->m_FanOpMode,
7872 0 : this->m_SuppHeatPartLoadFrac);
7873 : }
7874 26 : }
7875 :
7876 7036 : void UnitarySys::controlUnitarySystemtoLoad(EnergyPlusData &state,
7877 : int const AirLoopNum, // Primary air loop number
7878 : bool const FirstHVACIteration, // True when first HVAC iteration
7879 : HVAC::CompressorOp &CompressorOn, // Determines if compressor is on or off
7880 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7881 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7882 : Real64 &sysOutputProvided, // system sensible output at supply air node
7883 : Real64 &latOutputProvided // system latent output at supply air node
7884 : )
7885 : {
7886 :
7887 : // SUBROUTINE INFORMATION:
7888 : // AUTHOR Richard Raustad, FSEC
7889 : // DATE WRITTEN February 2013
7890 7036 : Real64 ZoneLoad = 0.0; // zone load (W)
7891 7036 : Real64 SupHeaterLoad = 0.0; // additional heating required by supplemental heater (W)
7892 7036 : Real64 OnOffAirFlowRatio = 1.0;
7893 7036 : this->updateUnitarySystemControl(state,
7894 : AirLoopNum,
7895 : this->CoolCoilOutletNodeNum,
7896 : this->CoolCtrlNode,
7897 : OnOffAirFlowRatio,
7898 : FirstHVACIteration,
7899 : OAUCoilOutTemp,
7900 : ZoneLoad,
7901 : this->DesignMaxOutletTemp);
7902 :
7903 : // will not be running supplemental heater on this CALL (simulate with supplemental heater off)
7904 7036 : Real64 FullSensibleOutput = 0.0;
7905 : // using furnace module logic
7906 : // first check to see if cycling fan with economizer can meet the load
7907 7036 : if (AirLoopNum > 0) {
7908 8 : if (this->m_CoolCoilExists && this->m_HeatCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingAirToAirVariableSpeed &&
7909 8 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed && !FirstHVACIteration &&
7910 18 : this->m_FanOpMode == HVAC::FanOp::Cycling && state.dataUnitarySystems->CoolingLoad &&
7911 2 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
7912 0 : CompressorOn = HVAC::CompressorOp::Off;
7913 0 : this->controlUnitarySystemOutput(
7914 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7915 0 : if (this->m_CoolingPartLoadFrac >= 1.0 || this->m_HeatingPartLoadFrac >= 1.0 ||
7916 0 : (this->m_CoolingPartLoadFrac <= 0.0 && this->m_HeatingPartLoadFrac <= 0.0)) {
7917 0 : CompressorOn = HVAC::CompressorOp::On;
7918 0 : this->controlUnitarySystemOutput(
7919 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7920 : }
7921 : } else {
7922 8 : CompressorOn = HVAC::CompressorOp::On;
7923 8 : this->controlUnitarySystemOutput(
7924 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7925 : }
7926 : } else {
7927 7028 : CompressorOn = HVAC::CompressorOp::On;
7928 7028 : this->controlUnitarySystemOutput(
7929 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7930 : }
7931 9764 : if (state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate < HVAC::SmallMassFlow && this->m_sysType != SysType::PackagedAC &&
7932 9764 : this->m_sysType != SysType::PackagedHP && this->m_sysType != SysType::PackagedWSHP) {
7933 5 : state.dataUnitarySystems->CoolingLoad = false;
7934 5 : state.dataUnitarySystems->HeatingLoad = false;
7935 5 : state.dataUnitarySystems->MoistureLoad = 0.0;
7936 5 : this->m_CoolingPartLoadFrac = 0.0;
7937 5 : this->m_HeatingPartLoadFrac = 0.0;
7938 5 : if (this->CoolCoilFluidInletNode > 0) {
7939 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
7940 : }
7941 5 : if (this->HeatCoilFluidInletNode > 0) {
7942 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = 0.0;
7943 : }
7944 5 : this->setAverageAirFlow(state, this->m_CoolingPartLoadFrac, OnOffAirFlowRatio);
7945 : // anything else need to be reset here when system is shut down on low flow?
7946 : }
7947 7036 : Real64 CoolPLR = this->m_CoolingPartLoadFrac;
7948 7036 : Real64 HeatPLR = this->m_HeatingPartLoadFrac;
7949 7036 : Real64 HeatCoilLoad = HeatPLR * this->m_DesignHeatingCapacity;
7950 :
7951 7036 : if (this->CoolCoilFluidInletNode > 0) {
7952 22 : PlantUtilities::SetComponentFlowRate(state,
7953 11 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate,
7954 : this->CoolCoilFluidInletNode,
7955 : this->CoolCoilFluidOutletNodeNum,
7956 11 : this->CoolCoilPlantLoc);
7957 : }
7958 7036 : if (this->HeatCoilFluidInletNode > 0) {
7959 22 : PlantUtilities::SetComponentFlowRate(state,
7960 11 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate,
7961 : this->HeatCoilFluidInletNode,
7962 : this->HeatCoilFluidOutletNodeNum,
7963 11 : this->HeatCoilPlantLoc);
7964 : }
7965 :
7966 14020 : if (this->m_SuppCoilExists &&
7967 6984 : (state.dataUnitarySystems->HeatingLoad || state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < 0.0)) {
7968 4241 : if ((FullSensibleOutput < (state.dataUnitarySystems->QToHeatSetPt - HVAC::SmallLoad)) && !FirstHVACIteration) {
7969 21 : SupHeaterLoad = max(0.0, state.dataUnitarySystems->QToHeatSetPt - FullSensibleOutput);
7970 21 : this->m_SupHeaterLoad = 0.0;
7971 : // what does this line even do? I know we want the supplemental heater on only if there is a dehum load,
7972 : // but for HP's the supp heater should also run if the heating coil can't turn on
7973 : // (i.e., this line calc's a supp heater load, then next line also calc's it?)
7974 21 : if (state.dataUnitarySystems->MoistureLoad < 0.0) {
7975 2 : this->m_SupHeaterLoad = SupHeaterLoad;
7976 : }
7977 : // so it look's like this next line should only be valid for HP's.
7978 21 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7979 21 : this->m_SuppHeatPartLoadFrac = min(1.0, SupHeaterLoad / this->m_DesignSuppHeatingCapacity);
7980 : }
7981 : } else {
7982 4220 : SupHeaterLoad = 0.0;
7983 4220 : this->m_SuppHeatPartLoadFrac = 0.0;
7984 : }
7985 : } else {
7986 2795 : SupHeaterLoad = 0.0;
7987 2795 : this->m_SuppHeatPartLoadFrac = 0.0;
7988 : }
7989 :
7990 7036 : this->calcUnitarySystemToLoad(state,
7991 : AirLoopNum,
7992 : FirstHVACIteration,
7993 : CoolPLR,
7994 : HeatPLR,
7995 : OnOffAirFlowRatio,
7996 : sysOutputProvided,
7997 : latOutputProvided,
7998 : HXUnitOn,
7999 : HeatCoilLoad,
8000 : SupHeaterLoad,
8001 : CompressorOn);
8002 : // Why need this second run?
8003 : // check supplemental heating coil outlet temp based on maximum allowed
8004 7036 : if (this->m_SuppCoilExists) {
8005 : // only need to test for high supply air temp if supplemental coil is operating
8006 6984 : if (this->m_SuppHeatPartLoadFrac > 0.0) {
8007 20 : this->calcUnitarySystemToLoad(state,
8008 : AirLoopNum,
8009 : FirstHVACIteration,
8010 : CoolPLR,
8011 : HeatPLR,
8012 : OnOffAirFlowRatio,
8013 : sysOutputProvided,
8014 : latOutputProvided,
8015 : HXUnitOn,
8016 : HeatCoilLoad,
8017 : SupHeaterLoad,
8018 : CompressorOn);
8019 20 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
8020 : // multistage coil part load fraction already set in the calcUnitarySystemToLoad
8021 20 : if (this->m_NumOfSpeedSuppHeating <= 1) {
8022 16 : this->m_SuppHeatPartLoadFrac = SupHeaterLoad / this->m_DesignSuppHeatingCapacity;
8023 : }
8024 : } else {
8025 0 : this->m_SuppHeatPartLoadFrac = 0.0;
8026 : }
8027 : }
8028 : }
8029 :
8030 7036 : if (this->m_SuppCoilFluidInletNode > 0) {
8031 0 : PlantUtilities::SetComponentFlowRate(state,
8032 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate,
8033 : this->m_SuppCoilFluidInletNode,
8034 : this->m_SuppCoilFluidOutletNodeNum,
8035 0 : this->m_SuppCoilPlantLoc);
8036 : }
8037 :
8038 7036 : if (this->m_HeatRecActive) {
8039 2 : PlantUtilities::SetComponentFlowRate(state,
8040 1 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate,
8041 : this->m_HeatRecoveryInletNodeNum,
8042 : this->m_HeatRecoveryOutletNodeNum,
8043 1 : this->m_HRPlantLoc);
8044 : }
8045 7036 : }
8046 :
8047 65316 : void UnitarySys::controlUnitarySystemtoSP(EnergyPlusData &state,
8048 : int const AirLoopNum, // Primary air loop number
8049 : bool const FirstHVACIteration, // True when first HVAC iteration
8050 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
8051 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
8052 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8053 : Real64 &sysOutputProvided, // sensible output at supply air node
8054 : Real64 &latOutputProvided // latent output at supply air node
8055 : )
8056 : {
8057 :
8058 : // SUBROUTINE INFORMATION:
8059 : // AUTHOR Richard Raustad, FSEC
8060 : // DATE WRITTEN February 2013
8061 :
8062 : // PURPOSE OF THIS SUBROUTINE:
8063 : // This subroutine manages component simulation.
8064 :
8065 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8066 65316 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
8067 65316 : Real64 OnOffAirFlowRatio = 1.0; // Setpoint based coil control does not use this variable
8068 65316 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
8069 65316 : Real64 ZoneLoad = 0.0;
8070 65316 : Real64 HeatCoilLoad = -999.0;
8071 :
8072 : // CALL the series of components that simulate a Unitary System
8073 65316 : if (this->ATMixerExists) {
8074 : // There is an air terminal mixer
8075 0 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
8076 : // set the primary air inlet mass flow rate
8077 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
8078 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
8079 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
8080 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
8081 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
8082 : }
8083 : }
8084 65316 : if (this->OAMixerExists) {
8085 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
8086 0 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
8087 : }
8088 65316 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
8089 39 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
8090 : }
8091 :
8092 65316 : if (this->m_CoolingCoilUpstream) {
8093 :
8094 65292 : if (this->m_CoolCoilExists) {
8095 65292 : this->updateUnitarySystemControl(state,
8096 : AirLoopNum,
8097 : this->CoolCoilOutletNodeNum,
8098 : this->CoolCtrlNode,
8099 : OnOffAirFlowRatio,
8100 : FirstHVACIteration,
8101 : OAUCoilOutTemp,
8102 : ZoneLoad,
8103 : this->DesignMaxOutletTemp);
8104 65292 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
8105 65292 : PartLoadRatio = this->m_CoolingPartLoadFrac;
8106 65292 : CompressorOn = HVAC::CompressorOp::Off;
8107 65292 : if (PartLoadRatio > 0.0) {
8108 24767 : CompressorOn = HVAC::CompressorOp::On;
8109 24767 : this->m_LastMode = CoolingMode;
8110 : }
8111 65292 : this->calcUnitaryCoolingSystem(
8112 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
8113 : }
8114 65292 : if (this->m_HeatCoilExists) {
8115 7 : this->updateUnitarySystemControl(state,
8116 : AirLoopNum,
8117 : this->HeatCoilOutletNodeNum,
8118 : this->HeatCtrlNode,
8119 : OnOffAirFlowRatio,
8120 : FirstHVACIteration,
8121 : OAUCoilOutTemp,
8122 : ZoneLoad,
8123 : this->DesignMaxOutletTemp);
8124 7 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
8125 7 : PartLoadRatio = this->m_HeatingPartLoadFrac;
8126 7 : HVAC::CompressorOp CompressOn = HVAC::CompressorOp::Off;
8127 7 : if (PartLoadRatio > 0.0) {
8128 3 : CompressOn = HVAC::CompressorOp::On;
8129 3 : this->m_LastMode = HeatingMode;
8130 : }
8131 7 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressOn, OnOffAirFlowRatio, HeatCoilLoad);
8132 : }
8133 :
8134 : } else {
8135 :
8136 24 : if (this->m_HeatCoilExists) {
8137 24 : this->updateUnitarySystemControl(state,
8138 : AirLoopNum,
8139 : this->HeatCoilOutletNodeNum,
8140 : this->HeatCtrlNode,
8141 : OnOffAirFlowRatio,
8142 : FirstHVACIteration,
8143 : OAUCoilOutTemp,
8144 : ZoneLoad,
8145 : this->DesignMaxOutletTemp);
8146 24 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
8147 24 : PartLoadRatio = this->m_HeatingPartLoadFrac;
8148 24 : CompressorOn = HVAC::CompressorOp::Off;
8149 24 : if (PartLoadRatio > 0.0) {
8150 15 : CompressorOn = HVAC::CompressorOp::On;
8151 15 : this->m_LastMode = HeatingMode;
8152 : }
8153 24 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
8154 : }
8155 24 : if (this->m_CoolCoilExists) {
8156 0 : this->updateUnitarySystemControl(state,
8157 : AirLoopNum,
8158 : this->CoolCoilOutletNodeNum,
8159 : this->CoolCtrlNode,
8160 : OnOffAirFlowRatio,
8161 : FirstHVACIteration,
8162 : OAUCoilOutTemp,
8163 : ZoneLoad,
8164 : this->DesignMaxOutletTemp);
8165 0 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
8166 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
8167 0 : CompressorOn = HVAC::CompressorOp::Off;
8168 0 : if (PartLoadRatio > 0.0) {
8169 0 : CompressorOn = HVAC::CompressorOp::On;
8170 0 : this->m_LastMode = CoolingMode;
8171 : }
8172 0 : this->calcUnitaryCoolingSystem(
8173 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
8174 : }
8175 : }
8176 :
8177 65316 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
8178 6 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
8179 : }
8180 :
8181 65316 : if (this->m_SuppCoilExists) {
8182 11 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
8183 11 : this->updateUnitarySystemControl(state,
8184 : AirLoopNum,
8185 : this->SuppCoilOutletNodeNum,
8186 : this->SuppCtrlNode,
8187 : OnOffAirFlowRatio,
8188 : FirstHVACIteration,
8189 : OAUCoilOutTemp,
8190 : ZoneLoad,
8191 : this->DesignMaxOutletTemp);
8192 11 : this->controlSuppHeatSystemToSP(state, AirLoopNum, FirstHVACIteration);
8193 11 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
8194 11 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
8195 : }
8196 :
8197 : // If there is a supply side air terminal mixer, calculate its output
8198 65316 : if (this->ATMixerExists) {
8199 0 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
8200 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
8201 : }
8202 : }
8203 :
8204 65316 : calculateCapacity(state, sysOutputProvided, latOutputProvided);
8205 65316 : this->m_InitHeatPump = false;
8206 65316 : }
8207 :
8208 72370 : void UnitarySys::updateUnitarySystemControl(EnergyPlusData &state,
8209 : int const AirLoopNum, // number of the current air loop being simulated
8210 : int const OutNode, // coil outlet node number
8211 : int const ControlNode, // control node number
8212 : Real64 &OnOffAirFlowRatio,
8213 : bool const FirstHVACIteration,
8214 : Real64 const OAUCoilOutletTemp, // "ONLY" for zoneHVAC:OutdoorAirUnit
8215 : Real64 &ZoneLoad,
8216 : Real64 const MaxOutletTemp // limits heating coil outlet temp [C]
8217 : )
8218 : {
8219 :
8220 : // SUBROUTINE INFORMATION:
8221 : // AUTHOR Richard Raustad, FSEC
8222 : // DATE WRITTEN February 2013
8223 :
8224 : // PURPOSE OF THIS SUBROUTINE:
8225 : // This subroutine is for sizing unitary systems.
8226 :
8227 : // METHODOLOGY EMPLOYED:
8228 : // Either CALL the coil model to get the size or size coil.
8229 : // Current method is to use same methodology as is used in coil objects.
8230 : // Future changes will include a common sizing algorithm and push the calculated
8231 : // size to the coil object prior to first call (so the coil will not DataSizing::AutoSize).
8232 :
8233 : // These initializations are done every iteration
8234 :
8235 : {
8236 72370 : state.dataUnitarySystems->MoistureLoad = 0.0;
8237 72370 : this->LoadSHR = 0.0;
8238 72370 : this->CoilSHR = 0.0;
8239 72370 : switch (this->m_ControlType) {
8240 7036 : case UnitarySysCtrlType::Load:
8241 : case UnitarySysCtrlType::CCMASHRAE: {
8242 7036 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAirUnit
8243 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
8244 0 : ShowFatalError(state, "...Load based control is not allowed when used with ZoneHVAC:OutdoorAirUnit");
8245 : }
8246 :
8247 : // here we need to deal with sequenced zone equip
8248 7036 : state.dataUnitarySystems->HeatingLoad = false;
8249 7036 : state.dataUnitarySystems->CoolingLoad = false;
8250 7036 : if (this->m_ZoneSequenceCoolingNum > 0 && this->m_ZoneSequenceHeatingNum > 0 && this->m_AirLoopEquipment) {
8251 : // air loop equipment uses sequenced variables
8252 4 : state.dataUnitarySystems->QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8253 4 : .SequencedOutputRequiredToCoolingSP(this->m_ZoneSequenceCoolingNum);
8254 4 : state.dataUnitarySystems->QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8255 4 : .SequencedOutputRequiredToHeatingSP(this->m_ZoneSequenceHeatingNum);
8256 7 : if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8257 3 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8258 3 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8259 3 : state.dataUnitarySystems->HeatingLoad = true;
8260 1 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8261 0 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleCool) {
8262 0 : ZoneLoad = 0.0;
8263 2 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8264 1 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8265 1 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8266 1 : state.dataUnitarySystems->CoolingLoad = true;
8267 0 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8268 0 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleHeat) {
8269 0 : ZoneLoad = 0.0;
8270 0 : } else if (state.dataUnitarySystems->QToHeatSetPt <= 0.0 && state.dataUnitarySystems->QToCoolSetPt >= 0.0) {
8271 0 : ZoneLoad = 0.0;
8272 : }
8273 8 : state.dataUnitarySystems->MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum)
8274 4 : .SequencedOutputRequiredToDehumidSP(this->m_ZoneSequenceCoolingNum);
8275 : } else {
8276 : // zone equipment uses Remaining* variables
8277 7032 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired;
8278 14064 : state.dataUnitarySystems->QToCoolSetPt =
8279 7032 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToCoolSP;
8280 14064 : state.dataUnitarySystems->QToHeatSetPt =
8281 7032 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToHeatSP;
8282 14064 : state.dataUnitarySystems->MoistureLoad =
8283 7032 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum).RemainingOutputReqToDehumidSP;
8284 7032 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
8285 7001 : this->m_sysType == SysType::PackagedWSHP) {
8286 : // ZoneSysAvailManager is turning on sooner than PTUnit in UnitarySystem. Mimic PTUnit logic.
8287 8486 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8288 1507 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8289 1507 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8290 8198 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 &&
8291 2726 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8292 2726 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8293 : } else {
8294 2746 : ZoneLoad = 0.0;
8295 : }
8296 : }
8297 : }
8298 :
8299 8572 : if (ZoneLoad < 0.0 && state.dataUnitarySystems->MoistureLoad <= 0.0 &&
8300 1536 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8301 9 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag)) {
8302 3 : this->LoadSHR =
8303 3 : ZoneLoad / (ZoneLoad + state.dataUnitarySystems->MoistureLoad *
8304 6 : Psychrometrics::PsyHgAirFnWTdb(
8305 3 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).airHumRat,
8306 3 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).MAT));
8307 3 : if (this->LoadSHR < 0.0) {
8308 0 : this->LoadSHR = 0.0;
8309 : }
8310 3 : this->CoilSHR = this->LoadSHR;
8311 : }
8312 :
8313 7036 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8314 8 : Real64 H2OHtOfVap = Psychrometrics::PsyHfgAirFnWTdb(state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
8315 8 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp);
8316 :
8317 : // positive MoistureLoad means no dehumidification load
8318 8 : state.dataUnitarySystems->MoistureLoad = min(0.0, state.dataUnitarySystems->MoistureLoad * H2OHtOfVap);
8319 : } else {
8320 7028 : state.dataUnitarySystems->MoistureLoad = 0.0;
8321 : }
8322 :
8323 7036 : this->initLoadBasedControl(state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad);
8324 :
8325 : // *** the location of this EMS override looks suspect. If EMS is active the load will be changed but the CoolingLoad and HeatingLoad
8326 : // flags are not updated. suggest this be moved up above InitLoadBasedControl function on previous line so the EMS loads are used in
8327 : // that routine EMS override point
8328 7036 : if (this->m_EMSOverrideSensZoneLoadRequest) {
8329 0 : ZoneLoad = this->m_EMSSensibleZoneLoadValue;
8330 : }
8331 7036 : if (this->m_EMSOverrideMoistZoneLoadRequest) {
8332 0 : state.dataUnitarySystems->MoistureLoad = this->m_EMSMoistureZoneLoadValue;
8333 : }
8334 :
8335 7036 : this->m_SimASHRAEModel = false; // flag used to invoke ASHRAE 90.1 model calculations
8336 : // allows non-ASHSRAE compliant coil types to be modeled using non-ASHAR90 method. Constant fan operating mode is required.
8337 7036 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
8338 35 : if (state.dataUnitarySystems->CoolingLoad) {
8339 13 : if (this->m_ValidASHRAECoolCoil) {
8340 5 : this->m_SimASHRAEModel = true;
8341 : }
8342 22 : } else if (state.dataUnitarySystems->HeatingLoad) {
8343 16 : if (this->m_ValidASHRAEHeatCoil) {
8344 12 : this->m_SimASHRAEModel = true;
8345 : }
8346 : }
8347 : }
8348 7036 : } break;
8349 65334 : case UnitarySysCtrlType::Setpoint: {
8350 65334 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAIRUNIT
8351 :
8352 4 : if (ControlNode == 0) {
8353 0 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8354 4 : } else if (ControlNode == OutNode) {
8355 4 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8356 : }
8357 : // If the unitary system is an Outdoor Air Unit, the desired coil outlet humidity level is set to 1.0 (no dehum)
8358 4 : this->m_DesiredOutletHumRat = 1.0;
8359 :
8360 : } else { // Not Outdoor Air Unit. Either airloop or zone equipment
8361 65330 : Real64 humRatMaxSP = 1.0;
8362 65330 : this->m_DesiredOutletHumRat = humRatMaxSP;
8363 65330 : if (ControlNode == 0) {
8364 0 : this->m_DesiredOutletTemp = 0.0;
8365 0 : if (OutNode > 0) {
8366 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8367 0 : this->m_DesiredOutletHumRat = state.dataLoopNodes->Node(OutNode).HumRatMax;
8368 : }
8369 : }
8370 65330 : } else if (ControlNode == OutNode) {
8371 65323 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8372 0 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8373 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8374 : }
8375 0 : this->frostControlSetPointLimit(state,
8376 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8377 : humRatMaxSP,
8378 0 : state.dataEnvrn->OutBaroPress,
8379 : this->DesignMinOutletTemp,
8380 : 1);
8381 : }
8382 65323 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
8383 : // IF HumRatMax is zero, then there is no request from SetpointManager:SingleZone:Humidity:Maximum
8384 : // user might place temp SP at system outlet and HumRat set point at coil outlet
8385 65323 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8386 9 : if (state.dataLoopNodes->Node(this->AirOutNode).HumRatMax > 0.0) {
8387 4 : humRatMaxSP = state.dataLoopNodes->Node(this->AirOutNode).HumRatMax;
8388 : }
8389 9 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8390 5 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8391 : }
8392 9 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8393 0 : this->frostControlSetPointLimit(state,
8394 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8395 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8396 0 : state.dataEnvrn->OutBaroPress,
8397 : this->DesignMinOutletTemp,
8398 : 2);
8399 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8400 : }
8401 9 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8402 : }
8403 : } else {
8404 7 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) {
8405 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8406 : }
8407 7 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8408 0 : humRatMaxSP = state.dataLoopNodes->Node(OutNode).HumRatMax;
8409 : }
8410 7 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8411 0 : this->frostControlSetPointLimit(state,
8412 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8413 : humRatMaxSP,
8414 0 : state.dataEnvrn->OutBaroPress,
8415 : this->DesignMinOutletTemp,
8416 : 1);
8417 : }
8418 7 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint -
8419 7 : (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(OutNode).Temp);
8420 7 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8421 0 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8422 0 : this->frostControlSetPointLimit(state,
8423 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8424 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8425 0 : state.dataEnvrn->OutBaroPress,
8426 : this->DesignMinOutletTemp,
8427 : 2);
8428 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8429 : }
8430 0 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8431 : }
8432 : }
8433 : }
8434 65334 : this->m_DesiredOutletTemp = min(this->m_DesiredOutletTemp, MaxOutletTemp);
8435 65334 : } break;
8436 0 : default: {
8437 : // should never get here, only 3 control types
8438 0 : } break;
8439 : }
8440 : }
8441 72370 : }
8442 2 : void UnitarySys::controlUnitarySystemOutputEMS(EnergyPlusData &state,
8443 : int const AirLoopNum, // Index to air loop
8444 : bool const FirstHVACIteration, // True when first HVAC iteration
8445 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8446 : Real64 const ZoneLoad,
8447 : Real64 &FullSensibleOutput,
8448 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8449 : HVAC::CompressorOp CompressorOn)
8450 : {
8451 2 : Real64 PartLoadRatio = 1.0;
8452 2 : Real64 CoolPLR = 0.0;
8453 2 : Real64 HeatPLR = 0.0;
8454 2 : HVAC::CompressorOp CompressorONFlag = CompressorOn;
8455 2 : Real64 HeatCoilLoad = 0.0;
8456 2 : Real64 SupHeaterLoad = 0.0;
8457 : Real64 SensOutput; // sensible output
8458 : Real64 LatOutput; // latent output
8459 2 : this->FanPartLoadRatio = 0.0;
8460 2 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8461 :
8462 2 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) {
8463 0 : return;
8464 : }
8465 2 : int SpeedNumEMS = ceil(this->m_EMSOverrideCoilSpeedNumValue);
8466 2 : bool useMaxedSpeed = false;
8467 2 : std::string useMaxedSpeedCoilName;
8468 2 : if (state.dataUnitarySystems->HeatingLoad) {
8469 0 : if (SpeedNumEMS > this->m_NumOfSpeedHeating) {
8470 0 : SpeedNumEMS = this->m_NumOfSpeedHeating;
8471 0 : useMaxedSpeed = true;
8472 0 : useMaxedSpeedCoilName = this->m_HeatingCoilName;
8473 : }
8474 0 : this->m_HeatingSpeedNum = SpeedNumEMS;
8475 : } else {
8476 2 : if (SpeedNumEMS > this->m_NumOfSpeedCooling) {
8477 0 : SpeedNumEMS = this->m_NumOfSpeedCooling;
8478 0 : useMaxedSpeed = true;
8479 0 : useMaxedSpeedCoilName = this->m_CoolingCoilName;
8480 : }
8481 2 : this->m_CoolingSpeedNum = SpeedNumEMS;
8482 : }
8483 2 : if (useMaxedSpeed) {
8484 0 : this->m_CoilSpeedErrIdx++;
8485 0 : ShowRecurringWarningErrorAtEnd(state,
8486 0 : "Wrong coil speed EMS override value, for unit=\"" + useMaxedSpeedCoilName +
8487 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
8488 0 : this->m_CoilSpeedErrIdx,
8489 0 : this->m_EMSOverrideCoilSpeedNumValue,
8490 0 : this->m_EMSOverrideCoilSpeedNumValue,
8491 : _,
8492 : "",
8493 : "");
8494 : }
8495 :
8496 2 : if (state.dataUnitarySystems->HeatingLoad) {
8497 0 : CoolPLR = 0.0;
8498 0 : HeatPLR = 1.0;
8499 0 : this->m_HeatingCoilSensDemand = ZoneLoad;
8500 :
8501 0 : if (this->m_HeatingSpeedNum == 1) {
8502 0 : this->m_HeatingSpeedRatio = 0.0;
8503 0 : this->m_HeatingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8504 0 : if (useMaxedSpeed || this->m_HeatingCycRatio == 0) {
8505 0 : this->m_HeatingCycRatio = 1;
8506 : }
8507 : } else {
8508 0 : this->m_HeatingCycRatio = 1.0;
8509 0 : this->m_HeatingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8510 0 : if (useMaxedSpeed || this->m_HeatingSpeedRatio == 0) {
8511 0 : this->m_HeatingSpeedRatio = 1;
8512 : }
8513 : }
8514 : } else { // Cooling or moisture load
8515 2 : HeatPLR = 0.0;
8516 2 : CoolPLR = 1.0;
8517 2 : if (state.dataUnitarySystems->CoolingLoad) {
8518 2 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8519 : } else {
8520 0 : this->m_CoolingCoilSensDemand = 0.0;
8521 : }
8522 2 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8523 :
8524 2 : if (this->m_CoolingSpeedNum == 1) {
8525 0 : this->m_CoolingSpeedRatio = 0.0;
8526 0 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8527 0 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
8528 0 : this->m_CoolingCycRatio = 1;
8529 : }
8530 : } else {
8531 2 : this->m_CoolingCycRatio = 1.0;
8532 2 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8533 2 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
8534 0 : this->m_CoolingSpeedRatio = 1;
8535 : }
8536 : }
8537 : }
8538 2 : this->calcUnitarySystemToLoad(state,
8539 : AirLoopNum,
8540 : FirstHVACIteration,
8541 : CoolPLR,
8542 : HeatPLR,
8543 : OnOffAirFlowRatio,
8544 : SensOutput,
8545 : LatOutput,
8546 2 : HXUnitOn,
8547 : HeatCoilLoad,
8548 : SupHeaterLoad,
8549 : CompressorONFlag);
8550 :
8551 2 : FullSensibleOutput = SensOutput;
8552 :
8553 2 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8554 : // no load
8555 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutput) {
8556 0 : return;
8557 : }
8558 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8559 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
8560 0 : return;
8561 : }
8562 : }
8563 2 : HXUnitOn = true;
8564 2 : this->calcUnitarySystemToLoad(state,
8565 : AirLoopNum,
8566 : FirstHVACIteration,
8567 : CoolPLR,
8568 : HeatPLR,
8569 : OnOffAirFlowRatio,
8570 : SensOutput,
8571 : LatOutput,
8572 2 : HXUnitOn,
8573 : HeatCoilLoad,
8574 : SupHeaterLoad,
8575 : CompressorONFlag);
8576 2 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
8577 : Real64 heatCoildT =
8578 2 : (this->m_HeatCoilExists)
8579 2 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
8580 2 : : 0.0;
8581 : Real64 CoolingOnlySensibleOutput =
8582 2 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
8583 2 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
8584 2 : heatCoildT);
8585 2 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
8586 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
8587 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
8588 2 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
8589 : // Heating mode and dehumidification is required
8590 : } else {
8591 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
8592 : // the heating coil pick up the load due to outdoor air.
8593 0 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
8594 : }
8595 2 : }
8596 :
8597 7036 : void UnitarySys::controlUnitarySystemOutput(EnergyPlusData &state,
8598 : int const AirLoopNum, // Index to air loop
8599 : bool const FirstHVACIteration, // True when first HVAC iteration
8600 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8601 : Real64 const ZoneLoad,
8602 : Real64 &FullSensibleOutput,
8603 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8604 : HVAC::CompressorOp CompressorOn)
8605 : {
8606 :
8607 : // SUBROUTINE INFORMATION:
8608 : // AUTHOR Richard Raustad, FSEC
8609 : // DATE WRITTEN February 2013
8610 :
8611 : // PURPOSE OF THIS SUBROUTINE:
8612 : // This subroutine determines operating PLR and calculates the load based system output.
8613 :
8614 : // SUBROUTINE PARAMETER DEFINITIONS:
8615 7036 : int constexpr MaxIter = 100; // maximum number of iterations
8616 :
8617 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8618 : int SpeedNum; // multi-speed coil speed number
8619 : Real64 SensOutputOn; // sensible output at PLR = 1 [W]
8620 : Real64 LatOutputOn; // latent output at PLR = 1 [W]
8621 : Real64 TempLoad; // represents either a sensible or latent load [W]
8622 : Real64 TempSysOutput; // represents either a sensible or latent capacity [W]
8623 : Real64 TempSensOutput; // iterative sensible capacity [W]
8624 : Real64 TempLatOutput; // iterative latent capacity [W]
8625 : Real64 TempMinPLR; // iterative minimum PLR
8626 : Real64 TempMaxPLR; // iterative maximum PLR
8627 : Real64 CpAir; // specific heat of air [J/kg_C]
8628 : Real64 FullLoadAirOutletTemp; // saved full load outlet air temperature [C]
8629 : Real64 FullLoadAirOutletHumRat; // saved full load outlet air humidity ratio [kg/kg]
8630 :
8631 7036 : std::string CompName = this->Name;
8632 7036 : int OutletNode = this->AirOutNode;
8633 :
8634 7036 : if (this->m_sysAvailSched->getCurrentVal() <= 0.0) {
8635 0 : return;
8636 : }
8637 7036 : if (this->m_EMSOverrideCoilSpeedNumOn) {
8638 2 : this->controlUnitarySystemOutputEMS(
8639 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
8640 2 : return;
8641 : }
8642 :
8643 7034 : Real64 PartLoadRatio = 0.0; // Get no load result
8644 7034 : this->m_EconoPartLoadRatio = 0;
8645 : // fan and coil PLR are disconnected when using ASHRAE model, don't confuse these for other models
8646 7034 : this->FanPartLoadRatio = 0.0;
8647 7034 : int SolFlag = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8648 7034 : int SolFlagLat = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8649 7034 : Real64 SensOutputOff = 0.0;
8650 7034 : Real64 LatOutputOff = 0.0;
8651 7034 : Real64 CoolPLR = 0.0;
8652 7034 : Real64 HeatPLR = 0.0;
8653 7034 : HVAC::CompressorOp CompressorONFlag = HVAC::CompressorOp::Off;
8654 7034 : Real64 HeatCoilLoad = 0.0;
8655 7034 : Real64 SupHeaterLoad = 0.0;
8656 :
8657 7034 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8658 :
8659 7034 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) {
8660 2749 : return;
8661 : }
8662 :
8663 4285 : this->calcUnitarySystemToLoad(state,
8664 : AirLoopNum,
8665 : FirstHVACIteration,
8666 : CoolPLR,
8667 : HeatPLR,
8668 : OnOffAirFlowRatio,
8669 : SensOutputOff,
8670 : LatOutputOff,
8671 4285 : HXUnitOn,
8672 : HeatCoilLoad,
8673 : SupHeaterLoad,
8674 : CompressorONFlag);
8675 4285 : FullSensibleOutput = SensOutputOff;
8676 :
8677 4285 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8678 : // no load
8679 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutputOff) {
8680 0 : return;
8681 : }
8682 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8683 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
8684 0 : return;
8685 : }
8686 : }
8687 :
8688 : // determine if PLR=0 meets the load
8689 4285 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8690 12 : case HVAC::SetptType::SingleHeat: {
8691 12 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8692 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8693 0 : return;
8694 : }
8695 12 : if (!state.dataUnitarySystems->HeatingLoad &&
8696 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8697 0 : return;
8698 : }
8699 12 : } break;
8700 0 : case HVAC::SetptType::SingleCool: {
8701 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8702 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8703 0 : return;
8704 : }
8705 0 : if (!state.dataUnitarySystems->CoolingLoad &&
8706 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8707 0 : return;
8708 : }
8709 0 : } break;
8710 4273 : case HVAC::SetptType::SingleHeatCool:
8711 : case HVAC::SetptType::DualHeatCool: {
8712 4273 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8713 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8714 0 : return;
8715 : }
8716 4275 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8717 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8718 0 : return;
8719 : }
8720 4273 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8721 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8722 0 : return;
8723 : }
8724 4273 : } break;
8725 0 : default: {
8726 : // should never get here
8727 0 : } break;
8728 : }
8729 :
8730 4285 : this->m_EconoSpeedNum = 0;
8731 4285 : if (this->OAControllerEconomizerStagingType == HVAC::EconomizerStagingType::EconomizerFirst) {
8732 0 : manageEconomizerStagingOperation(state, AirLoopNum, FirstHVACIteration, ZoneLoad);
8733 : }
8734 :
8735 : // if a variable speed unit, the SensOutputOff at SpeedNum=1 must be checked to see if it exceeds the ZoneLoad
8736 : // This is still no load but at the first speed above idle
8737 5839 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating > 0) ||
8738 1554 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling > 0)) {
8739 4253 : if (this->m_Staged) {
8740 2 : if (state.dataUnitarySystems->HeatingLoad) {
8741 1 : this->m_HeatingSpeedNum = this->m_StageNum;
8742 : } else {
8743 1 : this->m_CoolingSpeedNum = std::abs(this->m_StageNum);
8744 : }
8745 : } else {
8746 4251 : if (state.dataUnitarySystems->HeatingLoad) {
8747 2730 : this->m_HeatingSpeedNum = 1;
8748 : } else {
8749 1521 : this->m_CoolingSpeedNum = 1;
8750 : }
8751 : }
8752 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8753 4253 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8754 4253 : this->calcUnitarySystemToLoad(state,
8755 : AirLoopNum,
8756 : FirstHVACIteration,
8757 : CoolPLR,
8758 : HeatPLR,
8759 : OnOffAirFlowRatio,
8760 : SensOutputOff,
8761 : LatOutputOff,
8762 4253 : HXUnitOn,
8763 : HeatCoilLoad,
8764 : SupHeaterLoad,
8765 : CompressorONFlag);
8766 4253 : FullSensibleOutput = SensOutputOff;
8767 :
8768 4253 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8769 6 : case HVAC::SetptType::SingleHeat: {
8770 6 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8771 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8772 0 : return;
8773 : }
8774 6 : if (!state.dataUnitarySystems->HeatingLoad &&
8775 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8776 0 : return;
8777 : }
8778 6 : } break;
8779 0 : case HVAC::SetptType::SingleCool: {
8780 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8781 0 : this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
8782 0 : return;
8783 : }
8784 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8785 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8786 0 : return;
8787 : }
8788 0 : if (!state.dataUnitarySystems->CoolingLoad &&
8789 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8790 0 : return;
8791 : }
8792 0 : } break;
8793 4247 : case HVAC::SetptType::SingleHeatCool:
8794 : case HVAC::SetptType::DualHeatCool: {
8795 4247 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8796 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8797 0 : return;
8798 : }
8799 4249 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8800 2 : this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
8801 0 : return;
8802 : }
8803 4249 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8804 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8805 0 : return;
8806 : }
8807 4247 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8808 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff)) {
8809 0 : return;
8810 : }
8811 4247 : } break;
8812 0 : default: {
8813 : // should never get here
8814 0 : } break;
8815 : }
8816 : }
8817 :
8818 4285 : CompressorONFlag = CompressorOn;
8819 4285 : PartLoadRatio = 1.0;
8820 4285 : this->FanPartLoadRatio = 1.0;
8821 : // Get full load result for non-multistage economizer operations
8822 4285 : if (this->m_EconoSpeedNum == 0) {
8823 4285 : if (state.dataUnitarySystems->HeatingLoad) {
8824 2751 : CoolPLR = 0.0;
8825 2751 : HeatPLR = 1.0;
8826 2751 : this->m_HeatingCoilSensDemand = ZoneLoad;
8827 2751 : if (this->m_NumOfSpeedHeating > 0) {
8828 2731 : this->m_HeatingSpeedRatio = 1.0;
8829 2731 : this->m_HeatingCycRatio = 1.0;
8830 2731 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
8831 : }
8832 2751 : if (this->m_Staged && this->m_StageNum > 0) {
8833 1 : if (this->m_NumOfSpeedHeating > 0) {
8834 1 : this->m_HeatingSpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8835 1 : this->m_HeatingSpeedRatio = 0.0;
8836 : }
8837 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8838 1 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8839 1 : this->calcUnitarySystemToLoad(state,
8840 : AirLoopNum,
8841 : FirstHVACIteration,
8842 : CoolPLR,
8843 : HeatPLR,
8844 : OnOffAirFlowRatio,
8845 : SensOutputOff,
8846 : LatOutputOff,
8847 1 : HXUnitOn,
8848 : HeatCoilLoad,
8849 : SupHeaterLoad,
8850 : CompressorONFlag);
8851 1 : if (SensOutputOff > ZoneLoad) {
8852 1 : return;
8853 : }
8854 0 : if (this->m_NumOfSpeedHeating > 0) {
8855 0 : this->m_HeatingSpeedRatio = 1.0;
8856 : }
8857 : }
8858 1534 : } else if (state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < LatOutputOff) {
8859 1534 : CoolPLR = 1.0;
8860 1534 : HeatPLR = 0.0;
8861 1534 : if (state.dataUnitarySystems->CoolingLoad) {
8862 1534 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8863 : } else {
8864 0 : this->m_CoolingCoilSensDemand = 0.0;
8865 : }
8866 1534 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8867 1534 : if (this->m_NumOfSpeedCooling > 0) {
8868 1522 : this->m_CoolingSpeedRatio = 1.0;
8869 1522 : this->m_CoolingCycRatio = 1.0;
8870 1522 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
8871 : }
8872 1534 : if (this->m_Staged && this->m_StageNum < 0) {
8873 0 : if (this->m_NumOfSpeedCooling > 0) {
8874 0 : this->m_CoolingSpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8875 : }
8876 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8877 0 : this->m_CoolingSpeedRatio = 0.0;
8878 0 : this->calcUnitarySystemToLoad(state,
8879 : AirLoopNum,
8880 : FirstHVACIteration,
8881 : CoolPLR,
8882 : HeatPLR,
8883 : OnOffAirFlowRatio,
8884 : SensOutputOff,
8885 : LatOutputOff,
8886 0 : HXUnitOn,
8887 : HeatCoilLoad,
8888 : SupHeaterLoad,
8889 : CompressorONFlag);
8890 0 : if (SensOutputOff < ZoneLoad) {
8891 0 : return;
8892 : }
8893 0 : if (this->m_NumOfSpeedCooling > 0) {
8894 0 : this->m_CoolingSpeedRatio = 1.0;
8895 : }
8896 : }
8897 : } else {
8898 : // will return here when no cooling or heating load and MoistureLoad > LatOutputOff (i.e., PLR=0)
8899 0 : return;
8900 : }
8901 :
8902 4284 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8903 :
8904 4284 : this->calcUnitarySystemToLoad(state,
8905 : AirLoopNum,
8906 : FirstHVACIteration,
8907 : CoolPLR,
8908 : HeatPLR,
8909 : OnOffAirFlowRatio,
8910 : SensOutputOn,
8911 : LatOutputOn,
8912 4284 : HXUnitOn,
8913 : HeatCoilLoad,
8914 : SupHeaterLoad,
8915 : CompressorONFlag);
8916 4284 : FullSensibleOutput = SensOutputOn;
8917 4284 : FullLoadAirOutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
8918 4284 : FullLoadAirOutletHumRat = state.dataLoopNodes->Node(OutletNode).HumRat;
8919 :
8920 : // turn on HX if dehumidm_ControlType::Multimode
8921 2 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < 0.0 &&
8922 4286 : state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
8923 1 : HXUnitOn = true;
8924 1 : this->calcUnitarySystemToLoad(state,
8925 : AirLoopNum,
8926 : FirstHVACIteration,
8927 : CoolPLR,
8928 : HeatPLR,
8929 : OnOffAirFlowRatio,
8930 : SensOutputOn,
8931 : LatOutputOn,
8932 1 : HXUnitOn,
8933 : HeatCoilLoad,
8934 : SupHeaterLoad,
8935 : CompressorONFlag);
8936 1 : FullSensibleOutput = SensOutputOn;
8937 : }
8938 :
8939 : // test to see if full capacity is less than load, if so set to PLR=1 and RETURN if no moisture load
8940 8548 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating <= 1) ||
8941 4264 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling <= 1)) {
8942 57 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8943 6 : case HVAC::SetptType::SingleHeat: {
8944 6 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8945 0 : this->m_HeatingPartLoadFrac = 1.0;
8946 0 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
8947 0 : return;
8948 : }
8949 : }
8950 6 : if (!state.dataUnitarySystems->HeatingLoad &&
8951 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8952 0 : return;
8953 : }
8954 6 : } break;
8955 0 : case HVAC::SetptType::SingleCool: {
8956 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8957 0 : this->m_CoolingPartLoadFrac = 1.0;
8958 0 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
8959 0 : return;
8960 : }
8961 : }
8962 0 : if (!state.dataUnitarySystems->CoolingLoad &&
8963 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8964 0 : return;
8965 : }
8966 0 : } break;
8967 51 : case HVAC::SetptType::SingleHeatCool:
8968 : case HVAC::SetptType::DualHeatCool: {
8969 51 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8970 4 : this->m_HeatingPartLoadFrac = 1.0;
8971 4 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOn) {
8972 4 : return;
8973 : }
8974 : }
8975 47 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8976 6 : this->m_CoolingPartLoadFrac = 1.0;
8977 6 : return;
8978 : }
8979 41 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8980 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8981 0 : return;
8982 : }
8983 41 : } break;
8984 0 : default: {
8985 : // no other choices for thermostat control
8986 0 : } break;
8987 : }
8988 : }
8989 : } else {
8990 : // define the sensible load to meet for operation with multi-stage economizer
8991 0 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8992 : }
8993 : // will find speed for multispeed coils here and then RegulaFalsi on PLR at a fixed speed
8994 :
8995 : // Do the non-variable or non-multispeed coils have a NumOfSpeed = 0 ? We don't need to do this for single speed coils.
8996 : // Check to see which speed to meet the load
8997 4274 : this->m_HeatingSpeedNum = 0;
8998 4274 : this->m_CoolingSpeedNum = 0;
8999 4274 : if (!this->m_Staged) {
9000 4273 : if (state.dataUnitarySystems->HeatingLoad) {
9001 12227 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
9002 12199 : CoolPLR = 0.0;
9003 12199 : HeatPLR = 1.0;
9004 12199 : if (SpeedNum == 1) {
9005 2730 : this->m_HeatingSpeedRatio = 0.0;
9006 : } else {
9007 9469 : this->m_HeatingSpeedRatio = 1.0;
9008 : }
9009 12199 : this->m_HeatingCycRatio = 1.0;
9010 12199 : this->m_HeatingSpeedNum = SpeedNum;
9011 12199 : this->calcUnitarySystemToLoad(state,
9012 : AirLoopNum,
9013 : FirstHVACIteration,
9014 : CoolPLR,
9015 : HeatPLR,
9016 : OnOffAirFlowRatio,
9017 : SensOutputOn,
9018 : LatOutputOn,
9019 12199 : HXUnitOn,
9020 : HeatCoilLoad,
9021 : SupHeaterLoad,
9022 : CompressorONFlag);
9023 12199 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9024 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9025 : }
9026 12199 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
9027 2717 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater && !this->m_MultiSpeedHeatingCoil)) {
9028 0 : this->m_HeatingSpeedRatio = 0.0;
9029 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
9030 0 : if (this->m_HeatingSpeedNum == 0) {
9031 0 : this->m_HeatingCycRatio = 0.0;
9032 0 : HeatPLR = 0.0;
9033 : } else {
9034 0 : this->m_HeatingCycRatio = 1.0;
9035 0 : HeatPLR = 1.0;
9036 : }
9037 0 : this->calcUnitarySystemToLoad(state,
9038 : AirLoopNum,
9039 : FirstHVACIteration,
9040 : CoolPLR,
9041 : HeatPLR,
9042 : OnOffAirFlowRatio,
9043 : SensOutputOff,
9044 : LatOutputOff,
9045 0 : HXUnitOn,
9046 : HeatCoilLoad,
9047 : SupHeaterLoad,
9048 : CompressorONFlag);
9049 0 : this->m_HeatingSpeedNum = SpeedNum;
9050 : }
9051 12199 : if (ZoneLoad <= SensOutputOn) {
9052 2718 : break;
9053 : }
9054 : }
9055 : } else { // Cooling or moisture load
9056 5498 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9057 5488 : CoolPLR = 1.0;
9058 5488 : HeatPLR = 0.0;
9059 5488 : if (SpeedNum == 1) {
9060 1517 : this->m_CoolingSpeedRatio = 0.0;
9061 : } else {
9062 3971 : this->m_CoolingSpeedRatio = 1.0;
9063 : }
9064 5488 : this->m_CoolingCycRatio = 1.0;
9065 5488 : this->m_CoolingSpeedNum = SpeedNum;
9066 5488 : this->calcUnitarySystemToLoad(state,
9067 : AirLoopNum,
9068 : FirstHVACIteration,
9069 : CoolPLR,
9070 : HeatPLR,
9071 : OnOffAirFlowRatio,
9072 : SensOutputOn,
9073 : LatOutputOn,
9074 5488 : HXUnitOn,
9075 : HeatCoilLoad,
9076 : SupHeaterLoad,
9077 : CompressorONFlag);
9078 5491 : if (state.dataGlobal->DoCoilDirectSolutions &&
9079 3 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
9080 3 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1))) {
9081 3 : this->FullOutput[SpeedNum] = SensOutputOn;
9082 : }
9083 : // over specified logic? it has to be a water coil? what about other VS coil models?
9084 5488 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9085 914 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9086 0 : !this->m_DiscreteSpeedCoolingCoil)) {
9087 0 : this->m_CoolingSpeedRatio = 0.0;
9088 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9089 0 : if (this->m_CoolingSpeedNum == 0) {
9090 0 : this->m_CoolingCycRatio = 0.0;
9091 0 : CoolPLR = 0.0;
9092 : } else {
9093 0 : this->m_CoolingCycRatio = 1.0;
9094 0 : this->m_CoolingSpeedRatio = 0.0;
9095 0 : if (this->m_SingleMode == 1) {
9096 0 : CoolPLR = 1.0;
9097 : }
9098 : }
9099 :
9100 0 : this->calcUnitarySystemToLoad(state,
9101 : AirLoopNum,
9102 : FirstHVACIteration,
9103 : CoolPLR,
9104 : HeatPLR,
9105 : OnOffAirFlowRatio,
9106 : SensOutputOff,
9107 : LatOutputOff,
9108 0 : HXUnitOn,
9109 : HeatCoilLoad,
9110 : SupHeaterLoad,
9111 : CompressorONFlag);
9112 0 : this->m_CoolingSpeedNum = SpeedNum;
9113 : }
9114 5488 : if (ZoneLoad >= SensOutputOn) {
9115 1517 : break;
9116 : }
9117 : }
9118 : }
9119 : } else { // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
9120 : // Staged control
9121 1 : if (state.dataUnitarySystems->HeatingLoad) {
9122 0 : CoolPLR = 0.0;
9123 0 : HeatPLR = 1.0;
9124 0 : SpeedNum = this->m_StageNum;
9125 0 : if (SpeedNum == 1) {
9126 0 : this->m_HeatingSpeedRatio = 0.0;
9127 : } else {
9128 0 : this->m_HeatingSpeedRatio = 1.0;
9129 0 : SpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
9130 : }
9131 0 : this->m_HeatingCycRatio = 1.0;
9132 0 : this->m_HeatingSpeedNum = SpeedNum;
9133 0 : this->calcUnitarySystemToLoad(state,
9134 : AirLoopNum,
9135 : FirstHVACIteration,
9136 : CoolPLR,
9137 : HeatPLR,
9138 : OnOffAirFlowRatio,
9139 : SensOutputOn,
9140 : LatOutputOn,
9141 0 : HXUnitOn,
9142 : HeatCoilLoad,
9143 : SupHeaterLoad,
9144 : CompressorONFlag);
9145 0 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
9146 0 : this->m_HeatingSpeedRatio = 0.0;
9147 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
9148 0 : if (this->m_HeatingSpeedNum == 0) {
9149 0 : this->m_HeatingCycRatio = 0.0;
9150 0 : HeatPLR = 0.0;
9151 : } else {
9152 0 : this->m_HeatingCycRatio = 1.0;
9153 0 : HeatPLR = 1.0;
9154 : }
9155 0 : this->calcUnitarySystemToLoad(state,
9156 : AirLoopNum,
9157 : FirstHVACIteration,
9158 : CoolPLR,
9159 : HeatPLR,
9160 : OnOffAirFlowRatio,
9161 : SensOutputOff,
9162 : LatOutputOff,
9163 0 : HXUnitOn,
9164 : HeatCoilLoad,
9165 : SupHeaterLoad,
9166 : CompressorONFlag);
9167 0 : this->m_HeatingSpeedNum = SpeedNum;
9168 : }
9169 0 : if (ZoneLoad <= SensOutputOn) {
9170 : // EXIT ????????????
9171 : }
9172 : } else { // Cooling or moisture load
9173 1 : CoolPLR = 1.0;
9174 1 : HeatPLR = 0.0;
9175 1 : SpeedNum = std::abs(this->m_StageNum);
9176 1 : if (SpeedNum == 1) {
9177 1 : this->m_CoolingSpeedRatio = 0.0;
9178 : } else {
9179 0 : this->m_CoolingSpeedRatio = 1.0;
9180 0 : SpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
9181 : }
9182 1 : this->m_CoolingCycRatio = 1.0;
9183 1 : this->m_CoolingSpeedNum = SpeedNum;
9184 1 : this->calcUnitarySystemToLoad(state,
9185 : AirLoopNum,
9186 : FirstHVACIteration,
9187 : CoolPLR,
9188 : HeatPLR,
9189 : OnOffAirFlowRatio,
9190 : SensOutputOn,
9191 : LatOutputOn,
9192 1 : HXUnitOn,
9193 : HeatCoilLoad,
9194 : SupHeaterLoad,
9195 : CompressorONFlag);
9196 :
9197 1 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
9198 1 : this->m_CoolingSpeedRatio = 0.0;
9199 1 : this->m_CoolingSpeedNum = SpeedNum - 1;
9200 1 : if (this->m_CoolingSpeedNum == 0) {
9201 1 : this->m_CoolingCycRatio = 0.0;
9202 1 : CoolPLR = 0.0;
9203 : } else {
9204 0 : this->m_CoolingCycRatio = 1.0;
9205 0 : CoolPLR = 1.0;
9206 : }
9207 1 : this->calcUnitarySystemToLoad(state,
9208 : AirLoopNum,
9209 : FirstHVACIteration,
9210 : CoolPLR,
9211 : HeatPLR,
9212 : OnOffAirFlowRatio,
9213 : SensOutputOff,
9214 : LatOutputOff,
9215 1 : HXUnitOn,
9216 : HeatCoilLoad,
9217 : SupHeaterLoad,
9218 : CompressorONFlag);
9219 1 : this->m_CoolingSpeedNum = SpeedNum;
9220 : }
9221 1 : if (ZoneLoad >= SensOutputOn) {
9222 : // EXIT ???????????
9223 : }
9224 : }
9225 : } // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
9226 :
9227 4274 : FullSensibleOutput = SensOutputOn;
9228 :
9229 4274 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
9230 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
9231 : // if no load, or only a moisture load which can't be met at PLR=1, RETURN
9232 0 : return;
9233 : }
9234 :
9235 : // use the ASHRAE 90.1 method of reduced fan speed at low loads
9236 4274 : if (this->m_SimASHRAEModel) {
9237 :
9238 : // check to make sure unit has the capacity to meet the load
9239 17 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
9240 3 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
9241 14 : UnitarySys &SZVAVModel(state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum]);
9242 42 : SZVAVModel::calcSZVAVModel(state,
9243 : SZVAVModel,
9244 : this->m_UnitarySysNum,
9245 : FirstHVACIteration,
9246 14 : state.dataUnitarySystems->CoolingLoad,
9247 14 : state.dataUnitarySystems->HeatingLoad,
9248 : ZoneLoad,
9249 : OnOffAirFlowRatio,
9250 14 : HXUnitOn,
9251 : AirLoopNum,
9252 : PartLoadRatio,
9253 : CompressorONFlag);
9254 : }
9255 :
9256 : } else { // not ASHRAE model
9257 :
9258 : // must test to see if load is bounded by capacity before calling RegulaFalsi
9259 5797 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
9260 1537 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
9261 5773 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad > SensOutputOff) ||
9262 1525 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad < SensOutputOff)) {
9263 : Real64 SensOutput;
9264 : Real64 LatOutput;
9265 4252 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
9266 7 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
9267 3 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR > 0.0) {
9268 3 : int CoilInletNode = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapInletNodeIndex;
9269 3 : this->CoilSHR = 0.0;
9270 : Real64 LowSpeedCoilSen;
9271 : Real64 LowSpeedCoilLat;
9272 3 : CoolPLR = 0.0;
9273 3 : HeatPLR = 0.0;
9274 3 : this->m_CoolingSpeedNum = 1;
9275 3 : this->calcUnitarySystemToLoad(state,
9276 : AirLoopNum,
9277 : FirstHVACIteration,
9278 : CoolPLR,
9279 : HeatPLR,
9280 : OnOffAirFlowRatio,
9281 : SensOutputOff,
9282 : LatOutputOff,
9283 3 : HXUnitOn,
9284 : HeatCoilLoad,
9285 : SupHeaterLoad,
9286 : CompressorONFlag);
9287 3 : CoolPLR = 1.0;
9288 3 : HeatPLR = 0.0;
9289 3 : this->m_CoolingCycRatio = 1.0;
9290 3 : this->m_CoolingSpeedRatio = 0.0;
9291 : // this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9292 3 : this->calcUnitarySystemToLoad(state,
9293 : AirLoopNum,
9294 : FirstHVACIteration,
9295 : CoolPLR,
9296 : HeatPLR,
9297 : OnOffAirFlowRatio,
9298 : SensOutputOn,
9299 : LatOutputOn,
9300 3 : HXUnitOn,
9301 : HeatCoilLoad,
9302 : SupHeaterLoad,
9303 : CompressorONFlag);
9304 3 : Real64 ZoneLatLoad = ZoneLoad * (1.0 / this->LoadSHR - 1.0);
9305 3 : Real64 SenPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9306 3 : Real64 LatPLR = (ZoneLatLoad - LatOutputOff) / (LatOutputOn - LatOutputOff);
9307 3 : Real64 totalRate = 0.0;
9308 3 : Real64 sensRate = 0.0;
9309 3 : Real64 latRate = 0.0;
9310 3 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9311 3 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9312 3 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9313 3 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9314 3 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9315 : sensRate,
9316 : latRate,
9317 : totalRate);
9318 3 : if (LatPLR > 1.0 || LatPLR < 0.0) {
9319 1 : this->CoilSHR = this->LoadSHR;
9320 : } else {
9321 2 : Real64 coilSens = sensRate * SenPLR;
9322 2 : Real64 coilLat = latRate * LatPLR;
9323 2 : this->CoilSHR = coilSens / (coilSens + coilLat);
9324 : }
9325 3 : if (this->m_NumOfSpeedCooling > 1) {
9326 0 : this->SpeedSHR[1] = this->CoilSHR;
9327 0 : LowSpeedCoilSen = sensRate;
9328 0 : LowSpeedCoilLat = latRate;
9329 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9330 0 : this->SpeedSHR[SpeedNum] = this->LoadSHR;
9331 : }
9332 : }
9333 3 : if (this->CoilSHR < 0.0) {
9334 0 : this->CoilSHR = this->LoadSHR;
9335 : }
9336 3 : if (this->m_NumOfSpeedCooling > 1 && ZoneLoad < SensOutputOn) {
9337 : Real64 SenSPR;
9338 : Real64 LatSPR;
9339 0 : this->FullOutput[1] = SensOutputOn;
9340 0 : this->FullLatOutput[1] = LatOutputOn;
9341 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9342 0 : this->CoilSHR = 0.0;
9343 0 : CoolPLR = 1.0;
9344 0 : HeatPLR = 0.0;
9345 0 : this->m_CoolingSpeedRatio = 1.0;
9346 0 : this->m_CoolingCycRatio = 1.0;
9347 0 : this->m_CoolingSpeedNum = SpeedNum;
9348 0 : this->calcUnitarySystemToLoad(state,
9349 : AirLoopNum,
9350 : FirstHVACIteration,
9351 : CoolPLR,
9352 : HeatPLR,
9353 : OnOffAirFlowRatio,
9354 0 : this->FullOutput[SpeedNum],
9355 0 : this->FullLatOutput[SpeedNum],
9356 0 : HXUnitOn,
9357 : HeatCoilLoad,
9358 : SupHeaterLoad,
9359 : CompressorONFlag);
9360 0 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9361 0 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9362 0 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9363 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9364 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9365 : sensRate,
9366 : latRate,
9367 : totalRate);
9368 0 : SenSPR =
9369 0 : (ZoneLoad - this->FullOutput[SpeedNum - 1]) / (this->FullOutput[SpeedNum] - this->FullOutput[SpeedNum - 1]);
9370 0 : LatSPR = (ZoneLatLoad - this->FullLatOutput[SpeedNum - 1]) /
9371 0 : (this->FullLatOutput[SpeedNum] - this->FullLatOutput[SpeedNum - 1]);
9372 0 : if (LatSPR > 1.0 || LatSPR < 0.0) {
9373 0 : this->CoilSHR = this->LoadSHR;
9374 : } else {
9375 0 : Real64 coilSens = sensRate * SenSPR + (1.0 - SenSPR) * LowSpeedCoilSen;
9376 0 : Real64 coilLat = latRate * LatSPR + (1.0 - LatSPR) * LowSpeedCoilLat;
9377 0 : this->CoilSHR = coilSens / (coilSens + coilLat);
9378 : }
9379 0 : this->SpeedSHR[SpeedNum] = this->CoilSHR;
9380 0 : LowSpeedCoilSen = sensRate;
9381 0 : LowSpeedCoilLat = latRate;
9382 : }
9383 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9384 0 : CoolPLR = 1.0;
9385 0 : HeatPLR = 0.0;
9386 0 : if (SpeedNum == 1) {
9387 0 : this->m_CoolingSpeedRatio = 0.0;
9388 : } else {
9389 0 : this->m_CoolingSpeedRatio = 1.0;
9390 : }
9391 0 : this->m_CoolingCycRatio = 1.0;
9392 0 : this->m_CoolingSpeedNum = SpeedNum;
9393 0 : this->calcUnitarySystemToLoad(state,
9394 : AirLoopNum,
9395 : FirstHVACIteration,
9396 : CoolPLR,
9397 : HeatPLR,
9398 : OnOffAirFlowRatio,
9399 : SensOutputOn,
9400 : LatOutputOn,
9401 0 : HXUnitOn,
9402 : HeatCoilLoad,
9403 : SupHeaterLoad,
9404 : CompressorONFlag);
9405 0 : if (ZoneLoad >= SensOutputOn) {
9406 0 : this->CoilSHR = this->SpeedSHR[SpeedNum];
9407 0 : break;
9408 : }
9409 : }
9410 : }
9411 : }
9412 : }
9413 4247 : if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9414 2 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
9415 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9416 0 : HeatPLR = 0.0;
9417 0 : this->calcUnitarySystemToLoad(state,
9418 : AirLoopNum,
9419 : FirstHVACIteration,
9420 : CoolPLR,
9421 : HeatPLR,
9422 : OnOffAirFlowRatio,
9423 : SensOutput,
9424 : LatOutput,
9425 0 : HXUnitOn,
9426 : HeatCoilLoad,
9427 : SupHeaterLoad,
9428 : CompressorONFlag);
9429 0 : PartLoadRatio = CoolPLR;
9430 4247 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9431 4247 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1 &&
9432 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
9433 0 : HeatPLR = 0.0;
9434 0 : this->calcUnitarySystemToLoad(state,
9435 : AirLoopNum,
9436 : FirstHVACIteration,
9437 : 1.0,
9438 : HeatPLR,
9439 : OnOffAirFlowRatio,
9440 : SensOutputOn,
9441 : LatOutputOn,
9442 0 : HXUnitOn,
9443 : HeatCoilLoad,
9444 : SupHeaterLoad,
9445 : CompressorONFlag);
9446 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9447 0 : this->calcUnitarySystemToLoad(state,
9448 : AirLoopNum,
9449 : FirstHVACIteration,
9450 : CoolPLR,
9451 : HeatPLR,
9452 : OnOffAirFlowRatio,
9453 : SensOutput,
9454 : LatOutput,
9455 0 : HXUnitOn,
9456 : HeatCoilLoad,
9457 : SupHeaterLoad,
9458 : CompressorONFlag);
9459 0 : PartLoadRatio = CoolPLR;
9460 4247 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9461 4247 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1) {
9462 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9463 0 : HeatPLR = 0.0;
9464 0 : this->calcUnitarySystemToLoad(state,
9465 : AirLoopNum,
9466 : FirstHVACIteration,
9467 : CoolPLR,
9468 : HeatPLR,
9469 : OnOffAirFlowRatio,
9470 : SensOutput,
9471 : LatOutput,
9472 0 : HXUnitOn,
9473 : HeatCoilLoad,
9474 : SupHeaterLoad,
9475 : CompressorONFlag);
9476 0 : PartLoadRatio = CoolPLR;
9477 4245 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9478 0 : (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
9479 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
9480 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel)) {
9481 0 : CoolPLR = 0.0;
9482 0 : HeatPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9483 0 : this->calcUnitarySystemToLoad(state,
9484 : AirLoopNum,
9485 : FirstHVACIteration,
9486 : CoolPLR,
9487 : HeatPLR,
9488 : OnOffAirFlowRatio,
9489 : SensOutput,
9490 : LatOutput,
9491 0 : HXUnitOn,
9492 : HeatCoilLoad,
9493 : SupHeaterLoad,
9494 : CompressorONFlag);
9495 0 : PartLoadRatio = HeatPLR;
9496 4245 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9497 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9498 0 : CoolPLR = 0.0;
9499 0 : if (this->m_HeatingSpeedNum == 1) {
9500 0 : this->m_HeatingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_HeatingSpeedNum] - SensOutputOff);
9501 0 : HeatPLR = this->m_HeatingCycRatio;
9502 0 : this->m_HeatingSpeedRatio = 0.0;
9503 : } else {
9504 0 : this->m_HeatingCycRatio = 1.0;
9505 0 : this->m_HeatingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_HeatingSpeedNum - 1]) /
9506 0 : (this->FullOutput[this->m_HeatingSpeedNum] - this->FullOutput[this->m_HeatingSpeedNum - 1]);
9507 0 : HeatPLR = this->m_HeatingSpeedRatio;
9508 : }
9509 0 : this->calcUnitarySystemToLoad(state,
9510 : AirLoopNum,
9511 : FirstHVACIteration,
9512 : CoolPLR,
9513 : HeatPLR,
9514 : OnOffAirFlowRatio,
9515 : SensOutput,
9516 : LatOutput,
9517 0 : HXUnitOn,
9518 : HeatCoilLoad,
9519 : SupHeaterLoad,
9520 : CompressorONFlag);
9521 0 : PartLoadRatio = HeatPLR;
9522 4247 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9523 4247 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1) {
9524 2 : HeatPLR = 0.0;
9525 2 : if (this->m_CoolingSpeedNum == 1) {
9526 1 : this->m_CoolingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_CoolingSpeedNum] - SensOutputOff);
9527 1 : CoolPLR = this->m_CoolingCycRatio;
9528 1 : this->m_CoolingSpeedRatio = 0.0;
9529 : } else {
9530 1 : this->m_CoolingCycRatio = 1.0;
9531 1 : this->m_CoolingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_CoolingSpeedNum - 1]) /
9532 1 : (this->FullOutput[this->m_CoolingSpeedNum] - this->FullOutput[this->m_CoolingSpeedNum - 1]);
9533 1 : CoolPLR = this->m_CoolingSpeedRatio;
9534 : }
9535 2 : this->calcUnitarySystemToLoad(state,
9536 : AirLoopNum,
9537 : FirstHVACIteration,
9538 : CoolPLR,
9539 : HeatPLR,
9540 : OnOffAirFlowRatio,
9541 : SensOutput,
9542 : LatOutput,
9543 2 : HXUnitOn,
9544 : HeatCoilLoad,
9545 : SupHeaterLoad,
9546 : CompressorONFlag);
9547 2 : PartLoadRatio = CoolPLR;
9548 : } else {
9549 :
9550 4243 : Real64 par6 = state.dataUnitarySystems->CoolingLoad ? 1.0 : 0.0;
9551 28735 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9552 : Real64 const PartLoadRatio) {
9553 48984 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9554 : PartLoadRatio,
9555 24492 : this->m_UnitarySysNum,
9556 : FirstHVACIteration,
9557 : // par 3 not used?
9558 : CompressorONFlag,
9559 : ZoneLoad,
9560 : par6,
9561 : 1.0,
9562 : OnOffAirFlowRatio,
9563 : HXUnitOn,
9564 : // par 10 not used
9565 24492 : AirLoopNum);
9566 4243 : };
9567 : // Tolerance is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9568 4243 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
9569 :
9570 4243 : if (SolFlag == -1) {
9571 0 : if (state.dataUnitarySystems->HeatingLoad) {
9572 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9573 : // This does cause a problem when coil cannot turn on when OAT < min allowed or scheduled off
9574 : // If max iteration limit is exceeded, how do we know if the heating coil is operating?
9575 0 : TempMaxPLR = -0.1;
9576 0 : TempSensOutput = SensOutputOff;
9577 0 : while ((TempSensOutput - ZoneLoad) < 0.0 && TempMaxPLR < 1.0) {
9578 : // find upper limit of HeatingPLR
9579 0 : TempMaxPLR += 0.1;
9580 :
9581 : // SUBROUTINE SetSpeedVariables(UnitarySysNum, SensibleLoad, PartLoadRatio)
9582 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9583 0 : this->calcUnitarySystemToLoad(state,
9584 : AirLoopNum,
9585 : FirstHVACIteration,
9586 : CoolPLR,
9587 : TempMaxPLR,
9588 : OnOffAirFlowRatio,
9589 : TempSensOutput,
9590 : TempLatOutput,
9591 0 : HXUnitOn,
9592 : HeatCoilLoad,
9593 : SupHeaterLoad,
9594 : CompressorONFlag);
9595 : }
9596 0 : TempMinPLR = TempMaxPLR;
9597 0 : while ((TempSensOutput - ZoneLoad) > 0.0 && TempMinPLR > 0.0) {
9598 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9599 0 : TempMaxPLR = TempMinPLR;
9600 : // find minimum limit of HeatingPLR
9601 0 : TempMinPLR -= 0.01;
9602 0 : this->setSpeedVariables(state, true, TempMinPLR);
9603 0 : this->calcUnitarySystemToLoad(state,
9604 : AirLoopNum,
9605 : FirstHVACIteration,
9606 : CoolPLR,
9607 : TempMinPLR,
9608 : OnOffAirFlowRatio,
9609 : TempSensOutput,
9610 : TempLatOutput,
9611 0 : HXUnitOn,
9612 : HeatCoilLoad,
9613 : SupHeaterLoad,
9614 : CompressorONFlag);
9615 : }
9616 : // Now solve again with tighter PLR limits
9617 : auto f2 = // (AUTO_OK_LAMBDA)
9618 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9619 : Real64 const PartLoadRatio) {
9620 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9621 : PartLoadRatio,
9622 0 : this->m_UnitarySysNum,
9623 : FirstHVACIteration,
9624 : // par 3 not used?
9625 : CompressorONFlag,
9626 : ZoneLoad,
9627 : par6,
9628 : 1.0,
9629 : OnOffAirFlowRatio,
9630 : HXUnitOn,
9631 : // par 10 not used
9632 0 : AirLoopNum);
9633 0 : };
9634 0 : General::SolveRoot(state, this->m_HeatConvTol, MaxIter, SolFlag, HeatPLR, f2, TempMinPLR, TempMaxPLR);
9635 0 : this->calcUnitarySystemToLoad(state,
9636 : AirLoopNum,
9637 : FirstHVACIteration,
9638 : CoolPLR,
9639 : HeatPLR,
9640 : OnOffAirFlowRatio,
9641 : TempSensOutput,
9642 : TempLatOutput,
9643 0 : HXUnitOn,
9644 : HeatCoilLoad,
9645 : SupHeaterLoad,
9646 : CompressorONFlag);
9647 0 : } else if (state.dataUnitarySystems->CoolingLoad) {
9648 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9649 : // IF iteration limit is exceeded (SolFlag = -1), find tighter boundary of solution and repeat RegulaFalsi
9650 0 : TempMaxPLR = -0.1;
9651 0 : TempSysOutput = SensOutputOff;
9652 0 : TempLoad = ZoneLoad;
9653 0 : while ((TempSysOutput - TempLoad) > 0.0 &&
9654 : TempMaxPLR < 0.95) { // avoid PLR > 1 by limiting TempMaxPLR to 1 (i.e., TempMaxPLR += 0.1)
9655 : // find upper limit of HeatingPLR
9656 0 : TempMaxPLR += 0.1;
9657 0 : if (TempMaxPLR > 0.95 && TempMaxPLR < 1.05) {
9658 0 : TempMaxPLR = 1.0; // enforce a perfect 1.0 at the top end
9659 : }
9660 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9661 0 : this->calcUnitarySystemToLoad(state,
9662 : AirLoopNum,
9663 : FirstHVACIteration,
9664 : TempMaxPLR,
9665 : HeatPLR,
9666 : OnOffAirFlowRatio,
9667 : TempSensOutput,
9668 : TempLatOutput,
9669 0 : HXUnitOn,
9670 : HeatCoilLoad,
9671 : SupHeaterLoad,
9672 : CompressorONFlag);
9673 0 : TempSysOutput = TempSensOutput;
9674 : }
9675 0 : TempMinPLR = TempMaxPLR;
9676 0 : while ((TempSysOutput - TempLoad) < 0.0 &&
9677 : TempMinPLR > 0.025) { // lower limit might be changed to 0.005 without adverse affect
9678 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9679 0 : TempMaxPLR = TempMinPLR;
9680 : // find minimum limit of HeatingPLR
9681 0 : TempMinPLR -= 0.01;
9682 0 : this->setSpeedVariables(state, true, TempMinPLR);
9683 0 : this->calcUnitarySystemToLoad(state,
9684 : AirLoopNum,
9685 : FirstHVACIteration,
9686 : TempMinPLR,
9687 : HeatPLR,
9688 : OnOffAirFlowRatio,
9689 : TempSensOutput,
9690 : TempLatOutput,
9691 0 : HXUnitOn,
9692 : HeatCoilLoad,
9693 : SupHeaterLoad,
9694 : CompressorONFlag);
9695 0 : TempSysOutput = TempSensOutput;
9696 : }
9697 : // Now solve again with tighter PLR limits
9698 : auto f2 = // (AUTO_OK_LAMBDA)
9699 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9700 : Real64 const PartLoadRatio) {
9701 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9702 : PartLoadRatio,
9703 0 : this->m_UnitarySysNum,
9704 : FirstHVACIteration,
9705 : // par 3 not used?
9706 : CompressorONFlag,
9707 : ZoneLoad,
9708 : par6,
9709 : 1.0,
9710 : OnOffAirFlowRatio,
9711 : HXUnitOn,
9712 : // par 10 not used
9713 0 : AirLoopNum);
9714 0 : };
9715 0 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, CoolPLR, f2, TempMinPLR, TempMaxPLR);
9716 0 : this->calcUnitarySystemToLoad(state,
9717 : AirLoopNum,
9718 : FirstHVACIteration,
9719 : CoolPLR,
9720 : HeatPLR,
9721 : OnOffAirFlowRatio,
9722 : TempSensOutput,
9723 : TempLatOutput,
9724 0 : HXUnitOn,
9725 : HeatCoilLoad,
9726 : SupHeaterLoad,
9727 : CompressorONFlag);
9728 : } // IF(HeatingLoad)THEN
9729 0 : if (SolFlag == -1) {
9730 0 : if (std::abs(ZoneLoad - TempSensOutput) > HVAC::SmallLoad) {
9731 0 : if (this->MaxIterIndex == 0) {
9732 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9733 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system sensible part-load ratio.");
9734 0 : ShowContinueErrorTimeStamp(state,
9735 0 : format("Sensible load to be met = {:.2T} (watts), sensible output = {:.2T} "
9736 : "(watts), and the simulation continues.",
9737 : ZoneLoad,
9738 : TempSensOutput));
9739 : }
9740 0 : ShowRecurringWarningErrorAtEnd(state,
9741 0 : this->UnitType + " \"" + this->Name +
9742 : "\" - Iteration limit exceeded in calculating sensible part-load ratio error "
9743 : "continues. Sensible load statistics:",
9744 0 : this->MaxIterIndex,
9745 : ZoneLoad,
9746 : ZoneLoad);
9747 : }
9748 0 : } else if (SolFlag == -2) {
9749 0 : if (this->RegulaFalsiFailedIndex == 0) {
9750 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9751 0 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9752 0 : ShowContinueErrorTimeStamp(
9753 0 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9754 : }
9755 0 : ShowRecurringWarningErrorAtEnd(
9756 : state,
9757 0 : this->UnitType + " \"" + this->Name +
9758 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9759 0 : this->RegulaFalsiFailedIndex,
9760 : ZoneLoad,
9761 : ZoneLoad);
9762 : }
9763 4243 : } else if (SolFlag == -2) {
9764 0 : if (this->RegulaFalsiFailedIndex == 0) {
9765 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9766 0 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9767 0 : ShowContinueErrorTimeStamp(
9768 0 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9769 : }
9770 0 : ShowRecurringWarningErrorAtEnd(
9771 : state,
9772 0 : this->UnitType + " \"" + this->Name +
9773 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9774 0 : this->RegulaFalsiFailedIndex,
9775 : ZoneLoad,
9776 : ZoneLoad);
9777 : } // IF (SolFlag == -1) THEN
9778 : }
9779 : } else { // load is not bounded by capacity. Leave PLR=1 or turn off unit?
9780 3 : this->m_CoolingPartLoadFrac = 0.0;
9781 3 : this->m_HeatingPartLoadFrac = 0.0;
9782 3 : CoolPLR = 0.0;
9783 3 : HeatPLR = 0.0;
9784 3 : PartLoadRatio = 0.0;
9785 : } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN
9786 : } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN
9787 : }
9788 :
9789 4274 : if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) {
9790 2730 : if (this->m_HeatingSpeedNum == 1) {
9791 30 : this->m_HeatingCycRatio = PartLoadRatio;
9792 30 : this->m_HeatingSpeedRatio = 0.0;
9793 : } else {
9794 2700 : if (this->m_SingleMode == 0) {
9795 2699 : this->m_HeatingCycRatio = 1.0;
9796 2699 : this->m_HeatingSpeedRatio = PartLoadRatio;
9797 : } else {
9798 1 : this->m_HeatingCycRatio = PartLoadRatio;
9799 1 : this->m_HeatingSpeedRatio = 1.0;
9800 : }
9801 : }
9802 2730 : HeatPLR = PartLoadRatio;
9803 2730 : CoolPLR = 0.0;
9804 2730 : this->m_CoolingCycRatio = 0.0;
9805 2730 : this->m_CoolingSpeedRatio = 0.0;
9806 1544 : } else if (state.dataUnitarySystems->CoolingLoad && (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil)) {
9807 1500 : if (this->m_CoolingSpeedNum == 1) {
9808 455 : this->m_CoolingCycRatio = PartLoadRatio;
9809 455 : this->m_CoolingSpeedRatio = 0.0;
9810 : } else {
9811 1045 : if (this->m_SingleMode == 0) {
9812 1044 : this->m_CoolingCycRatio = 1.0;
9813 1044 : this->m_CoolingSpeedRatio = PartLoadRatio;
9814 : } else {
9815 1 : this->m_CoolingCycRatio = PartLoadRatio;
9816 1 : this->m_CoolingSpeedRatio = 1.0;
9817 : }
9818 : }
9819 1500 : this->m_HeatingCycRatio = 0.0;
9820 1500 : this->m_HeatingSpeedRatio = 0.0;
9821 1500 : HeatPLR = 0.0;
9822 1500 : CoolPLR = PartLoadRatio;
9823 : } else {
9824 44 : HeatPLR = this->m_HeatingPartLoadFrac;
9825 44 : CoolPLR = this->m_CoolingPartLoadFrac;
9826 : }
9827 :
9828 4274 : this->calcUnitarySystemToLoad(state,
9829 : AirLoopNum,
9830 : FirstHVACIteration,
9831 : CoolPLR,
9832 : HeatPLR,
9833 : OnOffAirFlowRatio,
9834 : TempSensOutput,
9835 : TempLatOutput,
9836 4274 : HXUnitOn,
9837 : HeatCoilLoad,
9838 : SupHeaterLoad,
9839 : CompressorONFlag);
9840 :
9841 : // FullSensibleOutput is used to set supplemental heater PLR in calling routine
9842 : // OnOffAirFlowRatio is used to average air flow between ON and OFF state
9843 4274 : FullSensibleOutput = TempSensOutput;
9844 4274 : LatOutputOn = TempLatOutput;
9845 :
9846 : // RETURN if the moisture load is met
9847 4274 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad >= TempLatOutput) {
9848 4270 : return;
9849 : }
9850 : // Multimode does not meet the latent load, only the sensible load with or without HX active
9851 : // what if there is a heating load for a system using Multimode?
9852 4 : if (!state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9853 0 : return;
9854 : }
9855 : // if HX was previously turned on return since sensible load is already met
9856 4 : if (state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode && HXUnitOn) {
9857 0 : return;
9858 : }
9859 : // IF(HeatingLoad .AND. UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)RETURN
9860 :
9861 4 : if ((this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
9862 :
9863 : // find maximum latent output IF not already calculated
9864 4 : if (state.dataUnitarySystems->HeatingLoad) {
9865 0 : CoolPLR = 1.0;
9866 0 : this->m_CoolingPartLoadFrac = 1.0;
9867 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9868 0 : this->m_CoolingSpeedRatio = 1.0;
9869 0 : this->m_CoolingCycRatio = 1.0;
9870 0 : if (this->m_CoolingSpeedNum > 0) {
9871 0 : this->m_HeatingPartLoadFrac = 0.0;
9872 0 : this->m_HeatingSpeedNum = 0;
9873 0 : HeatPLR = 0.0;
9874 0 : state.dataUnitarySystems->CoolingLoad = true;
9875 0 : state.dataUnitarySystems->HeatingLoad = false;
9876 0 : this->m_HeatingCoilSensDemand = 0.0;
9877 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9878 0 : this->calcUnitarySystemToLoad(state,
9879 : AirLoopNum,
9880 : FirstHVACIteration,
9881 : 0.0,
9882 : 0.0,
9883 : OnOffAirFlowRatio,
9884 : TempSensOutput,
9885 : TempLatOutput,
9886 0 : HXUnitOn,
9887 : HeatCoilLoad,
9888 : SupHeaterLoad,
9889 : CompressorONFlag);
9890 0 : this->calcUnitarySystemToLoad(state,
9891 : AirLoopNum,
9892 : FirstHVACIteration,
9893 : CoolPLR,
9894 : HeatPLR,
9895 : OnOffAirFlowRatio,
9896 : TempSensOutput,
9897 : LatOutputOn,
9898 0 : HXUnitOn,
9899 : HeatCoilLoad,
9900 : SupHeaterLoad,
9901 : CompressorONFlag);
9902 : } else {
9903 0 : this->m_HeatingCoilSensDemand = 0.0;
9904 0 : this->m_CoolingCoilLatentDemand = 0.0;
9905 0 : this->calcUnitarySystemToLoad(state,
9906 : AirLoopNum,
9907 : FirstHVACIteration,
9908 : 0.0,
9909 : 0.0,
9910 : OnOffAirFlowRatio,
9911 : TempSensOutput,
9912 : TempLatOutput,
9913 0 : HXUnitOn,
9914 : HeatCoilLoad,
9915 : SupHeaterLoad,
9916 : CompressorONFlag);
9917 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9918 0 : this->calcUnitarySystemToLoad(state,
9919 : AirLoopNum,
9920 : FirstHVACIteration,
9921 : CoolPLR,
9922 : HeatPLR,
9923 : OnOffAirFlowRatio,
9924 : TempSensOutput,
9925 : LatOutputOn,
9926 0 : HXUnitOn,
9927 : HeatCoilLoad,
9928 : SupHeaterLoad,
9929 : CompressorONFlag);
9930 : }
9931 : }
9932 :
9933 4 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
9934 0 : HXUnitOn = true;
9935 0 : CoolPLR = 1.0;
9936 0 : this->m_CoolingPartLoadFrac = 1.0;
9937 0 : this->calcUnitarySystemToLoad(state,
9938 : AirLoopNum,
9939 : FirstHVACIteration,
9940 : CoolPLR,
9941 : HeatPLR,
9942 : OnOffAirFlowRatio,
9943 : TempSensOutput,
9944 : LatOutputOn,
9945 0 : HXUnitOn,
9946 : HeatCoilLoad,
9947 : SupHeaterLoad,
9948 : CompressorONFlag);
9949 0 : FullSensibleOutput = TempSensOutput;
9950 : }
9951 :
9952 4 : if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
9953 4 : HXUnitOn = true; // HX is needed to meet moisture load
9954 4 : if (this->m_NumOfSpeedCooling > 0) {
9955 4 : for (SpeedNum = this->m_CoolingSpeedNum; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9956 3 : CoolPLR = 1.0;
9957 3 : this->m_CoolingPartLoadFrac = CoolPLR;
9958 3 : this->m_CoolingSpeedRatio = 1.0;
9959 3 : this->m_CoolingCycRatio = 1.0;
9960 3 : this->m_CoolingSpeedNum = SpeedNum;
9961 3 : this->calcUnitarySystemToLoad(state,
9962 : AirLoopNum,
9963 : FirstHVACIteration,
9964 : CoolPLR,
9965 : HeatPLR,
9966 : OnOffAirFlowRatio,
9967 : SensOutputOn,
9968 : LatOutputOn,
9969 3 : HXUnitOn,
9970 : HeatCoilLoad,
9971 : SupHeaterLoad,
9972 : CompressorONFlag);
9973 3 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
9974 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9975 : }
9976 : // over specified logic? it has to be a water coil? what about other VS coil models?
9977 3 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9978 3 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
9979 3 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9980 0 : !this->m_DiscreteSpeedCoolingCoil)) {
9981 0 : this->m_CoolingSpeedRatio = 0.0;
9982 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9983 0 : if (this->m_CoolingSpeedNum == 0) {
9984 0 : this->m_CoolingCycRatio = 0.0;
9985 0 : CoolPLR = 0.0;
9986 : } else {
9987 0 : this->m_CoolingCycRatio = 1.0;
9988 0 : this->m_CoolingSpeedRatio = 0.0;
9989 0 : if (this->m_SingleMode == 1) {
9990 0 : CoolPLR = 1.0;
9991 : }
9992 : }
9993 :
9994 0 : this->calcUnitarySystemToLoad(state,
9995 : AirLoopNum,
9996 : FirstHVACIteration,
9997 : CoolPLR,
9998 : HeatPLR,
9999 : OnOffAirFlowRatio,
10000 : SensOutputOn,
10001 : LatOutputOn,
10002 0 : HXUnitOn,
10003 : HeatCoilLoad,
10004 : SupHeaterLoad,
10005 : CompressorONFlag);
10006 0 : this->m_CoolingSpeedNum = SpeedNum;
10007 : }
10008 3 : if (state.dataUnitarySystems->MoistureLoad >= LatOutputOn) {
10009 2 : break;
10010 : }
10011 : }
10012 : } else {
10013 1 : CoolPLR = 1.0;
10014 1 : this->calcUnitarySystemToLoad(state,
10015 : AirLoopNum,
10016 : FirstHVACIteration,
10017 : CoolPLR,
10018 : HeatPLR,
10019 : OnOffAirFlowRatio,
10020 : SensOutputOn,
10021 : LatOutputOn,
10022 1 : HXUnitOn,
10023 : HeatCoilLoad,
10024 : SupHeaterLoad,
10025 : CompressorONFlag);
10026 1 : this->m_CoolingPartLoadFrac = CoolPLR;
10027 : }
10028 : }
10029 :
10030 8 : if ((state.dataUnitarySystems->MoistureLoad < TempLatOutput) &&
10031 4 : (state.dataUnitarySystems->MoistureLoad > LatOutputOn)) { // bounds check for RegulaFalsi
10032 :
10033 : // save heating PLR
10034 3 : HeatPLR = this->m_HeatingPartLoadFrac;
10035 : Real64 par5;
10036 : Real64 par7;
10037 3 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10038 0 : par5 = ZoneLoad;
10039 0 : par7 = 1.0;
10040 : } else {
10041 3 : par5 = state.dataUnitarySystems->MoistureLoad;
10042 3 : par7 = 0.0;
10043 : }
10044 : // Tolerance is fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
10045 14 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, par5, par7, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
10046 : Real64 const PartLoadRatio) {
10047 22 : return UnitarySys::calcUnitarySystemLoadResidual(state,
10048 : PartLoadRatio,
10049 11 : this->m_UnitarySysNum,
10050 : FirstHVACIteration,
10051 : // par 3 not used?
10052 : CompressorONFlag,
10053 : par5,
10054 : 1.0,
10055 : par7,
10056 : OnOffAirFlowRatio,
10057 : HXUnitOn,
10058 : // par 10 not used
10059 11 : AirLoopNum);
10060 3 : };
10061 3 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, PartLoadRatio, f, 0.0, 1.0);
10062 3 : this->m_CoolingPartLoadFrac = PartLoadRatio;
10063 3 : this->m_HeatingPartLoadFrac = HeatPLR;
10064 1 : } else if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
10065 : // Logic below needs further look...what to do if the bounds check for RegulaFalsi fail?
10066 : // I'm not even sure if this should be done.
10067 : // It's wrong anyway, since there won't be a cooling load if multimode (see RETURN about 80 lines up).
10068 1 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode) {
10069 1 : this->m_CoolingPartLoadFrac = 1.0;
10070 : }
10071 : }
10072 : }
10073 :
10074 4 : CoolPLR = this->m_CoolingPartLoadFrac;
10075 4 : HeatPLR = this->m_HeatingPartLoadFrac;
10076 :
10077 4 : this->calcUnitarySystemToLoad(state,
10078 : AirLoopNum,
10079 : FirstHVACIteration,
10080 : CoolPLR,
10081 : HeatPLR,
10082 : OnOffAirFlowRatio,
10083 : TempSensOutput,
10084 : TempLatOutput,
10085 4 : HXUnitOn,
10086 : HeatCoilLoad,
10087 : SupHeaterLoad,
10088 : CompressorONFlag);
10089 :
10090 4 : if (SolFlagLat == -1) {
10091 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
10092 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
10093 0 : TempMaxPLR = -0.1;
10094 0 : TempLatOutput = LatOutputOff;
10095 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
10096 : // find upper limit of HeatingPLR
10097 0 : TempMaxPLR += 0.1;
10098 0 : this->calcUnitarySystemToLoad(state,
10099 : AirLoopNum,
10100 : FirstHVACIteration,
10101 : TempMaxPLR,
10102 : HeatPLR,
10103 : OnOffAirFlowRatio,
10104 : TempSensOutput,
10105 : TempLatOutput,
10106 0 : HXUnitOn,
10107 : HeatCoilLoad,
10108 : SupHeaterLoad,
10109 : CompressorONFlag);
10110 : }
10111 0 : TempMinPLR = TempMaxPLR;
10112 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) < 0.0 && TempMinPLR > 0.0) {
10113 : // pull upper limit of HeatingPLR DOwn to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
10114 0 : TempMaxPLR = TempMinPLR;
10115 : // find minimum limit of HeatingPLR
10116 0 : TempMinPLR -= 0.01;
10117 0 : this->calcUnitarySystemToLoad(state,
10118 : AirLoopNum,
10119 : FirstHVACIteration,
10120 : TempMinPLR,
10121 : HeatPLR,
10122 : OnOffAirFlowRatio,
10123 : TempSensOutput,
10124 : TempLatOutput,
10125 0 : HXUnitOn,
10126 : HeatCoilLoad,
10127 : SupHeaterLoad,
10128 : CompressorONFlag);
10129 : }
10130 : // Now solve again with tighter PLR limits
10131 : Real64 par5;
10132 : Real64 par7;
10133 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10134 0 : par5 = ZoneLoad;
10135 0 : par7 = 1.0;
10136 : } else {
10137 0 : par5 = state.dataUnitarySystems->MoistureLoad;
10138 0 : par7 = 0.0;
10139 : }
10140 : // // Tolerance is fraction of load, M
10141 0 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, OnOffAirFlowRatio, HXUnitOn, AirLoopNum, par5, par7](
10142 : Real64 const PartLoadRatio) {
10143 : // TODO: The actual Par array being used here may have been altered through any of the sections above, and this line is not covered by
10144 : // a unit or integration test
10145 : // TODO: So I made some assumptions about the arguments. I'm not sure if ultimately this is even accessible, so maybe it doesn't
10146 : // matter.
10147 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
10148 : PartLoadRatio,
10149 0 : this->m_UnitarySysNum,
10150 : FirstHVACIteration,
10151 : // par 3 not used?
10152 : CompressorONFlag,
10153 : par5,
10154 : 1.0,
10155 : par7,
10156 : OnOffAirFlowRatio,
10157 : HXUnitOn,
10158 : // par 10 not used
10159 0 : AirLoopNum);
10160 0 : };
10161 0 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, CoolPLR, f, TempMinPLR, TempMaxPLR);
10162 0 : this->calcUnitarySystemToLoad(state,
10163 : AirLoopNum,
10164 : FirstHVACIteration,
10165 : CoolPLR,
10166 : HeatPLR,
10167 : OnOffAirFlowRatio,
10168 : TempSensOutput,
10169 : TempLatOutput,
10170 0 : HXUnitOn,
10171 : HeatCoilLoad,
10172 : SupHeaterLoad,
10173 : CompressorONFlag);
10174 0 : if (SolFlagLat == -1) {
10175 0 : if (std::abs(state.dataUnitarySystems->MoistureLoad - TempLatOutput) > HVAC::SmallLoad) {
10176 0 : if (this->warnIndex.m_LatMaxIterIndex == 0) {
10177 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
10178 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system Latent part-load ratio.");
10179 0 : ShowContinueErrorTimeStamp(
10180 : state,
10181 0 : format("Latent load to be met = {:.2T} (watts), Latent output = {:.2T} (watts), and the simulation continues.",
10182 0 : state.dataUnitarySystems->MoistureLoad,
10183 : TempLatOutput));
10184 : }
10185 0 : ShowRecurringWarningErrorAtEnd(
10186 : state,
10187 0 : this->UnitType + " \"" + this->Name +
10188 : "\" - Iteration limit exceeded in calculating Latent part-load ratio error continues. Latent load statistics:",
10189 0 : this->warnIndex.m_LatMaxIterIndex,
10190 0 : state.dataUnitarySystems->MoistureLoad,
10191 0 : state.dataUnitarySystems->MoistureLoad);
10192 : }
10193 0 : } else if (SolFlagLat == -2) {
10194 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
10195 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
10196 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
10197 0 : ShowContinueErrorTimeStamp(
10198 : state,
10199 0 : format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
10200 : }
10201 0 : ShowRecurringWarningErrorAtEnd(state,
10202 0 : this->UnitType + " \"" + this->Name +
10203 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
10204 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
10205 0 : state.dataUnitarySystems->MoistureLoad,
10206 0 : state.dataUnitarySystems->MoistureLoad);
10207 : }
10208 4 : } else if (SolFlagLat == -2) {
10209 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
10210 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
10211 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
10212 0 : ShowContinueErrorTimeStamp(
10213 0 : state, format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
10214 : }
10215 0 : ShowRecurringWarningErrorAtEnd(state,
10216 0 : this->UnitType + " \"" + this->Name +
10217 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
10218 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
10219 0 : state.dataUnitarySystems->MoistureLoad,
10220 0 : state.dataUnitarySystems->MoistureLoad);
10221 : }
10222 :
10223 4 : FullSensibleOutput = TempSensOutput;
10224 :
10225 4 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
10226 : Real64 heatCoildT =
10227 4 : (this->m_HeatCoilExists)
10228 4 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
10229 4 : : 0.0;
10230 : Real64 CoolingOnlySensibleOutput =
10231 4 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
10232 4 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
10233 4 : heatCoildT);
10234 4 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
10235 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
10236 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
10237 2 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
10238 : // Heating mode and dehumidification is required
10239 : } else {
10240 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
10241 : // the heating coil pick up the load due to outdoor air.
10242 2 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
10243 : }
10244 7036 : }
10245 :
10246 7036 : void UnitarySys::initLoadBasedControl(EnergyPlusData &state,
10247 : int const AirLoopNum, // number of the current air loop being simulated
10248 : bool const FirstHVACIteration,
10249 : Real64 &OnOffAirFlowRatio,
10250 : Real64 &ZoneLoad)
10251 : {
10252 :
10253 : // SUBROUTINE INFORMATION:
10254 : // AUTHOR Richard Raustad, FSEC
10255 : // DATE WRITTEN February 2013
10256 :
10257 : // PURPOSE OF THIS SUBROUTINE:
10258 : // This subroutine is for initializations of the load controlled Unitary Systems.
10259 :
10260 : // METHODOLOGY EMPLOYED:
10261 : // Initialize mass flow rates and speed ratios. Calculate loads and adjust if necessary when using constant fan.
10262 :
10263 : // SUBROUTINE PARAMETER DEFINITIONS:
10264 : static constexpr std::string_view routineName("InitUnitarySystems");
10265 7036 : Real64 QZnReq = 0.0;
10266 7036 : Real64 QActual = 0.0;
10267 7036 : Real64 SensOutputOff = 0.0;
10268 7036 : Real64 LatOutputOff = 0.0;
10269 7036 : Real64 HeatCoilLoad = 0.0;
10270 7036 : Real64 SupHeaterLoad = 0.0;
10271 7036 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
10272 :
10273 : // do the Begin Environment initializations
10274 7036 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag2) {
10275 :
10276 27 : bool errorsFound = false;
10277 : // set fluid-side hardware limits
10278 27 : if (this->HeatCoilFluidInletNode > 0) {
10279 :
10280 1 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
10281 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10282 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
10283 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
10284 : Real64 CoilMaxVolFlowRate =
10285 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_HeatingCoilName, errorsFound);
10286 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10287 0 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
10288 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
10289 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
10290 : }
10291 : }
10292 : // IF steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10293 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
10294 0 : SteamCoils::SimulateSteamCoilComponents(state,
10295 : this->m_HeatingCoilName,
10296 : FirstHVACIteration,
10297 0 : this->m_HeatingCoilIndex,
10298 0 : 1.0,
10299 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10300 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, errorsFound);
10301 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10302 0 : Real64 TempSteamIn = 100.0;
10303 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10304 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10305 : }
10306 : }
10307 : }
10308 :
10309 1 : PlantUtilities::InitComponentNodes(
10310 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
10311 : }
10312 27 : if (this->m_SuppCoilFluidInletNode > 0) {
10313 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
10314 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
10315 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10316 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
10317 : Real64 CoilMaxVolFlowRate =
10318 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_SuppHeatCoilName, errorsFound);
10319 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10320 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum)
10321 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
10322 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
10323 : }
10324 : }
10325 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
10326 0 : SteamCoils::SimulateSteamCoilComponents(state,
10327 : this->m_SuppHeatCoilName,
10328 : FirstHVACIteration,
10329 0 : this->m_SuppHeatCoilIndex,
10330 0 : 1.0,
10331 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10332 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, errorsFound);
10333 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10334 0 : Real64 TempSteamIn = 100.0;
10335 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10336 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10337 : }
10338 : }
10339 0 : PlantUtilities::InitComponentNodes(
10340 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
10341 : }
10342 : }
10343 27 : this->m_MyEnvrnFlag2 = false;
10344 : }
10345 :
10346 7036 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && this->m_MyCheckFlag) {
10347 7030 : if (this->m_AirLoopEquipment) {
10348 2 : int zoneInlet = this->m_ZoneInletNode;
10349 2 : if (zoneInlet == 0) {
10350 0 : this->m_ThisSysInputShouldBeGotten = true; // need to find zone inlet node once data is available
10351 0 : this->m_MySizingCheckFlag = true; // need to resize after getInput is read in again
10352 0 : this->m_OKToPrintSizing = true; // hope first time back through finds the data, else multiple prints to the eio
10353 0 : this->m_airLoopReturnCounter += 1;
10354 0 : if (this->m_airLoopReturnCounter < 3) {
10355 0 : return;
10356 : }
10357 : }
10358 : // setup zone equipment sequence information based on finding matching air terminal
10359 2 : if (state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex > 0) {
10360 2 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex)
10361 2 : .getPrioritiesForInletNode(state, zoneInlet, this->m_ZoneSequenceCoolingNum, this->m_ZoneSequenceHeatingNum);
10362 : }
10363 2 : this->m_MyCheckFlag = false;
10364 2 : if (this->m_ZoneSequenceCoolingNum == 0 || this->m_ZoneSequenceHeatingNum == 0) {
10365 0 : ShowSevereError(state,
10366 0 : format("{} \"{}\": Airloop air terminal in the zone equipment list for zone = {} not it or is not allowed "
10367 : "Zone Equipment Cooling or Heating Sequence = 0.",
10368 0 : this->UnitType,
10369 0 : this->Name,
10370 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10371 0 : ShowFatalError(
10372 : state,
10373 0 : format("Subroutine InitLoadBasedControl: Errors it in getting {} input. Preceding condition(s) causes termination.",
10374 0 : this->UnitType));
10375 : }
10376 : }
10377 7030 : if (this->m_ZoneInletNode == 0) {
10378 0 : ShowSevereError(state,
10379 0 : format("{} \"{}\": The zone inlet node in the controlled zone ({}) is not found.",
10380 0 : this->UnitType,
10381 0 : this->Name,
10382 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10383 0 : ShowFatalError(
10384 : state,
10385 0 : format("Subroutine InitLoadBasedControl: Errors found in getting {} input. Preceding condition(s) causes termination.",
10386 0 : this->UnitType));
10387 : }
10388 : }
10389 :
10390 : // What type of logic is this? Is the point to go through the main IF once? or every other time?
10391 : // RR: This was used with AirflowNetwork to calculate duct losses.
10392 : // RR: AFN counts the number of passes through airloop equipment (same logic in Furnaces and other modules) and resets the counter to 0 on
10393 : // BeginEnvrnFlag. RR: This has been changed in this module and AFN to use AirflowNetworkFanActivated if AirflowNetworkUnitarySystem is seen
10394 : // by AFN. RR: Search for AirflowNetworkFanActivated in this module to see usage. The following lines of code can probably be removed although
10395 : // it would require a AFN input file to test.
10396 7036 : if (state.dataGlobal->BeginEnvrnFlag && m_initLoadBasedControlAirLoopPass) {
10397 10 : m_airLoopPassCounter = 0;
10398 10 : m_initLoadBasedControlAirLoopPass = false;
10399 : }
10400 7036 : if (!state.dataGlobal->BeginEnvrnFlag) {
10401 6911 : this->m_MyEnvrnFlag2 = true; // this does not appear to be needed, only initializes autosized coil fluid flow rates
10402 6911 : m_initLoadBasedControlAirLoopPass = true;
10403 : }
10404 :
10405 7036 : ++m_airLoopPassCounter;
10406 7036 : if (m_airLoopPassCounter > 2) {
10407 3492 : m_airLoopPassCounter = 1;
10408 : }
10409 :
10410 : // reset duct losses from previous iteration
10411 7036 : if (FirstHVACIteration) {
10412 3485 : this->m_SenLoadLoss = 0.0;
10413 3485 : this->m_LatLoadLoss = 0.0;
10414 : }
10415 :
10416 : // Calculate air distribution losses
10417 7036 : if (!FirstHVACIteration && state.afn->AirflowNetworkFanActivated) {
10418 0 : Real64 DeltaMassRate = 0.0;
10419 0 : Real64 TotalOutput = 0.0; // total output rate, {W}
10420 0 : Real64 SensibleOutputDelta = 0.0; // delta sensible output rate, {W}
10421 0 : Real64 LatentOutputDelta = 0.0; // delta latent output rate, {W}
10422 0 : Real64 TotalOutputDelta = 0.0; // delta total output rate, {W}
10423 0 : int ZoneInNode = this->m_ZoneInletNode;
10424 0 : Real64 MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10425 0 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
10426 0 : this->m_sysType != SysType::PackagedWSHP) {
10427 0 : DeltaMassRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate -
10428 0 : state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10429 0 : if (DeltaMassRate < 0.0) {
10430 0 : DeltaMassRate = 0.0;
10431 : }
10432 : } else {
10433 0 : MassFlowRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
10434 0 : DeltaMassRate = 0.0;
10435 : }
10436 0 : CalcComponentSensibleLatentOutput(MassFlowRate,
10437 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10438 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10439 0 : state.dataLoopNodes->Node(ZoneInNode).Temp,
10440 0 : state.dataLoopNodes->Node(ZoneInNode).HumRat,
10441 0 : this->m_SenLoadLoss,
10442 0 : this->m_LatLoadLoss,
10443 : TotalOutput);
10444 0 : CalcComponentSensibleLatentOutput(DeltaMassRate,
10445 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10446 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10447 0 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
10448 0 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
10449 : SensibleOutputDelta,
10450 : LatentOutputDelta,
10451 : TotalOutputDelta);
10452 0 : this->m_SenLoadLoss = this->m_SenLoadLoss + SensibleOutputDelta;
10453 0 : if (std::abs(this->m_SensibleLoadMet) > 0.0) {
10454 0 : if (std::abs(this->m_SenLoadLoss / this->m_SensibleLoadMet) < 0.001) {
10455 0 : this->m_SenLoadLoss = 0.0;
10456 : }
10457 : }
10458 0 : if (this->m_Humidistat) {
10459 0 : this->m_LatLoadLoss = this->m_LatLoadLoss + LatentOutputDelta;
10460 0 : if (std::abs(this->m_LatentLoadMet) > 0.0) {
10461 0 : if (std::abs(this->m_LatLoadLoss / this->m_LatentLoadMet) < 0.001) {
10462 0 : this->m_LatLoadLoss = 0.0;
10463 : }
10464 : }
10465 : }
10466 : }
10467 :
10468 7036 : if (this->m_fanOpModeSched != nullptr) {
10469 7019 : if (this->m_fanOpModeSched->getCurrentVal() == 0.0) {
10470 6984 : this->m_FanOpMode = HVAC::FanOp::Cycling;
10471 : } else {
10472 35 : this->m_FanOpMode = HVAC::FanOp::Continuous;
10473 35 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10474 : }
10475 : }
10476 :
10477 : // System load calculation for cycling fan systems
10478 7036 : if (this->ControlZoneMassFlowFrac > 0.0) {
10479 7020 : QZnReq = ZoneLoad / this->ControlZoneMassFlowFrac;
10480 7020 : state.dataUnitarySystems->MoistureLoad /= this->ControlZoneMassFlowFrac;
10481 7020 : state.dataUnitarySystems->QToCoolSetPt /= this->ControlZoneMassFlowFrac;
10482 7020 : state.dataUnitarySystems->QToHeatSetPt /= this->ControlZoneMassFlowFrac;
10483 7020 : ZoneLoad = QZnReq;
10484 : } else {
10485 16 : QZnReq = ZoneLoad;
10486 16 : this->ControlZoneMassFlowFrac = 1.0;
10487 : }
10488 :
10489 7036 : state.dataUnitarySystems->CoolingLoad = false;
10490 7036 : state.dataUnitarySystems->HeatingLoad = false;
10491 7036 : Real64 smallLoadTolerance = this->m_SmallLoadTolerance;
10492 7036 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10493 6979 : smallLoadTolerance = HVAC::SmallLoad;
10494 : }
10495 7036 : if (QZnReq > smallLoadTolerance) { // no need to check deadband flag, QZnReq is correct.
10496 2750 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
10497 2750 : state.dataUnitarySystems->HeatingLoad = true;
10498 : }
10499 4286 : } else if (QZnReq < -smallLoadTolerance) {
10500 1536 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
10501 1536 : state.dataUnitarySystems->CoolingLoad = true;
10502 : }
10503 : }
10504 :
10505 : // System load calculation for constant fan systems
10506 7036 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10507 35 : bool HXUnitOn = false;
10508 35 : this->FanPartLoadRatio = 0.0; // sets fan to minimum for ASHRAE model
10509 35 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10510 : // the SpeedNum is set for PTUnits, might need to set this for all multi/var speed coils?
10511 19 : if (state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) {
10512 0 : m_CoolingSpeedNum = 1;
10513 19 : } else if (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil) {
10514 0 : m_HeatingSpeedNum = 1;
10515 : }
10516 : }
10517 35 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio,
10518 : 0.0); // CompOnMassFlow and CompOffMassFlow are scalar, reset to this system's values
10519 35 : this->calcUnitarySystemToLoad(state,
10520 : AirLoopNum,
10521 : FirstHVACIteration,
10522 : 0.0,
10523 : 0.0,
10524 : OnOffAirFlowRatio,
10525 : SensOutputOff,
10526 : LatOutputOff,
10527 : HXUnitOn,
10528 : HeatCoilLoad,
10529 : SupHeaterLoad,
10530 : CompressorOn);
10531 :
10532 35 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
10533 8 : case HVAC::SetptType::SingleHeat: {
10534 8 : state.dataUnitarySystems->CoolingLoad = false;
10535 : // No heating load and constant fan pushes zone below heating set point
10536 10 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt <= 0.0 &&
10537 2 : SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10538 2 : state.dataUnitarySystems->HeatingLoad = true;
10539 2 : state.dataUnitarySystems->CoolingLoad = false;
10540 2 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10541 : }
10542 8 : } break;
10543 :
10544 2 : case HVAC::SetptType::SingleCool: {
10545 2 : state.dataUnitarySystems->HeatingLoad = false;
10546 : // No heating load and constant fan pushes zone above cooling set point
10547 2 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
10548 0 : SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10549 0 : state.dataUnitarySystems->HeatingLoad = false;
10550 0 : state.dataUnitarySystems->CoolingLoad = true;
10551 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10552 : }
10553 2 : } break;
10554 :
10555 0 : case HVAC::SetptType::SingleHeatCool: {
10556 : // zone temp above cooling and heating set point temps
10557 0 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10558 : // zone pushed below heating set point
10559 0 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10560 0 : state.dataUnitarySystems->HeatingLoad = true;
10561 0 : state.dataUnitarySystems->CoolingLoad = false;
10562 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10563 : }
10564 : // zone temp below heating set point temp
10565 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10566 : // zone pushed above cooling set point
10567 0 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10568 0 : state.dataUnitarySystems->HeatingLoad = false;
10569 0 : state.dataUnitarySystems->CoolingLoad = true;
10570 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10571 : }
10572 : }
10573 0 : } break;
10574 :
10575 25 : case HVAC::SetptType::DualHeatCool: {
10576 : // zone temp above cooling and heating set point temps
10577 25 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10578 : // zone pushed into deadband
10579 14 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10580 2 : state.dataUnitarySystems->HeatingLoad = false;
10581 2 : state.dataUnitarySystems->CoolingLoad = false;
10582 2 : ZoneLoad = 0.0;
10583 : }
10584 : // zone pushed below heating set point
10585 14 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10586 2 : state.dataUnitarySystems->HeatingLoad = true;
10587 2 : state.dataUnitarySystems->CoolingLoad = false;
10588 2 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10589 : }
10590 : // zone temp below heating set point temp
10591 11 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10592 : // zone pushed into deadband
10593 4 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt > HVAC::SmallLoad) {
10594 0 : state.dataUnitarySystems->HeatingLoad = false;
10595 0 : state.dataUnitarySystems->CoolingLoad = false;
10596 0 : ZoneLoad = 0.0;
10597 : }
10598 : // zone pushed above cooling set point
10599 4 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10600 0 : state.dataUnitarySystems->HeatingLoad = false;
10601 0 : state.dataUnitarySystems->CoolingLoad = true;
10602 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10603 : }
10604 : // zone temp between set point temps
10605 7 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10606 : // zone pushed below heating set point
10607 2 : if (SensOutputOff < 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10608 0 : state.dataUnitarySystems->HeatingLoad = true;
10609 0 : state.dataUnitarySystems->CoolingLoad = false;
10610 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10611 : // zone pushed above cooling set point
10612 2 : } else if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10613 0 : state.dataUnitarySystems->HeatingLoad = false;
10614 0 : state.dataUnitarySystems->CoolingLoad = true;
10615 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10616 : }
10617 : }
10618 25 : } break;
10619 :
10620 0 : default: {
10621 0 : } break;
10622 : } // switch
10623 :
10624 : // push iteration mode stack and set current mode
10625 35 : this->m_IterationMode[2] = this->m_IterationMode[1];
10626 35 : this->m_IterationMode[1] = this->m_IterationMode[0];
10627 35 : if (state.dataUnitarySystems->CoolingLoad) {
10628 13 : this->m_IterationMode[0] = CoolingMode;
10629 22 : } else if (state.dataUnitarySystems->HeatingLoad) {
10630 17 : this->m_IterationMode[0] = HeatingMode;
10631 : } else {
10632 5 : this->m_IterationMode[0] = NoCoolHeat;
10633 : }
10634 : // IF small loads to meet or not converging, just shut down unit
10635 35 : if (std::abs(ZoneLoad) < smallLoadTolerance) {
10636 6 : ZoneLoad = 0.0;
10637 6 : state.dataUnitarySystems->CoolingLoad = false;
10638 6 : state.dataUnitarySystems->HeatingLoad = false;
10639 29 : } else if (this->m_IterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 6)) {
10640 : // attempt to lock output (air flow) if oscillations are detected
10641 4 : int OperatingMode = this->m_IterationMode[0]; // VS systems can take a few more iterations than single-speed systems
10642 4 : int OperatingModeMinusOne = this->m_IterationMode[1];
10643 4 : int OperatingModeMinusTwo = this->m_IterationMode[2];
10644 4 : bool Oscillate = true;
10645 4 : if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) {
10646 3 : Oscillate = false;
10647 : }
10648 4 : if (Oscillate) {
10649 1 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10650 1 : state.dataUnitarySystems->HeatingLoad = false;
10651 1 : state.dataUnitarySystems->CoolingLoad = true;
10652 1 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10653 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0) {
10654 0 : state.dataUnitarySystems->HeatingLoad = true;
10655 0 : state.dataUnitarySystems->CoolingLoad = false;
10656 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10657 : } else {
10658 0 : state.dataUnitarySystems->HeatingLoad = false;
10659 0 : state.dataUnitarySystems->CoolingLoad = false;
10660 0 : ZoneLoad = 0.0;
10661 : }
10662 : }
10663 : }
10664 : }
10665 :
10666 : // Determine the m_Staged status
10667 7036 : if (allocated(state.dataZoneCtrls->StageZoneLogic) && this->m_DesignSpecMSHPIndex > -1) {
10668 3 : if (state.dataZoneCtrls->StageZoneLogic(this->ControlZoneNum)) {
10669 3 : this->m_Staged = true;
10670 3 : this->m_StageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).StageNum;
10671 : } else {
10672 0 : if (this->m_MyStagedFlag) {
10673 0 : ShowWarningError(state,
10674 : "ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to this UnitarySystem "
10675 : "object with UnitarySystemPerformance:Multispeed type = ");
10676 0 : ShowContinueError(state, format("{}. Please make correction. Simulation continues...", this->Name));
10677 0 : this->m_MyStagedFlag = false;
10678 : }
10679 : }
10680 : }
10681 :
10682 : // Staged control
10683 7036 : if (this->m_Staged) {
10684 3 : if (this->m_StageNum == 0) {
10685 1 : state.dataUnitarySystems->HeatingLoad = false;
10686 1 : state.dataUnitarySystems->CoolingLoad = false;
10687 1 : QZnReq = 0.0;
10688 : } else {
10689 2 : QZnReq =
10690 2 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired / this->ControlZoneMassFlowFrac;
10691 2 : if (QZnReq > 0.0) {
10692 1 : state.dataUnitarySystems->HeatingLoad = true;
10693 1 : state.dataUnitarySystems->CoolingLoad = false;
10694 : } else {
10695 1 : state.dataUnitarySystems->HeatingLoad = false;
10696 1 : state.dataUnitarySystems->CoolingLoad = true;
10697 : }
10698 : }
10699 : }
10700 :
10701 7036 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10702 2 : if (state.dataUnitarySystems->HeatingLoad) {
10703 0 : state.dataUnitarySystems->MoistureLoad = 0.0;
10704 : }
10705 : }
10706 :
10707 : // Check load control
10708 7036 : if (this->m_RunOnLatentOnlyWithSensible && ZoneLoad == 0.0) {
10709 0 : state.dataUnitarySystems->MoistureLoad = 0.0;
10710 : }
10711 7036 : if (!this->m_RunOnSensibleLoad) {
10712 0 : ZoneLoad = 0.0;
10713 0 : state.dataUnitarySystems->CoolingLoad = false;
10714 0 : state.dataUnitarySystems->HeatingLoad = false;
10715 : }
10716 7036 : if (!this->m_RunOnLatentLoad) {
10717 7030 : state.dataUnitarySystems->MoistureLoad = 0.0;
10718 : }
10719 :
10720 : // Testing heat pump air to air with RH control with CoolReheat dehumidification control showed that when there was heating
10721 : // and moisture load, the cooling coil was turning on to meet the moisture load and reheat was then turning on to meet both
10722 : // heating load and excess cooling load caused by cooling coil. Adding the logic below caused the zone temperature,
10723 : // relative humidity, cooling/heating rate to line up for both the original and new file with unitary system object.
10724 :
10725 7036 : if (this->m_SuppCoilExists) {
10726 6984 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10727 6 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolCoilExists) {
10728 5 : state.dataUnitarySystems->HeatingLoad = false;
10729 5 : state.dataUnitarySystems->CoolingLoad = true;
10730 : }
10731 : }
10732 : }
10733 :
10734 : // set report variables for predicted sensible and latent load
10735 7036 : this->m_SensibleLoadPredicted = ZoneLoad;
10736 7036 : this->m_MoistureLoadPredicted = state.dataUnitarySystems->MoistureLoad;
10737 : }
10738 :
10739 81965 : void UnitarySys::setOnOffMassFlowRate(EnergyPlusData &state,
10740 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
10741 : Real64 const PartLoadRatio // coil part-load ratio
10742 : )
10743 : {
10744 :
10745 : // SUBROUTINE INFORMATION:
10746 : // AUTHOR Chandan Sharma
10747 : // DATE WRITTEN May 2013
10748 :
10749 : // PURPOSE OF THIS SUBROUTINE:
10750 : // This subroutine is for initializations of the components.
10751 :
10752 : // METHODOLOGY EMPLOYED:
10753 : // The unitarysystem may have alternate air flow rates
10754 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
10755 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
10756 : // based on PLR.
10757 :
10758 : // REFERENCES:
10759 : // Based on SetOnOffMassFlowRate by Richard Raustad
10760 :
10761 81965 : int HeatSpeedNum = 0;
10762 81965 : int CoolSpeedNum = 0;
10763 :
10764 81965 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10765 81965 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10766 81965 : state.dataUnitarySystems->m_massFlow1 = 0.0;
10767 81965 : state.dataUnitarySystems->m_massFlow2 = 0.0;
10768 81965 : state.dataUnitarySystems->OACompOnMassFlow = 0.0;
10769 81965 : state.dataUnitarySystems->OACompOffMassFlow = 0.0;
10770 :
10771 : // Set the compressor or coil ON mass flow rate
10772 81965 : if (state.dataUnitarySystems->HeatingLoad) {
10773 :
10774 51751 : this->m_LastMode = HeatingMode;
10775 :
10776 51751 : if (this->m_MultiOrVarSpeedHeatCoil) {
10777 :
10778 51616 : HeatSpeedNum = this->m_HeatingSpeedNum;
10779 :
10780 51616 : if (HeatSpeedNum == 0) {
10781 5475 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10782 5475 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10783 46141 : } else if (HeatSpeedNum == 1) {
10784 8372 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10785 8372 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10786 37769 : } else if (HeatSpeedNum > 1) {
10787 37769 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10788 37769 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10789 : }
10790 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10791 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10792 51616 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10793 49 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10794 2 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10795 2 : if (this->m_MultiOrVarSpeedCoolCoil) {
10796 2 : CoolSpeedNum = this->m_CoolingSpeedNum;
10797 2 : if (CoolSpeedNum < 1) {
10798 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10799 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10800 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10801 2 : } else if (CoolSpeedNum == 1) {
10802 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10803 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10804 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10805 : } else {
10806 2 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10807 2 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10808 2 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10809 : }
10810 : } else {
10811 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10812 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10813 : }
10814 2 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10815 : } else {
10816 45 : if (HeatSpeedNum == 0) {
10817 15 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10818 15 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10819 30 : } else if (HeatSpeedNum == 1) {
10820 17 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10821 17 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatMassFlowRate[HeatSpeedNum];
10822 : } else {
10823 13 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10824 13 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10825 : }
10826 45 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10827 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10828 45 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10829 45 : this->m_sysType == SysType::PackagedWSHP) {
10830 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10831 : }
10832 : }
10833 : } else { // cycling fan mode
10834 51569 : if (HeatSpeedNum <= 1) {
10835 13813 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10836 13813 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10837 : } else {
10838 37756 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10839 37756 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10840 : }
10841 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10842 51569 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10843 51569 : this->m_sysType == SysType::PackagedWSHP) {
10844 51437 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10845 : // does this assume OA flow <= min speed flow? without this there are SolveRoot failures.
10846 51437 : if (HeatSpeedNum > 1) {
10847 37690 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10848 : }
10849 : }
10850 : }
10851 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10852 : // If a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
10853 135 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10854 135 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && !this->m_DXHeatingCoil) {
10855 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10856 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10857 0 : if (CoolSpeedNum < 1) {
10858 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10859 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10860 0 : } else if (CoolSpeedNum == 1) {
10861 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10862 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10863 : } else {
10864 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10865 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10866 : }
10867 : } else { // IF (MultiOrVarSpeedCoolCoil) THEN
10868 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10869 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10870 0 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10871 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10872 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10873 : }
10874 : }
10875 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10876 : } else { // Heating load but no moisture load
10877 135 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10878 51 : this->m_sysType == SysType::PackagedWSHP) {
10879 : // this was missing for heating mode where multi speed coils are used
10880 84 : if (this->m_MultiOrVarSpeedHeatCoil) {
10881 0 : if (HeatSpeedNum == 0) {
10882 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10883 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10884 0 : } else if (HeatSpeedNum == 1) {
10885 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10886 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10887 0 : } else if (HeatSpeedNum > 1) {
10888 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10889 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10890 : }
10891 : } else {
10892 84 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10893 84 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10894 84 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10895 : }
10896 84 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10897 78 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10898 78 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10899 78 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10900 : }
10901 : } else {
10902 51 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10903 51 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10904 51 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10905 51 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10906 29 : if (this->m_AirFlowControl == UseCompFlow::On) {
10907 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10908 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10909 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10910 : } else {
10911 29 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10912 29 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10913 29 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10914 : }
10915 : }
10916 : }
10917 : }
10918 : }
10919 :
10920 : // If a cooling load exists, operate at the cooling mass flow rate
10921 30214 : } else if (state.dataUnitarySystems->CoolingLoad) {
10922 :
10923 24700 : this->m_LastMode = CoolingMode;
10924 :
10925 24700 : if (this->m_MultiOrVarSpeedCoolCoil) {
10926 :
10927 24350 : CoolSpeedNum = this->m_CoolingSpeedNum;
10928 :
10929 24350 : if (CoolSpeedNum == 0) {
10930 3002 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10931 3002 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10932 3002 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10933 21348 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation; set system flow rate to economizer flow rate
10934 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10935 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10936 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10937 21348 : } else if (CoolSpeedNum > 0) {
10938 21348 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10939 21348 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10940 21348 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10941 : }
10942 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10943 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10944 24350 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10945 27 : if (CoolSpeedNum == 0) {
10946 7 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10947 7 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10948 7 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10949 20 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10950 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10951 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10952 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10953 20 : } else if (CoolSpeedNum == 1) {
10954 16 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10955 16 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10956 16 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10957 : } else {
10958 4 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10959 4 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10960 4 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10961 : }
10962 : } else { // cycling fan mode
10963 24323 : if (this->m_EconoSpeedNum == 0 && CoolSpeedNum == 0) { // multi-stage economizer operation
10964 2995 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10965 2995 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10966 21328 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10967 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
10968 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum - 1];
10969 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10970 21328 : } else if (CoolSpeedNum == 0) {
10971 0 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10972 0 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10973 : } else {
10974 21328 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10975 21328 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10976 21328 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10977 : }
10978 : }
10979 : } else {
10980 350 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10981 350 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10982 350 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10983 350 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10984 109 : if (this->m_AirFlowControl == UseCompFlow::On) {
10985 92 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10986 92 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10987 92 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10988 : } else {
10989 17 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10990 17 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10991 17 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10992 : }
10993 : }
10994 : }
10995 :
10996 : } else { // No load
10997 : // If no load exists, set the compressor on mass flow rate.
10998 : // Set equal the mass flow rate when no heating or cooling is needed If no moisture load exists.
10999 : // If the user has set the off mass flow rate to 0, set according to the last operating mode.
11000 :
11001 5514 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
11002 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
11003 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
11004 0 : if (CoolSpeedNum < 1) {
11005 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11006 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11007 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11008 0 : } else if (CoolSpeedNum == 1) {
11009 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
11010 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
11011 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11012 : } else {
11013 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
11014 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
11015 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11016 : }
11017 :
11018 0 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11019 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
11020 0 : if (CoolSpeedNum <= 1) {
11021 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11022 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11023 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11024 : } else {
11025 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
11026 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
11027 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11028 : }
11029 : } else {
11030 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11031 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11032 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11033 : }
11034 : }
11035 :
11036 : } else { // IF (MultiOrVarSpeedCoolCoil(UnitarySysNum)) THEN
11037 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
11038 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
11039 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
11040 0 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11041 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
11042 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
11043 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11044 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11045 : } else {
11046 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11047 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11048 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11049 : }
11050 : }
11051 : }
11052 :
11053 : } else { // No Moisture Load
11054 :
11055 5514 : if (this->m_LastMode == HeatingMode) {
11056 : // this needs to be corrected to include UseCompressorOnFlow
11057 653 : if (this->m_MultiOrVarSpeedHeatCoil) {
11058 633 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11059 633 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11060 : } else {
11061 20 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11062 20 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
11063 : }
11064 : // this needs to happen regardless of system except maybe the CoilSystem objects
11065 : // do this only for PTUnit for the time being to reduce diffs for the PTUnit to UnitarySystem conversion
11066 653 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
11067 633 : this->m_sysType == SysType::PackagedWSHP) {
11068 652 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11069 18 : if (this->m_AirFlowControl == UseCompFlow::On) {
11070 16 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11071 16 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11072 16 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11073 : }
11074 : }
11075 : }
11076 : } else {
11077 : // this needs to be corrected to include UseCompressorOnFlow
11078 4861 : if (this->m_MultiOrVarSpeedCoolCoil) {
11079 4859 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11080 4859 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11081 : } else {
11082 2 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11083 2 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
11084 : }
11085 : }
11086 5514 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11087 5514 : if (state.dataUnitarySystems->CompOnMassFlow == 0.0) {
11088 2991 : if (this->m_LastMode == HeatingMode) {
11089 369 : if (this->m_MultiOrVarSpeedHeatCoil) {
11090 355 : HeatSpeedNum = this->m_HeatingSpeedNum;
11091 355 : if (HeatSpeedNum == 0) {
11092 354 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11093 354 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11094 1 : } else if (HeatSpeedNum == 1) {
11095 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
11096 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
11097 1 : } else if (HeatSpeedNum > 1) {
11098 1 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
11099 1 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
11100 : }
11101 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
11102 14 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
11103 14 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
11104 : }
11105 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11106 2622 : if (this->m_MultiOrVarSpeedCoolCoil) {
11107 2620 : CoolSpeedNum = this->m_CoolingSpeedNum;
11108 2620 : if (CoolSpeedNum == 0) {
11109 2620 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
11110 2620 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
11111 0 : } else if (CoolSpeedNum == 1) {
11112 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
11113 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
11114 0 : } else if (CoolSpeedNum > 1) {
11115 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
11116 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
11117 : }
11118 : } else { // IF(MultiOrVarSpeedCoolCoil) THEN
11119 2 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
11120 2 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
11121 : } // IF(MultiOrVarSpeedCoolCoil) THEN
11122 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11123 : } // IF(CompOnMassFlow .EQ. 0.0d0)THEN
11124 :
11125 5514 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11126 28 : if (this->m_AirFlowControl == UseCompFlow::On) {
11127 17 : if (this->m_LastMode == HeatingMode) {
11128 17 : if (this->m_MultiOrVarSpeedHeatCoil) {
11129 1 : HeatSpeedNum = this->m_HeatingSpeedNum;
11130 1 : if (HeatSpeedNum < 1) {
11131 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11132 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11133 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11134 1 : } else if (HeatSpeedNum == 1) {
11135 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[1];
11136 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[1];
11137 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11138 : } else {
11139 1 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
11140 1 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
11141 1 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11142 : }
11143 : } else {
11144 : // this is a no load case, added if for PTUnit to correct this for PTUnit to UnitarySystem conversion
11145 : // the else is incorrect?
11146 16 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
11147 0 : this->m_sysType == SysType::PackagedWSHP) {
11148 16 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11149 16 : if (this->m_AirFlowControl == UseCompFlow::On) {
11150 16 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11151 16 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11152 16 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11153 : }
11154 : }
11155 : } else {
11156 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
11157 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11158 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11159 : }
11160 : }
11161 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11162 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
11163 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
11164 0 : if (CoolSpeedNum < 1) {
11165 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11166 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11167 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11168 0 : } else if (CoolSpeedNum == 1) {
11169 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
11170 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
11171 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11172 : } else {
11173 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
11174 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
11175 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11176 : }
11177 : } else {
11178 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
11179 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11180 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11181 : }
11182 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
11183 : } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
11184 11 : if (this->m_LastMode == HeatingMode) {
11185 2 : if (this->m_MultiOrVarSpeedHeatCoil) {
11186 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11187 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11188 : } else {
11189 2 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11190 2 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
11191 : }
11192 : } else {
11193 9 : if (this->m_MultiOrVarSpeedCoolCoil) {
11194 9 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11195 9 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
11196 : } else {
11197 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
11198 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
11199 : }
11200 : }
11201 11 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
11202 : } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
11203 : } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN
11204 : } // ELSE ! No Moisture Load
11205 : } // No Heating/Cooling Load
11206 :
11207 81965 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11208 318 : if (this->m_AirFlowControl == UseCompFlow::On &&
11209 132 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)) {
11210 118 : if (this->m_LastMode == HeatingMode) {
11211 26 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
11212 : } else {
11213 92 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
11214 : }
11215 : }
11216 : }
11217 :
11218 81965 : if (this->m_MultiSpeedHeatingCoil && (state.dataUnitarySystems->HeatingLoad && HeatSpeedNum == 1)) {
11219 4263 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
11220 77702 : } else if (this->m_DiscreteSpeedCoolingCoil && (state.dataUnitarySystems->CoolingLoad && CoolSpeedNum == 1)) {
11221 4209 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
11222 : } else {
11223 73493 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOffMassFlow; // these need to be set for multi-speed coils
11224 : }
11225 163930 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
11226 81965 : state.dataUnitarySystems->CompOnMassFlow; // doesn't hurt to set these if multi-speed coils are not used
11227 81965 : state.dataHVACGlobal->MSUSEconoSpeedNum = this->m_EconoSpeedNum;
11228 :
11229 81965 : state.dataUnitarySystems->m_massFlow1 = state.dataUnitarySystems->CompOnMassFlow;
11230 81965 : state.dataUnitarySystems->m_massFlow2 = state.dataUnitarySystems->CompOffMassFlow;
11231 :
11232 : // Set the system mass flow rates
11233 81965 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
11234 81965 : }
11235 :
11236 106704 : void UnitarySys::setAverageAirFlow(EnergyPlusData &state,
11237 : Real64 const PartLoadRatio, // unit part load ratio
11238 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
11239 : )
11240 : {
11241 :
11242 : // SUBROUTINE INFORMATION:
11243 : // AUTHOR Richard Raustad
11244 : // DATE WRITTEN July 2005
11245 :
11246 : // PURPOSE OF THIS SUBROUTINE:
11247 : // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
11248 : // Set OnOffAirFlowRatio to be used by DX coils
11249 :
11250 : // METHODOLOGY EMPLOYED:
11251 : // The air flow rate in cooling, heating, and no cooling or heating can be different.
11252 : // Calculate the air flow rate based on initializations.
11253 :
11254 106704 : Real64 AverageUnitMassFlow = 0.0; // average supply air mass flow rate over time step
11255 106704 : bool FanOn = false;
11256 :
11257 106704 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
11258 106704 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11259 :
11260 106704 : Real64 FanPartLoadRatio = PartLoadRatio;
11261 106704 : if (this->m_SimASHRAEModel) {
11262 239 : FanPartLoadRatio = this->FanPartLoadRatio;
11263 : }
11264 106704 : if (this->m_EconoPartLoadRatio > 0) {
11265 0 : FanPartLoadRatio = this->m_EconoPartLoadRatio;
11266 : }
11267 106704 : int SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum, this->m_EconoSpeedNum);
11268 106704 : int InletNode = this->AirInNode;
11269 :
11270 106704 : if (SpeedNum > 1) {
11271 129570 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11272 55196 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11273 74372 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11274 19 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow +
11275 19 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow;
11276 : } else {
11277 74353 : Real64 tempSpeedRatio = 0;
11278 74353 : if (this->m_EconoPartLoadRatio > 0) {
11279 0 : tempSpeedRatio = this->FanPartLoadRatio;
11280 : } else {
11281 74353 : tempSpeedRatio = state.dataUnitarySystems->CoolingLoad ? this->m_CoolingSpeedRatio : this->m_HeatingSpeedRatio;
11282 : }
11283 74353 : AverageUnitMassFlow = tempSpeedRatio * state.dataUnitarySystems->CompOnMassFlow +
11284 74353 : (1.0 - tempSpeedRatio) * state.dataUnitarySystems->CompOffMassFlow;
11285 : }
11286 : } else {
11287 2 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11288 : }
11289 : } else {
11290 32330 : AverageUnitMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow) +
11291 32330 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow);
11292 : }
11293 :
11294 106704 : if (state.dataUnitarySystems->CompOffFlowRatio > 0.0) {
11295 74818 : if (SpeedNum > 1) {
11296 129570 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11297 55196 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11298 74372 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio +
11299 74372 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio;
11300 74372 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11301 74372 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11302 : } else {
11303 2 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11304 2 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11305 2 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11306 : }
11307 : } else {
11308 444 : state.dataUnitarySystems->FanSpeedRatio = (FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio) +
11309 444 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio);
11310 444 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11311 444 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11312 : }
11313 : } else {
11314 31886 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11315 31886 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11316 31886 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11317 : }
11318 :
11319 106704 : if (!(state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating == 0)) {
11320 106435 : if (this->m_SingleMode == 1) {
11321 51 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11322 0 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11323 0 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11324 0 : state.dataUnitarySystems->m_runTimeFraction1 = 1.0;
11325 0 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11326 : } else {
11327 51 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow;
11328 51 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio;
11329 51 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11330 51 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11331 : }
11332 : }
11333 : }
11334 :
11335 106704 : if (this->OAMixerExists) {
11336 95 : Real64 AverageOAMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->OACompOnMassFlow) +
11337 95 : ((1 - FanPartLoadRatio) * state.dataUnitarySystems->OACompOffMassFlow);
11338 :
11339 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = AverageOAMassFlow;
11340 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = AverageOAMassFlow;
11341 : // don't need to set relief node, delete them when working
11342 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = AverageOAMassFlow;
11343 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = AverageOAMassFlow;
11344 : }
11345 :
11346 : // BEGIN - refactor/move this to Init during FirstHVACIteration, need struct or module level global for turnFansOn and turnFansOff
11347 : // If the unitary system is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
11348 106704 : FanOn = (this->m_FanExists) ? (this->m_fanAvailSched->getCurrentVal() > 0) : true;
11349 : // END - move this to Init during FirstHVACIteration
11350 :
11351 106704 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && ((FanOn || state.dataHVACGlobal->TurnFansOn) && !state.dataHVACGlobal->TurnFansOff)) {
11352 106677 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11353 : // set point based equipment should use VAV terminal units to set the flow.
11354 : // zone equipment needs to set flow since no other device regulates flow (ZoneHVAC /= AirLoopEquipment)
11355 49 : if (!this->m_AirLoopEquipment) {
11356 43 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11357 43 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11358 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11359 : }
11360 49 : if (AverageUnitMassFlow > 0.0) {
11361 40 : OnOffAirFlowRatio = 1.0;
11362 : } else {
11363 9 : OnOffAirFlowRatio = 0.0;
11364 : }
11365 : } else {
11366 106628 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11367 106628 : if (!this->m_AirLoopEquipment) {
11368 106464 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11369 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11370 : }
11371 106628 : if (AverageUnitMassFlow > 0.0) {
11372 83077 : if (SpeedNum > 1) {
11373 74344 : OnOffAirFlowRatio = 1.0;
11374 : } else {
11375 8733 : OnOffAirFlowRatio = state.dataUnitarySystems->CompOnMassFlow / AverageUnitMassFlow;
11376 : }
11377 : } else {
11378 23551 : OnOffAirFlowRatio = 0.0;
11379 : }
11380 : }
11381 : } else {
11382 27 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
11383 : // fan will turn on unless these are reset, or maybe one of them. Might be a better way when calling fan.
11384 27 : state.dataUnitarySystems->m_massFlow1 = 0.0;
11385 27 : state.dataUnitarySystems->m_massFlow2 = 0.0;
11386 27 : OnOffAirFlowRatio = 1.0;
11387 27 : if (this->OAMixerExists) {
11388 : // maybe can just set MaxAvail = 0?
11389 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = 0.0;
11390 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = 0.0;
11391 : // don't need to set relief node, delete then when working
11392 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = 0.0;
11393 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = 0.0;
11394 : }
11395 : }
11396 106704 : }
11397 :
11398 66511 : void UnitarySys::calcUnitarySystemToLoad(EnergyPlusData &state,
11399 : int const AirLoopNum, // index to air loop
11400 : bool const FirstHVACIteration, // True when first HVAC iteration
11401 : Real64 const CoolPLR, // operating cooling part-load ratio []
11402 : Real64 const HeatPLR, // operating cooling part-load ratio []
11403 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
11404 : Real64 &SensOutput, // sensible capacity (W)
11405 : Real64 &LatOutput, // latent capacity (W)
11406 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
11407 : Real64 HeatCoilLoad, // Adjusted load to heating coil when SAT exceeds max limit (W)
11408 : Real64 SuppCoilLoad, // Adjusted load to supp heating coil when SAT exceeds max limit (W)
11409 : HVAC::CompressorOp const CompressorOn // Determines if compressor is on or off
11410 : )
11411 : {
11412 :
11413 : // SUBROUTINE INFORMATION:
11414 : // AUTHOR Richard Raustad, FSEC
11415 : // DATE WRITTEN February 2013
11416 :
11417 : // PURPOSE OF THIS SUBROUTINE:
11418 : // This subroutine calculates the resulting performance of the unitary system given
11419 : // the operating PLR. System output is calculated with respect to zone condition.
11420 :
11421 66511 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
11422 :
11423 66511 : HVAC::CompressorOp CoolingCompOn = HVAC::CompressorOp::Off;
11424 66511 : if (CoolPLR > 0) {
11425 15579 : CoolingCompOn = CompressorOn;
11426 50932 : } else if (CoolPLR == 0 && this->m_EconoSpeedNum > 0) { // turn compressor off for economizer calculations
11427 0 : CoolingCompOn = HVAC::CompressorOp::Off;
11428 50932 : } else if (this->m_CoolingSpeedNum > 1) { // for multispeed coils, comp is on IF speed > 1
11429 1044 : CoolingCompOn = HVAC::CompressorOp::On;
11430 : }
11431 :
11432 66511 : HVAC::CompressorOp HeatingCompOn = HVAC::CompressorOp::Off;
11433 66511 : if (HeatPLR > 0) {
11434 35338 : HeatingCompOn = CompressorOn;
11435 35338 : CoilCoolHeatRat = min(1.0, CoolPLR / HeatPLR);
11436 : }
11437 : // for multispeed coils, comp is on at PLR=0 IF speed > 1
11438 66511 : if (this->m_HeatingSpeedNum > 1) {
11439 35030 : HeatingCompOn = HVAC::CompressorOp::On;
11440 : }
11441 :
11442 : // set the operating flow rate
11443 66511 : if (this->m_NumOfSpeedCooling > 0 || this->m_NumOfSpeedHeating > 0) {
11444 66299 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, max(CoolPLR, HeatPLR));
11445 : } else {
11446 212 : this->setAverageAirFlow(state, max(CoolPLR, HeatPLR), OnOffAirFlowRatio);
11447 : }
11448 :
11449 : // Call the series of components that simulate a Unitary System
11450 66511 : if (this->ATMixerExists) {
11451 : // There is an air terminal mixer
11452 65899 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
11453 : // set the primary air inlet mass flow rate
11454 65836 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
11455 65836 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
11456 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
11457 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
11458 65836 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11459 : }
11460 : }
11461 66511 : if (this->OAMixerExists) {
11462 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
11463 : // use of a blank std::string is not great here, but I'm not ready to change this API at the moment, so passing a static blank string is
11464 : // at least better than constructing a new string each time to call this function
11465 65 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
11466 : }
11467 :
11468 66511 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
11469 66507 : state.dataFans->fans(this->m_FanIndex)
11470 199521 : ->simulate(state,
11471 : FirstHVACIteration,
11472 66507 : state.dataUnitarySystems->FanSpeedRatio,
11473 : _, // Pressure rise
11474 : _, // Flow fraction
11475 66507 : state.dataUnitarySystems->m_massFlow1,
11476 66507 : state.dataUnitarySystems->m_runTimeFraction1,
11477 66507 : state.dataUnitarySystems->m_massFlow2,
11478 66507 : state.dataUnitarySystems->m_runTimeFraction2,
11479 : _);
11480 : }
11481 :
11482 66511 : if (this->m_CoolingCoilUpstream) {
11483 :
11484 66438 : if (this->m_CoolCoilExists) {
11485 66438 : this->calcUnitaryCoolingSystem(
11486 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11487 : }
11488 66438 : if (this->m_HeatCoilExists) {
11489 : // operate the heating coil without regard to coil outlet temperature
11490 66429 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11491 66429 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11492 0 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11493 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11494 0 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11495 0 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11496 0 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11497 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11498 0 : HeatCoilLoad = MaxHeatCoilLoad;
11499 : }
11500 : }
11501 :
11502 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11503 66438 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11504 17826 : state.dataFans->fans(this->m_FanIndex)
11505 53478 : ->simulate(state,
11506 : FirstHVACIteration,
11507 17826 : state.dataUnitarySystems->FanSpeedRatio,
11508 : _, // Pressure rise
11509 : _, // Flow fraction
11510 17826 : state.dataUnitarySystems->m_massFlow1,
11511 17826 : state.dataUnitarySystems->m_runTimeFraction1,
11512 17826 : state.dataUnitarySystems->m_massFlow2,
11513 17826 : state.dataUnitarySystems->m_runTimeFraction2,
11514 : _);
11515 :
11516 17826 : if (this->m_CoolCoilExists) {
11517 17826 : this->calcUnitaryCoolingSystem(
11518 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11519 : }
11520 17826 : if (this->m_HeatCoilExists) {
11521 17826 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11522 17826 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11523 0 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11524 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11525 0 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11526 0 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11527 0 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11528 0 : this->calcUnitaryHeatingSystem(
11529 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11530 : }
11531 : }
11532 : }
11533 :
11534 : } else {
11535 :
11536 73 : if (this->m_HeatCoilExists) {
11537 73 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11538 73 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11539 5 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11540 5 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11541 5 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11542 5 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11543 5 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11544 5 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11545 : }
11546 : }
11547 73 : if (this->m_CoolCoilExists) {
11548 0 : this->calcUnitaryCoolingSystem(
11549 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11550 : }
11551 :
11552 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11553 73 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11554 0 : state.dataFans->fans(this->m_FanIndex)
11555 0 : ->simulate(state,
11556 : FirstHVACIteration,
11557 0 : state.dataUnitarySystems->FanSpeedRatio,
11558 : _, // Pressure rise
11559 : _, // Flow fraction
11560 0 : state.dataUnitarySystems->m_massFlow1,
11561 0 : state.dataUnitarySystems->m_runTimeFraction1,
11562 0 : state.dataUnitarySystems->m_massFlow2,
11563 0 : state.dataUnitarySystems->m_runTimeFraction2,
11564 : _);
11565 :
11566 0 : if (this->m_HeatCoilExists) {
11567 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11568 0 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11569 0 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11570 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11571 0 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11572 0 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11573 0 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11574 0 : this->calcUnitaryHeatingSystem(
11575 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11576 : }
11577 : }
11578 0 : if (this->m_CoolCoilExists) {
11579 0 : this->calcUnitaryCoolingSystem(
11580 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11581 : }
11582 : }
11583 : }
11584 :
11585 66511 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
11586 4 : state.dataFans->fans(this->m_FanIndex)
11587 12 : ->simulate(state,
11588 : FirstHVACIteration,
11589 4 : state.dataUnitarySystems->FanSpeedRatio,
11590 : _, // Pressure rise
11591 : _, // Flow fraction
11592 4 : state.dataUnitarySystems->m_massFlow1,
11593 4 : state.dataUnitarySystems->m_runTimeFraction1,
11594 4 : state.dataUnitarySystems->m_massFlow2,
11595 4 : state.dataUnitarySystems->m_runTimeFraction2,
11596 : _);
11597 : }
11598 66511 : if (this->m_SuppCoilExists) {
11599 66077 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, SuppCoilLoad);
11600 66078 : if ((state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp) && this->m_SuppHeatPartLoadFrac > 0.0 &&
11601 1 : !this->m_SimASHRAEModel) {
11602 : // EMS override will ignore this recalculation.
11603 1 : Real64 MDotAir = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).MassFlowRate;
11604 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).HumRat +
11605 1 : state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).HumRat));
11606 1 : Real64 HCDeltaT = max(0.0, this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).Temp);
11607 1 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11608 1 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, MaxHeatCoilLoad);
11609 1 : SuppCoilLoad = MaxHeatCoilLoad;
11610 : }
11611 : }
11612 :
11613 : // If there is a supply side air terminal mixer, calculate its output
11614 66511 : if (this->ATMixerExists) {
11615 65899 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11616 63 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11617 : }
11618 : }
11619 :
11620 66511 : calculateCapacity(state, SensOutput, LatOutput);
11621 66511 : }
11622 :
11623 48 : void UnitarySys::calcMultiStageSuppCoilStageByLoad(EnergyPlusData &state, Real64 const SuppHeatLoad, bool const FirstHVACIteration)
11624 : {
11625 48 : if (SuppHeatLoad <= 0.0) {
11626 43 : this->m_SuppHeatPartLoadFrac = 0.0;
11627 43 : this->m_SuppHeatingSpeedRatio = 0.0;
11628 43 : this->m_SuppHeatingCycRatio = 0.0;
11629 43 : return;
11630 : }
11631 5 : constexpr bool SuppHeatingCoilFlag(true);
11632 5 : Real64 PartLoadFrac = 0.0;
11633 5 : Real64 SpeedRatio = 0.0;
11634 5 : Real64 CycRatio = 0.0;
11635 5 : std::string CompName = this->m_SuppHeatCoilName;
11636 5 : int CompIndex = this->m_SuppHeatCoilIndex;
11637 5 : HVAC::FanOp fanOp = this->m_FanOpMode;
11638 5 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
11639 5 : int SpeedNum = 0;
11640 : // Get full load result
11641 5 : PartLoadFrac = 1.0;
11642 5 : CycRatio = 1.0;
11643 5 : SpeedRatio = 1.0;
11644 5 : int SolFla = 0;
11645 :
11646 : // SUBROUTINE PARAMETER DEFINITIONS:
11647 5 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11648 5 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
11649 :
11650 8 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
11651 8 : this->m_SuppHeatingSpeedNum = SpeedNum;
11652 8 : HeatingCoils::SimulateHeatingCoilComponents(state,
11653 : CompName,
11654 : FirstHVACIteration,
11655 : SuppHeatLoad,
11656 : CompIndex,
11657 : QCoilActual,
11658 : SuppHeatingCoilFlag,
11659 : fanOp,
11660 : PartLoadFrac,
11661 : SpeedNum,
11662 : SpeedRatio);
11663 8 : if (QCoilActual > SuppHeatLoad) {
11664 5 : break;
11665 : }
11666 : }
11667 5 : if (QCoilActual < SuppHeatLoad) {
11668 0 : this->m_SuppHeatPartLoadFrac = 1.0;
11669 0 : this->m_SuppHeatingSpeedRatio = 1.0;
11670 0 : this->m_SuppHeatingCycRatio = 1.0;
11671 0 : this->m_SuppHeatingSpeedNum = this->m_NumOfSpeedSuppHeating;
11672 0 : return;
11673 : } else {
11674 :
11675 5 : if (this->m_SuppHeatingSpeedNum > 1.0) {
11676 9 : auto f = [&state, this, CycRatio, fanOp, SuppHeatLoad](Real64 const SpeedRatio) {
11677 : Real64 QActual;
11678 9 : int CoilIndex = this->m_SuppHeatCoilIndex;
11679 9 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11680 9 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11681 9 : return SuppHeatLoad - QActual;
11682 3 : };
11683 :
11684 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
11685 3 : this->m_SuppHeatingCycRatio = CycRatio;
11686 3 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11687 3 : this->m_SuppHeatPartLoadFrac = SpeedRatio;
11688 3 : PartLoadFrac = SpeedRatio;
11689 : } else {
11690 2 : SpeedRatio = 0.0;
11691 2 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11692 6 : auto f = [&state, this, SpeedRatio, fanOp, SuppHeatLoad](Real64 const CycRatio) {
11693 : Real64 QActual;
11694 6 : int CoilIndex = this->m_SuppHeatCoilIndex;
11695 6 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11696 6 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11697 6 : return SuppHeatLoad - QActual;
11698 2 : };
11699 :
11700 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
11701 2 : this->m_SuppHeatingCycRatio = CycRatio;
11702 2 : this->m_SuppHeatPartLoadFrac = CycRatio;
11703 2 : PartLoadFrac = CycRatio;
11704 : }
11705 : }
11706 5 : }
11707 :
11708 131827 : void UnitarySys::calculateCapacity(EnergyPlusData &state, Real64 &SensOutput, Real64 &LatOutput)
11709 : {
11710 :
11711 : // Check delta T (outlet to reference temp), IF positive use reference HumRat ELSE outlet humrat to calculate
11712 : // sensible capacity as MdotDeltaH at constant humidity ratio
11713 131827 : int OutletNode = this->AirOutNode;
11714 131827 : Real64 AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
11715 131827 : Real64 RefTemp = 0.0;
11716 131827 : Real64 RefHumRat = 0.0;
11717 131827 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11718 65316 : RefTemp = state.dataLoopNodes->Node(this->AirInNode).Temp;
11719 65316 : RefHumRat = state.dataLoopNodes->Node(this->AirInNode).HumRat;
11720 : } else {
11721 66511 : RefTemp = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp;
11722 66511 : RefHumRat = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat;
11723 : }
11724 131827 : Real64 SensibleOutput(0.0); // sensible output rate, {W}
11725 131827 : Real64 LatentOutput(0.0); // latent output rate, {W}
11726 131827 : Real64 TotalOutput(0.0); // total output rate, {W}
11727 : // calculate sensible load met
11728 131827 : if (this->ATMixerExists) {
11729 65899 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11730 : // Air terminal supply side mixer
11731 63 : int ATMixOutNode = this->ATMixerOutNode;
11732 63 : CalcZoneSensibleLatentOutput(state.dataLoopNodes->Node(ATMixOutNode).MassFlowRate,
11733 63 : state.dataLoopNodes->Node(ATMixOutNode).Temp,
11734 63 : state.dataLoopNodes->Node(ATMixOutNode).HumRat,
11735 : RefTemp,
11736 : RefHumRat,
11737 : SensibleOutput,
11738 : LatentOutput,
11739 : TotalOutput);
11740 63 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11741 63 : if (this->m_Humidistat) {
11742 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11743 : } else {
11744 63 : LatOutput = 0.0;
11745 : }
11746 : } else {
11747 : // Air terminal inlet side mixer
11748 131672 : CalcZoneSensibleLatentOutput(AirMassFlow,
11749 65836 : state.dataLoopNodes->Node(OutletNode).Temp,
11750 65836 : state.dataLoopNodes->Node(OutletNode).HumRat,
11751 : RefTemp,
11752 : RefHumRat,
11753 : SensibleOutput,
11754 : LatentOutput,
11755 : TotalOutput);
11756 65836 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11757 65836 : if (this->m_Humidistat) {
11758 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11759 : } else {
11760 65836 : LatOutput = 0.0;
11761 : }
11762 : }
11763 : } else {
11764 : // Calculate sensible load met
11765 131856 : CalcZoneSensibleLatentOutput(AirMassFlow,
11766 65928 : state.dataLoopNodes->Node(OutletNode).Temp,
11767 65928 : state.dataLoopNodes->Node(OutletNode).HumRat,
11768 : RefTemp,
11769 : RefHumRat,
11770 : SensibleOutput,
11771 : LatentOutput,
11772 : TotalOutput);
11773 65928 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11774 65928 : if (this->m_Humidistat) {
11775 104 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11776 : } else {
11777 65824 : LatOutput = 0.0;
11778 : }
11779 : }
11780 131827 : this->m_SensibleLoadMet = SensOutput;
11781 131827 : this->m_LatentLoadMet = LatOutput;
11782 131827 : }
11783 :
11784 149586 : void UnitarySys::calcUnitaryCoolingSystem(EnergyPlusData &state,
11785 : int const AirLoopNum, // index to air loop
11786 : bool const FirstHVACIteration, // True when first HVAC iteration
11787 : Real64 const PartLoadRatio, // coil operating part-load ratio
11788 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11789 : Real64 const OnOffAirFlowRatio,
11790 : Real64 const CoilCoolHeatRat, // ratio of cooling to heating PLR for cycling fan RH control
11791 : bool const HXUnitOn // Flag to control HX for HXAssisted Cooling Coil
11792 : )
11793 : {
11794 :
11795 : // SUBROUTINE INFORMATION:
11796 : // AUTHOR Richard Raustad, FSEC
11797 : // DATE WRITTEN February 2013
11798 :
11799 : // PURPOSE OF THIS SUBROUTINE:
11800 : // This subroutine manages unitary cooling system component simulation.
11801 :
11802 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11803 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11804 : Real64 mdot; // water side flow rate (kg/s)
11805 : Real64 QActual; // actual coil output (W)
11806 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11807 :
11808 : // Simulate the coil component
11809 149586 : std::string CompName = this->m_CoolingCoilName;
11810 149586 : int CompIndex = this->m_CoolingCoilIndex;
11811 149586 : Real64 CoilPLR = 1.0;
11812 149586 : if (this->m_CondenserNodeNum != 0) {
11813 24867 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11814 : // IF node is not connected to anything, pressure = default, use weather data
11815 24867 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11816 91 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11817 : } else {
11818 24776 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11819 : }
11820 : } else {
11821 124719 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11822 : }
11823 :
11824 149586 : switch (this->m_CoolingCoilType_Num) {
11825 59945 : case HVAC::CoilDX_CoolingSingleSpeed: { // Coil:Cooling:DX:SingleSpeed
11826 59945 : DXCoils::SimDXCoil(state,
11827 : blankString,
11828 : CompressorOn,
11829 : FirstHVACIteration,
11830 : CompIndex,
11831 : this->m_FanOpMode,
11832 : PartLoadRatio,
11833 : OnOffAirFlowRatio,
11834 : CoilCoolHeatRat);
11835 59945 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11836 59945 : } break;
11837 91 : case HVAC::CoilDX_Cooling: { // CoilCoolingDX
11838 91 : bool const singleMode = (this->m_SingleMode == 1);
11839 91 : CoilPLR = 0.0;
11840 91 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11841 0 : if (CompressorOn == HVAC::CompressorOp::On) {
11842 0 : CoilPLR = (this->m_CoolingSpeedNum > 1) ? m_CoolingSpeedRatio : PartLoadRatio;
11843 : }
11844 : } else {
11845 91 : if (this->m_EMSOverrideCoilSpeedNumOn) {
11846 6 : CoilPLR = this->m_CoolingSpeedRatio;
11847 : } else {
11848 85 : if (state.dataUnitarySystems->CoolingLoad) {
11849 85 : if (CompressorOn == HVAC::CompressorOp::Off) {
11850 21 : if (this->m_CoolingSpeedNum > 1) { // NOTE: Cooling speed 0 should behave the same as speed 1, but doesn't, and must be
11851 : // allowed to pass into the simulation code
11852 0 : this->m_CoolingSpeedNum = 1; // Bypass mixed-speed calculations in called functions
11853 : }
11854 : } else {
11855 64 : if (singleMode) {
11856 0 : CoilPLR = (this->m_CoolingSpeedNum == 1)
11857 0 : ? PartLoadRatio
11858 : : 1.0; // singleMode allows cycling, but not part load operation at higher speeds
11859 : } else {
11860 64 : CoilPLR = PartLoadRatio;
11861 : }
11862 : }
11863 : }
11864 : }
11865 : }
11866 :
11867 91 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
11868 91 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
11869 50 : coilMode = HVAC::CoilMode::SubcoolReheat;
11870 41 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
11871 0 : coilMode = HVAC::CoilMode::Enhanced;
11872 : }
11873 :
11874 91 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
11875 : state, coilMode, this->m_CoolingSpeedNum, CoilPLR, this->m_FanOpMode, singleMode, this->CoilSHR);
11876 :
11877 91 : if (this->m_CoolingSpeedNum > 1) {
11878 20 : if (this->m_SingleMode == 0) {
11879 20 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11880 : } else {
11881 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11882 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11883 0 : this->m_CoolingSpeedRatio = 1.0;
11884 : }
11885 : } else {
11886 71 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11887 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11888 71 : this->m_CoolingSpeedRatio = 0.0;
11889 : }
11890 91 : } break;
11891 55 : case HVAC::CoilDX_CoolingHXAssisted:
11892 : case HVAC::CoilWater_CoolingHXAssisted: {
11893 55 : if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
11894 : mdot =
11895 0 : min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxCoolCoilFluidFlow * PartLoadRatio);
11896 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11897 : }
11898 110 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
11899 : blankString,
11900 : FirstHVACIteration,
11901 : CompressorOn,
11902 : PartLoadRatio,
11903 : CompIndex,
11904 : this->m_FanOpMode,
11905 : HXUnitOn,
11906 : OnOffAirFlowRatio,
11907 55 : state.dataUnitarySystems->economizerFlag,
11908 : _,
11909 55 : this->m_DehumidificationMode,
11910 55 : 0.0); // this->CoilSHR);
11911 55 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
11912 55 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11913 : }
11914 55 : } break;
11915 5665 : case HVAC::CoilDX_CoolingTwoSpeed: { // Coil:Cooling:DX:TwoSpeed
11916 : // formerly (v3 and beyond)COIL:DX:MULTISPEED:COOLINGEMPIRICAL
11917 5665 : DXCoils::SimDXCoilMultiSpeed(state, blankString, this->m_CoolingSpeedRatio, this->m_CoolingCycRatio, CompIndex);
11918 5665 : if (this->m_CoolingSpeedRatio > 0.0) {
11919 2547 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingSpeedRatio : 0.0;
11920 : } else {
11921 3118 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11922 : }
11923 5665 : } break;
11924 120 : case HVAC::CoilDX_MultiSpeedCooling: { // Coil:Cooling:DX:Multispeed
11925 120 : if (OutsideDryBulbTemp > this->m_MinOATCompressorCooling) {
11926 120 : DXCoils::SimDXCoilMultiSpeed(state,
11927 : CompName,
11928 : this->m_CoolingSpeedRatio,
11929 : this->m_CoolingCycRatio,
11930 : CompIndex,
11931 120 : this->m_CoolingSpeedNum,
11932 120 : this->m_FanOpMode,
11933 : CompressorOn,
11934 120 : this->m_SingleMode);
11935 120 : if (this->m_CoolingSpeedNum > 1) {
11936 18 : if (this->m_SingleMode == 0) {
11937 6 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11938 : } else {
11939 12 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11940 : }
11941 : } else {
11942 102 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11943 : }
11944 : } else {
11945 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 0.0, CompIndex, this->m_CoolingSpeedNum, this->m_FanOpMode, CompressorOn);
11946 0 : this->m_CoolCompPartLoadRatio = 0.0;
11947 : }
11948 120 : } break;
11949 0 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
11950 : // formerly (v3 and beyond) COIL:DX:MULTIMODE:COOLINGEMPIRICAL
11951 0 : DXCoils::SimDXCoilMultiMode(
11952 : state, CompName, CompressorOn, FirstHVACIteration, PartLoadRatio, this->m_DehumidificationMode, CompIndex, this->m_FanOpMode);
11953 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11954 0 : } break;
11955 0 : case HVAC::Coil_UserDefined: {
11956 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11957 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
11958 :
11959 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
11960 0 : } break;
11961 134 : case HVAC::Coil_CoolingWater:
11962 : case HVAC::Coil_CoolingWaterDetailed: {
11963 134 : if (this->CoolCoilWaterFlowRatio == 0.0) {
11964 112 : mdot = this->MaxCoolCoilFluidFlow * PartLoadRatio;
11965 : } else {
11966 22 : mdot = this->CoolCoilWaterFlowRatio * this->MaxCoolCoilFluidFlow;
11967 : }
11968 134 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11969 402 : WaterCoils::SimulateWaterCoilComponents(
11970 268 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11971 134 : } break;
11972 33689 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
11973 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
11974 33689 : if (this->m_CoolingSpeedNum > 1) {
11975 8715 : CoilPLR = 1.0;
11976 : } else {
11977 24974 : CoilPLR = PartLoadRatio;
11978 : }
11979 33689 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11980 : CompName,
11981 : CompIndex,
11982 : this->m_FanOpMode,
11983 : CompressorOn,
11984 : CoilPLR,
11985 : this->m_CoolingSpeedNum,
11986 : this->m_CoolingSpeedRatio,
11987 : this->m_CoolingCoilSensDemand,
11988 : this->m_CoolingCoilLatentDemand,
11989 : OnOffAirFlowRatio);
11990 33689 : if (this->m_CoolingSpeedNum > 1) {
11991 8715 : this->m_CoolCompPartLoadRatio = 1.0;
11992 : } else {
11993 24974 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11994 : }
11995 33689 : } break;
11996 49887 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
11997 :
11998 49887 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11999 : blankString,
12000 49887 : this->m_CoolingCoilIndex,
12001 : this->m_CoolingCoilSensDemand,
12002 : this->m_CoolingCoilLatentDemand,
12003 : this->m_FanOpMode,
12004 : CompressorOn,
12005 : PartLoadRatio,
12006 : FirstHVACIteration);
12007 49887 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
12008 49887 : } break;
12009 0 : case HVAC::Coil_CoolingWaterToAirHP: {
12010 :
12011 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12012 : blankString,
12013 0 : this->m_CoolingCoilIndex,
12014 : this->MaxCoolAirMassFlow,
12015 : this->m_FanOpMode,
12016 : FirstHVACIteration,
12017 0 : this->m_InitHeatPump,
12018 : this->m_CoolingCoilSensDemand,
12019 : this->m_CoolingCoilLatentDemand,
12020 : CompressorOn,
12021 : PartLoadRatio);
12022 :
12023 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
12024 0 : } break;
12025 0 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
12026 0 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, PartLoadRatio);
12027 0 : } break;
12028 0 : default:
12029 0 : break;
12030 : }
12031 :
12032 149586 : this->m_CoolingPartLoadFrac = PartLoadRatio;
12033 149586 : }
12034 :
12035 84403 : void UnitarySys::calcUnitaryHeatingSystem(EnergyPlusData &state,
12036 : int const AirLoopNum, // index to air loop
12037 : bool const FirstHVACIteration, // True when first HVAC iteration
12038 : Real64 const PartLoadRatio, // coil operating part-load ratio
12039 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
12040 : Real64 const OnOffAirFlowRatio, // ratio of on to off flow rate
12041 : Real64 HeatCoilLoad // adjusted heating coil load if outlet temp exceeds max (W)
12042 : )
12043 : {
12044 :
12045 : // SUBROUTINE INFORMATION:
12046 : // AUTHOR Richard Raustad, FSEC
12047 : // DATE WRITTEN February 2013
12048 :
12049 : // PURPOSE OF THIS SUBROUTINE:
12050 : // This subroutine manages unitary heating system component simulation.
12051 :
12052 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12053 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
12054 : Real64 mdot; // water side flow rate (kg/s)
12055 : Real64 QActual; // actual output of coil (W)
12056 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
12057 :
12058 84403 : std::string CompName = this->m_HeatingCoilName;
12059 84403 : Real64 dummy = 0.0;
12060 84403 : Real64 HeatPLR = 1.0;
12061 84403 : if (this->m_CondenserNodeNum != 0) {
12062 90 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
12063 : // IF node is not connected to anything, pressure = default, use weather data
12064 90 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
12065 90 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
12066 : } else {
12067 0 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12068 : }
12069 : } else {
12070 84313 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
12071 : }
12072 :
12073 84403 : switch (this->m_HeatingCoilType_Num) {
12074 53 : case HVAC::CoilDX_HeatingEmpirical: { // COIL:HEATING:DX:SINGLESPEED
12075 106 : DXCoils::SimDXCoil(
12076 53 : state, CompName, CompressorOn, FirstHVACIteration, this->m_HeatingCoilIndex, this->m_FanOpMode, PartLoadRatio, OnOffAirFlowRatio);
12077 53 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12078 53 : } break;
12079 0 : case HVAC::Coil_UserDefined: {
12080 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12081 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12082 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_HeatingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12083 0 : } break;
12084 472 : case HVAC::Coil_HeatingGasOrOtherFuel:
12085 : case HVAC::Coil_HeatingElectric: {
12086 472 : HeatCoilLoad = PartLoadRatio * m_DesignHeatingCapacity;
12087 1888 : HeatingCoils::SimulateHeatingCoilComponents(
12088 1416 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
12089 472 : } break;
12090 2 : case HVAC::Coil_HeatingDesuperheater: {
12091 8 : HeatingCoils::SimulateHeatingCoilComponents(
12092 6 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
12093 :
12094 2 : } break;
12095 83 : case HVAC::CoilDX_MultiSpeedHeating: {
12096 83 : if (OutsideDryBulbTemp > this->m_MinOATCompressorHeating) {
12097 83 : DXCoils::SimDXCoilMultiSpeed(state,
12098 : CompName,
12099 : this->m_HeatingSpeedRatio,
12100 : this->m_HeatingCycRatio,
12101 83 : this->m_HeatingCoilIndex,
12102 83 : this->m_HeatingSpeedNum,
12103 83 : this->m_FanOpMode,
12104 : CompressorOn,
12105 83 : this->m_SingleMode);
12106 83 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12107 : } else {
12108 0 : DXCoils::SimDXCoilMultiSpeed(
12109 0 : state, CompName, 0.0, 0.0, this->m_HeatingCoilIndex, this->m_HeatingSpeedNum, this->m_FanOpMode, CompressorOn);
12110 0 : this->m_HeatCompPartLoadRatio = 0.0;
12111 : }
12112 83 : } break;
12113 140 : case HVAC::Coil_HeatingElectric_MultiStage:
12114 : case HVAC::Coil_HeatingGas_MultiStage: {
12115 560 : HeatingCoils::SimulateHeatingCoilComponents(state,
12116 : CompName,
12117 : FirstHVACIteration,
12118 : _,
12119 280 : 0,
12120 : _,
12121 : _,
12122 140 : this->m_FanOpMode,
12123 : PartLoadRatio,
12124 140 : this->m_HeatingSpeedNum,
12125 140 : this->m_HeatingSpeedRatio);
12126 : // This doesn't look right when it was at higher speed
12127 : // this->m_HeatingCycRatio = PartLoadRatio;
12128 140 : } break;
12129 124 : case HVAC::Coil_HeatingWater: {
12130 124 : if (this->HeatCoilWaterFlowRatio == 0.0) {
12131 73 : mdot = this->MaxHeatCoilFluidFlow * PartLoadRatio;
12132 : } else {
12133 51 : mdot = this->HeatCoilWaterFlowRatio * this->MaxHeatCoilFluidFlow;
12134 : }
12135 124 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
12136 372 : WaterCoils::SimulateWaterCoilComponents(
12137 248 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
12138 124 : } break;
12139 0 : case HVAC::Coil_HeatingSteam: {
12140 : // this same CALL is made in the steam coil calc routine
12141 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxHeatCoilFluidFlow * PartLoadRatio);
12142 0 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
12143 : // tried this to resolve the PackagedTerminalAirConditioner steam spike issue, no help, but this is the correct way to do this
12144 0 : PlantUtilities::SetComponentFlowRate(
12145 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
12146 : } else {
12147 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
12148 : }
12149 0 : SteamCoils::SimulateSteamCoilComponents(state,
12150 : CompName,
12151 : FirstHVACIteration,
12152 0 : this->m_HeatingCoilIndex,
12153 0 : this->m_DesignHeatingCapacity * PartLoadRatio,
12154 : _,
12155 0 : this->m_FanOpMode,
12156 : PartLoadRatio);
12157 0 : } break;
12158 33642 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
12159 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
12160 33642 : if (this->m_HeatingSpeedNum > 1) {
12161 16258 : HeatPLR = 1.0;
12162 16258 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
12163 16256 : this->m_HeatingSpeedRatio = PartLoadRatio;
12164 : }
12165 : } else {
12166 17384 : HeatPLR = PartLoadRatio;
12167 : }
12168 :
12169 33642 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12170 : CompName,
12171 33642 : this->m_HeatingCoilIndex,
12172 : this->m_FanOpMode,
12173 : CompressorOn,
12174 : HeatPLR,
12175 : this->m_HeatingSpeedNum,
12176 : this->m_HeatingSpeedRatio,
12177 : this->m_HeatingCoilSensDemand,
12178 : dummy,
12179 : OnOffAirFlowRatio);
12180 33642 : if (this->m_HeatingSpeedNum > 1) {
12181 16258 : this->m_HeatCompPartLoadRatio = 1.0;
12182 : } else {
12183 17384 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12184 : }
12185 33642 : } break;
12186 49887 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
12187 :
12188 49887 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12189 : blankString,
12190 49887 : this->m_HeatingCoilIndex,
12191 : this->m_HeatingCoilSensDemand,
12192 : dummy,
12193 : this->m_FanOpMode,
12194 : CompressorOn,
12195 : PartLoadRatio,
12196 : FirstHVACIteration);
12197 49887 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12198 49887 : } break;
12199 0 : case HVAC::Coil_HeatingWaterToAirHP: {
12200 :
12201 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12202 : blankString,
12203 0 : this->m_HeatingCoilIndex,
12204 : this->MaxHeatAirMassFlow,
12205 : this->m_FanOpMode,
12206 : FirstHVACIteration,
12207 0 : this->m_InitHeatPump,
12208 : this->m_HeatingCoilSensDemand,
12209 : dummy,
12210 : CompressorOn,
12211 : PartLoadRatio);
12212 0 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
12213 0 : } break;
12214 0 : default: {
12215 0 : ShowFatalError(
12216 0 : state, format("CalcUnitaryHeatingSystem: Invalid Unitary System coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
12217 0 : } break;
12218 : }
12219 :
12220 84403 : this->m_HeatingPartLoadFrac = PartLoadRatio;
12221 84403 : }
12222 :
12223 66078 : void UnitarySys::calcUnitarySuppHeatingSystem(EnergyPlusData &state,
12224 : bool const FirstHVACIteration, // True when first HVAC iteration
12225 : Real64 const SuppCoilLoad // adjusted supp coil load when outlet temp exceeds max (W)
12226 : )
12227 : {
12228 :
12229 : // SUBROUTINE INFORMATION:
12230 : // AUTHOR Richard Raustad, FSEC
12231 : // DATE WRITTEN February 2013
12232 :
12233 : // PURPOSE OF THIS SUBROUTINE:
12234 : // This subroutine manages supplemental heater simulation.
12235 :
12236 : // SUBROUTINE PARAMETER DEFINITIONS:
12237 66078 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12238 66078 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12239 :
12240 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12241 : // std::string CompName; // Name of Unitary System object
12242 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
12243 : Real64 QActual; // actual coil output (W)
12244 : Real64 mdot; // water coil water mass flow rate (kg/s)
12245 66078 : std::vector<Real64> Par; // Parameter array passed to solver
12246 : Real64 PartLoadFrac; // temporary PLR variable
12247 :
12248 66078 : Par.resize(5);
12249 : // work is needed to figure out how to adjust other coil types if outlet temp exceeds maximum
12250 : // this works for gas and electric heating coils
12251 66078 : std::string CompName = this->m_SuppHeatCoilName;
12252 88806 : if (state.dataEnvrn->OutDryBulbTemp <= this->m_MaxOATSuppHeat ||
12253 22728 : (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolingPartLoadFrac > 0.0)) {
12254 43385 : SuppHeatCoilLoad = SuppCoilLoad;
12255 : //} else {
12256 : // SuppHeatCoilLoad = this->m_DesignSuppHeatingCapacity * PartLoadRatio;
12257 : //}
12258 : } else {
12259 22693 : SuppHeatCoilLoad = 0.0;
12260 : }
12261 66078 : switch (this->m_SuppHeatCoilType_Num) {
12262 66078 : case HVAC::Coil_HeatingGasOrOtherFuel:
12263 : case HVAC::Coil_HeatingElectric:
12264 : case HVAC::Coil_HeatingElectric_MultiStage: {
12265 66078 : switch (this->m_ControlType) {
12266 0 : case UnitarySysCtrlType::Setpoint: {
12267 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12268 : CompName,
12269 : FirstHVACIteration,
12270 : SuppHeatCoilLoad,
12271 0 : this->m_SuppHeatCoilIndex,
12272 : _,
12273 0 : true,
12274 0 : this->m_FanOpMode,
12275 0 : this->m_SuppHeatPartLoadFrac,
12276 0 : this->m_SuppHeatingSpeedNum,
12277 0 : this->m_SuppHeatingSpeedRatio);
12278 0 : } break;
12279 66078 : default: {
12280 66078 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
12281 16 : if (SuppHeatCoilLoad > 0.0) {
12282 4 : this->setEMSSuppCoilStagePLR(state);
12283 : } else {
12284 12 : this->m_SuppHeatingSpeedRatio = 0.0;
12285 12 : this->m_SuppHeatingCycRatio = 0.0;
12286 12 : this->m_SuppHeatPartLoadFrac = 0.0;
12287 : }
12288 : } else {
12289 66062 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
12290 48 : this->calcMultiStageSuppCoilStageByLoad(state, SuppHeatCoilLoad, FirstHVACIteration);
12291 : }
12292 : }
12293 198234 : HeatingCoils::SimulateHeatingCoilComponents(state,
12294 : CompName,
12295 : FirstHVACIteration,
12296 : SuppHeatCoilLoad,
12297 66078 : this->m_SuppHeatCoilIndex,
12298 : _,
12299 132156 : true,
12300 66078 : this->m_FanOpMode,
12301 66078 : this->m_SuppHeatPartLoadFrac,
12302 66078 : this->m_SuppHeatingSpeedNum,
12303 66078 : this->m_SuppHeatingSpeedRatio);
12304 66078 : } break;
12305 : }
12306 66078 : } break;
12307 0 : case HVAC::Coil_HeatingDesuperheater: {
12308 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12309 : CompName,
12310 : FirstHVACIteration,
12311 : SuppHeatCoilLoad,
12312 0 : this->m_SuppHeatCoilIndex,
12313 : _,
12314 0 : true,
12315 0 : this->m_FanOpMode,
12316 0 : this->m_SuppHeatPartLoadFrac);
12317 0 : } break;
12318 0 : case HVAC::Coil_HeatingWater: {
12319 : // see if HW coil has enough capacity to meet the load
12320 0 : if (SuppHeatCoilLoad > 0.0) {
12321 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->m_MaxSuppCoilFluidFlow);
12322 : } else {
12323 0 : mdot = 0.0;
12324 : }
12325 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12326 : // simulate water coil to find operating capacity
12327 0 : WaterCoils::SimulateWaterCoilComponents(state,
12328 : this->m_SuppHeatCoilName,
12329 : FirstHVACIteration,
12330 0 : this->m_SuppHeatCoilIndex,
12331 : QActual,
12332 0 : this->m_FanOpMode,
12333 0 : this->m_SuppHeatPartLoadFrac);
12334 0 : if (QActual > SuppHeatCoilLoad) {
12335 0 : auto f = [&state, this, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
12336 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12337 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
12338 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12339 0 : WaterCoils::SimulateWaterCoilComponents(
12340 0 : state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex, 0.0, this->m_FanOpMode, PartLoadFrac);
12341 0 : return SuppHeatCoilLoad;
12342 0 : };
12343 : int SolFla; // Flag of solver, num iterations if >0, else error index
12344 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12345 0 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
12346 : } else {
12347 0 : this->m_SuppHeatPartLoadFrac = (SuppHeatCoilLoad > 0.0) ? 1.0 : 0.0;
12348 : }
12349 0 : } break;
12350 0 : case HVAC::Coil_HeatingSteam: {
12351 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12352 0 : this->m_MaxSuppCoilFluidFlow * this->m_SuppHeatPartLoadFrac);
12353 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12354 0 : SteamCoils::SimulateSteamCoilComponents(
12355 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, SuppHeatCoilLoad, _, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
12356 0 : } break;
12357 0 : default:
12358 0 : break;
12359 : }
12360 66078 : }
12361 :
12362 6 : void UnitarySys::setEMSSuppCoilStagePLR(EnergyPlusData &state)
12363 : {
12364 6 : bool useMaxedSpeed = false;
12365 6 : int SpeedNumEMS = ceil(this->m_EMSOverrideSuppCoilSpeedNumValue);
12366 6 : if (SpeedNumEMS > this->m_NumOfSpeedSuppHeating) {
12367 0 : SpeedNumEMS = this->m_NumOfSpeedSuppHeating;
12368 0 : useMaxedSpeed = true;
12369 : }
12370 6 : this->m_SuppHeatingSpeedNum = SpeedNumEMS;
12371 6 : if (useMaxedSpeed) {
12372 0 : this->m_CoilSpeedErrIdx++;
12373 0 : ShowRecurringWarningErrorAtEnd(state,
12374 0 : format("Wrong coil speed EMS override value, for unit=\"{}\". Exceeding maximum coil speed "
12375 : "level. Speed level is set to the maximum coil speed level allowed.",
12376 0 : this->m_SuppHeatCoilName),
12377 0 : this->m_CoilSpeedErrIdx,
12378 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12379 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12380 : _,
12381 : "",
12382 : "");
12383 : }
12384 6 : if (this->m_SuppHeatingSpeedNum == 1) {
12385 2 : this->m_SuppHeatingSpeedRatio = 0.0;
12386 2 : this->m_SuppHeatingCycRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12387 2 : if (useMaxedSpeed || this->m_SuppHeatingCycRatio == 0) {
12388 0 : this->m_SuppHeatingCycRatio = 1;
12389 : }
12390 2 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingCycRatio;
12391 : } else {
12392 4 : this->m_SuppHeatingCycRatio = 1.0;
12393 4 : this->m_SuppHeatingSpeedRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12394 4 : if (useMaxedSpeed || this->m_SuppHeatingSpeedRatio == 0) {
12395 1 : this->m_SuppHeatingSpeedRatio = 1;
12396 : }
12397 4 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingSpeedRatio;
12398 : }
12399 6 : }
12400 :
12401 65306 : void UnitarySys::controlCoolingSystemToSP(EnergyPlusData &state,
12402 : int const AirLoopNum, // index to air loop
12403 : bool const FirstHVACIteration, // First HVAC iteration flag
12404 : bool &HXUnitOn, // flag to enable heat exchanger heat recovery
12405 : HVAC::CompressorOp &compressorOp // compressor on/off control
12406 : )
12407 : {
12408 : // SUBROUTINE INFORMATION:
12409 : // AUTHOR Richard Raustad, FSEC
12410 : // DATE WRITTEN February 2013
12411 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
12412 :
12413 : // PURPOSE OF THIS SUBROUTINE:
12414 : // Simulate the coil object at the required PLR.
12415 :
12416 : // METHODOLOGY EMPLOYED:
12417 : // Calculate operating PLR and adjust speed when using multispeed coils.
12418 : // Meet moisture load if required to do so.
12419 :
12420 : // SUBROUTINE PARAMETER DEFINITIONS:
12421 65306 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12422 65306 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12423 65306 : Real64 constexpr HumRatAcc(1.e-6); // Accuracy of solver result
12424 :
12425 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12426 : Real64 ReqOutput; // Sensible capacity (outlet - inlet) required to meet load or setpoint temperature
12427 : // for variable speed or 2 speed compressors
12428 : Real64 OutletTempDXCoil; // Actual outlet temperature of the DX cooling coil
12429 : Real64 OutletHumRatLS; // Actual outlet humrat of the variable speed DX cooling coil at low speed
12430 : Real64 OutletHumRatHS; // Actual outlet humrat of the variable speed DX cooling coil at high speed
12431 : Real64 OutletHumRatDXCoil; // Actual outlet humidity ratio of the DX cooling coil
12432 : Real64 TempMinPLR; // Used to find latent PLR when max iterations exceeded
12433 : Real64 TempMaxPLR; // Used to find latent PLR when max iterations exceeded
12434 : Real64 TempOutletTempDXCoil; // Used to find latent PLR when max iterations exceeded
12435 : Real64 OutletTemp;
12436 : Real64 OutdoorDryBulb; // local variable for OutDryBulbTemp
12437 : Real64 maxPartLoadFrac; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
12438 :
12439 : // Set local variables
12440 : // Retrieve the load on the controlled zone
12441 65306 : int OutletNode = this->CoolCoilOutletNodeNum;
12442 65306 : int InletNode = this->CoolCoilInletNodeNum;
12443 65306 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
12444 65306 : Real64 DesOutHumRat = this->m_DesiredOutletHumRat;
12445 65306 : int CoilType_Num = this->m_CoolingCoilType_Num;
12446 65306 : Real64 LoopDXCoilMaxRTFSave = 0.0;
12447 65306 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
12448 0 : this->m_sysType != SysType::PackagedWSHP) {
12449 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
12450 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
12451 : }
12452 :
12453 65306 : std::string CompName = this->m_CoolingCoilName;
12454 65306 : HVAC::FanOp fanOp = this->m_FanOpMode;
12455 65306 : Real64 SpeedRatio = 0.0;
12456 65306 : Real64 CycRatio = 0.0;
12457 65306 : Real64 PartLoadFrac = 0.0;
12458 65306 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal;
12459 65306 : Real64 dummy = 0.0;
12460 65306 : Real64 SensLoad = 0.0;
12461 65306 : int SolFla = 0;
12462 65306 : int SolFlaLat = 0;
12463 65306 : Real64 NoLoadTempOut = 0.0;
12464 65306 : Real64 NoLoadHumRatOut = 0.0;
12465 : // #8849, FullLoadHumRatOut set only at max speed
12466 65306 : Real64 FullLoadHumRatOut = 0.0;
12467 65306 : Real64 FullOutput = 0.0; // Sensible capacity (outlet - inlet) when the compressor is on
12468 65306 : Real64 OnOffAirFlowRatio = 0.0; // Autodesk:Init Patch to prevent use uninitialized in calls to SimVariableSpeedCoils
12469 65306 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
12470 :
12471 65306 : if (this->m_CondenserNodeNum != 0) {
12472 24779 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12473 : } else {
12474 40527 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12475 : }
12476 :
12477 : // Check the dehumidification control type. IF it's multimode, turn off the HX to find the sensible PLR. Then check to
12478 : // see if the humidity load is met without the use of the HX. Always run the HX for the other modes.
12479 65306 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode && this->m_CoolingCoilType_Num != HVAC::CoilDX_Cooling) {
12480 65303 : HXUnitOn = true;
12481 : } else {
12482 3 : HXUnitOn = false;
12483 : }
12484 :
12485 : // IF there is a fault of coil SAT Sensor
12486 65306 : if (this->m_FaultyCoilSATFlag) {
12487 : // calculate the sensor offset using fault information
12488 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
12489 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
12490 : // update the DesOutTemp
12491 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
12492 : }
12493 :
12494 : // IF UnitarySystem is scheduled on and there is flow
12495 130611 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && this->m_coolingCoilAvailSched->getCurrentVal() > 0.0 &&
12496 65305 : (state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow)) {
12497 :
12498 44938 : bool SensibleLoad = false;
12499 44938 : bool LatentLoad = false;
12500 44938 : bool unitSys = false;
12501 44938 : Real64 tempHumRatAcc = HumRatAcc;
12502 44938 : Real64 tempAcc = Acc;
12503 : // Determine if there is a sensible load on this system
12504 44938 : if (this->m_sysType == SysType::CoilCoolingDX) {
12505 44916 : if ((state.dataLoopNodes->Node(InletNode).Temp > state.dataLoopNodes->Node(this->CoolCtrlNode).TempSetPoint) &&
12506 69909 : (state.dataLoopNodes->Node(InletNode).Temp > DesOutTemp) &&
12507 24993 : (std::abs(state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp) > HVAC::TempControlTol)) {
12508 24762 : SensibleLoad = true;
12509 : }
12510 44916 : tempAcc = 0.0;
12511 44916 : tempHumRatAcc = 0.0;
12512 : } else {
12513 22 : unitSys = true;
12514 22 : if (state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp > HVAC::TempControlTol) {
12515 17 : SensibleLoad = true;
12516 : }
12517 : }
12518 :
12519 : // if a heat pump and other coil is on, disable this coil
12520 44938 : if (this->m_HeatPump && this->m_HeatingPartLoadFrac > 0.0) {
12521 0 : SensibleLoad = false;
12522 : }
12523 :
12524 : // Determine if there is a latent load on this system - for future use to serve latent-only loads
12525 44938 : if (this->m_sysType == SysType::CoilCoolingDX) {
12526 89832 : if ((state.dataLoopNodes->Node(InletNode).HumRat > state.dataLoopNodes->Node(InletNode).HumRatMax) &&
12527 44916 : (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat)) {
12528 7 : LatentLoad = true;
12529 : }
12530 : } else {
12531 22 : if (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat) {
12532 4 : LatentLoad = true;
12533 : }
12534 : }
12535 :
12536 : // disable latent dehumidification if there is no sensible load and latent only is not allowed
12537 44938 : if (this->m_RunOnLatentOnlyWithSensible && !SensibleLoad) {
12538 0 : LatentLoad = false;
12539 : }
12540 :
12541 : // disable compressor if OAT is below minimum outdoor temperature
12542 44938 : if (OutdoorDryBulb < this->m_MinOATCompressorCooling) {
12543 0 : SensibleLoad = false;
12544 0 : LatentLoad = false;
12545 : }
12546 :
12547 : // activate heat recovery loop coil if scheduled on and there is air flow
12548 44938 : if (this->m_WaterHRPlantLoopModel) {
12549 2 : if (this->temperatureOffsetControlStatus == 1) {
12550 1 : PartLoadFrac = 1.0;
12551 1 : mdot = this->MaxCoolCoilFluidFlow;
12552 : }
12553 2 : if (this->CoolCoilPlantLoc.loopNum > 0) {
12554 2 : PlantUtilities::SetComponentFlowRate(
12555 2 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12556 : }
12557 :
12558 6 : WaterCoils::SimulateWaterCoilComponents(
12559 4 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12560 2 : SensibleLoad = false; // fall through remaining checks
12561 2 : LatentLoad = false;
12562 44936 : } else if (this->m_TemperatureOffsetControlActive) {
12563 : // disable waterside economizer if the condition is NOT favorable
12564 3 : if (this->temperatureOffsetControlStatus == 0) {
12565 2 : SensibleLoad = false;
12566 2 : LatentLoad = false;
12567 2 : HXUnitOn = false;
12568 : }
12569 : }
12570 :
12571 : // IF DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
12572 : // Multimode coil will switch to enhanced dehumidification IF available and needed, but it
12573 : // still runs to meet the sensible load. Multimode applies to Multimode or HXAssistedCooling coils.
12574 44938 : if ((SensibleLoad && this->m_RunOnSensibleLoad) || (LatentLoad && this->m_RunOnLatentLoad)) {
12575 : // calculate sensible PLR, don't care IF latent is true here but need to guard for
12576 : // when LatentLoad=TRUE and SensibleLoad=FALSE
12577 24777 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12578 74331 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
12579 24777 : state.dataLoopNodes->Node(OutletNode).HumRat,
12580 24777 : state.dataLoopNodes->Node(InletNode).Temp,
12581 24777 : state.dataLoopNodes->Node(InletNode).HumRat);
12582 :
12583 24777 : PartLoadFrac = 0.0;
12584 24777 : compressorOp = HVAC::CompressorOp::Off;
12585 :
12586 24777 : if (this->m_EMSOverrideCoilSpeedNumOn && (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12587 3 : this->m_CoolingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
12588 3 : this->m_SpeedNum = this->m_CoolingSpeedNum;
12589 3 : bool useMaxedSpeed = false;
12590 3 : if (this->m_SpeedNum > this->m_NumOfSpeedCooling) {
12591 1 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
12592 1 : this->m_SpeedNum = this->m_NumOfSpeedCooling;
12593 1 : useMaxedSpeed = true;
12594 1 : if (this->m_CoilSpeedErrIdx == 0) {
12595 1 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12596 3 : ShowContinueError(state,
12597 : " Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.");
12598 : }
12599 8 : ShowRecurringWarningErrorAtEnd(
12600 : state,
12601 2 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12602 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
12603 1 : this->m_CoilSpeedErrIdx,
12604 1 : this->m_EMSOverrideCoilSpeedNumValue,
12605 1 : this->m_EMSOverrideCoilSpeedNumValue,
12606 : _,
12607 : "",
12608 : "");
12609 : }
12610 :
12611 3 : if (this->m_SpeedNum < 0) {
12612 0 : this->m_CoolingSpeedNum = 0;
12613 0 : this->m_SpeedNum = 0;
12614 0 : if (this->m_CoilSpeedErrIdx == 0) {
12615 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12616 0 : ShowContinueError(state, " Input speed value is below zero. Speed level is set to zero.");
12617 : }
12618 0 : ShowRecurringWarningErrorAtEnd(state,
12619 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12620 : "\". Input speed value is below zero. Speed level is set to zero.",
12621 0 : this->m_CoilSpeedErrIdx,
12622 0 : this->m_EMSOverrideCoilSpeedNumValue,
12623 0 : this->m_EMSOverrideCoilSpeedNumValue,
12624 : _,
12625 : "",
12626 : "");
12627 : }
12628 :
12629 3 : if (this->m_CoolingSpeedNum == 1) {
12630 1 : SpeedRatio = this->m_CoolingSpeedRatio = 0.0;
12631 1 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12632 1 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
12633 0 : CycRatio = this->m_CoolingCycRatio = 1;
12634 : } else {
12635 1 : CycRatio = this->m_CoolingCycRatio;
12636 : }
12637 1 : PartLoadFrac = this->m_CoolingCycRatio;
12638 : } else {
12639 2 : CycRatio = this->m_CoolingCycRatio = 1.0;
12640 2 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12641 2 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
12642 1 : SpeedRatio = this->m_CoolingSpeedRatio = 1;
12643 : } else {
12644 1 : SpeedRatio = this->m_CoolingSpeedRatio;
12645 : }
12646 2 : PartLoadFrac = this->m_CoolingSpeedRatio;
12647 : }
12648 3 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12649 3 : if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12650 3 : this->simMultiSpeedCoils(state,
12651 : AirLoopNum,
12652 : FirstHVACIteration,
12653 : compressorOp,
12654 : SensibleLoad,
12655 : LatentLoad,
12656 : PartLoadFrac,
12657 : CoolingCoil,
12658 : this->m_SpeedNum);
12659 3 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12660 3 : int SpeedNum = 0;
12661 3 : if (SpeedNum == this->m_NumOfSpeedCooling) { // should be using this->m_SpeedNum? Diffs?
12662 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12663 : }
12664 : } else {
12665 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12666 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12667 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12668 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12669 0 : coilMode = HVAC::CoilMode::Enhanced;
12670 : }
12671 0 : bool const singleMode = (this->m_SingleMode == 1);
12672 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12673 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode);
12674 : }
12675 :
12676 24777 : } else if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12677 20307 : this->m_CompPartLoadRatio = PartLoadFrac;
12678 :
12679 20307 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12680 :
12681 4467 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12682 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12683 :
12684 0 : if (this->CoolCoilFluidInletNode > 0) {
12685 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
12686 : }
12687 :
12688 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12689 : CompName,
12690 : FirstHVACIteration,
12691 : HVAC::CompressorOp::On,
12692 : PartLoadFrac,
12693 0 : this->m_CoolingCoilIndex,
12694 : fanOp,
12695 : HXUnitOn,
12696 : _,
12697 0 : state.dataUnitarySystems->economizerFlag,
12698 : _,
12699 0 : this->m_DehumidificationMode,
12700 0 : 0.0); // this->CoilSHR);
12701 0 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
12702 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12703 : }
12704 4467 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12705 :
12706 4447 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, PartLoadFrac, this->m_CoolingCoilIndex);
12707 :
12708 20 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12709 3 : this->simMultiSpeedCoils(
12710 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, this->m_SpeedNum);
12711 :
12712 17 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12713 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12714 :
12715 7 : int SpeedNum = 0;
12716 7 : this->m_CoolingCoilSensDemand = ReqOutput;
12717 7 : VariableSpeedCoils::SimVariableSpeedCoils(
12718 7 : state, "", this->m_CoolingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
12719 :
12720 17 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
12721 :
12722 0 : DXCoils::SimDXCoilMultiMode(
12723 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12724 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12725 10 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12726 : // SP control (tentatively) operates at constant air flow regardless of speed
12727 : // speed n uses MSHPMassFlowRateHigh and speed n-1 uses MSHPMassFlowRateLow
12728 3 : state.dataHVACGlobal->MSHPMassFlowRateLow = this->m_DesignMassFlowRate;
12729 3 : state.dataHVACGlobal->MSHPMassFlowRateHigh = this->m_DesignMassFlowRate;
12730 3 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12731 3 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12732 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12733 3 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12734 0 : coilMode = HVAC::CoilMode::Enhanced;
12735 : }
12736 3 : bool const singleMode = (this->m_SingleMode == 1);
12737 : // PartLoadFrac has not been set in this branch - so use m_CoolingSpeedRatio?
12738 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12739 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12740 3 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12741 7 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12742 :
12743 21 : WaterCoils::SimulateWaterCoilComponents(
12744 14 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12745 :
12746 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12747 :
12748 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12749 : blankString,
12750 0 : this->m_CoolingCoilIndex,
12751 : ReqOutput,
12752 : dummy,
12753 : fanOp,
12754 : HVAC::CompressorOp::Off,
12755 : PartLoadFrac,
12756 : FirstHVACIteration);
12757 0 : this->m_CoolingCoilSensDemand = 0.0;
12758 :
12759 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12760 :
12761 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12762 : blankString,
12763 0 : this->m_CoolingCoilIndex,
12764 : this->MaxCoolAirMassFlow,
12765 : fanOp,
12766 : FirstHVACIteration,
12767 0 : this->m_InitHeatPump,
12768 : ReqOutput,
12769 : dummy,
12770 : HVAC::CompressorOp::Off,
12771 : PartLoadFrac);
12772 :
12773 0 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12774 :
12775 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12776 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12777 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12778 0 : if (CoolingActive) {
12779 0 : PartLoadFrac = 1.0;
12780 : }
12781 :
12782 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12783 :
12784 0 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12785 :
12786 : } else {
12787 : }
12788 :
12789 24777 : NoLoadTempOut = state.dataLoopNodes->Node(OutletNode).Temp;
12790 24777 : NoLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12791 :
12792 24777 : Real64 NoOutput = 0.0; // CoilSystem:Cooling:DX
12793 24777 : FullOutput = 0.0;
12794 24777 : if (this->m_sysType == SysType::CoilCoolingDX) {
12795 24762 : NoOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12796 24762 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12797 24762 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12798 24762 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12799 49524 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12800 24762 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12801 : }
12802 :
12803 : // Changed logic to use temperature instead of load. The Psyc calcs can cause slight errors.
12804 : // For example it's possible that (NoOutput-ReqOutput) > Acc while (Node(OutletNode)%Temp-DesOutTemp) is not
12805 : // This can (and did) lead to RegulaFalsi errors
12806 :
12807 : // IF ((NoOutput-ReqOutput) .LT. Acc) THEN
12808 : // IF outlet temp at no load is lower than DesOutTemp (set point), do not operate the coil
12809 : // and if coolReheat, check hum rat as well
12810 24777 : bool doIt = false; // CoilSystem:Cooling:DX
12811 24777 : if (this->m_sysType == SysType::CoilCoolingDX) {
12812 24762 : if ((NoOutput - ReqOutput) < Acc) {
12813 0 : PartLoadFrac = 0.0;
12814 : } else {
12815 24762 : doIt = true;
12816 : }
12817 15 : } else if (this->m_EMSOverrideCoilSpeedNumOn &&
12818 0 : (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12819 : // do nothing, PartLoadFrac set above
12820 12 : } else if (((NoLoadTempOut - DesOutTemp) < Acc) && ((NoLoadHumRatOut - DesOutHumRat) < HumRatAcc)) {
12821 0 : PartLoadFrac = 0.0;
12822 : } else { // need to turn on compressor to see if load is met
12823 12 : doIt = true; // CoilSystem:Cooling:DX
12824 : } // CoilSystem:Cooling:DX
12825 24777 : if (this->m_EMSOverrideCoilSpeedNumOn) {
12826 3 : doIt = false;
12827 : }
12828 :
12829 24777 : if (doIt) { // CoilSystem:Cooling:DX
12830 24774 : PartLoadFrac = 1.0;
12831 24774 : compressorOp = HVAC::CompressorOp::On;
12832 :
12833 24774 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12834 :
12835 40614 : DXCoils::SimDXCoil(
12836 20307 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12837 20307 : this->m_CompPartLoadRatio = PartLoadFrac;
12838 20307 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12839 :
12840 4467 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12841 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12842 :
12843 0 : if (this->CoolCoilFluidInletNode > 0) {
12844 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = max(0.0, this->MaxCoolCoilFluidFlow);
12845 : }
12846 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12847 : CompName,
12848 : FirstHVACIteration,
12849 : HVAC::CompressorOp::On,
12850 : PartLoadFrac,
12851 0 : this->m_CoolingCoilIndex,
12852 : fanOp,
12853 : HXUnitOn,
12854 : _,
12855 0 : state.dataUnitarySystems->economizerFlag,
12856 : _,
12857 0 : this->m_DehumidificationMode,
12858 0 : 0.0); // this->CoilSHR);
12859 :
12860 0 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
12861 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12862 : }
12863 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12864 :
12865 4467 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12866 :
12867 4447 : CycRatio = 1.0;
12868 6994 : for (int speedRatio = 0; speedRatio < this->m_NumOfSpeedCooling; ++speedRatio) {
12869 6994 : SpeedRatio = Real64(speedRatio);
12870 6994 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
12871 6994 : OutletTemp = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
12872 6994 : if (SpeedRatio == 1) {
12873 2547 : FullLoadHumRatOut = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
12874 2547 : break;
12875 : }
12876 4447 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12877 1900 : break;
12878 : }
12879 : }
12880 :
12881 20 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12882 :
12883 3 : CycRatio = 1.0;
12884 3 : SpeedRatio = 0.0;
12885 3 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12886 3 : if (SpeedNum > 1) {
12887 0 : CycRatio = 0.0;
12888 0 : SpeedRatio = 1.0;
12889 : }
12890 3 : this->m_CoolingSpeedNum = SpeedNum;
12891 3 : this->simMultiSpeedCoils(
12892 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, SpeedNum);
12893 3 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12894 3 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12895 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12896 : }
12897 3 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12898 3 : break;
12899 : }
12900 : }
12901 :
12902 17 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12903 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12904 :
12905 7 : CycRatio = 1.0;
12906 7 : SpeedRatio = 1.0;
12907 7 : SensLoad = -1.0; // turns on coil
12908 7 : this->m_CoolingSpeedRatio = SpeedRatio;
12909 7 : this->m_CoolingPartLoadFrac = PartLoadFrac;
12910 14 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12911 14 : this->m_CoolingSpeedNum = SpeedNum;
12912 14 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12913 : "",
12914 14 : this->m_CoolingCoilIndex,
12915 : fanOp,
12916 : compressorOp,
12917 : CycRatio,
12918 : SpeedNum,
12919 : SpeedRatio,
12920 : SensLoad,
12921 : dummy,
12922 : OnOffAirFlowRatio);
12923 14 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12924 14 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12925 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12926 : }
12927 14 : if (OutletTemp < DesOutTemp && SensibleLoad) {
12928 7 : break;
12929 : }
12930 : }
12931 7 : if (this->m_CoolingSpeedNum == 1) {
12932 4 : CycRatio = 1.0;
12933 4 : SpeedRatio = 0.0;
12934 : } else {
12935 3 : CycRatio = 0.0;
12936 3 : SpeedRatio = 1.0;
12937 : }
12938 :
12939 17 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) { // Coil:Cooling:DX:TwoStageWithHumidityControlMode
12940 :
12941 0 : DXCoils::SimDXCoilMultiMode(
12942 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12943 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12944 :
12945 10 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12946 3 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12947 3 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12948 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12949 3 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12950 0 : coilMode = HVAC::CoilMode::Enhanced;
12951 : }
12952 3 : this->m_CoolingSpeedRatio = 1.0;
12953 3 : bool const singleMode = (this->m_SingleMode == 1);
12954 3 : for (int speedNum = 1; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
12955 3 : this->m_CoolingSpeedNum = speedNum;
12956 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12957 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12958 3 : if (speedNum == this->m_NumOfSpeedCooling) {
12959 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12960 : }
12961 3 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) {
12962 3 : break;
12963 : }
12964 : }
12965 3 : if (this->m_CoolingSpeedNum == 1) {
12966 3 : this->m_CompPartLoadRatio = PartLoadFrac;
12967 3 : this->m_CoolCompPartLoadRatio = PartLoadFrac; // why is the set only for a few?
12968 3 : SpeedRatio = 0.0;
12969 : } else {
12970 0 : SpeedRatio = PartLoadFrac;
12971 0 : PartLoadFrac = 1.0;
12972 0 : this->m_CompPartLoadRatio = 1.0;
12973 0 : this->m_CoolCompPartLoadRatio = 1.0;
12974 : }
12975 7 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12976 :
12977 7 : mdot = this->MaxCoolCoilFluidFlow;
12978 7 : PlantUtilities::SetComponentFlowRate(
12979 7 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12980 :
12981 21 : WaterCoils::SimulateWaterCoilComponents(
12982 14 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12983 7 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12984 :
12985 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12986 :
12987 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12988 : blankString,
12989 0 : this->m_CoolingCoilIndex,
12990 : ReqOutput,
12991 : dummy,
12992 : fanOp,
12993 : HVAC::CompressorOp::On,
12994 : PartLoadFrac,
12995 : FirstHVACIteration);
12996 0 : this->m_CoolingCoilSensDemand = ReqOutput;
12997 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12998 :
12999 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
13000 :
13001 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
13002 : blankString,
13003 0 : this->m_CoolingCoilIndex,
13004 : this->MaxCoolAirMassFlow,
13005 : fanOp,
13006 : FirstHVACIteration,
13007 0 : this->m_InitHeatPump,
13008 : ReqOutput,
13009 : dummy,
13010 : HVAC::CompressorOp::Off,
13011 : PartLoadFrac);
13012 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13013 :
13014 0 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13015 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
13016 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
13017 :
13018 0 : UserDefinedComponents::SimCoilUserDefined(
13019 0 : state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
13020 0 : if (CoolingActive) {
13021 0 : PartLoadFrac = 1.0;
13022 : }
13023 :
13024 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13025 :
13026 : // TES coil simulated above with PLR=0. Operating mode is known here, no need to simulate again to determine operating
13027 : // mode.
13028 0 : if (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13029 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly) { // cannot cool
13030 0 : PartLoadFrac = 0.0;
13031 : } else {
13032 : // Get full load result
13033 0 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
13034 : }
13035 :
13036 : } else {
13037 : }
13038 :
13039 24774 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13040 24774 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
13041 24774 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
13042 49548 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13043 24774 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13044 24774 : state.dataLoopNodes->Node(OutletNode).HumRat,
13045 24774 : state.dataLoopNodes->Node(InletNode).Temp,
13046 24774 : state.dataLoopNodes->Node(InletNode).HumRat);
13047 : }
13048 :
13049 : // IF ((FullOutput - ReqOutput) .GT. Acc) THEN ! old method
13050 : // IF ((Node(OutletNode)%Temp-DesOutTemp) .GT. Acc) THEN ! new method gets caught when temps are very close
13051 24777 : if (this->m_sysType == SysType::CoilCoolingDX) {
13052 24762 : if ((FullOutput - ReqOutput) > tempAcc) {
13053 611 : PartLoadFrac = 1.0;
13054 611 : doIt = false;
13055 : } else {
13056 24151 : doIt = true;
13057 : }
13058 : }
13059 24777 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13060 3 : doIt = false;
13061 : }
13062 :
13063 24777 : if (doIt) {
13064 24163 : if (unitSys && state.dataLoopNodes->Node(OutletNode).Temp > DesOutTemp - tempAcc) {
13065 1 : PartLoadFrac = 1.0;
13066 1 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13067 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13068 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13069 0 : PartLoadFrac = 0.0;
13070 : }
13071 24162 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13072 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
13073 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13074 0 : PartLoadFrac = 0.0;
13075 24162 : } else if (!SensibleLoad) {
13076 2 : PartLoadFrac = 0.0;
13077 : } else {
13078 :
13079 24160 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13080 84008 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadRatio) {
13081 84008 : int CoilIndex = this->m_CoolingCoilIndex;
13082 84008 : DXCoils::CalcDoe2DXCoil(state, CoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13083 84008 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
13084 :
13085 84008 : return DesOutTemp - OutletAirTemp;
13086 19817 : };
13087 19817 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13088 19817 : this->m_CompPartLoadRatio = PartLoadFrac;
13089 :
13090 4343 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) || (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) {
13091 :
13092 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadFrac) {
13093 0 : if (this->CoolCoilFluidInletNode > 0) {
13094 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = this->MaxCoolCoilFluidFlow * PartLoadFrac;
13095 : }
13096 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(
13097 : state,
13098 0 : this->m_CoolingCoilIndex,
13099 : FirstHVACIteration,
13100 : HVAC::CompressorOp::On,
13101 : PartLoadFrac,
13102 : HXUnitOn,
13103 : fanOp,
13104 : _,
13105 : _,
13106 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13107 0 : 0.0);
13108 0 : return DesOutTemp - state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13109 0 : };
13110 :
13111 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13112 0 : if (SolFla == -1) {
13113 :
13114 : // RegulaFalsi may not find sensible PLR when the latent degradation model is used.
13115 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13116 0 : TempMaxPLR = -0.1;
13117 0 : TempOutletTempDXCoil = state.dataLoopNodes->Node(InletNode).Temp;
13118 0 : while ((TempOutletTempDXCoil - DesOutTemp) > 0.0 && TempMaxPLR <= 1.0) {
13119 : // find upper limit of PLR
13120 0 : TempMaxPLR += 0.1;
13121 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13122 : CompName,
13123 : FirstHVACIteration,
13124 : HVAC::CompressorOp::On,
13125 : TempMaxPLR,
13126 0 : this->m_CoolingCoilIndex,
13127 : fanOp,
13128 : HXUnitOn,
13129 : _,
13130 0 : state.dataUnitarySystems->economizerFlag,
13131 : _,
13132 0 : this->m_DehumidificationMode,
13133 0 : 0.0); // this->CoilSHR);
13134 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13135 : }
13136 0 : TempMinPLR = TempMaxPLR;
13137 0 : while ((TempOutletTempDXCoil - DesOutTemp) < 0.0 && TempMinPLR >= 0.0) {
13138 : // pull upper limit of PLR DOwn to last valid limit (i.e. outlet temp still exceeds DesOutTemp)
13139 0 : TempMaxPLR = TempMinPLR;
13140 : // find minimum limit of PLR
13141 0 : TempMinPLR -= 0.01;
13142 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13143 : CompName,
13144 : FirstHVACIteration,
13145 : HVAC::CompressorOp::On,
13146 : TempMinPLR,
13147 0 : this->m_CoolingCoilIndex,
13148 : fanOp,
13149 : HXUnitOn,
13150 : _,
13151 0 : state.dataUnitarySystems->economizerFlag,
13152 : _,
13153 0 : this->m_DehumidificationMode,
13154 0 : 0.0); // this->CoilSHR);
13155 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13156 : }
13157 : // Relax boundary slightly to assure a solution can be found using RegulaFalsi (i.e. one boundary may
13158 : // be very near the desired result)
13159 0 : TempMinPLR = max(0.0, (TempMinPLR - 0.01));
13160 0 : TempMaxPLR = min(1.0, (TempMaxPLR + 0.01));
13161 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13162 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13163 0 : if (SolFla == -1) {
13164 0 : if (!state.dataGlobal->WarmupFlag) {
13165 0 : if (this->warnIndex.m_HXAssistedSensPLRIter < 1) {
13166 0 : ++this->warnIndex.m_HXAssistedSensPLRIter;
13167 0 : ShowWarningError(
13168 : state,
13169 0 : format("{} - Iteration limit exceeded calculating DX unit sensible part-load ratio for unit = {}",
13170 0 : this->UnitType,
13171 0 : this->Name));
13172 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13173 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13174 0 : ShowContinueErrorTimeStamp(
13175 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13176 : }
13177 0 : ShowRecurringWarningErrorAtEnd(state,
13178 0 : this->UnitType + " \"" + this->Name +
13179 : "\" - Iteration limit exceeded calculating sensible part-load ratio "
13180 : "error continues. Sensible PLR "
13181 : "statistics follow.",
13182 0 : this->warnIndex.m_HXAssistedSensPLRIterIndex,
13183 : PartLoadFrac,
13184 : PartLoadFrac);
13185 : }
13186 0 : } else if (SolFla == -2) {
13187 0 : PartLoadFrac = ReqOutput / FullOutput;
13188 0 : if (!state.dataGlobal->WarmupFlag) {
13189 0 : if (this->warnIndex.m_HXAssistedSensPLRFail < 1) {
13190 0 : ++this->warnIndex.m_HXAssistedSensPLRFail;
13191 0 : ShowWarningError(state,
13192 0 : format("{} - DX unit sensible part-load ratio calculation unexpectedly failed: "
13193 : "part-load ratio limits exceeded, for unit = {}",
13194 0 : this->UnitType,
13195 0 : this->Name));
13196 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13197 0 : ShowContinueErrorTimeStamp(
13198 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13199 : }
13200 0 : ShowRecurringWarningErrorAtEnd(state,
13201 0 : this->UnitType + " \"" + this->Name +
13202 : "\" - DX unit sensible part-load ratio calculation unexpectedly "
13203 : "failed error continues. Sensible PLR "
13204 : "statistics follow.",
13205 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex,
13206 : PartLoadFrac,
13207 : PartLoadFrac);
13208 : }
13209 : }
13210 0 : } else if (SolFla == -2) {
13211 0 : PartLoadFrac = ReqOutput / FullOutput;
13212 0 : if (!state.dataGlobal->WarmupFlag) {
13213 0 : if (this->warnIndex.m_HXAssistedSensPLRFail2 < 1) {
13214 0 : ++this->warnIndex.m_HXAssistedSensPLRFail2;
13215 0 : ShowWarningError(state,
13216 0 : format("{} - DX unit sensible part-load ratio calculation failed: part-load ratio limits "
13217 : "exceeded, for unit = {}",
13218 0 : this->UnitType,
13219 0 : this->Name));
13220 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13221 0 : ShowContinueErrorTimeStamp(
13222 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13223 : }
13224 0 : ShowRecurringWarningErrorAtEnd(state,
13225 0 : this->UnitType + " \"" + this->Name +
13226 : "\" - DX unit sensible part-load ratio calculation failed error continues. "
13227 : "Sensible PLR statistics follow.",
13228 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex2,
13229 : PartLoadFrac,
13230 : PartLoadFrac);
13231 : }
13232 : }
13233 0 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13234 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13235 : }
13236 :
13237 4343 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13238 4326 : this->m_CoolingSpeedRatio = SpeedRatio;
13239 4326 : if (SpeedRatio == 1.0) {
13240 10669 : auto f = [&state, this, DesOutTemp](Real64 const SpeedRatio) {
13241 10669 : int par1 = this->m_CoolingCoilIndex;
13242 10669 : Real64 par2 = DesOutTemp;
13243 10669 : int par3 = this->m_UnitarySysNum;
13244 : // 4-7 are not used for TwoSpeed coils, so these shouldn't matter at all
13245 10669 : Real64 par4_CycRatio = 0.0;
13246 10669 : int par5_SpeedNum = 0.0;
13247 10669 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
13248 10669 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13249 10669 : return UnitarySys::DXCoilVarSpeedResidual(
13250 10669 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13251 2426 : };
13252 2426 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13253 2426 : PartLoadFrac = SpeedRatio;
13254 : } else {
13255 5704 : auto f = [&state, this, DesOutTemp, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13256 : // several pars are not used in two speed coils, so these are just dummy values
13257 5704 : Real64 par4_SpeedRatio = 0.0;
13258 5704 : int par5_SpeedNum = 0.0;
13259 5704 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
13260 5704 : HVAC::CompressorOp par7_compressorOp = HVAC::CompressorOp::On;
13261 11408 : return UnitarySys::DXCoilCyclingResidual(state,
13262 : CycRatio,
13263 5704 : this->m_CoolingCoilIndex,
13264 : DesOutTemp,
13265 5704 : this->m_UnitarySysNum,
13266 : par4_SpeedRatio,
13267 : par5_SpeedNum,
13268 : par6_FanOpMode,
13269 : par7_compressorOp,
13270 : AirLoopNum,
13271 5704 : FirstHVACIteration);
13272 1900 : };
13273 1900 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13274 1900 : PartLoadFrac = CycRatio;
13275 : }
13276 :
13277 17 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13278 :
13279 3 : if (this->m_CoolingSpeedNum > 1.0) {
13280 0 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
13281 0 : int par1 = this->m_CoolingCoilIndex;
13282 0 : Real64 par2 = DesOutTemp;
13283 0 : int par3 = this->m_UnitarySysNum;
13284 0 : Real64 par4_CycRatio = CycRatio;
13285 0 : int par5_SpeedNum = this->m_CoolingSpeedNum;
13286 0 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Cycling;
13287 0 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13288 0 : return UnitarySys::DXCoilVarSpeedResidual(
13289 0 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13290 0 : };
13291 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13292 0 : PartLoadFrac = SpeedRatio;
13293 : } else {
13294 3 : SpeedRatio = 0.0;
13295 3 : this->m_CoolingSpeedRatio = SpeedRatio;
13296 11 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13297 22 : return UnitarySys::DXCoilCyclingResidual(state,
13298 : CycRatio,
13299 11 : this->m_CoolingCoilIndex,
13300 : DesOutTemp,
13301 11 : this->m_UnitarySysNum,
13302 : SpeedRatio,
13303 11 : this->m_CoolingSpeedNum,
13304 : HVAC::FanOp::Cycling,
13305 : HVAC::CompressorOp::On,
13306 : AirLoopNum,
13307 11 : FirstHVACIteration);
13308 3 : };
13309 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13310 3 : PartLoadFrac = CycRatio;
13311 : }
13312 :
13313 14 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13314 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13315 :
13316 7 : CycRatio = 1.0;
13317 7 : SpeedRatio = 1.0;
13318 :
13319 7 : if (this->m_CoolingSpeedNum > 1.0) {
13320 18 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
13321 18 : int par1 = this->m_CoolingCoilIndex;
13322 18 : Real64 par2 = DesOutTemp;
13323 18 : int par3 = this->m_UnitarySysNum;
13324 18 : Real64 par4_CycRatio = CycRatio;
13325 18 : int par5_SpeedNum = this->m_CoolingSpeedNum;
13326 18 : HVAC::FanOp par6_FanOpMode = this->m_FanOpMode;
13327 18 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
13328 18 : return UnitarySys::DXCoilVarSpeedResidual(
13329 18 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
13330 3 : };
13331 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13332 3 : this->m_CoolingCycRatio = CycRatio;
13333 3 : this->m_CoolingSpeedRatio = SpeedRatio;
13334 3 : this->m_CoolingPartLoadFrac = SpeedRatio;
13335 3 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13336 3 : PartLoadFrac = SpeedRatio;
13337 : } else {
13338 4 : this->m_CoolingSpeedRatio = SpeedRatio;
13339 17 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13340 34 : return UnitarySys::DXCoilCyclingResidual(state,
13341 : CycRatio,
13342 17 : this->m_CoolingCoilIndex,
13343 : DesOutTemp,
13344 17 : this->m_UnitarySysNum,
13345 : SpeedRatio,
13346 17 : this->m_CoolingSpeedNum,
13347 17 : this->m_FanOpMode,
13348 : HVAC::CompressorOp::On,
13349 : AirLoopNum,
13350 17 : FirstHVACIteration);
13351 4 : };
13352 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13353 4 : SpeedRatio = 0.0;
13354 4 : this->m_CoolingCycRatio = CycRatio;
13355 4 : this->m_CoolingPartLoadFrac = CycRatio;
13356 4 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13357 4 : PartLoadFrac = CycRatio;
13358 : }
13359 :
13360 14 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13361 0 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13362 0 : DXCoils::SimDXCoilMultiMode(
13363 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13364 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13365 0 : };
13366 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13367 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13368 7 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13369 12 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13370 12 : bool const singleMode = this->m_SingleMode;
13371 12 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13372 12 : state, DehumidMode, this->m_CoolingSpeedNum, PartLoadRatio, fanOp, singleMode);
13373 : Real64 outletCondition =
13374 12 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13375 12 : return DesOutTemp - outletCondition;
13376 3 : };
13377 :
13378 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13379 3 : if (this->m_CoolingSpeedNum == 1) {
13380 3 : this->m_CompPartLoadRatio = PartLoadFrac;
13381 3 : SpeedRatio = 0.0;
13382 : } else {
13383 0 : SpeedRatio = PartLoadFrac;
13384 0 : PartLoadFrac = 1.0;
13385 0 : this->m_CompPartLoadRatio = 1.0;
13386 : }
13387 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) {
13388 :
13389 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
13390 : maxPartLoadFrac =
13391 4 : min(1.0,
13392 4 : ((mdot / this->MaxCoolCoilFluidFlow) +
13393 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
13394 :
13395 24 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadRatio) {
13396 24 : Real64 mdot = min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13397 24 : this->MaxCoolCoilFluidFlow * PartLoadRatio);
13398 24 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
13399 48 : WaterCoils::SimulateWaterCoilComponents(
13400 24 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, _, _, PartLoadRatio);
13401 24 : return DesOutTemp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp;
13402 4 : };
13403 :
13404 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
13405 :
13406 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13407 0 : this->m_CoolingCoilSensDemand = ReqOutput;
13408 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
13409 0 : return UnitarySys::coolWatertoAirHPTempResidual(
13410 0 : state, PartLoadRatio, this->m_UnitarySysNum, FirstHVACIteration, DesOutTemp, ReqOutput);
13411 0 : };
13412 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13413 0 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13414 : // do nothing, user defined coil cannot be controlled
13415 :
13416 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13417 0 : auto f = [&state, this, DesOutTemp](Real64 const PartLoadRatio) {
13418 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13419 0 : PackagedThermalStorageCoil::SimTESCoil(state,
13420 : thisSys.m_CoolingCoilName,
13421 0 : thisSys.m_CoolingCoilIndex,
13422 : thisSys.m_FanOpMode,
13423 0 : thisSys.m_TESOpMode,
13424 : PartLoadRatio);
13425 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp - DesOutTemp;
13426 0 : };
13427 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13428 : } else {
13429 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
13430 0 : ShowFatalError(state,
13431 0 : format("ControlCoolingSystemToSP: Invalid cooling coil type = {}", HVAC::cAllCoilTypes(CoilType_Num)));
13432 : }
13433 : }
13434 : }
13435 : }
13436 :
13437 : // IF system does not operate to meet sensible load, use no load humidity ratio to test against humidity setpoint,
13438 : // ELSE use operating humidity ratio to test against humidity setpoint
13439 44938 : if (PartLoadFrac == 0.0) {
13440 20162 : OutletHumRatDXCoil = NoLoadHumRatOut;
13441 : } else {
13442 24776 : OutletHumRatDXCoil = state.dataLoopNodes->Node(OutletNode).HumRat;
13443 : }
13444 :
13445 : // IF humidity setpoint is not satisfied and humidity control type is MultiMode,
13446 : // then enable heat exchanger and run to meet sensible load
13447 :
13448 44938 : if ((OutletHumRatDXCoil > (DesOutHumRat + tempHumRatAcc)) && (!unitSys || PartLoadFrac < 1.0) &&
13449 11 : (this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
13450 :
13451 1 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13452 : // pass
13453 1 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
13454 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted,
13455 : // CoilSystem:Cooling:Water:HeatExchangerAssisted
13456 : // Determine required part load when heat exchanger is ON
13457 0 : HXUnitOn = true;
13458 0 : PartLoadFrac = 1.0;
13459 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13460 : CompName,
13461 : FirstHVACIteration,
13462 : HVAC::CompressorOp::On,
13463 : PartLoadFrac,
13464 0 : this->m_CoolingCoilIndex,
13465 : fanOp,
13466 : HXUnitOn,
13467 : _,
13468 0 : state.dataUnitarySystems->economizerFlag,
13469 : _,
13470 0 : this->m_DehumidificationMode,
13471 0 : 0.0); // this->CoilSHR);
13472 :
13473 0 : OutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13474 :
13475 : // FullOutput will be different than the FullOutput determined above during sensible PLR calculations
13476 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13477 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13478 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13479 0 : state.dataLoopNodes->Node(InletNode).Temp,
13480 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13481 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13482 :
13483 : // Check to see if the system can meet the load with the compressor off
13484 : // If NoOutput is lower than (more cooling than required) or very near the ReqOutput, do not run the compressor
13485 0 : if ((NoLoadTempOut - DesOutTemp) < Acc) {
13486 0 : PartLoadFrac = 0.0;
13487 : // OutletTempDXCoil is the full capacity outlet temperature at PartLoadFrac = 1 from the CALL above.
13488 : // if this temp is greater than or very near the desired outlet temp, then run the compressor at PartLoadFrac
13489 : // = 1.
13490 : // ELSEIF ((OutletTempDXCoil > DesOutTemp) .OR. ABS(OutletTempDXCoil - DesOutTemp) .LE. (Acc*2.0d0)) THEN
13491 0 : } else if (OutletTempDXCoil > DesOutTemp - (tempAcc * 2.0)) {
13492 0 : PartLoadFrac = 1.0;
13493 : } else {
13494 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadRatio) {
13495 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13496 :
13497 0 : if (thisSys.CoolCoilFluidInletNode > 0) {
13498 0 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = thisSys.MaxCoolCoilFluidFlow * PartLoadRatio;
13499 : }
13500 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13501 0 : this->m_CoolingCoilIndex,
13502 : FirstHVACIteration,
13503 : HVAC::CompressorOp::On,
13504 : PartLoadRatio,
13505 : HXUnitOn,
13506 : fanOp,
13507 : _,
13508 : _,
13509 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13510 0 : 0.0);
13511 0 : Real64 OutletAirTemp = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13512 0 : return DesOutTemp - OutletAirTemp;
13513 0 : };
13514 :
13515 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13516 : }
13517 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13518 :
13519 1 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13520 :
13521 : // Get full load result
13522 0 : PartLoadFrac = 1.0;
13523 0 : DehumidMode = HVAC::CoilMode::Enhanced;
13524 0 : this->m_DehumidificationMode = DehumidMode;
13525 0 : DXCoils::SimDXCoilMultiMode(
13526 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13527 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13528 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13529 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13530 0 : state.dataLoopNodes->Node(InletNode).Temp,
13531 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13532 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13533 :
13534 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
13535 : // Check that this is the case; IF not set PartLoadFrac = 0.0 (off) and return
13536 : // Calculate the part load fraction
13537 0 : if (FullOutput >= 0) {
13538 0 : PartLoadFrac = 0.0;
13539 : } else {
13540 0 : OutletTempDXCoil = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13541 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13542 : // If sensible load and setpoint cannot be met, set PLR = 1. if no sensible load and
13543 : // latent load exists and setpoint cannot be met, set PLR = 1.
13544 0 : if ((OutletTempDXCoil > (DesOutTemp - (tempAcc * 2.0)) && SensibleLoad && this->m_RunOnSensibleLoad) ||
13545 0 : (OutletHumRatDXCoil >= (DesOutHumRat - (tempHumRatAcc * 2.0)) && !SensibleLoad && LatentLoad &&
13546 0 : this->m_RunOnLatentLoad)) {
13547 0 : PartLoadFrac = 1.0;
13548 : // ELSEIF ((SensibleLoad .and. LatentLoad .AND. .NOT. UnitarySystem(UnitarySysNum)%RunOnLatentLoad
13549 : // .AND. &
13550 : // OutletHumRatDXCoil < DesOutHumRat)) THEN
13551 0 : } else if (!SensibleLoad && (OutletHumRatDXCoil < DesOutHumRat && LatentLoad && this->m_RunOnLatentLoad)) {
13552 0 : PartLoadFrac = ReqOutput / FullOutput;
13553 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13554 0 : DXCoils::SimDXCoilMultiMode(
13555 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13556 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13557 0 : };
13558 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13559 0 : } else { // must be a sensible load so find PLR
13560 0 : PartLoadFrac = ReqOutput / FullOutput;
13561 0 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13562 0 : DXCoils::SimDXCoilMultiMode(
13563 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13564 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13565 0 : };
13566 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13567 : }
13568 : }
13569 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13570 :
13571 1 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13572 1 : HVAC::CoilMode coilMode = HVAC::CoilMode::Enhanced;
13573 1 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
13574 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
13575 : }
13576 1 : if (this->m_CoolingSpeedNum == 0) {
13577 0 : this->m_CoolingSpeedNum = 1;
13578 : }
13579 1 : bool const singleMode = (this->m_SingleMode == 1);
13580 1 : PartLoadFrac = 1.0;
13581 1 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13582 1 : this->m_CoolingSpeedNum = speedNum;
13583 1 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13584 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13585 : // Cooling: break if outlet temp is lower than DesOutTemp or approaches DesOutTemp to within Acc from above
13586 1 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) {
13587 1 : break;
13588 : }
13589 : }
13590 :
13591 : // make sure outlet temp is below set point before calling SolveRoot
13592 : // Cooling: iterate only when outlet temp is below DesOutTemp by at least Acc
13593 1 : if ((DesOutTemp - state.dataLoopNodes->Node(OutletNode).Temp) > Acc) {
13594 :
13595 4 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadFrac) {
13596 4 : bool const singleMode = false;
13597 4 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13598 4 : state, HVAC::CoilMode::Enhanced, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13599 : Real64 outletCondition =
13600 4 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13601 :
13602 4 : return DesOutTemp - outletCondition;
13603 1 : };
13604 :
13605 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13606 : }
13607 1 : if (this->m_CoolingSpeedNum == 1) {
13608 1 : this->m_CompPartLoadRatio = PartLoadFrac;
13609 1 : SpeedRatio = 0.0;
13610 : } else {
13611 0 : SpeedRatio = PartLoadFrac;
13612 0 : PartLoadFrac = 1.0;
13613 0 : this->m_CompPartLoadRatio = 1.0;
13614 : }
13615 :
13616 : } else {
13617 : }
13618 : } // END IF humidity ratio setpoint not met - Multimode humidity control
13619 :
13620 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13621 : // then overcool to meet moisture load
13622 44938 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13623 : // pass
13624 44935 : } else if ((OutletHumRatDXCoil > DesOutHumRat) && (!unitSys || PartLoadFrac < 1.0) && LatentLoad &&
13625 11 : (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat)) {
13626 :
13627 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13628 : // do not run the compressor
13629 6 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc) {
13630 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13631 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the DesOutHumRat,
13632 : // run the compressor at PartLoadFrac = 1.
13633 : // ELSEIF ((DesOutHumRat-FullLoadHumRatOut) .LT. HumRatAcc) THEN
13634 6 : } else if (FullLoadHumRatOut > (DesOutHumRat - tempHumRatAcc)) {
13635 1 : PartLoadFrac = 1.0;
13636 1 : SpeedRatio = 1.0; // #8849, need to set properties of multi-speed/2-speed coils
13637 1 : if (this->m_IsDXCoil) {
13638 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13639 : }
13640 : // ELSE find the PLR to meet the load
13641 :
13642 : } else {
13643 :
13644 5 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13645 0 : auto f = [&state, this, DesOutHumRat, fanOp](Real64 const PartLoadRatio) {
13646 0 : DXCoils::CalcDoe2DXCoil(state, this->m_CoolingCoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13647 0 : Real64 OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13648 0 : return DesOutHumRat - OutletAirHumRat;
13649 0 : };
13650 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13651 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13652 5 : } else if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13653 :
13654 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13655 : // do not run the compressor
13656 0 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc * 2.0) {
13657 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13658 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the
13659 : // DesOutHumRat, run the compressor at PartLoadFrac = 1.
13660 0 : } else if ((DesOutHumRat - FullLoadHumRatOut) < tempHumRatAcc * 2.0) {
13661 0 : PartLoadFrac = 1.0;
13662 : // ELSE find the PLR to meet the load
13663 : } else {
13664 0 : auto f = [&state, this, FirstHVACIteration, HXUnitOn, fanOp, DesOutHumRat](Real64 const PartLoadRatio) {
13665 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13666 0 : this->m_CoolingCoilIndex,
13667 : FirstHVACIteration,
13668 : HVAC::CompressorOp::On,
13669 : PartLoadRatio,
13670 : HXUnitOn,
13671 : fanOp,
13672 : _,
13673 0 : state.dataUnitarySystems->economizerFlag,
13674 0 : HVAC::CoilMode::Normal,
13675 0 : 0.0);
13676 0 : return DesOutHumRat - state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13677 0 : };
13678 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13679 0 : if (SolFla == -1) {
13680 :
13681 : // RegulaFalsi may not find latent PLR when the latent degradation model is used.
13682 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13683 0 : TempMaxPLR = -0.1;
13684 0 : while ((OutletHumRatDXCoil - DesOutHumRat) >= 0.0 && TempMaxPLR <= 1.0) {
13685 : // find upper limit of LatentPLR
13686 0 : TempMaxPLR += 0.1;
13687 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13688 : CompName,
13689 : FirstHVACIteration,
13690 : HVAC::CompressorOp::On,
13691 : TempMaxPLR,
13692 0 : this->m_CoolingCoilIndex,
13693 : fanOp,
13694 : HXUnitOn,
13695 : _,
13696 0 : state.dataUnitarySystems->economizerFlag,
13697 : _,
13698 0 : this->m_DehumidificationMode,
13699 0 : 0.0); // this->CoilSHR);
13700 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13701 : }
13702 0 : TempMaxPLR = min(1.0, TempMaxPLR + 0.1);
13703 0 : TempMinPLR = TempMaxPLR;
13704 0 : while ((OutletHumRatDXCoil - DesOutHumRat) <= 0.0 && TempMinPLR >= 0.0) {
13705 : // pull upper limit of LatentPLR DOwn to last valid limit (i.e. latent output still
13706 : // exceeds SystemMoisuterLoad)
13707 : // find minimum limit of Latent PLR
13708 0 : TempMinPLR -= 0.02;
13709 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13710 : CompName,
13711 : FirstHVACIteration,
13712 : HVAC::CompressorOp::On,
13713 : TempMinPLR,
13714 0 : this->m_CoolingCoilIndex,
13715 : fanOp,
13716 : HXUnitOn,
13717 : _,
13718 0 : state.dataUnitarySystems->economizerFlag,
13719 : _,
13720 0 : this->m_DehumidificationMode,
13721 0 : 0.0); // this->CoilSHR);
13722 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13723 : }
13724 0 : TempMinPLR = max(0.0, TempMinPLR - 0.1);
13725 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13726 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13727 0 : if (SolFla == -1) {
13728 0 : if (!state.dataGlobal->WarmupFlag) {
13729 0 : if (this->warnIndex.m_HXAssistedCRLatPLRIter < 1) {
13730 0 : ++this->warnIndex.m_HXAssistedCRLatPLRIter;
13731 0 : ShowWarningError(
13732 : state,
13733 0 : format("{} - Iteration limit exceeded calculating DX unit latent part-load ratio for unit = {}",
13734 0 : this->UnitType,
13735 0 : this->Name));
13736 0 : ShowContinueError(state, format("Estimated latent part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13737 0 : ShowContinueError(state, format("Calculated latent part-load ratio = {:.3R}", PartLoadFrac));
13738 0 : ShowContinueErrorTimeStamp(state,
13739 : "The calculated latent part-load ratio will be used and the simulation "
13740 : "continues. Occurrence info:");
13741 : }
13742 0 : ShowRecurringWarningErrorAtEnd(state,
13743 0 : this->UnitType + " \"" + this->Name +
13744 : "\" - Iteration limit exceeded calculating latent part-load ratio "
13745 : "error continues. Latent PLR "
13746 : "statistics follow.",
13747 0 : this->warnIndex.m_HXAssistedCRLatPLRIterIndex,
13748 : PartLoadFrac,
13749 : PartLoadFrac);
13750 : }
13751 :
13752 0 : } else if (SolFla == -2) {
13753 :
13754 0 : PartLoadFrac = ReqOutput / FullOutput;
13755 0 : if (!state.dataGlobal->WarmupFlag) {
13756 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail < 1) {
13757 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail;
13758 0 : ShowWarningError(state,
13759 0 : format("{} - DX unit latent part-load ratio calculation failed unexpectedly: part-load "
13760 : "ratio limits exceeded, for unit = {}",
13761 0 : this->UnitType,
13762 0 : this->Name));
13763 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13764 0 : ShowContinueErrorTimeStamp(
13765 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13766 : }
13767 0 : ShowRecurringWarningErrorAtEnd(state,
13768 0 : this->UnitType + " \"" + this->Name +
13769 : "\" - DX unit latent part-load ratio calculation failed "
13770 : "unexpectedly error continues. Latent PLR "
13771 : "statistics follow.",
13772 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex,
13773 : PartLoadFrac,
13774 : PartLoadFrac);
13775 : }
13776 : }
13777 0 : } else if (SolFla == -2) {
13778 0 : PartLoadFrac = ReqOutput / FullOutput;
13779 0 : if (!state.dataGlobal->WarmupFlag) {
13780 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail2 < 1) {
13781 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail2;
13782 0 : ShowWarningError(state,
13783 0 : format("{} - DX unit latent part-load ratio calculation failed: part-load ratio limits "
13784 : "exceeded, for unit = {}",
13785 0 : this->UnitType,
13786 0 : this->Name));
13787 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13788 0 : ShowContinueErrorTimeStamp(
13789 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13790 : }
13791 0 : ShowRecurringWarningErrorAtEnd(
13792 : state,
13793 0 : this->UnitType + " \"" + this->Name +
13794 : "\" - DX unit latent part-load ratio calculation failed error continues. Latent PLR statistics "
13795 : "follow.",
13796 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex2,
13797 : PartLoadFrac,
13798 : PartLoadFrac);
13799 : }
13800 : }
13801 : }
13802 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13803 :
13804 5 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13805 :
13806 : // Simulate MultiSpeed DX coil at sensible result
13807 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13808 :
13809 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13810 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13811 : // then overcool to meet moisture load
13812 :
13813 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13814 :
13815 0 : CycRatio = 0.0;
13816 0 : SpeedRatio = 0.0;
13817 :
13818 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13819 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13820 0 : if (OutletHumRatLS > DesOutHumRat) {
13821 0 : CycRatio = 1.0;
13822 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13823 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13824 0 : if (OutletHumRatHS < DesOutHumRat) {
13825 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13826 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13827 : SpeedRatio,
13828 0 : this->m_CoolingCoilIndex,
13829 : DesOutHumRat,
13830 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13831 : 0.0, // Real64 CycRatio,
13832 : 0, // int SpeedNum,
13833 : HVAC::FanOp::Invalid, // int FanOpMode,
13834 0 : HVAC::CompressorOp::On);
13835 0 : };
13836 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13837 : } else {
13838 0 : SpeedRatio = 1.0;
13839 : }
13840 0 : PartLoadFrac = SpeedRatio;
13841 : } else {
13842 0 : SpeedRatio = 0.0;
13843 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13844 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13845 : state,
13846 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13847 0 : this->m_CoolingCoilIndex,
13848 : DesOutHumRat,
13849 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13850 : 1.0, // Real64 CycRatio,
13851 0 : this->m_CoolingSpeedNum,
13852 0 : this->m_FanOpMode, // int FanOpMode,
13853 0 : HVAC::CompressorOp::On);
13854 0 : };
13855 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13856 0 : PartLoadFrac = CycRatio;
13857 : }
13858 : }
13859 :
13860 5 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13861 :
13862 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13863 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13864 :
13865 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13866 : // then overcool to meet moisture load
13867 :
13868 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13869 :
13870 0 : CycRatio = 0.0;
13871 0 : SpeedRatio = 0.0;
13872 :
13873 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13874 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13875 0 : if (OutletHumRatLS > DesOutHumRat) {
13876 0 : CycRatio = 1.0;
13877 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13878 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13879 0 : if (OutletHumRatHS < DesOutHumRat) {
13880 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13881 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13882 : SpeedRatio,
13883 0 : this->m_CoolingCoilIndex,
13884 : DesOutHumRat,
13885 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13886 : 0.0, // Real64 CycRatio,
13887 : 0, // int SpeedNum,
13888 : HVAC::FanOp::Invalid, // int FanOpMode,
13889 0 : HVAC::CompressorOp::On);
13890 0 : };
13891 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13892 : } else {
13893 0 : SpeedRatio = 1.0;
13894 : }
13895 : } else {
13896 0 : SpeedRatio = 0.0;
13897 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13898 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13899 : state,
13900 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13901 0 : this->m_CoolingCoilIndex,
13902 : DesOutHumRat,
13903 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13904 : 0.0, // Real64 CycRatio,
13905 : 0,
13906 : HVAC::FanOp::Invalid, // int FanOpMode,
13907 0 : HVAC::CompressorOp::On);
13908 0 : };
13909 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13910 : }
13911 : }
13912 5 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13913 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13914 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13915 : CompName,
13916 1 : this->m_CoolingCoilIndex,
13917 : this->m_FanOpMode,
13918 : HVAC::CompressorOp::On,
13919 : CycRatio,
13920 : this->m_CoolingSpeedNum,
13921 : SpeedRatio,
13922 : ReqOutput,
13923 : dummy,
13924 : OnOffAirFlowRatio);
13925 1 : OutletHumRatLS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13926 :
13927 1 : if (OutletHumRatLS > DesOutHumRat) {
13928 1 : CycRatio = 1.0;
13929 :
13930 2 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; ++speedNum) {
13931 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13932 : CompName,
13933 2 : this->m_CoolingCoilIndex,
13934 : this->m_FanOpMode,
13935 : HVAC::CompressorOp::On,
13936 : 1.0,
13937 : speedNum,
13938 : 1.0,
13939 : ReqOutput,
13940 : dummy,
13941 : OnOffAirFlowRatio);
13942 2 : OutletHumRatHS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13943 2 : if (OutletHumRatHS < DesOutHumRat || speedNum == this->m_NumOfSpeedCooling) {
13944 1 : this->m_CoolingSpeedNum = speedNum;
13945 1 : break;
13946 : }
13947 : }
13948 :
13949 1 : if (OutletHumRatHS < DesOutHumRat) {
13950 1 : if (this->m_CoolingSpeedNum == 1) {
13951 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13952 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13953 : state,
13954 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13955 0 : this->m_CoolingCoilIndex,
13956 : DesOutHumRat,
13957 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13958 : 1.0, // Real64 CycRatio,
13959 0 : this->m_CoolingSpeedNum,
13960 0 : this->m_FanOpMode, // int FanOpMode,
13961 0 : HVAC::CompressorOp::On);
13962 0 : };
13963 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13964 : } else {
13965 4 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13966 8 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13967 : SpeedRatio,
13968 4 : this->m_CoolingCoilIndex,
13969 : DesOutHumRat,
13970 4 : this->m_UnitarySysNum, // int UnitarySysNum,
13971 : 1.0, // Real64 CycRatio,
13972 4 : this->m_CoolingSpeedNum,
13973 4 : this->m_FanOpMode, // int FanOpMode,
13974 4 : HVAC::CompressorOp::On);
13975 1 : };
13976 1 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13977 : }
13978 : } else {
13979 0 : if (this->m_CoolingSpeedNum == 1) {
13980 0 : CycRatio = 1.0;
13981 : } else {
13982 0 : SpeedRatio = 1.0;
13983 : }
13984 : }
13985 : } else {
13986 0 : SpeedRatio = 0.0;
13987 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13988 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13989 : SpeedRatio,
13990 0 : this->m_CoolingCoilIndex,
13991 : DesOutHumRat,
13992 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13993 : 0.0, // Real64 CycRatio,
13994 : 0, // int SpeedNum
13995 : HVAC::FanOp::Invalid, // int FanOpMode,
13996 0 : HVAC::CompressorOp::On);
13997 0 : };
13998 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13999 : }
14000 5 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
14001 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
14002 0 : DXCoils::SimDXCoilMultiMode(
14003 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
14004 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
14005 0 : };
14006 0 : General::SolveRoot(state, Acc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14007 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14008 4 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
14009 1 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
14010 1 : if (this->m_CoolingSpeedNum == 0) {
14011 0 : this->m_CoolingSpeedNum = 1;
14012 : }
14013 1 : bool const singleMode = (this->m_SingleMode == 1);
14014 1 : PartLoadFrac = 1.0;
14015 2 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
14016 2 : this->m_CoolingSpeedNum = speedNum;
14017 2 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14018 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
14019 : // Cooling: break if outlet humrat is lower than DesOutHumRat or approaches DesOutHumRat to within HumRatAcc from above
14020 2 : if ((state.dataLoopNodes->Node(OutletNode).HumRat - DesOutHumRat) < HumRatAcc) {
14021 1 : break;
14022 : }
14023 : }
14024 : // make sure outlet HumRat is below set point before calling SolveRoot
14025 : // Cooling: iterate only when outlet humrat is below DesOutHumRat by at least HumRatAcc
14026 1 : if ((DesOutHumRat - state.dataLoopNodes->Node(OutletNode).HumRat) > HumRatAcc) {
14027 :
14028 3 : auto f = [&state,
14029 : this, // 0
14030 : DesOutHumRat, // 1
14031 : fanOp // 3
14032 : ](Real64 const PartLoadFrac) {
14033 3 : bool const singleMode = false;
14034 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14035 3 : state, HVAC::CoilMode::Normal, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
14036 : Real64 outletCondition =
14037 3 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex)
14038 3 : .HumRat;
14039 3 : return DesOutHumRat - outletCondition;
14040 1 : };
14041 :
14042 1 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14043 : }
14044 1 : if (this->m_CoolingSpeedNum == 1) {
14045 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14046 0 : SpeedRatio = 0.0;
14047 : } else {
14048 1 : SpeedRatio = PartLoadFrac;
14049 1 : PartLoadFrac = 1.0;
14050 1 : this->m_CompPartLoadRatio = 1.0;
14051 : }
14052 :
14053 3 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
14054 :
14055 15 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat](Real64 const PartLoadRatio) {
14056 15 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14057 15 : Real64 mdot = min(state.dataLoopNodes->Node(thisSys.CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14058 15 : thisSys.MaxCoolCoilFluidFlow * PartLoadRatio);
14059 15 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = mdot;
14060 30 : WaterCoils::SimulateWaterCoilComponents(
14061 15 : state, thisSys.m_CoolingCoilName, FirstHVACIteration, thisSys.m_CoolingCoilIndex, _, _, PartLoadRatio);
14062 15 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
14063 3 : };
14064 :
14065 3 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14066 :
14067 3 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
14068 :
14069 0 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat, ReqOutput](Real64 const PartLoadRatio) {
14070 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14071 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
14072 0 : Real64 dummy = 0.0;
14073 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
14074 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14075 : blankString,
14076 0 : thisSys.m_CoolingCoilIndex,
14077 : ReqOutput,
14078 : dummy,
14079 : thisSys.m_FanOpMode,
14080 : HVAC::CompressorOp::Off,
14081 : PartLoadRatio,
14082 : FirstHVACIteration);
14083 : } else {
14084 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14085 : blankString,
14086 0 : thisSys.m_CoolingCoilIndex,
14087 : thisSys.MaxCoolAirMassFlow,
14088 : thisSys.m_FanOpMode,
14089 : FirstHVACIteration,
14090 0 : thisSys.m_InitHeatPump,
14091 : ReqOutput,
14092 : dummy,
14093 : HVAC::CompressorOp::Off,
14094 : PartLoadRatio);
14095 : }
14096 0 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
14097 0 : };
14098 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
14099 :
14100 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
14101 :
14102 0 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
14103 0 : (this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::Off &&
14104 0 : this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
14105 0 : auto f = [&state, this, DesOutHumRat](Real64 const PartLoadRatio) {
14106 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
14107 0 : PackagedThermalStorageCoil::SimTESCoil(state,
14108 : thisSys.m_CoolingCoilName,
14109 0 : thisSys.m_CoolingCoilIndex,
14110 : thisSys.m_FanOpMode,
14111 0 : thisSys.m_TESOpMode,
14112 : PartLoadRatio);
14113 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat - DesOutHumRat;
14114 0 : };
14115 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14116 : }
14117 :
14118 : } else {
14119 : }
14120 : }
14121 : }
14122 : }
14123 65306 : if (SolFla == -1) {
14124 0 : if (!state.dataGlobal->WarmupFlag) {
14125 0 : if (this->warnIndex.m_SensPLRIter < 1) {
14126 0 : ++this->warnIndex.m_SensPLRIter;
14127 0 : ShowWarningError(state,
14128 0 : format("{} - Iteration limit exceeded calculating part-load ratio for unit = {}", this->UnitType, this->Name));
14129 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14130 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14131 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14132 : } else {
14133 0 : ShowRecurringWarningErrorAtEnd(
14134 : state,
14135 0 : this->UnitType + " \"" + this->Name +
14136 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. Sensible PLR statistics follow.",
14137 0 : this->warnIndex.m_SensPLRIterIndex,
14138 : PartLoadFrac,
14139 : PartLoadFrac);
14140 : }
14141 : }
14142 65306 : } else if (SolFla == -2) {
14143 0 : PartLoadFrac = ReqOutput / FullOutput;
14144 0 : if (!state.dataGlobal->WarmupFlag) {
14145 0 : if (this->warnIndex.m_SensPLRFail < 1) {
14146 0 : ++this->warnIndex.m_SensPLRFail;
14147 0 : ShowWarningError(state,
14148 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14149 0 : this->UnitType,
14150 0 : this->Name));
14151 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14152 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14153 : } else {
14154 0 : ShowRecurringWarningErrorAtEnd(
14155 : state,
14156 0 : this->UnitType + " \"" + this->Name +
14157 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14158 0 : this->warnIndex.m_SensPLRFailIndex,
14159 : PartLoadFrac,
14160 : PartLoadFrac);
14161 : }
14162 : }
14163 : }
14164 :
14165 65306 : if (SolFlaLat == -1 && SolFla != -1) {
14166 0 : if (!state.dataGlobal->WarmupFlag) {
14167 0 : if (this->warnIndex.m_LatPLRIter < 1) {
14168 0 : ++this->warnIndex.m_LatPLRIter;
14169 0 : ShowWarningError(
14170 0 : state, format("{} - Iteration limit exceeded calculating latent part-load ratio for unit = {}", this->UnitType, this->Name));
14171 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14172 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14173 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14174 : }
14175 0 : ShowRecurringWarningErrorAtEnd(
14176 : state,
14177 0 : this->UnitType + " \"" + this->Name +
14178 : "\" - Iteration limit exceeded calculating latent part-load ratio error continues. Latent PLR statistics follow.",
14179 0 : this->warnIndex.m_LatPLRIterIndex,
14180 : PartLoadFrac,
14181 : PartLoadFrac);
14182 : }
14183 65306 : } else if (SolFlaLat == -2 && SolFla != -2) {
14184 : // RegulaFalsi returns PLR = minPLR when a solution cannot be found, recalculate PartLoadFrac.
14185 0 : if (NoLoadHumRatOut - FullLoadHumRatOut != 0.0) {
14186 0 : PartLoadFrac = (NoLoadHumRatOut - DesOutHumRat) / (NoLoadHumRatOut - FullLoadHumRatOut);
14187 : } else {
14188 0 : PartLoadFrac = 1.0;
14189 : }
14190 0 : if (!state.dataGlobal->WarmupFlag) {
14191 0 : if (this->warnIndex.m_LatPLRFail < 1) {
14192 0 : ++this->warnIndex.m_LatPLRFail;
14193 0 : ShowWarningError(state,
14194 0 : format("{} - latent part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14195 0 : this->UnitType,
14196 0 : this->Name));
14197 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14198 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14199 : }
14200 0 : ShowRecurringWarningErrorAtEnd(state,
14201 0 : this->UnitType + " \"" + this->Name +
14202 : "\" - latent part-load ratio calculation failed error continues. Latent PLR statistics follow.",
14203 0 : this->warnIndex.m_LatPLRFailIndex,
14204 : PartLoadFrac,
14205 : PartLoadFrac);
14206 : }
14207 : }
14208 : // Set the final results
14209 :
14210 65306 : if (PartLoadFrac > 1.0) {
14211 0 : PartLoadFrac = 1.0;
14212 65306 : } else if (PartLoadFrac < 0.0) {
14213 0 : PartLoadFrac = 0.0;
14214 : }
14215 :
14216 65306 : this->m_CoolingPartLoadFrac = PartLoadFrac;
14217 65306 : this->m_CoolingSpeedRatio = SpeedRatio;
14218 65306 : this->m_CoolingCycRatio = CycRatio;
14219 65306 : this->m_DehumidificationMode = DehumidMode;
14220 :
14221 65306 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14222 0 : this->m_sysType != SysType::PackagedWSHP) {
14223 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14224 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14225 : }
14226 :
14227 65306 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
14228 15 : mdot = PartLoadFrac * this->MaxCoolCoilFluidFlow;
14229 15 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
14230 : }
14231 65306 : } // namespace UnitarySystems
14232 :
14233 31 : void UnitarySys::controlHeatingSystemToSP(EnergyPlusData &state,
14234 : int const AirLoopNum, // index to air loop
14235 : bool const FirstHVACIteration, // First HVAC iteration flag
14236 : HVAC::CompressorOp &compressorOp, // compressor on/off control
14237 : Real64 &HeatCoilLoad // load met by heating coil
14238 : )
14239 : {
14240 : // SUBROUTINE INFORMATION:
14241 : // AUTHOR Richard Raustad, FSEC
14242 : // DATE WRITTEN February 2013
14243 :
14244 : // PURPOSE OF THIS SUBROUTINE:
14245 : // Simulate the coil object at the required PLR.
14246 :
14247 : // METHODOLOGY EMPLOYED:
14248 : // Calculate operating PLR and adjust speed when using multispeed coils.
14249 :
14250 : // SUBROUTINE PARAMETER DEFINITIONS:
14251 31 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14252 31 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14253 31 : bool constexpr SuppHeatingCoilFlag(false);
14254 :
14255 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14256 31 : Real64 FullOutput = 0; // Sensible capacity (outlet - inlet) when the compressor is on
14257 31 : Real64 ReqOutput = 0; // Sensible capacity (outlet - inlet) required to meet load or set point temperature
14258 :
14259 31 : Real64 OutdoorDryBulb = 0.0; // local variable for OutDryBulbTemp
14260 31 : Real64 OutdoorHumRat = 0.0; // local variable for OutHumRat
14261 31 : Real64 OutdoorPressure = 0.0; // local variable for OutBaroPress
14262 31 : Real64 OutdoorWetBulb = 0.0; // local variable for OutWetBulbTemp
14263 31 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14264 31 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14265 :
14266 : // Set local variables
14267 : // Retrieve the load on the controlled zone
14268 31 : int InletNode = this->HeatCoilInletNodeNum;
14269 31 : int OutletNode = this->HeatCoilOutletNodeNum;
14270 31 : std::string CompName = this->m_HeatingCoilName;
14271 31 : int CompIndex = this->m_HeatingCoilIndex;
14272 31 : HVAC::FanOp fanOp = this->m_FanOpMode;
14273 31 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14274 :
14275 31 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14276 31 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14277 31 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14278 0 : this->m_sysType != SysType::PackagedWSHP) {
14279 0 : LoopHeatingCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF;
14280 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
14281 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
14282 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
14283 : }
14284 :
14285 31 : Real64 PartLoadFrac = 0.0;
14286 31 : Real64 SpeedRatio = 0.0;
14287 31 : Real64 CycRatio = 0.0;
14288 31 : Real64 dummy = 0.0;
14289 31 : int SolFla = 0;
14290 31 : Real64 SensLoad = 0.0;
14291 31 : Real64 OutletTemp = 0.0;
14292 :
14293 31 : if (this->m_CondenserNodeNum != 0) {
14294 0 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
14295 0 : if (this->m_CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
14296 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14297 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14298 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14299 : } else {
14300 0 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
14301 : // IF node is not connected to anything, pressure = default, use weather data
14302 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
14303 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14304 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14305 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14306 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14307 : } else {
14308 0 : OutdoorHumRat = state.dataLoopNodes->Node(this->m_CondenserNodeNum).HumRat;
14309 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
14310 0 : OutdoorWetBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).OutAirWetBulb;
14311 : }
14312 : }
14313 : } else {
14314 31 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
14315 31 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
14316 31 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
14317 31 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
14318 : }
14319 :
14320 : // IF there is a fault of coil SAT Sensor
14321 31 : if (this->m_FaultyCoilSATFlag) {
14322 : // calculate the sensor offset using fault information
14323 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14324 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14325 : // update the DesOutTemp
14326 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14327 : }
14328 :
14329 : // IF DXHeatingSystem is scheduled on and there is flow
14330 62 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && this->m_heatingCoilAvailSched->getCurrentVal() > 0.0 &&
14331 31 : state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow) {
14332 :
14333 20 : bool SensibleLoad = false;
14334 : // Determine if there is a sensible load on this system
14335 20 : if (DesOutTemp - state.dataLoopNodes->Node(InletNode).Temp > HVAC::TempControlTol) {
14336 18 : SensibleLoad = true;
14337 : }
14338 : // if a heat pump and other coil is on, disable this coil
14339 20 : if (this->m_HeatPump && this->m_CoolingPartLoadFrac > 0.0) {
14340 1 : SensibleLoad = false;
14341 : }
14342 :
14343 : // disable compressor if OAT is below minimum outdoor temperature
14344 20 : if (OutdoorDryBulb < this->m_MinOATCompressorHeating) {
14345 0 : SensibleLoad = false;
14346 : }
14347 :
14348 : // IF DXHeatingSystem runs with a heating load then set PartLoadFrac on Heating System
14349 20 : if (SensibleLoad) {
14350 :
14351 18 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14352 54 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
14353 18 : state.dataLoopNodes->Node(InletNode).HumRat,
14354 18 : state.dataLoopNodes->Node(InletNode).Temp,
14355 18 : state.dataLoopNodes->Node(InletNode).HumRat);
14356 18 : ReqOutput = max(0.0, ReqOutput);
14357 :
14358 : // Get no load result
14359 18 : PartLoadFrac = 0.0;
14360 18 : compressorOp = HVAC::CompressorOp::Off;
14361 :
14362 18 : switch (this->m_HeatingCoilType_Num) {
14363 0 : case HVAC::CoilDX_HeatingEmpirical: {
14364 0 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, CompIndex, fanOp, PartLoadFrac);
14365 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14366 0 : } break;
14367 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
14368 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14369 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14370 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
14371 0 : if (HeatingActive) {
14372 0 : PartLoadFrac = 1.0;
14373 : }
14374 :
14375 0 : } break;
14376 11 : case HVAC::CoilDX_MultiSpeedHeating:
14377 : case HVAC::Coil_HeatingElectric_MultiStage:
14378 : case HVAC::Coil_HeatingGas_MultiStage: {
14379 11 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14380 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14381 0 : this->m_SpeedNum = this->m_HeatingSpeedNum;
14382 0 : bool useMaxedSpeed = false;
14383 0 : if (this->m_SpeedNum > this->m_NumOfSpeedHeating) {
14384 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14385 0 : this->m_SpeedNum = this->m_NumOfSpeedHeating;
14386 0 : this->m_CoilSpeedErrIdx++;
14387 0 : useMaxedSpeed = true;
14388 0 : ShowRecurringWarningErrorAtEnd(
14389 : state,
14390 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_HeatingCoilName +
14391 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
14392 0 : this->m_CoilSpeedErrIdx,
14393 0 : this->m_EMSOverrideCoilSpeedNumValue,
14394 0 : this->m_EMSOverrideCoilSpeedNumValue,
14395 : _,
14396 : "",
14397 : "");
14398 : }
14399 0 : if (this->m_HeatingSpeedNum == 1) {
14400 0 : this->m_HeatingSpeedRatio = 0.0;
14401 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14402 0 : this->m_HeatingCycRatio = CycRatio;
14403 0 : if (useMaxedSpeed || CycRatio == 0) {
14404 0 : this->m_HeatingCycRatio = 1;
14405 : } else {
14406 0 : this->m_HeatingCycRatio = CycRatio;
14407 : }
14408 : } else {
14409 0 : this->m_HeatingCycRatio = 1.0;
14410 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14411 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14412 0 : if (useMaxedSpeed || SpeedRatio == 0) {
14413 0 : this->m_HeatingSpeedRatio = 1;
14414 : } else {
14415 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14416 : }
14417 : }
14418 : }
14419 11 : bool LatentLoad = false;
14420 11 : this->simMultiSpeedCoils(
14421 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, this->m_SpeedNum);
14422 11 : } break;
14423 1 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14424 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14425 1 : int SpeedNum = 0;
14426 1 : this->m_HeatingCoilSensDemand = ReqOutput;
14427 1 : VariableSpeedCoils::SimVariableSpeedCoils(
14428 1 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14429 1 : } break;
14430 4 : case HVAC::Coil_HeatingGasOrOtherFuel:
14431 : case HVAC::Coil_HeatingElectric:
14432 : case HVAC::Coil_HeatingDesuperheater: {
14433 4 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, PartLoadFrac, CompIndex, _, _, fanOp);
14434 4 : } break;
14435 2 : case HVAC::Coil_HeatingWater: {
14436 6 : WaterCoils::SimulateWaterCoilComponents(
14437 4 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14438 2 : } break;
14439 0 : case HVAC::Coil_HeatingSteam: {
14440 0 : SteamCoils::SimulateSteamCoilComponents(state,
14441 : CompName,
14442 : FirstHVACIteration,
14443 0 : this->m_HeatingCoilIndex,
14444 0 : 1.0,
14445 : _,
14446 0 : this->m_FanOpMode,
14447 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14448 0 : } break;
14449 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14450 0 : if (FirstHVACIteration) {
14451 0 : this->m_CompPartLoadRatio = 1;
14452 : }
14453 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14454 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::Off, PartLoadFrac, FirstHVACIteration);
14455 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14456 0 : this->m_HeatingCoilSensDemand = 0.0;
14457 0 : } break;
14458 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14459 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14460 : blankString,
14461 : CompIndex,
14462 : this->MaxHeatAirMassFlow,
14463 : fanOp,
14464 : FirstHVACIteration,
14465 0 : this->m_InitHeatPump,
14466 : ReqOutput,
14467 : dummy,
14468 : HVAC::CompressorOp::Off,
14469 : PartLoadFrac);
14470 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14471 0 : } break;
14472 0 : default:
14473 0 : break;
14474 : }
14475 :
14476 : // IF outlet temp at no load is within ACC of set point, do not run the coil
14477 :
14478 36 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14479 18 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14480 : // do nothing, coil is at the set point.
14481 18 : } else if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) > Acc) { // IF outlet temp is above set point turn off coil
14482 0 : PartLoadFrac = 0.0;
14483 : } else { // ELSE get full load result
14484 :
14485 : // Get full load result
14486 18 : PartLoadFrac = 1.0;
14487 18 : compressorOp = HVAC::CompressorOp::On;
14488 :
14489 18 : switch (this->m_HeatingCoilType_Num) {
14490 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14491 0 : DXCoils::SimDXCoil(
14492 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_HeatingCoilIndex, fanOp, PartLoadFrac);
14493 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14494 0 : } break;
14495 0 : case HVAC::Coil_UserDefined: {
14496 : // should never get here, coil cannot be controlled and has already been simulated
14497 0 : } break;
14498 0 : case HVAC::CoilDX_MultiSpeedHeating: {
14499 0 : CycRatio = 1.0;
14500 0 : SpeedRatio = 0.0;
14501 0 : int SpeedNum = 0;
14502 0 : bool LatentLoad = false;
14503 0 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14504 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14505 0 : SpeedNum = this->m_HeatingSpeedNum;
14506 0 : if (this->m_HeatingSpeedNum == 1) {
14507 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14508 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14509 0 : this->m_HeatingCycRatio = CycRatio;
14510 0 : if (CycRatio == 0) {
14511 0 : this->m_HeatingCycRatio = 1;
14512 : } else {
14513 0 : this->m_HeatingCycRatio = CycRatio;
14514 : }
14515 : } else {
14516 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14517 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14518 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14519 0 : if (SpeedRatio == 0) {
14520 0 : this->m_HeatingSpeedRatio = 1;
14521 : } else {
14522 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14523 : }
14524 : }
14525 0 : if (SpeedNum > this->m_NumOfSpeedHeating) {
14526 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14527 0 : SpeedNum = this->m_NumOfSpeedHeating;
14528 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14529 0 : if (this->m_HeatingSpeedNum == 1) {
14530 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14531 : } else {
14532 0 : this->m_HeatingSpeedRatio = SpeedRatio = 1.0;
14533 : }
14534 : }
14535 0 : this->simMultiSpeedCoils(
14536 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14537 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14538 : } else {
14539 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14540 0 : if (SpeedNum > 1) {
14541 0 : CycRatio = 0.0;
14542 0 : SpeedRatio = 1.0;
14543 : }
14544 0 : this->m_HeatingSpeedNum = SpeedNum;
14545 0 : this->simMultiSpeedCoils(state,
14546 : AirLoopNum,
14547 : FirstHVACIteration,
14548 : compressorOp,
14549 : SensibleLoad,
14550 : LatentLoad,
14551 : PartLoadFrac,
14552 : HeatingCoil,
14553 : SpeedNum);
14554 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14555 0 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14556 0 : break;
14557 : }
14558 : }
14559 : }
14560 0 : } break;
14561 11 : case HVAC::Coil_HeatingElectric_MultiStage:
14562 : case HVAC::Coil_HeatingGas_MultiStage: {
14563 11 : bool LatentLoad = false;
14564 11 : CycRatio = 1.0;
14565 11 : SpeedRatio = 1.0;
14566 11 : SensLoad = 1.0; // turns on coil
14567 11 : this->m_HeatingSpeedRatio = SpeedRatio;
14568 11 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14569 22 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14570 18 : this->m_HeatingSpeedNum = SpeedNum;
14571 18 : this->simMultiSpeedCoils(
14572 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14573 18 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14574 18 : SpeedRatio = double(SpeedNum) - 1.0;
14575 18 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14576 7 : break;
14577 : }
14578 : }
14579 11 : } break;
14580 1 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14581 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14582 1 : CycRatio = 1.0;
14583 1 : SpeedRatio = 1.0;
14584 1 : SensLoad = 1.0; // turns on coil
14585 1 : this->m_HeatingSpeedRatio = SpeedRatio;
14586 1 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14587 2 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14588 2 : this->m_HeatingSpeedNum = SpeedNum;
14589 2 : VariableSpeedCoils::SimVariableSpeedCoils(
14590 2 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14591 2 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14592 2 : if (OutletTemp > DesOutTemp && SensibleLoad) {
14593 1 : break;
14594 : }
14595 : }
14596 1 : } break;
14597 3 : case HVAC::Coil_HeatingGasOrOtherFuel:
14598 : case HVAC::Coil_HeatingElectric: {
14599 6 : HeatingCoils::SimulateHeatingCoilComponents(
14600 3 : state, CompName, FirstHVACIteration, this->m_DesignHeatingCapacity, CompIndex, _, _, fanOp);
14601 3 : } break;
14602 1 : case HVAC::Coil_HeatingDesuperheater: {
14603 1 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, ReqOutput, CompIndex, _, _, fanOp);
14604 1 : } break;
14605 2 : case HVAC::Coil_HeatingWater: {
14606 2 : mdot = this->MaxHeatCoilFluidFlow;
14607 2 : PlantUtilities::SetComponentFlowRate(
14608 2 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14609 :
14610 6 : WaterCoils::SimulateWaterCoilComponents(
14611 4 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14612 2 : } break;
14613 0 : case HVAC::Coil_HeatingSteam: {
14614 0 : mdot = this->MaxHeatCoilFluidFlow;
14615 0 : PlantUtilities::SetComponentFlowRate(
14616 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14617 :
14618 0 : SteamCoils::SimulateSteamCoilComponents(state,
14619 : CompName,
14620 : FirstHVACIteration,
14621 0 : this->m_HeatingCoilIndex,
14622 0 : 1.0,
14623 : _,
14624 0 : this->m_FanOpMode,
14625 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14626 0 : } break;
14627 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14628 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14629 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::On, PartLoadFrac, FirstHVACIteration);
14630 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14631 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14632 0 : } break;
14633 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14634 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14635 : blankString,
14636 : CompIndex,
14637 : this->MaxHeatAirMassFlow,
14638 : fanOp,
14639 : FirstHVACIteration,
14640 0 : this->m_InitHeatPump,
14641 : ReqOutput,
14642 : dummy,
14643 : HVAC::CompressorOp::Off,
14644 : PartLoadFrac);
14645 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14646 0 : } break;
14647 0 : default:
14648 0 : break;
14649 : }
14650 :
14651 18 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14652 18 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
14653 18 : state.dataLoopNodes->Node(OutletNode).HumRat,
14654 18 : state.dataLoopNodes->Node(InletNode).Temp,
14655 18 : state.dataLoopNodes->Node(InletNode).HumRat);
14656 : // If the outlet temp is within ACC of set point,
14657 34 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14658 16 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14659 : // do nothing, coil is at set point
14660 16 : } else if (state.dataLoopNodes->Node(OutletNode).Temp < (DesOutTemp - Acc)) { // IF outlet temp is below set point coil must be on
14661 3 : PartLoadFrac = 1.0;
14662 : } else { // ELSE find the PLR to meet the set point
14663 :
14664 13 : switch (this->m_HeatingCoilType_Num) {
14665 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14666 0 : auto f = [&state, CompIndex, DesOutTemp](Real64 const PartLoadFrac) {
14667 0 : DXCoils::CalcDXHeatingCoil(state, CompIndex, PartLoadFrac, HVAC::FanOp::Continuous, 1.0);
14668 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(CompIndex);
14669 0 : };
14670 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14671 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14672 0 : } break;
14673 8 : case HVAC::CoilDX_MultiSpeedHeating:
14674 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14675 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
14676 : case HVAC::Coil_HeatingElectric_MultiStage:
14677 : case HVAC::Coil_HeatingGas_MultiStage: {
14678 8 : if (this->m_HeatingSpeedNum > 1.0) {
14679 12 : auto f = [&state, this, DesOutTemp, CycRatio, fanOp](Real64 const SpeedRatio) {
14680 24 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14681 : SpeedRatio,
14682 12 : this->m_HeatingCoilIndex,
14683 : DesOutTemp,
14684 12 : this->m_UnitarySysNum,
14685 : CycRatio,
14686 12 : this->m_HeatingSpeedNum,
14687 : fanOp,
14688 : HVAC::CompressorOp::On,
14689 12 : false);
14690 4 : };
14691 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14692 4 : this->m_HeatingCycRatio = CycRatio;
14693 4 : this->m_HeatingSpeedRatio = SpeedRatio;
14694 4 : this->m_HeatingPartLoadFrac = SpeedRatio;
14695 4 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14696 4 : PartLoadFrac = SpeedRatio;
14697 : } else {
14698 4 : SpeedRatio = 0.0;
14699 4 : this->m_HeatingSpeedRatio = SpeedRatio;
14700 12 : auto f = [&state, this, DesOutTemp, SpeedRatio, fanOp](Real64 const CycRatio) {
14701 24 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14702 : CycRatio,
14703 12 : this->m_HeatingCoilIndex,
14704 : DesOutTemp,
14705 12 : this->m_UnitarySysNum,
14706 : SpeedRatio,
14707 12 : this->m_HeatingSpeedNum,
14708 : fanOp,
14709 : HVAC::CompressorOp::On,
14710 12 : false);
14711 4 : };
14712 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14713 4 : this->m_HeatingCycRatio = CycRatio;
14714 4 : this->m_HeatingPartLoadFrac = CycRatio;
14715 4 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14716 4 : PartLoadFrac = CycRatio;
14717 : }
14718 8 : } break;
14719 1 : case HVAC::Coil_HeatingGasOrOtherFuel: {
14720 3 : HeatingCoils::SimulateHeatingCoilComponents(
14721 2 : state, this->m_HeatingCoilName, FirstHVACIteration, ReqOutput, CompIndex, _, true, fanOp, PartLoadFrac);
14722 1 : PartLoadFrac = ReqOutput / FullOutput;
14723 1 : HeatCoilLoad = ReqOutput;
14724 1 : } break;
14725 2 : case HVAC::Coil_HeatingElectric:
14726 : case HVAC::Coil_HeatingDesuperheater: {
14727 2 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14728 6 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, fanOp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14729 12 : return this->gasElecHeatingCoilResidual(state,
14730 : PartLoadFrac,
14731 6 : this->m_UnitarySysNum,
14732 : FirstHVACIteration,
14733 : DesOutTemp,
14734 : tmpSuppHeatingCoilFlag,
14735 : fanOp,
14736 6 : this->m_DesignHeatingCapacity);
14737 2 : };
14738 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14739 2 : } break;
14740 2 : case HVAC::Coil_HeatingWater: {
14741 :
14742 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14743 : maxPartLoadFrac =
14744 2 : min(1.0,
14745 2 : ((mdot / this->MaxHeatCoilFluidFlow) +
14746 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14747 :
14748 16 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const maxPartLoadFrac) {
14749 : Real64 OutletAirTemp; // Outlet air temperature [C]
14750 :
14751 16 : Real64 mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14752 16 : this->MaxHeatCoilFluidFlow * maxPartLoadFrac);
14753 16 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14754 48 : WaterCoils::SimulateWaterCoilComponents(state,
14755 16 : this->m_HeatingCoilName,
14756 : FirstHVACIteration,
14757 16 : this->m_HeatingCoilIndex,
14758 32 : 0.0, // QActual
14759 16 : this->m_FanOpMode,
14760 : maxPartLoadFrac);
14761 16 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14762 16 : return DesOutTemp - OutletAirTemp;
14763 2 : };
14764 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14765 2 : } break;
14766 0 : case HVAC::Coil_HeatingSteam: {
14767 :
14768 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14769 : maxPartLoadFrac =
14770 0 : min(1.0,
14771 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14772 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14773 :
14774 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14775 : Real64 OutletAirTemp; // Outlet air temperature [C]
14776 : Real64 mdot;
14777 :
14778 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14779 0 : this->MaxHeatCoilFluidFlow * PartLoadFrac);
14780 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14781 0 : SteamCoils::SimulateSteamCoilComponents(state,
14782 0 : this->m_HeatingCoilName,
14783 : FirstHVACIteration,
14784 0 : this->m_HeatingCoilIndex,
14785 0 : 1.0,
14786 : _,
14787 0 : this->m_FanOpMode,
14788 : PartLoadFrac);
14789 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp; // RR this should be supp coil
14790 0 : return DesOutTemp - OutletAirTemp;
14791 0 : };
14792 :
14793 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14794 0 : } break;
14795 0 : case HVAC::Coil_HeatingWaterToAirHPSimple:
14796 : case HVAC::Coil_HeatingWaterToAirHP: {
14797 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14798 :
14799 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
14800 : Real64 OutletAirTemp; // outlet air humidity ratio [kg/kg]
14801 : Real64 dummy;
14802 :
14803 0 : this->m_CompPartLoadRatio = PartLoadRatio;
14804 :
14805 0 : dummy = 0.0;
14806 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
14807 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14808 : blankString,
14809 0 : this->m_HeatingCoilIndex,
14810 : ReqOutput,
14811 : dummy,
14812 0 : this->m_FanOpMode,
14813 : HVAC::CompressorOp::On,
14814 : PartLoadRatio,
14815 : FirstHVACIteration);
14816 : } else {
14817 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14818 : blankString,
14819 0 : this->m_HeatingCoilIndex,
14820 0 : this->MaxHeatAirMassFlow,
14821 0 : this->m_FanOpMode,
14822 : FirstHVACIteration,
14823 0 : this->m_InitHeatPump,
14824 : ReqOutput,
14825 : dummy,
14826 : HVAC::CompressorOp::Off,
14827 : PartLoadRatio);
14828 : }
14829 :
14830 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14831 0 : return DesOutTemp - OutletAirTemp;
14832 0 : };
14833 :
14834 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14835 0 : } break;
14836 0 : case HVAC::Coil_UserDefined: {
14837 : // should never get here, user defined coil cannot be controlled and has already been simulated
14838 0 : } break;
14839 0 : default: {
14840 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
14841 0 : ShowFatalError(
14842 : state,
14843 0 : format("ControlHeatingSystemToSP: Invalid heating coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
14844 0 : } break;
14845 : }
14846 : }
14847 : }
14848 : }
14849 : }
14850 :
14851 31 : if (PartLoadFrac > 1.0) {
14852 0 : PartLoadFrac = 1.0;
14853 31 : } else if (PartLoadFrac < 0.0) {
14854 0 : PartLoadFrac = 0.0;
14855 : }
14856 :
14857 31 : if (SolFla < 0) {
14858 0 : if (SolFla == -1) {
14859 0 : if (!state.dataGlobal->WarmupFlag) {
14860 0 : if (this->warnIndex.m_HeatCoilSensPLRIter < 1) {
14861 0 : ++this->warnIndex.m_HeatCoilSensPLRIter;
14862 0 : ShowWarningError(
14863 : state,
14864 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}", this->UnitType, this->Name));
14865 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14866 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14867 0 : ShowContinueErrorTimeStamp(state,
14868 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14869 : } else {
14870 0 : ShowRecurringWarningErrorAtEnd(state,
14871 0 : this->UnitType + " \"" + this->Name +
14872 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. "
14873 : "Sensible PLR statistics follow.",
14874 0 : this->warnIndex.m_HeatCoilSensPLRIterIndex,
14875 : PartLoadFrac,
14876 : PartLoadFrac);
14877 : }
14878 : }
14879 0 : } else if (SolFla == -2) {
14880 0 : PartLoadFrac = ReqOutput / FullOutput;
14881 0 : if (!state.dataGlobal->WarmupFlag) {
14882 0 : if (this->warnIndex.m_HeatCoilSensPLRFail < 1) {
14883 0 : ++this->warnIndex.m_HeatCoilSensPLRFail;
14884 0 : ShowWarningError(state,
14885 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14886 0 : this->UnitType,
14887 0 : this->Name));
14888 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14889 0 : ShowContinueErrorTimeStamp(state,
14890 : "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14891 : } else {
14892 0 : ShowRecurringWarningErrorAtEnd(
14893 : state,
14894 0 : this->UnitType + " \"" + this->Name +
14895 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14896 0 : this->warnIndex.m_HeatCoilSensPLRFailIndex,
14897 : PartLoadFrac,
14898 : PartLoadFrac);
14899 : }
14900 : }
14901 : }
14902 : }
14903 :
14904 : // Set the final results
14905 31 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14906 31 : this->m_HeatingSpeedRatio = SpeedRatio;
14907 31 : this->m_HeatingCycRatio = CycRatio;
14908 31 : HeatCoilLoad = ReqOutput;
14909 :
14910 31 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14911 0 : this->m_sysType != SysType::PackagedWSHP) {
14912 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF =
14913 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14914 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14915 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14916 : }
14917 :
14918 31 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
14919 4 : mdot = PartLoadFrac * this->MaxHeatCoilFluidFlow;
14920 4 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14921 : }
14922 31 : }
14923 :
14924 11 : void UnitarySys::controlSuppHeatSystemToSP(EnergyPlusData &state,
14925 : int const AirLoopNum, // index to air loop
14926 : bool const FirstHVACIteration // First HVAC iteration flag
14927 : )
14928 : {
14929 : // SUBROUTINE INFORMATION:
14930 : // AUTHOR Richard Raustad, FSEC
14931 : // DATE WRITTEN February 2013
14932 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
14933 :
14934 : // PURPOSE OF THIS SUBROUTINE:
14935 : // This subroutine updates the System outlet nodes.
14936 :
14937 : // METHODOLOGY EMPLOYED:
14938 : // Data is moved from the System data structure to the System outlet nodes.
14939 :
14940 : // SUBROUTINE PARAMETER DEFINITIONS:
14941 11 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14942 11 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14943 11 : int constexpr SolveMaxIter(50);
14944 11 : constexpr bool SuppHeatingCoilFlag(true);
14945 :
14946 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14947 11 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
14948 11 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14949 11 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14950 11 : Real64 PartLoadFrac = 0.0;
14951 11 : Real64 SpeedRatio = 0.0;
14952 11 : Real64 CycRatio = 0.0;
14953 :
14954 : // Set local variables
14955 11 : auto &inletNode = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode);
14956 11 : auto &outletNode = state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum);
14957 11 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14958 11 : std::string_view CompName = this->m_SuppHeatCoilName;
14959 :
14960 11 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14961 11 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14962 11 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14963 0 : this->m_sysType != SysType::PackagedWSHP) {
14964 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14965 0 : LoopHeatingCoilMaxRTFSave = afnInfo.AFNLoopHeatingCoilMaxRTF;
14966 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = 0.0;
14967 0 : LoopDXCoilMaxRTFSave = afnInfo.AFNLoopDXCoilRTF;
14968 0 : afnInfo.AFNLoopDXCoilRTF = 0.0;
14969 : }
14970 :
14971 : // IF there is a fault of coil SAT Sensor
14972 11 : if (this->m_FaultyCoilSATFlag) {
14973 : // calculate the sensor offset using fault information
14974 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14975 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14976 : // update the DesOutTemp
14977 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14978 : }
14979 :
14980 11 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && (inletNode.MassFlowRate > HVAC::SmallAirVolFlow)) {
14981 :
14982 8 : if (inletNode.Temp < (DesOutTemp - HVAC::TempControlTol)) {
14983 6 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
14984 2 : this->setEMSSuppCoilStagePLR(state);
14985 : } else {
14986 : // Get no load result at PartLoadFrac = 0.0
14987 :
14988 4 : switch (this->m_SuppHeatCoilType_Num) {
14989 0 : case HVAC::Coil_HeatingGasOrOtherFuel:
14990 : case HVAC::Coil_HeatingElectric:
14991 : case HVAC::Coil_HeatingDesuperheater: {
14992 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
14993 : CompName,
14994 : FirstHVACIteration,
14995 : PartLoadFrac,
14996 0 : this->m_SuppHeatCoilIndex,
14997 : QCoilActual,
14998 : SuppHeatingCoilFlag,
14999 0 : this->m_FanOpMode,
15000 : PartLoadFrac); // QCoilReq=PartLoadFrac 0.0 for this call
15001 0 : } break;
15002 2 : case HVAC::Coil_HeatingElectric_MultiStage: {
15003 : // SpeedRatio = 0.0;
15004 8 : HeatingCoils::SimulateHeatingCoilComponents(state,
15005 : CompName,
15006 : FirstHVACIteration,
15007 : DataLoopNode::SensedLoadFlagValue,
15008 2 : this->m_SuppHeatCoilIndex,
15009 : QCoilActual,
15010 : SuppHeatingCoilFlag,
15011 2 : this->m_FanOpMode,
15012 : PartLoadFrac,
15013 4 : 0,
15014 : SpeedRatio);
15015 2 : } break;
15016 2 : case HVAC::Coil_HeatingWater: {
15017 6 : WaterCoils::SimulateWaterCoilComponents(
15018 4 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
15019 2 : } break;
15020 0 : case HVAC::Coil_HeatingSteam: {
15021 0 : SteamCoils::SimulateSteamCoilComponents(state,
15022 : CompName,
15023 : FirstHVACIteration,
15024 0 : this->m_SuppHeatCoilIndex,
15025 0 : 1.0,
15026 : _,
15027 0 : this->m_FanOpMode,
15028 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
15029 0 : } break;
15030 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
15031 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
15032 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
15033 0 : UserDefinedComponents::SimCoilUserDefined(
15034 0 : state, CompName, this->m_SuppHeatCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
15035 0 : if (HeatingActive) {
15036 0 : PartLoadFrac = 1.0;
15037 : }
15038 0 : } break;
15039 0 : default:
15040 0 : break;
15041 : }
15042 :
15043 4 : int SolFla = 0;
15044 : // If OutletTemp is within ACC of set point coil operation is not needed or UserDefined already met load.
15045 4 : if (outletNode.Temp > (DesOutTemp - Acc) || this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
15046 : // do nothing, coil is at or above set point
15047 : } else {
15048 : // outlet temp too low, turn on coil
15049 : // Get full load result
15050 4 : PartLoadFrac = 1.0;
15051 :
15052 4 : switch (this->m_SuppHeatCoilType_Num) {
15053 0 : case HVAC::Coil_HeatingGasOrOtherFuel:
15054 : case HVAC::Coil_HeatingElectric: {
15055 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
15056 : CompName,
15057 : FirstHVACIteration,
15058 0 : this->m_DesignSuppHeatingCapacity,
15059 0 : this->m_SuppHeatCoilIndex,
15060 : QCoilActual,
15061 : SuppHeatingCoilFlag,
15062 0 : this->m_FanOpMode,
15063 : PartLoadFrac);
15064 0 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
15065 0 : PartLoadFrac = QCoilActual / this->m_DesignSuppHeatingCapacity;
15066 : }
15067 0 : } break;
15068 2 : case HVAC::Coil_HeatingElectric_MultiStage: {
15069 2 : CycRatio = 1.0;
15070 2 : SpeedRatio = 1.0;
15071 2 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
15072 2 : this->m_SuppHeatingSpeedNum = SpeedNum;
15073 6 : HeatingCoils::SimulateHeatingCoilComponents(state,
15074 : CompName,
15075 : FirstHVACIteration,
15076 : DataLoopNode::SensedLoadFlagValue,
15077 2 : this->m_SuppHeatCoilIndex,
15078 : QCoilActual,
15079 : SuppHeatingCoilFlag,
15080 2 : this->m_FanOpMode,
15081 : PartLoadFrac,
15082 : SpeedNum,
15083 : SpeedRatio);
15084 2 : if (outletNode.Temp > DesOutTemp) {
15085 2 : break;
15086 : }
15087 : }
15088 2 : } break;
15089 0 : case HVAC::Coil_HeatingDesuperheater: {
15090 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
15091 : CompName,
15092 : FirstHVACIteration,
15093 0 : this->m_DesignSuppHeatingCapacity,
15094 0 : this->m_SuppHeatCoilIndex,
15095 : _,
15096 : SuppHeatingCoilFlag,
15097 0 : this->m_FanOpMode);
15098 0 : } break;
15099 2 : case HVAC::Coil_HeatingWater: {
15100 2 : mdot = this->m_MaxSuppCoilFluidFlow;
15101 2 : PlantUtilities::SetComponentFlowRate(
15102 2 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15103 :
15104 6 : WaterCoils::SimulateWaterCoilComponents(
15105 4 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
15106 2 : } break;
15107 0 : case HVAC::Coil_HeatingSteam: {
15108 0 : mdot = this->m_MaxSuppCoilFluidFlow;
15109 0 : PlantUtilities::SetComponentFlowRate(
15110 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15111 :
15112 0 : SteamCoils::SimulateSteamCoilComponents(state,
15113 : CompName,
15114 : FirstHVACIteration,
15115 0 : this->m_SuppHeatCoilIndex,
15116 0 : 1.0,
15117 : _,
15118 0 : this->m_FanOpMode,
15119 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
15120 0 : } break;
15121 0 : case HVAC::Coil_UserDefined: {
15122 : // should never get here, coil has already been simulated
15123 0 : } break;
15124 0 : default:
15125 0 : break;
15126 : }
15127 :
15128 : // run the coil at PartLoadFrac = 1.
15129 4 : if (outletNode.Temp < (DesOutTemp + Acc)) {
15130 0 : PartLoadFrac = 1.0; // these have already been set, leave as is for now
15131 0 : CycRatio = 1.0; // change to outletNode.Temp > and removed these vars and the "} else {"
15132 0 : SpeedRatio = 1.0;
15133 : } else {
15134 4 : switch (this->m_SuppHeatCoilType_Num) {
15135 0 : case HVAC::Coil_HeatingGasOrOtherFuel:
15136 : case HVAC::Coil_HeatingElectric:
15137 : case HVAC::Coil_HeatingDesuperheater: {
15138 0 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
15139 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
15140 0 : return this->gasElecHeatingCoilResidual(state,
15141 : PartLoadFrac,
15142 0 : this->m_UnitarySysNum,
15143 : FirstHVACIteration,
15144 : DesOutTemp,
15145 : tmpSuppHeatingCoilFlag,
15146 0 : this->m_FanOpMode,
15147 0 : this->m_DesignSuppHeatingCapacity);
15148 0 : };
15149 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
15150 0 : } break;
15151 2 : case HVAC::Coil_HeatingElectric_MultiStage: {
15152 2 : if (this->m_SuppHeatingSpeedNum > 1) {
15153 0 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
15154 0 : return UnitarySys::heatingCoilVarSpeedResidual(state,
15155 : SpeedRatio,
15156 0 : this->m_SuppHeatCoilIndex,
15157 : DesOutTemp,
15158 0 : this->m_UnitarySysNum,
15159 : CycRatio,
15160 0 : this->m_SuppHeatingSpeedNum,
15161 0 : this->m_FanOpMode,
15162 : HVAC::CompressorOp::On,
15163 0 : true);
15164 0 : };
15165 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
15166 0 : PartLoadFrac = SpeedRatio;
15167 : } else {
15168 2 : SpeedRatio = 0.0;
15169 2 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
15170 6 : auto f = [&state, this, DesOutTemp, SpeedRatio](Real64 const CycRatio) {
15171 12 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
15172 : CycRatio,
15173 6 : this->m_SuppHeatCoilIndex,
15174 : DesOutTemp,
15175 6 : this->m_UnitarySysNum,
15176 : SpeedRatio,
15177 6 : this->m_SuppHeatingSpeedNum,
15178 6 : this->m_FanOpMode,
15179 : HVAC::CompressorOp::On,
15180 6 : true);
15181 2 : };
15182 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
15183 2 : PartLoadFrac = CycRatio;
15184 : }
15185 2 : } break;
15186 2 : case HVAC::Coil_HeatingWater: {
15187 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
15188 : maxPartLoadFrac =
15189 2 : min(1.0,
15190 2 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
15191 : // max iteration limit (leave a little slop, 0.001)
15192 20 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
15193 20 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
15194 20 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
15195 20 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
15196 60 : WaterCoils::SimulateWaterCoilComponents(state,
15197 20 : this->m_SuppHeatCoilName,
15198 : FirstHVACIteration,
15199 20 : this->m_SuppHeatCoilIndex,
15200 40 : 0.0, // QActual
15201 20 : this->m_FanOpMode,
15202 : PartLoadFrac);
15203 :
15204 20 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
15205 2 : };
15206 :
15207 2 : General::SolveRoot(state, Acc, SolveMaxIter, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
15208 2 : } break;
15209 0 : case HVAC::Coil_HeatingSteam: {
15210 :
15211 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
15212 : maxPartLoadFrac =
15213 0 : min(1.0,
15214 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
15215 : // max iteration limit (leave a little slop, 0.001)
15216 :
15217 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
15218 : Real64 mdot;
15219 :
15220 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
15221 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
15222 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
15223 0 : SteamCoils::SimulateSteamCoilComponents(state,
15224 0 : this->m_SuppHeatCoilName,
15225 : FirstHVACIteration,
15226 0 : this->m_SuppHeatCoilIndex,
15227 0 : 1.0,
15228 : _,
15229 0 : this->m_FanOpMode,
15230 : PartLoadFrac);
15231 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
15232 0 : };
15233 :
15234 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
15235 0 : } break;
15236 0 : case HVAC::Coil_UserDefined: {
15237 : // do nothing, coil has already been simulated
15238 0 : } break;
15239 0 : default:
15240 0 : break;
15241 : }
15242 : }
15243 : } // IF (outletNode.Temp < (DesOutTemp + Acc)) THEN
15244 :
15245 4 : if (PartLoadFrac > 1.0) {
15246 0 : PartLoadFrac = 1.0;
15247 4 : } else if (PartLoadFrac < 0.0) {
15248 0 : PartLoadFrac = 0.0;
15249 : }
15250 :
15251 4 : if (SolFla == -1) {
15252 0 : if (!state.dataGlobal->WarmupFlag) {
15253 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRIter < 1) {
15254 0 : Real64 ReqOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
15255 0 : DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15256 : Real64 FullOutput =
15257 0 : inletNode.MassFlowRate *
15258 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15259 :
15260 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRIter;
15261 0 : ShowWarningError(state,
15262 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}",
15263 0 : this->UnitType,
15264 0 : this->Name));
15265 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
15266 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
15267 0 : ShowContinueErrorTimeStamp(
15268 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
15269 : } else {
15270 0 : ShowRecurringWarningErrorAtEnd(state,
15271 0 : format("{} \"{}\" - Iteration limit exceeded calculating sensible part-load ratio "
15272 : "error continues. Sensible PLR statistics follow.",
15273 0 : this->UnitType,
15274 0 : this->Name),
15275 0 : this->warnIndex.m_SuppHeatCoilSensPLRIterIndex,
15276 : PartLoadFrac,
15277 : PartLoadFrac);
15278 : }
15279 : } // IF(.NOT. WarmupFlag)THEN
15280 4 : } else if (SolFla == -2) {
15281 0 : Real64 ReqOutput = inletNode.MassFlowRate *
15282 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15283 0 : Real64 FullOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
15284 0 : outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
15285 :
15286 0 : PartLoadFrac = ReqOutput / FullOutput;
15287 0 : if (!state.dataGlobal->WarmupFlag) {
15288 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRFail < 1) {
15289 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRFail;
15290 0 : ShowWarningError(
15291 : state,
15292 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
15293 0 : this->UnitType,
15294 0 : this->Name));
15295 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
15296 0 : ShowContinueErrorTimeStamp(
15297 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
15298 : } else {
15299 0 : ShowRecurringWarningErrorAtEnd(
15300 : state,
15301 0 : format("{} \"{}\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
15302 0 : this->UnitType,
15303 0 : this->Name),
15304 0 : this->warnIndex.m_SuppHeatCoilSensPLRFailIndex,
15305 : PartLoadFrac,
15306 : PartLoadFrac);
15307 : }
15308 : }
15309 : } // IF (SolFla == -1) THEN
15310 :
15311 4 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
15312 4 : this->m_SuppHeatingCycRatio = CycRatio;
15313 4 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
15314 : } // IF (NOT EMS OVERRIDE) THEN
15315 :
15316 : } // IF SENSIBLE LOAD
15317 : } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. &
15318 :
15319 : // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel)
15320 11 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15321 0 : this->m_sysType != SysType::PackagedWSHP) {
15322 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
15323 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = max(afnInfo.AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
15324 0 : afnInfo.AFNLoopDXCoilRTF = max(afnInfo.AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
15325 : }
15326 :
15327 11 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
15328 4 : mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow;
15329 4 : PlantUtilities::SetComponentFlowRate(
15330 4 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
15331 : }
15332 11 : }
15333 :
15334 38 : void UnitarySys::simMultiSpeedCoils(EnergyPlusData &state,
15335 : int const AirLoopNum, // Index to air loop
15336 : bool const FirstHVACIteration, // True when first HVAC iteration
15337 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
15338 : bool const SensibleLoad,
15339 : bool const LatentLoad,
15340 : Real64 const PartLoadFrac,
15341 : int const CoilType,
15342 : int const SpeedNumber)
15343 : {
15344 :
15345 : // SUBROUTINE INFORMATION:
15346 : // AUTHOR Chandan Sharma, FSEC
15347 : // DATE WRITTEN March 2013
15348 :
15349 : // PURPOSE OF THIS SUBROUTINE:
15350 : // This subroutine manages multispeed and variable speed cooling coil simulation.
15351 :
15352 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15353 38 : std::string CompName; // Name of Unitary System object
15354 38 : Real64 SensLoad = 0.0;
15355 38 : Real64 LatLoad = 0.0;
15356 38 : int CoilTypeNum = 0;
15357 38 : int CompIndex = 0;
15358 38 : Real64 SpeedRatio = 0.0;
15359 38 : Real64 CycRatio = 0.0;
15360 38 : Real64 dummy = 0.0;
15361 :
15362 38 : if (CoilType == CoolingCoil) {
15363 :
15364 9 : CompName = this->m_CoolingCoilName;
15365 9 : CompIndex = this->m_CoolingCoilIndex;
15366 9 : CoilTypeNum = this->m_CoolingCoilType_Num;
15367 9 : if (SensibleLoad) {
15368 9 : SensLoad = -1.0;
15369 9 : state.dataUnitarySystems->CoolingLoad = true;
15370 9 : state.dataUnitarySystems->HeatingLoad = false;
15371 : }
15372 9 : if (LatentLoad) {
15373 0 : LatLoad = -1.0;
15374 : }
15375 :
15376 : } else {
15377 :
15378 29 : CompName = this->m_HeatingCoilName;
15379 29 : CompIndex = this->m_HeatingCoilIndex;
15380 29 : CoilTypeNum = this->m_HeatingCoilType_Num;
15381 :
15382 29 : if (SensibleLoad) {
15383 29 : SensLoad = 1.0;
15384 29 : state.dataUnitarySystems->CoolingLoad = false;
15385 29 : state.dataUnitarySystems->HeatingLoad = true;
15386 : } else {
15387 0 : SensLoad = 0.0;
15388 0 : state.dataUnitarySystems->HeatingLoad = false;
15389 : }
15390 29 : LatLoad = 0.0;
15391 : }
15392 :
15393 38 : Real64 OnOffAirFlowRatio = 1.0;
15394 38 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadFrac); // 1.0d0 = PartLoadRatio
15395 :
15396 38 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
15397 :
15398 38 : if ((CoilTypeNum == HVAC::CoilDX_MultiSpeedCooling) || (CoilTypeNum == HVAC::CoilDX_MultiSpeedHeating)) {
15399 9 : DXCoils::SimDXCoilMultiSpeed(
15400 9 : state, CompName, 0.0, PartLoadFrac, CompIndex, SpeedNumber, this->m_FanOpMode, HVAC::CompressorOp::On, this->m_SingleMode);
15401 :
15402 29 : } else if (CoilTypeNum == HVAC::CoilDX_Cooling) {
15403 0 : bool const singleMode = (this->m_SingleMode == 1);
15404 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
15405 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15406 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
15407 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
15408 0 : coilMode = HVAC::CoilMode::Enhanced;
15409 : }
15410 :
15411 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
15412 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode, this->CoilSHR);
15413 :
15414 29 : } else if (CoilTypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
15415 :
15416 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15417 : CompName,
15418 : CompIndex,
15419 : this->m_FanOpMode,
15420 : CompressorOn,
15421 : PartLoadFrac,
15422 : SpeedNumber,
15423 : this->m_CoolingSpeedRatio,
15424 : SensLoad,
15425 : dummy,
15426 : OnOffAirFlowRatio);
15427 :
15428 29 : } else if (CoilTypeNum == HVAC::Coil_HeatingAirToAirVariableSpeed) {
15429 :
15430 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15431 : CompName,
15432 : CompIndex,
15433 : this->m_FanOpMode,
15434 : CompressorOn,
15435 : PartLoadFrac,
15436 : SpeedNumber,
15437 : this->m_HeatingSpeedRatio,
15438 : SensLoad,
15439 : dummy,
15440 : OnOffAirFlowRatio);
15441 :
15442 29 : } else if (CoilTypeNum == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
15443 :
15444 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15445 : CompName,
15446 : CompIndex,
15447 : this->m_FanOpMode,
15448 : CompressorOn,
15449 : PartLoadFrac,
15450 : SpeedNumber,
15451 : this->m_CoolingSpeedRatio,
15452 : SensLoad,
15453 : dummy,
15454 : OnOffAirFlowRatio);
15455 :
15456 29 : } else if (CoilTypeNum == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
15457 :
15458 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15459 : CompName,
15460 : CompIndex,
15461 : this->m_FanOpMode,
15462 : CompressorOn,
15463 : PartLoadFrac,
15464 : SpeedNumber,
15465 : this->m_HeatingSpeedRatio,
15466 : SensLoad,
15467 : dummy,
15468 : OnOffAirFlowRatio);
15469 :
15470 29 : } else if ((CoilTypeNum == HVAC::Coil_HeatingElectric_MultiStage) || (CoilTypeNum == HVAC::Coil_HeatingGas_MultiStage)) {
15471 :
15472 58 : HeatingCoils::SimulateHeatingCoilComponents(
15473 58 : state, CompName, FirstHVACIteration, _, CompIndex, _, _, this->m_FanOpMode, PartLoadFrac, SpeedNumber, this->m_HeatingSpeedRatio);
15474 : } else {
15475 : }
15476 38 : }
15477 :
15478 60 : void UnitarySys::calcPassiveSystem(EnergyPlusData &state,
15479 : int const AirLoopNum, // index to air loop
15480 : bool const FirstHVACIteration // True when first HVAC iteration
15481 : )
15482 : {
15483 :
15484 : // SUBROUTINE INFORMATION:
15485 : // AUTHOR Richard Raustad, FSEC
15486 : // DATE WRITTEN February 2013
15487 :
15488 : // PURPOSE OF THIS SUBROUTINE:
15489 : // This subroutine calculates the set point based output of the unitary system.
15490 :
15491 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15492 60 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
15493 60 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off; // compressor control (0=off, 1=on)
15494 60 : Real64 OnOffAirFlowRatio = 1.0;
15495 60 : Real64 CoilCoolHeatRat = 1.0;
15496 60 : Real64 HeatCoilLoad = 0.0;
15497 : // CALL the series of components that simulate a Unitary System
15498 60 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
15499 52 : state.dataFans->fans(this->m_FanIndex)
15500 156 : ->simulate(state,
15501 : FirstHVACIteration,
15502 52 : state.dataUnitarySystems->FanSpeedRatio,
15503 : _, // Pressure rise
15504 : _, // Flow fraction
15505 52 : state.dataUnitarySystems->m_massFlow1,
15506 52 : state.dataUnitarySystems->m_runTimeFraction1,
15507 52 : state.dataUnitarySystems->m_massFlow2,
15508 52 : state.dataUnitarySystems->m_runTimeFraction2,
15509 : _);
15510 : }
15511 :
15512 60 : if (this->m_CoolingCoilUpstream) {
15513 :
15514 24 : if (this->m_CoolCoilExists) {
15515 24 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15516 24 : CompressorOn = HVAC::CompressorOp::Off;
15517 24 : if (PartLoadRatio > 0.0) {
15518 12 : CompressorOn = HVAC::CompressorOp::On;
15519 : }
15520 24 : bool HXUnitOn = false;
15521 24 : this->calcUnitaryCoolingSystem(
15522 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15523 : }
15524 24 : if (this->m_HeatCoilExists) {
15525 2 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15526 2 : CompressorOn = HVAC::CompressorOp::Off;
15527 2 : if (PartLoadRatio > 0.0) {
15528 1 : CompressorOn = HVAC::CompressorOp::On;
15529 : }
15530 2 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15531 : }
15532 :
15533 : } else {
15534 :
15535 36 : if (this->m_HeatCoilExists) {
15536 36 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15537 36 : CompressorOn = HVAC::CompressorOp::Off;
15538 36 : if (PartLoadRatio > 0.0) {
15539 25 : CompressorOn = HVAC::CompressorOp::On;
15540 : }
15541 36 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15542 : }
15543 36 : if (this->m_CoolCoilExists) {
15544 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15545 0 : CompressorOn = HVAC::CompressorOp::Off;
15546 0 : if (PartLoadRatio > 0.0) {
15547 0 : CompressorOn = HVAC::CompressorOp::On;
15548 : }
15549 0 : bool HXUnitOn = false;
15550 0 : this->calcUnitaryCoolingSystem(
15551 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15552 : }
15553 : }
15554 :
15555 60 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
15556 0 : state.dataFans->fans(this->m_FanIndex)
15557 0 : ->simulate(state,
15558 : FirstHVACIteration,
15559 0 : state.dataUnitarySystems->FanSpeedRatio,
15560 : _, // Pressure rise
15561 : _, // Flow fraction
15562 0 : state.dataUnitarySystems->m_massFlow1,
15563 0 : state.dataUnitarySystems->m_runTimeFraction1,
15564 0 : state.dataUnitarySystems->m_massFlow2,
15565 0 : state.dataUnitarySystems->m_runTimeFraction2,
15566 : _);
15567 : }
15568 :
15569 : // CALL reheat coils next
15570 60 : if (this->m_SuppCoilExists) {
15571 15 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
15572 15 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
15573 15 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
15574 : }
15575 60 : }
15576 :
15577 72368 : void UnitarySys::reportUnitarySystem(EnergyPlusData &state, int const AirLoopNum)
15578 : {
15579 :
15580 : // SUBROUTINE INFORMATION:
15581 : // AUTHOR Chandan Sharma
15582 : // DATE WRITTEN July 2013
15583 :
15584 : // PURPOSE OF THIS SUBROUTINE:
15585 : // This subroutine updates the report variable for the coils.
15586 :
15587 72368 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15588 :
15589 72368 : Real64 SensibleOutput = 0.0; // sensible output rate, {W}
15590 72368 : Real64 LatentOutput = 0.0; // latent output rate, {W}
15591 72368 : Real64 TotalOutput = 0.0; // total output rate, {W}
15592 72368 : Real64 QTotUnitOut = 0.0;
15593 72368 : Real64 QSensUnitOut = 0.0;
15594 72368 : this->m_PartLoadFrac = 0.0;
15595 72368 : this->m_CompPartLoadRatio = 0.0;
15596 72368 : this->m_CycRatio = 0.0;
15597 72368 : this->m_SpeedRatio = 0.0;
15598 72368 : this->FanPartLoadRatio = 0.0;
15599 72368 : this->m_TotalAuxElecPower = 0.0;
15600 72368 : this->m_HeatingAuxElecConsumption = 0.0;
15601 72368 : this->m_CoolingAuxElecConsumption = 0.0;
15602 72368 : this->m_ElecPower = 0.0;
15603 72368 : this->m_ElecPowerConsumption = 0.0;
15604 :
15605 72368 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
15606 72368 : switch (this->m_ControlType) {
15607 : // Noticed that these are calculated differently.
15608 : // That doesn't make sense except that NodeNumOfControlledZone = 0 for set point control because the control zone name is not required.
15609 65331 : case UnitarySysCtrlType::Setpoint: {
15610 65331 : if (this->AirOutNode > 0) {
15611 65331 : int InletNode = this->AirInNode;
15612 261324 : CalcComponentSensibleLatentOutput(AirMassFlow,
15613 65331 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15614 65331 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15615 65331 : state.dataLoopNodes->Node(InletNode).Temp,
15616 65331 : state.dataLoopNodes->Node(InletNode).HumRat,
15617 : SensibleOutput,
15618 : LatentOutput,
15619 : TotalOutput);
15620 65331 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15621 65331 : QTotUnitOut = TotalOutput;
15622 : }
15623 65331 : } break;
15624 7037 : default: {
15625 7037 : if (this->AirOutNode > 0 && this->NodeNumOfControlledZone > 0) {
15626 : // PTUnit uses old style method of calculating delivered capacity.
15627 : // Also PTUnit always uses inlet node data, which is good when inlet is connected to zone return node
15628 7037 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15629 6979 : Real64 SpecHumOut = state.dataLoopNodes->Node(this->AirOutNode).HumRat;
15630 6979 : Real64 SpecHumIn = state.dataLoopNodes->Node(this->AirInNode).HumRat;
15631 6979 : LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s (dehumid = negative)
15632 6979 : SensibleOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirOutNode).Temp,
15633 6979 : state.dataLoopNodes->Node(this->AirInNode).HumRat) -
15634 6979 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirInNode).Temp,
15635 6979 : state.dataLoopNodes->Node(this->AirInNode).HumRat));
15636 6979 : TotalOutput =
15637 6979 : AirMassFlow * (state.dataLoopNodes->Node(this->AirOutNode).Enthalpy - state.dataLoopNodes->Node(this->AirInNode).Enthalpy);
15638 6979 : } else {
15639 : // air loop systems don't use the Sensible capacity, zone equipment uses this to adjust RemainingOutputRequired
15640 232 : CalcZoneSensibleLatentOutput(AirMassFlow,
15641 58 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15642 58 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15643 58 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
15644 58 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
15645 : SensibleOutput,
15646 : LatentOutput,
15647 : TotalOutput);
15648 : }
15649 7037 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15650 7037 : QTotUnitOut = TotalOutput;
15651 : }
15652 7037 : } break;
15653 : }
15654 :
15655 : // set the system part-load ratio report variable
15656 72368 : this->m_PartLoadFrac = max(this->m_CoolingPartLoadFrac, this->m_HeatingPartLoadFrac);
15657 : // set the compressor part-load ratio report variable
15658 72368 : this->m_CompPartLoadRatio = max(this->m_CoolCompPartLoadRatio, this->m_HeatCompPartLoadRatio);
15659 :
15660 : // logic difference in PTUnit *Rate reporting vs UnitarySystem. Use PTUnit more compact method for 9093.
15661 72368 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15662 : // Issue 9093.
15663 : // PTHP reports these differently, seems this is correct. Can't change this now, need an issue to resolve
15664 6979 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15665 6979 : this->m_TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
15666 6979 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15667 6979 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15668 6979 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15669 6979 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15670 : } else {
15671 65389 : if (state.dataUnitarySystems->HeatingLoad) {
15672 42 : if (QTotUnitOut > 0.0) { // heating
15673 32 : this->m_TotCoolEnergyRate = 0.0;
15674 32 : this->m_SensCoolEnergyRate = 0.0;
15675 32 : this->m_LatCoolEnergyRate = 0.0;
15676 32 : this->m_TotHeatEnergyRate = QTotUnitOut;
15677 32 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15678 32 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15679 : } else {
15680 10 : this->m_TotCoolEnergyRate = std::abs(QTotUnitOut);
15681 10 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15682 10 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15683 10 : this->m_TotHeatEnergyRate = 0.0;
15684 10 : this->m_SensHeatEnergyRate = 0.0;
15685 10 : this->m_LatHeatEnergyRate = 0.0;
15686 : }
15687 : } else {
15688 65347 : if (QTotUnitOut <= 0.0) { // cooling
15689 65328 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15690 65328 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15691 65328 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15692 65328 : this->m_TotHeatEnergyRate = 0.0;
15693 65328 : this->m_SensHeatEnergyRate = 0.0;
15694 65328 : this->m_LatHeatEnergyRate = 0.0;
15695 : } else {
15696 19 : this->m_TotCoolEnergyRate = 0.0;
15697 19 : this->m_SensCoolEnergyRate = 0.0;
15698 19 : this->m_LatCoolEnergyRate = 0.0;
15699 19 : this->m_TotHeatEnergyRate = QTotUnitOut;
15700 19 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15701 19 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15702 : }
15703 : }
15704 : }
15705 :
15706 72368 : this->m_TotHeatEnergy = m_TotHeatEnergyRate * ReportingConstant;
15707 72368 : this->m_TotCoolEnergy = m_TotCoolEnergyRate * ReportingConstant;
15708 72368 : this->m_SensHeatEnergy = m_SensHeatEnergyRate * ReportingConstant;
15709 72368 : this->m_SensCoolEnergy = m_SensCoolEnergyRate * ReportingConstant;
15710 72368 : this->m_LatHeatEnergy = m_LatHeatEnergyRate * ReportingConstant;
15711 72368 : this->m_LatCoolEnergy = m_LatCoolEnergyRate * ReportingConstant;
15712 :
15713 72368 : if (this->m_FanExists && this->AirOutNode > 0) {
15714 7082 : if (state.dataUnitarySystems->CompOnMassFlow > 0.0) {
15715 5561 : this->FanPartLoadRatio = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate / state.dataUnitarySystems->CompOnMassFlow;
15716 : }
15717 7082 : if (AirLoopNum > 0) {
15718 8 : if (this->m_FanOpMode == HVAC::FanOp::Cycling) {
15719 8 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = this->FanPartLoadRatio;
15720 : } else {
15721 0 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0;
15722 : }
15723 : }
15724 : }
15725 :
15726 72368 : Real64 locFanElecPower = (this->m_FanIndex == 0) ? 0.0 : state.dataFans->fans(this->m_FanIndex)->totalPower;
15727 :
15728 72368 : Real64 elecCoolingPower = 0.0;
15729 72368 : Real64 elecHeatingPower = 0.0;
15730 72368 : Real64 suppHeatingPower = 0.0;
15731 72368 : Real64 defrostElecPower = 0.0;
15732 :
15733 72368 : switch (this->m_CoolingCoilType_Num) {
15734 5670 : case HVAC::CoilDX_CoolingTwoSpeed: {
15735 : // need to make sure these are 0 for non-variable speed coils (or not report these variables)
15736 5670 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15737 5670 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15738 5670 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15739 : // see :setSpeedVariables
15740 5670 : if (state.dataUnitarySystems->CoolingLoad && this->m_SpeedNum <= 1) {
15741 2 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15742 2 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15743 : }
15744 5670 : if (this->m_LastMode == CoolingMode) {
15745 5667 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15746 : }
15747 5670 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15748 5670 : } break;
15749 20 : case HVAC::CoilDX_MultiSpeedCooling: {
15750 20 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15751 20 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15752 20 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15753 :
15754 20 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15755 20 : if (state.dataUnitarySystems->CoolingLoad) {
15756 10 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15757 10 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15758 : }
15759 20 : if (this->m_LastMode == CoolingMode) {
15760 10 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15761 : }
15762 20 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15763 20 : } break;
15764 31 : case HVAC::Coil_CoolingWater:
15765 : case HVAC::Coil_CoolingWaterDetailed: {
15766 31 : if (this->m_DiscreteSpeedCoolingCoil) {
15767 5 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15768 5 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15769 5 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15770 5 : if (state.dataUnitarySystems->CoolingLoad) {
15771 : // if discrete, the coil cycles on and off
15772 2 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15773 2 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15774 : }
15775 5 : if (this->m_LastMode == CoolingMode) {
15776 3 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15777 : }
15778 : } else {
15779 26 : if (state.dataUnitarySystems->CoolingLoad) {
15780 : // if not discrete, the coil runs the entire time step.
15781 7 : this->m_TotalAuxElecPower =
15782 7 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15783 7 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15784 : }
15785 26 : if (this->m_LastMode == CoolingMode) {
15786 13 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15787 : }
15788 : }
15789 31 : this->m_ElecPower = locFanElecPower;
15790 31 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15791 31 : } break;
15792 : // May not need
15793 3476 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
15794 3476 : if (this->m_NumOfSpeedCooling > 1) {
15795 3474 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15796 3474 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15797 3474 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15798 : }
15799 3476 : if (state.dataUnitarySystems->CoolingLoad) {
15800 633 : this->m_TotalAuxElecPower =
15801 633 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15802 633 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15803 : }
15804 3476 : if (this->m_LastMode == CoolingMode) {
15805 1939 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15806 : }
15807 3476 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15808 3476 : } break;
15809 9 : case HVAC::CoilDX_Cooling: {
15810 9 : if (this->m_NumOfSpeedCooling > 1) {
15811 6 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15812 6 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15813 6 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15814 :
15815 6 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15816 6 : if (state.dataUnitarySystems->CoolingLoad) {
15817 6 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15818 6 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15819 : }
15820 6 : if (this->m_LastMode == CoolingMode) {
15821 6 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15822 : }
15823 6 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15824 : } else {
15825 3 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15826 3 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR == 0.0) {
15827 0 : this->LoadSHR = 1.0;
15828 0 : this->CoilSHR = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].performance.NormalSHR;
15829 : }
15830 : }
15831 3 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15832 3 : if (state.dataUnitarySystems->CoolingLoad) {
15833 3 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15834 3 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15835 : }
15836 3 : if (this->m_LastMode == CoolingMode) {
15837 3 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15838 : }
15839 3 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15840 : }
15841 9 : } break;
15842 0 : case HVAC::Coil_UserDefined:
15843 : case HVAC::CoilWater_CoolingHXAssisted:
15844 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
15845 0 : if (state.dataUnitarySystems->CoolingLoad) {
15846 0 : this->m_TotalAuxElecPower =
15847 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15848 0 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15849 : }
15850 0 : if (this->m_LastMode == CoolingMode) {
15851 0 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15852 : }
15853 : // these coil types do not consume electricity or report electricity at the plant
15854 0 : } break;
15855 63162 : default: { // all other DX cooling coils
15856 63162 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15857 63162 : if (state.dataUnitarySystems->CoolingLoad) {
15858 889 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15859 889 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15860 : }
15861 63162 : if (this->m_LastMode == CoolingMode) {
15862 61610 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15863 : }
15864 63162 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15865 63162 : } break;
15866 : }
15867 :
15868 72368 : switch (this->m_HeatingCoilType_Num) {
15869 7 : case HVAC::CoilDX_MultiSpeedHeating: {
15870 7 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15871 7 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15872 7 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15873 :
15874 7 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15875 7 : if (state.dataUnitarySystems->HeatingLoad) {
15876 3 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15877 3 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15878 : }
15879 7 : if (this->m_LastMode == HeatingMode) {
15880 4 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15881 : }
15882 7 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15883 7 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15884 7 : } break;
15885 26 : case HVAC::Coil_HeatingGas_MultiStage:
15886 : case HVAC::Coil_HeatingElectric_MultiStage: {
15887 26 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15888 26 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15889 :
15890 26 : if (state.dataUnitarySystems->HeatingLoad) {
15891 18 : this->m_TotalAuxElecPower =
15892 18 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15893 18 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15894 : }
15895 26 : if (this->m_LastMode == HeatingMode) {
15896 18 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15897 : }
15898 :
15899 26 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15900 26 : } break;
15901 6958 : case HVAC::CoilDX_HeatingEmpirical:
15902 : case HVAC::Coil_HeatingWaterToAirHP:
15903 : case HVAC::Coil_HeatingWaterToAirHPSimple:
15904 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15905 6958 : if (this->m_NumOfSpeedHeating > 1) {
15906 6948 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15907 6948 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15908 6948 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15909 : }
15910 6958 : if (state.dataUnitarySystems->HeatingLoad) {
15911 2725 : this->m_TotalAuxElecPower =
15912 2725 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15913 2725 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15914 : }
15915 6958 : if (this->m_LastMode == HeatingMode) {
15916 3040 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15917 : }
15918 6958 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15919 6958 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15920 6958 : } break;
15921 4 : case HVAC::Coil_HeatingAirToAirVariableSpeed: {
15922 4 : if (state.dataUnitarySystems->HeatingLoad) {
15923 0 : this->m_TotalAuxElecPower =
15924 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15925 0 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15926 : }
15927 4 : if (this->m_LastMode == HeatingMode) {
15928 1 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15929 : }
15930 :
15931 4 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15932 4 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15933 4 : } break;
15934 27 : case HVAC::Coil_UserDefined:
15935 : case HVAC::Coil_HeatingWater:
15936 : case HVAC::Coil_HeatingSteam:
15937 : case HVAC::Coil_HeatingDesuperheater: {
15938 27 : if (state.dataUnitarySystems->HeatingLoad) {
15939 12 : this->m_TotalAuxElecPower =
15940 12 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15941 12 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15942 : }
15943 27 : if (this->m_LastMode == HeatingMode) {
15944 13 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15945 : }
15946 27 : } break;
15947 65346 : default: {
15948 65346 : if (this->m_HeatCoilExists) {
15949 60 : if (state.dataUnitarySystems->HeatingLoad) {
15950 : // if discrete, the coil cycles on and off
15951 13 : this->m_TotalAuxElecPower =
15952 13 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15953 13 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15954 : }
15955 60 : if (this->m_LastMode == HeatingMode) {
15956 20 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15957 : }
15958 60 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15959 : }
15960 65346 : } break;
15961 : }
15962 :
15963 72368 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
15964 68045 : this->m_TotalAuxElecPower = this->m_AncillaryOffPower;
15965 : }
15966 :
15967 72368 : if (this->m_SuppCoilExists) {
15968 6995 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
15969 15 : suppHeatingPower = state.dataHVACGlobal->SuppHeatingCoilPower;
15970 : }
15971 : }
15972 :
15973 72368 : this->m_ElecPower = locFanElecPower + elecCoolingPower + elecHeatingPower + suppHeatingPower + defrostElecPower + this->m_TotalAuxElecPower;
15974 72368 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15975 :
15976 72368 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15977 0 : this->m_sysType != SysType::PackagedWSHP) {
15978 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataUnitarySystems->CompOnMassFlow;
15979 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataUnitarySystems->CompOffMassFlow;
15980 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = this->m_FanOpMode;
15981 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = this->FanPartLoadRatio;
15982 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopCompCycRatio = this->m_CycRatio;
15983 : }
15984 72368 : if (this->m_FirstPass) {
15985 80 : if (AirLoopNum > -1) {
15986 79 : if (!state.dataGlobal->SysSizingCalc) {
15987 :
15988 53 : int const CurOASysNum = state.dataSize->CurOASysNum;
15989 53 : if (CurOASysNum > 0) {
15990 4 : auto &thisOASysEqSizing = state.dataSize->OASysEqSizing(CurOASysNum);
15991 4 : thisOASysEqSizing.AirFlow = false;
15992 4 : thisOASysEqSizing.CoolingAirFlow = false;
15993 4 : thisOASysEqSizing.HeatingAirFlow = false;
15994 4 : thisOASysEqSizing.Capacity = false;
15995 4 : thisOASysEqSizing.CoolingCapacity = false;
15996 4 : thisOASysEqSizing.HeatingCapacity = false;
15997 4 : this->m_FirstPass = false;
15998 49 : } else if (state.dataSize->CurSysNum > 0) {
15999 14 : if (state.dataSize->CurSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
16000 14 : state.dataAirLoop->AirLoopControlInfo(state.dataSize->CurSysNum).UnitarySysSimulating = false;
16001 : }
16002 14 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
16003 35 : } else if (state.dataSize->CurZoneEqNum > 0) {
16004 33 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
16005 : } else {
16006 2 : this->m_FirstPass = false;
16007 : }
16008 : }
16009 : } else {
16010 1 : this->m_FirstPass = false;
16011 : }
16012 : // reset the global system type flags
16013 80 : state.dataSize->ZoneEqDXCoil = false;
16014 : }
16015 :
16016 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
16017 72368 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
16018 72368 : state.dataSize->ZoneEqUnitarySys = false;
16019 72368 : }
16020 :
16021 1 : void UnitarySys::unitarySystemHeatRecovery(EnergyPlusData &state)
16022 : {
16023 :
16024 : // SUBROUTINE INFORMATION:
16025 : // AUTHOR: Chandan Sharma
16026 : // DATE WRITTEN: May 2013
16027 :
16028 : // PURPOSE OF THIS SUBROUTINE:
16029 : // Calculate the heat recovered from UnitarySystem
16030 :
16031 : // SUBROUTINE PARAMETER DEFINITIONS:
16032 : static constexpr std::string_view routineName("UnitarySystemHeatRecovery");
16033 :
16034 1 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
16035 :
16036 1 : Real64 HeatRecInletTemp = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).Temp;
16037 1 : Real64 HeatRecOutletTemp = 0.0;
16038 1 : Real64 HeatRecMassFlowRate = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate;
16039 :
16040 1 : Real64 QHeatRec = state.dataHVACGlobal->MSHPWasteHeat;
16041 :
16042 1 : if (HeatRecMassFlowRate > 0.0) {
16043 :
16044 0 : Real64 CpHeatRec = state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).glycol->getSpecificHeat(state, HeatRecInletTemp, routineName);
16045 :
16046 0 : HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + HeatRecInletTemp;
16047 : // coil model should be handling max outlet water temp (via limit to heat transfer) since heat rejection needs to be accounted for by the
16048 : // coil
16049 0 : if (HeatRecOutletTemp > this->m_MaxHROutletWaterTemp) {
16050 0 : HeatRecOutletTemp = max(HeatRecInletTemp, this->m_MaxHROutletWaterTemp);
16051 0 : QHeatRec = HeatRecMassFlowRate * CpHeatRec * (HeatRecOutletTemp - HeatRecInletTemp);
16052 : }
16053 : } else {
16054 1 : HeatRecOutletTemp = HeatRecInletTemp;
16055 1 : QHeatRec = 0.0;
16056 : }
16057 :
16058 1 : PlantUtilities::SafeCopyPlantNode(state, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
16059 :
16060 1 : state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).Temp = HeatRecOutletTemp;
16061 :
16062 1 : this->m_HeatRecoveryRate = QHeatRec;
16063 1 : this->m_HeatRecoveryEnergy = this->m_HeatRecoveryRate * ReportingConstant;
16064 1 : this->m_HeatRecoveryInletTemp = HeatRecInletTemp;
16065 1 : this->m_HeatRecoveryOutletTemp = HeatRecOutletTemp;
16066 1 : this->m_HeatRecoveryMassFlowRate = HeatRecMassFlowRate;
16067 1 : }
16068 :
16069 24503 : Real64 UnitarySys::calcUnitarySystemLoadResidual(EnergyPlusData &state,
16070 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
16071 : int UnitarySysNum,
16072 : bool FirstHVACIteration,
16073 : // par 3 not used?
16074 : HVAC::CompressorOp compressorOp,
16075 : Real64 LoadToBeMet,
16076 : Real64 coolHeatFlag, // make bool?
16077 : Real64 SensibleLoad,
16078 : Real64 OnOffAirFlowRatio,
16079 : bool HXUnitOn,
16080 : // par 10 not used
16081 : int AirLoopNum)
16082 : {
16083 :
16084 : // FUNCTION INFORMATION:
16085 : // AUTHOR Richard Raustad, FSEC
16086 : // DATE WRITTEN February 2013
16087 :
16088 : // PURPOSE OF THIS SUBROUTINE:
16089 : // To calculate the part-load ratio for the unitary system
16090 :
16091 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16092 : Real64 SensOutput; // sensible output of system
16093 : Real64 LatOutput; // latent output of system
16094 24503 : Real64 HeatCoilLoad = 0.0;
16095 24503 : Real64 SupHeaterLoad = 0.0;
16096 24503 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16097 24503 : Real64 CoolPLR = coolHeatFlag == 1.0 ? PartLoadRatio : 0.0;
16098 24503 : Real64 HeatPLR = coolHeatFlag == 1.0 ? 0.0 : PartLoadRatio;
16099 24503 : thisSys.setSpeedVariables(state, SensibleLoad, PartLoadRatio);
16100 24503 : thisSys.calcUnitarySystemToLoad(state,
16101 : AirLoopNum,
16102 : FirstHVACIteration,
16103 : CoolPLR,
16104 : HeatPLR,
16105 : OnOffAirFlowRatio,
16106 : SensOutput,
16107 : LatOutput,
16108 : HXUnitOn,
16109 : HeatCoilLoad,
16110 : SupHeaterLoad,
16111 : compressorOp);
16112 : // Calculate residual based on output calculation flag
16113 24503 : Real64 baselineLoad = SensibleLoad == 1.0 ? SensOutput : LatOutput;
16114 24503 : Real64 divisor = std::abs(LoadToBeMet) == 0.0 ? 100.0 : LoadToBeMet;
16115 24503 : return (baselineLoad - LoadToBeMet) / divisor;
16116 : }
16117 :
16118 10687 : Real64 UnitarySys::DXCoilVarSpeedResidual(EnergyPlusData &state,
16119 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16120 : int CoilIndex,
16121 : Real64 DesOutTemp,
16122 : int UnitarySysNum,
16123 : Real64 CycRatio,
16124 : int SpeedNum,
16125 : HVAC::FanOp const fanOp,
16126 : HVAC::CompressorOp compressorOp)
16127 : {
16128 : // FUNCTION INFORMATION:
16129 : // AUTHOR Fred Buhl
16130 : // DATE WRITTEN September 2002
16131 :
16132 : // PURPOSE OF THIS FUNCTION:
16133 : // Calculates residual function (desired outlet temp - actual outlet temp).
16134 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16135 :
16136 : // METHODOLOGY EMPLOYED:
16137 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given compressor speed
16138 : // and calculates the residual as defined above
16139 :
16140 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16141 10687 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16142 :
16143 : Real64 dummy;
16144 : Real64 OnOffAirFlowRatio;
16145 : Real64 SensLoad;
16146 :
16147 10687 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16148 10687 : switch (thisSys.m_CoolingCoilType_Num) {
16149 10669 : case HVAC::CoilDX_CoolingTwoSpeed: {
16150 10669 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
16151 10669 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16152 10669 : } break;
16153 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16154 0 : OnOffAirFlowRatio = 1.0;
16155 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16156 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16157 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16158 0 : } break;
16159 18 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16160 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16161 18 : dummy = 0.0;
16162 18 : SensLoad = -1.0;
16163 18 : OnOffAirFlowRatio = 1.0;
16164 18 : VariableSpeedCoils::SimVariableSpeedCoils(
16165 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16166 :
16167 18 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16168 18 : } break;
16169 0 : default: {
16170 0 : assert(false);
16171 : } break;
16172 : }
16173 10687 : return DesOutTemp - OutletAirTemp;
16174 : }
16175 :
16176 12 : Real64 UnitarySys::heatingCoilVarSpeedResidual(EnergyPlusData &state,
16177 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16178 : int CoilIndex,
16179 : Real64 DesOutTemp,
16180 : int UnitarySysNum,
16181 : Real64 CycRatio,
16182 : int SpeedNum,
16183 : HVAC::FanOp const fanOp,
16184 : HVAC::CompressorOp compressorOp,
16185 : bool SuppHeat
16186 :
16187 : )
16188 : {
16189 : // FUNCTION INFORMATION:
16190 : // AUTHOR Fred Buhl
16191 : // DATE WRITTEN September 2002
16192 :
16193 : // PURPOSE OF THIS FUNCTION:
16194 : // Calculates residual function (desired outlet temp - actual outlet temp).
16195 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16196 :
16197 : // METHODOLOGY EMPLOYED:
16198 : // Calls calc routines of multi Speed or variable Coil to get outlet temperature at the given compressor speed
16199 : // and calculates the residual as defined above
16200 :
16201 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16202 12 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16203 : Real64 OnOffAirFlowRatio;
16204 : Real64 SensLoad;
16205 : Real64 LatLoad;
16206 : Real64 QActual;
16207 :
16208 12 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16209 :
16210 12 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16211 12 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16212 12 : if (SuppHeat) {
16213 0 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16214 0 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16215 : }
16216 :
16217 12 : switch (heatCoilType) {
16218 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16219 0 : OnOffAirFlowRatio = 1.0;
16220 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16221 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16222 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16223 0 : } break;
16224 3 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16225 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16226 3 : OnOffAirFlowRatio = 1.0;
16227 3 : SensLoad = 1.0;
16228 3 : LatLoad = -1.0;
16229 : // can't call only the calc routine with these coil types since Init sets air flow rate based on speed num and cycling ratio
16230 3 : VariableSpeedCoils::SimVariableSpeedCoils(
16231 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16232 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16233 3 : } break;
16234 3 : case HVAC::Coil_HeatingElectric_MultiStage: {
16235 3 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16236 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16237 3 : } break;
16238 6 : case HVAC::Coil_HeatingGas_MultiStage: {
16239 6 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16240 6 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16241 6 : } break;
16242 0 : default: {
16243 0 : assert(false);
16244 : } break;
16245 : }
16246 12 : return DesOutTemp - OutletAirTemp;
16247 : }
16248 :
16249 4 : Real64 UnitarySys::DXCoilVarSpeedHumRatResidual(EnergyPlusData &state,
16250 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
16251 : int CoilIndex,
16252 : Real64 DesOutHumRat,
16253 : int UnitarySysNum,
16254 : Real64 CycRatio,
16255 : int SpeedNum,
16256 : HVAC::FanOp const fanOp,
16257 : HVAC::CompressorOp compressorOp)
16258 : {
16259 : // FUNCTION INFORMATION:
16260 : // AUTHOR Richard Raustad
16261 : // DATE WRITTEN January 2008
16262 :
16263 : // PURPOSE OF THIS FUNCTION:
16264 : // Calculates residual function (desired outlet humrat - actual outlet humrat).
16265 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
16266 :
16267 : // METHODOLOGY EMPLOYED:
16268 : // Calls calc routines of multi speed or variable speed coils to get outlet humidity ratio at the given compressor speed
16269 : // and calculates the residual as defined above
16270 :
16271 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16272 4 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio
16273 : Real64 SensLoad;
16274 : Real64 LatLoad;
16275 : Real64 OnOffAirFlowRatio;
16276 4 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16277 4 : switch (thisSys.m_CoolingCoilType_Num) {
16278 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16279 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
16280 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16281 0 : } break;
16282 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16283 0 : OnOffAirFlowRatio = 1.0;
16284 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
16285 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16286 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16287 0 : } break;
16288 4 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16289 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16290 4 : SensLoad = -1.0;
16291 4 : LatLoad = 0.0;
16292 4 : OnOffAirFlowRatio = 1.0;
16293 4 : VariableSpeedCoils::SimVariableSpeedCoils(
16294 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16295 4 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16296 4 : } break;
16297 0 : default: {
16298 0 : assert(false);
16299 : } break;
16300 : }
16301 4 : return DesOutHumRat - OutletAirHumRat;
16302 : }
16303 :
16304 5732 : Real64 UnitarySys::DXCoilCyclingResidual(EnergyPlusData &state,
16305 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16306 : int CoilIndex,
16307 : Real64 DesOutTemp,
16308 : int UnitarySysNum,
16309 : Real64 SpeedRatio,
16310 : int SpeedNum,
16311 : HVAC::FanOp const fanOp,
16312 : HVAC::CompressorOp compressorOp,
16313 : int AirloopNum,
16314 : bool FirstHVACIteration
16315 :
16316 : )
16317 : {
16318 : // FUNCTION INFORMATION:
16319 : // AUTHOR Fred Buhl
16320 : // DATE WRITTEN September 2002
16321 :
16322 : // PURPOSE OF THIS FUNCTION:
16323 : // Calculates residual function (desired outlet temp - actual outlet temp)
16324 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16325 :
16326 : // METHODOLOGY EMPLOYED:
16327 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16328 : // and calculates the residual as defined above
16329 :
16330 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16331 5732 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16332 : Real64 OnOffAirFlowRatio;
16333 :
16334 5732 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16335 5732 : switch (thisSys.m_CoolingCoilType_Num) {
16336 5704 : case HVAC::CoilDX_CoolingTwoSpeed: {
16337 5704 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16338 0 : thisSys.m_CoolingCycRatio = CycRatio;
16339 0 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16340 0 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16341 : } else {
16342 5704 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16343 : }
16344 5704 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16345 5704 : } break;
16346 11 : case HVAC::CoilDX_MultiSpeedCooling: {
16347 11 : OnOffAirFlowRatio = 1.0;
16348 11 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16349 11 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16350 7 : thisSys.m_CoolingCycRatio = CycRatio;
16351 7 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16352 7 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16353 : } else {
16354 4 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16355 : }
16356 11 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16357 11 : } break;
16358 17 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16359 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16360 17 : if (CycRatio == 0.0) {
16361 4 : compressorOp = HVAC::CompressorOp::Off;
16362 : }
16363 17 : Real64 dummy = 0.0;
16364 17 : OnOffAirFlowRatio = 1.0;
16365 17 : Real64 SensLoad = -1.0;
16366 17 : VariableSpeedCoils::SimVariableSpeedCoils(
16367 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16368 17 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16369 17 : } break;
16370 0 : default: {
16371 0 : assert(false);
16372 : } break;
16373 : }
16374 5732 : return DesOutTemp - OutletAirTemp;
16375 : }
16376 :
16377 0 : Real64 UnitarySys::DXCoilCyclingHumRatResidual(EnergyPlusData &state,
16378 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16379 : int CoilIndex,
16380 : Real64 DesOutHumRat,
16381 : int UnitarySysNum,
16382 : Real64 SpeedRatio,
16383 : int SpeedNum,
16384 : HVAC::FanOp const fanOp,
16385 : HVAC::CompressorOp compressorOp)
16386 : {
16387 :
16388 : // FUNCTION INFORMATION:
16389 : // AUTHOR Fred Buhl
16390 : // DATE WRITTEN September 2002
16391 :
16392 : // PURPOSE OF THIS FUNCTION:
16393 : // Calculates residual function (desired outlet temp - actual outlet temp)
16394 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16395 :
16396 : // METHODOLOGY EMPLOYED:
16397 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given cycling ratio
16398 : // and calculates the residual as defined above
16399 :
16400 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16401 0 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio [kg/kg]
16402 : Real64 SensLoad;
16403 : Real64 LatLoad;
16404 : Real64 OnOffAirFlowRatio;
16405 :
16406 0 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16407 0 : switch (thisSys.m_CoolingCoilType_Num) {
16408 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16409 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16410 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16411 0 : } break;
16412 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16413 0 : OnOffAirFlowRatio = 1.0;
16414 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16415 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16416 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16417 0 : } break;
16418 0 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16419 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16420 0 : SensLoad = -1.0;
16421 0 : LatLoad = 0.0;
16422 0 : OnOffAirFlowRatio = 1.0;
16423 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16424 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16425 0 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16426 0 : } break;
16427 0 : default: {
16428 0 : assert(false);
16429 : } break;
16430 : }
16431 0 : return DesOutHumRat - OutletAirHumRat;
16432 : }
16433 :
16434 18 : Real64 UnitarySys::heatingCoilVarSpeedCycResidual(EnergyPlusData &state,
16435 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16436 : int CoilIndex,
16437 : Real64 DesOutTemp,
16438 : int UnitarySysNum,
16439 : Real64 SpeedRatio,
16440 : int SpeedNum,
16441 : HVAC::FanOp const fanOp,
16442 : HVAC::CompressorOp compressorOp,
16443 : bool SuppHeat)
16444 : {
16445 :
16446 : // FUNCTION INFORMATION:
16447 : // AUTHOR Fred Buhl
16448 : // DATE WRITTEN September 2002
16449 :
16450 : // PURPOSE OF THIS FUNCTION:
16451 : // Calculates residual function (desired outlet temp - actual outlet temp)
16452 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16453 :
16454 : // METHODOLOGY EMPLOYED:
16455 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16456 : // and calculates the residual as defined above
16457 :
16458 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16459 18 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16460 : Real64 SensLoad;
16461 : Real64 LatLoad;
16462 : Real64 OnOffAirFlowRatio;
16463 : Real64 QActual;
16464 :
16465 18 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16466 :
16467 18 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16468 18 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16469 18 : if (SuppHeat) {
16470 6 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16471 6 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16472 : }
16473 :
16474 18 : switch (heatCoilType) {
16475 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16476 0 : OnOffAirFlowRatio = 1.0;
16477 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16478 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16479 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16480 0 : } break;
16481 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16482 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16483 0 : if (CycRatio == 0.0) {
16484 0 : compressorOp = HVAC::CompressorOp::Off;
16485 : }
16486 0 : SensLoad = -1.0;
16487 0 : LatLoad = 0.0;
16488 0 : OnOffAirFlowRatio = 1.0;
16489 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16490 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16491 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16492 0 : } break;
16493 12 : case HVAC::Coil_HeatingElectric_MultiStage: {
16494 12 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16495 12 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16496 12 : } break;
16497 6 : case HVAC::Coil_HeatingGas_MultiStage: {
16498 6 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16499 6 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16500 6 : } break;
16501 0 : default: {
16502 0 : assert(false);
16503 : } break;
16504 : }
16505 :
16506 18 : return DesOutTemp - OutletAirTemp;
16507 : }
16508 :
16509 6 : Real64 UnitarySys::gasElecHeatingCoilResidual(EnergyPlusData &state,
16510 : Real64 const PartLoadFrac, // Compressor cycling ratio (1.0 is continuous, 0.0 is off)
16511 : int UnitarySysNum,
16512 : bool FirstHVACIteration,
16513 : Real64 desTemp,
16514 : bool SuppHeatingCoilFlag,
16515 : HVAC::FanOp const fanOp,
16516 : Real64 HeatingLoadArg)
16517 : {
16518 :
16519 : // FUNCTION INFORMATION:
16520 : // AUTHOR Chandan Sharma, FSEC
16521 : // DATE WRITTEN February 2013
16522 :
16523 : // PURPOSE OF THIS FUNCTION:
16524 : // Calculates residual function (desired outlet temp - actual outlet temp)
16525 : // hot water Coil output depends on the part load ratio which is being varied to zero the residual.
16526 :
16527 : // METHODOLOGY EMPLOYED:
16528 : // Calls SimulateHeatingCoilComponents to get outlet temperature at the given part load ratio
16529 : // and calculates the residual as defined above
16530 :
16531 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16532 6 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16533 6 : Real64 HeatingLoad = HeatingLoadArg * PartLoadFrac;
16534 : // heating coils using set point control pass DataLoopNode::SensedLoadFlagValue as QCoilReq to indicate temperature control
16535 6 : if (!SuppHeatingCoilFlag) {
16536 12 : HeatingCoils::SimulateHeatingCoilComponents(
16537 6 : state, thisSys.m_HeatingCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_HeatingCoilIndex, _, _, fanOp, PartLoadFrac);
16538 6 : return desTemp - state.dataLoopNodes->Node(thisSys.HeatCoilOutletNodeNum).Temp;
16539 : } else {
16540 0 : HeatingCoils::SimulateHeatingCoilComponents(
16541 0 : state, thisSys.m_SuppHeatCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_SuppHeatCoilIndex, _, true, fanOp, PartLoadFrac);
16542 0 : return desTemp - state.dataLoopNodes->Node(thisSys.SuppCoilOutletNodeNum).Temp;
16543 : }
16544 : }
16545 :
16546 0 : Real64 UnitarySys::coolWatertoAirHPTempResidual(EnergyPlusData &state,
16547 : Real64 const PartLoadRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16548 : int UnitarySysNum,
16549 : bool FirstHVACIteration,
16550 : Real64 DesOutTemp,
16551 : Real64 ReqOutput)
16552 : {
16553 :
16554 : // FUNCTION INFORMATION:
16555 : // AUTHOR Chandan Sharma, FSEC
16556 : // DATE WRITTEN January 2013
16557 :
16558 : // PURPOSE OF THIS FUNCTION:
16559 : // Calculates residual function (desired outlet temp - actual outlet temp)
16560 : // Cool water coil output depends on the part load ratio which is being varied to zero the residual.
16561 :
16562 : // METHODOLOGY EMPLOYED:
16563 : // Calls SimWatertoAirHP or SimWatertoAirHPSimple to get outlet humidity ratio at the given cycling ratio
16564 : // and calculates the residual as defined above
16565 :
16566 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16567 :
16568 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
16569 :
16570 0 : Real64 dummy = 0.0;
16571 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
16572 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
16573 : blankString,
16574 0 : thisSys.m_CoolingCoilIndex,
16575 : ReqOutput,
16576 : dummy,
16577 : thisSys.m_FanOpMode,
16578 : HVAC::CompressorOp::On,
16579 : PartLoadRatio,
16580 : FirstHVACIteration);
16581 : } else {
16582 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
16583 : blankString,
16584 0 : thisSys.m_CoolingCoilIndex,
16585 : thisSys.MaxCoolAirMassFlow,
16586 : thisSys.m_FanOpMode,
16587 : FirstHVACIteration,
16588 0 : thisSys.m_InitHeatPump,
16589 : ReqOutput,
16590 : dummy,
16591 : HVAC::CompressorOp::Off,
16592 : PartLoadRatio);
16593 : }
16594 0 : return DesOutTemp - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16595 : }
16596 :
16597 95 : Real64 UnitarySys::calcUnitarySystemWaterFlowResidual(EnergyPlusData &state,
16598 : Real64 const PartLoadRatio, // coil part load ratio
16599 : int UnitarySysNum,
16600 : bool FirstHVACIteration,
16601 : Real64 QZnReq,
16602 : int AirControlNode,
16603 : Real64 OnOffAirFlowRat,
16604 : int AirLoopNum,
16605 : int WaterControlNode,
16606 : Real64 highWaterMdot,
16607 : Real64 lowSpeedRatio,
16608 : Real64 airMdot,
16609 : Real64 par13_SATempTarget,
16610 : Real64 systemMaxAirFlowRate,
16611 : Real64 par15_LoadType,
16612 : Real64 par16_IterationMethod)
16613 : {
16614 :
16615 : // FUNCTION INFORMATION:
16616 : // AUTHOR Richard Raustad, FSEC
16617 : // DATE WRITTEN January 2017
16618 :
16619 : // PURPOSE OF THIS SUBROUTINE:
16620 : // To calculate the part-load ratio for the UnitarySystem coil with varying part load ratio
16621 :
16622 : // METHODOLOGY EMPLOYED:
16623 : // Use SolveRoot to CALL this Function to converge on a solution
16624 :
16625 95 : Real64 HeatCoilLoad = 0.0;
16626 95 : Real64 SupHeaterLoad = 0.0;
16627 :
16628 : // Convert parameters to usable variables
16629 95 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16630 95 : Real64 SATempTarget = 0.0;
16631 95 : bool LoadIsTarget = false;
16632 95 : if (par13_SATempTarget == 0.0) {
16633 95 : LoadIsTarget = true;
16634 : } else {
16635 0 : SATempTarget = par13_SATempTarget;
16636 : }
16637 95 : bool iterateOnAirOnly = (par16_IterationMethod > 1.0);
16638 95 : bool coolingLoad = (par15_LoadType > 0.0);
16639 :
16640 95 : bool HXUnitOn = true;
16641 :
16642 95 : if (iterateOnAirOnly) {
16643 :
16644 : // set air flow rate bounded by low speed and high speed air flow rates
16645 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
16646 : // FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model
16647 : // FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem
16648 0 : thisSys.FanPartLoadRatio = PartLoadRatio;
16649 : // if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot;
16650 :
16651 : } else {
16652 :
16653 95 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot;
16654 95 : if (lowSpeedRatio != 1.0) {
16655 : // division by zero when lowSpeedRatio == 1.0
16656 95 : thisSys.FanPartLoadRatio =
16657 95 : max(0.0, ((airMdot - (systemMaxAirFlowRate * lowSpeedRatio)) / ((1.0 - lowSpeedRatio) * systemMaxAirFlowRate)));
16658 : } else {
16659 0 : thisSys.FanPartLoadRatio = 1.0;
16660 : }
16661 95 : if (WaterControlNode > 0) {
16662 61 : Real64 waterMdot = highWaterMdot * PartLoadRatio;
16663 61 : state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot;
16664 : }
16665 : }
16666 :
16667 95 : Real64 coolingPLR = 0.0;
16668 95 : Real64 heatingPLR = 0.0;
16669 :
16670 95 : if (WaterControlNode > 0 && WaterControlNode == thisSys.CoolCoilFluidInletNode) {
16671 : // cooling load using water cooling coil
16672 17 : coolingPLR = PartLoadRatio;
16673 17 : thisSys.m_CoolingPartLoadFrac = PartLoadRatio;
16674 17 : if (thisSys.MaxCoolCoilFluidFlow > 0.0) {
16675 17 : thisSys.CoolCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxCoolCoilFluidFlow;
16676 : }
16677 78 : } else if (WaterControlNode > 0 && WaterControlNode == thisSys.HeatCoilFluidInletNode) {
16678 : // heating load using water heating coil
16679 44 : heatingPLR = PartLoadRatio;
16680 44 : thisSys.m_HeatingPartLoadFrac = PartLoadRatio;
16681 44 : if (thisSys.MaxHeatCoilFluidFlow > 0.0) {
16682 44 : thisSys.HeatCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxHeatCoilFluidFlow;
16683 : }
16684 34 : } else if (coolingLoad) { // non-water coil with cooling load
16685 7 : coolingPLR = PartLoadRatio;
16686 7 : thisSys.m_CoolingPartLoadFrac = coolingPLR;
16687 : } else { // must be non-water coil with heating load
16688 27 : heatingPLR = PartLoadRatio;
16689 27 : thisSys.m_HeatingPartLoadFrac = heatingPLR;
16690 : }
16691 :
16692 95 : Real64 SensOutput = 0.0;
16693 95 : Real64 LatOutput = 0.0;
16694 95 : thisSys.calcUnitarySystemToLoad(state,
16695 : AirLoopNum,
16696 : FirstHVACIteration,
16697 : coolingPLR,
16698 : heatingPLR,
16699 : OnOffAirFlowRat,
16700 : SensOutput,
16701 : LatOutput,
16702 : HXUnitOn,
16703 : HeatCoilLoad,
16704 : SupHeaterLoad,
16705 : HVAC::CompressorOp::On);
16706 :
16707 95 : if (LoadIsTarget) {
16708 : // Calculate residual based on output magnitude
16709 95 : if (std::abs(QZnReq) <= 100.0) {
16710 3 : return (SensOutput - QZnReq) / 100.0;
16711 : } else {
16712 92 : return (SensOutput - QZnReq) / QZnReq;
16713 : }
16714 : } else {
16715 : // Calculate residual based on outlet temperature
16716 0 : return (state.dataLoopNodes->Node(thisSys.AirOutNode).Temp - SATempTarget) * 10.0;
16717 : }
16718 : }
16719 :
16720 24510 : void UnitarySys::setSpeedVariables(EnergyPlusData &state,
16721 : bool const SensibleLoad, // True when meeting a sensible load (not a moisture load)
16722 : Real64 const PartLoadRatio // operating PLR
16723 : )
16724 : {
16725 :
16726 : // SUBROUTINE INFORMATION:
16727 : // AUTHOR Richard Raustad, FSEC
16728 : // DATE WRITTEN February 2013
16729 :
16730 : // PURPOSE OF THIS SUBROUTINE:
16731 : // This subroutine determines operating PLR and calculates the load based system output.
16732 :
16733 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16734 24510 : Real64 OnOffAirFlowRatio = 0.0; // compressor on to average flow rate
16735 :
16736 24510 : if (state.dataUnitarySystems->HeatingLoad && SensibleLoad) {
16737 17541 : this->m_CoolingSpeedRatio = 0.0;
16738 17541 : this->m_CoolingCycRatio = 0.0;
16739 17541 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
16740 17522 : if (this->m_HeatingSpeedNum <= 1) {
16741 101 : this->m_HeatingSpeedRatio = 0.0;
16742 101 : this->m_HeatingCycRatio = PartLoadRatio;
16743 101 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16744 : } else {
16745 17421 : if (this->m_SingleMode == 0) {
16746 17418 : this->m_HeatingSpeedRatio = PartLoadRatio;
16747 17418 : this->m_HeatingCycRatio = 1.0;
16748 : } else {
16749 3 : this->m_HeatingSpeedRatio = 1.0;
16750 3 : this->m_HeatingCycRatio = PartLoadRatio;
16751 : }
16752 : }
16753 19 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
16754 15 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
16755 4 : this->m_CompPartLoadRatio = PartLoadRatio;
16756 4 : this->m_HeatingSpeedNum = 0;
16757 : }
16758 : } else {
16759 6969 : this->m_HeatingSpeedRatio = 0.0;
16760 6969 : this->m_HeatingCycRatio = 0.0;
16761 6969 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
16762 6889 : if (this->m_CoolingSpeedNum <= 1) {
16763 1834 : this->m_CoolingSpeedRatio = 0.0;
16764 1834 : this->m_CoolingCycRatio = PartLoadRatio;
16765 1834 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16766 : } else {
16767 5055 : if (this->m_SingleMode == 0) {
16768 5052 : this->m_CoolingSpeedRatio = PartLoadRatio;
16769 5052 : this->m_CoolingCycRatio = 1.0;
16770 : } else {
16771 3 : this->m_CoolingSpeedRatio = 1.0;
16772 3 : this->m_CoolingCycRatio = PartLoadRatio;
16773 : }
16774 : }
16775 80 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
16776 76 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
16777 4 : this->m_CompPartLoadRatio = PartLoadRatio;
16778 4 : this->m_CoolingSpeedNum = 0;
16779 76 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
16780 0 : if (this->m_CoolingSpeedNum == 1) {
16781 0 : this->m_CoolingSpeedRatio = 0.0;
16782 0 : this->m_CoolingCycRatio = PartLoadRatio;
16783 : } else {
16784 0 : this->m_CoolingSpeedRatio = PartLoadRatio;
16785 0 : this->m_CoolingCycRatio = 1.0;
16786 : }
16787 : } else {
16788 76 : this->m_CoolingSpeedNum = 0;
16789 : }
16790 : }
16791 24510 : OnOffAirFlowRatio = 1.0;
16792 24510 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
16793 24510 : }
16794 :
16795 2 : void UnitarySys::checkUnitarySysCoilInOASysExists(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum)
16796 : {
16797 :
16798 : // SUBROUTINE INFORMATION:
16799 : // AUTHOR Chandan Sharma
16800 : // DATE WRITTEN April 2013
16801 :
16802 : // PURPOSE OF THIS SUBROUTINE:
16803 : // After making sure get input is done, checks if the Coil System DX coil is in the
16804 : // OA System. IF exists then the DX cooling coil is 100% DOAS DX coil.
16805 : // METHODOLOGY EMPLOYED:
16806 : // Based on CheckDXCoolingCoilInOASysExists by Bereket Nigusse
16807 :
16808 : // SUBROUTINE PARAMETER DEFINITIONS:
16809 : static constexpr std::string_view RoutineName("CheckUnitarySysCoilInOASysExists: "); // include trailing blank space
16810 :
16811 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16812 2 : if (state.dataUnitarySystems->getInputOnceFlag) {
16813 1 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16814 1 : state.dataUnitarySystems->getInputOnceFlag = false;
16815 : }
16816 :
16817 2 : if (state.dataUnitarySystems->numUnitarySystems > 0) {
16818 2 : bool UnitarySysFound = false;
16819 2 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16820 2 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16821 2 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten) {
16822 1 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16823 : }
16824 2 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ISHundredPercentDOASDXCoil) {
16825 0 : if (!(state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
16826 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num ==
16827 : HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
16828 0 : DXCoils::SetDXCoilTypeData(state, state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilName);
16829 : }
16830 : }
16831 2 : UnitarySysFound = true;
16832 2 : break;
16833 : }
16834 : }
16835 2 : if (!UnitarySysFound) {
16836 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16837 : }
16838 : } else {
16839 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16840 : }
16841 2 : }
16842 :
16843 0 : void UnitarySys::getUnitarySysHeatCoolCoil(EnergyPlusData &state,
16844 : std::string_view UnitarySysName, // Name of Unitary System object
16845 : bool &CoolingCoil, // Cooling coil exists
16846 : bool &HeatingCoil, // Heating coil exists
16847 : int const ZoneOAUnitNum // index to zone OA unit
16848 : )
16849 : {
16850 :
16851 : // FUNCTION INFORMATION:
16852 : // AUTHOR Chandan Sharma
16853 : // DATE WRITTEN April 2013
16854 :
16855 : // PURPOSE OF THIS FUNCTION:
16856 : // Determined weather Unitary system has heating or cooling coils
16857 :
16858 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16859 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16860 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16861 : }
16862 :
16863 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16864 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16865 0 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten) {
16866 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16867 : }
16868 0 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolCoilExists &&
16869 0 : !state.dataUnitarySystems->unitarySys[UnitarySysNum].m_WaterHRPlantLoopModel) {
16870 0 : CoolingCoil = true;
16871 : }
16872 0 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_HeatCoilExists ||
16873 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_SuppCoilExists) {
16874 0 : HeatingCoil = true;
16875 : }
16876 0 : break;
16877 : }
16878 : }
16879 0 : }
16880 :
16881 4 : int UnitarySys::getAirInNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16882 : {
16883 4 : if (state.dataUnitarySystems->getInputOnceFlag) {
16884 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16885 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16886 : }
16887 4 : int airNode = 0;
16888 4 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16889 4 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16890 4 : airNode = this->AirInNode;
16891 4 : break;
16892 : }
16893 : }
16894 4 : if (airNode == 0) {
16895 0 : errFlag = true;
16896 : }
16897 4 : return airNode;
16898 : }
16899 :
16900 9 : int getZoneEqIndex(EnergyPlusData &state, std::string const &UnitarySysName, DataZoneEquipment::ZoneEquipType zoneEquipType, int const OAUnitNum)
16901 : {
16902 :
16903 9 : if (state.dataUnitarySystems->getInputOnceFlag) {
16904 0 : UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, true, OAUnitNum);
16905 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16906 : }
16907 :
16908 9 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16909 9 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16910 9 : if (zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner ||
16911 1 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump ||
16912 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir ||
16913 : zoneEquipType == DataZoneEquipment::ZoneEquipType::UnitarySystem) {
16914 9 : return UnitarySysNum;
16915 : }
16916 : }
16917 : }
16918 0 : return -1;
16919 : }
16920 :
16921 4 : int UnitarySys::getAirOutNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16922 : {
16923 4 : if (state.dataUnitarySystems->getInputOnceFlag) {
16924 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16925 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16926 : }
16927 4 : int airNode = 0;
16928 4 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16929 4 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16930 4 : airNode = this->AirOutNode;
16931 4 : break;
16932 : }
16933 : }
16934 4 : if (airNode == 0) {
16935 0 : errFlag = true;
16936 : }
16937 4 : return airNode;
16938 : }
16939 :
16940 453 : int UnitarySys::getAirOutletNode()
16941 : {
16942 453 : return this->AirOutNode;
16943 : }
16944 :
16945 453 : int UnitarySys::getMixerOANode()
16946 : {
16947 453 : return this->m_OAMixerNodes[0];
16948 : }
16949 :
16950 453 : int UnitarySys::getMixerMixNode()
16951 : {
16952 453 : return this->m_OAMixerNodes[3];
16953 : }
16954 :
16955 453 : int UnitarySys::getMixerRetNode()
16956 : {
16957 453 : return this->m_OAMixerNodes[2];
16958 : }
16959 :
16960 40 : int UnitarySys::getEquipIndex()
16961 : {
16962 40 : return this->m_EquipCompNum;
16963 : }
16964 :
16965 6 : bool searchZoneInletNodes(EnergyPlusData &state, int nodeToFind, int &ZoneEquipConfigIndex, int &InletNodeIndex)
16966 : {
16967 17 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16968 27 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++ZoneInletNum) {
16969 16 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(ZoneInletNum) == nodeToFind) {
16970 5 : ZoneEquipConfigIndex = ControlledZoneNum;
16971 5 : InletNodeIndex = ZoneInletNum;
16972 5 : return true;
16973 : }
16974 : }
16975 : }
16976 1 : return false;
16977 : }
16978 :
16979 66 : bool searchZoneInletNodesByEquipmentIndex(EnergyPlusData &state, int nodeToFind, int zoneEquipmentIndex)
16980 : {
16981 66 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).NumInletNodes; ++ZoneInletNum) {
16982 66 : if (state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).InletNode(ZoneInletNum) == nodeToFind) {
16983 66 : return true;
16984 : }
16985 : }
16986 0 : return false;
16987 : }
16988 :
16989 4 : bool searchZoneInletNodeAirLoopNum(EnergyPlusData &state, int airLoopNumToFind, int ZoneEquipConfigIndex, int &InletNodeIndex)
16990 : {
16991 4 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).NumInletNodes; ++ZoneInletNum) {
16992 4 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).InletNodeAirLoopNum(ZoneInletNum) == airLoopNumToFind) {
16993 4 : InletNodeIndex = ZoneInletNum;
16994 4 : return true;
16995 : }
16996 : }
16997 0 : return false;
16998 : }
16999 :
17000 72 : bool searchExhaustNodes(EnergyPlusData &state, const int nodeToFind, int &ZoneEquipConfigIndex, int &ExhaustNodeIndex)
17001 : {
17002 101 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
17003 106 : for (int ZoneExhNum = 1; ZoneExhNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes; ++ZoneExhNum) {
17004 77 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum) == nodeToFind) {
17005 66 : ZoneEquipConfigIndex = ControlledZoneNum;
17006 66 : ExhaustNodeIndex = ZoneExhNum;
17007 66 : return true;
17008 : }
17009 : }
17010 : }
17011 6 : return false;
17012 : }
17013 :
17014 70 : void UnitarySys::setSystemParams(EnergyPlusData &state, Real64 &TotalFloorAreaOnAirLoop, const std::string &thisObjectName)
17015 : {
17016 70 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum);
17017 70 : this->NodeNumOfControlledZone = zoneEquipConfig.ZoneNode;
17018 70 : TotalFloorAreaOnAirLoop = state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
17019 70 : this->m_AirLoopEquipment = false;
17020 70 : if (zoneEquipConfig.EquipListIndex == 0) {
17021 0 : return;
17022 : }
17023 :
17024 70 : auto &zoneEquipList = state.dataZoneEquip->ZoneEquipList(zoneEquipConfig.EquipListIndex);
17025 103 : for (int EquipNum = 1; EquipNum <= zoneEquipList.NumOfEquipTypes; ++EquipNum) {
17026 136 : if ((zoneEquipList.EquipType(EquipNum) != DataZoneEquipment::ZoneEquipType::UnitarySystem) ||
17027 52 : zoneEquipList.EquipName(EquipNum) != thisObjectName) {
17028 33 : continue;
17029 : }
17030 51 : this->m_ZoneSequenceCoolingNum = zoneEquipList.CoolingPriority(EquipNum);
17031 51 : this->m_ZoneSequenceHeatingNum = zoneEquipList.HeatingPriority(EquipNum);
17032 51 : break;
17033 : }
17034 : }
17035 :
17036 30 : bool searchTotalComponents(EnergyPlusData &state,
17037 : SimAirServingZones::CompType compTypeToFind,
17038 : std::string_view objectNameToFind,
17039 : int &compIndex,
17040 : int &branchIndex,
17041 : int &airLoopIndex)
17042 : {
17043 34 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
17044 33 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
17045 55 : for (int CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
17046 : ++CompNum) {
17047 51 : if (compTypeToFind != state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num) {
17048 24 : continue;
17049 : }
17050 27 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
17051 : objectNameToFind)) {
17052 25 : compIndex = CompNum;
17053 25 : branchIndex = BranchNum;
17054 25 : airLoopIndex = AirLoopNum;
17055 25 : return true;
17056 : }
17057 : }
17058 : }
17059 : }
17060 5 : return false;
17061 : }
17062 :
17063 42 : bool getUnitarySystemNodeNumber(EnergyPlusData &state, int const nodeNumber)
17064 : {
17065 43 : for (int unitarySysIndex = 0; unitarySysIndex <= state.dataUnitarySystems->numUnitarySystems - 1; ++unitarySysIndex) {
17066 9 : auto &unitarySys = state.dataUnitarySystems->unitarySys[unitarySysIndex];
17067 :
17068 9 : int FanInletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->inletNodeNum;
17069 9 : int FanOutletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->outletNodeNum;
17070 :
17071 9 : bool noUnitarySysOutdoorAir = false;
17072 9 : if (unitarySys.m_CoolOutAirVolFlow == 0 && unitarySys.m_HeatOutAirVolFlow == 0 && unitarySys.m_NoCoolHeatOutAirVolFlow == 0) {
17073 9 : noUnitarySysOutdoorAir = true;
17074 : }
17075 :
17076 9 : if (unitarySys.m_sysType == UnitarySys::SysType::PackagedWSHP || unitarySys.m_sysType == UnitarySys::SysType::PackagedAC ||
17077 0 : unitarySys.m_sysType == UnitarySys::SysType::PackagedHP) {
17078 9 : if (noUnitarySysOutdoorAir && (nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex ||
17079 7 : nodeNumber == unitarySys.AirInNode || nodeNumber == unitarySys.m_OAMixerNodes[0] ||
17080 6 : nodeNumber == unitarySys.m_OAMixerNodes[1] || nodeNumber == unitarySys.m_OAMixerNodes[2]) ||
17081 20 : nodeNumber == unitarySys.m_OAMixerNodes[3] || nodeNumber == unitarySys.CoolCoilOutletNodeNum ||
17082 2 : nodeNumber == unitarySys.HeatCoilOutletNodeNum) {
17083 8 : return true;
17084 : }
17085 : }
17086 : }
17087 34 : return false;
17088 : }
17089 :
17090 45 : void setupAllOutputVars(EnergyPlusData &state, int const numAllSystemTypes)
17091 : {
17092 : // setup reports only once
17093 : // all report variable are set up here after all systems are allocated.
17094 : // UnitarySystem now models other equipment types, any new reports may be setup here.
17095 45 : if (numAllSystemTypes == state.dataUnitarySystems->numUnitarySystems) {
17096 99 : for (int sysNum = 0; sysNum < state.dataUnitarySystems->numUnitarySystems; ++sysNum) {
17097 54 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_sysType) {
17098 9 : case UnitarySys::SysType::Unitary:
17099 : // Setup Report variables for the Unitary System that are not reported in the components themselves
17100 18 : SetupOutputVariable(state,
17101 : "Unitary System Part Load Ratio",
17102 : Constant::Units::None,
17103 9 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17104 : OutputProcessor::TimeStepType::System,
17105 : OutputProcessor::StoreType::Average,
17106 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17107 18 : SetupOutputVariable(state,
17108 : "Unitary System Total Cooling Rate",
17109 : Constant::Units::W,
17110 9 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17111 : OutputProcessor::TimeStepType::System,
17112 : OutputProcessor::StoreType::Average,
17113 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17114 18 : SetupOutputVariable(state,
17115 : "Unitary System Sensible Cooling Rate",
17116 : Constant::Units::W,
17117 9 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17118 : OutputProcessor::TimeStepType::System,
17119 : OutputProcessor::StoreType::Average,
17120 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17121 18 : SetupOutputVariable(state,
17122 : "Unitary System Latent Cooling Rate",
17123 : Constant::Units::W,
17124 9 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17125 : OutputProcessor::TimeStepType::System,
17126 : OutputProcessor::StoreType::Average,
17127 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17128 18 : SetupOutputVariable(state,
17129 : "Unitary System Total Heating Rate",
17130 : Constant::Units::W,
17131 9 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17132 : OutputProcessor::TimeStepType::System,
17133 : OutputProcessor::StoreType::Average,
17134 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17135 18 : SetupOutputVariable(state,
17136 : "Unitary System Sensible Heating Rate",
17137 : Constant::Units::W,
17138 9 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17139 : OutputProcessor::TimeStepType::System,
17140 : OutputProcessor::StoreType::Average,
17141 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17142 18 : SetupOutputVariable(state,
17143 : "Unitary System Latent Heating Rate",
17144 : Constant::Units::W,
17145 9 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17146 : OutputProcessor::TimeStepType::System,
17147 : OutputProcessor::StoreType::Average,
17148 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17149 18 : SetupOutputVariable(state,
17150 : "Unitary System Ancillary Electricity Rate",
17151 : Constant::Units::W,
17152 9 : state.dataUnitarySystems->unitarySys[sysNum].m_TotalAuxElecPower,
17153 : OutputProcessor::TimeStepType::System,
17154 : OutputProcessor::StoreType::Average,
17155 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17156 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolCoilExists) {
17157 14 : SetupOutputVariable(state,
17158 : "Unitary System Cooling Ancillary Electricity Energy",
17159 : Constant::Units::J,
17160 7 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingAuxElecConsumption,
17161 : OutputProcessor::TimeStepType::System,
17162 : OutputProcessor::StoreType::Sum,
17163 7 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17164 : Constant::eResource::Electricity,
17165 : OutputProcessor::Group::HVAC,
17166 : OutputProcessor::EndUseCat::Cooling);
17167 : }
17168 10 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatCoilExists ||
17169 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SuppCoilExists) {
17170 16 : SetupOutputVariable(state,
17171 : "Unitary System Heating Ancillary Electricity Energy",
17172 : Constant::Units::J,
17173 8 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingAuxElecConsumption,
17174 : OutputProcessor::TimeStepType::System,
17175 : OutputProcessor::StoreType::Sum,
17176 8 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17177 : Constant::eResource::Electricity,
17178 : OutputProcessor::Group::HVAC,
17179 : OutputProcessor::EndUseCat::Heating);
17180 : }
17181 :
17182 18 : SetupOutputVariable(state,
17183 : "Unitary System Electricity Rate",
17184 : Constant::Units::W,
17185 9 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17186 : OutputProcessor::TimeStepType::System,
17187 : OutputProcessor::StoreType::Average,
17188 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17189 18 : SetupOutputVariable(state,
17190 : "Unitary System Electricity Energy",
17191 : Constant::Units::J,
17192 9 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17193 : OutputProcessor::TimeStepType::System,
17194 : OutputProcessor::StoreType::Sum,
17195 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17196 :
17197 : // report predicted load as determined by Unitary System for load control only
17198 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_ControlType != UnitarySys::UnitarySysCtrlType::Setpoint) {
17199 16 : SetupOutputVariable(state,
17200 : "Unitary System Predicted Sensible Load to Setpoint Heat Transfer Rate",
17201 : Constant::Units::W,
17202 8 : state.dataUnitarySystems->unitarySys[sysNum].m_SensibleLoadPredicted,
17203 : OutputProcessor::TimeStepType::System,
17204 : OutputProcessor::StoreType::Average,
17205 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17206 16 : SetupOutputVariable(state,
17207 : "Unitary System Predicted Moisture Load to Setpoint Heat Transfer Rate",
17208 : Constant::Units::W,
17209 8 : state.dataUnitarySystems->unitarySys[sysNum].m_MoistureLoadPredicted,
17210 : OutputProcessor::TimeStepType::System,
17211 : OutputProcessor::StoreType::Average,
17212 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17213 : }
17214 :
17215 : // IF(UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)THEN
17216 18 : SetupOutputVariable(state,
17217 : "Unitary System Dehumidification Induced Heating Demand Rate",
17218 : Constant::Units::W,
17219 9 : state.dataUnitarySystems->unitarySys[sysNum].m_DehumidInducedHeatingDemandRate,
17220 : OutputProcessor::TimeStepType::System,
17221 : OutputProcessor::StoreType::Average,
17222 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17223 : // END IF
17224 :
17225 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_FanExists) {
17226 16 : SetupOutputVariable(state,
17227 : "Unitary System Fan Part Load Ratio",
17228 : Constant::Units::None,
17229 8 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17230 : OutputProcessor::TimeStepType::System,
17231 : OutputProcessor::StoreType::Average,
17232 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17233 : }
17234 :
17235 18 : SetupOutputVariable(state,
17236 : "Unitary System Compressor Part Load Ratio",
17237 : Constant::Units::None,
17238 9 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17239 : OutputProcessor::TimeStepType::System,
17240 : OutputProcessor::StoreType::Average,
17241 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17242 :
17243 9 : SetupOutputVariable(state,
17244 : "Unitary System Frost Control Status",
17245 : Constant::Units::None,
17246 9 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17247 : OutputProcessor::TimeStepType::System,
17248 : OutputProcessor::StoreType::Average,
17249 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17250 :
17251 9 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num) {
17252 4 : case HVAC::CoilDX_MultiSpeedCooling:
17253 : case HVAC::CoilDX_Cooling: {
17254 4 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecActive) {
17255 2 : SetupOutputVariable(state,
17256 : "Unitary System Heat Recovery Rate",
17257 : Constant::Units::W,
17258 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryRate,
17259 : OutputProcessor::TimeStepType::System,
17260 : OutputProcessor::StoreType::Average,
17261 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17262 2 : SetupOutputVariable(state,
17263 : "Unitary System Heat Recovery Inlet Temperature",
17264 : Constant::Units::C,
17265 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryInletTemp,
17266 : OutputProcessor::TimeStepType::System,
17267 : OutputProcessor::StoreType::Average,
17268 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17269 2 : SetupOutputVariable(state,
17270 : "Unitary System Heat Recovery Outlet Temperature",
17271 : Constant::Units::C,
17272 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryOutletTemp,
17273 : OutputProcessor::TimeStepType::System,
17274 : OutputProcessor::StoreType::Average,
17275 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17276 2 : SetupOutputVariable(state,
17277 : "Unitary System Heat Recovery Fluid Mass Flow Rate",
17278 : Constant::Units::kg_s,
17279 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryMassFlowRate,
17280 : OutputProcessor::TimeStepType::System,
17281 : OutputProcessor::StoreType::Average,
17282 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17283 2 : SetupOutputVariable(state,
17284 : "Unitary System Heat Recovery Energy",
17285 : Constant::Units::J,
17286 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryEnergy,
17287 : OutputProcessor::TimeStepType::System,
17288 : OutputProcessor::StoreType::Sum,
17289 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17290 : }
17291 4 : } break;
17292 2 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
17293 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit:
17294 : case HVAC::Coil_CoolingWaterToAirHPSimple:
17295 : case HVAC::Coil_CoolingWaterToAirHP: {
17296 4 : SetupOutputVariable(state,
17297 : "Unitary System Requested Sensible Cooling Rate",
17298 : Constant::Units::W,
17299 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilSensDemand,
17300 : OutputProcessor::TimeStepType::System,
17301 : OutputProcessor::StoreType::Average,
17302 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17303 4 : SetupOutputVariable(state,
17304 : "Unitary System Requested Latent Cooling Rate",
17305 : Constant::Units::W,
17306 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilLatentDemand,
17307 : OutputProcessor::TimeStepType::System,
17308 : OutputProcessor::StoreType::Average,
17309 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17310 2 : } break;
17311 3 : default:
17312 3 : break;
17313 : }
17314 :
17315 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex >= 0) {
17316 11 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
17317 2 : state.dataCoilCoolingDX->coilCoolingDXs[state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex]
17318 2 : .SubcoolReheatFlag) {
17319 2 : SetupOutputVariable(state,
17320 : "Unitary System Zone Load Sensible Heat Ratio",
17321 : Constant::Units::None,
17322 1 : state.dataUnitarySystems->unitarySys[sysNum].LoadSHR,
17323 : OutputProcessor::TimeStepType::System,
17324 : OutputProcessor::StoreType::Average,
17325 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17326 2 : SetupOutputVariable(state,
17327 : "Unitary System Cooling Coil Load Sensible Heat Ratio",
17328 : Constant::Units::None,
17329 1 : state.dataUnitarySystems->unitarySys[sysNum].CoilSHR,
17330 : OutputProcessor::TimeStepType::System,
17331 : OutputProcessor::StoreType::Average,
17332 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17333 : }
17334 : }
17335 :
17336 9 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num) {
17337 2 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
17338 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
17339 : case HVAC::Coil_HeatingWaterToAirHPSimple:
17340 : case HVAC::Coil_HeatingWaterToAirHP: {
17341 4 : SetupOutputVariable(state,
17342 : "Unitary System Requested Heating Rate",
17343 : Constant::Units::W,
17344 2 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilSensDemand,
17345 : OutputProcessor::TimeStepType::System,
17346 : OutputProcessor::StoreType::Average,
17347 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17348 2 : } break;
17349 7 : default:
17350 7 : break;
17351 : }
17352 :
17353 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17354 7 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
17355 7 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
17356 5 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17357 20 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
17358 4 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
17359 10 : SetupOutputVariable(state,
17360 : "Unitary System DX Coil Cycling Ratio",
17361 : Constant::Units::None,
17362 5 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17363 : OutputProcessor::TimeStepType::System,
17364 : OutputProcessor::StoreType::Average,
17365 5 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17366 10 : SetupOutputVariable(state,
17367 : "Unitary System DX Coil Speed Ratio",
17368 : Constant::Units::None,
17369 5 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17370 : OutputProcessor::TimeStepType::System,
17371 : OutputProcessor::StoreType::Average,
17372 5 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17373 5 : SetupOutputVariable(state,
17374 : "Unitary System DX Coil Speed Level",
17375 : Constant::Units::None,
17376 5 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17377 : OutputProcessor::TimeStepType::System,
17378 : OutputProcessor::StoreType::Average,
17379 5 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17380 : }
17381 :
17382 9 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
17383 9 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
17384 18 : state.dataUnitarySystems->unitarySys[sysNum].m_DiscreteSpeedCoolingCoil) ||
17385 9 : (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWater &&
17386 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MultiSpeedHeatingCoil)) {
17387 0 : SetupOutputVariable(state,
17388 : "Unitary System Water Coil Cycling Ratio",
17389 : Constant::Units::None,
17390 0 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17391 : OutputProcessor::TimeStepType::System,
17392 : OutputProcessor::StoreType::Average,
17393 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17394 0 : SetupOutputVariable(state,
17395 : "Unitary System Water Coil Speed Ratio",
17396 : Constant::Units::None,
17397 0 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17398 : OutputProcessor::TimeStepType::System,
17399 : OutputProcessor::StoreType::Average,
17400 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17401 0 : SetupOutputVariable(state,
17402 : "Unitary System Water Coil Speed Level",
17403 : Constant::Units::None,
17404 0 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17405 : OutputProcessor::TimeStepType::System,
17406 : OutputProcessor::StoreType::Average,
17407 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17408 : }
17409 :
17410 9 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
17411 0 : SetupEMSActuator(state,
17412 : "UnitarySystem",
17413 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17414 : "Autosized Supply Air Flow Rate",
17415 : "[m3/s]",
17416 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideOn,
17417 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideValue);
17418 0 : SetupEMSActuator(state,
17419 : "UnitarySystem",
17420 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17421 : "Autosized Supply Air Flow Rate During Cooling Operation",
17422 : "[m3/s]",
17423 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideOn,
17424 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideValue);
17425 0 : SetupEMSActuator(state,
17426 : "UnitarySystem",
17427 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17428 : "Autosized Supply Air Flow Rate During Heating Operation",
17429 : "[m3/s]",
17430 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideOn,
17431 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideValue);
17432 0 : SetupEMSActuator(state,
17433 : "UnitarySystem",
17434 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17435 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
17436 : "[m3/s]",
17437 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideOn,
17438 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideValue);
17439 0 : SetupEMSInternalVariable(state,
17440 : "Unitary System Control Zone Mass Flow Fraction",
17441 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17442 : "[]",
17443 0 : state.dataUnitarySystems->unitarySys[sysNum].ControlZoneMassFlowFrac);
17444 0 : SetupEMSInternalVariable(state,
17445 : "Unitary HVAC Design Heating Capacity",
17446 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17447 : "[W]",
17448 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignHeatingCapacity);
17449 0 : SetupEMSInternalVariable(state,
17450 : "Unitary HVAC Design Cooling Capacity",
17451 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17452 : "[W]",
17453 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignCoolingCapacity);
17454 0 : SetupEMSActuator(state,
17455 : "Unitary HVAC",
17456 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17457 : "Sensible Load Request",
17458 : "[W]",
17459 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSensZoneLoadRequest,
17460 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSSensibleZoneLoadValue);
17461 0 : SetupEMSActuator(state,
17462 : "Unitary HVAC",
17463 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17464 : "Moisture Load Request",
17465 : "[W]",
17466 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideMoistZoneLoadRequest,
17467 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSMoistureZoneLoadValue);
17468 0 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17469 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17470 0 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
17471 0 : SetupEMSActuator(state,
17472 : "Coil Speed Control",
17473 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17474 : "Unitary System DX Coil Speed Value",
17475 : "[]",
17476 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumOn,
17477 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumValue);
17478 : }
17479 0 : SetupEMSActuator(state,
17480 : "Coil Speed Control",
17481 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17482 : "Unitary System Supplemental Coil Stage Level",
17483 : "[]",
17484 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumOn,
17485 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumValue);
17486 : }
17487 : bool anyEMSRan;
17488 9 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
17489 54 : break;
17490 22 : case UnitarySys::SysType::CoilCoolingDX:
17491 : // Setup Report variables for the DXCoolingSystem that is not reported in the components themselves
17492 22 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
17493 4 : SetupOutputVariable(state,
17494 : "Coil System Cycling Ratio",
17495 : Constant::Units::None,
17496 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17497 : OutputProcessor::TimeStepType::System,
17498 : OutputProcessor::StoreType::Average,
17499 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17500 4 : SetupOutputVariable(state,
17501 : "Coil System Compressor Speed Ratio",
17502 : Constant::Units::None,
17503 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17504 : OutputProcessor::TimeStepType::System,
17505 : OutputProcessor::StoreType::Average,
17506 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17507 20 : } else if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
17508 6 : SetupOutputVariable(state,
17509 : "Coil System Cycling Ratio",
17510 : Constant::Units::None,
17511 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17512 : OutputProcessor::TimeStepType::System,
17513 : OutputProcessor::StoreType::Average,
17514 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17515 6 : SetupOutputVariable(state,
17516 : "Coil System Compressor Speed Ratio",
17517 : Constant::Units::None,
17518 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17519 : OutputProcessor::TimeStepType::System,
17520 : OutputProcessor::StoreType::Average,
17521 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17522 3 : SetupOutputVariable(state,
17523 : "Coil System Compressor Speed Number",
17524 : Constant::Units::None,
17525 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedNum,
17526 : OutputProcessor::TimeStepType::System,
17527 : OutputProcessor::StoreType::Average,
17528 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17529 : } else {
17530 34 : SetupOutputVariable(state,
17531 : "Coil System Part Load Ratio",
17532 : Constant::Units::None,
17533 17 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingPartLoadFrac,
17534 : OutputProcessor::TimeStepType::System,
17535 : OutputProcessor::StoreType::Average,
17536 17 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17537 : }
17538 22 : SetupOutputVariable(state,
17539 : "Coil System Frost Control Status",
17540 : Constant::Units::None,
17541 22 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17542 : OutputProcessor::TimeStepType::System,
17543 : OutputProcessor::StoreType::Average,
17544 22 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17545 22 : break;
17546 6 : case UnitarySys::SysType::CoilCoolingWater:
17547 : // Setup Report variables for the CoilSystemWater
17548 12 : SetupOutputVariable(state,
17549 : "Coil System Water Part Load Ratio",
17550 : Constant::Units::None,
17551 6 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17552 : OutputProcessor::TimeStepType::System,
17553 : OutputProcessor::StoreType::Average,
17554 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17555 12 : SetupOutputVariable(state,
17556 : "Coil System Water Total Cooling Rate",
17557 : Constant::Units::W,
17558 6 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17559 : OutputProcessor::TimeStepType::System,
17560 : OutputProcessor::StoreType::Average,
17561 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17562 12 : SetupOutputVariable(state,
17563 : "Coil System Water Sensible Cooling Rate",
17564 : Constant::Units::W,
17565 6 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17566 : OutputProcessor::TimeStepType::System,
17567 : OutputProcessor::StoreType::Average,
17568 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17569 12 : SetupOutputVariable(state,
17570 : "Coil System Water Latent Cooling Rate",
17571 : Constant::Units::W,
17572 6 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17573 : OutputProcessor::TimeStepType::System,
17574 : OutputProcessor::StoreType::Average,
17575 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17576 :
17577 6 : if (state.dataUnitarySystems->unitarySys[sysNum].m_TemperatureOffsetControlActive) {
17578 6 : SetupOutputVariable(state,
17579 : "Coil System Water Control Status",
17580 : Constant::Units::None,
17581 6 : state.dataUnitarySystems->unitarySys[sysNum].temperatureOffsetControlStatus,
17582 : OutputProcessor::TimeStepType::System,
17583 : OutputProcessor::StoreType::Average,
17584 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17585 : }
17586 6 : break;
17587 12 : case UnitarySys::SysType::PackagedAC:
17588 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalAirConditioner'
17589 24 : SetupOutputVariable(state,
17590 : "Zone Packaged Terminal Air Conditioner Total Heating Rate",
17591 : Constant::Units::W,
17592 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17593 : OutputProcessor::TimeStepType::System,
17594 : OutputProcessor::StoreType::Average,
17595 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17596 24 : SetupOutputVariable(state,
17597 : "Zone Packaged Terminal Air Conditioner Total Heating Energy",
17598 : Constant::Units::J,
17599 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17600 : OutputProcessor::TimeStepType::System,
17601 : OutputProcessor::StoreType::Sum,
17602 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17603 24 : SetupOutputVariable(state,
17604 : "Zone Packaged Terminal Air Conditioner Total Cooling Rate",
17605 : Constant::Units::W,
17606 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17607 : OutputProcessor::TimeStepType::System,
17608 : OutputProcessor::StoreType::Average,
17609 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17610 24 : SetupOutputVariable(state,
17611 : "Zone Packaged Terminal Air Conditioner Total Cooling Energy",
17612 : Constant::Units::J,
17613 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17614 : OutputProcessor::TimeStepType::System,
17615 : OutputProcessor::StoreType::Sum,
17616 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17617 24 : SetupOutputVariable(state,
17618 : "Zone Packaged Terminal Air Conditioner Sensible Heating Rate",
17619 : Constant::Units::W,
17620 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17621 : OutputProcessor::TimeStepType::System,
17622 : OutputProcessor::StoreType::Average,
17623 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17624 24 : SetupOutputVariable(state,
17625 : "Zone Packaged Terminal Air Conditioner Sensible Heating Energy",
17626 : Constant::Units::J,
17627 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17628 : OutputProcessor::TimeStepType::System,
17629 : OutputProcessor::StoreType::Sum,
17630 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17631 24 : SetupOutputVariable(state,
17632 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Rate",
17633 : Constant::Units::W,
17634 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17635 : OutputProcessor::TimeStepType::System,
17636 : OutputProcessor::StoreType::Average,
17637 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17638 24 : SetupOutputVariable(state,
17639 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Energy",
17640 : Constant::Units::J,
17641 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17642 : OutputProcessor::TimeStepType::System,
17643 : OutputProcessor::StoreType::Sum,
17644 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17645 24 : SetupOutputVariable(state,
17646 : "Zone Packaged Terminal Air Conditioner Latent Heating Rate",
17647 : Constant::Units::W,
17648 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17649 : OutputProcessor::TimeStepType::System,
17650 : OutputProcessor::StoreType::Average,
17651 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17652 24 : SetupOutputVariable(state,
17653 : "Zone Packaged Terminal Air Conditioner Latent Heating Energy",
17654 : Constant::Units::J,
17655 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17656 : OutputProcessor::TimeStepType::System,
17657 : OutputProcessor::StoreType::Sum,
17658 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17659 24 : SetupOutputVariable(state,
17660 : "Zone Packaged Terminal Air Conditioner Latent Cooling Rate",
17661 : Constant::Units::W,
17662 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17663 : OutputProcessor::TimeStepType::System,
17664 : OutputProcessor::StoreType::Average,
17665 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17666 24 : SetupOutputVariable(state,
17667 : "Zone Packaged Terminal Air Conditioner Latent Cooling Energy",
17668 : Constant::Units::J,
17669 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17670 : OutputProcessor::TimeStepType::System,
17671 : OutputProcessor::StoreType::Sum,
17672 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17673 24 : SetupOutputVariable(state,
17674 : "Zone Packaged Terminal Air Conditioner Electricity Rate",
17675 : Constant::Units::W,
17676 12 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17677 : OutputProcessor::TimeStepType::System,
17678 : OutputProcessor::StoreType::Average,
17679 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17680 24 : SetupOutputVariable(state,
17681 : "Zone Packaged Terminal Air Conditioner Electricity Energy",
17682 : Constant::Units::J,
17683 12 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17684 : OutputProcessor::TimeStepType::System,
17685 : OutputProcessor::StoreType::Sum,
17686 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17687 24 : SetupOutputVariable(state,
17688 : "Zone Packaged Terminal Air Conditioner Fan Part Load Ratio",
17689 : Constant::Units::None,
17690 12 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17691 : OutputProcessor::TimeStepType::System,
17692 : OutputProcessor::StoreType::Average,
17693 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17694 24 : SetupOutputVariable(state,
17695 : "Zone Packaged Terminal Air Conditioner Compressor Part Load Ratio",
17696 : Constant::Units::None,
17697 12 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17698 : OutputProcessor::TimeStepType::System,
17699 : OutputProcessor::StoreType::Average,
17700 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17701 12 : SetupOutputVariable(state,
17702 : "Zone Packaged Terminal Air Conditioner Fan Availability Status",
17703 : Constant::Units::None,
17704 12 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17705 : OutputProcessor::TimeStepType::System,
17706 : OutputProcessor::StoreType::Average,
17707 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17708 12 : break;
17709 3 : case UnitarySys::SysType::PackagedHP:
17710 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalHeatPump'
17711 6 : SetupOutputVariable(state,
17712 : "Zone Packaged Terminal Heat Pump Total Heating Rate",
17713 : Constant::Units::W,
17714 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17715 : OutputProcessor::TimeStepType::System,
17716 : OutputProcessor::StoreType::Average,
17717 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17718 6 : SetupOutputVariable(state,
17719 : "Zone Packaged Terminal Heat Pump Total Heating Energy",
17720 : Constant::Units::J,
17721 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17722 : OutputProcessor::TimeStepType::System,
17723 : OutputProcessor::StoreType::Sum,
17724 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17725 6 : SetupOutputVariable(state,
17726 : "Zone Packaged Terminal Heat Pump Total Cooling Rate",
17727 : Constant::Units::W,
17728 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17729 : OutputProcessor::TimeStepType::System,
17730 : OutputProcessor::StoreType::Average,
17731 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17732 6 : SetupOutputVariable(state,
17733 : "Zone Packaged Terminal Heat Pump Total Cooling Energy",
17734 : Constant::Units::J,
17735 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17736 : OutputProcessor::TimeStepType::System,
17737 : OutputProcessor::StoreType::Sum,
17738 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17739 6 : SetupOutputVariable(state,
17740 : "Zone Packaged Terminal Heat Pump Sensible Heating Rate",
17741 : Constant::Units::W,
17742 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17743 : OutputProcessor::TimeStepType::System,
17744 : OutputProcessor::StoreType::Average,
17745 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17746 6 : SetupOutputVariable(state,
17747 : "Zone Packaged Terminal Heat Pump Sensible Heating Energy",
17748 : Constant::Units::J,
17749 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17750 : OutputProcessor::TimeStepType::System,
17751 : OutputProcessor::StoreType::Sum,
17752 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17753 6 : SetupOutputVariable(state,
17754 : "Zone Packaged Terminal Heat Pump Sensible Cooling Rate",
17755 : Constant::Units::W,
17756 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17757 : OutputProcessor::TimeStepType::System,
17758 : OutputProcessor::StoreType::Average,
17759 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17760 6 : SetupOutputVariable(state,
17761 : "Zone Packaged Terminal Heat Pump Sensible Cooling Energy",
17762 : Constant::Units::J,
17763 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17764 : OutputProcessor::TimeStepType::System,
17765 : OutputProcessor::StoreType::Sum,
17766 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17767 6 : SetupOutputVariable(state,
17768 : "Zone Packaged Terminal Heat Pump Latent Heating Rate",
17769 : Constant::Units::W,
17770 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17771 : OutputProcessor::TimeStepType::System,
17772 : OutputProcessor::StoreType::Average,
17773 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17774 6 : SetupOutputVariable(state,
17775 : "Zone Packaged Terminal Heat Pump Latent Heating Energy",
17776 : Constant::Units::J,
17777 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17778 : OutputProcessor::TimeStepType::System,
17779 : OutputProcessor::StoreType::Sum,
17780 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17781 6 : SetupOutputVariable(state,
17782 : "Zone Packaged Terminal Heat Pump Latent Cooling Rate",
17783 : Constant::Units::W,
17784 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17785 : OutputProcessor::TimeStepType::System,
17786 : OutputProcessor::StoreType::Average,
17787 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17788 6 : SetupOutputVariable(state,
17789 : "Zone Packaged Terminal Heat Pump Latent Cooling Energy",
17790 : Constant::Units::J,
17791 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17792 : OutputProcessor::TimeStepType::System,
17793 : OutputProcessor::StoreType::Sum,
17794 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17795 6 : SetupOutputVariable(state,
17796 : "Zone Packaged Terminal Heat Pump Electricity Rate",
17797 : Constant::Units::W,
17798 3 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17799 : OutputProcessor::TimeStepType::System,
17800 : OutputProcessor::StoreType::Average,
17801 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17802 6 : SetupOutputVariable(state,
17803 : "Zone Packaged Terminal Heat Pump Electricity Energy",
17804 : Constant::Units::J,
17805 3 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17806 : OutputProcessor::TimeStepType::System,
17807 : OutputProcessor::StoreType::Sum,
17808 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17809 6 : SetupOutputVariable(state,
17810 : "Zone Packaged Terminal Heat Pump Fan Part Load Ratio",
17811 : Constant::Units::None,
17812 3 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17813 : OutputProcessor::TimeStepType::System,
17814 : OutputProcessor::StoreType::Average,
17815 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17816 6 : SetupOutputVariable(state,
17817 : "Zone Packaged Terminal Heat Pump Compressor Part Load Ratio",
17818 : Constant::Units::None,
17819 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17820 : OutputProcessor::TimeStepType::System,
17821 : OutputProcessor::StoreType::Average,
17822 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17823 3 : SetupOutputVariable(state,
17824 : "Zone Packaged Terminal Heat Pump Fan Availability Status",
17825 : Constant::Units::None,
17826 3 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17827 : OutputProcessor::TimeStepType::System,
17828 : OutputProcessor::StoreType::Average,
17829 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17830 3 : break;
17831 2 : case UnitarySys::SysType::PackagedWSHP:
17832 : // CurrentModuleObject = 'ZoneHVAC:WaterToAirHeatPump'
17833 4 : SetupOutputVariable(state,
17834 : "Zone Water to Air Heat Pump Total Heating Rate",
17835 : Constant::Units::W,
17836 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17837 : OutputProcessor::TimeStepType::System,
17838 : OutputProcessor::StoreType::Average,
17839 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17840 4 : SetupOutputVariable(state,
17841 : "Zone Water to Air Heat Pump Total Heating Energy",
17842 : Constant::Units::J,
17843 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17844 : OutputProcessor::TimeStepType::System,
17845 : OutputProcessor::StoreType::Sum,
17846 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17847 4 : SetupOutputVariable(state,
17848 : "Zone Water to Air Heat Pump Total Cooling Rate",
17849 : Constant::Units::W,
17850 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17851 : OutputProcessor::TimeStepType::System,
17852 : OutputProcessor::StoreType::Average,
17853 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17854 4 : SetupOutputVariable(state,
17855 : "Zone Water to Air Heat Pump Total Cooling Energy",
17856 : Constant::Units::J,
17857 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17858 : OutputProcessor::TimeStepType::System,
17859 : OutputProcessor::StoreType::Sum,
17860 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17861 4 : SetupOutputVariable(state,
17862 : "Zone Water to Air Heat Pump Sensible Heating Rate",
17863 : Constant::Units::W,
17864 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17865 : OutputProcessor::TimeStepType::System,
17866 : OutputProcessor::StoreType::Average,
17867 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17868 4 : SetupOutputVariable(state,
17869 : "Zone Water to Air Heat Pump Sensible Heating Energy",
17870 : Constant::Units::J,
17871 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17872 : OutputProcessor::TimeStepType::System,
17873 : OutputProcessor::StoreType::Sum,
17874 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17875 4 : SetupOutputVariable(state,
17876 : "Zone Water to Air Heat Pump Sensible Cooling Rate",
17877 : Constant::Units::W,
17878 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17879 : OutputProcessor::TimeStepType::System,
17880 : OutputProcessor::StoreType::Average,
17881 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17882 4 : SetupOutputVariable(state,
17883 : "Zone Water to Air Heat Pump Sensible Cooling Energy",
17884 : Constant::Units::J,
17885 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17886 : OutputProcessor::TimeStepType::System,
17887 : OutputProcessor::StoreType::Sum,
17888 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17889 4 : SetupOutputVariable(state,
17890 : "Zone Water to Air Heat Pump Latent Heating Rate",
17891 : Constant::Units::W,
17892 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17893 : OutputProcessor::TimeStepType::System,
17894 : OutputProcessor::StoreType::Average,
17895 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17896 4 : SetupOutputVariable(state,
17897 : "Zone Water to Air Heat Pump Latent Heating Energy",
17898 : Constant::Units::J,
17899 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17900 : OutputProcessor::TimeStepType::System,
17901 : OutputProcessor::StoreType::Sum,
17902 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17903 4 : SetupOutputVariable(state,
17904 : "Zone Water to Air Heat Pump Latent Cooling Rate",
17905 : Constant::Units::W,
17906 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17907 : OutputProcessor::TimeStepType::System,
17908 : OutputProcessor::StoreType::Average,
17909 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17910 4 : SetupOutputVariable(state,
17911 : "Zone Water to Air Heat Pump Latent Cooling Energy",
17912 : Constant::Units::J,
17913 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17914 : OutputProcessor::TimeStepType::System,
17915 : OutputProcessor::StoreType::Sum,
17916 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17917 4 : SetupOutputVariable(state,
17918 : "Zone Water to Air Heat Pump Electricity Rate",
17919 : Constant::Units::W,
17920 2 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17921 : OutputProcessor::TimeStepType::System,
17922 : OutputProcessor::StoreType::Average,
17923 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17924 4 : SetupOutputVariable(state,
17925 : "Zone Water to Air Heat Pump Electricity Energy",
17926 : Constant::Units::J,
17927 2 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17928 : OutputProcessor::TimeStepType::System,
17929 : OutputProcessor::StoreType::Sum,
17930 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17931 4 : SetupOutputVariable(state,
17932 : "Zone Water to Air Heat Pump Fan Part Load Ratio",
17933 : Constant::Units::None,
17934 2 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17935 : OutputProcessor::TimeStepType::System,
17936 : OutputProcessor::StoreType::Average,
17937 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17938 4 : SetupOutputVariable(state,
17939 : "Zone Water to Air Heat Pump Compressor Part Load Ratio",
17940 : Constant::Units::None,
17941 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17942 : OutputProcessor::TimeStepType::System,
17943 : OutputProcessor::StoreType::Average,
17944 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17945 2 : SetupOutputVariable(state,
17946 : "Zone Water to Air Heat Pump Fan Availability Status",
17947 : Constant::Units::None,
17948 2 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17949 : OutputProcessor::TimeStepType::System,
17950 : OutputProcessor::StoreType::Average,
17951 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17952 2 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
17953 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
17954 4 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedCooling > 1) ||
17955 1 : ((state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
17956 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
17957 1 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedHeating > 1)) {
17958 2 : SetupOutputVariable(state,
17959 : "Unitary System Water Coil Multispeed Fan Cycling Ratio",
17960 : Constant::Units::None,
17961 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17962 : OutputProcessor::TimeStepType::System,
17963 : OutputProcessor::StoreType::Average,
17964 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17965 2 : SetupOutputVariable(state,
17966 : "Unitary System Water Coil Multispeed Fan Speed Ratio",
17967 : Constant::Units::None,
17968 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17969 : OutputProcessor::TimeStepType::System,
17970 : OutputProcessor::StoreType::Average,
17971 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17972 1 : SetupOutputVariable(state,
17973 : "Unitary System Water Coil Multispeed Fan Speed Level",
17974 : Constant::Units::None,
17975 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17976 : OutputProcessor::TimeStepType::System,
17977 : OutputProcessor::StoreType::Average,
17978 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17979 : }
17980 2 : break;
17981 0 : default:
17982 0 : ShowFatalError(state,
17983 : "setupAllOutputVar: Developer error. All report variables must be set up here after all systems are read in.");
17984 : }
17985 : }
17986 45 : state.dataUnitarySystems->setupOutputOnce = false;
17987 : } else {
17988 0 : ShowSevereError(state,
17989 : "setupAllOutputVar: Developer error. Should never get here. Remove when comfortable that UnitarySys::allocateUnitarySys "
17990 : "is working as expected.");
17991 0 : ShowFatalError(state, "setupAllOutputVar: Developer error. Conflict in number of UnitarySystems.");
17992 : }
17993 45 : }
17994 :
17995 4 : void isWaterCoilHeatRecoveryType(EnergyPlusData const &state, int const waterCoilNodeNum, bool &nodeNotFound)
17996 : {
17997 4 : if (!nodeNotFound) {
17998 4 : return;
17999 : }
18000 0 : nodeNotFound = std::none_of(
18001 0 : state.dataUnitarySystems->unitarySys.cbegin(), state.dataUnitarySystems->unitarySys.cend(), [waterCoilNodeNum](auto const &us) {
18002 0 : return us.m_WaterHRPlantLoopModel && us.m_HRcoolCoilFluidInletNode == waterCoilNodeNum;
18003 : });
18004 : }
18005 :
18006 15 : Real64 UnitarySys::getFanDeltaTemp(EnergyPlusData &state, bool const firstHVACIteration, Real64 const massFlowRate, Real64 const airFlowRatio)
18007 : {
18008 15 : int FanInletNode = 0;
18009 15 : int FanOutletNode = 0;
18010 :
18011 15 : auto *fan = state.dataFans->fans(this->m_FanIndex);
18012 15 : FanInletNode = fan->inletNodeNum;
18013 15 : FanOutletNode = fan->outletNodeNum;
18014 15 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = massFlowRate;
18015 15 : fan->simulate(state, firstHVACIteration, airFlowRatio, _, airFlowRatio, _, _, _);
18016 15 : return state.dataLoopNodes->Node(FanOutletNode).Temp - state.dataLoopNodes->Node(FanInletNode).Temp;
18017 : }
18018 :
18019 3 : void UnitarySys::setEconomizerStagingOperationSpeed(EnergyPlusData &state, bool const firstHVACIteration, Real64 const zoneLoad)
18020 : {
18021 3 : this->m_LowSpeedEconOutput = 0;
18022 3 : this->m_LowSpeedEconRuntime = 0;
18023 3 : this->m_EconoPartLoadRatio = 0;
18024 3 : this->m_EconoSpeedNum = 0;
18025 3 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
18026 3 : Real64 mixedTempAtMinOA = 0;
18027 3 : Real64 highSpeedEconMassFlowRate = 0;
18028 3 : Real64 highSpeedFanDT = 0;
18029 3 : Real64 econClgOutput = 0;
18030 3 : Real64 lowSpeedEconMassFlowRate = 0;
18031 3 : Real64 lowSpeedFanDT = 0;
18032 3 : Real64 highSpeedEconRuntime = 0;
18033 3 : Real64 econClgOutputMinOA = 0;
18034 : // determine outdoor air properties
18035 : using Psychrometrics::PsyCpAirFnW;
18036 3 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
18037 3 : Real64 outdoorAirTemp = state.dataLoopNodes->Node(outdoorAirController.InletNode).Temp;
18038 3 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
18039 : // iterate through the unitary system's cooling speed to see at which
18040 : // air flow rate the load can be met at 100% outdoor air fraction
18041 9 : for (int clgSpd = 1; clgSpd <= this->m_NumOfSpeedCooling; ++clgSpd) {
18042 : // calculations for "high speed" refer to operation at the current
18043 : // cooling speed, "clgSpd", and "low speed" is "clgSpd -1"
18044 9 : highSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd];
18045 : // determine air temperature difference for across the fan at this air flow rate
18046 9 : highSpeedFanDT = this->getFanDeltaTemp(state,
18047 : firstHVACIteration,
18048 : highSpeedEconMassFlowRate,
18049 9 : highSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18050 9 : econClgOutput = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + highSpeedFanDT));
18051 : // check if economizer alone can meet the load, or if we have reached the maximum cooling speed
18052 9 : if (econClgOutput > std::abs(zoneLoad) || clgSpd == this->m_NumOfSpeedCooling) {
18053 : // low speed economizer operation is handled through normal process (i.e., no staging operation)
18054 3 : if (clgSpd > 1) {
18055 : // check that the system output at the minimum outdoor air flow rate doesn't "overcool" at this speed
18056 3 : mixedTempAtMinOA = 0;
18057 3 : if (highSpeedEconMassFlowRate - outdoorAirController.MinOA > 0) {
18058 3 : mixedTempAtMinOA =
18059 3 : (outdoorAirTemp * outdoorAirController.MinOA + state.dataLoopNodes->Node(outdoorAirController.RetNode).Temp *
18060 3 : (highSpeedEconMassFlowRate - outdoorAirController.MinOA)) /
18061 : highSpeedEconMassFlowRate;
18062 : } else {
18063 0 : mixedTempAtMinOA = outdoorAirTemp;
18064 : }
18065 3 : econClgOutputMinOA = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (mixedTempAtMinOA + highSpeedFanDT));
18066 3 : if (econClgOutputMinOA < std::abs(zoneLoad)) {
18067 2 : highSpeedEconRuntime = 1.0;
18068 : } else {
18069 : // if running at this speed would "overcool", we run partly at the lower speed and partly at this speed
18070 1 : lowSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd - 1];
18071 1 : lowSpeedFanDT = this->getFanDeltaTemp(state,
18072 : firstHVACIteration,
18073 : lowSpeedEconMassFlowRate,
18074 1 : lowSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18075 1 : this->m_LowSpeedEconOutput = cpAir * lowSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + lowSpeedFanDT));
18076 : // determine this speed's runtime
18077 1 : highSpeedEconRuntime = (std::abs(zoneLoad) - this->m_LowSpeedEconOutput) / (econClgOutput - this->m_LowSpeedEconOutput);
18078 : }
18079 : } else {
18080 0 : highSpeedEconRuntime = 1.0;
18081 : }
18082 : // set economizer air flow "speed"
18083 3 : this->m_EconoSpeedNum = clgSpd;
18084 : // set economizer PLR, a.k.a the system fan part load ratio, and runtime at each speed
18085 3 : this->m_EconoPartLoadRatio = highSpeedEconRuntime;
18086 3 : this->m_LowSpeedEconRuntime = 1 - highSpeedEconRuntime;
18087 3 : break;
18088 : }
18089 : }
18090 3 : }
18091 :
18092 1 : void UnitarySys::calcMixedTempAirSPforEconomizerStagingOperation(EnergyPlusData &state,
18093 : int const airLoopNum,
18094 : bool const firstHVACIteration,
18095 : Real64 const zoneLoad)
18096 : {
18097 1 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
18098 : using Psychrometrics::PsyCpAirFnW;
18099 1 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
18100 1 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
18101 : // determine and set new air loop mixed air flow rate
18102 1 : Real64 mixedAirFlowRate = this->m_EconoPartLoadRatio * this->m_CoolMassFlowRate[this->m_EconoSpeedNum] +
18103 1 : this->m_LowSpeedEconRuntime * this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
18104 1 : if (airLoopNum > 0) {
18105 : // request fixed mixed flow rate
18106 0 : state.dataAirLoop->AirLoopControlInfo(airLoopNum).LoopFlowRateSet = true;
18107 0 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac = mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
18108 : // adjust mixed air flow rate for rated air flow rate adjustment (variable speed coils only)
18109 0 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac *=
18110 0 : this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling] / state.dataAirLoop->AirLoopFlow(airLoopNum).DesSupply;
18111 : }
18112 : // determine air temperature difference across fan based on new mixed air flow rate
18113 1 : int mixedAirNode = outdoorAirController.MixNode;
18114 1 : Real64 fanDTAtMixedAirFlowRate = this->getFanDeltaTemp(
18115 1 : state, firstHVACIteration, mixedAirFlowRate, mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
18116 : // determine new mixed air setpoint
18117 1 : Real64 newMixedAirSP = zoneTemp - std::abs(zoneLoad) / (cpAir * mixedAirFlowRate);
18118 1 : state.dataLoopNodes->Node(mixedAirNode).TempSetPoint = newMixedAirSP - fanDTAtMixedAirFlowRate;
18119 1 : }
18120 :
18121 : void
18122 0 : UnitarySys::manageEconomizerStagingOperation(EnergyPlusData &state, int const airLoopNum, bool const firstHVACIteration, Real64 const zoneLoad)
18123 : {
18124 0 : if (airLoopNum > 0) {
18125 0 : if (state.dataAirLoop->AirLoopControlInfo(airLoopNum).EconoActive == true && state.dataGlobal->WarmupFlag == false &&
18126 0 : state.dataUnitarySystems->CoolingLoad) {
18127 0 : this->setEconomizerStagingOperationSpeed(state, firstHVACIteration, zoneLoad);
18128 :
18129 : // adjustments are only needed when economizer speed is greater than the lowest speed
18130 0 : if (this->m_EconoSpeedNum > 0) {
18131 0 : this->calcMixedTempAirSPforEconomizerStagingOperation(state, airLoopNum, firstHVACIteration, zoneLoad);
18132 :
18133 : // recalculate the outdoor air fraction to meet the new mixed air setpoint at the new mixed air flow rate
18134 0 : MixedAir::ManageOutsideAirSystem(
18135 0 : state, state.dataAirLoop->OutsideAirSys(this->OASysIndex).Name, firstHVACIteration, airLoopNum, this->OASysIndex);
18136 : }
18137 : }
18138 : }
18139 0 : }
18140 :
18141 : } // namespace UnitarySystems
18142 : } // namespace EnergyPlus
|