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) return;
140 :
141 : // MassFlowRateMaxAvail issues are impeding non-VAV air loop equipment by limiting air flow
142 : // temporarily open up flow limits while simulating, and then set this same value at the INLET after this parent has simulated
143 72352 : Real64 tempMassFlowRateMaxAvail = state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail;
144 : // this is not working for CoilSystem simulated with UnitarySystem. Try to protect when this happens.
145 72352 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
146 8 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = this->m_DesignMassFlowRate;
147 : }
148 :
149 72352 : bool HXUnitOn = false;
150 72352 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
151 65316 : this->controlUnitarySystemtoSP(
152 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
153 : } else {
154 7036 : this->controlUnitarySystemtoLoad(
155 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
156 : }
157 :
158 : // Report the current output
159 72352 : this->reportUnitarySystem(state, AirLoopNum);
160 :
161 : // CoolActive = false; // set in call from ZoneEquipmentManager
162 72352 : if (this->m_CoolingPartLoadFrac * double(CompressorOn) > 0.0) CoolActive = true;
163 : // HeatActive = false; // set in call from ZoneEquipmentManager
164 72352 : if (this->m_HeatingPartLoadFrac * double(CompressorOn) > 0.0 || this->m_SuppHeatPartLoadFrac * double(CompressorOn) > 0.0) HeatActive = true;
165 :
166 : // set econo lockout flag
167 : // If the system is not an equipment of Outdoor air unit
168 72352 : if (AirLoopNum > 0 && !state.dataAirLoop->AirLoopControlInfo.empty() && this->m_AirLoopEquipment) {
169 :
170 50710 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor =
171 50710 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor &&
172 0 : (this->m_HeatCompPartLoadRatio > 0.0 || this->m_SpeedRatio > 0.0 || this->m_CycRatio > 0.0);
173 :
174 50710 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating =
175 50714 : HeatActive && (state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor ||
176 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithHeating);
177 : }
178 :
179 : // Calculate heat recovery
180 72352 : if (this->m_HeatRecActive) {
181 1 : this->unitarySystemHeatRecovery(state);
182 : }
183 :
184 : // Coils should have been sized by now. Set this flag to false in case other equipment is downstream of Unitary System.
185 : // No, can't do this since there are other checks that need this flag (e.g., HVACManager, SetHeatToReturnAirFlag())
186 : // AirLoopControlInfo(AirLoopNum)%UnitarySys = .FALSE.
187 :
188 72352 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
189 8 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = tempMassFlowRateMaxAvail;
190 : }
191 : }
192 :
193 49 : DesignSpecMSHP *DesignSpecMSHP::factory(EnergyPlusData &state, HVAC::UnitarySysType type, std::string const &objectName)
194 : {
195 :
196 49 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
197 22 : DesignSpecMSHP::getDesignSpecMSHP(state);
198 22 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
199 : }
200 51 : for (auto &dSpec : state.dataUnitarySystems->designSpecMSHP) {
201 49 : if (Util::SameString(dSpec.name, objectName) && dSpec.m_type == type) {
202 47 : return &dSpec;
203 : }
204 : }
205 2 : ShowSevereError(state, format("Design Specification MultiSpeed Heat Pump factory: Error getting inputs for system named: {}", objectName));
206 2 : return nullptr;
207 : }
208 :
209 22 : void DesignSpecMSHP::getDesignSpecMSHP(EnergyPlusData &state)
210 : {
211 22 : bool errorsFound(false);
212 :
213 22 : DesignSpecMSHP::getDesignSpecMSHPdata(state, errorsFound);
214 :
215 22 : if (errorsFound) {
216 0 : ShowFatalError(state, "Design Specification MultiSpeed Heat Pump: Previous errors cause termination.");
217 : }
218 22 : }
219 :
220 22 : void DesignSpecMSHP::getDesignSpecMSHPdata(EnergyPlusData &state, bool errorsFound)
221 : {
222 22 : std::string const cCurrentModuleObject = "UnitarySystemPerformance:Multispeed";
223 :
224 22 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
225 22 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end()) {
226 1 : errorsFound = true;
227 : } else {
228 21 : int designSpecNum = 0;
229 21 : auto &instancesValue = instances.value();
230 43 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
231 :
232 : // *************** used only to eliminate unused object warning when using only Json type getInput **********
233 22 : int TotalArgs = 0;
234 22 : int NumAlphas = 0;
235 22 : int NumNumbers = 0;
236 22 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
237 22 : int IOStatus = 0;
238 22 : Array1D_string Alphas(NumAlphas);
239 22 : Array1D<Real64> Numbers(NumNumbers, 0.0);
240 22 : Array1D_bool lNumericBlanks(NumNumbers, true);
241 22 : Array1D_bool lAlphaBlanks(NumAlphas, true);
242 22 : Array1D_string cAlphaFields(NumAlphas);
243 22 : Array1D_string cNumericFields(NumNumbers);
244 22 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
245 : cCurrentModuleObject,
246 : ++designSpecNum,
247 : Alphas,
248 : NumAlphas,
249 : Numbers,
250 : NumNumbers,
251 : IOStatus,
252 : lNumericBlanks,
253 : lAlphaBlanks,
254 : cAlphaFields,
255 : cNumericFields);
256 : // **********************************************************************************************************
257 :
258 22 : auto const &fields = instance.value();
259 22 : std::string const &thisObjectName = instance.key();
260 22 : DesignSpecMSHP thisDesignSpec;
261 :
262 22 : thisDesignSpec.name = Util::makeUPPER(thisObjectName);
263 44 : thisDesignSpec.numOfSpeedHeating = fields.at("number_of_speeds_for_heating").get<int>(); // required field
264 22 : thisDesignSpec.numOfSpeedCooling = fields.at("number_of_speeds_for_cooling").get<int>(); // required field
265 22 : int maxSpeeds = max(thisDesignSpec.numOfSpeedHeating, thisDesignSpec.numOfSpeedCooling);
266 22 : thisDesignSpec.m_type = HVAC::UnitarySysType::Furnace_HeatOnly; // add global int value for factory
267 :
268 44 : if (auto it = fields.find("single_mode_operation"); it != fields.end()) { // not required field
269 22 : std::string loc_m_SingleModeOp = Util::makeUPPER(it.value().get<std::string>());
270 22 : if (Util::SameString(loc_m_SingleModeOp, "Yes")) thisDesignSpec.m_SingleModeFlag = true;
271 22 : }
272 :
273 44 : if (auto it = fields.find("no_load_supply_air_flow_rate_ratio"); it != fields.end()) { // not required field
274 7 : thisDesignSpec.noLoadAirFlowRateRatio = it.value().get<Real64>();
275 : }
276 :
277 22 : thisDesignSpec.heatingVolFlowRatio.resize(maxSpeeds + 1);
278 22 : thisDesignSpec.coolingVolFlowRatio.resize(maxSpeeds + 1);
279 :
280 22 : auto speedFlowRatios = fields.find("flow_ratios");
281 22 : if (speedFlowRatios != fields.end()) {
282 22 : auto &flowRatioArray = speedFlowRatios.value();
283 22 : int numSpeedInputs = flowRatioArray.size();
284 22 : if (numSpeedInputs >= maxSpeeds) {
285 22 : int speedNum = -1;
286 105 : for (auto const &flowRatio : flowRatioArray) {
287 83 : speedNum += 1;
288 83 : if (speedNum < (maxSpeeds + 1)) {
289 76 : auto &cobj = flowRatio.at("cooling_speed_supply_air_flow_ratio");
290 76 : thisDesignSpec.coolingVolFlowRatio[speedNum] =
291 118 : (cobj.type() == nlohmann::detail::value_t::string && Util::SameString(cobj.get<std::string>(), "Autosize"))
292 118 : ? DataSizing::AutoSize
293 34 : : cobj.get<Real64>();
294 :
295 76 : auto &hobj = flowRatio.at("heating_speed_supply_air_flow_ratio");
296 76 : thisDesignSpec.heatingVolFlowRatio[speedNum] =
297 118 : (hobj.type() == nlohmann::detail::value_t::string && Util::SameString(hobj.get<std::string>(), "Autosize"))
298 118 : ? DataSizing::AutoSize
299 34 : : hobj.get<Real64>();
300 : }
301 : }
302 : } else {
303 0 : ShowSevereError(state, format("{}: Error getting inputs for system named: {}", cCurrentModuleObject, thisObjectName));
304 0 : ShowContinueError(state,
305 0 : format("Number of speed inputs ({:.0T} is less than number of speeds ({:.0T}).",
306 0 : Real64(numSpeedInputs),
307 0 : Real64(maxSpeeds)));
308 0 : errorsFound = true;
309 : }
310 : }
311 22 : state.dataUnitarySystems->designSpecMSHP.push_back(thisDesignSpec);
312 22 : }
313 : }
314 22 : } // namespace UnitarySystems
315 :
316 133 : HVACSystemData *UnitarySys::factory(
317 : EnergyPlusData &state, HVAC::UnitarySysType const type, std::string const &objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
318 : {
319 133 : if (state.dataUnitarySystems->getInputOnceFlag) {
320 91 : UnitarySys::getUnitarySystemInput(state, objectName, ZoneEquipment, ZoneOAUnitNum);
321 91 : state.dataUnitarySystems->getInputOnceFlag = false;
322 : }
323 133 : int sysNum = -1;
324 152 : for (auto &sys : state.dataUnitarySystems->unitarySys) {
325 152 : ++sysNum;
326 152 : if (Util::SameString(sys.Name, objectName) && type == HVAC::UnitarySysType::Unitary_AnyCoilType) {
327 133 : state.dataUnitarySystems->unitarySys[sysNum].m_UnitarySysNum = sysNum;
328 133 : return &sys;
329 : }
330 : }
331 0 : ShowFatalError(state, format("UnitarySystem factory: Error getting inputs for system named: {}", objectName));
332 0 : return nullptr;
333 : }
334 :
335 49 : int getDesignSpecMSHPIndex(
336 : EnergyPlusData &state, // lookup vector index for design spec object name in object array EnergyPlus::UnitarySystems::designSpecMSHP
337 : std::string_view objectName // IDF name in input
338 : )
339 : {
340 49 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
341 0 : DesignSpecMSHP::getDesignSpecMSHP(state);
342 0 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
343 : }
344 49 : int index = -1;
345 51 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->designSpecMSHP.size(); ++loop) {
346 49 : DesignSpecMSHP *thisDesignSpecMSHPObjec = &state.dataUnitarySystems->designSpecMSHP[loop];
347 49 : if (Util::SameString(objectName, thisDesignSpecMSHPObjec->name)) {
348 47 : index = loop;
349 47 : return index;
350 : }
351 : }
352 2 : ShowSevereError(state, format("getDesignSpecMSHPIndex: did not find UnitarySystemPerformance:Multispeed name ={}. Check inputs", objectName));
353 2 : return index;
354 : }
355 :
356 406 : int getUnitarySystemIndex(
357 : EnergyPlusData &state, // lookup vector index for UnitarySystem object name in object array EnergyPlus::UnitarySystems::unitarySys
358 : std::string_view objectName // IDF name in input
359 : )
360 : {
361 406 : int index = -1;
362 705 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->unitarySys.size(); ++loop) {
363 503 : UnitarySys *thisUnitarySysObjec = &state.dataUnitarySystems->unitarySys[loop];
364 503 : if (Util::SameString(objectName, thisUnitarySysObjec->Name)) {
365 204 : index = loop;
366 204 : break;
367 : }
368 : }
369 406 : return index;
370 : }
371 :
372 72365 : void UnitarySys::initUnitarySystems(EnergyPlusData &state, int const AirLoopNum, bool const FirstHVACIteration, Real64 const OAUCoilOutTemp)
373 : {
374 : static constexpr std::string_view routineName("InitUnitarySystems");
375 :
376 : // only access for zone equipment, UnitaySystem does not yet have input for Availability Manager List Name
377 151809 : if (this->m_IsZoneEquipment &&
378 79345 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
379 6980 : !state.dataAvail->ZoneComp.empty()) {
380 : // need to move to better location and save thisObjectIndex and thisObjectType in struct
381 : // this->m_EquipCompNum is by parent type, not total UnitarySystems
382 : // e.g., PTAC = 1,2,3; PTHP = 1,2; PTWSHP = 1,2,3,4; UnitarySystems = 9 total
383 6966 : DataZoneEquipment::ZoneEquipType thisObjectType = DataZoneEquipment::ZoneEquipType::Invalid;
384 6966 : switch (this->m_sysType) {
385 18 : case SysType::PackagedAC:
386 18 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
387 18 : break;
388 0 : case SysType::PackagedHP:
389 0 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump;
390 0 : break;
391 6948 : case SysType::PackagedWSHP:
392 6948 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir;
393 6948 : break;
394 0 : default:
395 0 : break;
396 : }
397 6966 : if (this->m_ZoneCompFlag) {
398 8 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).AvailManagerListName = this->m_AvailManagerListName;
399 8 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).ZoneNum = this->ControlZoneNum;
400 8 : this->m_ZoneCompFlag = false;
401 : }
402 6966 : this->m_AvailStatus = state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).availStatus;
403 : }
404 :
405 : // sizing does not execute until SysSizing is complete. This means we may not know plant connections for zone equipment.
406 : // when adding ((this->m_IsZoneEquipment && !state.dataGlobal->SysSizingCalc) || ()) here, eio gets out of sorts
407 72365 : if (!state.dataGlobal->SysSizingCalc && this->m_MySizingCheckFlag && !this->m_ThisSysInputShouldBeGotten) {
408 53 : if (AirLoopNum > 0) {
409 18 : if (this->m_FanExists && (this->m_CoolCoilExists && (this->m_HeatCoilExists || this->m_SuppCoilExists)))
410 1 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
411 18 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
412 18 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
413 2 : DXCoils::SetCoilSystemCoolingData(state, this->m_CoolingCoilName, this->Name);
414 : }
415 : // associates an air loop fan on main branch with a coil on main branch where parent does not have a fan
416 18 : if (!this->m_FanExists) {
417 17 : if (state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanType != HVAC::FanType::Invalid) {
418 15 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
419 15 : if (this->m_CoolCoilExists) {
420 15 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
421 : state,
422 15 : this->m_CoolingCoilName,
423 15 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
424 15 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
425 15 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
426 : primaryAirSystems.supFanNum);
427 : }
428 15 : if (this->m_HeatCoilExists) {
429 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
430 : state,
431 0 : this->m_HeatingCoilName,
432 0 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
433 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
434 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
435 : primaryAirSystems.supFanNum);
436 : }
437 15 : if (this->m_SuppCoilExists) {
438 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
439 : state,
440 0 : this->m_SuppHeatCoilName,
441 0 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
442 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
443 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
444 : primaryAirSystems.supFanNum);
445 : }
446 : }
447 : }
448 : }
449 53 : this->sizeSystem(state, FirstHVACIteration, AirLoopNum);
450 53 : this->m_MySizingCheckFlag = false;
451 53 : if (AirLoopNum > 0) {
452 18 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = this->m_FanOpMode;
453 18 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).cycFanSched = this->m_fanOpModeSched;
454 35 : } else if (AirLoopNum < 0) {
455 1 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
456 0 : ShowSevereError(state, format("{}: {}", this->UnitType, this->Name));
457 0 : ShowContinueError(state, " Invalid application of Control Type = SingleZoneVAV in outdoor air system.");
458 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
459 : }
460 : }
461 : }
462 :
463 72365 : if (this->m_MyFanFlag) { // should include " && !this->m_MySizingCheckFlag"
464 98 : if (this->m_ActualFanVolFlowRate != DataSizing::AutoSize) {
465 57 : if (this->m_ActualFanVolFlowRate > 0.0) {
466 57 : this->m_HeatingFanSpeedRatio = this->m_MaxHeatAirVolFlow / this->m_ActualFanVolFlowRate;
467 57 : this->m_CoolingFanSpeedRatio = this->m_MaxCoolAirVolFlow / this->m_ActualFanVolFlowRate;
468 57 : this->m_NoHeatCoolSpeedRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
469 57 : if (this->m_FanExists && !this->m_MultiOrVarSpeedHeatCoil && !this->m_MultiOrVarSpeedCoolCoil) {
470 21 : bool fanHasPowerSpeedRatioCurve = false;
471 21 : if (this->m_FanType == HVAC::FanType::SystemModel) {
472 1 : if (dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex))->powerModFuncFlowFracCurveNum > 0)
473 0 : fanHasPowerSpeedRatioCurve = true;
474 : } else {
475 20 : if (dynamic_cast<Fans::FanComponent *>(state.dataFans->fans(this->m_FanIndex))->powerRatioAtSpeedRatioCurveNum > 0)
476 0 : fanHasPowerSpeedRatioCurve = true;
477 : }
478 21 : if (fanHasPowerSpeedRatioCurve) {
479 :
480 0 : if (this->m_ActualFanVolFlowRate == this->m_MaxHeatAirVolFlow &&
481 0 : this->m_ActualFanVolFlowRate == this->m_MaxCoolAirVolFlow &&
482 0 : this->m_ActualFanVolFlowRate == this->m_MaxNoCoolHeatAirVolFlow) {
483 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
484 0 : ShowContinueError(
485 0 : state, format("...For fan type and name = {} \"{}\"", HVAC::fanTypeNames[(int)this->m_FanType], this->m_FanName));
486 0 : ShowContinueError(state,
487 : "...Fan power ratio function of speed ratio curve has no impact if fan volumetric flow rate is the "
488 : "same as the unitary system volumetric flow rate.");
489 0 : ShowContinueError(state,
490 0 : format("...Fan volumetric flow rate = {:.5R} m3/s.", this->m_ActualFanVolFlowRate));
491 0 : ShowContinueError(state, format("...Unitary system volumetric flow rate = {:.5R} m3/s.", this->m_MaxHeatAirVolFlow));
492 : }
493 : }
494 : }
495 57 : if (this->m_MultiOrVarSpeedHeatCoil || this->m_MultiOrVarSpeedCoolCoil) {
496 20 : if (this->m_MultiOrVarSpeedCoolCoil) {
497 14 : int NumSpeeds = this->m_NumOfSpeedCooling;
498 14 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(NumSpeeds + 1);
499 14 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(NumSpeeds + 1);
500 77 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
501 63 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
502 : }
503 : }
504 20 : if (this->m_MultiOrVarSpeedHeatCoil) {
505 12 : int NumSpeeds = this->m_NumOfSpeedHeating;
506 12 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(NumSpeeds + 1);
507 12 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(NumSpeeds + 1);
508 61 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
509 49 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
510 : }
511 : }
512 20 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
513 : }
514 : }
515 57 : this->m_MyFanFlag = false;
516 : } else {
517 41 : if (this->m_FanExists) {
518 41 : this->m_ActualFanVolFlowRate = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
519 : }
520 : // do not set false this->m_MyFanFlag so that next pass specific initialization and warning are executed
521 : }
522 : }
523 :
524 : // Scan hot water and steam heating coil plant components for one time initializations
525 72365 : if (this->m_MyPlantScanFlag && !state.dataPlnt->PlantLoop.empty()) {
526 28 : if (this->m_HeatRecActive) {
527 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
528 0 : PlantUtilities::ScanPlantLoopsForObject(state,
529 : this->Name,
530 : DataPlant::PlantEquipmentType::UnitarySysRecovery,
531 0 : this->m_HRPlantLoc,
532 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
533 : _,
534 : _,
535 : _,
536 : _,
537 : _);
538 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
539 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
540 : }
541 : }
542 28 : DataPlant::PlantEquipmentType TypeOfCoilWaterCooling{DataPlant::PlantEquipmentType::Invalid};
543 28 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed ||
544 22 : this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
545 12 : std::string CoolingCoilType = "";
546 6 : std::string CoolingCoilName = "";
547 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
548 6 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
549 6 : CoolingCoilType = "Coil:Cooling:Water";
550 6 : CoolingCoilName = this->m_CoolingCoilName;
551 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
552 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
553 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
554 0 : CoolingCoilName = this->m_CoolingCoilName;
555 : } else {
556 : TypeOfCoilWaterCooling = static_cast<DataPlant::PlantEquipmentType>(
557 0 : HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(state,
558 0 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
559 0 : this->m_CoolingCoilName,
560 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
561 : true));
562 0 : if (TypeOfCoilWaterCooling == static_cast<DataPlant::PlantEquipmentType>(HVAC::Coil_CoolingWater)) {
563 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
564 0 : CoolingCoilType = "Coil:Cooling:Water";
565 0 : } else if (TypeOfCoilWaterCooling == static_cast<DataPlant::PlantEquipmentType>(HVAC::Coil_CoolingWaterDetailed)) {
566 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
567 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
568 : }
569 0 : CoolingCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(state,
570 0 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
571 0 : this->m_CoolingCoilName,
572 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag);
573 : }
574 6 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
575 12 : PlantUtilities::ScanPlantLoopsForObject(state,
576 : CoolingCoilName,
577 : TypeOfCoilWaterCooling,
578 6 : this->CoolCoilPlantLoc,
579 6 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
580 : _,
581 : _,
582 : _,
583 : _,
584 : _);
585 6 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
586 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
587 : }
588 6 : this->MaxCoolCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
589 6 : state, CoolingCoilType, CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
590 :
591 6 : if (this->MaxCoolCoilFluidFlow > 0.0) {
592 : Real64 rho =
593 6 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
594 6 : this->MaxCoolCoilFluidFlow *= rho;
595 : }
596 : // fill outlet node for coil
597 6 : this->CoolCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->CoolCoilPlantLoc).NodeNumOut;
598 6 : }
599 28 : DataPlant::PlantEquipmentType TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::Invalid;
600 28 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
601 2 : std::string HeatingCoilType = "";
602 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
603 2 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
604 2 : HeatingCoilType = "Coil:Heating:Water";
605 : // this doesn't work good here, sizing may not have executed yet
606 : // air loops seem to work OK, zone equipment not so much, this->m_MaxHeatAirVolFlow = -99999.0
607 : // moved to sizing but left this original call
608 2 : WaterCoils::SetCoilDesFlow(state,
609 2 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
610 2 : this->m_HeatingCoilName,
611 : this->m_MaxHeatAirVolFlow,
612 2 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
613 : } else {
614 0 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
615 0 : HeatingCoilType = "Coil:Heating:Steam";
616 : }
617 2 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
618 4 : PlantUtilities::ScanPlantLoopsForObject(state,
619 : this->m_HeatingCoilName,
620 : TypeOfCoilWaterHeating,
621 2 : this->HeatCoilPlantLoc,
622 2 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
623 : _,
624 : _,
625 : _,
626 : _,
627 : _);
628 2 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
629 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
630 : }
631 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
632 2 : this->MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
633 2 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
634 :
635 2 : if (this->MaxHeatCoilFluidFlow > 0.0) {
636 2 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
637 2 : .glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
638 2 : this->MaxHeatCoilFluidFlow =
639 2 : WaterCoils::GetCoilMaxWaterFlowRate(
640 4 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
641 : rho;
642 : }
643 : } else {
644 0 : this->MaxHeatCoilFluidFlow =
645 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
646 0 : if (this->MaxHeatCoilFluidFlow > 0.0) {
647 0 : Real64 TempSteamIn = 100.0;
648 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
649 0 : this->MaxHeatCoilFluidFlow *= SteamDensity;
650 : }
651 : }
652 : // fill outlet node for coil
653 2 : this->HeatCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->HeatCoilPlantLoc).NodeNumOut;
654 2 : }
655 :
656 28 : this->m_MyPlantScanFlag = false;
657 72337 : } else if (this->m_MyPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
658 41 : this->m_MyPlantScanFlag = false;
659 : }
660 :
661 : // Scan Supplemental hot water and steam heating coil plant components for one time initializations
662 72365 : if (this->m_MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
663 42 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
664 1 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
665 2 : PlantUtilities::ScanPlantLoopsForObject(state,
666 : this->m_SuppHeatCoilName,
667 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
668 1 : this->m_SuppCoilPlantLoc,
669 1 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
670 : _,
671 : _,
672 : _,
673 : _,
674 : _);
675 1 : WaterCoils::SetCoilDesFlow(state,
676 1 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
677 1 : this->m_SuppHeatCoilName,
678 : this->m_MaxHeatAirVolFlow,
679 1 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
680 :
681 1 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
682 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
683 : }
684 1 : this->m_MaxSuppCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
685 1 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
686 :
687 1 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
688 : Real64 rho =
689 1 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
690 1 : this->m_MaxSuppCoilFluidFlow =
691 1 : WaterCoils::GetCoilMaxWaterFlowRate(
692 2 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
693 : rho;
694 : }
695 : // fill outlet node for coil
696 1 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
697 :
698 41 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
699 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
700 0 : PlantUtilities::ScanPlantLoopsForObject(state,
701 : this->m_SuppHeatCoilName,
702 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
703 0 : this->m_SuppCoilPlantLoc,
704 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
705 : _,
706 : _,
707 : _,
708 : _,
709 : _);
710 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
711 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
712 : }
713 0 : this->m_MaxSuppCoilFluidFlow =
714 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
715 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
716 0 : Real64 TempSteamIn = 100.0;
717 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
718 0 : this->m_MaxSuppCoilFluidFlow *= SteamDensity;
719 : }
720 :
721 : // fill outlet node for coil
722 0 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
723 : }
724 :
725 42 : this->m_MySuppCoilPlantScanFlag = false;
726 :
727 72323 : } else if (this->m_MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
728 27 : this->m_MySuppCoilPlantScanFlag = false;
729 : }
730 :
731 : // do the Begin Environment initializations
732 72365 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag) {
733 107 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
734 107 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
735 107 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
736 107 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
737 107 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
738 107 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
739 107 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
740 107 : if (this->OAMixerExists) {
741 2 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMax = max(this->m_CoolOutAirMassFlow, this->m_HeatOutAirMassFlow);
742 2 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMin = 0.0;
743 2 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMinAvail = 0.0;
744 : }
745 107 : this->m_CompPartLoadRatio = 0.0;
746 107 : this->m_CoolingCoilSensDemand = 0.0;
747 107 : this->m_CoolingCoilLatentDemand = 0.0;
748 107 : this->m_HeatingCoilSensDemand = 0.0;
749 107 : this->m_SenLoadLoss = 0.0;
750 107 : if (this->m_Humidistat) {
751 4 : this->m_LatLoadLoss = 0.0;
752 : }
753 :
754 107 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
755 :
756 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, routineName);
757 :
758 0 : this->m_DesignHeatRecMassFlowRate = this->m_DesignHRWaterVolumeFlow * rho;
759 :
760 0 : PlantUtilities::InitComponentNodes(
761 : state, 0.0, this->m_DesignHeatRecMassFlowRate, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
762 : }
763 : // set fluid-side hardware limits
764 107 : if (this->CoolCoilFluidInletNode > 0) {
765 :
766 3 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
767 : // If water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
768 0 : std::string CoolingCoilType = "";
769 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
770 0 : CoolingCoilType = "Coil:Cooling:Water";
771 : } else {
772 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
773 : }
774 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex);
775 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
776 0 : state, CoolingCoilType, this->m_CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
777 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
778 0 : Real64 rho = state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum)
779 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
780 0 : this->MaxCoolCoilFluidFlow = CoilMaxVolFlowRate * rho;
781 : }
782 0 : }
783 :
784 3 : PlantUtilities::InitComponentNodes(
785 : state, 0.0, this->MaxCoolCoilFluidFlow, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum);
786 : }
787 107 : if (this->HeatCoilFluidInletNode > 0) {
788 :
789 2 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
790 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
791 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
792 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
793 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
794 0 : state, "Coil:Heating:Water", this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
795 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
796 0 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
797 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
798 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
799 : }
800 : }
801 : // If steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
802 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
803 0 : SteamCoils::SimulateSteamCoilComponents(
804 : state,
805 : this->m_HeatingCoilName,
806 : FirstHVACIteration,
807 0 : this->m_HeatingCoilIndex,
808 0 : 1.0,
809 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity
810 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(
811 0 : state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
812 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
813 0 : Real64 TempSteamIn = 100.0;
814 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
815 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
816 : }
817 : }
818 : }
819 :
820 2 : PlantUtilities::InitComponentNodes(
821 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
822 : }
823 107 : if (this->m_SuppCoilFluidInletNode > 0) {
824 1 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
825 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
826 : // If water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
827 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
828 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
829 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
830 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
831 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum)
832 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
833 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
834 : }
835 : }
836 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
837 0 : SteamCoils::SimulateSteamCoilComponents(
838 : state,
839 : this->m_SuppHeatCoilName,
840 : FirstHVACIteration,
841 0 : this->m_SuppHeatCoilIndex,
842 0 : 1.0,
843 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity
844 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(
845 0 : state, this->m_SuppHeatCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
846 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
847 0 : Real64 TempSteamIn = 100.0;
848 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
849 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
850 : }
851 : }
852 0 : PlantUtilities::InitComponentNodes(
853 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
854 : }
855 : }
856 107 : this->m_MyEnvrnFlag = false;
857 : }
858 :
859 72365 : if (!state.dataGlobal->BeginEnvrnFlag) {
860 71622 : this->m_MyEnvrnFlag = true;
861 : }
862 :
863 : // Init maximum available Heat Recovery flow rate
864 72365 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
865 1 : Real64 mdotHR = 0.0;
866 1 : if (this->m_sysAvailSched->getCurrentVal() > 0.0) {
867 1 : if (FirstHVACIteration) {
868 1 : mdotHR = this->m_DesignHeatRecMassFlowRate;
869 : } else {
870 0 : if (this->m_HeatRecoveryMassFlowRate > 0.0) {
871 0 : mdotHR = this->m_HeatRecoveryMassFlowRate;
872 : } else {
873 0 : mdotHR = this->m_DesignHeatRecMassFlowRate;
874 : }
875 : }
876 : } else {
877 0 : mdotHR = 0.0;
878 : }
879 :
880 1 : mdotHR = min(state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).MassFlowRateMaxAvail, mdotHR);
881 1 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate = mdotHR;
882 : }
883 :
884 : // get operating capacity of water and steam coil
885 72365 : if (FirstHVACIteration || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
886 35871 : if (FirstHVACIteration) {
887 35859 : this->m_IterationCounter = 0;
888 35859 : std::fill(this->m_IterationMode.begin(), this->m_IterationMode.end(), 0);
889 :
890 : // for systems without a fan, just read the inlet node flow rate and let air loop decide flow
891 35859 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint && this->m_sysType == SysType::Unitary && this->m_FanExists) {
892 1 : if (this->m_sysAvailSched->getCurrentVal() > 0.0) {
893 1 : if (this->m_LastMode == CoolingMode) {
894 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
895 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
896 : } else {
897 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxCoolAirMassFlow;
898 : }
899 1 : } else if (this->m_LastMode == HeatingMode) {
900 0 : if (this->m_MultiOrVarSpeedHeatCoil) {
901 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_HeatMassFlowRate[this->m_NumOfSpeedHeating];
902 : } else {
903 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxHeatAirMassFlow;
904 : }
905 : } else {
906 1 : if (this->m_MultiOrVarSpeedCoolCoil) {
907 1 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
908 : } else {
909 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
910 : }
911 : }
912 : } else {
913 0 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = 0.0;
914 : }
915 : }
916 35859 : if (this->m_WaterHRPlantLoopModel) {
917 : // initialize loop water temp on FirstHVACIteration
918 2 : Real64 airInTemp = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp;
919 2 : Real64 companionAirInTemp = state.dataLoopNodes->Node(this->m_HRcoolCoilAirInNode).Temp;
920 2 : Real64 oneHalfAirDeltaT = (companionAirInTemp - airInTemp) / 2.0;
921 2 : Real64 initialLoopTemp = airInTemp + oneHalfAirDeltaT;
922 2 : if (initialLoopTemp > this->m_minWaterLoopTempForHR && std::abs(oneHalfAirDeltaT) > this->m_minAirToWaterTempOffset) {
923 2 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp = initialLoopTemp;
924 2 : this->temperatureOffsetControlStatus = 1;
925 : } else {
926 0 : this->temperatureOffsetControlStatus = 0;
927 : }
928 : }
929 : }
930 35871 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
931 :
932 : // set water-side mass flow rates
933 13 : Real64 mdot = this->MaxCoolCoilFluidFlow;
934 13 : PlantUtilities::SetComponentFlowRate(
935 13 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
936 : // simulate water coil to find operating capacity
937 26 : WaterCoils::SimulateWaterCoilComponents(state,
938 : this->m_CoolingCoilName,
939 : FirstHVACIteration,
940 13 : this->m_CoolingCoilIndex,
941 13 : state.dataUnitarySystems->initUnitarySystemsQActual);
942 13 : this->m_DesignCoolingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
943 :
944 : } // from IF(UnitarySystem(UnitarySysNum)%CoolingCoilType_Num == Coil_CoolingWater .OR. Coil_CoolingWaterDetailed
945 35871 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
946 :
947 : // set water-side mass flow rates
948 1 : Real64 mdot = this->MaxHeatCoilFluidFlow;
949 1 : PlantUtilities::SetComponentFlowRate(
950 1 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
951 : // simulate water coil to find operating capacity
952 2 : WaterCoils::SimulateWaterCoilComponents(state,
953 : this->m_HeatingCoilName,
954 : FirstHVACIteration,
955 1 : this->m_HeatingCoilIndex,
956 1 : state.dataUnitarySystems->initUnitarySystemsQActual);
957 1 : this->m_DesignHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
958 :
959 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingWater) THEN
960 :
961 35871 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
962 :
963 : // set water-side mass flow rates
964 0 : Real64 mdot = this->MaxHeatCoilFluidFlow;
965 0 : PlantUtilities::SetComponentFlowRate(
966 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
967 : // simulate steam coil to find operating capacity
968 0 : SteamCoils::SimulateSteamCoilComponents(
969 : state,
970 : this->m_HeatingCoilName,
971 : FirstHVACIteration,
972 0 : this->m_HeatingCoilIndex,
973 0 : 1.0,
974 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
975 0 : this->m_DesignHeatingCapacity = SteamCoils::GetCoilCapacity(state,
976 0 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
977 0 : this->m_HeatingCoilName,
978 0 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
979 :
980 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
981 35871 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
982 :
983 : // set steam-side mass flow rates
984 1 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
985 1 : PlantUtilities::SetComponentFlowRate(
986 1 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
987 : // simulate water coil to find operating capacity
988 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
989 : // speed issue where coil doesn't need to be simulation if mdot=0.
990 2 : WaterCoils::SimulateWaterCoilComponents(state,
991 : this->m_SuppHeatCoilName,
992 : FirstHVACIteration,
993 1 : this->m_SuppHeatCoilIndex,
994 1 : state.dataUnitarySystems->initUnitarySystemsQActual);
995 1 : this->m_DesignSuppHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
996 : } else {
997 0 : this->m_DesignSuppHeatingCapacity = 0.0;
998 : }
999 :
1000 : } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingWater) THEN
1001 :
1002 35871 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
1003 :
1004 : // set air-side and steam-side mass flow rates
1005 0 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
1006 0 : PlantUtilities::SetComponentFlowRate(
1007 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1008 : // simulate steam coil to find operating capacity
1009 0 : SteamCoils::SimulateSteamCoilComponents(
1010 : state,
1011 : this->m_SuppHeatCoilName,
1012 : FirstHVACIteration,
1013 0 : this->m_SuppHeatCoilIndex,
1014 0 : 1.0,
1015 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1016 0 : this->m_DesignSuppHeatingCapacity = SteamCoils::GetCoilCapacity(
1017 0 : state, "Coil:Heating:Steam", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
1018 :
1019 : } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN
1020 : } // from IF( FirstHVACIteration ) THEN
1021 :
1022 72365 : this->m_IterationCounter += 1;
1023 :
1024 72365 : if (this->m_MySetPointCheckFlag) {
1025 183 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACGlobal->DoSetPointTest) {
1026 33 : bool e = false;
1027 33 : if (this->m_CoolCoilExists) e = this->checkNodeSetPoint(state, AirLoopNum, this->CoolCtrlNode, CoolingCoil, OAUCoilOutTemp);
1028 33 : if (this->m_HeatCoilExists) e = this->checkNodeSetPoint(state, AirLoopNum, this->HeatCtrlNode, HeatingCoil, OAUCoilOutTemp) || e;
1029 33 : if (this->m_SuppCoilExists) e = this->checkNodeSetPoint(state, AirLoopNum, this->SuppCtrlNode, SuppHeatCoil, OAUCoilOutTemp) || e;
1030 33 : if (e) ShowFatalError(state, "Previous errors cause termination.");
1031 33 : this->m_MySetPointCheckFlag = false;
1032 : }
1033 : }
1034 :
1035 72365 : if (m_setFaultModelInput) {
1036 34487 : if ((!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
1037 :
1038 : // check FaultsManager if connection exists
1039 64 : FaultsManager::SetFaultyCoilSATSensor(state, this->UnitType, this->Name, this->m_FaultyCoilSATFlag, this->m_FaultyCoilSATIndex);
1040 64 : if (this->m_FaultyCoilSATFlag) {
1041 0 : if (this->m_ControlType != UnitarySysCtrlType::Setpoint) {
1042 0 : ShowWarningError(state,
1043 0 : format("{}: {}",
1044 0 : state.dataFaultsMgr->FaultsCoilSATSensor(this->m_FaultyCoilSATIndex).type,
1045 0 : state.dataFaultsMgr->FaultsCoilSATSensor(this->m_FaultyCoilSATIndex).Name));
1046 0 : ShowContinueError(state, format("For : {}: {}", this->UnitType, this->Name));
1047 0 : ShowContinueError(state,
1048 : "The specified unitary system is not controlled on leaving air temperature. The coil SAT sensor "
1049 : "fault model will not be applied.");
1050 0 : this->m_FaultyCoilSATFlag = false;
1051 : }
1052 : }
1053 64 : m_setFaultModelInput = false;
1054 : }
1055 : }
1056 :
1057 : // re-set water-side economizer flags each time step
1058 72365 : if (this->m_TemperatureOffsetControlActive && !this->m_WaterHRPlantLoopModel) {
1059 5 : if (state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp >
1060 5 : (state.dataLoopNodes->Node(this->AirInNode).Temp - this->m_minAirToWaterTempOffset)) {
1061 : // disable coilsystem if entering fluid temp is > entering air temp minus user specified temp offset
1062 2 : this->temperatureOffsetControlStatus = 0;
1063 : } else {
1064 : // enable coilsystem waterside economizer mode
1065 3 : this->temperatureOffsetControlStatus = 1;
1066 : }
1067 : }
1068 72365 : if (AirLoopNum > 0) {
1069 50720 : if (this->m_sysType == SysType::CoilCoolingWater) {
1070 7 : if (this->m_waterSideEconomizerFlag) { // CoilSystem:Cooling:Water has an input for economizer lockout
1071 7 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1072 7 : if (state.dataUnitarySystems->economizerFlag) {
1073 : // user input economizer lockout will disable heat recovery loop AND water economizer
1074 2 : this->temperatureOffsetControlStatus = 0;
1075 : }
1076 : } else {
1077 0 : state.dataUnitarySystems->economizerFlag = false;
1078 : }
1079 : } else {
1080 50713 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1081 : }
1082 : // get OA controller info
1083 50720 : this->OASysIndex = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).OASysNum;
1084 50720 : if (this->OASysIndex > 0) {
1085 50696 : this->OAControllerIndex = state.dataAirLoop->OutsideAirSys(this->OASysIndex).OAControllerIndex;
1086 50696 : if (this->OAControllerIndex > 0) {
1087 50696 : this->OAControllerEconomizerStagingType = state.dataMixedAir->OAController(this->OAControllerIndex).EconomizerStagingType;
1088 : }
1089 : }
1090 : }
1091 :
1092 72365 : this->m_CoolingPartLoadFrac = 0.0;
1093 72365 : this->m_HeatingPartLoadFrac = 0.0;
1094 72365 : this->m_SuppHeatPartLoadFrac = 0.0;
1095 72365 : this->m_CoolingCycRatio = 0.0;
1096 72365 : this->m_CoolingSpeedRatio = 0.0;
1097 72365 : this->m_CoolingSpeedNum = 0;
1098 72365 : this->m_HeatingCycRatio = 0.0;
1099 72365 : this->m_HeatingSpeedRatio = 0.0;
1100 72365 : this->m_HeatingSpeedNum = 0;
1101 72365 : this->m_SuppHeatingSpeedNum = 0;
1102 72365 : this->m_HeatingCoilSensDemand = 0.0;
1103 72365 : this->m_CoolingCoilSensDemand = 0.0;
1104 72365 : this->m_CoolingCoilLatentDemand = 0.0;
1105 72365 : this->m_DehumidInducedHeatingDemandRate = 0.0;
1106 72365 : this->CoolCoilWaterFlowRatio = 0.0;
1107 72365 : this->HeatCoilWaterFlowRatio = 0.0;
1108 :
1109 : // water/steam coil initialization
1110 72365 : if (this->CoolCoilFluidInletNode > 0) {
1111 28 : Real64 mdot = 0.0;
1112 28 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
1113 : }
1114 72365 : if (this->HeatCoilFluidInletNode > 0) {
1115 15 : Real64 mdot = 0.0;
1116 15 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
1117 : }
1118 72365 : if (this->m_SuppCoilFluidInletNode > 0) {
1119 4 : Real64 mdot = 0.0;
1120 4 : PlantUtilities::SetComponentFlowRate(
1121 4 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1122 : }
1123 :
1124 72365 : this->m_InitHeatPump = true;
1125 72365 : state.dataUnitarySystems->m_massFlow1 = 0.0;
1126 72365 : state.dataUnitarySystems->m_massFlow2 = 0.0;
1127 72365 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
1128 72365 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
1129 72365 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1130 : // this should be done in the child. DXElecHeatingPower not reset to 0 if coil is off, ZoneSysAvailManager
1131 : // zero the fan and DX coils electricity consumption
1132 6980 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
1133 6980 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
1134 6980 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
1135 6980 : state.dataHVACGlobal->DefrostElecPower = 0.0;
1136 : }
1137 72365 : }
1138 :
1139 45 : bool UnitarySys::checkNodeSetPoint(EnergyPlusData &state,
1140 : int const AirLoopNum, // number of the current air loop being simulated
1141 : int const ControlNode, // Node to test for set point
1142 : int const CoilType, // True if cooling coil, then test for HumRatMax set point
1143 : Real64 const OAUCoilOutTemp // the coil inlet temperature of OutdoorAirUnit
1144 : )
1145 : {
1146 :
1147 : // SUBROUTINE INFORMATION:
1148 : // AUTHOR Richard Raustad
1149 : // DATE WRITTEN March 2013
1150 :
1151 : // PURPOSE OF THIS SUBROUTINE:
1152 : // This subroutine checks for proper set point at control node.
1153 : constexpr static std::array<std::string_view, 3> coilTypes = {"cooling", "heating", "supplemental"};
1154 45 : bool SetPointErrorFlag = false;
1155 :
1156 45 : if (ControlNode == 0) {
1157 8 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1158 1 : int coilOutNode = this->CoolCoilOutletNodeNum;
1159 1 : if (CoilType == HeatingCoil) coilOutNode = this->HeatCoilOutletNodeNum;
1160 1 : if (CoilType == SuppHeatCoil) coilOutNode = this->SuppCoilOutletNodeNum;
1161 :
1162 1 : ShowSevereError(state, format("checkNodeSetPoint: Missing {} set point in {} = {}", coilTypes[CoilType], this->UnitType, this->Name));
1163 2 : ShowContinueError(state,
1164 3 : format("...Setpoint is required at system air outlet node = {} or {} coil air outlet node = {}",
1165 1 : state.dataLoopNodes->NodeID(this->AirOutNode),
1166 1 : coilTypes[CoilType],
1167 1 : state.dataLoopNodes->NodeID(coilOutNode)));
1168 1 : SetPointErrorFlag = true;
1169 : }
1170 8 : return SetPointErrorFlag;
1171 : }
1172 :
1173 37 : if (AirLoopNum == -1) { // Outdoor Air Unit
1174 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint = OAUCoilOutTemp; // Set the coil outlet temperature
1175 0 : if (this->m_ISHundredPercentDOASDXCoil) {
1176 0 : this->frostControlSetPointLimit(state,
1177 0 : this->m_DesiredOutletTemp,
1178 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
1179 0 : state.dataEnvrn->OutBaroPress,
1180 : this->DesignMinOutletTemp,
1181 : 1);
1182 : }
1183 : } else { // Not an Outdoor air unit
1184 :
1185 37 : if (state.dataLoopNodes->Node(ControlNode).TempSetPoint == DataLoopNode::SensedNodeFlagValue &&
1186 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1187 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1188 0 : ShowSevereError(state, format("{}: Missing temperature setpoint for unitary system = {}", this->UnitType, this->Name));
1189 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1190 0 : SetPointErrorFlag = true;
1191 : } else {
1192 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, ControlNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
1193 0 : if (SetPointErrorFlag) {
1194 0 : ShowSevereError(state, format("{}: Missing temperature setpoint for unitary system = {}", this->UnitType, this->Name));
1195 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1196 0 : ShowContinueError(state, " or use an EMS actuator to establish a temperature setpoint at the coil control node.");
1197 : }
1198 : }
1199 : }
1200 75 : if ((this->m_DehumidControlType_Num != DehumCtrlType::None) &&
1201 1 : (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) &&
1202 38 : this->m_ControlType == UnitarySysCtrlType::Setpoint && CoilType == CoolingCoil) {
1203 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel &&
1204 0 : state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
1205 0 : ShowSevereError(state,
1206 0 : format("{}: Missing humidity ratio setpoint (HUMRATMAX) for unitary system = {}", this->UnitType, this->Name));
1207 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1208 0 : SetPointErrorFlag = true;
1209 0 : } else if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
1210 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, ControlNode, HVAC::CtrlVarType::MaxHumRat, SetPointErrorFlag);
1211 0 : if (SetPointErrorFlag) {
1212 0 : ShowSevereError(
1213 : state,
1214 0 : format("{}: Missing maximum humidity ratio setpoint (HUMRATMAX) for unitary system = {}", this->UnitType, this->Name));
1215 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1216 0 : ShowContinueError(state, " or use an EMS actuator to establish a maximum humidity ratio setpoint.");
1217 : }
1218 : }
1219 : }
1220 : }
1221 37 : return SetPointErrorFlag; // these later errors will also cause a fatal error
1222 : }
1223 :
1224 0 : void UnitarySys::frostControlSetPointLimit(EnergyPlusData &state,
1225 : Real64 &TempSetPoint, // temperature setpoint of the sensor node
1226 : Real64 &HumRatSetPoint, // humidity ratio setpoint of the sensor node
1227 : Real64 const BaroPress, // barometric pressure, Pa [N/m^2]
1228 : Real64 const TfrostControl, // minimum temperature limit for frost control
1229 : int const ControlMode // temperature or humidity control mode
1230 : )
1231 : {
1232 :
1233 : // SUBROUTINE INFORMATION:
1234 : // AUTHOR Bereket Nigusse, FSEC
1235 : // DATE WRITTEN January 2013
1236 :
1237 : // PURPOSE OF THIS SUBROUTINE:
1238 : // Controls the frost formation condition based on user specified minimum DX coil outlet
1239 : // air temperature. Resets the cooling setpoint based on the user specified limiting
1240 : // temperature for frost control.
1241 :
1242 : // SUBROUTINE PARAMETER DEFINITIONS:
1243 0 : int constexpr RunOnSensible(1); // identifier for temperature (sensible load) control
1244 0 : int constexpr RunOnLatent(2); // identifier for humidity (latent load) control
1245 : static constexpr std::string_view routineName("FrostControlSetPointLimit");
1246 :
1247 0 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate;
1248 0 : if (ControlMode == RunOnSensible && AirMassFlow > HVAC::SmallAirVolFlow &&
1249 0 : TempSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp) {
1250 0 : if (TempSetPoint < TfrostControl) {
1251 0 : TempSetPoint = TfrostControl;
1252 0 : this->m_FrostControlStatus = 1;
1253 : }
1254 0 : } else if (ControlMode == RunOnLatent && AirMassFlow > HVAC::SmallAirVolFlow &&
1255 0 : HumRatSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat) {
1256 0 : Real64 HumRatioSat = Psychrometrics::PsyWFnTdpPb(state, TfrostControl, BaroPress, routineName);
1257 0 : if (HumRatioSat > HumRatSetPoint) {
1258 0 : HumRatSetPoint = HumRatioSat;
1259 0 : this->m_FrostControlStatus = 2;
1260 : }
1261 : } else {
1262 0 : this->m_FrostControlStatus = 0;
1263 : }
1264 0 : }
1265 :
1266 136 : void UnitarySys::getUnitarySystemInput(EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
1267 : {
1268 :
1269 136 : bool errorsFound(false);
1270 136 : UnitarySys::allocateUnitarySys(state);
1271 :
1272 136 : UnitarySys::getDXCoilSystemData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1273 136 : UnitarySys::getCoilWaterSystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1274 136 : UnitarySys::getPackagedTerminalUnitData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1275 136 : UnitarySys::getUnitarySystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1276 :
1277 136 : if (errorsFound) {
1278 0 : ShowFatalError(state, "getUnitarySystemInputData: previous errors cause termination. Check inputs");
1279 : }
1280 :
1281 : // all systems should have been processed at this point? I think so, so don't need to if test this call?
1282 272 : if (int(state.dataUnitarySystems->unitarySys.size()) == state.dataUnitarySystems->numUnitarySystems &&
1283 136 : state.dataZoneEquip->ZoneEquipInputsFilled) {
1284 71 : if (state.dataUnitarySystems->setupOutputOnce) {
1285 45 : setupAllOutputVars(state, state.dataUnitarySystems->numUnitarySystems);
1286 : }
1287 : }
1288 136 : }
1289 :
1290 86 : void UnitarySys::sizeSystem(EnergyPlusData &state, bool const FirstHVACIteration, int const AirLoopNum)
1291 : {
1292 :
1293 : // SUBROUTINE INFORMATION:
1294 : // AUTHOR Richard Raustad, FSEC
1295 : // DATE WRITTEN February 2013
1296 :
1297 : // PURPOSE OF THIS SUBROUTINE:
1298 : // This subroutine is for sizing unitary system components for which nominal capacities
1299 : // and flow rates have not been specified in the input. Coil sizing is preformed in the coil module.
1300 : // Future modifications will size coils here and "push" this info to the specific coil.
1301 :
1302 : // METHODOLOGY EMPLOYED:
1303 : // Obtains heating capacities and flow rates from the zone or system sizing arrays.
1304 : // NOTE: In UNITARYSYSTEM:HEATPUMP:AIRTOAIR we are sizing the heating capacity to be
1305 : // equal to the cooling capacity. Thus the cooling and
1306 : // and heating capacities of a DX heat pump system will be identical. In real life the ARI
1307 : // heating and cooling capacities are close but not identical.
1308 :
1309 : // SUBROUTINE PARAMETER DEFINITIONS:
1310 : static constexpr std::string_view RoutineName("SizeUnitarySystem");
1311 :
1312 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1313 : int Iter; // iteration count
1314 : int MSHPIndex; // Index to design Specification object
1315 : Real64 SystemFlow; // AirloopHVAC flow rate [m3/s]
1316 : Real64 BranchFanFlow; // branch fan flow rate [m3/s]
1317 : bool ErrFound; // logical error flag
1318 : HVAC::AirDuctType SaveCurDuctType; // used during sizing to save the current duct type
1319 : Real64 QActual; // water coil output [W]
1320 : Real64 capacityMultiplier; // used for ASHRAE model sizing
1321 :
1322 : Real64 TempSize; // DataSizing::AutoSized value of input field
1323 86 : int FieldNum = 2; // IDD numeric field number where input field description is found
1324 : int SizingMethod; // Integer representation of sizing method (e.g., HVAC::CoolingAirflowSizing, DataSizing::HeatingCapacitySizing,
1325 : // etc.)
1326 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
1327 86 : Real64 SumOfMassFlowRateMax(0.0); // the sum of zone inlet mass flow rates
1328 : Real64 minNoLoadFlow; // used for sizing MaxNoCoolHeatVolFlow for SingleZoneVAV method
1329 86 : Real64 dummy(0.0);
1330 : //////////// hoisted into namespace ////////////////////////////////////////////////
1331 : // static int NumUnitarySystemsSized( 0 ); // counter used to delete UnitarySystemNumericFields array after last system is sized
1332 : ////////////////////////////////////////////////////////////////////////////////////
1333 : // References
1334 86 : DataSizing::ZoneEqSizingData *select_EqSizing = nullptr;
1335 :
1336 86 : auto &OASysEqSizing = state.dataSize->OASysEqSizing;
1337 :
1338 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
1339 86 : if (state.dataSize->CurOASysNum > 0) {
1340 4 : select_EqSizing = &OASysEqSizing(state.dataSize->CurOASysNum);
1341 82 : } else if (state.dataSize->CurSysNum > 0) {
1342 20 : select_EqSizing = &state.dataSize->UnitarySysEqSizing(state.dataSize->CurSysNum);
1343 : // this was resetting data set by OutdoorAirUnit when UnitarySystem is child
1344 : // question is then who resets these (#8751 temporary fix)?
1345 : // move here for now and only reset UnitarySystem flags, then find better way to do this
1346 20 : select_EqSizing->AirFlow = false;
1347 20 : select_EqSizing->CoolingAirFlow = false;
1348 20 : select_EqSizing->HeatingAirFlow = false;
1349 20 : select_EqSizing->AirVolFlow = 0.0;
1350 20 : select_EqSizing->CoolingAirVolFlow = 0.0;
1351 20 : select_EqSizing->HeatingAirVolFlow = 0.0;
1352 20 : select_EqSizing->Capacity = false;
1353 20 : select_EqSizing->CoolingCapacity = false;
1354 20 : select_EqSizing->HeatingCapacity = false;
1355 20 : select_EqSizing->DesCoolingLoad = 0.0;
1356 20 : select_EqSizing->DesHeatingLoad = 0.0;
1357 20 : select_EqSizing->OAVolFlow = 0.0; // UnitarySys doesn't have OA
1358 62 : } else if (state.dataSize->CurZoneEqNum > 0) {
1359 62 : select_EqSizing = &state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
1360 62 : state.dataSize->ZoneEqUnitarySys = true;
1361 : // UnitarySystem never set this flag. Probably should for zone equipment.
1362 62 : if ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
1363 8 : this->m_IsDXCoil)
1364 8 : state.dataSize->ZoneEqDXCoil = true;
1365 :
1366 : } else {
1367 0 : assert(false);
1368 : }
1369 : // Object Data, points to specific array
1370 86 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
1371 :
1372 : // coil sizing requires this information to check proper flow/capacity limits (#8761)
1373 86 : if (this->m_ISHundredPercentDOASDXCoil) {
1374 0 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::DOAS; // uses 100% DX coil flow limits
1375 : } else {
1376 86 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::Regular; // uses normal DX coil flow limits
1377 : }
1378 : // sizing may need to know what type of coil is being sized
1379 86 : state.dataSize->DataCoolCoilType = this->m_CoolingCoilType_Num;
1380 86 : state.dataSize->DataCoolCoilIndex = this->m_CoolingCoilIndex;
1381 :
1382 : bool anyEMSRan;
1383 86 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::UnitarySystemSizing, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point
1384 : bool HardSizeNoDesRun; // Indicator to a hard-sized field with no design sizing data
1385 :
1386 : // Initiate all reporting variables
1387 152 : if (((state.dataSize->CurOASysNum > 0 || state.dataSize->CurSysNum > 0) && state.dataSize->SysSizingRunDone) ||
1388 66 : (state.dataSize->CurZoneEqNum > 0 && state.dataSize->ZoneSizingRunDone)) {
1389 71 : HardSizeNoDesRun = false;
1390 : } else {
1391 15 : HardSizeNoDesRun = true;
1392 : }
1393 86 : std::string SizingString;
1394 86 : std::string CompName = this->Name;
1395 86 : std::string CompType = this->UnitType;
1396 86 : int CoolingSAFlowMethod = this->m_CoolingSAFMethod;
1397 86 : int HeatingSAFlowMethod = this->m_HeatingSAFMethod;
1398 : // can't reset this to 0 for systems where DX heating coil is in downstream unit and DX cooling coil is in upstream unit
1399 : // DXCoolCap = 0.0;
1400 86 : state.dataSize->UnitaryHeatCap = 0.0;
1401 86 : state.dataSize->SuppHeatCap = 0.0;
1402 86 : bool TempCoolingLoad = state.dataUnitarySystems->CoolingLoad;
1403 86 : bool TempHeatingLoad = state.dataUnitarySystems->HeatingLoad;
1404 86 : state.dataUnitarySystems->CoolingLoad = true;
1405 86 : state.dataUnitarySystems->HeatingLoad = false;
1406 86 : state.dataSize->ZoneCoolingOnlyFan = false;
1407 86 : state.dataSize->ZoneHeatingOnlyFan = false;
1408 86 : bool IsAutoSize = false;
1409 86 : Real64 SysCoolingFlow = 0.0;
1410 86 : Real64 SysHeatingFlow = 0.0;
1411 86 : Real64 CoolCapAtPeak = 0.0;
1412 86 : Real64 HeatCapAtPeak = 0.0;
1413 :
1414 86 : if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0 && this->m_FanExists) {
1415 4 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum = this->m_FanIndex;
1416 4 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanType = this->m_FanType;
1417 4 : state.dataSize->DataFanType = this->m_FanType;
1418 4 : state.dataSize->DataFanIndex = this->m_FanIndex;
1419 :
1420 4 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanPlace = this->m_FanPlace;
1421 82 : } else if (state.dataSize->CurZoneEqNum > 0 && this->m_FanExists) {
1422 59 : state.dataSize->DataFanType = this->m_FanType;
1423 59 : state.dataSize->DataFanIndex = this->m_FanIndex;
1424 59 : state.dataSize->DataFanPlacement = this->m_FanPlace;
1425 : }
1426 :
1427 86 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for scalable capacity sizing
1428 6 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
1429 : }
1430 :
1431 86 : Real64 coolingCapacityMultiplier = 1.0;
1432 86 : Real64 heatingCapacityMultiplier = 1.0;
1433 86 : if (this->m_HVACSizingIndex > 0) {
1434 0 : if (this->m_CoolingCapMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
1435 0 : coolingCapacityMultiplier = this->m_DesignCoolingCapacity;
1436 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
1437 : }
1438 0 : if (this->m_HeatingCapMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
1439 0 : heatingCapacityMultiplier = this->m_DesignHeatingCapacity;
1440 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
1441 : }
1442 : }
1443 :
1444 : // zone equipment that have OA mixers will need to know the OA flow rate to size coil inlet conditions
1445 86 : bool SizingDesRunThisZone = false;
1446 86 : if (this->OAMixerExists) {
1447 1 : if (state.dataSize->CurZoneEqNum > 0) {
1448 1 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1449 1 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize || this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
1450 0 : CheckZoneSizing(state, this->UnitType, this->Name);
1451 : }
1452 : // initialize OA flow for sizing other inputs (e.g., capacity)
1453 1 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
1454 0 : EqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
1455 : } else {
1456 1 : EqSizing.OAVolFlow = this->m_CoolOutAirVolFlow;
1457 : }
1458 1 : if (this->m_HeatOutAirVolFlow != DataSizing::AutoSize) {
1459 1 : EqSizing.OAVolFlow = max(EqSizing.OAVolFlow, this->m_HeatOutAirVolFlow);
1460 : }
1461 : }
1462 : }
1463 :
1464 86 : PrintFlag = false;
1465 : // STEP 1: find the DataSizing::AutoSized cooling air flow rate and capacity
1466 : // Note: this call will request fan heat and size the fan.
1467 : // Either the few lines above are too early, or there needs to be a way to avoid requesting fan heat from
1468 : // BaseSizerWithFanHeatInputs::initializeWithinEP so the fan doesn't size until the parent wants it to size.
1469 : // see PackagedTerminalHeatPumpVSAS.idf where fan is not sized large enough for cooling coil air flow rate.
1470 :
1471 : // delay fan sizing in case a VS fan is used and air flow needs to be modified above max design flow
1472 : // this may also mean capacity result does not include fan heat? and table diffs?
1473 : // and causes unit test failures, e.g., UnitarySystemModel_MultispeedDXCoilSizing.
1474 : // comment this out until the PTUnit to UnitarySystem #9273 branch is merged, so nothing changes
1475 : // until this is implemented, unbalanced air flow warnings show up in VS coil PTUnits
1476 : // int saveDataFanIndex = state.dataSize->DataFanIndex;
1477 : // state.dataSize->DataFanIndex = -1;
1478 :
1479 86 : bool coolingAirFlowIsAutosized = this->m_MaxCoolAirVolFlow == DataSizing::AutoSize;
1480 86 : bool heatingAirFlowIsAutosized = this->m_MaxHeatAirVolFlow == DataSizing::AutoSize;
1481 86 : if (this->m_CoolCoilExists) {
1482 68 : if (!this->m_HeatCoilExists) state.dataSize->ZoneCoolingOnlyFan = true;
1483 68 : TempSize = this->m_MaxCoolAirVolFlow;
1484 68 : SaveCurDuctType = state.dataSize->CurDuctType;
1485 : // might want to rethink this method. Tries to find the larger of cooling or heating capacity
1486 : // however, if there is no heating coil the cooling air flow rate is used, not the main flow rate
1487 : // this is fine if there are no other systems on the branch. CoilSystem does not do this (#8761).
1488 68 : if (this->m_sysType == SysType::Unitary) state.dataSize->CurDuctType = HVAC::AirDuctType::Cooling;
1489 68 : bool errorsFound = false;
1490 68 : if ((CoolingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (CoolingSAFlowMethod == DataSizing::None)) {
1491 57 : CoolingAirFlowSizer sizingCoolingAirFlow;
1492 57 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1493 57 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1494 68 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1495 2 : CoolingAirFlowSizer sizingCoolingAirFlow;
1496 2 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1497 2 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1498 2 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1499 11 : } else if (CoolingSAFlowMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
1500 5 : TempSize = DataSizing::AutoSize;
1501 5 : CoolingAirFlowSizer sizingCoolingAirFlow;
1502 5 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1503 5 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1504 5 : SysCoolingFlow *= this->m_MaxCoolAirVolFlow;
1505 5 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1506 9 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerCoolingCapacity) {
1507 4 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
1508 4 : TempSize = DataSizing::AutoSize;
1509 4 : CoolingAirFlowSizer sizingCoolingAirFlow;
1510 4 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1511 4 : state.dataSize->DataFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1512 4 : SizingMethod = HVAC::CoolingCapacitySizing;
1513 4 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
1514 0 : state.dataSize->DataTotCapCurveIndex =
1515 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1516 0 : state.dataSize->DataIsDXCoil = true;
1517 4 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
1518 4 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1519 3 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1520 3 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1521 1 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1522 1 : state.dataSize->DataIsDXCoil = true;
1523 : }
1524 4 : CoolingCapacitySizer sizerCoolingCapacity;
1525 4 : sizerCoolingCapacity.overrideSizingString(SizingString);
1526 4 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1527 4 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1528 4 : SysCoolingFlow = CoolCapAtPeak * this->m_MaxCoolAirVolFlow;
1529 4 : state.dataSize->DataTotCapCurveIndex = 0;
1530 4 : EqSizing.CoolingCapacity = true;
1531 4 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1532 4 : } else {
1533 0 : SysCoolingFlow = this->m_DesignCoolingCapacity * this->m_MaxCoolAirVolFlow;
1534 0 : CoolCapAtPeak = this->m_DesignCoolingCapacity;
1535 0 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1536 : }
1537 4 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1538 : } else {
1539 : // should never happen
1540 0 : ShowSevereError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
1541 0 : ShowContinueError(state, "Illegal entry for Cooling Supply Air Flow Rate Method.");
1542 : }
1543 :
1544 68 : state.dataSize->CurDuctType = SaveCurDuctType;
1545 68 : EqSizing.CoolingAirFlow = true;
1546 68 : EqSizing.CoolingAirVolFlow = SysCoolingFlow;
1547 :
1548 : // Cooling airflow should be known at this point. Now find DataSizing::AutoSized design cooling capacity.
1549 68 : if (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity < 0.0) {
1550 46 : SizingMethod = HVAC::CoolingCapacitySizing;
1551 46 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1552 46 : TempSize = DataSizing::AutoSize;
1553 : // could probably move this up outside the IF and delete then next group below in the else
1554 46 : switch (this->m_CoolingCoilType_Num) {
1555 3 : case HVAC::CoilDX_Cooling: {
1556 6 : state.dataSize->DataTotCapCurveIndex =
1557 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1558 3 : state.dataSize->DataIsDXCoil = true;
1559 3 : } break;
1560 22 : case HVAC::CoilDX_CoolingSingleSpeed:
1561 : case HVAC::CoilDX_MultiSpeedCooling:
1562 : case HVAC::CoilDX_CoolingTwoSpeed:
1563 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
1564 22 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1565 22 : state.dataSize->DataIsDXCoil = true;
1566 22 : } break;
1567 2 : case HVAC::Coil_CoolingAirToAirVariableSpeed: {
1568 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1569 2 : state.dataSize->DataIsDXCoil = true;
1570 2 : } break;
1571 2 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
1572 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1573 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1574 : // state.dataSize->DataIsDXCoil = true;
1575 2 : } break;
1576 17 : default: {
1577 17 : } break;
1578 : }
1579 92 : CoolingCapacitySizer sizerCoolingCapacity;
1580 46 : sizerCoolingCapacity.overrideSizingString(SizingString);
1581 46 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1582 46 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1583 46 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1584 : // this probably needs to be more specific. Letting heating coil size itself if user has scalable sizing
1585 46 : if (this->m_HVACSizingIndex <= 0) state.dataSize->DXCoolCap = CoolCapAtPeak;
1586 : // CoilSystem does not size the cooling coil (#8761)
1587 46 : if ((this->m_sysType == SysType::Unitary) || (this->m_sysType == SysType::PackagedAC) || (this->m_sysType == SysType::PackagedHP) ||
1588 18 : (this->m_sysType == SysType::PackagedWSHP)) {
1589 30 : EqSizing.CoolingCapacity = true;
1590 30 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1591 : }
1592 68 : } else if (!HardSizeNoDesRun && (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1593 : // corrected code for #8756
1594 1 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1595 1 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1596 1 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1597 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1598 0 : state.dataSize->DataIsDXCoil = true;
1599 : }
1600 1 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
1601 0 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1602 0 : state.dataSize->DataIsDXCoil = true;
1603 : }
1604 1 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
1605 0 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1606 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1607 : // state.dataSize->DataIsDXCoil = true;
1608 : }
1609 : // PTUnit does not call CapacitySizer and adjust capacity based on flow per capacity limits
1610 1 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) {
1611 0 : state.dataSize->DataIsDXCoil = false;
1612 : }
1613 1 : SizingMethod = HVAC::CoolingCapacitySizing;
1614 1 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1615 1 : if (this->m_CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
1616 1 : (this->m_CoolingCapMethod == DataSizing::CoolingDesignCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1617 0 : TempSize = this->m_DesignCoolingCapacity;
1618 : } else {
1619 1 : TempSize = DataSizing::AutoSize;
1620 : }
1621 1 : CoolingCapacitySizer sizerCoolingCapacity;
1622 1 : sizerCoolingCapacity.overrideSizingString(SizingString);
1623 1 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1624 1 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1625 1 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1626 1 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1627 1 : EqSizing.CoolingCapacity = true;
1628 1 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1629 1 : } else {
1630 : // something seems missing here based on multiple conditional if above
1631 21 : if (this->m_DesignCoolingCapacity != DataSizing::AutoSize) CoolCapAtPeak = this->m_DesignCoolingCapacity;
1632 : }
1633 68 : state.dataSize->DataIsDXCoil = false;
1634 68 : state.dataSize->DataTotCapCurveIndex = 0;
1635 68 : state.dataSize->DataFlowUsedForSizing = 0.0;
1636 : }
1637 :
1638 : // STEP 2: find the DataSizing::AutoSized heating air flow rate and capacity
1639 86 : if (this->m_HeatCoilExists) {
1640 52 : if (!this->m_CoolCoilExists) state.dataSize->ZoneHeatingOnlyFan = true;
1641 52 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1642 52 : SizingMethod = HVAC::HeatingAirflowSizing;
1643 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1644 52 : TempSize = this->m_MaxHeatAirVolFlow;
1645 52 : SaveCurDuctType = state.dataSize->CurDuctType;
1646 52 : state.dataSize->CurDuctType = HVAC::AirDuctType::Heating;
1647 52 : if ((HeatingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (HeatingSAFlowMethod == DataSizing::None)) {
1648 43 : bool errorsFound = false;
1649 43 : HeatingAirFlowSizer sizingHeatingAirFlow;
1650 43 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1651 43 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1652 43 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1653 52 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1654 2 : bool errorsFound = false;
1655 2 : HeatingAirFlowSizer sizingHeatingAirFlow;
1656 2 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1657 2 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1658 2 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1659 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1660 9 : } else if (HeatingSAFlowMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
1661 3 : TempSize = DataSizing::AutoSize;
1662 3 : bool errorsFound = false;
1663 3 : HeatingAirFlowSizer sizingHeatingAirFlow;
1664 3 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1665 3 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1666 3 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1667 3 : SysHeatingFlow *= this->m_MaxHeatAirVolFlow;
1668 3 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1669 7 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerHeatingCapacity) {
1670 4 : TempSize = DataSizing::AutoSize;
1671 4 : bool errorsFound = false;
1672 4 : HeatingAirFlowSizer sizingHeatingAirFlow;
1673 4 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1674 4 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1675 4 : state.dataSize->DataFlowUsedForSizing = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1676 4 : SizingMethod = HVAC::HeatingCapacitySizing;
1677 4 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
1678 4 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1679 4 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
1680 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1681 0 : state.dataSize->DataIsDXCoil = true;
1682 : }
1683 4 : if (state.dataSize->CurSysNum > 0)
1684 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1685 : false; // set to false to allow calculation of actual heating capacity
1686 4 : HeatingCapacitySizer sizerHeatingCapacity;
1687 4 : sizerHeatingCapacity.overrideSizingString(SizingString);
1688 4 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1689 4 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1690 4 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1691 4 : SysHeatingFlow = HeatCapAtPeak * this->m_MaxHeatAirVolFlow;
1692 4 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1693 4 : EqSizing.HeatingCapacity = true;
1694 4 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1695 4 : } else {
1696 : // should never happen
1697 0 : ShowSevereError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
1698 0 : ShowContinueError(state, "Illegal entry for Heating Supply Air Flow Rate Method.");
1699 : }
1700 :
1701 52 : state.dataSize->CurDuctType = SaveCurDuctType;
1702 52 : EqSizing.HeatingAirFlow = true;
1703 52 : EqSizing.HeatingAirVolFlow = SysHeatingFlow;
1704 :
1705 : // Heating airflow should be known at this point. Now find DataSizing::AutoSized design heating capacity.
1706 52 : if (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
1707 26 : SizingMethod = HVAC::HeatingCapacitySizing;
1708 26 : if (m_sysType == SysType::Unitary || m_sysType == SysType::CoilCoolingDX || m_sysType == SysType::CoilCoolingWater) {
1709 24 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1710 : }
1711 26 : TempSize = DataSizing::AutoSize;
1712 26 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1713 26 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1714 1 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1715 1 : state.dataSize->DataIsDXCoil = true;
1716 : }
1717 : // should have VS coil capFT here also
1718 26 : if (this->m_sysType == SysType::PackagedWSHP && this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1719 1 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1720 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1721 : // state.dataSize->DataIsDXCoil = true;
1722 : }
1723 : // PTUnit does not call CapacitySizer and adjust capacity based on flow per capacity limits
1724 26 : if (this->m_sysType == SysType::PackagedHP) {
1725 0 : state.dataSize->DataIsDXCoil = false;
1726 : }
1727 26 : if (state.dataSize->CurSysNum > 0)
1728 2 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1729 : false; // set to false to allow calculation of actual heating capacity
1730 26 : bool errorsFound = false;
1731 26 : HeatingCapacitySizer sizerHeatingCapacity;
1732 26 : sizerHeatingCapacity.overrideSizingString(SizingString);
1733 26 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1734 26 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1735 26 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1736 26 : EqSizing.HeatingCapacity = true;
1737 26 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1738 26 : } else {
1739 26 : if (!HardSizeNoDesRun &&
1740 10 : (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity != DataSizing::AutoSize)) {
1741 : // should have other DX heating coil types here
1742 10 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1743 0 : SizingMethod = HVAC::HeatingCapacitySizing;
1744 0 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1745 0 : TempSize = DataSizing::AutoSize;
1746 0 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1747 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1748 0 : state.dataSize->DataIsDXCoil = true;
1749 0 : if (state.dataSize->CurSysNum > 0)
1750 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1751 : false; // set to false to allow calculation of actual heating capacity
1752 0 : bool errorsFound = false;
1753 0 : HeatingCapacitySizer sizerHeatingCapacity;
1754 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
1755 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1756 0 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1757 0 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1758 0 : EqSizing.HeatingCapacity = true;
1759 0 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1760 0 : }
1761 10 : } else {
1762 : // something seems missing here based on multiple conditional if above
1763 16 : if (this->m_DesignHeatingCapacity != DataSizing::AutoSize) HeatCapAtPeak = this->m_DesignHeatingCapacity;
1764 : }
1765 : }
1766 : // if ( ! UnitarySystem( UnitarySysNum ).CoolCoilExists )DXCoolCap = HeatCapAtPeak;
1767 52 : state.dataSize->DataIsDXCoil = false;
1768 52 : state.dataSize->DataTotCapCurveIndex = 0;
1769 52 : state.dataSize->DataFlowUsedForSizing = 0.0;
1770 52 : if (this->m_sysType == SysType::PackagedAC) EqSizing.HeatingCapacity = false;
1771 : }
1772 :
1773 86 : bool isWSVarSpeedCoolCoil = this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
1774 86 : bool isWSVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
1775 86 : bool isVarSpeedCoolCoil = this->m_HeatingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed;
1776 86 : bool isVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed;
1777 :
1778 86 : Real64 saveRawHeatingCapacity = HeatCapAtPeak;
1779 :
1780 : // STEP 3A: Find VS cooling coil air flow to capacity ratio and adjust design air flow
1781 122 : if (EqSizing.DesCoolingLoad > 0.0 && state.dataSize->CurZoneEqNum > 0 &&
1782 36 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
1783 35 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1784 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed))) {
1785 1 : Real64 coolingToHeatingCapRatio = 1.0;
1786 1 : if ((isWSVarSpeedCoolCoil && this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) ||
1787 0 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1788 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
1789 1 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NormSpedLevel;
1790 : Real64 coolingAirFlowToCapacityRatio =
1791 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1792 1 : EqSizing.CoolingAirVolFlow = EqSizing.DesCoolingLoad * coolingAirFlowToCapacityRatio;
1793 1 : if (EqSizing.DesHeatingLoad > 0.0) coolingToHeatingCapRatio = EqSizing.DesCoolingLoad / EqSizing.DesHeatingLoad;
1794 : }
1795 1 : if (((isWSVarSpeedHeatCoil || isVarSpeedHeatCoil) && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) ||
1796 0 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1797 0 : this->m_CoolingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed)) {
1798 1 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
1799 : Real64 heatingAirFlowToCapacityRatio =
1800 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1801 1 : EqSizing.DesHeatingLoad *= coolingToHeatingCapRatio;
1802 1 : EqSizing.HeatingAirVolFlow = EqSizing.DesHeatingLoad * heatingAirFlowToCapacityRatio;
1803 : }
1804 : }
1805 :
1806 : // STEP 3B: use the greater of cooling and heating air flow rates for system flow
1807 : // previous version of E+ used maximum flow rate for unitary systems. Keep this methodology for now.
1808 : // Delete next 2 lines and uncomment 2 lines inside next if (HeatPump) statement to allow non-heat pump systems to operate at different flow
1809 : // rates (might require additional change to if block logic).
1810 : // UnitarySystem is sizing heating coil size = cooling coil size for 5Zone_Unitary_HXAssistedCoil (not a heat pump)
1811 : // and WaterSideEconomizer_PreCoolCoil (not a heat pump)
1812 : // and 5Zone_Unitary_VSDesuperheatWaterHeater (not a heat pump)
1813 86 : if ((!isWSVarSpeedHeatCoil &&
1814 85 : (((this->m_sysType == SysType::PackagedAC && !isVarSpeedCoolCoil) && (this->m_sysType == SysType::PackagedHP && !isVarSpeedHeatCoil)) ||
1815 85 : (this->m_sysType == SysType::Unitary && this->m_HeatPump))) ||
1816 82 : (this->m_sysType == SysType::Unitary &&
1817 55 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
1818 49 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
1819 47 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling))) {
1820 16 : EqSizing.CoolingAirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1821 16 : EqSizing.HeatingAirVolFlow = EqSizing.CoolingAirVolFlow;
1822 : }
1823 :
1824 : // STEP 4: set heat pump coil capacities equal to greater of cooling or heating capacity
1825 : // if a heat pump, use maximum values and set main air flow and capacity variables
1826 86 : if (this->m_sysType == SysType::PackagedHP && !isVarSpeedCoolCoil) {
1827 : // PTPH allows the cooling coil to set DataCoolCoilCap so cooling coil sets capacity
1828 : // This is wrong since a larger heating load should set HP capacity (next else if)
1829 0 : EqSizing.HeatingCapacity = false;
1830 86 : } else if (this->m_HeatPump && (state.dataSize->CurZoneEqNum == 0 || !isWSVarSpeedCoolCoil)) {
1831 5 : EqSizing.AirFlow = true;
1832 5 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1833 5 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit &&
1834 5 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1835 5 : EqSizing.Capacity = true;
1836 5 : EqSizing.DesCoolingLoad = max(EqSizing.DesCoolingLoad, EqSizing.DesHeatingLoad);
1837 5 : EqSizing.DesHeatingLoad = EqSizing.DesCoolingLoad;
1838 5 : state.dataSize->DXCoolCap = EqSizing.DesCoolingLoad;
1839 : }
1840 81 : } else if (!this->m_CoolCoilExists && state.dataSize->CurZoneEqNum > 0) {
1841 18 : state.dataSize->DXCoolCap = EqSizing.DesHeatingLoad;
1842 : }
1843 :
1844 : // now size fans as necessary
1845 : // comment this out until the PTUnit to UnitarySystem #9273 branch is merged, so nothing changes
1846 : // until this is implemented, unbalanced air flow warning show up in VS coil PTUnits
1847 : // state.dataSize->DataFanIndex = saveDataFanIndex;
1848 :
1849 : // Some parent objects report sizing, some do not
1850 86 : if (this->m_OKToPrintSizing) {
1851 62 : if (this->m_sysType != SysType::CoilCoolingDX && this->m_sysType != SysType::CoilCoolingWater) {
1852 43 : PrintFlag = true;
1853 : }
1854 : }
1855 : // STEP 5: report system parameters (e.g., air flow rates, capacities, etc.)
1856 86 : if (this->m_FanExists) {
1857 63 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)
1858 8 : PrintFlag = false;
1859 :
1860 63 : EqSizing.SystemAirFlow = true;
1861 63 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1862 63 : if (this->m_DesignFanVolFlowRate <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1863 45 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
1864 : }
1865 63 : state.dataSize->DataEMSOverrideON = this->m_DesignFanVolFlowRateEMSOverrideOn;
1866 63 : state.dataSize->DataEMSOverride = this->m_DesignFanVolFlowRateEMSOverrideValue;
1867 :
1868 63 : bool errorsFound = false;
1869 63 : SystemAirFlowSizer sizerSystemAirFlow;
1870 63 : std::string sizingString = "Supply Air Flow Rate [m3/s]";
1871 63 : sizerSystemAirFlow.overrideSizingString(sizingString);
1872 63 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1873 63 : this->m_DesignFanVolFlowRate = sizerSystemAirFlow.size(state, this->m_DesignFanVolFlowRate, errorsFound);
1874 :
1875 63 : state.dataSize->DataEMSOverrideON = false;
1876 63 : EqSizing.SystemAirFlow = false;
1877 :
1878 63 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)
1879 8 : PrintFlag = true;
1880 63 : }
1881 :
1882 : // not sure what to do if UnitarySystem has only 1 coil type and flow needs to occur when present coil is off
1883 : // how does constant fan operating mode pertain here?
1884 86 : if (this->m_HeatCoilExists && !this->m_CoolCoilExists) {
1885 18 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_MaxCoolAirVolFlow = EqSizing.HeatingAirVolFlow;
1886 68 : } else if (this->m_CoolCoilExists && !this->m_HeatCoilExists) {
1887 34 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_MaxHeatAirVolFlow = EqSizing.CoolingAirVolFlow;
1888 34 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1889 : }
1890 :
1891 : // PT Units report sizing for cooling then heating, UnitarySystem reverses that order
1892 : // temporarily reverse reporting for PT units so eio diffs are cleaner, remove later
1893 86 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1894 8 : if (this->m_CoolCoilExists) {
1895 : // allow design size to report
1896 8 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) EqSizing.CoolingAirFlow = false;
1897 8 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1898 2 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1899 : }
1900 8 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
1901 8 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
1902 8 : TempSize = this->m_MaxCoolAirVolFlow;
1903 8 : bool errorsFound = false;
1904 8 : CoolingAirFlowSizer sizingCoolingAirFlow;
1905 8 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
1906 8 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
1907 8 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1908 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1909 8 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1910 8 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1911 8 : state.dataSize->DataEMSOverrideON = false;
1912 8 : state.dataSize->DataConstantUsedForSizing = 0.0;
1913 8 : }
1914 8 : if (this->m_HeatCoilExists) {
1915 : // allow design size to report
1916 8 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) EqSizing.HeatingAirFlow = false;
1917 8 : SizingMethod = HVAC::HeatingAirflowSizing;
1918 8 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1919 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1920 : }
1921 8 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
1922 8 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1923 1 : EqSizing.AirFlow = false;
1924 : }
1925 8 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1926 8 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
1927 8 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
1928 8 : TempSize = this->m_MaxHeatAirVolFlow;
1929 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1930 8 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
1931 8 : bool errorsFound = false;
1932 8 : HeatingAirFlowSizer sizingHeatingAirFlow;
1933 8 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1934 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1935 8 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1936 8 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1937 8 : state.dataSize->DataEMSOverrideON = false;
1938 8 : state.dataSize->DataConstantUsedForSizing = 0.0;
1939 8 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1940 1 : EqSizing.AirFlow = saveEqSizingAirFlow;
1941 : }
1942 8 : }
1943 :
1944 8 : } else {
1945 78 : if (this->m_HeatCoilExists) {
1946 :
1947 44 : SizingMethod = HVAC::HeatingAirflowSizing;
1948 44 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1949 36 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1950 : }
1951 44 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
1952 44 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1953 0 : EqSizing.AirFlow = false;
1954 : }
1955 44 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1956 44 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
1957 44 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
1958 44 : TempSize = this->m_MaxHeatAirVolFlow;
1959 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1960 44 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
1961 44 : bool errorsFound = false;
1962 44 : HeatingAirFlowSizer sizingHeatingAirFlow;
1963 44 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1964 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1965 44 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1966 44 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1967 44 : state.dataSize->DataEMSOverrideON = false;
1968 44 : state.dataSize->DataConstantUsedForSizing = 0.0;
1969 44 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1970 0 : EqSizing.AirFlow = saveEqSizingAirFlow;
1971 : }
1972 44 : }
1973 :
1974 78 : if (this->m_CoolCoilExists) {
1975 :
1976 60 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1977 47 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1978 : }
1979 60 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
1980 60 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
1981 60 : TempSize = this->m_MaxCoolAirVolFlow;
1982 60 : bool errorsFound = false;
1983 60 : CoolingAirFlowSizer sizingCoolingAirFlow;
1984 60 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
1985 60 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
1986 60 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1987 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1988 60 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1989 60 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1990 60 : state.dataSize->DataEMSOverrideON = false;
1991 60 : state.dataSize->DataConstantUsedForSizing = 0.0;
1992 60 : }
1993 : }
1994 :
1995 : // If not set, set DesignFanVolFlowRate as greater of cooling and heating to make sure this value > 0.
1996 : // If fan is hard-sized, use that value, otherwise the fan will size to DesignFanVolFlowRate
1997 86 : if (this->m_DesignFanVolFlowRate <= 0.0) {
1998 22 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
1999 22 : if (this->m_ActualFanVolFlowRate > 0.0) this->m_DesignFanVolFlowRate = this->m_ActualFanVolFlowRate;
2000 22 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2001 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2002 0 : ShowFatalError(state, "Unable to determine fan air flow rate.");
2003 : }
2004 : }
2005 86 : if (!this->m_FanExists) this->m_ActualFanVolFlowRate = this->m_DesignFanVolFlowRate;
2006 :
2007 86 : if (this->m_CoolCoilExists || this->m_HeatCoilExists || this->m_SuppCoilExists) {
2008 86 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2009 : // set no load air flow ratio local var
2010 86 : Real64 NoLoadCoolingAirFlowRateRatio = 1.0;
2011 86 : Real64 NoLoadHeatingAirFlowRateRatio = 1.0;
2012 86 : if (MSHPIndex > -1) {
2013 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling > 0) {
2014 18 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0] == DataSizing::AutoSize) {
2015 : NoLoadCoolingAirFlowRateRatio =
2016 6 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling));
2017 : } else {
2018 : NoLoadCoolingAirFlowRateRatio =
2019 12 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0]);
2020 : }
2021 : }
2022 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating > 0) {
2023 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0] == DataSizing::AutoSize) {
2024 : NoLoadHeatingAirFlowRateRatio =
2025 8 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating));
2026 : } else {
2027 : NoLoadHeatingAirFlowRateRatio =
2028 11 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0]);
2029 : }
2030 : }
2031 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio > 0.0) {
2032 13 : this->m_NoLoadAirFlowRateRatio = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2033 : } else {
2034 6 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2035 : }
2036 : } else {
2037 67 : if ((this->m_CoolCoilExists || this->m_HeatCoilExists) && this->m_useNoLoadLowSpeedAirFlow) {
2038 65 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2039 62 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
2040 : Real64 MaxSpeedFlowRate =
2041 4 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2042 4 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2043 4 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) >
2044 : 0.0) { // these are the air flow at speed fields, and could be 0
2045 3 : NoLoadCoolingAirFlowRateRatio =
2046 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2047 : } else {
2048 1 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2049 : }
2050 65 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
2051 : // for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum)
2052 : // for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum)
2053 : // PerfModeNum = DehumidModeNum * 2 + CapacityStageNum
2054 : // RatedAirVolFlowRate(PerfModeNum) so PerfModeNum = 1 to NumCapacityStages to find air flow rate
2055 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2056 0 : .RatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages);
2057 0 : if (MaxSpeedFlowRate > 0.0 &&
2058 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2059 0 : NoLoadCoolingAirFlowRateRatio =
2060 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2061 : } else { // if any flow rates are autosized use the ratio of number of capacity stages
2062 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages;
2063 : }
2064 61 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2065 : // RatedAirVolFlowRate(1) = high speed, RatedAirVolFlowRate2= low speed
2066 3 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1);
2067 3 : if (MaxSpeedFlowRate > 0.0 &&
2068 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 != DataSizing::AutoSize) {
2069 0 : NoLoadCoolingAirFlowRateRatio =
2070 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 / MaxSpeedFlowRate;
2071 : } else { // above flow rates for this coil could be autosized, use 1/2 for two speed coil
2072 3 : NoLoadCoolingAirFlowRateRatio = 0.5;
2073 : }
2074 58 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
2075 : // MSRatedAirVolFlowRate
2076 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2077 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2078 0 : if (MaxSpeedFlowRate > 0.0 &&
2079 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2080 0 : NoLoadCoolingAirFlowRateRatio =
2081 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2082 : } else { // if any flow rates are autosized use the ratio of number of speeds
2083 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2084 : }
2085 58 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2086 4 : NoLoadCoolingAirFlowRateRatio = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex]
2087 2 : .performance.normalMode.speeds[0]
2088 : .original_input_specs.evaporator_air_flow_fraction;
2089 : }
2090 65 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
2091 64 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2092 : Real64 MaxSpeedFlowRate =
2093 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2094 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2095 1 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) >
2096 : 0.0) { // these are the air flow at speed fields, and could be 0
2097 1 : NoLoadHeatingAirFlowRateRatio =
2098 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2099 : } else {
2100 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2101 : }
2102 65 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
2103 : // MSRatedAirVolFlowRate
2104 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex)
2105 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2106 0 : if (MaxSpeedFlowRate > 0.0 &&
2107 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2108 0 : NoLoadHeatingAirFlowRateRatio =
2109 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2110 : } else { // if any flow rates are autosized use the ratio of number of speeds
2111 0 : NoLoadHeatingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
2112 : }
2113 : }
2114 65 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2115 : }
2116 : }
2117 86 : if (this->m_NoCoolHeatSAFMethod <= DataSizing::SupplyAirFlowRate && this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
2118 2 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
2119 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2120 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
2121 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
2122 0 : minNoLoadFlow = 0.6667; // TODO: Should this have a Coil:Cooling:DX block?
2123 : } else {
2124 0 : if (this->m_NoLoadAirFlowRateRatio < 1.0) {
2125 0 : minNoLoadFlow = this->m_NoLoadAirFlowRateRatio;
2126 : } else {
2127 0 : minNoLoadFlow = 0.5;
2128 : }
2129 : }
2130 0 : if (this->m_MaxCoolAirVolFlow >= this->m_MaxHeatAirVolFlow) {
2131 0 : state.dataSize->DataFractionUsedForSizing =
2132 0 : min(minNoLoadFlow, (this->m_MaxHeatAirVolFlow / this->m_MaxCoolAirVolFlow) - 0.01);
2133 : } else {
2134 0 : state.dataSize->DataFractionUsedForSizing =
2135 0 : min(minNoLoadFlow, (this->m_MaxCoolAirVolFlow / this->m_MaxHeatAirVolFlow) - 0.01);
2136 : }
2137 : } else {
2138 2 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2139 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
2140 : }
2141 84 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
2142 1 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.CoolingAirVolFlow;
2143 1 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2144 1 : state.dataSize->DataFractionUsedForSizing = 1.0;
2145 1 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2146 83 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
2147 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.HeatingAirVolFlow;
2148 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2149 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2150 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2151 83 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerCoolingCapacity) {
2152 1 : if (EqSizing.DesCoolingLoad <= 0.0) {
2153 : // water coils not sizing yet
2154 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2155 0 : WaterCoils::SimulateWaterCoilComponents(
2156 0 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2157 0 : EqSizing.DesCoolingLoad = WaterCoils::GetWaterCoilCapacity(
2158 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
2159 : }
2160 : }
2161 1 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesCoolingLoad;
2162 1 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2163 1 : state.dataSize->DataFractionUsedForSizing = 1.0;
2164 1 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2165 82 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerHeatingCapacity) {
2166 0 : if (EqSizing.DesHeatingLoad <= 0.0) {
2167 : // water coil not sizing yet
2168 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2169 0 : WaterCoils::SimulateWaterCoilComponents(
2170 0 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2171 0 : EqSizing.DesHeatingLoad = WaterCoils::GetWaterCoilCapacity(
2172 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
2173 : }
2174 : }
2175 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesHeatingLoad;
2176 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2177 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2178 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2179 : } else {
2180 82 : state.dataSize->DataFractionUsedForSizing = this->m_NoLoadAirFlowRateRatio;
2181 : }
2182 :
2183 86 : FieldNum = 11; // N11 , \field No Load Supply Air Flow Rate
2184 86 : state.dataSize->DataEMSOverrideON = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideOn;
2185 86 : state.dataSize->DataEMSOverride = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideValue;
2186 86 : TempSize = this->m_MaxNoCoolHeatAirVolFlow;
2187 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2188 86 : SizingString = "No Load Supply Air Flow Rate [m3/s]";
2189 86 : bool errorsFound = false;
2190 86 : SystemAirFlowSizer sizerSystemAirFlow;
2191 86 : sizerSystemAirFlow.overrideSizingString(SizingString);
2192 86 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2193 86 : this->m_MaxNoCoolHeatAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
2194 86 : state.dataSize->DataEMSOverrideON = false;
2195 86 : state.dataSize->DataConstantUsedForSizing = 0.0;
2196 86 : state.dataSize->DataFractionUsedForSizing = 0.0;
2197 86 : }
2198 :
2199 86 : if (this->m_MaxCoolAirVolFlow > 0.0) {
2200 73 : this->LowSpeedCoolFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxCoolAirVolFlow;
2201 : }
2202 86 : if (this->m_MaxHeatAirVolFlow > 0.0) {
2203 62 : this->LowSpeedHeatFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxHeatAirVolFlow;
2204 : }
2205 :
2206 86 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for use in component sizing
2207 6 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
2208 : }
2209 :
2210 86 : if (this->OAMixerExists) {
2211 1 : IsAutoSize = false;
2212 1 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
2213 0 : IsAutoSize = true;
2214 : }
2215 1 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2216 1 : if (this->m_CoolOutAirVolFlow > 0.0) {
2217 1 : BaseSizer::reportSizerOutput(state,
2218 : this->UnitType,
2219 : this->Name,
2220 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2221 : this->m_CoolOutAirVolFlow);
2222 : }
2223 : } else {
2224 0 : CheckZoneSizing(state, this->UnitType, this->Name);
2225 0 : Real64 CoolOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2226 0 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2227 0 : CoolOutAirVolFlowDes = 0.0;
2228 : }
2229 0 : if (IsAutoSize) {
2230 0 : this->m_CoolOutAirVolFlow = CoolOutAirVolFlowDes;
2231 0 : BaseSizer::reportSizerOutput(
2232 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]", CoolOutAirVolFlowDes);
2233 : } else {
2234 0 : if (this->m_CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2235 0 : Real64 CoolOutAirVolFlowUser = this->m_CoolOutAirVolFlow;
2236 0 : BaseSizer::reportSizerOutput(state,
2237 : this->UnitType,
2238 : this->Name,
2239 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2240 : CoolOutAirVolFlowDes,
2241 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2242 : CoolOutAirVolFlowUser);
2243 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2244 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
2245 0 : state.dataSize->AutoVsHardSizingThreshold) {
2246 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2247 0 : ShowContinueError(
2248 : state,
2249 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
2250 0 : ShowContinueError(state,
2251 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
2252 : CoolOutAirVolFlowDes));
2253 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2254 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2255 : }
2256 : }
2257 : }
2258 : }
2259 : }
2260 :
2261 1 : IsAutoSize = false;
2262 1 : if (this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
2263 0 : IsAutoSize = true;
2264 : }
2265 1 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2266 1 : if (this->m_HeatOutAirVolFlow > 0.0) {
2267 1 : BaseSizer::reportSizerOutput(state,
2268 : this->UnitType,
2269 : this->Name,
2270 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2271 : this->m_HeatOutAirVolFlow);
2272 : }
2273 : } else {
2274 0 : CheckZoneSizing(state, this->UnitType, this->Name);
2275 0 : Real64 HeatOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2276 0 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2277 0 : HeatOutAirVolFlowDes = 0.0;
2278 : }
2279 0 : if (IsAutoSize) {
2280 0 : this->m_HeatOutAirVolFlow = HeatOutAirVolFlowDes;
2281 0 : BaseSizer::reportSizerOutput(
2282 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]", HeatOutAirVolFlowDes);
2283 : } else {
2284 0 : if (this->m_HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2285 0 : Real64 HeatOutAirVolFlowUser = this->m_HeatOutAirVolFlow;
2286 0 : BaseSizer::reportSizerOutput(state,
2287 : this->UnitType,
2288 : this->Name,
2289 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
2290 : HeatOutAirVolFlowDes,
2291 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2292 : HeatOutAirVolFlowUser);
2293 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2294 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
2295 0 : state.dataSize->AutoVsHardSizingThreshold) {
2296 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2297 0 : ShowContinueError(
2298 : state,
2299 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
2300 0 : ShowContinueError(state,
2301 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
2302 : HeatOutAirVolFlowDes));
2303 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2304 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2305 : }
2306 : }
2307 : }
2308 : }
2309 : }
2310 :
2311 1 : IsAutoSize = false;
2312 1 : if (this->m_NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
2313 0 : IsAutoSize = true;
2314 : }
2315 1 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2316 1 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0) {
2317 1 : BaseSizer::reportSizerOutput(state,
2318 : this->UnitType,
2319 : this->Name,
2320 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2321 : this->m_NoCoolHeatOutAirVolFlow);
2322 : }
2323 : } else {
2324 0 : CheckZoneSizing(state, this->UnitType, this->Name);
2325 : Real64 NoCoolHeatOutAirVolFlowDes =
2326 0 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, this->m_MaxNoCoolHeatAirVolFlow);
2327 0 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2328 0 : NoCoolHeatOutAirVolFlowDes = 0.0;
2329 : }
2330 0 : if (IsAutoSize) {
2331 0 : this->m_NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
2332 0 : BaseSizer::reportSizerOutput(state,
2333 : this->UnitType,
2334 : this->Name,
2335 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2336 : NoCoolHeatOutAirVolFlowDes);
2337 : } else {
2338 0 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2339 0 : Real64 NoCoolHeatOutAirVolFlowUser = this->m_NoCoolHeatOutAirVolFlow;
2340 0 : BaseSizer::reportSizerOutput(state,
2341 : this->UnitType,
2342 : this->Name,
2343 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2344 : NoCoolHeatOutAirVolFlowDes,
2345 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2346 : NoCoolHeatOutAirVolFlowUser);
2347 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2348 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
2349 0 : state.dataSize->AutoVsHardSizingThreshold) {
2350 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2351 0 : ShowContinueError(state,
2352 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2353 : NoCoolHeatOutAirVolFlowUser));
2354 0 : ShowContinueError(
2355 : state,
2356 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2357 : NoCoolHeatOutAirVolFlowDes));
2358 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2359 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2360 : }
2361 : }
2362 : }
2363 : }
2364 : }
2365 : }
2366 86 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) PrintFlag = false;
2367 :
2368 86 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2369 8 : if (this->m_AirFlowControl == UseCompFlow::On) {
2370 3 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2371 3 : this->m_NoLoadAirFlowRateRatio = 1.0;
2372 : }
2373 8 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2374 8 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2375 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
2376 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
2377 0 : Real64 airFlowAdjustmentRatio = 1.0;
2378 0 : if (!coolingAirFlowIsAutosized) {
2379 0 : airFlowAdjustmentRatio =
2380 0 : this->m_MaxCoolAirVolFlow /
2381 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2382 0 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2383 : }
2384 0 : this->m_MaxNoCoolHeatAirVolFlow =
2385 0 : airFlowAdjustmentRatio * state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1);
2386 : }
2387 : }
2388 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2389 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
2390 0 : Real64 airFlowAdjustmentRatio = 1.0;
2391 0 : if (!heatingAirFlowIsAutosized) {
2392 0 : airFlowAdjustmentRatio =
2393 0 : this->m_MaxHeatAirVolFlow /
2394 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2395 0 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2396 : }
2397 0 : if (this->m_CoolCoilExists) {
2398 0 : this->m_MaxNoCoolHeatAirVolFlow =
2399 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
2400 : airFlowAdjustmentRatio *
2401 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1));
2402 : } else {
2403 0 : this->m_MaxNoCoolHeatAirVolFlow =
2404 0 : airFlowAdjustmentRatio *
2405 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1);
2406 : }
2407 : }
2408 : }
2409 : }
2410 : }
2411 :
2412 : // Change the Volume Flow Rates to Mass Flow Rates
2413 86 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
2414 86 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
2415 86 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2416 86 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2417 86 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2418 86 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2419 86 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2420 :
2421 : // initialize multi-speed coils
2422 86 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) ||
2423 84 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
2424 6 : if (this->m_NumOfSpeedCooling > 0) {
2425 6 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2426 6 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2427 6 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2428 : }
2429 :
2430 6 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2431 6 : if (MSHPIndex > -1) {
2432 22 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1; --Iter) {
2433 20 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2434 10 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2435 10 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2436 : }
2437 : }
2438 : }
2439 :
2440 6 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2441 : blankString,
2442 6 : this->m_CoolingCoilIndex,
2443 : HVAC::FanOp::Invalid, // Invalid instead of off?
2444 : HVAC::CompressorOp::Off,
2445 : 0.0,
2446 : 1,
2447 : 0.0,
2448 : 0.0,
2449 : 0.0,
2450 : 0.0); // conduct the sizing operation in the VS WSHP
2451 6 : if (this->m_NumOfSpeedCooling != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds) {
2452 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2453 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2454 0 : ShowFatalError(state,
2455 0 : format("Cooling coil = {}: {}",
2456 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).VarSpeedCoilType,
2457 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).Name));
2458 : }
2459 6 : state.dataSize->DXCoolCap = VariableSpeedCoils::GetCoilCapacityVariableSpeed(
2460 6 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
2461 6 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2462 6 : if (this->m_DXHeatingCoil) {
2463 3 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2464 : }
2465 :
2466 61 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2467 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2468 55 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2469 20 : this->m_MSCoolingSpeedRatio[Iter] =
2470 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2471 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedCooling);
2472 10 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * this->m_MSCoolingSpeedRatio[Iter];
2473 10 : this->m_CoolMassFlowRate[Iter] = this->MaxCoolAirMassFlow * this->m_MSCoolingSpeedRatio[Iter];
2474 : } else {
2475 90 : this->m_CoolVolumeFlowRate[Iter] =
2476 45 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter);
2477 45 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2478 : // this is divided by the system max air flow, not the cooling coil max air flow, doesn't seem correct
2479 45 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2480 : }
2481 : }
2482 :
2483 6 : if (MSHPIndex > -1) {
2484 2 : this->m_MaxNoCoolHeatAirVolFlow =
2485 2 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2486 2 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2487 2 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2488 4 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2489 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2490 : }
2491 :
2492 80 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
2493 : // mine data from heat exchanger assisted cooling coil
2494 : // Get DX heat exchanger assisted cooling coil index
2495 1 : int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilType_Num;
2496 1 : if (childCCType_Num == HVAC::CoilDX_Cooling) {
2497 0 : int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilIndex;
2498 0 : if (childCCIndex < 0) {
2499 0 : ShowWarningError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
2500 0 : ShowFatalError(state, "No cooling coil = Coil:Cooling:DX found.");
2501 0 : ErrFound = true;
2502 : }
2503 0 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
2504 0 : this->m_NumOfSpeedCooling = newCoil.performance.normalMode.speeds.size();
2505 0 : if (this->m_NumOfSpeedCooling > 0) {
2506 0 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2507 0 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2508 0 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2509 : }
2510 :
2511 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2512 0 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2513 0 : if (MSHPIndex > -1) {
2514 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2515 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2516 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2517 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2518 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2519 : }
2520 : }
2521 : }
2522 :
2523 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2524 0 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2525 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2526 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2527 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2528 : }
2529 :
2530 : // Use discrete/continuous control algorithm regardless of number of speeds
2531 0 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2532 0 : this->m_DiscreteSpeedCoolingCoil = true;
2533 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2534 0 : this->m_ContSpeedCoolingCoil = true;
2535 : }
2536 :
2537 0 : newCoil.size(state);
2538 0 : if (MSHPIndex == -1) {
2539 0 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2540 0 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2541 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2542 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2543 0 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2544 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2545 : } else {
2546 0 : this->m_MSCoolingSpeedRatio[Iter] =
2547 0 : this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2548 : }
2549 : }
2550 : }
2551 :
2552 0 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2553 0 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2554 0 : if (this->m_HeatPump) EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2555 :
2556 0 : if (MSHPIndex > -1) {
2557 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2558 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2559 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2560 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2561 0 : this->m_CoolVolumeFlowRate[Iter] =
2562 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2563 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2564 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2565 : }
2566 0 : this->m_MaxNoCoolHeatAirVolFlow =
2567 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2568 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2569 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2570 0 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2571 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2572 : }
2573 : }
2574 79 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2575 6 : if (this->m_NumOfSpeedCooling > 0) {
2576 6 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2577 6 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2578 6 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2579 : }
2580 :
2581 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2582 6 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2583 6 : if (MSHPIndex > -1) {
2584 9 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2585 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2586 6 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2587 4 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2588 4 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2589 : }
2590 : }
2591 : }
2592 :
2593 : // mine capacity from Coil:Cooling:DX object
2594 6 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
2595 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2596 6 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2597 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2598 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2599 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2600 : }
2601 :
2602 : // Use discrete/continuous control algorithm regardless of number of speeds
2603 6 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2604 6 : this->m_DiscreteSpeedCoolingCoil = true;
2605 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2606 0 : this->m_ContSpeedCoolingCoil = true;
2607 : }
2608 :
2609 6 : newCoil.size(state);
2610 6 : if (MSHPIndex == -1) {
2611 : // Gotta loop backwards since we may try to access the last element when there are no fans
2612 8 : for (Iter = this->m_NumOfSpeedCooling; Iter >= 1; --Iter) {
2613 5 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2614 5 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2615 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2616 5 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2617 1 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2618 : } else {
2619 4 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2620 : }
2621 : }
2622 : }
2623 :
2624 6 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2625 6 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2626 6 : if (this->m_HeatPump) EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2627 :
2628 6 : if (MSHPIndex > -1) {
2629 9 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2630 6 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2631 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2632 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2633 12 : this->m_CoolVolumeFlowRate[Iter] =
2634 6 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2635 6 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2636 6 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2637 : }
2638 3 : this->m_MaxNoCoolHeatAirVolFlow =
2639 3 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2640 3 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2641 3 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2642 3 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2643 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2644 : }
2645 :
2646 73 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2647 8 : if (this->m_NumOfSpeedCooling > 0) {
2648 8 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2649 8 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2650 8 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2651 : }
2652 :
2653 : // 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
2654 : // system ran prior to this one)
2655 16 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
2656 16 : EqSizing.CoolingAirVolFlow *
2657 8 : state.dataEnvrn->StdRhoAir; // doesn't matter what this value is since only coil size is needed and CompressorOn = 0 here
2658 8 : DXCoils::SimDXCoilMultiSpeed(state, blankString, 1.0, 1.0, this->m_CoolingCoilIndex, 0, HVAC::FanOp::Invalid, HVAC::CompressorOp::Off);
2659 8 : if (!HardSizeNoDesRun && EqSizing.Capacity) {
2660 : // do nothing, the vars EqSizing.DesCoolingLoad and DataSizing::DXCoolCap are already set earlier and the values could be max of the
2661 : // cooling and heating autosized values. Thus resetting them here to user specified value may not be the design size used else where
2662 : } else {
2663 14 : state.dataSize->DXCoolCap =
2664 7 : DXCoils::GetCoilCapacityByIndexType(state, this->m_CoolingCoilIndex, this->m_CoolingCoilType_Num, ErrFound);
2665 7 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2666 : }
2667 8 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2668 :
2669 8 : if (MSHPIndex > -1) {
2670 : // use reverse order since we divide by CoolVolumeFlowRate(max)
2671 16 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2672 11 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2673 8 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2674 8 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2675 22 : this->m_CoolVolumeFlowRate[Iter] =
2676 11 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2677 11 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2678 11 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2679 : }
2680 5 : this->m_MaxNoCoolHeatAirVolFlow =
2681 5 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2682 5 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2683 5 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2684 3 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2685 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2686 : } else {
2687 9 : for (Iter = this->m_NumOfSpeedCooling; Iter > 0; --Iter) {
2688 6 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * Iter / this->m_NumOfSpeedCooling;
2689 6 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2690 6 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2691 : }
2692 3 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2693 3 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2694 : }
2695 65 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2696 7 : if (this->m_NumOfSpeedCooling > 0) {
2697 0 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2698 0 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2699 0 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2700 : }
2701 7 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2702 :
2703 7 : if (MSHPIndex > -1) {
2704 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2705 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2706 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2707 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2708 0 : this->m_CoolVolumeFlowRate[Iter] =
2709 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2710 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2711 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2712 : }
2713 0 : this->m_MaxNoCoolHeatAirVolFlow =
2714 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2715 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2716 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2717 7 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2718 7 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2719 : }
2720 : }
2721 :
2722 86 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2723 80 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2724 9 : if (this->m_NumOfSpeedHeating > 0) {
2725 9 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2726 9 : if (this->m_HeatMassFlowRate.empty()) this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2727 9 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2728 : }
2729 :
2730 9 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2731 :
2732 9 : if (MSHPIndex > -1) {
2733 : // use reverse order since we divide by HeatVolumeFlowRate(max)
2734 28 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2735 19 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2736 4 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint &&
2737 0 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2738 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage)) {
2739 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2740 : } else {
2741 4 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2742 4 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2743 : }
2744 : } else {
2745 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2746 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2747 15 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] < 1.0 &&
2748 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
2749 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2750 0 : ShowContinueError(
2751 0 : state, format("Design specification object = {}", state.dataUnitarySystems->designSpecMSHP[MSHPIndex].name));
2752 0 : ShowContinueError(state,
2753 : "When control type = SetPointBased the outlet air temperature must change with coil capacity, if "
2754 : "air flow also changes outlet air temperature will be relatively constant.");
2755 0 : ShowContinueError(
2756 : state,
2757 0 : format("Speed {} Supply Air Flow Ratio During Heating Operation will be set = 1.0 and the simulation continues",
2758 : Iter));
2759 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2760 : }
2761 : }
2762 : }
2763 38 : this->m_HeatVolumeFlowRate[Iter] =
2764 19 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2765 19 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2766 19 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2767 : }
2768 9 : if (this->m_CoolCoilExists) {
2769 1 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2770 1 : this->m_MaxNoCoolHeatAirVolFlow =
2771 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2772 1 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2773 1 : this->MaxNoCoolHeatAirMassFlow =
2774 1 : min(this->MaxNoCoolHeatAirMassFlow,
2775 1 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2776 1 : this->m_NoLoadAirFlowRateRatio =
2777 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2778 : } else {
2779 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2780 : }
2781 8 : } else if (MSHPIndex > -1) {
2782 8 : this->m_MaxNoCoolHeatAirVolFlow =
2783 8 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2784 8 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2785 8 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2786 : } else {
2787 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2788 : }
2789 : }
2790 77 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
2791 76 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2792 4 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2793 4 : if (MSHPIndex > -1) {
2794 33 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2795 30 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2796 20 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2797 20 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2798 : }
2799 : }
2800 : }
2801 :
2802 4 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2803 : blankString,
2804 4 : this->m_HeatingCoilIndex,
2805 : HVAC::FanOp::Invalid,
2806 : HVAC::CompressorOp::Off,
2807 : 0.0,
2808 : 1,
2809 : 0.0,
2810 : 0.0,
2811 : 0.0,
2812 : 0.0); // conduct the sizing operation in the VS WSHP
2813 :
2814 4 : if (this->m_NumOfSpeedHeating != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds) {
2815 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2816 0 : ShowContinueError(state, "Number of heating speeds does not match coil object.");
2817 0 : ShowFatalError(state,
2818 0 : format("Heating coil = {}: {}",
2819 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).VarSpeedCoilType,
2820 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).Name));
2821 : }
2822 :
2823 4 : if (this->m_NumOfSpeedHeating > 0) {
2824 4 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2825 4 : if (this->m_HeatMassFlowRate.empty()) this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2826 4 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2827 : }
2828 :
2829 39 : for (Iter = this->m_NumOfSpeedHeating; Iter >= 1; --Iter) {
2830 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2831 35 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2832 : // SpeedRatio is only used in OnOff fan and should represent the ratio of flow to fan max flow
2833 20 : this->m_MSHeatingSpeedRatio[Iter] =
2834 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2835 10 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedHeating);
2836 10 : this->m_HeatVolumeFlowRate[Iter] = this->m_MaxHeatAirVolFlow * this->m_MSHeatingSpeedRatio[Iter];
2837 10 : this->m_HeatMassFlowRate[Iter] = this->MaxHeatAirMassFlow * this->m_MSHeatingSpeedRatio[Iter];
2838 : } else {
2839 50 : this->m_HeatVolumeFlowRate[Iter] =
2840 25 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter);
2841 25 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2842 25 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2843 : // this is divided by the system max air flow, not the heating coil max air flow
2844 25 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2845 : } else {
2846 : // if there is no fan this doesn't matter? Should calculate SpeedRatio in fan model? and get rid of SpeedRatio variable?
2847 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_HeatVolumeFlowRate[this->m_NumOfSpeedHeating];
2848 : }
2849 : }
2850 : }
2851 :
2852 4 : if (this->m_CoolCoilExists && this->m_NumOfSpeedHeating > 0) {
2853 8 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2854 3 : this->m_MaxNoCoolHeatAirVolFlow =
2855 3 : min(this->m_MaxNoCoolHeatAirVolFlow,
2856 3 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2857 3 : this->MaxNoCoolHeatAirMassFlow =
2858 3 : min(this->MaxNoCoolHeatAirMassFlow,
2859 3 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2860 3 : this->m_NoLoadAirFlowRateRatio =
2861 3 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2862 1 : } else if (this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2863 0 : this->m_MaxNoCoolHeatAirVolFlow =
2864 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2865 0 : this->MaxNoCoolHeatAirMassFlow =
2866 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2867 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2868 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2869 1 : } else if (!this->m_CoolVolumeFlowRate.empty()) {
2870 : // what the heck is this next line? should be min of min cooling and min heating flow rates?
2871 : // this is calculated above so likely not even needed here, just have to be sure it's always calculated
2872 1 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
2873 1 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
2874 1 : this->m_sysType == SysType::PackagedWSHP) {
2875 0 : if (!this->m_MultiOrVarSpeedCoolCoil && !this->m_MultiOrVarSpeedHeatCoil) {
2876 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2877 : }
2878 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2879 : } else {
2880 : // this should be min of min cooling and min heating flow rates?
2881 1 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
2882 : }
2883 1 : this->m_NoLoadAirFlowRateRatio =
2884 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2885 : } else {
2886 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2887 : }
2888 0 : } else if (MSHPIndex > -1) {
2889 0 : this->m_MaxNoCoolHeatAirVolFlow =
2890 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2891 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2892 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2893 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2894 : } else {
2895 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2896 : }
2897 : }
2898 86 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2899 : // pass air flow rate to zone water coil
2900 6 : if (state.dataSize->CurZoneEqNum > 0) {
2901 4 : WaterCoils::SetCoilDesFlow(state,
2902 4 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
2903 4 : this->m_HeatingCoilName,
2904 : this->m_MaxHeatAirVolFlow,
2905 4 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
2906 : }
2907 :
2908 6 : if (this->m_NumOfSpeedHeating > 0) {
2909 0 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2910 0 : if (this->m_HeatMassFlowRate.empty()) this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2911 0 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2912 : }
2913 :
2914 6 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2915 6 : if (MSHPIndex > -1) {
2916 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2917 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2918 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2919 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2920 : }
2921 0 : this->m_HeatVolumeFlowRate[Iter] =
2922 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2923 0 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2924 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2925 : }
2926 0 : if (this->m_CoolCoilExists) {
2927 0 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > 0) {
2928 0 : this->m_MaxNoCoolHeatAirVolFlow =
2929 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
2930 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2931 0 : this->MaxNoCoolHeatAirMassFlow =
2932 0 : min(this->MaxNoCoolHeatAirMassFlow,
2933 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2934 0 : this->m_NoLoadAirFlowRateRatio =
2935 0 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2936 : } else {
2937 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
2938 0 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
2939 0 : this->m_NoLoadAirFlowRateRatio =
2940 0 : min(this->m_NoLoadAirFlowRateRatio, (this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate));
2941 : }
2942 : } else {
2943 0 : this->m_MaxNoCoolHeatAirVolFlow =
2944 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2945 0 : this->MaxNoCoolHeatAirMassFlow =
2946 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2947 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2948 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2949 : }
2950 : }
2951 : }
2952 :
2953 : // Not sure if this may be needed for special cases
2954 86 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow < 0.0) {
2955 0 : if (!state.dataSize->SysSizingRunDone) {
2956 0 : int BranchNum = BranchInputManager::GetAirBranchIndex(state, "AirloopHVAC:UnitarySystem", this->Name);
2957 0 : BranchFanFlow = 0.0;
2958 0 : if (BranchNum > 0.0) {
2959 0 : std::string FanType = "";
2960 0 : std::string FanName = "";
2961 0 : BranchInputManager::GetBranchFanTypeName(state, BranchNum, FanType, FanName, ErrFound);
2962 0 : if (!ErrFound) {
2963 0 : BranchFanFlow = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
2964 : }
2965 0 : }
2966 0 : if (BranchFanFlow > 0.0) {
2967 0 : this->m_MaxCoolAirVolFlow = BranchFanFlow;
2968 : } else {
2969 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
2970 0 : if (SystemFlow > 0.0) {
2971 0 : this->m_MaxCoolAirVolFlow = SystemFlow;
2972 : } else {
2973 : // what do I do?
2974 : }
2975 : }
2976 : }
2977 : }
2978 :
2979 : // why is this here?
2980 86 : this->m_SenLoadLoss = 0.0;
2981 86 : if (this->m_Humidistat) {
2982 3 : this->m_LatLoadLoss = 0.0;
2983 : }
2984 :
2985 86 : switch (this->m_sysType) {
2986 6 : case SysType::PackagedAC:
2987 : case SysType::PackagedHP:
2988 6 : PrintFlag = false;
2989 6 : break;
2990 80 : default:
2991 80 : break;
2992 : }
2993 86 : if (this->m_CoolCoilExists) {
2994 68 : SizingMethod = HVAC::CoolingCapacitySizing;
2995 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
2996 68 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2997 14 : WaterCoils::SimulateWaterCoilComponents(
2998 14 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2999 7 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3000 14 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
3001 7 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3002 7 : state.dataSize->DataFractionUsedForSizing = 1.0;
3003 7 : SizingMethod = HVAC::AutoCalculateSizing;
3004 7 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3005 61 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
3006 : std::string HXCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(
3007 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3008 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
3009 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound, true);
3010 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(
3011 0 : state, blankString, true, HVAC::CompressorOp::On, 1.0, this->m_CoolingCoilIndex, HVAC::FanOp::Cycling, false, 1.0, false);
3012 0 : state.dataSize->DataConstantUsedForSizing =
3013 0 : WaterCoils::GetWaterCoilCapacity(state, Util::makeUPPER(HVAC::cAllCoilTypes(ActualCoolCoilType)), HXCoilName, ErrFound);
3014 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3015 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3016 0 : SizingMethod = HVAC::AutoCalculateSizing;
3017 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3018 61 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3019 2 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3020 : blankString,
3021 2 : this->m_CoolingCoilIndex,
3022 : this->m_CoolingCoilSensDemand,
3023 : this->m_CoolingCoilLatentDemand,
3024 : HVAC::FanOp::Invalid,
3025 : HVAC::CompressorOp::Off,
3026 : 0.0,
3027 : FirstHVACIteration);
3028 2 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3029 2 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3030 2 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3031 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3032 2 : SizingMethod = HVAC::AutoCalculateSizing;
3033 2 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3034 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP)
3035 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3036 : // airflow sizing with multispeed fan
3037 4 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3038 2 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3039 2 : if (this->m_NumOfSpeedCooling > 1) {
3040 1 : int FanIndex = this->m_FanIndex;
3041 3 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
3042 2 : if (this->m_DesignSpecMSHPIndex > -1) {
3043 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] ==
3044 : DataSizing::AutoSize) {
3045 2 : this->m_CoolVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedCooling) * AirFlowRate;
3046 : } else {
3047 0 : this->m_CoolVolumeFlowRate[i] =
3048 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
3049 : }
3050 : } else {
3051 0 : this->m_CoolVolumeFlowRate[i] =
3052 0 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3053 : }
3054 2 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3055 : }
3056 : }
3057 59 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
3058 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
3059 : blankString,
3060 0 : this->m_CoolingCoilIndex,
3061 : this->MaxCoolAirMassFlow,
3062 : this->m_FanOpMode,
3063 : FirstHVACIteration,
3064 0 : this->m_InitHeatPump,
3065 : 0.0,
3066 : 0.0,
3067 : HVAC::CompressorOp::Off,
3068 : 0.0);
3069 0 : state.dataSize->DataConstantUsedForSizing =
3070 0 : WaterToAirHeatPump::GetCoilCapacity(state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3071 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3072 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3073 0 : SizingMethod = HVAC::AutoCalculateSizing;
3074 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
3075 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple)
3076 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3077 59 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
3078 0 : PackagedThermalStorageCoil::SimTESCoil(
3079 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, 0.0);
3080 0 : PackagedThermalStorageCoil::GetTESCoilCoolingCapacity(
3081 0 : state, this->m_CoolingCoilName, state.dataSize->DataConstantUsedForSizing, ErrFound, CompType);
3082 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3083 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3084 0 : SizingMethod = HVAC::AutoCalculateSizing;
3085 : }
3086 :
3087 68 : TempSize = this->m_DesignCoolingCapacity;
3088 68 : state.dataSize->DataFlowUsedForSizing = this->m_MaxCoolAirVolFlow;
3089 68 : SizingString = "Nominal Cooling Capacity [W]";
3090 68 : bool errorsFound = false;
3091 68 : CoolingCapacitySizer sizerCoolingCapacity;
3092 68 : sizerCoolingCapacity.overrideSizingString(SizingString);
3093 68 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3094 68 : this->m_DesignCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
3095 68 : state.dataSize->DataConstantUsedForSizing = 0.0;
3096 68 : state.dataSize->DataFractionUsedForSizing = 0.0;
3097 68 : state.dataSize->DataFlowUsedForSizing = 0.0;
3098 68 : }
3099 :
3100 86 : if (this->m_HeatCoilExists) {
3101 52 : SizingMethod = HVAC::HeatingCapacitySizing;
3102 :
3103 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3104 52 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3105 12 : WaterCoils::SimulateWaterCoilComponents(
3106 12 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3107 6 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3108 12 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
3109 6 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3110 6 : state.dataSize->DataFractionUsedForSizing = 1.0;
3111 6 : SizingMethod = HVAC::AutoCalculateSizing;
3112 6 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3113 46 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3114 2 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3115 : blankString,
3116 2 : this->m_HeatingCoilIndex,
3117 : this->m_HeatingCoilSensDemand,
3118 : dummy,
3119 : HVAC::FanOp::Invalid, // Invalid instead of off?
3120 : HVAC::CompressorOp::Off,
3121 : 0.0,
3122 : FirstHVACIteration);
3123 2 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3124 2 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3125 2 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3126 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3127 2 : SizingMethod = HVAC::AutoCalculateSizing;
3128 2 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3129 2 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3130 : // adjusted cooling coil capacity
3131 2 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3132 : blankString,
3133 2 : this->m_CoolingCoilIndex,
3134 : this->m_CoolingCoilSensDemand,
3135 : this->m_CoolingCoilLatentDemand,
3136 : HVAC::FanOp::Invalid, // Invalid instead of off?
3137 : HVAC::CompressorOp::Off,
3138 : 0.0,
3139 : FirstHVACIteration);
3140 2 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3141 2 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3142 2 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3143 : }
3144 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3145 2 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3146 : // airflow sizing with multispeed fan
3147 4 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3148 2 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3149 2 : if (this->m_NumOfSpeedHeating > 1) {
3150 1 : int FanIndex = this->m_FanIndex;
3151 3 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
3152 2 : if (this->m_DesignSpecMSHPIndex > -1) {
3153 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] ==
3154 : DataSizing::AutoSize) {
3155 2 : this->m_HeatVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedHeating) * AirFlowRate;
3156 : } else {
3157 0 : this->m_HeatVolumeFlowRate[i] =
3158 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
3159 : }
3160 : } else {
3161 0 : this->m_HeatVolumeFlowRate[i] =
3162 0 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3163 : }
3164 2 : this->m_HeatMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3165 : }
3166 : }
3167 : }
3168 :
3169 52 : TempSize = this->m_DesignHeatingCapacity;
3170 52 : SizingString = "Nominal Heating Capacity [W]";
3171 52 : if (state.dataSize->CurSysNum > 0)
3172 3 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
3173 : false; // set to false to allow calculation of parent object heating capacity
3174 52 : bool errorsFound = false;
3175 52 : HeatingCapacitySizer sizerHeatingCapacity;
3176 52 : sizerHeatingCapacity.overrideSizingString(SizingString);
3177 52 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3178 52 : TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3179 52 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) state.dataSize->DXCoolCap = TempSize;
3180 52 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
3181 52 : this->m_DesignHeatingCapacity = TempSize;
3182 52 : state.dataSize->DataConstantUsedForSizing = 0.0;
3183 52 : state.dataSize->DataFractionUsedForSizing = 0.0;
3184 52 : state.dataSize->DataHeatSizeRatio = 1.0;
3185 52 : }
3186 :
3187 86 : if (!HardSizeNoDesRun && (EqSizing.Capacity && EqSizing.DesHeatingLoad > 0.0)) {
3188 : // vars EqSizing.DesHeatingLoad is already set earlier and supplemental heating coil should
3189 : // be sized to design value instead of user specified value if HardSizeNoDesRun is false
3190 4 : state.dataSize->UnitaryHeatCap = EqSizing.DesHeatingLoad;
3191 :
3192 : } else {
3193 82 : state.dataSize->UnitaryHeatCap = this->m_DesignHeatingCapacity;
3194 : }
3195 :
3196 86 : if (this->m_sysType == SysType::PackagedWSHP) {
3197 2 : PrintFlag = true;
3198 : }
3199 :
3200 86 : if ((this->m_HeatCoilExists || this->m_SuppCoilExists) && this->m_ControlType != UnitarySysCtrlType::CCMASHRAE) {
3201 50 : TempSize = this->DesignMaxOutletTemp;
3202 50 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
3203 50 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3204 2 : PrintFlag = true;
3205 2 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
3206 2 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
3207 2 : }
3208 50 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3209 50 : this->DesignMaxOutletTemp = sizerMaxHeaterOutTemp.size(state, TempSize, ErrFound);
3210 50 : }
3211 :
3212 86 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3213 2 : PrintFlag = false;
3214 : }
3215 :
3216 86 : if (this->m_SuppCoilExists) {
3217 13 : switch (this->m_sysType) {
3218 2 : case SysType::PackagedWSHP:
3219 : case SysType::PackagedHP:
3220 2 : if (this->m_HVACSizingIndex <= 0) EqSizing.HeatingCapacity = false; // ensure PTHP supplemental heating coil sizes to load
3221 2 : break;
3222 11 : default:
3223 11 : break;
3224 : }
3225 :
3226 13 : TempSize = this->m_DesignSuppHeatingCapacity;
3227 13 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
3228 13 : if (TempSize == DataSizing::AutoSize) {
3229 5 : IsAutoSize = true;
3230 5 : if (this->m_sysType == SysType::Unitary) PrintFlag = false;
3231 5 : bool errorsFound = false;
3232 5 : HeatingCapacitySizer sizerHeatingCapacity;
3233 5 : sizerHeatingCapacity.overrideSizingString(SizingString);
3234 5 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3235 5 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3236 5 : }
3237 : // logic here isn't accurate. Replicating temporarily to minimize diffs in AutoSizingLibrary refactor
3238 13 : TempSize = this->m_DesignSuppHeatingCapacity;
3239 :
3240 13 : if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && IsAutoSize) {
3241 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_DesignSuppHeatingCapacity, this->m_DesignCoolingCapacity);
3242 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3243 0 : TempSize = DataSizing::AutoSize;
3244 : // pass design size to supplemental heater
3245 0 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3246 13 : } else if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
3247 0 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3248 : } else {
3249 13 : if (state.dataSize->CurZoneEqNum > 0) {
3250 13 : state.dataSize->SuppHeatCap = saveRawHeatingCapacity;
3251 : } else {
3252 0 : state.dataSize->SuppHeatCap = this->m_DesignHeatingCapacity;
3253 : }
3254 : }
3255 :
3256 13 : if (this->m_OKToPrintSizing &&
3257 13 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater))
3258 11 : PrintFlag = true;
3259 13 : state.dataSize->DataCoilIsSuppHeater = true;
3260 13 : bool errorsFound = false;
3261 13 : HeatingCapacitySizer sizerHeatingCapacity;
3262 13 : sizerHeatingCapacity.overrideSizingString(SizingString);
3263 13 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3264 13 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3265 13 : state.dataSize->DataConstantUsedForSizing = 0.0;
3266 13 : state.dataSize->DataFractionUsedForSizing = 0.0;
3267 13 : state.dataSize->DataCoilIsSuppHeater = false;
3268 : }
3269 :
3270 : // register plant flow rate. Not sure this has ever been tested.
3271 86 : if (this->m_HeatRecActive) {
3272 2 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->m_HeatRecoveryInletNodeNum, this->m_DesignHRWaterVolumeFlow);
3273 : }
3274 :
3275 : // Set flow rate for unitary system with no fan
3276 86 : if (state.dataSize->CurOASysNum == 0 && state.dataSize->CurZoneEqNum == 0 && this->m_DesignFanVolFlowRate <= 0.0) {
3277 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3278 0 : if (SystemFlow > 0.0) {
3279 0 : this->m_DesignFanVolFlowRate = SystemFlow;
3280 : } else {
3281 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3282 : }
3283 0 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
3284 : }
3285 :
3286 : // Moved from InitLoadBasedControl
3287 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
3288 86 : if (this->m_AirLoopEquipment && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
3289 25 : int NumAirLoopZones = 0; // number of zone inlet nodes in an air loop
3290 25 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
3291 1 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = true;
3292 1 : NumAirLoopZones =
3293 1 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
3294 1 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3295 : // zone inlet nodes for cooling
3296 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
3297 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
3298 : // the data structure for the zones inlet nodes has not been filled
3299 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3300 : }
3301 : }
3302 : // zone inlet nodes for heating
3303 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
3304 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
3305 : // the data structure for the zones inlet nodes has not been filled
3306 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3307 : }
3308 : }
3309 : }
3310 : }
3311 25 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady) {
3312 1 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
3313 1 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3314 0 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
3315 0 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3316 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == this->ControlZoneNum) {
3317 0 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
3318 0 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3319 : }
3320 : }
3321 1 : if (SumOfMassFlowRateMax != 0.0) {
3322 0 : if (state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
3323 0 : this->ControlZoneMassFlowFrac =
3324 0 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
3325 : } else {
3326 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3327 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
3328 0 : this->ControlZoneMassFlowFrac = 1.0;
3329 : }
3330 0 : this->m_SmallLoadTolerance = 5.0 / this->ControlZoneMassFlowFrac; // adjust 5W load tolerance by control zone fraction
3331 0 : BaseSizer::reportSizerOutput(state,
3332 : this->UnitType,
3333 : this->Name,
3334 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
3335 : this->ControlZoneMassFlowFrac);
3336 : }
3337 : }
3338 25 : } else {
3339 61 : this->ControlZoneMassFlowFrac = 1.0;
3340 : }
3341 :
3342 : // should only report for those that allow SZVAV inputs, e.g., control type == CCMASHRAE
3343 86 : PrintFlag = true;
3344 :
3345 86 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3346 2 : bool SizingDesRunThisSys = false;
3347 2 : state.dataSize->DataZoneUsedForSizing = this->ControlZoneNum;
3348 2 : CheckThisZoneForSizing(state, state.dataSize->DataZoneUsedForSizing, SizingDesRunThisSys);
3349 :
3350 2 : capacityMultiplier = 0.5; // one-half of design zone load
3351 2 : if (SizingDesRunThisSys) {
3352 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesCoolLoad * capacityMultiplier;
3353 : } else {
3354 2 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignCoolingCapacity * capacityMultiplier;
3355 : }
3356 2 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3357 2 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3358 2 : ASHRAEMinSATCoolingSizer sizerASHRAEMinSATCooling;
3359 2 : std::string stringOverride = "Minimum Supply Air Temperature [C]";
3360 2 : if (state.dataGlobal->isEpJSON) stringOverride = "minimum_supply_air_temperature [C]";
3361 2 : sizerASHRAEMinSATCooling.overrideSizingString(stringOverride);
3362 2 : sizerASHRAEMinSATCooling.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3363 2 : this->DesignMinOutletTemp = sizerASHRAEMinSATCooling.size(state, this->DesignMinOutletTemp, ErrFound);
3364 :
3365 2 : if (SizingDesRunThisSys) {
3366 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesHeatLoad * capacityMultiplier;
3367 : } else {
3368 2 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignHeatingCapacity * capacityMultiplier;
3369 : }
3370 2 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3371 2 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3372 2 : ASHRAEMaxSATHeatingSizer sizerASHRAEMaxSATHeating;
3373 2 : stringOverride = "Maximum Supply Air Temperature [C]";
3374 2 : if (state.dataGlobal->isEpJSON) stringOverride = "maximum_supply_air_temperature [C]";
3375 2 : sizerASHRAEMaxSATHeating.overrideSizingString(stringOverride);
3376 2 : sizerASHRAEMaxSATHeating.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3377 2 : this->DesignMaxOutletTemp = sizerASHRAEMaxSATHeating.size(state, this->DesignMaxOutletTemp, ErrFound);
3378 :
3379 2 : state.dataSize->DataCapacityUsedForSizing = 0.0; // reset so other routines don't use this inadvertently
3380 2 : state.dataSize->DataFlowUsedForSizing = 0.0;
3381 2 : state.dataSize->DataZoneUsedForSizing = 0;
3382 :
3383 : // check that MaxNoCoolHeatAirVolFlow is less than both MaxCoolAirVolFlow and MaxHeatAirVolFlow
3384 2 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3385 2 : if (this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxCoolAirVolFlow || this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxHeatAirVolFlow) {
3386 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3387 0 : ShowContinueError(
3388 : state,
3389 : " For SingleZoneVAV control the No Load Supply Air Flow Rate must be less than both the cooling and heating supply "
3390 : "air flow rates.");
3391 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow) - 0.01;
3392 0 : ShowContinueError(
3393 : state,
3394 0 : format(" The SingleZoneVAV control No Load Supply Air Flow Rate is reset to {:.5T} and the simulation continues.",
3395 0 : this->m_MaxNoCoolHeatAirVolFlow));
3396 : }
3397 : }
3398 2 : }
3399 :
3400 86 : state.dataUnitarySystems->CoolingLoad = TempCoolingLoad;
3401 86 : state.dataUnitarySystems->HeatingLoad = TempHeatingLoad;
3402 : // if (++NumUnitarySystemsSized == NumUnitarySystem)
3403 : // UnitarySystemNumericFields.deallocate(); // remove temporary array for field names at end of sizing
3404 86 : } // namespace UnitarySystems
3405 :
3406 203 : void UnitarySys::processInputSpec(EnergyPlusData &state,
3407 : const UnitarySysInputSpec &input_data,
3408 : int sysNum,
3409 : bool &errorsFound,
3410 : bool const ZoneEquipment,
3411 : int const ZoneOAUnitNum)
3412 : {
3413 : static constexpr std::string_view routineName = "UnitarySys::processInputSpec";
3414 :
3415 : using namespace OutputReportPredefined;
3416 :
3417 : static constexpr std::string_view unitarySysHeatPumpPerformanceObjectType("UnitarySystemPerformance:Multispeed");
3418 :
3419 203 : std::string const &cCurrentModuleObject = input_data.system_type;
3420 : DataLoopNode::ConnectionObjectType objType = static_cast<DataLoopNode::ConnectionObjectType>(
3421 203 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(input_data.system_type)));
3422 203 : std::string const &thisObjectName = input_data.name;
3423 :
3424 203 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisObjectName};
3425 :
3426 203 : this->Name = Util::makeUPPER(thisObjectName);
3427 203 : sysNum = getUnitarySystemIndex(state, thisObjectName);
3428 203 : this->m_UnitarySysNum = sysNum;
3429 :
3430 203 : if (ZoneEquipment) {
3431 142 : this->m_IsZoneEquipment = true;
3432 : }
3433 203 : if (state.dataUnitarySystems->getInputOnceFlag) {
3434 208 : this->AirInNode = NodeInputManager::GetOnlySingleNode(state,
3435 104 : input_data.air_inlet_node_name,
3436 : errorsFound,
3437 : objType,
3438 : thisObjectName,
3439 : DataLoopNode::NodeFluidType::Air,
3440 : DataLoopNode::ConnectionType::Inlet,
3441 : NodeInputManager::CompFluidStream::Primary,
3442 : DataLoopNode::ObjectIsParent);
3443 : } else {
3444 99 : this->AirInNode = Util::FindItemInList(input_data.air_inlet_node_name, state.dataLoopNodes->NodeID);
3445 : }
3446 :
3447 203 : if (state.dataUnitarySystems->getInputOnceFlag) {
3448 208 : this->AirOutNode = NodeInputManager::GetOnlySingleNode(state,
3449 104 : input_data.air_outlet_node_name,
3450 : errorsFound,
3451 : objType,
3452 : thisObjectName,
3453 : DataLoopNode::NodeFluidType::Air,
3454 : DataLoopNode::ConnectionType::Outlet,
3455 : NodeInputManager::CompFluidStream::Primary,
3456 : DataLoopNode::ObjectIsParent);
3457 : } else {
3458 99 : this->AirOutNode = Util::FindItemInList(input_data.air_outlet_node_name, state.dataLoopNodes->NodeID);
3459 : }
3460 :
3461 : // need to read in all information needed to SetupOutputVariable in setupAllOutputVars
3462 : // as soon as all systems are read in, regardless if all information is available, reports will be set up.
3463 : // make sure we have all the information needed to process reports (see IF blocks in setupAllOutputVars).
3464 : // all coil types, which comps exist, control type, heat recovery active, cooling coil index.
3465 203 : bool errFlag = false;
3466 203 : bool PrintMessage = false;
3467 :
3468 203 : if (!input_data.design_specification_multispeed_object_type.empty() && !input_data.design_specification_multispeed_object_name.empty()) {
3469 45 : this->m_DesignSpecMultispeedHPType = input_data.design_specification_multispeed_object_type;
3470 45 : this->m_DesignSpecMultispeedHPName = input_data.design_specification_multispeed_object_name;
3471 45 : DesignSpecMSHP thisDesignSpec;
3472 45 : this->m_CompPointerMSHP = thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, this->m_DesignSpecMultispeedHPName);
3473 45 : this->m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, this->m_DesignSpecMultispeedHPName);
3474 45 : }
3475 :
3476 : // these are needed for call from GetOASysNumHeat(Cool)ingCoils
3477 203 : this->m_HeatingCoilName = input_data.heating_coil_name;
3478 203 : this->m_HeatingCoilTypeName = input_data.heating_coil_object_type;
3479 203 : if (!this->m_HeatingCoilTypeName.empty()) {
3480 130 : this->m_HeatCoilExists = true;
3481 : }
3482 203 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num == 0) {
3483 64 : if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:VariableSpeed")) {
3484 4 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingAirToAirVariableSpeed;
3485 60 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:MultiSpeed")) {
3486 3 : this->m_HeatingCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
3487 57 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Water")) {
3488 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWater;
3489 5 : if (this->m_DesignSpecMSHPIndex > -1) {
3490 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
3491 1 : if (this->m_NumOfSpeedHeating > 1) {
3492 0 : this->m_MultiSpeedHeatingCoil = true;
3493 0 : this->m_MultiOrVarSpeedHeatCoil = true;
3494 : }
3495 : }
3496 52 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Steam")) {
3497 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
3498 52 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:EquationFit")) {
3499 2 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPSimple;
3500 50 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation")) {
3501 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHP;
3502 50 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3503 1 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
3504 49 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric:MultiStage")) {
3505 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingElectric_MultiStage;
3506 44 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Gas:MultiStage")) {
3507 3 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingGas_MultiStage;
3508 55 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Fuel") ||
3509 55 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric") ||
3510 46 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Desuperheater")) {
3511 37 : this->m_HeatingCoilType_Num =
3512 37 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
3513 4 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:UserDefined")) {
3514 0 : this->m_HeatingCoilType_Num = HVAC::Coil_UserDefined;
3515 4 : } else if (this->m_HeatCoilExists) {
3516 4 : this->m_HeatingCoilType_Num =
3517 4 : DXCoils::GetCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag, PrintMessage);
3518 : }
3519 :
3520 64 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
3521 61 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
3522 56 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
3523 11 : this->m_MultiSpeedHeatingCoil = true;
3524 53 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
3525 52 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
3526 5 : this->m_VarSpeedHeatingCoil = true;
3527 : }
3528 : }
3529 :
3530 203 : this->m_CoolingCoilName = input_data.cooling_coil_name;
3531 203 : if (!input_data.cooling_coil_object_type.empty()) { // not required field
3532 170 : this->m_CoolCoilExists = true;
3533 : }
3534 : // Find the type of coil. do not print message since this may not be the correct coil type.
3535 203 : errFlag = false;
3536 203 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num == 0) {
3537 86 : if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:VariableSpeed")) {
3538 7 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
3539 79 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:MultiSpeed")) {
3540 8 : this->m_CoolingCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3541 71 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water")) {
3542 11 : this->m_IsDXCoil = false;
3543 11 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3544 11 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3545 11 : if (this->m_DesignSpecMSHPIndex > -1) {
3546 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3547 1 : if (this->m_NumOfSpeedCooling > 1) {
3548 1 : this->m_DiscreteSpeedCoolingCoil = true;
3549 1 : this->m_MultiOrVarSpeedCoolCoil = true;
3550 : }
3551 : }
3552 60 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water:DetailedGeometry")) {
3553 1 : this->m_IsDXCoil = false;
3554 1 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterDetailed;
3555 1 : if (this->m_DesignSpecMSHPIndex > -1) {
3556 0 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3557 0 : if (this->m_NumOfSpeedCooling > 1) {
3558 0 : this->m_DiscreteSpeedCoolingCoil = true;
3559 0 : this->m_MultiOrVarSpeedCoolCoil = true;
3560 : }
3561 : }
3562 59 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
3563 0 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
3564 59 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
3565 2 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3566 2 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3567 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
3568 0 : this->m_IsDXCoil = false;
3569 0 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3570 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3571 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:EquationFit")) {
3572 2 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPSimple;
3573 55 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation")) {
3574 0 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHP;
3575 55 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3576 1 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
3577 54 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed")) {
3578 45 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
3579 9 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoSpeed")) {
3580 3 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
3581 6 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:UserDefined")) {
3582 0 : this->m_IsDXCoil = false;
3583 0 : this->m_CoolingCoilType_Num = HVAC::Coil_UserDefined;
3584 6 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed:ThermalStorage")) {
3585 0 : this->m_CoolingCoilType_Num = HVAC::CoilDX_PackagedThermalStorageCooling;
3586 6 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX")) { // CoilCoolingDX
3587 6 : this->m_CoolingCoilType_Num = HVAC::CoilDX_Cooling;
3588 6 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
3589 6 : if (this->m_CoolingCoilIndex == -1) {
3590 0 : ShowFatalError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
3591 : } else {
3592 : // set variable speed coil flag as necessary
3593 6 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
3594 6 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
3595 6 : if (this->m_NumOfSpeedCooling > 1) {
3596 5 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
3597 5 : this->m_DiscreteSpeedCoolingCoil = true;
3598 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
3599 0 : this->m_ContSpeedCoolingCoil = true;
3600 : }
3601 5 : this->m_MultiOrVarSpeedCoolCoil = true;
3602 : }
3603 : }
3604 : }
3605 :
3606 86 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
3607 8 : this->m_DiscreteSpeedCoolingCoil = true;
3608 78 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
3609 77 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
3610 8 : this->m_ContSpeedCoolingCoil = true;
3611 : }
3612 : }
3613 :
3614 203 : if (!input_data.supplemental_heating_coil_object_type.empty()) {
3615 53 : this->m_SuppCoilExists = true;
3616 : }
3617 :
3618 203 : if (!input_data.supply_fan_object_type.empty() && !input_data.supply_fan_name.empty()) {
3619 142 : this->m_FanExists = true;
3620 : }
3621 :
3622 : constexpr static std::array<std::string_view, static_cast<int>(UnitarySysCtrlType::Num)> UnitarySysCtrlTypeNamesUC = {
3623 : "NONE", "LOAD", "SETPOINT", "SINGLEZONEVAV"};
3624 203 : this->m_ControlType = static_cast<UnitarySysCtrlType>(getEnumValue(UnitarySysCtrlTypeNamesUC, Util::makeUPPER(input_data.control_type)));
3625 203 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3626 8 : this->m_ValidASHRAECoolCoil = true;
3627 8 : this->m_ValidASHRAEHeatCoil = true;
3628 : }
3629 :
3630 203 : this->m_DesignHRWaterVolumeFlow = input_data.design_heat_recovery_water_flow_rate;
3631 203 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
3632 9 : this->m_HeatRecActive = true;
3633 : }
3634 :
3635 203 : errFlag = false;
3636 203 : if (!input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) {
3637 13 : this->OAMixerIndex = MixedAir::GetOAMixerIndex(state, input_data.oa_mixer_name);
3638 13 : ValidateComponent(state, input_data.oa_mixer_type, input_data.oa_mixer_name, errFlag, cCurrentModuleObject);
3639 13 : if (errFlag) {
3640 0 : ShowContinueError(state, format("specified in {} = \"{}\".", cCurrentModuleObject, input_data.oa_mixer_name));
3641 0 : errorsFound = true;
3642 0 : errFlag = false;
3643 : } else {
3644 13 : this->OAMixerExists = true;
3645 : // OANodeNums = outside air mixer node numbers, OANodeNums(4) = outside air mixer mixed air node
3646 13 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, input_data.oa_mixer_name, errFlag);
3647 13 : if (errFlag) {
3648 0 : ShowContinueError(state, format("that was specified in {} = {}", cCurrentModuleObject, input_data.oa_mixer_name));
3649 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
3650 0 : errorsFound = true;
3651 0 : errFlag = false;
3652 : } else {
3653 13 : this->m_OAMixerNodes[0] = OANodeNums(1); // inlet
3654 13 : this->m_OAMixerNodes[1] = OANodeNums(2); // relief
3655 13 : this->m_OAMixerNodes[2] = OANodeNums(3); // return
3656 13 : this->m_OAMixerNodes[3] = OANodeNums(4); // mixed
3657 : }
3658 13 : }
3659 380 : } else if ((input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) ||
3660 190 : (!input_data.oa_mixer_type.empty() && input_data.oa_mixer_name.empty())) {
3661 0 : ShowSevereError(state, format("Missing one of {} Outdoor Air Mixer inputs.", cCurrentModuleObject));
3662 0 : ShowContinueError(state, format("..OutdoorAir:Mixer type = {}", input_data.oa_mixer_type));
3663 0 : ShowContinueError(state, format("..OutdoorAir:Mixer name = {}", input_data.oa_mixer_name));
3664 0 : errorsFound = true;
3665 : }
3666 203 : this->m_HeatConvTol = input_data.heat_conv_tol;
3667 203 : this->m_CoolConvTol = input_data.cool_conv_tol;
3668 :
3669 : // Early calls to ATMixer don't have enough info to pass GetInput. Need to get the data next time through.
3670 203 : if (sysNum == -1 || !state.dataZoneEquip->ZoneEquipInputsFilled) {
3671 103 : return;
3672 : }
3673 :
3674 102 : this->m_CoolOutAirVolFlow = input_data.cooling_oa_flow_rate;
3675 102 : this->m_HeatOutAirVolFlow = input_data.heating_oa_flow_rate;
3676 102 : this->m_NoCoolHeatOutAirVolFlow = input_data.no_load_oa_flow_rate;
3677 :
3678 102 : if (ZoneEquipment) {
3679 72 : this->m_OKToPrintSizing = true;
3680 : }
3681 :
3682 102 : this->m_IterationMode.resize(3);
3683 :
3684 102 : std::string loc_m_CoolingSAFMethod = input_data.cooling_supply_air_flow_rate_method;
3685 102 : Real64 loc_m_CoolingSAFMethod_SAFlow = input_data.cooling_supply_air_flow_rate;
3686 102 : Real64 loc_m_CoolingSAFMethod_SAFlowPerFloorArea = input_data.cooling_supply_air_flow_rate_per_floor_area;
3687 102 : Real64 loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.cooling_fraction_of_autosized_cooling_supply_air_flow_rate;
3688 102 : Real64 loc_m_CoolingSAFMethod_FlowPerCoolingCapacity = input_data.cooling_supply_air_flow_rate_per_unit_of_capacity;
3689 102 : std::string loc_m_HeatingSAFMethod = input_data.heating_supply_air_flow_rate_method;
3690 102 : Real64 loc_m_HeatingSAFMethod_SAFlow = input_data.heating_supply_air_flow_rate;
3691 102 : Real64 loc_m_HeatingSAFMethod_SAFlowPerFloorArea = input_data.heating_supply_air_flow_rate_per_floor_area;
3692 102 : Real64 loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.heating_fraction_of_autosized_heating_supply_air_flow_rate;
3693 102 : Real64 loc_m_HeatingSAFMethod_FlowPerHeatingCapacity = input_data.heating_supply_air_flow_rate_per_unit_of_capacity;
3694 102 : std::string loc_m_NoCoolHeatSAFMethod = input_data.no_load_supply_air_flow_rate_method;
3695 102 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlow = input_data.no_load_supply_air_flow_rate;
3696 102 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = input_data.no_load_supply_air_flow_rate_per_floor_area;
3697 102 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.no_load_fraction_of_autosized_cooling_supply_air_flow_rate;
3698 102 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.no_load_fraction_of_autosized_heating_supply_air_flow_rate;
3699 102 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity =
3700 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation;
3701 102 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity =
3702 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation;
3703 :
3704 102 : int FanInletNode = 0;
3705 102 : int FanOutletNode = 0;
3706 102 : Real64 FanVolFlowRate = 0.0;
3707 102 : int CoolingCoilInletNode = 0;
3708 102 : int CoolingCoilOutletNode = 0;
3709 102 : int HeatingCoilInletNode = 0;
3710 102 : int HeatingCoilOutletNode = 0;
3711 102 : int SupHeatCoilInletNode = 0;
3712 102 : int SupHeatCoilOutletNode = 0;
3713 :
3714 102 : bool isNotOK = false;
3715 :
3716 102 : if (input_data.availability_schedule_name.empty()) {
3717 22 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3718 80 : } else if ((this->m_sysAvailSched = Sched::GetSchedule(state, input_data.availability_schedule_name)) == nullptr) {
3719 1 : ShowWarningItemNotFound(state,
3720 : eoh,
3721 : "Availability Schedule Name",
3722 : input_data.availability_schedule_name,
3723 : "Set the default as Always On. Simulation continues.");
3724 1 : this->m_sysAvailSched = Sched::GetScheduleAlwaysOn(state);
3725 : }
3726 :
3727 102 : if (!input_data.controlling_zone_or_thermostat_location.empty()) { // not required field
3728 52 : this->ControlZoneNum = Util::FindItemInList(input_data.controlling_zone_or_thermostat_location, state.dataHeatBal->Zone);
3729 50 : } else if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3730 20 : if (this->m_sysType == SysType::Unitary) {
3731 1 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3732 2 : ShowContinueError(state, "Controlling Zone or Thermostat Location cannot be blank when Control Type = Load or SingleZoneVAV");
3733 1 : errorsFound = true;
3734 : }
3735 : }
3736 :
3737 : // check that control zone name is valid for load based control
3738 102 : if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3739 : // bypass this error for PTUnits
3740 55 : if (this->ControlZoneNum == 0 &&
3741 22 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3742 3 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3743 6 : ShowContinueError(state, "When Control Type = Load or SingleZoneVAV");
3744 6 : ShowContinueError(state,
3745 6 : format(" Controlling Zone or Thermostat Location must be a valid zone name, zone name = {}",
3746 3 : input_data.controlling_zone_or_thermostat_location));
3747 3 : errorsFound = true;
3748 : }
3749 : }
3750 :
3751 102 : if (Util::SameString(input_data.dehumidification_control_type, "None")) {
3752 96 : this->m_DehumidControlType_Num = DehumCtrlType::None;
3753 96 : this->m_Humidistat = false;
3754 6 : } else if (Util::SameString(input_data.dehumidification_control_type, "CoolReheat")) {
3755 6 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
3756 6 : this->m_Humidistat = true;
3757 0 : } else if (Util::SameString(input_data.dehumidification_control_type, "Multimode")) {
3758 0 : this->m_DehumidControlType_Num = DehumCtrlType::Multimode;
3759 0 : this->m_Humidistat = true;
3760 : }
3761 102 : if (this->m_Humidistat && this->m_ControlType == UnitarySysCtrlType::Load) {
3762 1 : bool AirNodeFound = false;
3763 2 : for (int HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
3764 1 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3765 1 : AirNodeFound = true;
3766 : }
3767 1 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3768 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3769 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
3770 0 : ShowContinueError(
3771 0 : state, format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3772 0 : errorsFound = true;
3773 : }
3774 : }
3775 :
3776 102 : Real64 TotalFloorAreaOnAirLoop = 0.0;
3777 102 : int AirLoopNumber = 0;
3778 102 : bool AirNodeFound = false;
3779 102 : bool AirLoopFound = false;
3780 102 : bool OASysFound = false;
3781 102 : bool ZoneEquipmentFound = false;
3782 102 : bool ZoneInletNodeFound = false;
3783 :
3784 : // Get AirTerminal mixer data
3785 102 : SingleDuct::GetATMixer(state,
3786 : thisObjectName,
3787 102 : this->m_ATMixerName,
3788 102 : this->m_ATMixerIndex,
3789 102 : this->ATMixerType,
3790 102 : this->m_ATMixerPriNode,
3791 102 : this->m_ATMixerSecNode,
3792 102 : this->ATMixerOutNode,
3793 : this->AirOutNode);
3794 102 : if (this->ATMixerType == HVAC::MixerType::InletSide || this->ATMixerType == HVAC::MixerType::SupplySide) {
3795 13 : this->ATMixerExists = true;
3796 : }
3797 : // check that heat pump doesn't have local outside air and DOA
3798 102 : if (this->ATMixerExists && this->m_OAMixerNodes[0] > 0 &&
3799 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)) {
3800 0 : ShowSevereError(state,
3801 0 : format("{} = \"{}\". System has local as well as central outdoor air specified", cCurrentModuleObject, this->Name));
3802 0 : errorsFound = true;
3803 : }
3804 :
3805 : // if part of ZoneHVAC:OutdoorAirUnit bypass most checks for connection to air loop or OASystem
3806 102 : if (ZoneOAUnitNum > 0) OASysFound = true;
3807 :
3808 102 : if (ZoneEquipment) {
3809 72 : int ControlledZoneNum = 0;
3810 72 : int ZoneExhNum = 0;
3811 72 : bool ZoneExhaustNodeFound = false;
3812 72 : bool InducedNodeFound = false;
3813 :
3814 72 : if (!this->ATMixerExists) {
3815 59 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3816 59 : if (ZoneExhaustNodeFound) {
3817 55 : ZoneEquipmentFound = true;
3818 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3819 : // this should be zoneExhaustNode
3820 55 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum);
3821 55 : this->ControlZoneNum = ControlledZoneNum;
3822 55 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3823 55 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3824 : } else { // find if the inlet node is an induced node from zone plenum
3825 4 : int ZoneInletNum = 0;
3826 4 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3827 4 : if (ZoneInletNodeFound) {
3828 6 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3829 : this->AirInNode,
3830 3 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3831 3 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3832 3 : if (InducedNodeFound) {
3833 2 : this->m_ZoneInletNode = this->AirOutNode;
3834 2 : ZoneEquipmentFound = true;
3835 2 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3836 : }
3837 : }
3838 : }
3839 13 : } else if (this->ATMixerType == HVAC::MixerType::InletSide) {
3840 8 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->m_ATMixerSecNode, ControlledZoneNum, ZoneExhNum);
3841 8 : if (ZoneExhaustNodeFound) {
3842 7 : ZoneEquipmentFound = true;
3843 7 : this->m_ZoneInletNode = this->AirOutNode;
3844 7 : this->ControlZoneNum = ControlledZoneNum;
3845 7 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3846 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3847 7 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3848 : } else {
3849 1 : int ZoneInletNum = 0;
3850 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3851 1 : if (ZoneInletNodeFound) {
3852 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3853 : this->m_ATMixerSecNode,
3854 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3855 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3856 1 : if (InducedNodeFound) {
3857 1 : this->m_ZoneInletNode = this->AirOutNode;
3858 1 : ZoneEquipmentFound = true;
3859 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3860 : }
3861 : }
3862 : }
3863 5 : } else if (this->ATMixerType == HVAC::MixerType::SupplySide) {
3864 5 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3865 5 : if (ZoneExhaustNodeFound) {
3866 4 : ZoneEquipmentFound = true;
3867 4 : this->m_ZoneInletNode = this->ATMixerOutNode;
3868 4 : this->ControlZoneNum = ControlledZoneNum;
3869 4 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3870 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3871 4 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->ATMixerOutNode, this->ControlZoneNum);
3872 : } else {
3873 1 : int ZoneInletNum = 0;
3874 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->ATMixerOutNode, this->ControlZoneNum, ZoneInletNum);
3875 1 : if (ZoneInletNodeFound) {
3876 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3877 : this->AirInNode,
3878 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3879 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3880 1 : if (InducedNodeFound) {
3881 1 : this->m_ZoneInletNode = this->ATMixerOutNode;
3882 1 : ZoneEquipmentFound = true;
3883 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3884 : }
3885 : }
3886 : }
3887 : }
3888 72 : if (!ZoneExhaustNodeFound && !InducedNodeFound) {
3889 : // Exhaust Node was not found
3890 2 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3891 4 : ShowContinueError(state,
3892 4 : format("Incorrect or misspelled Air Inlet Node Name or Exhaust Node Name or Induced Node Name. = {}",
3893 2 : input_data.air_inlet_node_name));
3894 4 : ShowContinueError(
3895 : state,
3896 4 : format("Air Inlet Node {} name does not match any controlled zone exhaust node name. Check ZoneHVAC:EquipmentConnections "
3897 : "object inputs.",
3898 2 : input_data.air_inlet_node_name));
3899 4 : ShowContinueError(state, "or Induced Air Outlet Node Name specified in AirLoopHVAC:ReturnPlenum object.");
3900 2 : errorsFound = true;
3901 70 : } else if (!ZoneInletNodeFound) {
3902 0 : bool ZoneInletNodeExists = false;
3903 0 : int InletControlledZoneNum = 0;
3904 0 : int ZoneInletNum = 0;
3905 0 : ZoneInletNodeExists = searchZoneInletNodes(state, this->AirOutNode, InletControlledZoneNum, ZoneInletNum);
3906 0 : if (!ZoneInletNodeExists) {
3907 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3908 0 : ShowContinueError(state, format("Incorrect or misspelled Air Outlet Node Name = {}", input_data.air_outlet_node_name));
3909 0 : ShowContinueError(state,
3910 : "Node name does not match any controlled zone inlet node name. Check ZoneHVAC:EquipmentConnections "
3911 : "object inputs.");
3912 0 : errorsFound = true;
3913 : }
3914 : }
3915 : } else {
3916 : // check if the UnitarySystem is connected to an air loop
3917 :
3918 : int compIndex;
3919 : int branchIndex;
3920 30 : AirLoopFound = searchTotalComponents(state, this->AirloopEqType, thisObjectName, compIndex, branchIndex, AirLoopNumber);
3921 30 : if (AirLoopFound && (this->ControlZoneNum > 0)) {
3922 : // Find the controlled zone number for the specified thermostat location
3923 2 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
3924 :
3925 : // Determine if system is on air loop served by the thermostat location specified
3926 2 : int ZoneInletNum = 0;
3927 2 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
3928 2 : if (ZoneInletNodeFound) {
3929 2 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
3930 2 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
3931 : }
3932 :
3933 4 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
3934 2 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3935 2 : AirNodeFound = true;
3936 : }
3937 2 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
3938 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3939 0 : AirNodeFound = true;
3940 : }
3941 2 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3942 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3943 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
3944 0 : ShowContinueError(
3945 : state,
3946 0 : format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3947 0 : errorsFound = true;
3948 : }
3949 :
3950 2 : if (this->ControlZoneNum > 0) {
3951 : // Find the controlled zone number for the specified thermostat location
3952 2 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
3953 :
3954 : // Determine if system is on air loop served by the thermostat location specified
3955 2 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
3956 2 : if (ZoneInletNodeFound) {
3957 2 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
3958 2 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
3959 : }
3960 :
3961 : // if (this->m_ZoneInletNode == 0) AirLoopFound = false;
3962 4 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
3963 2 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3964 2 : AirNodeFound = true;
3965 : }
3966 2 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
3967 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3968 0 : AirNodeFound = true;
3969 : }
3970 2 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3971 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3972 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
3973 0 : ShowContinueError(state,
3974 0 : format("specified Controlling Zone or Thermostat Location name = {}",
3975 0 : input_data.controlling_zone_or_thermostat_location));
3976 0 : errorsFound = true;
3977 : }
3978 : }
3979 : }
3980 :
3981 : // check if the UnitarySystem is connected to an outside air system
3982 30 : if (!AirLoopFound && state.dataAirLoop->NumOASystems > 0) {
3983 10 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
3984 12 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
3985 14 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum), thisObjectName) ||
3986 4 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject))
3987 6 : continue;
3988 4 : AirLoopNumber = OASysNum;
3989 4 : OASysFound = true;
3990 4 : break;
3991 : }
3992 : }
3993 : }
3994 : }
3995 :
3996 102 : if (AirLoopNumber == 0 && !ZoneEquipmentFound &&
3997 3 : (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE)) {
3998 2 : std::string_view zoneName = input_data.controlling_zone_or_thermostat_location;
3999 2 : if (zoneName.empty() && this->ControlZoneNum > 0) {
4000 1 : zoneName = state.dataHeatBal->Zone(this->ControlZoneNum).Name;
4001 : }
4002 2 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4003 4 : ShowContinueError(state, "Did not find proper connections for AirLoopHVAC or ZoneHVAC system.");
4004 2 : ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}", zoneName));
4005 2 : if (!AirNodeFound && !ZoneEquipmentFound) {
4006 2 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4007 4 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
4008 : // ShowContinueError(state, format("specified {} = {}", cAlphaFields(iControlZoneAlphaNum), Alphas(iControlZoneAlphaNum)));
4009 6 : ShowContinueError(state,
4010 : "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
4011 : }
4012 2 : errorsFound = true;
4013 : }
4014 :
4015 102 : if (!AirLoopFound && !ZoneEquipmentFound && !OASysFound) {
4016 : // Unsuccessful attempt to get all input data.
4017 2 : return;
4018 100 : } else if (ZoneEquipmentFound || OASysFound ||
4019 25 : (AirLoopFound && (this->m_ZoneInletNode > 0 || this->m_ControlType == UnitarySysCtrlType::Setpoint))) {
4020 100 : this->m_OKToPrintSizing = true;
4021 100 : this->m_ThisSysInputShouldBeGotten = false;
4022 : }
4023 :
4024 100 : this->m_AvailManagerListName = input_data.avail_manager_list_name;
4025 :
4026 100 : if (!input_data.design_spec_zonehvac_sizing_object_name.empty()) {
4027 0 : this->m_HVACSizingIndex = Util::FindItemInList(input_data.design_spec_zonehvac_sizing_object_name, state.dataSize->ZoneHVACSizing);
4028 0 : if (this->m_HVACSizingIndex == 0) {
4029 0 : ShowSevereError(
4030 : state,
4031 0 : format("Design Specification ZoneHVAC Sizing Object Name = {} not found.", input_data.design_spec_zonehvac_sizing_object_name));
4032 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, this->Name));
4033 0 : errorsFound = true;
4034 : }
4035 : }
4036 :
4037 100 : if (!ZoneEquipment)
4038 90 : BranchNodeConnections::TestCompSet(state,
4039 : cCurrentModuleObject,
4040 60 : Util::makeUPPER(thisObjectName),
4041 30 : input_data.air_inlet_node_name,
4042 30 : input_data.air_outlet_node_name,
4043 : "Air Nodes");
4044 :
4045 100 : std::string const &loc_fanType = input_data.supply_fan_object_type;
4046 100 : std::string const &loc_m_FanName = input_data.supply_fan_name;
4047 :
4048 100 : if (!loc_m_FanName.empty() && !loc_fanType.empty()) {
4049 71 : this->m_FanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(loc_fanType)));
4050 :
4051 71 : this->m_FanIndex = Fans::GetFanIndex(state, loc_m_FanName);
4052 71 : if (this->m_FanIndex == 0) {
4053 0 : ShowSevereItemNotFound(state, eoh, "fan_name", loc_m_FanName);
4054 0 : errorsFound = true;
4055 : } else {
4056 71 : auto const *fan = state.dataFans->fans(this->m_FanIndex);
4057 71 : FanVolFlowRate = fan->maxAirFlowRate;
4058 71 : if (FanVolFlowRate == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4059 71 : this->m_ActualFanVolFlowRate = FanVolFlowRate;
4060 71 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
4061 71 : FanInletNode = fan->inletNodeNum;
4062 71 : FanOutletNode = fan->outletNodeNum;
4063 71 : this->m_fanAvailSched = fan->availSched;
4064 : }
4065 :
4066 71 : this->m_FanExists = true;
4067 71 : this->m_FanName = loc_m_FanName;
4068 29 : } else if (!loc_m_FanName.empty() || !loc_fanType.empty()) {
4069 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4070 0 : ShowContinueError(state, format("Invalid Fan Type or Name: Fan Name = {}, Fan Type = {}", loc_m_FanName, loc_fanType));
4071 0 : errorsFound = true;
4072 : }
4073 :
4074 : // Add fan to component sets array
4075 100 : if (this->m_FanExists && this->m_FanCompNotSetYet) {
4076 134 : BranchNodeConnections::SetUpCompSets(state,
4077 : cCurrentModuleObject,
4078 : thisObjectName,
4079 : loc_fanType,
4080 : loc_m_FanName,
4081 67 : state.dataLoopNodes->NodeID(FanInletNode),
4082 67 : state.dataLoopNodes->NodeID(FanOutletNode));
4083 67 : this->m_FanCompNotSetYet = false;
4084 : }
4085 :
4086 100 : this->m_FanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Util::makeUPPER(input_data.fan_placement)));
4087 100 : if (this->m_FanPlace == HVAC::FanPlace::Invalid && this->m_FanExists) {
4088 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4089 0 : ShowContinueError(state, format("Illegal Fan Placement = {}", input_data.fan_placement));
4090 0 : errorsFound = true;
4091 : }
4092 :
4093 100 : if (input_data.supply_air_fan_operating_mode_schedule_name.empty()) {
4094 56 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4095 : // Fan operating mode must be constant fan so that the coil outlet temp is proportional to PLR
4096 : // Cycling fan always outputs the full load outlet air temp so should not be used with set point based control
4097 43 : this->m_FanOpMode = HVAC::FanOp::Continuous;
4098 : } else {
4099 13 : this->m_FanOpMode = HVAC::FanOp::Cycling;
4100 13 : if (this->m_FanType != HVAC::FanType::OnOff && this->m_FanType != HVAC::FanType::SystemModel && this->m_FanExists) {
4101 0 : ShowSevereEmptyField(state,
4102 : eoh,
4103 : "Fan Operating Mode Schedule Name",
4104 : "Fan type must be Fan:OnOff or Fan:SystemModel when Supply Air Fan Operating Mode Schedule Name is blank.");
4105 0 : errorsFound = true;
4106 : }
4107 : }
4108 44 : } else if ((this->m_fanOpModeSched = Sched::GetSchedule(state, input_data.supply_air_fan_operating_mode_schedule_name)) == nullptr) {
4109 0 : ShowSevereItemNotFound(state, eoh, "Fan Operating Mode Schedule Name", input_data.supply_air_fan_operating_mode_schedule_name);
4110 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iFanSchedAlphaNum), Alphas(iFanSchedAlphaNum)));
4111 0 : errorsFound = true;
4112 52 : } else if ((this->m_ControlType == UnitarySysCtrlType::Setpoint || this->m_FanType == HVAC::FanType::Constant) &&
4113 8 : !this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
4114 1 : Sched::ShowSevereBadMinMax(state,
4115 : eoh,
4116 : "Supply Air Fan Operating Mode Schedule Name",
4117 : input_data.supply_air_fan_operating_mode_schedule_name,
4118 : Clusive::Ex,
4119 : 0.0,
4120 : Clusive::In,
4121 : 1.0);
4122 1 : errorsFound = true;
4123 : }
4124 :
4125 100 : PrintMessage = true;
4126 : // Get coil data
4127 100 : this->m_HeatingSizingRatio = input_data.dx_heating_coil_sizing_ratio;
4128 100 : int HeatingCoilPLFCurveIndex = 0;
4129 100 : if (!this->m_HeatingCoilTypeName.empty()) {
4130 65 : PrintMessage = false;
4131 : } else {
4132 35 : this->m_ValidASHRAEHeatCoil = false;
4133 : }
4134 :
4135 100 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4136 :
4137 3 : this->m_DXHeatingCoil = true;
4138 :
4139 3 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4140 3 : if (isNotOK) {
4141 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4142 0 : errorsFound = true;
4143 :
4144 : } else { // mine data from DX heating coil
4145 :
4146 : // Get DX heating coil index
4147 3 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4148 3 : if (errFlag) {
4149 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4150 0 : errorsFound = true;
4151 0 : errFlag = false;
4152 : } else {
4153 3 : auto &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4154 3 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4155 3 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedTotCap(1);
4156 3 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4157 3 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate(1);
4158 3 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4159 3 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4160 3 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4161 3 : thisHeatCoil.HeatSizeRatio = this->m_HeatingSizingRatio;
4162 : }
4163 : }
4164 :
4165 97 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4166 92 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
4167 :
4168 6 : this->m_DXHeatingCoil = true;
4169 :
4170 6 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4171 6 : if (isNotOK) {
4172 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4173 0 : errorsFound = true;
4174 : } else {
4175 6 : this->m_HeatingCoilIndex =
4176 6 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4177 6 : if (errFlag) {
4178 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4179 0 : errorsFound = true;
4180 0 : errFlag = false;
4181 : } else {
4182 6 : auto const &thisHeatCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex);
4183 6 : this->m_NumOfSpeedHeating = thisHeatCoil.NumOfSpeeds;
4184 6 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4185 6 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4186 6 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4187 3 : this->m_RequestAutoSize = true;
4188 : } else {
4189 3 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NumOfSpeeds) /
4190 3 : thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NormSpedLevel) * thisHeatCoil.RatedAirVolFlowRate;
4191 : }
4192 6 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4193 6 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4194 6 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4195 6 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4196 : }
4197 : }
4198 97 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
4199 5 : this->m_DXHeatingCoil = true;
4200 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4201 5 : if (isNotOK) {
4202 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4203 0 : errorsFound = true;
4204 : } else {
4205 5 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, this->m_HeatingCoilTypeName);
4206 5 : if (errFlag) {
4207 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4208 0 : errorsFound = true;
4209 0 : errFlag = false;
4210 : } else {
4211 5 : auto const &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4212 5 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4213 5 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(1);
4214 5 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4215 5 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4216 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4217 5 : this->m_DesignHeatingCapacity = thisHeatCoil.MSRatedTotCap(thisHeatCoil.NumOfSpeeds);
4218 : }
4219 : }
4220 86 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
4221 81 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
4222 8 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4223 8 : if (isNotOK) {
4224 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4225 0 : errorsFound = true;
4226 : } else {
4227 8 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4228 8 : if (errFlag) {
4229 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4230 0 : errorsFound = true;
4231 0 : errFlag = false;
4232 : } else {
4233 8 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4234 8 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4235 8 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4236 8 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4237 8 : this->m_DesignHeatingCapacity = thisHeatCoil.MSNominalCapacity(thisHeatCoil.NumOfStages);
4238 8 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4239 : }
4240 : }
4241 86 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
4242 43 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
4243 36 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4244 36 : if (isNotOK) {
4245 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4246 0 : errorsFound = true;
4247 : } else { // mine data from heating coil
4248 36 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4249 36 : if (errFlag) {
4250 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4251 0 : errorsFound = true;
4252 0 : errFlag = false;
4253 : } else {
4254 36 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4255 36 : this->m_DesignHeatingCapacity = thisHeatCoil.NominalCapacity;
4256 36 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4257 36 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4258 36 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4259 36 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4260 36 : HeatingCoilPLFCurveIndex = thisHeatCoil.PLFCurveIndex;
4261 : // These heating coil types do not have an air flow input field
4262 36 : if (this->m_RequestAutoSize) {
4263 11 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4264 : }
4265 : }
4266 : } // IF (IsNotOK) THEN
4267 :
4268 78 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
4269 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4270 5 : if (isNotOK) {
4271 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4272 0 : errorsFound = true;
4273 : } else { // mine data from heating coil object
4274 5 : this->m_HeatingCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_HeatingCoilName, errFlag);
4275 5 : if (errFlag) {
4276 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4277 0 : errorsFound = true;
4278 0 : errFlag = false;
4279 : } else {
4280 5 : auto const &thisHeatCoil = state.dataWaterCoils->WaterCoil(this->m_HeatingCoilIndex);
4281 5 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4282 5 : this->HeatCoilFluidInletNode = thisHeatCoil.WaterInletNodeNum;
4283 5 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxWaterVolFlowRate;
4284 5 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4285 3 : this->m_RequestAutoSize = true;
4286 3 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4287 : }
4288 5 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4289 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4290 : }
4291 : }
4292 :
4293 37 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
4294 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4295 0 : if (isNotOK) {
4296 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4297 0 : errorsFound = true;
4298 : } else { // mine data from heating coil object
4299 0 : this->m_HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_HeatingCoilName, errFlag);
4300 0 : if (errFlag) {
4301 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4302 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4303 0 : errorsFound = true;
4304 0 : errFlag = false;
4305 : } else {
4306 0 : auto const &thisHeatCoil = state.dataSteamCoils->SteamCoil(this->m_HeatingCoilIndex);
4307 0 : this->m_heatingCoilAvailSched = thisHeatCoil.availSched;
4308 0 : this->HeatCoilFluidInletNode = thisHeatCoil.SteamInletNodeNum;
4309 0 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxSteamVolFlowRate;
4310 0 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4311 0 : this->m_RequestAutoSize = true;
4312 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4313 : }
4314 0 : if (this->MaxHeatCoilFluidFlow > 0.0) {
4315 0 : Real64 TempSteamIn = 100.0;
4316 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
4317 0 : this->MaxHeatCoilFluidFlow *= SteamDensity;
4318 0 : errFlag = false;
4319 : }
4320 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4321 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4322 0 : if (this->m_RequestAutoSize) {
4323 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4324 : }
4325 : }
4326 : }
4327 :
4328 37 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
4329 2 : this->m_DXHeatingCoil = true;
4330 2 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4331 2 : if (isNotOK) {
4332 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4333 0 : errorsFound = true;
4334 : } else { // mine data from heating coil object
4335 2 : this->m_HeatingCoilIndex =
4336 2 : WaterToAirHeatPumpSimple::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4337 2 : if (errFlag) {
4338 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4339 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4340 0 : errorsFound = true;
4341 0 : errFlag = false;
4342 : } else {
4343 2 : auto const &thisHeatCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_HeatingCoilIndex);
4344 2 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4345 2 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4346 2 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4347 2 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4348 2 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4349 2 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4350 : }
4351 : }
4352 :
4353 35 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
4354 0 : this->m_DXHeatingCoil = true;
4355 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4356 0 : if (isNotOK) {
4357 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4358 0 : errorsFound = true;
4359 : } else { // mine data from heating coil object
4360 0 : this->m_HeatingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4361 0 : if (errFlag) {
4362 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4363 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4364 0 : errorsFound = true;
4365 0 : errFlag = false;
4366 : } else {
4367 0 : auto const &thisHeatCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_HeatingCoilIndex);
4368 0 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4369 0 : this->m_DesignHeatingCapacity = thisHeatCoil.HeatingCapacity;
4370 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4371 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4372 : }
4373 : }
4374 :
4375 35 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
4376 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4377 0 : if (isNotOK) {
4378 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4379 0 : errorsFound = true;
4380 : } else { // mine data from Heating coil object
4381 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
4382 0 : state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, cCurrentModuleObject);
4383 0 : if (errFlag) {
4384 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4385 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4386 0 : errorsFound = true;
4387 0 : errFlag = false;
4388 : } else {
4389 0 : auto const &thisHeatCoil = state.dataUserDefinedComponents->UserCoil(this->m_HeatingCoilIndex);
4390 0 : this->m_heatingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4391 : // **** How to get this info ****
4392 : // UnitarySystem( UnitarySysNum ).DesignHeatingCapacity =
4393 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
4394 0 : HeatingCoilInletNode = thisHeatCoil.Air(1).InletNodeNum;
4395 0 : HeatingCoilOutletNode = thisHeatCoil.Air(1).OutletNodeNum;
4396 : }
4397 : }
4398 :
4399 35 : } else if (this->m_HeatCoilExists) {
4400 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4401 0 : ShowContinueError(state, format("Illegal Heating Coil Object Type = {}", this->m_HeatingCoilTypeName));
4402 0 : errorsFound = true;
4403 : } // IF (this->m_HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
4404 :
4405 : // coil outlet node set point has priority, IF not exist, then use system outlet node
4406 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) this->HeatCtrlNode = this->AirOutNode;
4407 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, HeatingCoilOutletNode, HVAC::CtrlVarType::Temp)) this->HeatCtrlNode = HeatingCoilOutletNode;
4408 :
4409 100 : this->HeatCoilInletNodeNum = HeatingCoilInletNode;
4410 100 : this->HeatCoilOutletNodeNum = HeatingCoilOutletNode;
4411 :
4412 : // Add heating coil to component sets array
4413 100 : if (this->m_HeatCoilExists && this->m_HeatCompNotSetYet) {
4414 61 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
4415 116 : BranchNodeConnections::SetUpCompSets(state,
4416 : cCurrentModuleObject,
4417 : thisObjectName,
4418 : this->m_HeatingCoilTypeName,
4419 : this->m_HeatingCoilName,
4420 58 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
4421 58 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4422 : } else {
4423 3 : BranchNodeConnections::SetUpCompSets(
4424 : state, cCurrentModuleObject, thisObjectName, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, "UNDEFINED", "UNDEFINED");
4425 : }
4426 61 : this->m_HeatCompNotSetYet = false;
4427 : }
4428 :
4429 : // Get Cooling Coil Information IF available
4430 100 : if (!input_data.cooling_coil_object_type.empty() && !this->m_CoolingCoilName.empty()) {
4431 :
4432 83 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4433 44 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4434 44 : if (isNotOK) {
4435 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4436 0 : errorsFound = true;
4437 :
4438 : } else { // mine data from DX cooling coil
4439 :
4440 44 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4441 3 : this->m_NumOfSpeedCooling = 2;
4442 3 : this->m_MultiOrVarSpeedCoolCoil = true;
4443 : } else {
4444 41 : this->m_NumOfSpeedCooling = 1;
4445 41 : this->m_MultiOrVarSpeedCoolCoil = false;
4446 : }
4447 :
4448 : // Get DX cooling coil index
4449 44 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4450 44 : if (isNotOK) {
4451 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4452 0 : errorsFound = true;
4453 : } else {
4454 44 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
4455 1 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
4456 : }
4457 44 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4458 44 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4459 44 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(1);
4460 44 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4461 44 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4462 44 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4463 44 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4464 44 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4465 44 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4466 :
4467 44 : if (this->m_FanExists) {
4468 26 : thisCoolCoil.SupplyFanName = this->m_FanName;
4469 26 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4470 26 : thisCoolCoil.supplyFanType = this->m_FanType;
4471 26 : if (this->m_FanType != HVAC::FanType::Invalid) {
4472 26 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
4473 : state,
4474 26 : thisCoolCoil.Name,
4475 26 : thisCoolCoil.DXCoilType,
4476 26 : state.dataFans->fans(thisCoolCoil.SupplyFanIndex)->Name,
4477 : this->m_FanType,
4478 : thisCoolCoil.SupplyFanIndex);
4479 : }
4480 : }
4481 44 : if (this->m_HeatCoilExists) {
4482 24 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4483 23 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4484 23 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4485 23 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4486 23 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4487 23 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4488 4 : this->m_HeatPump = true;
4489 : }
4490 : }
4491 :
4492 : // Push heating coil PLF curve index to DX coil
4493 44 : if (HeatingCoilPLFCurveIndex > 0) {
4494 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4495 : }
4496 : }
4497 : } // IF (IsNotOK) THEN
4498 :
4499 83 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
4500 6 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4501 6 : if (isNotOK) {
4502 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4503 0 : errorsFound = true;
4504 :
4505 : } else {
4506 : // // call CoilCoolingDX constructor
4507 6 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
4508 6 : if (this->m_CoolingCoilIndex == -1) {
4509 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4510 0 : errorsFound = true;
4511 : } else {
4512 :
4513 : // mine data from coil object
4514 : // TODO: Need to check for autosize on these I guess
4515 6 : auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
4516 6 : this->m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4517 6 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4518 6 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4519 6 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4520 6 : this->m_coolingCoilAvailSched = newCoil.availSched;
4521 6 : CoolingCoilInletNode = newCoil.evapInletNodeIndex;
4522 6 : CoolingCoilOutletNode = newCoil.evapOutletNodeIndex;
4523 6 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4524 6 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
4525 6 : this->m_MinOATCompressorCooling = newCoil.performance.minOutdoorDrybulb;
4526 6 : newCoil.supplyFanName = this->m_FanName;
4527 6 : newCoil.supplyFanIndex = this->m_FanIndex;
4528 6 : newCoil.supplyFanType = this->m_FanType;
4529 6 : if (newCoil.SubcoolReheatFlag) {
4530 1 : this->m_Humidistat = true;
4531 1 : if (this->m_NumOfSpeedCooling > 1) {
4532 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4533 0 : this->FullLatOutput.resize(this->m_NumOfSpeedCooling + 1);
4534 0 : this->SpeedSHR.resize(this->m_NumOfSpeedCooling + 1);
4535 : }
4536 1 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4537 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4538 0 : ShowContinueError(state,
4539 : "Setpoint control is not available for SubcoolReheat cooling coil. Load control is forced. "
4540 : "Simulation continues.");
4541 0 : this->m_ControlType = UnitarySysCtrlType::Load;
4542 : }
4543 : }
4544 6 : newCoil.setData(this->m_FanIndex, this->m_FanType, this->m_FanName, this->m_SuppCoilPlantLoc.loopNum);
4545 :
4546 : // Push heating coil PLF curve index to DX coil
4547 : // if ( HeatingCoilPLFCurveIndex > 0 ) {
4548 : // SetDXCoolingCoilData( UnitarySystem( UnitarySysNum ).CoolingCoilIndex, ErrorsFound,
4549 : // HeatingCoilPLFCurveIndex );
4550 : // }
4551 : }
4552 :
4553 6 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > 1) {
4554 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4555 : }
4556 :
4557 6 : if (this->m_HeatCoilExists) {
4558 3 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4559 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4560 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4561 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4562 3 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4563 3 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4564 0 : this->m_HeatPump = true;
4565 : }
4566 : }
4567 : }
4568 :
4569 33 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
4570 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4571 0 : if (isNotOK) {
4572 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4573 0 : errorsFound = true;
4574 :
4575 : } else { // mine data from DX cooling coil
4576 :
4577 : // Get DX cooling coil index
4578 0 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4579 0 : if (isNotOK) {
4580 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4581 0 : errorsFound = true;
4582 : } else {
4583 0 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4584 0 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4585 0 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(thisCoolCoil.NumCapacityStages);
4586 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4587 0 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4588 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4589 0 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4590 0 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4591 0 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4592 :
4593 : // Push heating coil PLF curve index to DX coil
4594 0 : if (HeatingCoilPLFCurveIndex > 0) {
4595 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4596 : }
4597 :
4598 0 : if (this->m_HeatCoilExists) {
4599 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4600 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4601 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4602 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4603 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4604 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4605 0 : this->m_HeatPump = true;
4606 : }
4607 : }
4608 : }
4609 : } // IF (IsNotOK) THEN
4610 :
4611 33 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
4612 2 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4613 2 : if (isNotOK) {
4614 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4615 0 : errorsFound = true;
4616 :
4617 : } else { // mine data from heat exchanger assisted cooling coil
4618 :
4619 : // Get DX heat exchanger assisted cooling coil index
4620 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4621 2 : if (isNotOK) {
4622 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4623 0 : errorsFound = true;
4624 : }
4625 :
4626 : std::string ChildCoolingCoilName =
4627 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4628 : std::string ChildCoolingCoilType =
4629 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4630 2 : if (isNotOK) {
4631 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4632 0 : errorsFound = true;
4633 : }
4634 :
4635 2 : if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
4636 :
4637 1 : int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
4638 1 : if (childCCIndex < 0) {
4639 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4640 0 : errorsFound = true;
4641 : }
4642 :
4643 1 : auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
4644 1 : this->m_coolingCoilAvailSched = newCoil.availSched;
4645 :
4646 : // thisSys.m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4647 : // Get Coil:Cooling:DX coil air flow rate. Later fields will overwrite this IF input field is present
4648 1 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4649 : // if (thisSys.m_DesignCoolingCapacity == DataSizing::AutoSize) thisSys.m_RequestAutoSize = true;
4650 1 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4651 :
4652 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4653 1 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4654 :
4655 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) {
4656 :
4657 0 : this->m_coolingCoilAvailSched = DXCoils::GetDXCoilAvailSched(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4658 0 : if (isNotOK) {
4659 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4660 0 : errorsFound = true;
4661 : }
4662 :
4663 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
4664 0 : this->m_MaxCoolAirVolFlow = DXCoils::GetDXCoilAirFlow(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4665 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4666 0 : if (errFlag) {
4667 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4668 0 : errFlag = false;
4669 0 : errorsFound = true;
4670 : }
4671 :
4672 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4673 0 : this->m_CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(
4674 : state,
4675 : "COIL:COOLING:DX:SINGLESPEED",
4676 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag),
4677 : errFlag);
4678 :
4679 0 : if (errFlag) {
4680 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4681 0 : errFlag = false;
4682 0 : errorsFound = true;
4683 : }
4684 :
4685 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED")) {
4686 1 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4687 1 : this->m_MaxCoolAirVolFlow =
4688 1 : VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4689 1 : if (errFlag) {
4690 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4691 0 : errFlag = false;
4692 0 : errorsFound = true;
4693 : }
4694 1 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, ChildCoolingCoilName, errFlag);
4695 1 : if (errFlag) {
4696 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4697 0 : errFlag = false;
4698 0 : errorsFound = true;
4699 : }
4700 : }
4701 :
4702 : // Get DX cooling coil capacity
4703 2 : this->m_DesignCoolingCapacity =
4704 2 : HVACHXAssistedCoolingCoil::GetCoilCapacity(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4705 2 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4706 2 : if (errFlag) {
4707 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4708 0 : errFlag = false;
4709 0 : errorsFound = true;
4710 : }
4711 :
4712 : // Get the Cooling Coil Nodes
4713 : CoolingCoilInletNode =
4714 2 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4715 : CoolingCoilOutletNode =
4716 2 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4717 2 : if (errFlag) {
4718 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4719 0 : errFlag = false;
4720 0 : errorsFound = true;
4721 : }
4722 :
4723 : // Push heating coil PLF curve index to DX coil
4724 2 : if (HeatingCoilPLFCurveIndex > 0) {
4725 : // get the actual index to the DX cooling coil object
4726 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4727 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4728 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4729 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4730 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4731 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4732 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4733 : }
4734 : // what could we do for VS coil here? odd thing here
4735 : }
4736 :
4737 2 : if (this->m_HeatCoilExists) {
4738 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4739 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4740 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4741 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4742 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4743 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4744 0 : this->m_HeatPump = true;
4745 : }
4746 : }
4747 :
4748 2 : } // IF (IsNotOK) THEN
4749 31 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
4750 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4751 0 : if (isNotOK) {
4752 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4753 0 : errorsFound = true;
4754 :
4755 : } else { // mine data from heat exchanger assisted cooling coil
4756 :
4757 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4758 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4759 : std::string HXCoilName =
4760 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4761 :
4762 0 : if (errFlag) {
4763 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4764 0 : errFlag = false;
4765 0 : errorsFound = true;
4766 : }
4767 :
4768 : // Get DX heat exchanger assisted cooling coil index
4769 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag);
4770 0 : if (errFlag) {
4771 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4772 0 : errFlag = false;
4773 0 : errorsFound = true;
4774 : }
4775 :
4776 0 : this->m_coolingCoilAvailSched =
4777 0 : WaterCoils::GetWaterCoilAvailSched(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4778 0 : this->MaxCoolCoilFluidFlow =
4779 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4780 : // Get the Cooling Coil water Inlet Node number
4781 0 : this->CoolCoilFluidInletNode =
4782 0 : WaterCoils::GetCoilWaterInletNode(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4783 0 : if (errFlag) {
4784 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4785 0 : errFlag = false;
4786 0 : errorsFound = true;
4787 : }
4788 :
4789 : // Get the Cooling Coil Nodes
4790 : CoolingCoilInletNode =
4791 0 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4792 : CoolingCoilOutletNode =
4793 0 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4794 0 : if (errFlag) {
4795 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4796 0 : errFlag = false;
4797 0 : errorsFound = true;
4798 : }
4799 :
4800 0 : this->m_MaxCoolAirVolFlow =
4801 0 : HVACHXAssistedCoolingCoil::GetHXCoilAirFlowRate(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4802 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4803 0 : this->m_RequestAutoSize = true;
4804 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
4805 : }
4806 0 : if (errFlag) {
4807 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4808 0 : errFlag = false;
4809 0 : errorsFound = true;
4810 : }
4811 :
4812 0 : this->m_CondenserNodeNum = 0;
4813 :
4814 : // Push heating coil PLF curve index to DX coil
4815 0 : if (HeatingCoilPLFCurveIndex > 0) {
4816 : // get the actual index to the DX cooling coil object
4817 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4818 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4819 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4820 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4821 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4822 : }
4823 : // VS coil issue here
4824 : }
4825 :
4826 0 : } // IF (IsNotOK) THEN
4827 31 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
4828 25 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
4829 7 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4830 7 : if (isNotOK) {
4831 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4832 0 : errorsFound = true;
4833 : } else {
4834 7 : this->m_CoolingCoilIndex =
4835 7 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4836 7 : if (errFlag) {
4837 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4838 0 : errorsFound = true;
4839 0 : errFlag = false;
4840 : } else {
4841 7 : auto &thisCoolCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex);
4842 7 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
4843 7 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
4844 7 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum;
4845 7 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4846 7 : this->m_NumOfSpeedCooling = thisCoolCoil.NumOfSpeeds;
4847 7 : if (this->m_NumOfSpeedCooling > 1) {
4848 7 : this->m_MultiOrVarSpeedCoolCoil = true;
4849 : }
4850 7 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
4851 7 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4852 7 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
4853 7 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4854 3 : this->m_RequestAutoSize = true;
4855 : } else {
4856 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NumOfSpeeds) /
4857 4 : thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NormSpedLevel) *
4858 4 : thisCoolCoil.RatedAirVolFlowRate;
4859 : }
4860 7 : if (this->m_FanExists) { // Set fan info
4861 5 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4862 5 : thisCoolCoil.supplyFanType = this->m_FanType;
4863 5 : thisCoolCoil.SupplyFanName = loc_m_FanName;
4864 : }
4865 : }
4866 : }
4867 :
4868 7 : if (this->m_HeatCoilExists) {
4869 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4870 3 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4871 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4872 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4873 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4874 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4875 3 : this->m_HeatPump = true;
4876 : }
4877 : }
4878 :
4879 31 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
4880 10 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4881 10 : if (isNotOK) {
4882 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4883 0 : errorsFound = true;
4884 : } else {
4885 10 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, input_data.cooling_coil_object_type);
4886 10 : if (errFlag) {
4887 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4888 0 : errorsFound = true;
4889 0 : errFlag = false;
4890 : } else {
4891 10 : auto const &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4892 10 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4893 10 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4894 10 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4895 10 : this->m_DesignCoolingCapacity = thisCoolCoil.MSRatedTotCap(thisCoolCoil.NumOfSpeeds);
4896 10 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4897 10 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(1);
4898 10 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4899 : }
4900 : }
4901 :
4902 10 : if (this->m_HeatCoilExists) {
4903 7 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4904 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4905 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4906 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4907 5 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4908 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4909 5 : this->m_HeatPump = true;
4910 : }
4911 : }
4912 :
4913 14 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
4914 :
4915 12 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4916 12 : if (isNotOK) {
4917 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4918 0 : errorsFound = true;
4919 : } else { // mine data from Cooling coil object
4920 12 : this->m_CoolingCoilIndex =
4921 12 : WaterCoils::GetWaterCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4922 12 : if (errFlag) {
4923 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4924 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
4925 0 : errorsFound = true;
4926 0 : errFlag = false;
4927 : } else {
4928 12 : auto const &thisCoolCoil = state.dataWaterCoils->WaterCoil(this->m_CoolingCoilIndex);
4929 12 : this->m_coolingCoilAvailSched = thisCoolCoil.availSched;
4930 12 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
4931 11 : this->m_MaxCoolAirVolFlow = thisCoolCoil.DesAirVolFlowRate;
4932 : }
4933 12 : this->CoolCoilFluidInletNode = thisCoolCoil.WaterInletNodeNum;
4934 12 : this->MaxCoolCoilFluidFlow = thisCoolCoil.MaxWaterVolFlowRate;
4935 12 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
4936 4 : this->m_RequestAutoSize = true;
4937 4 : this->m_DesignCoolingCapacity = DataSizing::AutoSize; // water coils don't have a capacity field, need other logic?
4938 : }
4939 12 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
4940 12 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
4941 : }
4942 : }
4943 14 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
4944 2 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4945 2 : if (isNotOK) {
4946 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4947 0 : errorsFound = true;
4948 : } else { // mine data from Cooling coil object
4949 2 : this->m_CoolingCoilIndex =
4950 2 : WaterToAirHeatPumpSimple::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4951 2 : if (errFlag) {
4952 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4953 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
4954 0 : errorsFound = true;
4955 0 : errFlag = false;
4956 : } else {
4957 2 : auto const &thisCoolCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_CoolingCoilIndex);
4958 2 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
4959 2 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
4960 :
4961 : // this isn't likely to work on getInput calls but is what happened before
4962 2 : int CompanionHeatingCoil = thisCoolCoil.CompanionHeatingCoilNum;
4963 2 : if (CompanionHeatingCoil > 0) {
4964 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize &&
4965 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).WAHPPlantType ==
4966 0 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
4967 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
4968 0 : state.dataSize->DXCoolCap > 0) {
4969 : // Heating coil has not yet been sized, returning the temporary cooling capacity
4970 0 : this->m_DesignCoolingCapacity = state.dataSize->DXCoolCap;
4971 : }
4972 : }
4973 :
4974 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
4975 2 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
4976 2 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4977 2 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
4978 2 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
4979 : }
4980 : }
4981 :
4982 2 : if (this->m_HeatCoilExists) {
4983 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4984 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4985 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4986 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4987 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4988 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4989 2 : this->m_HeatPump = true;
4990 : }
4991 : }
4992 :
4993 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
4994 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4995 0 : if (isNotOK) {
4996 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4997 0 : errorsFound = true;
4998 : } else { // mine data from Cooling coil object
4999 0 : this->m_CoolingCoilIndex =
5000 0 : WaterToAirHeatPump::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5001 0 : if (this->m_CoolingCoilIndex == 0) {
5002 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5003 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5004 0 : errorsFound = true;
5005 0 : errFlag = false;
5006 : } else {
5007 0 : auto const &thisCoolCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_CoolingCoilIndex);
5008 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5009 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingCapacity;
5010 0 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5011 0 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5012 : }
5013 : }
5014 :
5015 0 : if (this->m_HeatCoilExists) {
5016 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5017 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5018 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5019 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5020 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5021 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5022 0 : this->m_HeatPump = true;
5023 : }
5024 : }
5025 :
5026 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
5027 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5028 0 : if (isNotOK) {
5029 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5030 0 : errorsFound = true;
5031 : } else { // mine data from Cooling coil object
5032 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5033 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5034 0 : if (errFlag) {
5035 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5036 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5037 0 : errorsFound = true;
5038 0 : errFlag = false;
5039 : } else {
5040 0 : auto const &thisCoolCoil = state.dataUserDefinedComponents->UserCoil(this->m_CoolingCoilIndex);
5041 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5042 : // **** How to get this info ****
5043 : // UnitarySystem( UnitarySysNum ).DesignCoolingCapacity =
5044 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
5045 0 : CoolingCoilInletNode = thisCoolCoil.Air(1).InletNodeNum;
5046 0 : CoolingCoilOutletNode = thisCoolCoil.Air(1).OutletNodeNum;
5047 : }
5048 : }
5049 :
5050 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
5051 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5052 0 : if (isNotOK) {
5053 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5054 0 : errorsFound = true;
5055 : } else { // mine data from Cooling coil object
5056 0 : PackagedThermalStorageCoil::GetTESCoilIndex(
5057 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5058 0 : if (errFlag) {
5059 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5060 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5061 0 : errorsFound = true;
5062 0 : errFlag = false;
5063 : } else {
5064 0 : auto const &thisCoolCoil = state.dataPackagedThermalStorageCoil->TESCoil(this->m_CoolingCoilIndex);
5065 0 : this->m_coolingCoilAvailSched = Sched::GetScheduleAlwaysOn(state);
5066 0 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedEvapAirVolFlowRate;
5067 0 : if (thisCoolCoil.CoolingOnlyModeIsAvailable) {
5068 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingOnlyRatedTotCap;
5069 0 : } else if (thisCoolCoil.CoolingAndChargeModeAvailable) {
5070 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndChargeRatedTotCap;
5071 0 : } else if (thisCoolCoil.CoolingAndDischargeModeAvailable) {
5072 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndDischargeRatedTotCap;
5073 : } else {
5074 0 : this->m_DesignCoolingCapacity = 0.0;
5075 : }
5076 0 : CoolingCoilInletNode = thisCoolCoil.EvapAirInletNodeNum;
5077 0 : CoolingCoilOutletNode = thisCoolCoil.EvapAirOutletNodeNum;
5078 : }
5079 : }
5080 :
5081 : } else { // IF(.NOT. lAlphaBlanks(16))THEN
5082 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5083 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iCoolingCoilTypeAlphaNum), Alphas(iCoolingCoilTypeAlphaNum)));
5084 0 : errorsFound = true;
5085 : }
5086 :
5087 83 : if (!input_data.dx_cooling_coil_system_sensor_node_name.empty()) { // used by CoilSystem:Cooling:DX
5088 42 : this->CoolCtrlNode = NodeInputManager::GetOnlySingleNode(state,
5089 21 : input_data.dx_cooling_coil_system_sensor_node_name,
5090 : errFlag,
5091 : objType,
5092 : thisObjectName,
5093 : DataLoopNode::NodeFluidType::Air,
5094 : DataLoopNode::ConnectionType::Sensor,
5095 : NodeInputManager::CompFluidStream::Primary,
5096 : DataLoopNode::ObjectIsParent);
5097 : } else {
5098 62 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) this->CoolCtrlNode = this->AirOutNode;
5099 62 : if (SetPointManager::NodeHasSPMCtrlVarType(state, CoolingCoilOutletNode, HVAC::CtrlVarType::Temp))
5100 8 : this->CoolCtrlNode = CoolingCoilOutletNode;
5101 : }
5102 :
5103 83 : this->CoolCoilInletNodeNum = CoolingCoilInletNode;
5104 83 : this->CoolCoilOutletNodeNum = CoolingCoilOutletNode;
5105 :
5106 : } else {
5107 17 : this->m_ValidASHRAECoolCoil = false;
5108 : }
5109 :
5110 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple &&
5111 2 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5112 2 : if (!input_data.heat_pump_coil_water_flow_mode.empty()) {
5113 1 : this->m_WaterCyclingMode =
5114 1 : static_cast<HVAC::WaterFlow>(getEnumValue(HVAC::waterFlowNamesUC, Util::makeUPPER(input_data.heat_pump_coil_water_flow_mode)));
5115 : } else {
5116 1 : this->m_WaterCyclingMode = HVAC::WaterFlow::Cycling;
5117 : }
5118 2 : WaterToAirHeatPumpSimple::SetSimpleWSHPData(
5119 2 : state, this->m_CoolingCoilIndex, errorsFound, this->m_WaterCyclingMode, _, this->m_HeatingCoilIndex);
5120 : }
5121 :
5122 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
5123 1 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5124 1 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, this->m_HeatingCoilIndex);
5125 : }
5126 :
5127 : // Add cooling coil to component sets array
5128 100 : if (this->m_CoolCoilExists && this->m_CoolCompNotSetYet) {
5129 80 : if (this->m_CoolingCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
5130 144 : BranchNodeConnections::SetUpCompSets(state,
5131 : cCurrentModuleObject,
5132 : thisObjectName,
5133 : input_data.cooling_coil_object_type,
5134 : this->m_CoolingCoilName,
5135 72 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
5136 72 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
5137 : } else {
5138 8 : BranchNodeConnections::SetUpCompSets(state,
5139 : cCurrentModuleObject,
5140 : thisObjectName,
5141 : input_data.cooling_coil_object_type,
5142 : this->m_CoolingCoilName,
5143 : "UNDEFINED",
5144 : "UNDEFINED");
5145 : }
5146 80 : this->m_CoolCompNotSetYet = false;
5147 : }
5148 : // Run as 100% DOAS DX coil
5149 100 : if (!Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5150 100 : this->m_ISHundredPercentDOASDXCoil = false;
5151 : } else {
5152 0 : if (Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5153 0 : this->m_ISHundredPercentDOASDXCoil = true;
5154 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
5155 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5156 0 : ShowContinueError(state, "Variable DX Cooling Coil is not supported as 100% DOAS DX coil.");
5157 0 : ShowContinueError(state, "Variable DX Cooling Coil resets Use DOAS DX Cooling Coil = No and the simulation continues.");
5158 0 : this->m_ISHundredPercentDOASDXCoil = false;
5159 : }
5160 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "")) {
5161 0 : this->m_ISHundredPercentDOASDXCoil = false;
5162 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "No")) {
5163 0 : this->m_ISHundredPercentDOASDXCoil = false;
5164 : }
5165 : }
5166 :
5167 : // considered as as 100% DOAS DX cooling coil
5168 100 : if (this->m_ISHundredPercentDOASDXCoil) {
5169 : // set the system DX Coil application type to the child DX coil
5170 0 : if (!(this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5171 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
5172 0 : DXCoils::SetDXCoilTypeData(state, this->m_CoolingCoilName);
5173 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
5174 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].setToHundredPercentDOAS();
5175 : }
5176 : }
5177 : // DOAS DX Cooling Coil Leaving Minimum Air Temperature
5178 100 : this->DesignMinOutletTemp = input_data.minimum_supply_air_temperature;
5179 100 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp == DataSizing::AutoSize) {
5180 : // skip error for PTUnits
5181 15 : if (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater) {
5182 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5183 0 : ShowContinueError(state, "Invalid entry for Minimum Supply Air Temperature = AutoSize.");
5184 0 : ShowContinueError(state, "AutoSizing not allowed when Control Type = Load or Setpoint");
5185 0 : errorsFound = true;
5186 : }
5187 : }
5188 100 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp > 7.5) {
5189 5 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5190 5 : ShowContinueError(state, format("Invalid entry for Minimum Supply Air Temperature = {:.4R}", this->DesignMinOutletTemp));
5191 10 : ShowContinueError(state, "The minimum supply air temperature will be limited to 7.5C and the simulation continues.");
5192 5 : this->DesignMinOutletTemp = 7.5;
5193 : }
5194 :
5195 : // Get Latent Load Control flag
5196 100 : if (!input_data.latent_load_control.empty()) {
5197 100 : if (Util::SameString(input_data.latent_load_control, "SensibleOnlyLoadControl")) {
5198 95 : this->m_RunOnSensibleLoad = true;
5199 95 : this->m_RunOnLatentLoad = false;
5200 5 : } else if (Util::SameString(input_data.latent_load_control, "LatentOnlyLoadControl")) {
5201 0 : this->m_RunOnSensibleLoad = false;
5202 0 : this->m_RunOnLatentLoad = true;
5203 5 : } else if (Util::SameString(input_data.latent_load_control, "LatentOrSensibleLoadControl")) {
5204 5 : this->m_RunOnSensibleLoad = true;
5205 5 : this->m_RunOnLatentLoad = true;
5206 0 : } else if (Util::SameString(input_data.latent_load_control, "LatentWithSensibleLoadControl")) {
5207 0 : this->m_RunOnSensibleLoad = true;
5208 0 : this->m_RunOnLatentLoad = true;
5209 0 : this->m_RunOnLatentOnlyWithSensible = true;
5210 : }
5211 : }
5212 100 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
5213 6 : if (!this->m_RunOnLatentLoad && !this->m_RunOnLatentOnlyWithSensible && this->m_ControlType == UnitarySysCtrlType::Load) {
5214 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5215 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5216 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5217 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5218 0 : ShowContinueError(state, "Humidity/Moisture may not be controlled with these settings.");
5219 : }
5220 : } else {
5221 94 : if ((this->m_RunOnLatentLoad || this->m_RunOnLatentOnlyWithSensible) && this->m_ControlType == UnitarySysCtrlType::Load) {
5222 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5223 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5224 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5225 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5226 0 : ShowContinueError(state, "Humidity/Moisture will not be controlled with these settings.");
5227 0 : this->m_RunOnLatentLoad = false;
5228 0 : this->m_RunOnLatentOnlyWithSensible = false;
5229 : }
5230 : }
5231 : // Get reheat coil data if humidistat is used
5232 100 : this->m_SuppHeatCoilName = input_data.supplemental_heating_coil_name;
5233 100 : this->m_SuppHeatCoilTypeName = input_data.supplemental_heating_coil_object_type;
5234 :
5235 100 : if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Water")) {
5236 1 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
5237 99 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Steam")) {
5238 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
5239 177 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Fuel") ||
5240 155 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric") ||
5241 254 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric:MultiStage") ||
5242 172 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:DesuperHeater")) {
5243 26 : this->m_SuppHeatCoilType_Num =
5244 26 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5245 73 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:UserDefined")) {
5246 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_UserDefined;
5247 : }
5248 :
5249 100 : if (!this->m_SuppHeatCoilTypeName.empty() && !this->m_SuppHeatCoilName.empty()) {
5250 27 : errFlag = false;
5251 :
5252 27 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric ||
5253 5 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
5254 1 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
5255 :
5256 26 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5257 26 : if (isNotOK) {
5258 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5259 0 : errorsFound = true;
5260 :
5261 : } else { // mine data from reheat coil
5262 26 : this->m_SuppHeatCoilIndex =
5263 26 : HeatingCoils::GetHeatingCoilIndex(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5264 26 : if (errFlag) {
5265 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5266 0 : errorsFound = true;
5267 0 : errFlag = false;
5268 : } else {
5269 26 : auto const &thisSuppCoil = state.dataHeatingCoils->HeatingCoil(this->m_SuppHeatCoilIndex);
5270 26 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
5271 4 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.MSNominalCapacity(thisSuppCoil.NumOfStages);
5272 4 : this->m_NumOfSpeedSuppHeating = thisSuppCoil.NumOfStages;
5273 : } else {
5274 22 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.NominalCapacity;
5275 : }
5276 26 : if (this->m_DesignSuppHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
5277 26 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5278 26 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5279 : }
5280 : } // IF (IsNotOK) THEN
5281 :
5282 26 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5283 26 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5284 :
5285 27 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5286 :
5287 1 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5288 1 : if (isNotOK) {
5289 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5290 0 : errorsFound = true;
5291 : } else { // mine data from heating coil object
5292 1 : this->m_SuppHeatCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_SuppHeatCoilName, errFlag);
5293 1 : if (errFlag) {
5294 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5295 0 : errorsFound = true;
5296 0 : errFlag = false;
5297 : } else {
5298 1 : auto const &thisSuppCoil = state.dataWaterCoils->WaterCoil(this->m_SuppHeatCoilIndex);
5299 1 : this->m_SuppCoilFluidInletNode = thisSuppCoil.WaterInletNodeNum;
5300 1 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxWaterVolFlowRate;
5301 1 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5302 0 : this->m_RequestAutoSize = true;
5303 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize;
5304 : }
5305 1 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5306 1 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5307 1 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5308 1 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5309 : }
5310 : }
5311 :
5312 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5313 :
5314 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5315 0 : if (isNotOK) {
5316 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5317 0 : errorsFound = true;
5318 : } else { // mine data from heating coil object
5319 0 : this->m_SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_SuppHeatCoilName, errFlag);
5320 0 : if (errFlag) {
5321 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5322 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5323 0 : errorsFound = true;
5324 0 : errFlag = false;
5325 : } else {
5326 0 : auto const &thisSuppCoil = state.dataSteamCoils->SteamCoil(this->m_SuppHeatCoilIndex);
5327 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.SteamInletNodeNum;
5328 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxSteamVolFlowRate;
5329 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5330 0 : this->m_RequestAutoSize = true;
5331 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize; // not sure if steam coil needs this
5332 : }
5333 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
5334 0 : Real64 TempSteamIn = 100.0;
5335 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, "getUnitarySystemInputData");
5336 0 : this->m_MaxSuppCoilFluidFlow = this->m_MaxSuppCoilFluidFlow * SteamDensity;
5337 : }
5338 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5339 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5340 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5341 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5342 : }
5343 : }
5344 :
5345 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
5346 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5347 0 : if (isNotOK) {
5348 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5349 0 : errorsFound = true;
5350 : } else { // mine data from Heating coil object
5351 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5352 0 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilIndex, errFlag, cCurrentModuleObject);
5353 0 : if (errFlag) {
5354 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5355 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5356 0 : errorsFound = true;
5357 0 : errFlag = false;
5358 : } else {
5359 0 : auto const &thisSuppCoil = state.dataUserDefinedComponents->UserCoil(this->m_SuppHeatCoilIndex);
5360 0 : SupHeatCoilInletNode = thisSuppCoil.Air(1).InletNodeNum;
5361 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5362 0 : SupHeatCoilOutletNode = thisSuppCoil.Air(1).OutletNodeNum;
5363 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5364 : }
5365 : }
5366 :
5367 : } else { // Illegal reheating coil type
5368 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5369 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Type = {}", this->m_SuppHeatCoilTypeName));
5370 0 : errorsFound = true;
5371 : } // IF (this->SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
5372 :
5373 : } // IF(.NOT. lAlphaBlanks(iSuppHeatCoilTypeAlphaNum))THEN
5374 :
5375 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) this->SuppCtrlNode = this->AirOutNode;
5376 100 : if (SetPointManager::NodeHasSPMCtrlVarType(state, SupHeatCoilOutletNode, HVAC::CtrlVarType::Temp)) this->SuppCtrlNode = SupHeatCoilOutletNode;
5377 :
5378 : // Add supplemental heating coil to component sets array
5379 100 : if (this->m_SuppCoilExists && this->m_SuppCompNotSetYet) {
5380 50 : BranchNodeConnections::SetUpCompSets(state,
5381 : cCurrentModuleObject,
5382 : thisObjectName,
5383 : this->m_SuppHeatCoilTypeName,
5384 : this->m_SuppHeatCoilName,
5385 25 : state.dataLoopNodes->NodeID(SupHeatCoilInletNode),
5386 25 : state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
5387 25 : this->m_SuppCompNotSetYet = false;
5388 : }
5389 :
5390 100 : if (this->OAMixerExists) {
5391 : // Set up component set for OA mixer - use OA node and Mixed air node
5392 12 : BranchNodeConnections::SetUpCompSets(state,
5393 : this->UnitType,
5394 : this->Name,
5395 : input_data.oa_mixer_type,
5396 : input_data.oa_mixer_name,
5397 6 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[0]),
5398 6 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[3]));
5399 : }
5400 :
5401 : // set fan info for supplemental heating coils
5402 100 : if (this->m_SuppCoilExists && this->m_FanExists) {
5403 27 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
5404 27 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
5405 : }
5406 :
5407 : // Users may not provide SA flow input fields (below) and leave them blank. Check if other coil is AutoSized first to
5408 : // alleviate input requirements. check if coil has no air flow input (VolFlow = 0) and other coil isDataSizing::AutoSized. If so,
5409 : // use AutoSize for coil with 0 air flow rate. This means that the coils MUST mine the air flow rate if it exists
5410 100 : if (this->m_CoolCoilExists && this->m_HeatCoilExists) {
5411 48 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize && this->m_MaxHeatAirVolFlow == 0 && loc_m_HeatingSAFMethod == "") {
5412 3 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
5413 45 : } else if (this->m_MaxCoolAirVolFlow == 0 && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize && loc_m_CoolingSAFMethod == "") {
5414 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
5415 : }
5416 : }
5417 :
5418 : // translate DesignSpecification:ZoneHVAC:Sizing inputs
5419 : // UnitarySystem already has air flow scalable sizing, update locals
5420 : // UnitarySystem does not have capacity sizing, set inputs accordingly
5421 100 : if (this->m_HVACSizingIndex > 0) {
5422 0 : int zoneHVACIndex = this->m_HVACSizingIndex;
5423 0 : auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(zoneHVACIndex);
5424 0 : switch (zoneHVACSizing.CoolingSAFMethod) {
5425 0 : case DataSizing::None:
5426 0 : break; // do nothing?
5427 0 : case DataSizing::SupplyAirFlowRate:
5428 0 : loc_m_CoolingSAFMethod = "SupplyAirFlowRate";
5429 0 : loc_m_CoolingSAFMethod_SAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5430 0 : break;
5431 0 : case DataSizing::FlowPerFloorArea:
5432 0 : loc_m_CoolingSAFMethod = "FlowPerFloorArea";
5433 0 : loc_m_CoolingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxCoolAirVolFlow;
5434 0 : break;
5435 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5436 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5437 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5438 0 : break;
5439 0 : case DataSizing::FlowPerCoolingCapacity:
5440 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5441 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5442 0 : break;
5443 0 : default:
5444 : assert(true);
5445 : }
5446 :
5447 0 : switch (zoneHVACSizing.HeatingSAFMethod) {
5448 0 : case DataSizing::None:
5449 0 : break; // do nothing?
5450 0 : case DataSizing::SupplyAirFlowRate:
5451 0 : loc_m_HeatingSAFMethod = "SupplyAirFlowRate";
5452 0 : loc_m_HeatingSAFMethod_SAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5453 0 : break;
5454 0 : case DataSizing::FlowPerFloorArea:
5455 0 : loc_m_HeatingSAFMethod = "FlowPerFloorArea";
5456 0 : loc_m_HeatingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxHeatAirVolFlow;
5457 0 : break;
5458 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5459 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5460 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5461 0 : break;
5462 0 : case DataSizing::FlowPerHeatingCapacity:
5463 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5464 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5465 0 : break;
5466 0 : default:
5467 : assert(true);
5468 : }
5469 :
5470 0 : switch (zoneHVACSizing.NoCoolHeatSAFMethod) {
5471 0 : case DataSizing::None:
5472 0 : break; // do nothing?
5473 0 : case DataSizing::SupplyAirFlowRate:
5474 0 : loc_m_NoCoolHeatSAFMethod = "SupplyAirFlowRate";
5475 0 : loc_m_NoCoolHeatSAFMethod_SAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5476 0 : break;
5477 0 : case DataSizing::FlowPerFloorArea:
5478 0 : loc_m_NoCoolHeatSAFMethod = "FlowPerFloorArea";
5479 0 : loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5480 0 : break;
5481 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5482 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5483 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5484 0 : break;
5485 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5486 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5487 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5488 0 : break;
5489 0 : default:
5490 : assert(true);
5491 : }
5492 :
5493 0 : switch (zoneHVACSizing.CoolingCapMethod) {
5494 0 : case DataSizing::CoolingDesignCapacity:
5495 0 : this->m_CoolingCapMethod = DataSizing::CoolingDesignCapacity;
5496 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5497 0 : break;
5498 0 : case DataSizing::CapacityPerFloorArea:
5499 0 : this->m_CoolingCapMethod = DataSizing::CapacityPerFloorArea;
5500 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity * TotalFloorAreaOnAirLoop;
5501 0 : break;
5502 0 : case DataSizing::FractionOfAutosizedCoolingCapacity:
5503 0 : this->m_CoolingCapMethod = DataSizing::FractionOfAutosizedCoolingCapacity;
5504 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5505 0 : break;
5506 0 : default:
5507 : assert(true);
5508 : }
5509 :
5510 0 : switch (zoneHVACSizing.HeatingCapMethod) {
5511 0 : case DataSizing::HeatingDesignCapacity:
5512 0 : this->m_HeatingCapMethod = DataSizing::HeatingDesignCapacity;
5513 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5514 0 : break;
5515 0 : case DataSizing::CapacityPerFloorArea:
5516 0 : this->m_HeatingCapMethod = DataSizing::CapacityPerFloorArea;
5517 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity * TotalFloorAreaOnAirLoop;
5518 0 : break;
5519 0 : case DataSizing::FractionOfAutosizedHeatingCapacity:
5520 0 : this->m_HeatingCapMethod = DataSizing::FractionOfAutosizedHeatingCapacity;
5521 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5522 0 : break;
5523 0 : default:
5524 : assert(true);
5525 : }
5526 : }
5527 :
5528 : // Determine supply air flow rate sizing method for cooling mode
5529 100 : if (Util::SameString(loc_m_CoolingSAFMethod, "SupplyAirFlowRate")) {
5530 43 : this->m_CoolingSAFMethod = DataSizing::SupplyAirFlowRate;
5531 :
5532 43 : if (loc_m_CoolingSAFMethod_SAFlow != -999.0) {
5533 43 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlow;
5534 43 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5535 11 : this->m_RequestAutoSize = true;
5536 : } else {
5537 32 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5538 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5539 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5540 0 : ShowContinueError(
5541 : state,
5542 0 : format("Suspicious Cooling Supply Air Flow Rate = {:.7R} when cooling coil is present.", this->m_MaxCoolAirVolFlow));
5543 : }
5544 32 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5545 : }
5546 :
5547 : } else {
5548 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5549 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5550 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate.");
5551 0 : errorsFound = true;
5552 : }
5553 57 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerFloorArea")) {
5554 :
5555 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerFloorArea;
5556 0 : if (loc_m_CoolingSAFMethod_SAFlowPerFloorArea != -999.0) {
5557 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlowPerFloorArea;
5558 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5559 0 : if (this->m_MaxCoolAirVolFlow <= 0.0001 && this->m_CoolCoilExists) {
5560 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5561 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5562 0 : ShowContinueError(
5563 : state,
5564 0 : format("Suspicious Cooling Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when cooling coil is present.",
5565 0 : this->m_MaxCoolAirVolFlow));
5566 0 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5567 : }
5568 0 : this->m_MaxCoolAirVolFlow *= TotalFloorAreaOnAirLoop;
5569 0 : this->m_RequestAutoSize = true;
5570 : // AutoSized input is not allowed
5571 : } else {
5572 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5573 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5574 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Floor Area = Autosize");
5575 0 : errorsFound = true;
5576 : }
5577 : } else {
5578 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5579 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5580 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Floor Area.");
5581 0 : errorsFound = true;
5582 : }
5583 57 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FractionOfAutosizedCoolingValue")) {
5584 :
5585 1 : this->m_CoolingSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5586 1 : if (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5587 1 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow;
5588 1 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5589 1 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5590 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5591 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5592 0 : ShowContinueError(state,
5593 0 : format("Suspicious Cooling Fraction of Autosized Cooling Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5594 : "when cooling coil is present.",
5595 0 : this->m_MaxCoolAirVolFlow));
5596 0 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5597 : }
5598 1 : this->m_RequestAutoSize = true;
5599 : // AutoSized input is not allowed
5600 : } else {
5601 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5602 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5603 0 : ShowContinueError(state, "Illegal Cooling Fraction of Autosized Cooling Supply Air Flow Rate = Autosize");
5604 0 : errorsFound = true;
5605 : }
5606 : } else {
5607 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5608 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5609 0 : ShowContinueError(state, "Blank field not allowed for Cooling Fraction of Autosized Cooling Supply Air Flow Rate.");
5610 0 : errorsFound = true;
5611 : }
5612 56 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerCoolingCapacity")) {
5613 :
5614 4 : this->m_CoolingSAFMethod = DataSizing::FlowPerCoolingCapacity;
5615 4 : if (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity != -999.0) {
5616 4 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FlowPerCoolingCapacity;
5617 4 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5618 4 : if (this->m_MaxCoolAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5619 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5620 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5621 0 : ShowContinueError(state,
5622 0 : format("Suspicious Cooling Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5623 : "cooling coil is present.",
5624 0 : this->m_MaxCoolAirVolFlow));
5625 0 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5626 : }
5627 4 : this->m_RequestAutoSize = true;
5628 : // AutoSized input is not allowed
5629 : } else {
5630 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5631 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5632 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Unit of Capacity = Autosize");
5633 0 : errorsFound = true;
5634 : }
5635 : } else {
5636 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5637 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5638 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Unit of Capacity.");
5639 0 : errorsFound = true;
5640 : }
5641 :
5642 52 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "None") || loc_m_CoolingSAFMethod == "") {
5643 52 : this->m_CoolingSAFMethod = DataSizing::None;
5644 52 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow == 0) {
5645 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5646 0 : if (this->m_HeatCoilExists) {
5647 0 : ShowContinueError(state, "Blank field not allowed for this coil type when heating coil air flow rate is not AutoSized.");
5648 : } else {
5649 0 : ShowContinueError(state, "Blank field not allowed for this type of cooling coil.");
5650 : }
5651 0 : errorsFound = true;
5652 : }
5653 : }
5654 :
5655 : // Determine supply air flow rate sizing method for heating mode
5656 100 : if (Util::SameString(loc_m_HeatingSAFMethod, "SupplyAirFlowRate")) {
5657 60 : this->m_HeatingSAFMethod = DataSizing::SupplyAirFlowRate;
5658 60 : if (loc_m_HeatingSAFMethod_SAFlow != -999.0) {
5659 60 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlow;
5660 60 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
5661 28 : this->m_RequestAutoSize = true;
5662 : } else {
5663 32 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5664 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5665 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5666 0 : ShowContinueError(
5667 : state,
5668 0 : format("Suspicious Heating Supply Air Flow Rate = {:.7R} when heating coil is present.", this->m_MaxHeatAirVolFlow));
5669 : }
5670 32 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5671 : }
5672 : } else {
5673 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5674 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5675 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate.");
5676 0 : errorsFound = true;
5677 : }
5678 40 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerFloorArea")) {
5679 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerFloorArea;
5680 0 : if (loc_m_HeatingSAFMethod_SAFlowPerFloorArea != -999.0) {
5681 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlowPerFloorArea;
5682 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5683 0 : if (this->m_MaxHeatAirVolFlow <= 0.0001 && this->m_HeatCoilExists) {
5684 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5685 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5686 0 : ShowContinueError(
5687 : state,
5688 0 : format("Suspicious Heating Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when heating coil is present.",
5689 0 : this->m_MaxHeatAirVolFlow));
5690 : }
5691 0 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5692 0 : this->m_MaxHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5693 0 : this->m_RequestAutoSize = true;
5694 : } else {
5695 : // AutoSized input is not allowed
5696 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5697 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5698 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Floor Area = Autosize");
5699 0 : errorsFound = true;
5700 : }
5701 : } else {
5702 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5703 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5704 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Floor Area.");
5705 0 : errorsFound = true;
5706 : }
5707 40 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FractionOfAutosizedHeatingValue")) {
5708 1 : this->m_HeatingSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5709 1 : if (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5710 1 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow;
5711 1 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5712 1 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5713 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5714 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5715 0 : ShowContinueError(state,
5716 0 : format("Suspicious Heating Fraction of Autosized Heating Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5717 : "when heating coil is present.",
5718 0 : this->m_MaxHeatAirVolFlow));
5719 0 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5720 : }
5721 1 : this->m_RequestAutoSize = true;
5722 : // AutoSized input is not allowed
5723 : } else {
5724 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5725 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5726 0 : ShowContinueError(state, "Illegal input for Heating Fraction of Autosized Heating Supply Air Flow Rate = Autosize");
5727 0 : errorsFound = true;
5728 : }
5729 : } else {
5730 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5731 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5732 0 : ShowContinueError(state, "Blank field not allowed for Heating Fraction of Autosized Heating Supply Air Flow Rate");
5733 0 : errorsFound = true;
5734 : }
5735 39 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerHeatingCapacity")) {
5736 4 : this->m_HeatingSAFMethod = DataSizing::FlowPerHeatingCapacity;
5737 4 : if (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity != -999.0) {
5738 4 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FlowPerHeatingCapacity;
5739 4 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5740 4 : if (this->m_MaxHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5741 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5742 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5743 0 : ShowContinueError(state,
5744 0 : format("Suspicious Heating Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5745 : "heating coil is present.",
5746 0 : this->m_MaxHeatAirVolFlow));
5747 0 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5748 : }
5749 4 : this->m_RequestAutoSize = true;
5750 : // AutoSized input is not allowed
5751 : } else {
5752 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5753 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5754 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Unit of Capacity = Autosize");
5755 0 : errorsFound = true;
5756 : }
5757 : } else {
5758 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5759 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity");
5760 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Unit of Capacity");
5761 0 : errorsFound = true;
5762 : }
5763 35 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "None") || loc_m_HeatingSAFMethod == "") {
5764 35 : this->m_HeatingSAFMethod = DataSizing::None;
5765 35 : if (this->m_HeatCoilExists && this->m_MaxHeatAirVolFlow == 0) {
5766 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5767 1 : if (loc_m_HeatingSAFMethod == "") {
5768 3 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method is blank.");
5769 : } else {
5770 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = None.");
5771 : }
5772 1 : if (this->m_CoolCoilExists) {
5773 3 : ShowContinueError(state, "Blank field not allowed for this coil type when cooling coil air flow rate is not AutoSized.");
5774 : } else {
5775 0 : ShowContinueError(state, "Blank field not allowed for this type of heating coil.");
5776 : }
5777 1 : errorsFound = true;
5778 : }
5779 : }
5780 :
5781 : // Determine supply air flow rate sizing method when cooling or heating is not needed
5782 100 : if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "SupplyAirFlowRate")) {
5783 44 : this->m_NoCoolHeatSAFMethod = DataSizing::SupplyAirFlowRate;
5784 44 : if (loc_m_NoCoolHeatSAFMethod_SAFlow != -999.0) {
5785 44 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlow;
5786 44 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
5787 7 : this->m_RequestAutoSize = true;
5788 : } else {
5789 37 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
5790 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5791 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
5792 0 : ShowContinueError(state, format("Illegal No Load Supply Air Flow Rate = {:.7R}", this->m_MaxNoCoolHeatAirVolFlow));
5793 0 : errorsFound = true;
5794 : }
5795 : }
5796 :
5797 : } else {
5798 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5799 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
5800 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate");
5801 0 : errorsFound = true;
5802 : }
5803 56 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerFloorArea")) {
5804 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerFloorArea;
5805 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea != -999.0) {
5806 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea;
5807 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5808 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.0001) {
5809 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5810 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
5811 0 : ShowContinueError(
5812 : state,
5813 0 : format("Suspicious No Load Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2]", this->m_MaxNoCoolHeatAirVolFlow));
5814 : }
5815 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5816 0 : this->m_MaxNoCoolHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5817 0 : this->m_RequestAutoSize = true;
5818 : } else {
5819 : // AutoSized input is not allowed
5820 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5821 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
5822 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Floor Area = Autosize");
5823 0 : errorsFound = true;
5824 : }
5825 : } else {
5826 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5827 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
5828 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Floor Area");
5829 0 : errorsFound = true;
5830 : }
5831 56 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedCoolingValue")) {
5832 1 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5833 1 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5834 1 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow;
5835 1 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5836 1 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
5837 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5838 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5839 0 : ShowContinueError(
5840 : state,
5841 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/m3].",
5842 0 : this->m_MaxNoCoolHeatAirVolFlow));
5843 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5844 : }
5845 1 : this->m_RequestAutoSize = true;
5846 : // AutoSized input is not allowed
5847 : } else {
5848 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5849 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue");
5850 0 : ShowContinueError(state,
5851 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
5852 0 : errorsFound = true;
5853 : }
5854 : } else {
5855 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5856 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5857 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
5858 0 : errorsFound = true;
5859 : }
5860 55 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedHeatingValue")) {
5861 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5862 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5863 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow;
5864 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5865 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
5866 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5867 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5868 0 : ShowContinueError(
5869 : state,
5870 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/m3].",
5871 0 : this->m_MaxNoCoolHeatAirVolFlow));
5872 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5873 : }
5874 0 : this->m_RequestAutoSize = true;
5875 : // AutoSized input is not allowed
5876 : } else {
5877 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5878 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5879 0 : ShowContinueError(state,
5880 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
5881 0 : errorsFound = true;
5882 : }
5883 : } else {
5884 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5885 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5886 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
5887 0 : errorsFound = true;
5888 : }
5889 55 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerCoolingCapacity")) {
5890 2 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerCoolingCapacity;
5891 2 : if (loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity != -999.0) {
5892 2 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity;
5893 2 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5894 2 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5895 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5896 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5897 0 : ShowContinueError(
5898 : state,
5899 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/W].",
5900 0 : this->m_MaxNoCoolHeatAirVolFlow));
5901 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5902 : }
5903 2 : this->m_RequestAutoSize = true;
5904 : // AutoSized input is not allowed
5905 : } else {
5906 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5907 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5908 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
5909 0 : errorsFound = true;
5910 : }
5911 : } else {
5912 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5913 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5914 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
5915 0 : errorsFound = true;
5916 : }
5917 53 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerHeatingCapacity")) {
5918 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerHeatingCapacity;
5919 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity != -999.0) {
5920 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity;
5921 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5922 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5923 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5924 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5925 0 : ShowContinueError(
5926 : state,
5927 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/W].",
5928 0 : this->m_MaxNoCoolHeatAirVolFlow));
5929 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5930 : }
5931 0 : this->m_RequestAutoSize = true;
5932 : // AutoSized input is not allowed
5933 : } else {
5934 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5935 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5936 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
5937 0 : errorsFound = true;
5938 : }
5939 : } else {
5940 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5941 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5942 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
5943 0 : errorsFound = true;
5944 : }
5945 53 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "None") || loc_m_NoCoolHeatSAFMethod == "") {
5946 53 : this->m_NoCoolHeatSAFMethod = DataSizing::None;
5947 53 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
5948 1 : if (loc_m_NoCoolHeatSAFMethod_SAFlow == -99999.0) { // no load air flow is autosized
5949 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
5950 0 : this->m_RequestAutoSize = true;
5951 1 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == -999.0) { // no load air flow is blank
5952 1 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
5953 1 : this->m_RequestAutoSize = true;
5954 1 : ShowWarningError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
5955 1 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
5956 2 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be blank.");
5957 3 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate has been set to AutoSize and the simulation continues.");
5958 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == 0.0) { // no load air flow for SZVAV cannot be 0
5959 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
5960 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
5961 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
5962 0 : errorsFound = true;
5963 : }
5964 : }
5965 : }
5966 100 : if (this->input_specs.no_load_supply_air_flow_rate_low_speed == "NO") {
5967 6 : this->m_useNoLoadLowSpeedAirFlow = false;
5968 : }
5969 :
5970 : // check supply air flow calculation method
5971 100 : if (this->m_FanExists) {
5972 71 : if (this->m_CoolCoilExists) {
5973 54 : if (loc_m_CoolingSAFMethod.empty()) {
5974 9 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5975 18 : ShowContinueError(state,
5976 : "Method used to determine the cooling supply air flow rate is not specified when cooling coil is present.");
5977 : // check if all cooling flow calc method fields are blank
5978 9 : if (((loc_m_CoolingSAFMethod_SAFlow == -999.0) && (loc_m_CoolingSAFMethod_SAFlowPerFloorArea == -999.0) &&
5979 2 : (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow == -999.0) &&
5980 : (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity == -999.0))) {
5981 4 : ShowContinueError(state, "Cooling Supply Air Flow Rate field is blank.");
5982 4 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Floor Area field is blank.");
5983 4 : ShowContinueError(state, "Cooling Fraction of Autosized Cooling Supply Air Flow Rate field is blank.");
5984 4 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Unit of Capacity field is blank.");
5985 6 : ShowContinueError(state,
5986 : "Blank field not allowed for all four cooling supply air flow rate calculation methods when "
5987 : "cooling coil is present.");
5988 : }
5989 : }
5990 : // set fan info for cooling coils
5991 54 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
5992 54 : state, this->m_CoolingCoilName, input_data.cooling_coil_object_type, this->m_FanName, this->m_FanType, this->m_FanIndex);
5993 : }
5994 71 : if (this->m_HeatCoilExists) {
5995 65 : if (loc_m_HeatingSAFMethod.empty()) {
5996 5 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5997 10 : ShowContinueError(state,
5998 : "Method used to determine the heating supply air flow rate is not specified when heating coil is present.");
5999 : // check if all heating flow calc method fields are blank
6000 5 : if (((loc_m_HeatingSAFMethod_SAFlow == -999.0) && (loc_m_HeatingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6001 2 : (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow == -999.0) &&
6002 : (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity == -999.0))) {
6003 4 : ShowContinueError(state, "Heating Supply Air Flow Rate field is blank.");
6004 4 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Floor Area field is blank.");
6005 4 : ShowContinueError(state, "Heating Fraction of Autosized Heating Supply Air Flow Rate field is blank.");
6006 4 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Unit of Capacity field is blank.");
6007 6 : ShowContinueError(state,
6008 : "Blank field not allowed for all four heating supply air flow rate calculation methods when heating "
6009 : "coil is present.");
6010 : }
6011 : }
6012 : // set fan info for heating coils
6013 65 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6014 65 : state, this->m_HeatingCoilName, this->m_HeatingCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
6015 : }
6016 : }
6017 :
6018 : // Fan operating mode (cycling or constant) schedule. IF constant fan, then set AirFlowControl
6019 100 : if (this->m_fanOpModeSched != nullptr) {
6020 44 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6021 : // set fan operating mode to continuous so sizing can set VS coil data
6022 31 : this->m_FanOpMode = HVAC::FanOp::Continuous;
6023 : // set air flow control mode:
6024 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6025 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6026 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6027 31 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6028 10 : this->m_AirFlowControl = UseCompFlow::On;
6029 : } else {
6030 21 : this->m_AirFlowControl = UseCompFlow::Off;
6031 : }
6032 : }
6033 : }
6034 :
6035 100 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6036 0 : int numCoolingCoilModes = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getNumModes();
6037 0 : if (numCoolingCoilModes == 1) {
6038 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6039 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6040 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6041 0 : ShowContinueError(
6042 : state,
6043 0 : format("Cooling coil named: {} has only one mode", state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].name));
6044 0 : ShowFatalError(state, "Multimode cooling coil error causes program termination");
6045 : }
6046 100 : } else if (this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted &&
6047 98 : this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingTwoStageWHumControl &&
6048 98 : this->m_CoolingCoilType_Num != HVAC::CoilWater_CoolingHXAssisted && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6049 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6050 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6051 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6052 0 : if (this->m_SuppHeatCoilName == "" && this->m_SuppHeatCoilTypeName == "") {
6053 : } else {
6054 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
6055 0 : ShowContinueError(state, "Dehumidification control type is assumed to be None and the simulation continues.");
6056 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6057 : } else {
6058 0 : ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
6059 0 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
6060 : }
6061 : }
6062 : }
6063 :
6064 : // Check placement of cooling coil with respect to fan placement and dehumidification control type
6065 :
6066 100 : if (this->m_FanExists) {
6067 71 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6068 65 : if (FanOutletNode == HeatingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6069 17 : this->m_CoolingCoilUpstream = false;
6070 : }
6071 6 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) {
6072 6 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6073 0 : this->m_CoolingCoilUpstream = false;
6074 : }
6075 : }
6076 : } else {
6077 29 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6078 0 : this->m_CoolingCoilUpstream = false;
6079 : }
6080 29 : if (ZoneEquipmentFound) {
6081 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6082 2 : ShowContinueError(state, "ZoneHVAC equipment must contain a fan object.");
6083 1 : ShowContinueError(state, format("specified Supply Fan Object Type = {}", loc_fanType));
6084 1 : ShowContinueError(state, format("specified Supply Fan Name = {}", loc_m_FanName));
6085 1 : errorsFound = true;
6086 : }
6087 : }
6088 :
6089 : // check node connections
6090 100 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6091 :
6092 65 : int tmpAirInletNode = this->AirInNode;
6093 65 : if (this->OAMixerExists) {
6094 5 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6095 : }
6096 65 : if (FanInletNode != tmpAirInletNode) {
6097 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6098 0 : if (this->OAMixerExists) {
6099 0 : ShowContinueError(state,
6100 : "When a blow through fan is specified, the fan inlet node name must be the same as the outdoor "
6101 : "air mixer mixed air node name.");
6102 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6103 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6104 : } else {
6105 0 : ShowContinueError(state,
6106 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system "
6107 : "inlet node name.");
6108 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6109 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6110 : }
6111 0 : errorsFound = true;
6112 : }
6113 65 : if (this->m_CoolingCoilUpstream) {
6114 48 : if (FanOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6115 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6116 0 : ShowContinueError(state,
6117 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil "
6118 : "inlet node name.");
6119 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6120 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6121 0 : errorsFound = true;
6122 : }
6123 48 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6124 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6125 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6126 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6127 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6128 0 : errorsFound = true;
6129 : }
6130 48 : if (this->m_SuppCoilExists) {
6131 21 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6132 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6133 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6134 0 : ShowContinueError(state,
6135 0 : format("...Reheat coil outlet node name = {}" + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6136 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}" + state.dataLoopNodes->NodeID(this->AirOutNode)));
6137 0 : errorsFound = true;
6138 : }
6139 : } else { // IF((this->m_Humidistat ...
6140 : // Heating coil outlet node name must be the same as the Unitary system outlet node name
6141 27 : if (this->m_HeatCoilExists && HeatingCoilOutletNode != this->AirOutNode) {
6142 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6143 0 : ShowContinueError(state,
6144 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
6145 : "unitary system outlet node name.");
6146 0 : ShowContinueError(state,
6147 0 : format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6148 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6149 0 : errorsFound = true;
6150 : }
6151 : }
6152 : } else { // IF(this->CoolingCoilUpstream)THEN
6153 17 : if (FanOutletNode != HeatingCoilInletNode && this->m_FanExists && this->m_HeatCoilExists) {
6154 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6155 0 : ShowContinueError(state,
6156 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil "
6157 : "inlet node name.");
6158 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6159 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6160 0 : errorsFound = true;
6161 : }
6162 17 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6163 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6164 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6165 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6166 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6167 0 : errorsFound = true;
6168 : }
6169 17 : if (CoolingCoilOutletNode != this->AirOutNode && this->m_CoolCoilExists) {
6170 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6171 0 : ShowContinueError(state,
6172 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the unitary "
6173 : "system outlet node name.");
6174 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6175 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6176 0 : errorsFound = true;
6177 : }
6178 : }
6179 :
6180 35 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) { // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6181 :
6182 6 : int tmpAirInletNode = this->AirInNode;
6183 6 : if (this->OAMixerExists) {
6184 1 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6185 : }
6186 6 : if (this->m_CoolingCoilUpstream) {
6187 6 : if (CoolingCoilInletNode != tmpAirInletNode && CoolingCoilInletNode != 0 && this->m_FanExists) {
6188 0 : if (this->OAMixerExists) {
6189 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6190 0 : ShowContinueError(state,
6191 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the outdoor "
6192 : "air mixer mixed air node name.");
6193 0 : ShowContinueError(state,
6194 0 : format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6195 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6196 : } else {
6197 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6198 0 : ShowContinueError(state,
6199 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary "
6200 : "system inlet node name.");
6201 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6202 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6203 : }
6204 0 : errorsFound = true;
6205 : }
6206 6 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6207 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6208 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6209 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6210 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6211 0 : errorsFound = true;
6212 : }
6213 6 : if (HeatingCoilOutletNode != FanInletNode && this->m_HeatCoilExists && this->m_FanExists) {
6214 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6215 0 : ShowContinueError(state,
6216 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan "
6217 : "inlet node name.");
6218 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6219 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6220 0 : errorsFound = true;
6221 : }
6222 6 : if (this->m_SuppCoilExists) {
6223 2 : if (FanOutletNode != SupHeatCoilInletNode && this->m_FanExists) {
6224 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6225 0 : ShowContinueError(state,
6226 : "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
6227 : "inlet node name.");
6228 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6229 0 : ShowContinueError(state, format("...Reheat coil inlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
6230 0 : errorsFound = true;
6231 : }
6232 2 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6233 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6234 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6235 0 : ShowContinueError(state,
6236 0 : format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6237 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6238 0 : errorsFound = true;
6239 : }
6240 : } else {
6241 4 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6242 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6243 0 : ShowContinueError(state,
6244 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6245 : "outlet node name.");
6246 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6247 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6248 0 : errorsFound = true;
6249 : }
6250 : }
6251 : } else { // IF(this->CoolingCoilUpstream)THEN
6252 0 : if (HeatingCoilInletNode != tmpAirInletNode && HeatingCoilInletNode != 0 && this->m_FanExists) {
6253 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6254 0 : if (this->OAMixerExists) {
6255 0 : ShowContinueError(state,
6256 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6257 : "system mixer mixed air node name.");
6258 0 : ShowContinueError(state,
6259 0 : format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6260 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6261 : } else {
6262 0 : ShowContinueError(state,
6263 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6264 : "system inlet node name.");
6265 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6266 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6267 : }
6268 0 : errorsFound = true;
6269 : }
6270 0 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_HeatCoilExists && this->m_CoolCoilExists) {
6271 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6272 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6273 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6274 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6275 0 : errorsFound = true;
6276 : }
6277 0 : if (CoolingCoilOutletNode != FanInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6278 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6279 0 : ShowContinueError(state,
6280 : "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan "
6281 : "inlet node name.");
6282 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6283 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6284 0 : errorsFound = true;
6285 : }
6286 0 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6287 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6288 0 : ShowContinueError(state,
6289 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6290 : "outlet node name.");
6291 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6292 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6293 0 : errorsFound = true;
6294 : }
6295 : }
6296 : } // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6297 :
6298 : // Set the unitary system supplemental heater max outlet temperature
6299 : // this field will be 0 if the input is not specified (included) in the input file
6300 : // someone may use a default other than what we intended, allow it to be used
6301 : // so if this field is blank, and the input field is included, read the default, otherwise use 80
6302 : // if (!lNumericBlanks(iDesignMaxOutletTempNumericNum) && NumNumbers > (iDesignMaxOutletTempNumericNum - 1)) {
6303 100 : if (this->m_sysType == SysType::Unitary) {
6304 : // UnitarySystem has a single field for max outlet temp
6305 55 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6306 : } else {
6307 : // PTHP has a field for max outlet temp for supplemental heater and max outlet temp for SZVAV
6308 45 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6309 1 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6310 : } else {
6311 44 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature_from_supplemental_heater;
6312 : }
6313 : }
6314 100 : if (this->DesignMaxOutletTemp == DataSizing::AutoSize) this->m_RequestAutoSize = true;
6315 : //}
6316 :
6317 : // Set maximum Outdoor air temperature for supplemental heating coil operation
6318 : // this field will be 0 if the input is not specified (included) in the input file
6319 : // someone may use a default other than what we intended, allow it to be used
6320 : // so if this field is blank, and the input field is included, read the default, otherwise use 9999
6321 : // if (!lNumericBlanks(iMaxOATSuppHeatNumericNum) && NumNumbers > (iMaxOATSuppHeatNumericNum - 1)) {
6322 100 : this->m_MaxOATSuppHeat = input_data.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation;
6323 : // Can't let MaxOATSuppHeat default to 21C if using cool reheat since it would shut off supp heater when dehumidifying
6324 : // this may also allow supplemental heater to operate when in heating mode when it should not
6325 100 : if (this->m_MaxOATSuppHeat == 21.0 && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6326 6 : this->m_MaxOATSuppHeat = 999.0;
6327 : }
6328 100 : if (this->m_SuppCoilExists) {
6329 54 : OutputReportPredefined::PreDefTableEntry(
6330 27 : state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, this->m_HeatingCoilName, this->m_MaxOATSuppHeat);
6331 : }
6332 :
6333 100 : if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 &&
6334 37 : !this->m_RequestAutoSize) {
6335 28 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6336 72 : } else if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6337 11 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6338 61 : } else if (this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6339 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6340 : } else {
6341 61 : if (this->m_FanExists && this->m_DesignFanVolFlowRate == 0.0) {
6342 0 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
6343 : }
6344 : // need more of this type of warning when flow cannot be determined
6345 61 : if (this->m_MaxHeatAirVolFlow == 0.0 && this->m_HeatCoilExists) {
6346 0 : if (this->m_FanExists) {
6347 0 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6348 0 : if (this->m_MaxCoolAirVolFlow == 0.0) {
6349 0 : this->m_MaxHeatAirVolFlow = this->m_DesignFanVolFlowRate;
6350 : }
6351 : }
6352 0 : } else if (this->m_CoolCoilExists) {
6353 0 : this->m_MaxHeatAirVolFlow = this->m_MaxCoolAirVolFlow;
6354 : } else {
6355 0 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical &&
6356 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating &&
6357 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed) {
6358 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6359 0 : ShowContinueError(state,
6360 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6361 : "Supply Air Flow Rate Method");
6362 0 : errorsFound = true;
6363 : }
6364 : }
6365 61 : } else if (this->m_MaxHeatAirVolFlow == 0.0 && !this->m_FanExists && !this->m_CoolCoilExists) {
6366 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6367 0 : ShowContinueError(state,
6368 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6369 : "Supply Air Flow Rate Method");
6370 : }
6371 : }
6372 :
6373 100 : if (FanVolFlowRate != DataSizing::AutoSize && this->m_FanExists) {
6374 36 : if (FanVolFlowRate < this->m_MaxCoolAirVolFlow && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize && this->m_CoolCoilExists) {
6375 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6376 0 : ShowContinueError(
6377 : state,
6378 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
6379 : FanVolFlowRate,
6380 0 : this->m_FanName));
6381 0 : ShowContinueError(state, " The Cooling Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6382 0 : this->m_MaxCoolAirVolFlow = FanVolFlowRate;
6383 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6384 : }
6385 36 : if (FanVolFlowRate < this->m_MaxHeatAirVolFlow && this->m_MaxHeatAirVolFlow != DataSizing::AutoSize && this->m_HeatCoilExists) {
6386 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6387 0 : ShowContinueError(
6388 : state,
6389 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
6390 : FanVolFlowRate,
6391 0 : this->m_FanName));
6392 0 : ShowContinueError(state, " The Heating Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6393 0 : this->m_MaxHeatAirVolFlow = FanVolFlowRate;
6394 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6395 : }
6396 : }
6397 :
6398 100 : if (this->m_fanOpModeSched != nullptr) {
6399 44 : if (!this->m_fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
6400 : // set air flow control mode:
6401 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6402 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6403 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6404 31 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6405 10 : this->m_AirFlowControl = UseCompFlow::On;
6406 : } else {
6407 21 : this->m_AirFlowControl = UseCompFlow::Off;
6408 : }
6409 : }
6410 : }
6411 :
6412 : // Set minimum OAT for heat pump compressor operation in cooling mode
6413 : // get from coil module
6414 100 : errFlag = false;
6415 100 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6416 41 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6417 59 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6418 3 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6419 56 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6420 10 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6421 46 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6422 0 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6423 46 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6424 6 : this->m_MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6425 40 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
6426 : // already found in getInput
6427 : } else {
6428 34 : this->m_MinOATCompressorCooling = -1000.0;
6429 : }
6430 100 : if (errFlag) {
6431 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6432 0 : errorsFound = true;
6433 0 : errFlag = false;
6434 : }
6435 :
6436 : // Set minimum OAT for heat pump compressor operation in heating mode
6437 : // get from coil module
6438 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6439 5 : this->m_MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6440 95 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6441 8 : this->m_MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6442 : } else {
6443 87 : this->m_MinOATCompressorHeating = -1000.0;
6444 : }
6445 100 : if (errFlag) {
6446 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6447 0 : errorsFound = true;
6448 0 : errFlag = false;
6449 : }
6450 :
6451 : // Mine heatpump Outdoor condenser node from DX coil object
6452 100 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6453 41 : this->m_CondenserNodeNum =
6454 41 : DXCoils::GetCoilCondenserInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
6455 : // TODO: Should we add a block for the new DX Coil?
6456 59 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6457 6 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, this->m_CoolingCoilName, errFlag);
6458 53 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
6459 : // already filled
6460 : // UnitarySystem( UnitarySysNum ).CondenserNodeNum = GetDXCoilCondenserInletNode( "Coil:Cooling:DX:SingleSpeed",
6461 : // GetHXDXCoilName(state, CoolingCoilType, this->m_CoolingCoilName, errFlag ), errFlag );
6462 :
6463 : } else {
6464 51 : if (input_data.outdoor_dry_bulb_temperature_sensor_node_name != "") {
6465 2 : this->m_CondenserNodeNum = NodeInputManager::GetOnlySingleNode(state,
6466 1 : input_data.outdoor_dry_bulb_temperature_sensor_node_name,
6467 : errFlag,
6468 : objType,
6469 : thisObjectName,
6470 : DataLoopNode::NodeFluidType::Air,
6471 : DataLoopNode::ConnectionType::Inlet,
6472 : NodeInputManager::CompFluidStream::Primary,
6473 : DataLoopNode::ObjectIsParent);
6474 : } else {
6475 : // do nothing?
6476 : }
6477 : }
6478 100 : if (errFlag) {
6479 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6480 0 : errorsFound = true;
6481 0 : errFlag = false;
6482 : }
6483 :
6484 100 : this->m_AncillaryOnPower = input_data.ancillary_on_cycle_electric_power;
6485 100 : this->m_AncillaryOffPower = input_data.ancillary_off_cycle_electric_power;
6486 100 : this->m_MaxHROutletWaterTemp = input_data.maximum_temperature_for_heat_recovery;
6487 :
6488 100 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
6489 5 : this->m_HeatRecActive = true;
6490 5 : if (input_data.heat_recovery_water_inlet_node_name != "" && input_data.heat_recovery_water_outlet_node_name != "") {
6491 5 : this->m_HeatRecoveryInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6492 5 : input_data.heat_recovery_water_inlet_node_name,
6493 : errFlag,
6494 : objType,
6495 : thisObjectName,
6496 : DataLoopNode::NodeFluidType::Water,
6497 : DataLoopNode::ConnectionType::Inlet,
6498 : NodeInputManager::CompFluidStream::Tertiary,
6499 : DataLoopNode::ObjectIsNotParent);
6500 10 : this->m_HeatRecoveryOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6501 5 : input_data.heat_recovery_water_outlet_node_name,
6502 : errFlag,
6503 : objType,
6504 : thisObjectName,
6505 : DataLoopNode::NodeFluidType::Water,
6506 : DataLoopNode::ConnectionType::Outlet,
6507 : NodeInputManager::CompFluidStream::Tertiary,
6508 : DataLoopNode::ObjectIsNotParent);
6509 :
6510 10 : BranchNodeConnections::TestCompSet(state,
6511 : cCurrentModuleObject,
6512 : thisObjectName,
6513 5 : input_data.heat_recovery_water_inlet_node_name,
6514 5 : input_data.heat_recovery_water_outlet_node_name,
6515 : "Unitary System Heat Recovery Nodes");
6516 :
6517 5 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6518 2 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_CoolingCoilIndex);
6519 : }
6520 5 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6521 2 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_HeatingCoilIndex);
6522 : }
6523 5 : if (errFlag) {
6524 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6525 0 : errorsFound = true;
6526 : // errFlag = false; // not used after this point, uncomment if needed
6527 : }
6528 : } else {
6529 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6530 0 : ShowContinueError(state, format("Illegal Heat Recovery Water Inlet Node Name = {}", input_data.heat_recovery_water_inlet_node_name));
6531 0 : ShowContinueError(state,
6532 0 : format("Illegal Heat Recovery Water Outlet Node Name = {}", input_data.heat_recovery_water_outlet_node_name));
6533 0 : ShowContinueError(state,
6534 : "... heat recovery nodes must be specified when Design Heat Recovery Water Flow Rate"
6535 : " is greater than 0.");
6536 0 : ShowContinueError(state, format("... Design Heat Recovery Water Flow Rate = {:.7R}", this->m_DesignHRWaterVolumeFlow));
6537 0 : errorsFound = true;
6538 : }
6539 : }
6540 :
6541 100 : if (!this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) {
6542 :
6543 26 : if (this->m_DesignSpecMSHPIndex > -1) {
6544 :
6545 25 : this->m_NoLoadAirFlowRateRatio = this->m_CompPointerMSHP->noLoadAirFlowRateRatio;
6546 :
6547 25 : switch (this->m_HeatingCoilType_Num) {
6548 15 : case HVAC::CoilDX_MultiSpeedHeating:
6549 : case HVAC::Coil_HeatingElectric_MultiStage:
6550 : case HVAC::Coil_HeatingGas_MultiStage:
6551 : case HVAC::Coil_HeatingWaterToAirHPSimple:
6552 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
6553 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6554 15 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6555 15 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6556 15 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6557 15 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling < this->m_NumOfSpeedHeating) {
6558 0 : this->FullOutput.resize(this->m_NumOfSpeedHeating + 1);
6559 : }
6560 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple && this->m_NumOfSpeedHeating > 1) {
6561 1 : this->m_MultiSpeedHeatingCoil = true;
6562 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6563 : }
6564 62 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6565 47 : this->m_HeatMassFlowRate[i] = 0.0;
6566 47 : this->m_HeatVolumeFlowRate[i] = 0.0;
6567 47 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6568 : }
6569 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
6570 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6571 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_HeatingCoilName, errorsFound);
6572 1 : if (errorsFound) {
6573 0 : ShowSevereError(state,
6574 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_HeatingCoilName));
6575 : }
6576 1 : if (NumOfSpeed != this->m_NumOfSpeedHeating) {
6577 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_HeatingCoilName));
6578 0 : ShowContinueError(state,
6579 0 : format("... The number of heating coil speeds in the {} = {:.0R}",
6580 : MultispeedType,
6581 0 : double(this->m_NumOfSpeedHeating)));
6582 0 : ShowContinueError(
6583 : state,
6584 0 : format("... The number of heating coil speeds in Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6585 0 : double(NumOfSpeed)));
6586 0 : ShowContinueError(state, format("... The number of heating coil speeds in the {} will be used.", MultispeedType));
6587 : }
6588 1 : }
6589 15 : } break;
6590 : }
6591 25 : switch (this->m_CoolingCoilType_Num) {
6592 12 : case HVAC::CoilDX_MultiSpeedCooling:
6593 : case HVAC::Coil_CoolingWaterToAirHPSimple:
6594 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
6595 12 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6596 12 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6597 12 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6598 12 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6599 12 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > this->m_NumOfSpeedHeating) {
6600 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
6601 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
6602 : }
6603 12 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple && this->m_NumOfSpeedCooling > 1) {
6604 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6605 1 : this->m_DiscreteSpeedCoolingCoil = true;
6606 : }
6607 51 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6608 39 : this->m_CoolMassFlowRate[i] = 0.0;
6609 39 : this->m_CoolVolumeFlowRate[i] = 0.0;
6610 39 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6611 : }
6612 12 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
6613 1 : std::string MultispeedType = (this->m_DesignSpecMSHPIndex == -1) ? "Fan:SystemModel" : "UnitarySystemPerformance:Multispeed";
6614 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_CoolingCoilName, errorsFound);
6615 1 : if (errorsFound) {
6616 0 : ShowSevereError(state,
6617 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_CoolingCoilName));
6618 : }
6619 1 : if (NumOfSpeed != this->m_NumOfSpeedCooling) {
6620 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_CoolingCoilName));
6621 0 : ShowContinueError(state,
6622 0 : format("... The number of Cooling coil speeds in the {} = {:.0R}",
6623 : MultispeedType,
6624 0 : double(this->m_NumOfSpeedCooling)));
6625 0 : ShowContinueError(
6626 : state,
6627 0 : format("... The number of heating coil speeds in Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6628 0 : double(NumOfSpeed)));
6629 0 : ShowContinueError(state, format("... The number of Cooling coil speeds in the {} will be used.", MultispeedType));
6630 : }
6631 1 : }
6632 12 : } break;
6633 : }
6634 : } else {
6635 1 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6636 2 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6637 1 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6638 1 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6639 1 : errorsFound = true;
6640 : }
6641 74 : } else if (this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty()) {
6642 74 : if (this->m_FanType == HVAC::FanType::SystemModel) {
6643 1 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex));
6644 1 : assert(fanSystem != nullptr);
6645 1 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
6646 1 : if (fanSystem->numSpeeds > 1) {
6647 0 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6648 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6649 0 : this->m_sysType == SysType::PackagedWSHP) {
6650 0 : this->m_NumOfSpeedCooling = fanSystem->numSpeeds;
6651 0 : this->m_CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6652 0 : this->m_CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
6653 0 : this->m_MSCoolingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6654 0 : this->m_MultiOrVarSpeedCoolCoil = true;
6655 0 : this->m_DiscreteSpeedCoolingCoil = true;
6656 0 : if (fanSystem->maxAirFlowRate > 0.0) {
6657 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6658 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6659 0 : this->m_CoolVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6660 0 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6661 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6662 : }
6663 : } else {
6664 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6665 0 : this->m_CoolMassFlowRate[i] = 0.0;
6666 0 : this->m_CoolVolumeFlowRate[i] = 0.0;
6667 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6668 : }
6669 : }
6670 : }
6671 : }
6672 0 : if ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6673 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6674 0 : this->m_sysType == SysType::PackagedWSHP) {
6675 0 : this->m_NumOfSpeedHeating = fanSystem->numSpeeds;
6676 0 : this->m_HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6677 0 : this->m_HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
6678 0 : this->m_MSHeatingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6679 0 : this->m_MultiSpeedHeatingCoil = true;
6680 0 : this->m_MultiOrVarSpeedHeatCoil = true;
6681 0 : if (fanSystem->maxAirFlowRate > 0.0) {
6682 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
6683 0 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6684 0 : this->m_HeatVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6685 0 : this->m_HeatMassFlowRate[i] = this->m_HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6686 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6687 : }
6688 : } else {
6689 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6690 0 : this->m_HeatMassFlowRate[i] = 0.0;
6691 0 : this->m_HeatVolumeFlowRate[i] = 0.0;
6692 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6693 : }
6694 : }
6695 : }
6696 : }
6697 0 : if (((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6698 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6699 0 : this->m_sysType == SysType::PackagedWSHP) ||
6700 0 : ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6701 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6702 0 : this->m_sysType == SysType::PackagedWSHP)) {
6703 0 : ShowWarningError(state,
6704 0 : format("{} = {} with Fan:SystemModel is used in \"{}\"",
6705 : cCurrentModuleObject,
6706 0 : this->Name,
6707 0 : this->input_specs.supply_fan_name));
6708 0 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
6709 0 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
6710 : }
6711 : }
6712 : }
6713 : }
6714 0 : } else if ((this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) ||
6715 0 : (!this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty())) {
6716 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6717 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6718 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6719 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6720 0 : errorsFound = true;
6721 : }
6722 :
6723 100 : if (this->m_DiscreteSpeedCoolingCoil) {
6724 :
6725 17 : if (this->m_NumOfSpeedCooling == 0) {
6726 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6727 0 : ShowContinueError(state,
6728 0 : format("... Cooling coil object type requires valid {} for cooling to be specified with number of speeds > 0",
6729 : unitarySysHeatPumpPerformanceObjectType));
6730 0 : errorsFound = true;
6731 : }
6732 : }
6733 100 : if (this->m_MultiSpeedHeatingCoil) {
6734 :
6735 14 : if (this->m_DesignSpecMSHPIndex > -1) this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6736 :
6737 14 : if (this->m_NumOfSpeedHeating == 0) {
6738 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6739 0 : ShowContinueError(state,
6740 0 : format("... Heating coil object type requires valid {} for heating to be specified with number of speeds > 0",
6741 : unitarySysHeatPumpPerformanceObjectType));
6742 0 : errorsFound = true;
6743 : }
6744 : }
6745 :
6746 100 : if ((this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating &&
6747 5 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling)) ||
6748 97 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel &&
6749 28 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling))) {
6750 6 : if (this->m_DesignSpecMSHPIndex > -1) {
6751 5 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
6752 1 : this->m_SingleMode = 1;
6753 : }
6754 : }
6755 : } else {
6756 94 : if (this->m_DesignSpecMSHPIndex > -1) {
6757 20 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
6758 0 : ShowSevereError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6759 0 : ShowContinueError(state,
6760 : "In order to perform Single Mode Operation, the valid cooling coil type is Coil:Cooling:DX:MultiSpeed "
6761 : "or Coil:Cooling:DX and the valid heating is Coil:Heating:DX:MultiSpeed or Coil:Heating:Fuel.");
6762 0 : ShowContinueError(state,
6763 0 : format("The input cooling coil type = {} and the input heating coil type = {}",
6764 0 : input_data.cooling_coil_object_type,
6765 0 : this->m_HeatingCoilTypeName));
6766 : }
6767 : }
6768 : }
6769 :
6770 100 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6771 6 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
6772 : }
6773 :
6774 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6775 5 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_HeatingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
6776 : }
6777 :
6778 : // set global logicals that denote coil type
6779 100 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
6780 20 : this->m_MultiOrVarSpeedHeatCoil = true;
6781 : }
6782 100 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
6783 24 : this->m_MultiOrVarSpeedCoolCoil = true;
6784 : }
6785 :
6786 : // set global variables for multi-stage chilled and hot water coils
6787 100 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
6788 12 : if (this->m_DesignSpecMSHPIndex > -1) {
6789 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6790 1 : if (this->m_NumOfSpeedCooling > 1) {
6791 1 : this->m_DiscreteSpeedCoolingCoil = true;
6792 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6793 : }
6794 : }
6795 : }
6796 100 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
6797 : // designSpecIndex = this->m_DesignSpecMSHPIndex;
6798 5 : if (this->m_DesignSpecMSHPIndex > -1) {
6799 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6800 1 : if (this->m_NumOfSpeedHeating > 1) {
6801 0 : this->m_MultiSpeedHeatingCoil = true;
6802 0 : this->m_MultiOrVarSpeedHeatCoil = true;
6803 : }
6804 : }
6805 : }
6806 : // zone coils are now simulated before sizing is complete, data will not be available but array is allocated
6807 100 : if (this->m_MultiOrVarSpeedCoolCoil) {
6808 27 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6809 27 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6810 27 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6811 : }
6812 100 : if (this->m_MultiOrVarSpeedHeatCoil) {
6813 20 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6814 20 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6815 20 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6816 : }
6817 :
6818 : // check for specific input requirements for ASHRAE90.1 model
6819 100 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6820 :
6821 : // only allowed for water and DX cooling coils at this time
6822 4 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWater &&
6823 3 : this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterDetailed && this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingSingleSpeed) {
6824 0 : if (state.dataGlobal->DisplayExtraWarnings) {
6825 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6826 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific cooling coil types.");
6827 0 : ShowContinueError(state,
6828 : "Valid cooling coil types are Coil:Cooling:Water, Coil:Cooling:Water:DetailedGeometry and "
6829 : "Coil:Cooling:DX:SingleSpeed.");
6830 0 : ShowContinueError(state,
6831 0 : format("The input cooling coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
6832 0 : input_data.cooling_coil_object_type));
6833 : }
6834 : // mark this coil as non-ASHRAE90 type
6835 0 : this->m_ValidASHRAECoolCoil = false;
6836 : }
6837 : // only allow for water, fuel, or electric at this time
6838 4 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWater &&
6839 3 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingGasOrOtherFuel && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingElectric &&
6840 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical) {
6841 0 : if (state.dataGlobal->DisplayExtraWarnings) {
6842 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6843 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific heating coil types.");
6844 0 : ShowContinueError(state,
6845 : "Valid heating coil types are Coil:Heating:Water, Coil:Heating:Fuel, Coil:Heating:Electric and "
6846 : "Coil:Heating:DX:SingleSpeed.");
6847 0 : ShowContinueError(state,
6848 0 : format("The input heating coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
6849 0 : this->m_HeatingCoilTypeName));
6850 : }
6851 : // mark this coil as non-ASHRAE90 type
6852 0 : this->m_ValidASHRAEHeatCoil = false;
6853 : }
6854 4 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6855 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6856 0 : ShowContinueError(state, format("Invalid entry for Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6857 0 : ShowContinueError(state,
6858 : "ASHRAE90.1 control method does not support dehumidification at this time. Dehumidification control type is "
6859 : "assumed to be None.");
6860 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6861 : }
6862 4 : if (this->m_RunOnLatentLoad) {
6863 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6864 0 : ShowContinueError(state, format("Invalid entry for Latent Load Control: {}", input_data.latent_load_control));
6865 0 : ShowContinueError(state,
6866 : "ASHRAE90.1 control method does not support latent load control at this time. This input must be selected as "
6867 : "SensibleOnlyLoadControl.");
6868 0 : this->m_RunOnSensibleLoad = true;
6869 0 : this->m_RunOnLatentLoad = false;
6870 0 : this->m_RunOnLatentOnlyWithSensible = false;
6871 : }
6872 4 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) { // 0 min air flow not allowed for SZVAV
6873 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6874 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6875 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
6876 0 : errorsFound = true;
6877 : }
6878 : }
6879 106 : }
6880 :
6881 136 : void UnitarySys::getDXCoilSystemData(
6882 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
6883 : {
6884 136 : std::string const cCurrentModuleObject = "CoilSystem:Cooling:DX";
6885 136 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
6886 136 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
6887 42 : auto &instancesValue = instances.value();
6888 42 : int numCoilSystemDX = 0;
6889 93 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
6890 :
6891 51 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
6892 : // only get the current data once all data has been read in and vector unitarySys has been initialized
6893 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
6894 51 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
6895 :
6896 45 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
6897 45 : UnitarySys thisSys;
6898 45 : if (sysNum == -1) {
6899 24 : ++state.dataUnitarySystems->numUnitarySystems;
6900 24 : auto const &thisObjName = instance.key();
6901 24 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
6902 : } else {
6903 21 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
6904 : }
6905 :
6906 : // get CoilSystem:Cooling:DX object inputs
6907 45 : auto const &fields = instance.value();
6908 45 : thisSys.input_specs.name = thisObjectName;
6909 45 : thisSys.input_specs.system_type = cCurrentModuleObject;
6910 90 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
6911 45 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
6912 : }
6913 : thisSys.input_specs.air_inlet_node_name =
6914 90 : Util::makeUPPER(fields.at("dx_cooling_coil_system_inlet_node_name").get<std::string>()); // required field
6915 : thisSys.input_specs.air_outlet_node_name =
6916 90 : Util::makeUPPER(fields.at("dx_cooling_coil_system_outlet_node_name").get<std::string>()); // required field
6917 :
6918 : thisSys.input_specs.dx_cooling_coil_system_sensor_node_name =
6919 90 : Util::makeUPPER(fields.at("dx_cooling_coil_system_sensor_node_name").get<std::string>()); // required field
6920 :
6921 : thisSys.input_specs.cooling_coil_object_type =
6922 90 : Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>()); // required field
6923 90 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>()); // required field
6924 : // min-fields = 7, begin optional inputs
6925 90 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field
6926 : thisSys.input_specs.dehumidification_control_type =
6927 11 : it.value().get<std::string>(); // Don't capitalize this one, since it's an enum
6928 : } else {
6929 : // find default value
6930 34 : thisSys.input_specs.dehumidification_control_type = "None";
6931 : }
6932 90 : std::string loc_RunOnSensLoad("");
6933 90 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) { // not required field
6934 11 : loc_RunOnSensLoad = Util::makeUPPER(it.value().get<std::string>());
6935 : } else {
6936 : // find default value
6937 34 : loc_RunOnSensLoad = "YES";
6938 : }
6939 90 : std::string loc_RunOnLatLoad("");
6940 90 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) { // not required field
6941 11 : loc_RunOnLatLoad = Util::makeUPPER(it.value().get<std::string>());
6942 : } else {
6943 : // find default value
6944 34 : loc_RunOnLatLoad = "NO";
6945 : }
6946 45 : if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "NO") {
6947 41 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
6948 4 : } else if (loc_RunOnSensLoad == "NO" && loc_RunOnLatLoad == "YES") {
6949 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
6950 4 : } else if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "YES") {
6951 : // does DX system control on LatentOrSensibleLoadControl or LatentWithSensibleLoadControl?
6952 4 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
6953 : }
6954 :
6955 90 : if (auto it = fields.find("use_outdoor_air_dx_cooling_coil"); it != fields.end()) { // not required field
6956 7 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
6957 : } else {
6958 : // find default value
6959 38 : thisSys.input_specs.use_doas_dx_cooling_coil = "NO";
6960 : }
6961 90 : if (auto it = fields.find("outdoor_air_dx_cooling_coil_leaving_minimum_air_temperature"); it != fields.end()) { // not required field
6962 0 : thisSys.input_specs.minimum_supply_air_temperature = it.value().get<Real64>();
6963 : }
6964 : // set UnitarySystem specific inputs
6965 45 : thisSys.input_specs.control_type = "SETPOINT";
6966 :
6967 : // now translate to UnitarySystem
6968 45 : thisSys.UnitType = cCurrentModuleObject;
6969 45 : thisSys.m_sysType = SysType::CoilCoolingDX;
6970 45 : thisSys.AirloopEqType = SimAirServingZones::CompType::DXSystem;
6971 :
6972 : // TODO: figure out another way to set this next variable
6973 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
6974 45 : thisSys.m_LastMode = CoolingMode;
6975 45 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
6976 :
6977 45 : if (sysNum == -1) {
6978 24 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
6979 24 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
6980 : // zone equipment require a 1-n index for access to zone availability managers
6981 : // although not zone equipment, use same methodology
6982 24 : ++numCoilSystemDX;
6983 24 : thisSys.m_EquipCompNum = numCoilSystemDX;
6984 : } else {
6985 21 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
6986 : }
6987 51 : }
6988 : }
6989 136 : }
6990 :
6991 136 : void UnitarySys::getPackagedTerminalUnitData(
6992 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
6993 : {
6994 136 : std::string cCurrentModuleObject = "ZoneHVAC:PackagedTerminalAirConditioner";
6995 136 : SysType sysTypeNum = SysType::PackagedAC;
6996 136 : DataZoneEquipment::ZoneEquipType zoneEqType = DataZoneEquipment::ZoneEquipType::Invalid;
6997 136 : int numPTAC = 0;
6998 136 : int numPTHP = 0;
6999 136 : int numPTWSHP = 0;
7000 136 : auto &ip = state.dataInputProcessing->inputProcessor;
7001 544 : for (int getPTUnitType = 1; getPTUnitType <= 3; ++getPTUnitType) {
7002 408 : if (getPTUnitType == 2) {
7003 136 : sysTypeNum = SysType::PackagedHP;
7004 136 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7005 136 : cCurrentModuleObject = "ZoneHVAC:PackagedTerminalHeatPump";
7006 272 : } else if (getPTUnitType == 3) {
7007 136 : sysTypeNum = SysType::PackagedWSHP;
7008 136 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7009 136 : cCurrentModuleObject = "ZoneHVAC:WaterToAirHeatPump";
7010 : }
7011 408 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7012 408 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7013 30 : auto &instancesValue = instances.value();
7014 30 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
7015 87 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7016 :
7017 57 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7018 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7019 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7020 57 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
7021 :
7022 35 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7023 35 : UnitarySys thisSys;
7024 35 : if (sysNum == -1) {
7025 18 : ++state.dataUnitarySystems->numUnitarySystems;
7026 18 : auto const &thisObjName = instance.key();
7027 18 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7028 : } else {
7029 17 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7030 : }
7031 :
7032 : // get PackagedTerminal unit object inputs
7033 35 : auto const &fields = instance.value();
7034 35 : thisSys.input_specs.name = thisObjectName;
7035 35 : thisSys.input_specs.system_type = cCurrentModuleObject;
7036 70 : thisSys.input_specs.availability_schedule_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_schedule_name");
7037 70 : thisSys.input_specs.air_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_inlet_node_name");
7038 70 : thisSys.input_specs.air_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_outlet_node_name");
7039 :
7040 70 : thisSys.input_specs.oa_mixer_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_object_type");
7041 70 : thisSys.input_specs.oa_mixer_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_name");
7042 :
7043 35 : thisSys.input_specs.cooling_supply_air_flow_rate =
7044 70 : ip->getRealFieldValue(fields, objectSchemaProps, "cooling_supply_air_flow_rate");
7045 35 : thisSys.input_specs.heating_supply_air_flow_rate =
7046 70 : ip->getRealFieldValue(fields, objectSchemaProps, "heating_supply_air_flow_rate");
7047 35 : thisSys.input_specs.no_load_supply_air_flow_rate =
7048 70 : ip->getRealFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate");
7049 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed =
7050 70 : ip->getAlphaFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7051 70 : thisSys.input_specs.cooling_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_outdoor_air_flow_rate");
7052 70 : thisSys.input_specs.heating_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "heating_outdoor_air_flow_rate");
7053 70 : thisSys.input_specs.no_load_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "no_load_outdoor_air_flow_rate");
7054 :
7055 70 : thisSys.input_specs.supply_fan_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_object_type");
7056 70 : thisSys.input_specs.supply_fan_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_name");
7057 70 : thisSys.input_specs.heating_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_object_type");
7058 70 : thisSys.input_specs.heating_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_name");
7059 70 : thisSys.input_specs.cooling_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_object_type");
7060 70 : thisSys.input_specs.cooling_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_name");
7061 :
7062 70 : thisSys.input_specs.fan_placement = ip->getAlphaFieldValue(fields, objectSchemaProps, "fan_placement");
7063 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name =
7064 70 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_operating_mode_schedule_name");
7065 35 : if (getPTUnitType > 1) {
7066 10 : thisSys.input_specs.maximum_supply_air_temperature_from_supplemental_heater =
7067 20 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_from_supplemental_heater");
7068 : thisSys.input_specs.supplemental_heating_coil_object_type =
7069 20 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_object_type");
7070 : thisSys.input_specs.supplemental_heating_coil_name =
7071 20 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_name");
7072 20 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = ip->getRealFieldValue(
7073 : fields, objectSchemaProps, "maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7074 10 : if (getPTUnitType == 2) {
7075 12 : thisSys.input_specs.heat_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "heating_convergence_tolerance");
7076 18 : thisSys.input_specs.cool_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_convergence_tolerance");
7077 4 : } else if (getPTUnitType == 3) {
7078 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name =
7079 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_dry_bulb_temperature_sensor_node_name");
7080 : thisSys.input_specs.heat_pump_coil_water_flow_mode =
7081 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "heat_pump_coil_water_flow_mode");
7082 4 : thisSys.input_specs.control_type = "LOAD";
7083 : }
7084 : }
7085 35 : if (getPTUnitType < 3) {
7086 62 : thisSys.input_specs.control_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "capacity_control_method");
7087 31 : if (thisSys.input_specs.control_type.empty() || thisSys.input_specs.control_type == "NONE") {
7088 29 : thisSys.input_specs.control_type = "LOAD";
7089 : }
7090 31 : thisSys.input_specs.minimum_supply_air_temperature =
7091 62 : ip->getRealFieldValue(fields, objectSchemaProps, "minimum_supply_air_temperature_in_cooling_mode");
7092 31 : thisSys.input_specs.maximum_supply_air_temperature =
7093 93 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_in_heating_mode");
7094 : }
7095 :
7096 70 : thisSys.input_specs.avail_manager_list_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_manager_list_name");
7097 : thisSys.input_specs.design_spec_zonehvac_sizing_object_name =
7098 70 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_zonehvac_sizing_object_name");
7099 :
7100 35 : if (getPTUnitType == 3) {
7101 : thisSys.m_DesignSpecMultispeedHPType =
7102 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_type");
7103 : thisSys.m_DesignSpecMultispeedHPName =
7104 8 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_name");
7105 4 : if (!thisSys.m_DesignSpecMultispeedHPType.empty() && !thisSys.m_DesignSpecMultispeedHPName.empty()) {
7106 4 : DesignSpecMSHP thisDesignSpec;
7107 4 : thisSys.m_CompPointerMSHP =
7108 4 : thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, thisSys.m_DesignSpecMultispeedHPName);
7109 4 : thisSys.m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, thisSys.m_DesignSpecMultispeedHPName);
7110 4 : }
7111 : }
7112 :
7113 : // set UnitarySystem specific inputs
7114 35 : thisSys.input_specs.dehumidification_control_type = "None";
7115 35 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7116 35 : thisSys.input_specs.cooling_supply_air_flow_rate_method = "SupplyAirFlowRate";
7117 35 : thisSys.input_specs.heating_supply_air_flow_rate_method = "SupplyAirFlowRate";
7118 35 : thisSys.input_specs.no_load_supply_air_flow_rate_method = "SupplyAirFlowRate";
7119 :
7120 35 : thisSys.UnitType = cCurrentModuleObject;
7121 35 : thisSys.m_sysType = sysTypeNum;
7122 35 : thisSys.zoneEquipType = zoneEqType;
7123 :
7124 : // TODO: figure out another way to set this next variable
7125 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7126 35 : thisSys.m_LastMode = HeatingMode;
7127 35 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7128 :
7129 35 : if (sysNum == -1) {
7130 : // zone equipment require a 1-n index for access to zone availability managers
7131 18 : switch (getPTUnitType) {
7132 13 : case 1: // Excuse me?
7133 13 : ++numPTAC;
7134 13 : thisSys.m_EquipCompNum = numPTAC;
7135 13 : break;
7136 3 : case 2: // Baking powder?
7137 3 : ++numPTHP;
7138 3 : thisSys.m_EquipCompNum = numPTHP;
7139 3 : break;
7140 2 : case 3:
7141 2 : ++numPTWSHP;
7142 2 : thisSys.m_EquipCompNum = numPTWSHP;
7143 2 : break;
7144 18 : default:
7145 : assert(true);
7146 : }
7147 18 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7148 18 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7149 : } else {
7150 17 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7151 : }
7152 57 : }
7153 : }
7154 : }
7155 136 : }
7156 :
7157 136 : void UnitarySys::allocateUnitarySys(EnergyPlusData &state)
7158 : {
7159 136 : if (!state.dataUnitarySystems->unitarySys.empty()) return;
7160 92 : int numUnitarySystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:UnitarySystem");
7161 92 : int numCoilSystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:DX");
7162 92 : int numCoilSystemsWater = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:Water");
7163 92 : int numPackagedAC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalAirConditioner");
7164 92 : int numPackagedHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalHeatPump");
7165 92 : int numPackagedWSHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:WaterToAirHeatPump");
7166 92 : int numAllSystemTypes = numUnitarySystems + numCoilSystems + numCoilSystemsWater + numPackagedAC + numPackagedHP + numPackagedWSHP;
7167 193 : for (int sysCount = 0; sysCount < numAllSystemTypes; ++sysCount) {
7168 101 : UnitarySys thisSys;
7169 101 : state.dataUnitarySystems->unitarySys.push_back(thisSys);
7170 101 : }
7171 : }
7172 :
7173 142 : void UnitarySys::getCoilWaterSystemInputData(
7174 : EnergyPlusData &state, std::string_view CoilSysName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7175 : {
7176 :
7177 142 : std::string cCurrentModuleObject("CoilSystem:Cooling:Water");
7178 326 : static const std::string routineName("getCoilWaterSystemInputData: ");
7179 142 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7180 142 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7181 12 : auto &instancesValue = instances.value();
7182 12 : int numCoilSystemWater = 0;
7183 24 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7184 :
7185 12 : auto const &fields = instance.value();
7186 12 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7187 12 : if (!Util::SameString(CoilSysName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
7188 :
7189 12 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7190 12 : UnitarySys thisSys;
7191 12 : if (sysNum == -1) {
7192 6 : ++state.dataUnitarySystems->numUnitarySystems;
7193 6 : auto const &thisObjName = instance.key();
7194 6 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7195 : } else {
7196 6 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7197 : }
7198 :
7199 12 : thisSys.input_specs.name = thisObjectName;
7200 12 : thisSys.input_specs.system_type = cCurrentModuleObject;
7201 12 : thisSys.input_specs.control_type = "Setpoint";
7202 24 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>());
7203 24 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>());
7204 24 : std::string availScheduleName("");
7205 24 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field, has default value of Always On
7206 0 : availScheduleName = Util::makeUPPER(it.value().get<std::string>());
7207 : }
7208 12 : thisSys.input_specs.availability_schedule_name = availScheduleName;
7209 24 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>());
7210 12 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>());
7211 : // why is this cooling coil does not have a field for Design Air Vol Flow Rate
7212 : // set it "SupplyAirFlowRate" to avoid blank, which lead to fatal out during get input
7213 : static constexpr std::string_view loc_cooling_coil_object_type("COIL:COOLING:WATER:DETAILEDGEOMETRY");
7214 12 : if (Util::SameString(loc_cooling_coil_object_type, thisSys.input_specs.cooling_coil_object_type)) {
7215 2 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER("SupplyAirFlowRate");
7216 2 : thisSys.input_specs.cooling_supply_air_flow_rate = DataSizing::AutoSize;
7217 : }
7218 : // optional input fields
7219 12 : if (auto it = fields.find("minimum_air_to_water_temperature_offset");
7220 12 : it != fields.end()) { // not required field, has default value of 0.0
7221 12 : thisSys.m_minAirToWaterTempOffset = it.value().get<Real64>();
7222 : }
7223 24 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) {
7224 12 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7225 : } else {
7226 0 : thisSys.input_specs.dehumidification_control_type = "None";
7227 : }
7228 :
7229 12 : bool runOnSensibleLoad = true;
7230 24 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) {
7231 12 : runOnSensibleLoad = Util::SameString(it.value().get<std::string>(), "YES");
7232 : }
7233 12 : bool runOnLatentLoad = false;
7234 24 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) {
7235 12 : runOnLatentLoad = Util::SameString(it.value().get<std::string>(), "YES");
7236 : }
7237 :
7238 12 : if (runOnSensibleLoad && !runOnLatentLoad) {
7239 10 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7240 2 : } else if (!runOnSensibleLoad && runOnLatentLoad) {
7241 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7242 2 : } else if (runOnSensibleLoad && runOnLatentLoad) {
7243 2 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7244 : }
7245 :
7246 : // now translate to UnitarySystem
7247 12 : thisSys.UnitType = cCurrentModuleObject;
7248 12 : thisSys.m_sysType = SysType::CoilCoolingWater;
7249 12 : thisSys.AirloopEqType = SimAirServingZones::CompType::CoilSystemWater;
7250 12 : thisSys.input_specs.control_type = "Setpoint";
7251 12 : thisSys.m_CoolCoilExists = true; // is always true
7252 12 : thisSys.m_LastMode = CoolingMode;
7253 : // set water-side economizer flag
7254 12 : if (thisSys.m_minAirToWaterTempOffset > 0.0) thisSys.m_TemperatureOffsetControlActive = true;
7255 :
7256 : // heat recovery loop inputs
7257 24 : if (auto it = fields.find("minimum_water_loop_temperature_for_heat_recovery"); it != fields.end()) {
7258 0 : thisSys.m_minWaterLoopTempForHR = it.value().get<Real64>();
7259 : }
7260 24 : if (auto it = fields.find("economizer_lockout"); it != fields.end()) { // duplicate above as default
7261 0 : bool econoFlag = Util::SameString(it.value().get<std::string>(), "YES");
7262 0 : if (econoFlag) {
7263 0 : thisSys.m_waterSideEconomizerFlag = true;
7264 : }
7265 : } else {
7266 12 : thisSys.m_waterSideEconomizerFlag = true;
7267 : }
7268 12 : std::string HRWaterCoolingCoilName;
7269 24 : if (auto it = fields.find("companion_coil_used_for_heat_recovery"); it != fields.end()) {
7270 2 : HRWaterCoolingCoilName = Util::makeUPPER(it.value().get<std::string>());
7271 2 : thisSys.m_WaterHRPlantLoopModel = true;
7272 : }
7273 12 : if (thisSys.m_WaterHRPlantLoopModel) {
7274 2 : std::string const HRcoolingCoilType("COIL:COOLING:WATER");
7275 2 : bool errFound = false;
7276 2 : thisSys.m_HRcoolCoilAirInNode = WaterCoils::GetCoilInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7277 2 : thisSys.m_HRcoolCoilFluidInletNode =
7278 2 : WaterCoils::GetCoilWaterInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7279 2 : int HRCoilIndex = WaterCoils::GetWaterCoilIndex(state, Util::makeUPPER(HRcoolingCoilType), HRWaterCoolingCoilName, errFound);
7280 2 : bool heatRecoveryCoil = true; // use local here to highlight where this parameter is set
7281 2 : WaterCoils::SetWaterCoilData(state, HRCoilIndex, errFound, _, _, heatRecoveryCoil);
7282 2 : if (errFound) {
7283 0 : if (HRCoilIndex == 0) {
7284 0 : ShowContinueError(state, format("...cooling coil {} must be of type Coil:Cooling:Water.", HRWaterCoolingCoilName));
7285 : }
7286 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisObjectName));
7287 : }
7288 2 : errorsFound = errorsFound || errFound;
7289 2 : }
7290 : // end heat recovery loop inputs
7291 :
7292 12 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7293 :
7294 12 : if (sysNum == -1) {
7295 6 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7296 6 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7297 : // zone equipment require a 1-n index for access to zone availability managers
7298 : // although not zone equipment, use same methodology
7299 6 : ++numCoilSystemWater;
7300 6 : thisSys.m_EquipCompNum = numCoilSystemWater;
7301 : } else {
7302 6 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7303 : }
7304 12 : }
7305 :
7306 12 : if (errorsFound) {
7307 0 : ShowFatalError(
7308 : state,
7309 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", routineName, cCurrentModuleObject));
7310 : }
7311 : }
7312 142 : }
7313 :
7314 186 : void UnitarySys::getUnitarySystemInputData(
7315 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7316 : {
7317 :
7318 186 : std::string const cCurrentModuleObject = "AirLoopHVAC:UnitarySystem";
7319 372 : static std::string const getUnitarySystemInput("getUnitarySystemInputData");
7320 186 : int zoneUnitaryNum = 0;
7321 186 : int airloopUnitaryNum = 0;
7322 :
7323 186 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7324 186 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end() && state.dataUnitarySystems->numUnitarySystems == 0) {
7325 0 : ShowSevereError(state, "getUnitarySystemInputData: did not find AirLoopHVAC:UnitarySystem object in input file. Check inputs");
7326 0 : errorsFound = true;
7327 186 : } else if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7328 111 : auto &instancesValue = instances.value();
7329 111 : auto const &objectSchemaProps = state.dataInputProcessing->inputProcessor->getObjectSchemaProps(state, cCurrentModuleObject);
7330 222 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7331 :
7332 111 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7333 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7334 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the current object
7335 111 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
7336 :
7337 109 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7338 109 : UnitarySys thisSys;
7339 109 : if (sysNum == -1) {
7340 53 : ++state.dataUnitarySystems->numUnitarySystems;
7341 53 : auto const &thisObjName = instance.key();
7342 53 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7343 : } else {
7344 56 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7345 : }
7346 :
7347 109 : auto const &fields = instance.value();
7348 109 : thisSys.UnitType = cCurrentModuleObject;
7349 109 : thisSys.m_sysType = SysType::Unitary;
7350 109 : thisSys.AirloopEqType = SimAirServingZones::CompType::UnitarySystemModel;
7351 :
7352 109 : thisSys.input_specs.name = thisObjectName;
7353 109 : thisSys.input_specs.system_type = cCurrentModuleObject;
7354 218 : thisSys.input_specs.control_type = fields.at("control_type").get<std::string>();
7355 218 : if (auto it = fields.find("controlling_zone_or_thermostat_location"); it != fields.end()) { // not required field
7356 101 : thisSys.input_specs.controlling_zone_or_thermostat_location = Util::makeUPPER(it.value().get<std::string>());
7357 : }
7358 218 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field, has default
7359 108 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7360 : } else {
7361 1 : thisSys.input_specs.dehumidification_control_type = "NONE"; // default value
7362 : }
7363 218 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7364 83 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7365 : }
7366 218 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>()); // required
7367 218 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>()); // required
7368 218 : if (auto it = fields.find("supply_fan_object_type"); it != fields.end()) { // not required field
7369 105 : thisSys.input_specs.supply_fan_object_type = Util::makeUPPER(it.value().get<std::string>());
7370 : }
7371 :
7372 218 : if (auto it = fields.find("supply_fan_name"); it != fields.end()) { // not required field
7373 105 : thisSys.input_specs.supply_fan_name = Util::makeUPPER(it.value().get<std::string>());
7374 : }
7375 218 : if (auto it = fields.find("fan_placement"); it != fields.end()) { // not required field
7376 105 : thisSys.input_specs.fan_placement = Util::makeUPPER(it.value().get<std::string>());
7377 : }
7378 218 : if (auto it = fields.find("supply_air_fan_operating_mode_schedule_name"); it != fields.end()) { // not required field
7379 53 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7380 : }
7381 218 : if (auto it = fields.find("heating_coil_object_type"); it != fields.end()) { // not required field
7382 93 : thisSys.input_specs.heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7383 93 : thisSys.m_HeatCoilExists = true;
7384 : }
7385 218 : if (auto it = fields.find("heating_coil_name"); it != fields.end()) { // not required field
7386 93 : thisSys.input_specs.heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7387 : }
7388 218 : if (auto it = fields.find("dx_heating_coil_sizing_ratio"); it != fields.end()) { // not required field, has default
7389 19 : thisSys.input_specs.dx_heating_coil_sizing_ratio = it.value().get<Real64>();
7390 : }
7391 218 : if (auto it = fields.find("cooling_coil_object_type"); it != fields.end()) { // not required field
7392 76 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7393 76 : thisSys.m_CoolCoilExists = true;
7394 : }
7395 218 : if (auto it = fields.find("cooling_coil_name"); it != fields.end()) { // not required field
7396 76 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(it.value().get<std::string>());
7397 : }
7398 218 : if (auto it = fields.find("use_doas_dx_cooling_coil"); it != fields.end()) { // not required field, has default
7399 57 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7400 : } else {
7401 52 : thisSys.input_specs.use_doas_dx_cooling_coil = "No";
7402 : }
7403 109 : if (auto it = fields.find("minimum_supply_air_temperature");
7404 109 : it != fields.end()) { // not required field, has default (2C), and autosizable
7405 66 : thisSys.input_specs.minimum_supply_air_temperature =
7406 134 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7407 134 : ? DataSizing::AutoSize
7408 64 : : it.value().get<Real64>();
7409 : }
7410 218 : if (auto it = fields.find("latent_load_control"); it != fields.end()) { // not required field, has default
7411 58 : thisSys.input_specs.latent_load_control = it.value().get<std::string>();
7412 : } else {
7413 51 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7414 : }
7415 218 : if (auto it = fields.find("supplemental_heating_coil_object_type"); it != fields.end()) { // not required field
7416 43 : thisSys.input_specs.supplemental_heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7417 : }
7418 218 : if (auto it = fields.find("supplemental_heating_coil_name"); it != fields.end()) { // not required field
7419 43 : thisSys.input_specs.supplemental_heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7420 : }
7421 218 : if (auto it = fields.find("cooling_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7422 61 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER(it.value().get<std::string>());
7423 : }
7424 218 : if (auto it = fields.find("cooling_supply_air_flow_rate"); it != fields.end()) { // not required field, autosizable
7425 94 : thisSys.input_specs.cooling_supply_air_flow_rate =
7426 249 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7427 249 : ? DataSizing::AutoSize
7428 33 : : it.value().get<Real64>();
7429 : }
7430 218 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7431 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7432 : }
7433 218 : if (auto it = fields.find("cooling_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7434 2 : thisSys.input_specs.cooling_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7435 : }
7436 218 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7437 9 : thisSys.input_specs.cooling_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7438 : }
7439 218 : if (auto it = fields.find("heating_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7440 93 : thisSys.input_specs.heating_supply_air_flow_rate_method = it.value().get<std::string>();
7441 : }
7442 218 : if (auto it = fields.find("heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7443 97 : thisSys.input_specs.heating_supply_air_flow_rate =
7444 258 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7445 258 : ? DataSizing::AutoSize
7446 33 : : it.value().get<Real64>();
7447 : }
7448 218 : if (auto it = fields.find("heating_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7449 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7450 : }
7451 218 : if (auto it = fields.find("heating_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7452 2 : thisSys.input_specs.heating_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7453 : }
7454 218 : if (auto it = fields.find("heating_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7455 6 : thisSys.input_specs.heating_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7456 : }
7457 218 : if (auto it = fields.find("no_load_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7458 61 : thisSys.input_specs.no_load_supply_air_flow_rate_method = it.value().get<std::string>();
7459 : }
7460 218 : if (auto it = fields.find("no_load_supply_air_flow_rate"); it != fields.end()) { // not required field
7461 92 : thisSys.input_specs.no_load_supply_air_flow_rate =
7462 239 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7463 239 : ? DataSizing::AutoSize
7464 37 : : it.value().get<Real64>();
7465 : }
7466 218 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7467 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7468 : }
7469 218 : if (auto it = fields.find("no_load_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7470 2 : thisSys.input_specs.no_load_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7471 : }
7472 218 : if (auto it = fields.find("no_load_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7473 0 : thisSys.input_specs.no_load_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7474 : }
7475 109 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation");
7476 109 : it != fields.end()) { // not required field
7477 4 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation = it.value().get<Real64>();
7478 : }
7479 109 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation");
7480 109 : it != fields.end()) { // not required field
7481 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation = it.value().get<Real64>();
7482 : }
7483 327 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed = state.dataInputProcessing->inputProcessor->getAlphaFieldValue(
7484 109 : fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7485 327 : if (fields.find("maximum_supply_air_temperature") != fields.end()) { // not required field, has default of 80 C
7486 106 : auto const &obj = fields.at("maximum_supply_air_temperature");
7487 106 : thisSys.input_specs.maximum_supply_air_temperature =
7488 117 : (obj.type() == nlohmann::detail::value_t::string && Util::SameString(obj.get<std::string>(), "Autosize"))
7489 117 : ? DataSizing::AutoSize
7490 95 : : obj.get<Real64>();
7491 : }
7492 109 : if (auto it = fields.find("maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7493 109 : it != fields.end()) { // not required field, has default
7494 31 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = it.value().get<Real64>();
7495 : }
7496 218 : if (auto it = fields.find("outdoor_dry_bulb_temperature_sensor_node_name"); it != fields.end()) { // not required field
7497 2 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name = Util::makeUPPER(it.value().get<std::string>());
7498 : }
7499 218 : if (auto it = fields.find("ancillary_on_cycle_electric_power"); it != fields.end()) { // not required field, has default
7500 8 : thisSys.input_specs.ancillary_on_cycle_electric_power = it.value().get<Real64>();
7501 : }
7502 218 : if (auto it = fields.find("ancillary_off_cycle_electric_power"); it != fields.end()) { // not required field, has default
7503 8 : thisSys.input_specs.ancillary_off_cycle_electric_power = it.value().get<Real64>();
7504 : }
7505 218 : if (auto it = fields.find("design_heat_recovery_water_flow_rate"); it != fields.end()) { // not required field, has default
7506 9 : thisSys.input_specs.design_heat_recovery_water_flow_rate = it.value().get<Real64>();
7507 : }
7508 218 : if (auto it = fields.find("maximum_temperature_for_heat_recovery"); it != fields.end()) { // not required field, has default
7509 13 : thisSys.input_specs.maximum_temperature_for_heat_recovery = it.value().get<Real64>();
7510 : }
7511 218 : if (auto it = fields.find("heat_recovery_water_inlet_node_name"); it != fields.end()) { // not required field
7512 9 : thisSys.input_specs.heat_recovery_water_inlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7513 : }
7514 218 : if (auto it = fields.find("heat_recovery_water_outlet_node_name"); it != fields.end()) { // not required field
7515 9 : thisSys.input_specs.heat_recovery_water_outlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7516 : }
7517 218 : if (auto it = fields.find("design_specification_multispeed_object_type"); it != fields.end()) { // not required field
7518 45 : thisSys.input_specs.design_specification_multispeed_object_type = Util::makeUPPER(it.value().get<std::string>());
7519 : }
7520 218 : if (auto it = fields.find("design_specification_multispeed_object_name"); it != fields.end()) { // not required field
7521 45 : thisSys.input_specs.design_specification_multispeed_object_name = Util::makeUPPER(it.value().get<std::string>());
7522 : }
7523 :
7524 109 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7525 :
7526 109 : if (sysNum == -1) {
7527 53 : ++thisSys.m_UnitarySysNum;
7528 53 : if (ZoneEquipment) {
7529 : // zone equipment require a 1-n index for access to zone availability managers
7530 49 : ++zoneUnitaryNum;
7531 49 : thisSys.m_EquipCompNum = zoneUnitaryNum;
7532 : } else {
7533 : // zone equipment require a 1-n index for access to zone availability managers
7534 : // although not zone equipment, use same methodology
7535 : // keep OA system unitary equipment indexes separate?
7536 4 : ++airloopUnitaryNum;
7537 4 : thisSys.m_EquipCompNum = airloopUnitaryNum;
7538 : }
7539 53 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7540 53 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7541 : } else {
7542 56 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7543 : }
7544 111 : }
7545 : }
7546 186 : }
7547 :
7548 26 : void UnitarySys::calcUnitarySuppSystemToSP(EnergyPlusData &state, bool const FirstHVACIteration // True when first HVAC iteration
7549 : )
7550 : {
7551 :
7552 : // SUBROUTINE INFORMATION:
7553 : // AUTHOR Richard Raustad, FSEC
7554 : // DATE WRITTEN February 2013
7555 :
7556 : // PURPOSE OF THIS SUBROUTINE:
7557 : // This subroutine manages supplemental heater component simulation for setpoint based operation scheme.
7558 :
7559 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7560 : Real64 QActual;
7561 :
7562 26 : std::string CompName = this->m_SuppHeatCoilName;
7563 26 : int CoilType_Num = this->m_SuppHeatCoilType_Num;
7564 :
7565 26 : if ((CoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel) || (CoilType_Num == HVAC::Coil_HeatingElectric)) {
7566 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
7567 : CompName,
7568 : FirstHVACIteration,
7569 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7570 0 : this->m_SuppHeatCoilIndex,
7571 : _,
7572 0 : true,
7573 0 : this->m_FanOpMode,
7574 0 : this->m_SuppHeatPartLoadFrac);
7575 :
7576 26 : } else if (CoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
7577 44 : HeatingCoils::SimulateHeatingCoilComponents(state,
7578 : CompName,
7579 : FirstHVACIteration,
7580 : _,
7581 22 : this->m_SuppHeatCoilIndex,
7582 : _,
7583 : _,
7584 22 : this->m_FanOpMode,
7585 22 : this->m_SuppHeatPartLoadFrac,
7586 22 : this->m_SuppHeatingSpeedNum,
7587 22 : this->m_SuppHeatingSpeedRatio);
7588 :
7589 4 : } else if (CoilType_Num == HVAC::Coil_HeatingDesuperheater) {
7590 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
7591 : CompName,
7592 : FirstHVACIteration,
7593 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7594 0 : this->m_SuppHeatCoilIndex,
7595 : _,
7596 : _,
7597 0 : this->m_FanOpMode,
7598 0 : this->m_SuppHeatPartLoadFrac);
7599 :
7600 4 : } else if (CoilType_Num == HVAC::Coil_HeatingWater) {
7601 8 : WaterCoils::SimulateWaterCoilComponents(
7602 8 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, QActual, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
7603 :
7604 0 : } else if (CoilType_Num == HVAC::Coil_HeatingSteam) {
7605 0 : SteamCoils::SimulateSteamCoilComponents(state,
7606 : CompName,
7607 : FirstHVACIteration,
7608 0 : this->m_SuppHeatCoilIndex,
7609 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7610 : _,
7611 0 : this->m_FanOpMode,
7612 0 : this->m_SuppHeatPartLoadFrac);
7613 : }
7614 26 : }
7615 :
7616 7036 : void UnitarySys::controlUnitarySystemtoLoad(EnergyPlusData &state,
7617 : int const AirLoopNum, // Primary air loop number
7618 : bool const FirstHVACIteration, // True when first HVAC iteration
7619 : HVAC::CompressorOp &CompressorOn, // Determines if compressor is on or off
7620 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7621 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7622 : Real64 &sysOutputProvided, // system sensible output at supply air node
7623 : Real64 &latOutputProvided // system latent output at supply air node
7624 : )
7625 : {
7626 :
7627 : // SUBROUTINE INFORMATION:
7628 : // AUTHOR Richard Raustad, FSEC
7629 : // DATE WRITTEN February 2013
7630 7036 : Real64 ZoneLoad = 0.0; // zone load (W)
7631 7036 : Real64 SupHeaterLoad = 0.0; // additional heating required by supplemental heater (W)
7632 7036 : Real64 OnOffAirFlowRatio = 1.0;
7633 7036 : this->updateUnitarySystemControl(state,
7634 : AirLoopNum,
7635 : this->CoolCoilOutletNodeNum,
7636 : this->CoolCtrlNode,
7637 : OnOffAirFlowRatio,
7638 : FirstHVACIteration,
7639 : OAUCoilOutTemp,
7640 : ZoneLoad,
7641 : this->DesignMaxOutletTemp);
7642 :
7643 : // will not be running supplemental heater on this CALL (simulate with supplemental heater off)
7644 7036 : Real64 FullSensibleOutput = 0.0;
7645 : // using furnace module logic
7646 : // first check to see if cycling fan with economizer can meet the load
7647 7036 : if (AirLoopNum > 0) {
7648 8 : if (this->m_CoolCoilExists && this->m_HeatCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingAirToAirVariableSpeed &&
7649 8 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed && !FirstHVACIteration &&
7650 18 : this->m_FanOpMode == HVAC::FanOp::Cycling && state.dataUnitarySystems->CoolingLoad &&
7651 2 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
7652 0 : CompressorOn = HVAC::CompressorOp::Off;
7653 0 : this->controlUnitarySystemOutput(
7654 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7655 0 : if (this->m_CoolingPartLoadFrac >= 1.0 || this->m_HeatingPartLoadFrac >= 1.0 ||
7656 0 : (this->m_CoolingPartLoadFrac <= 0.0 && this->m_HeatingPartLoadFrac <= 0.0)) {
7657 0 : CompressorOn = HVAC::CompressorOp::On;
7658 0 : this->controlUnitarySystemOutput(
7659 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7660 : }
7661 : } else {
7662 8 : CompressorOn = HVAC::CompressorOp::On;
7663 8 : this->controlUnitarySystemOutput(
7664 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7665 : }
7666 : } else {
7667 7028 : CompressorOn = HVAC::CompressorOp::On;
7668 7028 : this->controlUnitarySystemOutput(
7669 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7670 : }
7671 9764 : if (state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate < HVAC::SmallMassFlow && this->m_sysType != SysType::PackagedAC &&
7672 9764 : this->m_sysType != SysType::PackagedHP && this->m_sysType != SysType::PackagedWSHP) {
7673 5 : state.dataUnitarySystems->CoolingLoad = false;
7674 5 : state.dataUnitarySystems->HeatingLoad = false;
7675 5 : state.dataUnitarySystems->MoistureLoad = 0.0;
7676 5 : this->m_CoolingPartLoadFrac = 0.0;
7677 5 : this->m_HeatingPartLoadFrac = 0.0;
7678 5 : if (this->CoolCoilFluidInletNode > 0) state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
7679 5 : if (this->HeatCoilFluidInletNode > 0) state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = 0.0;
7680 5 : this->setAverageAirFlow(state, this->m_CoolingPartLoadFrac, OnOffAirFlowRatio);
7681 : // anything else need to be reset here when system is shut down on low flow?
7682 : }
7683 7036 : Real64 CoolPLR = this->m_CoolingPartLoadFrac;
7684 7036 : Real64 HeatPLR = this->m_HeatingPartLoadFrac;
7685 7036 : Real64 HeatCoilLoad = HeatPLR * this->m_DesignHeatingCapacity;
7686 :
7687 7036 : if (this->CoolCoilFluidInletNode > 0) {
7688 22 : PlantUtilities::SetComponentFlowRate(state,
7689 11 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate,
7690 : this->CoolCoilFluidInletNode,
7691 : this->CoolCoilFluidOutletNodeNum,
7692 11 : this->CoolCoilPlantLoc);
7693 : }
7694 7036 : if (this->HeatCoilFluidInletNode > 0) {
7695 22 : PlantUtilities::SetComponentFlowRate(state,
7696 11 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate,
7697 : this->HeatCoilFluidInletNode,
7698 : this->HeatCoilFluidOutletNodeNum,
7699 11 : this->HeatCoilPlantLoc);
7700 : }
7701 :
7702 14020 : if (this->m_SuppCoilExists &&
7703 6984 : (state.dataUnitarySystems->HeatingLoad || state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < 0.0)) {
7704 4241 : if ((FullSensibleOutput < (state.dataUnitarySystems->QToHeatSetPt - HVAC::SmallLoad)) && !FirstHVACIteration) {
7705 21 : SupHeaterLoad = max(0.0, state.dataUnitarySystems->QToHeatSetPt - FullSensibleOutput);
7706 21 : this->m_SupHeaterLoad = 0.0;
7707 : // what does this line even do? I know we want the supplemental heater on only if there is a dehum load,
7708 : // but for HP's the supp heater should also run if the heating coil can't turn on
7709 : // (i.e., this line calc's a supp heater load, then next line also calc's it?)
7710 21 : if (state.dataUnitarySystems->MoistureLoad < 0.0) this->m_SupHeaterLoad = SupHeaterLoad;
7711 : // so it look's like this next line should only be valid for HP's.
7712 21 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7713 21 : this->m_SuppHeatPartLoadFrac = min(1.0, SupHeaterLoad / this->m_DesignSuppHeatingCapacity);
7714 : }
7715 : } else {
7716 4220 : SupHeaterLoad = 0.0;
7717 4220 : this->m_SuppHeatPartLoadFrac = 0.0;
7718 : }
7719 : } else {
7720 2795 : SupHeaterLoad = 0.0;
7721 2795 : this->m_SuppHeatPartLoadFrac = 0.0;
7722 : }
7723 :
7724 7036 : this->calcUnitarySystemToLoad(state,
7725 : AirLoopNum,
7726 : FirstHVACIteration,
7727 : CoolPLR,
7728 : HeatPLR,
7729 : OnOffAirFlowRatio,
7730 : sysOutputProvided,
7731 : latOutputProvided,
7732 : HXUnitOn,
7733 : HeatCoilLoad,
7734 : SupHeaterLoad,
7735 : CompressorOn);
7736 : // Why need this second run?
7737 : // check supplemental heating coil outlet temp based on maximum allowed
7738 7036 : if (this->m_SuppCoilExists) {
7739 : // only need to test for high supply air temp if supplemental coil is operating
7740 6984 : if (this->m_SuppHeatPartLoadFrac > 0.0) {
7741 20 : this->calcUnitarySystemToLoad(state,
7742 : AirLoopNum,
7743 : FirstHVACIteration,
7744 : CoolPLR,
7745 : HeatPLR,
7746 : OnOffAirFlowRatio,
7747 : sysOutputProvided,
7748 : latOutputProvided,
7749 : HXUnitOn,
7750 : HeatCoilLoad,
7751 : SupHeaterLoad,
7752 : CompressorOn);
7753 20 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7754 : // multistage coil part load fraction already set in the calcUnitarySystemToLoad
7755 20 : if (this->m_NumOfSpeedSuppHeating <= 1) {
7756 16 : this->m_SuppHeatPartLoadFrac = SupHeaterLoad / this->m_DesignSuppHeatingCapacity;
7757 : }
7758 : } else {
7759 0 : this->m_SuppHeatPartLoadFrac = 0.0;
7760 : }
7761 : }
7762 : }
7763 :
7764 7036 : if (this->m_SuppCoilFluidInletNode > 0) {
7765 0 : PlantUtilities::SetComponentFlowRate(state,
7766 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate,
7767 : this->m_SuppCoilFluidInletNode,
7768 : this->m_SuppCoilFluidOutletNodeNum,
7769 0 : this->m_SuppCoilPlantLoc);
7770 : }
7771 :
7772 7036 : if (this->m_HeatRecActive) {
7773 2 : PlantUtilities::SetComponentFlowRate(state,
7774 1 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate,
7775 : this->m_HeatRecoveryInletNodeNum,
7776 : this->m_HeatRecoveryOutletNodeNum,
7777 1 : this->m_HRPlantLoc);
7778 : }
7779 7036 : }
7780 :
7781 65316 : void UnitarySys::controlUnitarySystemtoSP(EnergyPlusData &state,
7782 : int const AirLoopNum, // Primary air loop number
7783 : bool const FirstHVACIteration, // True when first HVAC iteration
7784 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
7785 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7786 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7787 : Real64 &sysOutputProvided, // sensible output at supply air node
7788 : Real64 &latOutputProvided // latent output at supply air node
7789 : )
7790 : {
7791 :
7792 : // SUBROUTINE INFORMATION:
7793 : // AUTHOR Richard Raustad, FSEC
7794 : // DATE WRITTEN February 2013
7795 :
7796 : // PURPOSE OF THIS SUBROUTINE:
7797 : // This subroutine manages component simulation.
7798 :
7799 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7800 65316 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
7801 65316 : Real64 OnOffAirFlowRatio = 1.0; // Setpoint based coil control does not use this variable
7802 65316 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
7803 65316 : Real64 ZoneLoad = 0.0;
7804 65316 : Real64 HeatCoilLoad = -999.0;
7805 :
7806 : // CALL the series of components that simulate a Unitary System
7807 65316 : if (this->ATMixerExists) {
7808 : // There is an air terminal mixer
7809 0 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
7810 : // set the primary air inlet mass flow rate
7811 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
7812 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
7813 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
7814 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
7815 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
7816 : }
7817 : }
7818 65316 : if (this->OAMixerExists) {
7819 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
7820 0 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
7821 : }
7822 65316 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
7823 39 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
7824 : }
7825 :
7826 65316 : if (this->m_CoolingCoilUpstream) {
7827 :
7828 65292 : if (this->m_CoolCoilExists) {
7829 65292 : this->updateUnitarySystemControl(state,
7830 : AirLoopNum,
7831 : this->CoolCoilOutletNodeNum,
7832 : this->CoolCtrlNode,
7833 : OnOffAirFlowRatio,
7834 : FirstHVACIteration,
7835 : OAUCoilOutTemp,
7836 : ZoneLoad,
7837 : this->DesignMaxOutletTemp);
7838 65292 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
7839 65292 : PartLoadRatio = this->m_CoolingPartLoadFrac;
7840 65292 : CompressorOn = HVAC::CompressorOp::Off;
7841 65292 : if (PartLoadRatio > 0.0) {
7842 24767 : CompressorOn = HVAC::CompressorOp::On;
7843 24767 : this->m_LastMode = CoolingMode;
7844 : }
7845 65292 : this->calcUnitaryCoolingSystem(
7846 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
7847 : }
7848 65292 : if (this->m_HeatCoilExists) {
7849 7 : this->updateUnitarySystemControl(state,
7850 : AirLoopNum,
7851 : this->HeatCoilOutletNodeNum,
7852 : this->HeatCtrlNode,
7853 : OnOffAirFlowRatio,
7854 : FirstHVACIteration,
7855 : OAUCoilOutTemp,
7856 : ZoneLoad,
7857 : this->DesignMaxOutletTemp);
7858 7 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
7859 7 : PartLoadRatio = this->m_HeatingPartLoadFrac;
7860 7 : HVAC::CompressorOp CompressOn = HVAC::CompressorOp::Off;
7861 7 : if (PartLoadRatio > 0.0) {
7862 3 : CompressOn = HVAC::CompressorOp::On;
7863 3 : this->m_LastMode = HeatingMode;
7864 : }
7865 7 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressOn, OnOffAirFlowRatio, HeatCoilLoad);
7866 : }
7867 :
7868 : } else {
7869 :
7870 24 : if (this->m_HeatCoilExists) {
7871 24 : this->updateUnitarySystemControl(state,
7872 : AirLoopNum,
7873 : this->HeatCoilOutletNodeNum,
7874 : this->HeatCtrlNode,
7875 : OnOffAirFlowRatio,
7876 : FirstHVACIteration,
7877 : OAUCoilOutTemp,
7878 : ZoneLoad,
7879 : this->DesignMaxOutletTemp);
7880 24 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
7881 24 : PartLoadRatio = this->m_HeatingPartLoadFrac;
7882 24 : CompressorOn = HVAC::CompressorOp::Off;
7883 24 : if (PartLoadRatio > 0.0) {
7884 15 : CompressorOn = HVAC::CompressorOp::On;
7885 15 : this->m_LastMode = HeatingMode;
7886 : }
7887 24 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
7888 : }
7889 24 : if (this->m_CoolCoilExists) {
7890 0 : this->updateUnitarySystemControl(state,
7891 : AirLoopNum,
7892 : this->CoolCoilOutletNodeNum,
7893 : this->CoolCtrlNode,
7894 : OnOffAirFlowRatio,
7895 : FirstHVACIteration,
7896 : OAUCoilOutTemp,
7897 : ZoneLoad,
7898 : this->DesignMaxOutletTemp);
7899 0 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
7900 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
7901 0 : CompressorOn = HVAC::CompressorOp::Off;
7902 0 : if (PartLoadRatio > 0.0) {
7903 0 : CompressorOn = HVAC::CompressorOp::On;
7904 0 : this->m_LastMode = CoolingMode;
7905 : }
7906 0 : this->calcUnitaryCoolingSystem(
7907 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
7908 : }
7909 : }
7910 :
7911 65316 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
7912 6 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
7913 : }
7914 :
7915 65316 : if (this->m_SuppCoilExists) {
7916 11 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
7917 11 : this->updateUnitarySystemControl(state,
7918 : AirLoopNum,
7919 : this->SuppCoilOutletNodeNum,
7920 : this->SuppCtrlNode,
7921 : OnOffAirFlowRatio,
7922 : FirstHVACIteration,
7923 : OAUCoilOutTemp,
7924 : ZoneLoad,
7925 : this->DesignMaxOutletTemp);
7926 11 : this->controlSuppHeatSystemToSP(state, AirLoopNum, FirstHVACIteration);
7927 11 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
7928 11 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
7929 : }
7930 :
7931 : // If there is a supply side air terminal mixer, calculate its output
7932 65316 : if (this->ATMixerExists) {
7933 0 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
7934 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
7935 : }
7936 : }
7937 :
7938 65316 : calculateCapacity(state, sysOutputProvided, latOutputProvided);
7939 65316 : this->m_InitHeatPump = false;
7940 65316 : }
7941 :
7942 72370 : void UnitarySys::updateUnitarySystemControl(EnergyPlusData &state,
7943 : int const AirLoopNum, // number of the current air loop being simulated
7944 : int const OutNode, // coil outlet node number
7945 : int const ControlNode, // control node number
7946 : Real64 &OnOffAirFlowRatio,
7947 : bool const FirstHVACIteration,
7948 : Real64 const OAUCoilOutletTemp, // "ONLY" for zoneHVAC:OutdoorAirUnit
7949 : Real64 &ZoneLoad,
7950 : Real64 const MaxOutletTemp // limits heating coil outlet temp [C]
7951 : )
7952 : {
7953 :
7954 : // SUBROUTINE INFORMATION:
7955 : // AUTHOR Richard Raustad, FSEC
7956 : // DATE WRITTEN February 2013
7957 :
7958 : // PURPOSE OF THIS SUBROUTINE:
7959 : // This subroutine is for sizing unitary systems.
7960 :
7961 : // METHODOLOGY EMPLOYED:
7962 : // Either CALL the coil model to get the size or size coil.
7963 : // Current method is to use same methodology as is used in coil objects.
7964 : // Future changes will include a common sizing algorithm and push the calculated
7965 : // size to the coil object prior to first call (so the coil will not DataSizing::AutoSize).
7966 :
7967 : // These initializations are done every iteration
7968 :
7969 : {
7970 72370 : state.dataUnitarySystems->MoistureLoad = 0.0;
7971 72370 : this->LoadSHR = 0.0;
7972 72370 : this->CoilSHR = 0.0;
7973 72370 : switch (this->m_ControlType) {
7974 7036 : case UnitarySysCtrlType::Load:
7975 : case UnitarySysCtrlType::CCMASHRAE: {
7976 7036 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAirUnit
7977 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
7978 0 : ShowFatalError(state, "...Load based control is not allowed when used with ZoneHVAC:OutdoorAirUnit");
7979 : }
7980 :
7981 : // here we need to deal with sequenced zone equip
7982 7036 : state.dataUnitarySystems->HeatingLoad = false;
7983 7036 : state.dataUnitarySystems->CoolingLoad = false;
7984 7036 : if (this->m_ZoneSequenceCoolingNum > 0 && this->m_ZoneSequenceHeatingNum > 0 && this->m_AirLoopEquipment) {
7985 : // air loop equipment uses sequenced variables
7986 4 : state.dataUnitarySystems->QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
7987 4 : .SequencedOutputRequiredToCoolingSP(this->m_ZoneSequenceCoolingNum);
7988 4 : state.dataUnitarySystems->QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
7989 4 : .SequencedOutputRequiredToHeatingSP(this->m_ZoneSequenceHeatingNum);
7990 7 : if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
7991 3 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
7992 3 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
7993 3 : state.dataUnitarySystems->HeatingLoad = true;
7994 1 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
7995 0 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleCool) {
7996 0 : ZoneLoad = 0.0;
7997 2 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
7998 1 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
7999 1 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8000 1 : state.dataUnitarySystems->CoolingLoad = true;
8001 0 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8002 0 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::SetptType::SingleHeat) {
8003 0 : ZoneLoad = 0.0;
8004 0 : } else if (state.dataUnitarySystems->QToHeatSetPt <= 0.0 && state.dataUnitarySystems->QToCoolSetPt >= 0.0) {
8005 0 : ZoneLoad = 0.0;
8006 : }
8007 8 : state.dataUnitarySystems->MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum)
8008 4 : .SequencedOutputRequiredToDehumidSP(this->m_ZoneSequenceCoolingNum);
8009 : } else {
8010 : // zone equipment uses Remaining* variables
8011 7032 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired;
8012 14064 : state.dataUnitarySystems->QToCoolSetPt =
8013 7032 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToCoolSP;
8014 14064 : state.dataUnitarySystems->QToHeatSetPt =
8015 7032 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToHeatSP;
8016 14064 : state.dataUnitarySystems->MoistureLoad =
8017 7032 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum).RemainingOutputReqToDehumidSP;
8018 7032 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
8019 7001 : this->m_sysType == SysType::PackagedWSHP) {
8020 : // ZoneSysAvailManager is turning on sooner than PTUnit in UnitarySystem. Mimic PTUnit logic.
8021 8486 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8022 1507 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
8023 1507 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8024 8198 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 &&
8025 2726 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
8026 2726 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8027 : } else {
8028 2746 : ZoneLoad = 0.0;
8029 : }
8030 : }
8031 : }
8032 :
8033 8572 : if (ZoneLoad < 0.0 && state.dataUnitarySystems->MoistureLoad <= 0.0 &&
8034 1536 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8035 9 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag)) {
8036 3 : this->LoadSHR =
8037 3 : ZoneLoad / (ZoneLoad + state.dataUnitarySystems->MoistureLoad *
8038 6 : Psychrometrics::PsyHgAirFnWTdb(
8039 3 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).airHumRat,
8040 3 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).MAT));
8041 3 : if (this->LoadSHR < 0.0) {
8042 0 : this->LoadSHR = 0.0;
8043 : }
8044 3 : this->CoilSHR = this->LoadSHR;
8045 : }
8046 :
8047 7036 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8048 8 : Real64 H2OHtOfVap = Psychrometrics::PsyHfgAirFnWTdb(state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
8049 8 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp);
8050 :
8051 : // positive MoistureLoad means no dehumidification load
8052 8 : state.dataUnitarySystems->MoistureLoad = min(0.0, state.dataUnitarySystems->MoistureLoad * H2OHtOfVap);
8053 : } else {
8054 7028 : state.dataUnitarySystems->MoistureLoad = 0.0;
8055 : }
8056 :
8057 7036 : this->initLoadBasedControl(state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad);
8058 :
8059 : // *** the location of this EMS override looks suspect. If EMS is active the load will be changed but the CoolingLoad and HeatingLoad
8060 : // flags are not updated. suggest this be moved up above InitLoadBasedControl function on previous line so the EMS loads are used in
8061 : // that routine EMS override point
8062 7036 : if (this->m_EMSOverrideSensZoneLoadRequest) ZoneLoad = this->m_EMSSensibleZoneLoadValue;
8063 7036 : if (this->m_EMSOverrideMoistZoneLoadRequest) state.dataUnitarySystems->MoistureLoad = this->m_EMSMoistureZoneLoadValue;
8064 :
8065 7036 : this->m_SimASHRAEModel = false; // flag used to invoke ASHRAE 90.1 model calculations
8066 : // allows non-ASHSRAE compliant coil types to be modeled using non-ASHAR90 method. Constant fan operating mode is required.
8067 7036 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
8068 35 : if (state.dataUnitarySystems->CoolingLoad) {
8069 13 : if (this->m_ValidASHRAECoolCoil) this->m_SimASHRAEModel = true;
8070 22 : } else if (state.dataUnitarySystems->HeatingLoad) {
8071 16 : if (this->m_ValidASHRAEHeatCoil) this->m_SimASHRAEModel = true;
8072 : }
8073 : }
8074 7036 : } break;
8075 65334 : case UnitarySysCtrlType::Setpoint: {
8076 65334 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAIRUNIT
8077 :
8078 4 : if (ControlNode == 0) {
8079 0 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8080 4 : } else if (ControlNode == OutNode) {
8081 4 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8082 : }
8083 : // If the unitary system is an Outdoor Air Unit, the desired coil outlet humidity level is set to 1.0 (no dehum)
8084 4 : this->m_DesiredOutletHumRat = 1.0;
8085 :
8086 : } else { // Not Outdoor Air Unit. Either airloop or zone equipment
8087 65330 : Real64 humRatMaxSP = 1.0;
8088 65330 : this->m_DesiredOutletHumRat = humRatMaxSP;
8089 65330 : if (ControlNode == 0) {
8090 0 : this->m_DesiredOutletTemp = 0.0;
8091 0 : if (OutNode > 0) {
8092 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8093 0 : this->m_DesiredOutletHumRat = state.dataLoopNodes->Node(OutNode).HumRatMax;
8094 : }
8095 : }
8096 65330 : } else if (ControlNode == OutNode) {
8097 65323 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8098 0 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0)
8099 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8100 0 : this->frostControlSetPointLimit(state,
8101 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8102 : humRatMaxSP,
8103 0 : state.dataEnvrn->OutBaroPress,
8104 : this->DesignMinOutletTemp,
8105 : 1);
8106 : }
8107 65323 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
8108 : // IF HumRatMax is zero, then there is no request from SetpointManager:SingleZone:Humidity:Maximum
8109 : // user might place temp SP at system outlet and HumRat set point at coil outlet
8110 65323 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8111 9 : if (state.dataLoopNodes->Node(this->AirOutNode).HumRatMax > 0.0)
8112 4 : humRatMaxSP = state.dataLoopNodes->Node(this->AirOutNode).HumRatMax;
8113 9 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0)
8114 5 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8115 9 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8116 0 : this->frostControlSetPointLimit(state,
8117 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8118 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8119 0 : state.dataEnvrn->OutBaroPress,
8120 : this->DesignMinOutletTemp,
8121 : 2);
8122 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8123 : }
8124 9 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8125 : }
8126 : } else {
8127 7 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8128 7 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) humRatMaxSP = state.dataLoopNodes->Node(OutNode).HumRatMax;
8129 7 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8130 0 : this->frostControlSetPointLimit(state,
8131 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8132 : humRatMaxSP,
8133 0 : state.dataEnvrn->OutBaroPress,
8134 : this->DesignMinOutletTemp,
8135 : 1);
8136 : }
8137 7 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint -
8138 7 : (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(OutNode).Temp);
8139 7 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8140 0 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8141 0 : this->frostControlSetPointLimit(state,
8142 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8143 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8144 0 : state.dataEnvrn->OutBaroPress,
8145 : this->DesignMinOutletTemp,
8146 : 2);
8147 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8148 : }
8149 0 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8150 : }
8151 : }
8152 : }
8153 65334 : this->m_DesiredOutletTemp = min(this->m_DesiredOutletTemp, MaxOutletTemp);
8154 65334 : } break;
8155 0 : default: {
8156 : // should never get here, only 3 control types
8157 0 : } break;
8158 : }
8159 : }
8160 72370 : }
8161 2 : void UnitarySys::controlUnitarySystemOutputEMS(EnergyPlusData &state,
8162 : int const AirLoopNum, // Index to air loop
8163 : bool const FirstHVACIteration, // True when first HVAC iteration
8164 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8165 : Real64 const ZoneLoad,
8166 : Real64 &FullSensibleOutput,
8167 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8168 : HVAC::CompressorOp CompressorOn)
8169 : {
8170 2 : Real64 PartLoadRatio = 1.0;
8171 2 : Real64 CoolPLR = 0.0;
8172 2 : Real64 HeatPLR = 0.0;
8173 2 : HVAC::CompressorOp CompressorONFlag = CompressorOn;
8174 2 : Real64 HeatCoilLoad = 0.0;
8175 2 : Real64 SupHeaterLoad = 0.0;
8176 : Real64 SensOutput; // sensible output
8177 : Real64 LatOutput; // latent output
8178 2 : this->FanPartLoadRatio = 0.0;
8179 2 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8180 :
8181 2 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) return;
8182 2 : int SpeedNumEMS = ceil(this->m_EMSOverrideCoilSpeedNumValue);
8183 2 : bool useMaxedSpeed = false;
8184 2 : std::string useMaxedSpeedCoilName;
8185 2 : if (state.dataUnitarySystems->HeatingLoad) {
8186 0 : if (SpeedNumEMS > this->m_NumOfSpeedHeating) {
8187 0 : SpeedNumEMS = this->m_NumOfSpeedHeating;
8188 0 : useMaxedSpeed = true;
8189 0 : useMaxedSpeedCoilName = this->m_HeatingCoilName;
8190 : }
8191 0 : this->m_HeatingSpeedNum = SpeedNumEMS;
8192 : } else {
8193 2 : if (SpeedNumEMS > this->m_NumOfSpeedCooling) {
8194 0 : SpeedNumEMS = this->m_NumOfSpeedCooling;
8195 0 : useMaxedSpeed = true;
8196 0 : useMaxedSpeedCoilName = this->m_CoolingCoilName;
8197 : }
8198 2 : this->m_CoolingSpeedNum = SpeedNumEMS;
8199 : }
8200 2 : if (useMaxedSpeed) {
8201 0 : this->m_CoilSpeedErrIdx++;
8202 0 : ShowRecurringWarningErrorAtEnd(state,
8203 0 : "Wrong coil speed EMS override value, for unit=\"" + useMaxedSpeedCoilName +
8204 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
8205 0 : this->m_CoilSpeedErrIdx,
8206 0 : this->m_EMSOverrideCoilSpeedNumValue,
8207 0 : this->m_EMSOverrideCoilSpeedNumValue,
8208 : _,
8209 : "",
8210 : "");
8211 : }
8212 :
8213 2 : if (state.dataUnitarySystems->HeatingLoad) {
8214 0 : CoolPLR = 0.0;
8215 0 : HeatPLR = 1.0;
8216 0 : this->m_HeatingCoilSensDemand = ZoneLoad;
8217 :
8218 0 : if (this->m_HeatingSpeedNum == 1) {
8219 0 : this->m_HeatingSpeedRatio = 0.0;
8220 0 : this->m_HeatingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8221 0 : if (useMaxedSpeed || this->m_HeatingCycRatio == 0) {
8222 0 : this->m_HeatingCycRatio = 1;
8223 : }
8224 : } else {
8225 0 : this->m_HeatingCycRatio = 1.0;
8226 0 : this->m_HeatingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8227 0 : if (useMaxedSpeed || this->m_HeatingSpeedRatio == 0) {
8228 0 : this->m_HeatingSpeedRatio = 1;
8229 : }
8230 : }
8231 : } else { // Cooling or moisture load
8232 2 : HeatPLR = 0.0;
8233 2 : CoolPLR = 1.0;
8234 2 : if (state.dataUnitarySystems->CoolingLoad) {
8235 2 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8236 : } else {
8237 0 : this->m_CoolingCoilSensDemand = 0.0;
8238 : }
8239 2 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8240 :
8241 2 : if (this->m_CoolingSpeedNum == 1) {
8242 0 : this->m_CoolingSpeedRatio = 0.0;
8243 0 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8244 0 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
8245 0 : this->m_CoolingCycRatio = 1;
8246 : }
8247 : } else {
8248 2 : this->m_CoolingCycRatio = 1.0;
8249 2 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8250 2 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
8251 0 : this->m_CoolingSpeedRatio = 1;
8252 : }
8253 : }
8254 : }
8255 2 : this->calcUnitarySystemToLoad(state,
8256 : AirLoopNum,
8257 : FirstHVACIteration,
8258 : CoolPLR,
8259 : HeatPLR,
8260 : OnOffAirFlowRatio,
8261 : SensOutput,
8262 : LatOutput,
8263 2 : HXUnitOn,
8264 : HeatCoilLoad,
8265 : SupHeaterLoad,
8266 : CompressorONFlag);
8267 :
8268 2 : FullSensibleOutput = SensOutput;
8269 :
8270 2 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8271 : // no load
8272 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutput) return;
8273 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8274 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) return;
8275 : }
8276 2 : HXUnitOn = true;
8277 2 : this->calcUnitarySystemToLoad(state,
8278 : AirLoopNum,
8279 : FirstHVACIteration,
8280 : CoolPLR,
8281 : HeatPLR,
8282 : OnOffAirFlowRatio,
8283 : SensOutput,
8284 : LatOutput,
8285 2 : HXUnitOn,
8286 : HeatCoilLoad,
8287 : SupHeaterLoad,
8288 : CompressorONFlag);
8289 2 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
8290 : Real64 heatCoildT =
8291 2 : (this->m_HeatCoilExists)
8292 2 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
8293 2 : : 0.0;
8294 : Real64 CoolingOnlySensibleOutput =
8295 2 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
8296 2 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
8297 2 : heatCoildT);
8298 2 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
8299 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
8300 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
8301 2 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
8302 : // Heating mode and dehumidification is required
8303 : } else {
8304 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
8305 : // the heating coil pick up the load due to outdoor air.
8306 0 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
8307 : }
8308 2 : }
8309 :
8310 7036 : void UnitarySys::controlUnitarySystemOutput(EnergyPlusData &state,
8311 : int const AirLoopNum, // Index to air loop
8312 : bool const FirstHVACIteration, // True when first HVAC iteration
8313 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8314 : Real64 const ZoneLoad,
8315 : Real64 &FullSensibleOutput,
8316 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8317 : HVAC::CompressorOp CompressorOn)
8318 : {
8319 :
8320 : // SUBROUTINE INFORMATION:
8321 : // AUTHOR Richard Raustad, FSEC
8322 : // DATE WRITTEN February 2013
8323 :
8324 : // PURPOSE OF THIS SUBROUTINE:
8325 : // This subroutine determines operating PLR and calculates the load based system output.
8326 :
8327 : // SUBROUTINE PARAMETER DEFINITIONS:
8328 7036 : int constexpr MaxIter = 100; // maximum number of iterations
8329 :
8330 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8331 : int SpeedNum; // multi-speed coil speed number
8332 : Real64 SensOutputOn; // sensible output at PLR = 1 [W]
8333 : Real64 LatOutputOn; // latent output at PLR = 1 [W]
8334 : Real64 TempLoad; // represents either a sensible or latent load [W]
8335 : Real64 TempSysOutput; // represents either a sensible or latent capacity [W]
8336 : Real64 TempSensOutput; // iterative sensible capacity [W]
8337 : Real64 TempLatOutput; // iterative latent capacity [W]
8338 : Real64 TempMinPLR; // iterative minimum PLR
8339 : Real64 TempMaxPLR; // iterative maximum PLR
8340 : Real64 CpAir; // specific heat of air [J/kg_C]
8341 : Real64 FullLoadAirOutletTemp; // saved full load outlet air temperature [C]
8342 : Real64 FullLoadAirOutletHumRat; // saved full load outlet air humidity ratio [kg/kg]
8343 :
8344 7036 : std::string CompName = this->Name;
8345 7036 : int OutletNode = this->AirOutNode;
8346 :
8347 7036 : if (this->m_sysAvailSched->getCurrentVal() <= 0.0) {
8348 0 : return;
8349 : }
8350 7036 : if (this->m_EMSOverrideCoilSpeedNumOn) {
8351 2 : this->controlUnitarySystemOutputEMS(
8352 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
8353 2 : return;
8354 : }
8355 :
8356 7034 : Real64 PartLoadRatio = 0.0; // Get no load result
8357 7034 : this->m_EconoPartLoadRatio = 0;
8358 : // fan and coil PLR are disconnected when using ASHRAE model, don't confuse these for other models
8359 7034 : this->FanPartLoadRatio = 0.0;
8360 7034 : int SolFlag = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8361 7034 : int SolFlagLat = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8362 7034 : Real64 SensOutputOff = 0.0;
8363 7034 : Real64 LatOutputOff = 0.0;
8364 7034 : Real64 CoolPLR = 0.0;
8365 7034 : Real64 HeatPLR = 0.0;
8366 7034 : HVAC::CompressorOp CompressorONFlag = HVAC::CompressorOp::Off;
8367 7034 : Real64 HeatCoilLoad = 0.0;
8368 7034 : Real64 SupHeaterLoad = 0.0;
8369 :
8370 7034 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8371 :
8372 7034 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) return;
8373 :
8374 4285 : this->calcUnitarySystemToLoad(state,
8375 : AirLoopNum,
8376 : FirstHVACIteration,
8377 : CoolPLR,
8378 : HeatPLR,
8379 : OnOffAirFlowRatio,
8380 : SensOutputOff,
8381 : LatOutputOff,
8382 4285 : HXUnitOn,
8383 : HeatCoilLoad,
8384 : SupHeaterLoad,
8385 : CompressorONFlag);
8386 4285 : FullSensibleOutput = SensOutputOff;
8387 :
8388 4285 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8389 : // no load
8390 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutputOff) return;
8391 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8392 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) return;
8393 : }
8394 :
8395 : // determine if PLR=0 meets the load
8396 4285 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8397 12 : case HVAC::SetptType::SingleHeat: {
8398 12 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8399 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8400 0 : return;
8401 12 : if (!state.dataUnitarySystems->HeatingLoad &&
8402 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8403 0 : return;
8404 12 : } break;
8405 0 : case HVAC::SetptType::SingleCool: {
8406 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8407 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8408 0 : return;
8409 0 : if (!state.dataUnitarySystems->CoolingLoad &&
8410 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8411 0 : return;
8412 0 : } break;
8413 4273 : case HVAC::SetptType::SingleHeatCool:
8414 : case HVAC::SetptType::DualHeatCool: {
8415 4273 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8416 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8417 0 : return;
8418 4275 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8419 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8420 0 : return;
8421 4273 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8422 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8423 0 : return;
8424 4273 : } break;
8425 0 : default: {
8426 : // should never get here
8427 0 : } break;
8428 : }
8429 :
8430 4285 : this->m_EconoSpeedNum = 0;
8431 4285 : if (this->OAControllerEconomizerStagingType == HVAC::EconomizerStagingType::EconomizerFirst) {
8432 0 : manageEconomizerStagingOperation(state, AirLoopNum, FirstHVACIteration, ZoneLoad);
8433 : }
8434 :
8435 : // if a variable speed unit, the SensOutputOff at SpeedNum=1 must be checked to see if it exceeds the ZoneLoad
8436 : // This is still no load but at the first speed above idle
8437 5839 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating > 0) ||
8438 1554 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling > 0)) {
8439 4253 : if (this->m_Staged) {
8440 2 : if (state.dataUnitarySystems->HeatingLoad) {
8441 1 : this->m_HeatingSpeedNum = this->m_StageNum;
8442 : } else {
8443 1 : this->m_CoolingSpeedNum = std::abs(this->m_StageNum);
8444 : }
8445 : } else {
8446 4251 : if (state.dataUnitarySystems->HeatingLoad) {
8447 2730 : this->m_HeatingSpeedNum = 1;
8448 : } else {
8449 1521 : this->m_CoolingSpeedNum = 1;
8450 : }
8451 : }
8452 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8453 4253 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8454 4253 : this->calcUnitarySystemToLoad(state,
8455 : AirLoopNum,
8456 : FirstHVACIteration,
8457 : CoolPLR,
8458 : HeatPLR,
8459 : OnOffAirFlowRatio,
8460 : SensOutputOff,
8461 : LatOutputOff,
8462 4253 : HXUnitOn,
8463 : HeatCoilLoad,
8464 : SupHeaterLoad,
8465 : CompressorONFlag);
8466 4253 : FullSensibleOutput = SensOutputOff;
8467 :
8468 4253 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8469 6 : case HVAC::SetptType::SingleHeat: {
8470 6 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8471 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8472 0 : return;
8473 6 : if (!state.dataUnitarySystems->HeatingLoad &&
8474 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8475 0 : return;
8476 6 : } break;
8477 0 : case HVAC::SetptType::SingleCool: {
8478 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat)
8479 0 : return;
8480 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8481 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8482 0 : return;
8483 0 : if (!state.dataUnitarySystems->CoolingLoad &&
8484 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8485 0 : return;
8486 0 : } break;
8487 4247 : case HVAC::SetptType::SingleHeatCool:
8488 : case HVAC::SetptType::DualHeatCool: {
8489 4247 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8490 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8491 0 : return;
8492 4247 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat)
8493 0 : return;
8494 4249 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8495 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8496 0 : return;
8497 4247 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8498 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8499 0 : return;
8500 4247 : } break;
8501 0 : default: {
8502 : // should never get here
8503 0 : } break;
8504 : }
8505 : }
8506 :
8507 4285 : CompressorONFlag = CompressorOn;
8508 4285 : PartLoadRatio = 1.0;
8509 4285 : this->FanPartLoadRatio = 1.0;
8510 : // Get full load result for non-multistage economizer operations
8511 4285 : if (this->m_EconoSpeedNum == 0) {
8512 4285 : if (state.dataUnitarySystems->HeatingLoad) {
8513 2751 : CoolPLR = 0.0;
8514 2751 : HeatPLR = 1.0;
8515 2751 : this->m_HeatingCoilSensDemand = ZoneLoad;
8516 2751 : if (this->m_NumOfSpeedHeating > 0) {
8517 2731 : this->m_HeatingSpeedRatio = 1.0;
8518 2731 : this->m_HeatingCycRatio = 1.0;
8519 2731 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
8520 : }
8521 2751 : if (this->m_Staged && this->m_StageNum > 0) {
8522 1 : if (this->m_NumOfSpeedHeating > 0) {
8523 1 : this->m_HeatingSpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8524 1 : this->m_HeatingSpeedRatio = 0.0;
8525 : }
8526 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8527 1 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8528 1 : this->calcUnitarySystemToLoad(state,
8529 : AirLoopNum,
8530 : FirstHVACIteration,
8531 : CoolPLR,
8532 : HeatPLR,
8533 : OnOffAirFlowRatio,
8534 : SensOutputOff,
8535 : LatOutputOff,
8536 1 : HXUnitOn,
8537 : HeatCoilLoad,
8538 : SupHeaterLoad,
8539 : CompressorONFlag);
8540 1 : if (SensOutputOff > ZoneLoad) return;
8541 0 : if (this->m_NumOfSpeedHeating > 0) this->m_HeatingSpeedRatio = 1.0;
8542 : }
8543 1534 : } else if (state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < LatOutputOff) {
8544 1534 : CoolPLR = 1.0;
8545 1534 : HeatPLR = 0.0;
8546 1534 : if (state.dataUnitarySystems->CoolingLoad) {
8547 1534 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8548 : } else {
8549 0 : this->m_CoolingCoilSensDemand = 0.0;
8550 : }
8551 1534 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8552 1534 : if (this->m_NumOfSpeedCooling > 0) {
8553 1522 : this->m_CoolingSpeedRatio = 1.0;
8554 1522 : this->m_CoolingCycRatio = 1.0;
8555 1522 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
8556 : }
8557 1534 : if (this->m_Staged && this->m_StageNum < 0) {
8558 0 : if (this->m_NumOfSpeedCooling > 0) this->m_CoolingSpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8559 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8560 0 : this->m_CoolingSpeedRatio = 0.0;
8561 0 : this->calcUnitarySystemToLoad(state,
8562 : AirLoopNum,
8563 : FirstHVACIteration,
8564 : CoolPLR,
8565 : HeatPLR,
8566 : OnOffAirFlowRatio,
8567 : SensOutputOff,
8568 : LatOutputOff,
8569 0 : HXUnitOn,
8570 : HeatCoilLoad,
8571 : SupHeaterLoad,
8572 : CompressorONFlag);
8573 0 : if (SensOutputOff < ZoneLoad) return;
8574 0 : if (this->m_NumOfSpeedCooling > 0) this->m_CoolingSpeedRatio = 1.0;
8575 : }
8576 : } else {
8577 : // will return here when no cooling or heating load and MoistureLoad > LatOutputOff (i.e., PLR=0)
8578 0 : return;
8579 : }
8580 :
8581 4284 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8582 :
8583 4284 : this->calcUnitarySystemToLoad(state,
8584 : AirLoopNum,
8585 : FirstHVACIteration,
8586 : CoolPLR,
8587 : HeatPLR,
8588 : OnOffAirFlowRatio,
8589 : SensOutputOn,
8590 : LatOutputOn,
8591 4284 : HXUnitOn,
8592 : HeatCoilLoad,
8593 : SupHeaterLoad,
8594 : CompressorONFlag);
8595 4284 : FullSensibleOutput = SensOutputOn;
8596 4284 : FullLoadAirOutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
8597 4284 : FullLoadAirOutletHumRat = state.dataLoopNodes->Node(OutletNode).HumRat;
8598 :
8599 : // turn on HX if dehumidm_ControlType::Multimode
8600 2 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < 0.0 &&
8601 4286 : state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
8602 1 : HXUnitOn = true;
8603 1 : this->calcUnitarySystemToLoad(state,
8604 : AirLoopNum,
8605 : FirstHVACIteration,
8606 : CoolPLR,
8607 : HeatPLR,
8608 : OnOffAirFlowRatio,
8609 : SensOutputOn,
8610 : LatOutputOn,
8611 1 : HXUnitOn,
8612 : HeatCoilLoad,
8613 : SupHeaterLoad,
8614 : CompressorONFlag);
8615 1 : FullSensibleOutput = SensOutputOn;
8616 : }
8617 :
8618 : // test to see if full capacity is less than load, if so set to PLR=1 and RETURN if no moisture load
8619 8548 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating <= 1) ||
8620 4264 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling <= 1)) {
8621 57 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8622 6 : case HVAC::SetptType::SingleHeat: {
8623 6 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8624 0 : this->m_HeatingPartLoadFrac = 1.0;
8625 0 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) return;
8626 : }
8627 6 : if (!state.dataUnitarySystems->HeatingLoad &&
8628 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn))
8629 0 : return;
8630 6 : } break;
8631 0 : case HVAC::SetptType::SingleCool: {
8632 0 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8633 0 : this->m_CoolingPartLoadFrac = 1.0;
8634 0 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) return;
8635 : }
8636 0 : if (!state.dataUnitarySystems->CoolingLoad &&
8637 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn))
8638 0 : return;
8639 0 : } break;
8640 51 : case HVAC::SetptType::SingleHeatCool:
8641 : case HVAC::SetptType::DualHeatCool: {
8642 51 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8643 4 : this->m_HeatingPartLoadFrac = 1.0;
8644 4 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOn) return;
8645 : }
8646 47 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8647 6 : this->m_CoolingPartLoadFrac = 1.0;
8648 6 : return;
8649 : }
8650 41 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8651 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8652 0 : return;
8653 : }
8654 41 : } break;
8655 0 : default: {
8656 : // no other choices for thermostat control
8657 0 : } break;
8658 : }
8659 : }
8660 : } else {
8661 : // define the sensible load to meet for operation with multi-stage economizer
8662 0 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8663 : }
8664 : // will find speed for multispeed coils here and then RegulaFalsi on PLR at a fixed speed
8665 :
8666 : // Do the non-variable or non-multispeed coils have a NumOfSpeed = 0 ? We don't need to do this for single speed coils.
8667 : // Check to see which speed to meet the load
8668 4274 : this->m_HeatingSpeedNum = 0;
8669 4274 : this->m_CoolingSpeedNum = 0;
8670 4274 : if (!this->m_Staged) {
8671 4273 : if (state.dataUnitarySystems->HeatingLoad) {
8672 12227 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
8673 12199 : CoolPLR = 0.0;
8674 12199 : HeatPLR = 1.0;
8675 12199 : if (SpeedNum == 1) {
8676 2730 : this->m_HeatingSpeedRatio = 0.0;
8677 : } else {
8678 9469 : this->m_HeatingSpeedRatio = 1.0;
8679 : }
8680 12199 : this->m_HeatingCycRatio = 1.0;
8681 12199 : this->m_HeatingSpeedNum = SpeedNum;
8682 12199 : this->calcUnitarySystemToLoad(state,
8683 : AirLoopNum,
8684 : FirstHVACIteration,
8685 : CoolPLR,
8686 : HeatPLR,
8687 : OnOffAirFlowRatio,
8688 : SensOutputOn,
8689 : LatOutputOn,
8690 12199 : HXUnitOn,
8691 : HeatCoilLoad,
8692 : SupHeaterLoad,
8693 : CompressorONFlag);
8694 12199 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8695 0 : this->FullOutput[SpeedNum] = SensOutputOn;
8696 : }
8697 12199 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
8698 2717 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater && !this->m_MultiSpeedHeatingCoil)) {
8699 0 : this->m_HeatingSpeedRatio = 0.0;
8700 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
8701 0 : if (this->m_HeatingSpeedNum == 0) {
8702 0 : this->m_HeatingCycRatio = 0.0;
8703 0 : HeatPLR = 0.0;
8704 : } else {
8705 0 : this->m_HeatingCycRatio = 1.0;
8706 0 : HeatPLR = 1.0;
8707 : }
8708 0 : this->calcUnitarySystemToLoad(state,
8709 : AirLoopNum,
8710 : FirstHVACIteration,
8711 : CoolPLR,
8712 : HeatPLR,
8713 : OnOffAirFlowRatio,
8714 : SensOutputOff,
8715 : LatOutputOff,
8716 0 : HXUnitOn,
8717 : HeatCoilLoad,
8718 : SupHeaterLoad,
8719 : CompressorONFlag);
8720 0 : this->m_HeatingSpeedNum = SpeedNum;
8721 : }
8722 12199 : if (ZoneLoad <= SensOutputOn) {
8723 2718 : break;
8724 : }
8725 : }
8726 : } else { // Cooling or moisture load
8727 5498 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
8728 5488 : CoolPLR = 1.0;
8729 5488 : HeatPLR = 0.0;
8730 5488 : if (SpeedNum == 1) {
8731 1517 : this->m_CoolingSpeedRatio = 0.0;
8732 : } else {
8733 3971 : this->m_CoolingSpeedRatio = 1.0;
8734 : }
8735 5488 : this->m_CoolingCycRatio = 1.0;
8736 5488 : this->m_CoolingSpeedNum = SpeedNum;
8737 5488 : this->calcUnitarySystemToLoad(state,
8738 : AirLoopNum,
8739 : FirstHVACIteration,
8740 : CoolPLR,
8741 : HeatPLR,
8742 : OnOffAirFlowRatio,
8743 : SensOutputOn,
8744 : LatOutputOn,
8745 5488 : HXUnitOn,
8746 : HeatCoilLoad,
8747 : SupHeaterLoad,
8748 : CompressorONFlag);
8749 5491 : if (state.dataGlobal->DoCoilDirectSolutions &&
8750 3 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
8751 3 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1))) {
8752 3 : this->FullOutput[SpeedNum] = SensOutputOn;
8753 : }
8754 : // over specified logic? it has to be a water coil? what about other VS coil models?
8755 5488 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
8756 914 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
8757 0 : !this->m_DiscreteSpeedCoolingCoil)) {
8758 0 : this->m_CoolingSpeedRatio = 0.0;
8759 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
8760 0 : if (this->m_CoolingSpeedNum == 0) {
8761 0 : this->m_CoolingCycRatio = 0.0;
8762 0 : CoolPLR = 0.0;
8763 : } else {
8764 0 : this->m_CoolingCycRatio = 1.0;
8765 0 : this->m_CoolingSpeedRatio = 0.0;
8766 0 : if (this->m_SingleMode == 1) {
8767 0 : CoolPLR = 1.0;
8768 : }
8769 : }
8770 :
8771 0 : this->calcUnitarySystemToLoad(state,
8772 : AirLoopNum,
8773 : FirstHVACIteration,
8774 : CoolPLR,
8775 : HeatPLR,
8776 : OnOffAirFlowRatio,
8777 : SensOutputOff,
8778 : LatOutputOff,
8779 0 : HXUnitOn,
8780 : HeatCoilLoad,
8781 : SupHeaterLoad,
8782 : CompressorONFlag);
8783 0 : this->m_CoolingSpeedNum = SpeedNum;
8784 : }
8785 5488 : if (ZoneLoad >= SensOutputOn) {
8786 1517 : break;
8787 : }
8788 : }
8789 : }
8790 : } else { // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
8791 : // Staged control
8792 1 : if (state.dataUnitarySystems->HeatingLoad) {
8793 0 : CoolPLR = 0.0;
8794 0 : HeatPLR = 1.0;
8795 0 : SpeedNum = this->m_StageNum;
8796 0 : if (SpeedNum == 1) {
8797 0 : this->m_HeatingSpeedRatio = 0.0;
8798 : } else {
8799 0 : this->m_HeatingSpeedRatio = 1.0;
8800 0 : SpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8801 : }
8802 0 : this->m_HeatingCycRatio = 1.0;
8803 0 : this->m_HeatingSpeedNum = SpeedNum;
8804 0 : this->calcUnitarySystemToLoad(state,
8805 : AirLoopNum,
8806 : FirstHVACIteration,
8807 : CoolPLR,
8808 : HeatPLR,
8809 : OnOffAirFlowRatio,
8810 : SensOutputOn,
8811 : LatOutputOn,
8812 0 : HXUnitOn,
8813 : HeatCoilLoad,
8814 : SupHeaterLoad,
8815 : CompressorONFlag);
8816 0 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
8817 0 : this->m_HeatingSpeedRatio = 0.0;
8818 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
8819 0 : if (this->m_HeatingSpeedNum == 0) {
8820 0 : this->m_HeatingCycRatio = 0.0;
8821 0 : HeatPLR = 0.0;
8822 : } else {
8823 0 : this->m_HeatingCycRatio = 1.0;
8824 0 : HeatPLR = 1.0;
8825 : }
8826 0 : this->calcUnitarySystemToLoad(state,
8827 : AirLoopNum,
8828 : FirstHVACIteration,
8829 : CoolPLR,
8830 : HeatPLR,
8831 : OnOffAirFlowRatio,
8832 : SensOutputOff,
8833 : LatOutputOff,
8834 0 : HXUnitOn,
8835 : HeatCoilLoad,
8836 : SupHeaterLoad,
8837 : CompressorONFlag);
8838 0 : this->m_HeatingSpeedNum = SpeedNum;
8839 : }
8840 0 : if (ZoneLoad <= SensOutputOn) {
8841 : // EXIT ????????????
8842 : }
8843 : } else { // Cooling or moisture load
8844 1 : CoolPLR = 1.0;
8845 1 : HeatPLR = 0.0;
8846 1 : SpeedNum = std::abs(this->m_StageNum);
8847 1 : if (SpeedNum == 1) {
8848 1 : this->m_CoolingSpeedRatio = 0.0;
8849 : } else {
8850 0 : this->m_CoolingSpeedRatio = 1.0;
8851 0 : SpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8852 : }
8853 1 : this->m_CoolingCycRatio = 1.0;
8854 1 : this->m_CoolingSpeedNum = SpeedNum;
8855 1 : this->calcUnitarySystemToLoad(state,
8856 : AirLoopNum,
8857 : FirstHVACIteration,
8858 : CoolPLR,
8859 : HeatPLR,
8860 : OnOffAirFlowRatio,
8861 : SensOutputOn,
8862 : LatOutputOn,
8863 1 : HXUnitOn,
8864 : HeatCoilLoad,
8865 : SupHeaterLoad,
8866 : CompressorONFlag);
8867 :
8868 1 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
8869 1 : this->m_CoolingSpeedRatio = 0.0;
8870 1 : this->m_CoolingSpeedNum = SpeedNum - 1;
8871 1 : if (this->m_CoolingSpeedNum == 0) {
8872 1 : this->m_CoolingCycRatio = 0.0;
8873 1 : CoolPLR = 0.0;
8874 : } else {
8875 0 : this->m_CoolingCycRatio = 1.0;
8876 0 : CoolPLR = 1.0;
8877 : }
8878 1 : this->calcUnitarySystemToLoad(state,
8879 : AirLoopNum,
8880 : FirstHVACIteration,
8881 : CoolPLR,
8882 : HeatPLR,
8883 : OnOffAirFlowRatio,
8884 : SensOutputOff,
8885 : LatOutputOff,
8886 1 : HXUnitOn,
8887 : HeatCoilLoad,
8888 : SupHeaterLoad,
8889 : CompressorONFlag);
8890 1 : this->m_CoolingSpeedNum = SpeedNum;
8891 : }
8892 1 : if (ZoneLoad >= SensOutputOn) {
8893 : // EXIT ???????????
8894 : }
8895 : }
8896 : } // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
8897 :
8898 4274 : FullSensibleOutput = SensOutputOn;
8899 :
8900 4274 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8901 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8902 : // if no load, or only a moisture load which can't be met at PLR=1, RETURN
8903 0 : return;
8904 : }
8905 :
8906 : // use the ASHRAE 90.1 method of reduced fan speed at low loads
8907 4274 : if (this->m_SimASHRAEModel) {
8908 :
8909 : // check to make sure unit has the capacity to meet the load
8910 17 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
8911 3 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
8912 14 : UnitarySys &SZVAVModel(state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum]);
8913 42 : SZVAVModel::calcSZVAVModel(state,
8914 : SZVAVModel,
8915 : this->m_UnitarySysNum,
8916 : FirstHVACIteration,
8917 14 : state.dataUnitarySystems->CoolingLoad,
8918 14 : state.dataUnitarySystems->HeatingLoad,
8919 : ZoneLoad,
8920 : OnOffAirFlowRatio,
8921 14 : HXUnitOn,
8922 : AirLoopNum,
8923 : PartLoadRatio,
8924 : CompressorONFlag);
8925 : }
8926 :
8927 : } else { // not ASHRAE model
8928 :
8929 : // must test to see if load is bounded by capacity before calling RegulaFalsi
8930 5797 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
8931 1537 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
8932 5773 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad > SensOutputOff) ||
8933 1525 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad < SensOutputOff)) {
8934 : Real64 SensOutput;
8935 : Real64 LatOutput;
8936 4252 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8937 7 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
8938 3 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR > 0.0) {
8939 3 : int CoilInletNode = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapInletNodeIndex;
8940 3 : this->CoilSHR = 0.0;
8941 : Real64 LowSpeedCoilSen;
8942 : Real64 LowSpeedCoilLat;
8943 3 : CoolPLR = 0.0;
8944 3 : HeatPLR = 0.0;
8945 3 : this->m_CoolingSpeedNum = 1;
8946 3 : this->calcUnitarySystemToLoad(state,
8947 : AirLoopNum,
8948 : FirstHVACIteration,
8949 : CoolPLR,
8950 : HeatPLR,
8951 : OnOffAirFlowRatio,
8952 : SensOutputOff,
8953 : LatOutputOff,
8954 3 : HXUnitOn,
8955 : HeatCoilLoad,
8956 : SupHeaterLoad,
8957 : CompressorONFlag);
8958 3 : CoolPLR = 1.0;
8959 3 : HeatPLR = 0.0;
8960 3 : this->m_CoolingCycRatio = 1.0;
8961 3 : this->m_CoolingSpeedRatio = 0.0;
8962 : // this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
8963 3 : this->calcUnitarySystemToLoad(state,
8964 : AirLoopNum,
8965 : FirstHVACIteration,
8966 : CoolPLR,
8967 : HeatPLR,
8968 : OnOffAirFlowRatio,
8969 : SensOutputOn,
8970 : LatOutputOn,
8971 3 : HXUnitOn,
8972 : HeatCoilLoad,
8973 : SupHeaterLoad,
8974 : CompressorONFlag);
8975 3 : Real64 ZoneLatLoad = ZoneLoad * (1.0 / this->LoadSHR - 1.0);
8976 3 : Real64 SenPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
8977 3 : Real64 LatPLR = (ZoneLatLoad - LatOutputOff) / (LatOutputOn - LatOutputOff);
8978 3 : Real64 totalRate = 0.0;
8979 3 : Real64 sensRate = 0.0;
8980 3 : Real64 latRate = 0.0;
8981 3 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
8982 3 : state.dataLoopNodes->Node(CoilInletNode).Temp,
8983 3 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
8984 3 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
8985 3 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
8986 : sensRate,
8987 : latRate,
8988 : totalRate);
8989 3 : if (LatPLR > 1.0 || LatPLR < 0.0) {
8990 1 : this->CoilSHR = this->LoadSHR;
8991 : } else {
8992 2 : Real64 coilSens = sensRate * SenPLR;
8993 2 : Real64 coilLat = latRate * LatPLR;
8994 2 : this->CoilSHR = coilSens / (coilSens + coilLat);
8995 : }
8996 3 : if (this->m_NumOfSpeedCooling > 1) {
8997 0 : this->SpeedSHR[1] = this->CoilSHR;
8998 0 : LowSpeedCoilSen = sensRate;
8999 0 : LowSpeedCoilLat = latRate;
9000 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9001 0 : this->SpeedSHR[SpeedNum] = this->LoadSHR;
9002 : }
9003 : }
9004 3 : if (this->CoilSHR < 0.0) {
9005 0 : this->CoilSHR = this->LoadSHR;
9006 : }
9007 3 : if (this->m_NumOfSpeedCooling > 1 && ZoneLoad < SensOutputOn) {
9008 : Real64 SenSPR;
9009 : Real64 LatSPR;
9010 0 : this->FullOutput[1] = SensOutputOn;
9011 0 : this->FullLatOutput[1] = LatOutputOn;
9012 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9013 0 : this->CoilSHR = 0.0;
9014 0 : CoolPLR = 1.0;
9015 0 : HeatPLR = 0.0;
9016 0 : this->m_CoolingSpeedRatio = 1.0;
9017 0 : this->m_CoolingCycRatio = 1.0;
9018 0 : this->m_CoolingSpeedNum = SpeedNum;
9019 0 : this->calcUnitarySystemToLoad(state,
9020 : AirLoopNum,
9021 : FirstHVACIteration,
9022 : CoolPLR,
9023 : HeatPLR,
9024 : OnOffAirFlowRatio,
9025 0 : this->FullOutput[SpeedNum],
9026 0 : this->FullLatOutput[SpeedNum],
9027 0 : HXUnitOn,
9028 : HeatCoilLoad,
9029 : SupHeaterLoad,
9030 : CompressorONFlag);
9031 0 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9032 0 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9033 0 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9034 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9035 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9036 : sensRate,
9037 : latRate,
9038 : totalRate);
9039 0 : SenSPR =
9040 0 : (ZoneLoad - this->FullOutput[SpeedNum - 1]) / (this->FullOutput[SpeedNum] - this->FullOutput[SpeedNum - 1]);
9041 0 : LatSPR = (ZoneLatLoad - this->FullLatOutput[SpeedNum - 1]) /
9042 0 : (this->FullLatOutput[SpeedNum] - this->FullLatOutput[SpeedNum - 1]);
9043 0 : if (LatSPR > 1.0 || LatSPR < 0.0) {
9044 0 : this->CoilSHR = this->LoadSHR;
9045 : } else {
9046 0 : Real64 coilSens = sensRate * SenSPR + (1.0 - SenSPR) * LowSpeedCoilSen;
9047 0 : Real64 coilLat = latRate * LatSPR + (1.0 - LatSPR) * LowSpeedCoilLat;
9048 0 : this->CoilSHR = coilSens / (coilSens + coilLat);
9049 : }
9050 0 : this->SpeedSHR[SpeedNum] = this->CoilSHR;
9051 0 : LowSpeedCoilSen = sensRate;
9052 0 : LowSpeedCoilLat = latRate;
9053 : }
9054 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9055 0 : CoolPLR = 1.0;
9056 0 : HeatPLR = 0.0;
9057 0 : if (SpeedNum == 1) {
9058 0 : this->m_CoolingSpeedRatio = 0.0;
9059 : } else {
9060 0 : this->m_CoolingSpeedRatio = 1.0;
9061 : }
9062 0 : this->m_CoolingCycRatio = 1.0;
9063 0 : this->m_CoolingSpeedNum = SpeedNum;
9064 0 : this->calcUnitarySystemToLoad(state,
9065 : AirLoopNum,
9066 : FirstHVACIteration,
9067 : CoolPLR,
9068 : HeatPLR,
9069 : OnOffAirFlowRatio,
9070 : SensOutputOn,
9071 : LatOutputOn,
9072 0 : HXUnitOn,
9073 : HeatCoilLoad,
9074 : SupHeaterLoad,
9075 : CompressorONFlag);
9076 0 : if (ZoneLoad >= SensOutputOn) {
9077 0 : this->CoilSHR = this->SpeedSHR[SpeedNum];
9078 0 : break;
9079 : }
9080 : }
9081 : }
9082 : }
9083 : }
9084 4247 : if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9085 2 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
9086 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9087 0 : HeatPLR = 0.0;
9088 0 : this->calcUnitarySystemToLoad(state,
9089 : AirLoopNum,
9090 : FirstHVACIteration,
9091 : CoolPLR,
9092 : HeatPLR,
9093 : OnOffAirFlowRatio,
9094 : SensOutput,
9095 : LatOutput,
9096 0 : HXUnitOn,
9097 : HeatCoilLoad,
9098 : SupHeaterLoad,
9099 : CompressorONFlag);
9100 0 : PartLoadRatio = CoolPLR;
9101 4247 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9102 4247 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1 &&
9103 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
9104 0 : HeatPLR = 0.0;
9105 0 : this->calcUnitarySystemToLoad(state,
9106 : AirLoopNum,
9107 : FirstHVACIteration,
9108 : 1.0,
9109 : HeatPLR,
9110 : OnOffAirFlowRatio,
9111 : SensOutputOn,
9112 : LatOutputOn,
9113 0 : HXUnitOn,
9114 : HeatCoilLoad,
9115 : SupHeaterLoad,
9116 : CompressorONFlag);
9117 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9118 0 : this->calcUnitarySystemToLoad(state,
9119 : AirLoopNum,
9120 : FirstHVACIteration,
9121 : CoolPLR,
9122 : HeatPLR,
9123 : OnOffAirFlowRatio,
9124 : SensOutput,
9125 : LatOutput,
9126 0 : HXUnitOn,
9127 : HeatCoilLoad,
9128 : SupHeaterLoad,
9129 : CompressorONFlag);
9130 0 : PartLoadRatio = CoolPLR;
9131 4247 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9132 4247 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1) {
9133 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9134 0 : HeatPLR = 0.0;
9135 0 : this->calcUnitarySystemToLoad(state,
9136 : AirLoopNum,
9137 : FirstHVACIteration,
9138 : CoolPLR,
9139 : HeatPLR,
9140 : OnOffAirFlowRatio,
9141 : SensOutput,
9142 : LatOutput,
9143 0 : HXUnitOn,
9144 : HeatCoilLoad,
9145 : SupHeaterLoad,
9146 : CompressorONFlag);
9147 0 : PartLoadRatio = CoolPLR;
9148 4245 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9149 0 : (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
9150 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
9151 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel)) {
9152 0 : CoolPLR = 0.0;
9153 0 : HeatPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9154 0 : this->calcUnitarySystemToLoad(state,
9155 : AirLoopNum,
9156 : FirstHVACIteration,
9157 : CoolPLR,
9158 : HeatPLR,
9159 : OnOffAirFlowRatio,
9160 : SensOutput,
9161 : LatOutput,
9162 0 : HXUnitOn,
9163 : HeatCoilLoad,
9164 : SupHeaterLoad,
9165 : CompressorONFlag);
9166 0 : PartLoadRatio = HeatPLR;
9167 4245 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9168 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9169 0 : CoolPLR = 0.0;
9170 0 : if (this->m_HeatingSpeedNum == 1) {
9171 0 : this->m_HeatingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_HeatingSpeedNum] - SensOutputOff);
9172 0 : HeatPLR = this->m_HeatingCycRatio;
9173 0 : this->m_HeatingSpeedRatio = 0.0;
9174 : } else {
9175 0 : this->m_HeatingCycRatio = 1.0;
9176 0 : this->m_HeatingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_HeatingSpeedNum - 1]) /
9177 0 : (this->FullOutput[this->m_HeatingSpeedNum] - this->FullOutput[this->m_HeatingSpeedNum - 1]);
9178 0 : HeatPLR = this->m_HeatingSpeedRatio;
9179 : }
9180 0 : this->calcUnitarySystemToLoad(state,
9181 : AirLoopNum,
9182 : FirstHVACIteration,
9183 : CoolPLR,
9184 : HeatPLR,
9185 : OnOffAirFlowRatio,
9186 : SensOutput,
9187 : LatOutput,
9188 0 : HXUnitOn,
9189 : HeatCoilLoad,
9190 : SupHeaterLoad,
9191 : CompressorONFlag);
9192 0 : PartLoadRatio = HeatPLR;
9193 4247 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9194 4247 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1) {
9195 2 : HeatPLR = 0.0;
9196 2 : if (this->m_CoolingSpeedNum == 1) {
9197 1 : this->m_CoolingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_CoolingSpeedNum] - SensOutputOff);
9198 1 : CoolPLR = this->m_CoolingCycRatio;
9199 1 : this->m_CoolingSpeedRatio = 0.0;
9200 : } else {
9201 1 : this->m_CoolingCycRatio = 1.0;
9202 1 : this->m_CoolingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_CoolingSpeedNum - 1]) /
9203 1 : (this->FullOutput[this->m_CoolingSpeedNum] - this->FullOutput[this->m_CoolingSpeedNum - 1]);
9204 1 : CoolPLR = this->m_CoolingSpeedRatio;
9205 : }
9206 2 : this->calcUnitarySystemToLoad(state,
9207 : AirLoopNum,
9208 : FirstHVACIteration,
9209 : CoolPLR,
9210 : HeatPLR,
9211 : OnOffAirFlowRatio,
9212 : SensOutput,
9213 : LatOutput,
9214 2 : HXUnitOn,
9215 : HeatCoilLoad,
9216 : SupHeaterLoad,
9217 : CompressorONFlag);
9218 2 : PartLoadRatio = CoolPLR;
9219 : } else {
9220 :
9221 4243 : Real64 par6 = state.dataUnitarySystems->CoolingLoad ? 1.0 : 0.0;
9222 28735 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9223 : Real64 const PartLoadRatio) {
9224 48984 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9225 : PartLoadRatio,
9226 24492 : this->m_UnitarySysNum,
9227 : FirstHVACIteration,
9228 : // par 3 not used?
9229 : CompressorONFlag,
9230 : ZoneLoad,
9231 : par6,
9232 : 1.0,
9233 : OnOffAirFlowRatio,
9234 : HXUnitOn,
9235 : // par 10 not used
9236 24492 : AirLoopNum);
9237 4243 : };
9238 : // Tolerance is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9239 4243 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
9240 :
9241 4243 : if (SolFlag == -1) {
9242 0 : if (state.dataUnitarySystems->HeatingLoad) {
9243 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9244 : // This does cause a problem when coil cannot turn on when OAT < min allowed or scheduled off
9245 : // If max iteration limit is exceeded, how do we know if the heating coil is operating?
9246 0 : TempMaxPLR = -0.1;
9247 0 : TempSensOutput = SensOutputOff;
9248 0 : while ((TempSensOutput - ZoneLoad) < 0.0 && TempMaxPLR < 1.0) {
9249 : // find upper limit of HeatingPLR
9250 0 : TempMaxPLR += 0.1;
9251 :
9252 : // SUBROUTINE SetSpeedVariables(UnitarySysNum, SensibleLoad, PartLoadRatio)
9253 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9254 0 : this->calcUnitarySystemToLoad(state,
9255 : AirLoopNum,
9256 : FirstHVACIteration,
9257 : CoolPLR,
9258 : TempMaxPLR,
9259 : OnOffAirFlowRatio,
9260 : TempSensOutput,
9261 : TempLatOutput,
9262 0 : HXUnitOn,
9263 : HeatCoilLoad,
9264 : SupHeaterLoad,
9265 : CompressorONFlag);
9266 : }
9267 0 : TempMinPLR = TempMaxPLR;
9268 0 : while ((TempSensOutput - ZoneLoad) > 0.0 && TempMinPLR > 0.0) {
9269 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9270 0 : TempMaxPLR = TempMinPLR;
9271 : // find minimum limit of HeatingPLR
9272 0 : TempMinPLR -= 0.01;
9273 0 : this->setSpeedVariables(state, true, TempMinPLR);
9274 0 : this->calcUnitarySystemToLoad(state,
9275 : AirLoopNum,
9276 : FirstHVACIteration,
9277 : CoolPLR,
9278 : TempMinPLR,
9279 : OnOffAirFlowRatio,
9280 : TempSensOutput,
9281 : TempLatOutput,
9282 0 : HXUnitOn,
9283 : HeatCoilLoad,
9284 : SupHeaterLoad,
9285 : CompressorONFlag);
9286 : }
9287 : // Now solve again with tighter PLR limits
9288 : auto f2 = // (AUTO_OK_LAMBDA)
9289 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9290 : Real64 const PartLoadRatio) {
9291 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9292 : PartLoadRatio,
9293 0 : this->m_UnitarySysNum,
9294 : FirstHVACIteration,
9295 : // par 3 not used?
9296 : CompressorONFlag,
9297 : ZoneLoad,
9298 : par6,
9299 : 1.0,
9300 : OnOffAirFlowRatio,
9301 : HXUnitOn,
9302 : // par 10 not used
9303 0 : AirLoopNum);
9304 0 : };
9305 0 : General::SolveRoot(state, this->m_HeatConvTol, MaxIter, SolFlag, HeatPLR, f2, TempMinPLR, TempMaxPLR);
9306 0 : this->calcUnitarySystemToLoad(state,
9307 : AirLoopNum,
9308 : FirstHVACIteration,
9309 : CoolPLR,
9310 : HeatPLR,
9311 : OnOffAirFlowRatio,
9312 : TempSensOutput,
9313 : TempLatOutput,
9314 0 : HXUnitOn,
9315 : HeatCoilLoad,
9316 : SupHeaterLoad,
9317 : CompressorONFlag);
9318 0 : } else if (state.dataUnitarySystems->CoolingLoad) {
9319 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9320 : // IF iteration limit is exceeded (SolFlag = -1), find tighter boundary of solution and repeat RegulaFalsi
9321 0 : TempMaxPLR = -0.1;
9322 0 : TempSysOutput = SensOutputOff;
9323 0 : TempLoad = ZoneLoad;
9324 0 : while ((TempSysOutput - TempLoad) > 0.0 &&
9325 : TempMaxPLR < 0.95) { // avoid PLR > 1 by limiting TempMaxPLR to 1 (i.e., TempMaxPLR += 0.1)
9326 : // find upper limit of HeatingPLR
9327 0 : TempMaxPLR += 0.1;
9328 0 : if (TempMaxPLR > 0.95 && TempMaxPLR < 1.05) {
9329 0 : TempMaxPLR = 1.0; // enforce a perfect 1.0 at the top end
9330 : }
9331 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9332 0 : this->calcUnitarySystemToLoad(state,
9333 : AirLoopNum,
9334 : FirstHVACIteration,
9335 : TempMaxPLR,
9336 : HeatPLR,
9337 : OnOffAirFlowRatio,
9338 : TempSensOutput,
9339 : TempLatOutput,
9340 0 : HXUnitOn,
9341 : HeatCoilLoad,
9342 : SupHeaterLoad,
9343 : CompressorONFlag);
9344 0 : TempSysOutput = TempSensOutput;
9345 : }
9346 0 : TempMinPLR = TempMaxPLR;
9347 0 : while ((TempSysOutput - TempLoad) < 0.0 &&
9348 : TempMinPLR > 0.025) { // lower limit might be changed to 0.005 without adverse affect
9349 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9350 0 : TempMaxPLR = TempMinPLR;
9351 : // find minimum limit of HeatingPLR
9352 0 : TempMinPLR -= 0.01;
9353 0 : this->setSpeedVariables(state, true, TempMinPLR);
9354 0 : this->calcUnitarySystemToLoad(state,
9355 : AirLoopNum,
9356 : FirstHVACIteration,
9357 : TempMinPLR,
9358 : HeatPLR,
9359 : OnOffAirFlowRatio,
9360 : TempSensOutput,
9361 : TempLatOutput,
9362 0 : HXUnitOn,
9363 : HeatCoilLoad,
9364 : SupHeaterLoad,
9365 : CompressorONFlag);
9366 0 : TempSysOutput = TempSensOutput;
9367 : }
9368 : // Now solve again with tighter PLR limits
9369 : auto f2 = // (AUTO_OK_LAMBDA)
9370 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9371 : Real64 const PartLoadRatio) {
9372 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9373 : PartLoadRatio,
9374 0 : this->m_UnitarySysNum,
9375 : FirstHVACIteration,
9376 : // par 3 not used?
9377 : CompressorONFlag,
9378 : ZoneLoad,
9379 : par6,
9380 : 1.0,
9381 : OnOffAirFlowRatio,
9382 : HXUnitOn,
9383 : // par 10 not used
9384 0 : AirLoopNum);
9385 0 : };
9386 0 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, CoolPLR, f2, TempMinPLR, TempMaxPLR);
9387 0 : this->calcUnitarySystemToLoad(state,
9388 : AirLoopNum,
9389 : FirstHVACIteration,
9390 : CoolPLR,
9391 : HeatPLR,
9392 : OnOffAirFlowRatio,
9393 : TempSensOutput,
9394 : TempLatOutput,
9395 0 : HXUnitOn,
9396 : HeatCoilLoad,
9397 : SupHeaterLoad,
9398 : CompressorONFlag);
9399 : } // IF(HeatingLoad)THEN
9400 0 : if (SolFlag == -1) {
9401 0 : if (std::abs(ZoneLoad - TempSensOutput) > HVAC::SmallLoad) {
9402 0 : if (this->MaxIterIndex == 0) {
9403 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9404 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system sensible part-load ratio.");
9405 0 : ShowContinueErrorTimeStamp(state,
9406 0 : format("Sensible load to be met = {:.2T} (watts), sensible output = {:.2T} "
9407 : "(watts), and the simulation continues.",
9408 : ZoneLoad,
9409 : TempSensOutput));
9410 : }
9411 0 : ShowRecurringWarningErrorAtEnd(state,
9412 0 : this->UnitType + " \"" + this->Name +
9413 : "\" - Iteration limit exceeded in calculating sensible part-load ratio error "
9414 : "continues. Sensible load statistics:",
9415 0 : this->MaxIterIndex,
9416 : ZoneLoad,
9417 : ZoneLoad);
9418 : }
9419 0 : } else if (SolFlag == -2) {
9420 0 : if (this->RegulaFalsiFailedIndex == 0) {
9421 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9422 0 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9423 0 : ShowContinueErrorTimeStamp(
9424 0 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9425 : }
9426 0 : ShowRecurringWarningErrorAtEnd(
9427 : state,
9428 0 : this->UnitType + " \"" + this->Name +
9429 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9430 0 : this->RegulaFalsiFailedIndex,
9431 : ZoneLoad,
9432 : ZoneLoad);
9433 : }
9434 4243 : } else if (SolFlag == -2) {
9435 0 : if (this->RegulaFalsiFailedIndex == 0) {
9436 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9437 0 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9438 0 : ShowContinueErrorTimeStamp(
9439 0 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9440 : }
9441 0 : ShowRecurringWarningErrorAtEnd(
9442 : state,
9443 0 : this->UnitType + " \"" + this->Name +
9444 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9445 0 : this->RegulaFalsiFailedIndex,
9446 : ZoneLoad,
9447 : ZoneLoad);
9448 : } // IF (SolFlag == -1) THEN
9449 : }
9450 : } else { // load is not bounded by capacity. Leave PLR=1 or turn off unit?
9451 3 : this->m_CoolingPartLoadFrac = 0.0;
9452 3 : this->m_HeatingPartLoadFrac = 0.0;
9453 3 : CoolPLR = 0.0;
9454 3 : HeatPLR = 0.0;
9455 3 : PartLoadRatio = 0.0;
9456 : } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN
9457 : } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN
9458 : }
9459 :
9460 4274 : if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) {
9461 2730 : if (this->m_HeatingSpeedNum == 1) {
9462 30 : this->m_HeatingCycRatio = PartLoadRatio;
9463 30 : this->m_HeatingSpeedRatio = 0.0;
9464 : } else {
9465 2700 : if (this->m_SingleMode == 0) {
9466 2699 : this->m_HeatingCycRatio = 1.0;
9467 2699 : this->m_HeatingSpeedRatio = PartLoadRatio;
9468 : } else {
9469 1 : this->m_HeatingCycRatio = PartLoadRatio;
9470 1 : this->m_HeatingSpeedRatio = 1.0;
9471 : }
9472 : }
9473 2730 : HeatPLR = PartLoadRatio;
9474 2730 : CoolPLR = 0.0;
9475 2730 : this->m_CoolingCycRatio = 0.0;
9476 2730 : this->m_CoolingSpeedRatio = 0.0;
9477 1544 : } else if (state.dataUnitarySystems->CoolingLoad && (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil)) {
9478 1500 : if (this->m_CoolingSpeedNum == 1) {
9479 455 : this->m_CoolingCycRatio = PartLoadRatio;
9480 455 : this->m_CoolingSpeedRatio = 0.0;
9481 : } else {
9482 1045 : if (this->m_SingleMode == 0) {
9483 1044 : this->m_CoolingCycRatio = 1.0;
9484 1044 : this->m_CoolingSpeedRatio = PartLoadRatio;
9485 : } else {
9486 1 : this->m_CoolingCycRatio = PartLoadRatio;
9487 1 : this->m_CoolingSpeedRatio = 1.0;
9488 : }
9489 : }
9490 1500 : this->m_HeatingCycRatio = 0.0;
9491 1500 : this->m_HeatingSpeedRatio = 0.0;
9492 1500 : HeatPLR = 0.0;
9493 1500 : CoolPLR = PartLoadRatio;
9494 : } else {
9495 44 : HeatPLR = this->m_HeatingPartLoadFrac;
9496 44 : CoolPLR = this->m_CoolingPartLoadFrac;
9497 : }
9498 :
9499 4274 : this->calcUnitarySystemToLoad(state,
9500 : AirLoopNum,
9501 : FirstHVACIteration,
9502 : CoolPLR,
9503 : HeatPLR,
9504 : OnOffAirFlowRatio,
9505 : TempSensOutput,
9506 : TempLatOutput,
9507 4274 : HXUnitOn,
9508 : HeatCoilLoad,
9509 : SupHeaterLoad,
9510 : CompressorONFlag);
9511 :
9512 : // FullSensibleOutput is used to set supplemental heater PLR in calling routine
9513 : // OnOffAirFlowRatio is used to average air flow between ON and OFF state
9514 4274 : FullSensibleOutput = TempSensOutput;
9515 4274 : LatOutputOn = TempLatOutput;
9516 :
9517 : // RETURN if the moisture load is met
9518 4274 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad >= TempLatOutput) return;
9519 : // Multimode does not meet the latent load, only the sensible load with or without HX active
9520 : // what if there is a heating load for a system using Multimode?
9521 4 : if (!state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) return;
9522 : // if HX was previously turned on return since sensible load is already met
9523 4 : if (state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode && HXUnitOn) return;
9524 : // IF(HeatingLoad .AND. UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)RETURN
9525 :
9526 4 : if ((this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
9527 :
9528 : // find maximum latent output IF not already calculated
9529 4 : if (state.dataUnitarySystems->HeatingLoad) {
9530 0 : CoolPLR = 1.0;
9531 0 : this->m_CoolingPartLoadFrac = 1.0;
9532 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9533 0 : this->m_CoolingSpeedRatio = 1.0;
9534 0 : this->m_CoolingCycRatio = 1.0;
9535 0 : if (this->m_CoolingSpeedNum > 0) {
9536 0 : this->m_HeatingPartLoadFrac = 0.0;
9537 0 : this->m_HeatingSpeedNum = 0;
9538 0 : HeatPLR = 0.0;
9539 0 : state.dataUnitarySystems->CoolingLoad = true;
9540 0 : state.dataUnitarySystems->HeatingLoad = false;
9541 0 : this->m_HeatingCoilSensDemand = 0.0;
9542 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9543 0 : this->calcUnitarySystemToLoad(state,
9544 : AirLoopNum,
9545 : FirstHVACIteration,
9546 : 0.0,
9547 : 0.0,
9548 : OnOffAirFlowRatio,
9549 : TempSensOutput,
9550 : TempLatOutput,
9551 0 : HXUnitOn,
9552 : HeatCoilLoad,
9553 : SupHeaterLoad,
9554 : CompressorONFlag);
9555 0 : this->calcUnitarySystemToLoad(state,
9556 : AirLoopNum,
9557 : FirstHVACIteration,
9558 : CoolPLR,
9559 : HeatPLR,
9560 : OnOffAirFlowRatio,
9561 : TempSensOutput,
9562 : LatOutputOn,
9563 0 : HXUnitOn,
9564 : HeatCoilLoad,
9565 : SupHeaterLoad,
9566 : CompressorONFlag);
9567 : } else {
9568 0 : this->m_HeatingCoilSensDemand = 0.0;
9569 0 : this->m_CoolingCoilLatentDemand = 0.0;
9570 0 : this->calcUnitarySystemToLoad(state,
9571 : AirLoopNum,
9572 : FirstHVACIteration,
9573 : 0.0,
9574 : 0.0,
9575 : OnOffAirFlowRatio,
9576 : TempSensOutput,
9577 : TempLatOutput,
9578 0 : HXUnitOn,
9579 : HeatCoilLoad,
9580 : SupHeaterLoad,
9581 : CompressorONFlag);
9582 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9583 0 : this->calcUnitarySystemToLoad(state,
9584 : AirLoopNum,
9585 : FirstHVACIteration,
9586 : CoolPLR,
9587 : HeatPLR,
9588 : OnOffAirFlowRatio,
9589 : TempSensOutput,
9590 : LatOutputOn,
9591 0 : HXUnitOn,
9592 : HeatCoilLoad,
9593 : SupHeaterLoad,
9594 : CompressorONFlag);
9595 : }
9596 : }
9597 :
9598 4 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
9599 0 : HXUnitOn = true;
9600 0 : CoolPLR = 1.0;
9601 0 : this->m_CoolingPartLoadFrac = 1.0;
9602 0 : this->calcUnitarySystemToLoad(state,
9603 : AirLoopNum,
9604 : FirstHVACIteration,
9605 : CoolPLR,
9606 : HeatPLR,
9607 : OnOffAirFlowRatio,
9608 : TempSensOutput,
9609 : LatOutputOn,
9610 0 : HXUnitOn,
9611 : HeatCoilLoad,
9612 : SupHeaterLoad,
9613 : CompressorONFlag);
9614 0 : FullSensibleOutput = TempSensOutput;
9615 : }
9616 :
9617 4 : if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
9618 4 : HXUnitOn = true; // HX is needed to meet moisture load
9619 4 : if (this->m_NumOfSpeedCooling > 0) {
9620 4 : for (SpeedNum = this->m_CoolingSpeedNum; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9621 3 : CoolPLR = 1.0;
9622 3 : this->m_CoolingPartLoadFrac = CoolPLR;
9623 3 : this->m_CoolingSpeedRatio = 1.0;
9624 3 : this->m_CoolingCycRatio = 1.0;
9625 3 : this->m_CoolingSpeedNum = SpeedNum;
9626 3 : this->calcUnitarySystemToLoad(state,
9627 : AirLoopNum,
9628 : FirstHVACIteration,
9629 : CoolPLR,
9630 : HeatPLR,
9631 : OnOffAirFlowRatio,
9632 : SensOutputOn,
9633 : LatOutputOn,
9634 3 : HXUnitOn,
9635 : HeatCoilLoad,
9636 : SupHeaterLoad,
9637 : CompressorONFlag);
9638 3 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
9639 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9640 : }
9641 : // over specified logic? it has to be a water coil? what about other VS coil models?
9642 3 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9643 3 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
9644 3 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9645 0 : !this->m_DiscreteSpeedCoolingCoil)) {
9646 0 : this->m_CoolingSpeedRatio = 0.0;
9647 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9648 0 : if (this->m_CoolingSpeedNum == 0) {
9649 0 : this->m_CoolingCycRatio = 0.0;
9650 0 : CoolPLR = 0.0;
9651 : } else {
9652 0 : this->m_CoolingCycRatio = 1.0;
9653 0 : this->m_CoolingSpeedRatio = 0.0;
9654 0 : if (this->m_SingleMode == 1) {
9655 0 : CoolPLR = 1.0;
9656 : }
9657 : }
9658 :
9659 0 : this->calcUnitarySystemToLoad(state,
9660 : AirLoopNum,
9661 : FirstHVACIteration,
9662 : CoolPLR,
9663 : HeatPLR,
9664 : OnOffAirFlowRatio,
9665 : SensOutputOn,
9666 : LatOutputOn,
9667 0 : HXUnitOn,
9668 : HeatCoilLoad,
9669 : SupHeaterLoad,
9670 : CompressorONFlag);
9671 0 : this->m_CoolingSpeedNum = SpeedNum;
9672 : }
9673 3 : if (state.dataUnitarySystems->MoistureLoad >= LatOutputOn) {
9674 2 : break;
9675 : }
9676 : }
9677 : } else {
9678 1 : CoolPLR = 1.0;
9679 1 : this->calcUnitarySystemToLoad(state,
9680 : AirLoopNum,
9681 : FirstHVACIteration,
9682 : CoolPLR,
9683 : HeatPLR,
9684 : OnOffAirFlowRatio,
9685 : SensOutputOn,
9686 : LatOutputOn,
9687 1 : HXUnitOn,
9688 : HeatCoilLoad,
9689 : SupHeaterLoad,
9690 : CompressorONFlag);
9691 1 : this->m_CoolingPartLoadFrac = CoolPLR;
9692 : }
9693 : }
9694 :
9695 8 : if ((state.dataUnitarySystems->MoistureLoad < TempLatOutput) &&
9696 4 : (state.dataUnitarySystems->MoistureLoad > LatOutputOn)) { // bounds check for RegulaFalsi
9697 :
9698 : // save heating PLR
9699 3 : HeatPLR = this->m_HeatingPartLoadFrac;
9700 : Real64 par5;
9701 : Real64 par7;
9702 3 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9703 0 : par5 = ZoneLoad;
9704 0 : par7 = 1.0;
9705 : } else {
9706 3 : par5 = state.dataUnitarySystems->MoistureLoad;
9707 3 : par7 = 0.0;
9708 : }
9709 : // Tolerance is fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9710 14 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, par5, par7, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9711 : Real64 const PartLoadRatio) {
9712 22 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9713 : PartLoadRatio,
9714 11 : this->m_UnitarySysNum,
9715 : FirstHVACIteration,
9716 : // par 3 not used?
9717 : CompressorONFlag,
9718 : par5,
9719 : 1.0,
9720 : par7,
9721 : OnOffAirFlowRatio,
9722 : HXUnitOn,
9723 : // par 10 not used
9724 11 : AirLoopNum);
9725 3 : };
9726 3 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, PartLoadRatio, f, 0.0, 1.0);
9727 3 : this->m_CoolingPartLoadFrac = PartLoadRatio;
9728 3 : this->m_HeatingPartLoadFrac = HeatPLR;
9729 1 : } else if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
9730 : // Logic below needs further look...what to do if the bounds check for RegulaFalsi fail?
9731 : // I'm not even sure if this should be done.
9732 : // It's wrong anyway, since there won't be a cooling load if multimode (see RETURN about 80 lines up).
9733 1 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode) {
9734 1 : this->m_CoolingPartLoadFrac = 1.0;
9735 : }
9736 : }
9737 : }
9738 :
9739 4 : CoolPLR = this->m_CoolingPartLoadFrac;
9740 4 : HeatPLR = this->m_HeatingPartLoadFrac;
9741 :
9742 4 : this->calcUnitarySystemToLoad(state,
9743 : AirLoopNum,
9744 : FirstHVACIteration,
9745 : CoolPLR,
9746 : HeatPLR,
9747 : OnOffAirFlowRatio,
9748 : TempSensOutput,
9749 : TempLatOutput,
9750 4 : HXUnitOn,
9751 : HeatCoilLoad,
9752 : SupHeaterLoad,
9753 : CompressorONFlag);
9754 :
9755 4 : if (SolFlagLat == -1) {
9756 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9757 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9758 0 : TempMaxPLR = -0.1;
9759 0 : TempLatOutput = LatOutputOff;
9760 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
9761 : // find upper limit of HeatingPLR
9762 0 : TempMaxPLR += 0.1;
9763 0 : this->calcUnitarySystemToLoad(state,
9764 : AirLoopNum,
9765 : FirstHVACIteration,
9766 : TempMaxPLR,
9767 : HeatPLR,
9768 : OnOffAirFlowRatio,
9769 : TempSensOutput,
9770 : TempLatOutput,
9771 0 : HXUnitOn,
9772 : HeatCoilLoad,
9773 : SupHeaterLoad,
9774 : CompressorONFlag);
9775 : }
9776 0 : TempMinPLR = TempMaxPLR;
9777 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) < 0.0 && TempMinPLR > 0.0) {
9778 : // pull upper limit of HeatingPLR DOwn to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9779 0 : TempMaxPLR = TempMinPLR;
9780 : // find minimum limit of HeatingPLR
9781 0 : TempMinPLR -= 0.01;
9782 0 : this->calcUnitarySystemToLoad(state,
9783 : AirLoopNum,
9784 : FirstHVACIteration,
9785 : TempMinPLR,
9786 : HeatPLR,
9787 : OnOffAirFlowRatio,
9788 : TempSensOutput,
9789 : TempLatOutput,
9790 0 : HXUnitOn,
9791 : HeatCoilLoad,
9792 : SupHeaterLoad,
9793 : CompressorONFlag);
9794 : }
9795 : // Now solve again with tighter PLR limits
9796 : Real64 par5;
9797 : Real64 par7;
9798 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9799 0 : par5 = ZoneLoad;
9800 0 : par7 = 1.0;
9801 : } else {
9802 0 : par5 = state.dataUnitarySystems->MoistureLoad;
9803 0 : par7 = 0.0;
9804 : }
9805 : // // Tolerance is fraction of load, M
9806 0 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, OnOffAirFlowRatio, HXUnitOn, AirLoopNum, par5, par7](
9807 : Real64 const PartLoadRatio) {
9808 : // 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
9809 : // a unit or integration test
9810 : // TODO: So I made some assumptions about the arguments. I'm not sure if ultimately this is even accessible, so maybe it doesn't
9811 : // matter.
9812 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9813 : PartLoadRatio,
9814 0 : this->m_UnitarySysNum,
9815 : FirstHVACIteration,
9816 : // par 3 not used?
9817 : CompressorONFlag,
9818 : par5,
9819 : 1.0,
9820 : par7,
9821 : OnOffAirFlowRatio,
9822 : HXUnitOn,
9823 : // par 10 not used
9824 0 : AirLoopNum);
9825 0 : };
9826 0 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, CoolPLR, f, TempMinPLR, TempMaxPLR);
9827 0 : this->calcUnitarySystemToLoad(state,
9828 : AirLoopNum,
9829 : FirstHVACIteration,
9830 : CoolPLR,
9831 : HeatPLR,
9832 : OnOffAirFlowRatio,
9833 : TempSensOutput,
9834 : TempLatOutput,
9835 0 : HXUnitOn,
9836 : HeatCoilLoad,
9837 : SupHeaterLoad,
9838 : CompressorONFlag);
9839 0 : if (SolFlagLat == -1) {
9840 0 : if (std::abs(state.dataUnitarySystems->MoistureLoad - TempLatOutput) > HVAC::SmallLoad) {
9841 0 : if (this->warnIndex.m_LatMaxIterIndex == 0) {
9842 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9843 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system Latent part-load ratio.");
9844 0 : ShowContinueErrorTimeStamp(
9845 : state,
9846 0 : format("Latent load to be met = {:.2T} (watts), Latent output = {:.2T} (watts), and the simulation continues.",
9847 0 : state.dataUnitarySystems->MoistureLoad,
9848 : TempLatOutput));
9849 : }
9850 0 : ShowRecurringWarningErrorAtEnd(
9851 : state,
9852 0 : this->UnitType + " \"" + this->Name +
9853 : "\" - Iteration limit exceeded in calculating Latent part-load ratio error continues. Latent load statistics:",
9854 0 : this->warnIndex.m_LatMaxIterIndex,
9855 0 : state.dataUnitarySystems->MoistureLoad,
9856 0 : state.dataUnitarySystems->MoistureLoad);
9857 : }
9858 0 : } else if (SolFlagLat == -2) {
9859 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
9860 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9861 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
9862 0 : ShowContinueErrorTimeStamp(
9863 : state,
9864 0 : format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
9865 : }
9866 0 : ShowRecurringWarningErrorAtEnd(state,
9867 0 : this->UnitType + " \"" + this->Name +
9868 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
9869 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
9870 0 : state.dataUnitarySystems->MoistureLoad,
9871 0 : state.dataUnitarySystems->MoistureLoad);
9872 : }
9873 4 : } else if (SolFlagLat == -2) {
9874 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
9875 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9876 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
9877 0 : ShowContinueErrorTimeStamp(
9878 0 : state, format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
9879 : }
9880 0 : ShowRecurringWarningErrorAtEnd(state,
9881 0 : this->UnitType + " \"" + this->Name +
9882 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
9883 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
9884 0 : state.dataUnitarySystems->MoistureLoad,
9885 0 : state.dataUnitarySystems->MoistureLoad);
9886 : }
9887 :
9888 4 : FullSensibleOutput = TempSensOutput;
9889 :
9890 4 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
9891 : Real64 heatCoildT =
9892 4 : (this->m_HeatCoilExists)
9893 4 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
9894 4 : : 0.0;
9895 : Real64 CoolingOnlySensibleOutput =
9896 4 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
9897 4 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
9898 4 : heatCoildT);
9899 4 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
9900 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
9901 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
9902 2 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
9903 : // Heating mode and dehumidification is required
9904 : } else {
9905 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
9906 : // the heating coil pick up the load due to outdoor air.
9907 2 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
9908 : }
9909 7036 : }
9910 :
9911 7036 : void UnitarySys::initLoadBasedControl(EnergyPlusData &state,
9912 : int const AirLoopNum, // number of the current air loop being simulated
9913 : bool const FirstHVACIteration,
9914 : Real64 &OnOffAirFlowRatio,
9915 : Real64 &ZoneLoad)
9916 : {
9917 :
9918 : // SUBROUTINE INFORMATION:
9919 : // AUTHOR Richard Raustad, FSEC
9920 : // DATE WRITTEN February 2013
9921 :
9922 : // PURPOSE OF THIS SUBROUTINE:
9923 : // This subroutine is for initializations of the load controlled Unitary Systems.
9924 :
9925 : // METHODOLOGY EMPLOYED:
9926 : // Initialize mass flow rates and speed ratios. Calculate loads and adjust if necessary when using constant fan.
9927 :
9928 : // SUBROUTINE PARAMETER DEFINITIONS:
9929 : static constexpr std::string_view routineName("InitUnitarySystems");
9930 7036 : Real64 QZnReq = 0.0;
9931 7036 : Real64 QActual = 0.0;
9932 7036 : Real64 SensOutputOff = 0.0;
9933 7036 : Real64 LatOutputOff = 0.0;
9934 7036 : Real64 HeatCoilLoad = 0.0;
9935 7036 : Real64 SupHeaterLoad = 0.0;
9936 7036 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
9937 :
9938 : // do the Begin Environment initializations
9939 7036 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag2) {
9940 :
9941 27 : bool errorsFound = false;
9942 : // set fluid-side hardware limits
9943 27 : if (this->HeatCoilFluidInletNode > 0) {
9944 :
9945 1 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
9946 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
9947 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
9948 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
9949 : Real64 CoilMaxVolFlowRate =
9950 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_HeatingCoilName, errorsFound);
9951 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
9952 0 : Real64 rho = state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum)
9953 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
9954 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
9955 : }
9956 : }
9957 : // IF steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
9958 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
9959 0 : SteamCoils::SimulateSteamCoilComponents(state,
9960 : this->m_HeatingCoilName,
9961 : FirstHVACIteration,
9962 0 : this->m_HeatingCoilIndex,
9963 0 : 1.0,
9964 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
9965 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, errorsFound);
9966 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
9967 0 : Real64 TempSteamIn = 100.0;
9968 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
9969 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
9970 : }
9971 : }
9972 : }
9973 :
9974 1 : PlantUtilities::InitComponentNodes(
9975 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
9976 : }
9977 27 : if (this->m_SuppCoilFluidInletNode > 0) {
9978 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
9979 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
9980 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
9981 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
9982 : Real64 CoilMaxVolFlowRate =
9983 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_SuppHeatCoilName, errorsFound);
9984 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
9985 0 : Real64 rho = state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum)
9986 0 : .glycol->getDensity(state, Constant::CWInitConvTemp, routineName);
9987 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
9988 : }
9989 : }
9990 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
9991 0 : SteamCoils::SimulateSteamCoilComponents(state,
9992 : this->m_SuppHeatCoilName,
9993 : FirstHVACIteration,
9994 0 : this->m_SuppHeatCoilIndex,
9995 0 : 1.0,
9996 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
9997 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, errorsFound);
9998 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
9999 0 : Real64 TempSteamIn = 100.0;
10000 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, routineName);
10001 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10002 : }
10003 : }
10004 0 : PlantUtilities::InitComponentNodes(
10005 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
10006 : }
10007 : }
10008 27 : this->m_MyEnvrnFlag2 = false;
10009 : }
10010 :
10011 7036 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && this->m_MyCheckFlag) {
10012 7030 : if (this->m_AirLoopEquipment) {
10013 2 : int zoneInlet = this->m_ZoneInletNode;
10014 2 : if (zoneInlet == 0) {
10015 0 : this->m_ThisSysInputShouldBeGotten = true; // need to find zone inlet node once data is available
10016 0 : this->m_MySizingCheckFlag = true; // need to resize after getInput is read in again
10017 0 : this->m_OKToPrintSizing = true; // hope first time back through finds the data, else multiple prints to the eio
10018 0 : this->m_airLoopReturnCounter += 1;
10019 0 : if (this->m_airLoopReturnCounter < 3) return;
10020 : }
10021 : // setup zone equipment sequence information based on finding matching air terminal
10022 2 : if (state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex > 0) {
10023 2 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex)
10024 2 : .getPrioritiesForInletNode(state, zoneInlet, this->m_ZoneSequenceCoolingNum, this->m_ZoneSequenceHeatingNum);
10025 : }
10026 2 : this->m_MyCheckFlag = false;
10027 2 : if (this->m_ZoneSequenceCoolingNum == 0 || this->m_ZoneSequenceHeatingNum == 0) {
10028 0 : ShowSevereError(state,
10029 0 : format("{} \"{}\": Airloop air terminal in the zone equipment list for zone = {} not it or is not allowed "
10030 : "Zone Equipment Cooling or Heating Sequence = 0.",
10031 0 : this->UnitType,
10032 0 : this->Name,
10033 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10034 0 : ShowFatalError(
10035 : state,
10036 0 : format("Subroutine InitLoadBasedControl: Errors it in getting {} input. Preceding condition(s) causes termination.",
10037 0 : this->UnitType));
10038 : }
10039 : }
10040 7030 : if (this->m_ZoneInletNode == 0) {
10041 0 : ShowSevereError(state,
10042 0 : format("{} \"{}\": The zone inlet node in the controlled zone ({}) is not found.",
10043 0 : this->UnitType,
10044 0 : this->Name,
10045 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10046 0 : ShowFatalError(
10047 : state,
10048 0 : format("Subroutine InitLoadBasedControl: Errors found in getting {} input. Preceding condition(s) causes termination.",
10049 0 : this->UnitType));
10050 : }
10051 : }
10052 :
10053 : // What type of logic is this? Is the point to go through the main IF once? or every other time?
10054 : // RR: This was used with AirflowNetwork to calculate duct losses.
10055 : // RR: AFN counts the number of passes through airloop equipment (same logic in Furnaces and other modules) and resets the counter to 0 on
10056 : // BeginEnvrnFlag. RR: This has been changed in this module and AFN to use AirflowNetworkFanActivated if AirflowNetworkUnitarySystem is seen
10057 : // by AFN. RR: Search for AirflowNetworkFanActivated in this module to see usage. The following lines of code can probably be removed although
10058 : // it would require a AFN input file to test.
10059 7036 : if (state.dataGlobal->BeginEnvrnFlag && m_initLoadBasedControlAirLoopPass) {
10060 10 : m_airLoopPassCounter = 0;
10061 10 : m_initLoadBasedControlAirLoopPass = false;
10062 : }
10063 7036 : if (!state.dataGlobal->BeginEnvrnFlag) {
10064 6911 : this->m_MyEnvrnFlag2 = true; // this does not appear to be needed, only initializes autosized coil fluid flow rates
10065 6911 : m_initLoadBasedControlAirLoopPass = true;
10066 : }
10067 :
10068 7036 : ++m_airLoopPassCounter;
10069 7036 : if (m_airLoopPassCounter > 2) m_airLoopPassCounter = 1;
10070 :
10071 : // reset duct losses from previous iteration
10072 7036 : if (FirstHVACIteration) {
10073 3485 : this->m_SenLoadLoss = 0.0;
10074 3485 : this->m_LatLoadLoss = 0.0;
10075 : }
10076 :
10077 : // Calculate air distribution losses
10078 7036 : if (!FirstHVACIteration && state.afn->AirflowNetworkFanActivated) {
10079 0 : Real64 DeltaMassRate = 0.0;
10080 0 : Real64 TotalOutput = 0.0; // total output rate, {W}
10081 0 : Real64 SensibleOutputDelta = 0.0; // delta sensible output rate, {W}
10082 0 : Real64 LatentOutputDelta = 0.0; // delta latent output rate, {W}
10083 0 : Real64 TotalOutputDelta = 0.0; // delta total output rate, {W}
10084 0 : int ZoneInNode = this->m_ZoneInletNode;
10085 0 : Real64 MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10086 0 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
10087 0 : this->m_sysType != SysType::PackagedWSHP) {
10088 0 : DeltaMassRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate -
10089 0 : state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10090 0 : if (DeltaMassRate < 0.0) DeltaMassRate = 0.0;
10091 : } else {
10092 0 : MassFlowRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
10093 0 : DeltaMassRate = 0.0;
10094 : }
10095 0 : CalcComponentSensibleLatentOutput(MassFlowRate,
10096 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10097 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10098 0 : state.dataLoopNodes->Node(ZoneInNode).Temp,
10099 0 : state.dataLoopNodes->Node(ZoneInNode).HumRat,
10100 0 : this->m_SenLoadLoss,
10101 0 : this->m_LatLoadLoss,
10102 : TotalOutput);
10103 0 : CalcComponentSensibleLatentOutput(DeltaMassRate,
10104 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10105 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10106 0 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
10107 0 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
10108 : SensibleOutputDelta,
10109 : LatentOutputDelta,
10110 : TotalOutputDelta);
10111 0 : this->m_SenLoadLoss = this->m_SenLoadLoss + SensibleOutputDelta;
10112 0 : if (std::abs(this->m_SensibleLoadMet) > 0.0) {
10113 0 : if (std::abs(this->m_SenLoadLoss / this->m_SensibleLoadMet) < 0.001) this->m_SenLoadLoss = 0.0;
10114 : }
10115 0 : if (this->m_Humidistat) {
10116 0 : this->m_LatLoadLoss = this->m_LatLoadLoss + LatentOutputDelta;
10117 0 : if (std::abs(this->m_LatentLoadMet) > 0.0) {
10118 0 : if (std::abs(this->m_LatLoadLoss / this->m_LatentLoadMet) < 0.001) this->m_LatLoadLoss = 0.0;
10119 : }
10120 : }
10121 : }
10122 :
10123 7036 : if (this->m_fanOpModeSched != nullptr) {
10124 7019 : if (this->m_fanOpModeSched->getCurrentVal() == 0.0) {
10125 6984 : this->m_FanOpMode = HVAC::FanOp::Cycling;
10126 : } else {
10127 35 : this->m_FanOpMode = HVAC::FanOp::Continuous;
10128 35 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10129 : }
10130 : }
10131 :
10132 : // System load calculation for cycling fan systems
10133 7036 : if (this->ControlZoneMassFlowFrac > 0.0) {
10134 7020 : QZnReq = ZoneLoad / this->ControlZoneMassFlowFrac;
10135 7020 : state.dataUnitarySystems->MoistureLoad /= this->ControlZoneMassFlowFrac;
10136 7020 : state.dataUnitarySystems->QToCoolSetPt /= this->ControlZoneMassFlowFrac;
10137 7020 : state.dataUnitarySystems->QToHeatSetPt /= this->ControlZoneMassFlowFrac;
10138 7020 : ZoneLoad = QZnReq;
10139 : } else {
10140 16 : QZnReq = ZoneLoad;
10141 16 : this->ControlZoneMassFlowFrac = 1.0;
10142 : }
10143 :
10144 7036 : state.dataUnitarySystems->CoolingLoad = false;
10145 7036 : state.dataUnitarySystems->HeatingLoad = false;
10146 7036 : Real64 smallLoadTolerance = this->m_SmallLoadTolerance;
10147 7036 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10148 6979 : smallLoadTolerance = HVAC::SmallLoad;
10149 : }
10150 7036 : if (QZnReq > smallLoadTolerance) { // no need to check deadband flag, QZnReq is correct.
10151 2750 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleCool) {
10152 2750 : state.dataUnitarySystems->HeatingLoad = true;
10153 : }
10154 4286 : } else if (QZnReq < -smallLoadTolerance) {
10155 1536 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::SetptType::SingleHeat) {
10156 1536 : state.dataUnitarySystems->CoolingLoad = true;
10157 : }
10158 : }
10159 :
10160 : // System load calculation for constant fan systems
10161 7036 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10162 35 : bool HXUnitOn = false;
10163 35 : this->FanPartLoadRatio = 0.0; // sets fan to minimum for ASHRAE model
10164 35 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10165 : // the SpeedNum is set for PTUnits, might need to set this for all multi/var speed coils?
10166 19 : if (state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) {
10167 0 : m_CoolingSpeedNum = 1;
10168 19 : } else if (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil) {
10169 0 : m_HeatingSpeedNum = 1;
10170 : }
10171 : }
10172 35 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio,
10173 : 0.0); // CompOnMassFlow and CompOffMassFlow are scalar, reset to this system's values
10174 35 : this->calcUnitarySystemToLoad(state,
10175 : AirLoopNum,
10176 : FirstHVACIteration,
10177 : 0.0,
10178 : 0.0,
10179 : OnOffAirFlowRatio,
10180 : SensOutputOff,
10181 : LatOutputOff,
10182 : HXUnitOn,
10183 : HeatCoilLoad,
10184 : SupHeaterLoad,
10185 : CompressorOn);
10186 :
10187 35 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
10188 8 : case HVAC::SetptType::SingleHeat: {
10189 8 : state.dataUnitarySystems->CoolingLoad = false;
10190 : // No heating load and constant fan pushes zone below heating set point
10191 10 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt <= 0.0 &&
10192 2 : SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10193 2 : state.dataUnitarySystems->HeatingLoad = true;
10194 2 : state.dataUnitarySystems->CoolingLoad = false;
10195 2 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10196 : }
10197 8 : } break;
10198 :
10199 2 : case HVAC::SetptType::SingleCool: {
10200 2 : state.dataUnitarySystems->HeatingLoad = false;
10201 : // No heating load and constant fan pushes zone above cooling set point
10202 2 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
10203 0 : SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10204 0 : state.dataUnitarySystems->HeatingLoad = false;
10205 0 : state.dataUnitarySystems->CoolingLoad = true;
10206 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10207 : }
10208 2 : } break;
10209 :
10210 0 : case HVAC::SetptType::SingleHeatCool: {
10211 : // zone temp above cooling and heating set point temps
10212 0 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10213 : // zone pushed below heating set point
10214 0 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10215 0 : state.dataUnitarySystems->HeatingLoad = true;
10216 0 : state.dataUnitarySystems->CoolingLoad = false;
10217 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10218 : }
10219 : // zone temp below heating set point temp
10220 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10221 : // zone pushed above cooling set point
10222 0 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10223 0 : state.dataUnitarySystems->HeatingLoad = false;
10224 0 : state.dataUnitarySystems->CoolingLoad = true;
10225 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10226 : }
10227 : }
10228 0 : } break;
10229 :
10230 25 : case HVAC::SetptType::DualHeatCool: {
10231 : // zone temp above cooling and heating set point temps
10232 25 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10233 : // zone pushed into deadband
10234 14 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10235 2 : state.dataUnitarySystems->HeatingLoad = false;
10236 2 : state.dataUnitarySystems->CoolingLoad = false;
10237 2 : ZoneLoad = 0.0;
10238 : }
10239 : // zone pushed below heating set point
10240 14 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10241 2 : state.dataUnitarySystems->HeatingLoad = true;
10242 2 : state.dataUnitarySystems->CoolingLoad = false;
10243 2 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10244 : }
10245 : // zone temp below heating set point temp
10246 11 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10247 : // zone pushed into deadband
10248 4 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt > HVAC::SmallLoad) {
10249 0 : state.dataUnitarySystems->HeatingLoad = false;
10250 0 : state.dataUnitarySystems->CoolingLoad = false;
10251 0 : ZoneLoad = 0.0;
10252 : }
10253 : // zone pushed above cooling set point
10254 4 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10255 0 : state.dataUnitarySystems->HeatingLoad = false;
10256 0 : state.dataUnitarySystems->CoolingLoad = true;
10257 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10258 : }
10259 : // zone temp between set point temps
10260 7 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10261 : // zone pushed below heating set point
10262 2 : if (SensOutputOff < 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10263 0 : state.dataUnitarySystems->HeatingLoad = true;
10264 0 : state.dataUnitarySystems->CoolingLoad = false;
10265 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10266 : // zone pushed above cooling set point
10267 2 : } else if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10268 0 : state.dataUnitarySystems->HeatingLoad = false;
10269 0 : state.dataUnitarySystems->CoolingLoad = true;
10270 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10271 : }
10272 : }
10273 25 : } break;
10274 :
10275 0 : default: {
10276 0 : } break;
10277 : } // switch
10278 :
10279 : // push iteration mode stack and set current mode
10280 35 : this->m_IterationMode[2] = this->m_IterationMode[1];
10281 35 : this->m_IterationMode[1] = this->m_IterationMode[0];
10282 35 : if (state.dataUnitarySystems->CoolingLoad) {
10283 13 : this->m_IterationMode[0] = CoolingMode;
10284 22 : } else if (state.dataUnitarySystems->HeatingLoad) {
10285 17 : this->m_IterationMode[0] = HeatingMode;
10286 : } else {
10287 5 : this->m_IterationMode[0] = NoCoolHeat;
10288 : }
10289 : // IF small loads to meet or not converging, just shut down unit
10290 35 : if (std::abs(ZoneLoad) < smallLoadTolerance) {
10291 6 : ZoneLoad = 0.0;
10292 6 : state.dataUnitarySystems->CoolingLoad = false;
10293 6 : state.dataUnitarySystems->HeatingLoad = false;
10294 29 : } else if (this->m_IterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 6)) {
10295 : // attempt to lock output (air flow) if oscillations are detected
10296 4 : int OperatingMode = this->m_IterationMode[0]; // VS systems can take a few more iterations than single-speed systems
10297 4 : int OperatingModeMinusOne = this->m_IterationMode[1];
10298 4 : int OperatingModeMinusTwo = this->m_IterationMode[2];
10299 4 : bool Oscillate = true;
10300 4 : if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) Oscillate = false;
10301 4 : if (Oscillate) {
10302 1 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10303 1 : state.dataUnitarySystems->HeatingLoad = false;
10304 1 : state.dataUnitarySystems->CoolingLoad = true;
10305 1 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10306 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0) {
10307 0 : state.dataUnitarySystems->HeatingLoad = true;
10308 0 : state.dataUnitarySystems->CoolingLoad = false;
10309 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10310 : } else {
10311 0 : state.dataUnitarySystems->HeatingLoad = false;
10312 0 : state.dataUnitarySystems->CoolingLoad = false;
10313 0 : ZoneLoad = 0.0;
10314 : }
10315 : }
10316 : }
10317 : }
10318 :
10319 : // Determine the m_Staged status
10320 7036 : if (allocated(state.dataZoneCtrls->StageZoneLogic) && this->m_DesignSpecMSHPIndex > -1) {
10321 3 : if (state.dataZoneCtrls->StageZoneLogic(this->ControlZoneNum)) {
10322 3 : this->m_Staged = true;
10323 3 : this->m_StageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).StageNum;
10324 : } else {
10325 0 : if (this->m_MyStagedFlag) {
10326 0 : ShowWarningError(state,
10327 : "ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to this UnitarySystem "
10328 : "object with UnitarySystemPerformance:Multispeed type = ");
10329 0 : ShowContinueError(state, format("{}. Please make correction. Simulation continues...", this->Name));
10330 0 : this->m_MyStagedFlag = false;
10331 : }
10332 : }
10333 : }
10334 :
10335 : // Staged control
10336 7036 : if (this->m_Staged) {
10337 3 : if (this->m_StageNum == 0) {
10338 1 : state.dataUnitarySystems->HeatingLoad = false;
10339 1 : state.dataUnitarySystems->CoolingLoad = false;
10340 1 : QZnReq = 0.0;
10341 : } else {
10342 2 : QZnReq =
10343 2 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired / this->ControlZoneMassFlowFrac;
10344 2 : if (QZnReq > 0.0) {
10345 1 : state.dataUnitarySystems->HeatingLoad = true;
10346 1 : state.dataUnitarySystems->CoolingLoad = false;
10347 : } else {
10348 1 : state.dataUnitarySystems->HeatingLoad = false;
10349 1 : state.dataUnitarySystems->CoolingLoad = true;
10350 : }
10351 : }
10352 : }
10353 :
10354 7036 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10355 2 : if (state.dataUnitarySystems->HeatingLoad) state.dataUnitarySystems->MoistureLoad = 0.0;
10356 : }
10357 :
10358 : // Check load control
10359 7036 : if (this->m_RunOnLatentOnlyWithSensible && ZoneLoad == 0.0) state.dataUnitarySystems->MoistureLoad = 0.0;
10360 7036 : if (!this->m_RunOnSensibleLoad) {
10361 0 : ZoneLoad = 0.0;
10362 0 : state.dataUnitarySystems->CoolingLoad = false;
10363 0 : state.dataUnitarySystems->HeatingLoad = false;
10364 : }
10365 7036 : if (!this->m_RunOnLatentLoad) state.dataUnitarySystems->MoistureLoad = 0.0;
10366 :
10367 : // Testing heat pump air to air with RH control with CoolReheat dehumidification control showed that when there was heating
10368 : // and moisture load, the cooling coil was turning on to meet the moisture load and reheat was then turning on to meet both
10369 : // heating load and excess cooling load caused by cooling coil. Adding the logic below caused the zone temperature,
10370 : // relative humidity, cooling/heating rate to line up for both the original and new file with unitary system object.
10371 :
10372 7036 : if (this->m_SuppCoilExists) {
10373 6984 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10374 6 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolCoilExists) {
10375 5 : state.dataUnitarySystems->HeatingLoad = false;
10376 5 : state.dataUnitarySystems->CoolingLoad = true;
10377 : }
10378 : }
10379 : }
10380 :
10381 : // set report variables for predicted sensible and latent load
10382 7036 : this->m_SensibleLoadPredicted = ZoneLoad;
10383 7036 : this->m_MoistureLoadPredicted = state.dataUnitarySystems->MoistureLoad;
10384 : }
10385 :
10386 81965 : void UnitarySys::setOnOffMassFlowRate(EnergyPlusData &state,
10387 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
10388 : Real64 const PartLoadRatio // coil part-load ratio
10389 : )
10390 : {
10391 :
10392 : // SUBROUTINE INFORMATION:
10393 : // AUTHOR Chandan Sharma
10394 : // DATE WRITTEN May 2013
10395 :
10396 : // PURPOSE OF THIS SUBROUTINE:
10397 : // This subroutine is for initializations of the components.
10398 :
10399 : // METHODOLOGY EMPLOYED:
10400 : // The unitarysystem may have alternate air flow rates
10401 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
10402 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
10403 : // based on PLR.
10404 :
10405 : // REFERENCES:
10406 : // Based on SetOnOffMassFlowRate by Richard Raustad
10407 :
10408 81965 : int HeatSpeedNum = 0;
10409 81965 : int CoolSpeedNum = 0;
10410 :
10411 81965 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10412 81965 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10413 81965 : state.dataUnitarySystems->m_massFlow1 = 0.0;
10414 81965 : state.dataUnitarySystems->m_massFlow2 = 0.0;
10415 81965 : state.dataUnitarySystems->OACompOnMassFlow = 0.0;
10416 81965 : state.dataUnitarySystems->OACompOffMassFlow = 0.0;
10417 :
10418 : // Set the compressor or coil ON mass flow rate
10419 81965 : if (state.dataUnitarySystems->HeatingLoad) {
10420 :
10421 51751 : this->m_LastMode = HeatingMode;
10422 :
10423 51751 : if (this->m_MultiOrVarSpeedHeatCoil) {
10424 :
10425 51616 : HeatSpeedNum = this->m_HeatingSpeedNum;
10426 :
10427 51616 : if (HeatSpeedNum == 0) {
10428 5475 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10429 5475 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10430 46141 : } else if (HeatSpeedNum == 1) {
10431 8372 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10432 8372 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10433 37769 : } else if (HeatSpeedNum > 1) {
10434 37769 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10435 37769 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10436 : }
10437 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10438 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10439 51616 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10440 49 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10441 2 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10442 2 : if (this->m_MultiOrVarSpeedCoolCoil) {
10443 2 : CoolSpeedNum = this->m_CoolingSpeedNum;
10444 2 : if (CoolSpeedNum < 1) {
10445 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10446 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10447 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10448 2 : } else if (CoolSpeedNum == 1) {
10449 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10450 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10451 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10452 : } else {
10453 2 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10454 2 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10455 2 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10456 : }
10457 : } else {
10458 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10459 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10460 : }
10461 2 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10462 : } else {
10463 45 : if (HeatSpeedNum == 0) {
10464 15 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10465 15 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10466 30 : } else if (HeatSpeedNum == 1) {
10467 17 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10468 17 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatMassFlowRate[HeatSpeedNum];
10469 : } else {
10470 13 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10471 13 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10472 : }
10473 45 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10474 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10475 45 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10476 45 : this->m_sysType == SysType::PackagedWSHP) {
10477 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10478 : }
10479 : }
10480 : } else { // cycling fan mode
10481 51569 : if (HeatSpeedNum <= 1) {
10482 13813 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10483 13813 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10484 : } else {
10485 37756 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10486 37756 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10487 : }
10488 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10489 51569 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10490 51569 : this->m_sysType == SysType::PackagedWSHP) {
10491 51437 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10492 : // does this assume OA flow <= min speed flow? without this there are SolveRoot failures.
10493 51437 : if (HeatSpeedNum > 1) {
10494 37690 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10495 : }
10496 : }
10497 : }
10498 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10499 : // If a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
10500 135 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10501 135 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && !this->m_DXHeatingCoil) {
10502 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10503 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10504 0 : if (CoolSpeedNum < 1) {
10505 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10506 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10507 0 : } else if (CoolSpeedNum == 1) {
10508 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10509 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10510 : } else {
10511 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10512 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10513 : }
10514 : } else { // IF (MultiOrVarSpeedCoolCoil) THEN
10515 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10516 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10517 0 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10518 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10519 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10520 : }
10521 : }
10522 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10523 : } else { // Heating load but no moisture load
10524 135 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10525 51 : this->m_sysType == SysType::PackagedWSHP) {
10526 : // this was missing for heating mode where multi speed coils are used
10527 84 : if (this->m_MultiOrVarSpeedHeatCoil) {
10528 0 : if (HeatSpeedNum == 0) {
10529 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10530 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10531 0 : } else if (HeatSpeedNum == 1) {
10532 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10533 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10534 0 : } else if (HeatSpeedNum > 1) {
10535 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10536 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10537 : }
10538 : } else {
10539 84 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10540 84 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10541 84 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10542 : }
10543 84 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10544 78 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10545 78 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10546 78 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10547 : }
10548 : } else {
10549 51 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10550 51 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10551 51 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10552 51 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10553 29 : if (this->m_AirFlowControl == UseCompFlow::On) {
10554 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10555 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10556 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10557 : } else {
10558 29 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10559 29 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10560 29 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10561 : }
10562 : }
10563 : }
10564 : }
10565 : }
10566 :
10567 : // If a cooling load exists, operate at the cooling mass flow rate
10568 30214 : } else if (state.dataUnitarySystems->CoolingLoad) {
10569 :
10570 24700 : this->m_LastMode = CoolingMode;
10571 :
10572 24700 : if (this->m_MultiOrVarSpeedCoolCoil) {
10573 :
10574 24350 : CoolSpeedNum = this->m_CoolingSpeedNum;
10575 :
10576 24350 : if (CoolSpeedNum == 0) {
10577 3002 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10578 3002 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10579 3002 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10580 21348 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation; set system flow rate to economizer flow rate
10581 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10582 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10583 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10584 21348 : } else if (CoolSpeedNum > 0) {
10585 21348 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10586 21348 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10587 21348 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10588 : }
10589 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10590 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10591 24350 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10592 27 : if (CoolSpeedNum == 0) {
10593 7 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10594 7 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10595 7 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10596 20 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10597 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10598 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10599 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10600 20 : } else if (CoolSpeedNum == 1) {
10601 16 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10602 16 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10603 16 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10604 : } else {
10605 4 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10606 4 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10607 4 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10608 : }
10609 : } else { // cycling fan mode
10610 24323 : if (this->m_EconoSpeedNum == 0 && CoolSpeedNum == 0) { // multi-stage economizer operation
10611 2995 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10612 2995 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10613 21328 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10614 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
10615 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum - 1];
10616 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10617 21328 : } else if (CoolSpeedNum == 0) {
10618 0 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10619 0 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10620 : } else {
10621 21328 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10622 21328 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10623 21328 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10624 : }
10625 : }
10626 : } else {
10627 350 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10628 350 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10629 350 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10630 350 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10631 109 : if (this->m_AirFlowControl == UseCompFlow::On) {
10632 92 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10633 92 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10634 92 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10635 : } else {
10636 17 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10637 17 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10638 17 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10639 : }
10640 : }
10641 : }
10642 :
10643 : } else { // No load
10644 : // If no load exists, set the compressor on mass flow rate.
10645 : // Set equal the mass flow rate when no heating or cooling is needed If no moisture load exists.
10646 : // If the user has set the off mass flow rate to 0, set according to the last operating mode.
10647 :
10648 5514 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10649 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10650 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10651 0 : if (CoolSpeedNum < 1) {
10652 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10653 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10654 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10655 0 : } else if (CoolSpeedNum == 1) {
10656 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10657 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10658 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10659 : } else {
10660 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10661 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10662 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10663 : }
10664 :
10665 0 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10666 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
10667 0 : if (CoolSpeedNum <= 1) {
10668 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10669 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10670 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10671 : } else {
10672 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10673 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10674 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10675 : }
10676 : } else {
10677 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10678 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10679 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10680 : }
10681 : }
10682 :
10683 : } else { // IF (MultiOrVarSpeedCoolCoil(UnitarySysNum)) THEN
10684 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10685 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10686 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10687 0 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10688 0 : if (this->m_AirFlowControl == UseCompFlow::On) {
10689 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10690 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10691 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10692 : } else {
10693 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10694 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10695 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10696 : }
10697 : }
10698 : }
10699 :
10700 : } else { // No Moisture Load
10701 :
10702 5514 : if (this->m_LastMode == HeatingMode) {
10703 : // this needs to be corrected to include UseCompressorOnFlow
10704 653 : if (this->m_MultiOrVarSpeedHeatCoil) {
10705 633 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10706 633 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10707 : } else {
10708 20 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10709 20 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
10710 : }
10711 : // this needs to happen regardless of system except maybe the CoilSystem objects
10712 : // do this only for PTUnit for the time being to reduce diffs for the PTUnit to UnitarySystem conversion
10713 653 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10714 633 : this->m_sysType == SysType::PackagedWSHP) {
10715 652 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10716 18 : if (this->m_AirFlowControl == UseCompFlow::On) {
10717 16 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10718 16 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10719 16 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10720 : }
10721 : }
10722 : }
10723 : } else {
10724 : // this needs to be corrected to include UseCompressorOnFlow
10725 4861 : if (this->m_MultiOrVarSpeedCoolCoil) {
10726 4859 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10727 4859 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10728 : } else {
10729 2 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10730 2 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
10731 : }
10732 : }
10733 5514 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10734 5514 : if (state.dataUnitarySystems->CompOnMassFlow == 0.0) {
10735 2991 : if (this->m_LastMode == HeatingMode) {
10736 369 : if (this->m_MultiOrVarSpeedHeatCoil) {
10737 355 : HeatSpeedNum = this->m_HeatingSpeedNum;
10738 355 : if (HeatSpeedNum == 0) {
10739 354 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10740 354 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10741 1 : } else if (HeatSpeedNum == 1) {
10742 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10743 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10744 1 : } else if (HeatSpeedNum > 1) {
10745 1 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10746 1 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10747 : }
10748 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10749 14 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10750 14 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10751 : }
10752 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10753 2622 : if (this->m_MultiOrVarSpeedCoolCoil) {
10754 2620 : CoolSpeedNum = this->m_CoolingSpeedNum;
10755 2620 : if (CoolSpeedNum == 0) {
10756 2620 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10757 2620 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10758 0 : } else if (CoolSpeedNum == 1) {
10759 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10760 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10761 0 : } else if (CoolSpeedNum > 1) {
10762 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10763 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10764 : }
10765 : } else { // IF(MultiOrVarSpeedCoolCoil) THEN
10766 2 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10767 2 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10768 : } // IF(MultiOrVarSpeedCoolCoil) THEN
10769 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10770 : } // IF(CompOnMassFlow .EQ. 0.0d0)THEN
10771 :
10772 5514 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10773 28 : if (this->m_AirFlowControl == UseCompFlow::On) {
10774 17 : if (this->m_LastMode == HeatingMode) {
10775 17 : if (this->m_MultiOrVarSpeedHeatCoil) {
10776 1 : HeatSpeedNum = this->m_HeatingSpeedNum;
10777 1 : if (HeatSpeedNum < 1) {
10778 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10779 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10780 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10781 1 : } else if (HeatSpeedNum == 1) {
10782 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[1];
10783 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[1];
10784 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10785 : } else {
10786 1 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10787 1 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10788 1 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10789 : }
10790 : } else {
10791 : // this is a no load case, added if for PTUnit to correct this for PTUnit to UnitarySystem conversion
10792 : // the else is incorrect?
10793 16 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10794 0 : this->m_sysType == SysType::PackagedWSHP) {
10795 16 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10796 16 : if (this->m_AirFlowControl == UseCompFlow::On) {
10797 16 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10798 16 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10799 16 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10800 : }
10801 : }
10802 : } else {
10803 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10804 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10805 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10806 : }
10807 : }
10808 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10809 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10810 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10811 0 : if (CoolSpeedNum < 1) {
10812 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10813 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10814 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10815 0 : } else if (CoolSpeedNum == 1) {
10816 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10817 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10818 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10819 : } else {
10820 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10821 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10822 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10823 : }
10824 : } else {
10825 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10826 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10827 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10828 : }
10829 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10830 : } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
10831 11 : if (this->m_LastMode == HeatingMode) {
10832 2 : if (this->m_MultiOrVarSpeedHeatCoil) {
10833 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10834 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10835 : } else {
10836 2 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10837 2 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10838 : }
10839 : } else {
10840 9 : if (this->m_MultiOrVarSpeedCoolCoil) {
10841 9 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10842 9 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10843 : } else {
10844 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10845 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10846 : }
10847 : }
10848 11 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10849 : } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
10850 : } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN
10851 : } // ELSE ! No Moisture Load
10852 : } // No Heating/Cooling Load
10853 :
10854 81965 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10855 318 : if (this->m_AirFlowControl == UseCompFlow::On &&
10856 132 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)) {
10857 118 : if (this->m_LastMode == HeatingMode) {
10858 26 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10859 : } else {
10860 92 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10861 : }
10862 : }
10863 : }
10864 :
10865 81965 : if (this->m_MultiSpeedHeatingCoil && (state.dataUnitarySystems->HeatingLoad && HeatSpeedNum == 1)) {
10866 4263 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
10867 77702 : } else if (this->m_DiscreteSpeedCoolingCoil && (state.dataUnitarySystems->CoolingLoad && CoolSpeedNum == 1)) {
10868 4209 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
10869 : } else {
10870 73493 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOffMassFlow; // these need to be set for multi-speed coils
10871 : }
10872 163930 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
10873 81965 : state.dataUnitarySystems->CompOnMassFlow; // doesn't hurt to set these if multi-speed coils are not used
10874 81965 : state.dataHVACGlobal->MSUSEconoSpeedNum = this->m_EconoSpeedNum;
10875 :
10876 81965 : state.dataUnitarySystems->m_massFlow1 = state.dataUnitarySystems->CompOnMassFlow;
10877 81965 : state.dataUnitarySystems->m_massFlow2 = state.dataUnitarySystems->CompOffMassFlow;
10878 :
10879 : // Set the system mass flow rates
10880 81965 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
10881 81965 : }
10882 :
10883 106704 : void UnitarySys::setAverageAirFlow(EnergyPlusData &state,
10884 : Real64 const PartLoadRatio, // unit part load ratio
10885 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
10886 : )
10887 : {
10888 :
10889 : // SUBROUTINE INFORMATION:
10890 : // AUTHOR Richard Raustad
10891 : // DATE WRITTEN July 2005
10892 :
10893 : // PURPOSE OF THIS SUBROUTINE:
10894 : // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
10895 : // Set OnOffAirFlowRatio to be used by DX coils
10896 :
10897 : // METHODOLOGY EMPLOYED:
10898 : // The air flow rate in cooling, heating, and no cooling or heating can be different.
10899 : // Calculate the air flow rate based on initializations.
10900 :
10901 106704 : Real64 AverageUnitMassFlow = 0.0; // average supply air mass flow rate over time step
10902 106704 : bool FanOn = false;
10903 :
10904 106704 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
10905 106704 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
10906 :
10907 106704 : Real64 FanPartLoadRatio = PartLoadRatio;
10908 106704 : if (this->m_SimASHRAEModel) FanPartLoadRatio = this->FanPartLoadRatio;
10909 106704 : if (this->m_EconoPartLoadRatio > 0) FanPartLoadRatio = this->m_EconoPartLoadRatio;
10910 106704 : int SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum, this->m_EconoSpeedNum);
10911 106704 : int InletNode = this->AirInNode;
10912 :
10913 106704 : if (SpeedNum > 1) {
10914 129570 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
10915 55196 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
10916 74372 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10917 19 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow +
10918 19 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow;
10919 : } else {
10920 74353 : Real64 tempSpeedRatio = 0;
10921 74353 : if (this->m_EconoPartLoadRatio > 0) {
10922 0 : tempSpeedRatio = this->FanPartLoadRatio;
10923 : } else {
10924 74353 : tempSpeedRatio = state.dataUnitarySystems->CoolingLoad ? this->m_CoolingSpeedRatio : this->m_HeatingSpeedRatio;
10925 : }
10926 74353 : AverageUnitMassFlow = tempSpeedRatio * state.dataUnitarySystems->CompOnMassFlow +
10927 74353 : (1.0 - tempSpeedRatio) * state.dataUnitarySystems->CompOffMassFlow;
10928 : }
10929 : } else {
10930 2 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
10931 : }
10932 : } else {
10933 32330 : AverageUnitMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow) +
10934 32330 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow);
10935 : }
10936 :
10937 106704 : if (state.dataUnitarySystems->CompOffFlowRatio > 0.0) {
10938 74818 : if (SpeedNum > 1) {
10939 129570 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
10940 55196 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
10941 74372 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio +
10942 74372 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio;
10943 74372 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
10944 74372 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
10945 : } else {
10946 2 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
10947 2 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
10948 2 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
10949 : }
10950 : } else {
10951 444 : state.dataUnitarySystems->FanSpeedRatio = (FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio) +
10952 444 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio);
10953 444 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
10954 444 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
10955 : }
10956 : } else {
10957 31886 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
10958 31886 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
10959 31886 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
10960 : }
10961 :
10962 106704 : if (!(state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating == 0)) {
10963 106435 : if (this->m_SingleMode == 1) {
10964 51 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10965 0 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
10966 0 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
10967 0 : state.dataUnitarySystems->m_runTimeFraction1 = 1.0;
10968 0 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
10969 : } else {
10970 51 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow;
10971 51 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio;
10972 51 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
10973 51 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
10974 : }
10975 : }
10976 : }
10977 :
10978 106704 : if (this->OAMixerExists) {
10979 95 : Real64 AverageOAMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->OACompOnMassFlow) +
10980 95 : ((1 - FanPartLoadRatio) * state.dataUnitarySystems->OACompOffMassFlow);
10981 :
10982 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = AverageOAMassFlow;
10983 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = AverageOAMassFlow;
10984 : // don't need to set relief node, delete them when working
10985 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = AverageOAMassFlow;
10986 95 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = AverageOAMassFlow;
10987 : }
10988 :
10989 : // BEGIN - refactor/move this to Init during FirstHVACIteration, need struct or module level global for turnFansOn and turnFansOff
10990 : // If the unitary system is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
10991 106704 : FanOn = (this->m_FanExists) ? (this->m_fanAvailSched->getCurrentVal() > 0) : true;
10992 : // END - move this to Init during FirstHVACIteration
10993 :
10994 106704 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && ((FanOn || state.dataHVACGlobal->TurnFansOn) && !state.dataHVACGlobal->TurnFansOff)) {
10995 106677 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
10996 : // set point based equipment should use VAV terminal units to set the flow.
10997 : // zone equipment needs to set flow since no other device regulates flow (ZoneHVAC /= AirLoopEquipment)
10998 49 : if (!this->m_AirLoopEquipment) {
10999 43 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11000 43 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11001 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11002 : }
11003 49 : if (AverageUnitMassFlow > 0.0) {
11004 40 : OnOffAirFlowRatio = 1.0;
11005 : } else {
11006 9 : OnOffAirFlowRatio = 0.0;
11007 : }
11008 : } else {
11009 106628 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11010 106628 : if (!this->m_AirLoopEquipment) {
11011 106464 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11012 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11013 : }
11014 106628 : if (AverageUnitMassFlow > 0.0) {
11015 83077 : if (SpeedNum > 1) {
11016 74344 : OnOffAirFlowRatio = 1.0;
11017 : } else {
11018 8733 : OnOffAirFlowRatio = state.dataUnitarySystems->CompOnMassFlow / AverageUnitMassFlow;
11019 : }
11020 : } else {
11021 23551 : OnOffAirFlowRatio = 0.0;
11022 : }
11023 : }
11024 : } else {
11025 27 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
11026 : // fan will turn on unless these are reset, or maybe one of them. Might be a better way when calling fan.
11027 27 : state.dataUnitarySystems->m_massFlow1 = 0.0;
11028 27 : state.dataUnitarySystems->m_massFlow2 = 0.0;
11029 27 : OnOffAirFlowRatio = 1.0;
11030 27 : if (this->OAMixerExists) {
11031 : // maybe can just set MaxAvail = 0?
11032 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = 0.0;
11033 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = 0.0;
11034 : // don't need to set relief node, delete then when working
11035 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = 0.0;
11036 0 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = 0.0;
11037 : }
11038 : }
11039 106704 : }
11040 :
11041 66511 : void UnitarySys::calcUnitarySystemToLoad(EnergyPlusData &state,
11042 : int const AirLoopNum, // index to air loop
11043 : bool const FirstHVACIteration, // True when first HVAC iteration
11044 : Real64 const CoolPLR, // operating cooling part-load ratio []
11045 : Real64 const HeatPLR, // operating cooling part-load ratio []
11046 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
11047 : Real64 &SensOutput, // sensible capacity (W)
11048 : Real64 &LatOutput, // latent capacity (W)
11049 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
11050 : Real64 HeatCoilLoad, // Adjusted load to heating coil when SAT exceeds max limit (W)
11051 : Real64 SuppCoilLoad, // Adjusted load to supp heating coil when SAT exceeds max limit (W)
11052 : HVAC::CompressorOp const CompressorOn // Determines if compressor is on or off
11053 : )
11054 : {
11055 :
11056 : // SUBROUTINE INFORMATION:
11057 : // AUTHOR Richard Raustad, FSEC
11058 : // DATE WRITTEN February 2013
11059 :
11060 : // PURPOSE OF THIS SUBROUTINE:
11061 : // This subroutine calculates the resulting performance of the unitary system given
11062 : // the operating PLR. System output is calculated with respect to zone condition.
11063 :
11064 66511 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
11065 :
11066 66511 : HVAC::CompressorOp CoolingCompOn = HVAC::CompressorOp::Off;
11067 66511 : if (CoolPLR > 0) {
11068 15579 : CoolingCompOn = CompressorOn;
11069 50932 : } else if (CoolPLR == 0 && this->m_EconoSpeedNum > 0) { // turn compressor off for economizer calculations
11070 0 : CoolingCompOn = HVAC::CompressorOp::Off;
11071 50932 : } else if (this->m_CoolingSpeedNum > 1) { // for multispeed coils, comp is on IF speed > 1
11072 1044 : CoolingCompOn = HVAC::CompressorOp::On;
11073 : }
11074 :
11075 66511 : HVAC::CompressorOp HeatingCompOn = HVAC::CompressorOp::Off;
11076 66511 : if (HeatPLR > 0) {
11077 35338 : HeatingCompOn = CompressorOn;
11078 35338 : CoilCoolHeatRat = min(1.0, CoolPLR / HeatPLR);
11079 : }
11080 : // for multispeed coils, comp is on at PLR=0 IF speed > 1
11081 66511 : if (this->m_HeatingSpeedNum > 1) HeatingCompOn = HVAC::CompressorOp::On;
11082 :
11083 : // set the operating flow rate
11084 66511 : if (this->m_NumOfSpeedCooling > 0 || this->m_NumOfSpeedHeating > 0) {
11085 66299 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, max(CoolPLR, HeatPLR));
11086 : } else {
11087 212 : this->setAverageAirFlow(state, max(CoolPLR, HeatPLR), OnOffAirFlowRatio);
11088 : }
11089 :
11090 : // Call the series of components that simulate a Unitary System
11091 66511 : if (this->ATMixerExists) {
11092 : // There is an air terminal mixer
11093 65899 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
11094 : // set the primary air inlet mass flow rate
11095 65836 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
11096 65836 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
11097 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
11098 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
11099 65836 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11100 : }
11101 : }
11102 66511 : if (this->OAMixerExists) {
11103 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
11104 : // 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
11105 : // at least better than constructing a new string each time to call this function
11106 65 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
11107 : }
11108 :
11109 66511 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
11110 66507 : state.dataFans->fans(this->m_FanIndex)
11111 199521 : ->simulate(state,
11112 : FirstHVACIteration,
11113 66507 : state.dataUnitarySystems->FanSpeedRatio,
11114 : _, // Pressure rise
11115 : _, // Flow fraction
11116 66507 : state.dataUnitarySystems->m_massFlow1,
11117 66507 : state.dataUnitarySystems->m_runTimeFraction1,
11118 66507 : state.dataUnitarySystems->m_massFlow2,
11119 66507 : state.dataUnitarySystems->m_runTimeFraction2,
11120 : _);
11121 : }
11122 :
11123 66511 : if (this->m_CoolingCoilUpstream) {
11124 :
11125 66438 : if (this->m_CoolCoilExists) {
11126 66438 : this->calcUnitaryCoolingSystem(
11127 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11128 : }
11129 66438 : if (this->m_HeatCoilExists) {
11130 : // operate the heating coil without regard to coil outlet temperature
11131 66429 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11132 66429 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11133 0 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11134 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11135 0 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11136 0 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11137 0 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11138 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11139 0 : HeatCoilLoad = MaxHeatCoilLoad;
11140 : }
11141 : }
11142 :
11143 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11144 66438 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11145 17826 : state.dataFans->fans(this->m_FanIndex)
11146 53478 : ->simulate(state,
11147 : FirstHVACIteration,
11148 17826 : state.dataUnitarySystems->FanSpeedRatio,
11149 : _, // Pressure rise
11150 : _, // Flow fraction
11151 17826 : state.dataUnitarySystems->m_massFlow1,
11152 17826 : state.dataUnitarySystems->m_runTimeFraction1,
11153 17826 : state.dataUnitarySystems->m_massFlow2,
11154 17826 : state.dataUnitarySystems->m_runTimeFraction2,
11155 : _);
11156 :
11157 17826 : if (this->m_CoolCoilExists) {
11158 17826 : this->calcUnitaryCoolingSystem(
11159 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11160 : }
11161 17826 : if (this->m_HeatCoilExists) {
11162 17826 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11163 17826 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11164 0 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11165 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11166 0 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11167 0 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11168 0 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11169 0 : this->calcUnitaryHeatingSystem(
11170 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11171 : }
11172 : }
11173 : }
11174 :
11175 : } else {
11176 :
11177 73 : if (this->m_HeatCoilExists) {
11178 73 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11179 73 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11180 5 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11181 5 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11182 5 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11183 5 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11184 5 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11185 5 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11186 : }
11187 : }
11188 73 : if (this->m_CoolCoilExists) {
11189 0 : this->calcUnitaryCoolingSystem(
11190 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11191 : }
11192 :
11193 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11194 73 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11195 0 : state.dataFans->fans(this->m_FanIndex)
11196 0 : ->simulate(state,
11197 : FirstHVACIteration,
11198 0 : state.dataUnitarySystems->FanSpeedRatio,
11199 : _, // Pressure rise
11200 : _, // Flow fraction
11201 0 : state.dataUnitarySystems->m_massFlow1,
11202 0 : state.dataUnitarySystems->m_runTimeFraction1,
11203 0 : state.dataUnitarySystems->m_massFlow2,
11204 0 : state.dataUnitarySystems->m_runTimeFraction2,
11205 : _);
11206 :
11207 0 : if (this->m_HeatCoilExists) {
11208 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11209 0 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11210 0 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11211 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11212 0 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11213 0 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11214 0 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11215 0 : this->calcUnitaryHeatingSystem(
11216 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11217 : }
11218 : }
11219 0 : if (this->m_CoolCoilExists) {
11220 0 : this->calcUnitaryCoolingSystem(
11221 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11222 : }
11223 : }
11224 : }
11225 :
11226 66511 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
11227 4 : state.dataFans->fans(this->m_FanIndex)
11228 12 : ->simulate(state,
11229 : FirstHVACIteration,
11230 4 : state.dataUnitarySystems->FanSpeedRatio,
11231 : _, // Pressure rise
11232 : _, // Flow fraction
11233 4 : state.dataUnitarySystems->m_massFlow1,
11234 4 : state.dataUnitarySystems->m_runTimeFraction1,
11235 4 : state.dataUnitarySystems->m_massFlow2,
11236 4 : state.dataUnitarySystems->m_runTimeFraction2,
11237 : _);
11238 : }
11239 66511 : if (this->m_SuppCoilExists) {
11240 66077 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, SuppCoilLoad);
11241 66078 : if ((state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp) && this->m_SuppHeatPartLoadFrac > 0.0 &&
11242 1 : !this->m_SimASHRAEModel) {
11243 : // EMS override will ignore this recalculation.
11244 1 : Real64 MDotAir = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).MassFlowRate;
11245 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).HumRat +
11246 1 : state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).HumRat));
11247 1 : Real64 HCDeltaT = max(0.0, this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).Temp);
11248 1 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11249 1 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, MaxHeatCoilLoad);
11250 1 : SuppCoilLoad = MaxHeatCoilLoad;
11251 : }
11252 : }
11253 :
11254 : // If there is a supply side air terminal mixer, calculate its output
11255 66511 : if (this->ATMixerExists) {
11256 65899 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11257 63 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11258 : }
11259 : }
11260 :
11261 66511 : calculateCapacity(state, SensOutput, LatOutput);
11262 66511 : }
11263 :
11264 48 : void UnitarySys::calcMultiStageSuppCoilStageByLoad(EnergyPlusData &state, Real64 const SuppHeatLoad, bool const FirstHVACIteration)
11265 : {
11266 48 : if (SuppHeatLoad <= 0.0) {
11267 43 : this->m_SuppHeatPartLoadFrac = 0.0;
11268 43 : this->m_SuppHeatingSpeedRatio = 0.0;
11269 43 : this->m_SuppHeatingCycRatio = 0.0;
11270 43 : return;
11271 : }
11272 5 : constexpr bool SuppHeatingCoilFlag(true);
11273 5 : Real64 PartLoadFrac = 0.0;
11274 5 : Real64 SpeedRatio = 0.0;
11275 5 : Real64 CycRatio = 0.0;
11276 5 : std::string CompName = this->m_SuppHeatCoilName;
11277 5 : int CompIndex = this->m_SuppHeatCoilIndex;
11278 5 : HVAC::FanOp fanOp = this->m_FanOpMode;
11279 5 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
11280 5 : int SpeedNum = 0;
11281 : // Get full load result
11282 5 : PartLoadFrac = 1.0;
11283 5 : CycRatio = 1.0;
11284 5 : SpeedRatio = 1.0;
11285 5 : int SolFla = 0;
11286 :
11287 : // SUBROUTINE PARAMETER DEFINITIONS:
11288 5 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11289 5 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
11290 :
11291 8 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
11292 8 : this->m_SuppHeatingSpeedNum = SpeedNum;
11293 8 : HeatingCoils::SimulateHeatingCoilComponents(state,
11294 : CompName,
11295 : FirstHVACIteration,
11296 : SuppHeatLoad,
11297 : CompIndex,
11298 : QCoilActual,
11299 : SuppHeatingCoilFlag,
11300 : fanOp,
11301 : PartLoadFrac,
11302 : SpeedNum,
11303 : SpeedRatio);
11304 8 : if (QCoilActual > SuppHeatLoad) break;
11305 : }
11306 5 : if (QCoilActual < SuppHeatLoad) {
11307 0 : this->m_SuppHeatPartLoadFrac = 1.0;
11308 0 : this->m_SuppHeatingSpeedRatio = 1.0;
11309 0 : this->m_SuppHeatingCycRatio = 1.0;
11310 0 : this->m_SuppHeatingSpeedNum = this->m_NumOfSpeedSuppHeating;
11311 0 : return;
11312 : } else {
11313 :
11314 5 : if (this->m_SuppHeatingSpeedNum > 1.0) {
11315 9 : auto f = [&state, this, CycRatio, fanOp, SuppHeatLoad](Real64 const SpeedRatio) {
11316 : Real64 QActual;
11317 9 : int CoilIndex = this->m_SuppHeatCoilIndex;
11318 9 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11319 9 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11320 9 : return SuppHeatLoad - QActual;
11321 3 : };
11322 :
11323 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
11324 3 : this->m_SuppHeatingCycRatio = CycRatio;
11325 3 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11326 3 : this->m_SuppHeatPartLoadFrac = SpeedRatio;
11327 3 : PartLoadFrac = SpeedRatio;
11328 : } else {
11329 2 : SpeedRatio = 0.0;
11330 2 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11331 6 : auto f = [&state, this, SpeedRatio, fanOp, SuppHeatLoad](Real64 const CycRatio) {
11332 : Real64 QActual;
11333 6 : int CoilIndex = this->m_SuppHeatCoilIndex;
11334 6 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11335 6 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11336 6 : return SuppHeatLoad - QActual;
11337 2 : };
11338 :
11339 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
11340 2 : this->m_SuppHeatingCycRatio = CycRatio;
11341 2 : this->m_SuppHeatPartLoadFrac = CycRatio;
11342 2 : PartLoadFrac = CycRatio;
11343 : }
11344 : }
11345 5 : }
11346 :
11347 131827 : void UnitarySys::calculateCapacity(EnergyPlusData &state, Real64 &SensOutput, Real64 &LatOutput)
11348 : {
11349 :
11350 : // Check delta T (outlet to reference temp), IF positive use reference HumRat ELSE outlet humrat to calculate
11351 : // sensible capacity as MdotDeltaH at constant humidity ratio
11352 131827 : int OutletNode = this->AirOutNode;
11353 131827 : Real64 AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
11354 131827 : Real64 RefTemp = 0.0;
11355 131827 : Real64 RefHumRat = 0.0;
11356 131827 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11357 65316 : RefTemp = state.dataLoopNodes->Node(this->AirInNode).Temp;
11358 65316 : RefHumRat = state.dataLoopNodes->Node(this->AirInNode).HumRat;
11359 : } else {
11360 66511 : RefTemp = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp;
11361 66511 : RefHumRat = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat;
11362 : }
11363 131827 : Real64 SensibleOutput(0.0); // sensible output rate, {W}
11364 131827 : Real64 LatentOutput(0.0); // latent output rate, {W}
11365 131827 : Real64 TotalOutput(0.0); // total output rate, {W}
11366 : // calculate sensible load met
11367 131827 : if (this->ATMixerExists) {
11368 65899 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11369 : // Air terminal supply side mixer
11370 63 : int ATMixOutNode = this->ATMixerOutNode;
11371 63 : CalcZoneSensibleLatentOutput(state.dataLoopNodes->Node(ATMixOutNode).MassFlowRate,
11372 63 : state.dataLoopNodes->Node(ATMixOutNode).Temp,
11373 63 : state.dataLoopNodes->Node(ATMixOutNode).HumRat,
11374 : RefTemp,
11375 : RefHumRat,
11376 : SensibleOutput,
11377 : LatentOutput,
11378 : TotalOutput);
11379 63 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11380 63 : if (this->m_Humidistat) {
11381 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11382 : } else {
11383 63 : LatOutput = 0.0;
11384 : }
11385 : } else {
11386 : // Air terminal inlet side mixer
11387 131672 : CalcZoneSensibleLatentOutput(AirMassFlow,
11388 65836 : state.dataLoopNodes->Node(OutletNode).Temp,
11389 65836 : state.dataLoopNodes->Node(OutletNode).HumRat,
11390 : RefTemp,
11391 : RefHumRat,
11392 : SensibleOutput,
11393 : LatentOutput,
11394 : TotalOutput);
11395 65836 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11396 65836 : if (this->m_Humidistat) {
11397 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11398 : } else {
11399 65836 : LatOutput = 0.0;
11400 : }
11401 : }
11402 : } else {
11403 : // Calculate sensible load met
11404 131856 : CalcZoneSensibleLatentOutput(AirMassFlow,
11405 65928 : state.dataLoopNodes->Node(OutletNode).Temp,
11406 65928 : state.dataLoopNodes->Node(OutletNode).HumRat,
11407 : RefTemp,
11408 : RefHumRat,
11409 : SensibleOutput,
11410 : LatentOutput,
11411 : TotalOutput);
11412 65928 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11413 65928 : if (this->m_Humidistat) {
11414 104 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11415 : } else {
11416 65824 : LatOutput = 0.0;
11417 : }
11418 : }
11419 131827 : this->m_SensibleLoadMet = SensOutput;
11420 131827 : this->m_LatentLoadMet = LatOutput;
11421 131827 : }
11422 :
11423 149586 : void UnitarySys::calcUnitaryCoolingSystem(EnergyPlusData &state,
11424 : int const AirLoopNum, // index to air loop
11425 : bool const FirstHVACIteration, // True when first HVAC iteration
11426 : Real64 const PartLoadRatio, // coil operating part-load ratio
11427 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11428 : Real64 const OnOffAirFlowRatio,
11429 : Real64 const CoilCoolHeatRat, // ratio of cooling to heating PLR for cycling fan RH control
11430 : bool const HXUnitOn // Flag to control HX for HXAssisted Cooling Coil
11431 : )
11432 : {
11433 :
11434 : // SUBROUTINE INFORMATION:
11435 : // AUTHOR Richard Raustad, FSEC
11436 : // DATE WRITTEN February 2013
11437 :
11438 : // PURPOSE OF THIS SUBROUTINE:
11439 : // This subroutine manages unitary cooling system component simulation.
11440 :
11441 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11442 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11443 : Real64 mdot; // water side flow rate (kg/s)
11444 : Real64 QActual; // actual coil output (W)
11445 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11446 :
11447 : // Simulate the coil component
11448 149586 : std::string CompName = this->m_CoolingCoilName;
11449 149586 : int CompIndex = this->m_CoolingCoilIndex;
11450 149586 : Real64 CoilPLR = 1.0;
11451 149586 : if (this->m_CondenserNodeNum != 0) {
11452 24867 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11453 : // IF node is not connected to anything, pressure = default, use weather data
11454 24867 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11455 91 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11456 : } else {
11457 24776 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11458 : }
11459 : } else {
11460 124719 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11461 : }
11462 :
11463 149586 : switch (this->m_CoolingCoilType_Num) {
11464 59945 : case HVAC::CoilDX_CoolingSingleSpeed: { // Coil:Cooling:DX:SingleSpeed
11465 59945 : DXCoils::SimDXCoil(state,
11466 : blankString,
11467 : CompressorOn,
11468 : FirstHVACIteration,
11469 : CompIndex,
11470 : this->m_FanOpMode,
11471 : PartLoadRatio,
11472 : OnOffAirFlowRatio,
11473 : CoilCoolHeatRat);
11474 59945 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11475 59945 : } break;
11476 91 : case HVAC::CoilDX_Cooling: { // CoilCoolingDX
11477 91 : bool const singleMode = (this->m_SingleMode == 1);
11478 91 : CoilPLR = 0.0;
11479 91 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11480 0 : if (CompressorOn == HVAC::CompressorOp::On) {
11481 0 : CoilPLR = (this->m_CoolingSpeedNum > 1) ? m_CoolingSpeedRatio : PartLoadRatio;
11482 : }
11483 : } else {
11484 91 : if (this->m_EMSOverrideCoilSpeedNumOn) {
11485 6 : CoilPLR = this->m_CoolingSpeedRatio;
11486 : } else {
11487 85 : if (state.dataUnitarySystems->CoolingLoad) {
11488 85 : if (CompressorOn == HVAC::CompressorOp::Off) {
11489 21 : if (this->m_CoolingSpeedNum > 1) // NOTE: Cooling speed 0 should behave the same as speed 1, but doesn't, and must be
11490 : // allowed to pass into the simulation code
11491 0 : this->m_CoolingSpeedNum = 1; // Bypass mixed-speed calculations in called functions
11492 : } else {
11493 64 : if (singleMode) {
11494 0 : CoilPLR = (this->m_CoolingSpeedNum == 1)
11495 0 : ? PartLoadRatio
11496 : : 1.0; // singleMode allows cycling, but not part load operation at higher speeds
11497 : } else {
11498 64 : CoilPLR = PartLoadRatio;
11499 : }
11500 : }
11501 : }
11502 : }
11503 : }
11504 :
11505 91 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
11506 91 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
11507 50 : coilMode = HVAC::CoilMode::SubcoolReheat;
11508 41 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
11509 0 : coilMode = HVAC::CoilMode::Enhanced;
11510 : }
11511 :
11512 91 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
11513 : state, coilMode, this->m_CoolingSpeedNum, CoilPLR, this->m_FanOpMode, singleMode, this->CoilSHR);
11514 :
11515 91 : if (this->m_CoolingSpeedNum > 1) {
11516 20 : if (this->m_SingleMode == 0) {
11517 20 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11518 : } else {
11519 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11520 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11521 0 : this->m_CoolingSpeedRatio = 1.0;
11522 : }
11523 : } else {
11524 71 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11525 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11526 71 : this->m_CoolingSpeedRatio = 0.0;
11527 : }
11528 91 : } break;
11529 55 : case HVAC::CoilDX_CoolingHXAssisted:
11530 : case HVAC::CoilWater_CoolingHXAssisted: {
11531 55 : if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
11532 : mdot =
11533 0 : min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxCoolCoilFluidFlow * PartLoadRatio);
11534 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11535 : }
11536 110 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
11537 : blankString,
11538 : FirstHVACIteration,
11539 : CompressorOn,
11540 : PartLoadRatio,
11541 : CompIndex,
11542 : this->m_FanOpMode,
11543 : HXUnitOn,
11544 : OnOffAirFlowRatio,
11545 55 : state.dataUnitarySystems->economizerFlag,
11546 : _,
11547 55 : this->m_DehumidificationMode,
11548 55 : 0.0); // this->CoilSHR);
11549 55 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
11550 55 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11551 : }
11552 55 : } break;
11553 5665 : case HVAC::CoilDX_CoolingTwoSpeed: { // Coil:Cooling:DX:TwoSpeed
11554 : // formerly (v3 and beyond)COIL:DX:MULTISPEED:COOLINGEMPIRICAL
11555 5665 : DXCoils::SimDXCoilMultiSpeed(state, blankString, this->m_CoolingSpeedRatio, this->m_CoolingCycRatio, CompIndex);
11556 5665 : if (this->m_CoolingSpeedRatio > 0.0) {
11557 2547 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingSpeedRatio : 0.0;
11558 : } else {
11559 3118 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11560 : }
11561 5665 : } break;
11562 120 : case HVAC::CoilDX_MultiSpeedCooling: { // Coil:Cooling:DX:Multispeed
11563 120 : if (OutsideDryBulbTemp > this->m_MinOATCompressorCooling) {
11564 120 : DXCoils::SimDXCoilMultiSpeed(state,
11565 : CompName,
11566 : this->m_CoolingSpeedRatio,
11567 : this->m_CoolingCycRatio,
11568 : CompIndex,
11569 120 : this->m_CoolingSpeedNum,
11570 120 : this->m_FanOpMode,
11571 : CompressorOn,
11572 120 : this->m_SingleMode);
11573 120 : if (this->m_CoolingSpeedNum > 1) {
11574 18 : if (this->m_SingleMode == 0) {
11575 6 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11576 : } else {
11577 12 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11578 : }
11579 : } else {
11580 102 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11581 : }
11582 : } else {
11583 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 0.0, CompIndex, this->m_CoolingSpeedNum, this->m_FanOpMode, CompressorOn);
11584 0 : this->m_CoolCompPartLoadRatio = 0.0;
11585 : }
11586 120 : } break;
11587 0 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
11588 : // formerly (v3 and beyond) COIL:DX:MULTIMODE:COOLINGEMPIRICAL
11589 0 : DXCoils::SimDXCoilMultiMode(
11590 : state, CompName, CompressorOn, FirstHVACIteration, PartLoadRatio, this->m_DehumidificationMode, CompIndex, this->m_FanOpMode);
11591 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11592 0 : } break;
11593 0 : case HVAC::Coil_UserDefined: {
11594 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11595 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
11596 :
11597 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
11598 0 : } break;
11599 134 : case HVAC::Coil_CoolingWater:
11600 : case HVAC::Coil_CoolingWaterDetailed: {
11601 134 : if (this->CoolCoilWaterFlowRatio == 0.0) {
11602 112 : mdot = this->MaxCoolCoilFluidFlow * PartLoadRatio;
11603 : } else {
11604 22 : mdot = this->CoolCoilWaterFlowRatio * this->MaxCoolCoilFluidFlow;
11605 : }
11606 134 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11607 402 : WaterCoils::SimulateWaterCoilComponents(
11608 268 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11609 134 : } break;
11610 33689 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
11611 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
11612 33689 : if (this->m_CoolingSpeedNum > 1) {
11613 8715 : CoilPLR = 1.0;
11614 : } else {
11615 24974 : CoilPLR = PartLoadRatio;
11616 : }
11617 33689 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11618 : CompName,
11619 : CompIndex,
11620 : this->m_FanOpMode,
11621 : CompressorOn,
11622 : CoilPLR,
11623 : this->m_CoolingSpeedNum,
11624 : this->m_CoolingSpeedRatio,
11625 : this->m_CoolingCoilSensDemand,
11626 : this->m_CoolingCoilLatentDemand,
11627 : OnOffAirFlowRatio);
11628 33689 : if (this->m_CoolingSpeedNum > 1) {
11629 8715 : this->m_CoolCompPartLoadRatio = 1.0;
11630 : } else {
11631 24974 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11632 : }
11633 33689 : } break;
11634 49887 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
11635 :
11636 49887 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11637 : blankString,
11638 49887 : this->m_CoolingCoilIndex,
11639 : this->m_CoolingCoilSensDemand,
11640 : this->m_CoolingCoilLatentDemand,
11641 : this->m_FanOpMode,
11642 : CompressorOn,
11643 : PartLoadRatio,
11644 : FirstHVACIteration);
11645 49887 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11646 49887 : } break;
11647 0 : case HVAC::Coil_CoolingWaterToAirHP: {
11648 :
11649 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
11650 : blankString,
11651 0 : this->m_CoolingCoilIndex,
11652 : this->MaxCoolAirMassFlow,
11653 : this->m_FanOpMode,
11654 : FirstHVACIteration,
11655 0 : this->m_InitHeatPump,
11656 : this->m_CoolingCoilSensDemand,
11657 : this->m_CoolingCoilLatentDemand,
11658 : CompressorOn,
11659 : PartLoadRatio);
11660 :
11661 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11662 0 : } break;
11663 0 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
11664 0 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, PartLoadRatio);
11665 0 : } break;
11666 0 : default:
11667 0 : break;
11668 : }
11669 :
11670 149586 : this->m_CoolingPartLoadFrac = PartLoadRatio;
11671 149586 : }
11672 :
11673 84403 : void UnitarySys::calcUnitaryHeatingSystem(EnergyPlusData &state,
11674 : int const AirLoopNum, // index to air loop
11675 : bool const FirstHVACIteration, // True when first HVAC iteration
11676 : Real64 const PartLoadRatio, // coil operating part-load ratio
11677 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11678 : Real64 const OnOffAirFlowRatio, // ratio of on to off flow rate
11679 : Real64 HeatCoilLoad // adjusted heating coil load if outlet temp exceeds max (W)
11680 : )
11681 : {
11682 :
11683 : // SUBROUTINE INFORMATION:
11684 : // AUTHOR Richard Raustad, FSEC
11685 : // DATE WRITTEN February 2013
11686 :
11687 : // PURPOSE OF THIS SUBROUTINE:
11688 : // This subroutine manages unitary heating system component simulation.
11689 :
11690 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11691 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11692 : Real64 mdot; // water side flow rate (kg/s)
11693 : Real64 QActual; // actual output of coil (W)
11694 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11695 :
11696 84403 : std::string CompName = this->m_HeatingCoilName;
11697 84403 : Real64 dummy = 0.0;
11698 84403 : Real64 HeatPLR = 1.0;
11699 84403 : if (this->m_CondenserNodeNum != 0) {
11700 90 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11701 : // IF node is not connected to anything, pressure = default, use weather data
11702 90 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11703 90 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11704 : } else {
11705 0 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11706 : }
11707 : } else {
11708 84313 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11709 : }
11710 :
11711 84403 : switch (this->m_HeatingCoilType_Num) {
11712 53 : case HVAC::CoilDX_HeatingEmpirical: { // COIL:HEATING:DX:SINGLESPEED
11713 106 : DXCoils::SimDXCoil(
11714 53 : state, CompName, CompressorOn, FirstHVACIteration, this->m_HeatingCoilIndex, this->m_FanOpMode, PartLoadRatio, OnOffAirFlowRatio);
11715 53 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11716 53 : } break;
11717 0 : case HVAC::Coil_UserDefined: {
11718 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11719 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
11720 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_HeatingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
11721 0 : } break;
11722 472 : case HVAC::Coil_HeatingGasOrOtherFuel:
11723 : case HVAC::Coil_HeatingElectric: {
11724 472 : HeatCoilLoad = PartLoadRatio * m_DesignHeatingCapacity;
11725 1888 : HeatingCoils::SimulateHeatingCoilComponents(
11726 1416 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
11727 472 : } break;
11728 2 : case HVAC::Coil_HeatingDesuperheater: {
11729 8 : HeatingCoils::SimulateHeatingCoilComponents(
11730 6 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
11731 :
11732 2 : } break;
11733 83 : case HVAC::CoilDX_MultiSpeedHeating: {
11734 83 : if (OutsideDryBulbTemp > this->m_MinOATCompressorHeating) {
11735 83 : DXCoils::SimDXCoilMultiSpeed(state,
11736 : CompName,
11737 : this->m_HeatingSpeedRatio,
11738 : this->m_HeatingCycRatio,
11739 83 : this->m_HeatingCoilIndex,
11740 83 : this->m_HeatingSpeedNum,
11741 83 : this->m_FanOpMode,
11742 : CompressorOn,
11743 83 : this->m_SingleMode);
11744 83 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11745 : } else {
11746 0 : DXCoils::SimDXCoilMultiSpeed(
11747 0 : state, CompName, 0.0, 0.0, this->m_HeatingCoilIndex, this->m_HeatingSpeedNum, this->m_FanOpMode, CompressorOn);
11748 0 : this->m_HeatCompPartLoadRatio = 0.0;
11749 : }
11750 83 : } break;
11751 140 : case HVAC::Coil_HeatingElectric_MultiStage:
11752 : case HVAC::Coil_HeatingGas_MultiStage: {
11753 560 : HeatingCoils::SimulateHeatingCoilComponents(state,
11754 : CompName,
11755 : FirstHVACIteration,
11756 : _,
11757 280 : 0,
11758 : _,
11759 : _,
11760 140 : this->m_FanOpMode,
11761 : PartLoadRatio,
11762 140 : this->m_HeatingSpeedNum,
11763 140 : this->m_HeatingSpeedRatio);
11764 : // This doesn't look right when it was at higher speed
11765 : // this->m_HeatingCycRatio = PartLoadRatio;
11766 140 : } break;
11767 124 : case HVAC::Coil_HeatingWater: {
11768 124 : if (this->HeatCoilWaterFlowRatio == 0.0) {
11769 73 : mdot = this->MaxHeatCoilFluidFlow * PartLoadRatio;
11770 : } else {
11771 51 : mdot = this->HeatCoilWaterFlowRatio * this->MaxHeatCoilFluidFlow;
11772 : }
11773 124 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
11774 372 : WaterCoils::SimulateWaterCoilComponents(
11775 248 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11776 124 : } break;
11777 0 : case HVAC::Coil_HeatingSteam: {
11778 : // this same CALL is made in the steam coil calc routine
11779 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxHeatCoilFluidFlow * PartLoadRatio);
11780 0 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
11781 : // tried this to resolve the PackagedTerminalAirConditioner steam spike issue, no help, but this is the correct way to do this
11782 0 : PlantUtilities::SetComponentFlowRate(
11783 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
11784 : } else {
11785 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
11786 : }
11787 0 : SteamCoils::SimulateSteamCoilComponents(state,
11788 : CompName,
11789 : FirstHVACIteration,
11790 0 : this->m_HeatingCoilIndex,
11791 0 : this->m_DesignHeatingCapacity * PartLoadRatio,
11792 : _,
11793 0 : this->m_FanOpMode,
11794 : PartLoadRatio);
11795 0 : } break;
11796 33642 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
11797 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
11798 33642 : if (this->m_HeatingSpeedNum > 1) {
11799 16258 : HeatPLR = 1.0;
11800 16258 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
11801 16256 : this->m_HeatingSpeedRatio = PartLoadRatio;
11802 : }
11803 : } else {
11804 17384 : HeatPLR = PartLoadRatio;
11805 : }
11806 :
11807 33642 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11808 : CompName,
11809 33642 : this->m_HeatingCoilIndex,
11810 : this->m_FanOpMode,
11811 : CompressorOn,
11812 : HeatPLR,
11813 : this->m_HeatingSpeedNum,
11814 : this->m_HeatingSpeedRatio,
11815 : this->m_HeatingCoilSensDemand,
11816 : dummy,
11817 : OnOffAirFlowRatio);
11818 33642 : if (this->m_HeatingSpeedNum > 1) {
11819 16258 : this->m_HeatCompPartLoadRatio = 1.0;
11820 : } else {
11821 17384 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11822 : }
11823 33642 : } break;
11824 49887 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
11825 :
11826 49887 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11827 : blankString,
11828 49887 : this->m_HeatingCoilIndex,
11829 : this->m_HeatingCoilSensDemand,
11830 : dummy,
11831 : this->m_FanOpMode,
11832 : CompressorOn,
11833 : PartLoadRatio,
11834 : FirstHVACIteration);
11835 49887 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11836 49887 : } break;
11837 0 : case HVAC::Coil_HeatingWaterToAirHP: {
11838 :
11839 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
11840 : blankString,
11841 0 : this->m_HeatingCoilIndex,
11842 : this->MaxHeatAirMassFlow,
11843 : this->m_FanOpMode,
11844 : FirstHVACIteration,
11845 0 : this->m_InitHeatPump,
11846 : this->m_HeatingCoilSensDemand,
11847 : dummy,
11848 : CompressorOn,
11849 : PartLoadRatio);
11850 0 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11851 0 : } break;
11852 0 : default: {
11853 0 : ShowFatalError(
11854 0 : state, format("CalcUnitaryHeatingSystem: Invalid Unitary System coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
11855 0 : } break;
11856 : }
11857 :
11858 84403 : this->m_HeatingPartLoadFrac = PartLoadRatio;
11859 84403 : }
11860 :
11861 66078 : void UnitarySys::calcUnitarySuppHeatingSystem(EnergyPlusData &state,
11862 : bool const FirstHVACIteration, // True when first HVAC iteration
11863 : Real64 const SuppCoilLoad // adjusted supp coil load when outlet temp exceeds max (W)
11864 : )
11865 : {
11866 :
11867 : // SUBROUTINE INFORMATION:
11868 : // AUTHOR Richard Raustad, FSEC
11869 : // DATE WRITTEN February 2013
11870 :
11871 : // PURPOSE OF THIS SUBROUTINE:
11872 : // This subroutine manages supplemental heater simulation.
11873 :
11874 : // SUBROUTINE PARAMETER DEFINITIONS:
11875 66078 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11876 66078 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
11877 :
11878 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11879 : // std::string CompName; // Name of Unitary System object
11880 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
11881 : Real64 QActual; // actual coil output (W)
11882 : Real64 mdot; // water coil water mass flow rate (kg/s)
11883 66078 : std::vector<Real64> Par; // Parameter array passed to solver
11884 : Real64 PartLoadFrac; // temporary PLR variable
11885 :
11886 66078 : Par.resize(5);
11887 : // work is needed to figure out how to adjust other coil types if outlet temp exceeds maximum
11888 : // this works for gas and electric heating coils
11889 66078 : std::string CompName = this->m_SuppHeatCoilName;
11890 88806 : if (state.dataEnvrn->OutDryBulbTemp <= this->m_MaxOATSuppHeat ||
11891 22728 : (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolingPartLoadFrac > 0.0)) {
11892 43385 : SuppHeatCoilLoad = SuppCoilLoad;
11893 : //} else {
11894 : // SuppHeatCoilLoad = this->m_DesignSuppHeatingCapacity * PartLoadRatio;
11895 : //}
11896 : } else {
11897 22693 : SuppHeatCoilLoad = 0.0;
11898 : }
11899 66078 : switch (this->m_SuppHeatCoilType_Num) {
11900 66078 : case HVAC::Coil_HeatingGasOrOtherFuel:
11901 : case HVAC::Coil_HeatingElectric:
11902 : case HVAC::Coil_HeatingElectric_MultiStage: {
11903 66078 : switch (this->m_ControlType) {
11904 0 : case UnitarySysCtrlType::Setpoint: {
11905 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
11906 : CompName,
11907 : FirstHVACIteration,
11908 : SuppHeatCoilLoad,
11909 0 : this->m_SuppHeatCoilIndex,
11910 : _,
11911 0 : true,
11912 0 : this->m_FanOpMode,
11913 0 : this->m_SuppHeatPartLoadFrac,
11914 0 : this->m_SuppHeatingSpeedNum,
11915 0 : this->m_SuppHeatingSpeedRatio);
11916 0 : } break;
11917 66078 : default: {
11918 66078 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
11919 16 : if (SuppHeatCoilLoad > 0.0) {
11920 4 : this->setEMSSuppCoilStagePLR(state);
11921 : } else {
11922 12 : this->m_SuppHeatingSpeedRatio = 0.0;
11923 12 : this->m_SuppHeatingCycRatio = 0.0;
11924 12 : this->m_SuppHeatPartLoadFrac = 0.0;
11925 : }
11926 : } else {
11927 66062 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
11928 48 : this->calcMultiStageSuppCoilStageByLoad(state, SuppHeatCoilLoad, FirstHVACIteration);
11929 : }
11930 : }
11931 198234 : HeatingCoils::SimulateHeatingCoilComponents(state,
11932 : CompName,
11933 : FirstHVACIteration,
11934 : SuppHeatCoilLoad,
11935 66078 : this->m_SuppHeatCoilIndex,
11936 : _,
11937 132156 : true,
11938 66078 : this->m_FanOpMode,
11939 66078 : this->m_SuppHeatPartLoadFrac,
11940 66078 : this->m_SuppHeatingSpeedNum,
11941 66078 : this->m_SuppHeatingSpeedRatio);
11942 66078 : } break;
11943 : }
11944 66078 : } break;
11945 0 : case HVAC::Coil_HeatingDesuperheater: {
11946 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
11947 : CompName,
11948 : FirstHVACIteration,
11949 : SuppHeatCoilLoad,
11950 0 : this->m_SuppHeatCoilIndex,
11951 : _,
11952 0 : true,
11953 0 : this->m_FanOpMode,
11954 0 : this->m_SuppHeatPartLoadFrac);
11955 0 : } break;
11956 0 : case HVAC::Coil_HeatingWater: {
11957 : // see if HW coil has enough capacity to meet the load
11958 0 : if (SuppHeatCoilLoad > 0.0) {
11959 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->m_MaxSuppCoilFluidFlow);
11960 : } else {
11961 0 : mdot = 0.0;
11962 : }
11963 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
11964 : // simulate water coil to find operating capacity
11965 0 : WaterCoils::SimulateWaterCoilComponents(state,
11966 : this->m_SuppHeatCoilName,
11967 : FirstHVACIteration,
11968 0 : this->m_SuppHeatCoilIndex,
11969 : QActual,
11970 0 : this->m_FanOpMode,
11971 0 : this->m_SuppHeatPartLoadFrac);
11972 0 : if (QActual > SuppHeatCoilLoad) {
11973 0 : auto f = [&state, this, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
11974 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
11975 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
11976 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
11977 0 : WaterCoils::SimulateWaterCoilComponents(
11978 0 : state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex, 0.0, this->m_FanOpMode, PartLoadFrac);
11979 0 : return SuppHeatCoilLoad;
11980 0 : };
11981 : int SolFla; // Flag of solver, num iterations if >0, else error index
11982 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
11983 0 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
11984 : } else {
11985 0 : this->m_SuppHeatPartLoadFrac = (SuppHeatCoilLoad > 0.0) ? 1.0 : 0.0;
11986 : }
11987 0 : } break;
11988 0 : case HVAC::Coil_HeatingSteam: {
11989 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
11990 0 : this->m_MaxSuppCoilFluidFlow * this->m_SuppHeatPartLoadFrac);
11991 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
11992 0 : SteamCoils::SimulateSteamCoilComponents(
11993 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, SuppHeatCoilLoad, _, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
11994 0 : } break;
11995 0 : default:
11996 0 : break;
11997 : }
11998 66078 : }
11999 :
12000 6 : void UnitarySys::setEMSSuppCoilStagePLR(EnergyPlusData &state)
12001 : {
12002 6 : bool useMaxedSpeed = false;
12003 6 : int SpeedNumEMS = ceil(this->m_EMSOverrideSuppCoilSpeedNumValue);
12004 6 : if (SpeedNumEMS > this->m_NumOfSpeedSuppHeating) {
12005 0 : SpeedNumEMS = this->m_NumOfSpeedSuppHeating;
12006 0 : useMaxedSpeed = true;
12007 : }
12008 6 : this->m_SuppHeatingSpeedNum = SpeedNumEMS;
12009 6 : if (useMaxedSpeed) {
12010 0 : this->m_CoilSpeedErrIdx++;
12011 0 : ShowRecurringWarningErrorAtEnd(state,
12012 0 : format("Wrong coil speed EMS override value, for unit=\"{}\". Exceeding maximum coil speed "
12013 : "level. Speed level is set to the maximum coil speed level allowed.",
12014 0 : this->m_SuppHeatCoilName),
12015 0 : this->m_CoilSpeedErrIdx,
12016 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12017 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12018 : _,
12019 : "",
12020 : "");
12021 : }
12022 6 : if (this->m_SuppHeatingSpeedNum == 1) {
12023 2 : this->m_SuppHeatingSpeedRatio = 0.0;
12024 2 : this->m_SuppHeatingCycRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12025 2 : if (useMaxedSpeed || this->m_SuppHeatingCycRatio == 0) {
12026 0 : this->m_SuppHeatingCycRatio = 1;
12027 : }
12028 2 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingCycRatio;
12029 : } else {
12030 4 : this->m_SuppHeatingCycRatio = 1.0;
12031 4 : this->m_SuppHeatingSpeedRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12032 4 : if (useMaxedSpeed || this->m_SuppHeatingSpeedRatio == 0) {
12033 1 : this->m_SuppHeatingSpeedRatio = 1;
12034 : }
12035 4 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingSpeedRatio;
12036 : }
12037 6 : }
12038 :
12039 65306 : void UnitarySys::controlCoolingSystemToSP(EnergyPlusData &state,
12040 : int const AirLoopNum, // index to air loop
12041 : bool const FirstHVACIteration, // First HVAC iteration flag
12042 : bool &HXUnitOn, // flag to enable heat exchanger heat recovery
12043 : HVAC::CompressorOp &compressorOp // compressor on/off control
12044 : )
12045 : {
12046 : // SUBROUTINE INFORMATION:
12047 : // AUTHOR Richard Raustad, FSEC
12048 : // DATE WRITTEN February 2013
12049 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
12050 :
12051 : // PURPOSE OF THIS SUBROUTINE:
12052 : // Simulate the coil object at the required PLR.
12053 :
12054 : // METHODOLOGY EMPLOYED:
12055 : // Calculate operating PLR and adjust speed when using multispeed coils.
12056 : // Meet moisture load if required to do so.
12057 :
12058 : // SUBROUTINE PARAMETER DEFINITIONS:
12059 65306 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12060 65306 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12061 65306 : Real64 constexpr HumRatAcc(1.e-6); // Accuracy of solver result
12062 :
12063 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12064 : Real64 ReqOutput; // Sensible capacity (outlet - inlet) required to meet load or setpoint temperature
12065 : // for variable speed or 2 speed compressors
12066 : Real64 OutletTempDXCoil; // Actual outlet temperature of the DX cooling coil
12067 : Real64 OutletHumRatLS; // Actual outlet humrat of the variable speed DX cooling coil at low speed
12068 : Real64 OutletHumRatHS; // Actual outlet humrat of the variable speed DX cooling coil at high speed
12069 : Real64 OutletHumRatDXCoil; // Actual outlet humidity ratio of the DX cooling coil
12070 : Real64 TempMinPLR; // Used to find latent PLR when max iterations exceeded
12071 : Real64 TempMaxPLR; // Used to find latent PLR when max iterations exceeded
12072 : Real64 TempOutletTempDXCoil; // Used to find latent PLR when max iterations exceeded
12073 : Real64 OutletTemp;
12074 : Real64 OutdoorDryBulb; // local variable for OutDryBulbTemp
12075 : Real64 maxPartLoadFrac; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
12076 :
12077 : // Set local variables
12078 : // Retrieve the load on the controlled zone
12079 65306 : int OutletNode = this->CoolCoilOutletNodeNum;
12080 65306 : int InletNode = this->CoolCoilInletNodeNum;
12081 65306 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
12082 65306 : Real64 DesOutHumRat = this->m_DesiredOutletHumRat;
12083 65306 : int CoilType_Num = this->m_CoolingCoilType_Num;
12084 65306 : Real64 LoopDXCoilMaxRTFSave = 0.0;
12085 65306 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
12086 0 : this->m_sysType != SysType::PackagedWSHP) {
12087 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
12088 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
12089 : }
12090 :
12091 65306 : std::string CompName = this->m_CoolingCoilName;
12092 65306 : HVAC::FanOp fanOp = this->m_FanOpMode;
12093 65306 : Real64 SpeedRatio = 0.0;
12094 65306 : Real64 CycRatio = 0.0;
12095 65306 : Real64 PartLoadFrac = 0.0;
12096 65306 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal;
12097 65306 : Real64 dummy = 0.0;
12098 65306 : Real64 SensLoad = 0.0;
12099 65306 : int SolFla = 0;
12100 65306 : int SolFlaLat = 0;
12101 65306 : Real64 NoLoadTempOut = 0.0;
12102 65306 : Real64 NoLoadHumRatOut = 0.0;
12103 : // #8849, FullLoadHumRatOut set only at max speed
12104 65306 : Real64 FullLoadHumRatOut = 0.0;
12105 65306 : Real64 FullOutput = 0.0; // Sensible capacity (outlet - inlet) when the compressor is on
12106 65306 : Real64 OnOffAirFlowRatio = 0.0; // Autodesk:Init Patch to prevent use uninitialized in calls to SimVariableSpeedCoils
12107 65306 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
12108 :
12109 65306 : if (this->m_CondenserNodeNum != 0) {
12110 24779 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12111 : } else {
12112 40527 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12113 : }
12114 :
12115 : // Check the dehumidification control type. IF it's multimode, turn off the HX to find the sensible PLR. Then check to
12116 : // see if the humidity load is met without the use of the HX. Always run the HX for the other modes.
12117 65306 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode && this->m_CoolingCoilType_Num != HVAC::CoilDX_Cooling) {
12118 65303 : HXUnitOn = true;
12119 : } else {
12120 3 : HXUnitOn = false;
12121 : }
12122 :
12123 : // IF there is a fault of coil SAT Sensor
12124 65306 : if (this->m_FaultyCoilSATFlag) {
12125 : // calculate the sensor offset using fault information
12126 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
12127 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
12128 : // update the DesOutTemp
12129 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
12130 : }
12131 :
12132 : // IF UnitarySystem is scheduled on and there is flow
12133 130611 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && this->m_coolingCoilAvailSched->getCurrentVal() > 0.0 &&
12134 65305 : (state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow)) {
12135 :
12136 44938 : bool SensibleLoad = false;
12137 44938 : bool LatentLoad = false;
12138 44938 : bool unitSys = false;
12139 44938 : Real64 tempHumRatAcc = HumRatAcc;
12140 44938 : Real64 tempAcc = Acc;
12141 : // Determine if there is a sensible load on this system
12142 44938 : if (this->m_sysType == SysType::CoilCoolingDX) {
12143 44916 : if ((state.dataLoopNodes->Node(InletNode).Temp > state.dataLoopNodes->Node(this->CoolCtrlNode).TempSetPoint) &&
12144 69909 : (state.dataLoopNodes->Node(InletNode).Temp > DesOutTemp) &&
12145 24993 : (std::abs(state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp) > HVAC::TempControlTol)) {
12146 24762 : SensibleLoad = true;
12147 : }
12148 44916 : tempAcc = 0.0;
12149 44916 : tempHumRatAcc = 0.0;
12150 : } else {
12151 22 : unitSys = true;
12152 22 : if (state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp > HVAC::TempControlTol) SensibleLoad = true;
12153 : }
12154 :
12155 : // if a heat pump and other coil is on, disable this coil
12156 44938 : if (this->m_HeatPump && this->m_HeatingPartLoadFrac > 0.0) SensibleLoad = false;
12157 :
12158 : // Determine if there is a latent load on this system - for future use to serve latent-only loads
12159 44938 : if (this->m_sysType == SysType::CoilCoolingDX) {
12160 89832 : if ((state.dataLoopNodes->Node(InletNode).HumRat > state.dataLoopNodes->Node(InletNode).HumRatMax) &&
12161 44916 : (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat))
12162 7 : LatentLoad = true;
12163 : } else {
12164 22 : if (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat) LatentLoad = true;
12165 : }
12166 :
12167 : // disable latent dehumidification if there is no sensible load and latent only is not allowed
12168 44938 : if (this->m_RunOnLatentOnlyWithSensible && !SensibleLoad) LatentLoad = false;
12169 :
12170 : // disable compressor if OAT is below minimum outdoor temperature
12171 44938 : if (OutdoorDryBulb < this->m_MinOATCompressorCooling) {
12172 0 : SensibleLoad = false;
12173 0 : LatentLoad = false;
12174 : }
12175 :
12176 : // activate heat recovery loop coil if scheduled on and there is air flow
12177 44938 : if (this->m_WaterHRPlantLoopModel) {
12178 2 : if (this->temperatureOffsetControlStatus == 1) {
12179 1 : PartLoadFrac = 1.0;
12180 1 : mdot = this->MaxCoolCoilFluidFlow;
12181 : }
12182 2 : if (this->CoolCoilPlantLoc.loopNum > 0) {
12183 2 : PlantUtilities::SetComponentFlowRate(
12184 2 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12185 : }
12186 :
12187 6 : WaterCoils::SimulateWaterCoilComponents(
12188 4 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12189 2 : SensibleLoad = false; // fall through remaining checks
12190 2 : LatentLoad = false;
12191 44936 : } else if (this->m_TemperatureOffsetControlActive) {
12192 : // disable waterside economizer if the condition is NOT favorable
12193 3 : if (this->temperatureOffsetControlStatus == 0) {
12194 2 : SensibleLoad = false;
12195 2 : LatentLoad = false;
12196 2 : HXUnitOn = false;
12197 : }
12198 : }
12199 :
12200 : // IF DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
12201 : // Multimode coil will switch to enhanced dehumidification IF available and needed, but it
12202 : // still runs to meet the sensible load. Multimode applies to Multimode or HXAssistedCooling coils.
12203 44938 : if ((SensibleLoad && this->m_RunOnSensibleLoad) || (LatentLoad && this->m_RunOnLatentLoad)) {
12204 : // calculate sensible PLR, don't care IF latent is true here but need to guard for
12205 : // when LatentLoad=TRUE and SensibleLoad=FALSE
12206 24777 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12207 74331 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
12208 24777 : state.dataLoopNodes->Node(OutletNode).HumRat,
12209 24777 : state.dataLoopNodes->Node(InletNode).Temp,
12210 24777 : state.dataLoopNodes->Node(InletNode).HumRat);
12211 :
12212 24777 : PartLoadFrac = 0.0;
12213 24777 : compressorOp = HVAC::CompressorOp::Off;
12214 :
12215 24777 : if (this->m_EMSOverrideCoilSpeedNumOn && (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12216 3 : this->m_CoolingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
12217 3 : this->m_SpeedNum = this->m_CoolingSpeedNum;
12218 3 : bool useMaxedSpeed = false;
12219 3 : if (this->m_SpeedNum > this->m_NumOfSpeedCooling) {
12220 1 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
12221 1 : this->m_SpeedNum = this->m_NumOfSpeedCooling;
12222 1 : useMaxedSpeed = true;
12223 1 : if (this->m_CoilSpeedErrIdx == 0) {
12224 1 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12225 3 : ShowContinueError(state,
12226 : " Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.");
12227 : }
12228 8 : ShowRecurringWarningErrorAtEnd(
12229 : state,
12230 2 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12231 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
12232 1 : this->m_CoilSpeedErrIdx,
12233 1 : this->m_EMSOverrideCoilSpeedNumValue,
12234 1 : this->m_EMSOverrideCoilSpeedNumValue,
12235 : _,
12236 : "",
12237 : "");
12238 : }
12239 :
12240 3 : if (this->m_SpeedNum < 0) {
12241 0 : this->m_CoolingSpeedNum = 0;
12242 0 : this->m_SpeedNum = 0;
12243 0 : if (this->m_CoilSpeedErrIdx == 0) {
12244 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12245 0 : ShowContinueError(state, " Input speed value is below zero. Speed level is set to zero.");
12246 : }
12247 0 : ShowRecurringWarningErrorAtEnd(state,
12248 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12249 : "\". Input speed value is below zero. Speed level is set to zero.",
12250 0 : this->m_CoilSpeedErrIdx,
12251 0 : this->m_EMSOverrideCoilSpeedNumValue,
12252 0 : this->m_EMSOverrideCoilSpeedNumValue,
12253 : _,
12254 : "",
12255 : "");
12256 : }
12257 :
12258 3 : if (this->m_CoolingSpeedNum == 1) {
12259 1 : SpeedRatio = this->m_CoolingSpeedRatio = 0.0;
12260 1 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12261 1 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
12262 0 : CycRatio = this->m_CoolingCycRatio = 1;
12263 : } else {
12264 1 : CycRatio = this->m_CoolingCycRatio;
12265 : }
12266 1 : PartLoadFrac = this->m_CoolingCycRatio;
12267 : } else {
12268 2 : CycRatio = this->m_CoolingCycRatio = 1.0;
12269 2 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12270 2 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
12271 1 : SpeedRatio = this->m_CoolingSpeedRatio = 1;
12272 : } else {
12273 1 : SpeedRatio = this->m_CoolingSpeedRatio;
12274 : }
12275 2 : PartLoadFrac = this->m_CoolingSpeedRatio;
12276 : }
12277 3 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12278 3 : if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12279 3 : this->simMultiSpeedCoils(state,
12280 : AirLoopNum,
12281 : FirstHVACIteration,
12282 : compressorOp,
12283 : SensibleLoad,
12284 : LatentLoad,
12285 : PartLoadFrac,
12286 : CoolingCoil,
12287 : this->m_SpeedNum);
12288 3 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12289 3 : int SpeedNum = 0;
12290 3 : if (SpeedNum == this->m_NumOfSpeedCooling) { // should be using this->m_SpeedNum? Diffs?
12291 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12292 : }
12293 : } else {
12294 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12295 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12296 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12297 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12298 0 : coilMode = HVAC::CoilMode::Enhanced;
12299 : }
12300 0 : bool const singleMode = (this->m_SingleMode == 1);
12301 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12302 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode);
12303 : }
12304 :
12305 24777 : } else if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12306 20307 : this->m_CompPartLoadRatio = PartLoadFrac;
12307 :
12308 20307 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12309 :
12310 4467 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12311 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12312 :
12313 0 : if (this->CoolCoilFluidInletNode > 0) state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
12314 :
12315 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12316 : CompName,
12317 : FirstHVACIteration,
12318 : HVAC::CompressorOp::On,
12319 : PartLoadFrac,
12320 0 : this->m_CoolingCoilIndex,
12321 : fanOp,
12322 : HXUnitOn,
12323 : _,
12324 0 : state.dataUnitarySystems->economizerFlag,
12325 : _,
12326 0 : this->m_DehumidificationMode,
12327 0 : 0.0); // this->CoilSHR);
12328 0 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) this->m_CompPartLoadRatio = PartLoadFrac;
12329 4467 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12330 :
12331 4447 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, PartLoadFrac, this->m_CoolingCoilIndex);
12332 :
12333 20 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12334 3 : this->simMultiSpeedCoils(
12335 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, this->m_SpeedNum);
12336 :
12337 17 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12338 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12339 :
12340 7 : int SpeedNum = 0;
12341 7 : this->m_CoolingCoilSensDemand = ReqOutput;
12342 7 : VariableSpeedCoils::SimVariableSpeedCoils(
12343 7 : state, "", this->m_CoolingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
12344 :
12345 17 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
12346 :
12347 0 : DXCoils::SimDXCoilMultiMode(
12348 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12349 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12350 10 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12351 : // SP control (tentatively) operates at constant air flow regardless of speed
12352 : // speed n uses MSHPMassFlowRateHigh and speed n-1 uses MSHPMassFlowRateLow
12353 3 : state.dataHVACGlobal->MSHPMassFlowRateLow = this->m_DesignMassFlowRate;
12354 3 : state.dataHVACGlobal->MSHPMassFlowRateHigh = this->m_DesignMassFlowRate;
12355 3 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12356 3 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12357 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12358 3 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12359 0 : coilMode = HVAC::CoilMode::Enhanced;
12360 : }
12361 3 : bool const singleMode = (this->m_SingleMode == 1);
12362 : // PartLoadFrac has not been set in this branch - so use m_CoolingSpeedRatio?
12363 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12364 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12365 3 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12366 7 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12367 :
12368 21 : WaterCoils::SimulateWaterCoilComponents(
12369 14 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12370 :
12371 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12372 :
12373 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12374 : blankString,
12375 0 : this->m_CoolingCoilIndex,
12376 : ReqOutput,
12377 : dummy,
12378 : fanOp,
12379 : HVAC::CompressorOp::Off,
12380 : PartLoadFrac,
12381 : FirstHVACIteration);
12382 0 : this->m_CoolingCoilSensDemand = 0.0;
12383 :
12384 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12385 :
12386 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12387 : blankString,
12388 0 : this->m_CoolingCoilIndex,
12389 : this->MaxCoolAirMassFlow,
12390 : fanOp,
12391 : FirstHVACIteration,
12392 0 : this->m_InitHeatPump,
12393 : ReqOutput,
12394 : dummy,
12395 : HVAC::CompressorOp::Off,
12396 : PartLoadFrac);
12397 :
12398 0 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12399 :
12400 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12401 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12402 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12403 0 : if (CoolingActive) PartLoadFrac = 1.0;
12404 :
12405 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12406 :
12407 0 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12408 :
12409 : } else {
12410 : }
12411 :
12412 24777 : NoLoadTempOut = state.dataLoopNodes->Node(OutletNode).Temp;
12413 24777 : NoLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12414 :
12415 24777 : Real64 NoOutput = 0.0; // CoilSystem:Cooling:DX
12416 24777 : FullOutput = 0.0;
12417 24777 : if (this->m_sysType == SysType::CoilCoolingDX) {
12418 24762 : NoOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12419 24762 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12420 24762 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12421 24762 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12422 49524 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12423 24762 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12424 : }
12425 :
12426 : // Changed logic to use temperature instead of load. The Psyc calcs can cause slight errors.
12427 : // For example it's possible that (NoOutput-ReqOutput) > Acc while (Node(OutletNode)%Temp-DesOutTemp) is not
12428 : // This can (and did) lead to RegulaFalsi errors
12429 :
12430 : // IF ((NoOutput-ReqOutput) .LT. Acc) THEN
12431 : // IF outlet temp at no load is lower than DesOutTemp (set point), do not operate the coil
12432 : // and if coolReheat, check hum rat as well
12433 24777 : bool doIt = false; // CoilSystem:Cooling:DX
12434 24777 : if (this->m_sysType == SysType::CoilCoolingDX) {
12435 24762 : if ((NoOutput - ReqOutput) < Acc) {
12436 0 : PartLoadFrac = 0.0;
12437 : } else {
12438 24762 : doIt = true;
12439 : }
12440 15 : } else if (this->m_EMSOverrideCoilSpeedNumOn &&
12441 0 : (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12442 : // do nothing, PartLoadFrac set above
12443 12 : } else if (((NoLoadTempOut - DesOutTemp) < Acc) && ((NoLoadHumRatOut - DesOutHumRat) < HumRatAcc)) {
12444 0 : PartLoadFrac = 0.0;
12445 : } else { // need to turn on compressor to see if load is met
12446 12 : doIt = true; // CoilSystem:Cooling:DX
12447 : } // CoilSystem:Cooling:DX
12448 24777 : if (this->m_EMSOverrideCoilSpeedNumOn) doIt = false;
12449 :
12450 24777 : if (doIt) { // CoilSystem:Cooling:DX
12451 24774 : PartLoadFrac = 1.0;
12452 24774 : compressorOp = HVAC::CompressorOp::On;
12453 :
12454 24774 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12455 :
12456 40614 : DXCoils::SimDXCoil(
12457 20307 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12458 20307 : this->m_CompPartLoadRatio = PartLoadFrac;
12459 20307 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12460 :
12461 4467 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12462 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12463 :
12464 0 : if (this->CoolCoilFluidInletNode > 0)
12465 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = max(0.0, this->MaxCoolCoilFluidFlow);
12466 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12467 : CompName,
12468 : FirstHVACIteration,
12469 : HVAC::CompressorOp::On,
12470 : PartLoadFrac,
12471 0 : this->m_CoolingCoilIndex,
12472 : fanOp,
12473 : HXUnitOn,
12474 : _,
12475 0 : state.dataUnitarySystems->economizerFlag,
12476 : _,
12477 0 : this->m_DehumidificationMode,
12478 0 : 0.0); // this->CoilSHR);
12479 :
12480 0 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) this->m_CompPartLoadRatio = PartLoadFrac;
12481 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12482 :
12483 4467 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12484 :
12485 4447 : CycRatio = 1.0;
12486 6994 : for (int speedRatio = 0; speedRatio < this->m_NumOfSpeedCooling; ++speedRatio) {
12487 6994 : SpeedRatio = Real64(speedRatio);
12488 6994 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
12489 6994 : OutletTemp = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
12490 6994 : if (SpeedRatio == 1) {
12491 2547 : FullLoadHumRatOut = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
12492 2547 : break;
12493 : }
12494 4447 : if (OutletTemp < DesOutTemp && SensibleLoad) break;
12495 : }
12496 :
12497 20 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12498 :
12499 3 : CycRatio = 1.0;
12500 3 : SpeedRatio = 0.0;
12501 3 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12502 3 : if (SpeedNum > 1) {
12503 0 : CycRatio = 0.0;
12504 0 : SpeedRatio = 1.0;
12505 : }
12506 3 : this->m_CoolingSpeedNum = SpeedNum;
12507 3 : this->simMultiSpeedCoils(
12508 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, SpeedNum);
12509 3 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12510 3 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12511 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12512 : }
12513 3 : if (OutletTemp < DesOutTemp && SensibleLoad) break;
12514 : }
12515 :
12516 17 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12517 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12518 :
12519 7 : CycRatio = 1.0;
12520 7 : SpeedRatio = 1.0;
12521 7 : SensLoad = -1.0; // turns on coil
12522 7 : this->m_CoolingSpeedRatio = SpeedRatio;
12523 7 : this->m_CoolingPartLoadFrac = PartLoadFrac;
12524 14 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12525 14 : this->m_CoolingSpeedNum = SpeedNum;
12526 14 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12527 : "",
12528 14 : this->m_CoolingCoilIndex,
12529 : fanOp,
12530 : compressorOp,
12531 : CycRatio,
12532 : SpeedNum,
12533 : SpeedRatio,
12534 : SensLoad,
12535 : dummy,
12536 : OnOffAirFlowRatio);
12537 14 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12538 14 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12539 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12540 : }
12541 14 : if (OutletTemp < DesOutTemp && SensibleLoad) break;
12542 : }
12543 7 : if (this->m_CoolingSpeedNum == 1) {
12544 4 : CycRatio = 1.0;
12545 4 : SpeedRatio = 0.0;
12546 : } else {
12547 3 : CycRatio = 0.0;
12548 3 : SpeedRatio = 1.0;
12549 : }
12550 :
12551 17 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) { // Coil:Cooling:DX:TwoStageWithHumidityControlMode
12552 :
12553 0 : DXCoils::SimDXCoilMultiMode(
12554 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12555 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12556 :
12557 10 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12558 3 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12559 3 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12560 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12561 3 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12562 0 : coilMode = HVAC::CoilMode::Enhanced;
12563 : }
12564 3 : this->m_CoolingSpeedRatio = 1.0;
12565 3 : bool const singleMode = (this->m_SingleMode == 1);
12566 3 : for (int speedNum = 1; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
12567 3 : this->m_CoolingSpeedNum = speedNum;
12568 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12569 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12570 3 : if (speedNum == this->m_NumOfSpeedCooling) {
12571 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12572 : }
12573 3 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) break;
12574 : }
12575 3 : if (this->m_CoolingSpeedNum == 1) {
12576 3 : this->m_CompPartLoadRatio = PartLoadFrac;
12577 3 : this->m_CoolCompPartLoadRatio = PartLoadFrac; // why is the set only for a few?
12578 3 : SpeedRatio = 0.0;
12579 : } else {
12580 0 : SpeedRatio = PartLoadFrac;
12581 0 : PartLoadFrac = 1.0;
12582 0 : this->m_CompPartLoadRatio = 1.0;
12583 0 : this->m_CoolCompPartLoadRatio = 1.0;
12584 : }
12585 7 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12586 :
12587 7 : mdot = this->MaxCoolCoilFluidFlow;
12588 7 : PlantUtilities::SetComponentFlowRate(
12589 7 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12590 :
12591 21 : WaterCoils::SimulateWaterCoilComponents(
12592 14 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12593 7 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12594 :
12595 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12596 :
12597 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12598 : blankString,
12599 0 : this->m_CoolingCoilIndex,
12600 : ReqOutput,
12601 : dummy,
12602 : fanOp,
12603 : HVAC::CompressorOp::On,
12604 : PartLoadFrac,
12605 : FirstHVACIteration);
12606 0 : this->m_CoolingCoilSensDemand = ReqOutput;
12607 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12608 :
12609 0 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12610 :
12611 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12612 : blankString,
12613 0 : this->m_CoolingCoilIndex,
12614 : this->MaxCoolAirMassFlow,
12615 : fanOp,
12616 : FirstHVACIteration,
12617 0 : this->m_InitHeatPump,
12618 : ReqOutput,
12619 : dummy,
12620 : HVAC::CompressorOp::Off,
12621 : PartLoadFrac);
12622 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12623 :
12624 0 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12625 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12626 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
12627 :
12628 0 : UserDefinedComponents::SimCoilUserDefined(
12629 0 : state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12630 0 : if (CoolingActive) PartLoadFrac = 1.0;
12631 :
12632 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12633 :
12634 : // TES coil simulated above with PLR=0. Operating mode is known here, no need to simulate again to determine operating
12635 : // mode.
12636 0 : if (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
12637 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly) { // cannot cool
12638 0 : PartLoadFrac = 0.0;
12639 : } else {
12640 : // Get full load result
12641 0 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12642 : }
12643 :
12644 : } else {
12645 : }
12646 :
12647 24774 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12648 24774 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12649 24774 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12650 49548 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12651 24774 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
12652 24774 : state.dataLoopNodes->Node(OutletNode).HumRat,
12653 24774 : state.dataLoopNodes->Node(InletNode).Temp,
12654 24774 : state.dataLoopNodes->Node(InletNode).HumRat);
12655 : }
12656 :
12657 : // IF ((FullOutput - ReqOutput) .GT. Acc) THEN ! old method
12658 : // IF ((Node(OutletNode)%Temp-DesOutTemp) .GT. Acc) THEN ! new method gets caught when temps are very close
12659 24777 : if (this->m_sysType == SysType::CoilCoolingDX) {
12660 24762 : if ((FullOutput - ReqOutput) > tempAcc) {
12661 611 : PartLoadFrac = 1.0;
12662 611 : doIt = false;
12663 : } else {
12664 24151 : doIt = true;
12665 : }
12666 : }
12667 24777 : if (this->m_EMSOverrideCoilSpeedNumOn) doIt = false;
12668 :
12669 24777 : if (doIt) {
12670 24163 : if (unitSys && state.dataLoopNodes->Node(OutletNode).Temp > DesOutTemp - tempAcc) {
12671 1 : PartLoadFrac = 1.0;
12672 1 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
12673 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
12674 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
12675 0 : PartLoadFrac = 0.0;
12676 : }
12677 24162 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
12678 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
12679 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
12680 0 : PartLoadFrac = 0.0;
12681 24162 : } else if (!SensibleLoad) {
12682 2 : PartLoadFrac = 0.0;
12683 : } else {
12684 :
12685 24160 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
12686 84008 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadRatio) {
12687 84008 : int CoilIndex = this->m_CoolingCoilIndex;
12688 84008 : DXCoils::CalcDoe2DXCoil(state, CoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
12689 84008 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
12690 :
12691 84008 : return DesOutTemp - OutletAirTemp;
12692 19817 : };
12693 19817 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12694 19817 : this->m_CompPartLoadRatio = PartLoadFrac;
12695 :
12696 4343 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) || (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) {
12697 :
12698 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadFrac) {
12699 0 : if (this->CoolCoilFluidInletNode > 0) {
12700 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = this->MaxCoolCoilFluidFlow * PartLoadFrac;
12701 : }
12702 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(
12703 : state,
12704 0 : this->m_CoolingCoilIndex,
12705 : FirstHVACIteration,
12706 : HVAC::CompressorOp::On,
12707 : PartLoadFrac,
12708 : HXUnitOn,
12709 : fanOp,
12710 : _,
12711 : _,
12712 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
12713 0 : 0.0);
12714 0 : return DesOutTemp - state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
12715 0 : };
12716 :
12717 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12718 0 : if (SolFla == -1) {
12719 :
12720 : // RegulaFalsi may not find sensible PLR when the latent degradation model is used.
12721 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
12722 0 : TempMaxPLR = -0.1;
12723 0 : TempOutletTempDXCoil = state.dataLoopNodes->Node(InletNode).Temp;
12724 0 : while ((TempOutletTempDXCoil - DesOutTemp) > 0.0 && TempMaxPLR <= 1.0) {
12725 : // find upper limit of PLR
12726 0 : TempMaxPLR += 0.1;
12727 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12728 : CompName,
12729 : FirstHVACIteration,
12730 : HVAC::CompressorOp::On,
12731 : TempMaxPLR,
12732 0 : this->m_CoolingCoilIndex,
12733 : fanOp,
12734 : HXUnitOn,
12735 : _,
12736 0 : state.dataUnitarySystems->economizerFlag,
12737 : _,
12738 0 : this->m_DehumidificationMode,
12739 0 : 0.0); // this->CoilSHR);
12740 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
12741 : }
12742 0 : TempMinPLR = TempMaxPLR;
12743 0 : while ((TempOutletTempDXCoil - DesOutTemp) < 0.0 && TempMinPLR >= 0.0) {
12744 : // pull upper limit of PLR DOwn to last valid limit (i.e. outlet temp still exceeds DesOutTemp)
12745 0 : TempMaxPLR = TempMinPLR;
12746 : // find minimum limit of PLR
12747 0 : TempMinPLR -= 0.01;
12748 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12749 : CompName,
12750 : FirstHVACIteration,
12751 : HVAC::CompressorOp::On,
12752 : TempMinPLR,
12753 0 : this->m_CoolingCoilIndex,
12754 : fanOp,
12755 : HXUnitOn,
12756 : _,
12757 0 : state.dataUnitarySystems->economizerFlag,
12758 : _,
12759 0 : this->m_DehumidificationMode,
12760 0 : 0.0); // this->CoilSHR);
12761 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
12762 : }
12763 : // Relax boundary slightly to assure a solution can be found using RegulaFalsi (i.e. one boundary may
12764 : // be very near the desired result)
12765 0 : TempMinPLR = max(0.0, (TempMinPLR - 0.01));
12766 0 : TempMaxPLR = min(1.0, (TempMaxPLR + 0.01));
12767 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
12768 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
12769 0 : if (SolFla == -1) {
12770 0 : if (!state.dataGlobal->WarmupFlag) {
12771 0 : if (this->warnIndex.m_HXAssistedSensPLRIter < 1) {
12772 0 : ++this->warnIndex.m_HXAssistedSensPLRIter;
12773 0 : ShowWarningError(
12774 : state,
12775 0 : format("{} - Iteration limit exceeded calculating DX unit sensible part-load ratio for unit = {}",
12776 0 : this->UnitType,
12777 0 : this->Name));
12778 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
12779 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
12780 0 : ShowContinueErrorTimeStamp(
12781 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
12782 : }
12783 0 : ShowRecurringWarningErrorAtEnd(state,
12784 0 : this->UnitType + " \"" + this->Name +
12785 : "\" - Iteration limit exceeded calculating sensible part-load ratio "
12786 : "error continues. Sensible PLR "
12787 : "statistics follow.",
12788 0 : this->warnIndex.m_HXAssistedSensPLRIterIndex,
12789 : PartLoadFrac,
12790 : PartLoadFrac);
12791 : }
12792 0 : } else if (SolFla == -2) {
12793 0 : PartLoadFrac = ReqOutput / FullOutput;
12794 0 : if (!state.dataGlobal->WarmupFlag) {
12795 0 : if (this->warnIndex.m_HXAssistedSensPLRFail < 1) {
12796 0 : ++this->warnIndex.m_HXAssistedSensPLRFail;
12797 0 : ShowWarningError(state,
12798 0 : format("{} - DX unit sensible part-load ratio calculation unexpectedly failed: "
12799 : "part-load ratio limits exceeded, for unit = {}",
12800 0 : this->UnitType,
12801 0 : this->Name));
12802 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
12803 0 : ShowContinueErrorTimeStamp(
12804 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
12805 : }
12806 0 : ShowRecurringWarningErrorAtEnd(state,
12807 0 : this->UnitType + " \"" + this->Name +
12808 : "\" - DX unit sensible part-load ratio calculation unexpectedly "
12809 : "failed error continues. Sensible PLR "
12810 : "statistics follow.",
12811 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex,
12812 : PartLoadFrac,
12813 : PartLoadFrac);
12814 : }
12815 : }
12816 0 : } else if (SolFla == -2) {
12817 0 : PartLoadFrac = ReqOutput / FullOutput;
12818 0 : if (!state.dataGlobal->WarmupFlag) {
12819 0 : if (this->warnIndex.m_HXAssistedSensPLRFail2 < 1) {
12820 0 : ++this->warnIndex.m_HXAssistedSensPLRFail2;
12821 0 : ShowWarningError(state,
12822 0 : format("{} - DX unit sensible part-load ratio calculation failed: part-load ratio limits "
12823 : "exceeded, for unit = {}",
12824 0 : this->UnitType,
12825 0 : this->Name));
12826 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
12827 0 : ShowContinueErrorTimeStamp(
12828 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
12829 : }
12830 0 : ShowRecurringWarningErrorAtEnd(state,
12831 0 : this->UnitType + " \"" + this->Name +
12832 : "\" - DX unit sensible part-load ratio calculation failed error continues. "
12833 : "Sensible PLR statistics follow.",
12834 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex2,
12835 : PartLoadFrac,
12836 : PartLoadFrac);
12837 : }
12838 : }
12839 0 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) this->m_CompPartLoadRatio = PartLoadFrac;
12840 :
12841 4343 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12842 4326 : this->m_CoolingSpeedRatio = SpeedRatio;
12843 4326 : if (SpeedRatio == 1.0) {
12844 10669 : auto f = [&state, this, DesOutTemp](Real64 const SpeedRatio) {
12845 10669 : int par1 = this->m_CoolingCoilIndex;
12846 10669 : Real64 par2 = DesOutTemp;
12847 10669 : int par3 = this->m_UnitarySysNum;
12848 : // 4-7 are not used for TwoSpeed coils, so these shouldn't matter at all
12849 10669 : Real64 par4_CycRatio = 0.0;
12850 10669 : int par5_SpeedNum = 0.0;
12851 10669 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
12852 10669 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
12853 10669 : return UnitarySys::DXCoilVarSpeedResidual(
12854 10669 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
12855 2426 : };
12856 2426 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
12857 2426 : PartLoadFrac = SpeedRatio;
12858 : } else {
12859 5704 : auto f = [&state, this, DesOutTemp, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
12860 : // several pars are not used in two speed coils, so these are just dummy values
12861 5704 : Real64 par4_SpeedRatio = 0.0;
12862 5704 : int par5_SpeedNum = 0.0;
12863 5704 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
12864 5704 : HVAC::CompressorOp par7_compressorOp = HVAC::CompressorOp::On;
12865 11408 : return UnitarySys::DXCoilCyclingResidual(state,
12866 : CycRatio,
12867 5704 : this->m_CoolingCoilIndex,
12868 : DesOutTemp,
12869 5704 : this->m_UnitarySysNum,
12870 : par4_SpeedRatio,
12871 : par5_SpeedNum,
12872 : par6_FanOpMode,
12873 : par7_compressorOp,
12874 : AirLoopNum,
12875 5704 : FirstHVACIteration);
12876 1900 : };
12877 1900 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
12878 1900 : PartLoadFrac = CycRatio;
12879 : }
12880 :
12881 17 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12882 :
12883 3 : if (this->m_CoolingSpeedNum > 1.0) {
12884 0 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
12885 0 : int par1 = this->m_CoolingCoilIndex;
12886 0 : Real64 par2 = DesOutTemp;
12887 0 : int par3 = this->m_UnitarySysNum;
12888 0 : Real64 par4_CycRatio = CycRatio;
12889 0 : int par5_SpeedNum = this->m_CoolingSpeedNum;
12890 0 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Cycling;
12891 0 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
12892 0 : return UnitarySys::DXCoilVarSpeedResidual(
12893 0 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
12894 0 : };
12895 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
12896 0 : PartLoadFrac = SpeedRatio;
12897 : } else {
12898 3 : SpeedRatio = 0.0;
12899 3 : this->m_CoolingSpeedRatio = SpeedRatio;
12900 11 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
12901 22 : return UnitarySys::DXCoilCyclingResidual(state,
12902 : CycRatio,
12903 11 : this->m_CoolingCoilIndex,
12904 : DesOutTemp,
12905 11 : this->m_UnitarySysNum,
12906 : SpeedRatio,
12907 11 : this->m_CoolingSpeedNum,
12908 : HVAC::FanOp::Cycling,
12909 : HVAC::CompressorOp::On,
12910 : AirLoopNum,
12911 11 : FirstHVACIteration);
12912 3 : };
12913 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
12914 3 : PartLoadFrac = CycRatio;
12915 : }
12916 :
12917 14 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12918 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12919 :
12920 7 : CycRatio = 1.0;
12921 7 : SpeedRatio = 1.0;
12922 :
12923 7 : if (this->m_CoolingSpeedNum > 1.0) {
12924 18 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
12925 18 : int par1 = this->m_CoolingCoilIndex;
12926 18 : Real64 par2 = DesOutTemp;
12927 18 : int par3 = this->m_UnitarySysNum;
12928 18 : Real64 par4_CycRatio = CycRatio;
12929 18 : int par5_SpeedNum = this->m_CoolingSpeedNum;
12930 18 : HVAC::FanOp par6_FanOpMode = this->m_FanOpMode;
12931 18 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
12932 18 : return UnitarySys::DXCoilVarSpeedResidual(
12933 18 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
12934 3 : };
12935 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
12936 3 : this->m_CoolingCycRatio = CycRatio;
12937 3 : this->m_CoolingSpeedRatio = SpeedRatio;
12938 3 : this->m_CoolingPartLoadFrac = SpeedRatio;
12939 3 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
12940 3 : PartLoadFrac = SpeedRatio;
12941 : } else {
12942 4 : this->m_CoolingSpeedRatio = SpeedRatio;
12943 17 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
12944 34 : return UnitarySys::DXCoilCyclingResidual(state,
12945 : CycRatio,
12946 17 : this->m_CoolingCoilIndex,
12947 : DesOutTemp,
12948 17 : this->m_UnitarySysNum,
12949 : SpeedRatio,
12950 17 : this->m_CoolingSpeedNum,
12951 17 : this->m_FanOpMode,
12952 : HVAC::CompressorOp::On,
12953 : AirLoopNum,
12954 17 : FirstHVACIteration);
12955 4 : };
12956 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
12957 4 : SpeedRatio = 0.0;
12958 4 : this->m_CoolingCycRatio = CycRatio;
12959 4 : this->m_CoolingPartLoadFrac = CycRatio;
12960 4 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
12961 4 : PartLoadFrac = CycRatio;
12962 : }
12963 :
12964 14 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
12965 0 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
12966 0 : DXCoils::SimDXCoilMultiMode(
12967 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12968 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
12969 0 : };
12970 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12971 0 : this->m_CompPartLoadRatio = PartLoadFrac;
12972 7 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12973 12 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
12974 12 : bool const singleMode = this->m_SingleMode;
12975 12 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12976 12 : state, DehumidMode, this->m_CoolingSpeedNum, PartLoadRatio, fanOp, singleMode);
12977 : Real64 outletCondition =
12978 12 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
12979 12 : return DesOutTemp - outletCondition;
12980 3 : };
12981 :
12982 3 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12983 3 : if (this->m_CoolingSpeedNum == 1) {
12984 3 : this->m_CompPartLoadRatio = PartLoadFrac;
12985 3 : SpeedRatio = 0.0;
12986 : } else {
12987 0 : SpeedRatio = PartLoadFrac;
12988 0 : PartLoadFrac = 1.0;
12989 0 : this->m_CompPartLoadRatio = 1.0;
12990 : }
12991 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) {
12992 :
12993 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
12994 : maxPartLoadFrac =
12995 4 : min(1.0,
12996 4 : ((mdot / this->MaxCoolCoilFluidFlow) +
12997 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
12998 :
12999 24 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadRatio) {
13000 24 : Real64 mdot = min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13001 24 : this->MaxCoolCoilFluidFlow * PartLoadRatio);
13002 24 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
13003 48 : WaterCoils::SimulateWaterCoilComponents(
13004 24 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, _, _, PartLoadRatio);
13005 24 : return DesOutTemp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp;
13006 4 : };
13007 :
13008 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
13009 :
13010 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13011 0 : this->m_CoolingCoilSensDemand = ReqOutput;
13012 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
13013 0 : return UnitarySys::coolWatertoAirHPTempResidual(
13014 0 : state, PartLoadRatio, this->m_UnitarySysNum, FirstHVACIteration, DesOutTemp, ReqOutput);
13015 0 : };
13016 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13017 0 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13018 : // do nothing, user defined coil cannot be controlled
13019 :
13020 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13021 0 : auto f = [&state, this, DesOutTemp](Real64 const PartLoadRatio) {
13022 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13023 0 : PackagedThermalStorageCoil::SimTESCoil(state,
13024 : thisSys.m_CoolingCoilName,
13025 0 : thisSys.m_CoolingCoilIndex,
13026 : thisSys.m_FanOpMode,
13027 0 : thisSys.m_TESOpMode,
13028 : PartLoadRatio);
13029 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp - DesOutTemp;
13030 0 : };
13031 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13032 : } else {
13033 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
13034 0 : ShowFatalError(state,
13035 0 : format("ControlCoolingSystemToSP: Invalid cooling coil type = {}", HVAC::cAllCoilTypes(CoilType_Num)));
13036 : }
13037 : }
13038 : }
13039 : }
13040 :
13041 : // IF system does not operate to meet sensible load, use no load humidity ratio to test against humidity setpoint,
13042 : // ELSE use operating humidity ratio to test against humidity setpoint
13043 44938 : if (PartLoadFrac == 0.0) {
13044 20162 : OutletHumRatDXCoil = NoLoadHumRatOut;
13045 : } else {
13046 24776 : OutletHumRatDXCoil = state.dataLoopNodes->Node(OutletNode).HumRat;
13047 : }
13048 :
13049 : // IF humidity setpoint is not satisfied and humidity control type is MultiMode,
13050 : // then enable heat exchanger and run to meet sensible load
13051 :
13052 44938 : if ((OutletHumRatDXCoil > (DesOutHumRat + tempHumRatAcc)) && (!unitSys || PartLoadFrac < 1.0) &&
13053 11 : (this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
13054 :
13055 1 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13056 : // pass
13057 1 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
13058 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted,
13059 : // CoilSystem:Cooling:Water:HeatExchangerAssisted
13060 : // Determine required part load when heat exchanger is ON
13061 0 : HXUnitOn = true;
13062 0 : PartLoadFrac = 1.0;
13063 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13064 : CompName,
13065 : FirstHVACIteration,
13066 : HVAC::CompressorOp::On,
13067 : PartLoadFrac,
13068 0 : this->m_CoolingCoilIndex,
13069 : fanOp,
13070 : HXUnitOn,
13071 : _,
13072 0 : state.dataUnitarySystems->economizerFlag,
13073 : _,
13074 0 : this->m_DehumidificationMode,
13075 0 : 0.0); // this->CoilSHR);
13076 :
13077 0 : OutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13078 :
13079 : // FullOutput will be different than the FullOutput determined above during sensible PLR calculations
13080 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13081 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13082 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13083 0 : state.dataLoopNodes->Node(InletNode).Temp,
13084 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13085 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13086 :
13087 : // Check to see if the system can meet the load with the compressor off
13088 : // If NoOutput is lower than (more cooling than required) or very near the ReqOutput, do not run the compressor
13089 0 : if ((NoLoadTempOut - DesOutTemp) < Acc) {
13090 0 : PartLoadFrac = 0.0;
13091 : // OutletTempDXCoil is the full capacity outlet temperature at PartLoadFrac = 1 from the CALL above.
13092 : // if this temp is greater than or very near the desired outlet temp, then run the compressor at PartLoadFrac
13093 : // = 1.
13094 : // ELSEIF ((OutletTempDXCoil > DesOutTemp) .OR. ABS(OutletTempDXCoil - DesOutTemp) .LE. (Acc*2.0d0)) THEN
13095 0 : } else if (OutletTempDXCoil > DesOutTemp - (tempAcc * 2.0)) {
13096 0 : PartLoadFrac = 1.0;
13097 : } else {
13098 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadRatio) {
13099 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13100 :
13101 0 : if (thisSys.CoolCoilFluidInletNode > 0) {
13102 0 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = thisSys.MaxCoolCoilFluidFlow * PartLoadRatio;
13103 : }
13104 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13105 0 : this->m_CoolingCoilIndex,
13106 : FirstHVACIteration,
13107 : HVAC::CompressorOp::On,
13108 : PartLoadRatio,
13109 : HXUnitOn,
13110 : fanOp,
13111 : _,
13112 : _,
13113 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13114 0 : 0.0);
13115 0 : Real64 OutletAirTemp = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13116 0 : return DesOutTemp - OutletAirTemp;
13117 0 : };
13118 :
13119 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13120 : }
13121 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13122 :
13123 1 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13124 :
13125 : // Get full load result
13126 0 : PartLoadFrac = 1.0;
13127 0 : DehumidMode = HVAC::CoilMode::Enhanced;
13128 0 : this->m_DehumidificationMode = DehumidMode;
13129 0 : DXCoils::SimDXCoilMultiMode(
13130 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13131 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13132 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13133 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13134 0 : state.dataLoopNodes->Node(InletNode).Temp,
13135 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13136 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13137 :
13138 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
13139 : // Check that this is the case; IF not set PartLoadFrac = 0.0 (off) and return
13140 : // Calculate the part load fraction
13141 0 : if (FullOutput >= 0) {
13142 0 : PartLoadFrac = 0.0;
13143 : } else {
13144 0 : OutletTempDXCoil = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13145 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13146 : // If sensible load and setpoint cannot be met, set PLR = 1. if no sensible load and
13147 : // latent load exists and setpoint cannot be met, set PLR = 1.
13148 0 : if ((OutletTempDXCoil > (DesOutTemp - (tempAcc * 2.0)) && SensibleLoad && this->m_RunOnSensibleLoad) ||
13149 0 : (OutletHumRatDXCoil >= (DesOutHumRat - (tempHumRatAcc * 2.0)) && !SensibleLoad && LatentLoad &&
13150 0 : this->m_RunOnLatentLoad)) {
13151 0 : PartLoadFrac = 1.0;
13152 : // ELSEIF ((SensibleLoad .and. LatentLoad .AND. .NOT. UnitarySystem(UnitarySysNum)%RunOnLatentLoad
13153 : // .AND. &
13154 : // OutletHumRatDXCoil < DesOutHumRat)) THEN
13155 0 : } else if (!SensibleLoad && (OutletHumRatDXCoil < DesOutHumRat && LatentLoad && this->m_RunOnLatentLoad)) {
13156 0 : PartLoadFrac = ReqOutput / FullOutput;
13157 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13158 0 : DXCoils::SimDXCoilMultiMode(
13159 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13160 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13161 0 : };
13162 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13163 0 : } else { // must be a sensible load so find PLR
13164 0 : PartLoadFrac = ReqOutput / FullOutput;
13165 0 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13166 0 : DXCoils::SimDXCoilMultiMode(
13167 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13168 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13169 0 : };
13170 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13171 : }
13172 : }
13173 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13174 :
13175 1 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13176 1 : HVAC::CoilMode coilMode = HVAC::CoilMode::Enhanced;
13177 1 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
13178 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
13179 : }
13180 1 : if (this->m_CoolingSpeedNum == 0) this->m_CoolingSpeedNum = 1;
13181 1 : bool const singleMode = (this->m_SingleMode == 1);
13182 1 : PartLoadFrac = 1.0;
13183 1 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13184 1 : this->m_CoolingSpeedNum = speedNum;
13185 1 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13186 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13187 : // Cooling: break if outlet temp is lower than DesOutTemp or approaches DesOutTemp to within Acc from above
13188 1 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) break;
13189 : }
13190 :
13191 : // make sure outlet temp is below set point before calling SolveRoot
13192 : // Cooling: iterate only when outlet temp is below DesOutTemp by at least Acc
13193 1 : if ((DesOutTemp - state.dataLoopNodes->Node(OutletNode).Temp) > Acc) {
13194 :
13195 4 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadFrac) {
13196 4 : bool const singleMode = false;
13197 4 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13198 4 : state, HVAC::CoilMode::Enhanced, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13199 : Real64 outletCondition =
13200 4 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex).Temp;
13201 :
13202 4 : return DesOutTemp - outletCondition;
13203 1 : };
13204 :
13205 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13206 : }
13207 1 : if (this->m_CoolingSpeedNum == 1) {
13208 1 : this->m_CompPartLoadRatio = PartLoadFrac;
13209 1 : SpeedRatio = 0.0;
13210 : } else {
13211 0 : SpeedRatio = PartLoadFrac;
13212 0 : PartLoadFrac = 1.0;
13213 0 : this->m_CompPartLoadRatio = 1.0;
13214 : }
13215 :
13216 : } else {
13217 : }
13218 : } // END IF humidity ratio setpoint not met - Multimode humidity control
13219 :
13220 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13221 : // then overcool to meet moisture load
13222 44938 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13223 : // pass
13224 44935 : } else if ((OutletHumRatDXCoil > DesOutHumRat) && (!unitSys || PartLoadFrac < 1.0) && LatentLoad &&
13225 11 : (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat)) {
13226 :
13227 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13228 : // do not run the compressor
13229 6 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc) {
13230 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13231 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the DesOutHumRat,
13232 : // run the compressor at PartLoadFrac = 1.
13233 : // ELSEIF ((DesOutHumRat-FullLoadHumRatOut) .LT. HumRatAcc) THEN
13234 6 : } else if (FullLoadHumRatOut > (DesOutHumRat - tempHumRatAcc)) {
13235 1 : PartLoadFrac = 1.0;
13236 1 : SpeedRatio = 1.0; // #8849, need to set properties of multi-speed/2-speed coils
13237 1 : if (this->m_IsDXCoil) {
13238 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13239 : }
13240 : // ELSE find the PLR to meet the load
13241 :
13242 : } else {
13243 :
13244 5 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13245 0 : auto f = [&state, this, DesOutHumRat, fanOp](Real64 const PartLoadRatio) {
13246 0 : DXCoils::CalcDoe2DXCoil(state, this->m_CoolingCoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13247 0 : Real64 OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13248 0 : return DesOutHumRat - OutletAirHumRat;
13249 0 : };
13250 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13251 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13252 5 : } else if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13253 :
13254 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13255 : // do not run the compressor
13256 0 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc * 2.0) {
13257 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13258 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the
13259 : // DesOutHumRat, run the compressor at PartLoadFrac = 1.
13260 0 : } else if ((DesOutHumRat - FullLoadHumRatOut) < tempHumRatAcc * 2.0) {
13261 0 : PartLoadFrac = 1.0;
13262 : // ELSE find the PLR to meet the load
13263 : } else {
13264 0 : auto f = [&state, this, FirstHVACIteration, HXUnitOn, fanOp, DesOutHumRat](Real64 const PartLoadRatio) {
13265 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13266 0 : this->m_CoolingCoilIndex,
13267 : FirstHVACIteration,
13268 : HVAC::CompressorOp::On,
13269 : PartLoadRatio,
13270 : HXUnitOn,
13271 : fanOp,
13272 : _,
13273 0 : state.dataUnitarySystems->economizerFlag,
13274 0 : HVAC::CoilMode::Normal,
13275 0 : 0.0);
13276 0 : return DesOutHumRat - state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13277 0 : };
13278 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13279 0 : if (SolFla == -1) {
13280 :
13281 : // RegulaFalsi may not find latent PLR when the latent degradation model is used.
13282 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13283 0 : TempMaxPLR = -0.1;
13284 0 : while ((OutletHumRatDXCoil - DesOutHumRat) >= 0.0 && TempMaxPLR <= 1.0) {
13285 : // find upper limit of LatentPLR
13286 0 : TempMaxPLR += 0.1;
13287 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13288 : CompName,
13289 : FirstHVACIteration,
13290 : HVAC::CompressorOp::On,
13291 : TempMaxPLR,
13292 0 : this->m_CoolingCoilIndex,
13293 : fanOp,
13294 : HXUnitOn,
13295 : _,
13296 0 : state.dataUnitarySystems->economizerFlag,
13297 : _,
13298 0 : this->m_DehumidificationMode,
13299 0 : 0.0); // this->CoilSHR);
13300 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13301 : }
13302 0 : TempMaxPLR = min(1.0, TempMaxPLR + 0.1);
13303 0 : TempMinPLR = TempMaxPLR;
13304 0 : while ((OutletHumRatDXCoil - DesOutHumRat) <= 0.0 && TempMinPLR >= 0.0) {
13305 : // pull upper limit of LatentPLR DOwn to last valid limit (i.e. latent output still
13306 : // exceeds SystemMoisuterLoad)
13307 : // find minimum limit of Latent PLR
13308 0 : TempMinPLR -= 0.02;
13309 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13310 : CompName,
13311 : FirstHVACIteration,
13312 : HVAC::CompressorOp::On,
13313 : TempMinPLR,
13314 0 : this->m_CoolingCoilIndex,
13315 : fanOp,
13316 : HXUnitOn,
13317 : _,
13318 0 : state.dataUnitarySystems->economizerFlag,
13319 : _,
13320 0 : this->m_DehumidificationMode,
13321 0 : 0.0); // this->CoilSHR);
13322 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13323 : }
13324 0 : TempMinPLR = max(0.0, TempMinPLR - 0.1);
13325 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13326 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13327 0 : if (SolFla == -1) {
13328 0 : if (!state.dataGlobal->WarmupFlag) {
13329 0 : if (this->warnIndex.m_HXAssistedCRLatPLRIter < 1) {
13330 0 : ++this->warnIndex.m_HXAssistedCRLatPLRIter;
13331 0 : ShowWarningError(
13332 : state,
13333 0 : format("{} - Iteration limit exceeded calculating DX unit latent part-load ratio for unit = {}",
13334 0 : this->UnitType,
13335 0 : this->Name));
13336 0 : ShowContinueError(state, format("Estimated latent part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13337 0 : ShowContinueError(state, format("Calculated latent part-load ratio = {:.3R}", PartLoadFrac));
13338 0 : ShowContinueErrorTimeStamp(state,
13339 : "The calculated latent part-load ratio will be used and the simulation "
13340 : "continues. Occurrence info:");
13341 : }
13342 0 : ShowRecurringWarningErrorAtEnd(state,
13343 0 : this->UnitType + " \"" + this->Name +
13344 : "\" - Iteration limit exceeded calculating latent part-load ratio "
13345 : "error continues. Latent PLR "
13346 : "statistics follow.",
13347 0 : this->warnIndex.m_HXAssistedCRLatPLRIterIndex,
13348 : PartLoadFrac,
13349 : PartLoadFrac);
13350 : }
13351 :
13352 0 : } else if (SolFla == -2) {
13353 :
13354 0 : PartLoadFrac = ReqOutput / FullOutput;
13355 0 : if (!state.dataGlobal->WarmupFlag) {
13356 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail < 1) {
13357 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail;
13358 0 : ShowWarningError(state,
13359 0 : format("{} - DX unit latent part-load ratio calculation failed unexpectedly: part-load "
13360 : "ratio limits exceeded, for unit = {}",
13361 0 : this->UnitType,
13362 0 : this->Name));
13363 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13364 0 : ShowContinueErrorTimeStamp(
13365 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13366 : }
13367 0 : ShowRecurringWarningErrorAtEnd(state,
13368 0 : this->UnitType + " \"" + this->Name +
13369 : "\" - DX unit latent part-load ratio calculation failed "
13370 : "unexpectedly error continues. Latent PLR "
13371 : "statistics follow.",
13372 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex,
13373 : PartLoadFrac,
13374 : PartLoadFrac);
13375 : }
13376 : }
13377 0 : } else if (SolFla == -2) {
13378 0 : PartLoadFrac = ReqOutput / FullOutput;
13379 0 : if (!state.dataGlobal->WarmupFlag) {
13380 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail2 < 1) {
13381 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail2;
13382 0 : ShowWarningError(state,
13383 0 : format("{} - DX unit latent part-load ratio calculation failed: part-load ratio limits "
13384 : "exceeded, for unit = {}",
13385 0 : this->UnitType,
13386 0 : this->Name));
13387 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13388 0 : ShowContinueErrorTimeStamp(
13389 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13390 : }
13391 0 : ShowRecurringWarningErrorAtEnd(
13392 : state,
13393 0 : this->UnitType + " \"" + this->Name +
13394 : "\" - DX unit latent part-load ratio calculation failed error continues. Latent PLR statistics "
13395 : "follow.",
13396 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex2,
13397 : PartLoadFrac,
13398 : PartLoadFrac);
13399 : }
13400 : }
13401 : }
13402 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13403 :
13404 5 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13405 :
13406 : // Simulate MultiSpeed DX coil at sensible result
13407 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13408 :
13409 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13410 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13411 : // then overcool to meet moisture load
13412 :
13413 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13414 :
13415 0 : CycRatio = 0.0;
13416 0 : SpeedRatio = 0.0;
13417 :
13418 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13419 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13420 0 : if (OutletHumRatLS > DesOutHumRat) {
13421 0 : CycRatio = 1.0;
13422 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13423 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13424 0 : if (OutletHumRatHS < DesOutHumRat) {
13425 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13426 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13427 : SpeedRatio,
13428 0 : this->m_CoolingCoilIndex,
13429 : DesOutHumRat,
13430 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13431 : 0.0, // Real64 CycRatio,
13432 : 0, // int SpeedNum,
13433 : HVAC::FanOp::Invalid, // int FanOpMode,
13434 0 : HVAC::CompressorOp::On);
13435 0 : };
13436 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13437 : } else {
13438 0 : SpeedRatio = 1.0;
13439 : }
13440 0 : PartLoadFrac = SpeedRatio;
13441 : } else {
13442 0 : SpeedRatio = 0.0;
13443 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13444 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13445 : state,
13446 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13447 0 : this->m_CoolingCoilIndex,
13448 : DesOutHumRat,
13449 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13450 : 1.0, // Real64 CycRatio,
13451 0 : this->m_CoolingSpeedNum,
13452 0 : this->m_FanOpMode, // int FanOpMode,
13453 0 : HVAC::CompressorOp::On);
13454 0 : };
13455 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13456 0 : PartLoadFrac = CycRatio;
13457 : }
13458 : }
13459 :
13460 5 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13461 :
13462 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13463 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13464 :
13465 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13466 : // then overcool to meet moisture load
13467 :
13468 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13469 :
13470 0 : CycRatio = 0.0;
13471 0 : SpeedRatio = 0.0;
13472 :
13473 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13474 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13475 0 : if (OutletHumRatLS > DesOutHumRat) {
13476 0 : CycRatio = 1.0;
13477 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13478 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13479 0 : if (OutletHumRatHS < DesOutHumRat) {
13480 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13481 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13482 : SpeedRatio,
13483 0 : this->m_CoolingCoilIndex,
13484 : DesOutHumRat,
13485 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13486 : 0.0, // Real64 CycRatio,
13487 : 0, // int SpeedNum,
13488 : HVAC::FanOp::Invalid, // int FanOpMode,
13489 0 : HVAC::CompressorOp::On);
13490 0 : };
13491 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13492 : } else {
13493 0 : SpeedRatio = 1.0;
13494 : }
13495 : } else {
13496 0 : SpeedRatio = 0.0;
13497 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13498 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13499 : state,
13500 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13501 0 : this->m_CoolingCoilIndex,
13502 : DesOutHumRat,
13503 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13504 : 0.0, // Real64 CycRatio,
13505 : 0,
13506 : HVAC::FanOp::Invalid, // int FanOpMode,
13507 0 : HVAC::CompressorOp::On);
13508 0 : };
13509 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13510 : }
13511 : }
13512 5 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13513 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13514 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13515 : CompName,
13516 1 : this->m_CoolingCoilIndex,
13517 : this->m_FanOpMode,
13518 : HVAC::CompressorOp::On,
13519 : CycRatio,
13520 : this->m_CoolingSpeedNum,
13521 : SpeedRatio,
13522 : ReqOutput,
13523 : dummy,
13524 : OnOffAirFlowRatio);
13525 1 : OutletHumRatLS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13526 :
13527 1 : if (OutletHumRatLS > DesOutHumRat) {
13528 1 : CycRatio = 1.0;
13529 :
13530 2 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; ++speedNum) {
13531 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13532 : CompName,
13533 2 : this->m_CoolingCoilIndex,
13534 : this->m_FanOpMode,
13535 : HVAC::CompressorOp::On,
13536 : 1.0,
13537 : speedNum,
13538 : 1.0,
13539 : ReqOutput,
13540 : dummy,
13541 : OnOffAirFlowRatio);
13542 2 : OutletHumRatHS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13543 2 : if (OutletHumRatHS < DesOutHumRat || speedNum == this->m_NumOfSpeedCooling) {
13544 1 : this->m_CoolingSpeedNum = speedNum;
13545 1 : break;
13546 : }
13547 : }
13548 :
13549 1 : if (OutletHumRatHS < DesOutHumRat) {
13550 1 : if (this->m_CoolingSpeedNum == 1) {
13551 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13552 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13553 : state,
13554 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13555 0 : this->m_CoolingCoilIndex,
13556 : DesOutHumRat,
13557 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13558 : 1.0, // Real64 CycRatio,
13559 0 : this->m_CoolingSpeedNum,
13560 0 : this->m_FanOpMode, // int FanOpMode,
13561 0 : HVAC::CompressorOp::On);
13562 0 : };
13563 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13564 : } else {
13565 4 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13566 8 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13567 : SpeedRatio,
13568 4 : this->m_CoolingCoilIndex,
13569 : DesOutHumRat,
13570 4 : this->m_UnitarySysNum, // int UnitarySysNum,
13571 : 1.0, // Real64 CycRatio,
13572 4 : this->m_CoolingSpeedNum,
13573 4 : this->m_FanOpMode, // int FanOpMode,
13574 4 : HVAC::CompressorOp::On);
13575 1 : };
13576 1 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13577 : }
13578 : } else {
13579 0 : if (this->m_CoolingSpeedNum == 1) {
13580 0 : CycRatio = 1.0;
13581 : } else {
13582 0 : SpeedRatio = 1.0;
13583 : }
13584 : }
13585 : } else {
13586 0 : SpeedRatio = 0.0;
13587 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13588 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13589 : SpeedRatio,
13590 0 : this->m_CoolingCoilIndex,
13591 : DesOutHumRat,
13592 0 : this->m_UnitarySysNum, // int UnitarySysNum,
13593 : 0.0, // Real64 CycRatio,
13594 : 0, // int SpeedNum
13595 : HVAC::FanOp::Invalid, // int FanOpMode,
13596 0 : HVAC::CompressorOp::On);
13597 0 : };
13598 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13599 : }
13600 5 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13601 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13602 0 : DXCoils::SimDXCoilMultiMode(
13603 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13604 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13605 0 : };
13606 0 : General::SolveRoot(state, Acc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13607 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13608 4 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13609 1 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
13610 1 : if (this->m_CoolingSpeedNum == 0) this->m_CoolingSpeedNum = 1;
13611 1 : bool const singleMode = (this->m_SingleMode == 1);
13612 1 : PartLoadFrac = 1.0;
13613 2 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13614 2 : this->m_CoolingSpeedNum = speedNum;
13615 2 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13616 : state, coilMode, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13617 : // Cooling: break if outlet humrat is lower than DesOutHumRat or approaches DesOutHumRat to within HumRatAcc from above
13618 2 : if ((state.dataLoopNodes->Node(OutletNode).HumRat - DesOutHumRat) < HumRatAcc) break;
13619 : }
13620 : // make sure outlet HumRat is below set point before calling SolveRoot
13621 : // Cooling: iterate only when outlet humrat is below DesOutHumRat by at least HumRatAcc
13622 1 : if ((DesOutHumRat - state.dataLoopNodes->Node(OutletNode).HumRat) > HumRatAcc) {
13623 :
13624 3 : auto f = [&state,
13625 : this, // 0
13626 : DesOutHumRat, // 1
13627 : fanOp // 3
13628 : ](Real64 const PartLoadFrac) {
13629 3 : bool const singleMode = false;
13630 3 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13631 3 : state, HVAC::CoilMode::Normal, this->m_CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13632 : Real64 outletCondition =
13633 3 : state.dataLoopNodes->Node(state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapOutletNodeIndex)
13634 3 : .HumRat;
13635 3 : return DesOutHumRat - outletCondition;
13636 1 : };
13637 :
13638 1 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13639 : }
13640 1 : if (this->m_CoolingSpeedNum == 1) {
13641 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13642 0 : SpeedRatio = 0.0;
13643 : } else {
13644 1 : SpeedRatio = PartLoadFrac;
13645 1 : PartLoadFrac = 1.0;
13646 1 : this->m_CompPartLoadRatio = 1.0;
13647 : }
13648 :
13649 3 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
13650 :
13651 15 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat](Real64 const PartLoadRatio) {
13652 15 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13653 15 : Real64 mdot = min(state.dataLoopNodes->Node(thisSys.CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13654 15 : thisSys.MaxCoolCoilFluidFlow * PartLoadRatio);
13655 15 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = mdot;
13656 30 : WaterCoils::SimulateWaterCoilComponents(
13657 15 : state, thisSys.m_CoolingCoilName, FirstHVACIteration, thisSys.m_CoolingCoilIndex, _, _, PartLoadRatio);
13658 15 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
13659 3 : };
13660 :
13661 3 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13662 :
13663 3 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13664 :
13665 0 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat, ReqOutput](Real64 const PartLoadRatio) {
13666 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13667 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
13668 0 : Real64 dummy = 0.0;
13669 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
13670 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
13671 : blankString,
13672 0 : thisSys.m_CoolingCoilIndex,
13673 : ReqOutput,
13674 : dummy,
13675 : thisSys.m_FanOpMode,
13676 : HVAC::CompressorOp::Off,
13677 : PartLoadRatio,
13678 : FirstHVACIteration);
13679 : } else {
13680 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
13681 : blankString,
13682 0 : thisSys.m_CoolingCoilIndex,
13683 : thisSys.MaxCoolAirMassFlow,
13684 : thisSys.m_FanOpMode,
13685 : FirstHVACIteration,
13686 0 : thisSys.m_InitHeatPump,
13687 : ReqOutput,
13688 : dummy,
13689 : HVAC::CompressorOp::Off,
13690 : PartLoadRatio);
13691 : }
13692 0 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
13693 0 : };
13694 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13695 :
13696 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13697 :
13698 0 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13699 0 : (this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::Off &&
13700 0 : this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13701 0 : auto f = [&state, this, DesOutHumRat](Real64 const PartLoadRatio) {
13702 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13703 0 : PackagedThermalStorageCoil::SimTESCoil(state,
13704 : thisSys.m_CoolingCoilName,
13705 0 : thisSys.m_CoolingCoilIndex,
13706 : thisSys.m_FanOpMode,
13707 0 : thisSys.m_TESOpMode,
13708 : PartLoadRatio);
13709 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat - DesOutHumRat;
13710 0 : };
13711 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13712 : }
13713 :
13714 : } else {
13715 : }
13716 : }
13717 : }
13718 : }
13719 65306 : if (SolFla == -1) {
13720 0 : if (!state.dataGlobal->WarmupFlag) {
13721 0 : if (this->warnIndex.m_SensPLRIter < 1) {
13722 0 : ++this->warnIndex.m_SensPLRIter;
13723 0 : ShowWarningError(state,
13724 0 : format("{} - Iteration limit exceeded calculating part-load ratio for unit = {}", this->UnitType, this->Name));
13725 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13726 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13727 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13728 : } else {
13729 0 : ShowRecurringWarningErrorAtEnd(
13730 : state,
13731 0 : this->UnitType + " \"" + this->Name +
13732 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. Sensible PLR statistics follow.",
13733 0 : this->warnIndex.m_SensPLRIterIndex,
13734 : PartLoadFrac,
13735 : PartLoadFrac);
13736 : }
13737 : }
13738 65306 : } else if (SolFla == -2) {
13739 0 : PartLoadFrac = ReqOutput / FullOutput;
13740 0 : if (!state.dataGlobal->WarmupFlag) {
13741 0 : if (this->warnIndex.m_SensPLRFail < 1) {
13742 0 : ++this->warnIndex.m_SensPLRFail;
13743 0 : ShowWarningError(state,
13744 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
13745 0 : this->UnitType,
13746 0 : this->Name));
13747 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13748 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13749 : } else {
13750 0 : ShowRecurringWarningErrorAtEnd(
13751 : state,
13752 0 : this->UnitType + " \"" + this->Name +
13753 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
13754 0 : this->warnIndex.m_SensPLRFailIndex,
13755 : PartLoadFrac,
13756 : PartLoadFrac);
13757 : }
13758 : }
13759 : }
13760 :
13761 65306 : if (SolFlaLat == -1 && SolFla != -1) {
13762 0 : if (!state.dataGlobal->WarmupFlag) {
13763 0 : if (this->warnIndex.m_LatPLRIter < 1) {
13764 0 : ++this->warnIndex.m_LatPLRIter;
13765 0 : ShowWarningError(
13766 0 : state, format("{} - Iteration limit exceeded calculating latent part-load ratio for unit = {}", this->UnitType, this->Name));
13767 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13768 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13769 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13770 : }
13771 0 : ShowRecurringWarningErrorAtEnd(
13772 : state,
13773 0 : this->UnitType + " \"" + this->Name +
13774 : "\" - Iteration limit exceeded calculating latent part-load ratio error continues. Latent PLR statistics follow.",
13775 0 : this->warnIndex.m_LatPLRIterIndex,
13776 : PartLoadFrac,
13777 : PartLoadFrac);
13778 : }
13779 65306 : } else if (SolFlaLat == -2 && SolFla != -2) {
13780 : // RegulaFalsi returns PLR = minPLR when a solution cannot be found, recalculate PartLoadFrac.
13781 0 : if (NoLoadHumRatOut - FullLoadHumRatOut != 0.0) {
13782 0 : PartLoadFrac = (NoLoadHumRatOut - DesOutHumRat) / (NoLoadHumRatOut - FullLoadHumRatOut);
13783 : } else {
13784 0 : PartLoadFrac = 1.0;
13785 : }
13786 0 : if (!state.dataGlobal->WarmupFlag) {
13787 0 : if (this->warnIndex.m_LatPLRFail < 1) {
13788 0 : ++this->warnIndex.m_LatPLRFail;
13789 0 : ShowWarningError(state,
13790 0 : format("{} - latent part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
13791 0 : this->UnitType,
13792 0 : this->Name));
13793 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13794 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13795 : }
13796 0 : ShowRecurringWarningErrorAtEnd(state,
13797 0 : this->UnitType + " \"" + this->Name +
13798 : "\" - latent part-load ratio calculation failed error continues. Latent PLR statistics follow.",
13799 0 : this->warnIndex.m_LatPLRFailIndex,
13800 : PartLoadFrac,
13801 : PartLoadFrac);
13802 : }
13803 : }
13804 : // Set the final results
13805 :
13806 65306 : if (PartLoadFrac > 1.0) {
13807 0 : PartLoadFrac = 1.0;
13808 65306 : } else if (PartLoadFrac < 0.0) {
13809 0 : PartLoadFrac = 0.0;
13810 : }
13811 :
13812 65306 : this->m_CoolingPartLoadFrac = PartLoadFrac;
13813 65306 : this->m_CoolingSpeedRatio = SpeedRatio;
13814 65306 : this->m_CoolingCycRatio = CycRatio;
13815 65306 : this->m_DehumidificationMode = DehumidMode;
13816 :
13817 65306 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
13818 0 : this->m_sysType != SysType::PackagedWSHP) {
13819 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
13820 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
13821 : }
13822 :
13823 65306 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
13824 15 : mdot = PartLoadFrac * this->MaxCoolCoilFluidFlow;
13825 15 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
13826 : }
13827 65306 : } // namespace UnitarySystems
13828 :
13829 31 : void UnitarySys::controlHeatingSystemToSP(EnergyPlusData &state,
13830 : int const AirLoopNum, // index to air loop
13831 : bool const FirstHVACIteration, // First HVAC iteration flag
13832 : HVAC::CompressorOp &compressorOp, // compressor on/off control
13833 : Real64 &HeatCoilLoad // load met by heating coil
13834 : )
13835 : {
13836 : // SUBROUTINE INFORMATION:
13837 : // AUTHOR Richard Raustad, FSEC
13838 : // DATE WRITTEN February 2013
13839 :
13840 : // PURPOSE OF THIS SUBROUTINE:
13841 : // Simulate the coil object at the required PLR.
13842 :
13843 : // METHODOLOGY EMPLOYED:
13844 : // Calculate operating PLR and adjust speed when using multispeed coils.
13845 :
13846 : // SUBROUTINE PARAMETER DEFINITIONS:
13847 31 : int constexpr MaxIte(500); // Maximum number of iterations for solver
13848 31 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
13849 31 : bool constexpr SuppHeatingCoilFlag(false);
13850 :
13851 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13852 31 : Real64 FullOutput = 0; // Sensible capacity (outlet - inlet) when the compressor is on
13853 31 : Real64 ReqOutput = 0; // Sensible capacity (outlet - inlet) required to meet load or set point temperature
13854 :
13855 31 : Real64 OutdoorDryBulb = 0.0; // local variable for OutDryBulbTemp
13856 31 : Real64 OutdoorHumRat = 0.0; // local variable for OutHumRat
13857 31 : Real64 OutdoorPressure = 0.0; // local variable for OutBaroPress
13858 31 : Real64 OutdoorWetBulb = 0.0; // local variable for OutWetBulbTemp
13859 31 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
13860 31 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
13861 :
13862 : // Set local variables
13863 : // Retrieve the load on the controlled zone
13864 31 : int InletNode = this->HeatCoilInletNodeNum;
13865 31 : int OutletNode = this->HeatCoilOutletNodeNum;
13866 31 : std::string CompName = this->m_HeatingCoilName;
13867 31 : int CompIndex = this->m_HeatingCoilIndex;
13868 31 : HVAC::FanOp fanOp = this->m_FanOpMode;
13869 31 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
13870 :
13871 31 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
13872 31 : Real64 LoopDXCoilMaxRTFSave = 0.0;
13873 31 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
13874 0 : this->m_sysType != SysType::PackagedWSHP) {
13875 0 : LoopHeatingCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF;
13876 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
13877 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
13878 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
13879 : }
13880 :
13881 31 : Real64 PartLoadFrac = 0.0;
13882 31 : Real64 SpeedRatio = 0.0;
13883 31 : Real64 CycRatio = 0.0;
13884 31 : Real64 dummy = 0.0;
13885 31 : int SolFla = 0;
13886 31 : Real64 SensLoad = 0.0;
13887 31 : Real64 OutletTemp = 0.0;
13888 :
13889 31 : if (this->m_CondenserNodeNum != 0) {
13890 0 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
13891 0 : if (this->m_CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
13892 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13893 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13894 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
13895 : } else {
13896 0 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
13897 : // IF node is not connected to anything, pressure = default, use weather data
13898 0 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
13899 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13900 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13901 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13902 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
13903 : } else {
13904 0 : OutdoorHumRat = state.dataLoopNodes->Node(this->m_CondenserNodeNum).HumRat;
13905 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
13906 0 : OutdoorWetBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).OutAirWetBulb;
13907 : }
13908 : }
13909 : } else {
13910 31 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13911 31 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13912 31 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13913 31 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
13914 : }
13915 :
13916 : // IF there is a fault of coil SAT Sensor
13917 31 : if (this->m_FaultyCoilSATFlag) {
13918 : // calculate the sensor offset using fault information
13919 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
13920 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
13921 : // update the DesOutTemp
13922 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
13923 : }
13924 :
13925 : // IF DXHeatingSystem is scheduled on and there is flow
13926 62 : if (this->m_sysAvailSched->getCurrentVal() > 0.0 && this->m_heatingCoilAvailSched->getCurrentVal() > 0.0 &&
13927 31 : state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow) {
13928 :
13929 20 : bool SensibleLoad = false;
13930 : // Determine if there is a sensible load on this system
13931 20 : if (DesOutTemp - state.dataLoopNodes->Node(InletNode).Temp > HVAC::TempControlTol) SensibleLoad = true;
13932 : // if a heat pump and other coil is on, disable this coil
13933 20 : if (this->m_HeatPump && this->m_CoolingPartLoadFrac > 0.0) SensibleLoad = false;
13934 :
13935 : // disable compressor if OAT is below minimum outdoor temperature
13936 20 : if (OutdoorDryBulb < this->m_MinOATCompressorHeating) {
13937 0 : SensibleLoad = false;
13938 : }
13939 :
13940 : // IF DXHeatingSystem runs with a heating load then set PartLoadFrac on Heating System
13941 20 : if (SensibleLoad) {
13942 :
13943 18 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13944 54 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
13945 18 : state.dataLoopNodes->Node(InletNode).HumRat,
13946 18 : state.dataLoopNodes->Node(InletNode).Temp,
13947 18 : state.dataLoopNodes->Node(InletNode).HumRat);
13948 18 : ReqOutput = max(0.0, ReqOutput);
13949 :
13950 : // Get no load result
13951 18 : PartLoadFrac = 0.0;
13952 18 : compressorOp = HVAC::CompressorOp::Off;
13953 :
13954 18 : switch (this->m_HeatingCoilType_Num) {
13955 0 : case HVAC::CoilDX_HeatingEmpirical: {
13956 0 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, CompIndex, fanOp, PartLoadFrac);
13957 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13958 0 : } break;
13959 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
13960 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
13961 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
13962 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
13963 0 : if (HeatingActive) PartLoadFrac = 1.0;
13964 :
13965 0 : } break;
13966 11 : case HVAC::CoilDX_MultiSpeedHeating:
13967 : case HVAC::Coil_HeatingElectric_MultiStage:
13968 : case HVAC::Coil_HeatingGas_MultiStage: {
13969 11 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13970 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
13971 0 : this->m_SpeedNum = this->m_HeatingSpeedNum;
13972 0 : bool useMaxedSpeed = false;
13973 0 : if (this->m_SpeedNum > this->m_NumOfSpeedHeating) {
13974 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
13975 0 : this->m_SpeedNum = this->m_NumOfSpeedHeating;
13976 0 : this->m_CoilSpeedErrIdx++;
13977 0 : useMaxedSpeed = true;
13978 0 : ShowRecurringWarningErrorAtEnd(
13979 : state,
13980 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_HeatingCoilName +
13981 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
13982 0 : this->m_CoilSpeedErrIdx,
13983 0 : this->m_EMSOverrideCoilSpeedNumValue,
13984 0 : this->m_EMSOverrideCoilSpeedNumValue,
13985 : _,
13986 : "",
13987 : "");
13988 : }
13989 0 : if (this->m_HeatingSpeedNum == 1) {
13990 0 : this->m_HeatingSpeedRatio = 0.0;
13991 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
13992 0 : this->m_HeatingCycRatio = CycRatio;
13993 0 : if (useMaxedSpeed || CycRatio == 0) {
13994 0 : this->m_HeatingCycRatio = 1;
13995 : } else {
13996 0 : this->m_HeatingCycRatio = CycRatio;
13997 : }
13998 : } else {
13999 0 : this->m_HeatingCycRatio = 1.0;
14000 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14001 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14002 0 : if (useMaxedSpeed || SpeedRatio == 0) {
14003 0 : this->m_HeatingSpeedRatio = 1;
14004 : } else {
14005 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14006 : }
14007 : }
14008 : }
14009 11 : bool LatentLoad = false;
14010 11 : this->simMultiSpeedCoils(
14011 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, this->m_SpeedNum);
14012 11 : } break;
14013 1 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14014 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14015 1 : int SpeedNum = 0;
14016 1 : this->m_HeatingCoilSensDemand = ReqOutput;
14017 1 : VariableSpeedCoils::SimVariableSpeedCoils(
14018 1 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14019 1 : } break;
14020 4 : case HVAC::Coil_HeatingGasOrOtherFuel:
14021 : case HVAC::Coil_HeatingElectric:
14022 : case HVAC::Coil_HeatingDesuperheater: {
14023 4 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, PartLoadFrac, CompIndex, _, _, fanOp);
14024 4 : } break;
14025 2 : case HVAC::Coil_HeatingWater: {
14026 6 : WaterCoils::SimulateWaterCoilComponents(
14027 4 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14028 2 : } break;
14029 0 : case HVAC::Coil_HeatingSteam: {
14030 0 : SteamCoils::SimulateSteamCoilComponents(state,
14031 : CompName,
14032 : FirstHVACIteration,
14033 0 : this->m_HeatingCoilIndex,
14034 0 : 1.0,
14035 : _,
14036 0 : this->m_FanOpMode,
14037 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14038 0 : } break;
14039 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14040 0 : if (FirstHVACIteration) this->m_CompPartLoadRatio = 1;
14041 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14042 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::Off, PartLoadFrac, FirstHVACIteration);
14043 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14044 0 : this->m_HeatingCoilSensDemand = 0.0;
14045 0 : } break;
14046 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14047 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14048 : blankString,
14049 : CompIndex,
14050 : this->MaxHeatAirMassFlow,
14051 : fanOp,
14052 : FirstHVACIteration,
14053 0 : this->m_InitHeatPump,
14054 : ReqOutput,
14055 : dummy,
14056 : HVAC::CompressorOp::Off,
14057 : PartLoadFrac);
14058 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14059 0 : } break;
14060 0 : default:
14061 0 : break;
14062 : }
14063 :
14064 : // IF outlet temp at no load is within ACC of set point, do not run the coil
14065 :
14066 36 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14067 18 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14068 : // do nothing, coil is at the set point.
14069 18 : } else if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) > Acc) { // IF outlet temp is above set point turn off coil
14070 0 : PartLoadFrac = 0.0;
14071 : } else { // ELSE get full load result
14072 :
14073 : // Get full load result
14074 18 : PartLoadFrac = 1.0;
14075 18 : compressorOp = HVAC::CompressorOp::On;
14076 :
14077 18 : switch (this->m_HeatingCoilType_Num) {
14078 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14079 0 : DXCoils::SimDXCoil(
14080 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_HeatingCoilIndex, fanOp, PartLoadFrac);
14081 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14082 0 : } break;
14083 0 : case HVAC::Coil_UserDefined: {
14084 : // should never get here, coil cannot be controlled and has already been simulated
14085 0 : } break;
14086 0 : case HVAC::CoilDX_MultiSpeedHeating: {
14087 0 : CycRatio = 1.0;
14088 0 : SpeedRatio = 0.0;
14089 0 : int SpeedNum = 0;
14090 0 : bool LatentLoad = false;
14091 0 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14092 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14093 0 : SpeedNum = this->m_HeatingSpeedNum;
14094 0 : if (this->m_HeatingSpeedNum == 1) {
14095 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14096 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14097 0 : this->m_HeatingCycRatio = CycRatio;
14098 0 : if (CycRatio == 0) {
14099 0 : this->m_HeatingCycRatio = 1;
14100 : } else {
14101 0 : this->m_HeatingCycRatio = CycRatio;
14102 : }
14103 : } else {
14104 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14105 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14106 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14107 0 : if (SpeedRatio == 0) {
14108 0 : this->m_HeatingSpeedRatio = 1;
14109 : } else {
14110 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14111 : }
14112 : }
14113 0 : if (SpeedNum > this->m_NumOfSpeedHeating) {
14114 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14115 0 : SpeedNum = this->m_NumOfSpeedHeating;
14116 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14117 0 : if (this->m_HeatingSpeedNum == 1) {
14118 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14119 : } else {
14120 0 : this->m_HeatingSpeedRatio = SpeedRatio = 1.0;
14121 : }
14122 : }
14123 0 : this->simMultiSpeedCoils(
14124 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14125 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14126 : } else {
14127 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14128 0 : if (SpeedNum > 1) {
14129 0 : CycRatio = 0.0;
14130 0 : SpeedRatio = 1.0;
14131 : }
14132 0 : this->m_HeatingSpeedNum = SpeedNum;
14133 0 : this->simMultiSpeedCoils(state,
14134 : AirLoopNum,
14135 : FirstHVACIteration,
14136 : compressorOp,
14137 : SensibleLoad,
14138 : LatentLoad,
14139 : PartLoadFrac,
14140 : HeatingCoil,
14141 : SpeedNum);
14142 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14143 0 : if (OutletTemp > DesOutTemp && SensibleLoad) break;
14144 : }
14145 : }
14146 0 : } break;
14147 11 : case HVAC::Coil_HeatingElectric_MultiStage:
14148 : case HVAC::Coil_HeatingGas_MultiStage: {
14149 11 : bool LatentLoad = false;
14150 11 : CycRatio = 1.0;
14151 11 : SpeedRatio = 1.0;
14152 11 : SensLoad = 1.0; // turns on coil
14153 11 : this->m_HeatingSpeedRatio = SpeedRatio;
14154 11 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14155 22 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14156 18 : this->m_HeatingSpeedNum = SpeedNum;
14157 18 : this->simMultiSpeedCoils(
14158 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14159 18 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14160 18 : SpeedRatio = double(SpeedNum) - 1.0;
14161 18 : if (OutletTemp > DesOutTemp && SensibleLoad) break;
14162 : }
14163 11 : } break;
14164 1 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14165 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14166 1 : CycRatio = 1.0;
14167 1 : SpeedRatio = 1.0;
14168 1 : SensLoad = 1.0; // turns on coil
14169 1 : this->m_HeatingSpeedRatio = SpeedRatio;
14170 1 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14171 2 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14172 2 : this->m_HeatingSpeedNum = SpeedNum;
14173 2 : VariableSpeedCoils::SimVariableSpeedCoils(
14174 2 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14175 2 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14176 2 : if (OutletTemp > DesOutTemp && SensibleLoad) break;
14177 : }
14178 1 : } break;
14179 3 : case HVAC::Coil_HeatingGasOrOtherFuel:
14180 : case HVAC::Coil_HeatingElectric: {
14181 6 : HeatingCoils::SimulateHeatingCoilComponents(
14182 3 : state, CompName, FirstHVACIteration, this->m_DesignHeatingCapacity, CompIndex, _, _, fanOp);
14183 3 : } break;
14184 1 : case HVAC::Coil_HeatingDesuperheater: {
14185 1 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, ReqOutput, CompIndex, _, _, fanOp);
14186 1 : } break;
14187 2 : case HVAC::Coil_HeatingWater: {
14188 2 : mdot = this->MaxHeatCoilFluidFlow;
14189 2 : PlantUtilities::SetComponentFlowRate(
14190 2 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14191 :
14192 6 : WaterCoils::SimulateWaterCoilComponents(
14193 4 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14194 2 : } break;
14195 0 : case HVAC::Coil_HeatingSteam: {
14196 0 : mdot = this->MaxHeatCoilFluidFlow;
14197 0 : PlantUtilities::SetComponentFlowRate(
14198 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14199 :
14200 0 : SteamCoils::SimulateSteamCoilComponents(state,
14201 : CompName,
14202 : FirstHVACIteration,
14203 0 : this->m_HeatingCoilIndex,
14204 0 : 1.0,
14205 : _,
14206 0 : this->m_FanOpMode,
14207 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14208 0 : } break;
14209 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14210 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14211 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::On, PartLoadFrac, FirstHVACIteration);
14212 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14213 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14214 0 : } break;
14215 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14216 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14217 : blankString,
14218 : CompIndex,
14219 : this->MaxHeatAirMassFlow,
14220 : fanOp,
14221 : FirstHVACIteration,
14222 0 : this->m_InitHeatPump,
14223 : ReqOutput,
14224 : dummy,
14225 : HVAC::CompressorOp::Off,
14226 : PartLoadFrac);
14227 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14228 0 : } break;
14229 0 : default:
14230 0 : break;
14231 : }
14232 :
14233 18 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14234 18 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
14235 18 : state.dataLoopNodes->Node(OutletNode).HumRat,
14236 18 : state.dataLoopNodes->Node(InletNode).Temp,
14237 18 : state.dataLoopNodes->Node(InletNode).HumRat);
14238 : // If the outlet temp is within ACC of set point,
14239 34 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14240 16 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14241 : // do nothing, coil is at set point
14242 16 : } else if (state.dataLoopNodes->Node(OutletNode).Temp < (DesOutTemp - Acc)) { // IF outlet temp is below set point coil must be on
14243 3 : PartLoadFrac = 1.0;
14244 : } else { // ELSE find the PLR to meet the set point
14245 :
14246 13 : switch (this->m_HeatingCoilType_Num) {
14247 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14248 0 : auto f = [&state, CompIndex, DesOutTemp](Real64 const PartLoadFrac) {
14249 0 : DXCoils::CalcDXHeatingCoil(state, CompIndex, PartLoadFrac, HVAC::FanOp::Continuous, 1.0);
14250 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(CompIndex);
14251 0 : };
14252 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14253 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14254 0 : } break;
14255 8 : case HVAC::CoilDX_MultiSpeedHeating:
14256 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14257 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
14258 : case HVAC::Coil_HeatingElectric_MultiStage:
14259 : case HVAC::Coil_HeatingGas_MultiStage: {
14260 8 : if (this->m_HeatingSpeedNum > 1.0) {
14261 12 : auto f = [&state, this, DesOutTemp, CycRatio, fanOp](Real64 const SpeedRatio) {
14262 24 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14263 : SpeedRatio,
14264 12 : this->m_HeatingCoilIndex,
14265 : DesOutTemp,
14266 12 : this->m_UnitarySysNum,
14267 : CycRatio,
14268 12 : this->m_HeatingSpeedNum,
14269 : fanOp,
14270 : HVAC::CompressorOp::On,
14271 12 : false);
14272 4 : };
14273 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14274 4 : this->m_HeatingCycRatio = CycRatio;
14275 4 : this->m_HeatingSpeedRatio = SpeedRatio;
14276 4 : this->m_HeatingPartLoadFrac = SpeedRatio;
14277 4 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14278 4 : PartLoadFrac = SpeedRatio;
14279 : } else {
14280 4 : SpeedRatio = 0.0;
14281 4 : this->m_HeatingSpeedRatio = SpeedRatio;
14282 12 : auto f = [&state, this, DesOutTemp, SpeedRatio, fanOp](Real64 const CycRatio) {
14283 24 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14284 : CycRatio,
14285 12 : this->m_HeatingCoilIndex,
14286 : DesOutTemp,
14287 12 : this->m_UnitarySysNum,
14288 : SpeedRatio,
14289 12 : this->m_HeatingSpeedNum,
14290 : fanOp,
14291 : HVAC::CompressorOp::On,
14292 12 : false);
14293 4 : };
14294 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14295 4 : this->m_HeatingCycRatio = CycRatio;
14296 4 : this->m_HeatingPartLoadFrac = CycRatio;
14297 4 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14298 4 : PartLoadFrac = CycRatio;
14299 : }
14300 8 : } break;
14301 1 : case HVAC::Coil_HeatingGasOrOtherFuel: {
14302 3 : HeatingCoils::SimulateHeatingCoilComponents(
14303 2 : state, this->m_HeatingCoilName, FirstHVACIteration, ReqOutput, CompIndex, _, true, fanOp, PartLoadFrac);
14304 1 : PartLoadFrac = ReqOutput / FullOutput;
14305 1 : HeatCoilLoad = ReqOutput;
14306 1 : } break;
14307 2 : case HVAC::Coil_HeatingElectric:
14308 : case HVAC::Coil_HeatingDesuperheater: {
14309 2 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14310 6 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, fanOp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14311 12 : return this->gasElecHeatingCoilResidual(state,
14312 : PartLoadFrac,
14313 6 : this->m_UnitarySysNum,
14314 : FirstHVACIteration,
14315 : DesOutTemp,
14316 : tmpSuppHeatingCoilFlag,
14317 : fanOp,
14318 6 : this->m_DesignHeatingCapacity);
14319 2 : };
14320 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14321 2 : } break;
14322 2 : case HVAC::Coil_HeatingWater: {
14323 :
14324 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14325 : maxPartLoadFrac =
14326 2 : min(1.0,
14327 2 : ((mdot / this->MaxHeatCoilFluidFlow) +
14328 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14329 :
14330 16 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const maxPartLoadFrac) {
14331 : Real64 OutletAirTemp; // Outlet air temperature [C]
14332 :
14333 16 : Real64 mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14334 16 : this->MaxHeatCoilFluidFlow * maxPartLoadFrac);
14335 16 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14336 48 : WaterCoils::SimulateWaterCoilComponents(state,
14337 16 : this->m_HeatingCoilName,
14338 : FirstHVACIteration,
14339 16 : this->m_HeatingCoilIndex,
14340 32 : 0.0, // QActual
14341 16 : this->m_FanOpMode,
14342 : maxPartLoadFrac);
14343 16 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14344 16 : return DesOutTemp - OutletAirTemp;
14345 2 : };
14346 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14347 2 : } break;
14348 0 : case HVAC::Coil_HeatingSteam: {
14349 :
14350 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14351 : maxPartLoadFrac =
14352 0 : min(1.0,
14353 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14354 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14355 :
14356 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14357 : Real64 OutletAirTemp; // Outlet air temperature [C]
14358 : Real64 mdot;
14359 :
14360 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14361 0 : this->MaxHeatCoilFluidFlow * PartLoadFrac);
14362 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14363 0 : SteamCoils::SimulateSteamCoilComponents(state,
14364 0 : this->m_HeatingCoilName,
14365 : FirstHVACIteration,
14366 0 : this->m_HeatingCoilIndex,
14367 0 : 1.0,
14368 : _,
14369 0 : this->m_FanOpMode,
14370 : PartLoadFrac);
14371 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp; // RR this should be supp coil
14372 0 : return DesOutTemp - OutletAirTemp;
14373 0 : };
14374 :
14375 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14376 0 : } break;
14377 0 : case HVAC::Coil_HeatingWaterToAirHPSimple:
14378 : case HVAC::Coil_HeatingWaterToAirHP: {
14379 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14380 :
14381 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
14382 : Real64 OutletAirTemp; // outlet air humidity ratio [kg/kg]
14383 : Real64 dummy;
14384 :
14385 0 : this->m_CompPartLoadRatio = PartLoadRatio;
14386 :
14387 0 : dummy = 0.0;
14388 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
14389 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14390 : blankString,
14391 0 : this->m_HeatingCoilIndex,
14392 : ReqOutput,
14393 : dummy,
14394 0 : this->m_FanOpMode,
14395 : HVAC::CompressorOp::On,
14396 : PartLoadRatio,
14397 : FirstHVACIteration);
14398 : } else {
14399 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14400 : blankString,
14401 0 : this->m_HeatingCoilIndex,
14402 0 : this->MaxHeatAirMassFlow,
14403 0 : this->m_FanOpMode,
14404 : FirstHVACIteration,
14405 0 : this->m_InitHeatPump,
14406 : ReqOutput,
14407 : dummy,
14408 : HVAC::CompressorOp::Off,
14409 : PartLoadRatio);
14410 : }
14411 :
14412 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14413 0 : return DesOutTemp - OutletAirTemp;
14414 0 : };
14415 :
14416 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14417 0 : } break;
14418 0 : case HVAC::Coil_UserDefined: {
14419 : // should never get here, user defined coil cannot be controlled and has already been simulated
14420 0 : } break;
14421 0 : default: {
14422 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
14423 0 : ShowFatalError(
14424 : state,
14425 0 : format("ControlHeatingSystemToSP: Invalid heating coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
14426 0 : } break;
14427 : }
14428 : }
14429 : }
14430 : }
14431 : }
14432 :
14433 31 : if (PartLoadFrac > 1.0) {
14434 0 : PartLoadFrac = 1.0;
14435 31 : } else if (PartLoadFrac < 0.0) {
14436 0 : PartLoadFrac = 0.0;
14437 : }
14438 :
14439 31 : if (SolFla < 0) {
14440 0 : if (SolFla == -1) {
14441 0 : if (!state.dataGlobal->WarmupFlag) {
14442 0 : if (this->warnIndex.m_HeatCoilSensPLRIter < 1) {
14443 0 : ++this->warnIndex.m_HeatCoilSensPLRIter;
14444 0 : ShowWarningError(
14445 : state,
14446 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}", this->UnitType, this->Name));
14447 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14448 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14449 0 : ShowContinueErrorTimeStamp(state,
14450 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14451 : } else {
14452 0 : ShowRecurringWarningErrorAtEnd(state,
14453 0 : this->UnitType + " \"" + this->Name +
14454 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. "
14455 : "Sensible PLR statistics follow.",
14456 0 : this->warnIndex.m_HeatCoilSensPLRIterIndex,
14457 : PartLoadFrac,
14458 : PartLoadFrac);
14459 : }
14460 : }
14461 0 : } else if (SolFla == -2) {
14462 0 : PartLoadFrac = ReqOutput / FullOutput;
14463 0 : if (!state.dataGlobal->WarmupFlag) {
14464 0 : if (this->warnIndex.m_HeatCoilSensPLRFail < 1) {
14465 0 : ++this->warnIndex.m_HeatCoilSensPLRFail;
14466 0 : ShowWarningError(state,
14467 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14468 0 : this->UnitType,
14469 0 : this->Name));
14470 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14471 0 : ShowContinueErrorTimeStamp(state,
14472 : "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14473 : } else {
14474 0 : ShowRecurringWarningErrorAtEnd(
14475 : state,
14476 0 : this->UnitType + " \"" + this->Name +
14477 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14478 0 : this->warnIndex.m_HeatCoilSensPLRFailIndex,
14479 : PartLoadFrac,
14480 : PartLoadFrac);
14481 : }
14482 : }
14483 : }
14484 : }
14485 :
14486 : // Set the final results
14487 31 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14488 31 : this->m_HeatingSpeedRatio = SpeedRatio;
14489 31 : this->m_HeatingCycRatio = CycRatio;
14490 31 : HeatCoilLoad = ReqOutput;
14491 :
14492 31 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14493 0 : this->m_sysType != SysType::PackagedWSHP) {
14494 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF =
14495 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14496 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14497 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14498 : }
14499 :
14500 31 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
14501 4 : mdot = PartLoadFrac * this->MaxHeatCoilFluidFlow;
14502 4 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14503 : }
14504 31 : }
14505 :
14506 11 : void UnitarySys::controlSuppHeatSystemToSP(EnergyPlusData &state,
14507 : int const AirLoopNum, // index to air loop
14508 : bool const FirstHVACIteration // First HVAC iteration flag
14509 : )
14510 : {
14511 : // SUBROUTINE INFORMATION:
14512 : // AUTHOR Richard Raustad, FSEC
14513 : // DATE WRITTEN February 2013
14514 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
14515 :
14516 : // PURPOSE OF THIS SUBROUTINE:
14517 : // This subroutine updates the System outlet nodes.
14518 :
14519 : // METHODOLOGY EMPLOYED:
14520 : // Data is moved from the System data structure to the System outlet nodes.
14521 :
14522 : // SUBROUTINE PARAMETER DEFINITIONS:
14523 11 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14524 11 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14525 11 : int constexpr SolveMaxIter(50);
14526 11 : constexpr bool SuppHeatingCoilFlag(true);
14527 :
14528 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14529 11 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
14530 11 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14531 11 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14532 11 : Real64 PartLoadFrac = 0.0;
14533 11 : Real64 SpeedRatio = 0.0;
14534 11 : Real64 CycRatio = 0.0;
14535 :
14536 : // Set local variables
14537 11 : auto &inletNode = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode);
14538 11 : auto &outletNode = state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum);
14539 11 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14540 11 : std::string_view CompName = this->m_SuppHeatCoilName;
14541 :
14542 11 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14543 11 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14544 11 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14545 0 : this->m_sysType != SysType::PackagedWSHP) {
14546 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14547 0 : LoopHeatingCoilMaxRTFSave = afnInfo.AFNLoopHeatingCoilMaxRTF;
14548 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = 0.0;
14549 0 : LoopDXCoilMaxRTFSave = afnInfo.AFNLoopDXCoilRTF;
14550 0 : afnInfo.AFNLoopDXCoilRTF = 0.0;
14551 : }
14552 :
14553 : // IF there is a fault of coil SAT Sensor
14554 11 : if (this->m_FaultyCoilSATFlag) {
14555 : // calculate the sensor offset using fault information
14556 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14557 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14558 : // update the DesOutTemp
14559 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14560 : }
14561 :
14562 11 : if ((this->m_sysAvailSched->getCurrentVal() > 0.0) && (inletNode.MassFlowRate > HVAC::SmallAirVolFlow)) {
14563 :
14564 8 : if (inletNode.Temp < (DesOutTemp - HVAC::TempControlTol)) {
14565 6 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
14566 2 : this->setEMSSuppCoilStagePLR(state);
14567 : } else {
14568 : // Get no load result at PartLoadFrac = 0.0
14569 :
14570 4 : switch (this->m_SuppHeatCoilType_Num) {
14571 0 : case HVAC::Coil_HeatingGasOrOtherFuel:
14572 : case HVAC::Coil_HeatingElectric:
14573 : case HVAC::Coil_HeatingDesuperheater: {
14574 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
14575 : CompName,
14576 : FirstHVACIteration,
14577 : PartLoadFrac,
14578 0 : this->m_SuppHeatCoilIndex,
14579 : QCoilActual,
14580 : SuppHeatingCoilFlag,
14581 0 : this->m_FanOpMode,
14582 : PartLoadFrac); // QCoilReq=PartLoadFrac 0.0 for this call
14583 0 : } break;
14584 2 : case HVAC::Coil_HeatingElectric_MultiStage: {
14585 : // SpeedRatio = 0.0;
14586 8 : HeatingCoils::SimulateHeatingCoilComponents(state,
14587 : CompName,
14588 : FirstHVACIteration,
14589 : DataLoopNode::SensedLoadFlagValue,
14590 2 : this->m_SuppHeatCoilIndex,
14591 : QCoilActual,
14592 : SuppHeatingCoilFlag,
14593 2 : this->m_FanOpMode,
14594 : PartLoadFrac,
14595 4 : 0,
14596 : SpeedRatio);
14597 2 : } break;
14598 2 : case HVAC::Coil_HeatingWater: {
14599 6 : WaterCoils::SimulateWaterCoilComponents(
14600 4 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14601 2 : } break;
14602 0 : case HVAC::Coil_HeatingSteam: {
14603 0 : SteamCoils::SimulateSteamCoilComponents(state,
14604 : CompName,
14605 : FirstHVACIteration,
14606 0 : this->m_SuppHeatCoilIndex,
14607 0 : 1.0,
14608 : _,
14609 0 : this->m_FanOpMode,
14610 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14611 0 : } break;
14612 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
14613 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14614 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14615 0 : UserDefinedComponents::SimCoilUserDefined(
14616 0 : state, CompName, this->m_SuppHeatCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
14617 0 : if (HeatingActive) PartLoadFrac = 1.0;
14618 0 : } break;
14619 0 : default:
14620 0 : break;
14621 : }
14622 :
14623 4 : int SolFla = 0;
14624 : // If OutletTemp is within ACC of set point coil operation is not needed or UserDefined already met load.
14625 4 : if (outletNode.Temp > (DesOutTemp - Acc) || this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
14626 : // do nothing, coil is at or above set point
14627 : } else {
14628 : // outlet temp too low, turn on coil
14629 : // Get full load result
14630 4 : PartLoadFrac = 1.0;
14631 :
14632 4 : switch (this->m_SuppHeatCoilType_Num) {
14633 0 : case HVAC::Coil_HeatingGasOrOtherFuel:
14634 : case HVAC::Coil_HeatingElectric: {
14635 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
14636 : CompName,
14637 : FirstHVACIteration,
14638 0 : this->m_DesignSuppHeatingCapacity,
14639 0 : this->m_SuppHeatCoilIndex,
14640 : QCoilActual,
14641 : SuppHeatingCoilFlag,
14642 0 : this->m_FanOpMode,
14643 : PartLoadFrac);
14644 0 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
14645 0 : PartLoadFrac = QCoilActual / this->m_DesignSuppHeatingCapacity;
14646 : }
14647 0 : } break;
14648 2 : case HVAC::Coil_HeatingElectric_MultiStage: {
14649 2 : CycRatio = 1.0;
14650 2 : SpeedRatio = 1.0;
14651 2 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
14652 2 : this->m_SuppHeatingSpeedNum = SpeedNum;
14653 6 : HeatingCoils::SimulateHeatingCoilComponents(state,
14654 : CompName,
14655 : FirstHVACIteration,
14656 : DataLoopNode::SensedLoadFlagValue,
14657 2 : this->m_SuppHeatCoilIndex,
14658 : QCoilActual,
14659 : SuppHeatingCoilFlag,
14660 2 : this->m_FanOpMode,
14661 : PartLoadFrac,
14662 : SpeedNum,
14663 : SpeedRatio);
14664 2 : if (outletNode.Temp > DesOutTemp) break;
14665 : }
14666 2 : } break;
14667 0 : case HVAC::Coil_HeatingDesuperheater: {
14668 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
14669 : CompName,
14670 : FirstHVACIteration,
14671 0 : this->m_DesignSuppHeatingCapacity,
14672 0 : this->m_SuppHeatCoilIndex,
14673 : _,
14674 : SuppHeatingCoilFlag,
14675 0 : this->m_FanOpMode);
14676 0 : } break;
14677 2 : case HVAC::Coil_HeatingWater: {
14678 2 : mdot = this->m_MaxSuppCoilFluidFlow;
14679 2 : PlantUtilities::SetComponentFlowRate(
14680 2 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
14681 :
14682 6 : WaterCoils::SimulateWaterCoilComponents(
14683 4 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14684 2 : } break;
14685 0 : case HVAC::Coil_HeatingSteam: {
14686 0 : mdot = this->m_MaxSuppCoilFluidFlow;
14687 0 : PlantUtilities::SetComponentFlowRate(
14688 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
14689 :
14690 0 : SteamCoils::SimulateSteamCoilComponents(state,
14691 : CompName,
14692 : FirstHVACIteration,
14693 0 : this->m_SuppHeatCoilIndex,
14694 0 : 1.0,
14695 : _,
14696 0 : this->m_FanOpMode,
14697 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14698 0 : } break;
14699 0 : case HVAC::Coil_UserDefined: {
14700 : // should never get here, coil has already been simulated
14701 0 : } break;
14702 0 : default:
14703 0 : break;
14704 : }
14705 :
14706 : // run the coil at PartLoadFrac = 1.
14707 4 : if (outletNode.Temp < (DesOutTemp + Acc)) {
14708 0 : PartLoadFrac = 1.0; // these have already been set, leave as is for now
14709 0 : CycRatio = 1.0; // change to outletNode.Temp > and removed these vars and the "} else {"
14710 0 : SpeedRatio = 1.0;
14711 : } else {
14712 4 : switch (this->m_SuppHeatCoilType_Num) {
14713 0 : case HVAC::Coil_HeatingGasOrOtherFuel:
14714 : case HVAC::Coil_HeatingElectric:
14715 : case HVAC::Coil_HeatingDesuperheater: {
14716 0 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14717 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14718 0 : return this->gasElecHeatingCoilResidual(state,
14719 : PartLoadFrac,
14720 0 : this->m_UnitarySysNum,
14721 : FirstHVACIteration,
14722 : DesOutTemp,
14723 : tmpSuppHeatingCoilFlag,
14724 0 : this->m_FanOpMode,
14725 0 : this->m_DesignSuppHeatingCapacity);
14726 0 : };
14727 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14728 0 : } break;
14729 2 : case HVAC::Coil_HeatingElectric_MultiStage: {
14730 2 : if (this->m_SuppHeatingSpeedNum > 1) {
14731 0 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
14732 0 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14733 : SpeedRatio,
14734 0 : this->m_SuppHeatCoilIndex,
14735 : DesOutTemp,
14736 0 : this->m_UnitarySysNum,
14737 : CycRatio,
14738 0 : this->m_SuppHeatingSpeedNum,
14739 0 : this->m_FanOpMode,
14740 : HVAC::CompressorOp::On,
14741 0 : true);
14742 0 : };
14743 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14744 0 : PartLoadFrac = SpeedRatio;
14745 : } else {
14746 2 : SpeedRatio = 0.0;
14747 2 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
14748 6 : auto f = [&state, this, DesOutTemp, SpeedRatio](Real64 const CycRatio) {
14749 12 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14750 : CycRatio,
14751 6 : this->m_SuppHeatCoilIndex,
14752 : DesOutTemp,
14753 6 : this->m_UnitarySysNum,
14754 : SpeedRatio,
14755 6 : this->m_SuppHeatingSpeedNum,
14756 6 : this->m_FanOpMode,
14757 : HVAC::CompressorOp::On,
14758 6 : true);
14759 2 : };
14760 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14761 2 : PartLoadFrac = CycRatio;
14762 : }
14763 2 : } break;
14764 2 : case HVAC::Coil_HeatingWater: {
14765 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14766 : maxPartLoadFrac =
14767 2 : min(1.0,
14768 2 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
14769 : // max iteration limit (leave a little slop, 0.001)
14770 20 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14771 20 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14772 20 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
14773 20 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
14774 60 : WaterCoils::SimulateWaterCoilComponents(state,
14775 20 : this->m_SuppHeatCoilName,
14776 : FirstHVACIteration,
14777 20 : this->m_SuppHeatCoilIndex,
14778 40 : 0.0, // QActual
14779 20 : this->m_FanOpMode,
14780 : PartLoadFrac);
14781 :
14782 20 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
14783 2 : };
14784 :
14785 2 : General::SolveRoot(state, Acc, SolveMaxIter, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14786 2 : } break;
14787 0 : case HVAC::Coil_HeatingSteam: {
14788 :
14789 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14790 : maxPartLoadFrac =
14791 0 : min(1.0,
14792 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
14793 : // max iteration limit (leave a little slop, 0.001)
14794 :
14795 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14796 : Real64 mdot;
14797 :
14798 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14799 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
14800 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
14801 0 : SteamCoils::SimulateSteamCoilComponents(state,
14802 0 : this->m_SuppHeatCoilName,
14803 : FirstHVACIteration,
14804 0 : this->m_SuppHeatCoilIndex,
14805 0 : 1.0,
14806 : _,
14807 0 : this->m_FanOpMode,
14808 : PartLoadFrac);
14809 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
14810 0 : };
14811 :
14812 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14813 0 : } break;
14814 0 : case HVAC::Coil_UserDefined: {
14815 : // do nothing, coil has already been simulated
14816 0 : } break;
14817 0 : default:
14818 0 : break;
14819 : }
14820 : }
14821 : } // IF (outletNode.Temp < (DesOutTemp + Acc)) THEN
14822 :
14823 4 : if (PartLoadFrac > 1.0) {
14824 0 : PartLoadFrac = 1.0;
14825 4 : } else if (PartLoadFrac < 0.0) {
14826 0 : PartLoadFrac = 0.0;
14827 : }
14828 :
14829 4 : if (SolFla == -1) {
14830 0 : if (!state.dataGlobal->WarmupFlag) {
14831 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRIter < 1) {
14832 0 : Real64 ReqOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
14833 0 : DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14834 : Real64 FullOutput =
14835 0 : inletNode.MassFlowRate *
14836 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14837 :
14838 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRIter;
14839 0 : ShowWarningError(state,
14840 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}",
14841 0 : this->UnitType,
14842 0 : this->Name));
14843 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14844 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14845 0 : ShowContinueErrorTimeStamp(
14846 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14847 : } else {
14848 0 : ShowRecurringWarningErrorAtEnd(state,
14849 0 : format("{} \"{}\" - Iteration limit exceeded calculating sensible part-load ratio "
14850 : "error continues. Sensible PLR statistics follow.",
14851 0 : this->UnitType,
14852 0 : this->Name),
14853 0 : this->warnIndex.m_SuppHeatCoilSensPLRIterIndex,
14854 : PartLoadFrac,
14855 : PartLoadFrac);
14856 : }
14857 : } // IF(.NOT. WarmupFlag)THEN
14858 4 : } else if (SolFla == -2) {
14859 0 : Real64 ReqOutput = inletNode.MassFlowRate *
14860 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14861 0 : Real64 FullOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
14862 0 : outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14863 :
14864 0 : PartLoadFrac = ReqOutput / FullOutput;
14865 0 : if (!state.dataGlobal->WarmupFlag) {
14866 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRFail < 1) {
14867 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRFail;
14868 0 : ShowWarningError(
14869 : state,
14870 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14871 0 : this->UnitType,
14872 0 : this->Name));
14873 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14874 0 : ShowContinueErrorTimeStamp(
14875 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14876 : } else {
14877 0 : ShowRecurringWarningErrorAtEnd(
14878 : state,
14879 0 : format("{} \"{}\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14880 0 : this->UnitType,
14881 0 : this->Name),
14882 0 : this->warnIndex.m_SuppHeatCoilSensPLRFailIndex,
14883 : PartLoadFrac,
14884 : PartLoadFrac);
14885 : }
14886 : }
14887 : } // IF (SolFla == -1) THEN
14888 :
14889 4 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
14890 4 : this->m_SuppHeatingCycRatio = CycRatio;
14891 4 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
14892 : } // IF (NOT EMS OVERRIDE) THEN
14893 :
14894 : } // IF SENSIBLE LOAD
14895 : } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. &
14896 :
14897 : // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel)
14898 11 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14899 0 : this->m_sysType != SysType::PackagedWSHP) {
14900 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14901 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = max(afnInfo.AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14902 0 : afnInfo.AFNLoopDXCoilRTF = max(afnInfo.AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14903 : }
14904 :
14905 11 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
14906 4 : mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow;
14907 4 : PlantUtilities::SetComponentFlowRate(
14908 4 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
14909 : }
14910 11 : }
14911 :
14912 38 : void UnitarySys::simMultiSpeedCoils(EnergyPlusData &state,
14913 : int const AirLoopNum, // Index to air loop
14914 : bool const FirstHVACIteration, // True when first HVAC iteration
14915 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
14916 : bool const SensibleLoad,
14917 : bool const LatentLoad,
14918 : Real64 const PartLoadFrac,
14919 : int const CoilType,
14920 : int const SpeedNumber)
14921 : {
14922 :
14923 : // SUBROUTINE INFORMATION:
14924 : // AUTHOR Chandan Sharma, FSEC
14925 : // DATE WRITTEN March 2013
14926 :
14927 : // PURPOSE OF THIS SUBROUTINE:
14928 : // This subroutine manages multispeed and variable speed cooling coil simulation.
14929 :
14930 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14931 38 : std::string CompName; // Name of Unitary System object
14932 38 : Real64 SensLoad = 0.0;
14933 38 : Real64 LatLoad = 0.0;
14934 38 : int CoilTypeNum = 0;
14935 38 : int CompIndex = 0;
14936 38 : Real64 SpeedRatio = 0.0;
14937 38 : Real64 CycRatio = 0.0;
14938 38 : Real64 dummy = 0.0;
14939 :
14940 38 : if (CoilType == CoolingCoil) {
14941 :
14942 9 : CompName = this->m_CoolingCoilName;
14943 9 : CompIndex = this->m_CoolingCoilIndex;
14944 9 : CoilTypeNum = this->m_CoolingCoilType_Num;
14945 9 : if (SensibleLoad) {
14946 9 : SensLoad = -1.0;
14947 9 : state.dataUnitarySystems->CoolingLoad = true;
14948 9 : state.dataUnitarySystems->HeatingLoad = false;
14949 : }
14950 9 : if (LatentLoad) LatLoad = -1.0;
14951 :
14952 : } else {
14953 :
14954 29 : CompName = this->m_HeatingCoilName;
14955 29 : CompIndex = this->m_HeatingCoilIndex;
14956 29 : CoilTypeNum = this->m_HeatingCoilType_Num;
14957 :
14958 29 : if (SensibleLoad) {
14959 29 : SensLoad = 1.0;
14960 29 : state.dataUnitarySystems->CoolingLoad = false;
14961 29 : state.dataUnitarySystems->HeatingLoad = true;
14962 : } else {
14963 0 : SensLoad = 0.0;
14964 0 : state.dataUnitarySystems->HeatingLoad = false;
14965 : }
14966 29 : LatLoad = 0.0;
14967 : }
14968 :
14969 38 : Real64 OnOffAirFlowRatio = 1.0;
14970 38 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadFrac); // 1.0d0 = PartLoadRatio
14971 :
14972 38 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14973 :
14974 38 : if ((CoilTypeNum == HVAC::CoilDX_MultiSpeedCooling) || (CoilTypeNum == HVAC::CoilDX_MultiSpeedHeating)) {
14975 9 : DXCoils::SimDXCoilMultiSpeed(
14976 9 : state, CompName, 0.0, PartLoadFrac, CompIndex, SpeedNumber, this->m_FanOpMode, HVAC::CompressorOp::On, this->m_SingleMode);
14977 :
14978 29 : } else if (CoilTypeNum == HVAC::CoilDX_Cooling) {
14979 0 : bool const singleMode = (this->m_SingleMode == 1);
14980 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
14981 0 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
14982 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
14983 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
14984 0 : coilMode = HVAC::CoilMode::Enhanced;
14985 : }
14986 :
14987 0 : state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
14988 : state, coilMode, this->m_CoolingSpeedNum, PartLoadFrac, this->m_FanOpMode, singleMode, this->CoilSHR);
14989 :
14990 29 : } else if (CoilTypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
14991 :
14992 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
14993 : CompName,
14994 : CompIndex,
14995 : this->m_FanOpMode,
14996 : CompressorOn,
14997 : PartLoadFrac,
14998 : SpeedNumber,
14999 : this->m_CoolingSpeedRatio,
15000 : SensLoad,
15001 : dummy,
15002 : OnOffAirFlowRatio);
15003 :
15004 29 : } else if (CoilTypeNum == HVAC::Coil_HeatingAirToAirVariableSpeed) {
15005 :
15006 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15007 : CompName,
15008 : CompIndex,
15009 : this->m_FanOpMode,
15010 : CompressorOn,
15011 : PartLoadFrac,
15012 : SpeedNumber,
15013 : this->m_HeatingSpeedRatio,
15014 : SensLoad,
15015 : dummy,
15016 : OnOffAirFlowRatio);
15017 :
15018 29 : } else if (CoilTypeNum == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
15019 :
15020 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15021 : CompName,
15022 : CompIndex,
15023 : this->m_FanOpMode,
15024 : CompressorOn,
15025 : PartLoadFrac,
15026 : SpeedNumber,
15027 : this->m_CoolingSpeedRatio,
15028 : SensLoad,
15029 : dummy,
15030 : OnOffAirFlowRatio);
15031 :
15032 29 : } else if (CoilTypeNum == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
15033 :
15034 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15035 : CompName,
15036 : CompIndex,
15037 : this->m_FanOpMode,
15038 : CompressorOn,
15039 : PartLoadFrac,
15040 : SpeedNumber,
15041 : this->m_HeatingSpeedRatio,
15042 : SensLoad,
15043 : dummy,
15044 : OnOffAirFlowRatio);
15045 :
15046 29 : } else if ((CoilTypeNum == HVAC::Coil_HeatingElectric_MultiStage) || (CoilTypeNum == HVAC::Coil_HeatingGas_MultiStage)) {
15047 :
15048 58 : HeatingCoils::SimulateHeatingCoilComponents(
15049 58 : state, CompName, FirstHVACIteration, _, CompIndex, _, _, this->m_FanOpMode, PartLoadFrac, SpeedNumber, this->m_HeatingSpeedRatio);
15050 : } else {
15051 : }
15052 38 : }
15053 :
15054 60 : void UnitarySys::calcPassiveSystem(EnergyPlusData &state,
15055 : int const AirLoopNum, // index to air loop
15056 : bool const FirstHVACIteration // True when first HVAC iteration
15057 : )
15058 : {
15059 :
15060 : // SUBROUTINE INFORMATION:
15061 : // AUTHOR Richard Raustad, FSEC
15062 : // DATE WRITTEN February 2013
15063 :
15064 : // PURPOSE OF THIS SUBROUTINE:
15065 : // This subroutine calculates the set point based output of the unitary system.
15066 :
15067 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15068 60 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
15069 60 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off; // compressor control (0=off, 1=on)
15070 60 : Real64 OnOffAirFlowRatio = 1.0;
15071 60 : Real64 CoilCoolHeatRat = 1.0;
15072 60 : Real64 HeatCoilLoad = 0.0;
15073 : // CALL the series of components that simulate a Unitary System
15074 60 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
15075 52 : state.dataFans->fans(this->m_FanIndex)
15076 156 : ->simulate(state,
15077 : FirstHVACIteration,
15078 52 : state.dataUnitarySystems->FanSpeedRatio,
15079 : _, // Pressure rise
15080 : _, // Flow fraction
15081 52 : state.dataUnitarySystems->m_massFlow1,
15082 52 : state.dataUnitarySystems->m_runTimeFraction1,
15083 52 : state.dataUnitarySystems->m_massFlow2,
15084 52 : state.dataUnitarySystems->m_runTimeFraction2,
15085 : _);
15086 : }
15087 :
15088 60 : if (this->m_CoolingCoilUpstream) {
15089 :
15090 24 : if (this->m_CoolCoilExists) {
15091 24 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15092 24 : CompressorOn = HVAC::CompressorOp::Off;
15093 24 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15094 24 : bool HXUnitOn = false;
15095 24 : this->calcUnitaryCoolingSystem(
15096 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15097 : }
15098 24 : if (this->m_HeatCoilExists) {
15099 2 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15100 2 : CompressorOn = HVAC::CompressorOp::Off;
15101 2 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15102 2 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15103 : }
15104 :
15105 : } else {
15106 :
15107 36 : if (this->m_HeatCoilExists) {
15108 36 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15109 36 : CompressorOn = HVAC::CompressorOp::Off;
15110 36 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15111 36 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15112 : }
15113 36 : if (this->m_CoolCoilExists) {
15114 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15115 0 : CompressorOn = HVAC::CompressorOp::Off;
15116 0 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15117 0 : bool HXUnitOn = false;
15118 0 : this->calcUnitaryCoolingSystem(
15119 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15120 : }
15121 : }
15122 :
15123 60 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
15124 0 : state.dataFans->fans(this->m_FanIndex)
15125 0 : ->simulate(state,
15126 : FirstHVACIteration,
15127 0 : state.dataUnitarySystems->FanSpeedRatio,
15128 : _, // Pressure rise
15129 : _, // Flow fraction
15130 0 : state.dataUnitarySystems->m_massFlow1,
15131 0 : state.dataUnitarySystems->m_runTimeFraction1,
15132 0 : state.dataUnitarySystems->m_massFlow2,
15133 0 : state.dataUnitarySystems->m_runTimeFraction2,
15134 : _);
15135 : }
15136 :
15137 : // CALL reheat coils next
15138 60 : if (this->m_SuppCoilExists) {
15139 15 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
15140 15 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
15141 15 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
15142 : }
15143 60 : }
15144 :
15145 72368 : void UnitarySys::reportUnitarySystem(EnergyPlusData &state, int const AirLoopNum)
15146 : {
15147 :
15148 : // SUBROUTINE INFORMATION:
15149 : // AUTHOR Chandan Sharma
15150 : // DATE WRITTEN July 2013
15151 :
15152 : // PURPOSE OF THIS SUBROUTINE:
15153 : // This subroutine updates the report variable for the coils.
15154 :
15155 72368 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15156 :
15157 72368 : Real64 SensibleOutput = 0.0; // sensible output rate, {W}
15158 72368 : Real64 LatentOutput = 0.0; // latent output rate, {W}
15159 72368 : Real64 TotalOutput = 0.0; // total output rate, {W}
15160 72368 : Real64 QTotUnitOut = 0.0;
15161 72368 : Real64 QSensUnitOut = 0.0;
15162 72368 : this->m_PartLoadFrac = 0.0;
15163 72368 : this->m_CompPartLoadRatio = 0.0;
15164 72368 : this->m_CycRatio = 0.0;
15165 72368 : this->m_SpeedRatio = 0.0;
15166 72368 : this->FanPartLoadRatio = 0.0;
15167 72368 : this->m_TotalAuxElecPower = 0.0;
15168 72368 : this->m_HeatingAuxElecConsumption = 0.0;
15169 72368 : this->m_CoolingAuxElecConsumption = 0.0;
15170 72368 : this->m_ElecPower = 0.0;
15171 72368 : this->m_ElecPowerConsumption = 0.0;
15172 :
15173 72368 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
15174 72368 : switch (this->m_ControlType) {
15175 : // Noticed that these are calculated differently.
15176 : // That doesn't make sense except that NodeNumOfControlledZone = 0 for set point control because the control zone name is not required.
15177 65331 : case UnitarySysCtrlType::Setpoint: {
15178 65331 : if (this->AirOutNode > 0) {
15179 65331 : int InletNode = this->AirInNode;
15180 261324 : CalcComponentSensibleLatentOutput(AirMassFlow,
15181 65331 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15182 65331 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15183 65331 : state.dataLoopNodes->Node(InletNode).Temp,
15184 65331 : state.dataLoopNodes->Node(InletNode).HumRat,
15185 : SensibleOutput,
15186 : LatentOutput,
15187 : TotalOutput);
15188 65331 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15189 65331 : QTotUnitOut = TotalOutput;
15190 : }
15191 65331 : } break;
15192 7037 : default: {
15193 7037 : if (this->AirOutNode > 0 && this->NodeNumOfControlledZone > 0) {
15194 : // PTUnit uses old style method of calculating delivered capacity.
15195 : // Also PTUnit always uses inlet node data, which is good when inlet is connected to zone return node
15196 7037 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15197 6979 : Real64 SpecHumOut = state.dataLoopNodes->Node(this->AirOutNode).HumRat;
15198 6979 : Real64 SpecHumIn = state.dataLoopNodes->Node(this->AirInNode).HumRat;
15199 6979 : LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s (dehumid = negative)
15200 6979 : SensibleOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirOutNode).Temp,
15201 6979 : state.dataLoopNodes->Node(this->AirInNode).HumRat) -
15202 6979 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirInNode).Temp,
15203 6979 : state.dataLoopNodes->Node(this->AirInNode).HumRat));
15204 6979 : TotalOutput =
15205 6979 : AirMassFlow * (state.dataLoopNodes->Node(this->AirOutNode).Enthalpy - state.dataLoopNodes->Node(this->AirInNode).Enthalpy);
15206 6979 : } else {
15207 : // air loop systems don't use the Sensible capacity, zone equipment uses this to adjust RemainingOutputRequired
15208 232 : CalcZoneSensibleLatentOutput(AirMassFlow,
15209 58 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15210 58 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15211 58 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
15212 58 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
15213 : SensibleOutput,
15214 : LatentOutput,
15215 : TotalOutput);
15216 : }
15217 7037 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15218 7037 : QTotUnitOut = TotalOutput;
15219 : }
15220 7037 : } break;
15221 : }
15222 :
15223 : // set the system part-load ratio report variable
15224 72368 : this->m_PartLoadFrac = max(this->m_CoolingPartLoadFrac, this->m_HeatingPartLoadFrac);
15225 : // set the compressor part-load ratio report variable
15226 72368 : this->m_CompPartLoadRatio = max(this->m_CoolCompPartLoadRatio, this->m_HeatCompPartLoadRatio);
15227 :
15228 : // logic difference in PTUnit *Rate reporting vs UnitarySystem. Use PTUnit more compact method for 9093.
15229 72368 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15230 : // Issue 9093.
15231 : // PTHP reports these differently, seems this is correct. Can't change this now, need an issue to resolve
15232 6979 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15233 6979 : this->m_TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
15234 6979 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15235 6979 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15236 6979 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15237 6979 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15238 : } else {
15239 65389 : if (state.dataUnitarySystems->HeatingLoad) {
15240 42 : if (QTotUnitOut > 0.0) { // heating
15241 32 : this->m_TotCoolEnergyRate = 0.0;
15242 32 : this->m_SensCoolEnergyRate = 0.0;
15243 32 : this->m_LatCoolEnergyRate = 0.0;
15244 32 : this->m_TotHeatEnergyRate = QTotUnitOut;
15245 32 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15246 32 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15247 : } else {
15248 10 : this->m_TotCoolEnergyRate = std::abs(QTotUnitOut);
15249 10 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15250 10 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15251 10 : this->m_TotHeatEnergyRate = 0.0;
15252 10 : this->m_SensHeatEnergyRate = 0.0;
15253 10 : this->m_LatHeatEnergyRate = 0.0;
15254 : }
15255 : } else {
15256 65347 : if (QTotUnitOut <= 0.0) { // cooling
15257 65328 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15258 65328 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15259 65328 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15260 65328 : this->m_TotHeatEnergyRate = 0.0;
15261 65328 : this->m_SensHeatEnergyRate = 0.0;
15262 65328 : this->m_LatHeatEnergyRate = 0.0;
15263 : } else {
15264 19 : this->m_TotCoolEnergyRate = 0.0;
15265 19 : this->m_SensCoolEnergyRate = 0.0;
15266 19 : this->m_LatCoolEnergyRate = 0.0;
15267 19 : this->m_TotHeatEnergyRate = QTotUnitOut;
15268 19 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15269 19 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15270 : }
15271 : }
15272 : }
15273 :
15274 72368 : this->m_TotHeatEnergy = m_TotHeatEnergyRate * ReportingConstant;
15275 72368 : this->m_TotCoolEnergy = m_TotCoolEnergyRate * ReportingConstant;
15276 72368 : this->m_SensHeatEnergy = m_SensHeatEnergyRate * ReportingConstant;
15277 72368 : this->m_SensCoolEnergy = m_SensCoolEnergyRate * ReportingConstant;
15278 72368 : this->m_LatHeatEnergy = m_LatHeatEnergyRate * ReportingConstant;
15279 72368 : this->m_LatCoolEnergy = m_LatCoolEnergyRate * ReportingConstant;
15280 :
15281 72368 : if (this->m_FanExists && this->AirOutNode > 0) {
15282 7082 : if (state.dataUnitarySystems->CompOnMassFlow > 0.0) {
15283 5561 : this->FanPartLoadRatio = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate / state.dataUnitarySystems->CompOnMassFlow;
15284 : }
15285 7082 : if (AirLoopNum > 0) {
15286 8 : if (this->m_FanOpMode == HVAC::FanOp::Cycling) {
15287 8 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = this->FanPartLoadRatio;
15288 : } else {
15289 0 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0;
15290 : }
15291 : }
15292 : }
15293 :
15294 72368 : Real64 locFanElecPower = (this->m_FanIndex == 0) ? 0.0 : state.dataFans->fans(this->m_FanIndex)->totalPower;
15295 :
15296 72368 : Real64 elecCoolingPower = 0.0;
15297 72368 : Real64 elecHeatingPower = 0.0;
15298 72368 : Real64 suppHeatingPower = 0.0;
15299 72368 : Real64 defrostElecPower = 0.0;
15300 :
15301 72368 : switch (this->m_CoolingCoilType_Num) {
15302 5670 : case HVAC::CoilDX_CoolingTwoSpeed: {
15303 : // need to make sure these are 0 for non-variable speed coils (or not report these variables)
15304 5670 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15305 5670 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15306 5670 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15307 : // see :setSpeedVariables
15308 5670 : if (state.dataUnitarySystems->CoolingLoad && this->m_SpeedNum <= 1) {
15309 2 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15310 2 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15311 : }
15312 5670 : if (this->m_LastMode == CoolingMode) {
15313 5667 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15314 : }
15315 5670 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15316 5670 : } break;
15317 20 : case HVAC::CoilDX_MultiSpeedCooling: {
15318 20 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15319 20 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15320 20 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15321 :
15322 20 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15323 20 : if (state.dataUnitarySystems->CoolingLoad) {
15324 10 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15325 10 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15326 : }
15327 20 : if (this->m_LastMode == CoolingMode) {
15328 10 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15329 : }
15330 20 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15331 20 : } break;
15332 31 : case HVAC::Coil_CoolingWater:
15333 : case HVAC::Coil_CoolingWaterDetailed: {
15334 31 : if (this->m_DiscreteSpeedCoolingCoil) {
15335 5 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15336 5 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15337 5 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15338 5 : if (state.dataUnitarySystems->CoolingLoad) {
15339 : // if discrete, the coil cycles on and off
15340 2 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15341 2 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15342 : }
15343 5 : if (this->m_LastMode == CoolingMode) {
15344 3 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15345 : }
15346 : } else {
15347 26 : if (state.dataUnitarySystems->CoolingLoad) {
15348 : // if not discrete, the coil runs the entire time step.
15349 7 : this->m_TotalAuxElecPower =
15350 7 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15351 7 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15352 : }
15353 26 : if (this->m_LastMode == CoolingMode) {
15354 13 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15355 : }
15356 : }
15357 31 : this->m_ElecPower = locFanElecPower;
15358 31 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15359 31 : } break;
15360 : // May not need
15361 3476 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
15362 3476 : if (this->m_NumOfSpeedCooling > 1) {
15363 3474 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15364 3474 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15365 3474 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15366 : }
15367 3476 : if (state.dataUnitarySystems->CoolingLoad) {
15368 633 : this->m_TotalAuxElecPower =
15369 633 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15370 633 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15371 : }
15372 3476 : if (this->m_LastMode == CoolingMode) {
15373 1939 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15374 : }
15375 3476 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15376 3476 : } break;
15377 9 : case HVAC::CoilDX_Cooling: {
15378 9 : if (this->m_NumOfSpeedCooling > 1) {
15379 6 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15380 6 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15381 6 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15382 :
15383 6 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15384 6 : if (state.dataUnitarySystems->CoolingLoad) {
15385 6 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15386 6 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15387 : }
15388 6 : if (this->m_LastMode == CoolingMode) {
15389 6 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15390 : }
15391 6 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15392 : } else {
15393 3 : if (state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15394 3 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR == 0.0) {
15395 0 : this->LoadSHR = 1.0;
15396 0 : this->CoilSHR = state.dataCoilCoolingDX->coilCoolingDXs[this->m_CoolingCoilIndex].performance.NormalSHR;
15397 : }
15398 : }
15399 3 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15400 3 : if (state.dataUnitarySystems->CoolingLoad) {
15401 3 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15402 3 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15403 : }
15404 3 : if (this->m_LastMode == CoolingMode) {
15405 3 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15406 : }
15407 3 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15408 : }
15409 9 : } break;
15410 0 : case HVAC::Coil_UserDefined:
15411 : case HVAC::CoilWater_CoolingHXAssisted:
15412 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
15413 0 : if (state.dataUnitarySystems->CoolingLoad) {
15414 0 : this->m_TotalAuxElecPower =
15415 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15416 0 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15417 : }
15418 0 : if (this->m_LastMode == CoolingMode) {
15419 0 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15420 : }
15421 : // these coil types do not consume electricity or report electricity at the plant
15422 0 : } break;
15423 63162 : default: { // all other DX cooling coils
15424 63162 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15425 63162 : if (state.dataUnitarySystems->CoolingLoad) {
15426 889 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15427 889 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15428 : }
15429 63162 : if (this->m_LastMode == CoolingMode) {
15430 61610 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15431 : }
15432 63162 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15433 63162 : } break;
15434 : }
15435 :
15436 72368 : switch (this->m_HeatingCoilType_Num) {
15437 7 : case HVAC::CoilDX_MultiSpeedHeating: {
15438 7 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15439 7 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15440 7 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15441 :
15442 7 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15443 7 : if (state.dataUnitarySystems->HeatingLoad) {
15444 3 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15445 3 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15446 : }
15447 7 : if (this->m_LastMode == HeatingMode) {
15448 4 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15449 : }
15450 7 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15451 7 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15452 7 : } break;
15453 26 : case HVAC::Coil_HeatingGas_MultiStage:
15454 : case HVAC::Coil_HeatingElectric_MultiStage: {
15455 26 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15456 26 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15457 :
15458 26 : if (state.dataUnitarySystems->HeatingLoad) {
15459 18 : this->m_TotalAuxElecPower =
15460 18 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15461 18 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15462 : }
15463 26 : if (this->m_LastMode == HeatingMode) {
15464 18 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15465 : }
15466 :
15467 26 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15468 26 : } break;
15469 6958 : case HVAC::CoilDX_HeatingEmpirical:
15470 : case HVAC::Coil_HeatingWaterToAirHP:
15471 : case HVAC::Coil_HeatingWaterToAirHPSimple:
15472 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15473 6958 : if (this->m_NumOfSpeedHeating > 1) {
15474 6948 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15475 6948 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15476 6948 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15477 : }
15478 6958 : if (state.dataUnitarySystems->HeatingLoad) {
15479 2725 : this->m_TotalAuxElecPower =
15480 2725 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15481 2725 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15482 : }
15483 6958 : if (this->m_LastMode == HeatingMode) {
15484 3040 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15485 : }
15486 6958 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15487 6958 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15488 6958 : } break;
15489 4 : case HVAC::Coil_HeatingAirToAirVariableSpeed: {
15490 4 : if (state.dataUnitarySystems->HeatingLoad) {
15491 0 : this->m_TotalAuxElecPower =
15492 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15493 0 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15494 : }
15495 4 : if (this->m_LastMode == HeatingMode) {
15496 1 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15497 : }
15498 :
15499 4 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15500 4 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15501 4 : } break;
15502 27 : case HVAC::Coil_UserDefined:
15503 : case HVAC::Coil_HeatingWater:
15504 : case HVAC::Coil_HeatingSteam:
15505 : case HVAC::Coil_HeatingDesuperheater: {
15506 27 : if (state.dataUnitarySystems->HeatingLoad) {
15507 12 : this->m_TotalAuxElecPower =
15508 12 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15509 12 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15510 : }
15511 27 : if (this->m_LastMode == HeatingMode) {
15512 13 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15513 : }
15514 27 : } break;
15515 65346 : default: {
15516 65346 : if (this->m_HeatCoilExists) {
15517 60 : if (state.dataUnitarySystems->HeatingLoad) {
15518 : // if discrete, the coil cycles on and off
15519 13 : this->m_TotalAuxElecPower =
15520 13 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15521 13 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15522 : }
15523 60 : if (this->m_LastMode == HeatingMode) {
15524 20 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15525 : }
15526 60 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15527 : }
15528 65346 : } break;
15529 : }
15530 :
15531 72368 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
15532 68045 : this->m_TotalAuxElecPower = this->m_AncillaryOffPower;
15533 : }
15534 :
15535 72368 : if (this->m_SuppCoilExists) {
15536 6995 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
15537 15 : suppHeatingPower = state.dataHVACGlobal->SuppHeatingCoilPower;
15538 : }
15539 : }
15540 :
15541 72368 : this->m_ElecPower = locFanElecPower + elecCoolingPower + elecHeatingPower + suppHeatingPower + defrostElecPower + this->m_TotalAuxElecPower;
15542 72368 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15543 :
15544 72368 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15545 0 : this->m_sysType != SysType::PackagedWSHP) {
15546 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataUnitarySystems->CompOnMassFlow;
15547 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataUnitarySystems->CompOffMassFlow;
15548 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = this->m_FanOpMode;
15549 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = this->FanPartLoadRatio;
15550 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopCompCycRatio = this->m_CycRatio;
15551 : }
15552 72368 : if (this->m_FirstPass) {
15553 80 : if (AirLoopNum > -1) {
15554 79 : if (!state.dataGlobal->SysSizingCalc) {
15555 :
15556 53 : int const CurOASysNum = state.dataSize->CurOASysNum;
15557 53 : if (CurOASysNum > 0) {
15558 4 : auto &thisOASysEqSizing = state.dataSize->OASysEqSizing(CurOASysNum);
15559 4 : thisOASysEqSizing.AirFlow = false;
15560 4 : thisOASysEqSizing.CoolingAirFlow = false;
15561 4 : thisOASysEqSizing.HeatingAirFlow = false;
15562 4 : thisOASysEqSizing.Capacity = false;
15563 4 : thisOASysEqSizing.CoolingCapacity = false;
15564 4 : thisOASysEqSizing.HeatingCapacity = false;
15565 4 : this->m_FirstPass = false;
15566 49 : } else if (state.dataSize->CurSysNum > 0) {
15567 14 : if (state.dataSize->CurSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
15568 14 : state.dataAirLoop->AirLoopControlInfo(state.dataSize->CurSysNum).UnitarySysSimulating = false;
15569 : }
15570 14 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
15571 35 : } else if (state.dataSize->CurZoneEqNum > 0) {
15572 33 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
15573 : } else {
15574 2 : this->m_FirstPass = false;
15575 : }
15576 : }
15577 : } else {
15578 1 : this->m_FirstPass = false;
15579 : }
15580 : // reset the global system type flags
15581 80 : state.dataSize->ZoneEqDXCoil = false;
15582 : }
15583 :
15584 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
15585 72368 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
15586 72368 : state.dataSize->ZoneEqUnitarySys = false;
15587 72368 : }
15588 :
15589 1 : void UnitarySys::unitarySystemHeatRecovery(EnergyPlusData &state)
15590 : {
15591 :
15592 : // SUBROUTINE INFORMATION:
15593 : // AUTHOR: Chandan Sharma
15594 : // DATE WRITTEN: May 2013
15595 :
15596 : // PURPOSE OF THIS SUBROUTINE:
15597 : // Calculate the heat recovered from UnitarySystem
15598 :
15599 : // SUBROUTINE PARAMETER DEFINITIONS:
15600 : static constexpr std::string_view routineName("UnitarySystemHeatRecovery");
15601 :
15602 1 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15603 :
15604 1 : Real64 HeatRecInletTemp = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).Temp;
15605 1 : Real64 HeatRecOutletTemp = 0.0;
15606 1 : Real64 HeatRecMassFlowRate = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate;
15607 :
15608 1 : Real64 QHeatRec = state.dataHVACGlobal->MSHPWasteHeat;
15609 :
15610 1 : if (HeatRecMassFlowRate > 0.0) {
15611 :
15612 0 : Real64 CpHeatRec = state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).glycol->getSpecificHeat(state, HeatRecInletTemp, routineName);
15613 :
15614 0 : HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + HeatRecInletTemp;
15615 : // coil model should be handling max outlet water temp (via limit to heat transfer) since heat rejection needs to be accounted for by the
15616 : // coil
15617 0 : if (HeatRecOutletTemp > this->m_MaxHROutletWaterTemp) {
15618 0 : HeatRecOutletTemp = max(HeatRecInletTemp, this->m_MaxHROutletWaterTemp);
15619 0 : QHeatRec = HeatRecMassFlowRate * CpHeatRec * (HeatRecOutletTemp - HeatRecInletTemp);
15620 : }
15621 : } else {
15622 1 : HeatRecOutletTemp = HeatRecInletTemp;
15623 1 : QHeatRec = 0.0;
15624 : }
15625 :
15626 1 : PlantUtilities::SafeCopyPlantNode(state, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
15627 :
15628 1 : state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).Temp = HeatRecOutletTemp;
15629 :
15630 1 : this->m_HeatRecoveryRate = QHeatRec;
15631 1 : this->m_HeatRecoveryEnergy = this->m_HeatRecoveryRate * ReportingConstant;
15632 1 : this->m_HeatRecoveryInletTemp = HeatRecInletTemp;
15633 1 : this->m_HeatRecoveryOutletTemp = HeatRecOutletTemp;
15634 1 : this->m_HeatRecoveryMassFlowRate = HeatRecMassFlowRate;
15635 1 : }
15636 :
15637 24503 : Real64 UnitarySys::calcUnitarySystemLoadResidual(EnergyPlusData &state,
15638 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
15639 : int UnitarySysNum,
15640 : bool FirstHVACIteration,
15641 : // par 3 not used?
15642 : HVAC::CompressorOp compressorOp,
15643 : Real64 LoadToBeMet,
15644 : Real64 coolHeatFlag, // make bool?
15645 : Real64 SensibleLoad,
15646 : Real64 OnOffAirFlowRatio,
15647 : bool HXUnitOn,
15648 : // par 10 not used
15649 : int AirLoopNum)
15650 : {
15651 :
15652 : // FUNCTION INFORMATION:
15653 : // AUTHOR Richard Raustad, FSEC
15654 : // DATE WRITTEN February 2013
15655 :
15656 : // PURPOSE OF THIS SUBROUTINE:
15657 : // To calculate the part-load ratio for the unitary system
15658 :
15659 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15660 : Real64 SensOutput; // sensible output of system
15661 : Real64 LatOutput; // latent output of system
15662 24503 : Real64 HeatCoilLoad = 0.0;
15663 24503 : Real64 SupHeaterLoad = 0.0;
15664 24503 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15665 24503 : Real64 CoolPLR = coolHeatFlag == 1.0 ? PartLoadRatio : 0.0;
15666 24503 : Real64 HeatPLR = coolHeatFlag == 1.0 ? 0.0 : PartLoadRatio;
15667 24503 : thisSys.setSpeedVariables(state, SensibleLoad, PartLoadRatio);
15668 24503 : thisSys.calcUnitarySystemToLoad(state,
15669 : AirLoopNum,
15670 : FirstHVACIteration,
15671 : CoolPLR,
15672 : HeatPLR,
15673 : OnOffAirFlowRatio,
15674 : SensOutput,
15675 : LatOutput,
15676 : HXUnitOn,
15677 : HeatCoilLoad,
15678 : SupHeaterLoad,
15679 : compressorOp);
15680 : // Calculate residual based on output calculation flag
15681 24503 : Real64 baselineLoad = SensibleLoad == 1.0 ? SensOutput : LatOutput;
15682 24503 : Real64 divisor = std::abs(LoadToBeMet) == 0.0 ? 100.0 : LoadToBeMet;
15683 24503 : return (baselineLoad - LoadToBeMet) / divisor;
15684 : }
15685 :
15686 10687 : Real64 UnitarySys::DXCoilVarSpeedResidual(EnergyPlusData &state,
15687 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
15688 : int CoilIndex,
15689 : Real64 DesOutTemp,
15690 : int UnitarySysNum,
15691 : Real64 CycRatio,
15692 : int SpeedNum,
15693 : HVAC::FanOp const fanOp,
15694 : HVAC::CompressorOp compressorOp)
15695 : {
15696 : // FUNCTION INFORMATION:
15697 : // AUTHOR Fred Buhl
15698 : // DATE WRITTEN September 2002
15699 :
15700 : // PURPOSE OF THIS FUNCTION:
15701 : // Calculates residual function (desired outlet temp - actual outlet temp).
15702 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
15703 :
15704 : // METHODOLOGY EMPLOYED:
15705 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given compressor speed
15706 : // and calculates the residual as defined above
15707 :
15708 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15709 10687 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
15710 :
15711 : Real64 dummy;
15712 : Real64 OnOffAirFlowRatio;
15713 : Real64 SensLoad;
15714 :
15715 10687 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15716 10687 : switch (thisSys.m_CoolingCoilType_Num) {
15717 10669 : case HVAC::CoilDX_CoolingTwoSpeed: {
15718 10669 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
15719 10669 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15720 10669 : } break;
15721 0 : case HVAC::CoilDX_MultiSpeedCooling: {
15722 0 : OnOffAirFlowRatio = 1.0;
15723 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
15724 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
15725 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15726 0 : } break;
15727 18 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
15728 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
15729 18 : dummy = 0.0;
15730 18 : SensLoad = -1.0;
15731 18 : OnOffAirFlowRatio = 1.0;
15732 18 : VariableSpeedCoils::SimVariableSpeedCoils(
15733 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
15734 :
15735 18 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
15736 18 : } break;
15737 0 : default: {
15738 0 : assert(false);
15739 : } break;
15740 : }
15741 10687 : return DesOutTemp - OutletAirTemp;
15742 : }
15743 :
15744 12 : Real64 UnitarySys::heatingCoilVarSpeedResidual(EnergyPlusData &state,
15745 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
15746 : int CoilIndex,
15747 : Real64 DesOutTemp,
15748 : int UnitarySysNum,
15749 : Real64 CycRatio,
15750 : int SpeedNum,
15751 : HVAC::FanOp const fanOp,
15752 : HVAC::CompressorOp compressorOp,
15753 : bool SuppHeat
15754 :
15755 : )
15756 : {
15757 : // FUNCTION INFORMATION:
15758 : // AUTHOR Fred Buhl
15759 : // DATE WRITTEN September 2002
15760 :
15761 : // PURPOSE OF THIS FUNCTION:
15762 : // Calculates residual function (desired outlet temp - actual outlet temp).
15763 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
15764 :
15765 : // METHODOLOGY EMPLOYED:
15766 : // Calls calc routines of multi Speed or variable Coil to get outlet temperature at the given compressor speed
15767 : // and calculates the residual as defined above
15768 :
15769 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15770 12 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
15771 : Real64 OnOffAirFlowRatio;
15772 : Real64 SensLoad;
15773 : Real64 LatLoad;
15774 : Real64 QActual;
15775 :
15776 12 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15777 :
15778 12 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
15779 12 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
15780 12 : if (SuppHeat) {
15781 0 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
15782 0 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
15783 : }
15784 :
15785 12 : switch (heatCoilType) {
15786 0 : case HVAC::CoilDX_MultiSpeedHeating: {
15787 0 : OnOffAirFlowRatio = 1.0;
15788 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
15789 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
15790 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15791 0 : } break;
15792 3 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
15793 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15794 3 : OnOffAirFlowRatio = 1.0;
15795 3 : SensLoad = 1.0;
15796 3 : LatLoad = -1.0;
15797 : // can't call only the calc routine with these coil types since Init sets air flow rate based on speed num and cycling ratio
15798 3 : VariableSpeedCoils::SimVariableSpeedCoils(
15799 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
15800 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
15801 3 : } break;
15802 3 : case HVAC::Coil_HeatingElectric_MultiStage: {
15803 3 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
15804 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
15805 3 : } break;
15806 6 : case HVAC::Coil_HeatingGas_MultiStage: {
15807 6 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
15808 6 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
15809 6 : } break;
15810 0 : default: {
15811 0 : assert(false);
15812 : } break;
15813 : }
15814 12 : return DesOutTemp - OutletAirTemp;
15815 : }
15816 :
15817 4 : Real64 UnitarySys::DXCoilVarSpeedHumRatResidual(EnergyPlusData &state,
15818 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
15819 : int CoilIndex,
15820 : Real64 DesOutHumRat,
15821 : int UnitarySysNum,
15822 : Real64 CycRatio,
15823 : int SpeedNum,
15824 : HVAC::FanOp const fanOp,
15825 : HVAC::CompressorOp compressorOp)
15826 : {
15827 : // FUNCTION INFORMATION:
15828 : // AUTHOR Richard Raustad
15829 : // DATE WRITTEN January 2008
15830 :
15831 : // PURPOSE OF THIS FUNCTION:
15832 : // Calculates residual function (desired outlet humrat - actual outlet humrat).
15833 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
15834 :
15835 : // METHODOLOGY EMPLOYED:
15836 : // Calls calc routines of multi speed or variable speed coils to get outlet humidity ratio at the given compressor speed
15837 : // and calculates the residual as defined above
15838 :
15839 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15840 4 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio
15841 : Real64 SensLoad;
15842 : Real64 LatLoad;
15843 : Real64 OnOffAirFlowRatio;
15844 4 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15845 4 : switch (thisSys.m_CoolingCoilType_Num) {
15846 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
15847 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
15848 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
15849 0 : } break;
15850 0 : case HVAC::CoilDX_MultiSpeedCooling: {
15851 0 : OnOffAirFlowRatio = 1.0;
15852 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
15853 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
15854 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
15855 0 : } break;
15856 4 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
15857 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
15858 4 : SensLoad = -1.0;
15859 4 : LatLoad = 0.0;
15860 4 : OnOffAirFlowRatio = 1.0;
15861 4 : VariableSpeedCoils::SimVariableSpeedCoils(
15862 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
15863 4 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
15864 4 : } break;
15865 0 : default: {
15866 0 : assert(false);
15867 : } break;
15868 : }
15869 4 : return DesOutHumRat - OutletAirHumRat;
15870 : }
15871 :
15872 5732 : Real64 UnitarySys::DXCoilCyclingResidual(EnergyPlusData &state,
15873 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
15874 : int CoilIndex,
15875 : Real64 DesOutTemp,
15876 : int UnitarySysNum,
15877 : Real64 SpeedRatio,
15878 : int SpeedNum,
15879 : HVAC::FanOp const fanOp,
15880 : HVAC::CompressorOp compressorOp,
15881 : int AirloopNum,
15882 : bool FirstHVACIteration
15883 :
15884 : )
15885 : {
15886 : // FUNCTION INFORMATION:
15887 : // AUTHOR Fred Buhl
15888 : // DATE WRITTEN September 2002
15889 :
15890 : // PURPOSE OF THIS FUNCTION:
15891 : // Calculates residual function (desired outlet temp - actual outlet temp)
15892 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
15893 :
15894 : // METHODOLOGY EMPLOYED:
15895 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
15896 : // and calculates the residual as defined above
15897 :
15898 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15899 5732 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
15900 : Real64 OnOffAirFlowRatio;
15901 :
15902 5732 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15903 5732 : switch (thisSys.m_CoolingCoilType_Num) {
15904 5704 : case HVAC::CoilDX_CoolingTwoSpeed: {
15905 5704 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
15906 0 : thisSys.m_CoolingCycRatio = CycRatio;
15907 0 : thisSys.m_CoolingPartLoadFrac = CycRatio;
15908 0 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
15909 : } else {
15910 5704 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
15911 : }
15912 5704 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15913 5704 : } break;
15914 11 : case HVAC::CoilDX_MultiSpeedCooling: {
15915 11 : OnOffAirFlowRatio = 1.0;
15916 11 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
15917 11 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
15918 7 : thisSys.m_CoolingCycRatio = CycRatio;
15919 7 : thisSys.m_CoolingPartLoadFrac = CycRatio;
15920 7 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
15921 : } else {
15922 4 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
15923 : }
15924 11 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15925 11 : } break;
15926 17 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
15927 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
15928 17 : if (CycRatio == 0.0) compressorOp = HVAC::CompressorOp::Off;
15929 17 : Real64 dummy = 0.0;
15930 17 : OnOffAirFlowRatio = 1.0;
15931 17 : Real64 SensLoad = -1.0;
15932 17 : VariableSpeedCoils::SimVariableSpeedCoils(
15933 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
15934 17 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
15935 17 : } break;
15936 0 : default: {
15937 0 : assert(false);
15938 : } break;
15939 : }
15940 5732 : return DesOutTemp - OutletAirTemp;
15941 : }
15942 :
15943 0 : Real64 UnitarySys::DXCoilCyclingHumRatResidual(EnergyPlusData &state,
15944 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
15945 : int CoilIndex,
15946 : Real64 DesOutHumRat,
15947 : int UnitarySysNum,
15948 : Real64 SpeedRatio,
15949 : int SpeedNum,
15950 : HVAC::FanOp const fanOp,
15951 : HVAC::CompressorOp compressorOp)
15952 : {
15953 :
15954 : // FUNCTION INFORMATION:
15955 : // AUTHOR Fred Buhl
15956 : // DATE WRITTEN September 2002
15957 :
15958 : // PURPOSE OF THIS FUNCTION:
15959 : // Calculates residual function (desired outlet temp - actual outlet temp)
15960 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
15961 :
15962 : // METHODOLOGY EMPLOYED:
15963 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given cycling ratio
15964 : // and calculates the residual as defined above
15965 :
15966 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15967 0 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio [kg/kg]
15968 : Real64 SensLoad;
15969 : Real64 LatLoad;
15970 : Real64 OnOffAirFlowRatio;
15971 :
15972 0 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15973 0 : switch (thisSys.m_CoolingCoilType_Num) {
15974 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
15975 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
15976 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
15977 0 : } break;
15978 0 : case HVAC::CoilDX_MultiSpeedCooling: {
15979 0 : OnOffAirFlowRatio = 1.0;
15980 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
15981 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
15982 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
15983 0 : } break;
15984 0 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
15985 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
15986 0 : SensLoad = -1.0;
15987 0 : LatLoad = 0.0;
15988 0 : OnOffAirFlowRatio = 1.0;
15989 0 : VariableSpeedCoils::SimVariableSpeedCoils(
15990 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
15991 0 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
15992 0 : } break;
15993 0 : default: {
15994 0 : assert(false);
15995 : } break;
15996 : }
15997 0 : return DesOutHumRat - OutletAirHumRat;
15998 : }
15999 :
16000 18 : Real64 UnitarySys::heatingCoilVarSpeedCycResidual(EnergyPlusData &state,
16001 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16002 : int CoilIndex,
16003 : Real64 DesOutTemp,
16004 : int UnitarySysNum,
16005 : Real64 SpeedRatio,
16006 : int SpeedNum,
16007 : HVAC::FanOp const fanOp,
16008 : HVAC::CompressorOp compressorOp,
16009 : bool SuppHeat)
16010 : {
16011 :
16012 : // FUNCTION INFORMATION:
16013 : // AUTHOR Fred Buhl
16014 : // DATE WRITTEN September 2002
16015 :
16016 : // PURPOSE OF THIS FUNCTION:
16017 : // Calculates residual function (desired outlet temp - actual outlet temp)
16018 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16019 :
16020 : // METHODOLOGY EMPLOYED:
16021 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16022 : // and calculates the residual as defined above
16023 :
16024 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16025 18 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16026 : Real64 SensLoad;
16027 : Real64 LatLoad;
16028 : Real64 OnOffAirFlowRatio;
16029 : Real64 QActual;
16030 :
16031 18 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16032 :
16033 18 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16034 18 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16035 18 : if (SuppHeat) {
16036 6 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16037 6 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16038 : }
16039 :
16040 18 : switch (heatCoilType) {
16041 0 : case HVAC::CoilDX_MultiSpeedHeating: {
16042 0 : OnOffAirFlowRatio = 1.0;
16043 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16044 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16045 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16046 0 : } break;
16047 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16048 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16049 0 : if (CycRatio == 0.0) compressorOp = HVAC::CompressorOp::Off;
16050 0 : SensLoad = -1.0;
16051 0 : LatLoad = 0.0;
16052 0 : OnOffAirFlowRatio = 1.0;
16053 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16054 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16055 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16056 0 : } break;
16057 12 : case HVAC::Coil_HeatingElectric_MultiStage: {
16058 12 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16059 12 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16060 12 : } break;
16061 6 : case HVAC::Coil_HeatingGas_MultiStage: {
16062 6 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16063 6 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16064 6 : } break;
16065 0 : default: {
16066 0 : assert(false);
16067 : } break;
16068 : }
16069 :
16070 18 : return DesOutTemp - OutletAirTemp;
16071 : }
16072 :
16073 6 : Real64 UnitarySys::gasElecHeatingCoilResidual(EnergyPlusData &state,
16074 : Real64 const PartLoadFrac, // Compressor cycling ratio (1.0 is continuous, 0.0 is off)
16075 : int UnitarySysNum,
16076 : bool FirstHVACIteration,
16077 : Real64 desTemp,
16078 : bool SuppHeatingCoilFlag,
16079 : HVAC::FanOp const fanOp,
16080 : Real64 HeatingLoadArg)
16081 : {
16082 :
16083 : // FUNCTION INFORMATION:
16084 : // AUTHOR Chandan Sharma, FSEC
16085 : // DATE WRITTEN February 2013
16086 :
16087 : // PURPOSE OF THIS FUNCTION:
16088 : // Calculates residual function (desired outlet temp - actual outlet temp)
16089 : // hot water Coil output depends on the part load ratio which is being varied to zero the residual.
16090 :
16091 : // METHODOLOGY EMPLOYED:
16092 : // Calls SimulateHeatingCoilComponents to get outlet temperature at the given part load ratio
16093 : // and calculates the residual as defined above
16094 :
16095 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16096 6 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16097 6 : Real64 HeatingLoad = HeatingLoadArg * PartLoadFrac;
16098 : // heating coils using set point control pass DataLoopNode::SensedLoadFlagValue as QCoilReq to indicate temperature control
16099 6 : if (!SuppHeatingCoilFlag) {
16100 12 : HeatingCoils::SimulateHeatingCoilComponents(
16101 6 : state, thisSys.m_HeatingCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_HeatingCoilIndex, _, _, fanOp, PartLoadFrac);
16102 6 : return desTemp - state.dataLoopNodes->Node(thisSys.HeatCoilOutletNodeNum).Temp;
16103 : } else {
16104 0 : HeatingCoils::SimulateHeatingCoilComponents(
16105 0 : state, thisSys.m_SuppHeatCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_SuppHeatCoilIndex, _, true, fanOp, PartLoadFrac);
16106 0 : return desTemp - state.dataLoopNodes->Node(thisSys.SuppCoilOutletNodeNum).Temp;
16107 : }
16108 : }
16109 :
16110 0 : Real64 UnitarySys::coolWatertoAirHPTempResidual(EnergyPlusData &state,
16111 : Real64 const PartLoadRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16112 : int UnitarySysNum,
16113 : bool FirstHVACIteration,
16114 : Real64 DesOutTemp,
16115 : Real64 ReqOutput)
16116 : {
16117 :
16118 : // FUNCTION INFORMATION:
16119 : // AUTHOR Chandan Sharma, FSEC
16120 : // DATE WRITTEN January 2013
16121 :
16122 : // PURPOSE OF THIS FUNCTION:
16123 : // Calculates residual function (desired outlet temp - actual outlet temp)
16124 : // Cool water coil output depends on the part load ratio which is being varied to zero the residual.
16125 :
16126 : // METHODOLOGY EMPLOYED:
16127 : // Calls SimWatertoAirHP or SimWatertoAirHPSimple to get outlet humidity ratio at the given cycling ratio
16128 : // and calculates the residual as defined above
16129 :
16130 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16131 :
16132 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
16133 :
16134 0 : Real64 dummy = 0.0;
16135 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
16136 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
16137 : blankString,
16138 0 : thisSys.m_CoolingCoilIndex,
16139 : ReqOutput,
16140 : dummy,
16141 : thisSys.m_FanOpMode,
16142 : HVAC::CompressorOp::On,
16143 : PartLoadRatio,
16144 : FirstHVACIteration);
16145 : } else {
16146 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
16147 : blankString,
16148 0 : thisSys.m_CoolingCoilIndex,
16149 : thisSys.MaxCoolAirMassFlow,
16150 : thisSys.m_FanOpMode,
16151 : FirstHVACIteration,
16152 0 : thisSys.m_InitHeatPump,
16153 : ReqOutput,
16154 : dummy,
16155 : HVAC::CompressorOp::Off,
16156 : PartLoadRatio);
16157 : }
16158 0 : return DesOutTemp - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16159 : }
16160 :
16161 95 : Real64 UnitarySys::calcUnitarySystemWaterFlowResidual(EnergyPlusData &state,
16162 : Real64 const PartLoadRatio, // coil part load ratio
16163 : int UnitarySysNum,
16164 : bool FirstHVACIteration,
16165 : Real64 QZnReq,
16166 : int AirControlNode,
16167 : Real64 OnOffAirFlowRat,
16168 : int AirLoopNum,
16169 : int WaterControlNode,
16170 : Real64 highWaterMdot,
16171 : Real64 lowSpeedRatio,
16172 : Real64 airMdot,
16173 : Real64 par13_SATempTarget,
16174 : Real64 systemMaxAirFlowRate,
16175 : Real64 par15_LoadType,
16176 : Real64 par16_IterationMethod)
16177 : {
16178 :
16179 : // FUNCTION INFORMATION:
16180 : // AUTHOR Richard Raustad, FSEC
16181 : // DATE WRITTEN January 2017
16182 :
16183 : // PURPOSE OF THIS SUBROUTINE:
16184 : // To calculate the part-load ratio for the UnitarySystem coil with varying part load ratio
16185 :
16186 : // METHODOLOGY EMPLOYED:
16187 : // Use SolveRoot to CALL this Function to converge on a solution
16188 :
16189 95 : Real64 HeatCoilLoad = 0.0;
16190 95 : Real64 SupHeaterLoad = 0.0;
16191 :
16192 : // Convert parameters to usable variables
16193 95 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16194 95 : Real64 SATempTarget = 0.0;
16195 95 : bool LoadIsTarget = false;
16196 95 : if (par13_SATempTarget == 0.0) {
16197 95 : LoadIsTarget = true;
16198 : } else {
16199 0 : SATempTarget = par13_SATempTarget;
16200 : }
16201 95 : bool iterateOnAirOnly = (par16_IterationMethod > 1.0);
16202 95 : bool coolingLoad = (par15_LoadType > 0.0);
16203 :
16204 95 : bool HXUnitOn = true;
16205 :
16206 95 : if (iterateOnAirOnly) {
16207 :
16208 : // set air flow rate bounded by low speed and high speed air flow rates
16209 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
16210 : // FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model
16211 : // FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem
16212 0 : thisSys.FanPartLoadRatio = PartLoadRatio;
16213 : // if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot;
16214 :
16215 : } else {
16216 :
16217 95 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot;
16218 95 : if (lowSpeedRatio != 1.0) {
16219 : // division by zero when lowSpeedRatio == 1.0
16220 95 : thisSys.FanPartLoadRatio =
16221 95 : max(0.0, ((airMdot - (systemMaxAirFlowRate * lowSpeedRatio)) / ((1.0 - lowSpeedRatio) * systemMaxAirFlowRate)));
16222 : } else {
16223 0 : thisSys.FanPartLoadRatio = 1.0;
16224 : }
16225 95 : if (WaterControlNode > 0) {
16226 61 : Real64 waterMdot = highWaterMdot * PartLoadRatio;
16227 61 : state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot;
16228 : }
16229 : }
16230 :
16231 95 : Real64 coolingPLR = 0.0;
16232 95 : Real64 heatingPLR = 0.0;
16233 :
16234 95 : if (WaterControlNode > 0 && WaterControlNode == thisSys.CoolCoilFluidInletNode) {
16235 : // cooling load using water cooling coil
16236 17 : coolingPLR = PartLoadRatio;
16237 17 : thisSys.m_CoolingPartLoadFrac = PartLoadRatio;
16238 17 : if (thisSys.MaxCoolCoilFluidFlow > 0.0)
16239 17 : thisSys.CoolCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxCoolCoilFluidFlow;
16240 78 : } else if (WaterControlNode > 0 && WaterControlNode == thisSys.HeatCoilFluidInletNode) {
16241 : // heating load using water heating coil
16242 44 : heatingPLR = PartLoadRatio;
16243 44 : thisSys.m_HeatingPartLoadFrac = PartLoadRatio;
16244 44 : if (thisSys.MaxHeatCoilFluidFlow > 0.0)
16245 44 : thisSys.HeatCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxHeatCoilFluidFlow;
16246 34 : } else if (coolingLoad) { // non-water coil with cooling load
16247 7 : coolingPLR = PartLoadRatio;
16248 7 : thisSys.m_CoolingPartLoadFrac = coolingPLR;
16249 : } else { // must be non-water coil with heating load
16250 27 : heatingPLR = PartLoadRatio;
16251 27 : thisSys.m_HeatingPartLoadFrac = heatingPLR;
16252 : }
16253 :
16254 95 : Real64 SensOutput = 0.0;
16255 95 : Real64 LatOutput = 0.0;
16256 95 : thisSys.calcUnitarySystemToLoad(state,
16257 : AirLoopNum,
16258 : FirstHVACIteration,
16259 : coolingPLR,
16260 : heatingPLR,
16261 : OnOffAirFlowRat,
16262 : SensOutput,
16263 : LatOutput,
16264 : HXUnitOn,
16265 : HeatCoilLoad,
16266 : SupHeaterLoad,
16267 : HVAC::CompressorOp::On);
16268 :
16269 95 : if (LoadIsTarget) {
16270 : // Calculate residual based on output magnitude
16271 95 : if (std::abs(QZnReq) <= 100.0) {
16272 3 : return (SensOutput - QZnReq) / 100.0;
16273 : } else {
16274 92 : return (SensOutput - QZnReq) / QZnReq;
16275 : }
16276 : } else {
16277 : // Calculate residual based on outlet temperature
16278 0 : return (state.dataLoopNodes->Node(thisSys.AirOutNode).Temp - SATempTarget) * 10.0;
16279 : }
16280 : }
16281 :
16282 24510 : void UnitarySys::setSpeedVariables(EnergyPlusData &state,
16283 : bool const SensibleLoad, // True when meeting a sensible load (not a moisture load)
16284 : Real64 const PartLoadRatio // operating PLR
16285 : )
16286 : {
16287 :
16288 : // SUBROUTINE INFORMATION:
16289 : // AUTHOR Richard Raustad, FSEC
16290 : // DATE WRITTEN February 2013
16291 :
16292 : // PURPOSE OF THIS SUBROUTINE:
16293 : // This subroutine determines operating PLR and calculates the load based system output.
16294 :
16295 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16296 24510 : Real64 OnOffAirFlowRatio = 0.0; // compressor on to average flow rate
16297 :
16298 24510 : if (state.dataUnitarySystems->HeatingLoad && SensibleLoad) {
16299 17541 : this->m_CoolingSpeedRatio = 0.0;
16300 17541 : this->m_CoolingCycRatio = 0.0;
16301 17541 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
16302 17522 : if (this->m_HeatingSpeedNum <= 1) {
16303 101 : this->m_HeatingSpeedRatio = 0.0;
16304 101 : this->m_HeatingCycRatio = PartLoadRatio;
16305 101 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16306 : } else {
16307 17421 : if (this->m_SingleMode == 0) {
16308 17418 : this->m_HeatingSpeedRatio = PartLoadRatio;
16309 17418 : this->m_HeatingCycRatio = 1.0;
16310 : } else {
16311 3 : this->m_HeatingSpeedRatio = 1.0;
16312 3 : this->m_HeatingCycRatio = PartLoadRatio;
16313 : }
16314 : }
16315 19 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
16316 15 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
16317 4 : this->m_CompPartLoadRatio = PartLoadRatio;
16318 4 : this->m_HeatingSpeedNum = 0;
16319 : }
16320 : } else {
16321 6969 : this->m_HeatingSpeedRatio = 0.0;
16322 6969 : this->m_HeatingCycRatio = 0.0;
16323 6969 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
16324 6889 : if (this->m_CoolingSpeedNum <= 1) {
16325 1834 : this->m_CoolingSpeedRatio = 0.0;
16326 1834 : this->m_CoolingCycRatio = PartLoadRatio;
16327 1834 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16328 : } else {
16329 5055 : if (this->m_SingleMode == 0) {
16330 5052 : this->m_CoolingSpeedRatio = PartLoadRatio;
16331 5052 : this->m_CoolingCycRatio = 1.0;
16332 : } else {
16333 3 : this->m_CoolingSpeedRatio = 1.0;
16334 3 : this->m_CoolingCycRatio = PartLoadRatio;
16335 : }
16336 : }
16337 80 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
16338 76 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
16339 4 : this->m_CompPartLoadRatio = PartLoadRatio;
16340 4 : this->m_CoolingSpeedNum = 0;
16341 76 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
16342 0 : if (this->m_CoolingSpeedNum == 1) {
16343 0 : this->m_CoolingSpeedRatio = 0.0;
16344 0 : this->m_CoolingCycRatio = PartLoadRatio;
16345 : } else {
16346 0 : this->m_CoolingSpeedRatio = PartLoadRatio;
16347 0 : this->m_CoolingCycRatio = 1.0;
16348 : }
16349 : } else {
16350 76 : this->m_CoolingSpeedNum = 0;
16351 : }
16352 : }
16353 24510 : OnOffAirFlowRatio = 1.0;
16354 24510 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
16355 24510 : }
16356 :
16357 2 : void UnitarySys::checkUnitarySysCoilInOASysExists(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum)
16358 : {
16359 :
16360 : // SUBROUTINE INFORMATION:
16361 : // AUTHOR Chandan Sharma
16362 : // DATE WRITTEN April 2013
16363 :
16364 : // PURPOSE OF THIS SUBROUTINE:
16365 : // After making sure get input is done, checks if the Coil System DX coil is in the
16366 : // OA System. IF exists then the DX cooling coil is 100% DOAS DX coil.
16367 : // METHODOLOGY EMPLOYED:
16368 : // Based on CheckDXCoolingCoilInOASysExists by Bereket Nigusse
16369 :
16370 : // SUBROUTINE PARAMETER DEFINITIONS:
16371 : static constexpr std::string_view RoutineName("CheckUnitarySysCoilInOASysExists: "); // include trailing blank space
16372 :
16373 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16374 2 : if (state.dataUnitarySystems->getInputOnceFlag) {
16375 1 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16376 1 : state.dataUnitarySystems->getInputOnceFlag = false;
16377 : }
16378 :
16379 2 : if (state.dataUnitarySystems->numUnitarySystems > 0) {
16380 2 : bool UnitarySysFound = false;
16381 2 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16382 2 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16383 2 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten)
16384 1 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16385 2 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ISHundredPercentDOASDXCoil) {
16386 0 : if (!(state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
16387 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num ==
16388 : HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
16389 0 : DXCoils::SetDXCoilTypeData(state, state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilName);
16390 : }
16391 : }
16392 2 : UnitarySysFound = true;
16393 2 : break;
16394 : }
16395 : }
16396 2 : if (!UnitarySysFound) {
16397 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16398 : }
16399 : } else {
16400 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16401 : }
16402 2 : }
16403 :
16404 0 : void UnitarySys::getUnitarySysHeatCoolCoil(EnergyPlusData &state,
16405 : std::string_view UnitarySysName, // Name of Unitary System object
16406 : bool &CoolingCoil, // Cooling coil exists
16407 : bool &HeatingCoil, // Heating coil exists
16408 : int const ZoneOAUnitNum // index to zone OA unit
16409 : )
16410 : {
16411 :
16412 : // FUNCTION INFORMATION:
16413 : // AUTHOR Chandan Sharma
16414 : // DATE WRITTEN April 2013
16415 :
16416 : // PURPOSE OF THIS FUNCTION:
16417 : // Determined weather Unitary system has heating or cooling coils
16418 :
16419 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16420 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16421 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16422 : }
16423 :
16424 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16425 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16426 0 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten)
16427 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16428 0 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolCoilExists &&
16429 0 : !state.dataUnitarySystems->unitarySys[UnitarySysNum].m_WaterHRPlantLoopModel) {
16430 0 : CoolingCoil = true;
16431 : }
16432 0 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_HeatCoilExists ||
16433 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_SuppCoilExists) {
16434 0 : HeatingCoil = true;
16435 : }
16436 0 : break;
16437 : }
16438 : }
16439 0 : }
16440 :
16441 4 : int UnitarySys::getAirInNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16442 : {
16443 4 : if (state.dataUnitarySystems->getInputOnceFlag) {
16444 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16445 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16446 : }
16447 4 : int airNode = 0;
16448 4 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16449 4 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16450 4 : airNode = this->AirInNode;
16451 4 : break;
16452 : }
16453 : }
16454 4 : if (airNode == 0) errFlag = true;
16455 4 : return airNode;
16456 : }
16457 :
16458 9 : int getZoneEqIndex(EnergyPlusData &state, std::string const &UnitarySysName, DataZoneEquipment::ZoneEquipType zoneEquipType, int const OAUnitNum)
16459 : {
16460 :
16461 9 : if (state.dataUnitarySystems->getInputOnceFlag) {
16462 0 : UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, true, OAUnitNum);
16463 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16464 : }
16465 :
16466 9 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16467 9 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16468 9 : if (zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner ||
16469 1 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump ||
16470 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir ||
16471 : zoneEquipType == DataZoneEquipment::ZoneEquipType::UnitarySystem) {
16472 9 : return UnitarySysNum;
16473 : }
16474 : }
16475 : }
16476 0 : return -1;
16477 : }
16478 :
16479 4 : int UnitarySys::getAirOutNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16480 : {
16481 4 : if (state.dataUnitarySystems->getInputOnceFlag) {
16482 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16483 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16484 : }
16485 4 : int airNode = 0;
16486 4 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16487 4 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16488 4 : airNode = this->AirOutNode;
16489 4 : break;
16490 : }
16491 : }
16492 4 : if (airNode == 0) errFlag = true;
16493 4 : return airNode;
16494 : }
16495 :
16496 453 : int UnitarySys::getAirOutletNode()
16497 : {
16498 453 : return this->AirOutNode;
16499 : }
16500 :
16501 453 : int UnitarySys::getMixerOANode()
16502 : {
16503 453 : return this->m_OAMixerNodes[0];
16504 : }
16505 :
16506 453 : int UnitarySys::getMixerMixNode()
16507 : {
16508 453 : return this->m_OAMixerNodes[3];
16509 : }
16510 :
16511 453 : int UnitarySys::getMixerRetNode()
16512 : {
16513 453 : return this->m_OAMixerNodes[2];
16514 : }
16515 :
16516 40 : int UnitarySys::getEquipIndex()
16517 : {
16518 40 : return this->m_EquipCompNum;
16519 : }
16520 :
16521 6 : bool searchZoneInletNodes(EnergyPlusData &state, int nodeToFind, int &ZoneEquipConfigIndex, int &InletNodeIndex)
16522 : {
16523 17 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16524 27 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++ZoneInletNum) {
16525 16 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(ZoneInletNum) == nodeToFind) {
16526 5 : ZoneEquipConfigIndex = ControlledZoneNum;
16527 5 : InletNodeIndex = ZoneInletNum;
16528 5 : return true;
16529 : }
16530 : }
16531 : }
16532 1 : return false;
16533 : }
16534 :
16535 66 : bool searchZoneInletNodesByEquipmentIndex(EnergyPlusData &state, int nodeToFind, int zoneEquipmentIndex)
16536 : {
16537 66 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).NumInletNodes; ++ZoneInletNum) {
16538 66 : if (state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).InletNode(ZoneInletNum) == nodeToFind) {
16539 66 : return true;
16540 : }
16541 : }
16542 0 : return false;
16543 : }
16544 :
16545 4 : bool searchZoneInletNodeAirLoopNum(EnergyPlusData &state, int airLoopNumToFind, int ZoneEquipConfigIndex, int &InletNodeIndex)
16546 : {
16547 4 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).NumInletNodes; ++ZoneInletNum) {
16548 4 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).InletNodeAirLoopNum(ZoneInletNum) == airLoopNumToFind) {
16549 4 : InletNodeIndex = ZoneInletNum;
16550 4 : return true;
16551 : }
16552 : }
16553 0 : return false;
16554 : }
16555 :
16556 72 : bool searchExhaustNodes(EnergyPlusData &state, const int nodeToFind, int &ZoneEquipConfigIndex, int &ExhaustNodeIndex)
16557 : {
16558 101 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16559 106 : for (int ZoneExhNum = 1; ZoneExhNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes; ++ZoneExhNum) {
16560 77 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum) == nodeToFind) {
16561 66 : ZoneEquipConfigIndex = ControlledZoneNum;
16562 66 : ExhaustNodeIndex = ZoneExhNum;
16563 66 : return true;
16564 : }
16565 : }
16566 : }
16567 6 : return false;
16568 : }
16569 :
16570 70 : void UnitarySys::setSystemParams(EnergyPlusData &state, Real64 &TotalFloorAreaOnAirLoop, const std::string &thisObjectName)
16571 : {
16572 70 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum);
16573 70 : this->NodeNumOfControlledZone = zoneEquipConfig.ZoneNode;
16574 70 : TotalFloorAreaOnAirLoop = state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
16575 70 : this->m_AirLoopEquipment = false;
16576 70 : if (zoneEquipConfig.EquipListIndex == 0) return;
16577 :
16578 70 : auto &zoneEquipList = state.dataZoneEquip->ZoneEquipList(zoneEquipConfig.EquipListIndex);
16579 103 : for (int EquipNum = 1; EquipNum <= zoneEquipList.NumOfEquipTypes; ++EquipNum) {
16580 136 : if ((zoneEquipList.EquipType(EquipNum) != DataZoneEquipment::ZoneEquipType::UnitarySystem) ||
16581 52 : zoneEquipList.EquipName(EquipNum) != thisObjectName) {
16582 33 : continue;
16583 : }
16584 51 : this->m_ZoneSequenceCoolingNum = zoneEquipList.CoolingPriority(EquipNum);
16585 51 : this->m_ZoneSequenceHeatingNum = zoneEquipList.HeatingPriority(EquipNum);
16586 51 : break;
16587 : }
16588 : }
16589 :
16590 30 : bool searchTotalComponents(EnergyPlusData &state,
16591 : SimAirServingZones::CompType compTypeToFind,
16592 : std::string_view objectNameToFind,
16593 : int &compIndex,
16594 : int &branchIndex,
16595 : int &airLoopIndex)
16596 : {
16597 34 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
16598 33 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
16599 55 : for (int CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
16600 : ++CompNum) {
16601 51 : if (compTypeToFind != state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num)
16602 24 : continue;
16603 27 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
16604 : objectNameToFind)) {
16605 25 : compIndex = CompNum;
16606 25 : branchIndex = BranchNum;
16607 25 : airLoopIndex = AirLoopNum;
16608 25 : return true;
16609 : }
16610 : }
16611 : }
16612 : }
16613 5 : return false;
16614 : }
16615 :
16616 42 : bool getUnitarySystemNodeNumber(EnergyPlusData &state, int const nodeNumber)
16617 : {
16618 43 : for (int unitarySysIndex = 0; unitarySysIndex <= state.dataUnitarySystems->numUnitarySystems - 1; ++unitarySysIndex) {
16619 9 : auto &unitarySys = state.dataUnitarySystems->unitarySys[unitarySysIndex];
16620 :
16621 9 : int FanInletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->inletNodeNum;
16622 9 : int FanOutletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->outletNodeNum;
16623 :
16624 9 : bool noUnitarySysOutdoorAir = false;
16625 9 : if (unitarySys.m_CoolOutAirVolFlow == 0 && unitarySys.m_HeatOutAirVolFlow == 0 && unitarySys.m_NoCoolHeatOutAirVolFlow == 0) {
16626 9 : noUnitarySysOutdoorAir = true;
16627 : }
16628 :
16629 9 : if (unitarySys.m_sysType == UnitarySys::SysType::PackagedWSHP || unitarySys.m_sysType == UnitarySys::SysType::PackagedAC ||
16630 0 : unitarySys.m_sysType == UnitarySys::SysType::PackagedHP) {
16631 9 : if (noUnitarySysOutdoorAir && (nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex ||
16632 7 : nodeNumber == unitarySys.AirInNode || nodeNumber == unitarySys.m_OAMixerNodes[0] ||
16633 6 : nodeNumber == unitarySys.m_OAMixerNodes[1] || nodeNumber == unitarySys.m_OAMixerNodes[2]) ||
16634 20 : nodeNumber == unitarySys.m_OAMixerNodes[3] || nodeNumber == unitarySys.CoolCoilOutletNodeNum ||
16635 2 : nodeNumber == unitarySys.HeatCoilOutletNodeNum) {
16636 8 : return true;
16637 : }
16638 : }
16639 : }
16640 34 : return false;
16641 : }
16642 :
16643 45 : void setupAllOutputVars(EnergyPlusData &state, int const numAllSystemTypes)
16644 : {
16645 : // setup reports only once
16646 : // all report variable are set up here after all systems are allocated.
16647 : // UnitarySystem now models other equipment types, any new reports may be setup here.
16648 45 : if (numAllSystemTypes == state.dataUnitarySystems->numUnitarySystems) {
16649 99 : for (int sysNum = 0; sysNum < state.dataUnitarySystems->numUnitarySystems; ++sysNum) {
16650 54 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_sysType) {
16651 9 : case UnitarySys::SysType::Unitary:
16652 : // Setup Report variables for the Unitary System that are not reported in the components themselves
16653 18 : SetupOutputVariable(state,
16654 : "Unitary System Part Load Ratio",
16655 : Constant::Units::None,
16656 9 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
16657 : OutputProcessor::TimeStepType::System,
16658 : OutputProcessor::StoreType::Average,
16659 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16660 18 : SetupOutputVariable(state,
16661 : "Unitary System Total Cooling Rate",
16662 : Constant::Units::W,
16663 9 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
16664 : OutputProcessor::TimeStepType::System,
16665 : OutputProcessor::StoreType::Average,
16666 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16667 18 : SetupOutputVariable(state,
16668 : "Unitary System Sensible Cooling Rate",
16669 : Constant::Units::W,
16670 9 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
16671 : OutputProcessor::TimeStepType::System,
16672 : OutputProcessor::StoreType::Average,
16673 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16674 18 : SetupOutputVariable(state,
16675 : "Unitary System Latent Cooling Rate",
16676 : Constant::Units::W,
16677 9 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
16678 : OutputProcessor::TimeStepType::System,
16679 : OutputProcessor::StoreType::Average,
16680 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16681 18 : SetupOutputVariable(state,
16682 : "Unitary System Total Heating Rate",
16683 : Constant::Units::W,
16684 9 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
16685 : OutputProcessor::TimeStepType::System,
16686 : OutputProcessor::StoreType::Average,
16687 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16688 18 : SetupOutputVariable(state,
16689 : "Unitary System Sensible Heating Rate",
16690 : Constant::Units::W,
16691 9 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
16692 : OutputProcessor::TimeStepType::System,
16693 : OutputProcessor::StoreType::Average,
16694 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16695 18 : SetupOutputVariable(state,
16696 : "Unitary System Latent Heating Rate",
16697 : Constant::Units::W,
16698 9 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
16699 : OutputProcessor::TimeStepType::System,
16700 : OutputProcessor::StoreType::Average,
16701 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16702 18 : SetupOutputVariable(state,
16703 : "Unitary System Ancillary Electricity Rate",
16704 : Constant::Units::W,
16705 9 : state.dataUnitarySystems->unitarySys[sysNum].m_TotalAuxElecPower,
16706 : OutputProcessor::TimeStepType::System,
16707 : OutputProcessor::StoreType::Average,
16708 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16709 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolCoilExists) {
16710 14 : SetupOutputVariable(state,
16711 : "Unitary System Cooling Ancillary Electricity Energy",
16712 : Constant::Units::J,
16713 7 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingAuxElecConsumption,
16714 : OutputProcessor::TimeStepType::System,
16715 : OutputProcessor::StoreType::Sum,
16716 7 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16717 : Constant::eResource::Electricity,
16718 : OutputProcessor::Group::HVAC,
16719 : OutputProcessor::EndUseCat::Cooling);
16720 : }
16721 10 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatCoilExists ||
16722 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SuppCoilExists) {
16723 16 : SetupOutputVariable(state,
16724 : "Unitary System Heating Ancillary Electricity Energy",
16725 : Constant::Units::J,
16726 8 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingAuxElecConsumption,
16727 : OutputProcessor::TimeStepType::System,
16728 : OutputProcessor::StoreType::Sum,
16729 8 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16730 : Constant::eResource::Electricity,
16731 : OutputProcessor::Group::HVAC,
16732 : OutputProcessor::EndUseCat::Heating);
16733 : }
16734 :
16735 18 : SetupOutputVariable(state,
16736 : "Unitary System Electricity Rate",
16737 : Constant::Units::W,
16738 9 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
16739 : OutputProcessor::TimeStepType::System,
16740 : OutputProcessor::StoreType::Average,
16741 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16742 18 : SetupOutputVariable(state,
16743 : "Unitary System Electricity Energy",
16744 : Constant::Units::J,
16745 9 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
16746 : OutputProcessor::TimeStepType::System,
16747 : OutputProcessor::StoreType::Sum,
16748 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16749 :
16750 : // report predicted load as determined by Unitary System for load control only
16751 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_ControlType != UnitarySys::UnitarySysCtrlType::Setpoint) {
16752 16 : SetupOutputVariable(state,
16753 : "Unitary System Predicted Sensible Load to Setpoint Heat Transfer Rate",
16754 : Constant::Units::W,
16755 8 : state.dataUnitarySystems->unitarySys[sysNum].m_SensibleLoadPredicted,
16756 : OutputProcessor::TimeStepType::System,
16757 : OutputProcessor::StoreType::Average,
16758 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16759 16 : SetupOutputVariable(state,
16760 : "Unitary System Predicted Moisture Load to Setpoint Heat Transfer Rate",
16761 : Constant::Units::W,
16762 8 : state.dataUnitarySystems->unitarySys[sysNum].m_MoistureLoadPredicted,
16763 : OutputProcessor::TimeStepType::System,
16764 : OutputProcessor::StoreType::Average,
16765 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16766 : }
16767 :
16768 : // IF(UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)THEN
16769 18 : SetupOutputVariable(state,
16770 : "Unitary System Dehumidification Induced Heating Demand Rate",
16771 : Constant::Units::W,
16772 9 : state.dataUnitarySystems->unitarySys[sysNum].m_DehumidInducedHeatingDemandRate,
16773 : OutputProcessor::TimeStepType::System,
16774 : OutputProcessor::StoreType::Average,
16775 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16776 : // END IF
16777 :
16778 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_FanExists) {
16779 16 : SetupOutputVariable(state,
16780 : "Unitary System Fan Part Load Ratio",
16781 : Constant::Units::None,
16782 8 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
16783 : OutputProcessor::TimeStepType::System,
16784 : OutputProcessor::StoreType::Average,
16785 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16786 : }
16787 :
16788 18 : SetupOutputVariable(state,
16789 : "Unitary System Compressor Part Load Ratio",
16790 : Constant::Units::None,
16791 9 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
16792 : OutputProcessor::TimeStepType::System,
16793 : OutputProcessor::StoreType::Average,
16794 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16795 :
16796 9 : SetupOutputVariable(state,
16797 : "Unitary System Frost Control Status",
16798 : Constant::Units::None,
16799 9 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
16800 : OutputProcessor::TimeStepType::System,
16801 : OutputProcessor::StoreType::Average,
16802 9 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16803 :
16804 9 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num) {
16805 4 : case HVAC::CoilDX_MultiSpeedCooling:
16806 : case HVAC::CoilDX_Cooling: {
16807 4 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecActive) {
16808 2 : SetupOutputVariable(state,
16809 : "Unitary System Heat Recovery Rate",
16810 : Constant::Units::W,
16811 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryRate,
16812 : OutputProcessor::TimeStepType::System,
16813 : OutputProcessor::StoreType::Average,
16814 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16815 2 : SetupOutputVariable(state,
16816 : "Unitary System Heat Recovery Inlet Temperature",
16817 : Constant::Units::C,
16818 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryInletTemp,
16819 : OutputProcessor::TimeStepType::System,
16820 : OutputProcessor::StoreType::Average,
16821 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16822 2 : SetupOutputVariable(state,
16823 : "Unitary System Heat Recovery Outlet Temperature",
16824 : Constant::Units::C,
16825 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryOutletTemp,
16826 : OutputProcessor::TimeStepType::System,
16827 : OutputProcessor::StoreType::Average,
16828 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16829 2 : SetupOutputVariable(state,
16830 : "Unitary System Heat Recovery Fluid Mass Flow Rate",
16831 : Constant::Units::kg_s,
16832 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryMassFlowRate,
16833 : OutputProcessor::TimeStepType::System,
16834 : OutputProcessor::StoreType::Average,
16835 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16836 2 : SetupOutputVariable(state,
16837 : "Unitary System Heat Recovery Energy",
16838 : Constant::Units::J,
16839 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryEnergy,
16840 : OutputProcessor::TimeStepType::System,
16841 : OutputProcessor::StoreType::Sum,
16842 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16843 : }
16844 4 : } break;
16845 2 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16846 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit:
16847 : case HVAC::Coil_CoolingWaterToAirHPSimple:
16848 : case HVAC::Coil_CoolingWaterToAirHP: {
16849 4 : SetupOutputVariable(state,
16850 : "Unitary System Requested Sensible Cooling Rate",
16851 : Constant::Units::W,
16852 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilSensDemand,
16853 : OutputProcessor::TimeStepType::System,
16854 : OutputProcessor::StoreType::Average,
16855 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16856 4 : SetupOutputVariable(state,
16857 : "Unitary System Requested Latent Cooling Rate",
16858 : Constant::Units::W,
16859 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilLatentDemand,
16860 : OutputProcessor::TimeStepType::System,
16861 : OutputProcessor::StoreType::Average,
16862 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16863 2 : } break;
16864 3 : default:
16865 3 : break;
16866 : }
16867 :
16868 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex >= 0) {
16869 11 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
16870 2 : state.dataCoilCoolingDX->coilCoolingDXs[state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex]
16871 2 : .SubcoolReheatFlag) {
16872 2 : SetupOutputVariable(state,
16873 : "Unitary System Zone Load Sensible Heat Ratio",
16874 : Constant::Units::None,
16875 1 : state.dataUnitarySystems->unitarySys[sysNum].LoadSHR,
16876 : OutputProcessor::TimeStepType::System,
16877 : OutputProcessor::StoreType::Average,
16878 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16879 2 : SetupOutputVariable(state,
16880 : "Unitary System Cooling Coil Load Sensible Heat Ratio",
16881 : Constant::Units::None,
16882 1 : state.dataUnitarySystems->unitarySys[sysNum].CoilSHR,
16883 : OutputProcessor::TimeStepType::System,
16884 : OutputProcessor::StoreType::Average,
16885 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16886 : }
16887 : }
16888 :
16889 9 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num) {
16890 2 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16891 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
16892 : case HVAC::Coil_HeatingWaterToAirHPSimple:
16893 : case HVAC::Coil_HeatingWaterToAirHP: {
16894 4 : SetupOutputVariable(state,
16895 : "Unitary System Requested Heating Rate",
16896 : Constant::Units::W,
16897 2 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilSensDemand,
16898 : OutputProcessor::TimeStepType::System,
16899 : OutputProcessor::StoreType::Average,
16900 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16901 2 : } break;
16902 7 : default:
16903 7 : break;
16904 : }
16905 :
16906 9 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
16907 7 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
16908 7 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
16909 5 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
16910 20 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
16911 4 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
16912 10 : SetupOutputVariable(state,
16913 : "Unitary System DX Coil Cycling Ratio",
16914 : Constant::Units::None,
16915 5 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
16916 : OutputProcessor::TimeStepType::System,
16917 : OutputProcessor::StoreType::Average,
16918 5 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16919 10 : SetupOutputVariable(state,
16920 : "Unitary System DX Coil Speed Ratio",
16921 : Constant::Units::None,
16922 5 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
16923 : OutputProcessor::TimeStepType::System,
16924 : OutputProcessor::StoreType::Average,
16925 5 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16926 5 : SetupOutputVariable(state,
16927 : "Unitary System DX Coil Speed Level",
16928 : Constant::Units::None,
16929 5 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
16930 : OutputProcessor::TimeStepType::System,
16931 : OutputProcessor::StoreType::Average,
16932 5 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16933 : }
16934 :
16935 9 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
16936 9 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
16937 18 : state.dataUnitarySystems->unitarySys[sysNum].m_DiscreteSpeedCoolingCoil) ||
16938 9 : (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWater &&
16939 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MultiSpeedHeatingCoil)) {
16940 0 : SetupOutputVariable(state,
16941 : "Unitary System Water Coil Cycling Ratio",
16942 : Constant::Units::None,
16943 0 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
16944 : OutputProcessor::TimeStepType::System,
16945 : OutputProcessor::StoreType::Average,
16946 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16947 0 : SetupOutputVariable(state,
16948 : "Unitary System Water Coil Speed Ratio",
16949 : Constant::Units::None,
16950 0 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
16951 : OutputProcessor::TimeStepType::System,
16952 : OutputProcessor::StoreType::Average,
16953 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16954 0 : SetupOutputVariable(state,
16955 : "Unitary System Water Coil Speed Level",
16956 : Constant::Units::None,
16957 0 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
16958 : OutputProcessor::TimeStepType::System,
16959 : OutputProcessor::StoreType::Average,
16960 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16961 : }
16962 :
16963 9 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
16964 0 : SetupEMSActuator(state,
16965 : "UnitarySystem",
16966 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16967 : "Autosized Supply Air Flow Rate",
16968 : "[m3/s]",
16969 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideOn,
16970 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideValue);
16971 0 : SetupEMSActuator(state,
16972 : "UnitarySystem",
16973 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16974 : "Autosized Supply Air Flow Rate During Cooling Operation",
16975 : "[m3/s]",
16976 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideOn,
16977 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideValue);
16978 0 : SetupEMSActuator(state,
16979 : "UnitarySystem",
16980 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16981 : "Autosized Supply Air Flow Rate During Heating Operation",
16982 : "[m3/s]",
16983 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideOn,
16984 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideValue);
16985 0 : SetupEMSActuator(state,
16986 : "UnitarySystem",
16987 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16988 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
16989 : "[m3/s]",
16990 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideOn,
16991 0 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideValue);
16992 0 : SetupEMSInternalVariable(state,
16993 : "Unitary System Control Zone Mass Flow Fraction",
16994 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16995 : "[]",
16996 0 : state.dataUnitarySystems->unitarySys[sysNum].ControlZoneMassFlowFrac);
16997 0 : SetupEMSInternalVariable(state,
16998 : "Unitary HVAC Design Heating Capacity",
16999 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17000 : "[W]",
17001 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignHeatingCapacity);
17002 0 : SetupEMSInternalVariable(state,
17003 : "Unitary HVAC Design Cooling Capacity",
17004 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17005 : "[W]",
17006 0 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignCoolingCapacity);
17007 0 : SetupEMSActuator(state,
17008 : "Unitary HVAC",
17009 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17010 : "Sensible Load Request",
17011 : "[W]",
17012 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSensZoneLoadRequest,
17013 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSSensibleZoneLoadValue);
17014 0 : SetupEMSActuator(state,
17015 : "Unitary HVAC",
17016 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17017 : "Moisture Load Request",
17018 : "[W]",
17019 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideMoistZoneLoadRequest,
17020 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSMoistureZoneLoadValue);
17021 0 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17022 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17023 0 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
17024 0 : SetupEMSActuator(state,
17025 : "Coil Speed Control",
17026 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17027 : "Unitary System DX Coil Speed Value",
17028 : "[]",
17029 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumOn,
17030 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumValue);
17031 : }
17032 0 : SetupEMSActuator(state,
17033 : "Coil Speed Control",
17034 0 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17035 : "Unitary System Supplemental Coil Stage Level",
17036 : "[]",
17037 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumOn,
17038 0 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumValue);
17039 : }
17040 : bool anyEMSRan;
17041 9 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
17042 54 : break;
17043 22 : case UnitarySys::SysType::CoilCoolingDX:
17044 : // Setup Report variables for the DXCoolingSystem that is not reported in the components themselves
17045 22 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
17046 4 : SetupOutputVariable(state,
17047 : "Coil System Cycling Ratio",
17048 : Constant::Units::None,
17049 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17050 : OutputProcessor::TimeStepType::System,
17051 : OutputProcessor::StoreType::Average,
17052 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17053 4 : SetupOutputVariable(state,
17054 : "Coil System Compressor Speed Ratio",
17055 : Constant::Units::None,
17056 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17057 : OutputProcessor::TimeStepType::System,
17058 : OutputProcessor::StoreType::Average,
17059 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17060 20 : } else if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
17061 6 : SetupOutputVariable(state,
17062 : "Coil System Cycling Ratio",
17063 : Constant::Units::None,
17064 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17065 : OutputProcessor::TimeStepType::System,
17066 : OutputProcessor::StoreType::Average,
17067 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17068 6 : SetupOutputVariable(state,
17069 : "Coil System Compressor Speed Ratio",
17070 : Constant::Units::None,
17071 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17072 : OutputProcessor::TimeStepType::System,
17073 : OutputProcessor::StoreType::Average,
17074 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17075 3 : SetupOutputVariable(state,
17076 : "Coil System Compressor Speed Number",
17077 : Constant::Units::None,
17078 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedNum,
17079 : OutputProcessor::TimeStepType::System,
17080 : OutputProcessor::StoreType::Average,
17081 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17082 : } else {
17083 34 : SetupOutputVariable(state,
17084 : "Coil System Part Load Ratio",
17085 : Constant::Units::None,
17086 17 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingPartLoadFrac,
17087 : OutputProcessor::TimeStepType::System,
17088 : OutputProcessor::StoreType::Average,
17089 17 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17090 : }
17091 22 : SetupOutputVariable(state,
17092 : "Coil System Frost Control Status",
17093 : Constant::Units::None,
17094 22 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17095 : OutputProcessor::TimeStepType::System,
17096 : OutputProcessor::StoreType::Average,
17097 22 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17098 22 : break;
17099 6 : case UnitarySys::SysType::CoilCoolingWater:
17100 : // Setup Report variables for the CoilSystemWater
17101 12 : SetupOutputVariable(state,
17102 : "Coil System Water Part Load Ratio",
17103 : Constant::Units::None,
17104 6 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17105 : OutputProcessor::TimeStepType::System,
17106 : OutputProcessor::StoreType::Average,
17107 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17108 12 : SetupOutputVariable(state,
17109 : "Coil System Water Total Cooling Rate",
17110 : Constant::Units::W,
17111 6 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17112 : OutputProcessor::TimeStepType::System,
17113 : OutputProcessor::StoreType::Average,
17114 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17115 12 : SetupOutputVariable(state,
17116 : "Coil System Water Sensible Cooling Rate",
17117 : Constant::Units::W,
17118 6 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17119 : OutputProcessor::TimeStepType::System,
17120 : OutputProcessor::StoreType::Average,
17121 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17122 12 : SetupOutputVariable(state,
17123 : "Coil System Water Latent Cooling Rate",
17124 : Constant::Units::W,
17125 6 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17126 : OutputProcessor::TimeStepType::System,
17127 : OutputProcessor::StoreType::Average,
17128 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17129 :
17130 6 : if (state.dataUnitarySystems->unitarySys[sysNum].m_TemperatureOffsetControlActive) {
17131 6 : SetupOutputVariable(state,
17132 : "Coil System Water Control Status",
17133 : Constant::Units::None,
17134 6 : state.dataUnitarySystems->unitarySys[sysNum].temperatureOffsetControlStatus,
17135 : OutputProcessor::TimeStepType::System,
17136 : OutputProcessor::StoreType::Average,
17137 6 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17138 : }
17139 6 : break;
17140 12 : case UnitarySys::SysType::PackagedAC:
17141 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalAirConditioner'
17142 24 : SetupOutputVariable(state,
17143 : "Zone Packaged Terminal Air Conditioner Total Heating Rate",
17144 : Constant::Units::W,
17145 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17146 : OutputProcessor::TimeStepType::System,
17147 : OutputProcessor::StoreType::Average,
17148 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17149 24 : SetupOutputVariable(state,
17150 : "Zone Packaged Terminal Air Conditioner Total Heating Energy",
17151 : Constant::Units::J,
17152 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17153 : OutputProcessor::TimeStepType::System,
17154 : OutputProcessor::StoreType::Sum,
17155 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17156 24 : SetupOutputVariable(state,
17157 : "Zone Packaged Terminal Air Conditioner Total Cooling Rate",
17158 : Constant::Units::W,
17159 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17160 : OutputProcessor::TimeStepType::System,
17161 : OutputProcessor::StoreType::Average,
17162 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17163 24 : SetupOutputVariable(state,
17164 : "Zone Packaged Terminal Air Conditioner Total Cooling Energy",
17165 : Constant::Units::J,
17166 12 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17167 : OutputProcessor::TimeStepType::System,
17168 : OutputProcessor::StoreType::Sum,
17169 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17170 24 : SetupOutputVariable(state,
17171 : "Zone Packaged Terminal Air Conditioner Sensible Heating Rate",
17172 : Constant::Units::W,
17173 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17174 : OutputProcessor::TimeStepType::System,
17175 : OutputProcessor::StoreType::Average,
17176 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17177 24 : SetupOutputVariable(state,
17178 : "Zone Packaged Terminal Air Conditioner Sensible Heating Energy",
17179 : Constant::Units::J,
17180 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17181 : OutputProcessor::TimeStepType::System,
17182 : OutputProcessor::StoreType::Sum,
17183 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17184 24 : SetupOutputVariable(state,
17185 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Rate",
17186 : Constant::Units::W,
17187 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17188 : OutputProcessor::TimeStepType::System,
17189 : OutputProcessor::StoreType::Average,
17190 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17191 24 : SetupOutputVariable(state,
17192 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Energy",
17193 : Constant::Units::J,
17194 12 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17195 : OutputProcessor::TimeStepType::System,
17196 : OutputProcessor::StoreType::Sum,
17197 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17198 24 : SetupOutputVariable(state,
17199 : "Zone Packaged Terminal Air Conditioner Latent Heating Rate",
17200 : Constant::Units::W,
17201 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17202 : OutputProcessor::TimeStepType::System,
17203 : OutputProcessor::StoreType::Average,
17204 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17205 24 : SetupOutputVariable(state,
17206 : "Zone Packaged Terminal Air Conditioner Latent Heating Energy",
17207 : Constant::Units::J,
17208 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17209 : OutputProcessor::TimeStepType::System,
17210 : OutputProcessor::StoreType::Sum,
17211 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17212 24 : SetupOutputVariable(state,
17213 : "Zone Packaged Terminal Air Conditioner Latent Cooling Rate",
17214 : Constant::Units::W,
17215 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17216 : OutputProcessor::TimeStepType::System,
17217 : OutputProcessor::StoreType::Average,
17218 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17219 24 : SetupOutputVariable(state,
17220 : "Zone Packaged Terminal Air Conditioner Latent Cooling Energy",
17221 : Constant::Units::J,
17222 12 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17223 : OutputProcessor::TimeStepType::System,
17224 : OutputProcessor::StoreType::Sum,
17225 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17226 24 : SetupOutputVariable(state,
17227 : "Zone Packaged Terminal Air Conditioner Electricity Rate",
17228 : Constant::Units::W,
17229 12 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17230 : OutputProcessor::TimeStepType::System,
17231 : OutputProcessor::StoreType::Average,
17232 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17233 24 : SetupOutputVariable(state,
17234 : "Zone Packaged Terminal Air Conditioner Electricity Energy",
17235 : Constant::Units::J,
17236 12 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17237 : OutputProcessor::TimeStepType::System,
17238 : OutputProcessor::StoreType::Sum,
17239 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17240 24 : SetupOutputVariable(state,
17241 : "Zone Packaged Terminal Air Conditioner Fan Part Load Ratio",
17242 : Constant::Units::None,
17243 12 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17244 : OutputProcessor::TimeStepType::System,
17245 : OutputProcessor::StoreType::Average,
17246 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17247 24 : SetupOutputVariable(state,
17248 : "Zone Packaged Terminal Air Conditioner Compressor Part Load Ratio",
17249 : Constant::Units::None,
17250 12 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17251 : OutputProcessor::TimeStepType::System,
17252 : OutputProcessor::StoreType::Average,
17253 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17254 12 : SetupOutputVariable(state,
17255 : "Zone Packaged Terminal Air Conditioner Fan Availability Status",
17256 : Constant::Units::None,
17257 12 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17258 : OutputProcessor::TimeStepType::System,
17259 : OutputProcessor::StoreType::Average,
17260 12 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17261 12 : break;
17262 3 : case UnitarySys::SysType::PackagedHP:
17263 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalHeatPump'
17264 6 : SetupOutputVariable(state,
17265 : "Zone Packaged Terminal Heat Pump Total Heating Rate",
17266 : Constant::Units::W,
17267 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17268 : OutputProcessor::TimeStepType::System,
17269 : OutputProcessor::StoreType::Average,
17270 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17271 6 : SetupOutputVariable(state,
17272 : "Zone Packaged Terminal Heat Pump Total Heating Energy",
17273 : Constant::Units::J,
17274 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17275 : OutputProcessor::TimeStepType::System,
17276 : OutputProcessor::StoreType::Sum,
17277 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17278 6 : SetupOutputVariable(state,
17279 : "Zone Packaged Terminal Heat Pump Total Cooling Rate",
17280 : Constant::Units::W,
17281 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17282 : OutputProcessor::TimeStepType::System,
17283 : OutputProcessor::StoreType::Average,
17284 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17285 6 : SetupOutputVariable(state,
17286 : "Zone Packaged Terminal Heat Pump Total Cooling Energy",
17287 : Constant::Units::J,
17288 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17289 : OutputProcessor::TimeStepType::System,
17290 : OutputProcessor::StoreType::Sum,
17291 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17292 6 : SetupOutputVariable(state,
17293 : "Zone Packaged Terminal Heat Pump Sensible Heating Rate",
17294 : Constant::Units::W,
17295 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17296 : OutputProcessor::TimeStepType::System,
17297 : OutputProcessor::StoreType::Average,
17298 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17299 6 : SetupOutputVariable(state,
17300 : "Zone Packaged Terminal Heat Pump Sensible Heating Energy",
17301 : Constant::Units::J,
17302 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17303 : OutputProcessor::TimeStepType::System,
17304 : OutputProcessor::StoreType::Sum,
17305 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17306 6 : SetupOutputVariable(state,
17307 : "Zone Packaged Terminal Heat Pump Sensible Cooling Rate",
17308 : Constant::Units::W,
17309 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17310 : OutputProcessor::TimeStepType::System,
17311 : OutputProcessor::StoreType::Average,
17312 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17313 6 : SetupOutputVariable(state,
17314 : "Zone Packaged Terminal Heat Pump Sensible Cooling Energy",
17315 : Constant::Units::J,
17316 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17317 : OutputProcessor::TimeStepType::System,
17318 : OutputProcessor::StoreType::Sum,
17319 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17320 6 : SetupOutputVariable(state,
17321 : "Zone Packaged Terminal Heat Pump Latent Heating Rate",
17322 : Constant::Units::W,
17323 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17324 : OutputProcessor::TimeStepType::System,
17325 : OutputProcessor::StoreType::Average,
17326 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17327 6 : SetupOutputVariable(state,
17328 : "Zone Packaged Terminal Heat Pump Latent Heating Energy",
17329 : Constant::Units::J,
17330 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17331 : OutputProcessor::TimeStepType::System,
17332 : OutputProcessor::StoreType::Sum,
17333 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17334 6 : SetupOutputVariable(state,
17335 : "Zone Packaged Terminal Heat Pump Latent Cooling Rate",
17336 : Constant::Units::W,
17337 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17338 : OutputProcessor::TimeStepType::System,
17339 : OutputProcessor::StoreType::Average,
17340 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17341 6 : SetupOutputVariable(state,
17342 : "Zone Packaged Terminal Heat Pump Latent Cooling Energy",
17343 : Constant::Units::J,
17344 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17345 : OutputProcessor::TimeStepType::System,
17346 : OutputProcessor::StoreType::Sum,
17347 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17348 6 : SetupOutputVariable(state,
17349 : "Zone Packaged Terminal Heat Pump Electricity Rate",
17350 : Constant::Units::W,
17351 3 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17352 : OutputProcessor::TimeStepType::System,
17353 : OutputProcessor::StoreType::Average,
17354 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17355 6 : SetupOutputVariable(state,
17356 : "Zone Packaged Terminal Heat Pump Electricity Energy",
17357 : Constant::Units::J,
17358 3 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17359 : OutputProcessor::TimeStepType::System,
17360 : OutputProcessor::StoreType::Sum,
17361 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17362 6 : SetupOutputVariable(state,
17363 : "Zone Packaged Terminal Heat Pump Fan Part Load Ratio",
17364 : Constant::Units::None,
17365 3 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17366 : OutputProcessor::TimeStepType::System,
17367 : OutputProcessor::StoreType::Average,
17368 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17369 6 : SetupOutputVariable(state,
17370 : "Zone Packaged Terminal Heat Pump Compressor Part Load Ratio",
17371 : Constant::Units::None,
17372 3 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17373 : OutputProcessor::TimeStepType::System,
17374 : OutputProcessor::StoreType::Average,
17375 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17376 3 : SetupOutputVariable(state,
17377 : "Zone Packaged Terminal Heat Pump Fan Availability Status",
17378 : Constant::Units::None,
17379 3 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17380 : OutputProcessor::TimeStepType::System,
17381 : OutputProcessor::StoreType::Average,
17382 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17383 3 : break;
17384 2 : case UnitarySys::SysType::PackagedWSHP:
17385 : // CurrentModuleObject = 'ZoneHVAC:WaterToAirHeatPump'
17386 4 : SetupOutputVariable(state,
17387 : "Zone Water to Air Heat Pump Total Heating Rate",
17388 : Constant::Units::W,
17389 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17390 : OutputProcessor::TimeStepType::System,
17391 : OutputProcessor::StoreType::Average,
17392 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17393 4 : SetupOutputVariable(state,
17394 : "Zone Water to Air Heat Pump Total Heating Energy",
17395 : Constant::Units::J,
17396 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17397 : OutputProcessor::TimeStepType::System,
17398 : OutputProcessor::StoreType::Sum,
17399 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17400 4 : SetupOutputVariable(state,
17401 : "Zone Water to Air Heat Pump Total Cooling Rate",
17402 : Constant::Units::W,
17403 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17404 : OutputProcessor::TimeStepType::System,
17405 : OutputProcessor::StoreType::Average,
17406 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17407 4 : SetupOutputVariable(state,
17408 : "Zone Water to Air Heat Pump Total Cooling Energy",
17409 : Constant::Units::J,
17410 2 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17411 : OutputProcessor::TimeStepType::System,
17412 : OutputProcessor::StoreType::Sum,
17413 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17414 4 : SetupOutputVariable(state,
17415 : "Zone Water to Air Heat Pump Sensible Heating Rate",
17416 : Constant::Units::W,
17417 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17418 : OutputProcessor::TimeStepType::System,
17419 : OutputProcessor::StoreType::Average,
17420 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17421 4 : SetupOutputVariable(state,
17422 : "Zone Water to Air Heat Pump Sensible Heating Energy",
17423 : Constant::Units::J,
17424 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17425 : OutputProcessor::TimeStepType::System,
17426 : OutputProcessor::StoreType::Sum,
17427 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17428 4 : SetupOutputVariable(state,
17429 : "Zone Water to Air Heat Pump Sensible Cooling Rate",
17430 : Constant::Units::W,
17431 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17432 : OutputProcessor::TimeStepType::System,
17433 : OutputProcessor::StoreType::Average,
17434 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17435 4 : SetupOutputVariable(state,
17436 : "Zone Water to Air Heat Pump Sensible Cooling Energy",
17437 : Constant::Units::J,
17438 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17439 : OutputProcessor::TimeStepType::System,
17440 : OutputProcessor::StoreType::Sum,
17441 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17442 4 : SetupOutputVariable(state,
17443 : "Zone Water to Air Heat Pump Latent Heating Rate",
17444 : Constant::Units::W,
17445 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17446 : OutputProcessor::TimeStepType::System,
17447 : OutputProcessor::StoreType::Average,
17448 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17449 4 : SetupOutputVariable(state,
17450 : "Zone Water to Air Heat Pump Latent Heating Energy",
17451 : Constant::Units::J,
17452 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17453 : OutputProcessor::TimeStepType::System,
17454 : OutputProcessor::StoreType::Sum,
17455 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17456 4 : SetupOutputVariable(state,
17457 : "Zone Water to Air Heat Pump Latent Cooling Rate",
17458 : Constant::Units::W,
17459 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17460 : OutputProcessor::TimeStepType::System,
17461 : OutputProcessor::StoreType::Average,
17462 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17463 4 : SetupOutputVariable(state,
17464 : "Zone Water to Air Heat Pump Latent Cooling Energy",
17465 : Constant::Units::J,
17466 2 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17467 : OutputProcessor::TimeStepType::System,
17468 : OutputProcessor::StoreType::Sum,
17469 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17470 4 : SetupOutputVariable(state,
17471 : "Zone Water to Air Heat Pump Electricity Rate",
17472 : Constant::Units::W,
17473 2 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17474 : OutputProcessor::TimeStepType::System,
17475 : OutputProcessor::StoreType::Average,
17476 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17477 4 : SetupOutputVariable(state,
17478 : "Zone Water to Air Heat Pump Electricity Energy",
17479 : Constant::Units::J,
17480 2 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17481 : OutputProcessor::TimeStepType::System,
17482 : OutputProcessor::StoreType::Sum,
17483 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17484 4 : SetupOutputVariable(state,
17485 : "Zone Water to Air Heat Pump Fan Part Load Ratio",
17486 : Constant::Units::None,
17487 2 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17488 : OutputProcessor::TimeStepType::System,
17489 : OutputProcessor::StoreType::Average,
17490 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17491 4 : SetupOutputVariable(state,
17492 : "Zone Water to Air Heat Pump Compressor Part Load Ratio",
17493 : Constant::Units::None,
17494 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17495 : OutputProcessor::TimeStepType::System,
17496 : OutputProcessor::StoreType::Average,
17497 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17498 2 : SetupOutputVariable(state,
17499 : "Zone Water to Air Heat Pump Fan Availability Status",
17500 : Constant::Units::None,
17501 2 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17502 : OutputProcessor::TimeStepType::System,
17503 : OutputProcessor::StoreType::Average,
17504 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17505 2 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
17506 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
17507 4 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedCooling > 1) ||
17508 1 : ((state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
17509 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
17510 1 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedHeating > 1)) {
17511 2 : SetupOutputVariable(state,
17512 : "Unitary System Water Coil Multispeed Fan Cycling Ratio",
17513 : Constant::Units::None,
17514 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17515 : OutputProcessor::TimeStepType::System,
17516 : OutputProcessor::StoreType::Average,
17517 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17518 2 : SetupOutputVariable(state,
17519 : "Unitary System Water Coil Multispeed Fan Speed Ratio",
17520 : Constant::Units::None,
17521 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17522 : OutputProcessor::TimeStepType::System,
17523 : OutputProcessor::StoreType::Average,
17524 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17525 1 : SetupOutputVariable(state,
17526 : "Unitary System Water Coil Multispeed Fan Speed Level",
17527 : Constant::Units::None,
17528 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17529 : OutputProcessor::TimeStepType::System,
17530 : OutputProcessor::StoreType::Average,
17531 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17532 : }
17533 2 : break;
17534 0 : default:
17535 0 : ShowFatalError(state,
17536 : "setupAllOutputVar: Developer error. All report variables must be set up here after all systems are read in.");
17537 : }
17538 : }
17539 45 : state.dataUnitarySystems->setupOutputOnce = false;
17540 : } else {
17541 0 : ShowSevereError(state,
17542 : "setupAllOutputVar: Developer error. Should never get here. Remove when comfortable that UnitarySys::allocateUnitarySys "
17543 : "is working as expected.");
17544 0 : ShowFatalError(state, "setupAllOutputVar: Developer error. Conflict in number of UnitarySystems.");
17545 : }
17546 45 : }
17547 :
17548 4 : void isWaterCoilHeatRecoveryType(EnergyPlusData const &state, int const waterCoilNodeNum, bool &nodeNotFound)
17549 : {
17550 4 : if (!nodeNotFound) return;
17551 0 : nodeNotFound = std::none_of(
17552 0 : state.dataUnitarySystems->unitarySys.cbegin(), state.dataUnitarySystems->unitarySys.cend(), [waterCoilNodeNum](auto const &us) {
17553 0 : return us.m_WaterHRPlantLoopModel && us.m_HRcoolCoilFluidInletNode == waterCoilNodeNum;
17554 : });
17555 : }
17556 :
17557 15 : Real64 UnitarySys::getFanDeltaTemp(EnergyPlusData &state, bool const firstHVACIteration, Real64 const massFlowRate, Real64 const airFlowRatio)
17558 : {
17559 15 : int FanInletNode = 0;
17560 15 : int FanOutletNode = 0;
17561 :
17562 15 : auto *fan = state.dataFans->fans(this->m_FanIndex);
17563 15 : FanInletNode = fan->inletNodeNum;
17564 15 : FanOutletNode = fan->outletNodeNum;
17565 15 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = massFlowRate;
17566 15 : fan->simulate(state, firstHVACIteration, airFlowRatio, _, airFlowRatio, _, _, _);
17567 15 : return state.dataLoopNodes->Node(FanOutletNode).Temp - state.dataLoopNodes->Node(FanInletNode).Temp;
17568 : }
17569 :
17570 3 : void UnitarySys::setEconomizerStagingOperationSpeed(EnergyPlusData &state, bool const firstHVACIteration, Real64 const zoneLoad)
17571 : {
17572 3 : this->m_LowSpeedEconOutput = 0;
17573 3 : this->m_LowSpeedEconRuntime = 0;
17574 3 : this->m_EconoPartLoadRatio = 0;
17575 3 : this->m_EconoSpeedNum = 0;
17576 3 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
17577 3 : Real64 mixedTempAtMinOA = 0;
17578 3 : Real64 highSpeedEconMassFlowRate = 0;
17579 3 : Real64 highSpeedFanDT = 0;
17580 3 : Real64 econClgOutput = 0;
17581 3 : Real64 lowSpeedEconMassFlowRate = 0;
17582 3 : Real64 lowSpeedFanDT = 0;
17583 3 : Real64 highSpeedEconRuntime = 0;
17584 3 : Real64 econClgOutputMinOA = 0;
17585 : // determine outdoor air properties
17586 : using Psychrometrics::PsyCpAirFnW;
17587 3 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
17588 3 : Real64 outdoorAirTemp = state.dataLoopNodes->Node(outdoorAirController.InletNode).Temp;
17589 3 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
17590 : // iterate through the unitary system's cooling speed to see at which
17591 : // air flow rate the load can be met at 100% outdoor air fraction
17592 9 : for (int clgSpd = 1; clgSpd <= this->m_NumOfSpeedCooling; ++clgSpd) {
17593 : // calculations for "high speed" refer to operation at the current
17594 : // cooling speed, "clgSpd", and "low speed" is "clgSpd -1"
17595 9 : highSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd];
17596 : // determine air temperature difference for across the fan at this air flow rate
17597 9 : highSpeedFanDT = this->getFanDeltaTemp(state,
17598 : firstHVACIteration,
17599 : highSpeedEconMassFlowRate,
17600 9 : highSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
17601 9 : econClgOutput = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + highSpeedFanDT));
17602 : // check if economizer alone can meet the load, or if we have reached the maximum cooling speed
17603 9 : if (econClgOutput > std::abs(zoneLoad) || clgSpd == this->m_NumOfSpeedCooling) {
17604 : // low speed economizer operation is handled through normal process (i.e., no staging operation)
17605 3 : if (clgSpd > 1) {
17606 : // check that the system output at the minimum outdoor air flow rate doesn't "overcool" at this speed
17607 3 : mixedTempAtMinOA = 0;
17608 3 : if (highSpeedEconMassFlowRate - outdoorAirController.MinOA > 0) {
17609 3 : mixedTempAtMinOA =
17610 3 : (outdoorAirTemp * outdoorAirController.MinOA + state.dataLoopNodes->Node(outdoorAirController.RetNode).Temp *
17611 3 : (highSpeedEconMassFlowRate - outdoorAirController.MinOA)) /
17612 : highSpeedEconMassFlowRate;
17613 : } else {
17614 0 : mixedTempAtMinOA = outdoorAirTemp;
17615 : }
17616 3 : econClgOutputMinOA = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (mixedTempAtMinOA + highSpeedFanDT));
17617 3 : if (econClgOutputMinOA < std::abs(zoneLoad)) {
17618 2 : highSpeedEconRuntime = 1.0;
17619 : } else {
17620 : // if running at this speed would "overcool", we run partly at the lower speed and partly at this speed
17621 1 : lowSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd - 1];
17622 1 : lowSpeedFanDT = this->getFanDeltaTemp(state,
17623 : firstHVACIteration,
17624 : lowSpeedEconMassFlowRate,
17625 1 : lowSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
17626 1 : this->m_LowSpeedEconOutput = cpAir * lowSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + lowSpeedFanDT));
17627 : // determine this speed's runtime
17628 1 : highSpeedEconRuntime = (std::abs(zoneLoad) - this->m_LowSpeedEconOutput) / (econClgOutput - this->m_LowSpeedEconOutput);
17629 : }
17630 : } else {
17631 0 : highSpeedEconRuntime = 1.0;
17632 : }
17633 : // set economizer air flow "speed"
17634 3 : this->m_EconoSpeedNum = clgSpd;
17635 : // set economizer PLR, a.k.a the system fan part load ratio, and runtime at each speed
17636 3 : this->m_EconoPartLoadRatio = highSpeedEconRuntime;
17637 3 : this->m_LowSpeedEconRuntime = 1 - highSpeedEconRuntime;
17638 3 : break;
17639 : }
17640 : }
17641 3 : }
17642 :
17643 1 : void UnitarySys::calcMixedTempAirSPforEconomizerStagingOperation(EnergyPlusData &state,
17644 : int const airLoopNum,
17645 : bool const firstHVACIteration,
17646 : Real64 const zoneLoad)
17647 : {
17648 1 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
17649 : using Psychrometrics::PsyCpAirFnW;
17650 1 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
17651 1 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
17652 : // determine and set new air loop mixed air flow rate
17653 1 : Real64 mixedAirFlowRate = this->m_EconoPartLoadRatio * this->m_CoolMassFlowRate[this->m_EconoSpeedNum] +
17654 1 : this->m_LowSpeedEconRuntime * this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
17655 1 : if (airLoopNum > 0) {
17656 : // request fixed mixed flow rate
17657 0 : state.dataAirLoop->AirLoopControlInfo(airLoopNum).LoopFlowRateSet = true;
17658 0 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac = mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
17659 : // adjust mixed air flow rate for rated air flow rate adjustment (variable speed coils only)
17660 0 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac *=
17661 0 : this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling] / state.dataAirLoop->AirLoopFlow(airLoopNum).DesSupply;
17662 : }
17663 : // determine air temperature difference across fan based on new mixed air flow rate
17664 1 : int mixedAirNode = outdoorAirController.MixNode;
17665 1 : Real64 fanDTAtMixedAirFlowRate = this->getFanDeltaTemp(
17666 1 : state, firstHVACIteration, mixedAirFlowRate, mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
17667 : // determine new mixed air setpoint
17668 1 : Real64 newMixedAirSP = zoneTemp - std::abs(zoneLoad) / (cpAir * mixedAirFlowRate);
17669 1 : state.dataLoopNodes->Node(mixedAirNode).TempSetPoint = newMixedAirSP - fanDTAtMixedAirFlowRate;
17670 1 : }
17671 :
17672 : void
17673 0 : UnitarySys::manageEconomizerStagingOperation(EnergyPlusData &state, int const airLoopNum, bool const firstHVACIteration, Real64 const zoneLoad)
17674 : {
17675 0 : if (airLoopNum > 0) {
17676 0 : if (state.dataAirLoop->AirLoopControlInfo(airLoopNum).EconoActive == true && state.dataGlobal->WarmupFlag == false &&
17677 0 : state.dataUnitarySystems->CoolingLoad) {
17678 0 : this->setEconomizerStagingOperationSpeed(state, firstHVACIteration, zoneLoad);
17679 :
17680 : // adjustments are only needed when economizer speed is greater than the lowest speed
17681 0 : if (this->m_EconoSpeedNum > 0) {
17682 0 : this->calcMixedTempAirSPforEconomizerStagingOperation(state, airLoopNum, firstHVACIteration, zoneLoad);
17683 :
17684 : // recalculate the outdoor air fraction to meet the new mixed air setpoint at the new mixed air flow rate
17685 0 : MixedAir::ManageOutsideAirSystem(
17686 0 : state, state.dataAirLoop->OutsideAirSys(this->OASysIndex).Name, firstHVACIteration, airLoopNum, this->OASysIndex);
17687 : }
17688 : }
17689 : }
17690 0 : }
17691 :
17692 : } // namespace UnitarySystems
17693 : } // namespace EnergyPlus
|