Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, 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 fluidNameSteam("STEAM");
115 : static constexpr std::string_view blankString("");
116 : static const std::string blankStdString("");
117 :
118 7705441 : void UnitarySys::simulate(EnergyPlusData &state,
119 : std::string_view Name,
120 : bool const FirstHVACIteration,
121 : int const AirLoopNum,
122 : int &CompIndex,
123 : bool &HeatActive,
124 : bool &CoolActive,
125 : int const ZoneOAUnitNum,
126 : Real64 const OAUCoilOutTemp,
127 : bool const ZoneEquipment,
128 : Real64 &sysOutputProvided,
129 : Real64 &latOutputProvided)
130 : {
131 7705441 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
132 :
133 : // Obtains and Allocates unitary system related parameters from input file
134 7705441 : if (this->m_ThisSysInputShouldBeGotten) {
135 505 : getUnitarySystemInput(state, Name, ZoneEquipment, ZoneOAUnitNum);
136 : }
137 7705441 : CompIndex = this->m_EquipCompNum;
138 7705441 : state.dataUnitarySystems->FanSpeedRatio = 1.0;
139 7705441 : this->initUnitarySystems(state, AirLoopNum, FirstHVACIteration, OAUCoilOutTemp);
140 7705441 : if (!this->m_OKToPrintSizing) return;
141 :
142 : // MassFlowRateMaxAvail issues are impeding non-VAV air loop equipment by limiting air flow
143 : // temporarily open up flow limits while simulating, and then set this same value at the INLET after this parent has simulated
144 7705441 : Real64 tempMassFlowRateMaxAvail = state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail;
145 : // this is not working for CoilSystem simulated with UnitarySystem. Try to protect when this happens.
146 7705441 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
147 2660380 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = this->m_DesignMassFlowRate;
148 : }
149 :
150 7705441 : bool HXUnitOn = false;
151 7705441 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
152 3607422 : this->controlUnitarySystemtoSP(
153 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
154 : } else {
155 4098019 : this->controlUnitarySystemtoLoad(
156 : state, AirLoopNum, FirstHVACIteration, CompressorOn, OAUCoilOutTemp, HXUnitOn, sysOutputProvided, latOutputProvided);
157 : }
158 :
159 : // Report the current output
160 7705441 : this->reportUnitarySystem(state, AirLoopNum);
161 :
162 : // CoolActive = false; // set in call from ZoneEquipmentManager
163 7705441 : if (this->m_CoolingPartLoadFrac * double(CompressorOn) > 0.0) CoolActive = true;
164 : // HeatActive = false; // set in call from ZoneEquipmentManager
165 7705441 : if (this->m_HeatingPartLoadFrac * double(CompressorOn) > 0.0 || this->m_SuppHeatPartLoadFrac * double(CompressorOn) > 0.0) HeatActive = true;
166 :
167 : // set econo lockout flag
168 : // If the system is not an equipment of Outdoor air unit
169 7705441 : if (AirLoopNum > 0 && !state.dataAirLoop->AirLoopControlInfo.empty() && this->m_AirLoopEquipment) {
170 :
171 6193477 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor =
172 6832702 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor &&
173 639225 : (this->m_HeatCompPartLoadRatio > 0.0 || this->m_SpeedRatio > 0.0 || this->m_CycRatio > 0.0);
174 :
175 6193477 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating =
176 6925960 : HeatActive && (state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor ||
177 732483 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithHeating);
178 : }
179 :
180 : // Calculate heat recovery
181 7705441 : if (this->m_HeatRecActive) {
182 0 : this->unitarySystemHeatRecovery(state);
183 : }
184 :
185 : // Coils should have been sized by now. Set this flag to false in case other equipment is downstream of Unitary System.
186 : // No, can't do this since there are other checks that need this flag (e.g., HVACManager, SetHeatToReturnAirFlag())
187 : // AirLoopControlInfo(AirLoopNum)%UnitarySys = .FALSE.
188 :
189 7705441 : if (AirLoopNum > 0 && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
190 2660380 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRateMaxAvail = tempMassFlowRateMaxAvail;
191 : }
192 : }
193 :
194 124 : DesignSpecMSHP *DesignSpecMSHP::factory(EnergyPlusData &state, HVAC::UnitarySysType type, std::string const &objectName)
195 : {
196 :
197 124 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
198 21 : DesignSpecMSHP::getDesignSpecMSHP(state);
199 21 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
200 : }
201 352 : for (auto &dSpec : state.dataUnitarySystems->designSpecMSHP) {
202 352 : if (Util::SameString(dSpec.name, objectName) && dSpec.m_type == type) {
203 124 : return &dSpec;
204 : }
205 248 : }
206 0 : ShowSevereError(state, format("Design Specification MultiSpeed Heat Pump factory: Error getting inputs for system named: {}", objectName));
207 0 : return nullptr;
208 : }
209 :
210 22 : void DesignSpecMSHP::getDesignSpecMSHP(EnergyPlusData &state)
211 : {
212 22 : bool errorsFound(false);
213 :
214 22 : DesignSpecMSHP::getDesignSpecMSHPdata(state, errorsFound);
215 :
216 22 : if (errorsFound) {
217 0 : ShowFatalError(state, "Design Specification MultiSpeed Heat Pump: Previous errors cause termination.");
218 : }
219 22 : }
220 :
221 22 : void DesignSpecMSHP::getDesignSpecMSHPdata(EnergyPlusData &state, bool errorsFound)
222 : {
223 22 : std::string const cCurrentModuleObject = "UnitarySystemPerformance:Multispeed";
224 :
225 22 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
226 22 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end()) {
227 0 : errorsFound = true;
228 : } else {
229 22 : int designSpecNum = 0;
230 22 : auto &instancesValue = instances.value();
231 85 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
232 :
233 : // *************** used only to eliminate unused object warning when using only Json type getInput **********
234 63 : int TotalArgs = 0;
235 63 : int NumAlphas = 0;
236 63 : int NumNumbers = 0;
237 63 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
238 63 : int IOStatus = 0;
239 63 : Array1D_string Alphas(NumAlphas);
240 63 : Array1D<Real64> Numbers(NumNumbers, 0.0);
241 63 : Array1D_bool lNumericBlanks(NumNumbers, true);
242 63 : Array1D_bool lAlphaBlanks(NumAlphas, true);
243 63 : Array1D_string cAlphaFields(NumAlphas);
244 63 : Array1D_string cNumericFields(NumNumbers);
245 63 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
246 : cCurrentModuleObject,
247 : ++designSpecNum,
248 : Alphas,
249 : NumAlphas,
250 : Numbers,
251 : NumNumbers,
252 : IOStatus,
253 : lNumericBlanks,
254 : lAlphaBlanks,
255 : cAlphaFields,
256 : cNumericFields);
257 : // **********************************************************************************************************
258 :
259 63 : auto const &fields = instance.value();
260 63 : std::string const &thisObjectName = instance.key();
261 63 : DesignSpecMSHP thisDesignSpec;
262 :
263 63 : thisDesignSpec.name = Util::makeUPPER(thisObjectName);
264 63 : thisDesignSpec.numOfSpeedHeating = fields.at("number_of_speeds_for_heating").get<int>(); // required field
265 63 : thisDesignSpec.numOfSpeedCooling = fields.at("number_of_speeds_for_cooling").get<int>(); // required field
266 63 : int maxSpeeds = max(thisDesignSpec.numOfSpeedHeating, thisDesignSpec.numOfSpeedCooling);
267 63 : thisDesignSpec.m_type = HVAC::UnitarySysType::Furnace_HeatOnly; // add global int value for factory
268 :
269 63 : if (auto it = fields.find("single_mode_operation"); it != fields.end()) { // not required field
270 63 : std::string loc_m_SingleModeOp = Util::makeUPPER(it.value().get<std::string>());
271 63 : if (Util::SameString(loc_m_SingleModeOp, "Yes")) thisDesignSpec.m_SingleModeFlag = true;
272 126 : }
273 :
274 63 : if (auto it = fields.find("no_load_supply_air_flow_rate_ratio"); it != fields.end()) { // not required field
275 39 : thisDesignSpec.noLoadAirFlowRateRatio = it.value().get<Real64>();
276 63 : }
277 :
278 63 : thisDesignSpec.heatingVolFlowRatio.resize(maxSpeeds + 1);
279 63 : thisDesignSpec.coolingVolFlowRatio.resize(maxSpeeds + 1);
280 :
281 63 : auto speedFlowRatios = fields.find("flow_ratios");
282 63 : if (speedFlowRatios != fields.end()) {
283 63 : auto &flowRatioArray = speedFlowRatios.value();
284 63 : int numSpeedInputs = flowRatioArray.size();
285 63 : if (numSpeedInputs >= maxSpeeds) {
286 63 : int speedNum = -1;
287 393 : for (auto const &flowRatio : flowRatioArray) {
288 330 : speedNum += 1;
289 330 : if (speedNum < (maxSpeeds + 1)) {
290 191 : auto &cobj = flowRatio.at("cooling_speed_supply_air_flow_ratio");
291 191 : thisDesignSpec.coolingVolFlowRatio[speedNum] =
292 302 : (cobj.type() == nlohmann::detail::value_t::string && Util::SameString(cobj.get<std::string>(), "Autosize"))
293 302 : ? DataSizing::AutoSize
294 80 : : cobj.get<Real64>();
295 :
296 191 : auto &hobj = flowRatio.at("heating_speed_supply_air_flow_ratio");
297 191 : thisDesignSpec.heatingVolFlowRatio[speedNum] =
298 302 : (hobj.type() == nlohmann::detail::value_t::string && Util::SameString(hobj.get<std::string>(), "Autosize"))
299 302 : ? DataSizing::AutoSize
300 80 : : hobj.get<Real64>();
301 : }
302 63 : }
303 : } else {
304 0 : ShowSevereError(state, format("{}: Error getting inputs for system named: {}", cCurrentModuleObject, thisObjectName));
305 0 : ShowContinueError(state,
306 0 : format("Number of speed inputs ({:.0T} is less than number of speeds ({:.0T}).",
307 0 : Real64(numSpeedInputs),
308 0 : Real64(maxSpeeds)));
309 0 : errorsFound = true;
310 : }
311 : }
312 63 : state.dataUnitarySystems->designSpecMSHP.push_back(thisDesignSpec);
313 85 : }
314 : }
315 22 : } // namespace UnitarySystems
316 :
317 622 : HVACSystemData *UnitarySys::factory(
318 : EnergyPlusData &state, HVAC::UnitarySysType const type, std::string const &objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
319 : {
320 622 : if (state.dataUnitarySystems->getInputOnceFlag) {
321 163 : UnitarySys::getUnitarySystemInput(state, objectName, ZoneEquipment, ZoneOAUnitNum);
322 163 : state.dataUnitarySystems->getInputOnceFlag = false;
323 : }
324 622 : int sysNum = -1;
325 4572 : for (auto &sys : state.dataUnitarySystems->unitarySys) {
326 4572 : ++sysNum;
327 4572 : if (Util::SameString(sys.Name, objectName) && type == HVAC::UnitarySysType::Unitary_AnyCoilType) {
328 622 : state.dataUnitarySystems->unitarySys[sysNum].m_UnitarySysNum = sysNum;
329 622 : return &sys;
330 : }
331 1244 : }
332 0 : ShowFatalError(state, format("UnitarySystem factory: Error getting inputs for system named: {}", objectName));
333 0 : return nullptr;
334 : }
335 :
336 125 : int getDesignSpecMSHPIndex(
337 : EnergyPlusData &state, // lookup vector index for design spec object name in object array EnergyPlus::UnitarySystems::designSpecMSHP
338 : std::string_view objectName // IDF name in input
339 : )
340 : {
341 125 : if (state.dataUnitarySystems->getMSHPInputOnceFlag) {
342 1 : DesignSpecMSHP::getDesignSpecMSHP(state);
343 1 : state.dataUnitarySystems->getMSHPInputOnceFlag = false;
344 : }
345 125 : int index = -1;
346 353 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->designSpecMSHP.size(); ++loop) {
347 353 : DesignSpecMSHP *thisDesignSpecMSHPObjec = &state.dataUnitarySystems->designSpecMSHP[loop];
348 353 : if (Util::SameString(objectName, thisDesignSpecMSHPObjec->name)) {
349 125 : index = loop;
350 125 : return index;
351 : }
352 : }
353 0 : ShowSevereError(state, format("getDesignSpecMSHPIndex: did not find UnitarySystemPerformance:Multispeed name ={}. Check inputs", objectName));
354 0 : return index;
355 : }
356 :
357 2488 : int getUnitarySystemIndex(
358 : EnergyPlusData &state, // lookup vector index for UnitarySystem object name in object array EnergyPlus::UnitarySystems::unitarySys
359 : std::string_view objectName // IDF name in input
360 : )
361 : {
362 2488 : int index = -1;
363 27432 : for (std::size_t loop = 0; loop < state.dataUnitarySystems->unitarySys.size(); ++loop) {
364 26188 : UnitarySys *thisUnitarySysObjec = &state.dataUnitarySystems->unitarySys[loop];
365 26188 : if (Util::SameString(objectName, thisUnitarySysObjec->Name)) {
366 1244 : index = loop;
367 1244 : break;
368 : }
369 : }
370 2488 : return index;
371 : }
372 :
373 7705441 : void UnitarySys::initUnitarySystems(EnergyPlusData &state, int const AirLoopNum, bool const FirstHVACIteration, Real64 const OAUCoilOutTemp)
374 : {
375 : static constexpr std::string_view routineName("InitUnitarySystems");
376 :
377 : // only access for zone equipment, UnitaySystem does not yet have input for Availability Manager List Name
378 17134390 : if (this->m_IsZoneEquipment &&
379 8959898 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
380 1254457 : !state.dataAvail->ZoneComp.empty()) {
381 : // need to move to better location and save thisObjectIndex and thisObjectType in struct
382 : // this->m_EquipCompNum is by parent type, not total UnitarySystems
383 : // e.g., PTAC = 1,2,3; PTHP = 1,2; PTWSHP = 1,2,3,4; UnitarySystems = 9 total
384 1254457 : DataZoneEquipment::ZoneEquipType thisObjectType = DataZoneEquipment::ZoneEquipType::Invalid;
385 1254457 : switch (this->m_sysType) {
386 1066756 : case SysType::PackagedAC:
387 1066756 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
388 1066756 : break;
389 92466 : case SysType::PackagedHP:
390 92466 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump;
391 92466 : break;
392 95235 : case SysType::PackagedWSHP:
393 95235 : thisObjectType = DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir;
394 95235 : break;
395 0 : default:
396 0 : break;
397 : }
398 1254457 : if (this->m_ZoneCompFlag) {
399 197 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).AvailManagerListName = this->m_AvailManagerListName;
400 197 : state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).ZoneNum = this->ControlZoneNum;
401 197 : this->m_ZoneCompFlag = false;
402 : }
403 1254457 : this->m_AvailStatus = state.dataAvail->ZoneComp(thisObjectType).ZoneCompAvailMgrs(this->m_EquipCompNum).availStatus;
404 : }
405 :
406 : // sizing does not execute until SysSizing is complete. This means we may not know plant connections for zone equipment.
407 : // when adding ((this->m_IsZoneEquipment && !state.dataGlobal->SysSizingCalc) || ()) here, eio gets out of sorts
408 7705441 : if (!state.dataGlobal->SysSizingCalc && this->m_MySizingCheckFlag && !this->m_ThisSysInputShouldBeGotten) {
409 622 : if (AirLoopNum > 0) {
410 396 : if (this->m_FanExists && (this->m_CoolCoilExists && (this->m_HeatCoilExists || this->m_SuppCoilExists)))
411 107 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
412 396 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
413 396 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
414 67 : DXCoils::SetCoilSystemCoolingData(state, this->m_CoolingCoilName, this->Name);
415 : }
416 : // associates an air loop fan on main branch with a coil on main branch where parent does not have a fan
417 396 : if (!this->m_FanExists) {
418 289 : if (state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanType != HVAC::FanType::Invalid) {
419 286 : auto &primaryAirSystems = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum);
420 286 : if (this->m_CoolCoilExists) {
421 285 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
422 : state,
423 285 : this->m_CoolingCoilName,
424 285 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
425 285 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
426 285 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
427 : primaryAirSystems.supFanNum);
428 : }
429 286 : if (this->m_HeatCoilExists) {
430 1 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
431 : state,
432 1 : this->m_HeatingCoilName,
433 1 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
434 1 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
435 1 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
436 : primaryAirSystems.supFanNum);
437 : }
438 286 : if (this->m_SuppCoilExists) {
439 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
440 : state,
441 0 : this->m_SuppHeatCoilName,
442 0 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
443 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->Name,
444 0 : state.dataFans->fans(primaryAirSystems.supFanNum)->type,
445 : primaryAirSystems.supFanNum);
446 : }
447 : }
448 : }
449 : }
450 622 : this->sizeSystem(state, FirstHVACIteration, AirLoopNum);
451 622 : this->m_MySizingCheckFlag = false;
452 622 : if (AirLoopNum > 0) {
453 396 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = this->m_FanOpMode;
454 396 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CycFanSchedPtr = this->m_FanOpModeSchedPtr;
455 226 : } else if (AirLoopNum < 0) {
456 8 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
457 0 : ShowSevereError(state, format("{}: {}", this->UnitType, this->Name));
458 0 : ShowContinueError(state, " Invalid application of Control Type = SingleZoneVAV in outdoor air system.");
459 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
460 : }
461 : }
462 : }
463 :
464 7705441 : if (this->m_MyFanFlag) { // should include " && !this->m_MySizingCheckFlag"
465 1253 : if (this->m_ActualFanVolFlowRate != DataSizing::AutoSize) {
466 622 : if (this->m_ActualFanVolFlowRate > 0.0) {
467 622 : this->m_HeatingFanSpeedRatio = this->m_MaxHeatAirVolFlow / this->m_ActualFanVolFlowRate;
468 622 : this->m_CoolingFanSpeedRatio = this->m_MaxCoolAirVolFlow / this->m_ActualFanVolFlowRate;
469 622 : this->m_NoHeatCoolSpeedRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
470 622 : if (this->m_FanExists && !this->m_MultiOrVarSpeedHeatCoil && !this->m_MultiOrVarSpeedCoolCoil) {
471 236 : bool fanHasPowerSpeedRatioCurve = false;
472 236 : if (this->m_FanType == HVAC::FanType::SystemModel) {
473 30 : if (dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex))->powerModFuncFlowFracCurveNum > 0)
474 2 : fanHasPowerSpeedRatioCurve = true;
475 : } else {
476 206 : if (dynamic_cast<Fans::FanComponent *>(state.dataFans->fans(this->m_FanIndex))->powerRatioAtSpeedRatioCurveNum > 0)
477 5 : fanHasPowerSpeedRatioCurve = true;
478 : }
479 236 : if (fanHasPowerSpeedRatioCurve) {
480 :
481 7 : if (this->m_ActualFanVolFlowRate == this->m_MaxHeatAirVolFlow &&
482 6 : this->m_ActualFanVolFlowRate == this->m_MaxCoolAirVolFlow &&
483 5 : this->m_ActualFanVolFlowRate == this->m_MaxNoCoolHeatAirVolFlow) {
484 1 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
485 2 : ShowContinueError(
486 2 : state, format("...For fan type and name = {} \"{}\"", HVAC::fanTypeNames[(int)this->m_FanType], this->m_FanName));
487 1 : ShowContinueError(state,
488 : "...Fan power ratio function of speed ratio curve has no impact if fan volumetric flow rate is the "
489 : "same as the unitary system volumetric flow rate.");
490 2 : ShowContinueError(state,
491 2 : format("...Fan volumetric flow rate = {:.5R} m3/s.", this->m_ActualFanVolFlowRate));
492 1 : ShowContinueError(state, format("...Unitary system volumetric flow rate = {:.5R} m3/s.", this->m_MaxHeatAirVolFlow));
493 : }
494 : }
495 : }
496 622 : if (this->m_MultiOrVarSpeedHeatCoil || this->m_MultiOrVarSpeedCoolCoil) {
497 158 : if (this->m_MultiOrVarSpeedCoolCoil) {
498 158 : int NumSpeeds = this->m_NumOfSpeedCooling;
499 158 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(NumSpeeds + 1);
500 158 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(NumSpeeds + 1);
501 587 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
502 429 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
503 : }
504 : }
505 158 : if (this->m_MultiOrVarSpeedHeatCoil) {
506 23 : int NumSpeeds = this->m_NumOfSpeedHeating;
507 23 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(NumSpeeds + 1);
508 23 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(NumSpeeds + 1);
509 139 : for (int Iter = 1; Iter <= NumSpeeds; ++Iter) {
510 116 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_ActualFanVolFlowRate;
511 : }
512 : }
513 158 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_ActualFanVolFlowRate;
514 : }
515 : }
516 622 : this->m_MyFanFlag = false;
517 : } else {
518 631 : if (this->m_FanExists) {
519 631 : this->m_ActualFanVolFlowRate = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
520 : }
521 : // do not set false this->m_MyFanFlag so that next pass specific initialization and warning are executed
522 : }
523 : }
524 :
525 : // Scan hot water and steam heating coil plant components for one time initializations
526 7705441 : if (this->m_MyPlantScanFlag && !state.dataPlnt->PlantLoop.empty()) {
527 413 : if (this->m_HeatRecActive) {
528 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
529 0 : PlantUtilities::ScanPlantLoopsForObject(state,
530 : this->Name,
531 : DataPlant::PlantEquipmentType::UnitarySysRecovery,
532 0 : this->m_HRPlantLoc,
533 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
534 : _,
535 : _,
536 : _,
537 : _,
538 : _);
539 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
540 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
541 : }
542 : }
543 413 : DataPlant::PlantEquipmentType TypeOfCoilWaterCooling{DataPlant::PlantEquipmentType::Invalid};
544 413 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed ||
545 393 : this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
546 20 : std::string CoolingCoilType = "";
547 20 : std::string CoolingCoilName = "";
548 20 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
549 20 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
550 20 : CoolingCoilType = "Coil:Cooling:Water";
551 20 : CoolingCoilName = this->m_CoolingCoilName;
552 0 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
553 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
554 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
555 0 : CoolingCoilName = this->m_CoolingCoilName;
556 : } else {
557 : TypeOfCoilWaterCooling = static_cast<DataPlant::PlantEquipmentType>(
558 0 : HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(state,
559 0 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
560 0 : this->m_CoolingCoilName,
561 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
562 : true));
563 0 : if (TypeOfCoilWaterCooling == static_cast<DataPlant::PlantEquipmentType>(HVAC::Coil_CoolingWater)) {
564 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterCooling;
565 0 : CoolingCoilType = "Coil:Cooling:Water";
566 0 : } else if (TypeOfCoilWaterCooling == static_cast<DataPlant::PlantEquipmentType>(HVAC::Coil_CoolingWaterDetailed)) {
567 0 : TypeOfCoilWaterCooling = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
568 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
569 : }
570 0 : CoolingCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(state,
571 0 : HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num),
572 0 : this->m_CoolingCoilName,
573 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag);
574 : }
575 20 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
576 40 : PlantUtilities::ScanPlantLoopsForObject(state,
577 : CoolingCoilName,
578 : TypeOfCoilWaterCooling,
579 20 : this->CoolCoilPlantLoc,
580 20 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
581 : _,
582 : _,
583 : _,
584 : _,
585 : _);
586 20 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
587 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
588 : }
589 20 : this->MaxCoolCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
590 20 : state, CoolingCoilType, CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
591 :
592 20 : if (this->MaxCoolCoilFluidFlow > 0.0) {
593 5 : Real64 rho = FluidProperties::GetDensityGlycol(state,
594 5 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).FluidName,
595 : Constant::CWInitConvTemp,
596 5 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).FluidIndex,
597 : routineName);
598 5 : this->MaxCoolCoilFluidFlow *= rho;
599 : }
600 : // fill outlet node for coil
601 20 : this->CoolCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->CoolCoilPlantLoc).NodeNumOut;
602 20 : }
603 413 : DataPlant::PlantEquipmentType TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::Invalid;
604 413 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
605 11 : std::string HeatingCoilType = "";
606 11 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
607 9 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
608 9 : HeatingCoilType = "Coil:Heating:Water";
609 : // this doesn't work good here, sizing may not have executed yet
610 : // air loops seem to work OK, zone equipment not so much, this->m_MaxHeatAirVolFlow = -99999.0
611 : // moved to sizing but left this original call
612 9 : WaterCoils::SetCoilDesFlow(state,
613 9 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
614 9 : this->m_HeatingCoilName,
615 : this->m_MaxHeatAirVolFlow,
616 9 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
617 : } else {
618 2 : TypeOfCoilWaterHeating = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
619 2 : HeatingCoilType = "Coil:Heating:Steam";
620 : }
621 11 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
622 22 : PlantUtilities::ScanPlantLoopsForObject(state,
623 : this->m_HeatingCoilName,
624 : TypeOfCoilWaterHeating,
625 11 : this->HeatCoilPlantLoc,
626 11 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
627 : _,
628 : _,
629 : _,
630 : _,
631 : _);
632 11 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
633 0 : ShowFatalError(state, "InitUnitarySystem: Program terminated for previous conditions.");
634 : }
635 11 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
636 9 : this->MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
637 9 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
638 :
639 9 : if (this->MaxHeatCoilFluidFlow > 0.0) {
640 2 : Real64 rho = FluidProperties::GetDensityGlycol(state,
641 2 : state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum).FluidName,
642 : Constant::HWInitConvTemp,
643 2 : state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum).FluidIndex,
644 : routineName);
645 2 : this->MaxHeatCoilFluidFlow =
646 2 : WaterCoils::GetCoilMaxWaterFlowRate(
647 4 : state, HeatingCoilType, this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
648 : rho;
649 : }
650 : } else {
651 2 : this->MaxHeatCoilFluidFlow =
652 2 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
653 2 : if (this->MaxHeatCoilFluidFlow > 0.0) {
654 2 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
655 2 : Real64 TempSteamIn = 100.0;
656 2 : Real64 SteamDensity = FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, routineName);
657 2 : this->MaxHeatCoilFluidFlow *= SteamDensity;
658 : }
659 : }
660 : // fill outlet node for coil
661 11 : this->HeatCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->HeatCoilPlantLoc).NodeNumOut;
662 11 : }
663 :
664 413 : this->m_MyPlantScanFlag = false;
665 7705028 : } else if (this->m_MyPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
666 209 : this->m_MyPlantScanFlag = false;
667 : }
668 :
669 : // Scan Supplemental hot water and steam heating coil plant components for one time initializations
670 7705441 : if (this->m_MySuppCoilPlantScanFlag && allocated(state.dataPlnt->PlantLoop)) {
671 622 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
672 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
673 0 : PlantUtilities::ScanPlantLoopsForObject(state,
674 : this->m_SuppHeatCoilName,
675 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
676 0 : this->m_SuppCoilPlantLoc,
677 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
678 : _,
679 : _,
680 : _,
681 : _,
682 : _);
683 0 : WaterCoils::SetCoilDesFlow(state,
684 0 : HVAC::cAllCoilTypes(this->m_SuppHeatCoilType_Num),
685 0 : this->m_SuppHeatCoilName,
686 : this->m_MaxHeatAirVolFlow,
687 0 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
688 :
689 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
690 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
691 : }
692 0 : this->m_MaxSuppCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(
693 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
694 :
695 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
696 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
697 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).FluidName,
698 : Constant::CWInitConvTemp,
699 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).FluidIndex,
700 : routineName);
701 0 : this->m_MaxSuppCoilFluidFlow =
702 0 : WaterCoils::GetCoilMaxWaterFlowRate(
703 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound) *
704 : rho;
705 : }
706 : // fill outlet node for coil
707 0 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
708 :
709 622 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
710 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag = false;
711 0 : PlantUtilities::ScanPlantLoopsForObject(state,
712 : this->m_SuppHeatCoilName,
713 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
714 0 : this->m_SuppCoilPlantLoc,
715 0 : state.dataUnitarySystems->initUnitarySystemsErrFlag,
716 : _,
717 : _,
718 : _,
719 : _,
720 : _);
721 0 : if (state.dataUnitarySystems->initUnitarySystemsErrFlag) {
722 0 : ShowFatalError(state, "InitUnitarySystems: Program terminated for previous conditions.");
723 : }
724 0 : this->m_MaxSuppCoilFluidFlow =
725 0 : SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
726 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
727 0 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
728 0 : Real64 TempSteamIn = 100.0;
729 0 : Real64 SteamDensity = FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, routineName);
730 0 : this->m_MaxSuppCoilFluidFlow *= SteamDensity;
731 : }
732 :
733 : // fill outlet node for coil
734 0 : this->m_SuppCoilFluidOutletNodeNum = DataPlant::CompData::getPlantComponent(state, this->m_SuppCoilPlantLoc).NodeNumOut;
735 : }
736 :
737 622 : this->m_MySuppCoilPlantScanFlag = false;
738 :
739 7704819 : } else if (this->m_MySuppCoilPlantScanFlag && !state.dataGlobal->AnyPlantInModel) {
740 0 : this->m_MySuppCoilPlantScanFlag = false;
741 : }
742 :
743 : // do the Begin Environment initializations
744 7705441 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag) {
745 3589 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
746 3589 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
747 3589 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
748 3589 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
749 3589 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
750 3589 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
751 3589 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
752 3589 : if (this->OAMixerExists) {
753 957 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMax = max(this->m_CoolOutAirMassFlow, this->m_HeatOutAirMassFlow);
754 957 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMin = 0.0;
755 957 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMinAvail = 0.0;
756 : }
757 3589 : this->m_CompPartLoadRatio = 0.0;
758 3589 : this->m_CoolingCoilSensDemand = 0.0;
759 3589 : this->m_CoolingCoilLatentDemand = 0.0;
760 3589 : this->m_HeatingCoilSensDemand = 0.0;
761 3589 : this->m_SenLoadLoss = 0.0;
762 3589 : if (this->m_Humidistat) {
763 153 : this->m_LatLoadLoss = 0.0;
764 : }
765 :
766 3589 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
767 :
768 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
769 0 : state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).FluidName,
770 : Constant::HWInitConvTemp,
771 0 : state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).FluidIndex,
772 : routineName);
773 :
774 0 : this->m_DesignHeatRecMassFlowRate = this->m_DesignHRWaterVolumeFlow * rho;
775 :
776 0 : PlantUtilities::InitComponentNodes(
777 : state, 0.0, this->m_DesignHeatRecMassFlowRate, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
778 : }
779 : // set fluid-side hardware limits
780 3589 : if (this->CoolCoilFluidInletNode > 0) {
781 :
782 109 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
783 : // If water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
784 15 : std::string CoolingCoilType = "";
785 15 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
786 15 : CoolingCoilType = "Coil:Cooling:Water";
787 : } else {
788 0 : CoolingCoilType = "Coil:Cooling:Water:DetailedGeometry";
789 : }
790 15 : WaterCoils::SimulateWaterCoilComponents(state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex);
791 15 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
792 15 : state, CoolingCoilType, this->m_CoolingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
793 15 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
794 15 : Real64 rho = FluidProperties::GetDensityGlycol(state,
795 15 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).FluidName,
796 : Constant::CWInitConvTemp,
797 15 : state.dataPlnt->PlantLoop(this->CoolCoilPlantLoc.loopNum).FluidIndex,
798 : routineName);
799 15 : this->MaxCoolCoilFluidFlow = CoilMaxVolFlowRate * rho;
800 : }
801 15 : }
802 :
803 109 : PlantUtilities::InitComponentNodes(
804 : state, 0.0, this->MaxCoolCoilFluidFlow, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum);
805 : }
806 3589 : if (this->HeatCoilFluidInletNode > 0) {
807 :
808 62 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
809 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
810 7 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
811 7 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
812 7 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
813 7 : state, "Coil:Heating:Water", this->m_HeatingCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
814 7 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
815 7 : Real64 rho = FluidProperties::GetDensityGlycol(state,
816 7 : state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum).FluidName,
817 : Constant::CWInitConvTemp,
818 7 : state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum).FluidIndex,
819 : routineName);
820 7 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
821 : }
822 : }
823 : // If steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
824 7 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
825 0 : SteamCoils::SimulateSteamCoilComponents(
826 : state,
827 : this->m_HeatingCoilName,
828 : FirstHVACIteration,
829 0 : this->m_HeatingCoilIndex,
830 0 : 1.0,
831 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity
832 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(
833 0 : state, this->m_HeatingCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
834 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
835 0 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
836 0 : Real64 TempSteamIn = 100.0;
837 : Real64 SteamDensity =
838 0 : FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, routineName);
839 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
840 : }
841 : }
842 : }
843 :
844 62 : PlantUtilities::InitComponentNodes(
845 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
846 : }
847 3589 : if (this->m_SuppCoilFluidInletNode > 0) {
848 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
849 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
850 : // If water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
851 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
852 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(
853 0 : state, "Coil:Heating:Water", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
854 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
855 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
856 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).FluidName,
857 : Constant::CWInitConvTemp,
858 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).FluidIndex,
859 : routineName);
860 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
861 : }
862 : }
863 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
864 0 : SteamCoils::SimulateSteamCoilComponents(
865 : state,
866 : this->m_SuppHeatCoilName,
867 : FirstHVACIteration,
868 0 : this->m_SuppHeatCoilIndex,
869 0 : 1.0,
870 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity
871 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(
872 0 : state, this->m_SuppHeatCoilIndex, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
873 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
874 0 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
875 0 : Real64 TempSteamIn = 100.0;
876 : Real64 SteamDensity =
877 0 : FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, routineName);
878 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
879 : }
880 : }
881 0 : PlantUtilities::InitComponentNodes(
882 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
883 : }
884 : }
885 3589 : this->m_MyEnvrnFlag = false;
886 : }
887 :
888 7705441 : if (!state.dataGlobal->BeginEnvrnFlag) {
889 7670660 : this->m_MyEnvrnFlag = true;
890 : }
891 :
892 : // Init maximum available Heat Recovery flow rate
893 7705441 : if ((this->m_HeatRecActive) && (!this->m_MyPlantScanFlag)) {
894 0 : Real64 mdotHR = 0.0;
895 0 : if (ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0) {
896 0 : if (FirstHVACIteration) {
897 0 : mdotHR = this->m_DesignHeatRecMassFlowRate;
898 : } else {
899 0 : if (this->m_HeatRecoveryMassFlowRate > 0.0) {
900 0 : mdotHR = this->m_HeatRecoveryMassFlowRate;
901 : } else {
902 0 : mdotHR = this->m_DesignHeatRecMassFlowRate;
903 : }
904 : }
905 : } else {
906 0 : mdotHR = 0.0;
907 : }
908 :
909 0 : mdotHR = min(state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).MassFlowRateMaxAvail, mdotHR);
910 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate = mdotHR;
911 : }
912 :
913 : // get operating capacity of water and steam coil
914 7705441 : if (FirstHVACIteration || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
915 3194375 : if (FirstHVACIteration) {
916 3053354 : this->m_IterationCounter = 0;
917 3053354 : std::fill(this->m_IterationMode.begin(), this->m_IterationMode.end(), 0);
918 :
919 : // for DX systems, just read the inlet node flow rate and let air loop decide flow
920 3053354 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint && this->m_sysType == SysType::Unitary) {
921 23578 : if (ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0) {
922 23563 : if (this->m_LastMode == CoolingMode) {
923 11356 : if (this->m_MultiOrVarSpeedCoolCoil) {
924 5402 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
925 : } else {
926 5954 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxCoolAirMassFlow;
927 : }
928 12207 : } else if (this->m_LastMode == HeatingMode) {
929 8115 : if (this->m_MultiOrVarSpeedHeatCoil) {
930 1125 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->m_HeatMassFlowRate[this->m_NumOfSpeedHeating];
931 : } else {
932 6990 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxHeatAirMassFlow;
933 : }
934 : } else {
935 4092 : if (this->m_MultiOrVarSpeedCoolCoil) {
936 3 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
937 : } else {
938 4089 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = this->MaxNoCoolHeatAirMassFlow;
939 : }
940 : }
941 : } else {
942 15 : state.dataLoopNodes->Node(this->AirInNode).MassFlowRate = 0.0;
943 : }
944 : }
945 3053354 : if (this->m_WaterHRPlantLoopModel) {
946 : // initialize loop water temp on FirstHVACIteration
947 5377 : Real64 airInTemp = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp;
948 5377 : Real64 companionAirInTemp = state.dataLoopNodes->Node(this->m_HRcoolCoilAirInNode).Temp;
949 5377 : Real64 oneHalfAirDeltaT = (companionAirInTemp - airInTemp) / 2.0;
950 5377 : Real64 initialLoopTemp = airInTemp + oneHalfAirDeltaT;
951 5377 : if (initialLoopTemp > this->m_minWaterLoopTempForHR && std::abs(oneHalfAirDeltaT) > this->m_minAirToWaterTempOffset) {
952 12 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp = initialLoopTemp;
953 12 : this->temperatureOffsetControlStatus = 1;
954 : } else {
955 5365 : this->temperatureOffsetControlStatus = 0;
956 : }
957 : }
958 : }
959 3194375 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
960 :
961 : // set water-side mass flow rates
962 145296 : Real64 mdot = this->MaxCoolCoilFluidFlow;
963 145296 : PlantUtilities::SetComponentFlowRate(
964 145296 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
965 : // simulate water coil to find operating capacity
966 290592 : WaterCoils::SimulateWaterCoilComponents(state,
967 : this->m_CoolingCoilName,
968 : FirstHVACIteration,
969 145296 : this->m_CoolingCoilIndex,
970 145296 : state.dataUnitarySystems->initUnitarySystemsQActual);
971 145296 : this->m_DesignCoolingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
972 :
973 : } // from IF(UnitarySystem(UnitarySysNum)%CoolingCoilType_Num == Coil_CoolingWater .OR. Coil_CoolingWaterDetailed
974 3194375 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
975 :
976 : // set water-side mass flow rates
977 25768 : Real64 mdot = this->MaxHeatCoilFluidFlow;
978 25768 : PlantUtilities::SetComponentFlowRate(
979 25768 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
980 : // simulate water coil to find operating capacity
981 51536 : WaterCoils::SimulateWaterCoilComponents(state,
982 : this->m_HeatingCoilName,
983 : FirstHVACIteration,
984 25768 : this->m_HeatingCoilIndex,
985 25768 : state.dataUnitarySystems->initUnitarySystemsQActual);
986 25768 : this->m_DesignHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
987 :
988 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingWater) THEN
989 :
990 3194375 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
991 :
992 : // set water-side mass flow rates
993 2968 : Real64 mdot = this->MaxHeatCoilFluidFlow;
994 2968 : PlantUtilities::SetComponentFlowRate(
995 2968 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
996 : // simulate steam coil to find operating capacity
997 8904 : SteamCoils::SimulateSteamCoilComponents(
998 : state,
999 : this->m_HeatingCoilName,
1000 : FirstHVACIteration,
1001 2968 : this->m_HeatingCoilIndex,
1002 5936 : 1.0,
1003 2968 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1004 2968 : this->m_DesignHeatingCapacity = SteamCoils::GetCoilCapacity(state,
1005 2968 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
1006 2968 : this->m_HeatingCoilName,
1007 2968 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
1008 :
1009 : } // from IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
1010 3194375 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
1011 :
1012 : // set steam-side mass flow rates
1013 0 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
1014 0 : PlantUtilities::SetComponentFlowRate(
1015 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1016 : // simulate water coil to find operating capacity
1017 0 : if (mdot > 0.0) { // not sure why this is here and not used for other coil types, wouldn't capacity be 0 if water flow = 0? Maybe a
1018 : // speed issue where coil doesn't need to be simulation if mdot=0.
1019 0 : WaterCoils::SimulateWaterCoilComponents(state,
1020 : this->m_SuppHeatCoilName,
1021 : FirstHVACIteration,
1022 0 : this->m_SuppHeatCoilIndex,
1023 0 : state.dataUnitarySystems->initUnitarySystemsQActual);
1024 0 : this->m_DesignSuppHeatingCapacity = state.dataUnitarySystems->initUnitarySystemsQActual;
1025 : } else {
1026 0 : this->m_DesignSuppHeatingCapacity = 0.0;
1027 : }
1028 :
1029 : } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingWater) THEN
1030 :
1031 3194375 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
1032 :
1033 : // set air-side and steam-side mass flow rates
1034 0 : Real64 mdot = this->m_MaxSuppCoilFluidFlow;
1035 0 : PlantUtilities::SetComponentFlowRate(
1036 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1037 : // simulate steam coil to find operating capacity
1038 0 : SteamCoils::SimulateSteamCoilComponents(
1039 : state,
1040 : this->m_SuppHeatCoilName,
1041 : FirstHVACIteration,
1042 0 : this->m_SuppHeatCoilIndex,
1043 0 : 1.0,
1044 0 : state.dataUnitarySystems->initUnitarySystemsQActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1045 0 : this->m_DesignSuppHeatingCapacity = SteamCoils::GetCoilCapacity(
1046 0 : state, "Coil:Heating:Steam", this->m_SuppHeatCoilName, state.dataUnitarySystems->initUnitarySystemsErrorsFound);
1047 :
1048 : } // from IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN
1049 : } // from IF( FirstHVACIteration ) THEN
1050 :
1051 7705441 : this->m_IterationCounter += 1;
1052 :
1053 7705441 : if (this->m_MySetPointCheckFlag) {
1054 3934 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACGlobal->DoSetPointTest) {
1055 622 : bool e = false;
1056 622 : if (this->m_CoolCoilExists) e = this->checkNodeSetPoint(state, AirLoopNum, this->CoolCtrlNode, CoolingCoil, OAUCoilOutTemp);
1057 622 : if (this->m_HeatCoilExists) e = this->checkNodeSetPoint(state, AirLoopNum, this->HeatCtrlNode, HeatingCoil, OAUCoilOutTemp) || e;
1058 622 : if (this->m_SuppCoilExists) e = this->checkNodeSetPoint(state, AirLoopNum, this->SuppCtrlNode, SuppHeatCoil, OAUCoilOutTemp) || e;
1059 622 : if (e) ShowFatalError(state, "Previous errors cause termination.");
1060 622 : this->m_MySetPointCheckFlag = false;
1061 : }
1062 : }
1063 :
1064 7705441 : if (m_setFaultModelInput) {
1065 1910243 : if ((!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
1066 :
1067 : // check FaultsManager if connection exists
1068 617 : FaultsManager::SetFaultyCoilSATSensor(state, this->UnitType, this->Name, this->m_FaultyCoilSATFlag, this->m_FaultyCoilSATIndex);
1069 617 : if (this->m_FaultyCoilSATFlag) {
1070 0 : if (this->m_ControlType != UnitarySysCtrlType::Setpoint) {
1071 0 : ShowWarningError(state,
1072 0 : format("{}: {}",
1073 0 : state.dataFaultsMgr->FaultsCoilSATSensor(this->m_FaultyCoilSATIndex).type,
1074 0 : state.dataFaultsMgr->FaultsCoilSATSensor(this->m_FaultyCoilSATIndex).Name));
1075 0 : ShowContinueError(state, format("For : {}: {}", this->UnitType, this->Name));
1076 0 : ShowContinueError(state,
1077 : "The specified unitary system is not controlled on leaving air temperature. The coil SAT sensor "
1078 : "fault model will not be applied.");
1079 0 : this->m_FaultyCoilSATFlag = false;
1080 : }
1081 : }
1082 617 : m_setFaultModelInput = false;
1083 : }
1084 : }
1085 :
1086 : // re-set water-side economizer flags each time step
1087 7705441 : if (this->m_TemperatureOffsetControlActive && !this->m_WaterHRPlantLoopModel) {
1088 60192 : if (state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).Temp >
1089 60192 : (state.dataLoopNodes->Node(this->AirInNode).Temp - this->m_minAirToWaterTempOffset)) {
1090 : // disable coilsystem if entering fluid temp is > entering air temp minus user specified temp offset
1091 59688 : this->temperatureOffsetControlStatus = 0;
1092 : } else {
1093 : // enable coilsystem waterside economizer mode
1094 504 : this->temperatureOffsetControlStatus = 1;
1095 : }
1096 : }
1097 7705441 : if (AirLoopNum > 0) {
1098 6193477 : if (this->m_sysType == SysType::CoilCoolingWater) {
1099 76032 : if (this->m_waterSideEconomizerFlag) { // CoilSystem:Cooling:Water has an input for economizer lockout
1100 76032 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1101 76032 : if (state.dataUnitarySystems->economizerFlag) {
1102 : // user input economizer lockout will disable heat recovery loop AND water economizer
1103 54 : this->temperatureOffsetControlStatus = 0;
1104 : }
1105 : } else {
1106 0 : state.dataUnitarySystems->economizerFlag = false;
1107 : }
1108 : } else {
1109 6117445 : state.dataUnitarySystems->economizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
1110 : }
1111 : // get OA controller info
1112 6193477 : this->OASysIndex = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).OASysNum;
1113 6193477 : if (this->OASysIndex > 0) {
1114 5956792 : this->OAControllerIndex = state.dataAirLoop->OutsideAirSys(this->OASysIndex).OAControllerIndex;
1115 5956792 : if (this->OAControllerIndex > 0) {
1116 5956792 : this->OAControllerEconomizerStagingType = state.dataMixedAir->OAController(this->OAControllerIndex).EconomizerStagingType;
1117 : }
1118 : }
1119 : }
1120 :
1121 7705441 : this->m_CoolingPartLoadFrac = 0.0;
1122 7705441 : this->m_HeatingPartLoadFrac = 0.0;
1123 7705441 : this->m_SuppHeatPartLoadFrac = 0.0;
1124 7705441 : this->m_CoolingCycRatio = 0.0;
1125 7705441 : this->m_CoolingSpeedRatio = 0.0;
1126 7705441 : this->m_CoolingSpeedNum = 0;
1127 7705441 : this->m_HeatingCycRatio = 0.0;
1128 7705441 : this->m_HeatingSpeedRatio = 0.0;
1129 7705441 : this->m_HeatingSpeedNum = 0;
1130 7705441 : this->m_SuppHeatingSpeedNum = 0;
1131 7705441 : this->m_HeatingCoilSensDemand = 0.0;
1132 7705441 : this->m_CoolingCoilSensDemand = 0.0;
1133 7705441 : this->m_CoolingCoilLatentDemand = 0.0;
1134 7705441 : this->m_DehumidInducedHeatingDemandRate = 0.0;
1135 7705441 : this->CoolCoilWaterFlowRatio = 0.0;
1136 7705441 : this->HeatCoilWaterFlowRatio = 0.0;
1137 :
1138 : // water/steam coil initialization
1139 7705441 : if (this->CoolCoilFluidInletNode > 0) {
1140 272541 : Real64 mdot = 0.0;
1141 272541 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
1142 : }
1143 7705441 : if (this->HeatCoilFluidInletNode > 0) {
1144 78594 : Real64 mdot = 0.0;
1145 78594 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
1146 : }
1147 7705441 : if (this->m_SuppCoilFluidInletNode > 0) {
1148 0 : Real64 mdot = 0.0;
1149 0 : PlantUtilities::SetComponentFlowRate(
1150 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
1151 : }
1152 :
1153 7705441 : this->m_InitHeatPump = true;
1154 7705441 : state.dataUnitarySystems->m_massFlow1 = 0.0;
1155 7705441 : state.dataUnitarySystems->m_massFlow2 = 0.0;
1156 7705441 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
1157 7705441 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
1158 7705441 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1159 : // this should be done in the child. DXElecHeatingPower not reset to 0 if coil is off, ZoneSysAvailManager
1160 : // zero the fan and DX coils electricity consumption
1161 1254457 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
1162 1254457 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
1163 1254457 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
1164 1254457 : state.dataHVACGlobal->DefrostElecPower = 0.0;
1165 : }
1166 7705441 : }
1167 :
1168 1029 : bool UnitarySys::checkNodeSetPoint(EnergyPlusData &state,
1169 : int const AirLoopNum, // number of the current air loop being simulated
1170 : int const ControlNode, // Node to test for set point
1171 : int const CoilType, // True if cooling coil, then test for HumRatMax set point
1172 : Real64 const OAUCoilOutTemp // the coil inlet temperature of OutdoorAirUnit
1173 : )
1174 : {
1175 :
1176 : // SUBROUTINE INFORMATION:
1177 : // AUTHOR Richard Raustad
1178 : // DATE WRITTEN March 2013
1179 :
1180 : // PURPOSE OF THIS SUBROUTINE:
1181 : // This subroutine checks for proper set point at control node.
1182 : constexpr static std::array<std::string_view, 3> coilTypes = {"cooling", "heating", "supplemental"};
1183 1029 : bool SetPointErrorFlag = false;
1184 :
1185 1029 : if (ControlNode == 0) {
1186 522 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1187 0 : int coilOutNode = this->CoolCoilOutletNodeNum;
1188 0 : if (CoilType == HeatingCoil) coilOutNode = this->HeatCoilOutletNodeNum;
1189 0 : if (CoilType == SuppHeatCoil) coilOutNode = this->SuppCoilOutletNodeNum;
1190 :
1191 0 : ShowSevereError(state, format("checkNodeSetPoint: Missing {} set point in {} = {}", coilTypes[CoilType], this->UnitType, this->Name));
1192 0 : ShowContinueError(state,
1193 0 : format("...Setpoint is required at system air outlet node = {} or {} coil air outlet node = {}",
1194 0 : state.dataLoopNodes->NodeID(this->AirOutNode),
1195 0 : coilTypes[CoilType],
1196 0 : state.dataLoopNodes->NodeID(coilOutNode)));
1197 0 : SetPointErrorFlag = true;
1198 : }
1199 522 : return SetPointErrorFlag;
1200 : }
1201 :
1202 507 : if (AirLoopNum == -1) { // Outdoor Air Unit
1203 8 : state.dataLoopNodes->Node(ControlNode).TempSetPoint = OAUCoilOutTemp; // Set the coil outlet temperature
1204 8 : if (this->m_ISHundredPercentDOASDXCoil) {
1205 0 : this->frostControlSetPointLimit(state,
1206 0 : this->m_DesiredOutletTemp,
1207 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
1208 0 : state.dataEnvrn->OutBaroPress,
1209 : this->DesignMinOutletTemp,
1210 : 1);
1211 : }
1212 : } else { // Not an Outdoor air unit
1213 :
1214 499 : if (state.dataLoopNodes->Node(ControlNode).TempSetPoint == DataLoopNode::SensedNodeFlagValue &&
1215 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
1216 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1217 0 : ShowSevereError(state, format("{}: Missing temperature setpoint for unitary system = {}", this->UnitType, this->Name));
1218 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1219 0 : SetPointErrorFlag = true;
1220 : } else {
1221 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, ControlNode, HVAC::CtrlVarType::Temp, SetPointErrorFlag);
1222 0 : if (SetPointErrorFlag) {
1223 0 : ShowSevereError(state, format("{}: Missing temperature setpoint for unitary system = {}", this->UnitType, this->Name));
1224 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1225 0 : ShowContinueError(state, " or use an EMS actuator to establish a temperature setpoint at the coil control node.");
1226 : }
1227 : }
1228 : }
1229 1042 : if ((this->m_DehumidControlType_Num != DehumCtrlType::None) &&
1230 44 : (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) &&
1231 543 : this->m_ControlType == UnitarySysCtrlType::Setpoint && CoilType == CoolingCoil) {
1232 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel &&
1233 0 : state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
1234 0 : ShowSevereError(state,
1235 0 : format("{}: Missing humidity ratio setpoint (HUMRATMAX) for unitary system = {}", this->UnitType, this->Name));
1236 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1237 0 : SetPointErrorFlag = true;
1238 0 : } else if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
1239 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, ControlNode, HVAC::CtrlVarType::MaxHumRat, SetPointErrorFlag);
1240 0 : if (SetPointErrorFlag) {
1241 0 : ShowSevereError(
1242 : state,
1243 0 : format("{}: Missing maximum humidity ratio setpoint (HUMRATMAX) for unitary system = {}", this->UnitType, this->Name));
1244 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the coil control node.");
1245 0 : ShowContinueError(state, " or use an EMS actuator to establish a maximum humidity ratio setpoint.");
1246 : }
1247 : }
1248 : }
1249 : }
1250 507 : return SetPointErrorFlag; // these later errors will also cause a fatal error
1251 : }
1252 :
1253 43486 : void UnitarySys::frostControlSetPointLimit(EnergyPlusData &state,
1254 : Real64 &TempSetPoint, // temperature setpoint of the sensor node
1255 : Real64 &HumRatSetPoint, // humidity ratio setpoint of the sensor node
1256 : Real64 const BaroPress, // barometric pressure, Pa [N/m^2]
1257 : Real64 const TfrostControl, // minimum temperature limit for frost control
1258 : int const ControlMode // temperature or humidity control mode
1259 : )
1260 : {
1261 :
1262 : // SUBROUTINE INFORMATION:
1263 : // AUTHOR Bereket Nigusse, FSEC
1264 : // DATE WRITTEN January 2013
1265 :
1266 : // PURPOSE OF THIS SUBROUTINE:
1267 : // Controls the frost formation condition based on user specified minimum DX coil outlet
1268 : // air temperature. Resets the cooling setpoint based on the user specified limiting
1269 : // temperature for frost control.
1270 :
1271 : // SUBROUTINE PARAMETER DEFINITIONS:
1272 43486 : int constexpr RunOnSensible(1); // identifier for temperature (sensible load) control
1273 43486 : int constexpr RunOnLatent(2); // identifier for humidity (latent load) control
1274 : static constexpr std::string_view routineName("FrostControlSetPointLimit");
1275 :
1276 43486 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate;
1277 51023 : if (ControlMode == RunOnSensible && AirMassFlow > HVAC::SmallAirVolFlow &&
1278 7537 : TempSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).Temp) {
1279 6831 : if (TempSetPoint < TfrostControl) {
1280 0 : TempSetPoint = TfrostControl;
1281 0 : this->m_FrostControlStatus = 1;
1282 : }
1283 42524 : } else if (ControlMode == RunOnLatent && AirMassFlow > HVAC::SmallAirVolFlow &&
1284 5869 : HumRatSetPoint < state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat) {
1285 5869 : Real64 HumRatioSat = Psychrometrics::PsyWFnTdpPb(state, TfrostControl, BaroPress, routineName);
1286 5869 : if (HumRatioSat > HumRatSetPoint) {
1287 331 : HumRatSetPoint = HumRatioSat;
1288 331 : this->m_FrostControlStatus = 2;
1289 : }
1290 : } else {
1291 30786 : this->m_FrostControlStatus = 0;
1292 : }
1293 43486 : }
1294 :
1295 787 : void UnitarySys::getUnitarySystemInput(EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum)
1296 : {
1297 :
1298 787 : bool errorsFound(false);
1299 787 : UnitarySys::allocateUnitarySys(state);
1300 :
1301 787 : UnitarySys::getDXCoilSystemData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1302 787 : UnitarySys::getCoilWaterSystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1303 787 : UnitarySys::getPackagedTerminalUnitData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1304 787 : UnitarySys::getUnitarySystemInputData(state, objectName, ZoneEquipment, ZoneOAUnitNum, errorsFound);
1305 :
1306 787 : if (errorsFound) {
1307 0 : ShowFatalError(state, "getUnitarySystemInputData: previous errors cause termination. Check inputs");
1308 : }
1309 :
1310 : // all systems should have been processed at this point? I think so, so don't need to if test this call?
1311 1574 : if (int(state.dataUnitarySystems->unitarySys.size()) == state.dataUnitarySystems->numUnitarySystems &&
1312 787 : state.dataZoneEquip->ZoneEquipInputsFilled) {
1313 754 : if (state.dataUnitarySystems->setupOutputOnce) {
1314 165 : setupAllOutputVars(state, state.dataUnitarySystems->numUnitarySystems);
1315 : }
1316 : }
1317 787 : }
1318 :
1319 622 : void UnitarySys::sizeSystem(EnergyPlusData &state, bool const FirstHVACIteration, int const AirLoopNum)
1320 : {
1321 :
1322 : // SUBROUTINE INFORMATION:
1323 : // AUTHOR Richard Raustad, FSEC
1324 : // DATE WRITTEN February 2013
1325 :
1326 : // PURPOSE OF THIS SUBROUTINE:
1327 : // This subroutine is for sizing unitary system components for which nominal capacities
1328 : // and flow rates have not been specified in the input. Coil sizing is preformed in the coil module.
1329 : // Future modifications will size coils here and "push" this info to the specific coil.
1330 :
1331 : // METHODOLOGY EMPLOYED:
1332 : // Obtains heating capacities and flow rates from the zone or system sizing arrays.
1333 : // NOTE: In UNITARYSYSTEM:HEATPUMP:AIRTOAIR we are sizing the heating capacity to be
1334 : // equal to the cooling capacity. Thus the cooling and
1335 : // and heating capacities of a DX heat pump system will be identical. In real life the ARI
1336 : // heating and cooling capacities are close but not identical.
1337 :
1338 : // SUBROUTINE PARAMETER DEFINITIONS:
1339 : static constexpr std::string_view RoutineName("SizeUnitarySystem");
1340 :
1341 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1342 : int Iter; // iteration count
1343 : int MSHPIndex; // Index to design Specification object
1344 : Real64 SystemFlow; // AirloopHVAC flow rate [m3/s]
1345 : Real64 BranchFanFlow; // branch fan flow rate [m3/s]
1346 : bool ErrFound; // logical error flag
1347 : HVAC::AirDuctType SaveCurDuctType; // used during sizing to save the current duct type
1348 : Real64 QActual; // water coil output [W]
1349 : Real64 capacityMultiplier; // used for ASHRAE model sizing
1350 :
1351 : Real64 TempSize; // DataSizing::AutoSized value of input field
1352 622 : int FieldNum = 2; // IDD numeric field number where input field description is found
1353 : int SizingMethod; // Integer representation of sizing method (e.g., HVAC::CoolingAirflowSizing, DataSizing::HeatingCapacitySizing,
1354 : // etc.)
1355 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
1356 622 : Real64 SumOfMassFlowRateMax(0.0); // the sum of zone inlet mass flow rates
1357 : Real64 minNoLoadFlow; // used for sizing MaxNoCoolHeatVolFlow for SingleZoneVAV method
1358 622 : Real64 dummy(0.0);
1359 : //////////// hoisted into namespace ////////////////////////////////////////////////
1360 : // static int NumUnitarySystemsSized( 0 ); // counter used to delete UnitarySystemNumericFields array after last system is sized
1361 : ////////////////////////////////////////////////////////////////////////////////////
1362 : // References
1363 622 : DataSizing::ZoneEqSizingData *select_EqSizing = nullptr;
1364 :
1365 622 : auto &OASysEqSizing = state.dataSize->OASysEqSizing;
1366 :
1367 : // sweep specific data into one pointer to avoid if statements throughout this subroutine
1368 622 : if (state.dataSize->CurOASysNum > 0) {
1369 2 : select_EqSizing = &OASysEqSizing(state.dataSize->CurOASysNum);
1370 620 : } else if (state.dataSize->CurSysNum > 0) {
1371 394 : select_EqSizing = &state.dataSize->UnitarySysEqSizing(state.dataSize->CurSysNum);
1372 : // this was resetting data set by OutdoorAirUnit when UnitarySystem is child
1373 : // question is then who resets these (#8751 temporary fix)?
1374 : // move here for now and only reset UnitarySystem flags, then find better way to do this
1375 394 : select_EqSizing->AirFlow = false;
1376 394 : select_EqSizing->CoolingAirFlow = false;
1377 394 : select_EqSizing->HeatingAirFlow = false;
1378 394 : select_EqSizing->AirVolFlow = 0.0;
1379 394 : select_EqSizing->CoolingAirVolFlow = 0.0;
1380 394 : select_EqSizing->HeatingAirVolFlow = 0.0;
1381 394 : select_EqSizing->Capacity = false;
1382 394 : select_EqSizing->CoolingCapacity = false;
1383 394 : select_EqSizing->HeatingCapacity = false;
1384 394 : select_EqSizing->DesCoolingLoad = 0.0;
1385 394 : select_EqSizing->DesHeatingLoad = 0.0;
1386 394 : select_EqSizing->OAVolFlow = 0.0; // UnitarySys doesn't have OA
1387 226 : } else if (state.dataSize->CurZoneEqNum > 0) {
1388 226 : select_EqSizing = &state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
1389 226 : state.dataSize->ZoneEqUnitarySys = true;
1390 : // UnitarySystem never set this flag. Probably should for zone equipment.
1391 226 : if ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) &&
1392 197 : this->m_IsDXCoil)
1393 197 : state.dataSize->ZoneEqDXCoil = true;
1394 :
1395 : } else {
1396 0 : assert(false);
1397 : }
1398 : // Object Data, points to specific array
1399 622 : DataSizing::ZoneEqSizingData &EqSizing(*select_EqSizing);
1400 :
1401 : // coil sizing requires this information to check proper flow/capacity limits (#8761)
1402 622 : if (this->m_ISHundredPercentDOASDXCoil) {
1403 5 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::DOAS; // uses 100% DX coil flow limits
1404 : } else {
1405 617 : state.dataHVACGlobal->DXCT = HVAC::DXCoilType::Regular; // uses normal DX coil flow limits
1406 : }
1407 : // sizing may need to know what type of coil is being sized
1408 622 : state.dataSize->DataCoolCoilType = this->m_CoolingCoilType_Num;
1409 622 : state.dataSize->DataCoolCoilIndex = this->m_CoolingCoilIndex;
1410 :
1411 : bool anyEMSRan;
1412 622 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::UnitarySystemSizing, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point
1413 : bool HardSizeNoDesRun; // Indicator to a hard-sized field with no design sizing data
1414 :
1415 : // Initiate all reporting variables
1416 902 : if (((state.dataSize->CurOASysNum > 0 || state.dataSize->CurSysNum > 0) && state.dataSize->SysSizingRunDone) ||
1417 280 : (state.dataSize->CurZoneEqNum > 0 && state.dataSize->ZoneSizingRunDone)) {
1418 568 : HardSizeNoDesRun = false;
1419 : } else {
1420 54 : HardSizeNoDesRun = true;
1421 : }
1422 622 : std::string SizingString;
1423 622 : std::string CompName = this->Name;
1424 622 : std::string CompType = this->UnitType;
1425 622 : int CoolingSAFlowMethod = this->m_CoolingSAFMethod;
1426 622 : int HeatingSAFlowMethod = this->m_HeatingSAFMethod;
1427 : // can't reset this to 0 for systems where DX heating coil is in downstream unit and DX cooling coil is in upstream unit
1428 : // DXCoolCap = 0.0;
1429 622 : state.dataSize->UnitaryHeatCap = 0.0;
1430 622 : state.dataSize->SuppHeatCap = 0.0;
1431 622 : bool TempCoolingLoad = state.dataUnitarySystems->CoolingLoad;
1432 622 : bool TempHeatingLoad = state.dataUnitarySystems->HeatingLoad;
1433 622 : state.dataUnitarySystems->CoolingLoad = true;
1434 622 : state.dataUnitarySystems->HeatingLoad = false;
1435 622 : state.dataSize->ZoneCoolingOnlyFan = false;
1436 622 : state.dataSize->ZoneHeatingOnlyFan = false;
1437 622 : bool IsAutoSize = false;
1438 622 : Real64 SysCoolingFlow = 0.0;
1439 622 : Real64 SysHeatingFlow = 0.0;
1440 622 : Real64 CoolCapAtPeak = 0.0;
1441 622 : Real64 HeatCapAtPeak = 0.0;
1442 :
1443 622 : if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0 && this->m_FanExists) {
1444 107 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum = this->m_FanIndex;
1445 107 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanType = this->m_FanType;
1446 107 : state.dataSize->DataFanType = this->m_FanType;
1447 107 : state.dataSize->DataFanIndex = this->m_FanIndex;
1448 :
1449 107 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).supFanPlace = this->m_FanPlace;
1450 515 : } else if (state.dataSize->CurZoneEqNum > 0 && this->m_FanExists) {
1451 218 : state.dataSize->DataFanType = this->m_FanType;
1452 218 : state.dataSize->DataFanIndex = this->m_FanIndex;
1453 218 : state.dataSize->DataFanPlacement = this->m_FanPlace;
1454 : }
1455 :
1456 622 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for scalable capacity sizing
1457 34 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
1458 : }
1459 :
1460 622 : Real64 coolingCapacityMultiplier = 1.0;
1461 622 : Real64 heatingCapacityMultiplier = 1.0;
1462 622 : if (this->m_HVACSizingIndex > 0) {
1463 0 : if (this->m_CoolingCapMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
1464 0 : coolingCapacityMultiplier = this->m_DesignCoolingCapacity;
1465 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
1466 : }
1467 0 : if (this->m_HeatingCapMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
1468 0 : heatingCapacityMultiplier = this->m_DesignHeatingCapacity;
1469 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
1470 : }
1471 : }
1472 :
1473 : // zone equipment that have OA mixers will need to know the OA flow rate to size coil inlet conditions
1474 622 : bool SizingDesRunThisZone = false;
1475 622 : if (this->OAMixerExists) {
1476 167 : if (state.dataSize->CurZoneEqNum > 0) {
1477 167 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1478 167 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize || this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
1479 110 : CheckZoneSizing(state, this->UnitType, this->Name);
1480 : }
1481 : // initialize OA flow for sizing other inputs (e.g., capacity)
1482 167 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
1483 110 : EqSizing.OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
1484 : } else {
1485 57 : EqSizing.OAVolFlow = this->m_CoolOutAirVolFlow;
1486 : }
1487 167 : if (this->m_HeatOutAirVolFlow != DataSizing::AutoSize) {
1488 57 : EqSizing.OAVolFlow = max(EqSizing.OAVolFlow, this->m_HeatOutAirVolFlow);
1489 : }
1490 : }
1491 : }
1492 :
1493 622 : PrintFlag = false;
1494 : // STEP 1: find the DataSizing::AutoSized cooling air flow rate and capacity
1495 : // Note: this call will request fan heat and size the fan.
1496 : // Either the few lines above are too early, or there needs to be a way to avoid requesting fan heat from
1497 : // BaseSizerWithFanHeatInputs::initializeWithinEP so the fan doesn't size until the parent wants it to size.
1498 : // see PackagedTerminalHeatPumpVSAS.idf where fan is not sized large enough for cooling coil air flow rate.
1499 :
1500 : // delay fan sizing in case a VS fan is used and air flow needs to be modified above max design flow
1501 : // this may also mean capacity result does not include fan heat? and table diffs?
1502 : // and causes unit test failures, e.g., UnitarySystemModel_MultispeedDXCoilSizing.
1503 : // comment this out until the PTUnit to UnitarySystem #9273 branch is merged, so nothing changes
1504 : // until this is implemented, unbalanced air flow warnings show up in VS coil PTUnits
1505 : // int saveDataFanIndex = state.dataSize->DataFanIndex;
1506 : // state.dataSize->DataFanIndex = -1;
1507 :
1508 622 : bool coolingAirFlowIsAutosized = this->m_MaxCoolAirVolFlow == DataSizing::AutoSize;
1509 622 : bool heatingAirFlowIsAutosized = this->m_MaxHeatAirVolFlow == DataSizing::AutoSize;
1510 622 : if (this->m_CoolCoilExists) {
1511 621 : if (!this->m_HeatCoilExists) state.dataSize->ZoneCoolingOnlyFan = true;
1512 621 : TempSize = this->m_MaxCoolAirVolFlow;
1513 621 : SaveCurDuctType = state.dataSize->CurDuctType;
1514 : // might want to rethink this method. Tries to find the larger of cooling or heating capacity
1515 : // however, if there is no heating coil the cooling air flow rate is used, not the main flow rate
1516 : // this is fine if there are no other systems on the branch. CoilSystem does not do this (#8761).
1517 621 : if (this->m_sysType == SysType::Unitary) state.dataSize->CurDuctType = HVAC::AirDuctType::Cooling;
1518 621 : bool errorsFound = false;
1519 621 : if ((CoolingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (CoolingSAFlowMethod == DataSizing::None)) {
1520 621 : CoolingAirFlowSizer sizingCoolingAirFlow;
1521 621 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1522 621 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1523 621 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1524 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1525 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1526 0 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1527 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1528 0 : } else if (CoolingSAFlowMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
1529 0 : TempSize = DataSizing::AutoSize;
1530 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1531 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1532 0 : SysCoolingFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1533 0 : SysCoolingFlow *= this->m_MaxCoolAirVolFlow;
1534 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1535 0 : } else if (CoolingSAFlowMethod == DataSizing::FlowPerCoolingCapacity) {
1536 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) {
1537 0 : TempSize = DataSizing::AutoSize;
1538 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1539 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1540 0 : state.dataSize->DataFlowUsedForSizing = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1541 0 : SizingMethod = HVAC::CoolingCapacitySizing;
1542 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
1543 0 : state.dataSize->DataTotCapCurveIndex =
1544 0 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1545 0 : state.dataSize->DataIsDXCoil = true;
1546 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
1547 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1548 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1549 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1550 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1551 0 : state.dataSize->DataIsDXCoil = true;
1552 : }
1553 0 : CoolingCapacitySizer sizerCoolingCapacity;
1554 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
1555 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1556 0 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1557 0 : SysCoolingFlow = CoolCapAtPeak * this->m_MaxCoolAirVolFlow;
1558 0 : state.dataSize->DataTotCapCurveIndex = 0;
1559 0 : EqSizing.CoolingCapacity = true;
1560 0 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1561 0 : } else {
1562 0 : SysCoolingFlow = this->m_DesignCoolingCapacity * this->m_MaxCoolAirVolFlow;
1563 0 : CoolCapAtPeak = this->m_DesignCoolingCapacity;
1564 0 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1565 : }
1566 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1567 : } else {
1568 : // should never happen
1569 0 : ShowSevereError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
1570 0 : ShowContinueError(state, "Illegal entry for Cooling Supply Air Flow Rate Method.");
1571 : }
1572 :
1573 621 : state.dataSize->CurDuctType = SaveCurDuctType;
1574 621 : EqSizing.CoolingAirFlow = true;
1575 621 : EqSizing.CoolingAirVolFlow = SysCoolingFlow;
1576 :
1577 : // Cooling airflow should be known at this point. Now find DataSizing::AutoSized design cooling capacity.
1578 621 : if (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity < 0.0) {
1579 463 : SizingMethod = HVAC::CoolingCapacitySizing;
1580 463 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1581 463 : TempSize = DataSizing::AutoSize;
1582 : // could probably move this up outside the IF and delete then next group below in the else
1583 463 : switch (this->m_CoolingCoilType_Num) {
1584 50 : case HVAC::CoilDX_Cooling: {
1585 100 : state.dataSize->DataTotCapCurveIndex =
1586 50 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getOpModeCapFTIndex(HVAC::CoilMode::Normal);
1587 50 : state.dataSize->DataIsDXCoil = true;
1588 50 : } break;
1589 366 : case HVAC::CoilDX_CoolingSingleSpeed:
1590 : case HVAC::CoilDX_MultiSpeedCooling:
1591 : case HVAC::CoilDX_CoolingTwoSpeed:
1592 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
1593 366 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1594 366 : state.dataSize->DataIsDXCoil = true;
1595 366 : } break;
1596 7 : case HVAC::Coil_CoolingAirToAirVariableSpeed: {
1597 7 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1598 7 : state.dataSize->DataIsDXCoil = true;
1599 7 : } break;
1600 3 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
1601 3 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1602 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1603 : // state.dataSize->DataIsDXCoil = true;
1604 3 : } break;
1605 37 : default: {
1606 37 : } break;
1607 : }
1608 926 : CoolingCapacitySizer sizerCoolingCapacity;
1609 463 : sizerCoolingCapacity.overrideSizingString(SizingString);
1610 463 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1611 463 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1612 463 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1613 : // this probably needs to be more specific. Letting heating coil size itself if user has scalable sizing
1614 463 : if (this->m_HVACSizingIndex <= 0) state.dataSize->DXCoolCap = CoolCapAtPeak;
1615 : // CoilSystem does not size the cooling coil (#8761)
1616 463 : if ((this->m_sysType == SysType::Unitary) || (this->m_sysType == SysType::PackagedAC) || (this->m_sysType == SysType::PackagedHP) ||
1617 274 : (this->m_sysType == SysType::PackagedWSHP)) {
1618 216 : EqSizing.CoolingCapacity = true;
1619 216 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1620 : }
1621 621 : } else if (!HardSizeNoDesRun && (CoolingSAFlowMethod != DataSizing::FlowPerCoolingCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1622 : // corrected code for #8756
1623 89 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
1624 8 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
1625 3 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
1626 86 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1627 86 : state.dataSize->DataIsDXCoil = true;
1628 : }
1629 89 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
1630 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1631 2 : state.dataSize->DataIsDXCoil = true;
1632 : }
1633 89 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
1634 0 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1635 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1636 : // state.dataSize->DataIsDXCoil = true;
1637 : }
1638 : // PTUnit does not call CapacitySizer and adjust capacity based on flow per capacity limits
1639 89 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) {
1640 47 : state.dataSize->DataIsDXCoil = false;
1641 : }
1642 89 : SizingMethod = HVAC::CoolingCapacitySizing;
1643 89 : state.dataSize->DataFlowUsedForSizing = EqSizing.CoolingAirVolFlow;
1644 89 : if (this->m_CoolingCapMethod == DataSizing::CapacityPerFloorArea ||
1645 89 : (this->m_CoolingCapMethod == DataSizing::CoolingDesignCapacity && this->m_DesignCoolingCapacity > 0.0)) {
1646 0 : TempSize = this->m_DesignCoolingCapacity;
1647 : } else {
1648 89 : TempSize = DataSizing::AutoSize;
1649 : }
1650 89 : CoolingCapacitySizer sizerCoolingCapacity;
1651 89 : sizerCoolingCapacity.overrideSizingString(SizingString);
1652 89 : state.dataSize->DataFracOfAutosizedCoolingCapacity = coolingCapacityMultiplier;
1653 89 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1654 89 : CoolCapAtPeak = sizerCoolingCapacity.size(state, TempSize, errorsFound);
1655 89 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1656 89 : EqSizing.CoolingCapacity = true;
1657 89 : EqSizing.DesCoolingLoad = CoolCapAtPeak;
1658 89 : } else {
1659 : // something seems missing here based on multiple conditional if above
1660 69 : if (this->m_DesignCoolingCapacity != DataSizing::AutoSize) CoolCapAtPeak = this->m_DesignCoolingCapacity;
1661 : }
1662 621 : state.dataSize->DataIsDXCoil = false;
1663 621 : state.dataSize->DataTotCapCurveIndex = 0;
1664 621 : state.dataSize->DataFlowUsedForSizing = 0.0;
1665 : }
1666 :
1667 : // STEP 2: find the DataSizing::AutoSized heating air flow rate and capacity
1668 622 : if (this->m_HeatCoilExists) {
1669 311 : if (!this->m_CoolCoilExists) state.dataSize->ZoneHeatingOnlyFan = true;
1670 311 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1671 311 : SizingMethod = HVAC::HeatingAirflowSizing;
1672 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1673 311 : TempSize = this->m_MaxHeatAirVolFlow;
1674 311 : SaveCurDuctType = state.dataSize->CurDuctType;
1675 311 : state.dataSize->CurDuctType = HVAC::AirDuctType::Heating;
1676 311 : if ((HeatingSAFlowMethod == DataSizing::SupplyAirFlowRate) || (HeatingSAFlowMethod == DataSizing::None)) {
1677 311 : bool errorsFound = false;
1678 311 : HeatingAirFlowSizer sizingHeatingAirFlow;
1679 311 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1680 311 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1681 311 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1682 311 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerFloorArea) {
1683 0 : bool errorsFound = false;
1684 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1685 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1686 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1687 0 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1688 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1689 0 : } else if (HeatingSAFlowMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
1690 0 : TempSize = DataSizing::AutoSize;
1691 0 : bool errorsFound = false;
1692 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1693 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1694 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1695 0 : SysHeatingFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1696 0 : SysHeatingFlow *= this->m_MaxHeatAirVolFlow;
1697 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1698 0 : } else if (HeatingSAFlowMethod == DataSizing::FlowPerHeatingCapacity) {
1699 0 : TempSize = DataSizing::AutoSize;
1700 0 : bool errorsFound = false;
1701 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1702 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1703 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1704 0 : state.dataSize->DataFlowUsedForSizing = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1705 0 : SizingMethod = HVAC::HeatingCapacitySizing;
1706 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
1707 0 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1708 0 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
1709 0 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1710 0 : state.dataSize->DataIsDXCoil = true;
1711 : }
1712 0 : if (state.dataSize->CurSysNum > 0)
1713 0 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1714 : false; // set to false to allow calculation of actual heating capacity
1715 0 : HeatingCapacitySizer sizerHeatingCapacity;
1716 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
1717 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1718 0 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1719 0 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1720 0 : SysHeatingFlow = HeatCapAtPeak * this->m_MaxHeatAirVolFlow;
1721 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1722 0 : EqSizing.HeatingCapacity = true;
1723 0 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1724 0 : } else {
1725 : // should never happen
1726 0 : ShowSevereError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
1727 0 : ShowContinueError(state, "Illegal entry for Heating Supply Air Flow Rate Method.");
1728 : }
1729 :
1730 311 : state.dataSize->CurDuctType = SaveCurDuctType;
1731 311 : EqSizing.HeatingAirFlow = true;
1732 311 : EqSizing.HeatingAirVolFlow = SysHeatingFlow;
1733 :
1734 : // Heating airflow should be known at this point. Now find DataSizing::AutoSized design heating capacity.
1735 311 : if (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity == DataSizing::AutoSize) {
1736 282 : SizingMethod = HVAC::HeatingCapacitySizing;
1737 282 : if (m_sysType == SysType::Unitary || m_sysType == SysType::CoilCoolingDX || m_sysType == SysType::CoilCoolingWater) {
1738 100 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1739 : }
1740 282 : TempSize = DataSizing::AutoSize;
1741 282 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1742 282 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1743 45 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1744 45 : state.dataSize->DataIsDXCoil = true;
1745 : }
1746 : // should have VS coil capFT here also
1747 282 : if (this->m_sysType == SysType::PackagedWSHP && this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1748 2 : state.dataSize->DataTotCapCurveIndex = VariableSpeedCoils::GetVSCoilCapFTCurveIndex(state, this->m_CoolingCoilIndex, ErrFound);
1749 : // VS coil model does not check for flow/capacity ratio, this will disable that test in Capacity sizer
1750 : // state.dataSize->DataIsDXCoil = true;
1751 : }
1752 : // PTUnit does not call CapacitySizer and adjust capacity based on flow per capacity limits
1753 282 : if (this->m_sysType == SysType::PackagedHP) {
1754 22 : state.dataSize->DataIsDXCoil = false;
1755 : }
1756 282 : if (state.dataSize->CurSysNum > 0)
1757 94 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1758 : false; // set to false to allow calculation of actual heating capacity
1759 282 : bool errorsFound = false;
1760 282 : HeatingCapacitySizer sizerHeatingCapacity;
1761 282 : sizerHeatingCapacity.overrideSizingString(SizingString);
1762 282 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1763 282 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1764 282 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1765 282 : EqSizing.HeatingCapacity = true;
1766 282 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1767 282 : } else {
1768 29 : if (!HardSizeNoDesRun &&
1769 18 : (HeatingSAFlowMethod != DataSizing::FlowPerHeatingCapacity && this->m_DesignHeatingCapacity != DataSizing::AutoSize)) {
1770 : // should have other DX heating coil types here
1771 18 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
1772 3 : SizingMethod = HVAC::HeatingCapacitySizing;
1773 3 : state.dataSize->DataFlowUsedForSizing = EqSizing.HeatingAirVolFlow;
1774 3 : TempSize = DataSizing::AutoSize;
1775 3 : state.dataSize->DataHeatSizeRatio = this->m_HeatingSizingRatio;
1776 3 : state.dataSize->DataTotCapCurveIndex = DXCoils::GetDXCoilCapFTCurveIndex(state, this->m_HeatingCoilIndex, ErrFound);
1777 3 : state.dataSize->DataIsDXCoil = true;
1778 3 : if (state.dataSize->CurSysNum > 0)
1779 3 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
1780 : false; // set to false to allow calculation of actual heating capacity
1781 3 : bool errorsFound = false;
1782 3 : HeatingCapacitySizer sizerHeatingCapacity;
1783 3 : sizerHeatingCapacity.overrideSizingString(SizingString);
1784 3 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1785 3 : HeatCapAtPeak = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1786 3 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
1787 3 : EqSizing.HeatingCapacity = true;
1788 3 : EqSizing.DesHeatingLoad = HeatCapAtPeak;
1789 3 : }
1790 18 : } else {
1791 : // something seems missing here based on multiple conditional if above
1792 11 : if (this->m_DesignHeatingCapacity != DataSizing::AutoSize) HeatCapAtPeak = this->m_DesignHeatingCapacity;
1793 : }
1794 : }
1795 : // if ( ! UnitarySystem( UnitarySysNum ).CoolCoilExists )DXCoolCap = HeatCapAtPeak;
1796 311 : state.dataSize->DataIsDXCoil = false;
1797 311 : state.dataSize->DataTotCapCurveIndex = 0;
1798 311 : state.dataSize->DataFlowUsedForSizing = 0.0;
1799 311 : if (this->m_sysType == SysType::PackagedAC) EqSizing.HeatingCapacity = false;
1800 : }
1801 :
1802 622 : bool isWSVarSpeedCoolCoil = this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
1803 622 : bool isWSVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
1804 622 : bool isVarSpeedCoolCoil = this->m_HeatingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed;
1805 622 : bool isVarSpeedHeatCoil = this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed;
1806 :
1807 622 : Real64 saveRawHeatingCapacity = HeatCapAtPeak;
1808 :
1809 : // STEP 3A: Find VS cooling coil air flow to capacity ratio and adjust design air flow
1810 825 : if (EqSizing.DesCoolingLoad > 0.0 && state.dataSize->CurZoneEqNum > 0 &&
1811 203 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
1812 200 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1813 170 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed))) {
1814 9 : Real64 coolingToHeatingCapRatio = 1.0;
1815 9 : if ((isWSVarSpeedCoolCoil && this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) ||
1816 6 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1817 6 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
1818 9 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NormSpedLevel;
1819 : Real64 coolingAirFlowToCapacityRatio =
1820 9 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1821 9 : EqSizing.CoolingAirVolFlow = EqSizing.DesCoolingLoad * coolingAirFlowToCapacityRatio;
1822 9 : if (EqSizing.DesHeatingLoad > 0.0) coolingToHeatingCapRatio = EqSizing.DesCoolingLoad / EqSizing.DesHeatingLoad;
1823 : }
1824 9 : if (((isWSVarSpeedHeatCoil || isVarSpeedHeatCoil) && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) ||
1825 4 : ((this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP) &&
1826 4 : this->m_CoolingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed)) {
1827 5 : int normSpeed = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
1828 : Real64 heatingAirFlowToCapacityRatio =
1829 5 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowPerRatedTotCap(normSpeed);
1830 5 : EqSizing.DesHeatingLoad *= coolingToHeatingCapRatio;
1831 5 : EqSizing.HeatingAirVolFlow = EqSizing.DesHeatingLoad * heatingAirFlowToCapacityRatio;
1832 : }
1833 : }
1834 :
1835 : // STEP 3B: use the greater of cooling and heating air flow rates for system flow
1836 : // previous version of E+ used maximum flow rate for unitary systems. Keep this methodology for now.
1837 : // Delete next 2 lines and uncomment 2 lines inside next if (HeatPump) statement to allow non-heat pump systems to operate at different flow
1838 : // rates (might require additional change to if block logic).
1839 : // UnitarySystem is sizing heating coil size = cooling coil size for 5Zone_Unitary_HXAssistedCoil (not a heat pump)
1840 : // and WaterSideEconomizer_PreCoolCoil (not a heat pump)
1841 : // and 5Zone_Unitary_VSDesuperheatWaterHeater (not a heat pump)
1842 622 : if ((!isWSVarSpeedHeatCoil &&
1843 618 : (((this->m_sysType == SysType::PackagedAC && !isVarSpeedCoolCoil) && (this->m_sysType == SysType::PackagedHP && !isVarSpeedHeatCoil)) ||
1844 618 : (this->m_sysType == SysType::Unitary && this->m_HeatPump))) ||
1845 588 : (this->m_sysType == SysType::Unitary &&
1846 96 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
1847 62 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
1848 61 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling))) {
1849 102 : EqSizing.CoolingAirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1850 102 : EqSizing.HeatingAirVolFlow = EqSizing.CoolingAirVolFlow;
1851 : }
1852 :
1853 : // STEP 4: set heat pump coil capacities equal to greater of cooling or heating capacity
1854 : // if a heat pump, use maximum values and set main air flow and capacity variables
1855 622 : if (this->m_sysType == SysType::PackagedHP && !isVarSpeedCoolCoil) {
1856 : // PTPH allows the cooling coil to set DataCoolCoilCap so cooling coil sets capacity
1857 : // This is wrong since a larger heating load should set HP capacity (next else if)
1858 28 : EqSizing.HeatingCapacity = false;
1859 594 : } else if (this->m_HeatPump && (state.dataSize->CurZoneEqNum == 0 || !isWSVarSpeedCoolCoil)) {
1860 60 : EqSizing.AirFlow = true;
1861 60 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1862 60 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit &&
1863 59 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1864 59 : EqSizing.Capacity = true;
1865 59 : EqSizing.DesCoolingLoad = max(EqSizing.DesCoolingLoad, EqSizing.DesHeatingLoad);
1866 59 : EqSizing.DesHeatingLoad = EqSizing.DesCoolingLoad;
1867 59 : state.dataSize->DXCoolCap = EqSizing.DesCoolingLoad;
1868 : }
1869 534 : } else if (!this->m_CoolCoilExists && state.dataSize->CurZoneEqNum > 0) {
1870 0 : state.dataSize->DXCoolCap = EqSizing.DesHeatingLoad;
1871 : }
1872 :
1873 : // now size fans as necessary
1874 : // comment this out until the PTUnit to UnitarySystem #9273 branch is merged, so nothing changes
1875 : // until this is implemented, unbalanced air flow warning show up in VS coil PTUnits
1876 : // state.dataSize->DataFanIndex = saveDataFanIndex;
1877 :
1878 : // Some parent objects report sizing, some do not
1879 622 : if (this->m_OKToPrintSizing) {
1880 622 : if (this->m_sysType != SysType::CoilCoolingDX && this->m_sysType != SysType::CoilCoolingWater) {
1881 327 : PrintFlag = true;
1882 : }
1883 : }
1884 : // STEP 5: report system parameters (e.g., air flow rates, capacities, etc.)
1885 622 : if (this->m_FanExists) {
1886 325 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)
1887 197 : PrintFlag = false;
1888 :
1889 325 : EqSizing.SystemAirFlow = true;
1890 325 : EqSizing.AirVolFlow = max(EqSizing.CoolingAirVolFlow, EqSizing.HeatingAirVolFlow);
1891 325 : if (this->m_DesignFanVolFlowRate <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1892 262 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
1893 : }
1894 325 : state.dataSize->DataEMSOverrideON = this->m_DesignFanVolFlowRateEMSOverrideOn;
1895 325 : state.dataSize->DataEMSOverride = this->m_DesignFanVolFlowRateEMSOverrideValue;
1896 :
1897 325 : bool errorsFound = false;
1898 325 : SystemAirFlowSizer sizerSystemAirFlow;
1899 325 : std::string sizingString = "Supply Air Flow Rate [m3/s]";
1900 325 : sizerSystemAirFlow.overrideSizingString(sizingString);
1901 325 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1902 325 : this->m_DesignFanVolFlowRate = sizerSystemAirFlow.size(state, this->m_DesignFanVolFlowRate, errorsFound);
1903 :
1904 325 : state.dataSize->DataEMSOverrideON = false;
1905 325 : EqSizing.SystemAirFlow = false;
1906 :
1907 325 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)
1908 197 : PrintFlag = true;
1909 325 : }
1910 :
1911 : // not sure what to do if UnitarySystem has only 1 coil type and flow needs to occur when present coil is off
1912 : // how does constant fan operating mode pertain here?
1913 622 : if (this->m_HeatCoilExists && !this->m_CoolCoilExists) {
1914 1 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_MaxCoolAirVolFlow = EqSizing.HeatingAirVolFlow;
1915 621 : } else if (this->m_CoolCoilExists && !this->m_HeatCoilExists) {
1916 311 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_MaxHeatAirVolFlow = EqSizing.CoolingAirVolFlow;
1917 311 : state.dataSize->DXCoolCap = CoolCapAtPeak;
1918 : }
1919 :
1920 : // PT Units report sizing for cooling then heating, UnitarySystem reverses that order
1921 : // temporarily reverse reporting for PT units so eio diffs are cleaner, remove later
1922 622 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
1923 197 : if (this->m_CoolCoilExists) {
1924 : // allow design size to report
1925 197 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) EqSizing.CoolingAirFlow = false;
1926 197 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1927 150 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
1928 : }
1929 197 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
1930 197 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
1931 197 : TempSize = this->m_MaxCoolAirVolFlow;
1932 197 : bool errorsFound = false;
1933 197 : CoolingAirFlowSizer sizingCoolingAirFlow;
1934 197 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
1935 197 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
1936 197 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1937 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1938 197 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1939 197 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
1940 197 : state.dataSize->DataEMSOverrideON = false;
1941 197 : state.dataSize->DataConstantUsedForSizing = 0.0;
1942 197 : }
1943 197 : if (this->m_HeatCoilExists) {
1944 : // allow design size to report
1945 197 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) EqSizing.HeatingAirFlow = false;
1946 197 : SizingMethod = HVAC::HeatingAirflowSizing;
1947 197 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1948 150 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1949 : }
1950 197 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
1951 197 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1952 2 : EqSizing.AirFlow = false;
1953 : }
1954 197 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1955 197 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
1956 197 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
1957 197 : TempSize = this->m_MaxHeatAirVolFlow;
1958 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1959 197 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
1960 197 : bool errorsFound = false;
1961 197 : HeatingAirFlowSizer sizingHeatingAirFlow;
1962 197 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1963 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1964 197 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1965 197 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1966 197 : state.dataSize->DataEMSOverrideON = false;
1967 197 : state.dataSize->DataConstantUsedForSizing = 0.0;
1968 197 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1969 2 : EqSizing.AirFlow = saveEqSizingAirFlow;
1970 : }
1971 197 : }
1972 :
1973 197 : } else {
1974 425 : if (this->m_HeatCoilExists) {
1975 :
1976 114 : SizingMethod = HVAC::HeatingAirflowSizing;
1977 114 : if (this->m_MaxHeatAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
1978 102 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
1979 : }
1980 114 : bool saveEqSizingAirFlow = EqSizing.AirFlow;
1981 114 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1982 2 : EqSizing.AirFlow = false;
1983 : }
1984 114 : FieldNum = 7; // N7 , \field Heating Supply Air Flow Rate
1985 114 : state.dataSize->DataEMSOverrideON = this->m_MaxHeatAirVolFlowEMSOverrideOn;
1986 114 : state.dataSize->DataEMSOverride = this->m_MaxHeatAirVolFlowEMSOverrideValue;
1987 114 : TempSize = this->m_MaxHeatAirVolFlow;
1988 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
1989 114 : SizingString = "Heating Supply Air Flow Rate [m3/s]";
1990 114 : bool errorsFound = false;
1991 114 : HeatingAirFlowSizer sizingHeatingAirFlow;
1992 114 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1993 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1994 114 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1995 114 : this->m_MaxHeatAirVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
1996 114 : state.dataSize->DataEMSOverrideON = false;
1997 114 : state.dataSize->DataConstantUsedForSizing = 0.0;
1998 114 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
1999 2 : EqSizing.AirFlow = saveEqSizingAirFlow;
2000 : }
2001 114 : }
2002 :
2003 425 : if (this->m_CoolCoilExists) {
2004 :
2005 424 : if (this->m_MaxCoolAirVolFlow <= 0.0) { // attempt to catch any missed logic in GetUnitarySystem
2006 361 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
2007 : }
2008 424 : state.dataSize->DataEMSOverrideON = this->m_MaxCoolAirVolFlowEMSOverrideOn;
2009 424 : state.dataSize->DataEMSOverride = this->m_MaxCoolAirVolFlowEMSOverrideValue;
2010 424 : TempSize = this->m_MaxCoolAirVolFlow;
2011 424 : bool errorsFound = false;
2012 424 : CoolingAirFlowSizer sizingCoolingAirFlow;
2013 424 : std::string stringOverride = "Cooling Supply Air Flow Rate [m3/s]";
2014 424 : if (state.dataGlobal->isEpJSON) stringOverride = "cooling_supply_air_flow_rate [m3/s]";
2015 424 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
2016 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2017 424 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2018 424 : this->m_MaxCoolAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
2019 424 : state.dataSize->DataEMSOverrideON = false;
2020 424 : state.dataSize->DataConstantUsedForSizing = 0.0;
2021 424 : }
2022 : }
2023 :
2024 : // If not set, set DesignFanVolFlowRate as greater of cooling and heating to make sure this value > 0.
2025 : // If fan is hard-sized, use that value, otherwise the fan will size to DesignFanVolFlowRate
2026 622 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2027 249 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2028 249 : if (this->m_ActualFanVolFlowRate > 0.0) this->m_DesignFanVolFlowRate = this->m_ActualFanVolFlowRate;
2029 249 : if (this->m_DesignFanVolFlowRate <= 0.0) {
2030 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2031 0 : ShowFatalError(state, "Unable to determine fan air flow rate.");
2032 : }
2033 : }
2034 622 : if (!this->m_FanExists) this->m_ActualFanVolFlowRate = this->m_DesignFanVolFlowRate;
2035 :
2036 622 : if (this->m_CoolCoilExists || this->m_HeatCoilExists || this->m_SuppCoilExists) {
2037 622 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2038 : // set no load air flow ratio local var
2039 622 : Real64 NoLoadCoolingAirFlowRateRatio = 1.0;
2040 622 : Real64 NoLoadHeatingAirFlowRateRatio = 1.0;
2041 622 : if (MSHPIndex > -1) {
2042 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling > 0) {
2043 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0] == DataSizing::AutoSize) {
2044 : NoLoadCoolingAirFlowRateRatio =
2045 24 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling));
2046 : } else {
2047 : NoLoadCoolingAirFlowRateRatio =
2048 38 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[0]);
2049 : }
2050 : }
2051 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating > 0) {
2052 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0] == DataSizing::AutoSize) {
2053 : NoLoadHeatingAirFlowRateRatio =
2054 24 : min(this->m_NoLoadAirFlowRateRatio, 1.0 / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating));
2055 : } else {
2056 : NoLoadHeatingAirFlowRateRatio =
2057 38 : min(this->m_NoLoadAirFlowRateRatio, state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[0]);
2058 : }
2059 : }
2060 62 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio > 0.0) {
2061 62 : this->m_NoLoadAirFlowRateRatio = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2062 : } else {
2063 0 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2064 : }
2065 : } else {
2066 560 : if ((this->m_CoolCoilExists || this->m_HeatCoilExists) && this->m_useNoLoadLowSpeedAirFlow) {
2067 541 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2068 532 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
2069 : Real64 MaxSpeedFlowRate =
2070 9 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2071 9 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2072 9 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) >
2073 : 0.0) { // these are the air flow at speed fields, and could be 0
2074 9 : NoLoadCoolingAirFlowRateRatio =
2075 9 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2076 : } else {
2077 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2078 : }
2079 541 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
2080 : // for (DehumidModeNum = 0; DehumidModeNum <= thisDXCoil.NumDehumidModes; ++DehumidModeNum)
2081 : // for (CapacityStageNum = 1; CapacityStageNum <= thisDXCoil.NumCapacityStages; ++CapacityStageNum)
2082 : // PerfModeNum = DehumidModeNum * 2 + CapacityStageNum
2083 : // RatedAirVolFlowRate(PerfModeNum) so PerfModeNum = 1 to NumCapacityStages to find air flow rate
2084 9 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2085 9 : .RatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages);
2086 12 : if (MaxSpeedFlowRate > 0.0 &&
2087 3 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2088 3 : NoLoadCoolingAirFlowRateRatio =
2089 3 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2090 : } else { // if any flow rates are autosized use the ratio of number of capacity stages
2091 6 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumCapacityStages;
2092 : }
2093 523 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2094 : // RatedAirVolFlowRate(1) = high speed, RatedAirVolFlowRate2= low speed
2095 67 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate(1);
2096 74 : if (MaxSpeedFlowRate > 0.0 &&
2097 7 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 != DataSizing::AutoSize) {
2098 7 : NoLoadCoolingAirFlowRateRatio =
2099 7 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).RatedAirVolFlowRate2 / MaxSpeedFlowRate;
2100 : } else { // above flow rates for this coil could be autosized, use 1/2 for two speed coil
2101 60 : NoLoadCoolingAirFlowRateRatio = 0.5;
2102 : }
2103 456 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
2104 : // MSRatedAirVolFlowRate
2105 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex)
2106 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2107 0 : if (MaxSpeedFlowRate > 0.0 &&
2108 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2109 0 : NoLoadCoolingAirFlowRateRatio =
2110 0 : state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2111 : } else { // if any flow rates are autosized use the ratio of number of speeds
2112 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2113 : }
2114 456 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2115 34 : NoLoadCoolingAirFlowRateRatio = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex]
2116 17 : .performance.normalMode.speeds[0]
2117 : .original_input_specs.evaporator_air_flow_fraction;
2118 : }
2119 541 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
2120 538 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
2121 : Real64 MaxSpeedFlowRate =
2122 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2123 3 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2124 3 : if (MaxSpeedFlowRate > 0.0 && state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) >
2125 : 0.0) { // these are the air flow at speed fields, and could be 0
2126 3 : NoLoadHeatingAirFlowRateRatio =
2127 3 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2128 : } else {
2129 0 : NoLoadCoolingAirFlowRateRatio = 1.0 / state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds;
2130 : }
2131 541 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
2132 : // MSRatedAirVolFlowRate
2133 0 : Real64 MaxSpeedFlowRate = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex)
2134 0 : .MSRatedAirVolFlowRate(state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2135 0 : if (MaxSpeedFlowRate > 0.0 &&
2136 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) != DataSizing::AutoSize) {
2137 0 : NoLoadHeatingAirFlowRateRatio =
2138 0 : state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1) / MaxSpeedFlowRate;
2139 : } else { // if any flow rates are autosized use the ratio of number of speeds
2140 0 : NoLoadHeatingAirFlowRateRatio = 1.0 / state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex).NumOfSpeeds;
2141 : }
2142 : }
2143 541 : this->m_NoLoadAirFlowRateRatio = min(NoLoadCoolingAirFlowRateRatio, NoLoadHeatingAirFlowRateRatio);
2144 : }
2145 : }
2146 622 : if (this->m_NoCoolHeatSAFMethod <= DataSizing::SupplyAirFlowRate && this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
2147 0 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
2148 0 : state.dataSize->DataConstantUsedForSizing = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2149 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed ||
2150 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
2151 0 : minNoLoadFlow = 0.6667; // TODO: Should this have a Coil:Cooling:DX block?
2152 : } else {
2153 0 : if (this->m_NoLoadAirFlowRateRatio < 1.0) {
2154 0 : minNoLoadFlow = this->m_NoLoadAirFlowRateRatio;
2155 : } else {
2156 0 : minNoLoadFlow = 0.5;
2157 : }
2158 : }
2159 0 : if (this->m_MaxCoolAirVolFlow >= this->m_MaxHeatAirVolFlow) {
2160 0 : state.dataSize->DataFractionUsedForSizing =
2161 0 : min(minNoLoadFlow, (this->m_MaxHeatAirVolFlow / this->m_MaxCoolAirVolFlow) - 0.01);
2162 : } else {
2163 0 : state.dataSize->DataFractionUsedForSizing =
2164 0 : min(minNoLoadFlow, (this->m_MaxCoolAirVolFlow / this->m_MaxHeatAirVolFlow) - 0.01);
2165 : }
2166 : } else {
2167 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2168 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2169 : }
2170 622 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
2171 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.CoolingAirVolFlow;
2172 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2173 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2174 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2175 622 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
2176 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.HeatingAirVolFlow;
2177 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2178 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2179 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2180 622 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerCoolingCapacity) {
2181 0 : if (EqSizing.DesCoolingLoad <= 0.0) {
2182 : // water coils not sizing yet
2183 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2184 0 : WaterCoils::SimulateWaterCoilComponents(
2185 0 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2186 0 : EqSizing.DesCoolingLoad = WaterCoils::GetWaterCoilCapacity(
2187 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
2188 : }
2189 : }
2190 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesCoolingLoad;
2191 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2192 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2193 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2194 622 : } else if (this->m_NoCoolHeatSAFMethod == DataSizing::FlowPerHeatingCapacity) {
2195 0 : if (EqSizing.DesHeatingLoad <= 0.0) {
2196 : // water coil not sizing yet
2197 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2198 0 : WaterCoils::SimulateWaterCoilComponents(
2199 0 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
2200 0 : EqSizing.DesHeatingLoad = WaterCoils::GetWaterCoilCapacity(
2201 0 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
2202 : }
2203 : }
2204 0 : this->m_MaxNoCoolHeatAirVolFlow *= EqSizing.DesHeatingLoad;
2205 0 : state.dataSize->DataConstantUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
2206 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
2207 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
2208 : } else {
2209 622 : state.dataSize->DataFractionUsedForSizing = this->m_NoLoadAirFlowRateRatio;
2210 : }
2211 :
2212 622 : FieldNum = 11; // N11 , \field No Load Supply Air Flow Rate
2213 622 : state.dataSize->DataEMSOverrideON = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideOn;
2214 622 : state.dataSize->DataEMSOverride = this->m_MaxNoCoolHeatAirVolFlowEMSOverrideValue;
2215 622 : TempSize = this->m_MaxNoCoolHeatAirVolFlow;
2216 : // SizingString = UnitarySystemNumericFields(UnitarySysNum).FieldNames(FieldNum) + " [m3/s]";
2217 622 : SizingString = "No Load Supply Air Flow Rate [m3/s]";
2218 622 : bool errorsFound = false;
2219 622 : SystemAirFlowSizer sizerSystemAirFlow;
2220 622 : sizerSystemAirFlow.overrideSizingString(SizingString);
2221 622 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2222 622 : this->m_MaxNoCoolHeatAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
2223 622 : state.dataSize->DataEMSOverrideON = false;
2224 622 : state.dataSize->DataConstantUsedForSizing = 0.0;
2225 622 : state.dataSize->DataFractionUsedForSizing = 0.0;
2226 622 : }
2227 :
2228 622 : if (this->m_MaxCoolAirVolFlow > 0.0) {
2229 621 : this->LowSpeedCoolFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxCoolAirVolFlow;
2230 : }
2231 622 : if (this->m_MaxHeatAirVolFlow > 0.0) {
2232 311 : this->LowSpeedHeatFanRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_MaxHeatAirVolFlow;
2233 : }
2234 :
2235 622 : if (this->ATMixerExists && state.dataSize->CurZoneEqNum > 0) { // set up ATMixer conditions for use in component sizing
2236 34 : SingleDuct::setATMixerSizingProperties(state, this->m_ATMixerIndex, this->ControlZoneNum, state.dataSize->CurZoneEqNum);
2237 : }
2238 :
2239 622 : if (this->OAMixerExists) {
2240 167 : IsAutoSize = false;
2241 167 : if (this->m_CoolOutAirVolFlow == DataSizing::AutoSize) {
2242 110 : IsAutoSize = true;
2243 : }
2244 167 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2245 0 : if (this->m_CoolOutAirVolFlow > 0.0) {
2246 0 : BaseSizer::reportSizerOutput(state,
2247 : this->UnitType,
2248 : this->Name,
2249 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2250 : this->m_CoolOutAirVolFlow);
2251 : }
2252 : } else {
2253 167 : CheckZoneSizing(state, this->UnitType, this->Name);
2254 167 : Real64 CoolOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2255 167 : if (CoolOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2256 3 : CoolOutAirVolFlowDes = 0.0;
2257 : }
2258 167 : if (IsAutoSize) {
2259 110 : this->m_CoolOutAirVolFlow = CoolOutAirVolFlowDes;
2260 110 : BaseSizer::reportSizerOutput(
2261 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]", CoolOutAirVolFlowDes);
2262 : } else {
2263 57 : if (this->m_CoolOutAirVolFlow > 0.0 && CoolOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2264 47 : Real64 CoolOutAirVolFlowUser = this->m_CoolOutAirVolFlow;
2265 47 : BaseSizer::reportSizerOutput(state,
2266 : this->UnitType,
2267 : this->Name,
2268 : "Design Size Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2269 : CoolOutAirVolFlowDes,
2270 : "User-Specified Outdoor Air Flow Rate During Cooling Operation [m3/s]",
2271 : CoolOutAirVolFlowUser);
2272 47 : if (state.dataGlobal->DisplayExtraWarnings) {
2273 0 : if ((std::abs(CoolOutAirVolFlowDes - CoolOutAirVolFlowUser) / CoolOutAirVolFlowUser) >
2274 0 : state.dataSize->AutoVsHardSizingThreshold) {
2275 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2276 0 : ShowContinueError(
2277 : state,
2278 0 : format("User-Specified Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]", CoolOutAirVolFlowUser));
2279 0 : ShowContinueError(state,
2280 0 : format("differs from Design Size Outdoor Air Flow Rate During Cooling Operation of {:.5R} [m3/s]",
2281 : CoolOutAirVolFlowDes));
2282 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2283 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2284 : }
2285 : }
2286 : }
2287 : }
2288 : }
2289 :
2290 167 : IsAutoSize = false;
2291 167 : if (this->m_HeatOutAirVolFlow == DataSizing::AutoSize) {
2292 110 : IsAutoSize = true;
2293 : }
2294 167 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2295 0 : if (this->m_HeatOutAirVolFlow > 0.0) {
2296 0 : BaseSizer::reportSizerOutput(state,
2297 : this->UnitType,
2298 : this->Name,
2299 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2300 : this->m_HeatOutAirVolFlow);
2301 : }
2302 : } else {
2303 167 : CheckZoneSizing(state, this->UnitType, this->Name);
2304 167 : Real64 HeatOutAirVolFlowDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
2305 167 : if (HeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2306 3 : HeatOutAirVolFlowDes = 0.0;
2307 : }
2308 167 : if (IsAutoSize) {
2309 110 : this->m_HeatOutAirVolFlow = HeatOutAirVolFlowDes;
2310 110 : BaseSizer::reportSizerOutput(
2311 : state, this->UnitType, this->Name, "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]", HeatOutAirVolFlowDes);
2312 : } else {
2313 57 : if (this->m_HeatOutAirVolFlow > 0.0 && HeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2314 47 : Real64 HeatOutAirVolFlowUser = this->m_HeatOutAirVolFlow;
2315 47 : BaseSizer::reportSizerOutput(state,
2316 : this->UnitType,
2317 : this->Name,
2318 : "Design Size Outdoor Air Flow Rate During Heating Operation [m3/s]",
2319 : HeatOutAirVolFlowDes,
2320 : "User-Specified Outdoor Air Flow Rate During Heating Operation [m3/s]",
2321 : HeatOutAirVolFlowUser);
2322 47 : if (state.dataGlobal->DisplayExtraWarnings) {
2323 0 : if ((std::abs(HeatOutAirVolFlowDes - HeatOutAirVolFlowUser) / HeatOutAirVolFlowUser) >
2324 0 : state.dataSize->AutoVsHardSizingThreshold) {
2325 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2326 0 : ShowContinueError(
2327 : state,
2328 0 : format("User-Specified Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]", HeatOutAirVolFlowUser));
2329 0 : ShowContinueError(state,
2330 0 : format("differs from Design Size Outdoor Air Flow Rate During Heating Operation of {:.5R} [m3/s]",
2331 : HeatOutAirVolFlowDes));
2332 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2333 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2334 : }
2335 : }
2336 : }
2337 : }
2338 : }
2339 :
2340 167 : IsAutoSize = false;
2341 167 : if (this->m_NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
2342 110 : IsAutoSize = true;
2343 : }
2344 167 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
2345 0 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0) {
2346 0 : BaseSizer::reportSizerOutput(state,
2347 : this->UnitType,
2348 : this->Name,
2349 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2350 : this->m_NoCoolHeatOutAirVolFlow);
2351 : }
2352 : } else {
2353 167 : CheckZoneSizing(state, this->UnitType, this->Name);
2354 : Real64 NoCoolHeatOutAirVolFlowDes =
2355 167 : min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, this->m_MaxNoCoolHeatAirVolFlow);
2356 167 : if (NoCoolHeatOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
2357 37 : NoCoolHeatOutAirVolFlowDes = 0.0;
2358 : }
2359 167 : if (IsAutoSize) {
2360 110 : this->m_NoCoolHeatOutAirVolFlow = NoCoolHeatOutAirVolFlowDes;
2361 110 : BaseSizer::reportSizerOutput(state,
2362 : this->UnitType,
2363 : this->Name,
2364 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2365 : NoCoolHeatOutAirVolFlowDes);
2366 : } else {
2367 57 : if (this->m_NoCoolHeatOutAirVolFlow > 0.0 && NoCoolHeatOutAirVolFlowDes > 0.0 && SizingDesRunThisZone) {
2368 39 : Real64 NoCoolHeatOutAirVolFlowUser = this->m_NoCoolHeatOutAirVolFlow;
2369 39 : BaseSizer::reportSizerOutput(state,
2370 : this->UnitType,
2371 : this->Name,
2372 : "Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2373 : NoCoolHeatOutAirVolFlowDes,
2374 : "User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
2375 : NoCoolHeatOutAirVolFlowUser);
2376 39 : if (state.dataGlobal->DisplayExtraWarnings) {
2377 0 : if ((std::abs(NoCoolHeatOutAirVolFlowDes - NoCoolHeatOutAirVolFlowUser) / NoCoolHeatOutAirVolFlowUser) >
2378 0 : state.dataSize->AutoVsHardSizingThreshold) {
2379 0 : ShowMessage(state, format("SizePTUnit: Potential issue with equipment sizing for {} {}", this->UnitType, this->Name));
2380 0 : ShowContinueError(state,
2381 0 : format("User-Specified Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2382 : NoCoolHeatOutAirVolFlowUser));
2383 0 : ShowContinueError(
2384 : state,
2385 0 : format("differs from Design Size Outdoor Air Flow Rate When No Cooling or Heating is Needed of {:.5R} [m3/s]",
2386 : NoCoolHeatOutAirVolFlowDes));
2387 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2388 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2389 : }
2390 : }
2391 : }
2392 : }
2393 : }
2394 : }
2395 622 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) PrintFlag = false;
2396 :
2397 622 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2398 197 : if (this->m_AirFlowControl == UseCompFlow::On) {
2399 21 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2400 21 : this->m_NoLoadAirFlowRateRatio = 1.0;
2401 : }
2402 197 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
2403 191 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2404 6 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
2405 6 : if (this->m_AirFlowControl == UseCompFlow::On) {
2406 2 : Real64 airFlowAdjustmentRatio = 1.0;
2407 2 : if (!coolingAirFlowIsAutosized) {
2408 2 : airFlowAdjustmentRatio =
2409 2 : this->m_MaxCoolAirVolFlow /
2410 2 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex)
2411 2 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds);
2412 : }
2413 2 : this->m_MaxNoCoolHeatAirVolFlow =
2414 2 : airFlowAdjustmentRatio * state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1);
2415 : }
2416 : }
2417 6 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2418 3 : if (this->m_AirFlowControl == UseCompFlow::On) {
2419 1 : Real64 airFlowAdjustmentRatio = 1.0;
2420 1 : if (!heatingAirFlowIsAutosized) {
2421 1 : airFlowAdjustmentRatio =
2422 1 : this->m_MaxHeatAirVolFlow /
2423 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex)
2424 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds);
2425 : }
2426 1 : if (this->m_CoolCoilExists) {
2427 1 : this->m_MaxNoCoolHeatAirVolFlow =
2428 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2429 : airFlowAdjustmentRatio *
2430 1 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(1));
2431 : } else {
2432 0 : this->m_MaxNoCoolHeatAirVolFlow =
2433 0 : airFlowAdjustmentRatio *
2434 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(1);
2435 : }
2436 : }
2437 : }
2438 : }
2439 : }
2440 :
2441 : // Change the Volume Flow Rates to Mass Flow Rates
2442 622 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
2443 622 : this->MaxCoolAirMassFlow = this->m_MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
2444 622 : this->MaxHeatAirMassFlow = this->m_MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2445 622 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2446 622 : this->m_CoolOutAirMassFlow = this->m_CoolOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2447 622 : this->m_HeatOutAirMassFlow = this->m_HeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2448 622 : this->m_NoCoolHeatOutAirMassFlow = this->m_NoCoolHeatOutAirVolFlow * state.dataEnvrn->StdRhoAir;
2449 :
2450 : // initialize multi-speed coils
2451 622 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) ||
2452 618 : (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed)) {
2453 14 : if (this->m_NumOfSpeedCooling > 0) {
2454 14 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2455 14 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2456 14 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2457 : }
2458 :
2459 14 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2460 14 : if (MSHPIndex > -1) {
2461 16 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1; --Iter) {
2462 14 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2463 14 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2464 14 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2465 : }
2466 : }
2467 : }
2468 :
2469 14 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2470 : blankString,
2471 14 : this->m_CoolingCoilIndex,
2472 : HVAC::FanOp::Invalid, // Invalid instead of off?
2473 : HVAC::CompressorOp::Off,
2474 : 0.0,
2475 : 1,
2476 : 0.0,
2477 : 0.0,
2478 : 0.0,
2479 : 0.0); // conduct the sizing operation in the VS WSHP
2480 14 : if (this->m_NumOfSpeedCooling != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).NumOfSpeeds) {
2481 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2482 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2483 0 : ShowFatalError(state,
2484 0 : format("Cooling coil = {}: {}",
2485 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).VarSpeedCoilType,
2486 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).Name));
2487 : }
2488 14 : state.dataSize->DXCoolCap = VariableSpeedCoils::GetCoilCapacityVariableSpeed(
2489 14 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
2490 14 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2491 14 : if (this->m_DXHeatingCoil) {
2492 8 : EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2493 : }
2494 :
2495 124 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2496 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2497 110 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2498 160 : this->m_MSCoolingSpeedRatio[Iter] =
2499 80 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2500 80 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedCooling);
2501 80 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * this->m_MSCoolingSpeedRatio[Iter];
2502 80 : this->m_CoolMassFlowRate[Iter] = this->MaxCoolAirMassFlow * this->m_MSCoolingSpeedRatio[Iter];
2503 : } else {
2504 60 : this->m_CoolVolumeFlowRate[Iter] =
2505 30 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex).MSRatedAirVolFlowRate(Iter);
2506 30 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2507 : // this is divided by the system max air flow, not the cooling coil max air flow, doesn't seem correct
2508 30 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2509 : }
2510 : }
2511 :
2512 14 : if (MSHPIndex > -1) {
2513 2 : this->m_MaxNoCoolHeatAirVolFlow =
2514 2 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2515 2 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2516 2 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2517 12 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2518 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2519 : }
2520 :
2521 608 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
2522 : // mine data from heat exchanger assisted cooling coil
2523 : // Get DX heat exchanger assisted cooling coil index
2524 2 : int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilType_Num;
2525 2 : if (childCCType_Num == HVAC::CoilDX_Cooling) {
2526 0 : int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(this->m_CoolingCoilIndex).CoolingCoilIndex;
2527 0 : if (childCCIndex < 0) {
2528 0 : ShowWarningError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
2529 0 : ShowFatalError(state, "No cooling coil = Coil:Cooling:DX found.");
2530 0 : ErrFound = true;
2531 : }
2532 0 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[childCCIndex];
2533 0 : this->m_NumOfSpeedCooling = newCoil.performance.normalMode.speeds.size();
2534 0 : if (this->m_NumOfSpeedCooling > 0) {
2535 0 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2536 0 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2537 0 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2538 : }
2539 :
2540 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2541 0 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2542 0 : if (MSHPIndex > -1) {
2543 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2544 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2545 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2546 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2547 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2548 : }
2549 : }
2550 : }
2551 :
2552 : // TODO: Determine operating mode based on dehumidification stuff, using normalMode for now
2553 0 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2554 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2555 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2556 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2557 : }
2558 :
2559 : // Use discrete/continuous control algorithm regardless of number of speeds
2560 0 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2561 0 : this->m_DiscreteSpeedCoolingCoil = true;
2562 0 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2563 0 : this->m_ContSpeedCoolingCoil = true;
2564 : }
2565 :
2566 0 : newCoil.size(state);
2567 0 : if (MSHPIndex == -1) {
2568 0 : for (Iter = 1; Iter <= this->m_NumOfSpeedCooling; ++Iter) {
2569 0 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2570 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2571 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2572 0 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2573 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2574 : } else {
2575 0 : this->m_MSCoolingSpeedRatio[Iter] =
2576 0 : this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2577 : }
2578 : }
2579 : }
2580 :
2581 0 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2582 0 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2583 0 : if (this->m_HeatPump) EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2584 :
2585 0 : if (MSHPIndex > -1) {
2586 0 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2587 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2588 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2589 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2590 0 : this->m_CoolVolumeFlowRate[Iter] =
2591 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2592 0 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2593 0 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2594 : }
2595 0 : this->m_MaxNoCoolHeatAirVolFlow =
2596 0 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2597 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2598 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2599 0 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2600 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2601 : }
2602 : }
2603 606 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
2604 53 : if (this->m_NumOfSpeedCooling > 0) {
2605 53 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2606 53 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2607 53 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2608 : }
2609 :
2610 : // it feels like we are jamming the rectangular DXCoil into an oval box here
2611 53 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2612 53 : if (MSHPIndex > -1) {
2613 86 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter >= 1;
2614 : --Iter) { // use reverse order since we divide by HeatVolumeFlowRate(max)
2615 66 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2616 62 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2617 62 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2618 : }
2619 : }
2620 : }
2621 :
2622 : // mine capacity from Coil:Cooling:DX object
2623 53 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
2624 : // TODO: Determine operating mode based on dehumdification stuff, using normalMode for now
2625 53 : if (this->m_NumOfSpeedCooling != (int)newCoil.performance.normalMode.speeds.size()) {
2626 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2627 0 : ShowContinueError(state, "Number of cooling speeds does not match coil object.");
2628 0 : ShowFatalError(state, format("Cooling coil = Coil:Cooling:DX: {}", newCoil.name));
2629 : }
2630 :
2631 : // Use discrete/continuous control algorithm regardless of number of speeds
2632 53 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
2633 51 : this->m_DiscreteSpeedCoolingCoil = true;
2634 2 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
2635 2 : this->m_ContSpeedCoolingCoil = true;
2636 : }
2637 :
2638 53 : newCoil.size(state);
2639 53 : if (MSHPIndex == -1) {
2640 : // Gotta loop backwards since we may try to access the last element when there are no fans
2641 82 : for (Iter = this->m_NumOfSpeedCooling; Iter >= 1; --Iter) {
2642 49 : this->m_CoolVolumeFlowRate[Iter] = newCoil.performance.normalMode.speeds[Iter - 1].evap_air_flow_rate;
2643 49 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2644 : // it seems the ratio should reference the actual flow rates, not the fan flow ???
2645 49 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2646 47 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2647 : } else {
2648 2 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_CoolVolumeFlowRate[this->m_NumOfSpeedCooling];
2649 : }
2650 : }
2651 : }
2652 :
2653 53 : state.dataSize->DXCoolCap = newCoil.performance.normalMode.ratedGrossTotalCap;
2654 53 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2655 53 : if (this->m_HeatPump) EqSizing.DesHeatingLoad = state.dataSize->DXCoolCap;
2656 :
2657 53 : if (MSHPIndex > -1) {
2658 86 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2659 66 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2660 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2661 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2662 132 : this->m_CoolVolumeFlowRate[Iter] =
2663 66 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2664 66 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2665 66 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2666 : }
2667 20 : this->m_MaxNoCoolHeatAirVolFlow =
2668 20 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2669 20 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2670 20 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2671 33 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2672 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2673 : }
2674 :
2675 553 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
2676 105 : if (this->m_NumOfSpeedCooling > 0) {
2677 105 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2678 105 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2679 105 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2680 : }
2681 :
2682 : // 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
2683 : // system ran prior to this one)
2684 210 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
2685 210 : EqSizing.CoolingAirVolFlow *
2686 105 : state.dataEnvrn->StdRhoAir; // doesn't matter what this value is since only coil size is needed and CompressorOn = 0 here
2687 105 : DXCoils::SimDXCoilMultiSpeed(state, blankString, 1.0, 1.0, this->m_CoolingCoilIndex, 0, HVAC::FanOp::Invalid, HVAC::CompressorOp::Off);
2688 105 : if (!HardSizeNoDesRun && EqSizing.Capacity) {
2689 : // do nothing, the vars EqSizing.DesCoolingLoad and DataSizing::DXCoolCap are already set earlier and the values could be max of the
2690 : // cooling and heating autosized values. Thus resetting them here to user specified value may not be the design size used else where
2691 : } else {
2692 200 : state.dataSize->DXCoolCap =
2693 100 : DXCoils::GetCoilCapacityByIndexType(state, this->m_CoolingCoilIndex, this->m_CoolingCoilType_Num, ErrFound);
2694 100 : EqSizing.DesCoolingLoad = state.dataSize->DXCoolCap;
2695 : }
2696 105 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2697 :
2698 105 : if (MSHPIndex > -1) {
2699 : // use reverse order since we divide by CoolVolumeFlowRate(max)
2700 117 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2701 79 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2702 7 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2703 7 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2704 158 : this->m_CoolVolumeFlowRate[Iter] =
2705 79 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2706 79 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2707 79 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2708 : }
2709 38 : this->m_MaxNoCoolHeatAirVolFlow =
2710 38 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2711 38 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2712 38 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2713 67 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2714 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2715 : } else {
2716 201 : for (Iter = this->m_NumOfSpeedCooling; Iter > 0; --Iter) {
2717 134 : this->m_CoolVolumeFlowRate[Iter] = this->m_MaxCoolAirVolFlow * Iter / this->m_NumOfSpeedCooling;
2718 134 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2719 134 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2720 : }
2721 67 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2722 67 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2723 : }
2724 448 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
2725 20 : if (this->m_NumOfSpeedCooling > 0) {
2726 1 : if (this->m_CoolVolumeFlowRate.empty()) this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2727 1 : if (this->m_CoolMassFlowRate.empty()) this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
2728 1 : if (this->m_MSCoolingSpeedRatio.empty()) this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
2729 : }
2730 20 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2731 :
2732 20 : if (MSHPIndex > -1) {
2733 5 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling; Iter > 0; --Iter) {
2734 4 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] == DataSizing::AutoSize)
2735 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1] =
2736 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedCooling);
2737 8 : this->m_CoolVolumeFlowRate[Iter] =
2738 4 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].coolingVolFlowRatio[Iter - 1];
2739 4 : this->m_CoolMassFlowRate[Iter] = this->m_CoolVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2740 4 : this->m_MSCoolingSpeedRatio[Iter] = this->m_CoolVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2741 : }
2742 1 : this->m_MaxNoCoolHeatAirVolFlow =
2743 1 : this->m_MaxCoolAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2744 1 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2745 1 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2746 19 : } else if (this->m_CoolVolumeFlowRate.empty()) {
2747 19 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2748 : }
2749 : }
2750 :
2751 622 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2752 609 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2753 13 : if (this->m_NumOfSpeedHeating > 0) {
2754 13 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2755 13 : if (this->m_HeatMassFlowRate.empty()) this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2756 13 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2757 : }
2758 :
2759 13 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2760 :
2761 13 : if (MSHPIndex > -1) {
2762 : // use reverse order since we divide by HeatVolumeFlowRate(max)
2763 51 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2764 38 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2765 26 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint &&
2766 0 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2767 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage)) {
2768 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2769 : } else {
2770 26 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2771 26 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2772 : }
2773 : } else {
2774 12 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
2775 12 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
2776 0 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] < 1.0 &&
2777 0 : this->m_ControlType == UnitarySysCtrlType::Setpoint) {
2778 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2779 0 : ShowContinueError(
2780 0 : state, format("Design specification object = {}", state.dataUnitarySystems->designSpecMSHP[MSHPIndex].name));
2781 0 : ShowContinueError(state,
2782 : "When control type = SetPointBased the outlet air temperature must change with coil capacity, if "
2783 : "air flow also changes outlet air temperature will be relatively constant.");
2784 0 : ShowContinueError(
2785 : state,
2786 0 : format("Speed {} Supply Air Flow Ratio During Heating Operation will be set = 1.0 and the simulation continues",
2787 : Iter));
2788 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] = 1.0;
2789 : }
2790 : }
2791 : }
2792 76 : this->m_HeatVolumeFlowRate[Iter] =
2793 38 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2794 38 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2795 38 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2796 : }
2797 13 : if (this->m_CoolCoilExists) {
2798 13 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2799 13 : this->m_MaxNoCoolHeatAirVolFlow =
2800 13 : min(this->m_MaxNoCoolHeatAirVolFlow,
2801 13 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2802 13 : this->MaxNoCoolHeatAirMassFlow =
2803 13 : min(this->MaxNoCoolHeatAirMassFlow,
2804 13 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2805 13 : this->m_NoLoadAirFlowRateRatio =
2806 13 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2807 : } else {
2808 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2809 : }
2810 0 : } else if (MSHPIndex > -1) {
2811 0 : this->m_MaxNoCoolHeatAirVolFlow =
2812 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2813 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2814 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2815 : } else {
2816 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2817 : }
2818 : }
2819 609 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
2820 605 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
2821 7 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2822 7 : if (MSHPIndex > -1) {
2823 11 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2824 10 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2825 10 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2826 10 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2827 : }
2828 : }
2829 : }
2830 :
2831 7 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2832 : blankString,
2833 7 : this->m_HeatingCoilIndex,
2834 : HVAC::FanOp::Invalid,
2835 : HVAC::CompressorOp::Off,
2836 : 0.0,
2837 : 1,
2838 : 0.0,
2839 : 0.0,
2840 : 0.0,
2841 : 0.0); // conduct the sizing operation in the VS WSHP
2842 :
2843 7 : if (this->m_NumOfSpeedHeating != state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).NumOfSpeeds) {
2844 0 : ShowWarningError(state, format("{}: {} = {}", RoutineName, CompType, CompName));
2845 0 : ShowContinueError(state, "Number of heating speeds does not match coil object.");
2846 0 : ShowFatalError(state,
2847 0 : format("Heating coil = {}: {}",
2848 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).VarSpeedCoilType,
2849 0 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).Name));
2850 : }
2851 :
2852 7 : if (this->m_NumOfSpeedHeating > 0) {
2853 7 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2854 7 : if (this->m_HeatMassFlowRate.empty()) this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2855 7 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2856 : }
2857 :
2858 77 : for (Iter = this->m_NumOfSpeedHeating; Iter >= 1; --Iter) {
2859 : // using only for PTUnit to UnitarySystem conversion for the time being, should use this all the time
2860 70 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
2861 : // SpeedRatio is only used in OnOff fan and should represent the ratio of flow to fan max flow
2862 100 : this->m_MSHeatingSpeedRatio[Iter] =
2863 50 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter) /
2864 50 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(this->m_NumOfSpeedHeating);
2865 50 : this->m_HeatVolumeFlowRate[Iter] = this->m_MaxHeatAirVolFlow * this->m_MSHeatingSpeedRatio[Iter];
2866 50 : this->m_HeatMassFlowRate[Iter] = this->MaxHeatAirMassFlow * this->m_MSHeatingSpeedRatio[Iter];
2867 : } else {
2868 40 : this->m_HeatVolumeFlowRate[Iter] =
2869 20 : state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex).MSRatedAirVolFlowRate(Iter);
2870 20 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2871 20 : if (this->m_DesignFanVolFlowRate > 0.0 && this->m_FanExists) {
2872 : // this is divided by the system max air flow, not the heating coil max air flow
2873 20 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2874 : } else {
2875 : // if there is no fan this doesn't matter? Should calculate SpeedRatio in fan model? and get rid of SpeedRatio variable?
2876 0 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_HeatVolumeFlowRate[this->m_NumOfSpeedHeating];
2877 : }
2878 : }
2879 : }
2880 :
2881 7 : if (this->m_CoolCoilExists && this->m_NumOfSpeedHeating > 0) {
2882 7 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2883 1 : this->m_MaxNoCoolHeatAirVolFlow =
2884 1 : min(this->m_MaxNoCoolHeatAirVolFlow,
2885 1 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2886 1 : this->MaxNoCoolHeatAirMassFlow =
2887 1 : min(this->MaxNoCoolHeatAirMassFlow,
2888 1 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2889 1 : this->m_NoLoadAirFlowRateRatio =
2890 1 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2891 6 : } else if (this->m_CoolVolumeFlowRate.empty() && MSHPIndex > -1) {
2892 0 : this->m_MaxNoCoolHeatAirVolFlow =
2893 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2894 0 : this->MaxNoCoolHeatAirMassFlow =
2895 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2896 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2897 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2898 6 : } else if (!this->m_CoolVolumeFlowRate.empty()) {
2899 : // what the heck is this next line? should be min of min cooling and min heating flow rates?
2900 : // this is calculated above so likely not even needed here, just have to be sure it's always calculated
2901 6 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
2902 6 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
2903 3 : this->m_sysType == SysType::PackagedWSHP) {
2904 4 : if (!this->m_MultiOrVarSpeedCoolCoil && !this->m_MultiOrVarSpeedHeatCoil) {
2905 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
2906 : }
2907 4 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2908 : } else {
2909 : // this should be min of min cooling and min heating flow rates?
2910 2 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
2911 : }
2912 6 : this->m_NoLoadAirFlowRateRatio =
2913 6 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2914 : } else {
2915 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2916 : }
2917 0 : } else if (MSHPIndex > -1) {
2918 0 : this->m_MaxNoCoolHeatAirVolFlow =
2919 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2920 0 : this->MaxNoCoolHeatAirMassFlow = this->m_MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
2921 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2922 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2923 : } else {
2924 0 : this->m_NoLoadAirFlowRateRatio = this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate;
2925 : }
2926 : }
2927 622 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
2928 : // pass air flow rate to zone water coil
2929 9 : if (state.dataSize->CurZoneEqNum > 0) {
2930 7 : WaterCoils::SetCoilDesFlow(state,
2931 7 : HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num),
2932 7 : this->m_HeatingCoilName,
2933 : this->m_MaxHeatAirVolFlow,
2934 7 : state.dataUnitarySystems->initUnitarySystemsErrorsFound);
2935 : }
2936 :
2937 9 : if (this->m_NumOfSpeedHeating > 0) {
2938 1 : if (this->m_HeatVolumeFlowRate.empty()) this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2939 1 : if (this->m_HeatMassFlowRate.empty()) this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
2940 1 : if (this->m_MSHeatingSpeedRatio.empty()) this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
2941 : }
2942 :
2943 9 : MSHPIndex = this->m_DesignSpecMSHPIndex;
2944 9 : if (MSHPIndex > -1) {
2945 5 : for (Iter = state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating; Iter > 0; --Iter) {
2946 4 : if (state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] == DataSizing::AutoSize) {
2947 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1] =
2948 0 : double(Iter) / double(state.dataUnitarySystems->designSpecMSHP[MSHPIndex].numOfSpeedHeating);
2949 : }
2950 8 : this->m_HeatVolumeFlowRate[Iter] =
2951 4 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].heatingVolFlowRatio[Iter - 1];
2952 4 : this->m_HeatMassFlowRate[Iter] = this->m_HeatVolumeFlowRate[Iter] * state.dataEnvrn->StdRhoAir;
2953 4 : this->m_MSHeatingSpeedRatio[Iter] = this->m_HeatVolumeFlowRate[Iter] / this->m_DesignFanVolFlowRate;
2954 : }
2955 1 : if (this->m_CoolCoilExists) {
2956 1 : if (!this->m_CoolVolumeFlowRate.empty() && MSHPIndex > 0) {
2957 0 : this->m_MaxNoCoolHeatAirVolFlow =
2958 0 : min(this->m_MaxNoCoolHeatAirVolFlow,
2959 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2960 0 : this->MaxNoCoolHeatAirMassFlow =
2961 0 : min(this->MaxNoCoolHeatAirMassFlow,
2962 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio);
2963 0 : this->m_NoLoadAirFlowRateRatio =
2964 0 : min(this->m_NoLoadAirFlowRateRatio, this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate);
2965 : } else {
2966 1 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxNoCoolHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
2967 1 : this->MaxNoCoolHeatAirMassFlow = min(this->MaxNoCoolHeatAirMassFlow, this->MaxNoCoolHeatAirMassFlow);
2968 1 : this->m_NoLoadAirFlowRateRatio =
2969 1 : min(this->m_NoLoadAirFlowRateRatio, (this->m_MaxNoCoolHeatAirVolFlow / this->m_DesignFanVolFlowRate));
2970 : }
2971 : } else {
2972 0 : this->m_MaxNoCoolHeatAirVolFlow =
2973 0 : this->m_MaxHeatAirVolFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2974 0 : this->MaxNoCoolHeatAirMassFlow =
2975 0 : this->MaxHeatAirMassFlow * state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2976 0 : this->m_NoLoadAirFlowRateRatio = this->m_MSHeatingSpeedRatio[this->m_NumOfSpeedHeating] *
2977 0 : state.dataUnitarySystems->designSpecMSHP[MSHPIndex].noLoadAirFlowRateRatio;
2978 : }
2979 : }
2980 : }
2981 :
2982 : // Not sure if this may be needed for special cases
2983 622 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow < 0.0) {
2984 0 : if (!state.dataSize->SysSizingRunDone) {
2985 0 : int BranchNum = BranchInputManager::GetAirBranchIndex(state, "AirloopHVAC:UnitarySystem", this->Name);
2986 0 : std::string FanType = "";
2987 0 : std::string m_FanName = ""; // the notation m_ implies member variables, and this is a local
2988 0 : BranchFanFlow = 0.0;
2989 0 : if (BranchNum > 0.0) BranchInputManager::GetBranchFanTypeName(state, BranchNum, FanType, m_FanName, ErrFound);
2990 0 : if (!ErrFound && BranchNum > 0) {
2991 0 : BranchFanFlow = state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate;
2992 : }
2993 0 : if (BranchFanFlow > 0.0) {
2994 0 : this->m_MaxCoolAirVolFlow = BranchFanFlow;
2995 : } else {
2996 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
2997 0 : if (SystemFlow > 0.0) {
2998 0 : this->m_MaxCoolAirVolFlow = SystemFlow;
2999 : } else {
3000 : // what do I do?
3001 : }
3002 : }
3003 0 : }
3004 : }
3005 :
3006 : // why is this here?
3007 622 : this->m_SenLoadLoss = 0.0;
3008 622 : if (this->m_Humidistat) {
3009 25 : this->m_LatLoadLoss = 0.0;
3010 : }
3011 :
3012 622 : switch (this->m_sysType) {
3013 170 : case SysType::PackagedAC:
3014 : case SysType::PackagedHP:
3015 170 : PrintFlag = false;
3016 170 : break;
3017 452 : default:
3018 452 : break;
3019 : }
3020 622 : if (this->m_CoolCoilExists) {
3021 621 : SizingMethod = HVAC::CoolingCapacitySizing;
3022 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3023 621 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
3024 40 : WaterCoils::SimulateWaterCoilComponents(
3025 40 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3026 20 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3027 40 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num)), this->m_CoolingCoilName, ErrFound);
3028 20 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3029 20 : state.dataSize->DataFractionUsedForSizing = 1.0;
3030 20 : SizingMethod = HVAC::AutoCalculateSizing;
3031 20 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3032 601 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
3033 : std::string HXCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(
3034 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3035 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
3036 0 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound, true);
3037 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(
3038 0 : state, blankString, true, HVAC::CompressorOp::On, 1.0, this->m_CoolingCoilIndex, HVAC::FanOp::Cycling, false, 1.0, false);
3039 0 : state.dataSize->DataConstantUsedForSizing =
3040 0 : WaterCoils::GetWaterCoilCapacity(state, Util::makeUPPER(HVAC::cAllCoilTypes(ActualCoolCoilType)), HXCoilName, ErrFound);
3041 0 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3042 0 : state.dataSize->DataFractionUsedForSizing = 1.0;
3043 0 : SizingMethod = HVAC::AutoCalculateSizing;
3044 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3045 601 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
3046 26 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3047 : blankString,
3048 26 : this->m_CoolingCoilIndex,
3049 : this->m_CoolingCoilSensDemand,
3050 : this->m_CoolingCoilLatentDemand,
3051 : HVAC::FanOp::Invalid,
3052 : HVAC::CompressorOp::Off,
3053 : 0.0,
3054 : FirstHVACIteration);
3055 26 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3056 26 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3057 26 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3058 26 : state.dataSize->DataFractionUsedForSizing = 1.0;
3059 26 : SizingMethod = HVAC::AutoCalculateSizing;
3060 26 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3061 26 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP)
3062 0 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3063 : // airflow sizing with multispeed fan
3064 52 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3065 26 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3066 26 : if (this->m_NumOfSpeedCooling > 1) {
3067 2 : int FanIndex = this->m_FanIndex;
3068 6 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
3069 4 : if (this->m_DesignSpecMSHPIndex > -1) {
3070 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] ==
3071 : DataSizing::AutoSize) {
3072 2 : this->m_CoolVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedCooling) * AirFlowRate;
3073 : } else {
3074 0 : this->m_CoolVolumeFlowRate[i] =
3075 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].coolingVolFlowRatio[i] * AirFlowRate;
3076 : }
3077 : } else {
3078 2 : this->m_CoolVolumeFlowRate[i] =
3079 2 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3080 : }
3081 4 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3082 : }
3083 : }
3084 575 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
3085 5 : WaterToAirHeatPump::SimWatertoAirHP(state,
3086 : blankString,
3087 5 : this->m_CoolingCoilIndex,
3088 : this->MaxCoolAirMassFlow,
3089 : this->m_FanOpMode,
3090 : FirstHVACIteration,
3091 5 : this->m_InitHeatPump,
3092 : 0.0,
3093 : 0.0,
3094 : HVAC::CompressorOp::Off,
3095 : 0.0);
3096 10 : state.dataSize->DataConstantUsedForSizing =
3097 5 : WaterToAirHeatPump::GetCoilCapacity(state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3098 5 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3099 5 : state.dataSize->DataFractionUsedForSizing = 1.0;
3100 5 : SizingMethod = HVAC::AutoCalculateSizing;
3101 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
3102 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple)
3103 5 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3104 570 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
3105 4 : PackagedThermalStorageCoil::SimTESCoil(
3106 4 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, 0.0);
3107 4 : PackagedThermalStorageCoil::GetTESCoilCoolingCapacity(
3108 4 : state, this->m_CoolingCoilName, state.dataSize->DataConstantUsedForSizing, ErrFound, CompType);
3109 4 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3110 4 : state.dataSize->DataFractionUsedForSizing = 1.0;
3111 4 : SizingMethod = HVAC::AutoCalculateSizing;
3112 : }
3113 :
3114 621 : TempSize = this->m_DesignCoolingCapacity;
3115 621 : state.dataSize->DataFlowUsedForSizing = this->m_MaxCoolAirVolFlow;
3116 621 : SizingString = "Nominal Cooling Capacity [W]";
3117 621 : bool errorsFound = false;
3118 621 : CoolingCapacitySizer sizerCoolingCapacity;
3119 621 : sizerCoolingCapacity.overrideSizingString(SizingString);
3120 621 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3121 621 : this->m_DesignCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, errorsFound);
3122 621 : state.dataSize->DataConstantUsedForSizing = 0.0;
3123 621 : state.dataSize->DataFractionUsedForSizing = 0.0;
3124 621 : state.dataSize->DataFlowUsedForSizing = 0.0;
3125 621 : }
3126 :
3127 622 : if (this->m_HeatCoilExists) {
3128 311 : SizingMethod = HVAC::HeatingCapacitySizing;
3129 :
3130 : // water coils must report their size to parent objects (or split out sizing routines for water coils so they can be call from here)
3131 311 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
3132 18 : WaterCoils::SimulateWaterCoilComponents(
3133 18 : state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, 1.0);
3134 9 : state.dataSize->DataConstantUsedForSizing = WaterCoils::GetWaterCoilCapacity(
3135 18 : state, Util::makeUPPER(HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)), this->m_HeatingCoilName, ErrFound);
3136 9 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3137 9 : state.dataSize->DataFractionUsedForSizing = 1.0;
3138 9 : SizingMethod = HVAC::AutoCalculateSizing;
3139 9 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3140 302 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
3141 26 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3142 : blankString,
3143 26 : this->m_HeatingCoilIndex,
3144 : this->m_HeatingCoilSensDemand,
3145 : dummy,
3146 : HVAC::FanOp::Invalid, // Invalid instead of off?
3147 : HVAC::CompressorOp::Off,
3148 : 0.0,
3149 : FirstHVACIteration);
3150 26 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3151 26 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3152 26 : EqSizing.DesHeatingLoad = state.dataSize->DataConstantUsedForSizing;
3153 26 : state.dataSize->DataFractionUsedForSizing = 1.0;
3154 26 : SizingMethod = HVAC::AutoCalculateSizing;
3155 26 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
3156 26 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple)
3157 : // adjusted cooling coil capacity
3158 26 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
3159 : blankString,
3160 26 : this->m_CoolingCoilIndex,
3161 : this->m_CoolingCoilSensDemand,
3162 : this->m_CoolingCoilLatentDemand,
3163 : HVAC::FanOp::Invalid, // Invalid instead of off?
3164 : HVAC::CompressorOp::Off,
3165 : 0.0,
3166 : FirstHVACIteration);
3167 26 : state.dataSize->DataConstantUsedForSizing = WaterToAirHeatPumpSimple::GetCoilCapacity(
3168 26 : state, HVAC::cAllCoilTypes(this->m_CoolingCoilType_Num), this->m_CoolingCoilName, ErrFound);
3169 26 : EqSizing.DesCoolingLoad = state.dataSize->DataConstantUsedForSizing;
3170 26 : state.dataSize->DataFractionUsedForSizing = 1.0;
3171 26 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
3172 : // airflow sizing with multispeed fan
3173 52 : Real64 AirFlowRate = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(
3174 26 : state, HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num), this->m_HeatingCoilName, ErrFound);
3175 26 : if (this->m_NumOfSpeedHeating > 1) {
3176 2 : int FanIndex = this->m_FanIndex;
3177 6 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
3178 4 : if (this->m_DesignSpecMSHPIndex > -1) {
3179 2 : if (state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] ==
3180 : DataSizing::AutoSize) {
3181 2 : this->m_HeatVolumeFlowRate[i] = double(i) / double(this->m_NumOfSpeedHeating) * AirFlowRate;
3182 : } else {
3183 0 : this->m_HeatVolumeFlowRate[i] =
3184 0 : state.dataUnitarySystems->designSpecMSHP[this->m_DesignSpecMSHPIndex].heatingVolFlowRatio[i] * AirFlowRate;
3185 : }
3186 : } else {
3187 2 : this->m_HeatVolumeFlowRate[i] =
3188 2 : dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(FanIndex))->massFlowAtSpeed[i - 1] / state.dataEnvrn->StdRhoAir;
3189 : }
3190 4 : this->m_HeatMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
3191 : }
3192 : }
3193 : }
3194 :
3195 311 : TempSize = this->m_DesignHeatingCapacity;
3196 311 : SizingString = "Nominal Heating Capacity [W]";
3197 311 : if (state.dataSize->CurSysNum > 0)
3198 108 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating =
3199 : false; // set to false to allow calculation of parent object heating capacity
3200 311 : bool errorsFound = false;
3201 311 : HeatingCapacitySizer sizerHeatingCapacity;
3202 311 : sizerHeatingCapacity.overrideSizingString(SizingString);
3203 311 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3204 311 : TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3205 311 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) state.dataSize->DXCoolCap = TempSize;
3206 311 : if (state.dataSize->CurSysNum > 0) state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySysSimulating = true;
3207 311 : this->m_DesignHeatingCapacity = TempSize;
3208 311 : state.dataSize->DataConstantUsedForSizing = 0.0;
3209 311 : state.dataSize->DataFractionUsedForSizing = 0.0;
3210 311 : state.dataSize->DataHeatSizeRatio = 1.0;
3211 311 : }
3212 :
3213 622 : if (!HardSizeNoDesRun && (EqSizing.Capacity && EqSizing.DesHeatingLoad > 0.0)) {
3214 : // vars EqSizing.DesHeatingLoad is already set earlier and supplemental heating coil should
3215 : // be sized to design value instead of user specified value if HardSizeNoDesRun is false
3216 53 : state.dataSize->UnitaryHeatCap = EqSizing.DesHeatingLoad;
3217 :
3218 : } else {
3219 569 : state.dataSize->UnitaryHeatCap = this->m_DesignHeatingCapacity;
3220 : }
3221 :
3222 622 : if (this->m_sysType == SysType::PackagedWSHP) {
3223 27 : PrintFlag = true;
3224 : }
3225 :
3226 622 : if ((this->m_HeatCoilExists || this->m_SuppCoilExists) && this->m_ControlType != UnitarySysCtrlType::CCMASHRAE) {
3227 311 : TempSize = this->DesignMaxOutletTemp;
3228 311 : MaxHeaterOutletTempSizer sizerMaxHeaterOutTemp;
3229 311 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3230 55 : PrintFlag = true;
3231 55 : std::string stringOverride = "Maximum Supply Air Temperature from Supplemental Heater [C]";
3232 55 : sizerMaxHeaterOutTemp.overrideSizingString(stringOverride);
3233 55 : }
3234 311 : sizerMaxHeaterOutTemp.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3235 311 : this->DesignMaxOutletTemp = sizerMaxHeaterOutTemp.size(state, TempSize, ErrFound);
3236 311 : }
3237 :
3238 622 : if (this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
3239 55 : PrintFlag = false;
3240 : }
3241 :
3242 622 : if (this->m_SuppCoilExists) {
3243 97 : switch (this->m_sysType) {
3244 55 : case SysType::PackagedWSHP:
3245 : case SysType::PackagedHP:
3246 55 : if (this->m_HVACSizingIndex <= 0) EqSizing.HeatingCapacity = false; // ensure PTHP supplemental heating coil sizes to load
3247 55 : break;
3248 42 : default:
3249 42 : break;
3250 : }
3251 :
3252 97 : TempSize = this->m_DesignSuppHeatingCapacity;
3253 97 : SizingString = "Supplemental Heating Coil Nominal Capacity [W]";
3254 97 : if (TempSize == DataSizing::AutoSize) {
3255 79 : IsAutoSize = true;
3256 79 : if (this->m_sysType == SysType::Unitary) PrintFlag = false;
3257 79 : bool errorsFound = false;
3258 79 : HeatingCapacitySizer sizerHeatingCapacity;
3259 79 : sizerHeatingCapacity.overrideSizingString(SizingString);
3260 79 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3261 79 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3262 79 : }
3263 : // logic here isn't accurate. Replicating temporarily to minimize diffs in AutoSizingLibrary refactor
3264 97 : TempSize = this->m_DesignSuppHeatingCapacity;
3265 :
3266 97 : if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && IsAutoSize) {
3267 2 : state.dataSize->DataConstantUsedForSizing = max(this->m_DesignSuppHeatingCapacity, this->m_DesignCoolingCapacity);
3268 2 : state.dataSize->DataFractionUsedForSizing = 1.0;
3269 2 : TempSize = DataSizing::AutoSize;
3270 : // pass design size to supplemental heater
3271 2 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3272 95 : } else if (this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
3273 4 : state.dataSize->SuppHeatCap = max(this->m_DesignCoolingCapacity, this->m_DesignHeatingCapacity);
3274 : } else {
3275 91 : if (state.dataSize->CurZoneEqNum > 0) {
3276 56 : state.dataSize->SuppHeatCap = saveRawHeatingCapacity;
3277 : } else {
3278 35 : state.dataSize->SuppHeatCap = this->m_DesignHeatingCapacity;
3279 : }
3280 : }
3281 :
3282 97 : if (this->m_OKToPrintSizing &&
3283 97 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater))
3284 42 : PrintFlag = true;
3285 97 : state.dataSize->DataCoilIsSuppHeater = true;
3286 97 : bool errorsFound = false;
3287 97 : HeatingCapacitySizer sizerHeatingCapacity;
3288 97 : sizerHeatingCapacity.overrideSizingString(SizingString);
3289 97 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3290 97 : this->m_DesignSuppHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
3291 97 : state.dataSize->DataConstantUsedForSizing = 0.0;
3292 97 : state.dataSize->DataFractionUsedForSizing = 0.0;
3293 97 : state.dataSize->DataCoilIsSuppHeater = false;
3294 : }
3295 :
3296 : // register plant flow rate. Not sure this has ever been tested.
3297 622 : if (this->m_HeatRecActive) {
3298 0 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->m_HeatRecoveryInletNodeNum, this->m_DesignHRWaterVolumeFlow);
3299 : }
3300 :
3301 : // Set flow rate for unitary system with no fan
3302 622 : if (state.dataSize->CurOASysNum == 0 && state.dataSize->CurZoneEqNum == 0 && this->m_DesignFanVolFlowRate <= 0.0) {
3303 0 : SystemFlow = (AirLoopNum > 0) ? state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).DesignVolFlowRate : 0;
3304 0 : if (SystemFlow > 0.0) {
3305 0 : this->m_DesignFanVolFlowRate = SystemFlow;
3306 : } else {
3307 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow);
3308 : }
3309 0 : this->m_DesignMassFlowRate = this->m_DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
3310 : }
3311 :
3312 : // Moved from InitLoadBasedControl
3313 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
3314 622 : if (this->m_AirLoopEquipment && this->m_ControlType != UnitarySysCtrlType::Setpoint) {
3315 101 : int NumAirLoopZones = 0; // number of zone inlet nodes in an air loop
3316 101 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo)) {
3317 101 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = true;
3318 101 : NumAirLoopZones =
3319 101 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
3320 220 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3321 : // zone inlet nodes for cooling
3322 119 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
3323 119 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
3324 : // the data structure for the zones inlet nodes has not been filled
3325 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3326 : }
3327 : }
3328 : // zone inlet nodes for heating
3329 119 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
3330 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
3331 : // the data structure for the zones inlet nodes has not been filled
3332 0 : state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady = false;
3333 : }
3334 : }
3335 : }
3336 : }
3337 101 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataUnitarySystems->initLoadBasedControlFlowFracFlagReady) {
3338 101 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
3339 220 : for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
3340 119 : int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
3341 119 : SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3342 119 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == this->ControlZoneNum) {
3343 101 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax =
3344 101 : state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
3345 : }
3346 : }
3347 101 : if (SumOfMassFlowRateMax != 0.0) {
3348 101 : if (state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
3349 101 : this->ControlZoneMassFlowFrac =
3350 101 : state.dataUnitarySystems->initLoadBasedControlCntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
3351 : } else {
3352 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3353 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
3354 0 : this->ControlZoneMassFlowFrac = 1.0;
3355 : }
3356 101 : this->m_SmallLoadTolerance = 5.0 / this->ControlZoneMassFlowFrac; // adjust 5W load tolerance by control zone fraction
3357 101 : BaseSizer::reportSizerOutput(state,
3358 : this->UnitType,
3359 : this->Name,
3360 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
3361 : this->ControlZoneMassFlowFrac);
3362 : }
3363 : }
3364 101 : } else {
3365 521 : this->ControlZoneMassFlowFrac = 1.0;
3366 : }
3367 :
3368 : // should only report for those that allow SZVAV inputs, e.g., control type == CCMASHRAE
3369 622 : PrintFlag = true;
3370 :
3371 622 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3372 0 : bool SizingDesRunThisSys = false;
3373 0 : state.dataSize->DataZoneUsedForSizing = this->ControlZoneNum;
3374 0 : CheckThisZoneForSizing(state, state.dataSize->DataZoneUsedForSizing, SizingDesRunThisSys);
3375 :
3376 0 : capacityMultiplier = 0.5; // one-half of design zone load
3377 0 : if (SizingDesRunThisSys) {
3378 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesCoolLoad * capacityMultiplier;
3379 : } else {
3380 0 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignCoolingCapacity * capacityMultiplier;
3381 : }
3382 0 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3383 0 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3384 0 : ASHRAEMinSATCoolingSizer sizerASHRAEMinSATCooling;
3385 0 : std::string stringOverride = "Minimum Supply Air Temperature [C]";
3386 0 : if (state.dataGlobal->isEpJSON) stringOverride = "minimum_supply_air_temperature [C]";
3387 0 : sizerASHRAEMinSATCooling.overrideSizingString(stringOverride);
3388 0 : sizerASHRAEMinSATCooling.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3389 0 : this->DesignMinOutletTemp = sizerASHRAEMinSATCooling.size(state, this->DesignMinOutletTemp, ErrFound);
3390 :
3391 0 : if (SizingDesRunThisSys) {
3392 0 : state.dataSize->DataCapacityUsedForSizing = state.dataSize->FinalZoneSizing(this->ControlZoneNum).DesHeatLoad * capacityMultiplier;
3393 : } else {
3394 0 : state.dataSize->DataCapacityUsedForSizing = this->m_DesignHeatingCapacity * capacityMultiplier;
3395 : }
3396 0 : state.dataSize->DataCapacityUsedForSizing /= this->ControlZoneMassFlowFrac;
3397 0 : state.dataSize->DataFlowUsedForSizing = this->m_MaxNoCoolHeatAirVolFlow;
3398 0 : ASHRAEMaxSATHeatingSizer sizerASHRAEMaxSATHeating;
3399 0 : stringOverride = "Maximum Supply Air Temperature [C]";
3400 0 : if (state.dataGlobal->isEpJSON) stringOverride = "maximum_supply_air_temperature [C]";
3401 0 : sizerASHRAEMaxSATHeating.overrideSizingString(stringOverride);
3402 0 : sizerASHRAEMaxSATHeating.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
3403 0 : this->DesignMaxOutletTemp = sizerASHRAEMaxSATHeating.size(state, this->DesignMaxOutletTemp, ErrFound);
3404 :
3405 0 : state.dataSize->DataCapacityUsedForSizing = 0.0; // reset so other routines don't use this inadvertently
3406 0 : state.dataSize->DataFlowUsedForSizing = 0.0;
3407 0 : state.dataSize->DataZoneUsedForSizing = 0;
3408 :
3409 : // check that MaxNoCoolHeatAirVolFlow is less than both MaxCoolAirVolFlow and MaxHeatAirVolFlow
3410 0 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3411 0 : if (this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxCoolAirVolFlow || this->m_MaxNoCoolHeatAirVolFlow >= this->m_MaxHeatAirVolFlow) {
3412 0 : ShowSevereError(state, format("{} = {}", this->UnitType, this->Name));
3413 0 : ShowContinueError(
3414 : state,
3415 : " For SingleZoneVAV control the No Load Supply Air Flow Rate must be less than both the cooling and heating supply "
3416 : "air flow rates.");
3417 0 : this->m_MaxNoCoolHeatAirVolFlow = min(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow) - 0.01;
3418 0 : ShowContinueError(
3419 : state,
3420 0 : format(" The SingleZoneVAV control No Load Supply Air Flow Rate is reset to {:.5T} and the simulation continues.",
3421 0 : this->m_MaxNoCoolHeatAirVolFlow));
3422 : }
3423 : }
3424 0 : }
3425 :
3426 622 : state.dataUnitarySystems->CoolingLoad = TempCoolingLoad;
3427 622 : state.dataUnitarySystems->HeatingLoad = TempHeatingLoad;
3428 : // if (++NumUnitarySystemsSized == NumUnitarySystem)
3429 : // UnitarySystemNumericFields.deallocate(); // remove temporary array for field names at end of sizing
3430 622 : } // namespace UnitarySystems
3431 :
3432 1244 : void UnitarySys::processInputSpec(EnergyPlusData &state,
3433 : const UnitarySysInputSpec &input_data,
3434 : int sysNum,
3435 : bool &errorsFound,
3436 : bool const ZoneEquipment,
3437 : int const ZoneOAUnitNum)
3438 : {
3439 : static constexpr std::string_view routineName = "UnitarySys::processInputSpec";
3440 :
3441 : using namespace OutputReportPredefined;
3442 :
3443 : static constexpr std::string_view unitarySysHeatPumpPerformanceObjectType("UnitarySystemPerformance:Multispeed");
3444 :
3445 1244 : std::string const &cCurrentModuleObject = input_data.system_type;
3446 : DataLoopNode::ConnectionObjectType objType = static_cast<DataLoopNode::ConnectionObjectType>(
3447 1244 : getEnumValue(BranchNodeConnections::ConnectionObjectTypeNamesUC, Util::makeUPPER(input_data.system_type)));
3448 1244 : std::string const &thisObjectName = input_data.name;
3449 :
3450 1244 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisObjectName};
3451 :
3452 1244 : this->Name = Util::makeUPPER(thisObjectName);
3453 1244 : sysNum = getUnitarySystemIndex(state, thisObjectName);
3454 1244 : this->m_UnitarySysNum = sysNum;
3455 :
3456 1244 : if (ZoneEquipment) {
3457 465 : this->m_IsZoneEquipment = true;
3458 : }
3459 1244 : if (state.dataUnitarySystems->getInputOnceFlag) {
3460 1244 : this->AirInNode = NodeInputManager::GetOnlySingleNode(state,
3461 622 : input_data.air_inlet_node_name,
3462 : errorsFound,
3463 : objType,
3464 : thisObjectName,
3465 : DataLoopNode::NodeFluidType::Air,
3466 : DataLoopNode::ConnectionType::Inlet,
3467 : NodeInputManager::CompFluidStream::Primary,
3468 : DataLoopNode::ObjectIsParent);
3469 : } else {
3470 622 : this->AirInNode = Util::FindItemInList(input_data.air_inlet_node_name, state.dataLoopNodes->NodeID);
3471 : }
3472 :
3473 1244 : if (state.dataUnitarySystems->getInputOnceFlag) {
3474 1244 : this->AirOutNode = NodeInputManager::GetOnlySingleNode(state,
3475 622 : input_data.air_outlet_node_name,
3476 : errorsFound,
3477 : objType,
3478 : thisObjectName,
3479 : DataLoopNode::NodeFluidType::Air,
3480 : DataLoopNode::ConnectionType::Outlet,
3481 : NodeInputManager::CompFluidStream::Primary,
3482 : DataLoopNode::ObjectIsParent);
3483 : } else {
3484 622 : this->AirOutNode = Util::FindItemInList(input_data.air_outlet_node_name, state.dataLoopNodes->NodeID);
3485 : }
3486 :
3487 : // need to read in all information needed to SetupOutputVariable in setupAllOutputVars
3488 : // as soon as all systems are read in, regardless if all information is available, reports will be set up.
3489 : // make sure we have all the information needed to process reports (see IF blocks in setupAllOutputVars).
3490 : // all coil types, which comps exist, control type, heat recovery active, cooling coil index.
3491 1244 : bool errFlag = false;
3492 1244 : bool PrintMessage = false;
3493 :
3494 1244 : if (!input_data.design_specification_multispeed_object_type.empty() && !input_data.design_specification_multispeed_object_name.empty()) {
3495 120 : this->m_DesignSpecMultispeedHPType = input_data.design_specification_multispeed_object_type;
3496 120 : this->m_DesignSpecMultispeedHPName = input_data.design_specification_multispeed_object_name;
3497 120 : DesignSpecMSHP thisDesignSpec;
3498 120 : this->m_CompPointerMSHP = thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, this->m_DesignSpecMultispeedHPName);
3499 120 : this->m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, this->m_DesignSpecMultispeedHPName);
3500 120 : }
3501 :
3502 : // these are needed for call from GetOASysNumHeat(Cool)ingCoils
3503 1244 : this->m_HeatingCoilName = input_data.heating_coil_name;
3504 1244 : this->m_HeatingCoilTypeName = input_data.heating_coil_object_type;
3505 1244 : if (!this->m_HeatingCoilTypeName.empty()) {
3506 622 : this->m_HeatCoilExists = true;
3507 : }
3508 1244 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num == 0) {
3509 311 : if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:VariableSpeed")) {
3510 3 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingAirToAirVariableSpeed;
3511 308 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:DX:MultiSpeed")) {
3512 13 : this->m_HeatingCoilType_Num = HVAC::CoilDX_MultiSpeedHeating;
3513 295 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Water")) {
3514 9 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWater;
3515 9 : if (this->m_DesignSpecMSHPIndex > -1) {
3516 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
3517 1 : if (this->m_NumOfSpeedHeating > 1) {
3518 1 : this->m_MultiSpeedHeatingCoil = true;
3519 1 : this->m_MultiOrVarSpeedHeatCoil = true;
3520 : }
3521 : }
3522 286 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Steam")) {
3523 2 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
3524 284 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:EquationFit")) {
3525 26 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPSimple;
3526 258 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation")) {
3527 5 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHP;
3528 253 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3529 4 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
3530 249 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric:MultiStage")) {
3531 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingElectric_MultiStage;
3532 249 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Gas:MultiStage")) {
3533 0 : this->m_HeatingCoilType_Num = HVAC::Coil_HeatingGas_MultiStage;
3534 420 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Fuel") ||
3535 420 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Electric") ||
3536 290 : Util::SameString(this->m_HeatingCoilTypeName, "Coil:Heating:Desuperheater")) {
3537 208 : this->m_HeatingCoilType_Num =
3538 208 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
3539 41 : } else if (Util::SameString(this->m_HeatingCoilTypeName, "Coil:UserDefined")) {
3540 0 : this->m_HeatingCoilType_Num = HVAC::Coil_UserDefined;
3541 41 : } else if (this->m_HeatCoilExists) {
3542 41 : this->m_HeatingCoilType_Num =
3543 41 : DXCoils::GetCoilTypeNum(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag, PrintMessage);
3544 : }
3545 :
3546 311 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
3547 298 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
3548 298 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
3549 13 : this->m_MultiSpeedHeatingCoil = true;
3550 298 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
3551 294 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
3552 7 : this->m_VarSpeedHeatingCoil = true;
3553 : }
3554 : }
3555 :
3556 1244 : this->m_CoolingCoilName = input_data.cooling_coil_name;
3557 1244 : if (!input_data.cooling_coil_object_type.empty()) { // not required field
3558 1242 : this->m_CoolCoilExists = true;
3559 : }
3560 : // Find the type of coil. do not print message since this may not be the correct coil type.
3561 1244 : errFlag = false;
3562 1244 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num == 0) {
3563 621 : if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:VariableSpeed")) {
3564 10 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
3565 611 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:MultiSpeed")) {
3566 38 : this->m_CoolingCoilType_Num = HVAC::CoilDX_MultiSpeedCooling;
3567 573 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water")) {
3568 20 : this->m_IsDXCoil = false;
3569 20 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3570 20 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWater;
3571 20 : if (this->m_DesignSpecMSHPIndex > -1) {
3572 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3573 1 : if (this->m_NumOfSpeedCooling > 1) {
3574 1 : this->m_DiscreteSpeedCoolingCoil = true;
3575 1 : this->m_MultiOrVarSpeedCoolCoil = true;
3576 : }
3577 : }
3578 553 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:Water:DetailedGeometry")) {
3579 0 : this->m_IsDXCoil = false;
3580 0 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterDetailed;
3581 0 : if (this->m_DesignSpecMSHPIndex > -1) {
3582 0 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
3583 0 : if (this->m_NumOfSpeedCooling > 1) {
3584 0 : this->m_DiscreteSpeedCoolingCoil = true;
3585 0 : this->m_MultiOrVarSpeedCoolCoil = true;
3586 : }
3587 : }
3588 553 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
3589 9 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoStageWHumControl;
3590 544 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
3591 2 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3592 2 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3593 542 : } else if (Util::SameString(input_data.cooling_coil_object_type, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
3594 0 : this->m_IsDXCoil = false;
3595 0 : this->m_CoolingCoilType_Num = HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(
3596 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, PrintMessage);
3597 542 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:EquationFit")) {
3598 26 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPSimple;
3599 516 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation")) {
3600 5 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHP;
3601 511 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit")) {
3602 4 : this->m_CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
3603 507 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed")) {
3604 383 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingSingleSpeed;
3605 124 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:TwoSpeed")) {
3606 67 : this->m_CoolingCoilType_Num = HVAC::CoilDX_CoolingTwoSpeed;
3607 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:UserDefined")) {
3608 0 : this->m_IsDXCoil = false;
3609 0 : this->m_CoolingCoilType_Num = HVAC::Coil_UserDefined;
3610 57 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX:SingleSpeed:ThermalStorage")) {
3611 4 : this->m_CoolingCoilType_Num = HVAC::CoilDX_PackagedThermalStorageCooling;
3612 53 : } else if (Util::SameString(input_data.cooling_coil_object_type, "Coil:Cooling:DX")) { // CoilCoolingDX
3613 53 : this->m_CoolingCoilType_Num = HVAC::CoilDX_Cooling;
3614 53 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
3615 53 : if (this->m_CoolingCoilIndex == -1) {
3616 0 : ShowFatalError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
3617 : } else {
3618 : // set variable speed coil flag as necessary
3619 53 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
3620 53 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
3621 53 : if (this->m_NumOfSpeedCooling > 1) {
3622 36 : if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::DISCRETE) {
3623 35 : this->m_DiscreteSpeedCoolingCoil = true;
3624 1 : } else if (newCoil.performance.capControlMethod == CoilCoolingDXCurveFitPerformance::CapControlMethod::CONTINUOUS) {
3625 1 : this->m_ContSpeedCoolingCoil = true;
3626 : }
3627 36 : this->m_MultiOrVarSpeedCoolCoil = true;
3628 : }
3629 : }
3630 : }
3631 :
3632 621 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
3633 38 : this->m_DiscreteSpeedCoolingCoil = true;
3634 583 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
3635 579 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
3636 14 : this->m_ContSpeedCoolingCoil = true;
3637 : }
3638 : }
3639 :
3640 1244 : if (!input_data.supplemental_heating_coil_object_type.empty()) {
3641 194 : this->m_SuppCoilExists = true;
3642 : }
3643 :
3644 1244 : if (!input_data.supply_fan_object_type.empty() && !input_data.supply_fan_name.empty()) {
3645 650 : this->m_FanExists = true;
3646 : }
3647 :
3648 : constexpr static std::array<std::string_view, static_cast<int>(UnitarySysCtrlType::Num)> UnitarySysCtrlTypeNamesUC = {
3649 : "NONE", "LOAD", "SETPOINT", "SINGLEZONEVAV"};
3650 1244 : this->m_ControlType = static_cast<UnitarySysCtrlType>(getEnumValue(UnitarySysCtrlTypeNamesUC, Util::makeUPPER(input_data.control_type)));
3651 1244 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3652 0 : this->m_ValidASHRAECoolCoil = true;
3653 0 : this->m_ValidASHRAEHeatCoil = true;
3654 : }
3655 :
3656 1244 : this->m_DesignHRWaterVolumeFlow = input_data.design_heat_recovery_water_flow_rate;
3657 1244 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
3658 0 : this->m_HeatRecActive = true;
3659 : }
3660 :
3661 1244 : errFlag = false;
3662 1244 : if (!input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) {
3663 334 : this->OAMixerIndex = MixedAir::GetOAMixerIndex(state, input_data.oa_mixer_name);
3664 334 : ValidateComponent(state, input_data.oa_mixer_type, input_data.oa_mixer_name, errFlag, cCurrentModuleObject);
3665 334 : if (errFlag) {
3666 0 : ShowContinueError(state, format("specified in {} = \"{}\".", cCurrentModuleObject, input_data.oa_mixer_name));
3667 0 : errorsFound = true;
3668 0 : errFlag = false;
3669 : } else {
3670 334 : this->OAMixerExists = true;
3671 : // OANodeNums = outside air mixer node numbers, OANodeNums(4) = outside air mixer mixed air node
3672 334 : Array1D_int OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, input_data.oa_mixer_name, errFlag);
3673 334 : if (errFlag) {
3674 0 : ShowContinueError(state, format("that was specified in {} = {}", cCurrentModuleObject, input_data.oa_mixer_name));
3675 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
3676 0 : errorsFound = true;
3677 0 : errFlag = false;
3678 : } else {
3679 334 : this->m_OAMixerNodes[0] = OANodeNums(1); // inlet
3680 334 : this->m_OAMixerNodes[1] = OANodeNums(2); // relief
3681 334 : this->m_OAMixerNodes[2] = OANodeNums(3); // return
3682 334 : this->m_OAMixerNodes[3] = OANodeNums(4); // mixed
3683 : }
3684 334 : }
3685 1820 : } else if ((input_data.oa_mixer_type.empty() && !input_data.oa_mixer_name.empty()) ||
3686 910 : (!input_data.oa_mixer_type.empty() && input_data.oa_mixer_name.empty())) {
3687 0 : ShowSevereError(state, format("Missing one of {} Outdoor Air Mixer inputs.", cCurrentModuleObject));
3688 0 : ShowContinueError(state, format("..OutdoorAir:Mixer type = {}", input_data.oa_mixer_type));
3689 0 : ShowContinueError(state, format("..OutdoorAir:Mixer name = {}", input_data.oa_mixer_name));
3690 0 : errorsFound = true;
3691 : }
3692 1244 : this->m_HeatConvTol = input_data.heat_conv_tol;
3693 1244 : this->m_CoolConvTol = input_data.cool_conv_tol;
3694 :
3695 : // Early calls to ATMixer don't have enough info to pass GetInput. Need to get the data next time through.
3696 1244 : if (sysNum == -1 || !state.dataZoneEquip->ZoneEquipInputsFilled) {
3697 622 : return;
3698 : }
3699 :
3700 622 : this->m_CoolOutAirVolFlow = input_data.cooling_oa_flow_rate;
3701 622 : this->m_HeatOutAirVolFlow = input_data.heating_oa_flow_rate;
3702 622 : this->m_NoCoolHeatOutAirVolFlow = input_data.no_load_oa_flow_rate;
3703 :
3704 622 : if (ZoneEquipment) {
3705 218 : this->m_OKToPrintSizing = true;
3706 : }
3707 :
3708 622 : this->m_IterationMode.resize(3);
3709 :
3710 622 : std::string loc_m_CoolingSAFMethod = input_data.cooling_supply_air_flow_rate_method;
3711 622 : Real64 loc_m_CoolingSAFMethod_SAFlow = input_data.cooling_supply_air_flow_rate;
3712 622 : Real64 loc_m_CoolingSAFMethod_SAFlowPerFloorArea = input_data.cooling_supply_air_flow_rate_per_floor_area;
3713 622 : Real64 loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.cooling_fraction_of_autosized_cooling_supply_air_flow_rate;
3714 622 : Real64 loc_m_CoolingSAFMethod_FlowPerCoolingCapacity = input_data.cooling_supply_air_flow_rate_per_unit_of_capacity;
3715 622 : std::string loc_m_HeatingSAFMethod = input_data.heating_supply_air_flow_rate_method;
3716 622 : Real64 loc_m_HeatingSAFMethod_SAFlow = input_data.heating_supply_air_flow_rate;
3717 622 : Real64 loc_m_HeatingSAFMethod_SAFlowPerFloorArea = input_data.heating_supply_air_flow_rate_per_floor_area;
3718 622 : Real64 loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.heating_fraction_of_autosized_heating_supply_air_flow_rate;
3719 622 : Real64 loc_m_HeatingSAFMethod_FlowPerHeatingCapacity = input_data.heating_supply_air_flow_rate_per_unit_of_capacity;
3720 622 : std::string loc_m_NoCoolHeatSAFMethod = input_data.no_load_supply_air_flow_rate_method;
3721 622 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlow = input_data.no_load_supply_air_flow_rate;
3722 622 : Real64 loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = input_data.no_load_supply_air_flow_rate_per_floor_area;
3723 622 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow = input_data.no_load_fraction_of_autosized_cooling_supply_air_flow_rate;
3724 622 : Real64 loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = input_data.no_load_fraction_of_autosized_heating_supply_air_flow_rate;
3725 622 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity =
3726 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation;
3727 622 : Real64 loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity =
3728 : input_data.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation;
3729 :
3730 622 : int FanInletNode = 0;
3731 622 : int FanOutletNode = 0;
3732 622 : Real64 FanVolFlowRate = 0.0;
3733 622 : int CoolingCoilInletNode = 0;
3734 622 : int CoolingCoilOutletNode = 0;
3735 622 : int HeatingCoilInletNode = 0;
3736 622 : int HeatingCoilOutletNode = 0;
3737 622 : int SupHeatCoilInletNode = 0;
3738 622 : int SupHeatCoilOutletNode = 0;
3739 :
3740 622 : bool isNotOK = false;
3741 :
3742 622 : if (!input_data.availability_schedule_name.empty()) {
3743 542 : this->m_SysAvailSchedPtr = ScheduleManager::GetScheduleIndex(state, input_data.availability_schedule_name);
3744 542 : if (this->m_SysAvailSchedPtr == 0) {
3745 0 : ShowWarningError(state,
3746 0 : format("getUnitarySystemInputData {}=\"{}\", invalid Availability Schedule Name = {}",
3747 : cCurrentModuleObject,
3748 0 : this->Name,
3749 0 : input_data.availability_schedule_name));
3750 0 : ShowContinueError(state, "Set the default as Always On. Simulation continues.");
3751 0 : this->m_SysAvailSchedPtr = ScheduleManager::ScheduleAlwaysOn;
3752 : }
3753 : } else {
3754 80 : this->m_SysAvailSchedPtr = ScheduleManager::ScheduleAlwaysOn;
3755 : }
3756 :
3757 622 : if (!input_data.controlling_zone_or_thermostat_location.empty()) { // not required field
3758 122 : this->ControlZoneNum = Util::FindItemInList(input_data.controlling_zone_or_thermostat_location, state.dataHeatBal->Zone);
3759 500 : } else if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3760 197 : if (this->m_sysType == SysType::Unitary) {
3761 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3762 0 : ShowContinueError(state, "Controlling Zone or Thermostat Location cannot be blank when Control Type = Load or SingleZoneVAV");
3763 0 : errorsFound = true;
3764 : }
3765 : }
3766 :
3767 : // check that control zone name is valid for load based control
3768 622 : if (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
3769 : // bypass this error for PTUnits
3770 319 : if (this->ControlZoneNum == 0 &&
3771 197 : (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater)) {
3772 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3773 0 : ShowContinueError(state, "When Control Type = Load or SingleZoneVAV");
3774 0 : ShowContinueError(state,
3775 0 : format(" Controlling Zone or Thermostat Location must be a valid zone name, zone name = {}",
3776 0 : input_data.controlling_zone_or_thermostat_location));
3777 0 : errorsFound = true;
3778 : }
3779 : }
3780 :
3781 622 : if (Util::SameString(input_data.dehumidification_control_type, "None")) {
3782 598 : this->m_DehumidControlType_Num = DehumCtrlType::None;
3783 598 : this->m_Humidistat = false;
3784 24 : } else if (Util::SameString(input_data.dehumidification_control_type, "CoolReheat")) {
3785 13 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
3786 13 : this->m_Humidistat = true;
3787 11 : } else if (Util::SameString(input_data.dehumidification_control_type, "Multimode")) {
3788 11 : this->m_DehumidControlType_Num = DehumCtrlType::Multimode;
3789 11 : this->m_Humidistat = true;
3790 : }
3791 622 : if (this->m_Humidistat && this->m_ControlType == UnitarySysCtrlType::Load) {
3792 9 : bool AirNodeFound = false;
3793 42 : for (int HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
3794 33 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3795 9 : AirNodeFound = true;
3796 : }
3797 9 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3798 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3799 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
3800 0 : ShowContinueError(
3801 0 : state, format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3802 0 : errorsFound = true;
3803 : }
3804 : }
3805 :
3806 622 : Real64 TotalFloorAreaOnAirLoop = 0.0;
3807 622 : int AirLoopNumber = 0;
3808 622 : bool AirNodeFound = false;
3809 622 : bool AirLoopFound = false;
3810 622 : bool OASysFound = false;
3811 622 : bool ZoneEquipmentFound = false;
3812 622 : bool ZoneInletNodeFound = false;
3813 :
3814 : // Get AirTerminal mixer data
3815 622 : SingleDuct::GetATMixer(state,
3816 : thisObjectName,
3817 622 : this->m_ATMixerName,
3818 622 : this->m_ATMixerIndex,
3819 622 : this->ATMixerType,
3820 622 : this->m_ATMixerPriNode,
3821 622 : this->m_ATMixerSecNode,
3822 622 : this->ATMixerOutNode,
3823 : this->AirOutNode);
3824 622 : if (this->ATMixerType == HVAC::MixerType::InletSide || this->ATMixerType == HVAC::MixerType::SupplySide) {
3825 34 : this->ATMixerExists = true;
3826 : }
3827 : // check that heat pump doesn't have local outside air and DOA
3828 622 : if (this->ATMixerExists && this->m_OAMixerNodes[0] > 0 &&
3829 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)) {
3830 0 : ShowSevereError(state,
3831 0 : format("{} = \"{}\". System has local as well as central outdoor air specified", cCurrentModuleObject, this->Name));
3832 0 : errorsFound = true;
3833 : }
3834 :
3835 : // if part of ZoneHVAC:OutdoorAirUnit bypass most checks for connection to air loop or OASystem
3836 622 : if (ZoneOAUnitNum > 0) OASysFound = true;
3837 :
3838 622 : if (ZoneEquipment) {
3839 218 : int ControlledZoneNum = 0;
3840 218 : int ZoneExhNum = 0;
3841 218 : bool ZoneExhaustNodeFound = false;
3842 218 : bool InducedNodeFound = false;
3843 :
3844 218 : if (!this->ATMixerExists) {
3845 184 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3846 184 : if (ZoneExhaustNodeFound) {
3847 183 : ZoneEquipmentFound = true;
3848 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3849 : // this should be zoneExhaustNode
3850 183 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum);
3851 183 : this->ControlZoneNum = ControlledZoneNum;
3852 183 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3853 183 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3854 : } else { // find if the inlet node is an induced node from zone plenum
3855 1 : int ZoneInletNum = 0;
3856 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3857 1 : if (ZoneInletNodeFound) {
3858 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3859 : this->AirInNode,
3860 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3861 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3862 1 : if (InducedNodeFound) {
3863 1 : this->m_ZoneInletNode = this->AirOutNode;
3864 1 : ZoneEquipmentFound = true;
3865 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3866 : }
3867 : }
3868 : }
3869 34 : } else if (this->ATMixerType == HVAC::MixerType::InletSide) {
3870 21 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->m_ATMixerSecNode, ControlledZoneNum, ZoneExhNum);
3871 21 : if (ZoneExhaustNodeFound) {
3872 20 : ZoneEquipmentFound = true;
3873 20 : this->m_ZoneInletNode = this->AirOutNode;
3874 20 : this->ControlZoneNum = ControlledZoneNum;
3875 20 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3876 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3877 20 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->AirOutNode, this->ControlZoneNum);
3878 : } else {
3879 1 : int ZoneInletNum = 0;
3880 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->AirOutNode, this->ControlZoneNum, ZoneInletNum);
3881 1 : if (ZoneInletNodeFound) {
3882 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3883 : this->m_ATMixerSecNode,
3884 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3885 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3886 1 : if (InducedNodeFound) {
3887 1 : this->m_ZoneInletNode = this->AirOutNode;
3888 1 : ZoneEquipmentFound = true;
3889 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3890 : }
3891 : }
3892 : }
3893 13 : } else if (this->ATMixerType == HVAC::MixerType::SupplySide) {
3894 13 : ZoneExhaustNodeFound = searchExhaustNodes(state, this->AirInNode, ControlledZoneNum, ZoneExhNum);
3895 13 : if (ZoneExhaustNodeFound) {
3896 12 : ZoneEquipmentFound = true;
3897 12 : this->m_ZoneInletNode = this->ATMixerOutNode;
3898 12 : this->ControlZoneNum = ControlledZoneNum;
3899 12 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3900 : // The Node was found among the exhaust nodes, now check that a matching inlet node exists
3901 12 : ZoneInletNodeFound = searchZoneInletNodesByEquipmentIndex(state, this->ATMixerOutNode, this->ControlZoneNum);
3902 : } else {
3903 1 : int ZoneInletNum = 0;
3904 1 : ZoneInletNodeFound = searchZoneInletNodes(state, this->ATMixerOutNode, this->ControlZoneNum, ZoneInletNum);
3905 1 : if (ZoneInletNodeFound) {
3906 2 : InducedNodeFound = ZonePlenum::ValidateInducedNode(state,
3907 : this->AirInNode,
3908 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).NumReturnNodes,
3909 1 : state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ReturnNode);
3910 1 : if (InducedNodeFound) {
3911 1 : this->m_ZoneInletNode = this->ATMixerOutNode;
3912 1 : ZoneEquipmentFound = true;
3913 1 : this->setSystemParams(state, TotalFloorAreaOnAirLoop, thisObjectName);
3914 : }
3915 : }
3916 : }
3917 : }
3918 218 : if (!ZoneExhaustNodeFound && !InducedNodeFound) {
3919 : // Exhaust Node was not found
3920 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3921 0 : ShowContinueError(state,
3922 0 : format("Incorrect or misspelled Air Inlet Node Name or Exhaust Node Name or Induced Node Name. = {}",
3923 0 : input_data.air_inlet_node_name));
3924 0 : ShowContinueError(
3925 : state,
3926 0 : format("Air Inlet Node {} name does not match any controlled zone exhaust node name. Check ZoneHVAC:EquipmentConnections "
3927 : "object inputs.",
3928 0 : input_data.air_inlet_node_name));
3929 0 : ShowContinueError(state, "or Induced Air Outlet Node Name specified in AirLoopHVAC:ReturnPlenum object.");
3930 0 : errorsFound = true;
3931 218 : } else if (!ZoneInletNodeFound) {
3932 0 : bool ZoneInletNodeExists = false;
3933 0 : int InletControlledZoneNum = 0;
3934 0 : int ZoneInletNum = 0;
3935 0 : ZoneInletNodeExists = searchZoneInletNodes(state, this->AirOutNode, InletControlledZoneNum, ZoneInletNum);
3936 0 : if (!ZoneInletNodeExists) {
3937 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3938 0 : ShowContinueError(state, format("Incorrect or misspelled Air Outlet Node Name = {}", input_data.air_outlet_node_name));
3939 0 : ShowContinueError(state,
3940 : "Node name does not match any controlled zone inlet node name. Check ZoneHVAC:EquipmentConnections "
3941 : "object inputs.");
3942 0 : errorsFound = true;
3943 : }
3944 : }
3945 : } else {
3946 : // check if the UnitarySystem is connected to an air loop
3947 :
3948 : int compIndex;
3949 : int branchIndex;
3950 404 : AirLoopFound = searchTotalComponents(state, this->AirloopEqType, thisObjectName, compIndex, branchIndex, AirLoopNumber);
3951 404 : if (AirLoopFound && (this->ControlZoneNum > 0)) {
3952 : // Find the controlled zone number for the specified thermostat location
3953 101 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
3954 :
3955 : // Determine if system is on air loop served by the thermostat location specified
3956 101 : int ZoneInletNum = 0;
3957 101 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
3958 101 : if (ZoneInletNodeFound) {
3959 101 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
3960 101 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
3961 : }
3962 :
3963 1059 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
3964 958 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3965 101 : AirNodeFound = true;
3966 : }
3967 101 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
3968 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3969 0 : AirNodeFound = true;
3970 : }
3971 101 : if (!AirNodeFound && this->ControlZoneNum > 0) {
3972 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
3973 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
3974 0 : ShowContinueError(
3975 : state,
3976 0 : format("specified Controlling Zone or Thermostat Location name = {}", input_data.controlling_zone_or_thermostat_location));
3977 0 : errorsFound = true;
3978 : }
3979 :
3980 101 : if (this->ControlZoneNum > 0) {
3981 : // Find the controlled zone number for the specified thermostat location
3982 101 : this->NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode;
3983 :
3984 : // Determine if system is on air loop served by the thermostat location specified
3985 101 : ZoneInletNodeFound = searchZoneInletNodeAirLoopNum(state, AirLoopNumber, this->ControlZoneNum, ZoneInletNum);
3986 101 : if (ZoneInletNodeFound) {
3987 101 : this->m_ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).InletNode(ZoneInletNum);
3988 101 : TotalFloorAreaOnAirLoop += state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
3989 : }
3990 :
3991 : // if (this->m_ZoneInletNode == 0) AirLoopFound = false;
3992 1059 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
3993 958 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3994 101 : AirNodeFound = true;
3995 : }
3996 101 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
3997 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != this->ControlZoneNum) continue;
3998 0 : AirNodeFound = true;
3999 : }
4000 101 : if (!AirNodeFound && this->ControlZoneNum > 0) {
4001 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4002 0 : ShowContinueError(state, "Did not find Air Node (Zone with Thermostat or Thermal Comfort Thermostat).");
4003 0 : ShowContinueError(state,
4004 0 : format("specified Controlling Zone or Thermostat Location name = {}",
4005 0 : input_data.controlling_zone_or_thermostat_location));
4006 0 : errorsFound = true;
4007 : }
4008 : }
4009 : }
4010 :
4011 : // check if the UnitarySystem is connected to an outside air system
4012 404 : if (!AirLoopFound && state.dataAirLoop->NumOASystems > 0) {
4013 4 : for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; ++OASysNum) {
4014 2 : for (int OACompNum = 1; OACompNum <= state.dataAirLoop->OutsideAirSys(OASysNum).NumComponents; ++OACompNum) {
4015 4 : if (!Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentName(OACompNum), thisObjectName) ||
4016 2 : !Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ComponentType(OACompNum), cCurrentModuleObject))
4017 0 : continue;
4018 2 : AirLoopNumber = OASysNum;
4019 2 : OASysFound = true;
4020 2 : break;
4021 : }
4022 : }
4023 : }
4024 : }
4025 :
4026 622 : if (AirLoopNumber == 0 && !ZoneEquipmentFound &&
4027 8 : (this->m_ControlType == UnitarySysCtrlType::Load || this->m_ControlType == UnitarySysCtrlType::CCMASHRAE)) {
4028 0 : std::string_view zoneName = input_data.controlling_zone_or_thermostat_location;
4029 0 : if (zoneName.empty() && this->ControlZoneNum > 0) {
4030 0 : zoneName = state.dataHeatBal->Zone(this->ControlZoneNum).Name;
4031 : }
4032 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4033 0 : ShowContinueError(state, "Did not find proper connections for AirLoopHVAC or ZoneHVAC system.");
4034 0 : ShowContinueError(state, format("specified Controlling Zone or Thermostat Location name = {}", zoneName));
4035 0 : if (!AirNodeFound && !ZoneEquipmentFound) {
4036 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4037 0 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
4038 : // ShowContinueError(state, format("specified {} = {}", cAlphaFields(iControlZoneAlphaNum), Alphas(iControlZoneAlphaNum)));
4039 0 : ShowContinueError(state,
4040 : "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
4041 : }
4042 0 : errorsFound = true;
4043 : }
4044 :
4045 622 : if (!AirLoopFound && !ZoneEquipmentFound && !OASysFound) {
4046 : // Unsuccessful attempt to get all input data.
4047 0 : return;
4048 622 : } else if (ZoneEquipmentFound || OASysFound ||
4049 394 : (AirLoopFound && (this->m_ZoneInletNode > 0 || this->m_ControlType == UnitarySysCtrlType::Setpoint))) {
4050 622 : this->m_OKToPrintSizing = true;
4051 622 : this->m_ThisSysInputShouldBeGotten = false;
4052 : }
4053 :
4054 622 : this->m_AvailManagerListName = input_data.avail_manager_list_name;
4055 :
4056 622 : if (!input_data.design_spec_zonehvac_sizing_object_name.empty()) {
4057 0 : this->m_HVACSizingIndex = Util::FindItemInList(input_data.design_spec_zonehvac_sizing_object_name, state.dataSize->ZoneHVACSizing);
4058 0 : if (this->m_HVACSizingIndex == 0) {
4059 0 : ShowSevereError(
4060 : state,
4061 0 : format("Design Specification ZoneHVAC Sizing Object Name = {} not found.", input_data.design_spec_zonehvac_sizing_object_name));
4062 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, this->Name));
4063 0 : errorsFound = true;
4064 : }
4065 : }
4066 :
4067 622 : if (!ZoneEquipment)
4068 1212 : BranchNodeConnections::TestCompSet(state,
4069 : cCurrentModuleObject,
4070 808 : Util::makeUPPER(thisObjectName),
4071 404 : input_data.air_inlet_node_name,
4072 404 : input_data.air_outlet_node_name,
4073 : "Air Nodes");
4074 :
4075 622 : std::string const &loc_fanType = input_data.supply_fan_object_type;
4076 622 : std::string const &loc_m_FanName = input_data.supply_fan_name;
4077 :
4078 622 : if (!loc_m_FanName.empty() && !loc_fanType.empty()) {
4079 325 : this->m_FanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Util::makeUPPER(loc_fanType)));
4080 :
4081 325 : this->m_FanIndex = Fans::GetFanIndex(state, loc_m_FanName);
4082 325 : if (this->m_FanIndex == 0) {
4083 0 : ShowSevereItemNotFound(state, eoh, "fan_name", loc_m_FanName);
4084 0 : errorsFound = true;
4085 : } else {
4086 325 : auto const *fan = state.dataFans->fans(this->m_FanIndex);
4087 325 : FanVolFlowRate = fan->maxAirFlowRate;
4088 325 : if (FanVolFlowRate == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4089 325 : this->m_ActualFanVolFlowRate = FanVolFlowRate;
4090 325 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
4091 325 : FanInletNode = fan->inletNodeNum;
4092 325 : FanOutletNode = fan->outletNodeNum;
4093 325 : this->m_FanAvailSchedPtr = fan->availSchedNum;
4094 : }
4095 :
4096 325 : this->m_FanExists = true;
4097 325 : this->m_FanName = loc_m_FanName;
4098 297 : } else if (!loc_m_FanName.empty() || !loc_fanType.empty()) {
4099 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
4100 0 : ShowContinueError(state, format("Invalid Fan Type or Name: Fan Name = {}, Fan Type = {}", loc_m_FanName, loc_fanType));
4101 0 : errorsFound = true;
4102 : }
4103 :
4104 : // Add fan to component sets array
4105 622 : if (this->m_FanExists && this->m_FanCompNotSetYet) {
4106 650 : BranchNodeConnections::SetUpCompSets(state,
4107 : cCurrentModuleObject,
4108 : thisObjectName,
4109 : loc_fanType,
4110 : loc_m_FanName,
4111 325 : state.dataLoopNodes->NodeID(FanInletNode),
4112 325 : state.dataLoopNodes->NodeID(FanOutletNode));
4113 325 : this->m_FanCompNotSetYet = false;
4114 : }
4115 :
4116 622 : this->m_FanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Util::makeUPPER(input_data.fan_placement)));
4117 622 : if (this->m_FanPlace == HVAC::FanPlace::Invalid && this->m_FanExists) {
4118 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4119 0 : ShowContinueError(state, format("Illegal Fan Placement = {}", input_data.fan_placement));
4120 0 : errorsFound = true;
4121 : }
4122 :
4123 622 : this->m_FanOpModeSchedPtr = ScheduleManager::GetScheduleIndex(state, input_data.supply_air_fan_operating_mode_schedule_name);
4124 622 : if (!input_data.supply_air_fan_operating_mode_schedule_name.empty() && this->m_FanOpModeSchedPtr == 0) {
4125 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4126 0 : ShowContinueError(state, format("Illegal Fan Operating Mode Schedule Name = {}", input_data.supply_air_fan_operating_mode_schedule_name));
4127 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iFanSchedAlphaNum), Alphas(iFanSchedAlphaNum)));
4128 0 : errorsFound = true;
4129 622 : } else if (this->m_FanOpModeSchedPtr == 0) {
4130 303 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4131 : // Fan operating mode must be constant fan so that the coil outlet temp is proportional to PLR
4132 : // Cycling fan always outputs the full load outlet air temp so should not be used with set point based control
4133 302 : this->m_FanOpMode = HVAC::FanOp::Continuous;
4134 : } else {
4135 1 : this->m_FanOpMode = HVAC::FanOp::Cycling;
4136 1 : if (this->m_FanType != HVAC::FanType::OnOff && this->m_FanType != HVAC::FanType::SystemModel && this->m_FanExists) {
4137 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4138 : // ShowContinueError(state, format("{} = {}", cAlphaFields(iFanTypeAlphaNum), Alphas(iFanTypeAlphaNum)));
4139 : // ShowContinueError(state, format("Fan type must be Fan:OnOff of Fan:SystemModel when {} =
4140 : // Blank.", cAlphaFields(iFanSchedAlphaNum)));
4141 0 : ShowContinueError(state,
4142 : "Fan type must be Fan:OnOff or Fan:SystemModel when Supply Air Fan Operating Mode Schedule Name is blank.");
4143 0 : errorsFound = true;
4144 : }
4145 : }
4146 319 : } else if (this->m_FanOpModeSchedPtr > 0 && this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4147 1 : if (!ScheduleManager::CheckScheduleValueMinMax(state, this->m_FanOpModeSchedPtr, ">", 0.0, "<=", 1.0)) {
4148 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4149 0 : ShowContinueError(state, format("For {} = {}", loc_fanType, loc_m_FanName));
4150 0 : ShowContinueError(state, "Fan operating mode must be continuous (fan operating mode schedule values > 0).");
4151 0 : ShowContinueError(
4152 : state,
4153 0 : format("Error found in Supply Air Fan Operating Mode Schedule Name {}", input_data.supply_air_fan_operating_mode_schedule_name));
4154 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
4155 0 : errorsFound = true;
4156 : }
4157 : }
4158 :
4159 : // Check fan's schedule for cycling fan operation IF constant volume fan is used
4160 622 : if (this->m_FanOpModeSchedPtr > 0 && this->m_FanType == HVAC::FanType::Constant) {
4161 3 : if (!ScheduleManager::CheckScheduleValueMinMax(state, this->m_FanOpModeSchedPtr, ">", 0.0, "<=", 1.0)) {
4162 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4163 0 : ShowContinueError(state, "Fan operating mode must be continuous (fan operating mode schedule values > 0).");
4164 0 : ShowContinueError(
4165 : state,
4166 0 : format("Error found in Supply Air Fan Operating Mode Schedule Name {}", input_data.supply_air_fan_operating_mode_schedule_name));
4167 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
4168 0 : errorsFound = true;
4169 : }
4170 : }
4171 :
4172 622 : PrintMessage = true;
4173 : // Get coil data
4174 622 : this->m_HeatingSizingRatio = input_data.dx_heating_coil_sizing_ratio;
4175 622 : int HeatingCoilPLFCurveIndex = 0;
4176 622 : if (!this->m_HeatingCoilTypeName.empty()) {
4177 311 : PrintMessage = false;
4178 : } else {
4179 311 : this->m_ValidASHRAEHeatCoil = false;
4180 : }
4181 :
4182 622 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4183 :
4184 41 : this->m_DXHeatingCoil = true;
4185 :
4186 41 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4187 41 : if (isNotOK) {
4188 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4189 0 : errorsFound = true;
4190 :
4191 : } else { // mine data from DX heating coil
4192 :
4193 : // Get DX heating coil index
4194 41 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4195 41 : if (errFlag) {
4196 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4197 0 : errorsFound = true;
4198 0 : errFlag = false;
4199 : } else {
4200 41 : auto &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4201 41 : this->m_HeatingCoilAvailSchPtr = thisHeatCoil.SchedPtr;
4202 41 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedTotCap(1);
4203 41 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4204 41 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate(1);
4205 41 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4206 41 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4207 41 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4208 41 : thisHeatCoil.HeatSizeRatio = this->m_HeatingSizingRatio;
4209 : }
4210 : }
4211 :
4212 581 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4213 578 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
4214 :
4215 7 : this->m_DXHeatingCoil = true;
4216 :
4217 7 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4218 7 : if (isNotOK) {
4219 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4220 0 : errorsFound = true;
4221 : } else {
4222 7 : this->m_HeatingCoilIndex =
4223 7 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4224 7 : if (errFlag) {
4225 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4226 0 : errorsFound = true;
4227 0 : errFlag = false;
4228 : } else {
4229 7 : auto const &thisHeatCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_HeatingCoilIndex);
4230 7 : this->m_NumOfSpeedHeating = thisHeatCoil.NumOfSpeeds;
4231 7 : this->m_HeatingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
4232 7 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4233 7 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
4234 5 : this->m_RequestAutoSize = true;
4235 : } else {
4236 2 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NumOfSpeeds) /
4237 2 : thisHeatCoil.MSRatedAirVolFlowRate(thisHeatCoil.NormSpedLevel) * thisHeatCoil.RatedAirVolFlowRate;
4238 : }
4239 7 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4240 7 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4241 7 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4242 7 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4243 : }
4244 : }
4245 581 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
4246 13 : this->m_DXHeatingCoil = true;
4247 13 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4248 13 : if (isNotOK) {
4249 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4250 0 : errorsFound = true;
4251 : } else {
4252 13 : DXCoils::GetDXCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, this->m_HeatingCoilTypeName);
4253 13 : if (errFlag) {
4254 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4255 0 : errorsFound = true;
4256 0 : errFlag = false;
4257 : } else {
4258 13 : auto const &thisHeatCoil = state.dataDXCoils->DXCoil(this->m_HeatingCoilIndex);
4259 13 : this->m_HeatingCoilAvailSchPtr = thisHeatCoil.SchedPtr;
4260 13 : this->m_MaxHeatAirVolFlow = thisHeatCoil.MSRatedAirVolFlowRate(1);
4261 13 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4262 13 : HeatingCoilInletNode = thisHeatCoil.AirInNode;
4263 13 : HeatingCoilOutletNode = thisHeatCoil.AirOutNode;
4264 13 : this->m_DesignHeatingCapacity = thisHeatCoil.MSRatedTotCap(thisHeatCoil.NumOfSpeeds);
4265 : }
4266 : }
4267 561 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
4268 561 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
4269 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4270 0 : if (isNotOK) {
4271 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4272 0 : errorsFound = true;
4273 : } else {
4274 0 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4275 0 : if (errFlag) {
4276 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4277 0 : errorsFound = true;
4278 0 : errFlag = false;
4279 : } else {
4280 0 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4281 0 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4282 0 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4283 0 : this->m_HeatingCoilAvailSchPtr = thisHeatCoil.SchedPtr;
4284 0 : this->m_DesignHeatingCapacity = thisHeatCoil.MSNominalCapacity(thisHeatCoil.NumOfStages);
4285 0 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4286 : }
4287 : }
4288 561 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
4289 353 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
4290 208 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4291 208 : if (isNotOK) {
4292 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4293 0 : errorsFound = true;
4294 : } else { // mine data from heating coil
4295 208 : HeatingCoils::GetCoilIndex(state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag);
4296 208 : if (errFlag) {
4297 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4298 0 : errorsFound = true;
4299 0 : errFlag = false;
4300 : } else {
4301 208 : auto const &thisHeatCoil = state.dataHeatingCoils->HeatingCoil(this->m_HeatingCoilIndex);
4302 208 : this->m_DesignHeatingCapacity = thisHeatCoil.NominalCapacity;
4303 208 : if (this->m_DesignHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4304 208 : this->m_HeatingCoilAvailSchPtr = thisHeatCoil.SchedPtr;
4305 208 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4306 208 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4307 208 : HeatingCoilPLFCurveIndex = thisHeatCoil.PLFCurveIndex;
4308 : // These heating coil types do not have an air flow input field
4309 208 : if (this->m_RequestAutoSize) {
4310 204 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4311 : }
4312 : }
4313 : } // IF (IsNotOK) THEN
4314 :
4315 561 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
4316 9 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4317 9 : if (isNotOK) {
4318 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4319 0 : errorsFound = true;
4320 : } else { // mine data from heating coil object
4321 9 : this->m_HeatingCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_HeatingCoilName, errFlag);
4322 9 : if (errFlag) {
4323 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4324 0 : errorsFound = true;
4325 0 : errFlag = false;
4326 : } else {
4327 9 : auto const &thisHeatCoil = state.dataWaterCoils->WaterCoil(this->m_HeatingCoilIndex);
4328 9 : this->m_HeatingCoilAvailSchPtr = thisHeatCoil.SchedPtr;
4329 9 : this->HeatCoilFluidInletNode = thisHeatCoil.WaterInletNodeNum;
4330 9 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxWaterVolFlowRate;
4331 9 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4332 9 : this->m_RequestAutoSize = true;
4333 9 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4334 : }
4335 9 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4336 9 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4337 : }
4338 : }
4339 :
4340 344 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
4341 2 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4342 2 : if (isNotOK) {
4343 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4344 0 : errorsFound = true;
4345 : } else { // mine data from heating coil object
4346 2 : this->m_HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_HeatingCoilName, errFlag);
4347 2 : if (errFlag) {
4348 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4349 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4350 0 : errorsFound = true;
4351 0 : errFlag = false;
4352 : } else {
4353 2 : auto const &thisHeatCoil = state.dataSteamCoils->SteamCoil(this->m_HeatingCoilIndex);
4354 2 : this->m_HeatingCoilAvailSchPtr = thisHeatCoil.SchedPtr;
4355 2 : this->HeatCoilFluidInletNode = thisHeatCoil.SteamInletNodeNum;
4356 2 : this->MaxHeatCoilFluidFlow = thisHeatCoil.MaxSteamVolFlowRate;
4357 2 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
4358 0 : this->m_RequestAutoSize = true;
4359 0 : this->m_DesignHeatingCapacity = DataSizing::AutoSize;
4360 : }
4361 2 : if (this->MaxHeatCoilFluidFlow > 0.0) {
4362 2 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
4363 2 : Real64 TempSteamIn = 100.0;
4364 : Real64 SteamDensity =
4365 2 : FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, "getUnitarySystemInputData");
4366 2 : this->MaxHeatCoilFluidFlow *= SteamDensity;
4367 2 : errFlag = false;
4368 : }
4369 2 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4370 2 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4371 2 : if (this->m_RequestAutoSize) {
4372 2 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
4373 : }
4374 : }
4375 : }
4376 :
4377 342 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
4378 26 : this->m_DXHeatingCoil = true;
4379 26 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4380 26 : if (isNotOK) {
4381 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4382 0 : errorsFound = true;
4383 : } else { // mine data from heating coil object
4384 26 : this->m_HeatingCoilIndex =
4385 26 : WaterToAirHeatPumpSimple::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4386 26 : if (errFlag) {
4387 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4388 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4389 0 : errorsFound = true;
4390 0 : errFlag = false;
4391 : } else {
4392 26 : auto const &thisHeatCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_HeatingCoilIndex);
4393 26 : this->m_HeatingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
4394 26 : this->m_DesignHeatingCapacity = thisHeatCoil.RatedCapHeat;
4395 26 : this->m_MaxHeatAirVolFlow = thisHeatCoil.RatedAirVolFlowRate;
4396 26 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4397 26 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4398 26 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4399 : }
4400 : }
4401 :
4402 316 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
4403 5 : this->m_DXHeatingCoil = true;
4404 5 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4405 5 : if (isNotOK) {
4406 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4407 0 : errorsFound = true;
4408 : } else { // mine data from heating coil object
4409 5 : this->m_HeatingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, errFlag);
4410 5 : if (errFlag) {
4411 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4412 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4413 0 : errorsFound = true;
4414 0 : errFlag = false;
4415 : } else {
4416 5 : auto const &thisHeatCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_HeatingCoilIndex);
4417 5 : this->m_HeatingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
4418 5 : this->m_DesignHeatingCapacity = thisHeatCoil.HeatingCapacity;
4419 5 : HeatingCoilInletNode = thisHeatCoil.AirInletNodeNum;
4420 5 : HeatingCoilOutletNode = thisHeatCoil.AirOutletNodeNum;
4421 : }
4422 : }
4423 :
4424 311 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
4425 0 : ValidateComponent(state, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, isNotOK, cCurrentModuleObject);
4426 0 : if (isNotOK) {
4427 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4428 0 : errorsFound = true;
4429 : } else { // mine data from Heating coil object
4430 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
4431 0 : state, this->m_HeatingCoilName, this->m_HeatingCoilIndex, errFlag, cCurrentModuleObject);
4432 0 : if (errFlag) {
4433 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4434 0 : ShowContinueError(state, format("Illegal Heating Coil Name = {}", this->m_HeatingCoilName));
4435 0 : errorsFound = true;
4436 0 : errFlag = false;
4437 : } else {
4438 0 : auto const &thisHeatCoil = state.dataUserDefinedComponents->UserCoil(this->m_HeatingCoilIndex);
4439 0 : this->m_HeatingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
4440 : // **** How to get this info ****
4441 : // UnitarySystem( UnitarySysNum ).DesignHeatingCapacity =
4442 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
4443 0 : HeatingCoilInletNode = thisHeatCoil.Air(1).InletNodeNum;
4444 0 : HeatingCoilOutletNode = thisHeatCoil.Air(1).OutletNodeNum;
4445 : }
4446 : }
4447 :
4448 311 : } else if (this->m_HeatCoilExists) {
4449 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4450 0 : ShowContinueError(state, format("Illegal Heating Coil Object Type = {}", this->m_HeatingCoilTypeName));
4451 0 : errorsFound = true;
4452 : } // IF (this->m_HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
4453 :
4454 : // coil outlet node set point has priority, IF not exist, then use system outlet node
4455 622 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) this->HeatCtrlNode = this->AirOutNode;
4456 622 : if (SetPointManager::NodeHasSPMCtrlVarType(state, HeatingCoilOutletNode, HVAC::CtrlVarType::Temp)) this->HeatCtrlNode = HeatingCoilOutletNode;
4457 :
4458 622 : this->HeatCoilInletNodeNum = HeatingCoilInletNode;
4459 622 : this->HeatCoilOutletNodeNum = HeatingCoilOutletNode;
4460 :
4461 : // Add heating coil to component sets array
4462 622 : if (this->m_HeatCoilExists && this->m_HeatCompNotSetYet) {
4463 311 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating) {
4464 596 : BranchNodeConnections::SetUpCompSets(state,
4465 : cCurrentModuleObject,
4466 : thisObjectName,
4467 : this->m_HeatingCoilTypeName,
4468 : this->m_HeatingCoilName,
4469 298 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
4470 298 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4471 : } else {
4472 13 : BranchNodeConnections::SetUpCompSets(
4473 : state, cCurrentModuleObject, thisObjectName, this->m_HeatingCoilTypeName, this->m_HeatingCoilName, "UNDEFINED", "UNDEFINED");
4474 : }
4475 311 : this->m_HeatCompNotSetYet = false;
4476 : }
4477 :
4478 : // Get Cooling Coil Information IF available
4479 622 : if (!input_data.cooling_coil_object_type.empty() && !this->m_CoolingCoilName.empty()) {
4480 :
4481 621 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed || this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4482 450 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4483 450 : if (isNotOK) {
4484 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4485 0 : errorsFound = true;
4486 :
4487 : } else { // mine data from DX cooling coil
4488 :
4489 450 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
4490 67 : this->m_NumOfSpeedCooling = 2;
4491 67 : this->m_MultiOrVarSpeedCoolCoil = true;
4492 : } else {
4493 383 : this->m_NumOfSpeedCooling = 1;
4494 383 : this->m_MultiOrVarSpeedCoolCoil = false;
4495 : }
4496 :
4497 : // Get DX cooling coil index
4498 450 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4499 450 : if (isNotOK) {
4500 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4501 0 : errorsFound = true;
4502 : } else {
4503 450 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
4504 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
4505 : }
4506 450 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4507 450 : this->m_CoolingCoilAvailSchPtr = thisCoolCoil.SchedPtr;
4508 450 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(1);
4509 450 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4510 450 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4511 450 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4512 450 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4513 450 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4514 450 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4515 :
4516 450 : if (this->m_FanExists) {
4517 174 : thisCoolCoil.SupplyFanName = this->m_FanName;
4518 174 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4519 174 : thisCoolCoil.supplyFanType = this->m_FanType;
4520 174 : if (this->m_FanType != HVAC::FanType::Invalid) {
4521 174 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
4522 : state,
4523 174 : thisCoolCoil.Name,
4524 174 : thisCoolCoil.DXCoilType,
4525 174 : state.dataFans->fans(thisCoolCoil.SupplyFanIndex)->Name,
4526 : this->m_FanType,
4527 : thisCoolCoil.SupplyFanIndex);
4528 : }
4529 : }
4530 450 : if (this->m_HeatCoilExists) {
4531 174 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4532 174 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4533 174 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4534 174 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4535 174 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4536 174 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4537 28 : this->m_HeatPump = true;
4538 : }
4539 : }
4540 :
4541 : // Push heating coil PLF curve index to DX coil
4542 450 : if (HeatingCoilPLFCurveIndex > 0) {
4543 2 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4544 : }
4545 : }
4546 : } // IF (IsNotOK) THEN
4547 :
4548 621 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
4549 53 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4550 53 : if (isNotOK) {
4551 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4552 0 : errorsFound = true;
4553 :
4554 : } else {
4555 : // // call CoilCoolingDX constructor
4556 53 : this->m_CoolingCoilIndex = CoilCoolingDX::factory(state, this->m_CoolingCoilName);
4557 53 : if (this->m_CoolingCoilIndex == -1) {
4558 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4559 0 : errorsFound = true;
4560 : } else {
4561 :
4562 : // mine data from coil object
4563 : // TODO: Need to check for autosize on these I guess
4564 53 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex];
4565 53 : this->m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4566 53 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4567 53 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4568 53 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4569 53 : this->m_CoolingCoilAvailSchPtr = newCoil.availScheduleIndex;
4570 53 : CoolingCoilInletNode = newCoil.evapInletNodeIndex;
4571 53 : CoolingCoilOutletNode = newCoil.evapOutletNodeIndex;
4572 53 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4573 53 : this->m_NumOfSpeedCooling = (int)newCoil.performance.normalMode.speeds.size();
4574 53 : this->m_MinOATCompressorCooling = newCoil.performance.minOutdoorDrybulb;
4575 53 : newCoil.supplyFanName = this->m_FanName;
4576 53 : newCoil.supplyFanIndex = this->m_FanIndex;
4577 53 : newCoil.supplyFanType = this->m_FanType;
4578 53 : if (newCoil.SubcoolReheatFlag) {
4579 1 : this->m_Humidistat = true;
4580 1 : if (this->m_NumOfSpeedCooling > 1) {
4581 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4582 0 : this->FullLatOutput.resize(this->m_NumOfSpeedCooling + 1);
4583 0 : this->SpeedSHR.resize(this->m_NumOfSpeedCooling + 1);
4584 : }
4585 1 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
4586 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4587 0 : ShowContinueError(state,
4588 : "Setpoint control is not available for SubcoolReheat cooling coil. Load control is forced. "
4589 : "Simulation continues.");
4590 0 : this->m_ControlType = UnitarySysCtrlType::Load;
4591 : }
4592 : }
4593 53 : newCoil.setData(this->m_FanIndex, this->m_FanType, this->m_FanName, this->m_SuppCoilPlantLoc.loopNum);
4594 :
4595 : // Push heating coil PLF curve index to DX coil
4596 : // if ( HeatingCoilPLFCurveIndex > 0 ) {
4597 : // SetDXCoolingCoilData( UnitarySystem( UnitarySysNum ).CoolingCoilIndex, ErrorsFound,
4598 : // HeatingCoilPLFCurveIndex );
4599 : // }
4600 : }
4601 :
4602 53 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > 1) {
4603 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
4604 : }
4605 :
4606 53 : if (this->m_HeatCoilExists) {
4607 51 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4608 51 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4609 51 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4610 51 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4611 51 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4612 44 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4613 19 : this->m_HeatPump = true;
4614 : }
4615 : }
4616 : }
4617 :
4618 118 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
4619 9 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4620 9 : if (isNotOK) {
4621 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4622 0 : errorsFound = true;
4623 :
4624 : } else { // mine data from DX cooling coil
4625 :
4626 : // Get DX cooling coil index
4627 9 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4628 9 : if (isNotOK) {
4629 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4630 0 : errorsFound = true;
4631 : } else {
4632 9 : auto &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4633 9 : this->m_CoolingCoilAvailSchPtr = thisCoolCoil.SchedPtr;
4634 9 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedTotCap(thisCoolCoil.NumCapacityStages);
4635 9 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4636 9 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate(1);
4637 9 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4638 9 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4639 9 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4640 9 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum(1);
4641 :
4642 : // Push heating coil PLF curve index to DX coil
4643 9 : if (HeatingCoilPLFCurveIndex > 0) {
4644 0 : thisCoolCoil.HeatingCoilPLFCurvePTR = HeatingCoilPLFCurveIndex;
4645 : }
4646 :
4647 9 : if (this->m_HeatCoilExists) {
4648 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4649 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4650 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4651 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4652 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4653 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4654 0 : this->m_HeatPump = true;
4655 : }
4656 : }
4657 : }
4658 : } // IF (IsNotOK) THEN
4659 :
4660 109 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
4661 2 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4662 2 : if (isNotOK) {
4663 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4664 0 : errorsFound = true;
4665 :
4666 : } else { // mine data from heat exchanger assisted cooling coil
4667 :
4668 : // Get DX heat exchanger assisted cooling coil index
4669 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, isNotOK);
4670 2 : if (isNotOK) {
4671 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4672 0 : errorsFound = true;
4673 : }
4674 :
4675 : std::string ChildCoolingCoilName =
4676 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4677 : std::string ChildCoolingCoilType =
4678 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK);
4679 2 : if (isNotOK) {
4680 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4681 0 : errorsFound = true;
4682 : }
4683 :
4684 2 : if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
4685 :
4686 0 : int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
4687 0 : if (childCCIndex < 0) {
4688 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4689 0 : errorsFound = true;
4690 : }
4691 :
4692 0 : auto const &newCoil = state.dataCoilCooingDX->coilCoolingDXs[childCCIndex];
4693 0 : this->m_CoolingCoilAvailSchPtr = newCoil.availScheduleIndex;
4694 :
4695 : // thisSys.m_DesignCoolingCapacity = newCoil.performance.normalMode.ratedGrossTotalCap;
4696 : // Get Coil:Cooling:DX coil air flow rate. Later fields will overwrite this IF input field is present
4697 0 : this->m_MaxCoolAirVolFlow = newCoil.performance.normalMode.ratedEvapAirFlowRate;
4698 : // if (thisSys.m_DesignCoolingCapacity == DataSizing::AutoSize) thisSys.m_RequestAutoSize = true;
4699 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4700 :
4701 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4702 0 : this->m_CondenserNodeNum = newCoil.condInletNodeIndex;
4703 :
4704 2 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) {
4705 :
4706 1 : this->m_CoolingCoilAvailSchPtr = DXCoils::GetDXCoilAvailSchPtr(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4707 1 : if (isNotOK) {
4708 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4709 0 : errorsFound = true;
4710 : }
4711 :
4712 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
4713 1 : this->m_MaxCoolAirVolFlow = DXCoils::GetDXCoilAirFlow(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4714 1 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4715 1 : if (errFlag) {
4716 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4717 0 : errFlag = false;
4718 0 : errorsFound = true;
4719 : }
4720 :
4721 : // Get Outdoor condenser node from heat exchanger assisted DX coil object
4722 1 : this->m_CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(
4723 : state,
4724 : "COIL:COOLING:DX:SINGLESPEED",
4725 2 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag),
4726 : errFlag);
4727 :
4728 1 : if (errFlag) {
4729 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4730 0 : errFlag = false;
4731 0 : errorsFound = true;
4732 : }
4733 :
4734 1 : } else if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED")) {
4735 1 : this->m_CoolingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
4736 1 : this->m_MaxCoolAirVolFlow =
4737 1 : VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, ChildCoolingCoilType, ChildCoolingCoilName, errFlag);
4738 1 : if (errFlag) {
4739 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4740 0 : errFlag = false;
4741 0 : errorsFound = true;
4742 : }
4743 1 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, ChildCoolingCoilName, errFlag);
4744 1 : if (errFlag) {
4745 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4746 0 : errFlag = false;
4747 0 : errorsFound = true;
4748 : }
4749 : }
4750 :
4751 : // Get DX cooling coil capacity
4752 2 : this->m_DesignCoolingCapacity =
4753 2 : HVACHXAssistedCoolingCoil::GetCoilCapacity(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4754 2 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4755 2 : if (errFlag) {
4756 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4757 0 : errFlag = false;
4758 0 : errorsFound = true;
4759 : }
4760 :
4761 : // Get the Cooling Coil Nodes
4762 : CoolingCoilInletNode =
4763 2 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4764 : CoolingCoilOutletNode =
4765 2 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4766 2 : if (errFlag) {
4767 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4768 0 : errFlag = false;
4769 0 : errorsFound = true;
4770 : }
4771 :
4772 : // Push heating coil PLF curve index to DX coil
4773 2 : if (HeatingCoilPLFCurveIndex > 0) {
4774 : // get the actual index to the DX cooling coil object
4775 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4776 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4777 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4778 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4779 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4780 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4781 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4782 : }
4783 : // what could we do for VS coil here? odd thing here
4784 : }
4785 :
4786 2 : if (this->m_HeatCoilExists) {
4787 2 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4788 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4789 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4790 2 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4791 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4792 2 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4793 0 : this->m_HeatPump = true;
4794 : }
4795 : }
4796 :
4797 2 : } // IF (IsNotOK) THEN
4798 107 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
4799 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4800 0 : if (isNotOK) {
4801 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4802 0 : errorsFound = true;
4803 :
4804 : } else { // mine data from heat exchanger assisted cooling coil
4805 :
4806 0 : int ActualCoolCoilType = HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(
4807 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag, true);
4808 : std::string HXCoilName =
4809 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4810 :
4811 0 : if (errFlag) {
4812 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4813 0 : errFlag = false;
4814 0 : errorsFound = true;
4815 : }
4816 :
4817 : // Get DX heat exchanger assisted cooling coil index
4818 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag);
4819 0 : if (errFlag) {
4820 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4821 0 : errFlag = false;
4822 0 : errorsFound = true;
4823 : }
4824 :
4825 0 : this->m_CoolingCoilAvailSchPtr =
4826 0 : WaterCoils::GetWaterCoilAvailScheduleIndex(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4827 0 : this->MaxCoolCoilFluidFlow =
4828 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4829 : // Get the Cooling Coil water Inlet Node number
4830 0 : this->CoolCoilFluidInletNode =
4831 0 : WaterCoils::GetCoilWaterInletNode(state, HVAC::cAllCoilTypes(ActualCoolCoilType), HXCoilName, errFlag);
4832 0 : if (errFlag) {
4833 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4834 0 : errFlag = false;
4835 0 : errorsFound = true;
4836 : }
4837 :
4838 : // Get the Cooling Coil Nodes
4839 : CoolingCoilInletNode =
4840 0 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4841 : CoolingCoilOutletNode =
4842 0 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4843 0 : if (errFlag) {
4844 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4845 0 : errFlag = false;
4846 0 : errorsFound = true;
4847 : }
4848 :
4849 0 : this->m_MaxCoolAirVolFlow =
4850 0 : HVACHXAssistedCoolingCoil::GetHXCoilAirFlowRate(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4851 0 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4852 0 : this->m_RequestAutoSize = true;
4853 0 : this->m_DesignCoolingCapacity = DataSizing::AutoSize;
4854 : }
4855 0 : if (errFlag) {
4856 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4857 0 : errFlag = false;
4858 0 : errorsFound = true;
4859 : }
4860 :
4861 0 : this->m_CondenserNodeNum = 0;
4862 :
4863 : // Push heating coil PLF curve index to DX coil
4864 0 : if (HeatingCoilPLFCurveIndex > 0) {
4865 : // get the actual index to the DX cooling coil object
4866 0 : int DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(
4867 0 : state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errorsFound);
4868 0 : this->m_ActualDXCoilIndexForHXAssisted = DXCoilIndex;
4869 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
4870 0 : DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, errorsFound, HeatingCoilPLFCurveIndex);
4871 : }
4872 : // VS coil issue here
4873 : }
4874 :
4875 0 : } // IF (IsNotOK) THEN
4876 107 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
4877 97 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
4878 14 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4879 14 : if (isNotOK) {
4880 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4881 0 : errorsFound = true;
4882 : } else {
4883 14 : this->m_CoolingCoilIndex =
4884 14 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4885 14 : if (errFlag) {
4886 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4887 0 : errorsFound = true;
4888 0 : errFlag = false;
4889 : } else {
4890 14 : auto &thisCoolCoil = state.dataVariableSpeedCoils->VarSpeedCoil(this->m_CoolingCoilIndex);
4891 14 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
4892 14 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
4893 14 : this->m_CondenserNodeNum = thisCoolCoil.CondenserInletNodeNum;
4894 14 : this->m_CoolingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
4895 14 : this->m_NumOfSpeedCooling = thisCoolCoil.NumOfSpeeds;
4896 14 : if (this->m_NumOfSpeedCooling > 1) {
4897 12 : this->m_MultiOrVarSpeedCoolCoil = true;
4898 : }
4899 14 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
4900 14 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4901 14 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
4902 14 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
4903 10 : this->m_RequestAutoSize = true;
4904 : } else {
4905 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NumOfSpeeds) /
4906 4 : thisCoolCoil.MSRatedAirVolFlowRate(thisCoolCoil.NormSpedLevel) *
4907 4 : thisCoolCoil.RatedAirVolFlowRate;
4908 : }
4909 14 : if (this->m_FanExists) { // Set fan info
4910 12 : thisCoolCoil.SupplyFanIndex = this->m_FanIndex;
4911 12 : thisCoolCoil.supplyFanType = this->m_FanType;
4912 12 : thisCoolCoil.SupplyFanName = loc_m_FanName;
4913 : }
4914 : }
4915 : }
4916 :
4917 14 : if (this->m_HeatCoilExists) {
4918 12 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4919 9 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4920 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4921 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4922 5 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4923 4 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4924 8 : this->m_HeatPump = true;
4925 : }
4926 : }
4927 :
4928 107 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
4929 38 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4930 38 : if (isNotOK) {
4931 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4932 0 : errorsFound = true;
4933 : } else {
4934 38 : DXCoils::GetDXCoilIndex(state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, input_data.cooling_coil_object_type);
4935 38 : if (errFlag) {
4936 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4937 0 : errorsFound = true;
4938 0 : errFlag = false;
4939 : } else {
4940 38 : auto const &thisCoolCoil = state.dataDXCoils->DXCoil(this->m_CoolingCoilIndex);
4941 38 : this->m_CoolingCoilAvailSchPtr = thisCoolCoil.SchedPtr;
4942 38 : CoolingCoilInletNode = thisCoolCoil.AirInNode;
4943 38 : CoolingCoilOutletNode = thisCoolCoil.AirOutNode;
4944 38 : this->m_DesignCoolingCapacity = thisCoolCoil.MSRatedTotCap(thisCoolCoil.NumOfSpeeds);
4945 38 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4946 38 : this->m_MaxCoolAirVolFlow = thisCoolCoil.MSRatedAirVolFlowRate(1);
4947 38 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
4948 : }
4949 : }
4950 :
4951 38 : if (this->m_HeatCoilExists) {
4952 38 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
4953 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
4954 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
4955 38 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
4956 38 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
4957 33 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
4958 5 : this->m_HeatPump = true;
4959 : }
4960 : }
4961 :
4962 55 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
4963 :
4964 20 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4965 20 : if (isNotOK) {
4966 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4967 0 : errorsFound = true;
4968 : } else { // mine data from Cooling coil object
4969 20 : this->m_CoolingCoilIndex =
4970 20 : WaterCoils::GetWaterCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
4971 20 : if (errFlag) {
4972 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
4973 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
4974 0 : errorsFound = true;
4975 0 : errFlag = false;
4976 : } else {
4977 20 : auto const &thisCoolCoil = state.dataWaterCoils->WaterCoil(this->m_CoolingCoilIndex);
4978 20 : this->m_CoolingCoilAvailSchPtr = thisCoolCoil.SchedPtr;
4979 20 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater) {
4980 20 : this->m_MaxCoolAirVolFlow = thisCoolCoil.DesAirVolFlowRate;
4981 : }
4982 20 : this->CoolCoilFluidInletNode = thisCoolCoil.WaterInletNodeNum;
4983 20 : this->MaxCoolCoilFluidFlow = thisCoolCoil.MaxWaterVolFlowRate;
4984 20 : if (this->MaxCoolCoilFluidFlow == DataSizing::AutoSize) {
4985 20 : this->m_RequestAutoSize = true;
4986 20 : this->m_DesignCoolingCapacity = DataSizing::AutoSize; // water coils don't have a capacity field, need other logic?
4987 : }
4988 20 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
4989 20 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
4990 : }
4991 : }
4992 55 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
4993 26 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
4994 26 : if (isNotOK) {
4995 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
4996 0 : errorsFound = true;
4997 : } else { // mine data from Cooling coil object
4998 26 : this->m_CoolingCoilIndex =
4999 26 : WaterToAirHeatPumpSimple::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5000 26 : if (errFlag) {
5001 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5002 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5003 0 : errorsFound = true;
5004 0 : errFlag = false;
5005 : } else {
5006 26 : auto const &thisCoolCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(this->m_CoolingCoilIndex);
5007 26 : this->m_CoolingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
5008 26 : this->m_DesignCoolingCapacity = thisCoolCoil.RatedCapCoolTotal;
5009 :
5010 : // this isn't likely to work on getInput calls but is what happened before
5011 26 : int CompanionHeatingCoil = thisCoolCoil.CompanionHeatingCoilNum;
5012 26 : if (CompanionHeatingCoil > 0) {
5013 0 : if (this->m_DesignCoolingCapacity == DataSizing::AutoSize &&
5014 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).WAHPPlantType ==
5015 0 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
5016 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
5017 0 : state.dataSize->DXCoolCap > 0) {
5018 : // Heating coil has not yet been sized, returning the temporary cooling capacity
5019 0 : this->m_DesignCoolingCapacity = state.dataSize->DXCoolCap;
5020 : }
5021 : }
5022 :
5023 : // Get DX coil air flow rate. Later fields will overwrite this IF input field is present
5024 26 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedAirVolFlowRate;
5025 26 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) this->m_RequestAutoSize = true;
5026 26 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5027 26 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5028 : }
5029 : }
5030 :
5031 26 : if (this->m_HeatCoilExists) {
5032 26 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5033 26 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5034 26 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5035 26 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5036 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5037 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5038 26 : this->m_HeatPump = true;
5039 : }
5040 : }
5041 :
5042 9 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
5043 5 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5044 5 : if (isNotOK) {
5045 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5046 0 : errorsFound = true;
5047 : } else { // mine data from Cooling coil object
5048 5 : this->m_CoolingCoilIndex =
5049 5 : WaterToAirHeatPump::GetCoilIndex(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
5050 5 : if (this->m_CoolingCoilIndex == 0) {
5051 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5052 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5053 0 : errorsFound = true;
5054 0 : errFlag = false;
5055 : } else {
5056 5 : auto const &thisCoolCoil = state.dataWaterToAirHeatPump->WatertoAirHP(this->m_CoolingCoilIndex);
5057 5 : this->m_CoolingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
5058 5 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingCapacity;
5059 5 : CoolingCoilInletNode = thisCoolCoil.AirInletNodeNum;
5060 5 : CoolingCoilOutletNode = thisCoolCoil.AirOutletNodeNum;
5061 : }
5062 : }
5063 :
5064 5 : if (this->m_HeatCoilExists) {
5065 5 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed ||
5066 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
5067 5 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP ||
5068 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
5069 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
5070 0 : this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
5071 5 : this->m_HeatPump = true;
5072 : }
5073 : }
5074 :
5075 4 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
5076 0 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5077 0 : if (isNotOK) {
5078 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5079 0 : errorsFound = true;
5080 : } else { // mine data from Cooling coil object
5081 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5082 0 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5083 0 : if (errFlag) {
5084 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5085 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5086 0 : errorsFound = true;
5087 0 : errFlag = false;
5088 : } else {
5089 0 : auto const &thisCoolCoil = state.dataUserDefinedComponents->UserCoil(this->m_CoolingCoilIndex);
5090 0 : this->m_CoolingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
5091 : // **** How to get this info ****
5092 : // UnitarySystem( UnitarySysNum ).DesignCoolingCapacity =
5093 : // GetWtoAHPCoilCapacity(CoolingCoilType, this->m_CoolingCoilName, errFlag );
5094 0 : CoolingCoilInletNode = thisCoolCoil.Air(1).InletNodeNum;
5095 0 : CoolingCoilOutletNode = thisCoolCoil.Air(1).OutletNodeNum;
5096 : }
5097 : }
5098 :
5099 4 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
5100 4 : ValidateComponent(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, isNotOK, cCurrentModuleObject);
5101 4 : if (isNotOK) {
5102 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5103 0 : errorsFound = true;
5104 : } else { // mine data from Cooling coil object
5105 4 : PackagedThermalStorageCoil::GetTESCoilIndex(
5106 4 : state, this->m_CoolingCoilName, this->m_CoolingCoilIndex, errFlag, cCurrentModuleObject);
5107 4 : if (errFlag) {
5108 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5109 0 : ShowContinueError(state, format("Illegal Cooling Coil Name = {}", this->m_CoolingCoilName));
5110 0 : errorsFound = true;
5111 0 : errFlag = false;
5112 : } else {
5113 4 : auto const &thisCoolCoil = state.dataPackagedThermalStorageCoil->TESCoil(this->m_CoolingCoilIndex);
5114 4 : this->m_CoolingCoilAvailSchPtr = ScheduleManager::ScheduleAlwaysOn;
5115 4 : this->m_MaxCoolAirVolFlow = thisCoolCoil.RatedEvapAirVolFlowRate;
5116 4 : if (thisCoolCoil.CoolingOnlyModeIsAvailable) {
5117 4 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingOnlyRatedTotCap;
5118 0 : } else if (thisCoolCoil.CoolingAndChargeModeAvailable) {
5119 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndChargeRatedTotCap;
5120 0 : } else if (thisCoolCoil.CoolingAndDischargeModeAvailable) {
5121 0 : this->m_DesignCoolingCapacity = thisCoolCoil.CoolingAndDischargeRatedTotCap;
5122 : } else {
5123 0 : this->m_DesignCoolingCapacity = 0.0;
5124 : }
5125 4 : CoolingCoilInletNode = thisCoolCoil.EvapAirInletNodeNum;
5126 4 : CoolingCoilOutletNode = thisCoolCoil.EvapAirOutletNodeNum;
5127 : }
5128 : }
5129 :
5130 : } else { // IF(.NOT. lAlphaBlanks(16))THEN
5131 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5132 : // ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iCoolingCoilTypeAlphaNum), Alphas(iCoolingCoilTypeAlphaNum)));
5133 0 : errorsFound = true;
5134 : }
5135 :
5136 621 : if (!input_data.dx_cooling_coil_system_sensor_node_name.empty()) { // used by CoilSystem:Cooling:DX
5137 584 : this->CoolCtrlNode = NodeInputManager::GetOnlySingleNode(state,
5138 292 : input_data.dx_cooling_coil_system_sensor_node_name,
5139 : errFlag,
5140 : objType,
5141 : thisObjectName,
5142 : DataLoopNode::NodeFluidType::Air,
5143 : DataLoopNode::ConnectionType::Sensor,
5144 : NodeInputManager::CompFluidStream::Primary,
5145 : DataLoopNode::ObjectIsParent);
5146 : } else {
5147 329 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) this->CoolCtrlNode = this->AirOutNode;
5148 329 : if (SetPointManager::NodeHasSPMCtrlVarType(state, CoolingCoilOutletNode, HVAC::CtrlVarType::Temp))
5149 43 : this->CoolCtrlNode = CoolingCoilOutletNode;
5150 : }
5151 :
5152 621 : this->CoolCoilInletNodeNum = CoolingCoilInletNode;
5153 621 : this->CoolCoilOutletNodeNum = CoolingCoilOutletNode;
5154 :
5155 : } else {
5156 1 : this->m_ValidASHRAECoolCoil = false;
5157 : }
5158 :
5159 622 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple &&
5160 26 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
5161 26 : if (!input_data.heat_pump_coil_water_flow_mode.empty()) {
5162 25 : this->m_WaterCyclingMode =
5163 25 : static_cast<HVAC::WaterFlow>(getEnumValue(HVAC::waterFlowNamesUC, Util::makeUPPER(input_data.heat_pump_coil_water_flow_mode)));
5164 : } else {
5165 1 : this->m_WaterCyclingMode = HVAC::WaterFlow::Cycling;
5166 : }
5167 26 : WaterToAirHeatPumpSimple::SetSimpleWSHPData(
5168 26 : state, this->m_CoolingCoilIndex, errorsFound, this->m_WaterCyclingMode, _, this->m_HeatingCoilIndex);
5169 : }
5170 :
5171 622 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
5172 4 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
5173 4 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, this->m_HeatingCoilIndex);
5174 : }
5175 :
5176 : // Add cooling coil to component sets array
5177 622 : if (this->m_CoolCoilExists && this->m_CoolCompNotSetYet) {
5178 621 : if (this->m_CoolingCoilType_Num != HVAC::CoilDX_MultiSpeedCooling) {
5179 1166 : BranchNodeConnections::SetUpCompSets(state,
5180 : cCurrentModuleObject,
5181 : thisObjectName,
5182 : input_data.cooling_coil_object_type,
5183 : this->m_CoolingCoilName,
5184 583 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
5185 583 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
5186 : } else {
5187 38 : BranchNodeConnections::SetUpCompSets(state,
5188 : cCurrentModuleObject,
5189 : thisObjectName,
5190 : input_data.cooling_coil_object_type,
5191 : this->m_CoolingCoilName,
5192 : "UNDEFINED",
5193 : "UNDEFINED");
5194 : }
5195 621 : this->m_CoolCompNotSetYet = false;
5196 : }
5197 : // Run as 100% DOAS DX coil
5198 622 : if (!Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5199 617 : this->m_ISHundredPercentDOASDXCoil = false;
5200 : } else {
5201 5 : if (Util::SameString(input_data.use_doas_dx_cooling_coil, "Yes")) {
5202 5 : this->m_ISHundredPercentDOASDXCoil = true;
5203 5 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
5204 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5205 0 : ShowContinueError(state, "Variable DX Cooling Coil is not supported as 100% DOAS DX coil.");
5206 0 : ShowContinueError(state, "Variable DX Cooling Coil resets Use DOAS DX Cooling Coil = No and the simulation continues.");
5207 0 : this->m_ISHundredPercentDOASDXCoil = false;
5208 : }
5209 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "")) {
5210 0 : this->m_ISHundredPercentDOASDXCoil = false;
5211 0 : } else if (Util::SameString(input_data.use_doas_dx_cooling_coil, "No")) {
5212 0 : this->m_ISHundredPercentDOASDXCoil = false;
5213 : }
5214 : }
5215 :
5216 : // considered as as 100% DOAS DX cooling coil
5217 622 : if (this->m_ISHundredPercentDOASDXCoil) {
5218 : // set the system DX Coil application type to the child DX coil
5219 5 : if (!(this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
5220 5 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
5221 5 : DXCoils::SetDXCoilTypeData(state, this->m_CoolingCoilName);
5222 0 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
5223 0 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].setToHundredPercentDOAS();
5224 : }
5225 : }
5226 : // DOAS DX Cooling Coil Leaving Minimum Air Temperature
5227 622 : this->DesignMinOutletTemp = input_data.minimum_supply_air_temperature;
5228 622 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp == DataSizing::AutoSize) {
5229 : // skip error for PTUnits
5230 170 : if (this->m_sysType == SysType::Unitary || this->m_sysType == SysType::CoilCoolingDX || this->m_sysType == SysType::CoilCoolingWater) {
5231 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5232 0 : ShowContinueError(state, "Invalid entry for Minimum Supply Air Temperature = AutoSize.");
5233 0 : ShowContinueError(state, "AutoSizing not allowed when Control Type = Load or Setpoint");
5234 0 : errorsFound = true;
5235 : }
5236 : }
5237 622 : if (this->m_ControlType != UnitarySysCtrlType::CCMASHRAE && this->DesignMinOutletTemp > 7.5) {
5238 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5239 0 : ShowContinueError(state, format("Invalid entry for Minimum Supply Air Temperature = {:.4R}", this->DesignMinOutletTemp));
5240 0 : ShowContinueError(state, "The minimum supply air temperature will be limited to 7.5C and the simulation continues.");
5241 0 : this->DesignMinOutletTemp = 7.5;
5242 : }
5243 :
5244 : // Get Latent Load Control flag
5245 622 : if (!input_data.latent_load_control.empty()) {
5246 622 : if (Util::SameString(input_data.latent_load_control, "SensibleOnlyLoadControl")) {
5247 604 : this->m_RunOnSensibleLoad = true;
5248 604 : this->m_RunOnLatentLoad = false;
5249 18 : } else if (Util::SameString(input_data.latent_load_control, "LatentOnlyLoadControl")) {
5250 0 : this->m_RunOnSensibleLoad = false;
5251 0 : this->m_RunOnLatentLoad = true;
5252 18 : } else if (Util::SameString(input_data.latent_load_control, "LatentOrSensibleLoadControl")) {
5253 9 : this->m_RunOnSensibleLoad = true;
5254 9 : this->m_RunOnLatentLoad = true;
5255 9 : } else if (Util::SameString(input_data.latent_load_control, "LatentWithSensibleLoadControl")) {
5256 9 : this->m_RunOnSensibleLoad = true;
5257 9 : this->m_RunOnLatentLoad = true;
5258 9 : this->m_RunOnLatentOnlyWithSensible = true;
5259 : }
5260 : }
5261 622 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
5262 24 : if (!this->m_RunOnLatentLoad && !this->m_RunOnLatentOnlyWithSensible && this->m_ControlType == UnitarySysCtrlType::Load) {
5263 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5264 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5265 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5266 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5267 0 : ShowContinueError(state, "Humidity/Moisture may not be controlled with these settings.");
5268 : }
5269 : } else {
5270 598 : if ((this->m_RunOnLatentLoad || this->m_RunOnLatentOnlyWithSensible) && this->m_ControlType == UnitarySysCtrlType::Load) {
5271 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5272 0 : ShowContinueError(state, "Inconsistent moisture control inputs.");
5273 0 : ShowContinueError(state, format("Dehumidification Control Type = {}", input_data.dehumidification_control_type));
5274 0 : ShowContinueError(state, format("Latent Load Control = {}", input_data.latent_load_control));
5275 0 : ShowContinueError(state, "Humidity/Moisture will not be controlled with these settings.");
5276 0 : this->m_RunOnLatentLoad = false;
5277 0 : this->m_RunOnLatentOnlyWithSensible = false;
5278 : }
5279 : }
5280 : // Get reheat coil data if humidistat is used
5281 622 : this->m_SuppHeatCoilName = input_data.supplemental_heating_coil_name;
5282 622 : this->m_SuppHeatCoilTypeName = input_data.supplemental_heating_coil_object_type;
5283 :
5284 622 : if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Water")) {
5285 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
5286 622 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Steam")) {
5287 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
5288 1200 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Fuel") ||
5289 1108 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric") ||
5290 1730 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:Electric:MultiStage") ||
5291 1148 : Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:Heating:DesuperHeater")) {
5292 97 : this->m_SuppHeatCoilType_Num =
5293 97 : HeatingCoils::GetHeatingCoilTypeNum(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5294 525 : } else if (Util::SameString(this->m_SuppHeatCoilTypeName, "Coil:UserDefined")) {
5295 0 : this->m_SuppHeatCoilType_Num = HVAC::Coil_UserDefined;
5296 : }
5297 :
5298 622 : if (!this->m_SuppHeatCoilTypeName.empty() && !this->m_SuppHeatCoilName.empty()) {
5299 97 : errFlag = false;
5300 :
5301 97 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric ||
5302 5 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
5303 1 : this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
5304 :
5305 97 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5306 97 : if (isNotOK) {
5307 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5308 0 : errorsFound = true;
5309 :
5310 : } else { // mine data from reheat coil
5311 97 : this->m_SuppHeatCoilIndex =
5312 97 : HeatingCoils::GetHeatingCoilIndex(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, errFlag);
5313 97 : if (errFlag) {
5314 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5315 0 : errorsFound = true;
5316 0 : errFlag = false;
5317 : } else {
5318 97 : auto const &thisSuppCoil = state.dataHeatingCoils->HeatingCoil(this->m_SuppHeatCoilIndex);
5319 97 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
5320 4 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.MSNominalCapacity(thisSuppCoil.NumOfStages);
5321 4 : this->m_NumOfSpeedSuppHeating = thisSuppCoil.NumOfStages;
5322 : } else {
5323 93 : this->m_DesignSuppHeatingCapacity = thisSuppCoil.NominalCapacity;
5324 : }
5325 97 : if (this->m_DesignSuppHeatingCapacity == DataSizing::AutoSize) this->m_RequestAutoSize = true;
5326 97 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5327 97 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5328 : }
5329 : } // IF (IsNotOK) THEN
5330 :
5331 97 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5332 97 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5333 :
5334 97 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
5335 :
5336 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5337 0 : if (isNotOK) {
5338 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5339 0 : errorsFound = true;
5340 : } else { // mine data from heating coil object
5341 0 : this->m_SuppHeatCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", this->m_SuppHeatCoilName, errFlag);
5342 0 : if (errFlag) {
5343 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5344 0 : errorsFound = true;
5345 0 : errFlag = false;
5346 : } else {
5347 0 : auto const &thisSuppCoil = state.dataWaterCoils->WaterCoil(this->m_SuppHeatCoilIndex);
5348 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.WaterInletNodeNum;
5349 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxWaterVolFlowRate;
5350 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5351 0 : this->m_RequestAutoSize = true;
5352 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize;
5353 : }
5354 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5355 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5356 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5357 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5358 : }
5359 : }
5360 :
5361 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
5362 :
5363 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5364 0 : if (isNotOK) {
5365 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5366 0 : errorsFound = true;
5367 : } else { // mine data from heating coil object
5368 0 : this->m_SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", this->m_SuppHeatCoilName, errFlag);
5369 0 : if (errFlag) {
5370 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5371 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5372 0 : errorsFound = true;
5373 0 : errFlag = false;
5374 : } else {
5375 0 : auto const &thisSuppCoil = state.dataSteamCoils->SteamCoil(this->m_SuppHeatCoilIndex);
5376 0 : this->m_SuppCoilFluidInletNode = thisSuppCoil.SteamInletNodeNum;
5377 0 : this->m_MaxSuppCoilFluidFlow = thisSuppCoil.MaxSteamVolFlowRate;
5378 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5379 0 : this->m_RequestAutoSize = true;
5380 0 : this->m_DesignSuppHeatingCapacity = DataSizing::AutoSize; // not sure if steam coil needs this
5381 : }
5382 0 : if (this->m_MaxSuppCoilFluidFlow > 0.0) {
5383 0 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
5384 0 : Real64 TempSteamIn = 100.0;
5385 0 : Real64 SteamDensity = FluidProperties::GetSatDensityRefrig(
5386 : state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, "getUnitarySystemInputData");
5387 0 : this->m_MaxSuppCoilFluidFlow = this->m_MaxSuppCoilFluidFlow * SteamDensity;
5388 : }
5389 0 : SupHeatCoilInletNode = thisSuppCoil.AirInletNodeNum;
5390 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5391 0 : SupHeatCoilOutletNode = thisSuppCoil.AirOutletNodeNum;
5392 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5393 : }
5394 : }
5395 :
5396 0 : } else if (this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
5397 0 : ValidateComponent(state, this->m_SuppHeatCoilTypeName, this->m_SuppHeatCoilName, isNotOK, cCurrentModuleObject);
5398 0 : if (isNotOK) {
5399 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
5400 0 : errorsFound = true;
5401 : } else { // mine data from Heating coil object
5402 0 : UserDefinedComponents::GetUserDefinedCoilIndex(
5403 0 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilIndex, errFlag, cCurrentModuleObject);
5404 0 : if (errFlag) {
5405 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5406 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Name = {}", this->m_SuppHeatCoilName));
5407 0 : errorsFound = true;
5408 0 : errFlag = false;
5409 : } else {
5410 0 : auto const &thisSuppCoil = state.dataUserDefinedComponents->UserCoil(this->m_SuppHeatCoilIndex);
5411 0 : SupHeatCoilInletNode = thisSuppCoil.Air(1).InletNodeNum;
5412 0 : this->m_SuppCoilAirInletNode = SupHeatCoilInletNode;
5413 0 : SupHeatCoilOutletNode = thisSuppCoil.Air(1).OutletNodeNum;
5414 0 : this->SuppCoilOutletNodeNum = SupHeatCoilOutletNode;
5415 : }
5416 : }
5417 :
5418 : } else { // Illegal reheating coil type
5419 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5420 0 : ShowContinueError(state, format("Illegal Supplemental Heating Coil Type = {}", this->m_SuppHeatCoilTypeName));
5421 0 : errorsFound = true;
5422 : } // IF (this->SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
5423 :
5424 : } // IF(.NOT. lAlphaBlanks(iSuppHeatCoilTypeAlphaNum))THEN
5425 :
5426 622 : if (SetPointManager::NodeHasSPMCtrlVarType(state, this->AirOutNode, HVAC::CtrlVarType::Temp)) this->SuppCtrlNode = this->AirOutNode;
5427 622 : if (SetPointManager::NodeHasSPMCtrlVarType(state, SupHeatCoilOutletNode, HVAC::CtrlVarType::Temp)) this->SuppCtrlNode = SupHeatCoilOutletNode;
5428 :
5429 : // Add supplemental heating coil to component sets array
5430 622 : if (this->m_SuppCoilExists && this->m_SuppCompNotSetYet) {
5431 194 : BranchNodeConnections::SetUpCompSets(state,
5432 : cCurrentModuleObject,
5433 : thisObjectName,
5434 : this->m_SuppHeatCoilTypeName,
5435 : this->m_SuppHeatCoilName,
5436 97 : state.dataLoopNodes->NodeID(SupHeatCoilInletNode),
5437 97 : state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
5438 97 : this->m_SuppCompNotSetYet = false;
5439 : }
5440 :
5441 622 : if (this->OAMixerExists) {
5442 : // Set up component set for OA mixer - use OA node and Mixed air node
5443 334 : BranchNodeConnections::SetUpCompSets(state,
5444 : this->UnitType,
5445 : this->Name,
5446 : input_data.oa_mixer_type,
5447 : input_data.oa_mixer_name,
5448 167 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[0]),
5449 167 : state.dataLoopNodes->NodeID(this->m_OAMixerNodes[3]));
5450 : }
5451 :
5452 : // set fan info for supplemental heating coils
5453 622 : if (this->m_SuppCoilExists && this->m_FanExists) {
5454 97 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
5455 97 : state, this->m_SuppHeatCoilName, this->m_SuppHeatCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
5456 : }
5457 :
5458 : // Users may not provide SA flow input fields (below) and leave them blank. Check if other coil is AutoSized first to
5459 : // alleviate input requirements. check if coil has no air flow input (VolFlow = 0) and other coil isDataSizing::AutoSized. If so,
5460 : // use AutoSize for coil with 0 air flow rate. This means that the coils MUST mine the air flow rate if it exists
5461 622 : if (this->m_CoolCoilExists && this->m_HeatCoilExists) {
5462 310 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize && this->m_MaxHeatAirVolFlow == 0 && loc_m_HeatingSAFMethod == "") {
5463 0 : this->m_MaxHeatAirVolFlow = DataSizing::AutoSize;
5464 310 : } else if (this->m_MaxCoolAirVolFlow == 0 && this->m_MaxHeatAirVolFlow == DataSizing::AutoSize && loc_m_CoolingSAFMethod == "") {
5465 0 : this->m_MaxCoolAirVolFlow = DataSizing::AutoSize;
5466 : }
5467 : }
5468 :
5469 : // translate DesignSpecification:ZoneHVAC:Sizing inputs
5470 : // UnitarySystem already has air flow scalable sizing, update locals
5471 : // UnitarySystem does not have capacity sizing, set inputs accordingly
5472 622 : if (this->m_HVACSizingIndex > 0) {
5473 0 : int zoneHVACIndex = this->m_HVACSizingIndex;
5474 0 : auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(zoneHVACIndex);
5475 0 : switch (zoneHVACSizing.CoolingSAFMethod) {
5476 0 : case DataSizing::None:
5477 0 : break; // do nothing?
5478 0 : case DataSizing::SupplyAirFlowRate:
5479 0 : loc_m_CoolingSAFMethod = "SupplyAirFlowRate";
5480 0 : loc_m_CoolingSAFMethod_SAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5481 0 : break;
5482 0 : case DataSizing::FlowPerFloorArea:
5483 0 : loc_m_CoolingSAFMethod = "FlowPerFloorArea";
5484 0 : loc_m_CoolingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxCoolAirVolFlow;
5485 0 : break;
5486 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5487 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5488 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5489 0 : break;
5490 0 : case DataSizing::FlowPerCoolingCapacity:
5491 0 : loc_m_CoolingSAFMethod = "FractionOfAutosizedCoolingValue";
5492 0 : loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow = zoneHVACSizing.MaxCoolAirVolFlow;
5493 0 : break;
5494 0 : default:
5495 : assert(true);
5496 : }
5497 :
5498 0 : switch (zoneHVACSizing.HeatingSAFMethod) {
5499 0 : case DataSizing::None:
5500 0 : break; // do nothing?
5501 0 : case DataSizing::SupplyAirFlowRate:
5502 0 : loc_m_HeatingSAFMethod = "SupplyAirFlowRate";
5503 0 : loc_m_HeatingSAFMethod_SAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5504 0 : break;
5505 0 : case DataSizing::FlowPerFloorArea:
5506 0 : loc_m_HeatingSAFMethod = "FlowPerFloorArea";
5507 0 : loc_m_HeatingSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxHeatAirVolFlow;
5508 0 : break;
5509 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5510 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5511 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5512 0 : break;
5513 0 : case DataSizing::FlowPerHeatingCapacity:
5514 0 : loc_m_HeatingSAFMethod = "FractionOfAutosizedHeatingValue";
5515 0 : loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxHeatAirVolFlow;
5516 0 : break;
5517 0 : default:
5518 : assert(true);
5519 : }
5520 :
5521 0 : switch (zoneHVACSizing.NoCoolHeatSAFMethod) {
5522 0 : case DataSizing::None:
5523 0 : break; // do nothing?
5524 0 : case DataSizing::SupplyAirFlowRate:
5525 0 : loc_m_NoCoolHeatSAFMethod = "SupplyAirFlowRate";
5526 0 : loc_m_NoCoolHeatSAFMethod_SAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5527 0 : break;
5528 0 : case DataSizing::FlowPerFloorArea:
5529 0 : loc_m_NoCoolHeatSAFMethod = "FlowPerFloorArea";
5530 0 : loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5531 0 : break;
5532 0 : case DataSizing::FractionOfAutosizedCoolingAirflow:
5533 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5534 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5535 0 : break;
5536 0 : case DataSizing::FractionOfAutosizedHeatingAirflow:
5537 0 : loc_m_NoCoolHeatSAFMethod = "FractionOfAutosizedHeatingValue";
5538 0 : loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow = zoneHVACSizing.MaxNoCoolHeatAirVolFlow;
5539 0 : break;
5540 0 : default:
5541 : assert(true);
5542 : }
5543 :
5544 0 : switch (zoneHVACSizing.CoolingCapMethod) {
5545 0 : case DataSizing::CoolingDesignCapacity:
5546 0 : this->m_CoolingCapMethod = DataSizing::CoolingDesignCapacity;
5547 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5548 0 : break;
5549 0 : case DataSizing::CapacityPerFloorArea:
5550 0 : this->m_CoolingCapMethod = DataSizing::CapacityPerFloorArea;
5551 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity * TotalFloorAreaOnAirLoop;
5552 0 : break;
5553 0 : case DataSizing::FractionOfAutosizedCoolingCapacity:
5554 0 : this->m_CoolingCapMethod = DataSizing::FractionOfAutosizedCoolingCapacity;
5555 0 : this->m_DesignCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
5556 0 : break;
5557 0 : default:
5558 : assert(true);
5559 : }
5560 :
5561 0 : switch (zoneHVACSizing.HeatingCapMethod) {
5562 0 : case DataSizing::HeatingDesignCapacity:
5563 0 : this->m_HeatingCapMethod = DataSizing::HeatingDesignCapacity;
5564 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5565 0 : break;
5566 0 : case DataSizing::CapacityPerFloorArea:
5567 0 : this->m_HeatingCapMethod = DataSizing::CapacityPerFloorArea;
5568 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity * TotalFloorAreaOnAirLoop;
5569 0 : break;
5570 0 : case DataSizing::FractionOfAutosizedHeatingCapacity:
5571 0 : this->m_HeatingCapMethod = DataSizing::FractionOfAutosizedHeatingCapacity;
5572 0 : this->m_DesignHeatingCapacity = zoneHVACSizing.ScaledHeatingCapacity;
5573 0 : break;
5574 0 : default:
5575 : assert(true);
5576 : }
5577 : }
5578 :
5579 : // Determine supply air flow rate sizing method for cooling mode
5580 622 : if (Util::SameString(loc_m_CoolingSAFMethod, "SupplyAirFlowRate")) {
5581 325 : this->m_CoolingSAFMethod = DataSizing::SupplyAirFlowRate;
5582 :
5583 325 : if (loc_m_CoolingSAFMethod_SAFlow != -999.0) {
5584 325 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlow;
5585 325 : if (this->m_MaxCoolAirVolFlow == DataSizing::AutoSize) {
5586 266 : this->m_RequestAutoSize = true;
5587 : } else {
5588 59 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5589 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5590 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5591 0 : ShowContinueError(
5592 : state,
5593 0 : format("Suspicious Cooling Supply Air Flow Rate = {:.7R} when cooling coil is present.", this->m_MaxCoolAirVolFlow));
5594 : }
5595 59 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5596 : }
5597 :
5598 : } else {
5599 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5600 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = SupplyAirFlowRate.");
5601 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate.");
5602 0 : errorsFound = true;
5603 : }
5604 297 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerFloorArea")) {
5605 :
5606 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerFloorArea;
5607 0 : if (loc_m_CoolingSAFMethod_SAFlowPerFloorArea != -999.0) {
5608 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_SAFlowPerFloorArea;
5609 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5610 0 : if (this->m_MaxCoolAirVolFlow <= 0.0001 && this->m_CoolCoilExists) {
5611 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5612 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5613 0 : ShowContinueError(
5614 : state,
5615 0 : format("Suspicious Cooling Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when cooling coil is present.",
5616 0 : this->m_MaxCoolAirVolFlow));
5617 0 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5618 : }
5619 0 : this->m_MaxCoolAirVolFlow *= TotalFloorAreaOnAirLoop;
5620 0 : this->m_RequestAutoSize = true;
5621 : // AutoSized input is not allowed
5622 : } else {
5623 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5624 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5625 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Floor Area = Autosize");
5626 0 : errorsFound = true;
5627 : }
5628 : } else {
5629 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5630 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerFloorArea.");
5631 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Floor Area.");
5632 0 : errorsFound = true;
5633 : }
5634 297 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FractionOfAutosizedCoolingValue")) {
5635 :
5636 0 : this->m_CoolingSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5637 0 : if (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5638 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow;
5639 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5640 0 : if (this->m_MaxCoolAirVolFlow <= HVAC::SmallAirVolFlow && this->m_CoolCoilExists) {
5641 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5642 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5643 0 : ShowContinueError(state,
5644 0 : format("Suspicious Cooling Fraction of Autosized Cooling Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5645 : "when cooling coil is present.",
5646 0 : this->m_MaxCoolAirVolFlow));
5647 0 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5648 : }
5649 0 : this->m_RequestAutoSize = true;
5650 : // AutoSized input is not allowed
5651 : } else {
5652 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5653 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5654 0 : ShowContinueError(state, "Illegal Cooling Fraction of Autosized Cooling Supply Air Flow Rate = Autosize");
5655 0 : errorsFound = true;
5656 : }
5657 : } else {
5658 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5659 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5660 0 : ShowContinueError(state, "Blank field not allowed for Cooling Fraction of Autosized Cooling Supply Air Flow Rate.");
5661 0 : errorsFound = true;
5662 : }
5663 297 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "FlowPerCoolingCapacity")) {
5664 :
5665 0 : this->m_CoolingSAFMethod = DataSizing::FlowPerCoolingCapacity;
5666 0 : if (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity != -999.0) {
5667 0 : this->m_MaxCoolAirVolFlow = loc_m_CoolingSAFMethod_FlowPerCoolingCapacity;
5668 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
5669 0 : if (this->m_MaxCoolAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5670 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5671 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5672 0 : ShowContinueError(state,
5673 0 : format("Suspicious Cooling Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5674 : "cooling coil is present.",
5675 0 : this->m_MaxCoolAirVolFlow));
5676 0 : if (this->m_MaxCoolAirVolFlow < 0.0) errorsFound = true;
5677 : }
5678 0 : this->m_RequestAutoSize = true;
5679 : // AutoSized input is not allowed
5680 : } else {
5681 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5682 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5683 0 : ShowContinueError(state, "Illegal Cooling Supply Air Flow Rate Per Unit of Capacity = Autosize");
5684 0 : errorsFound = true;
5685 : }
5686 : } else {
5687 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5688 0 : ShowContinueError(state, "Input for Cooling Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5689 0 : ShowContinueError(state, "Blank field not allowed for Cooling Supply Air Flow Rate Per Unit of Capacity.");
5690 0 : errorsFound = true;
5691 : }
5692 :
5693 297 : } else if (Util::SameString(loc_m_CoolingSAFMethod, "None") || loc_m_CoolingSAFMethod == "") {
5694 297 : this->m_CoolingSAFMethod = DataSizing::None;
5695 297 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow == 0) {
5696 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5697 0 : if (this->m_HeatCoilExists) {
5698 0 : ShowContinueError(state, "Blank field not allowed for this coil type when heating coil air flow rate is not AutoSized.");
5699 : } else {
5700 0 : ShowContinueError(state, "Blank field not allowed for this type of cooling coil.");
5701 : }
5702 0 : errorsFound = true;
5703 : }
5704 : }
5705 :
5706 : // Determine supply air flow rate sizing method for heating mode
5707 622 : if (Util::SameString(loc_m_HeatingSAFMethod, "SupplyAirFlowRate")) {
5708 310 : this->m_HeatingSAFMethod = DataSizing::SupplyAirFlowRate;
5709 310 : if (loc_m_HeatingSAFMethod_SAFlow != -999.0) {
5710 310 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlow;
5711 310 : if (this->m_MaxHeatAirVolFlow == DataSizing::AutoSize) {
5712 251 : this->m_RequestAutoSize = true;
5713 : } else {
5714 59 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5715 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5716 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5717 0 : ShowContinueError(
5718 : state,
5719 0 : format("Suspicious Heating Supply Air Flow Rate = {:.7R} when heating coil is present.", this->m_MaxHeatAirVolFlow));
5720 : }
5721 59 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5722 : }
5723 : } else {
5724 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5725 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = SupplyAirFlowRate.");
5726 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate.");
5727 0 : errorsFound = true;
5728 : }
5729 312 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerFloorArea")) {
5730 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerFloorArea;
5731 0 : if (loc_m_HeatingSAFMethod_SAFlowPerFloorArea != -999.0) {
5732 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_SAFlowPerFloorArea;
5733 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5734 0 : if (this->m_MaxHeatAirVolFlow <= 0.0001 && this->m_HeatCoilExists) {
5735 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5736 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5737 0 : ShowContinueError(
5738 : state,
5739 0 : format("Suspicious Heating Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2] when heating coil is present.",
5740 0 : this->m_MaxHeatAirVolFlow));
5741 : }
5742 0 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5743 0 : this->m_MaxHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5744 0 : this->m_RequestAutoSize = true;
5745 : } else {
5746 : // AutoSized input is not allowed
5747 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5748 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5749 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Floor Area = Autosize");
5750 0 : errorsFound = true;
5751 : }
5752 : } else {
5753 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5754 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerFloorArea.");
5755 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Floor Area.");
5756 0 : errorsFound = true;
5757 : }
5758 312 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FractionOfAutosizedHeatingValue")) {
5759 0 : this->m_HeatingSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5760 0 : if (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5761 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow;
5762 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5763 0 : if (this->m_MaxHeatAirVolFlow <= HVAC::SmallAirVolFlow && this->m_HeatCoilExists) {
5764 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5765 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5766 0 : ShowContinueError(state,
5767 0 : format("Suspicious Heating Fraction of Autosized Heating Supply Air Flow Rate = {:.7R} [m3/s/m3] "
5768 : "when heating coil is present.",
5769 0 : this->m_MaxHeatAirVolFlow));
5770 0 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5771 : }
5772 0 : this->m_RequestAutoSize = true;
5773 : // AutoSized input is not allowed
5774 : } else {
5775 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5776 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5777 0 : ShowContinueError(state, "Illegal input for Heating Fraction of Autosized Heating Supply Air Flow Rate = Autosize");
5778 0 : errorsFound = true;
5779 : }
5780 : } else {
5781 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5782 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5783 0 : ShowContinueError(state, "Blank field not allowed for Heating Fraction of Autosized Heating Supply Air Flow Rate");
5784 0 : errorsFound = true;
5785 : }
5786 312 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "FlowPerHeatingCapacity")) {
5787 0 : this->m_HeatingSAFMethod = DataSizing::FlowPerHeatingCapacity;
5788 0 : if (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity != -999.0) {
5789 0 : this->m_MaxHeatAirVolFlow = loc_m_HeatingSAFMethod_FlowPerHeatingCapacity;
5790 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
5791 0 : if (this->m_MaxHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5792 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5793 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5794 0 : ShowContinueError(state,
5795 0 : format("Suspicious Heating Supply Air Flow Rate Per Unit of Capacity = {:.7R} [m3/s/W] when "
5796 : "heating coil is present.",
5797 0 : this->m_MaxHeatAirVolFlow));
5798 0 : if (this->m_MaxHeatAirVolFlow < 0.0) errorsFound = true;
5799 : }
5800 0 : this->m_RequestAutoSize = true;
5801 : // AutoSized input is not allowed
5802 : } else {
5803 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5804 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5805 0 : ShowContinueError(state, "Illegal Heating Supply Air Flow Rate Per Unit of Capacity = Autosize");
5806 0 : errorsFound = true;
5807 : }
5808 : } else {
5809 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5810 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = FlowPerHeatingCapacity");
5811 0 : ShowContinueError(state, "Blank field not allowed for Heating Supply Air Flow Rate Per Unit of Capacity");
5812 0 : errorsFound = true;
5813 : }
5814 312 : } else if (Util::SameString(loc_m_HeatingSAFMethod, "None") || loc_m_HeatingSAFMethod == "") {
5815 312 : this->m_HeatingSAFMethod = DataSizing::None;
5816 312 : if (this->m_HeatCoilExists && this->m_MaxHeatAirVolFlow == 0) {
5817 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5818 0 : if (loc_m_HeatingSAFMethod == "") {
5819 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method is blank.");
5820 : } else {
5821 0 : ShowContinueError(state, "Input for Heating Supply Air Flow Rate Method = None.");
5822 : }
5823 0 : if (this->m_CoolCoilExists) {
5824 0 : ShowContinueError(state, "Blank field not allowed for this coil type when cooling coil air flow rate is not AutoSized.");
5825 : } else {
5826 0 : ShowContinueError(state, "Blank field not allowed for this type of heating coil.");
5827 : }
5828 0 : errorsFound = true;
5829 : }
5830 : }
5831 :
5832 : // Determine supply air flow rate sizing method when cooling or heating is not needed
5833 622 : if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "SupplyAirFlowRate")) {
5834 305 : this->m_NoCoolHeatSAFMethod = DataSizing::SupplyAirFlowRate;
5835 305 : if (loc_m_NoCoolHeatSAFMethod_SAFlow != -999.0) {
5836 305 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlow;
5837 305 : if (this->m_MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
5838 188 : this->m_RequestAutoSize = true;
5839 : } else {
5840 117 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) {
5841 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5842 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
5843 0 : ShowContinueError(state, format("Illegal No Load Supply Air Flow Rate = {:.7R}", this->m_MaxNoCoolHeatAirVolFlow));
5844 0 : errorsFound = true;
5845 : }
5846 : }
5847 :
5848 : } else {
5849 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5850 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = SupplyAirFlowRate");
5851 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate");
5852 0 : errorsFound = true;
5853 : }
5854 317 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerFloorArea")) {
5855 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerFloorArea;
5856 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea != -999.0) {
5857 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_SAFlowPerFloorArea;
5858 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5859 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.0001) {
5860 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5861 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
5862 0 : ShowContinueError(
5863 : state,
5864 0 : format("Suspicious No Load Supply Air Flow Rate Per Floor Area = {:.7R} [m3/s/m2]", this->m_MaxNoCoolHeatAirVolFlow));
5865 : }
5866 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5867 0 : this->m_MaxNoCoolHeatAirVolFlow *= TotalFloorAreaOnAirLoop;
5868 0 : this->m_RequestAutoSize = true;
5869 : } else {
5870 : // AutoSized input is not allowed
5871 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5872 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
5873 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Floor Area = Autosize");
5874 0 : errorsFound = true;
5875 : }
5876 : } else {
5877 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5878 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerFloorArea.");
5879 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Floor Area");
5880 0 : errorsFound = true;
5881 : }
5882 317 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedCoolingValue")) {
5883 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedCoolingAirflow;
5884 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow != -999.0) {
5885 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedCoolingSAFlow;
5886 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5887 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
5888 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5889 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5890 0 : ShowContinueError(
5891 : state,
5892 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/m3].",
5893 0 : this->m_MaxNoCoolHeatAirVolFlow));
5894 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5895 : }
5896 0 : this->m_RequestAutoSize = true;
5897 : // AutoSized input is not allowed
5898 : } else {
5899 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5900 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue");
5901 0 : ShowContinueError(state,
5902 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
5903 0 : errorsFound = true;
5904 : }
5905 : } else {
5906 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5907 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedCoolingValue.");
5908 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
5909 0 : errorsFound = true;
5910 : }
5911 317 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FractionOfAutosizedHeatingValue")) {
5912 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FractionOfAutosizedHeatingAirflow;
5913 0 : if (loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow != -999.0) {
5914 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FracOfAutosizedHeatingSAFlow;
5915 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5916 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= HVAC::SmallAirVolFlow) {
5917 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5918 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5919 0 : ShowContinueError(
5920 : state,
5921 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/m3].",
5922 0 : this->m_MaxNoCoolHeatAirVolFlow));
5923 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5924 : }
5925 0 : this->m_RequestAutoSize = true;
5926 : // AutoSized input is not allowed
5927 : } else {
5928 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5929 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue");
5930 0 : ShowContinueError(state,
5931 : "Illegal input for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
5932 0 : errorsFound = true;
5933 : }
5934 : } else {
5935 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5936 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FractionOfAutosizedHeatingValue.");
5937 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
5938 0 : errorsFound = true;
5939 : }
5940 317 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerCoolingCapacity")) {
5941 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerCoolingCapacity;
5942 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity != -999.0) {
5943 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerCoolingCapacity;
5944 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5945 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_CoolCoilExists) {
5946 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5947 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5948 0 : ShowContinueError(
5949 : state,
5950 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = {:.7R} [m3/s/W].",
5951 0 : this->m_MaxNoCoolHeatAirVolFlow));
5952 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5953 : }
5954 0 : this->m_RequestAutoSize = true;
5955 : // AutoSized input is not allowed
5956 : } else {
5957 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5958 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5959 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation = Autosize");
5960 0 : errorsFound = true;
5961 : }
5962 : } else {
5963 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5964 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerCoolingCapacity.");
5965 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Cooling Operation");
5966 0 : errorsFound = true;
5967 : }
5968 317 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "FlowPerHeatingCapacity")) {
5969 0 : this->m_NoCoolHeatSAFMethod = DataSizing::FlowPerHeatingCapacity;
5970 0 : if (loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity != -999.0) {
5971 0 : this->m_MaxNoCoolHeatAirVolFlow = loc_m_NoCoolHeatSAFMethod_FlowPerHeatingCapacity;
5972 0 : if (this->m_MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
5973 0 : if (this->m_MaxNoCoolHeatAirVolFlow <= 0.00001 && this->m_HeatCoilExists) {
5974 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5975 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5976 0 : ShowContinueError(
5977 : state,
5978 0 : format("Suspicious No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = {:.7R} [m3/s/W].",
5979 0 : this->m_MaxNoCoolHeatAirVolFlow));
5980 0 : if (this->m_MaxNoCoolHeatAirVolFlow < 0.0) errorsFound = true;
5981 : }
5982 0 : this->m_RequestAutoSize = true;
5983 : // AutoSized input is not allowed
5984 : } else {
5985 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5986 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5987 0 : ShowContinueError(state, "Illegal No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation = Autosize");
5988 0 : errorsFound = true;
5989 : }
5990 : } else {
5991 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
5992 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate Method = FlowPerHeatingCapacity.");
5993 0 : ShowContinueError(state, "Blank field not allowed for No Load Supply Air Flow Rate Per Unit of Capacity During Heating Operation");
5994 0 : errorsFound = true;
5995 : }
5996 317 : } else if (Util::SameString(loc_m_NoCoolHeatSAFMethod, "None") || loc_m_NoCoolHeatSAFMethod == "") {
5997 317 : this->m_NoCoolHeatSAFMethod = DataSizing::None;
5998 317 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
5999 0 : if (loc_m_NoCoolHeatSAFMethod_SAFlow == -99999.0) { // no load air flow is autosized
6000 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6001 0 : this->m_RequestAutoSize = true;
6002 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == -999.0) { // no load air flow is blank
6003 0 : this->m_MaxNoCoolHeatAirVolFlow = DataSizing::AutoSize;
6004 0 : this->m_RequestAutoSize = true;
6005 0 : ShowWarningError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6006 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6007 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be blank.");
6008 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate has been set to AutoSize and the simulation continues.");
6009 0 : } else if (loc_m_NoCoolHeatSAFMethod_SAFlow == 0.0) { // no load air flow for SZVAV cannot be 0
6010 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6011 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6012 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
6013 0 : errorsFound = true;
6014 : }
6015 : }
6016 : }
6017 622 : if (this->input_specs.no_load_supply_air_flow_rate_low_speed == "NO") {
6018 52 : this->m_useNoLoadLowSpeedAirFlow = false;
6019 : }
6020 :
6021 : // check supply air flow calculation method
6022 622 : if (this->m_FanExists) {
6023 325 : if (this->m_CoolCoilExists) {
6024 325 : if (loc_m_CoolingSAFMethod.empty()) {
6025 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6026 0 : ShowContinueError(state,
6027 : "Method used to determine the cooling supply air flow rate is not specified when cooling coil is present.");
6028 : // check if all cooling flow calc method fields are blank
6029 0 : if (((loc_m_CoolingSAFMethod_SAFlow == -999.0) && (loc_m_CoolingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6030 0 : (loc_m_CoolingSAFMethod_FracOfAutosizedCoolingSAFlow == -999.0) &&
6031 : (loc_m_CoolingSAFMethod_FlowPerCoolingCapacity == -999.0))) {
6032 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate field is blank.");
6033 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Floor Area field is blank.");
6034 0 : ShowContinueError(state, "Cooling Fraction of Autosized Cooling Supply Air Flow Rate field is blank.");
6035 0 : ShowContinueError(state, "Cooling Supply Air Flow Rate Per Unit of Capacity field is blank.");
6036 0 : ShowContinueError(state,
6037 : "Blank field not allowed for all four cooling supply air flow rate calculation methods when "
6038 : "cooling coil is present.");
6039 : }
6040 : }
6041 : // set fan info for cooling coils
6042 325 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6043 325 : state, this->m_CoolingCoilName, input_data.cooling_coil_object_type, this->m_FanName, this->m_FanType, this->m_FanIndex);
6044 : }
6045 325 : if (this->m_HeatCoilExists) {
6046 310 : if (loc_m_HeatingSAFMethod.empty()) {
6047 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6048 0 : ShowContinueError(state,
6049 : "Method used to determine the heating supply air flow rate is not specified when heating coil is present.");
6050 : // check if all heating flow calc method fields are blank
6051 0 : if (((loc_m_HeatingSAFMethod_SAFlow == -999.0) && (loc_m_HeatingSAFMethod_SAFlowPerFloorArea == -999.0) &&
6052 0 : (loc_m_HeatingSAFMethod_FracOfAutosizedHeatingSAFlow == -999.0) &&
6053 : (loc_m_HeatingSAFMethod_FlowPerHeatingCapacity == -999.0))) {
6054 0 : ShowContinueError(state, "Heating Supply Air Flow Rate field is blank.");
6055 0 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Floor Area field is blank.");
6056 0 : ShowContinueError(state, "Heating Fraction of Autosized Heating Supply Air Flow Rate field is blank.");
6057 0 : ShowContinueError(state, "Heating Supply Air Flow Rate Per Unit of Capacity field is blank.");
6058 0 : ShowContinueError(state,
6059 : "Blank field not allowed for all four heating supply air flow rate calculation methods when heating "
6060 : "coil is present.");
6061 : }
6062 : }
6063 : // set fan info for heating coils
6064 310 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
6065 310 : state, this->m_HeatingCoilName, this->m_HeatingCoilTypeName, this->m_FanName, this->m_FanType, this->m_FanIndex);
6066 : }
6067 : }
6068 :
6069 : // Fan operating mode (cycling or constant) schedule. IF constant fan, then set AirFlowControl
6070 622 : if (this->m_FanOpModeSchedPtr > 0) {
6071 319 : if (!ScheduleManager::CheckScheduleValueMinMax(state, this->m_FanOpModeSchedPtr, ">=", 0.0, "<=", 0.0)) {
6072 : // set fan operating mode to continuous so sizing can set VS coil data
6073 172 : this->m_FanOpMode = HVAC::FanOp::Continuous;
6074 : // set air flow control mode:
6075 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6076 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6077 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6078 172 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6079 39 : this->m_AirFlowControl = UseCompFlow::On;
6080 : } else {
6081 133 : this->m_AirFlowControl = UseCompFlow::Off;
6082 : }
6083 : }
6084 : }
6085 :
6086 622 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6087 4 : int numCoolingCoilModes = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].getNumModes();
6088 4 : if (numCoolingCoilModes == 1) {
6089 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6090 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6091 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6092 0 : ShowContinueError(
6093 0 : state, format("Cooling coil named: {} has only one mode", state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].name));
6094 0 : ShowFatalError(state, "Multimode cooling coil error causes program termination");
6095 : }
6096 622 : } else if (this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted &&
6097 616 : this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingTwoStageWHumControl &&
6098 607 : this->m_CoolingCoilType_Num != HVAC::CoilWater_CoolingHXAssisted && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
6099 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6100 0 : ShowContinueError(state, format("Illegal Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6101 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted or Multimode Cooling Coil.");
6102 0 : if (this->m_SuppHeatCoilName == "" && this->m_SuppHeatCoilTypeName == "") {
6103 : } else {
6104 0 : if (this->m_CoolingCoilType_Num == HVAC::Coil_UserDefined) {
6105 0 : ShowContinueError(state, "Dehumidification control type is assumed to be None and the simulation continues.");
6106 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6107 : } else {
6108 0 : ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
6109 0 : this->m_DehumidControlType_Num = DehumCtrlType::CoolReheat;
6110 : }
6111 : }
6112 : }
6113 :
6114 : // Check placement of cooling coil with respect to fan placement and dehumidification control type
6115 :
6116 622 : if (this->m_FanExists) {
6117 325 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6118 166 : if (FanOutletNode == HeatingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6119 23 : this->m_CoolingCoilUpstream = false;
6120 : }
6121 159 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) {
6122 159 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6123 0 : this->m_CoolingCoilUpstream = false;
6124 : }
6125 : }
6126 : } else {
6127 297 : if (HeatingCoilOutletNode == CoolingCoilInletNode && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat) {
6128 0 : this->m_CoolingCoilUpstream = false;
6129 : }
6130 297 : if (ZoneEquipmentFound) {
6131 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6132 0 : ShowContinueError(state, "ZoneHVAC equipment must contain a fan object.");
6133 0 : ShowContinueError(state, format("specified Supply Fan Object Type = {}", loc_fanType));
6134 0 : ShowContinueError(state, format("specified Supply Fan Name = {}", loc_m_FanName));
6135 0 : errorsFound = true;
6136 : }
6137 : }
6138 :
6139 : // check node connections
6140 622 : if (this->m_FanPlace == HVAC::FanPlace::BlowThru) {
6141 :
6142 166 : int tmpAirInletNode = this->AirInNode;
6143 166 : if (this->OAMixerExists) {
6144 27 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6145 : }
6146 166 : if (FanInletNode != tmpAirInletNode) {
6147 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6148 0 : if (this->OAMixerExists) {
6149 0 : ShowContinueError(state,
6150 : "When a blow through fan is specified, the fan inlet node name must be the same as the outdoor "
6151 : "air mixer mixed air node name.");
6152 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6153 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6154 : } else {
6155 0 : ShowContinueError(state,
6156 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system "
6157 : "inlet node name.");
6158 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6159 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6160 : }
6161 0 : errorsFound = true;
6162 : }
6163 166 : if (this->m_CoolingCoilUpstream) {
6164 143 : if (FanOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6165 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6166 0 : ShowContinueError(state,
6167 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil "
6168 : "inlet node name.");
6169 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6170 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6171 0 : errorsFound = true;
6172 : }
6173 143 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6174 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6175 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6176 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6177 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6178 0 : errorsFound = true;
6179 : }
6180 143 : if (this->m_SuppCoilExists) {
6181 81 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6182 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6183 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6184 0 : ShowContinueError(state,
6185 0 : format("...Reheat coil outlet node name = {}" + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6186 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}" + state.dataLoopNodes->NodeID(this->AirOutNode)));
6187 0 : errorsFound = true;
6188 : }
6189 : } else { // IF((this->m_Humidistat ...
6190 : // Heating coil outlet node name must be the same as the Unitary system outlet node name
6191 62 : if (this->m_HeatCoilExists && HeatingCoilOutletNode != this->AirOutNode) {
6192 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6193 0 : ShowContinueError(state,
6194 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
6195 : "unitary system outlet node name.");
6196 0 : ShowContinueError(state,
6197 0 : format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6198 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6199 0 : errorsFound = true;
6200 : }
6201 : }
6202 : } else { // IF(this->CoolingCoilUpstream)THEN
6203 23 : if (FanOutletNode != HeatingCoilInletNode && this->m_FanExists && this->m_HeatCoilExists) {
6204 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6205 0 : ShowContinueError(state,
6206 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil "
6207 : "inlet node name.");
6208 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6209 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6210 0 : errorsFound = true;
6211 : }
6212 23 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6213 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6214 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6215 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6216 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6217 0 : errorsFound = true;
6218 : }
6219 23 : if (CoolingCoilOutletNode != this->AirOutNode && this->m_CoolCoilExists) {
6220 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6221 0 : ShowContinueError(state,
6222 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the unitary "
6223 : "system outlet node name.");
6224 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6225 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6226 0 : errorsFound = true;
6227 : }
6228 : }
6229 :
6230 456 : } else if (this->m_FanPlace == HVAC::FanPlace::DrawThru) { // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6231 :
6232 159 : int tmpAirInletNode = this->AirInNode;
6233 159 : if (this->OAMixerExists) {
6234 140 : tmpAirInletNode = this->m_OAMixerNodes[3]; // mixed air node
6235 : }
6236 159 : if (this->m_CoolingCoilUpstream) {
6237 159 : if (CoolingCoilInletNode != tmpAirInletNode && CoolingCoilInletNode != 0 && this->m_FanExists) {
6238 0 : if (this->OAMixerExists) {
6239 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6240 0 : ShowContinueError(state,
6241 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the outdoor "
6242 : "air mixer mixed air node name.");
6243 0 : ShowContinueError(state,
6244 0 : format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6245 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6246 : } else {
6247 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6248 0 : ShowContinueError(state,
6249 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary "
6250 : "system inlet node name.");
6251 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6252 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6253 : }
6254 0 : errorsFound = true;
6255 : }
6256 159 : if (CoolingCoilOutletNode != HeatingCoilInletNode && this->m_CoolCoilExists && this->m_HeatCoilExists) {
6257 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6258 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
6259 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6260 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6261 0 : errorsFound = true;
6262 : }
6263 159 : if (HeatingCoilOutletNode != FanInletNode && this->m_HeatCoilExists && this->m_FanExists) {
6264 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6265 0 : ShowContinueError(state,
6266 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan "
6267 : "inlet node name.");
6268 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6269 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6270 0 : errorsFound = true;
6271 : }
6272 159 : if (this->m_SuppCoilExists) {
6273 16 : if (FanOutletNode != SupHeatCoilInletNode && this->m_FanExists) {
6274 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6275 0 : ShowContinueError(state,
6276 : "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
6277 : "inlet node name.");
6278 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6279 0 : ShowContinueError(state, format("...Reheat coil inlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
6280 0 : errorsFound = true;
6281 : }
6282 16 : if (SupHeatCoilOutletNode != this->AirOutNode) {
6283 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6284 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
6285 0 : ShowContinueError(state,
6286 0 : format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
6287 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6288 0 : errorsFound = true;
6289 : }
6290 : } else {
6291 143 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6292 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6293 0 : ShowContinueError(state,
6294 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6295 : "outlet node name.");
6296 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6297 0 : ShowContinueError(state, format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6298 0 : errorsFound = true;
6299 : }
6300 : }
6301 : } else { // IF(this->CoolingCoilUpstream)THEN
6302 0 : if (HeatingCoilInletNode != tmpAirInletNode && HeatingCoilInletNode != 0 && this->m_FanExists) {
6303 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6304 0 : if (this->OAMixerExists) {
6305 0 : ShowContinueError(state,
6306 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6307 : "system mixer mixed air node name.");
6308 0 : ShowContinueError(state,
6309 0 : format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6310 0 : ShowContinueError(state, format("...UnitarySystem mixed air node name = {}", state.dataLoopNodes->NodeID(tmpAirInletNode)));
6311 : } else {
6312 0 : ShowContinueError(state,
6313 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
6314 : "system inlet node name.");
6315 0 : ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
6316 0 : ShowContinueError(state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(this->AirInNode)));
6317 : }
6318 0 : errorsFound = true;
6319 : }
6320 0 : if (HeatingCoilOutletNode != CoolingCoilInletNode && this->m_HeatCoilExists && this->m_CoolCoilExists) {
6321 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6322 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
6323 0 : ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
6324 0 : ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
6325 0 : errorsFound = true;
6326 : }
6327 0 : if (CoolingCoilOutletNode != FanInletNode && this->m_CoolCoilExists && this->m_FanExists) {
6328 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6329 0 : ShowContinueError(state,
6330 : "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan "
6331 : "inlet node name.");
6332 0 : ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
6333 0 : ShowContinueError(state, format("...Fan inlet node name = {}", state.dataLoopNodes->NodeID(FanInletNode)));
6334 0 : errorsFound = true;
6335 : }
6336 0 : if (FanOutletNode != this->AirOutNode && this->m_FanExists) {
6337 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6338 0 : ShowContinueError(state,
6339 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
6340 : "outlet node name.");
6341 0 : ShowContinueError(state, format("...Fan outlet node name = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
6342 0 : ShowContinueError(state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(this->AirOutNode)));
6343 0 : errorsFound = true;
6344 : }
6345 : }
6346 : } // ELSE from IF(this->FanPlace .EQ. BlowThru)THEN
6347 :
6348 : // Set the unitary system supplemental heater max outlet temperature
6349 : // this field will be 0 if the input is not specified (included) in the input file
6350 : // someone may use a default other than what we intended, allow it to be used
6351 : // so if this field is blank, and the input field is included, read the default, otherwise use 80
6352 : // if (!lNumericBlanks(iDesignMaxOutletTempNumericNum) && NumNumbers > (iDesignMaxOutletTempNumericNum - 1)) {
6353 622 : if (this->m_sysType == SysType::Unitary) {
6354 : // UnitarySystem has a single field for max outlet temp
6355 130 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6356 : } else {
6357 : // PTHP has a field for max outlet temp for supplemental heater and max outlet temp for SZVAV
6358 492 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6359 0 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature;
6360 : } else {
6361 492 : this->DesignMaxOutletTemp = input_data.maximum_supply_air_temperature_from_supplemental_heater;
6362 : }
6363 : }
6364 622 : if (this->DesignMaxOutletTemp == DataSizing::AutoSize) this->m_RequestAutoSize = true;
6365 : //}
6366 :
6367 : // Set maximum Outdoor air temperature for supplemental heating coil operation
6368 : // this field will be 0 if the input is not specified (included) in the input file
6369 : // someone may use a default other than what we intended, allow it to be used
6370 : // so if this field is blank, and the input field is included, read the default, otherwise use 9999
6371 : // if (!lNumericBlanks(iMaxOATSuppHeatNumericNum) && NumNumbers > (iMaxOATSuppHeatNumericNum - 1)) {
6372 622 : this->m_MaxOATSuppHeat = input_data.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation;
6373 : // Can't let MaxOATSuppHeat default to 21C if using cool reheat since it would shut off supp heater when dehumidifying
6374 : // this may also allow supplemental heater to operate when in heating mode when it should not
6375 622 : if (this->m_MaxOATSuppHeat == 21.0 && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6376 13 : this->m_MaxOATSuppHeat = 999.0;
6377 : }
6378 622 : if (this->m_SuppCoilExists) {
6379 194 : OutputReportPredefined::PreDefTableEntry(
6380 97 : state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, this->m_HeatingCoilName, this->m_MaxOATSuppHeat);
6381 : }
6382 :
6383 622 : if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 &&
6384 59 : !this->m_RequestAutoSize) {
6385 12 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6386 610 : } else if (this->m_MaxCoolAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6387 48 : this->m_DesignFanVolFlowRate = max(this->m_MaxCoolAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6388 562 : } else if (this->m_MaxHeatAirVolFlow > 0.0 && this->m_MaxNoCoolHeatAirVolFlow >= 0.0 && !this->m_RequestAutoSize) {
6389 0 : this->m_DesignFanVolFlowRate = max(this->m_MaxHeatAirVolFlow, this->m_MaxNoCoolHeatAirVolFlow);
6390 : } else {
6391 562 : if (this->m_FanExists && this->m_DesignFanVolFlowRate == 0.0) {
6392 0 : this->m_DesignFanVolFlowRate = DataSizing::AutoSize;
6393 : }
6394 : // need more of this type of warning when flow cannot be determined
6395 562 : if (this->m_MaxHeatAirVolFlow == 0.0 && this->m_HeatCoilExists) {
6396 0 : if (this->m_FanExists) {
6397 0 : if (this->m_CoolCoilExists && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6398 0 : if (this->m_MaxCoolAirVolFlow == 0.0) {
6399 0 : this->m_MaxHeatAirVolFlow = this->m_DesignFanVolFlowRate;
6400 : }
6401 : }
6402 0 : } else if (this->m_CoolCoilExists) {
6403 0 : this->m_MaxHeatAirVolFlow = this->m_MaxCoolAirVolFlow;
6404 : } else {
6405 0 : if (this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical &&
6406 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_MultiSpeedHeating &&
6407 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed) {
6408 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6409 0 : ShowContinueError(state,
6410 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6411 : "Supply Air Flow Rate Method");
6412 0 : errorsFound = true;
6413 : }
6414 : }
6415 562 : } else if (this->m_MaxHeatAirVolFlow == 0.0 && !this->m_FanExists && !this->m_CoolCoilExists) {
6416 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6417 0 : ShowContinueError(state,
6418 : "When non-DX heating coils are specified, the heating air flow rate must be entered in Heating "
6419 : "Supply Air Flow Rate Method");
6420 : }
6421 : }
6422 :
6423 622 : if (FanVolFlowRate != DataSizing::AutoSize && this->m_FanExists) {
6424 63 : if (FanVolFlowRate < this->m_MaxCoolAirVolFlow && this->m_MaxCoolAirVolFlow != DataSizing::AutoSize && this->m_CoolCoilExists) {
6425 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6426 0 : ShowContinueError(
6427 : state,
6428 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
6429 : FanVolFlowRate,
6430 0 : this->m_FanName));
6431 0 : ShowContinueError(state, " The Cooling Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6432 0 : this->m_MaxCoolAirVolFlow = FanVolFlowRate;
6433 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6434 : }
6435 63 : if (FanVolFlowRate < this->m_MaxHeatAirVolFlow && this->m_MaxHeatAirVolFlow != DataSizing::AutoSize && this->m_HeatCoilExists) {
6436 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6437 0 : ShowContinueError(
6438 : state,
6439 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
6440 : FanVolFlowRate,
6441 0 : this->m_FanName));
6442 0 : ShowContinueError(state, " The Heating Supply Air Flow Rate is reset to the fan flow rate and the simulation continues.");
6443 0 : this->m_MaxHeatAirVolFlow = FanVolFlowRate;
6444 0 : this->m_DesignFanVolFlowRate = FanVolFlowRate;
6445 : }
6446 : }
6447 :
6448 622 : if (this->m_FanOpModeSchedPtr > 0) {
6449 319 : if (!ScheduleManager::CheckScheduleValueMinMax(state, this->m_FanOpModeSchedPtr, ">=", 0.0, "<=", 0.0)) {
6450 : // set air flow control mode:
6451 : // m_AirFlowControl = UseCompFlow::On means operate at last cooling or heating air flow requested when compressor is off
6452 : // m_AirFlowControl = UseCompFlow::Off means operate at no load air flow value specified by user
6453 : // AirFlowControl only valid if fan opmode = ContFanCycComp
6454 172 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) {
6455 39 : this->m_AirFlowControl = UseCompFlow::On;
6456 : } else {
6457 133 : this->m_AirFlowControl = UseCompFlow::Off;
6458 : }
6459 : }
6460 : }
6461 :
6462 : // Set minimum OAT for heat pump compressor operation in cooling mode
6463 : // get from coil module
6464 622 : errFlag = false;
6465 622 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6466 383 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6467 239 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
6468 67 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6469 172 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6470 38 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6471 134 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
6472 9 : this->m_MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6473 125 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6474 10 : this->m_MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_CoolingCoilIndex, errFlag);
6475 115 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
6476 : // already found in getInput
6477 : } else {
6478 62 : this->m_MinOATCompressorCooling = -1000.0;
6479 : }
6480 622 : if (errFlag) {
6481 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6482 0 : errorsFound = true;
6483 0 : errFlag = false;
6484 : }
6485 :
6486 : // Set minimum OAT for heat pump compressor operation in heating mode
6487 : // get from coil module
6488 622 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6489 3 : this->m_MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6490 619 : } else if (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical || this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6491 54 : this->m_MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, this->m_HeatingCoilIndex, errFlag);
6492 : } else {
6493 565 : this->m_MinOATCompressorHeating = -1000.0;
6494 : }
6495 622 : if (errFlag) {
6496 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6497 0 : errorsFound = true;
6498 0 : errFlag = false;
6499 : }
6500 :
6501 : // Mine heatpump Outdoor condenser node from DX coil object
6502 622 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
6503 383 : this->m_CondenserNodeNum =
6504 383 : DXCoils::GetCoilCondenserInletNode(state, input_data.cooling_coil_object_type, this->m_CoolingCoilName, errFlag);
6505 : // TODO: Should we add a block for the new DX Coil?
6506 239 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6507 10 : this->m_CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, this->m_CoolingCoilName, errFlag);
6508 229 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
6509 : // already filled
6510 : // UnitarySystem( UnitarySysNum ).CondenserNodeNum = GetDXCoilCondenserInletNode( "Coil:Cooling:DX:SingleSpeed",
6511 : // GetHXDXCoilName(state, CoolingCoilType, this->m_CoolingCoilName, errFlag ), errFlag );
6512 :
6513 : } else {
6514 227 : if (input_data.outdoor_dry_bulb_temperature_sensor_node_name != "") {
6515 36 : this->m_CondenserNodeNum = NodeInputManager::GetOnlySingleNode(state,
6516 18 : input_data.outdoor_dry_bulb_temperature_sensor_node_name,
6517 : errFlag,
6518 : objType,
6519 : thisObjectName,
6520 : DataLoopNode::NodeFluidType::Air,
6521 : DataLoopNode::ConnectionType::Inlet,
6522 : NodeInputManager::CompFluidStream::Primary,
6523 : DataLoopNode::ObjectIsParent);
6524 : } else {
6525 : // do nothing?
6526 : }
6527 : }
6528 622 : if (errFlag) {
6529 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6530 0 : errorsFound = true;
6531 0 : errFlag = false;
6532 : }
6533 :
6534 622 : this->m_AncillaryOnPower = input_data.ancillary_on_cycle_electric_power;
6535 622 : this->m_AncillaryOffPower = input_data.ancillary_off_cycle_electric_power;
6536 622 : this->m_MaxHROutletWaterTemp = input_data.maximum_temperature_for_heat_recovery;
6537 :
6538 622 : if (this->m_DesignHRWaterVolumeFlow > 0.0) {
6539 0 : this->m_HeatRecActive = true;
6540 0 : if (input_data.heat_recovery_water_inlet_node_name != "" && input_data.heat_recovery_water_outlet_node_name != "") {
6541 0 : this->m_HeatRecoveryInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6542 0 : input_data.heat_recovery_water_inlet_node_name,
6543 : errFlag,
6544 : objType,
6545 : thisObjectName,
6546 : DataLoopNode::NodeFluidType::Water,
6547 : DataLoopNode::ConnectionType::Inlet,
6548 : NodeInputManager::CompFluidStream::Tertiary,
6549 : DataLoopNode::ObjectIsNotParent);
6550 0 : this->m_HeatRecoveryOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
6551 0 : input_data.heat_recovery_water_outlet_node_name,
6552 : errFlag,
6553 : objType,
6554 : thisObjectName,
6555 : DataLoopNode::NodeFluidType::Water,
6556 : DataLoopNode::ConnectionType::Outlet,
6557 : NodeInputManager::CompFluidStream::Tertiary,
6558 : DataLoopNode::ObjectIsNotParent);
6559 :
6560 0 : BranchNodeConnections::TestCompSet(state,
6561 : cCurrentModuleObject,
6562 : thisObjectName,
6563 0 : input_data.heat_recovery_water_inlet_node_name,
6564 0 : input_data.heat_recovery_water_outlet_node_name,
6565 : "Unitary System Heat Recovery Nodes");
6566 :
6567 0 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
6568 0 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_CoolingCoilIndex);
6569 : }
6570 0 : if (this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
6571 0 : DXCoils::SetMSHPDXCoilHeatRecoveryFlag(state, this->m_HeatingCoilIndex);
6572 : }
6573 0 : if (errFlag) {
6574 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisObjectName));
6575 0 : errorsFound = true;
6576 : // errFlag = false; // not used after this point, uncomment if needed
6577 : }
6578 : } else {
6579 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6580 0 : ShowContinueError(state, format("Illegal Heat Recovery Water Inlet Node Name = {}", input_data.heat_recovery_water_inlet_node_name));
6581 0 : ShowContinueError(state,
6582 0 : format("Illegal Heat Recovery Water Outlet Node Name = {}", input_data.heat_recovery_water_outlet_node_name));
6583 0 : ShowContinueError(state,
6584 : "... heat recovery nodes must be specified when Design Heat Recovery Water Flow Rate"
6585 : " is greater than 0.");
6586 0 : ShowContinueError(state, format("... Design Heat Recovery Water Flow Rate = {:.7R}", this->m_DesignHRWaterVolumeFlow));
6587 0 : errorsFound = true;
6588 : }
6589 : }
6590 :
6591 622 : if (!this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) {
6592 :
6593 62 : if (this->m_DesignSpecMSHPIndex > -1) {
6594 :
6595 62 : this->m_NoLoadAirFlowRateRatio = this->m_CompPointerMSHP->noLoadAirFlowRateRatio;
6596 :
6597 62 : switch (this->m_HeatingCoilType_Num) {
6598 15 : case HVAC::CoilDX_MultiSpeedHeating:
6599 : case HVAC::Coil_HeatingElectric_MultiStage:
6600 : case HVAC::Coil_HeatingGas_MultiStage:
6601 : case HVAC::Coil_HeatingWaterToAirHPSimple:
6602 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
6603 15 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6604 15 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6605 15 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6606 15 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6607 15 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling < this->m_NumOfSpeedHeating) {
6608 0 : this->FullOutput.resize(this->m_NumOfSpeedHeating + 1);
6609 : }
6610 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple && this->m_NumOfSpeedHeating > 1) {
6611 1 : this->m_MultiSpeedHeatingCoil = true;
6612 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6613 : }
6614 65 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6615 50 : this->m_HeatMassFlowRate[i] = 0.0;
6616 50 : this->m_HeatVolumeFlowRate[i] = 0.0;
6617 50 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6618 : }
6619 15 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
6620 1 : std::string MultispeedType = "UnitarySystemPerformance:Multispeed";
6621 1 : if (this->m_DesignSpecMSHPIndex == -1) {
6622 0 : std::string MultispeedType = "Fan:SystemModel";
6623 0 : }
6624 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_HeatingCoilName, errorsFound);
6625 1 : if (errorsFound) {
6626 0 : ShowSevereError(state,
6627 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_HeatingCoilName));
6628 : }
6629 1 : if (NumOfSpeed != this->m_NumOfSpeedHeating) {
6630 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_HeatingCoilName));
6631 0 : ShowContinueError(state,
6632 0 : format("... The number of heating coil speeds in the {} = {:.0R}",
6633 : MultispeedType,
6634 0 : double(this->m_NumOfSpeedHeating)));
6635 0 : ShowContinueError(
6636 : state,
6637 0 : format("... The number of heating coil speeds in Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6638 0 : double(NumOfSpeed)));
6639 0 : ShowContinueError(state, format("... The number of heating coil speeds in the {} will be used.", MultispeedType));
6640 : }
6641 1 : }
6642 15 : } break;
6643 : }
6644 62 : switch (this->m_CoolingCoilType_Num) {
6645 40 : case HVAC::CoilDX_MultiSpeedCooling:
6646 : case HVAC::Coil_CoolingWaterToAirHPSimple:
6647 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
6648 40 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6649 40 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6650 40 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6651 40 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6652 40 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_NumOfSpeedCooling > this->m_NumOfSpeedHeating) {
6653 0 : this->FullOutput.resize(this->m_NumOfSpeedCooling + 1);
6654 0 : DXCoils::DisableLatentDegradation(state, this->m_CoolingCoilIndex);
6655 : }
6656 40 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple && this->m_NumOfSpeedCooling > 1) {
6657 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6658 1 : this->m_DiscreteSpeedCoolingCoil = true;
6659 : }
6660 131 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6661 91 : this->m_CoolMassFlowRate[i] = 0.0;
6662 91 : this->m_CoolVolumeFlowRate[i] = 0.0;
6663 91 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6664 : }
6665 40 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
6666 1 : std::string MultispeedType = "UnitarySystemPerformance:Multispeed";
6667 1 : if (this->m_DesignSpecMSHPIndex == -1) {
6668 0 : std::string MultispeedType = "Fan:SystemModel";
6669 0 : }
6670 1 : int NumOfSpeed = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, this->m_CoolingCoilName, errorsFound);
6671 1 : if (errorsFound) {
6672 0 : ShowSevereError(state,
6673 0 : format("{} = {} is not found. Please check the input.", cCurrentModuleObject, this->m_CoolingCoilName));
6674 : }
6675 1 : if (NumOfSpeed != this->m_NumOfSpeedCooling) {
6676 0 : ShowWarningError(state, format("{} = {}.", cCurrentModuleObject, this->m_CoolingCoilName));
6677 0 : ShowContinueError(state,
6678 0 : format("... The number of Cooling coil speeds in the {} = {:.0R}",
6679 : MultispeedType,
6680 0 : double(this->m_NumOfSpeedCooling)));
6681 0 : ShowContinueError(
6682 : state,
6683 0 : format("... The number of heating coil speeds in Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit = {:.0R}",
6684 0 : double(NumOfSpeed)));
6685 0 : ShowContinueError(state, format("... The number of Cooling coil speeds in the {} will be used.", MultispeedType));
6686 : }
6687 1 : }
6688 40 : } break;
6689 : }
6690 : } else {
6691 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6692 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6693 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6694 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6695 0 : errorsFound = true;
6696 : }
6697 560 : } else if (this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty()) {
6698 560 : if (this->m_FanType == HVAC::FanType::SystemModel) {
6699 39 : auto *fanSystem = dynamic_cast<Fans::FanSystem *>(state.dataFans->fans(this->m_FanIndex));
6700 39 : assert(fanSystem != nullptr);
6701 39 : if (fanSystem->speedControl == Fans::SpeedControl::Discrete) {
6702 36 : if (fanSystem->numSpeeds > 1) {
6703 1 : if ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6704 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6705 1 : this->m_sysType == SysType::PackagedWSHP) {
6706 1 : this->m_NumOfSpeedCooling = fanSystem->numSpeeds;
6707 1 : this->m_CoolVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6708 1 : this->m_CoolMassFlowRate.resize(fanSystem->numSpeeds + 1);
6709 1 : this->m_MSCoolingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6710 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6711 1 : this->m_DiscreteSpeedCoolingCoil = true;
6712 1 : if (fanSystem->maxAirFlowRate > 0.0) {
6713 0 : if (this->m_MaxCoolAirVolFlow != DataSizing::AutoSize) {
6714 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6715 0 : this->m_CoolVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6716 0 : this->m_CoolMassFlowRate[i] = this->m_CoolVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6717 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6718 : }
6719 : } else {
6720 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6721 0 : this->m_CoolMassFlowRate[i] = 0.0;
6722 0 : this->m_CoolVolumeFlowRate[i] = 0.0;
6723 0 : this->m_MSCoolingSpeedRatio[i] = 1.0;
6724 : }
6725 : }
6726 : }
6727 : }
6728 1 : if ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6729 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6730 1 : this->m_sysType == SysType::PackagedWSHP) {
6731 1 : this->m_NumOfSpeedHeating = fanSystem->numSpeeds;
6732 1 : this->m_HeatVolumeFlowRate.resize(fanSystem->numSpeeds + 1);
6733 1 : this->m_HeatMassFlowRate.resize(fanSystem->numSpeeds + 1);
6734 1 : this->m_MSHeatingSpeedRatio.resize(fanSystem->numSpeeds + 1);
6735 1 : this->m_MultiSpeedHeatingCoil = true;
6736 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6737 1 : if (fanSystem->maxAirFlowRate > 0.0) {
6738 0 : if (this->m_MaxHeatAirVolFlow != DataSizing::AutoSize) {
6739 0 : for (int i = 1; i <= this->m_NumOfSpeedHeating; ++i) {
6740 0 : this->m_HeatVolumeFlowRate[i] = fanSystem->maxAirFlowRate * fanSystem->flowFracAtSpeed[i - 1];
6741 0 : this->m_HeatMassFlowRate[i] = this->m_HeatVolumeFlowRate[i] * state.dataEnvrn->StdRhoAir;
6742 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6743 : }
6744 : } else {
6745 0 : for (int i = 1; i <= this->m_NumOfSpeedCooling; ++i) {
6746 0 : this->m_HeatMassFlowRate[i] = 0.0;
6747 0 : this->m_HeatVolumeFlowRate[i] = 0.0;
6748 0 : this->m_MSHeatingSpeedRatio[i] = 1.0;
6749 : }
6750 : }
6751 : }
6752 : }
6753 1 : if (((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
6754 0 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
6755 1 : this->m_sysType == SysType::PackagedWSHP) ||
6756 0 : ((this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
6757 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
6758 0 : this->m_sysType == SysType::PackagedWSHP)) {
6759 2 : ShowWarningError(state,
6760 2 : format("{} = {} with Fan:SystemModel is used in \"{}\"",
6761 : cCurrentModuleObject,
6762 1 : this->Name,
6763 1 : this->input_specs.supply_fan_name));
6764 1 : ShowContinueError(state, format("...The number of speed = {:.0R}.", double(fanSystem->numSpeeds)));
6765 1 : ShowContinueError(state, "...Multiple speed fan will be applied to this unit. The speed number is determined by load.");
6766 : }
6767 : }
6768 : }
6769 : }
6770 0 : } else if ((this->m_DesignSpecMultispeedHPType.empty() && !this->m_DesignSpecMultispeedHPName.empty()) ||
6771 0 : (!this->m_DesignSpecMultispeedHPType.empty() && this->m_DesignSpecMultispeedHPName.empty())) {
6772 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6773 0 : ShowContinueError(state, "... one or both of the following inputs are invalid.");
6774 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Type = {}", this->m_DesignSpecMultispeedHPType));
6775 0 : ShowContinueError(state, format("Field Design Specification Multispeed Object Name = {}", this->m_DesignSpecMultispeedHPName));
6776 0 : errorsFound = true;
6777 : }
6778 :
6779 622 : if (this->m_DiscreteSpeedCoolingCoil) {
6780 :
6781 76 : if (this->m_NumOfSpeedCooling == 0) {
6782 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6783 0 : ShowContinueError(state,
6784 0 : format("... Cooling coil object type requires valid {} for cooling to be specified with number of speeds > 0",
6785 : unitarySysHeatPumpPerformanceObjectType));
6786 0 : errorsFound = true;
6787 : }
6788 : }
6789 622 : if (this->m_MultiSpeedHeatingCoil) {
6790 :
6791 16 : if (this->m_DesignSpecMSHPIndex > -1) this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6792 :
6793 16 : if (this->m_NumOfSpeedHeating == 0) {
6794 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6795 0 : ShowContinueError(state,
6796 0 : format("... Heating coil object type requires valid {} for heating to be specified with number of speeds > 0",
6797 : unitarySysHeatPumpPerformanceObjectType));
6798 0 : errorsFound = true;
6799 : }
6800 : }
6801 :
6802 622 : if ((this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating &&
6803 13 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling)) ||
6804 610 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel &&
6805 78 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling || this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling))) {
6806 67 : if (this->m_DesignSpecMSHPIndex > -1) {
6807 53 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
6808 1 : this->m_SingleMode = 1;
6809 : }
6810 : }
6811 : } else {
6812 555 : if (this->m_DesignSpecMSHPIndex > -1) {
6813 9 : if (this->m_CompPointerMSHP->m_SingleModeFlag) {
6814 0 : ShowSevereError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6815 0 : ShowContinueError(state,
6816 : "In order to perform Single Mode Operation, the valid cooling coil type is Coil:Cooling:DX:MultiSpeed "
6817 : "or Coil:Cooling:DX and the valid heating is Coil:Heating:DX:MultiSpeed or Coil:Heating:Fuel.");
6818 0 : ShowContinueError(state,
6819 0 : format("The input cooling coil type = {} and the input heating coil type = {}",
6820 0 : input_data.cooling_coil_object_type,
6821 0 : this->m_HeatingCoilTypeName));
6822 : }
6823 : }
6824 : }
6825 :
6826 622 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
6827 10 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_CoolingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
6828 : }
6829 :
6830 622 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
6831 3 : VariableSpeedCoils::SetVarSpeedCoilData(state, this->m_HeatingCoilIndex, errorsFound, _, _, this->m_DesignSpecMSHPIndex);
6832 : }
6833 :
6834 : // set global logicals that denote coil type
6835 622 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
6836 23 : this->m_MultiOrVarSpeedHeatCoil = true;
6837 : }
6838 622 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
6839 91 : this->m_MultiOrVarSpeedCoolCoil = true;
6840 : }
6841 :
6842 : // set global variables for multi-stage chilled and hot water coils
6843 622 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
6844 20 : if (this->m_DesignSpecMSHPIndex > -1) {
6845 1 : this->m_NumOfSpeedCooling = this->m_CompPointerMSHP->numOfSpeedCooling;
6846 1 : if (this->m_NumOfSpeedCooling > 1) {
6847 1 : this->m_DiscreteSpeedCoolingCoil = true;
6848 1 : this->m_MultiOrVarSpeedCoolCoil = true;
6849 : }
6850 : }
6851 : }
6852 622 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
6853 : // designSpecIndex = this->m_DesignSpecMSHPIndex;
6854 9 : if (this->m_DesignSpecMSHPIndex > -1) {
6855 1 : this->m_NumOfSpeedHeating = this->m_CompPointerMSHP->numOfSpeedHeating;
6856 1 : if (this->m_NumOfSpeedHeating > 1) {
6857 1 : this->m_MultiSpeedHeatingCoil = true;
6858 1 : this->m_MultiOrVarSpeedHeatCoil = true;
6859 : }
6860 : }
6861 : }
6862 : // zone coils are now simulated before sizing is complete, data will not be available but array is allocated
6863 622 : if (this->m_MultiOrVarSpeedCoolCoil) {
6864 158 : this->m_CoolVolumeFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6865 158 : this->m_CoolMassFlowRate.resize(this->m_NumOfSpeedCooling + 1);
6866 158 : this->m_MSCoolingSpeedRatio.resize(this->m_NumOfSpeedCooling + 1);
6867 : }
6868 622 : if (this->m_MultiOrVarSpeedHeatCoil) {
6869 23 : this->m_HeatVolumeFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6870 23 : this->m_HeatMassFlowRate.resize(this->m_NumOfSpeedHeating + 1);
6871 23 : this->m_MSHeatingSpeedRatio.resize(this->m_NumOfSpeedHeating + 1);
6872 : }
6873 :
6874 : // check for specific input requirements for ASHRAE90.1 model
6875 622 : if (this->m_ControlType == UnitarySysCtrlType::CCMASHRAE) {
6876 :
6877 : // only allowed for water and DX cooling coils at this time
6878 0 : if (this->m_CoolCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWater &&
6879 0 : this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterDetailed && this->m_CoolingCoilType_Num != HVAC::CoilDX_CoolingSingleSpeed) {
6880 0 : if (state.dataGlobal->DisplayExtraWarnings) {
6881 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6882 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific cooling coil types.");
6883 0 : ShowContinueError(state,
6884 : "Valid cooling coil types are Coil:Cooling:Water, Coil:Cooling:Water:DetailedGeometry and "
6885 : "Coil:Cooling:DX:SingleSpeed.");
6886 0 : ShowContinueError(state,
6887 0 : format("The input cooling coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
6888 0 : input_data.cooling_coil_object_type));
6889 : }
6890 : // mark this coil as non-ASHRAE90 type
6891 0 : this->m_ValidASHRAECoolCoil = false;
6892 : }
6893 : // only allow for water, fuel, or electric at this time
6894 0 : if (this->m_HeatCoilExists && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWater &&
6895 0 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingGasOrOtherFuel && this->m_HeatingCoilType_Num != HVAC::Coil_HeatingElectric &&
6896 0 : this->m_HeatingCoilType_Num != HVAC::CoilDX_HeatingEmpirical) {
6897 0 : if (state.dataGlobal->DisplayExtraWarnings) {
6898 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6899 0 : ShowContinueError(state, "ASHRAE90.1 control method requires specific heating coil types.");
6900 0 : ShowContinueError(state,
6901 : "Valid heating coil types are Coil:Heating:Water, Coil:Heating:Fuel, Coil:Heating:Electric and "
6902 : "Coil:Heating:DX:SingleSpeed.");
6903 0 : ShowContinueError(state,
6904 0 : format("The input heating coil type = {}. This coil will not be modeled using the ASHRAE 90.1 algorithm.",
6905 0 : this->m_HeatingCoilTypeName));
6906 : }
6907 : // mark this coil as non-ASHRAE90 type
6908 0 : this->m_ValidASHRAEHeatCoil = false;
6909 : }
6910 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode || this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
6911 0 : ShowWarningError(state, format("{}: {}", cCurrentModuleObject, thisObjectName));
6912 0 : ShowContinueError(state, format("Invalid entry for Dehumidification Control Type = {}", input_data.dehumidification_control_type));
6913 0 : ShowContinueError(state,
6914 : "ASHRAE90.1 control method does not support dehumidification at this time. Dehumidification control type is "
6915 : "assumed to be None.");
6916 0 : this->m_DehumidControlType_Num = DehumCtrlType::None;
6917 : }
6918 0 : if (this->m_RunOnLatentLoad) {
6919 0 : ShowWarningError(state, format("{} = {}", cCurrentModuleObject, thisObjectName));
6920 0 : ShowContinueError(state, format("Invalid entry for Latent Load Control: {}", input_data.latent_load_control));
6921 0 : ShowContinueError(state,
6922 : "ASHRAE90.1 control method does not support latent load control at this time. This input must be selected as "
6923 : "SensibleOnlyLoadControl.");
6924 0 : this->m_RunOnSensibleLoad = true;
6925 0 : this->m_RunOnLatentLoad = false;
6926 0 : this->m_RunOnLatentOnlyWithSensible = false;
6927 : }
6928 0 : if (this->m_MaxNoCoolHeatAirVolFlow == 0.0) { // 0 min air flow not allowed for SZVAV
6929 0 : ShowSevereError(state, format("Input errors for {}:{}", cCurrentModuleObject, thisObjectName));
6930 0 : ShowContinueError(state, format("Control Type = {}", input_data.control_type));
6931 0 : ShowContinueError(state, "Input for No Load Supply Air Flow Rate cannot be 0.");
6932 0 : errorsFound = true;
6933 : }
6934 : }
6935 622 : }
6936 :
6937 787 : void UnitarySys::getDXCoilSystemData(
6938 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
6939 : {
6940 787 : std::string const cCurrentModuleObject = "CoilSystem:Cooling:DX";
6941 787 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
6942 787 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
6943 468 : auto &instancesValue = instances.value();
6944 468 : int numCoilSystemDX = 0;
6945 3048 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
6946 :
6947 2580 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
6948 : // only get the current data once all data has been read in and vector unitarySys has been initialized
6949 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the curren object
6950 2580 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
6951 :
6952 584 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
6953 584 : UnitarySys thisSys;
6954 584 : if (sysNum == -1) {
6955 292 : ++state.dataUnitarySystems->numUnitarySystems;
6956 292 : auto const &thisObjName = instance.key();
6957 292 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
6958 : } else {
6959 292 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
6960 : }
6961 :
6962 : // get CoilSystem:Cooling:DX object inputs
6963 584 : auto const &fields = instance.value();
6964 584 : thisSys.input_specs.name = thisObjectName;
6965 584 : thisSys.input_specs.system_type = cCurrentModuleObject;
6966 584 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
6967 572 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
6968 584 : }
6969 : thisSys.input_specs.air_inlet_node_name =
6970 584 : Util::makeUPPER(fields.at("dx_cooling_coil_system_inlet_node_name").get<std::string>()); // required field
6971 : thisSys.input_specs.air_outlet_node_name =
6972 584 : Util::makeUPPER(fields.at("dx_cooling_coil_system_outlet_node_name").get<std::string>()); // required field
6973 :
6974 : thisSys.input_specs.dx_cooling_coil_system_sensor_node_name =
6975 584 : Util::makeUPPER(fields.at("dx_cooling_coil_system_sensor_node_name").get<std::string>()); // required field
6976 :
6977 : thisSys.input_specs.cooling_coil_object_type =
6978 584 : Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>()); // required field
6979 584 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>()); // required field
6980 : // min-fields = 7, begin optional inputs
6981 584 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field
6982 : thisSys.input_specs.dehumidification_control_type =
6983 36 : it.value().get<std::string>(); // Don't capitalize this one, since it's an enum
6984 : } else {
6985 : // find default value
6986 548 : thisSys.input_specs.dehumidification_control_type = "None";
6987 584 : }
6988 584 : std::string loc_RunOnSensLoad("");
6989 584 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) { // not required field
6990 34 : loc_RunOnSensLoad = Util::makeUPPER(it.value().get<std::string>());
6991 : } else {
6992 : // find default value
6993 550 : loc_RunOnSensLoad = "YES";
6994 584 : }
6995 584 : std::string loc_RunOnLatLoad("");
6996 584 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) { // not required field
6997 34 : loc_RunOnLatLoad = Util::makeUPPER(it.value().get<std::string>());
6998 : } else {
6999 : // find default value
7000 550 : loc_RunOnLatLoad = "NO";
7001 584 : }
7002 584 : if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "NO") {
7003 570 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7004 14 : } else if (loc_RunOnSensLoad == "NO" && loc_RunOnLatLoad == "YES") {
7005 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7006 14 : } else if (loc_RunOnSensLoad == "YES" && loc_RunOnLatLoad == "YES") {
7007 : // does DX system control on LatentOrSensibleLoadControl or LatentWithSensibleLoadControl?
7008 14 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7009 : }
7010 :
7011 584 : if (auto it = fields.find("use_outdoor_air_dx_cooling_coil"); it != fields.end()) { // not required field
7012 10 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7013 : } else {
7014 : // find default value
7015 574 : thisSys.input_specs.use_doas_dx_cooling_coil = "NO";
7016 584 : }
7017 584 : if (auto it = fields.find("outdoor_air_dx_cooling_coil_leaving_minimum_air_temperature"); it != fields.end()) { // not required field
7018 8 : thisSys.input_specs.minimum_supply_air_temperature = it.value().get<Real64>();
7019 584 : }
7020 : // set UnitarySystem specific inputs
7021 584 : thisSys.input_specs.control_type = "SETPOINT";
7022 :
7023 : // now translate to UnitarySystem
7024 584 : thisSys.UnitType = cCurrentModuleObject;
7025 584 : thisSys.m_sysType = SysType::CoilCoolingDX;
7026 584 : thisSys.AirloopEqType = SimAirServingZones::CompType::DXSystem;
7027 :
7028 : // TODO: figure out another way to set this next variable
7029 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7030 584 : thisSys.m_LastMode = CoolingMode;
7031 584 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7032 :
7033 584 : if (sysNum == -1) {
7034 292 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7035 292 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7036 : // zone equipment require a 1-n index for access to zone availability managers
7037 : // although not zone equipment, use same methodology
7038 292 : ++numCoilSystemDX;
7039 292 : thisSys.m_EquipCompNum = numCoilSystemDX;
7040 : } else {
7041 292 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7042 : }
7043 3048 : }
7044 : }
7045 787 : }
7046 :
7047 787 : void UnitarySys::getPackagedTerminalUnitData(
7048 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7049 : {
7050 787 : std::string cCurrentModuleObject = "ZoneHVAC:PackagedTerminalAirConditioner";
7051 787 : SysType sysTypeNum = SysType::PackagedAC;
7052 787 : DataZoneEquipment::ZoneEquipType zoneEqType = DataZoneEquipment::ZoneEquipType::Invalid;
7053 787 : int numPTAC = 0;
7054 787 : int numPTHP = 0;
7055 787 : int numPTWSHP = 0;
7056 787 : auto &ip = state.dataInputProcessing->inputProcessor;
7057 3148 : for (int getPTUnitType = 1; getPTUnitType <= 3; ++getPTUnitType) {
7058 2361 : if (getPTUnitType == 2) {
7059 787 : sysTypeNum = SysType::PackagedHP;
7060 787 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7061 787 : cCurrentModuleObject = "ZoneHVAC:PackagedTerminalHeatPump";
7062 1574 : } else if (getPTUnitType == 3) {
7063 787 : sysTypeNum = SysType::PackagedWSHP;
7064 787 : zoneEqType = DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner;
7065 787 : cCurrentModuleObject = "ZoneHVAC:WaterToAirHeatPump";
7066 : }
7067 2361 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7068 2361 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7069 256 : auto &instancesValue = instances.value();
7070 256 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
7071 5783 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7072 :
7073 5527 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7074 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7075 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the curren object
7076 5527 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
7077 :
7078 394 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7079 394 : UnitarySys thisSys;
7080 394 : if (sysNum == -1) {
7081 197 : ++state.dataUnitarySystems->numUnitarySystems;
7082 197 : auto const &thisObjName = instance.key();
7083 197 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7084 : } else {
7085 197 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7086 : }
7087 :
7088 : // get PackagedTerminal unit object inputs
7089 394 : auto const &fields = instance.value();
7090 394 : thisSys.input_specs.name = thisObjectName;
7091 394 : thisSys.input_specs.system_type = cCurrentModuleObject;
7092 394 : thisSys.input_specs.availability_schedule_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_schedule_name");
7093 394 : thisSys.input_specs.air_inlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_inlet_node_name");
7094 394 : thisSys.input_specs.air_outlet_node_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "air_outlet_node_name");
7095 :
7096 394 : thisSys.input_specs.oa_mixer_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_object_type");
7097 394 : thisSys.input_specs.oa_mixer_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_air_mixer_name");
7098 :
7099 394 : thisSys.input_specs.cooling_supply_air_flow_rate =
7100 394 : ip->getRealFieldValue(fields, objectSchemaProps, "cooling_supply_air_flow_rate");
7101 394 : thisSys.input_specs.heating_supply_air_flow_rate =
7102 394 : ip->getRealFieldValue(fields, objectSchemaProps, "heating_supply_air_flow_rate");
7103 394 : thisSys.input_specs.no_load_supply_air_flow_rate =
7104 394 : ip->getRealFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate");
7105 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed =
7106 394 : ip->getAlphaFieldValue(fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7107 394 : thisSys.input_specs.cooling_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_outdoor_air_flow_rate");
7108 394 : thisSys.input_specs.heating_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "heating_outdoor_air_flow_rate");
7109 394 : thisSys.input_specs.no_load_oa_flow_rate = ip->getRealFieldValue(fields, objectSchemaProps, "no_load_outdoor_air_flow_rate");
7110 :
7111 394 : thisSys.input_specs.supply_fan_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_object_type");
7112 394 : thisSys.input_specs.supply_fan_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_name");
7113 394 : thisSys.input_specs.heating_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_object_type");
7114 394 : thisSys.input_specs.heating_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "heating_coil_name");
7115 394 : thisSys.input_specs.cooling_coil_object_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_object_type");
7116 394 : thisSys.input_specs.cooling_coil_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "cooling_coil_name");
7117 :
7118 394 : thisSys.input_specs.fan_placement = ip->getAlphaFieldValue(fields, objectSchemaProps, "fan_placement");
7119 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name =
7120 394 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supply_air_fan_operating_mode_schedule_name");
7121 394 : if (getPTUnitType > 1) {
7122 110 : thisSys.input_specs.maximum_supply_air_temperature_from_supplemental_heater =
7123 110 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_from_supplemental_heater");
7124 : thisSys.input_specs.supplemental_heating_coil_object_type =
7125 110 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_object_type");
7126 : thisSys.input_specs.supplemental_heating_coil_name =
7127 110 : ip->getAlphaFieldValue(fields, objectSchemaProps, "supplemental_heating_coil_name");
7128 110 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = ip->getRealFieldValue(
7129 : fields, objectSchemaProps, "maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7130 110 : if (getPTUnitType == 2) {
7131 56 : thisSys.input_specs.heat_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "heating_convergence_tolerance");
7132 56 : thisSys.input_specs.cool_conv_tol = ip->getRealFieldValue(fields, objectSchemaProps, "cooling_convergence_tolerance");
7133 54 : } else if (getPTUnitType == 3) {
7134 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name =
7135 54 : ip->getAlphaFieldValue(fields, objectSchemaProps, "outdoor_dry_bulb_temperature_sensor_node_name");
7136 : thisSys.input_specs.heat_pump_coil_water_flow_mode =
7137 54 : ip->getAlphaFieldValue(fields, objectSchemaProps, "heat_pump_coil_water_flow_mode");
7138 54 : thisSys.input_specs.control_type = "LOAD";
7139 : }
7140 : }
7141 394 : if (getPTUnitType < 3) {
7142 340 : thisSys.input_specs.control_type = ip->getAlphaFieldValue(fields, objectSchemaProps, "capacity_control_method");
7143 340 : if (thisSys.input_specs.control_type.empty() || thisSys.input_specs.control_type == "NONE") {
7144 340 : thisSys.input_specs.control_type = "LOAD";
7145 : }
7146 340 : thisSys.input_specs.minimum_supply_air_temperature =
7147 340 : ip->getRealFieldValue(fields, objectSchemaProps, "minimum_supply_air_temperature_in_cooling_mode");
7148 340 : thisSys.input_specs.maximum_supply_air_temperature =
7149 340 : ip->getRealFieldValue(fields, objectSchemaProps, "maximum_supply_air_temperature_in_heating_mode");
7150 : }
7151 :
7152 394 : thisSys.input_specs.avail_manager_list_name = ip->getAlphaFieldValue(fields, objectSchemaProps, "availability_manager_list_name");
7153 : thisSys.input_specs.design_spec_zonehvac_sizing_object_name =
7154 394 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_zonehvac_sizing_object_name");
7155 :
7156 394 : if (getPTUnitType == 3) {
7157 : thisSys.m_DesignSpecMultispeedHPType =
7158 54 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_type");
7159 : thisSys.m_DesignSpecMultispeedHPName =
7160 54 : ip->getAlphaFieldValue(fields, objectSchemaProps, "design_specification_multispeed_object_name");
7161 54 : if (!thisSys.m_DesignSpecMultispeedHPType.empty() && !thisSys.m_DesignSpecMultispeedHPName.empty()) {
7162 4 : DesignSpecMSHP thisDesignSpec;
7163 4 : thisSys.m_CompPointerMSHP =
7164 4 : thisDesignSpec.factory(state, HVAC::UnitarySysType::Furnace_HeatOnly, thisSys.m_DesignSpecMultispeedHPName);
7165 4 : thisSys.m_DesignSpecMSHPIndex = getDesignSpecMSHPIndex(state, thisSys.m_DesignSpecMultispeedHPName);
7166 4 : }
7167 : }
7168 :
7169 : // set UnitarySystem specific inputs
7170 394 : thisSys.input_specs.dehumidification_control_type = "None";
7171 394 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7172 394 : thisSys.input_specs.cooling_supply_air_flow_rate_method = "SupplyAirFlowRate";
7173 394 : thisSys.input_specs.heating_supply_air_flow_rate_method = "SupplyAirFlowRate";
7174 394 : thisSys.input_specs.no_load_supply_air_flow_rate_method = "SupplyAirFlowRate";
7175 :
7176 394 : thisSys.UnitType = cCurrentModuleObject;
7177 394 : thisSys.m_sysType = sysTypeNum;
7178 394 : thisSys.zoneEquipType = zoneEqType;
7179 :
7180 : // TODO: figure out another way to set this next variable
7181 : // Unitary System will not turn on unless this mode is set OR a different method is used to set air flow rate
7182 394 : thisSys.m_LastMode = HeatingMode;
7183 394 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7184 :
7185 394 : if (sysNum == -1) {
7186 : // zone equipment require a 1-n index for access to zone availability managers
7187 197 : switch (getPTUnitType) {
7188 142 : case 1: // Excuse me?
7189 142 : ++numPTAC;
7190 142 : thisSys.m_EquipCompNum = numPTAC;
7191 142 : break;
7192 28 : case 2: // Baking powder?
7193 28 : ++numPTHP;
7194 28 : thisSys.m_EquipCompNum = numPTHP;
7195 28 : break;
7196 27 : case 3:
7197 27 : ++numPTWSHP;
7198 27 : thisSys.m_EquipCompNum = numPTWSHP;
7199 27 : break;
7200 197 : default:
7201 : assert(true);
7202 : }
7203 197 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7204 197 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7205 : } else {
7206 197 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7207 : }
7208 5783 : }
7209 : }
7210 2361 : }
7211 787 : }
7212 :
7213 787 : void UnitarySys::allocateUnitarySys(EnergyPlusData &state)
7214 : {
7215 787 : if (!state.dataUnitarySystems->unitarySys.empty()) return;
7216 165 : int numUnitarySystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:UnitarySystem");
7217 165 : int numCoilSystems = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:DX");
7218 165 : int numCoilSystemsWater = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoilSystem:Cooling:Water");
7219 165 : int numPackagedAC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalAirConditioner");
7220 165 : int numPackagedHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:PackagedTerminalHeatPump");
7221 165 : int numPackagedWSHP = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:WaterToAirHeatPump");
7222 165 : int numAllSystemTypes = numUnitarySystems + numCoilSystems + numCoilSystemsWater + numPackagedAC + numPackagedHP + numPackagedWSHP;
7223 787 : for (int sysCount = 0; sysCount < numAllSystemTypes; ++sysCount) {
7224 622 : UnitarySys thisSys;
7225 622 : state.dataUnitarySystems->unitarySys.push_back(thisSys);
7226 622 : }
7227 : }
7228 :
7229 787 : void UnitarySys::getCoilWaterSystemInputData(
7230 : EnergyPlusData &state, std::string_view CoilSysName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7231 : {
7232 :
7233 787 : std::string cCurrentModuleObject("CoilSystem:Cooling:Water");
7234 787 : static const std::string routineName("getCoilWaterSystemInputData: ");
7235 787 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7236 787 : if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7237 8 : auto &instancesValue = instances.value();
7238 8 : int numCoilSystemWater = 0;
7239 16 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7240 :
7241 8 : auto const &fields = instance.value();
7242 8 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7243 8 : if (!Util::SameString(CoilSysName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
7244 :
7245 6 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7246 6 : UnitarySys thisSys;
7247 6 : if (sysNum == -1) {
7248 3 : ++state.dataUnitarySystems->numUnitarySystems;
7249 3 : auto const &thisObjName = instance.key();
7250 3 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7251 : } else {
7252 3 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7253 : }
7254 :
7255 6 : thisSys.input_specs.name = thisObjectName;
7256 6 : thisSys.input_specs.system_type = cCurrentModuleObject;
7257 6 : thisSys.input_specs.control_type = "Setpoint";
7258 6 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>());
7259 6 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>());
7260 6 : std::string availScheduleName("");
7261 6 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field, has default value of Always On
7262 2 : availScheduleName = Util::makeUPPER(it.value().get<std::string>());
7263 6 : }
7264 6 : thisSys.input_specs.availability_schedule_name = availScheduleName;
7265 6 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(fields.at("cooling_coil_object_type").get<std::string>());
7266 6 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(fields.at("cooling_coil_name").get<std::string>());
7267 : // why is this cooling coil does not have a field for Design Air Vol Flow Rate
7268 : // set it "SupplyAirFlowRate" to avoid blank, which lead to fatal out during get input
7269 : static constexpr std::string_view loc_cooling_coil_object_type("COIL:COOLING:WATER:DETAILEDGEOMETRY");
7270 6 : if (Util::SameString(loc_cooling_coil_object_type, thisSys.input_specs.cooling_coil_object_type)) {
7271 0 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER("SupplyAirFlowRate");
7272 0 : thisSys.input_specs.cooling_supply_air_flow_rate = DataSizing::AutoSize;
7273 : }
7274 : // optional input fields
7275 6 : if (auto it = fields.find("minimum_air_to_water_temperature_offset");
7276 6 : it != fields.end()) { // not required field, has default value of 0.0
7277 6 : thisSys.m_minAirToWaterTempOffset = it.value().get<Real64>();
7278 6 : }
7279 6 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) {
7280 4 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7281 : } else {
7282 2 : thisSys.input_specs.dehumidification_control_type = "None";
7283 6 : }
7284 :
7285 6 : bool runOnSensibleLoad = true;
7286 6 : if (auto it = fields.find("run_on_sensible_load"); it != fields.end()) {
7287 4 : runOnSensibleLoad = Util::SameString(it.value().get<std::string>(), "YES");
7288 6 : }
7289 6 : bool runOnLatentLoad = false;
7290 6 : if (auto it = fields.find("run_on_latent_load"); it != fields.end()) {
7291 4 : runOnLatentLoad = Util::SameString(it.value().get<std::string>(), "YES");
7292 6 : }
7293 :
7294 6 : if (runOnSensibleLoad && !runOnLatentLoad) {
7295 2 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7296 4 : } else if (!runOnSensibleLoad && runOnLatentLoad) {
7297 0 : thisSys.input_specs.latent_load_control = "LatentOnlyLoadControl";
7298 4 : } else if (runOnSensibleLoad && runOnLatentLoad) {
7299 4 : thisSys.input_specs.latent_load_control = "LatentOrSensibleLoadControl";
7300 : }
7301 :
7302 : // now translate to UnitarySystem
7303 6 : thisSys.UnitType = cCurrentModuleObject;
7304 6 : thisSys.m_sysType = SysType::CoilCoolingWater;
7305 6 : thisSys.AirloopEqType = SimAirServingZones::CompType::CoilSystemWater;
7306 6 : thisSys.input_specs.control_type = "Setpoint";
7307 6 : thisSys.m_CoolCoilExists = true; // is always true
7308 6 : thisSys.m_LastMode = CoolingMode;
7309 : // set water-side economizer flag
7310 6 : if (thisSys.m_minAirToWaterTempOffset > 0.0) thisSys.m_TemperatureOffsetControlActive = true;
7311 :
7312 : // heat recovery loop inputs
7313 6 : if (auto it = fields.find("minimum_water_loop_temperature_for_heat_recovery"); it != fields.end()) {
7314 2 : thisSys.m_minWaterLoopTempForHR = it.value().get<Real64>();
7315 6 : }
7316 6 : if (auto it = fields.find("economizer_lockout"); it != fields.end()) { // duplicate above as default
7317 0 : bool econoFlag = Util::SameString(it.value().get<std::string>(), "YES");
7318 0 : if (econoFlag) {
7319 0 : thisSys.m_waterSideEconomizerFlag = true;
7320 : }
7321 : } else {
7322 6 : thisSys.m_waterSideEconomizerFlag = true;
7323 6 : }
7324 6 : std::string HRWaterCoolingCoilName;
7325 6 : if (auto it = fields.find("companion_coil_used_for_heat_recovery"); it != fields.end()) {
7326 2 : HRWaterCoolingCoilName = Util::makeUPPER(it.value().get<std::string>());
7327 2 : thisSys.m_WaterHRPlantLoopModel = true;
7328 6 : }
7329 6 : if (thisSys.m_WaterHRPlantLoopModel) {
7330 2 : std::string const HRcoolingCoilType("COIL:COOLING:WATER");
7331 2 : bool errFound = false;
7332 2 : thisSys.m_HRcoolCoilAirInNode = WaterCoils::GetCoilInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7333 2 : thisSys.m_HRcoolCoilFluidInletNode =
7334 2 : WaterCoils::GetCoilWaterInletNode(state, HRcoolingCoilType, HRWaterCoolingCoilName, errFound);
7335 2 : int HRCoilIndex = WaterCoils::GetWaterCoilIndex(state, Util::makeUPPER(HRcoolingCoilType), HRWaterCoolingCoilName, errFound);
7336 2 : bool heatRecoveryCoil = true; // use local here to highlight where this parameter is set
7337 2 : WaterCoils::SetWaterCoilData(state, HRCoilIndex, errFound, _, _, heatRecoveryCoil);
7338 2 : if (errFound) {
7339 0 : if (HRCoilIndex == 0) {
7340 0 : ShowContinueError(state, format("...cooling coil {} must be of type Coil:Cooling:Water.", HRWaterCoolingCoilName));
7341 : }
7342 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisObjectName));
7343 : }
7344 2 : errorsFound = errorsFound || errFound;
7345 2 : }
7346 : // end heat recovery loop inputs
7347 :
7348 6 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7349 :
7350 6 : if (sysNum == -1) {
7351 3 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7352 3 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7353 : // zone equipment require a 1-n index for access to zone availability managers
7354 : // although not zone equipment, use same methodology
7355 3 : ++numCoilSystemWater;
7356 3 : thisSys.m_EquipCompNum = numCoilSystemWater;
7357 : } else {
7358 3 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7359 : }
7360 16 : }
7361 :
7362 8 : if (errorsFound) {
7363 0 : ShowFatalError(
7364 : state,
7365 0 : format("{}Errors found in getting {} input. Preceding condition(s) causes termination.", routineName, cCurrentModuleObject));
7366 : }
7367 : }
7368 787 : }
7369 :
7370 787 : void UnitarySys::getUnitarySystemInputData(
7371 : EnergyPlusData &state, std::string_view objectName, bool const ZoneEquipment, int const ZoneOAUnitNum, bool &errorsFound)
7372 : {
7373 :
7374 787 : std::string const cCurrentModuleObject = "AirLoopHVAC:UnitarySystem";
7375 787 : static std::string const getUnitarySystemInput("getUnitarySystemInputData");
7376 787 : int zoneUnitaryNum = 0;
7377 787 : int airloopUnitaryNum = 0;
7378 :
7379 787 : auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
7380 787 : if (instances == state.dataInputProcessing->inputProcessor->epJSON.end() && state.dataUnitarySystems->numUnitarySystems == 0) {
7381 0 : ShowSevereError(state, "getUnitarySystemInputData: did not find AirLoopHVAC:UnitarySystem object in input file. Check inputs");
7382 0 : errorsFound = true;
7383 787 : } else if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
7384 219 : auto &instancesValue = instances.value();
7385 219 : auto const &objectSchemaProps = state.dataInputProcessing->inputProcessor->getObjectSchemaProps(state, cCurrentModuleObject);
7386 1248 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
7387 :
7388 1029 : std::string const &thisObjectName = Util::makeUPPER(instance.key());
7389 : // only get the current data once all data has been read in and vector unitarySys has been initialized
7390 : // when UnitarySystems::getInputOnceFlag is true read all unitary systems, otherwise read just the curren object
7391 1029 : if (!Util::SameString(objectName, thisObjectName) && !state.dataUnitarySystems->getInputOnceFlag) continue;
7392 :
7393 260 : int sysNum = getUnitarySystemIndex(state, thisObjectName);
7394 260 : UnitarySys thisSys;
7395 260 : if (sysNum == -1) {
7396 130 : ++state.dataUnitarySystems->numUnitarySystems;
7397 130 : auto const &thisObjName = instance.key();
7398 130 : state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjName);
7399 : } else {
7400 130 : thisSys = state.dataUnitarySystems->unitarySys[sysNum];
7401 : }
7402 :
7403 260 : auto const &fields = instance.value();
7404 260 : thisSys.UnitType = cCurrentModuleObject;
7405 260 : thisSys.m_sysType = SysType::Unitary;
7406 260 : thisSys.AirloopEqType = SimAirServingZones::CompType::UnitarySystemModel;
7407 :
7408 260 : thisSys.input_specs.name = thisObjectName;
7409 260 : thisSys.input_specs.system_type = cCurrentModuleObject;
7410 260 : thisSys.input_specs.control_type = fields.at("control_type").get<std::string>();
7411 260 : if (auto it = fields.find("controlling_zone_or_thermostat_location"); it != fields.end()) { // not required field
7412 244 : thisSys.input_specs.controlling_zone_or_thermostat_location = Util::makeUPPER(it.value().get<std::string>());
7413 260 : }
7414 260 : if (auto it = fields.find("dehumidification_control_type"); it != fields.end()) { // not required field, has default
7415 232 : thisSys.input_specs.dehumidification_control_type = it.value().get<std::string>();
7416 : } else {
7417 28 : thisSys.input_specs.dehumidification_control_type = "NONE"; // default value
7418 260 : }
7419 260 : if (auto it = fields.find("availability_schedule_name"); it != fields.end()) { // not required field
7420 160 : thisSys.input_specs.availability_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7421 260 : }
7422 260 : thisSys.input_specs.air_inlet_node_name = Util::makeUPPER(fields.at("air_inlet_node_name").get<std::string>()); // required
7423 260 : thisSys.input_specs.air_outlet_node_name = Util::makeUPPER(fields.at("air_outlet_node_name").get<std::string>()); // required
7424 260 : if (auto it = fields.find("supply_fan_object_type"); it != fields.end()) { // not required field
7425 256 : thisSys.input_specs.supply_fan_object_type = Util::makeUPPER(it.value().get<std::string>());
7426 260 : }
7427 :
7428 260 : if (auto it = fields.find("supply_fan_name"); it != fields.end()) { // not required field
7429 256 : thisSys.input_specs.supply_fan_name = Util::makeUPPER(it.value().get<std::string>());
7430 260 : }
7431 260 : if (auto it = fields.find("fan_placement"); it != fields.end()) { // not required field
7432 256 : thisSys.input_specs.fan_placement = Util::makeUPPER(it.value().get<std::string>());
7433 260 : }
7434 260 : if (auto it = fields.find("supply_air_fan_operating_mode_schedule_name"); it != fields.end()) { // not required field
7435 246 : thisSys.input_specs.supply_air_fan_operating_mode_schedule_name = Util::makeUPPER(it.value().get<std::string>());
7436 260 : }
7437 260 : if (auto it = fields.find("heating_coil_object_type"); it != fields.end()) { // not required field
7438 228 : thisSys.input_specs.heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7439 228 : thisSys.m_HeatCoilExists = true;
7440 260 : }
7441 260 : if (auto it = fields.find("heating_coil_name"); it != fields.end()) { // not required field
7442 228 : thisSys.input_specs.heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7443 260 : }
7444 260 : if (auto it = fields.find("dx_heating_coil_sizing_ratio"); it != fields.end()) { // not required field, has default
7445 176 : thisSys.input_specs.dx_heating_coil_sizing_ratio = it.value().get<Real64>();
7446 260 : }
7447 260 : if (auto it = fields.find("cooling_coil_object_type"); it != fields.end()) { // not required field
7448 258 : thisSys.input_specs.cooling_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7449 258 : thisSys.m_CoolCoilExists = true;
7450 260 : }
7451 260 : if (auto it = fields.find("cooling_coil_name"); it != fields.end()) { // not required field
7452 258 : thisSys.input_specs.cooling_coil_name = Util::makeUPPER(it.value().get<std::string>());
7453 260 : }
7454 260 : if (auto it = fields.find("use_doas_dx_cooling_coil"); it != fields.end()) { // not required field, has default
7455 74 : thisSys.input_specs.use_doas_dx_cooling_coil = Util::makeUPPER(it.value().get<std::string>());
7456 : } else {
7457 186 : thisSys.input_specs.use_doas_dx_cooling_coil = "No";
7458 260 : }
7459 260 : if (auto it = fields.find("minimum_supply_air_temperature");
7460 260 : it != fields.end()) { // not required field, has default (2C), and autosizable
7461 74 : thisSys.input_specs.minimum_supply_air_temperature =
7462 148 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7463 148 : ? DataSizing::AutoSize
7464 74 : : it.value().get<Real64>();
7465 260 : }
7466 260 : if (auto it = fields.find("latent_load_control"); it != fields.end()) { // not required field, has default
7467 102 : thisSys.input_specs.latent_load_control = it.value().get<std::string>();
7468 : } else {
7469 158 : thisSys.input_specs.latent_load_control = "SensibleOnlyLoadControl";
7470 260 : }
7471 260 : if (auto it = fields.find("supplemental_heating_coil_object_type"); it != fields.end()) { // not required field
7472 84 : thisSys.input_specs.supplemental_heating_coil_object_type = Util::makeUPPER(it.value().get<std::string>());
7473 260 : }
7474 260 : if (auto it = fields.find("supplemental_heating_coil_name"); it != fields.end()) { // not required field
7475 84 : thisSys.input_specs.supplemental_heating_coil_name = Util::makeUPPER(it.value().get<std::string>());
7476 260 : }
7477 260 : if (auto it = fields.find("cooling_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7478 256 : thisSys.input_specs.cooling_supply_air_flow_rate_method = Util::makeUPPER(it.value().get<std::string>());
7479 260 : }
7480 260 : if (auto it = fields.find("cooling_supply_air_flow_rate"); it != fields.end()) { // not required field, autosizable
7481 256 : thisSys.input_specs.cooling_supply_air_flow_rate =
7482 744 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7483 744 : ? DataSizing::AutoSize
7484 24 : : it.value().get<Real64>();
7485 260 : }
7486 260 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7487 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7488 260 : }
7489 260 : if (auto it = fields.find("cooling_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7490 0 : thisSys.input_specs.cooling_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7491 260 : }
7492 260 : if (auto it = fields.find("cooling_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7493 0 : thisSys.input_specs.cooling_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7494 260 : }
7495 260 : if (auto it = fields.find("heating_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7496 226 : thisSys.input_specs.heating_supply_air_flow_rate_method = it.value().get<std::string>();
7497 260 : }
7498 260 : if (auto it = fields.find("heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7499 226 : thisSys.input_specs.heating_supply_air_flow_rate =
7500 654 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7501 654 : ? DataSizing::AutoSize
7502 24 : : it.value().get<Real64>();
7503 260 : }
7504 260 : if (auto it = fields.find("heating_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7505 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7506 260 : }
7507 260 : if (auto it = fields.find("heating_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7508 0 : thisSys.input_specs.heating_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7509 260 : }
7510 260 : if (auto it = fields.find("heating_supply_air_flow_rate_per_unit_of_capacity"); it != fields.end()) { // not required field
7511 0 : thisSys.input_specs.heating_supply_air_flow_rate_per_unit_of_capacity = it.value().get<Real64>();
7512 260 : }
7513 260 : if (auto it = fields.find("no_load_supply_air_flow_rate_method"); it != fields.end()) { // not required field
7514 216 : thisSys.input_specs.no_load_supply_air_flow_rate_method = it.value().get<std::string>();
7515 260 : }
7516 260 : if (auto it = fields.find("no_load_supply_air_flow_rate"); it != fields.end()) { // not required field
7517 226 : thisSys.input_specs.no_load_supply_air_flow_rate =
7518 644 : (it.value().type() == nlohmann::detail::value_t::string && Util::SameString(it.value().get<std::string>(), "Autosize"))
7519 644 : ? DataSizing::AutoSize
7520 34 : : it.value().get<Real64>();
7521 260 : }
7522 260 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_floor_area"); it != fields.end()) { // not required field
7523 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_floor_area = it.value().get<Real64>();
7524 260 : }
7525 260 : if (auto it = fields.find("no_load_fraction_of_autosized_cooling_supply_air_flow_rate"); it != fields.end()) { // not required field
7526 0 : thisSys.input_specs.no_load_fraction_of_autosized_cooling_supply_air_flow_rate = it.value().get<Real64>();
7527 260 : }
7528 260 : if (auto it = fields.find("no_load_fraction_of_autosized_heating_supply_air_flow_rate"); it != fields.end()) { // not required field
7529 0 : thisSys.input_specs.no_load_fraction_of_autosized_heating_supply_air_flow_rate = it.value().get<Real64>();
7530 260 : }
7531 260 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation");
7532 260 : it != fields.end()) { // not required field
7533 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_cooling_operation = it.value().get<Real64>();
7534 260 : }
7535 260 : if (auto it = fields.find("no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation");
7536 260 : it != fields.end()) { // not required field
7537 0 : thisSys.input_specs.no_load_supply_air_flow_rate_per_unit_of_capacity_during_heating_operation = it.value().get<Real64>();
7538 260 : }
7539 520 : thisSys.input_specs.no_load_supply_air_flow_rate_low_speed = state.dataInputProcessing->inputProcessor->getAlphaFieldValue(
7540 260 : fields, objectSchemaProps, "no_load_supply_air_flow_rate_control_set_to_low_speed");
7541 260 : if (fields.find("maximum_supply_air_temperature") != fields.end()) { // not required field, has default of 80 C
7542 224 : auto const &obj = fields.at("maximum_supply_air_temperature");
7543 224 : thisSys.input_specs.maximum_supply_air_temperature =
7544 404 : (obj.type() == nlohmann::detail::value_t::string && Util::SameString(obj.get<std::string>(), "Autosize"))
7545 404 : ? DataSizing::AutoSize
7546 44 : : obj.get<Real64>();
7547 : }
7548 260 : if (auto it = fields.find("maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation");
7549 260 : it != fields.end()) { // not required field, has default
7550 130 : thisSys.input_specs.maximum_outdoor_dry_bulb_temperature_for_supplemental_heater_operation = it.value().get<Real64>();
7551 260 : }
7552 260 : if (auto it = fields.find("outdoor_dry_bulb_temperature_sensor_node_name"); it != fields.end()) { // not required field
7553 12 : thisSys.input_specs.outdoor_dry_bulb_temperature_sensor_node_name = Util::makeUPPER(it.value().get<std::string>());
7554 260 : }
7555 260 : if (auto it = fields.find("ancillary_on_cycle_electric_power"); it != fields.end()) { // not required field, has default
7556 10 : thisSys.input_specs.ancillary_on_cycle_electric_power = it.value().get<Real64>();
7557 260 : }
7558 260 : if (auto it = fields.find("ancillary_off_cycle_electric_power"); it != fields.end()) { // not required field, has default
7559 10 : thisSys.input_specs.ancillary_off_cycle_electric_power = it.value().get<Real64>();
7560 260 : }
7561 260 : if (auto it = fields.find("design_heat_recovery_water_flow_rate"); it != fields.end()) { // not required field, has default
7562 0 : thisSys.input_specs.design_heat_recovery_water_flow_rate = it.value().get<Real64>();
7563 260 : }
7564 260 : if (auto it = fields.find("maximum_temperature_for_heat_recovery"); it != fields.end()) { // not required field, has default
7565 0 : thisSys.input_specs.maximum_temperature_for_heat_recovery = it.value().get<Real64>();
7566 260 : }
7567 260 : if (auto it = fields.find("heat_recovery_water_inlet_node_name"); it != fields.end()) { // not required field
7568 0 : thisSys.input_specs.heat_recovery_water_inlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7569 260 : }
7570 260 : if (auto it = fields.find("heat_recovery_water_outlet_node_name"); it != fields.end()) { // not required field
7571 0 : thisSys.input_specs.heat_recovery_water_outlet_node_name = Util::makeUPPER(it.value().get<std::string>());
7572 260 : }
7573 260 : if (auto it = fields.find("design_specification_multispeed_object_type"); it != fields.end()) { // not required field
7574 120 : thisSys.input_specs.design_specification_multispeed_object_type = Util::makeUPPER(it.value().get<std::string>());
7575 260 : }
7576 260 : if (auto it = fields.find("design_specification_multispeed_object_name"); it != fields.end()) { // not required field
7577 120 : thisSys.input_specs.design_specification_multispeed_object_name = Util::makeUPPER(it.value().get<std::string>());
7578 260 : }
7579 :
7580 260 : thisSys.processInputSpec(state, thisSys.input_specs, sysNum, errorsFound, ZoneEquipment, ZoneOAUnitNum);
7581 :
7582 260 : if (sysNum == -1) {
7583 130 : ++thisSys.m_UnitarySysNum;
7584 130 : if (ZoneEquipment) {
7585 : // zone equipment require a 1-n index for access to zone availability managers
7586 25 : ++zoneUnitaryNum;
7587 25 : thisSys.m_EquipCompNum = zoneUnitaryNum;
7588 : } else {
7589 : // zone equipment require a 1-n index for access to zone availability managers
7590 : // although not zone equipment, use same methodology
7591 : // keep OA system unitary equipment indexes separate?
7592 105 : ++airloopUnitaryNum;
7593 105 : thisSys.m_EquipCompNum = airloopUnitaryNum;
7594 : }
7595 130 : int thisSysNum = state.dataUnitarySystems->numUnitarySystems - 1;
7596 130 : state.dataUnitarySystems->unitarySys[thisSysNum] = thisSys;
7597 : } else {
7598 130 : state.dataUnitarySystems->unitarySys[sysNum] = thisSys;
7599 : }
7600 1248 : }
7601 : }
7602 787 : }
7603 :
7604 127610 : void UnitarySys::calcUnitarySuppSystemToSP(EnergyPlusData &state, bool const FirstHVACIteration // True when first HVAC iteration
7605 : )
7606 : {
7607 :
7608 : // SUBROUTINE INFORMATION:
7609 : // AUTHOR Richard Raustad, FSEC
7610 : // DATE WRITTEN February 2013
7611 :
7612 : // PURPOSE OF THIS SUBROUTINE:
7613 : // This subroutine manages supplemental heater component simulation for setpoint based operation scheme.
7614 :
7615 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7616 : Real64 QActual;
7617 :
7618 127610 : std::string CompName = this->m_SuppHeatCoilName;
7619 127610 : int CoilType_Num = this->m_SuppHeatCoilType_Num;
7620 :
7621 127610 : if ((CoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel) || (CoilType_Num == HVAC::Coil_HeatingElectric)) {
7622 446850 : HeatingCoils::SimulateHeatingCoilComponents(state,
7623 : CompName,
7624 : FirstHVACIteration,
7625 178740 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7626 89370 : this->m_SuppHeatCoilIndex,
7627 : _,
7628 178740 : true,
7629 89370 : this->m_FanOpMode,
7630 89370 : this->m_SuppHeatPartLoadFrac);
7631 :
7632 38240 : } else if (CoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
7633 59614 : HeatingCoils::SimulateHeatingCoilComponents(state,
7634 : CompName,
7635 : FirstHVACIteration,
7636 : _,
7637 29807 : this->m_SuppHeatCoilIndex,
7638 : _,
7639 : _,
7640 29807 : this->m_FanOpMode,
7641 29807 : this->m_SuppHeatPartLoadFrac,
7642 29807 : this->m_SuppHeatingSpeedNum,
7643 29807 : this->m_SuppHeatingSpeedRatio);
7644 :
7645 8433 : } else if (CoilType_Num == HVAC::Coil_HeatingDesuperheater) {
7646 33732 : HeatingCoils::SimulateHeatingCoilComponents(state,
7647 : CompName,
7648 : FirstHVACIteration,
7649 16866 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7650 8433 : this->m_SuppHeatCoilIndex,
7651 : _,
7652 : _,
7653 8433 : this->m_FanOpMode,
7654 8433 : this->m_SuppHeatPartLoadFrac);
7655 :
7656 0 : } else if (CoilType_Num == HVAC::Coil_HeatingWater) {
7657 0 : WaterCoils::SimulateWaterCoilComponents(
7658 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, QActual, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
7659 :
7660 0 : } else if (CoilType_Num == HVAC::Coil_HeatingSteam) {
7661 0 : SteamCoils::SimulateSteamCoilComponents(state,
7662 : CompName,
7663 : FirstHVACIteration,
7664 0 : this->m_SuppHeatCoilIndex,
7665 0 : this->m_DesignSuppHeatingCapacity * this->m_SuppHeatPartLoadFrac,
7666 : _,
7667 0 : this->m_FanOpMode,
7668 0 : this->m_SuppHeatPartLoadFrac);
7669 : }
7670 127610 : }
7671 :
7672 4098019 : void UnitarySys::controlUnitarySystemtoLoad(EnergyPlusData &state,
7673 : int const AirLoopNum, // Primary air loop number
7674 : bool const FirstHVACIteration, // True when first HVAC iteration
7675 : HVAC::CompressorOp &CompressorOn, // Determines if compressor is on or off
7676 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7677 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7678 : Real64 &sysOutputProvided, // system sensible output at supply air node
7679 : Real64 &latOutputProvided // sytsem latent output at supply air node
7680 : )
7681 : {
7682 :
7683 : // SUBROUTINE INFORMATION:
7684 : // AUTHOR Richard Raustad, FSEC
7685 : // DATE WRITTEN February 2013
7686 4098019 : Real64 ZoneLoad = 0.0; // zone load (W)
7687 4098019 : Real64 SupHeaterLoad = 0.0; // additional heating required by supplemental heater (W)
7688 4098019 : Real64 OnOffAirFlowRatio = 1.0;
7689 4098019 : this->updateUnitarySystemControl(state,
7690 : AirLoopNum,
7691 : this->CoolCoilOutletNodeNum,
7692 : this->CoolCtrlNode,
7693 : OnOffAirFlowRatio,
7694 : FirstHVACIteration,
7695 : OAUCoilOutTemp,
7696 : ZoneLoad,
7697 : this->DesignMaxOutletTemp);
7698 :
7699 : // will not be running supplemental heater on this CALL (simulate with supplemental heater off)
7700 4098019 : Real64 FullSensibleOutput = 0.0;
7701 : // using furnace module logic
7702 : // first check to see if cycling fan with economizer can meet the load
7703 4098019 : if (AirLoopNum > 0) {
7704 2660380 : if (this->m_CoolCoilExists && this->m_HeatCoilExists && this->m_CoolingCoilType_Num != HVAC::Coil_CoolingAirToAirVariableSpeed &&
7705 2393252 : this->m_HeatingCoilType_Num != HVAC::Coil_HeatingAirToAirVariableSpeed && !FirstHVACIteration &&
7706 5517386 : this->m_FanOpMode == HVAC::FanOp::Cycling && state.dataUnitarySystems->CoolingLoad &&
7707 196626 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
7708 70610 : CompressorOn = HVAC::CompressorOp::Off;
7709 70610 : this->controlUnitarySystemOutput(
7710 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7711 70610 : if (this->m_CoolingPartLoadFrac >= 1.0 || this->m_HeatingPartLoadFrac >= 1.0 ||
7712 66969 : (this->m_CoolingPartLoadFrac <= 0.0 && this->m_HeatingPartLoadFrac <= 0.0)) {
7713 67988 : CompressorOn = HVAC::CompressorOp::On;
7714 67988 : this->controlUnitarySystemOutput(
7715 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7716 : }
7717 : } else {
7718 2589770 : CompressorOn = HVAC::CompressorOp::On;
7719 2589770 : this->controlUnitarySystemOutput(
7720 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7721 : }
7722 : } else {
7723 1437639 : CompressorOn = HVAC::CompressorOp::On;
7724 1437639 : this->controlUnitarySystemOutput(
7725 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
7726 : }
7727 4709976 : if (state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate < HVAC::SmallMassFlow && this->m_sysType != SysType::PackagedAC &&
7728 4709976 : this->m_sysType != SysType::PackagedHP && this->m_sysType != SysType::PackagedWSHP) {
7729 571498 : state.dataUnitarySystems->CoolingLoad = false;
7730 571498 : state.dataUnitarySystems->HeatingLoad = false;
7731 571498 : state.dataUnitarySystems->MoistureLoad = 0.0;
7732 571498 : this->m_CoolingPartLoadFrac = 0.0;
7733 571498 : this->m_HeatingPartLoadFrac = 0.0;
7734 571498 : if (this->CoolCoilFluidInletNode > 0) state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
7735 571498 : if (this->HeatCoilFluidInletNode > 0) state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = 0.0;
7736 571498 : this->setAverageAirFlow(state, this->m_CoolingPartLoadFrac, OnOffAirFlowRatio);
7737 : // anything else need to be reset here when system is shut down on low flow?
7738 : }
7739 4098019 : Real64 CoolPLR = this->m_CoolingPartLoadFrac;
7740 4098019 : Real64 HeatPLR = this->m_HeatingPartLoadFrac;
7741 4098019 : Real64 HeatCoilLoad = HeatPLR * this->m_DesignHeatingCapacity;
7742 :
7743 4098019 : if (this->CoolCoilFluidInletNode > 0) {
7744 393018 : PlantUtilities::SetComponentFlowRate(state,
7745 196509 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate,
7746 : this->CoolCoilFluidInletNode,
7747 : this->CoolCoilFluidOutletNodeNum,
7748 196509 : this->CoolCoilPlantLoc);
7749 : }
7750 4098019 : if (this->HeatCoilFluidInletNode > 0) {
7751 157188 : PlantUtilities::SetComponentFlowRate(state,
7752 78594 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate,
7753 : this->HeatCoilFluidInletNode,
7754 : this->HeatCoilFluidOutletNodeNum,
7755 78594 : this->HeatCoilPlantLoc);
7756 : }
7757 :
7758 5352196 : if (this->m_SuppCoilExists &&
7759 1254177 : (state.dataUnitarySystems->HeatingLoad || state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < 0.0)) {
7760 915616 : if ((FullSensibleOutput < (state.dataUnitarySystems->QToHeatSetPt - HVAC::SmallLoad)) && !FirstHVACIteration) {
7761 255493 : SupHeaterLoad = max(0.0, state.dataUnitarySystems->QToHeatSetPt - FullSensibleOutput);
7762 255493 : this->m_SupHeaterLoad = 0.0;
7763 : // what does this line even do? I know we want the supplemental heater on only if there is a dehum load,
7764 : // but for HP's the supp heater should also run if the heating coil can't turn on
7765 : // (i.e., this line calc's a supp heater load, then next line also calc's it?)
7766 255493 : if (state.dataUnitarySystems->MoistureLoad < 0.0) this->m_SupHeaterLoad = SupHeaterLoad;
7767 : // so it look's like this next line should only be valid for HP's.
7768 255493 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7769 255493 : this->m_SuppHeatPartLoadFrac = min(1.0, SupHeaterLoad / this->m_DesignSuppHeatingCapacity);
7770 : }
7771 : } else {
7772 660123 : SupHeaterLoad = 0.0;
7773 660123 : this->m_SuppHeatPartLoadFrac = 0.0;
7774 : }
7775 : } else {
7776 3182403 : SupHeaterLoad = 0.0;
7777 3182403 : this->m_SuppHeatPartLoadFrac = 0.0;
7778 : }
7779 :
7780 4098019 : this->calcUnitarySystemToLoad(state,
7781 : AirLoopNum,
7782 : FirstHVACIteration,
7783 : CoolPLR,
7784 : HeatPLR,
7785 : OnOffAirFlowRatio,
7786 : sysOutputProvided,
7787 : latOutputProvided,
7788 : HXUnitOn,
7789 : HeatCoilLoad,
7790 : SupHeaterLoad,
7791 : CompressorOn);
7792 : // Why need this second run?
7793 : // check supplemental heating coil outlet temp based on maximum allowed
7794 4098019 : if (this->m_SuppCoilExists) {
7795 : // only need to test for high supply air temp if supplemental coil is operating
7796 1254177 : if (this->m_SuppHeatPartLoadFrac > 0.0) {
7797 255485 : this->calcUnitarySystemToLoad(state,
7798 : AirLoopNum,
7799 : FirstHVACIteration,
7800 : CoolPLR,
7801 : HeatPLR,
7802 : OnOffAirFlowRatio,
7803 : sysOutputProvided,
7804 : latOutputProvided,
7805 : HXUnitOn,
7806 : HeatCoilLoad,
7807 : SupHeaterLoad,
7808 : CompressorOn);
7809 255485 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
7810 : // multistage coil part load fraction already set in the calcUnitarySystemToLoad
7811 255485 : if (this->m_NumOfSpeedSuppHeating <= 1) {
7812 205983 : this->m_SuppHeatPartLoadFrac = SupHeaterLoad / this->m_DesignSuppHeatingCapacity;
7813 : }
7814 : } else {
7815 0 : this->m_SuppHeatPartLoadFrac = 0.0;
7816 : }
7817 : }
7818 : }
7819 :
7820 4098019 : if (this->m_SuppCoilFluidInletNode > 0) {
7821 0 : PlantUtilities::SetComponentFlowRate(state,
7822 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate,
7823 : this->m_SuppCoilFluidInletNode,
7824 : this->m_SuppCoilFluidOutletNodeNum,
7825 0 : this->m_SuppCoilPlantLoc);
7826 : }
7827 :
7828 4098019 : if (this->m_HeatRecActive) {
7829 0 : PlantUtilities::SetComponentFlowRate(state,
7830 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate,
7831 : this->m_HeatRecoveryInletNodeNum,
7832 : this->m_HeatRecoveryOutletNodeNum,
7833 0 : this->m_HRPlantLoc);
7834 : }
7835 4098019 : }
7836 :
7837 3607422 : void UnitarySys::controlUnitarySystemtoSP(EnergyPlusData &state,
7838 : int const AirLoopNum, // Primary air loop number
7839 : bool const FirstHVACIteration, // True when first HVAC iteration
7840 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
7841 : Real64 const OAUCoilOutTemp, // the coil inlet temperature of OutdoorAirUnit
7842 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
7843 : Real64 &sysOutputProvided, // sensible output at supply air node
7844 : Real64 &latOutputProvided // latent output at supply air node
7845 : )
7846 : {
7847 :
7848 : // SUBROUTINE INFORMATION:
7849 : // AUTHOR Richard Raustad, FSEC
7850 : // DATE WRITTEN February 2013
7851 :
7852 : // PURPOSE OF THIS SUBROUTINE:
7853 : // This subroutine manages component simulation.
7854 :
7855 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7856 3607422 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
7857 3607422 : Real64 OnOffAirFlowRatio = 1.0; // Setpoint based coil control does not use this variable
7858 3607422 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
7859 3607422 : Real64 ZoneLoad = 0.0;
7860 3607422 : Real64 HeatCoilLoad = -999.0;
7861 :
7862 : // CALL the series of components that simulate a Unitary System
7863 3607422 : if (this->ATMixerExists) {
7864 : // There is an air terminal mixer
7865 0 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
7866 : // set the primary air inlet mass flow rate
7867 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
7868 0 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
7869 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
7870 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
7871 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
7872 : }
7873 : }
7874 3607422 : if (this->OAMixerExists) {
7875 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
7876 0 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
7877 : }
7878 3607422 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
7879 98727 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
7880 : }
7881 :
7882 3607422 : if (this->m_CoolingCoilUpstream) {
7883 :
7884 3607422 : if (this->m_CoolCoilExists) {
7885 3601299 : this->updateUnitarySystemControl(state,
7886 : AirLoopNum,
7887 : this->CoolCoilOutletNodeNum,
7888 : this->CoolCtrlNode,
7889 : OnOffAirFlowRatio,
7890 : FirstHVACIteration,
7891 : OAUCoilOutTemp,
7892 : ZoneLoad,
7893 : this->DesignMaxOutletTemp);
7894 3601299 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
7895 3601299 : PartLoadRatio = this->m_CoolingPartLoadFrac;
7896 3601299 : CompressorOn = HVAC::CompressorOp::Off;
7897 3601299 : if (PartLoadRatio > 0.0) {
7898 1215214 : CompressorOn = HVAC::CompressorOp::On;
7899 1215214 : this->m_LastMode = CoolingMode;
7900 : }
7901 3601299 : this->calcUnitaryCoolingSystem(
7902 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
7903 : }
7904 3607422 : if (this->m_HeatCoilExists) {
7905 104850 : this->updateUnitarySystemControl(state,
7906 : AirLoopNum,
7907 : this->HeatCoilOutletNodeNum,
7908 : this->HeatCtrlNode,
7909 : OnOffAirFlowRatio,
7910 : FirstHVACIteration,
7911 : OAUCoilOutTemp,
7912 : ZoneLoad,
7913 : this->DesignMaxOutletTemp);
7914 104850 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
7915 104850 : PartLoadRatio = this->m_HeatingPartLoadFrac;
7916 104850 : HVAC::CompressorOp CompressOn = HVAC::CompressorOp::Off;
7917 104850 : if (PartLoadRatio > 0.0) {
7918 28886 : CompressOn = HVAC::CompressorOp::On;
7919 28886 : this->m_LastMode = HeatingMode;
7920 : }
7921 104850 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressOn, OnOffAirFlowRatio, HeatCoilLoad);
7922 : }
7923 :
7924 : } else {
7925 :
7926 0 : if (this->m_HeatCoilExists) {
7927 0 : this->updateUnitarySystemControl(state,
7928 : AirLoopNum,
7929 : this->HeatCoilOutletNodeNum,
7930 : this->HeatCtrlNode,
7931 : OnOffAirFlowRatio,
7932 : FirstHVACIteration,
7933 : OAUCoilOutTemp,
7934 : ZoneLoad,
7935 : this->DesignMaxOutletTemp);
7936 0 : this->controlHeatingSystemToSP(state, AirLoopNum, FirstHVACIteration, CompressorOn, HeatCoilLoad);
7937 0 : PartLoadRatio = this->m_HeatingPartLoadFrac;
7938 0 : CompressorOn = HVAC::CompressorOp::Off;
7939 0 : if (PartLoadRatio > 0.0) {
7940 0 : CompressorOn = HVAC::CompressorOp::On;
7941 0 : this->m_LastMode = HeatingMode;
7942 : }
7943 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
7944 : }
7945 0 : if (this->m_CoolCoilExists) {
7946 0 : this->updateUnitarySystemControl(state,
7947 : AirLoopNum,
7948 : this->CoolCoilOutletNodeNum,
7949 : this->CoolCtrlNode,
7950 : OnOffAirFlowRatio,
7951 : FirstHVACIteration,
7952 : OAUCoilOutTemp,
7953 : ZoneLoad,
7954 : this->DesignMaxOutletTemp);
7955 0 : this->controlCoolingSystemToSP(state, AirLoopNum, FirstHVACIteration, HXUnitOn, CompressorOn);
7956 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
7957 0 : CompressorOn = HVAC::CompressorOp::Off;
7958 0 : if (PartLoadRatio > 0.0) {
7959 0 : CompressorOn = HVAC::CompressorOp::On;
7960 0 : this->m_LastMode = CoolingMode;
7961 : }
7962 0 : this->calcUnitaryCoolingSystem(
7963 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
7964 : }
7965 : }
7966 :
7967 3607422 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
7968 0 : state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration, state.dataUnitarySystems->FanSpeedRatio);
7969 : }
7970 :
7971 3607422 : if (this->m_SuppCoilExists) {
7972 98727 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
7973 98727 : this->updateUnitarySystemControl(state,
7974 : AirLoopNum,
7975 : this->SuppCoilOutletNodeNum,
7976 : this->SuppCtrlNode,
7977 : OnOffAirFlowRatio,
7978 : FirstHVACIteration,
7979 : OAUCoilOutTemp,
7980 : ZoneLoad,
7981 : this->DesignMaxOutletTemp);
7982 98727 : this->controlSuppHeatSystemToSP(state, AirLoopNum, FirstHVACIteration);
7983 98727 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
7984 98727 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
7985 : }
7986 :
7987 : // If there is a supply side air terminal mixer, calculate its output
7988 3607422 : if (this->ATMixerExists) {
7989 0 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
7990 0 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
7991 : }
7992 : }
7993 :
7994 3607422 : calculateCapacity(state, sysOutputProvided, latOutputProvided);
7995 3607422 : this->m_InitHeatPump = false;
7996 3607422 : }
7997 :
7998 7902895 : void UnitarySys::updateUnitarySystemControl(EnergyPlusData &state,
7999 : int const AirLoopNum, // number of the current air loop being simulated
8000 : int const OutNode, // coil outlet node number
8001 : int const ControlNode, // control node number
8002 : Real64 &OnOffAirFlowRatio,
8003 : bool const FirstHVACIteration,
8004 : Real64 const OAUCoilOutletTemp, // "ONLY" for zoneHVAC:OutdoorAirUnit
8005 : Real64 &ZoneLoad,
8006 : Real64 const MaxOutletTemp // limits heating coil outlet temp [C]
8007 : )
8008 : {
8009 :
8010 : // SUBROUTINE INFORMATION:
8011 : // AUTHOR Richard Raustad, FSEC
8012 : // DATE WRITTEN February 2013
8013 :
8014 : // PURPOSE OF THIS SUBROUTINE:
8015 : // This subroutine is for sizing unitary systems.
8016 :
8017 : // METHODOLOGY EMPLOYED:
8018 : // Either CALL the coil model to get the size or size coil.
8019 : // Current method is to use same methodology as is used in coil objects.
8020 : // Future changes will include a common sizing algorithm and push the calculated
8021 : // size to the coil object prior to first call (so the coil will not DataSizing::AutoSize).
8022 :
8023 : // These initializations are done every iteration
8024 :
8025 : {
8026 7902895 : state.dataUnitarySystems->MoistureLoad = 0.0;
8027 7902895 : this->LoadSHR = 0.0;
8028 7902895 : this->CoilSHR = 0.0;
8029 7902895 : switch (this->m_ControlType) {
8030 4098019 : case UnitarySysCtrlType::Load:
8031 : case UnitarySysCtrlType::CCMASHRAE: {
8032 4098019 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAirUnit
8033 0 : ShowWarningError(state, format("{} \"{}\"", this->UnitType, this->Name));
8034 0 : ShowFatalError(state, "...Load based control is not allowed when used with ZoneHVAC:OutdoorAirUnit");
8035 : }
8036 :
8037 : // here we need to deal with sequenced zone equip
8038 4098019 : state.dataUnitarySystems->HeatingLoad = false;
8039 4098019 : state.dataUnitarySystems->CoolingLoad = false;
8040 4098019 : if (this->m_ZoneSequenceCoolingNum > 0 && this->m_ZoneSequenceHeatingNum > 0 && this->m_AirLoopEquipment) {
8041 : // air loop equipment uses sequenced variables
8042 2660279 : state.dataUnitarySystems->QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8043 2660279 : .SequencedOutputRequiredToCoolingSP(this->m_ZoneSequenceCoolingNum);
8044 2660279 : state.dataUnitarySystems->QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum)
8045 2660279 : .SequencedOutputRequiredToHeatingSP(this->m_ZoneSequenceHeatingNum);
8046 3300890 : if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8047 640611 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::ThermostatType::SingleCooling) {
8048 636167 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8049 636167 : state.dataUnitarySystems->HeatingLoad = true;
8050 2028556 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
8051 4444 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::ThermostatType::SingleCooling) {
8052 4444 : ZoneLoad = 0.0;
8053 3141676 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8054 1122008 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::ThermostatType::SingleHeating) {
8055 1117193 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8056 1117193 : state.dataUnitarySystems->CoolingLoad = true;
8057 907290 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8058 4815 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) == HVAC::ThermostatType::SingleHeating) {
8059 4815 : ZoneLoad = 0.0;
8060 897660 : } else if (state.dataUnitarySystems->QToHeatSetPt <= 0.0 && state.dataUnitarySystems->QToCoolSetPt >= 0.0) {
8061 897660 : ZoneLoad = 0.0;
8062 : }
8063 5320558 : state.dataUnitarySystems->MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum)
8064 2660279 : .SequencedOutputRequiredToDehumidSP(this->m_ZoneSequenceCoolingNum);
8065 : } else {
8066 : // zone equipment uses Remaining* variables
8067 1437740 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired;
8068 2875480 : state.dataUnitarySystems->QToCoolSetPt =
8069 1437740 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToCoolSP;
8070 2875480 : state.dataUnitarySystems->QToHeatSetPt =
8071 1437740 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputReqToHeatSP;
8072 2875480 : state.dataUnitarySystems->MoistureLoad =
8073 1437740 : state.dataZoneEnergyDemand->ZoneSysMoistureDemand(this->ControlZoneNum).RemainingOutputReqToDehumidSP;
8074 1437740 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
8075 278518 : this->m_sysType == SysType::PackagedWSHP) {
8076 : // ZoneSysAvailManager is turning on sooner than PTUnit in UnitarySystem. Mimic PTUnit logic.
8077 1858928 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0 &&
8078 604471 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::ThermostatType::SingleHeating) {
8079 599470 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
8080 1258450 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 &&
8081 603463 : state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::ThermostatType::SingleCooling) {
8082 603133 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
8083 : } else {
8084 51854 : ZoneLoad = 0.0;
8085 : }
8086 : }
8087 : }
8088 :
8089 5758539 : if (ZoneLoad < 0.0 && state.dataUnitarySystems->MoistureLoad <= 0.0 &&
8090 1660520 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8091 720769 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag)) {
8092 1196 : this->LoadSHR =
8093 1196 : ZoneLoad / (ZoneLoad + state.dataUnitarySystems->MoistureLoad *
8094 2392 : Psychrometrics::PsyHgAirFnWTdb(
8095 1196 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).airHumRat,
8096 1196 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).MAT));
8097 1196 : if (this->LoadSHR < 0.0) {
8098 0 : this->LoadSHR = 0.0;
8099 : }
8100 1196 : this->CoilSHR = this->LoadSHR;
8101 : }
8102 :
8103 4098019 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8104 193460 : Real64 H2OHtOfVap = Psychrometrics::PsyHfgAirFnWTdb(state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
8105 193460 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp);
8106 :
8107 : // positive MoistureLoad means no dehumidification load
8108 193460 : state.dataUnitarySystems->MoistureLoad = min(0.0, state.dataUnitarySystems->MoistureLoad * H2OHtOfVap);
8109 : } else {
8110 3904559 : state.dataUnitarySystems->MoistureLoad = 0.0;
8111 : }
8112 :
8113 4098019 : this->initLoadBasedControl(state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad);
8114 :
8115 : // *** the location of this EMS override looks suspect. If EMS is active the load will be changed but the CoolingLoad and HeatingLoad
8116 : // flags are not updated. suggest this be moved up above InitLoadBasedControl function on previous line so the EMS loads are used in
8117 : // that routine EMS override point
8118 4098019 : if (this->m_EMSOverrideSensZoneLoadRequest) ZoneLoad = this->m_EMSSensibleZoneLoadValue;
8119 4098019 : if (this->m_EMSOverrideMoistZoneLoadRequest) state.dataUnitarySystems->MoistureLoad = this->m_EMSMoistureZoneLoadValue;
8120 :
8121 4098019 : this->m_SimASHRAEModel = false; // flag used to envoke ASHRAE 90.1 model calculations
8122 : // allows non-ASHSRAE compliant coil types to be modeled using non-ASHAR90 method. Constant fan operating mode is required.
8123 4098019 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
8124 2180026 : if (state.dataUnitarySystems->CoolingLoad) {
8125 929774 : if (this->m_ValidASHRAECoolCoil) this->m_SimASHRAEModel = true;
8126 1250252 : } else if (state.dataUnitarySystems->HeatingLoad) {
8127 869246 : if (this->m_ValidASHRAEHeatCoil) this->m_SimASHRAEModel = true;
8128 : }
8129 : }
8130 4098019 : } break;
8131 3804876 : case UnitarySysCtrlType::Setpoint: {
8132 3804876 : if (AirLoopNum == -1) { // This IF-THEN routine is just for ZoneHVAC:OutdoorAIRUNIT
8133 :
8134 74325 : if (ControlNode == 0) {
8135 0 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8136 74325 : } else if (ControlNode == OutNode) {
8137 74325 : this->m_DesiredOutletTemp = OAUCoilOutletTemp;
8138 : }
8139 : // If the unitary system is an Outdoor Air Unit, the desired coil outlet humidity level is set to 1.0 (no dehum)
8140 74325 : this->m_DesiredOutletHumRat = 1.0;
8141 :
8142 : } else { // Not Outdoor Air Unit. Either airloop or zone equipment
8143 3730551 : Real64 humRatMaxSP = 1.0;
8144 3730551 : this->m_DesiredOutletHumRat = humRatMaxSP;
8145 3730551 : if (ControlNode == 0) {
8146 0 : this->m_DesiredOutletTemp = 0.0;
8147 0 : if (OutNode > 0) {
8148 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) {
8149 0 : this->m_DesiredOutletHumRat = state.dataLoopNodes->Node(OutNode).HumRatMax;
8150 : }
8151 : }
8152 3730551 : } else if (ControlNode == OutNode) {
8153 3445372 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8154 23577 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0)
8155 19909 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8156 70731 : this->frostControlSetPointLimit(state,
8157 23577 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8158 : humRatMaxSP,
8159 23577 : state.dataEnvrn->OutBaroPress,
8160 : this->DesignMinOutletTemp,
8161 : 1);
8162 : }
8163 3445372 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
8164 : // IF HumRatMax is zero, then there is no request from SetpointManager:SingleZone:Humidity:Maximum
8165 : // user might place temp SP at system outlet and HumRat set point at coil outlet
8166 3445372 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8167 208011 : if (state.dataLoopNodes->Node(this->AirOutNode).HumRatMax > 0.0)
8168 203573 : humRatMaxSP = state.dataLoopNodes->Node(this->AirOutNode).HumRatMax;
8169 208011 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0)
8170 172466 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8171 208011 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8172 59727 : this->frostControlSetPointLimit(state,
8173 19909 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8174 19909 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8175 19909 : state.dataEnvrn->OutBaroPress,
8176 : this->DesignMinOutletTemp,
8177 : 2);
8178 19909 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8179 : }
8180 208011 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8181 : }
8182 : } else {
8183 285179 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax > 0.0) humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8184 285179 : if (state.dataLoopNodes->Node(OutNode).HumRatMax > 0.0) humRatMaxSP = state.dataLoopNodes->Node(OutNode).HumRatMax;
8185 285179 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnSensibleLoad) {
8186 0 : this->frostControlSetPointLimit(state,
8187 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8188 : humRatMaxSP,
8189 0 : state.dataEnvrn->OutBaroPress,
8190 : this->DesignMinOutletTemp,
8191 : 1);
8192 : }
8193 285179 : this->m_DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint -
8194 285179 : (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(OutNode).Temp);
8195 285179 : if (this->m_DehumidControlType_Num != DehumCtrlType::None) {
8196 0 : if (this->m_ISHundredPercentDOASDXCoil && this->m_RunOnLatentLoad) {
8197 0 : this->frostControlSetPointLimit(state,
8198 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint,
8199 0 : state.dataLoopNodes->Node(ControlNode).HumRatMax,
8200 0 : state.dataEnvrn->OutBaroPress,
8201 : this->DesignMinOutletTemp,
8202 : 2);
8203 0 : humRatMaxSP = state.dataLoopNodes->Node(ControlNode).HumRatMax;
8204 : }
8205 0 : this->m_DesiredOutletHumRat = humRatMaxSP; // should this be outside so as to capture humrat for 100%DOASDXCoil ?
8206 : }
8207 : }
8208 : }
8209 3804876 : this->m_DesiredOutletTemp = min(this->m_DesiredOutletTemp, MaxOutletTemp);
8210 3804876 : } break;
8211 0 : default: {
8212 : // should never get here, only 3 control types
8213 0 : } break;
8214 : }
8215 : }
8216 7902895 : }
8217 37402 : void UnitarySys::controlUnitarySystemOutputEMS(EnergyPlusData &state,
8218 : int const AirLoopNum, // Index to air loop
8219 : bool const FirstHVACIteration, // True when first HVAC iteration
8220 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8221 : Real64 const ZoneLoad,
8222 : Real64 &FullSensibleOutput,
8223 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8224 : HVAC::CompressorOp CompressorOn)
8225 : {
8226 37402 : Real64 PartLoadRatio = 1.0;
8227 37402 : Real64 CoolPLR = 0.0;
8228 37402 : Real64 HeatPLR = 0.0;
8229 37402 : HVAC::CompressorOp CompressorONFlag = CompressorOn;
8230 37402 : Real64 HeatCoilLoad = 0.0;
8231 37402 : Real64 SupHeaterLoad = 0.0;
8232 : Real64 SensOutput; // sensible output
8233 : Real64 LatOutput; // latent output
8234 37402 : this->FanPartLoadRatio = 0.0;
8235 37402 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8236 :
8237 37402 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) return;
8238 35996 : int SpeedNumEMS = ceil(this->m_EMSOverrideCoilSpeedNumValue);
8239 35996 : bool useMaxedSpeed = false;
8240 35996 : std::string useMaxedSpeedCoilName;
8241 35996 : if (state.dataUnitarySystems->HeatingLoad) {
8242 0 : if (SpeedNumEMS > this->m_NumOfSpeedHeating) {
8243 0 : SpeedNumEMS = this->m_NumOfSpeedHeating;
8244 0 : useMaxedSpeed = true;
8245 0 : useMaxedSpeedCoilName = this->m_HeatingCoilName;
8246 : }
8247 0 : this->m_HeatingSpeedNum = SpeedNumEMS;
8248 : } else {
8249 35996 : if (SpeedNumEMS > this->m_NumOfSpeedCooling) {
8250 0 : SpeedNumEMS = this->m_NumOfSpeedCooling;
8251 0 : useMaxedSpeed = true;
8252 0 : useMaxedSpeedCoilName = this->m_CoolingCoilName;
8253 : }
8254 35996 : this->m_CoolingSpeedNum = SpeedNumEMS;
8255 : }
8256 35996 : if (useMaxedSpeed) {
8257 0 : this->m_CoilSpeedErrIdx++;
8258 0 : ShowRecurringWarningErrorAtEnd(state,
8259 0 : "Wrong coil speed EMS override value, for unit=\"" + useMaxedSpeedCoilName +
8260 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
8261 0 : this->m_CoilSpeedErrIdx,
8262 0 : this->m_EMSOverrideCoilSpeedNumValue,
8263 0 : this->m_EMSOverrideCoilSpeedNumValue,
8264 : _,
8265 : "",
8266 : "");
8267 : }
8268 :
8269 35996 : if (state.dataUnitarySystems->HeatingLoad) {
8270 0 : CoolPLR = 0.0;
8271 0 : HeatPLR = 1.0;
8272 0 : this->m_HeatingCoilSensDemand = ZoneLoad;
8273 :
8274 0 : if (this->m_HeatingSpeedNum == 1) {
8275 0 : this->m_HeatingSpeedRatio = 0.0;
8276 0 : this->m_HeatingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8277 0 : if (useMaxedSpeed || this->m_HeatingCycRatio == 0) {
8278 0 : this->m_HeatingCycRatio = 1;
8279 : }
8280 : } else {
8281 0 : this->m_HeatingCycRatio = 1.0;
8282 0 : this->m_HeatingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8283 0 : if (useMaxedSpeed || this->m_HeatingSpeedRatio == 0) {
8284 0 : this->m_HeatingSpeedRatio = 1;
8285 : }
8286 : }
8287 : } else { // Cooling or moisture load
8288 35996 : HeatPLR = 0.0;
8289 35996 : CoolPLR = 1.0;
8290 35996 : if (state.dataUnitarySystems->CoolingLoad) {
8291 35996 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8292 : } else {
8293 0 : this->m_CoolingCoilSensDemand = 0.0;
8294 : }
8295 35996 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8296 :
8297 35996 : if (this->m_CoolingSpeedNum == 1) {
8298 17605 : this->m_CoolingSpeedRatio = 0.0;
8299 17605 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8300 17605 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
8301 17605 : this->m_CoolingCycRatio = 1;
8302 : }
8303 : } else {
8304 18391 : this->m_CoolingCycRatio = 1.0;
8305 18391 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
8306 18391 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
8307 0 : this->m_CoolingSpeedRatio = 1;
8308 : }
8309 : }
8310 : }
8311 35996 : this->calcUnitarySystemToLoad(state,
8312 : AirLoopNum,
8313 : FirstHVACIteration,
8314 : CoolPLR,
8315 : HeatPLR,
8316 : OnOffAirFlowRatio,
8317 : SensOutput,
8318 : LatOutput,
8319 35996 : HXUnitOn,
8320 : HeatCoilLoad,
8321 : SupHeaterLoad,
8322 : CompressorONFlag);
8323 :
8324 35996 : FullSensibleOutput = SensOutput;
8325 :
8326 35996 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8327 : // no load
8328 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutput) return;
8329 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8330 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) return;
8331 : }
8332 35996 : HXUnitOn = true;
8333 35996 : this->calcUnitarySystemToLoad(state,
8334 : AirLoopNum,
8335 : FirstHVACIteration,
8336 : CoolPLR,
8337 : HeatPLR,
8338 : OnOffAirFlowRatio,
8339 : SensOutput,
8340 : LatOutput,
8341 35996 : HXUnitOn,
8342 : HeatCoilLoad,
8343 : SupHeaterLoad,
8344 : CompressorONFlag);
8345 35996 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
8346 : Real64 heatCoildT =
8347 35996 : (this->m_HeatCoilExists)
8348 35996 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
8349 35996 : : 0.0;
8350 : Real64 CoolingOnlySensibleOutput =
8351 35996 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
8352 35996 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
8353 35996 : heatCoildT);
8354 35996 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
8355 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
8356 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
8357 35996 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
8358 : // Heating mode and dehumidification is required
8359 : } else {
8360 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
8361 : // the heating coil pick up the load due to outdoor air.
8362 0 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
8363 : }
8364 35996 : }
8365 :
8366 4166007 : void UnitarySys::controlUnitarySystemOutput(EnergyPlusData &state,
8367 : int const AirLoopNum, // Index to air loop
8368 : bool const FirstHVACIteration, // True when first HVAC iteration
8369 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
8370 : Real64 const ZoneLoad,
8371 : Real64 &FullSensibleOutput,
8372 : bool &HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
8373 : HVAC::CompressorOp CompressorOn)
8374 : {
8375 :
8376 : // SUBROUTINE INFORMATION:
8377 : // AUTHOR Richard Raustad, FSEC
8378 : // DATE WRITTEN February 2013
8379 :
8380 : // PURPOSE OF THIS SUBROUTINE:
8381 : // This subroutine determines operating PLR and calculates the load based system output.
8382 :
8383 : // SUBROUTINE PARAMETER DEFINITIONS:
8384 4166007 : int constexpr MaxIter = 100; // maximum number of iterations
8385 :
8386 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8387 : int SpeedNum; // multi-speed coil speed number
8388 : Real64 SensOutputOn; // sensible output at PLR = 1 [W]
8389 : Real64 LatOutputOn; // latent output at PLR = 1 [W]
8390 : Real64 TempLoad; // represents either a sensible or latent load [W]
8391 : Real64 TempSysOutput; // represents either a sensible or latent capacity [W]
8392 : Real64 TempSensOutput; // iterative sensible capacity [W]
8393 : Real64 TempLatOutput; // iterative latent capacity [W]
8394 : Real64 TempMinPLR; // iterative minimum PLR
8395 : Real64 TempMaxPLR; // iterative maximum PLR
8396 : Real64 CpAir; // specific heat of air [J/kg_C]
8397 : Real64 FullLoadAirOutletTemp; // saved full load outlet air temperature [C]
8398 : Real64 FullLoadAirOutletHumRat; // saved full load outlet air humidity ratio [kg/kg]
8399 :
8400 4166007 : std::string CompName = this->Name;
8401 4166007 : int OutletNode = this->AirOutNode;
8402 :
8403 4166007 : if (ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) <= 0.0) {
8404 4494 : return;
8405 : }
8406 4161513 : if (this->m_EMSOverrideCoilSpeedNumOn) {
8407 37402 : this->controlUnitarySystemOutputEMS(
8408 : state, AirLoopNum, FirstHVACIteration, OnOffAirFlowRatio, ZoneLoad, FullSensibleOutput, HXUnitOn, CompressorOn);
8409 37402 : return;
8410 : }
8411 :
8412 4124111 : Real64 PartLoadRatio = 0.0; // Get no load result
8413 4124111 : this->m_EconoPartLoadRatio = 0;
8414 : // fan and coil PLR are disconnected when using ASHRAE model, don't confuse these for other models
8415 4124111 : this->FanPartLoadRatio = 0.0;
8416 4124111 : int SolFlag = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8417 4124111 : int SolFlagLat = 0; // # of iterations IF positive, -1 means failed to converge, -2 means bounds are incorrect
8418 4124111 : Real64 SensOutputOff = 0.0;
8419 4124111 : Real64 LatOutputOff = 0.0;
8420 4124111 : Real64 CoolPLR = 0.0;
8421 4124111 : Real64 HeatPLR = 0.0;
8422 4124111 : HVAC::CompressorOp CompressorONFlag = HVAC::CompressorOp::Off;
8423 4124111 : Real64 HeatCoilLoad = 0.0;
8424 4124111 : Real64 SupHeaterLoad = 0.0;
8425 :
8426 4124111 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8427 :
8428 4124111 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad && state.dataUnitarySystems->MoistureLoad >= 0.0) return;
8429 :
8430 3278595 : this->calcUnitarySystemToLoad(state,
8431 : AirLoopNum,
8432 : FirstHVACIteration,
8433 : CoolPLR,
8434 : HeatPLR,
8435 : OnOffAirFlowRatio,
8436 : SensOutputOff,
8437 : LatOutputOff,
8438 3278595 : HXUnitOn,
8439 : HeatCoilLoad,
8440 : SupHeaterLoad,
8441 : CompressorONFlag);
8442 3278595 : FullSensibleOutput = SensOutputOff;
8443 :
8444 3278595 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
8445 : // no load
8446 0 : if (state.dataUnitarySystems->MoistureLoad > LatOutputOff) return;
8447 : // Dehumcontrol_Multimode only controls RH if there is a sensible load
8448 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) return;
8449 : }
8450 :
8451 : // determine if PLR=0 meets the load
8452 3278595 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8453 48933 : case HVAC::ThermostatType::SingleHeating: {
8454 48933 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8455 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8456 0 : return;
8457 48933 : if (!state.dataUnitarySystems->HeatingLoad &&
8458 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8459 0 : return;
8460 48933 : } break;
8461 53651 : case HVAC::ThermostatType::SingleCooling: {
8462 53653 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8463 2 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8464 2 : return;
8465 53649 : if (!state.dataUnitarySystems->CoolingLoad &&
8466 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8467 0 : return;
8468 53649 : } break;
8469 3176011 : case HVAC::ThermostatType::SingleHeatCool:
8470 : case HVAC::ThermostatType::DualSetPointWithDeadBand: {
8471 3176027 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8472 16 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8473 16 : return;
8474 3188313 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8475 12318 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8476 10109 : return;
8477 3165886 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8478 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8479 0 : return;
8480 3165886 : } break;
8481 0 : default: {
8482 : // should never get here
8483 0 : } break;
8484 : }
8485 :
8486 3268468 : this->m_EconoSpeedNum = 0;
8487 3268468 : if (this->OAControllerEconomizerStagingType == HVAC::EconomizerStagingType::EconomizerFirst) {
8488 740540 : manageEconomizerStagingOperation(state, AirLoopNum, FirstHVACIteration, ZoneLoad);
8489 : }
8490 :
8491 : // if a variable speed unit, the SensOutputOff at SpeedNum=1 must be checked to see if it exceeds the ZoneLoad
8492 : // This is still no load but at the first speed above idle
8493 6225347 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating > 0) ||
8494 2956879 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling > 0)) {
8495 1898906 : if (this->m_Staged) {
8496 0 : if (state.dataUnitarySystems->HeatingLoad) {
8497 0 : this->m_HeatingSpeedNum = this->m_StageNum;
8498 : } else {
8499 0 : this->m_CoolingSpeedNum = std::abs(this->m_StageNum);
8500 : }
8501 : } else {
8502 1898906 : if (state.dataUnitarySystems->HeatingLoad) {
8503 311589 : this->m_HeatingSpeedNum = 1;
8504 : } else {
8505 1587317 : this->m_CoolingSpeedNum = 1;
8506 : }
8507 : }
8508 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8509 1898906 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8510 1898906 : this->calcUnitarySystemToLoad(state,
8511 : AirLoopNum,
8512 : FirstHVACIteration,
8513 : CoolPLR,
8514 : HeatPLR,
8515 : OnOffAirFlowRatio,
8516 : SensOutputOff,
8517 : LatOutputOff,
8518 1898906 : HXUnitOn,
8519 : HeatCoilLoad,
8520 : SupHeaterLoad,
8521 : CompressorONFlag);
8522 1898906 : FullSensibleOutput = SensOutputOff;
8523 :
8524 1898906 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8525 4496 : case HVAC::ThermostatType::SingleHeating: {
8526 4496 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8527 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8528 0 : return;
8529 4496 : if (!state.dataUnitarySystems->HeatingLoad &&
8530 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8531 0 : return;
8532 4496 : } break;
8533 39789 : case HVAC::ThermostatType::SingleCooling: {
8534 39789 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat)
8535 0 : return;
8536 39789 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8537 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8538 0 : return;
8539 39789 : if (!state.dataUnitarySystems->CoolingLoad &&
8540 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8541 0 : return;
8542 39789 : } break;
8543 1854621 : case HVAC::ThermostatType::SingleHeatCool:
8544 : case HVAC::ThermostatType::DualSetPointWithDeadBand: {
8545 1860757 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOff > ZoneLoad &&
8546 6136 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8547 6136 : return;
8548 1848485 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad && this->m_DehumidControlType_Num != DehumCtrlType::CoolReheat)
8549 168498 : return;
8550 1681336 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOff < ZoneLoad &&
8551 1349 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8552 12 : return;
8553 1679975 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8554 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOff))
8555 0 : return;
8556 1679975 : } break;
8557 0 : default: {
8558 : // should never get here
8559 0 : } break;
8560 : }
8561 : }
8562 :
8563 3093822 : CompressorONFlag = CompressorOn;
8564 3093822 : PartLoadRatio = 1.0;
8565 3093822 : this->FanPartLoadRatio = 1.0;
8566 : // Get full load result for non-multistage economizer operations
8567 3093822 : if (this->m_EconoSpeedNum == 0) {
8568 3081612 : if (state.dataUnitarySystems->HeatingLoad) {
8569 1594540 : CoolPLR = 0.0;
8570 1594540 : HeatPLR = 1.0;
8571 1594540 : this->m_HeatingCoilSensDemand = ZoneLoad;
8572 1594540 : if (this->m_NumOfSpeedHeating > 0) {
8573 305453 : this->m_HeatingSpeedRatio = 1.0;
8574 305453 : this->m_HeatingCycRatio = 1.0;
8575 305453 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
8576 : }
8577 1594540 : if (this->m_Staged && this->m_StageNum > 0) {
8578 0 : if (this->m_NumOfSpeedHeating > 0) {
8579 0 : this->m_HeatingSpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8580 0 : this->m_HeatingSpeedRatio = 0.0;
8581 : }
8582 : // calcUnitarySystemToLoad calls setOnOffMassFlowRate so probably no need to call this here
8583 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8584 0 : this->calcUnitarySystemToLoad(state,
8585 : AirLoopNum,
8586 : FirstHVACIteration,
8587 : CoolPLR,
8588 : HeatPLR,
8589 : OnOffAirFlowRatio,
8590 : SensOutputOff,
8591 : LatOutputOff,
8592 0 : HXUnitOn,
8593 : HeatCoilLoad,
8594 : SupHeaterLoad,
8595 : CompressorONFlag);
8596 0 : if (SensOutputOff > ZoneLoad) return;
8597 0 : if (this->m_NumOfSpeedHeating > 0) this->m_HeatingSpeedRatio = 1.0;
8598 : }
8599 1487072 : } else if (state.dataUnitarySystems->CoolingLoad || state.dataUnitarySystems->MoistureLoad < LatOutputOff) {
8600 1487072 : CoolPLR = 1.0;
8601 1487072 : HeatPLR = 0.0;
8602 1487072 : if (state.dataUnitarySystems->CoolingLoad) {
8603 1487072 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8604 : } else {
8605 0 : this->m_CoolingCoilSensDemand = 0.0;
8606 : }
8607 1487072 : this->m_CoolingCoilLatentDemand = std::abs(state.dataUnitarySystems->MoistureLoad);
8608 1487072 : if (this->m_NumOfSpeedCooling > 0) {
8609 1406597 : this->m_CoolingSpeedRatio = 1.0;
8610 1406597 : this->m_CoolingCycRatio = 1.0;
8611 1406597 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
8612 : }
8613 1487072 : if (this->m_Staged && this->m_StageNum < 0) {
8614 0 : if (this->m_NumOfSpeedCooling > 0) this->m_CoolingSpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8615 0 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8616 0 : this->m_CoolingSpeedRatio = 0.0;
8617 0 : this->calcUnitarySystemToLoad(state,
8618 : AirLoopNum,
8619 : FirstHVACIteration,
8620 : CoolPLR,
8621 : HeatPLR,
8622 : OnOffAirFlowRatio,
8623 : SensOutputOff,
8624 : LatOutputOff,
8625 0 : HXUnitOn,
8626 : HeatCoilLoad,
8627 : SupHeaterLoad,
8628 : CompressorONFlag);
8629 0 : if (SensOutputOff < ZoneLoad) return;
8630 0 : if (this->m_NumOfSpeedCooling > 0) this->m_CoolingSpeedRatio = 1.0;
8631 : }
8632 : } else {
8633 : // will return here when no cooling or heating load and MoistureLoad > LatOutputOff (i.e., PLR=0)
8634 0 : return;
8635 : }
8636 :
8637 3081612 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadRatio);
8638 :
8639 3081612 : this->calcUnitarySystemToLoad(state,
8640 : AirLoopNum,
8641 : FirstHVACIteration,
8642 : CoolPLR,
8643 : HeatPLR,
8644 : OnOffAirFlowRatio,
8645 : SensOutputOn,
8646 : LatOutputOn,
8647 3081612 : HXUnitOn,
8648 : HeatCoilLoad,
8649 : SupHeaterLoad,
8650 : CompressorONFlag);
8651 3081612 : FullSensibleOutput = SensOutputOn;
8652 3081612 : FullLoadAirOutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
8653 3081612 : FullLoadAirOutletHumRat = state.dataLoopNodes->Node(OutletNode).HumRat;
8654 :
8655 : // turn on HX if dehumidm_ControlType::Multimode
8656 69394 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < 0.0 &&
8657 3151006 : state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
8658 20914 : HXUnitOn = true;
8659 20914 : this->calcUnitarySystemToLoad(state,
8660 : AirLoopNum,
8661 : FirstHVACIteration,
8662 : CoolPLR,
8663 : HeatPLR,
8664 : OnOffAirFlowRatio,
8665 : SensOutputOn,
8666 : LatOutputOn,
8667 20914 : HXUnitOn,
8668 : HeatCoilLoad,
8669 : SupHeaterLoad,
8670 : CompressorONFlag);
8671 20914 : FullSensibleOutput = SensOutputOn;
8672 : }
8673 :
8674 : // test to see if full capacity is less than load, if so set to PLR=1 and RETURN if no moisture load
8675 4673335 : if ((state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating <= 1) ||
8676 1591723 : (state.dataUnitarySystems->CoolingLoad && this->m_NumOfSpeedCooling <= 1)) {
8677 2207840 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
8678 44437 : case HVAC::ThermostatType::SingleHeating: {
8679 44437 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8680 8088 : this->m_HeatingPartLoadFrac = 1.0;
8681 8088 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) return;
8682 : }
8683 36349 : if (!state.dataUnitarySystems->HeatingLoad &&
8684 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn))
8685 0 : return;
8686 36349 : } break;
8687 42145 : case HVAC::ThermostatType::SingleCooling: {
8688 42145 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8689 4953 : this->m_CoolingPartLoadFrac = 1.0;
8690 4953 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn) return;
8691 : }
8692 37192 : if (!state.dataUnitarySystems->CoolingLoad &&
8693 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn))
8694 0 : return;
8695 37192 : } break;
8696 2121258 : case HVAC::ThermostatType::SingleHeatCool:
8697 : case HVAC::ThermostatType::DualSetPointWithDeadBand: {
8698 2121258 : if (state.dataUnitarySystems->HeatingLoad && SensOutputOn < ZoneLoad) {
8699 370281 : this->m_HeatingPartLoadFrac = 1.0;
8700 370281 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad > LatOutputOn) return;
8701 : }
8702 1750977 : if (state.dataUnitarySystems->CoolingLoad && SensOutputOn > ZoneLoad) {
8703 21660 : this->m_CoolingPartLoadFrac = 1.0;
8704 21660 : return;
8705 : }
8706 1729317 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8707 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8708 0 : return;
8709 : }
8710 1729317 : } break;
8711 0 : default: {
8712 : // no other choices for thermostat control
8713 0 : } break;
8714 : }
8715 : }
8716 : } else {
8717 : // define the sensible load to meet for operation with multi-stage economizer
8718 12210 : this->m_CoolingCoilSensDemand = std::abs(ZoneLoad);
8719 : }
8720 : // will find speed for multispeed coils here and then RegulaFalsi on PLR at a fixed speed
8721 :
8722 : // Do the non-variable or non-multispeed coils have a NumOfSpeed = 0 ? We don't need to do this for single speed coils.
8723 : // Check to see which speed to meet the load
8724 2688840 : this->m_HeatingSpeedNum = 0;
8725 2688840 : this->m_CoolingSpeedNum = 0;
8726 2688840 : if (!this->m_Staged) {
8727 2688840 : if (state.dataUnitarySystems->HeatingLoad) {
8728 1469151 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
8729 317880 : CoolPLR = 0.0;
8730 317880 : HeatPLR = 1.0;
8731 317880 : if (SpeedNum == 1) {
8732 145361 : this->m_HeatingSpeedRatio = 0.0;
8733 : } else {
8734 172519 : this->m_HeatingSpeedRatio = 1.0;
8735 : }
8736 317880 : this->m_HeatingCycRatio = 1.0;
8737 317880 : this->m_HeatingSpeedNum = SpeedNum;
8738 317880 : this->calcUnitarySystemToLoad(state,
8739 : AirLoopNum,
8740 : FirstHVACIteration,
8741 : CoolPLR,
8742 : HeatPLR,
8743 : OnOffAirFlowRatio,
8744 : SensOutputOn,
8745 : LatOutputOn,
8746 317880 : HXUnitOn,
8747 : HeatCoilLoad,
8748 : SupHeaterLoad,
8749 : CompressorONFlag);
8750 317880 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
8751 0 : this->FullOutput[SpeedNum] = SensOutputOn;
8752 : }
8753 317880 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit &&
8754 268032 : (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater && !this->m_MultiSpeedHeatingCoil)) {
8755 0 : this->m_HeatingSpeedRatio = 0.0;
8756 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
8757 0 : if (this->m_HeatingSpeedNum == 0) {
8758 0 : this->m_HeatingCycRatio = 0.0;
8759 0 : HeatPLR = 0.0;
8760 : } else {
8761 0 : this->m_HeatingCycRatio = 1.0;
8762 0 : HeatPLR = 1.0;
8763 : }
8764 0 : this->calcUnitarySystemToLoad(state,
8765 : AirLoopNum,
8766 : FirstHVACIteration,
8767 : CoolPLR,
8768 : HeatPLR,
8769 : OnOffAirFlowRatio,
8770 : SensOutputOff,
8771 : LatOutputOff,
8772 0 : HXUnitOn,
8773 : HeatCoilLoad,
8774 : SupHeaterLoad,
8775 : CompressorONFlag);
8776 0 : this->m_HeatingSpeedNum = SpeedNum;
8777 : }
8778 317880 : if (ZoneLoad <= SensOutputOn) {
8779 64900 : break;
8780 : }
8781 : }
8782 : } else { // Cooling or moisture load
8783 2270423 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
8784 2166031 : CoolPLR = 1.0;
8785 2166031 : HeatPLR = 0.0;
8786 2166031 : if (SpeedNum == 1) {
8787 1398777 : this->m_CoolingSpeedRatio = 0.0;
8788 : } else {
8789 767254 : this->m_CoolingSpeedRatio = 1.0;
8790 : }
8791 2166031 : this->m_CoolingCycRatio = 1.0;
8792 2166031 : this->m_CoolingSpeedNum = SpeedNum;
8793 2166031 : this->calcUnitarySystemToLoad(state,
8794 : AirLoopNum,
8795 : FirstHVACIteration,
8796 : CoolPLR,
8797 : HeatPLR,
8798 : OnOffAirFlowRatio,
8799 : SensOutputOn,
8800 : LatOutputOn,
8801 2166031 : HXUnitOn,
8802 : HeatCoilLoad,
8803 : SupHeaterLoad,
8804 : CompressorONFlag);
8805 2166031 : if (state.dataGlobal->DoCoilDirectSolutions &&
8806 0 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
8807 0 : (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1))) {
8808 0 : this->FullOutput[SpeedNum] = SensOutputOn;
8809 : }
8810 : // over specified logic? it has to be a water coil? what about other VS coil models?
8811 2166031 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
8812 2153535 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
8813 10198 : !this->m_DiscreteSpeedCoolingCoil)) {
8814 0 : this->m_CoolingSpeedRatio = 0.0;
8815 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
8816 0 : if (this->m_CoolingSpeedNum == 0) {
8817 0 : this->m_CoolingCycRatio = 0.0;
8818 0 : CoolPLR = 0.0;
8819 : } else {
8820 0 : this->m_CoolingCycRatio = 1.0;
8821 0 : this->m_CoolingSpeedRatio = 0.0;
8822 0 : if (this->m_SingleMode == 1) {
8823 0 : CoolPLR = 1.0;
8824 : }
8825 : }
8826 :
8827 0 : this->calcUnitarySystemToLoad(state,
8828 : AirLoopNum,
8829 : FirstHVACIteration,
8830 : CoolPLR,
8831 : HeatPLR,
8832 : OnOffAirFlowRatio,
8833 : SensOutputOff,
8834 : LatOutputOff,
8835 0 : HXUnitOn,
8836 : HeatCoilLoad,
8837 : SupHeaterLoad,
8838 : CompressorONFlag);
8839 0 : this->m_CoolingSpeedNum = SpeedNum;
8840 : }
8841 2166031 : if (ZoneLoad >= SensOutputOn) {
8842 1368277 : break;
8843 : }
8844 : }
8845 : }
8846 : } else { // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
8847 : // Staged control
8848 0 : if (state.dataUnitarySystems->HeatingLoad) {
8849 0 : CoolPLR = 0.0;
8850 0 : HeatPLR = 1.0;
8851 0 : SpeedNum = this->m_StageNum;
8852 0 : if (SpeedNum == 1) {
8853 0 : this->m_HeatingSpeedRatio = 0.0;
8854 : } else {
8855 0 : this->m_HeatingSpeedRatio = 1.0;
8856 0 : SpeedNum = min(this->m_StageNum, this->m_NumOfSpeedHeating);
8857 : }
8858 0 : this->m_HeatingCycRatio = 1.0;
8859 0 : this->m_HeatingSpeedNum = SpeedNum;
8860 0 : this->calcUnitarySystemToLoad(state,
8861 : AirLoopNum,
8862 : FirstHVACIteration,
8863 : CoolPLR,
8864 : HeatPLR,
8865 : OnOffAirFlowRatio,
8866 : SensOutputOn,
8867 : LatOutputOn,
8868 0 : HXUnitOn,
8869 : HeatCoilLoad,
8870 : SupHeaterLoad,
8871 : CompressorONFlag);
8872 0 : if (this->m_HeatingCoilType_Num != HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
8873 0 : this->m_HeatingSpeedRatio = 0.0;
8874 0 : this->m_HeatingSpeedNum = SpeedNum - 1;
8875 0 : if (this->m_HeatingSpeedNum == 0) {
8876 0 : this->m_HeatingCycRatio = 0.0;
8877 0 : HeatPLR = 0.0;
8878 : } else {
8879 0 : this->m_HeatingCycRatio = 1.0;
8880 0 : HeatPLR = 1.0;
8881 : }
8882 0 : this->calcUnitarySystemToLoad(state,
8883 : AirLoopNum,
8884 : FirstHVACIteration,
8885 : CoolPLR,
8886 : HeatPLR,
8887 : OnOffAirFlowRatio,
8888 : SensOutputOff,
8889 : LatOutputOff,
8890 0 : HXUnitOn,
8891 : HeatCoilLoad,
8892 : SupHeaterLoad,
8893 : CompressorONFlag);
8894 0 : this->m_HeatingSpeedNum = SpeedNum;
8895 : }
8896 0 : if (ZoneLoad <= SensOutputOn) {
8897 : // EXIT ????????????
8898 : }
8899 : } else { // Cooling or moisture load
8900 0 : CoolPLR = 1.0;
8901 0 : HeatPLR = 0.0;
8902 0 : SpeedNum = std::abs(this->m_StageNum);
8903 0 : if (SpeedNum == 1) {
8904 0 : this->m_CoolingSpeedRatio = 0.0;
8905 : } else {
8906 0 : this->m_CoolingSpeedRatio = 1.0;
8907 0 : SpeedNum = min(std::abs(this->m_StageNum), this->m_NumOfSpeedCooling);
8908 : }
8909 0 : this->m_CoolingCycRatio = 1.0;
8910 0 : this->m_CoolingSpeedNum = SpeedNum;
8911 0 : this->calcUnitarySystemToLoad(state,
8912 : AirLoopNum,
8913 : FirstHVACIteration,
8914 : CoolPLR,
8915 : HeatPLR,
8916 : OnOffAirFlowRatio,
8917 : SensOutputOn,
8918 : LatOutputOn,
8919 0 : HXUnitOn,
8920 : HeatCoilLoad,
8921 : SupHeaterLoad,
8922 : CompressorONFlag);
8923 :
8924 0 : if (this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
8925 0 : this->m_CoolingSpeedRatio = 0.0;
8926 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
8927 0 : if (this->m_CoolingSpeedNum == 0) {
8928 0 : this->m_CoolingCycRatio = 0.0;
8929 0 : CoolPLR = 0.0;
8930 : } else {
8931 0 : this->m_CoolingCycRatio = 1.0;
8932 0 : CoolPLR = 1.0;
8933 : }
8934 0 : this->calcUnitarySystemToLoad(state,
8935 : AirLoopNum,
8936 : FirstHVACIteration,
8937 : CoolPLR,
8938 : HeatPLR,
8939 : OnOffAirFlowRatio,
8940 : SensOutputOff,
8941 : LatOutputOff,
8942 0 : HXUnitOn,
8943 : HeatCoilLoad,
8944 : SupHeaterLoad,
8945 : CompressorONFlag);
8946 0 : this->m_CoolingSpeedNum = SpeedNum;
8947 : }
8948 0 : if (ZoneLoad >= SensOutputOn) {
8949 : // EXIT ???????????
8950 : }
8951 : }
8952 : } // IF (.NOT. UnitarySystem(UnitarySysNum)%Staged) THEN
8953 :
8954 2688840 : FullSensibleOutput = SensOutputOn;
8955 :
8956 2688840 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad &&
8957 0 : (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad < LatOutputOn)) {
8958 : // if no load, or only a moisture load which can't be met at PLR=1, RETURN
8959 0 : return;
8960 : }
8961 :
8962 : // use the ASHRAE 90.1 method of reduced fan speed at low loads
8963 2688840 : if (this->m_SimASHRAEModel) {
8964 :
8965 : // check to make sure unit has the capacity to meet the load
8966 0 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
8967 0 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
8968 0 : UnitarySys &SZVAVModel(state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum]);
8969 0 : SZVAVModel::calcSZVAVModel(state,
8970 : SZVAVModel,
8971 : this->m_UnitarySysNum,
8972 : FirstHVACIteration,
8973 0 : state.dataUnitarySystems->CoolingLoad,
8974 0 : state.dataUnitarySystems->HeatingLoad,
8975 : ZoneLoad,
8976 : OnOffAirFlowRatio,
8977 0 : HXUnitOn,
8978 : AirLoopNum,
8979 : PartLoadRatio,
8980 : CompressorONFlag);
8981 : }
8982 :
8983 : } else { // not ASHRAE model
8984 :
8985 : // must test to see if load is bounded by capacity before calling RegulaFalsi
8986 4241970 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad < SensOutputOn) ||
8987 1553130 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad > SensOutputOn)) {
8988 4020048 : if ((state.dataUnitarySystems->HeatingLoad && ZoneLoad > SensOutputOff) ||
8989 1442169 : (state.dataUnitarySystems->CoolingLoad && ZoneLoad < SensOutputOff)) {
8990 : Real64 SensOutput;
8991 : Real64 LatOutput;
8992 3458931 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
8993 882389 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
8994 7754 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR > 0.0) {
8995 1164 : int CoilInletNode = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].evapInletNodeIndex;
8996 1164 : this->CoilSHR = 0.0;
8997 : Real64 LowSpeedCoilSen;
8998 : Real64 LowSpeedCoilLat;
8999 1164 : CoolPLR = 0.0;
9000 1164 : HeatPLR = 0.0;
9001 1164 : this->m_CoolingSpeedNum = 1;
9002 1164 : this->calcUnitarySystemToLoad(state,
9003 : AirLoopNum,
9004 : FirstHVACIteration,
9005 : CoolPLR,
9006 : HeatPLR,
9007 : OnOffAirFlowRatio,
9008 : SensOutputOff,
9009 : LatOutputOff,
9010 1164 : HXUnitOn,
9011 : HeatCoilLoad,
9012 : SupHeaterLoad,
9013 : CompressorONFlag);
9014 1164 : CoolPLR = 1.0;
9015 1164 : HeatPLR = 0.0;
9016 1164 : this->m_CoolingCycRatio = 1.0;
9017 1164 : this->m_CoolingSpeedRatio = 0.0;
9018 : // this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9019 1164 : this->calcUnitarySystemToLoad(state,
9020 : AirLoopNum,
9021 : FirstHVACIteration,
9022 : CoolPLR,
9023 : HeatPLR,
9024 : OnOffAirFlowRatio,
9025 : SensOutputOn,
9026 : LatOutputOn,
9027 1164 : HXUnitOn,
9028 : HeatCoilLoad,
9029 : SupHeaterLoad,
9030 : CompressorONFlag);
9031 1164 : Real64 ZoneLatLoad = ZoneLoad * (1.0 / this->LoadSHR - 1.0);
9032 1164 : Real64 SenPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9033 1164 : Real64 LatPLR = (ZoneLatLoad - LatOutputOff) / (LatOutputOn - LatOutputOff);
9034 1164 : Real64 totalRate = 0.0;
9035 1164 : Real64 sensRate = 0.0;
9036 1164 : Real64 latRate = 0.0;
9037 1164 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9038 1164 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9039 1164 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9040 1164 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9041 1164 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9042 : sensRate,
9043 : latRate,
9044 : totalRate);
9045 1164 : if (LatPLR > 1.0 || LatPLR < 0.0) {
9046 0 : this->CoilSHR = this->LoadSHR;
9047 : } else {
9048 1164 : Real64 coilSens = sensRate * SenPLR;
9049 1164 : Real64 coilLat = latRate * LatPLR;
9050 1164 : this->CoilSHR = coilSens / (coilSens + coilLat);
9051 : }
9052 1164 : if (this->m_NumOfSpeedCooling > 1) {
9053 0 : this->SpeedSHR[1] = this->CoilSHR;
9054 0 : LowSpeedCoilSen = sensRate;
9055 0 : LowSpeedCoilLat = latRate;
9056 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9057 0 : this->SpeedSHR[SpeedNum] = this->LoadSHR;
9058 : }
9059 : }
9060 1164 : if (this->CoilSHR < 0.0) {
9061 0 : this->CoilSHR = this->LoadSHR;
9062 : }
9063 1164 : if (this->m_NumOfSpeedCooling > 1 && ZoneLoad < SensOutputOn) {
9064 : Real64 SenSPR;
9065 : Real64 LatSPR;
9066 0 : this->FullOutput[1] = SensOutputOn;
9067 0 : this->FullLatOutput[1] = LatOutputOn;
9068 0 : for (SpeedNum = 2; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9069 0 : this->CoilSHR = 0.0;
9070 0 : CoolPLR = 1.0;
9071 0 : HeatPLR = 0.0;
9072 0 : this->m_CoolingSpeedRatio = 1.0;
9073 0 : this->m_CoolingCycRatio = 1.0;
9074 0 : this->m_CoolingSpeedNum = SpeedNum;
9075 0 : this->calcUnitarySystemToLoad(state,
9076 : AirLoopNum,
9077 : FirstHVACIteration,
9078 : CoolPLR,
9079 : HeatPLR,
9080 : OnOffAirFlowRatio,
9081 0 : this->FullOutput[SpeedNum],
9082 0 : this->FullLatOutput[SpeedNum],
9083 0 : HXUnitOn,
9084 : HeatCoilLoad,
9085 : SupHeaterLoad,
9086 : CompressorONFlag);
9087 0 : CalcComponentSensibleLatentOutput(state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate,
9088 0 : state.dataLoopNodes->Node(CoilInletNode).Temp,
9089 0 : state.dataLoopNodes->Node(CoilInletNode).HumRat,
9090 0 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
9091 0 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
9092 : sensRate,
9093 : latRate,
9094 : totalRate);
9095 0 : SenSPR =
9096 0 : (ZoneLoad - this->FullOutput[SpeedNum - 1]) / (this->FullOutput[SpeedNum] - this->FullOutput[SpeedNum - 1]);
9097 0 : LatSPR = (ZoneLatLoad - this->FullLatOutput[SpeedNum - 1]) /
9098 0 : (this->FullLatOutput[SpeedNum] - this->FullLatOutput[SpeedNum - 1]);
9099 0 : if (LatSPR > 1.0 || LatSPR < 0.0) {
9100 0 : this->CoilSHR = this->LoadSHR;
9101 : } else {
9102 0 : Real64 coilSens = sensRate * SenSPR + (1.0 - SenSPR) * LowSpeedCoilSen;
9103 0 : Real64 coilLat = latRate * LatSPR + (1.0 - LatSPR) * LowSpeedCoilLat;
9104 0 : this->CoilSHR = coilSens / (coilSens + coilLat);
9105 : }
9106 0 : this->SpeedSHR[SpeedNum] = this->CoilSHR;
9107 0 : LowSpeedCoilSen = sensRate;
9108 0 : LowSpeedCoilLat = latRate;
9109 : }
9110 0 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9111 0 : CoolPLR = 1.0;
9112 0 : HeatPLR = 0.0;
9113 0 : if (SpeedNum == 1) {
9114 0 : this->m_CoolingSpeedRatio = 0.0;
9115 : } else {
9116 0 : this->m_CoolingSpeedRatio = 1.0;
9117 : }
9118 0 : this->m_CoolingCycRatio = 1.0;
9119 0 : this->m_CoolingSpeedNum = SpeedNum;
9120 0 : this->calcUnitarySystemToLoad(state,
9121 : AirLoopNum,
9122 : FirstHVACIteration,
9123 : CoolPLR,
9124 : HeatPLR,
9125 : OnOffAirFlowRatio,
9126 : SensOutputOn,
9127 : LatOutputOn,
9128 0 : HXUnitOn,
9129 : HeatCoilLoad,
9130 : SupHeaterLoad,
9131 : CompressorONFlag);
9132 0 : if (ZoneLoad >= SensOutputOn) {
9133 0 : this->CoilSHR = this->SpeedSHR[SpeedNum];
9134 0 : break;
9135 : }
9136 : }
9137 : }
9138 : }
9139 : }
9140 2576542 : if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9141 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
9142 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9143 0 : HeatPLR = 0.0;
9144 0 : this->calcUnitarySystemToLoad(state,
9145 : AirLoopNum,
9146 : FirstHVACIteration,
9147 : CoolPLR,
9148 : HeatPLR,
9149 : OnOffAirFlowRatio,
9150 : SensOutput,
9151 : LatOutput,
9152 0 : HXUnitOn,
9153 : HeatCoilLoad,
9154 : SupHeaterLoad,
9155 : CompressorONFlag);
9156 0 : PartLoadRatio = CoolPLR;
9157 2576542 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9158 2576542 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1 &&
9159 0 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
9160 0 : HeatPLR = 0.0;
9161 0 : this->calcUnitarySystemToLoad(state,
9162 : AirLoopNum,
9163 : FirstHVACIteration,
9164 : 1.0,
9165 : HeatPLR,
9166 : OnOffAirFlowRatio,
9167 : SensOutputOn,
9168 : LatOutputOn,
9169 0 : HXUnitOn,
9170 : HeatCoilLoad,
9171 : SupHeaterLoad,
9172 : CompressorONFlag);
9173 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9174 0 : this->calcUnitarySystemToLoad(state,
9175 : AirLoopNum,
9176 : FirstHVACIteration,
9177 : CoolPLR,
9178 : HeatPLR,
9179 : OnOffAirFlowRatio,
9180 : SensOutput,
9181 : LatOutput,
9182 0 : HXUnitOn,
9183 : HeatCoilLoad,
9184 : SupHeaterLoad,
9185 : CompressorONFlag);
9186 0 : PartLoadRatio = CoolPLR;
9187 2576542 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9188 2576542 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling == 1) {
9189 0 : CoolPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9190 0 : HeatPLR = 0.0;
9191 0 : this->calcUnitarySystemToLoad(state,
9192 : AirLoopNum,
9193 : FirstHVACIteration,
9194 : CoolPLR,
9195 : HeatPLR,
9196 : OnOffAirFlowRatio,
9197 : SensOutput,
9198 : LatOutput,
9199 0 : HXUnitOn,
9200 : HeatCoilLoad,
9201 : SupHeaterLoad,
9202 : CompressorONFlag);
9203 0 : PartLoadRatio = CoolPLR;
9204 2576542 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9205 0 : (this->m_HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical ||
9206 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
9207 0 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel)) {
9208 0 : CoolPLR = 0.0;
9209 0 : HeatPLR = (ZoneLoad - SensOutputOff) / (SensOutputOn - SensOutputOff);
9210 0 : this->calcUnitarySystemToLoad(state,
9211 : AirLoopNum,
9212 : FirstHVACIteration,
9213 : CoolPLR,
9214 : HeatPLR,
9215 : OnOffAirFlowRatio,
9216 : SensOutput,
9217 : LatOutput,
9218 0 : HXUnitOn,
9219 : HeatCoilLoad,
9220 : SupHeaterLoad,
9221 : CompressorONFlag);
9222 0 : PartLoadRatio = HeatPLR;
9223 2576542 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->HeatingLoad &&
9224 0 : this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating) {
9225 0 : CoolPLR = 0.0;
9226 0 : if (this->m_HeatingSpeedNum == 1) {
9227 0 : this->m_HeatingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_HeatingSpeedNum] - SensOutputOff);
9228 0 : HeatPLR = this->m_HeatingCycRatio;
9229 0 : this->m_HeatingSpeedRatio = 0.0;
9230 : } else {
9231 0 : this->m_HeatingCycRatio = 1.0;
9232 0 : this->m_HeatingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_HeatingSpeedNum - 1]) /
9233 0 : (this->FullOutput[this->m_HeatingSpeedNum] - this->FullOutput[this->m_HeatingSpeedNum - 1]);
9234 0 : HeatPLR = this->m_HeatingSpeedRatio;
9235 : }
9236 0 : this->calcUnitarySystemToLoad(state,
9237 : AirLoopNum,
9238 : FirstHVACIteration,
9239 : CoolPLR,
9240 : HeatPLR,
9241 : OnOffAirFlowRatio,
9242 : SensOutput,
9243 : LatOutput,
9244 0 : HXUnitOn,
9245 : HeatCoilLoad,
9246 : SupHeaterLoad,
9247 : CompressorONFlag);
9248 0 : PartLoadRatio = HeatPLR;
9249 2576542 : } else if (state.dataGlobal->DoCoilDirectSolutions && state.dataUnitarySystems->CoolingLoad &&
9250 2576542 : this->m_CoolingCoilType_Num == HVAC::CoilDX_Cooling && this->m_NumOfSpeedCooling > 1) {
9251 0 : HeatPLR = 0.0;
9252 0 : if (this->m_CoolingSpeedNum == 1) {
9253 0 : this->m_CoolingCycRatio = (ZoneLoad - SensOutputOff) / (this->FullOutput[this->m_CoolingSpeedNum] - SensOutputOff);
9254 0 : CoolPLR = this->m_CoolingCycRatio;
9255 0 : this->m_CoolingSpeedRatio = 0.0;
9256 : } else {
9257 0 : this->m_CoolingCycRatio = 1.0;
9258 0 : this->m_CoolingSpeedRatio = (ZoneLoad - this->FullOutput[this->m_CoolingSpeedNum - 1]) /
9259 0 : (this->FullOutput[this->m_CoolingSpeedNum] - this->FullOutput[this->m_CoolingSpeedNum - 1]);
9260 0 : CoolPLR = this->m_CoolingSpeedRatio;
9261 : }
9262 0 : this->calcUnitarySystemToLoad(state,
9263 : AirLoopNum,
9264 : FirstHVACIteration,
9265 : CoolPLR,
9266 : HeatPLR,
9267 : OnOffAirFlowRatio,
9268 : SensOutput,
9269 : LatOutput,
9270 0 : HXUnitOn,
9271 : HeatCoilLoad,
9272 : SupHeaterLoad,
9273 : CompressorONFlag);
9274 0 : PartLoadRatio = CoolPLR;
9275 : } else {
9276 :
9277 2576542 : Real64 par6 = state.dataUnitarySystems->CoolingLoad ? 1.0 : 0.0;
9278 12057227 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9279 9480685 : Real64 const PartLoadRatio) {
9280 9480685 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9281 : PartLoadRatio,
9282 : this->m_UnitarySysNum,
9283 : FirstHVACIteration,
9284 : // par 3 not used?
9285 : CompressorONFlag,
9286 : ZoneLoad,
9287 : par6,
9288 : 1.0,
9289 : OnOffAirFlowRatio,
9290 : HXUnitOn,
9291 : // par 10 not used
9292 9480685 : AirLoopNum);
9293 2576542 : };
9294 : // Tolerance is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9295 2576542 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
9296 :
9297 2576542 : if (SolFlag == -1) {
9298 321 : if (state.dataUnitarySystems->HeatingLoad) {
9299 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9300 : // This does cause a problem when coil cannot turn on when OAT < min allowed or scheduled off
9301 : // If max iteration limit is exceeded, how do we know if the heating coil is operating?
9302 0 : TempMaxPLR = -0.1;
9303 0 : TempSensOutput = SensOutputOff;
9304 0 : while ((TempSensOutput - ZoneLoad) < 0.0 && TempMaxPLR < 1.0) {
9305 : // find upper limit of HeatingPLR
9306 0 : TempMaxPLR += 0.1;
9307 :
9308 : // SUBROUTINE SetSpeedVariables(UnitarySysNum, SensibleLoad, PartLoadRatio)
9309 0 : this->setSpeedVariables(state, true, TempMaxPLR);
9310 0 : this->calcUnitarySystemToLoad(state,
9311 : AirLoopNum,
9312 : FirstHVACIteration,
9313 : CoolPLR,
9314 : TempMaxPLR,
9315 : OnOffAirFlowRatio,
9316 : TempSensOutput,
9317 : TempLatOutput,
9318 0 : HXUnitOn,
9319 : HeatCoilLoad,
9320 : SupHeaterLoad,
9321 : CompressorONFlag);
9322 : }
9323 0 : TempMinPLR = TempMaxPLR;
9324 0 : while ((TempSensOutput - ZoneLoad) > 0.0 && TempMinPLR > 0.0) {
9325 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9326 0 : TempMaxPLR = TempMinPLR;
9327 : // find minimum limit of HeatingPLR
9328 0 : TempMinPLR -= 0.01;
9329 0 : this->setSpeedVariables(state, true, TempMinPLR);
9330 0 : this->calcUnitarySystemToLoad(state,
9331 : AirLoopNum,
9332 : FirstHVACIteration,
9333 : CoolPLR,
9334 : TempMinPLR,
9335 : OnOffAirFlowRatio,
9336 : TempSensOutput,
9337 : TempLatOutput,
9338 0 : HXUnitOn,
9339 : HeatCoilLoad,
9340 : SupHeaterLoad,
9341 : CompressorONFlag);
9342 : }
9343 : // Now solve again with tighter PLR limits
9344 : auto f2 = // (AUTO_OK_LAMBDA)
9345 0 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9346 0 : Real64 const PartLoadRatio) {
9347 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9348 : PartLoadRatio,
9349 : this->m_UnitarySysNum,
9350 : FirstHVACIteration,
9351 : // par 3 not used?
9352 : CompressorONFlag,
9353 : ZoneLoad,
9354 : par6,
9355 : 1.0,
9356 : OnOffAirFlowRatio,
9357 : HXUnitOn,
9358 : // par 10 not used
9359 0 : AirLoopNum);
9360 0 : };
9361 0 : General::SolveRoot(state, this->m_HeatConvTol, MaxIter, SolFlag, HeatPLR, f2, TempMinPLR, TempMaxPLR);
9362 0 : this->calcUnitarySystemToLoad(state,
9363 : AirLoopNum,
9364 : FirstHVACIteration,
9365 : CoolPLR,
9366 : HeatPLR,
9367 : OnOffAirFlowRatio,
9368 : TempSensOutput,
9369 : TempLatOutput,
9370 0 : HXUnitOn,
9371 : HeatCoilLoad,
9372 : SupHeaterLoad,
9373 : CompressorONFlag);
9374 321 : } else if (state.dataUnitarySystems->CoolingLoad) {
9375 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9376 : // IF iteration limit is exceeded (SolFlag = -1), find tighter boundary of solution and repeat RegulaFalsi
9377 321 : TempMaxPLR = -0.1;
9378 321 : TempSysOutput = SensOutputOff;
9379 321 : TempLoad = ZoneLoad;
9380 1284 : while ((TempSysOutput - TempLoad) > 0.0 &&
9381 : TempMaxPLR < 0.95) { // avoid PLR > 1 by limiting TempMaxPLR to 1 (i.e., TempMaxPLR += 0.1)
9382 : // find upper limit of HeatingPLR
9383 963 : TempMaxPLR += 0.1;
9384 963 : if (TempMaxPLR > 0.95 && TempMaxPLR < 1.05) {
9385 0 : TempMaxPLR = 1.0; // enforce a perfect 1.0 at the top end
9386 : }
9387 963 : this->setSpeedVariables(state, true, TempMaxPLR);
9388 963 : this->calcUnitarySystemToLoad(state,
9389 : AirLoopNum,
9390 : FirstHVACIteration,
9391 : TempMaxPLR,
9392 : HeatPLR,
9393 : OnOffAirFlowRatio,
9394 : TempSensOutput,
9395 : TempLatOutput,
9396 963 : HXUnitOn,
9397 : HeatCoilLoad,
9398 : SupHeaterLoad,
9399 : CompressorONFlag);
9400 963 : TempSysOutput = TempSensOutput;
9401 : }
9402 321 : TempMinPLR = TempMaxPLR;
9403 2532 : while ((TempSysOutput - TempLoad) < 0.0 &&
9404 : TempMinPLR > 0.025) { // lower limit might be changed to 0.005 without adverse affect
9405 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9406 2211 : TempMaxPLR = TempMinPLR;
9407 : // find minimum limit of HeatingPLR
9408 2211 : TempMinPLR -= 0.01;
9409 2211 : this->setSpeedVariables(state, true, TempMinPLR);
9410 2211 : this->calcUnitarySystemToLoad(state,
9411 : AirLoopNum,
9412 : FirstHVACIteration,
9413 : TempMinPLR,
9414 : HeatPLR,
9415 : OnOffAirFlowRatio,
9416 : TempSensOutput,
9417 : TempLatOutput,
9418 2211 : HXUnitOn,
9419 : HeatCoilLoad,
9420 : SupHeaterLoad,
9421 : CompressorONFlag);
9422 2211 : TempSysOutput = TempSensOutput;
9423 : }
9424 : // Now solve again with tighter PLR limits
9425 : auto f2 = // (AUTO_OK_LAMBDA)
9426 1866 : [&state, this, FirstHVACIteration, CompressorONFlag, ZoneLoad, par6, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9427 1545 : Real64 const PartLoadRatio) {
9428 1545 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9429 : PartLoadRatio,
9430 : this->m_UnitarySysNum,
9431 : FirstHVACIteration,
9432 : // par 3 not used?
9433 : CompressorONFlag,
9434 : ZoneLoad,
9435 : par6,
9436 : 1.0,
9437 : OnOffAirFlowRatio,
9438 : HXUnitOn,
9439 : // par 10 not used
9440 1545 : AirLoopNum);
9441 321 : };
9442 321 : General::SolveRoot(state, this->m_CoolConvTol, MaxIter, SolFlag, CoolPLR, f2, TempMinPLR, TempMaxPLR);
9443 321 : this->calcUnitarySystemToLoad(state,
9444 : AirLoopNum,
9445 : FirstHVACIteration,
9446 : CoolPLR,
9447 : HeatPLR,
9448 : OnOffAirFlowRatio,
9449 : TempSensOutput,
9450 : TempLatOutput,
9451 321 : HXUnitOn,
9452 : HeatCoilLoad,
9453 : SupHeaterLoad,
9454 : CompressorONFlag);
9455 : } // IF(HeatingLoad)THEN
9456 321 : if (SolFlag == -1) {
9457 33 : if (std::abs(ZoneLoad - TempSensOutput) > HVAC::SmallLoad) {
9458 33 : if (this->MaxIterIndex == 0) {
9459 5 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9460 5 : ShowContinueError(state, " Iteration limit exceeded in calculating system sensible part-load ratio.");
9461 10 : ShowContinueErrorTimeStamp(state,
9462 10 : format("Sensible load to be met = {:.2T} (watts), sensible output = {:.2T} "
9463 : "(watts), and the simulation continues.",
9464 : ZoneLoad,
9465 : TempSensOutput));
9466 : }
9467 99 : ShowRecurringWarningErrorAtEnd(state,
9468 66 : this->UnitType + " \"" + this->Name +
9469 : "\" - Iteration limit exceeded in calculating sensible part-load ratio error "
9470 : "continues. Sensible load statistics:",
9471 33 : this->MaxIterIndex,
9472 : ZoneLoad,
9473 : ZoneLoad);
9474 : }
9475 288 : } else if (SolFlag == -2) {
9476 202 : if (this->RegulaFalsiFailedIndex == 0) {
9477 4 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9478 4 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9479 8 : ShowContinueErrorTimeStamp(
9480 8 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9481 : }
9482 606 : ShowRecurringWarningErrorAtEnd(
9483 : state,
9484 404 : this->UnitType + " \"" + this->Name +
9485 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9486 202 : this->RegulaFalsiFailedIndex,
9487 : ZoneLoad,
9488 : ZoneLoad);
9489 : }
9490 2576221 : } else if (SolFlag == -2) {
9491 3463 : if (this->RegulaFalsiFailedIndex == 0) {
9492 8 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9493 8 : ShowContinueError(state, " sensible part-load ratio determined to be outside the range of 0-1.");
9494 16 : ShowContinueErrorTimeStamp(
9495 16 : state, format("Sensible load to be met = {:.2T} (watts), and the simulation continues.", ZoneLoad));
9496 : }
9497 10389 : ShowRecurringWarningErrorAtEnd(
9498 : state,
9499 6926 : this->UnitType + " \"" + this->Name +
9500 : "\" - sensible part-load ratio out of range error continues. Sensible load statistics:",
9501 3463 : this->RegulaFalsiFailedIndex,
9502 : ZoneLoad,
9503 : ZoneLoad);
9504 : } // IF (SolFlag == -1) THEN
9505 : }
9506 : } else { // load is not bounded by capacity. Leave PLR=1 or turn off unit?
9507 1337 : this->m_CoolingPartLoadFrac = 0.0;
9508 1337 : this->m_HeatingPartLoadFrac = 0.0;
9509 1337 : CoolPLR = 0.0;
9510 1337 : HeatPLR = 0.0;
9511 1337 : PartLoadRatio = 0.0;
9512 : } // IF((HeatingLoad .AND. ZoneLoad > SensOutputOff) .OR. (CoolingLoad .AND. ZoneLoad < SensOutputOff))THEN
9513 : } // IF((HeatingLoad .AND. ZoneLoad < SensOutputOn) .OR. (CoolingLoad .AND. ZoneLoad > SensOutputOn))THEN
9514 : }
9515 :
9516 2688840 : if (state.dataUnitarySystems->HeatingLoad && (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil)) {
9517 145361 : if (this->m_HeatingSpeedNum == 1) {
9518 45829 : this->m_HeatingCycRatio = PartLoadRatio;
9519 45829 : this->m_HeatingSpeedRatio = 0.0;
9520 : } else {
9521 99532 : if (this->m_SingleMode == 0) {
9522 97522 : this->m_HeatingCycRatio = 1.0;
9523 97522 : this->m_HeatingSpeedRatio = PartLoadRatio;
9524 : } else {
9525 2010 : this->m_HeatingCycRatio = PartLoadRatio;
9526 2010 : this->m_HeatingSpeedRatio = 1.0;
9527 : }
9528 : }
9529 145361 : HeatPLR = PartLoadRatio;
9530 145361 : CoolPLR = 0.0;
9531 145361 : this->m_CoolingCycRatio = 0.0;
9532 145361 : this->m_CoolingSpeedRatio = 0.0;
9533 2543479 : } else if (state.dataUnitarySystems->CoolingLoad && (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil)) {
9534 823077 : if (this->m_CoolingSpeedNum == 1) {
9535 316445 : this->m_CoolingCycRatio = PartLoadRatio;
9536 316445 : this->m_CoolingSpeedRatio = 0.0;
9537 : } else {
9538 506632 : if (this->m_SingleMode == 0) {
9539 503584 : this->m_CoolingCycRatio = 1.0;
9540 503584 : this->m_CoolingSpeedRatio = PartLoadRatio;
9541 : } else {
9542 3048 : this->m_CoolingCycRatio = PartLoadRatio;
9543 3048 : this->m_CoolingSpeedRatio = 1.0;
9544 : }
9545 : }
9546 823077 : this->m_HeatingCycRatio = 0.0;
9547 823077 : this->m_HeatingSpeedRatio = 0.0;
9548 823077 : HeatPLR = 0.0;
9549 823077 : CoolPLR = PartLoadRatio;
9550 : } else {
9551 1720402 : HeatPLR = this->m_HeatingPartLoadFrac;
9552 1720402 : CoolPLR = this->m_CoolingPartLoadFrac;
9553 : }
9554 :
9555 2688840 : this->calcUnitarySystemToLoad(state,
9556 : AirLoopNum,
9557 : FirstHVACIteration,
9558 : CoolPLR,
9559 : HeatPLR,
9560 : OnOffAirFlowRatio,
9561 : TempSensOutput,
9562 : TempLatOutput,
9563 2688840 : HXUnitOn,
9564 : HeatCoilLoad,
9565 : SupHeaterLoad,
9566 : CompressorONFlag);
9567 :
9568 : // FullSensibleOutput is used to set supplemental heater PLR in calling routine
9569 : // OnOffAirFlowRatio is used to average air flow between ON and OFF state
9570 2688840 : FullSensibleOutput = TempSensOutput;
9571 2688840 : LatOutputOn = TempLatOutput;
9572 :
9573 : // RETURN if the moisture load is met
9574 2688840 : if (state.dataUnitarySystems->MoistureLoad >= 0.0 || state.dataUnitarySystems->MoistureLoad >= TempLatOutput) return;
9575 : // Multimode does not meet the latent load, only the sensible load with or without HX active
9576 : // what if there is a heating load for a system using Multimode?
9577 34812 : if (!state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode) return;
9578 : // if HX was previously turned on return since sensible load is already met
9579 34812 : if (state.dataUnitarySystems->CoolingLoad && this->m_DehumidControlType_Num == DehumCtrlType::Multimode && HXUnitOn) return;
9580 : // IF(HeatingLoad .AND. UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)RETURN
9581 :
9582 13898 : if ((this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat || this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
9583 :
9584 : // find maximum latent output IF not already calculated
9585 13898 : if (state.dataUnitarySystems->HeatingLoad) {
9586 0 : CoolPLR = 1.0;
9587 0 : this->m_CoolingPartLoadFrac = 1.0;
9588 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
9589 0 : this->m_CoolingSpeedRatio = 1.0;
9590 0 : this->m_CoolingCycRatio = 1.0;
9591 0 : if (this->m_CoolingSpeedNum > 0) {
9592 0 : this->m_HeatingPartLoadFrac = 0.0;
9593 0 : this->m_HeatingSpeedNum = 0;
9594 0 : HeatPLR = 0.0;
9595 0 : state.dataUnitarySystems->CoolingLoad = true;
9596 0 : state.dataUnitarySystems->HeatingLoad = false;
9597 0 : this->m_HeatingCoilSensDemand = 0.0;
9598 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9599 0 : this->calcUnitarySystemToLoad(state,
9600 : AirLoopNum,
9601 : FirstHVACIteration,
9602 : 0.0,
9603 : 0.0,
9604 : OnOffAirFlowRatio,
9605 : TempSensOutput,
9606 : TempLatOutput,
9607 0 : HXUnitOn,
9608 : HeatCoilLoad,
9609 : SupHeaterLoad,
9610 : CompressorONFlag);
9611 0 : this->calcUnitarySystemToLoad(state,
9612 : AirLoopNum,
9613 : FirstHVACIteration,
9614 : CoolPLR,
9615 : HeatPLR,
9616 : OnOffAirFlowRatio,
9617 : TempSensOutput,
9618 : LatOutputOn,
9619 0 : HXUnitOn,
9620 : HeatCoilLoad,
9621 : SupHeaterLoad,
9622 : CompressorONFlag);
9623 : } else {
9624 0 : this->m_HeatingCoilSensDemand = 0.0;
9625 0 : this->m_CoolingCoilLatentDemand = 0.0;
9626 0 : this->calcUnitarySystemToLoad(state,
9627 : AirLoopNum,
9628 : FirstHVACIteration,
9629 : 0.0,
9630 : 0.0,
9631 : OnOffAirFlowRatio,
9632 : TempSensOutput,
9633 : TempLatOutput,
9634 0 : HXUnitOn,
9635 : HeatCoilLoad,
9636 : SupHeaterLoad,
9637 : CompressorONFlag);
9638 0 : this->m_CoolingCoilLatentDemand = state.dataUnitarySystems->MoistureLoad;
9639 0 : this->calcUnitarySystemToLoad(state,
9640 : AirLoopNum,
9641 : FirstHVACIteration,
9642 : CoolPLR,
9643 : HeatPLR,
9644 : OnOffAirFlowRatio,
9645 : TempSensOutput,
9646 : LatOutputOn,
9647 0 : HXUnitOn,
9648 : HeatCoilLoad,
9649 : SupHeaterLoad,
9650 : CompressorONFlag);
9651 : }
9652 : }
9653 :
9654 13898 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode && state.dataUnitarySystems->MoistureLoad < LatOutputOn) {
9655 4700 : HXUnitOn = true;
9656 4700 : CoolPLR = 1.0;
9657 4700 : this->m_CoolingPartLoadFrac = 1.0;
9658 4700 : this->calcUnitarySystemToLoad(state,
9659 : AirLoopNum,
9660 : FirstHVACIteration,
9661 : CoolPLR,
9662 : HeatPLR,
9663 : OnOffAirFlowRatio,
9664 : TempSensOutput,
9665 : LatOutputOn,
9666 4700 : HXUnitOn,
9667 : HeatCoilLoad,
9668 : SupHeaterLoad,
9669 : CompressorONFlag);
9670 4700 : FullSensibleOutput = TempSensOutput;
9671 : }
9672 :
9673 13898 : if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
9674 9198 : HXUnitOn = true; // HX is needed to meet moisture load
9675 9198 : if (this->m_NumOfSpeedCooling > 0) {
9676 19461 : for (SpeedNum = this->m_CoolingSpeedNum; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
9677 14636 : CoolPLR = 1.0;
9678 14636 : this->m_CoolingPartLoadFrac = CoolPLR;
9679 14636 : this->m_CoolingSpeedRatio = 1.0;
9680 14636 : this->m_CoolingCycRatio = 1.0;
9681 14636 : this->m_CoolingSpeedNum = SpeedNum;
9682 14636 : this->calcUnitarySystemToLoad(state,
9683 : AirLoopNum,
9684 : FirstHVACIteration,
9685 : CoolPLR,
9686 : HeatPLR,
9687 : OnOffAirFlowRatio,
9688 : SensOutputOn,
9689 : LatOutputOn,
9690 14636 : HXUnitOn,
9691 : HeatCoilLoad,
9692 : SupHeaterLoad,
9693 : CompressorONFlag);
9694 14636 : if (state.dataGlobal->DoCoilDirectSolutions && this->m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
9695 0 : this->FullOutput[SpeedNum] = SensOutputOn;
9696 : }
9697 : // over specified logic? it has to be a water coil? what about other VS coil models?
9698 14636 : if ((this->m_CoolingCoilType_Num != HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
9699 14636 : ((this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
9700 14636 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
9701 0 : !this->m_DiscreteSpeedCoolingCoil)) {
9702 0 : this->m_CoolingSpeedRatio = 0.0;
9703 0 : this->m_CoolingSpeedNum = SpeedNum - 1;
9704 0 : if (this->m_CoolingSpeedNum == 0) {
9705 0 : this->m_CoolingCycRatio = 0.0;
9706 0 : CoolPLR = 0.0;
9707 : } else {
9708 0 : this->m_CoolingCycRatio = 1.0;
9709 0 : this->m_CoolingSpeedRatio = 0.0;
9710 0 : if (this->m_SingleMode == 1) {
9711 0 : CoolPLR = 1.0;
9712 : }
9713 : }
9714 :
9715 0 : this->calcUnitarySystemToLoad(state,
9716 : AirLoopNum,
9717 : FirstHVACIteration,
9718 : CoolPLR,
9719 : HeatPLR,
9720 : OnOffAirFlowRatio,
9721 : SensOutputOn,
9722 : LatOutputOn,
9723 0 : HXUnitOn,
9724 : HeatCoilLoad,
9725 : SupHeaterLoad,
9726 : CompressorONFlag);
9727 0 : this->m_CoolingSpeedNum = SpeedNum;
9728 : }
9729 14636 : if (state.dataUnitarySystems->MoistureLoad >= LatOutputOn) {
9730 4373 : break;
9731 : }
9732 : }
9733 : } else {
9734 0 : CoolPLR = 1.0;
9735 0 : this->calcUnitarySystemToLoad(state,
9736 : AirLoopNum,
9737 : FirstHVACIteration,
9738 : CoolPLR,
9739 : HeatPLR,
9740 : OnOffAirFlowRatio,
9741 : SensOutputOn,
9742 : LatOutputOn,
9743 0 : HXUnitOn,
9744 : HeatCoilLoad,
9745 : SupHeaterLoad,
9746 : CompressorONFlag);
9747 0 : this->m_CoolingPartLoadFrac = CoolPLR;
9748 : }
9749 : }
9750 :
9751 27796 : if ((state.dataUnitarySystems->MoistureLoad < TempLatOutput) &&
9752 13898 : (state.dataUnitarySystems->MoistureLoad > LatOutputOn)) { // bounds check for RegulaFalsi
9753 :
9754 : // save heating PLR
9755 6137 : HeatPLR = this->m_HeatingPartLoadFrac;
9756 : Real64 par5;
9757 : Real64 par7;
9758 6137 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9759 1764 : par5 = ZoneLoad;
9760 1764 : par7 = 1.0;
9761 : } else {
9762 4373 : par5 = state.dataUnitarySystems->MoistureLoad;
9763 4373 : par7 = 0.0;
9764 : }
9765 : // Tolerance is fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
9766 29129 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, par5, par7, OnOffAirFlowRatio, HXUnitOn, AirLoopNum](
9767 22992 : Real64 const PartLoadRatio) {
9768 22992 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9769 : PartLoadRatio,
9770 : this->m_UnitarySysNum,
9771 : FirstHVACIteration,
9772 : // par 3 not used?
9773 : CompressorONFlag,
9774 : par5,
9775 : 1.0,
9776 : par7,
9777 : OnOffAirFlowRatio,
9778 : HXUnitOn,
9779 : // par 10 not used
9780 22992 : AirLoopNum);
9781 6137 : };
9782 6137 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, PartLoadRatio, f, 0.0, 1.0);
9783 6137 : this->m_CoolingPartLoadFrac = PartLoadRatio;
9784 6137 : this->m_HeatingPartLoadFrac = HeatPLR;
9785 7761 : } else if (state.dataUnitarySystems->MoistureLoad < LatOutputOn && state.dataUnitarySystems->CoolingLoad) {
9786 : // Logic below needs further look...what to do if the bounds check for RegulaFalsi fail?
9787 : // I'm not even sure if this should be done.
9788 : // It's wrong anyway, since there won't be a cooling load if multimode (see RETURN about 80 lines up).
9789 7761 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode) {
9790 4825 : this->m_CoolingPartLoadFrac = 1.0;
9791 : }
9792 : }
9793 : }
9794 :
9795 13898 : CoolPLR = this->m_CoolingPartLoadFrac;
9796 13898 : HeatPLR = this->m_HeatingPartLoadFrac;
9797 :
9798 13898 : this->calcUnitarySystemToLoad(state,
9799 : AirLoopNum,
9800 : FirstHVACIteration,
9801 : CoolPLR,
9802 : HeatPLR,
9803 : OnOffAirFlowRatio,
9804 : TempSensOutput,
9805 : TempLatOutput,
9806 13898 : HXUnitOn,
9807 : HeatCoilLoad,
9808 : SupHeaterLoad,
9809 : CompressorONFlag);
9810 :
9811 13898 : if (SolFlagLat == -1) {
9812 : // RegulaFalsi may not find cooling PLR when the latent degradation model is used.
9813 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
9814 0 : TempMaxPLR = -0.1;
9815 0 : TempLatOutput = LatOutputOff;
9816 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
9817 : // find upper limit of HeatingPLR
9818 0 : TempMaxPLR += 0.1;
9819 0 : this->calcUnitarySystemToLoad(state,
9820 : AirLoopNum,
9821 : FirstHVACIteration,
9822 : TempMaxPLR,
9823 : HeatPLR,
9824 : OnOffAirFlowRatio,
9825 : TempSensOutput,
9826 : TempLatOutput,
9827 0 : HXUnitOn,
9828 : HeatCoilLoad,
9829 : SupHeaterLoad,
9830 : CompressorONFlag);
9831 : }
9832 0 : TempMinPLR = TempMaxPLR;
9833 0 : while ((TempLatOutput - state.dataUnitarySystems->MoistureLoad) < 0.0 && TempMinPLR > 0.0) {
9834 : // pull upper limit of HeatingPLR DOwn to last valid limit (i.e. heat output still exceeds SystemSensibleLoad)
9835 0 : TempMaxPLR = TempMinPLR;
9836 : // find minimum limit of HeatingPLR
9837 0 : TempMinPLR -= 0.01;
9838 0 : this->calcUnitarySystemToLoad(state,
9839 : AirLoopNum,
9840 : FirstHVACIteration,
9841 : TempMinPLR,
9842 : HeatPLR,
9843 : OnOffAirFlowRatio,
9844 : TempSensOutput,
9845 : TempLatOutput,
9846 0 : HXUnitOn,
9847 : HeatCoilLoad,
9848 : SupHeaterLoad,
9849 : CompressorONFlag);
9850 : }
9851 : // Now solve again with tighter PLR limits
9852 : Real64 par5;
9853 : Real64 par7;
9854 0 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
9855 0 : par5 = ZoneLoad;
9856 0 : par7 = 1.0;
9857 : } else {
9858 0 : par5 = state.dataUnitarySystems->MoistureLoad;
9859 0 : par7 = 0.0;
9860 : }
9861 : // // Tolerance is fraction of load, M
9862 0 : auto f = [&state, this, FirstHVACIteration, CompressorONFlag, OnOffAirFlowRatio, HXUnitOn, AirLoopNum, par5, par7](
9863 0 : Real64 const PartLoadRatio) {
9864 : // 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
9865 : // a unit or integration test
9866 : // TODO: So I made some assumptions about the arguments. I'm not sure if ultimately this is even accessible, so maybe it doesn't
9867 : // matter.
9868 0 : return UnitarySys::calcUnitarySystemLoadResidual(state,
9869 : PartLoadRatio,
9870 : this->m_UnitarySysNum,
9871 : FirstHVACIteration,
9872 : // par 3 not used?
9873 : CompressorONFlag,
9874 : par5,
9875 : 1.0,
9876 : par7,
9877 : OnOffAirFlowRatio,
9878 : HXUnitOn,
9879 : // par 10 not used
9880 0 : AirLoopNum);
9881 0 : };
9882 0 : General::SolveRoot(state, 0.001, MaxIter, SolFlagLat, CoolPLR, f, TempMinPLR, TempMaxPLR);
9883 0 : this->calcUnitarySystemToLoad(state,
9884 : AirLoopNum,
9885 : FirstHVACIteration,
9886 : CoolPLR,
9887 : HeatPLR,
9888 : OnOffAirFlowRatio,
9889 : TempSensOutput,
9890 : TempLatOutput,
9891 0 : HXUnitOn,
9892 : HeatCoilLoad,
9893 : SupHeaterLoad,
9894 : CompressorONFlag);
9895 0 : if (SolFlagLat == -1) {
9896 0 : if (std::abs(state.dataUnitarySystems->MoistureLoad - TempLatOutput) > HVAC::SmallLoad) {
9897 0 : if (this->warnIndex.m_LatMaxIterIndex == 0) {
9898 0 : ShowWarningMessage(state, format("Coil control failed to converge for {}:{}", this->UnitType, this->Name));
9899 0 : ShowContinueError(state, " Iteration limit exceeded in calculating system Latent part-load ratio.");
9900 0 : ShowContinueErrorTimeStamp(
9901 : state,
9902 0 : format("Latent load to be met = {:.2T} (watts), Latent output = {:.2T} (watts), and the simulation continues.",
9903 0 : state.dataUnitarySystems->MoistureLoad,
9904 : TempLatOutput));
9905 : }
9906 0 : ShowRecurringWarningErrorAtEnd(
9907 : state,
9908 0 : this->UnitType + " \"" + this->Name +
9909 : "\" - Iteration limit exceeded in calculating Latent part-load ratio error continues. Latent load statistics:",
9910 0 : this->warnIndex.m_LatMaxIterIndex,
9911 0 : state.dataUnitarySystems->MoistureLoad,
9912 0 : state.dataUnitarySystems->MoistureLoad);
9913 : }
9914 0 : } else if (SolFlagLat == -2) {
9915 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
9916 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9917 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
9918 0 : ShowContinueErrorTimeStamp(
9919 : state,
9920 0 : format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
9921 : }
9922 0 : ShowRecurringWarningErrorAtEnd(state,
9923 0 : this->UnitType + " \"" + this->Name +
9924 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
9925 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
9926 0 : state.dataUnitarySystems->MoistureLoad,
9927 0 : state.dataUnitarySystems->MoistureLoad);
9928 : }
9929 13898 : } else if (SolFlagLat == -2) {
9930 0 : if (this->warnIndex.m_LatRegulaFalsiFailedIndex == 0) {
9931 0 : ShowWarningMessage(state, format("Coil control failed for {}:{}", this->UnitType, this->Name));
9932 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
9933 0 : ShowContinueErrorTimeStamp(
9934 0 : state, format("Latent load to be met = {:.2T} (watts), and the simulation continues.", state.dataUnitarySystems->MoistureLoad));
9935 : }
9936 0 : ShowRecurringWarningErrorAtEnd(state,
9937 0 : this->UnitType + " \"" + this->Name +
9938 : "\" - Latent part-load ratio out of range error continues. Latent load statistics:",
9939 0 : this->warnIndex.m_LatRegulaFalsiFailedIndex,
9940 0 : state.dataUnitarySystems->MoistureLoad,
9941 0 : state.dataUnitarySystems->MoistureLoad);
9942 : }
9943 :
9944 13898 : FullSensibleOutput = TempSensOutput;
9945 :
9946 13898 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).HumRat);
9947 : Real64 heatCoildT =
9948 13898 : (this->m_HeatCoilExists)
9949 13898 : ? (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp)
9950 13898 : : 0.0;
9951 : Real64 CoolingOnlySensibleOutput =
9952 13898 : state.dataLoopNodes->Node(this->CoolCoilInletNodeNum).MassFlowRate * CpAir *
9953 13898 : ((state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp) -
9954 13898 : heatCoildT);
9955 13898 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0) {
9956 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
9957 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
9958 13193 : this->m_DehumidInducedHeatingDemandRate = max(0.0, (CoolingOnlySensibleOutput + state.dataUnitarySystems->QToHeatSetPt));
9959 : // Heating mode and dehumidification is required
9960 : } else {
9961 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
9962 : // the heating coil pick up the load due to outdoor air.
9963 705 : this->m_DehumidInducedHeatingDemandRate = max(0.0, CoolingOnlySensibleOutput);
9964 : }
9965 4166007 : }
9966 :
9967 4098019 : void UnitarySys::initLoadBasedControl(EnergyPlusData &state,
9968 : int const AirLoopNum, // number of the current air loop being simulated
9969 : bool const FirstHVACIteration,
9970 : Real64 &OnOffAirFlowRatio,
9971 : Real64 &ZoneLoad)
9972 : {
9973 :
9974 : // SUBROUTINE INFORMATION:
9975 : // AUTHOR Richard Raustad, FSEC
9976 : // DATE WRITTEN February 2013
9977 :
9978 : // PURPOSE OF THIS SUBROUTINE:
9979 : // This subroutine is for initializations of the load controlled Unitary Systems.
9980 :
9981 : // METHODOLOGY EMPLOYED:
9982 : // Initialize mass flow rates and speed ratios. Calculate loads and adjust if necessary when using constant fan.
9983 :
9984 : // SUBROUTINE PARAMETER DEFINITIONS:
9985 : static constexpr std::string_view routineName("InitUnitarySystems");
9986 4098019 : Real64 QZnReq = 0.0;
9987 4098019 : Real64 QActual = 0.0;
9988 4098019 : Real64 SensOutputOff = 0.0;
9989 4098019 : Real64 LatOutputOff = 0.0;
9990 4098019 : Real64 HeatCoilLoad = 0.0;
9991 4098019 : Real64 SupHeaterLoad = 0.0;
9992 4098019 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off;
9993 :
9994 : // do the Begin Environment initializations
9995 4098019 : if (state.dataGlobal->BeginEnvrnFlag && this->m_MyEnvrnFlag2) {
9996 :
9997 1875 : bool errorsFound = false;
9998 : // set fluid-side hardware limits
9999 1875 : if (this->HeatCoilFluidInletNode > 0) {
10000 :
10001 62 : if (this->MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
10002 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10003 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
10004 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_HeatingCoilName, FirstHVACIteration, this->m_HeatingCoilIndex);
10005 : Real64 CoilMaxVolFlowRate =
10006 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_HeatingCoilName, errorsFound);
10007 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10008 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
10009 0 : state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum).FluidName,
10010 : Constant::CWInitConvTemp,
10011 0 : state.dataPlnt->PlantLoop(this->HeatCoilPlantLoc.loopNum).FluidIndex,
10012 : routineName);
10013 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
10014 : }
10015 : }
10016 : // IF steam coil max steam flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10017 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
10018 0 : SteamCoils::SimulateSteamCoilComponents(state,
10019 : this->m_HeatingCoilName,
10020 : FirstHVACIteration,
10021 0 : this->m_HeatingCoilIndex,
10022 0 : 1.0,
10023 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10024 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_HeatingCoilIndex, errorsFound);
10025 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10026 0 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
10027 0 : Real64 TempSteamIn = 100.0;
10028 : Real64 SteamDensity =
10029 0 : FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, routineName);
10030 0 : this->MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10031 : }
10032 : }
10033 : }
10034 :
10035 62 : PlantUtilities::InitComponentNodes(
10036 : state, 0.0, this->MaxHeatCoilFluidFlow, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum);
10037 : }
10038 1875 : if (this->m_SuppCoilFluidInletNode > 0) {
10039 0 : if (this->m_MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
10040 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
10041 : // IF water coil max water flow rate is DataSizing::AutoSized, simulate once in order to mine max flow rate
10042 0 : WaterCoils::SimulateWaterCoilComponents(state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex);
10043 : Real64 CoilMaxVolFlowRate =
10044 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", this->m_SuppHeatCoilName, errorsFound);
10045 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10046 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
10047 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).FluidName,
10048 : Constant::CWInitConvTemp,
10049 0 : state.dataPlnt->PlantLoop(this->m_SuppCoilPlantLoc.loopNum).FluidIndex,
10050 : routineName);
10051 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
10052 : }
10053 : }
10054 0 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
10055 0 : SteamCoils::SimulateSteamCoilComponents(state,
10056 : this->m_SuppHeatCoilName,
10057 : FirstHVACIteration,
10058 0 : this->m_SuppHeatCoilIndex,
10059 0 : 1.0,
10060 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
10061 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, this->m_SuppHeatCoilIndex, errorsFound);
10062 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
10063 0 : int SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
10064 0 : Real64 TempSteamIn = 100.0;
10065 : Real64 SteamDensity =
10066 0 : FluidProperties::GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, SteamIndex, routineName);
10067 0 : this->m_MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
10068 : }
10069 : }
10070 0 : PlantUtilities::InitComponentNodes(
10071 : state, 0.0, this->m_MaxSuppCoilFluidFlow, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum);
10072 : }
10073 : }
10074 1875 : this->m_MyEnvrnFlag2 = false;
10075 : }
10076 :
10077 4098019 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && this->m_MyCheckFlag) {
10078 1437740 : if (this->m_AirLoopEquipment) {
10079 101 : int zoneInlet = this->m_ZoneInletNode;
10080 101 : if (zoneInlet == 0) {
10081 0 : this->m_ThisSysInputShouldBeGotten = true; // need to find zone inlet node once data is available
10082 0 : this->m_MySizingCheckFlag = true; // need to resize after getInput is read in again
10083 0 : this->m_OKToPrintSizing = true; // hope first time back through finds the data, else multiple prints to the eio
10084 0 : this->m_airLoopReturnCounter += 1;
10085 0 : if (this->m_airLoopReturnCounter < 3) return;
10086 : }
10087 : // setup zone equipment sequence information based on finding matching air terminal
10088 101 : if (state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex > 0) {
10089 101 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).EquipListIndex)
10090 101 : .getPrioritiesForInletNode(state, zoneInlet, this->m_ZoneSequenceCoolingNum, this->m_ZoneSequenceHeatingNum);
10091 : }
10092 101 : this->m_MyCheckFlag = false;
10093 101 : if (this->m_ZoneSequenceCoolingNum == 0 || this->m_ZoneSequenceHeatingNum == 0) {
10094 0 : ShowSevereError(state,
10095 0 : format("{} \"{}\": Airloop air terminal in the zone equipment list for zone = {} not it or is not allowed "
10096 : "Zone Equipment Cooling or Heating Sequence = 0.",
10097 0 : this->UnitType,
10098 0 : this->Name,
10099 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10100 0 : ShowFatalError(
10101 : state,
10102 0 : format("Subroutine InitLoadBasedControl: Errors it in getting {} input. Preceding condition(s) causes termination.",
10103 0 : this->UnitType));
10104 : }
10105 : }
10106 1437740 : if (this->m_ZoneInletNode == 0) {
10107 0 : ShowSevereError(state,
10108 0 : format("{} \"{}\": The zone inlet node in the controlled zone ({}) is not found.",
10109 0 : this->UnitType,
10110 0 : this->Name,
10111 0 : state.dataHeatBal->Zone(this->ControlZoneNum).Name));
10112 0 : ShowFatalError(
10113 : state,
10114 0 : format("Subroutine InitLoadBasedControl: Errors found in getting {} input. Preceding condition(s) causes termination.",
10115 0 : this->UnitType));
10116 : }
10117 : }
10118 :
10119 : // What type of logic is this? Is the point to go through the main IF once? or every other time?
10120 : // RR: This was used with AirflowNetwork to calculate duct losses.
10121 : // RR: AFN counts the number of passes through airloop equipment (same logic in Furnaces and other modules) and resets the counter to 0 on
10122 : // BeginEnvrnFlag. RR: This has been changed in this module and AFN to use AirflowNetworkFanActivated if AirflowNetworkUnitarySystem is seen
10123 : // by AFN. RR: Search for AirflowNetworkFanActivated in this module to see usage. The following lines of code can probably be removed although
10124 : // it would require a AFN input file to test.
10125 4098019 : if (state.dataGlobal->BeginEnvrnFlag && m_initLoadBasedControlAirLoopPass) {
10126 1774 : m_airLoopPassCounter = 0;
10127 1774 : m_initLoadBasedControlAirLoopPass = false;
10128 : }
10129 4098019 : if (!state.dataGlobal->BeginEnvrnFlag) {
10130 4081586 : this->m_MyEnvrnFlag2 = true; // this does not appear to be needed, only initializes autosized coil fluid flow rates
10131 4081586 : m_initLoadBasedControlAirLoopPass = true;
10132 : }
10133 :
10134 4098019 : ++m_airLoopPassCounter;
10135 4098019 : if (m_airLoopPassCounter > 2) m_airLoopPassCounter = 1;
10136 :
10137 : // reset duct losses from previous iteration
10138 4098019 : if (FirstHVACIteration) {
10139 1262135 : this->m_SenLoadLoss = 0.0;
10140 1262135 : this->m_LatLoadLoss = 0.0;
10141 : }
10142 :
10143 : // Calcuate air distribution losses
10144 4098019 : if (!FirstHVACIteration && state.afn->AirflowNetworkFanActivated) {
10145 9960 : Real64 DeltaMassRate = 0.0;
10146 9960 : Real64 TotalOutput = 0.0; // total output rate, {W}
10147 9960 : Real64 SensibleOutputDelta = 0.0; // delta sensible output rate, {W}
10148 9960 : Real64 LatentOutputDelta = 0.0; // delta latent output rate, {W}
10149 9960 : Real64 TotalOutputDelta = 0.0; // delta total output rate, {W}
10150 9960 : int ZoneInNode = this->m_ZoneInletNode;
10151 9960 : Real64 MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10152 19920 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
10153 9960 : this->m_sysType != SysType::PackagedWSHP) {
10154 9960 : DeltaMassRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate -
10155 9960 : state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / this->ControlZoneMassFlowFrac;
10156 9960 : if (DeltaMassRate < 0.0) DeltaMassRate = 0.0;
10157 : } else {
10158 0 : MassFlowRate = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
10159 0 : DeltaMassRate = 0.0;
10160 : }
10161 39840 : CalcComponentSensibleLatentOutput(MassFlowRate,
10162 9960 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10163 9960 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10164 9960 : state.dataLoopNodes->Node(ZoneInNode).Temp,
10165 9960 : state.dataLoopNodes->Node(ZoneInNode).HumRat,
10166 9960 : this->m_SenLoadLoss,
10167 9960 : this->m_LatLoadLoss,
10168 : TotalOutput);
10169 39840 : CalcComponentSensibleLatentOutput(DeltaMassRate,
10170 9960 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
10171 9960 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
10172 9960 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
10173 9960 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
10174 : SensibleOutputDelta,
10175 : LatentOutputDelta,
10176 : TotalOutputDelta);
10177 9960 : this->m_SenLoadLoss = this->m_SenLoadLoss + SensibleOutputDelta;
10178 9960 : if (std::abs(this->m_SensibleLoadMet) > 0.0) {
10179 9960 : if (std::abs(this->m_SenLoadLoss / this->m_SensibleLoadMet) < 0.001) this->m_SenLoadLoss = 0.0;
10180 : }
10181 9960 : if (this->m_Humidistat) {
10182 0 : this->m_LatLoadLoss = this->m_LatLoadLoss + LatentOutputDelta;
10183 0 : if (std::abs(this->m_LatentLoadMet) > 0.0) {
10184 0 : if (std::abs(this->m_LatLoadLoss / this->m_LatentLoadMet) < 0.001) this->m_LatLoadLoss = 0.0;
10185 : }
10186 : }
10187 : }
10188 :
10189 4098019 : if (this->m_FanOpModeSchedPtr > 0) {
10190 4095511 : if (ScheduleManager::GetCurrentScheduleValue(state, this->m_FanOpModeSchedPtr) == 0.0) {
10191 1915485 : this->m_FanOpMode = HVAC::FanOp::Cycling;
10192 : } else {
10193 2180026 : this->m_FanOpMode = HVAC::FanOp::Continuous;
10194 2180026 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10195 : }
10196 : }
10197 :
10198 : // System load calculation for cycling fan systems
10199 4098019 : if (this->ControlZoneMassFlowFrac > 0.0) {
10200 4097801 : QZnReq = ZoneLoad / this->ControlZoneMassFlowFrac;
10201 4097801 : state.dataUnitarySystems->MoistureLoad /= this->ControlZoneMassFlowFrac;
10202 4097801 : state.dataUnitarySystems->QToCoolSetPt /= this->ControlZoneMassFlowFrac;
10203 4097801 : state.dataUnitarySystems->QToHeatSetPt /= this->ControlZoneMassFlowFrac;
10204 4097801 : ZoneLoad = QZnReq;
10205 : } else {
10206 218 : QZnReq = ZoneLoad;
10207 218 : this->ControlZoneMassFlowFrac = 1.0;
10208 : }
10209 :
10210 4098019 : state.dataUnitarySystems->CoolingLoad = false;
10211 4098019 : state.dataUnitarySystems->HeatingLoad = false;
10212 4098019 : Real64 smallLoadTolerance = this->m_SmallLoadTolerance;
10213 4098019 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10214 1254457 : smallLoadTolerance = HVAC::SmallLoad;
10215 : }
10216 4098019 : if (QZnReq > smallLoadTolerance) { // no need to check deadband flag, QZnReq is correct.
10217 1367820 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::ThermostatType::SingleCooling) {
10218 1367820 : state.dataUnitarySystems->HeatingLoad = true;
10219 : }
10220 2730199 : } else if (QZnReq < -smallLoadTolerance) {
10221 1745103 : if (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum) != HVAC::ThermostatType::SingleHeating) {
10222 1745092 : state.dataUnitarySystems->CoolingLoad = true;
10223 : }
10224 : }
10225 :
10226 : // System load calculation for constant fan systems
10227 4098019 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10228 2180026 : bool HXUnitOn = false;
10229 2180026 : this->FanPartLoadRatio = 0.0; // sets fan to minimum for ASHRAE model
10230 2180026 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
10231 : // the SpeedNum is set for PTUnits, might need to set this for all multi/var speed coils?
10232 291804 : if (state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) {
10233 5991 : m_CoolingSpeedNum = 1;
10234 285813 : } else if (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil) {
10235 1726 : m_HeatingSpeedNum = 1;
10236 : }
10237 : }
10238 2180026 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio,
10239 : 0.0); // CompOnMassFlow and CompOffMassFlow are scalar, reset to this system's values
10240 2180026 : this->calcUnitarySystemToLoad(state,
10241 : AirLoopNum,
10242 : FirstHVACIteration,
10243 : 0.0,
10244 : 0.0,
10245 : OnOffAirFlowRatio,
10246 : SensOutputOff,
10247 : LatOutputOff,
10248 : HXUnitOn,
10249 : HeatCoilLoad,
10250 : SupHeaterLoad,
10251 : CompressorOn);
10252 :
10253 2180026 : switch (state.dataHeatBalFanSys->TempControlType(this->ControlZoneNum)) {
10254 9143 : case HVAC::ThermostatType::SingleHeating:
10255 9143 : state.dataUnitarySystems->CoolingLoad = false;
10256 : // No heating load and constant fan pushes zone below heating set point
10257 13873 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt <= 0.0 &&
10258 4730 : SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10259 156 : state.dataUnitarySystems->HeatingLoad = true;
10260 156 : state.dataUnitarySystems->CoolingLoad = false;
10261 156 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10262 : }
10263 9143 : break;
10264 8938 : case HVAC::ThermostatType::SingleCooling:
10265 8938 : state.dataUnitarySystems->HeatingLoad = false;
10266 : // No heating load and constant fan pushes zone above cooling set point
10267 9055 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0 &&
10268 117 : SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10269 70 : state.dataUnitarySystems->HeatingLoad = false;
10270 70 : state.dataUnitarySystems->CoolingLoad = true;
10271 70 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10272 : }
10273 8938 : break;
10274 0 : case HVAC::ThermostatType::SingleHeatCool:
10275 : // zone temp above cooling and heating set point temps
10276 0 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10277 : // zone pushed below heating set point
10278 0 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10279 0 : state.dataUnitarySystems->HeatingLoad = true;
10280 0 : state.dataUnitarySystems->CoolingLoad = false;
10281 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10282 : }
10283 : // zone temp below heating set point temp
10284 0 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10285 : // zone pushed above cooling set point
10286 0 : if (SensOutputOff > 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10287 0 : state.dataUnitarySystems->HeatingLoad = false;
10288 0 : state.dataUnitarySystems->CoolingLoad = true;
10289 0 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10290 : }
10291 : }
10292 0 : break;
10293 2161945 : case HVAC::ThermostatType::DualSetPointWithDeadBand:
10294 : // zone temp above cooling and heating set point temps
10295 2161945 : if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10296 : // zone pushed into deadband
10297 1017676 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToCoolSetPt - SensOutputOff > HVAC::SmallLoad) {
10298 117837 : state.dataUnitarySystems->HeatingLoad = false;
10299 117837 : state.dataUnitarySystems->CoolingLoad = false;
10300 117837 : ZoneLoad = 0.0;
10301 : }
10302 : // zone pushed below heating set point
10303 1017676 : if (SensOutputOff < 0.0 && state.dataUnitarySystems->QToHeatSetPt - SensOutputOff > HVAC::SmallLoad) {
10304 34638 : state.dataUnitarySystems->HeatingLoad = true;
10305 34638 : state.dataUnitarySystems->CoolingLoad = false;
10306 34638 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10307 : }
10308 : // zone temp below heating set point temp
10309 1144269 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10310 : // zone pushed into deadband
10311 625047 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt > HVAC::SmallLoad) {
10312 977 : state.dataUnitarySystems->HeatingLoad = false;
10313 977 : state.dataUnitarySystems->CoolingLoad = false;
10314 977 : ZoneLoad = 0.0;
10315 : }
10316 : // zone pushed above cooling set point
10317 625047 : if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10318 42 : state.dataUnitarySystems->HeatingLoad = false;
10319 42 : state.dataUnitarySystems->CoolingLoad = true;
10320 42 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10321 : }
10322 : // zone temp between set point temps
10323 519222 : } else if (state.dataUnitarySystems->QToHeatSetPt < 0.0 && state.dataUnitarySystems->QToCoolSetPt > 0.0) {
10324 : // zone pushed below heating set point
10325 519222 : if (SensOutputOff < 0.0 && SensOutputOff - state.dataUnitarySystems->QToHeatSetPt < -HVAC::SmallLoad) {
10326 216045 : state.dataUnitarySystems->HeatingLoad = true;
10327 216045 : state.dataUnitarySystems->CoolingLoad = false;
10328 216045 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10329 : // zone pushed above cooling set point
10330 303177 : } else if (SensOutputOff > 0.0 && SensOutputOff - state.dataUnitarySystems->QToCoolSetPt > HVAC::SmallLoad) {
10331 17160 : state.dataUnitarySystems->HeatingLoad = false;
10332 17160 : state.dataUnitarySystems->CoolingLoad = true;
10333 17160 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10334 : }
10335 : }
10336 2161945 : break;
10337 0 : default:
10338 0 : break;
10339 : }
10340 :
10341 : // push iteration mode stack and set current mode
10342 2180026 : this->m_IterationMode[2] = this->m_IterationMode[1];
10343 2180026 : this->m_IterationMode[1] = this->m_IterationMode[0];
10344 2180026 : if (state.dataUnitarySystems->CoolingLoad) {
10345 925734 : this->m_IterationMode[0] = CoolingMode;
10346 1254292 : } else if (state.dataUnitarySystems->HeatingLoad) {
10347 886281 : this->m_IterationMode[0] = HeatingMode;
10348 : } else {
10349 368011 : this->m_IterationMode[0] = NoCoolHeat;
10350 : }
10351 : // IF small loads to meet or not converging, just shut down unit
10352 2180026 : if (std::abs(ZoneLoad) < smallLoadTolerance) {
10353 369217 : ZoneLoad = 0.0;
10354 369217 : state.dataUnitarySystems->CoolingLoad = false;
10355 369217 : state.dataUnitarySystems->HeatingLoad = false;
10356 1810809 : } else if (this->m_IterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 6)) {
10357 : // attempt to lock output (air flow) if oscillations are detected
10358 204364 : int OperatingMode = this->m_IterationMode[0]; // VS systems can take a few more iterations than single-speed systems
10359 204364 : int OperatingModeMinusOne = this->m_IterationMode[1];
10360 204364 : int OperatingModeMinusTwo = this->m_IterationMode[2];
10361 204364 : bool Oscillate = true;
10362 204364 : if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) Oscillate = false;
10363 204364 : if (Oscillate) {
10364 29787 : if (state.dataUnitarySystems->QToCoolSetPt < 0.0) {
10365 17998 : state.dataUnitarySystems->HeatingLoad = false;
10366 17998 : state.dataUnitarySystems->CoolingLoad = true;
10367 17998 : ZoneLoad = state.dataUnitarySystems->QToCoolSetPt;
10368 11789 : } else if (state.dataUnitarySystems->QToHeatSetPt > 0.0) {
10369 0 : state.dataUnitarySystems->HeatingLoad = true;
10370 0 : state.dataUnitarySystems->CoolingLoad = false;
10371 0 : ZoneLoad = state.dataUnitarySystems->QToHeatSetPt;
10372 : } else {
10373 11789 : state.dataUnitarySystems->HeatingLoad = false;
10374 11789 : state.dataUnitarySystems->CoolingLoad = false;
10375 11789 : ZoneLoad = 0.0;
10376 : }
10377 : }
10378 : }
10379 : }
10380 :
10381 : // Determine the m_Staged status
10382 4098019 : if (allocated(state.dataZoneCtrls->StageZoneLogic) && this->m_DesignSpecMSHPIndex > -1) {
10383 0 : if (state.dataZoneCtrls->StageZoneLogic(this->ControlZoneNum)) {
10384 0 : this->m_Staged = true;
10385 0 : this->m_StageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).StageNum;
10386 : } else {
10387 0 : if (this->m_MyStagedFlag) {
10388 0 : ShowWarningError(state,
10389 : "ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to this UnitarySystem "
10390 : "object with UnitarySystemPerformance:Multispeed type = ");
10391 0 : ShowContinueError(state, format("{}. Please make correction. Simulation continues...", this->Name));
10392 0 : this->m_MyStagedFlag = false;
10393 : }
10394 : }
10395 : }
10396 :
10397 : // Staged control
10398 4098019 : if (this->m_Staged) {
10399 0 : if (this->m_StageNum == 0) {
10400 0 : state.dataUnitarySystems->HeatingLoad = false;
10401 0 : state.dataUnitarySystems->CoolingLoad = false;
10402 0 : QZnReq = 0.0;
10403 : } else {
10404 0 : QZnReq =
10405 0 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(this->ControlZoneNum).RemainingOutputRequired / this->ControlZoneMassFlowFrac;
10406 0 : if (QZnReq > 0.0) {
10407 0 : state.dataUnitarySystems->HeatingLoad = true;
10408 0 : state.dataUnitarySystems->CoolingLoad = false;
10409 : } else {
10410 0 : state.dataUnitarySystems->HeatingLoad = false;
10411 0 : state.dataUnitarySystems->CoolingLoad = true;
10412 : }
10413 : }
10414 : }
10415 :
10416 4098019 : if (this->m_DehumidControlType_Num == DehumCtrlType::Multimode) {
10417 117640 : if (state.dataUnitarySystems->HeatingLoad) state.dataUnitarySystems->MoistureLoad = 0.0;
10418 : }
10419 :
10420 : // Check load control
10421 4098019 : if (this->m_RunOnLatentOnlyWithSensible && ZoneLoad == 0.0) state.dataUnitarySystems->MoistureLoad = 0.0;
10422 4098019 : if (!this->m_RunOnSensibleLoad) {
10423 0 : ZoneLoad = 0.0;
10424 0 : state.dataUnitarySystems->CoolingLoad = false;
10425 0 : state.dataUnitarySystems->HeatingLoad = false;
10426 : }
10427 4098019 : if (!this->m_RunOnLatentLoad) state.dataUnitarySystems->MoistureLoad = 0.0;
10428 :
10429 : // Testing heat pump air to air with RH control with CoolReheat dehumidifaction control showed that when there was heating
10430 : // and moisture load, the cooling coil was turning on to meet the moisture load and reheat was then turning on to meet both
10431 : // heating load and excess cooling load caused by cooling coil. Adding the logic below caused the zone temperature,
10432 : // relative humidity, cooling/heating rate to line up for both the orignal and new file with unitary system object.
10433 :
10434 4098019 : if (this->m_SuppCoilExists) {
10435 1254177 : if (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10436 39744 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolCoilExists) {
10437 5574 : state.dataUnitarySystems->HeatingLoad = false;
10438 5574 : state.dataUnitarySystems->CoolingLoad = true;
10439 : }
10440 : }
10441 : }
10442 :
10443 : // set report variables for predicted sensible and latent load
10444 4098019 : this->m_SensibleLoadPredicted = ZoneLoad;
10445 4098019 : this->m_MoistureLoadPredicted = state.dataUnitarySystems->MoistureLoad;
10446 : }
10447 :
10448 38979650 : void UnitarySys::setOnOffMassFlowRate(EnergyPlusData &state,
10449 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
10450 : Real64 const PartLoadRatio // coil part-load ratio
10451 : )
10452 : {
10453 :
10454 : // SUBROUTINE INFORMATION:
10455 : // AUTHOR Chandan Sharma
10456 : // DATE WRITTEN May 2013
10457 :
10458 : // PURPOSE OF THIS SUBROUTINE:
10459 : // This subroutine is for initializations of the components.
10460 :
10461 : // METHODOLOGY EMPLOYED:
10462 : // The unitarysystem may have alternate air flow rates
10463 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
10464 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
10465 : // based on PLR.
10466 :
10467 : // REFERENCES:
10468 : // Based on SetOnOffMassFlowRate by Richard Raustad
10469 :
10470 38979650 : int HeatSpeedNum = 0;
10471 38979650 : int CoolSpeedNum = 0;
10472 :
10473 38979650 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10474 38979650 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10475 38979650 : state.dataUnitarySystems->m_massFlow1 = 0.0;
10476 38979650 : state.dataUnitarySystems->m_massFlow2 = 0.0;
10477 38979650 : state.dataUnitarySystems->OACompOnMassFlow = 0.0;
10478 38979650 : state.dataUnitarySystems->OACompOffMassFlow = 0.0;
10479 :
10480 : // Set the compressor or coil ON mass flow rate
10481 38979650 : if (state.dataUnitarySystems->HeatingLoad) {
10482 :
10483 14662605 : this->m_LastMode = HeatingMode;
10484 :
10485 14662605 : if (this->m_MultiOrVarSpeedHeatCoil) {
10486 :
10487 3408723 : HeatSpeedNum = this->m_HeatingSpeedNum;
10488 :
10489 3408723 : if (HeatSpeedNum == 0) {
10490 898855 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10491 898855 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10492 2509868 : } else if (HeatSpeedNum == 1) {
10493 1727233 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10494 1727233 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10495 782635 : } else if (HeatSpeedNum > 1) {
10496 782635 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10497 782635 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10498 : }
10499 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10500 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10501 3408723 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10502 2465321 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10503 0 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10504 0 : if (this->m_MultiOrVarSpeedCoolCoil) {
10505 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10506 0 : if (CoolSpeedNum < 1) {
10507 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10508 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10509 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10510 0 : } else if (CoolSpeedNum == 1) {
10511 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10512 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10513 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10514 : } else {
10515 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10516 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10517 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10518 : }
10519 : } else {
10520 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10521 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10522 : }
10523 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10524 : } else {
10525 2465321 : if (HeatSpeedNum == 0) {
10526 735251 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10527 735251 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10528 1730070 : } else if (HeatSpeedNum == 1) {
10529 1420890 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10530 1420890 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatMassFlowRate[HeatSpeedNum];
10531 : } else {
10532 309180 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10533 309180 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10534 : }
10535 2465321 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10536 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10537 2465321 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10538 2438803 : this->m_sysType == SysType::PackagedWSHP) {
10539 26518 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10540 : }
10541 : }
10542 : } else { // cycling fan mode
10543 943402 : if (HeatSpeedNum <= 1) {
10544 469947 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10545 469947 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10546 : } else {
10547 473455 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10548 473455 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10549 : }
10550 : // only used for PTUnit to UnitarySystem conversion, should use all the time
10551 943402 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10552 920422 : this->m_sysType == SysType::PackagedWSHP) {
10553 128196 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10554 : // does this assume OA flow <= min speed flow? wihtout this there are SolveRoot failures.
10555 128196 : if (HeatSpeedNum > 1) {
10556 82125 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10557 : }
10558 : }
10559 : }
10560 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10561 : // If a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
10562 11255338 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat &&
10563 11255338 : this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat && !this->m_DXHeatingCoil) {
10564 1456 : if (this->m_MultiOrVarSpeedCoolCoil) {
10565 0 : CoolSpeedNum = this->m_CoolingSpeedNum;
10566 0 : if (CoolSpeedNum < 1) {
10567 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10568 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10569 0 : } else if (CoolSpeedNum == 1) {
10570 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10571 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10572 : } else {
10573 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10574 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10575 : }
10576 : } else { // IF (MultiOrVarSpeedCoolCoil) THEN
10577 1456 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10578 1456 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10579 1456 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10580 1456 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10581 1456 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10582 : }
10583 : }
10584 1456 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10585 : } else { // Heating load but no moisture load
10586 11252426 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10587 5687077 : this->m_sysType == SysType::PackagedWSHP) {
10588 : // this was missing for heating mode where multi speed coils are used
10589 5635965 : if (this->m_MultiOrVarSpeedHeatCoil) {
10590 0 : if (HeatSpeedNum == 0) {
10591 0 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10592 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10593 0 : } else if (HeatSpeedNum == 1) {
10594 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10595 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10596 0 : } else if (HeatSpeedNum > 1) {
10597 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10598 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10599 : }
10600 : } else {
10601 5635965 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10602 5635965 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10603 5635965 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10604 : }
10605 5635965 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10606 1611254 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10607 1611254 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10608 1611254 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10609 : }
10610 : } else {
10611 5616461 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10612 5616461 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10613 5616461 : state.dataUnitarySystems->OACompOnMassFlow = this->m_HeatOutAirMassFlow;
10614 5616461 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10615 4686947 : if (this->m_AirFlowControl == UseCompFlow::On) {
10616 126882 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10617 126882 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10618 126882 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10619 : } else {
10620 4560065 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10621 4560065 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10622 4560065 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10623 : }
10624 : }
10625 : }
10626 : }
10627 : }
10628 :
10629 : // If a cooling load exists, operate at the cooling mass flow rate
10630 24317045 : } else if (state.dataUnitarySystems->CoolingLoad) {
10631 :
10632 21611565 : this->m_LastMode = CoolingMode;
10633 :
10634 21611565 : if (this->m_MultiOrVarSpeedCoolCoil) {
10635 :
10636 12990972 : CoolSpeedNum = this->m_CoolingSpeedNum;
10637 :
10638 12990972 : if (CoolSpeedNum == 0) {
10639 3422731 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10640 3422731 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10641 3422731 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10642 9568241 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation; set system flow rate to economizer flow rate
10643 654838 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10644 654838 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10645 654838 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10646 8913403 : } else if (CoolSpeedNum > 0) {
10647 8913403 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10648 8913403 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10649 8913403 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10650 : }
10651 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
10652 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
10653 12990972 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10654 10459536 : if (CoolSpeedNum == 0) {
10655 2974868 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10656 2974868 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10657 2974868 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10658 7484668 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10659 125888 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum];
10660 125888 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum];
10661 125888 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10662 7358780 : } else if (CoolSpeedNum == 1) {
10663 3047821 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10664 3047821 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10665 3047821 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10666 : } else {
10667 4310959 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10668 4310959 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10669 4310959 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10670 : }
10671 : } else { // cycling fan mode
10672 2531436 : if (this->m_EconoSpeedNum == 0 && CoolSpeedNum == 0) { // multi-stage economizer operation
10673 287773 : state.dataUnitarySystems->CompOffMassFlow = 0.0;
10674 287773 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10675 2243663 : } else if (this->m_EconoSpeedNum > 0) { // multi-stage economizer operation
10676 689040 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
10677 689040 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[this->m_EconoSpeedNum - 1];
10678 689040 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10679 1554623 : } else if (CoolSpeedNum == 0) {
10680 0 : state.dataUnitarySystems->CompOffMassFlow = 0.0; // #5518
10681 0 : state.dataUnitarySystems->CompOffFlowRatio = 0.0;
10682 : } else {
10683 1554623 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10684 1554623 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10685 1554623 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10686 : }
10687 : }
10688 : } else {
10689 8620593 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10690 8620593 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10691 8620593 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10692 8620593 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10693 2843954 : if (this->m_AirFlowControl == UseCompFlow::On) {
10694 668628 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10695 668628 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10696 668628 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10697 : } else {
10698 2175326 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10699 2175326 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10700 2175326 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10701 : }
10702 : }
10703 : }
10704 :
10705 : } else { // No load
10706 : // If no load exists, set the compressor on mass flow rate.
10707 : // Set equal the mass flow rate when no heating or cooling is needed If no moisture load exists.
10708 : // If the user has set the off mass flow rate to 0, set according to the last operating mode.
10709 :
10710 2705480 : if (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_Humidistat && this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat) {
10711 40580 : if (this->m_MultiOrVarSpeedCoolCoil) {
10712 40032 : CoolSpeedNum = this->m_CoolingSpeedNum;
10713 40032 : if (CoolSpeedNum < 1) {
10714 40032 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10715 40032 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10716 40032 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10717 0 : } else if (CoolSpeedNum == 1) {
10718 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10719 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10720 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10721 : } else {
10722 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10723 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10724 0 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10725 : }
10726 :
10727 40032 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10728 40032 : if (this->m_AirFlowControl == UseCompFlow::On) {
10729 0 : if (CoolSpeedNum <= 1) {
10730 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10731 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10732 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10733 : } else {
10734 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10735 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10736 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10737 : }
10738 : } else {
10739 40032 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10740 40032 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10741 40032 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10742 : }
10743 : }
10744 :
10745 : } else { // IF (MultiOrVarSpeedCoolCoil(UnitarySysNum)) THEN
10746 548 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10747 548 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10748 548 : state.dataUnitarySystems->OACompOnMassFlow = this->m_CoolOutAirMassFlow;
10749 548 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10750 548 : if (this->m_AirFlowControl == UseCompFlow::On) {
10751 0 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10752 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10753 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10754 : } else {
10755 548 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10756 548 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10757 548 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10758 : }
10759 : }
10760 : }
10761 :
10762 : } else { // No Moisture Load
10763 :
10764 2664900 : if (this->m_LastMode == HeatingMode) {
10765 : // this needs to be corrected to include UseCompressorOnFlow
10766 1435340 : if (this->m_MultiOrVarSpeedHeatCoil) {
10767 647468 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10768 647468 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10769 : } else {
10770 787872 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10771 787872 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
10772 : }
10773 : // this needs to happen regardless of system except maybe the CoilSystem objects
10774 : // do this only for PTUnit for the time being to reduce diffs for the PTUnit to UnitarySystem conversion
10775 1435340 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10776 1396730 : this->m_sysType == SysType::PackagedWSHP) {
10777 44507 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10778 27060 : if (this->m_AirFlowControl == UseCompFlow::On) {
10779 5772 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10780 5772 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10781 5772 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10782 : }
10783 : }
10784 : }
10785 : } else {
10786 : // this needs to be corrected to include UseCompressorOnFlow
10787 1229560 : if (this->m_MultiOrVarSpeedCoolCoil) {
10788 1088266 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10789 1088266 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10790 : } else {
10791 141294 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10792 141294 : state.dataUnitarySystems->CompOnFlowRatio = 1.0;
10793 : }
10794 : }
10795 2664900 : state.dataUnitarySystems->OACompOnMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10796 2664900 : if (state.dataUnitarySystems->CompOnMassFlow == 0.0) {
10797 90112 : if (this->m_LastMode == HeatingMode) {
10798 39377 : if (this->m_MultiOrVarSpeedHeatCoil) {
10799 3090 : HeatSpeedNum = this->m_HeatingSpeedNum;
10800 3090 : if (HeatSpeedNum == 0) {
10801 3080 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10802 3080 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10803 10 : } else if (HeatSpeedNum == 1) {
10804 10 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[1];
10805 10 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[1];
10806 0 : } else if (HeatSpeedNum > 1) {
10807 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum];
10808 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum];
10809 : }
10810 : } else { // IF(MultiOrVarSpeedHeatCoil) THEN
10811 36287 : state.dataUnitarySystems->CompOnMassFlow = this->MaxHeatAirMassFlow;
10812 36287 : state.dataUnitarySystems->CompOnFlowRatio = this->m_HeatingFanSpeedRatio;
10813 : }
10814 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10815 50735 : if (this->m_MultiOrVarSpeedCoolCoil) {
10816 8686 : CoolSpeedNum = this->m_CoolingSpeedNum;
10817 8686 : if (CoolSpeedNum == 0) {
10818 8686 : state.dataUnitarySystems->CompOnMassFlow = this->MaxNoCoolHeatAirMassFlow;
10819 8686 : state.dataUnitarySystems->CompOnFlowRatio = this->m_NoLoadAirFlowRateRatio;
10820 0 : } else if (CoolSpeedNum == 1) {
10821 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[1];
10822 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[1];
10823 0 : } else if (CoolSpeedNum > 1) {
10824 0 : state.dataUnitarySystems->CompOnMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum];
10825 0 : state.dataUnitarySystems->CompOnFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum];
10826 : }
10827 : } else { // IF(MultiOrVarSpeedCoolCoil) THEN
10828 42049 : state.dataUnitarySystems->CompOnMassFlow = this->MaxCoolAirMassFlow;
10829 42049 : state.dataUnitarySystems->CompOnFlowRatio = this->m_CoolingFanSpeedRatio;
10830 : } // IF(MultiOrVarSpeedCoolCoil) THEN
10831 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10832 : } // IF(CompOnMassFlow .EQ. 0.0d0)THEN
10833 :
10834 2664900 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10835 1751357 : if (this->m_AirFlowControl == UseCompFlow::On) {
10836 32428 : if (this->m_LastMode == HeatingMode) {
10837 8818 : if (this->m_MultiOrVarSpeedHeatCoil) {
10838 1614 : HeatSpeedNum = this->m_HeatingSpeedNum;
10839 1614 : if (HeatSpeedNum < 1) {
10840 1614 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10841 1614 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10842 1614 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10843 0 : } else if (HeatSpeedNum == 1) {
10844 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[1];
10845 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[1];
10846 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10847 : } else {
10848 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_HeatMassFlowRate[HeatSpeedNum - 1];
10849 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSHeatingSpeedRatio[HeatSpeedNum - 1];
10850 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10851 : }
10852 : } else {
10853 : // this is a no load case, added if for PTUnit to correct this for PTUnit to UnitarySystem conversion
10854 : // the else is incorrect?
10855 7204 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP ||
10856 1630 : this->m_sysType == SysType::PackagedWSHP) {
10857 5574 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10858 5574 : if (this->m_AirFlowControl == UseCompFlow::On) {
10859 5574 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10860 5574 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10861 5574 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10862 : }
10863 : }
10864 : } else {
10865 1630 : state.dataUnitarySystems->CompOffMassFlow = this->MaxHeatAirMassFlow;
10866 1630 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10867 1630 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10868 : }
10869 : }
10870 : } else { // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10871 23610 : if (this->m_MultiOrVarSpeedCoolCoil) {
10872 5686 : CoolSpeedNum = this->m_CoolingSpeedNum;
10873 5686 : if (CoolSpeedNum < 1) {
10874 5666 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10875 5666 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10876 5666 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10877 20 : } else if (CoolSpeedNum == 1) {
10878 20 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[1];
10879 20 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[1];
10880 20 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10881 : } else {
10882 0 : state.dataUnitarySystems->CompOffMassFlow = this->m_CoolMassFlowRate[CoolSpeedNum - 1];
10883 0 : state.dataUnitarySystems->CompOffFlowRatio = this->m_MSCoolingSpeedRatio[CoolSpeedNum - 1];
10884 0 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10885 : }
10886 : } else {
10887 17924 : state.dataUnitarySystems->CompOffMassFlow = this->MaxCoolAirMassFlow;
10888 17924 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10889 17924 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10890 : }
10891 : } // IF(UnitarySystem(UnitarySysNum)%LastMode .EQ. HeatingMode)THEN
10892 : } else { // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
10893 1718929 : if (this->m_LastMode == HeatingMode) {
10894 855451 : if (this->m_MultiOrVarSpeedHeatCoil) {
10895 455028 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10896 455028 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10897 : } else {
10898 400423 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10899 400423 : state.dataUnitarySystems->CompOffFlowRatio = this->m_HeatingFanSpeedRatio;
10900 : }
10901 : } else {
10902 863478 : if (this->m_MultiOrVarSpeedCoolCoil) {
10903 796090 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10904 796090 : state.dataUnitarySystems->CompOffFlowRatio = this->m_NoLoadAirFlowRateRatio;
10905 : } else {
10906 67388 : state.dataUnitarySystems->CompOffMassFlow = this->MaxNoCoolHeatAirMassFlow;
10907 67388 : state.dataUnitarySystems->CompOffFlowRatio = this->m_CoolingFanSpeedRatio;
10908 : }
10909 : }
10910 1718929 : state.dataUnitarySystems->OACompOffMassFlow = this->m_NoCoolHeatOutAirMassFlow;
10911 : } // IF (UnitarySystem(UnitarySysNum)%AirFlowControl .EQ. UseCompressorOnFlow) THEN
10912 : } // IF(UnitarySystem(UnitarySysNum)%FanOpMode == HVAC::FanOp::Continuous)THEN
10913 : } // ELSE ! No Moisture Load
10914 : } // No Heating/Cooling Load
10915 :
10916 38979650 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10917 23860405 : if (this->m_AirFlowControl == UseCompFlow::On &&
10918 1325634 : (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP)) {
10919 881226 : if (this->m_LastMode == HeatingMode) {
10920 285939 : state.dataUnitarySystems->OACompOffMassFlow = this->m_HeatOutAirMassFlow;
10921 : } else {
10922 595287 : state.dataUnitarySystems->OACompOffMassFlow = this->m_CoolOutAirMassFlow;
10923 : }
10924 : }
10925 : }
10926 :
10927 38979650 : if (this->m_MultiSpeedHeatingCoil && (state.dataUnitarySystems->HeatingLoad && HeatSpeedNum == 1)) {
10928 1651689 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
10929 37327961 : } else if (this->m_DiscreteSpeedCoolingCoil && (state.dataUnitarySystems->CoolingLoad && CoolSpeedNum == 1)) {
10930 4263650 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
10931 : } else {
10932 33064311 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOffMassFlow; // these need to be set for multi-speed coils
10933 : }
10934 77959300 : state.dataHVACGlobal->MSHPMassFlowRateHigh =
10935 38979650 : state.dataUnitarySystems->CompOnMassFlow; // doesn't hurt to set these if multi-speed coils are not used
10936 38979650 : state.dataHVACGlobal->MSUSEconoSpeedNum = this->m_EconoSpeedNum;
10937 :
10938 38979650 : state.dataUnitarySystems->m_massFlow1 = state.dataUnitarySystems->CompOnMassFlow;
10939 38979650 : state.dataUnitarySystems->m_massFlow2 = state.dataUnitarySystems->CompOffMassFlow;
10940 :
10941 : // Set the system mass flow rates
10942 38979650 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
10943 38979650 : }
10944 :
10945 51027148 : void UnitarySys::setAverageAirFlow(EnergyPlusData &state,
10946 : Real64 const PartLoadRatio, // unit part load ratio
10947 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
10948 : )
10949 : {
10950 :
10951 : // SUBROUTINE INFORMATION:
10952 : // AUTHOR Richard Raustad
10953 : // DATE WRITTEN July 2005
10954 :
10955 : // PURPOSE OF THIS SUBROUTINE:
10956 : // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
10957 : // Set OnOffAirFlowRatio to be used by DX coils
10958 :
10959 : // METHODOLOGY EMPLOYED:
10960 : // The air flow rate in cooling, heating, and no cooling or heating can be different.
10961 : // Calculate the air flow rate based on initializations.
10962 :
10963 51027148 : Real64 AverageUnitMassFlow = 0.0; // average supply air mass flow rate over time step
10964 51027148 : bool FanOn = false;
10965 :
10966 51027148 : state.dataUnitarySystems->m_runTimeFraction1 = 0.0;
10967 51027148 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
10968 :
10969 51027148 : Real64 FanPartLoadRatio = PartLoadRatio;
10970 51027148 : if (this->m_SimASHRAEModel) FanPartLoadRatio = this->FanPartLoadRatio;
10971 51027148 : if (this->m_EconoPartLoadRatio > 0) FanPartLoadRatio = this->m_EconoPartLoadRatio;
10972 51027148 : int SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum, this->m_EconoSpeedNum);
10973 51027148 : int InletNode = this->AirInNode;
10974 :
10975 51027148 : if (SpeedNum > 1) {
10976 8954509 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
10977 939470 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
10978 7995724 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
10979 6385038 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow +
10980 6385038 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow;
10981 : } else {
10982 1610686 : Real64 tempSpeedRatio = 0;
10983 1610686 : if (this->m_EconoPartLoadRatio > 0) {
10984 182056 : tempSpeedRatio = this->FanPartLoadRatio;
10985 : } else {
10986 1428630 : tempSpeedRatio = state.dataUnitarySystems->CoolingLoad ? this->m_CoolingSpeedRatio : this->m_HeatingSpeedRatio;
10987 : }
10988 1610686 : AverageUnitMassFlow = tempSpeedRatio * state.dataUnitarySystems->CompOnMassFlow +
10989 1610686 : (1.0 - tempSpeedRatio) * state.dataUnitarySystems->CompOffMassFlow;
10990 : }
10991 : } else {
10992 19315 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
10993 : }
10994 : } else {
10995 43012109 : AverageUnitMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow) +
10996 43012109 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffMassFlow);
10997 : }
10998 :
10999 51027148 : if (state.dataUnitarySystems->CompOffFlowRatio > 0.0) {
11000 31341123 : if (SpeedNum > 1) {
11001 8932714 : if ((state.dataUnitarySystems->CoolingLoad && this->m_MultiOrVarSpeedCoolCoil) ||
11002 931693 : (state.dataUnitarySystems->HeatingLoad && this->m_MultiOrVarSpeedHeatCoil)) {
11003 7989483 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio +
11004 7989483 : (1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio;
11005 7989483 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11006 7989483 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11007 : } else {
11008 11538 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11009 11538 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11010 11538 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11011 : }
11012 : } else {
11013 23340102 : state.dataUnitarySystems->FanSpeedRatio = (FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio) +
11014 23340102 : ((1.0 - FanPartLoadRatio) * state.dataUnitarySystems->CompOffFlowRatio);
11015 23340102 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11016 23340102 : state.dataUnitarySystems->m_runTimeFraction2 = 1.0 - FanPartLoadRatio;
11017 : }
11018 : } else {
11019 19686025 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11020 19686025 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11021 19686025 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11022 : }
11023 :
11024 51027148 : if (!(state.dataUnitarySystems->HeatingLoad && this->m_NumOfSpeedHeating == 0)) {
11025 34967091 : if (this->m_SingleMode == 1) {
11026 76083 : if (this->m_FanOpMode == HVAC::FanOp::Continuous) {
11027 0 : AverageUnitMassFlow = state.dataUnitarySystems->CompOnMassFlow;
11028 0 : state.dataUnitarySystems->FanSpeedRatio = state.dataUnitarySystems->CompOnFlowRatio;
11029 0 : state.dataUnitarySystems->m_runTimeFraction1 = 1.0;
11030 0 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11031 : } else {
11032 76083 : AverageUnitMassFlow = FanPartLoadRatio * state.dataUnitarySystems->CompOnMassFlow;
11033 76083 : state.dataUnitarySystems->FanSpeedRatio = FanPartLoadRatio * state.dataUnitarySystems->CompOnFlowRatio;
11034 76083 : state.dataUnitarySystems->m_runTimeFraction1 = FanPartLoadRatio;
11035 76083 : state.dataUnitarySystems->m_runTimeFraction2 = 0.0;
11036 : }
11037 : }
11038 : }
11039 :
11040 51027148 : if (this->OAMixerExists) {
11041 16684827 : Real64 AverageOAMassFlow = (FanPartLoadRatio * state.dataUnitarySystems->OACompOnMassFlow) +
11042 16684827 : ((1 - FanPartLoadRatio) * state.dataUnitarySystems->OACompOffMassFlow);
11043 :
11044 16684827 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = AverageOAMassFlow;
11045 16684827 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = AverageOAMassFlow;
11046 : // don't need to set relief node, delete them when working
11047 16684827 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = AverageOAMassFlow;
11048 16684827 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = AverageOAMassFlow;
11049 : }
11050 :
11051 : // BEGIN - refactor/move this to Init during FirstHVACIteration, need struct or module level global for turnFansOn and turnFansOff
11052 : // If the unitary system is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
11053 51027148 : FanOn = (this->m_FanExists) ? ScheduleManager::GetCurrentScheduleValue(state, this->m_FanAvailSchedPtr) > 0 : true;
11054 : // END - move this to Init during FirstHVACIteration
11055 :
11056 102045421 : if (ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0 &&
11057 51018273 : ((FanOn || state.dataHVACGlobal->TurnFansOn) && !state.dataHVACGlobal->TurnFansOff)) {
11058 50135635 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11059 : // set point based equipment should use VAV terminal units to set the flow.
11060 : // zone equipment needs to set flow since no other device regulates flow (ZoneHVAC /= AirLoopEquipment)
11061 22618 : if (!this->m_AirLoopEquipment) {
11062 0 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11063 0 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11064 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11065 : }
11066 22618 : if (AverageUnitMassFlow > 0.0) {
11067 22618 : OnOffAirFlowRatio = 1.0;
11068 : } else {
11069 0 : OnOffAirFlowRatio = 0.0;
11070 : }
11071 : } else {
11072 50113017 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
11073 50113017 : if (!this->m_AirLoopEquipment) {
11074 19121122 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail =
11075 : AverageUnitMassFlow; // #5531 zone equipment needs MaxAvail set or fan will not turn ON
11076 : }
11077 50113017 : if (AverageUnitMassFlow > 0.0) {
11078 42444473 : if (SpeedNum > 1) {
11079 7957684 : OnOffAirFlowRatio = 1.0;
11080 : } else {
11081 34486789 : OnOffAirFlowRatio = state.dataUnitarySystems->CompOnMassFlow / AverageUnitMassFlow;
11082 : }
11083 : } else {
11084 7668544 : OnOffAirFlowRatio = 0.0;
11085 : }
11086 : }
11087 : } else {
11088 891513 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
11089 : // fan will turn on unless these are reset, or maybe one of them. Might be a better way when calling fan.
11090 891513 : state.dataUnitarySystems->m_massFlow1 = 0.0;
11091 891513 : state.dataUnitarySystems->m_massFlow2 = 0.0;
11092 891513 : OnOffAirFlowRatio = 1.0;
11093 891513 : if (this->OAMixerExists) {
11094 : // maybe can just set MaxAvail = 0?
11095 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRate = 0.0;
11096 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[0]).MassFlowRateMaxAvail = 0.0;
11097 : // don't need to set relief node, delete then when working
11098 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRate = 0.0;
11099 5847 : state.dataLoopNodes->Node(this->m_OAMixerNodes[1]).MassFlowRateMaxAvail = 0.0;
11100 : }
11101 : }
11102 51027148 : }
11103 :
11104 29602579 : void UnitarySys::calcUnitarySystemToLoad(EnergyPlusData &state,
11105 : int const AirLoopNum, // index to air loop
11106 : bool const FirstHVACIteration, // True when first HVAC iteration
11107 : Real64 const CoolPLR, // operating cooling part-load ratio []
11108 : Real64 const HeatPLR, // operating cooling part-load ratio []
11109 : Real64 &OnOffAirFlowRatio, // ratio of heating PLR to cooling PLR (is this correct?)
11110 : Real64 &SensOutput, // sensible capacity (W)
11111 : Real64 &LatOutput, // latent capacity (W)
11112 : bool HXUnitOn, // Flag to control HX for HXAssisted Cooling Coil
11113 : Real64 HeatCoilLoad, // Adjusted load to heating coil when SAT exceeds max limit (W)
11114 : Real64 SuppCoilLoad, // Adjusted load to supp heating coil when SAT exceeds max limit (W)
11115 : HVAC::CompressorOp const CompressorOn // Determines if compressor is on or off
11116 : )
11117 : {
11118 :
11119 : // SUBROUTINE INFORMATION:
11120 : // AUTHOR Richard Raustad, FSEC
11121 : // DATE WRITTEN February 2013
11122 :
11123 : // PURPOSE OF THIS SUBROUTINE:
11124 : // This subroutine calculates the resulting performance of the unitary system given
11125 : // the operating PLR. System output is calculated with respect to zone condition.
11126 :
11127 29602579 : Real64 CoilCoolHeatRat = 1.0; // ratio of cooling to heating PLR for cycling fan RH control
11128 :
11129 29602579 : HVAC::CompressorOp CoolingCompOn = HVAC::CompressorOp::Off;
11130 29602579 : if (CoolPLR > 0) {
11131 10721108 : CoolingCompOn = CompressorOn;
11132 18881471 : } else if (CoolPLR == 0 && this->m_EconoSpeedNum > 0) { // turn compressor off for economizer calculations
11133 549169 : CoolingCompOn = HVAC::CompressorOp::Off;
11134 18332302 : } else if (this->m_CoolingSpeedNum > 1) { // for multispeed coils, comp is on IF speed > 1
11135 489961 : CoolingCompOn = HVAC::CompressorOp::On;
11136 : }
11137 :
11138 29602579 : HVAC::CompressorOp HeatingCompOn = HVAC::CompressorOp::Off;
11139 29602579 : if (HeatPLR > 0) {
11140 7812429 : HeatingCompOn = CompressorOn;
11141 7812429 : CoilCoolHeatRat = min(1.0, CoolPLR / HeatPLR);
11142 : }
11143 : // for multispeed coils, comp is on at PLR=0 IF speed > 1
11144 29602579 : if (this->m_HeatingSpeedNum > 1) HeatingCompOn = HVAC::CompressorOp::On;
11145 :
11146 : // set the operating flow rate
11147 29602579 : if (this->m_NumOfSpeedCooling > 0 || this->m_NumOfSpeedHeating > 0) {
11148 27635338 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, max(CoolPLR, HeatPLR));
11149 : } else {
11150 1967241 : this->setAverageAirFlow(state, max(CoolPLR, HeatPLR), OnOffAirFlowRatio);
11151 : }
11152 :
11153 : // Call the series of components that simulate a Unitary System
11154 29602579 : if (this->ATMixerExists) {
11155 : // There is an air terminal mixer
11156 995259 : if (this->ATMixerType == HVAC::MixerType::InletSide) { // if there is an inlet side air terminal mixer
11157 : // set the primary air inlet mass flow rate
11158 680709 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRate = min(
11159 680709 : state.dataLoopNodes->Node(this->m_ATMixerPriNode).MassFlowRateMaxAvail, state.dataLoopNodes->Node(this->AirInNode).MassFlowRate);
11160 : // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
11161 : // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
11162 680709 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11163 : }
11164 : }
11165 29602579 : if (this->OAMixerExists) {
11166 : // the PTHP does one or the other, but why can't an OA Mixer exist with the AT Mixer?
11167 : // 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
11168 : // at least better than constructing a new string each time to call this function
11169 9724727 : MixedAir::SimOAMixer(state, blankStdString, this->OAMixerIndex);
11170 : }
11171 :
11172 29602579 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
11173 16762115 : state.dataFans->fans(this->m_FanIndex)
11174 50286345 : ->simulate(state,
11175 : FirstHVACIteration,
11176 16762115 : state.dataUnitarySystems->FanSpeedRatio,
11177 : _, // Pressure rise
11178 : _, // Flow fraction
11179 16762115 : state.dataUnitarySystems->m_massFlow1,
11180 16762115 : state.dataUnitarySystems->m_runTimeFraction1,
11181 16762115 : state.dataUnitarySystems->m_massFlow2,
11182 16762115 : state.dataUnitarySystems->m_runTimeFraction2,
11183 : _);
11184 : }
11185 :
11186 29602579 : if (this->m_CoolingCoilUpstream) {
11187 :
11188 28356637 : if (this->m_CoolCoilExists) {
11189 28356637 : this->calcUnitaryCoolingSystem(
11190 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11191 : }
11192 28356637 : if (this->m_HeatCoilExists) {
11193 : // operate the heating coil without regard to coil outlet temperature
11194 27719759 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11195 27719759 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11196 719287 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11197 719287 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11198 719287 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11199 719287 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11200 719287 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11201 719287 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11202 719287 : HeatCoilLoad = MaxHeatCoilLoad;
11203 : }
11204 : }
11205 :
11206 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11207 28356637 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11208 629104 : state.dataFans->fans(this->m_FanIndex)
11209 1887312 : ->simulate(state,
11210 : FirstHVACIteration,
11211 629104 : state.dataUnitarySystems->FanSpeedRatio,
11212 : _, // Pressure rise
11213 : _, // Flow fraction
11214 629104 : state.dataUnitarySystems->m_massFlow1,
11215 629104 : state.dataUnitarySystems->m_runTimeFraction1,
11216 629104 : state.dataUnitarySystems->m_massFlow2,
11217 629104 : state.dataUnitarySystems->m_runTimeFraction2,
11218 : _);
11219 :
11220 629104 : if (this->m_CoolCoilExists) {
11221 629104 : this->calcUnitaryCoolingSystem(
11222 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11223 : }
11224 629104 : if (this->m_HeatCoilExists) {
11225 629104 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11226 629104 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11227 23036 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11228 23036 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11229 23036 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11230 23036 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11231 23036 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11232 23036 : this->calcUnitaryHeatingSystem(
11233 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11234 : }
11235 : }
11236 : }
11237 :
11238 : } else {
11239 :
11240 1245942 : if (this->m_HeatCoilExists) {
11241 1245942 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11242 1245942 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11243 167050 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11244 167050 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11245 167050 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11246 167050 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11247 167050 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11248 167050 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11249 : }
11250 : }
11251 1245942 : if (this->m_CoolCoilExists) {
11252 1245942 : this->calcUnitaryCoolingSystem(
11253 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11254 : }
11255 :
11256 : // If blow thru fan is used, the fan must be simulated after coil sets OnOffFanPartLoadFraction
11257 1245942 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru && state.dataHVACGlobal->OnOffFanPartLoadFraction < 1.0) {
11258 18737 : state.dataFans->fans(this->m_FanIndex)
11259 56211 : ->simulate(state,
11260 : FirstHVACIteration,
11261 18737 : state.dataUnitarySystems->FanSpeedRatio,
11262 : _, // Pressure rise
11263 : _, // Flow fraction
11264 18737 : state.dataUnitarySystems->m_massFlow1,
11265 18737 : state.dataUnitarySystems->m_runTimeFraction1,
11266 18737 : state.dataUnitarySystems->m_massFlow2,
11267 18737 : state.dataUnitarySystems->m_runTimeFraction2,
11268 : _);
11269 :
11270 18737 : if (this->m_HeatCoilExists) {
11271 18737 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, HeatCoilLoad);
11272 18737 : if (state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp && !this->m_SimASHRAEModel) {
11273 8516 : Real64 MDotAir = state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).MassFlowRate;
11274 8516 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).HumRat +
11275 8516 : state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).HumRat));
11276 8516 : Real64 HCDeltaT = this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->HeatCoilInletNodeNum).Temp;
11277 8516 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11278 8516 : this->calcUnitaryHeatingSystem(
11279 : state, AirLoopNum, FirstHVACIteration, HeatPLR, HeatingCompOn, OnOffAirFlowRatio, MaxHeatCoilLoad);
11280 : }
11281 : }
11282 18737 : if (this->m_CoolCoilExists) {
11283 18737 : this->calcUnitaryCoolingSystem(
11284 : state, AirLoopNum, FirstHVACIteration, CoolPLR, CoolingCompOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
11285 : }
11286 : }
11287 : }
11288 :
11289 29602579 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
11290 12840464 : state.dataFans->fans(this->m_FanIndex)
11291 38521392 : ->simulate(state,
11292 : FirstHVACIteration,
11293 12840464 : state.dataUnitarySystems->FanSpeedRatio,
11294 : _, // Pressure rise
11295 : _, // Flow fraction
11296 12840464 : state.dataUnitarySystems->m_massFlow1,
11297 12840464 : state.dataUnitarySystems->m_runTimeFraction1,
11298 12840464 : state.dataUnitarySystems->m_massFlow2,
11299 12840464 : state.dataUnitarySystems->m_runTimeFraction2,
11300 : _);
11301 : }
11302 29602579 : if (this->m_SuppCoilExists) {
11303 8342050 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, SuppCoilLoad);
11304 8346716 : if ((state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp > this->DesignMaxOutletTemp) && this->m_SuppHeatPartLoadFrac > 0.0 &&
11305 4666 : !this->m_SimASHRAEModel) {
11306 : // EMS override will ignore this recalculation.
11307 4666 : Real64 MDotAir = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).MassFlowRate;
11308 4666 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).HumRat +
11309 4666 : state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).HumRat));
11310 4666 : Real64 HCDeltaT = max(0.0, this->DesignMaxOutletTemp - state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode).Temp);
11311 4666 : Real64 MaxHeatCoilLoad = MDotAir * CpAir * HCDeltaT;
11312 4666 : this->calcUnitarySuppHeatingSystem(state, FirstHVACIteration, MaxHeatCoilLoad);
11313 4666 : SuppCoilLoad = MaxHeatCoilLoad;
11314 : }
11315 : }
11316 :
11317 : // If there is a supply side air terminal mixer, calculate its output
11318 29602579 : if (this->ATMixerExists) {
11319 995259 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11320 314550 : SingleDuct::SimATMixer(state, this->m_ATMixerName, FirstHVACIteration, this->m_ATMixerIndex);
11321 : }
11322 : }
11323 :
11324 29602579 : calculateCapacity(state, SensOutput, LatOutput);
11325 29602579 : }
11326 :
11327 302026 : void UnitarySys::calcMultiStageSuppCoilStageByLoad(EnergyPlusData &state, Real64 const SuppHeatLoad, bool const FirstHVACIteration)
11328 : {
11329 302026 : if (SuppHeatLoad <= 0.0) {
11330 293002 : this->m_SuppHeatPartLoadFrac = 0.0;
11331 293002 : this->m_SuppHeatingSpeedRatio = 0.0;
11332 293002 : this->m_SuppHeatingCycRatio = 0.0;
11333 297458 : return;
11334 : }
11335 9024 : constexpr bool SuppHeatingCoilFlag(true);
11336 9024 : Real64 PartLoadFrac = 0.0;
11337 9024 : Real64 SpeedRatio = 0.0;
11338 9024 : Real64 CycRatio = 0.0;
11339 9024 : std::string CompName = this->m_SuppHeatCoilName;
11340 9024 : int CompIndex = this->m_SuppHeatCoilIndex;
11341 9024 : HVAC::FanOp fanOp = this->m_FanOpMode;
11342 9024 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
11343 9024 : int SpeedNum = 0;
11344 : // Get full load result
11345 9024 : PartLoadFrac = 1.0;
11346 9024 : CycRatio = 1.0;
11347 9024 : SpeedRatio = 1.0;
11348 9024 : int SolFla = 0.0;
11349 :
11350 : // SUBROUTINE PARAMETER DEFINITIONS:
11351 9024 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11352 9024 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
11353 :
11354 30680 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
11355 26224 : this->m_SuppHeatingSpeedNum = SpeedNum;
11356 26224 : HeatingCoils::SimulateHeatingCoilComponents(state,
11357 : CompName,
11358 : FirstHVACIteration,
11359 : SuppHeatLoad,
11360 : CompIndex,
11361 : QCoilActual,
11362 : SuppHeatingCoilFlag,
11363 : fanOp,
11364 : PartLoadFrac,
11365 : SpeedNum,
11366 : SpeedRatio);
11367 26224 : if (QCoilActual > SuppHeatLoad) break;
11368 : }
11369 9024 : if (QCoilActual < SuppHeatLoad) {
11370 4456 : this->m_SuppHeatPartLoadFrac = 1.0;
11371 4456 : this->m_SuppHeatingSpeedRatio = 1.0;
11372 4456 : this->m_SuppHeatingCycRatio = 1.0;
11373 4456 : this->m_SuppHeatingSpeedNum = this->m_NumOfSpeedSuppHeating;
11374 4456 : return;
11375 : } else {
11376 :
11377 4568 : if (this->m_SuppHeatingSpeedNum > 1.0) {
11378 27384 : auto f = [&state, this, CycRatio, fanOp, SuppHeatLoad](Real64 const SpeedRatio) {
11379 : Real64 QActual;
11380 13692 : int CoilIndex = this->m_SuppHeatCoilIndex;
11381 13692 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11382 13692 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11383 13692 : return SuppHeatLoad - QActual;
11384 4564 : };
11385 :
11386 4564 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
11387 4564 : this->m_SuppHeatingCycRatio = CycRatio;
11388 4564 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11389 4564 : this->m_SuppHeatPartLoadFrac = SpeedRatio;
11390 4564 : PartLoadFrac = SpeedRatio;
11391 : } else {
11392 4 : SpeedRatio = 0.0;
11393 4 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
11394 24 : auto f = [&state, this, SpeedRatio, fanOp, SuppHeatLoad](Real64 const CycRatio) {
11395 : Real64 QActual;
11396 12 : int CoilIndex = this->m_SuppHeatCoilIndex;
11397 12 : int SpeedNum = this->m_SuppHeatingSpeedNum;
11398 12 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, true);
11399 12 : return SuppHeatLoad - QActual;
11400 4 : };
11401 :
11402 4 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
11403 4 : this->m_SuppHeatingCycRatio = CycRatio;
11404 4 : this->m_SuppHeatPartLoadFrac = CycRatio;
11405 4 : PartLoadFrac = CycRatio;
11406 : }
11407 : }
11408 9024 : }
11409 :
11410 33210001 : void UnitarySys::calculateCapacity(EnergyPlusData &state, Real64 &SensOutput, Real64 &LatOutput)
11411 : {
11412 :
11413 : // Check delta T (outlet to reference temp), IF positive use reference HumRat ELSE outlet humrat to calculate
11414 : // sensible capacity as MdotDeltaH at constant humidity ratio
11415 33210001 : int OutletNode = this->AirOutNode;
11416 33210001 : Real64 AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
11417 33210001 : Real64 RefTemp = 0.0;
11418 33210001 : Real64 RefHumRat = 0.0;
11419 33210001 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11420 3607422 : RefTemp = state.dataLoopNodes->Node(this->AirInNode).Temp;
11421 3607422 : RefHumRat = state.dataLoopNodes->Node(this->AirInNode).HumRat;
11422 : } else {
11423 29602579 : RefTemp = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp;
11424 29602579 : RefHumRat = state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat;
11425 : }
11426 33210001 : Real64 SensibleOutput(0.0); // sensible output rate, {W}
11427 33210001 : Real64 LatentOutput(0.0); // latent output rate, {W}
11428 33210001 : Real64 TotalOutput(0.0); // total output rate, {W}
11429 : // calculate sensible load met
11430 33210001 : if (this->ATMixerExists) {
11431 995259 : if (this->ATMixerType == HVAC::MixerType::SupplySide) {
11432 : // Air terminal supply side mixer
11433 314550 : int ATMixOutNode = this->ATMixerOutNode;
11434 314550 : CalcZoneSensibleLatentOutput(state.dataLoopNodes->Node(ATMixOutNode).MassFlowRate,
11435 314550 : state.dataLoopNodes->Node(ATMixOutNode).Temp,
11436 314550 : state.dataLoopNodes->Node(ATMixOutNode).HumRat,
11437 : RefTemp,
11438 : RefHumRat,
11439 : SensibleOutput,
11440 : LatentOutput,
11441 : TotalOutput);
11442 314550 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11443 314550 : if (this->m_Humidistat) {
11444 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11445 : } else {
11446 314550 : LatOutput = 0.0;
11447 : }
11448 : } else {
11449 : // Air terminal inlet side mixer
11450 1361418 : CalcZoneSensibleLatentOutput(AirMassFlow,
11451 680709 : state.dataLoopNodes->Node(OutletNode).Temp,
11452 680709 : state.dataLoopNodes->Node(OutletNode).HumRat,
11453 : RefTemp,
11454 : RefHumRat,
11455 : SensibleOutput,
11456 : LatentOutput,
11457 : TotalOutput);
11458 680709 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11459 680709 : if (this->m_Humidistat) {
11460 0 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11461 : } else {
11462 680709 : LatOutput = 0.0;
11463 : }
11464 : }
11465 : } else {
11466 : // Calculate sensible load met
11467 64429484 : CalcZoneSensibleLatentOutput(AirMassFlow,
11468 32214742 : state.dataLoopNodes->Node(OutletNode).Temp,
11469 32214742 : state.dataLoopNodes->Node(OutletNode).HumRat,
11470 : RefTemp,
11471 : RefHumRat,
11472 : SensibleOutput,
11473 : LatentOutput,
11474 : TotalOutput);
11475 32214742 : SensOutput = SensibleOutput - this->m_SenLoadLoss;
11476 32214742 : if (this->m_Humidistat) {
11477 1649021 : LatOutput = LatentOutput - this->m_LatLoadLoss;
11478 : } else {
11479 30565721 : LatOutput = 0.0;
11480 : }
11481 : }
11482 33210001 : this->m_SensibleLoadMet = SensOutput;
11483 33210001 : this->m_LatentLoadMet = LatOutput;
11484 33210001 : }
11485 :
11486 33885414 : void UnitarySys::calcUnitaryCoolingSystem(EnergyPlusData &state,
11487 : int const AirLoopNum, // index to air loop
11488 : bool const FirstHVACIteration, // True when first HVAC iteration
11489 : Real64 const PartLoadRatio, // coil operating part-load ratio
11490 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11491 : Real64 const OnOffAirFlowRatio,
11492 : Real64 const CoilCoolHeatRat, // ratio of cooling to heating PLR for cycling fan RH control
11493 : bool const HXUnitOn // Flag to control HX for HXAssisted Cooling Coil
11494 : )
11495 : {
11496 :
11497 : // SUBROUTINE INFORMATION:
11498 : // AUTHOR Richard Raustad, FSEC
11499 : // DATE WRITTEN February 2013
11500 :
11501 : // PURPOSE OF THIS SUBROUTINE:
11502 : // This subroutine manages unitary cooling system component simulation.
11503 :
11504 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11505 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11506 : Real64 mdot; // water side flow rate (kg/s)
11507 : Real64 QActual; // actual coil output (W)
11508 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11509 :
11510 : // Simulate the coil component
11511 33885414 : std::string CompName = this->m_CoolingCoilName;
11512 33885414 : int CompIndex = this->m_CoolingCoilIndex;
11513 33885414 : Real64 CoilPLR = 1.0;
11514 33885414 : if (this->m_CondenserNodeNum != 0) {
11515 12524228 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11516 : // IF node is not connected to anything, pressure = default, use weather data
11517 12524228 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11518 2125 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11519 : } else {
11520 12522103 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11521 : }
11522 : } else {
11523 21361186 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11524 : }
11525 :
11526 33885414 : switch (this->m_CoolingCoilType_Num) {
11527 12882808 : case HVAC::CoilDX_CoolingSingleSpeed: { // Coil:Cooling:DX:SingleSpeed
11528 12882808 : DXCoils::SimDXCoil(state,
11529 : blankString,
11530 : CompressorOn,
11531 : FirstHVACIteration,
11532 : CompIndex,
11533 : this->m_FanOpMode,
11534 : PartLoadRatio,
11535 : OnOffAirFlowRatio,
11536 : CoilCoolHeatRat);
11537 12882808 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11538 12882808 : } break;
11539 10926026 : case HVAC::CoilDX_Cooling: { // CoilCoolingDX
11540 10926026 : bool const singleMode = (this->m_SingleMode == 1);
11541 10926026 : if (this->m_ControlType == UnitarySysCtrlType::Setpoint) {
11542 78835 : if (CompressorOn == HVAC::CompressorOp::On) {
11543 66050 : CoilPLR = (this->m_CoolingSpeedNum > 1) ? 1.0 : PartLoadRatio;
11544 : } else
11545 12785 : CoilPLR = 0.0;
11546 : } else {
11547 10847191 : if (this->m_EMSOverrideCoilSpeedNumOn) {
11548 146796 : CoilPLR = this->m_CoolingSpeedRatio;
11549 : } else {
11550 10700395 : if (state.dataUnitarySystems->CoolingLoad) {
11551 7080656 : if (this->m_CoolingSpeedNum > 1) {
11552 2874409 : if (!singleMode) {
11553 2851113 : CoilPLR = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11554 2851113 : this->m_CoolingSpeedRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11555 : } else {
11556 23296 : CoilPLR = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11557 : }
11558 : } else {
11559 4206247 : CoilPLR = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11560 : }
11561 : } else {
11562 3619739 : CoilPLR = 0.0;
11563 : }
11564 : }
11565 : }
11566 :
11567 10926026 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
11568 10926026 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
11569 76864 : coilMode = HVAC::CoilMode::SubcoolReheat;
11570 10849162 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
11571 0 : coilMode = HVAC::CoilMode::Enhanced;
11572 : }
11573 :
11574 10926026 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
11575 : state, coilMode, CoilPLR, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode, this->CoilSHR);
11576 :
11577 10926026 : if (this->m_CoolingSpeedNum > 1) {
11578 2970398 : if (this->m_SingleMode == 0) {
11579 2947102 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11580 : } else {
11581 23296 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11582 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11583 23296 : this->m_CoolingSpeedRatio = 1.0;
11584 : }
11585 : } else {
11586 7955628 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11587 : // this->m_CoolingCycRatio = this->m_CoolingSpeedRatio;
11588 7955628 : this->m_CoolingSpeedRatio = 0.0;
11589 : }
11590 10926026 : } break;
11591 25322 : case HVAC::CoilDX_CoolingHXAssisted:
11592 : case HVAC::CoilWater_CoolingHXAssisted: {
11593 25322 : if (this->m_CoolingCoilType_Num == HVAC::CoilWater_CoolingHXAssisted) {
11594 : mdot =
11595 0 : min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxCoolCoilFluidFlow * PartLoadRatio);
11596 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11597 : }
11598 50644 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
11599 : blankString,
11600 : FirstHVACIteration,
11601 : CompressorOn,
11602 : PartLoadRatio,
11603 : CompIndex,
11604 : this->m_FanOpMode,
11605 : HXUnitOn,
11606 : OnOffAirFlowRatio,
11607 25322 : state.dataUnitarySystems->economizerFlag,
11608 : _,
11609 25322 : this->m_DehumidificationMode,
11610 25322 : 0.0); // this->CoilSHR);
11611 25322 : if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
11612 25322 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11613 : }
11614 25322 : } break;
11615 1032924 : case HVAC::CoilDX_CoolingTwoSpeed: { // Coil:Cooling:DX:TwoSpeed
11616 : // formerly (v3 and beyond)COIL:DX:MULTISPEED:COOLINGEMPIRICAL
11617 1032924 : DXCoils::SimDXCoilMultiSpeed(state, blankString, this->m_CoolingSpeedRatio, this->m_CoolingCycRatio, CompIndex);
11618 1032924 : if (this->m_CoolingSpeedRatio > 0.0) {
11619 351539 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingSpeedRatio : 0.0;
11620 : } else {
11621 681385 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11622 : }
11623 1032924 : } break;
11624 4385175 : case HVAC::CoilDX_MultiSpeedCooling: { // Coil:Cooling:DX:Multispeed
11625 4385175 : if (OutsideDryBulbTemp > this->m_MinOATCompressorCooling) {
11626 4385175 : DXCoils::SimDXCoilMultiSpeed(state,
11627 : CompName,
11628 : this->m_CoolingSpeedRatio,
11629 : this->m_CoolingCycRatio,
11630 : CompIndex,
11631 4385175 : this->m_CoolingSpeedNum,
11632 4385175 : this->m_FanOpMode,
11633 : CompressorOn,
11634 4385175 : this->m_SingleMode);
11635 4385175 : if (this->m_CoolingSpeedNum > 1) {
11636 894951 : if (this->m_SingleMode == 0) {
11637 894951 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? 1.0 : 0.0;
11638 : } else {
11639 0 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11640 : }
11641 : } else {
11642 3490224 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? this->m_CoolingCycRatio : 0.0;
11643 : }
11644 : } else {
11645 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 0.0, CompIndex, this->m_CoolingSpeedNum, this->m_FanOpMode, CompressorOn);
11646 0 : this->m_CoolCompPartLoadRatio = 0.0;
11647 : }
11648 4385175 : } break;
11649 48603 : case HVAC::CoilDX_CoolingTwoStageWHumControl: {
11650 : // formerly (v3 and beyond) COIL:DX:MULTIMODE:COOLINGEMPIRICAL
11651 48603 : DXCoils::SimDXCoilMultiMode(
11652 : state, CompName, CompressorOn, FirstHVACIteration, PartLoadRatio, this->m_DehumidificationMode, CompIndex, this->m_FanOpMode);
11653 48603 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11654 48603 : } break;
11655 0 : case HVAC::Coil_UserDefined: {
11656 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11657 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
11658 :
11659 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
11660 0 : } break;
11661 1364358 : case HVAC::Coil_CoolingWater:
11662 : case HVAC::Coil_CoolingWaterDetailed: {
11663 1364358 : if (this->CoolCoilWaterFlowRatio == 0.0) {
11664 1364358 : mdot = this->MaxCoolCoilFluidFlow * PartLoadRatio;
11665 : } else {
11666 0 : mdot = this->CoolCoilWaterFlowRatio * this->MaxCoolCoilFluidFlow;
11667 : }
11668 1364358 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
11669 4093074 : WaterCoils::SimulateWaterCoilComponents(
11670 2728716 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11671 1364358 : } break;
11672 1825849 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
11673 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
11674 1825849 : if (this->m_CoolingSpeedNum > 1) {
11675 306991 : CoilPLR = 1.0;
11676 : } else {
11677 1518858 : CoilPLR = PartLoadRatio;
11678 : }
11679 1825849 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11680 : CompName,
11681 : CompIndex,
11682 : this->m_FanOpMode,
11683 : CompressorOn,
11684 : CoilPLR,
11685 : this->m_CoolingSpeedNum,
11686 : this->m_CoolingSpeedRatio,
11687 : this->m_CoolingCoilSensDemand,
11688 : this->m_CoolingCoilLatentDemand,
11689 : OnOffAirFlowRatio);
11690 1825849 : if (this->m_CoolingSpeedNum > 1) {
11691 306991 : this->m_CoolCompPartLoadRatio = 1.0;
11692 : } else {
11693 1518858 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11694 : }
11695 1825849 : } break;
11696 948627 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
11697 :
11698 948627 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11699 : blankString,
11700 948627 : this->m_CoolingCoilIndex,
11701 : this->m_CoolingCoilSensDemand,
11702 : this->m_CoolingCoilLatentDemand,
11703 : this->m_FanOpMode,
11704 : CompressorOn,
11705 : PartLoadRatio,
11706 : FirstHVACIteration);
11707 948627 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11708 948627 : } break;
11709 416870 : case HVAC::Coil_CoolingWaterToAirHP: {
11710 :
11711 416870 : WaterToAirHeatPump::SimWatertoAirHP(state,
11712 : blankString,
11713 416870 : this->m_CoolingCoilIndex,
11714 : this->MaxCoolAirMassFlow,
11715 : this->m_FanOpMode,
11716 : FirstHVACIteration,
11717 416870 : this->m_InitHeatPump,
11718 : this->m_CoolingCoilSensDemand,
11719 : this->m_CoolingCoilLatentDemand,
11720 : CompressorOn,
11721 : PartLoadRatio);
11722 :
11723 416870 : this->m_CoolCompPartLoadRatio = (CompressorOn == HVAC::CompressorOp::On) ? PartLoadRatio : 0.0;
11724 416870 : } break;
11725 28852 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
11726 28852 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, this->m_FanOpMode, this->m_TESOpMode, PartLoadRatio);
11727 28852 : } break;
11728 0 : default:
11729 0 : break;
11730 : }
11731 :
11732 33885414 : this->m_CoolingPartLoadFrac = PartLoadRatio;
11733 33885414 : }
11734 :
11735 30665164 : void UnitarySys::calcUnitaryHeatingSystem(EnergyPlusData &state,
11736 : int const AirLoopNum, // index to air loop
11737 : bool const FirstHVACIteration, // True when first HVAC iteration
11738 : Real64 const PartLoadRatio, // coil operating part-load ratio
11739 : HVAC::CompressorOp const CompressorOn, // compressor control (0=off, 1=on)
11740 : Real64 const OnOffAirFlowRatio, // ratio of on to off flow rate
11741 : Real64 HeatCoilLoad // adjusted heating coil load if outlet temp exceeds max (W)
11742 : )
11743 : {
11744 :
11745 : // SUBROUTINE INFORMATION:
11746 : // AUTHOR Richard Raustad, FSEC
11747 : // DATE WRITTEN February 2013
11748 :
11749 : // PURPOSE OF THIS SUBROUTINE:
11750 : // This subroutine manages unitary heating system component simulation.
11751 :
11752 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11753 : Real64 OutsideDryBulbTemp; // outdoor temperature (C)
11754 : Real64 mdot; // water side flow rate (kg/s)
11755 : Real64 QActual; // actual output of coil (W)
11756 : Real64 OutdoorPressure; // Outdoor barometric pressure at condenser (Pa)
11757 :
11758 30665164 : std::string CompName = this->m_HeatingCoilName;
11759 30665164 : Real64 dummy = 0.0;
11760 30665164 : Real64 HeatPLR = 1.0;
11761 30665164 : if (this->m_CondenserNodeNum != 0) {
11762 13061959 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
11763 : // IF node is not connected to anything, pressure = default, use weather data
11764 13061959 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
11765 2219 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11766 : } else {
11767 13059740 : OutsideDryBulbTemp = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
11768 : }
11769 : } else {
11770 17603205 : OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
11771 : }
11772 :
11773 30665164 : switch (this->m_HeatingCoilType_Num) {
11774 2205629 : case HVAC::CoilDX_HeatingEmpirical: { // COIL:HEATING:DX:SINGLESPEED
11775 4411258 : DXCoils::SimDXCoil(
11776 2205629 : state, CompName, CompressorOn, FirstHVACIteration, this->m_HeatingCoilIndex, this->m_FanOpMode, PartLoadRatio, OnOffAirFlowRatio);
11777 2205629 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11778 2205629 : } break;
11779 0 : case HVAC::Coil_UserDefined: {
11780 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
11781 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
11782 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_HeatingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
11783 0 : } break;
11784 20520576 : case HVAC::Coil_HeatingGasOrOtherFuel:
11785 : case HVAC::Coil_HeatingElectric: {
11786 20520576 : HeatCoilLoad = PartLoadRatio * m_DesignHeatingCapacity;
11787 82082304 : HeatingCoils::SimulateHeatingCoilComponents(
11788 61561728 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
11789 20520576 : } break;
11790 0 : case HVAC::Coil_HeatingDesuperheater: {
11791 0 : HeatingCoils::SimulateHeatingCoilComponents(
11792 0 : state, CompName, FirstHVACIteration, HeatCoilLoad, this->m_HeatingCoilIndex, _, false, this->m_FanOpMode, PartLoadRatio);
11793 :
11794 0 : } break;
11795 5002033 : case HVAC::CoilDX_MultiSpeedHeating: {
11796 5002033 : if (OutsideDryBulbTemp > this->m_MinOATCompressorHeating) {
11797 4618899 : DXCoils::SimDXCoilMultiSpeed(state,
11798 : CompName,
11799 : this->m_HeatingSpeedRatio,
11800 : this->m_HeatingCycRatio,
11801 4618899 : this->m_HeatingCoilIndex,
11802 4618899 : this->m_HeatingSpeedNum,
11803 4618899 : this->m_FanOpMode,
11804 : CompressorOn,
11805 4618899 : this->m_SingleMode);
11806 4618899 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11807 : } else {
11808 766268 : DXCoils::SimDXCoilMultiSpeed(
11809 383134 : state, CompName, 0.0, 0.0, this->m_HeatingCoilIndex, this->m_HeatingSpeedNum, this->m_FanOpMode, CompressorOn);
11810 383134 : this->m_HeatCompPartLoadRatio = 0.0;
11811 : }
11812 5002033 : } break;
11813 0 : case HVAC::Coil_HeatingElectric_MultiStage:
11814 : case HVAC::Coil_HeatingGas_MultiStage: {
11815 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
11816 : CompName,
11817 : FirstHVACIteration,
11818 : _,
11819 0 : 0,
11820 : _,
11821 : _,
11822 0 : this->m_FanOpMode,
11823 : PartLoadRatio,
11824 0 : this->m_HeatingSpeedNum,
11825 0 : this->m_HeatingSpeedRatio);
11826 : // This doesn't look right when it was at higher speed
11827 : // this->m_HeatingCycRatio = PartLoadRatio;
11828 0 : } break;
11829 1184720 : case HVAC::Coil_HeatingWater: {
11830 1184720 : if (this->HeatCoilWaterFlowRatio == 0.0) {
11831 1184720 : mdot = this->MaxHeatCoilFluidFlow * PartLoadRatio;
11832 : } else {
11833 0 : mdot = this->HeatCoilWaterFlowRatio * this->MaxHeatCoilFluidFlow;
11834 : }
11835 1184720 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
11836 3554160 : WaterCoils::SimulateWaterCoilComponents(
11837 2369440 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, QActual, this->m_FanOpMode, PartLoadRatio);
11838 1184720 : } break;
11839 55178 : case HVAC::Coil_HeatingSteam: {
11840 : // this same CALL is made in the steam coil calc routine
11841 55178 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->MaxHeatCoilFluidFlow * PartLoadRatio);
11842 55178 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
11843 : // tried this to resolve the PackagedTerminalAirConditioner steam spike issue, no help, but this is the correct way to do this
11844 55178 : PlantUtilities::SetComponentFlowRate(
11845 55178 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
11846 : } else {
11847 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
11848 : }
11849 220712 : SteamCoils::SimulateSteamCoilComponents(state,
11850 : CompName,
11851 : FirstHVACIteration,
11852 55178 : this->m_HeatingCoilIndex,
11853 110356 : this->m_DesignHeatingCapacity * PartLoadRatio,
11854 : _,
11855 55178 : this->m_FanOpMode,
11856 : PartLoadRatio);
11857 55178 : } break;
11858 331464 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
11859 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
11860 331464 : if (this->m_HeatingSpeedNum > 1) {
11861 106030 : HeatPLR = 1.0;
11862 106030 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
11863 44092 : this->m_HeatingSpeedRatio = PartLoadRatio;
11864 : }
11865 : } else {
11866 225434 : HeatPLR = PartLoadRatio;
11867 : }
11868 :
11869 331464 : VariableSpeedCoils::SimVariableSpeedCoils(state,
11870 : CompName,
11871 331464 : this->m_HeatingCoilIndex,
11872 : this->m_FanOpMode,
11873 : CompressorOn,
11874 : HeatPLR,
11875 : this->m_HeatingSpeedNum,
11876 : this->m_HeatingSpeedRatio,
11877 : this->m_HeatingCoilSensDemand,
11878 : dummy,
11879 : OnOffAirFlowRatio);
11880 331464 : if (this->m_HeatingSpeedNum > 1) {
11881 106030 : this->m_HeatCompPartLoadRatio = 1.0;
11882 : } else {
11883 225434 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11884 : }
11885 331464 : } break;
11886 948694 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
11887 :
11888 948694 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
11889 : blankString,
11890 948694 : this->m_HeatingCoilIndex,
11891 : this->m_HeatingCoilSensDemand,
11892 : dummy,
11893 : this->m_FanOpMode,
11894 : CompressorOn,
11895 : PartLoadRatio,
11896 : FirstHVACIteration);
11897 948694 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11898 948694 : } break;
11899 416870 : case HVAC::Coil_HeatingWaterToAirHP: {
11900 :
11901 416870 : WaterToAirHeatPump::SimWatertoAirHP(state,
11902 : blankString,
11903 416870 : this->m_HeatingCoilIndex,
11904 : this->MaxHeatAirMassFlow,
11905 : this->m_FanOpMode,
11906 : FirstHVACIteration,
11907 416870 : this->m_InitHeatPump,
11908 : this->m_HeatingCoilSensDemand,
11909 : dummy,
11910 : CompressorOn,
11911 : PartLoadRatio);
11912 416870 : this->m_HeatCompPartLoadRatio = PartLoadRatio * double(CompressorOn);
11913 416870 : } break;
11914 0 : default: {
11915 0 : ShowFatalError(
11916 0 : state, format("CalcUnitaryHeatingSystem: Invalid Unitary System coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
11917 0 : } break;
11918 : }
11919 :
11920 30665164 : this->m_HeatingPartLoadFrac = PartLoadRatio;
11921 30665164 : }
11922 :
11923 8346716 : void UnitarySys::calcUnitarySuppHeatingSystem(EnergyPlusData &state,
11924 : bool const FirstHVACIteration, // True when first HVAC iteration
11925 : Real64 const SuppCoilLoad // adjusted supp coil load when outlet temp exceeds max (W)
11926 : )
11927 : {
11928 :
11929 : // SUBROUTINE INFORMATION:
11930 : // AUTHOR Richard Raustad, FSEC
11931 : // DATE WRITTEN February 2013
11932 :
11933 : // PURPOSE OF THIS SUBROUTINE:
11934 : // This subroutine manages supplemental heater simulation.
11935 :
11936 : // SUBROUTINE PARAMETER DEFINITIONS:
11937 8346716 : int constexpr MaxIte(500); // Maximum number of iterations for solver
11938 8346716 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
11939 :
11940 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11941 : // std::string CompName; // Name of Unitary System object
11942 : Real64 SuppHeatCoilLoad; // load passed to supplemental heating coil (W)
11943 : Real64 QActual; // actual coil output (W)
11944 : Real64 mdot; // water coil water mass flow rate (kg/s)
11945 8346716 : std::vector<Real64> Par; // Parameter array passed to solver
11946 : Real64 PartLoadFrac; // temporary PLR variable
11947 :
11948 8346716 : Par.resize(5);
11949 : // work is needed to figure out how to adjust other coil types if outlet temp exceeds maximum
11950 : // this works for gas and electric heating coils
11951 8346716 : std::string CompName = this->m_SuppHeatCoilName;
11952 12605727 : if (state.dataEnvrn->OutDryBulbTemp <= this->m_MaxOATSuppHeat ||
11953 4259011 : (state.dataUnitarySystems->MoistureLoad < 0.0 && this->m_CoolingPartLoadFrac > 0.0)) {
11954 4172065 : SuppHeatCoilLoad = SuppCoilLoad;
11955 : //} else {
11956 : // SuppHeatCoilLoad = this->m_DesignSuppHeatingCapacity * PartLoadRatio;
11957 : //}
11958 : } else {
11959 4174651 : SuppHeatCoilLoad = 0.0;
11960 : }
11961 8346716 : switch (this->m_SuppHeatCoilType_Num) {
11962 8346716 : case HVAC::Coil_HeatingGasOrOtherFuel:
11963 : case HVAC::Coil_HeatingElectric:
11964 : case HVAC::Coil_HeatingElectric_MultiStage: {
11965 8346716 : switch (this->m_ControlType) {
11966 0 : case UnitarySysCtrlType::Setpoint: {
11967 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
11968 : CompName,
11969 : FirstHVACIteration,
11970 : SuppHeatCoilLoad,
11971 0 : this->m_SuppHeatCoilIndex,
11972 : _,
11973 0 : true,
11974 0 : this->m_FanOpMode,
11975 0 : this->m_SuppHeatPartLoadFrac,
11976 0 : this->m_SuppHeatingSpeedNum,
11977 0 : this->m_SuppHeatingSpeedRatio);
11978 0 : } break;
11979 8346716 : default: {
11980 8346716 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
11981 461070 : if (SuppHeatCoilLoad > 0.0) {
11982 94464 : this->setEMSSuppCoilStagePLR(state);
11983 : } else {
11984 366606 : this->m_SuppHeatingSpeedRatio = 0.0;
11985 366606 : this->m_SuppHeatingCycRatio = 0.0;
11986 366606 : this->m_SuppHeatPartLoadFrac = 0.0;
11987 : }
11988 : } else {
11989 7885646 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
11990 302026 : this->calcMultiStageSuppCoilStageByLoad(state, SuppHeatCoilLoad, FirstHVACIteration);
11991 : }
11992 : }
11993 25040148 : HeatingCoils::SimulateHeatingCoilComponents(state,
11994 : CompName,
11995 : FirstHVACIteration,
11996 : SuppHeatCoilLoad,
11997 8346716 : this->m_SuppHeatCoilIndex,
11998 : _,
11999 16693432 : true,
12000 8346716 : this->m_FanOpMode,
12001 8346716 : this->m_SuppHeatPartLoadFrac,
12002 8346716 : this->m_SuppHeatingSpeedNum,
12003 8346716 : this->m_SuppHeatingSpeedRatio);
12004 8346716 : } break;
12005 : }
12006 8346716 : } break;
12007 0 : case HVAC::Coil_HeatingDesuperheater: {
12008 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
12009 : CompName,
12010 : FirstHVACIteration,
12011 : SuppHeatCoilLoad,
12012 0 : this->m_SuppHeatCoilIndex,
12013 : _,
12014 0 : true,
12015 0 : this->m_FanOpMode,
12016 0 : this->m_SuppHeatPartLoadFrac);
12017 0 : } break;
12018 0 : case HVAC::Coil_HeatingWater: {
12019 : // see if HW coil has enough capacity to meet the load
12020 0 : if (SuppHeatCoilLoad > 0.0) {
12021 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail, this->m_MaxSuppCoilFluidFlow);
12022 : } else {
12023 0 : mdot = 0.0;
12024 : }
12025 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12026 : // simulate water coil to find operating capacity
12027 0 : WaterCoils::SimulateWaterCoilComponents(state,
12028 : this->m_SuppHeatCoilName,
12029 : FirstHVACIteration,
12030 0 : this->m_SuppHeatCoilIndex,
12031 : QActual,
12032 0 : this->m_FanOpMode,
12033 0 : this->m_SuppHeatPartLoadFrac);
12034 0 : if (QActual > SuppHeatCoilLoad) {
12035 0 : auto f = [&state, this, FirstHVACIteration, SuppHeatCoilLoad](Real64 const PartLoadFrac) {
12036 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12037 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
12038 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12039 0 : WaterCoils::SimulateWaterCoilComponents(
12040 0 : state, this->m_SuppHeatCoilName, FirstHVACIteration, this->m_SuppHeatCoilIndex, 0.0, this->m_FanOpMode, PartLoadFrac);
12041 0 : return SuppHeatCoilLoad;
12042 0 : };
12043 : int SolFla; // Flag of solver, num iterations if >0, else error index
12044 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12045 0 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
12046 : } else {
12047 0 : this->m_SuppHeatPartLoadFrac = (SuppHeatCoilLoad > 0.0) ? 1.0 : 0.0;
12048 : }
12049 0 : } break;
12050 0 : case HVAC::Coil_HeatingSteam: {
12051 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
12052 0 : this->m_MaxSuppCoilFluidFlow * this->m_SuppHeatPartLoadFrac);
12053 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
12054 0 : SteamCoils::SimulateSteamCoilComponents(
12055 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, SuppHeatCoilLoad, _, this->m_FanOpMode, this->m_SuppHeatPartLoadFrac);
12056 0 : } break;
12057 0 : default:
12058 0 : break;
12059 : }
12060 8346716 : }
12061 :
12062 94464 : void UnitarySys::setEMSSuppCoilStagePLR(EnergyPlusData &state)
12063 : {
12064 94464 : bool useMaxedSpeed = false;
12065 94464 : int SpeedNumEMS = ceil(this->m_EMSOverrideSuppCoilSpeedNumValue);
12066 94464 : if (SpeedNumEMS > this->m_NumOfSpeedSuppHeating) {
12067 0 : SpeedNumEMS = this->m_NumOfSpeedSuppHeating;
12068 0 : useMaxedSpeed = true;
12069 : }
12070 94464 : this->m_SuppHeatingSpeedNum = SpeedNumEMS;
12071 94464 : if (useMaxedSpeed) {
12072 0 : this->m_CoilSpeedErrIdx++;
12073 0 : ShowRecurringWarningErrorAtEnd(state,
12074 0 : format("Wrong coil speed EMS override value, for unit=\"{}\". Exceeding maximum coil speed "
12075 : "level. Speed level is set to the maximum coil speed level allowed.",
12076 0 : this->m_SuppHeatCoilName),
12077 0 : this->m_CoilSpeedErrIdx,
12078 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12079 0 : this->m_EMSOverrideSuppCoilSpeedNumValue,
12080 : _,
12081 : "",
12082 : "");
12083 : }
12084 94464 : if (this->m_SuppHeatingSpeedNum == 1) {
12085 16 : this->m_SuppHeatingSpeedRatio = 0.0;
12086 16 : this->m_SuppHeatingCycRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12087 16 : if (useMaxedSpeed || this->m_SuppHeatingCycRatio == 0) {
12088 16 : this->m_SuppHeatingCycRatio = 1;
12089 : }
12090 16 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingCycRatio;
12091 : } else {
12092 94448 : this->m_SuppHeatingCycRatio = 1.0;
12093 94448 : this->m_SuppHeatingSpeedRatio = this->m_EMSOverrideSuppCoilSpeedNumValue - floor(this->m_EMSOverrideSuppCoilSpeedNumValue);
12094 94448 : if (useMaxedSpeed || this->m_SuppHeatingSpeedRatio == 0) {
12095 0 : this->m_SuppHeatingSpeedRatio = 1;
12096 : }
12097 94448 : this->m_SuppHeatPartLoadFrac = this->m_SuppHeatingSpeedRatio;
12098 : }
12099 94464 : }
12100 :
12101 3601299 : void UnitarySys::controlCoolingSystemToSP(EnergyPlusData &state,
12102 : int const AirLoopNum, // index to air loop
12103 : bool const FirstHVACIteration, // First HVAC iteration flag
12104 : bool &HXUnitOn, // flag to enable heat exchanger heat recovery
12105 : HVAC::CompressorOp &compressorOp // compressor on/off control
12106 : )
12107 : {
12108 : // SUBROUTINE INFORMATION:
12109 : // AUTHOR Richard Raustad, FSEC
12110 : // DATE WRITTEN February 2013
12111 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
12112 :
12113 : // PURPOSE OF THIS SUBROUTINE:
12114 : // Simulate the coil object at the required PLR.
12115 :
12116 : // METHODOLOGY EMPLOYED:
12117 : // Calculate operating PLR and adjust speed when using multispeed coils.
12118 : // Meet moisture load if required to do so.
12119 :
12120 : // SUBROUTINE PARAMETER DEFINITIONS:
12121 3601299 : int constexpr MaxIte(500); // Maximum number of iterations for solver
12122 3601299 : Real64 constexpr Acc(1.e-3); // Accuracy of solver result
12123 3601299 : Real64 constexpr HumRatAcc(1.e-6); // Accuracy of solver result
12124 :
12125 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12126 : Real64 ReqOutput; // Sensible capacity (outlet - inlet) required to meet load or setpoint temperature
12127 : // for variable speed or 2 speed compressors
12128 : Real64 OutletTempDXCoil; // Actual outlet temperature of the DX cooling coil
12129 : Real64 OutletHumRatLS; // Actual outlet humrat of the variable speed DX cooling coil at low speed
12130 : Real64 OutletHumRatHS; // Actual outlet humrat of the variable speed DX cooling coil at high speed
12131 : Real64 OutletHumRatDXCoil; // Actual outlet humidity ratio of the DX cooling coil
12132 : Real64 TempMinPLR; // Used to find latent PLR when max iterations exceeded
12133 : Real64 TempMaxPLR; // Used to find latent PLR when max iterations exceeded
12134 : Real64 TempOutletTempDXCoil; // Used to find latent PLR when max iterations exceeded
12135 : Real64 OutletTemp;
12136 : Real64 OutdoorDryBulb; // local variable for OutDryBulbTemp
12137 : Real64 maxPartLoadFrac; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
12138 :
12139 : // Set local variables
12140 : // Retrieve the load on the controlled zone
12141 3601299 : int OutletNode = this->CoolCoilOutletNodeNum;
12142 3601299 : int InletNode = this->CoolCoilInletNodeNum;
12143 3601299 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
12144 3601299 : Real64 DesOutHumRat = this->m_DesiredOutletHumRat;
12145 3601299 : int CoilType_Num = this->m_CoolingCoilType_Num;
12146 3601299 : Real64 LoopDXCoilMaxRTFSave = 0.0;
12147 3723831 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
12148 122532 : this->m_sysType != SysType::PackagedWSHP) {
12149 122532 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
12150 122532 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
12151 : }
12152 :
12153 3601299 : std::string CompName = this->m_CoolingCoilName;
12154 3601299 : HVAC::FanOp fanOp = this->m_FanOpMode;
12155 3601299 : Real64 SpeedRatio = 0.0;
12156 3601299 : Real64 CycRatio = 0.0;
12157 3601299 : Real64 PartLoadFrac = 0.0;
12158 3601299 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal;
12159 3601299 : Real64 dummy = 0.0;
12160 3601299 : Real64 SensLoad = 0.0;
12161 3601299 : int SolFla = 0;
12162 3601299 : int SolFlaLat = 0;
12163 3601299 : Real64 NoLoadTempOut = 0.0;
12164 3601299 : Real64 NoLoadHumRatOut = 0.0;
12165 : // #8849, FullLoadHumRatOut set only at max speed
12166 3601299 : Real64 FullLoadHumRatOut = 0.0;
12167 3601299 : Real64 FullOutput = 0.0; // Sensible capacity (outlet - inlet) when the compressor is on
12168 3601299 : Real64 OnOffAirFlowRatio = 0.0; // Autodesk:Init Patch to prevent use uninitialized in calls to SimVariableSpeedCoils
12169 3601299 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
12170 :
12171 3601299 : if (this->m_CondenserNodeNum != 0) {
12172 163714 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
12173 : } else {
12174 3437585 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
12175 : }
12176 :
12177 : // Check the dehumidification control type. IF it's multimode, turn off the HX to find the sensible PLR. Then check to
12178 : // see if the humidity load is met without the use of the HX. Always run the HX for the other modes.
12179 3601299 : if (this->m_DehumidControlType_Num != DehumCtrlType::Multimode && this->m_CoolingCoilType_Num != HVAC::CoilDX_Cooling) {
12180 3488401 : HXUnitOn = true;
12181 : } else {
12182 112898 : HXUnitOn = false;
12183 : }
12184 :
12185 : // IF there is a fault of coil SAT Sensor
12186 3601299 : if (this->m_FaultyCoilSATFlag) {
12187 : // calculate the sensor offset using fault information
12188 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
12189 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
12190 : // update the DesOutTemp
12191 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
12192 : }
12193 :
12194 : // IF UnitarySystem is scheduled on and there is flow
12195 3601299 : if ((ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0) &&
12196 6845053 : ScheduleManager::GetCurrentScheduleValue(state, this->m_CoolingCoilAvailSchPtr) > 0.0 &&
12197 3243754 : (state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow)) {
12198 :
12199 2687987 : bool SensibleLoad = false;
12200 2687987 : bool LatentLoad = false;
12201 2687987 : bool unitSys = false;
12202 2687987 : Real64 tempHumRatAcc = HumRatAcc;
12203 2687987 : Real64 tempAcc = Acc;
12204 : // Determine if there is a sensible load on this system
12205 2687987 : if (this->m_sysType == SysType::CoilCoolingDX) {
12206 2507157 : if ((state.dataLoopNodes->Node(InletNode).Temp > state.dataLoopNodes->Node(this->CoolCtrlNode).TempSetPoint) &&
12207 3811690 : (state.dataLoopNodes->Node(InletNode).Temp > DesOutTemp) &&
12208 1304533 : (std::abs(state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp) > HVAC::TempControlTol)) {
12209 1127063 : SensibleLoad = true;
12210 : }
12211 2507157 : tempAcc = 0.0;
12212 2507157 : tempHumRatAcc = 0.0;
12213 : } else {
12214 180830 : unitSys = true;
12215 180830 : if (state.dataLoopNodes->Node(InletNode).Temp - DesOutTemp > HVAC::TempControlTol) SensibleLoad = true;
12216 : }
12217 :
12218 : // if a heat pump and other coil is on, disable this coil
12219 2687987 : if (this->m_HeatPump && this->m_HeatingPartLoadFrac > 0.0) SensibleLoad = false;
12220 :
12221 : // Determine if there is a latent load on this system - for future use to serve latent-only loads
12222 2687987 : if (this->m_sysType == SysType::CoilCoolingDX) {
12223 4992685 : if ((state.dataLoopNodes->Node(InletNode).HumRat > state.dataLoopNodes->Node(InletNode).HumRatMax) &&
12224 2485528 : (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat))
12225 11701 : LatentLoad = true;
12226 : } else {
12227 180830 : if (state.dataLoopNodes->Node(InletNode).HumRat > DesOutHumRat) LatentLoad = true;
12228 : }
12229 :
12230 : // disable latent dehumidification if there is no sensible load and latent only is not allowed
12231 2687987 : if (this->m_RunOnLatentOnlyWithSensible && !SensibleLoad) LatentLoad = false;
12232 :
12233 : // disable compressor if OAT is below minimum outdoor temperature
12234 2687987 : if (OutdoorDryBulb < this->m_MinOATCompressorCooling) {
12235 0 : SensibleLoad = false;
12236 0 : LatentLoad = false;
12237 : }
12238 :
12239 : // activate heat recovery loop coil if scheduled on and there is air flow
12240 2687987 : if (this->m_WaterHRPlantLoopModel) {
12241 15820 : if (this->temperatureOffsetControlStatus == 1) {
12242 1 : PartLoadFrac = 1.0;
12243 1 : mdot = this->MaxCoolCoilFluidFlow;
12244 : }
12245 15820 : if (this->CoolCoilPlantLoc.loopNum > 0) {
12246 15820 : PlantUtilities::SetComponentFlowRate(
12247 15820 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12248 : }
12249 :
12250 47460 : WaterCoils::SimulateWaterCoilComponents(
12251 31640 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12252 15820 : SensibleLoad = false; // fall through remaining checks
12253 15820 : LatentLoad = false;
12254 2672167 : } else if (this->m_TemperatureOffsetControlActive) {
12255 : // disable waterside economizer if the condition is NOT favorable
12256 60192 : if (this->temperatureOffsetControlStatus == 0) {
12257 59694 : SensibleLoad = false;
12258 59694 : LatentLoad = false;
12259 59694 : HXUnitOn = false;
12260 : }
12261 : }
12262 :
12263 : // IF DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
12264 : // Multimode coil will switch to enhanced dehumidification IF available and needed, but it
12265 : // still runs to meet the sensible load. Multimode applies to Multimode or HXAssistedCooling coils.
12266 2687987 : if ((SensibleLoad && this->m_RunOnSensibleLoad) || (LatentLoad && this->m_RunOnLatentLoad)) {
12267 : // calculate sensible PLR, don't care IF latent is true here but need to gaurd for
12268 : // when LatentLoad=TRUE and SensibleLoad=FALSE
12269 1215213 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12270 3645639 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
12271 1215213 : state.dataLoopNodes->Node(OutletNode).HumRat,
12272 1215213 : state.dataLoopNodes->Node(InletNode).Temp,
12273 1215213 : state.dataLoopNodes->Node(InletNode).HumRat);
12274 :
12275 1215213 : PartLoadFrac = 0.0;
12276 1215213 : compressorOp = HVAC::CompressorOp::Off;
12277 :
12278 1215213 : if (this->m_EMSOverrideCoilSpeedNumOn && (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12279 36467 : this->m_CoolingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
12280 36467 : this->m_SpeedNum = this->m_CoolingSpeedNum;
12281 36467 : bool useMaxedSpeed = false;
12282 36467 : if (this->m_SpeedNum > this->m_NumOfSpeedCooling) {
12283 0 : this->m_CoolingSpeedNum = this->m_NumOfSpeedCooling;
12284 0 : this->m_SpeedNum = this->m_NumOfSpeedCooling;
12285 0 : useMaxedSpeed = true;
12286 0 : if (this->m_CoilSpeedErrIdx == 0) {
12287 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12288 0 : ShowContinueError(state,
12289 : " Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.");
12290 : }
12291 0 : ShowRecurringWarningErrorAtEnd(
12292 : state,
12293 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12294 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
12295 0 : this->m_CoilSpeedErrIdx,
12296 0 : this->m_EMSOverrideCoilSpeedNumValue,
12297 0 : this->m_EMSOverrideCoilSpeedNumValue,
12298 : _,
12299 : "",
12300 : "");
12301 : }
12302 :
12303 36467 : if (this->m_SpeedNum < 0) {
12304 0 : this->m_CoolingSpeedNum = 0;
12305 0 : this->m_SpeedNum = 0;
12306 0 : if (this->m_CoilSpeedErrIdx == 0) {
12307 0 : ShowWarningMessage(state, format("Wrong coil speed EMS override value, for unit=\"{}", this->m_CoolingCoilName));
12308 0 : ShowContinueError(state, " Input speed value is below zero. Speed level is set to zero.");
12309 : }
12310 0 : ShowRecurringWarningErrorAtEnd(state,
12311 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_CoolingCoilName +
12312 : "\". Input speed value is below zero. Speed level is set to zero.",
12313 0 : this->m_CoilSpeedErrIdx,
12314 0 : this->m_EMSOverrideCoilSpeedNumValue,
12315 0 : this->m_EMSOverrideCoilSpeedNumValue,
12316 : _,
12317 : "",
12318 : "");
12319 : }
12320 :
12321 36467 : if (this->m_CoolingSpeedNum == 1) {
12322 3889 : SpeedRatio = this->m_CoolingSpeedRatio = 0.0;
12323 3889 : this->m_CoolingCycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12324 3889 : if (useMaxedSpeed || this->m_CoolingCycRatio == 0) {
12325 3889 : CycRatio = this->m_CoolingCycRatio = 1;
12326 : } else {
12327 0 : CycRatio = this->m_CoolingCycRatio;
12328 : }
12329 3889 : PartLoadFrac = this->m_CoolingCycRatio;
12330 : } else {
12331 32578 : CycRatio = this->m_CoolingCycRatio = 1.0;
12332 32578 : this->m_CoolingSpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
12333 32578 : if (useMaxedSpeed || this->m_CoolingSpeedRatio == 0) {
12334 0 : SpeedRatio = this->m_CoolingSpeedRatio = 1;
12335 : } else {
12336 32578 : SpeedRatio = this->m_CoolingSpeedRatio;
12337 : }
12338 32578 : PartLoadFrac = this->m_CoolingSpeedRatio;
12339 : }
12340 36467 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12341 36467 : if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12342 0 : this->simMultiSpeedCoils(state,
12343 : AirLoopNum,
12344 : FirstHVACIteration,
12345 : compressorOp,
12346 : SensibleLoad,
12347 : LatentLoad,
12348 : PartLoadFrac,
12349 : CoolingCoil,
12350 : this->m_SpeedNum);
12351 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12352 0 : int SpeedNum = 0;
12353 0 : if (SpeedNum == this->m_NumOfSpeedCooling) { // should be using this->m_SpeedNum? Diffs?
12354 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12355 : }
12356 : } else {
12357 36467 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12358 36467 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12359 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12360 36467 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12361 0 : coilMode = HVAC::CoilMode::Enhanced;
12362 : }
12363 36467 : bool const singleMode = (this->m_SingleMode == 1);
12364 36467 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12365 : state, coilMode, PartLoadFrac, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12366 : }
12367 :
12368 1215213 : } else if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12369 701729 : this->m_CompPartLoadRatio = PartLoadFrac;
12370 :
12371 701729 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12372 :
12373 477017 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12374 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12375 :
12376 10182 : if (this->CoolCoilFluidInletNode > 0) state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = 0.0;
12377 :
12378 30546 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12379 : CompName,
12380 : FirstHVACIteration,
12381 : HVAC::CompressorOp::On,
12382 : PartLoadFrac,
12383 10182 : this->m_CoolingCoilIndex,
12384 : fanOp,
12385 : HXUnitOn,
12386 : _,
12387 10182 : state.dataUnitarySystems->economizerFlag,
12388 : _,
12389 10182 : this->m_DehumidificationMode,
12390 10182 : 0.0); // this->CoilSHR);
12391 10182 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) this->m_CompPartLoadRatio = PartLoadFrac;
12392 466835 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12393 :
12394 401020 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, PartLoadFrac, this->m_CoolingCoilIndex);
12395 :
12396 65815 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12397 5179 : this->simMultiSpeedCoils(
12398 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, this->m_SpeedNum);
12399 :
12400 60636 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12401 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12402 :
12403 13133 : int SpeedNum = 0;
12404 13133 : this->m_CoolingCoilSensDemand = ReqOutput;
12405 13133 : VariableSpeedCoils::SimVariableSpeedCoils(
12406 13133 : state, "", this->m_CoolingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
12407 :
12408 60636 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
12409 :
12410 11039 : DXCoils::SimDXCoilMultiMode(
12411 11039 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12412 11039 : this->m_CompPartLoadRatio = PartLoadFrac;
12413 36464 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12414 : // SP control (tentatively) operates at constant air flow regardless of speed
12415 : // speed n uses MSHPMassFlowRateHigh and speed n-1 uses MSHPMassFlowRateLow
12416 29583 : state.dataHVACGlobal->MSHPMassFlowRateLow = this->m_DesignMassFlowRate;
12417 29583 : state.dataHVACGlobal->MSHPMassFlowRateHigh = this->m_DesignMassFlowRate;
12418 29583 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12419 29583 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12420 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12421 29583 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12422 0 : coilMode = HVAC::CoilMode::Enhanced;
12423 : }
12424 29583 : bool const singleMode = (this->m_SingleMode == 1);
12425 29583 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12426 : state, coilMode, PartLoadFrac, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12427 29583 : this->m_CoolCompPartLoadRatio = PartLoadFrac;
12428 6881 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12429 :
12430 1350 : WaterCoils::SimulateWaterCoilComponents(
12431 900 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12432 :
12433 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12434 :
12435 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12436 : blankString,
12437 0 : this->m_CoolingCoilIndex,
12438 : ReqOutput,
12439 : dummy,
12440 : fanOp,
12441 : HVAC::CompressorOp::Off,
12442 : PartLoadFrac,
12443 : FirstHVACIteration);
12444 0 : this->m_CoolingCoilSensDemand = 0.0;
12445 :
12446 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12447 :
12448 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12449 : blankString,
12450 0 : this->m_CoolingCoilIndex,
12451 : this->MaxCoolAirMassFlow,
12452 : fanOp,
12453 : FirstHVACIteration,
12454 0 : this->m_InitHeatPump,
12455 : ReqOutput,
12456 : dummy,
12457 : HVAC::CompressorOp::Off,
12458 : PartLoadFrac);
12459 :
12460 6431 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12461 :
12462 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12463 0 : bool CoolingActive = true; // set to arbitrary value on entry to function
12464 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12465 0 : if (CoolingActive) PartLoadFrac = 1.0;
12466 :
12467 6431 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12468 :
12469 6431 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12470 :
12471 : } else {
12472 : }
12473 :
12474 1215213 : NoLoadTempOut = state.dataLoopNodes->Node(OutletNode).Temp;
12475 1215213 : NoLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12476 :
12477 1215213 : Real64 NoOutput = 0.0; // CoilSystem:Cooling:DX
12478 1215213 : FullOutput = 0.0;
12479 1215213 : if (this->m_sysType == SysType::CoilCoolingDX) {
12480 1127063 : NoOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12481 1127063 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12482 1127063 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12483 1127063 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12484 2254126 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12485 1127063 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12486 : }
12487 :
12488 : // Changed logic to use temperature instead of load. The Psyc calcs can cause slight errors.
12489 : // For example it's possible that (NoOutput-ReqOutput) > Acc while (Node(OutletNode)%Temp-DesOutTemp) is not
12490 : // This can (and did) lead to RegulaFalsi errors
12491 :
12492 : // IF ((NoOutput-ReqOutput) .LT. Acc) THEN
12493 : // IF outlet temp at no load is lower than DesOutTemp (set point), do not operate the coil
12494 : // and if coolReheat, check hum rat as well
12495 1215213 : bool doIt = false; // CoilSystem:Cooling:DX
12496 1215213 : if (this->m_sysType == SysType::CoilCoolingDX) {
12497 1127063 : if ((NoOutput - ReqOutput) < Acc) {
12498 0 : PartLoadFrac = 0.0;
12499 : } else {
12500 1127063 : doIt = true;
12501 : }
12502 88150 : } else if (this->m_EMSOverrideCoilSpeedNumOn &&
12503 36467 : (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling || CoilType_Num == HVAC::CoilDX_Cooling)) {
12504 : // do nothing, PartLoadFrac set above
12505 51683 : } else if (((NoLoadTempOut - DesOutTemp) < Acc) && ((NoLoadHumRatOut - DesOutHumRat) < HumRatAcc)) {
12506 0 : PartLoadFrac = 0.0;
12507 : } else { // need to turn on compressor to see if load is met
12508 51683 : doIt = true; // CoilSystem:Cooling:DX
12509 : } // CoilSystem:Cooling:DX
12510 1215213 : if (this->m_EMSOverrideCoilSpeedNumOn) doIt = false;
12511 :
12512 1215213 : if (doIt) { // CoilSystem:Cooling:DX
12513 1178746 : PartLoadFrac = 1.0;
12514 1178746 : compressorOp = HVAC::CompressorOp::On;
12515 :
12516 1178746 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) { // COIL:DX:COOLINGBYPASSFACTOREMPIRICAL
12517 :
12518 1403458 : DXCoils::SimDXCoil(
12519 701729 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_CoolingCoilIndex, fanOp, PartLoadFrac);
12520 701729 : this->m_CompPartLoadRatio = PartLoadFrac;
12521 701729 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12522 :
12523 477017 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
12524 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted
12525 :
12526 10182 : if (this->CoolCoilFluidInletNode > 0)
12527 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = max(0.0, this->MaxCoolCoilFluidFlow);
12528 30546 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12529 : CompName,
12530 : FirstHVACIteration,
12531 : HVAC::CompressorOp::On,
12532 : PartLoadFrac,
12533 10182 : this->m_CoolingCoilIndex,
12534 : fanOp,
12535 : HXUnitOn,
12536 : _,
12537 10182 : state.dataUnitarySystems->economizerFlag,
12538 : _,
12539 10182 : this->m_DehumidificationMode,
12540 10182 : 0.0); // this->CoilSHR);
12541 :
12542 10182 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) this->m_CompPartLoadRatio = PartLoadFrac;
12543 10182 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12544 :
12545 466835 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12546 :
12547 401020 : CycRatio = 1.0;
12548 752559 : for (int speedRatio = 0; speedRatio < this->m_NumOfSpeedCooling; ++speedRatio) {
12549 752559 : SpeedRatio = Real64(speedRatio);
12550 752559 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
12551 752559 : OutletTemp = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
12552 752559 : if (SpeedRatio == 1) {
12553 351539 : FullLoadHumRatOut = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
12554 351539 : break;
12555 : }
12556 401020 : if (OutletTemp < DesOutTemp && SensibleLoad) break;
12557 : }
12558 :
12559 65815 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12560 :
12561 5179 : CycRatio = 1.0;
12562 5179 : SpeedRatio = 0.0;
12563 15494 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12564 10337 : if (SpeedNum > 1) {
12565 5158 : CycRatio = 0.0;
12566 5158 : SpeedRatio = 1.0;
12567 : }
12568 10337 : this->m_CoolingSpeedNum = SpeedNum;
12569 10337 : this->simMultiSpeedCoils(
12570 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, CoolingCoil, SpeedNum);
12571 10337 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12572 10337 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12573 5158 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12574 : }
12575 10337 : if (OutletTemp < DesOutTemp && SensibleLoad) break;
12576 : }
12577 :
12578 60636 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12579 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12580 :
12581 13133 : CycRatio = 1.0;
12582 13133 : SpeedRatio = 1.0;
12583 13133 : SensLoad = -1.0; // turns on coil
12584 13133 : this->m_CoolingSpeedRatio = SpeedRatio;
12585 13133 : this->m_CoolingPartLoadFrac = PartLoadFrac;
12586 17779 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedCooling; ++SpeedNum) {
12587 15962 : this->m_CoolingSpeedNum = SpeedNum;
12588 15962 : VariableSpeedCoils::SimVariableSpeedCoils(state,
12589 : "",
12590 15962 : this->m_CoolingCoilIndex,
12591 : fanOp,
12592 : compressorOp,
12593 : CycRatio,
12594 : SpeedNum,
12595 : SpeedRatio,
12596 : SensLoad,
12597 : dummy,
12598 : OnOffAirFlowRatio);
12599 15962 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
12600 15962 : if (SpeedNum == this->m_NumOfSpeedCooling) {
12601 11101 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12602 : }
12603 15962 : if (OutletTemp < DesOutTemp && SensibleLoad) break;
12604 : }
12605 13133 : if (this->m_CoolingSpeedNum == 1) {
12606 11195 : CycRatio = 1.0;
12607 11195 : SpeedRatio = 0.0;
12608 : } else {
12609 1938 : CycRatio = 0.0;
12610 1938 : SpeedRatio = 1.0;
12611 : }
12612 :
12613 60636 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) { // Coil:Cooling:DX:TwoStageWithHumidityControlMode
12614 :
12615 11039 : DXCoils::SimDXCoilMultiMode(
12616 11039 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
12617 11039 : this->m_CompPartLoadRatio = PartLoadFrac;
12618 :
12619 36464 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
12620 29583 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
12621 29583 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
12622 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
12623 29583 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
12624 0 : coilMode = HVAC::CoilMode::Enhanced;
12625 : }
12626 29583 : this->m_CoolingSpeedRatio = 1.0;
12627 29583 : bool const singleMode = (this->m_SingleMode == 1);
12628 42092 : for (int speedNum = 1; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
12629 37821 : this->m_CoolingSpeedNum = speedNum;
12630 37821 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
12631 : state, coilMode, PartLoadFrac, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
12632 37821 : if (speedNum == this->m_NumOfSpeedCooling) {
12633 24955 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12634 : }
12635 37821 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) break;
12636 : }
12637 29583 : if (this->m_CoolingSpeedNum == 1) {
12638 21345 : this->m_CompPartLoadRatio = PartLoadFrac;
12639 21345 : this->m_CoolCompPartLoadRatio = PartLoadFrac; // why is the set only for a few?
12640 21345 : SpeedRatio = 0.0;
12641 : } else {
12642 8238 : SpeedRatio = PartLoadFrac;
12643 8238 : PartLoadFrac = 1.0;
12644 8238 : this->m_CompPartLoadRatio = 1.0;
12645 8238 : this->m_CoolCompPartLoadRatio = 1.0;
12646 : }
12647 6881 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
12648 :
12649 450 : mdot = this->MaxCoolCoilFluidFlow;
12650 450 : PlantUtilities::SetComponentFlowRate(
12651 450 : state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
12652 :
12653 1350 : WaterCoils::SimulateWaterCoilComponents(
12654 900 : state, CompName, FirstHVACIteration, this->m_CoolingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
12655 450 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12656 :
12657 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
12658 :
12659 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
12660 : blankString,
12661 0 : this->m_CoolingCoilIndex,
12662 : ReqOutput,
12663 : dummy,
12664 : fanOp,
12665 : HVAC::CompressorOp::On,
12666 : PartLoadFrac,
12667 : FirstHVACIteration);
12668 0 : this->m_CoolingCoilSensDemand = ReqOutput;
12669 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12670 :
12671 6431 : } else if (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
12672 :
12673 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
12674 : blankString,
12675 0 : this->m_CoolingCoilIndex,
12676 : this->MaxCoolAirMassFlow,
12677 : fanOp,
12678 : FirstHVACIteration,
12679 0 : this->m_InitHeatPump,
12680 : ReqOutput,
12681 : dummy,
12682 : HVAC::CompressorOp::Off,
12683 : PartLoadFrac);
12684 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
12685 :
12686 6431 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
12687 0 : bool HeatingActive = false; // set to arbitrary value on entry to function
12688 0 : bool CoolingActive = false; // set to arbitrary value on entry to function
12689 :
12690 0 : UserDefinedComponents::SimCoilUserDefined(
12691 0 : state, CompName, this->m_CoolingCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
12692 0 : if (CoolingActive) PartLoadFrac = 1.0;
12693 :
12694 6431 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
12695 :
12696 : // TES coil simulated above with PLR=0. Operating mode is known here, no need to simulate again to determine operating
12697 : // mode.
12698 6431 : if (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
12699 6431 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly) { // cannot cool
12700 5 : PartLoadFrac = 0.0;
12701 : } else {
12702 : // Get full load result
12703 6426 : PackagedThermalStorageCoil::SimTESCoil(state, CompName, this->m_CoolingCoilIndex, fanOp, this->m_TESOpMode, PartLoadFrac);
12704 : }
12705 :
12706 : } else {
12707 : }
12708 :
12709 1178746 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12710 1178746 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(OutletNode).HumRat) -
12711 1178746 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat));
12712 2357492 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
12713 1178746 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
12714 1178746 : state.dataLoopNodes->Node(OutletNode).HumRat,
12715 1178746 : state.dataLoopNodes->Node(InletNode).Temp,
12716 1178746 : state.dataLoopNodes->Node(InletNode).HumRat);
12717 : }
12718 :
12719 : // IF ((FullOutput - ReqOutput) .GT. Acc) THEN ! old method
12720 : // IF ((Node(OutletNode)%Temp-DesOutTemp) .GT. Acc) THEN ! new method gets caught when temps are very close
12721 1215213 : if (this->m_sysType == SysType::CoilCoolingDX) {
12722 1127063 : if ((FullOutput - ReqOutput) > tempAcc) {
12723 171256 : PartLoadFrac = 1.0;
12724 171256 : doIt = false;
12725 : } else {
12726 955807 : doIt = true;
12727 : }
12728 : }
12729 1215213 : if (this->m_EMSOverrideCoilSpeedNumOn) doIt = false;
12730 :
12731 1215213 : if (doIt) {
12732 1007490 : if (unitSys && state.dataLoopNodes->Node(OutletNode).Temp > DesOutTemp - tempAcc) {
12733 18363 : PartLoadFrac = 1.0;
12734 18363 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
12735 0 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
12736 0 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
12737 0 : PartLoadFrac = 0.0;
12738 : }
12739 989127 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
12740 5389 : (this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::Off ||
12741 5389 : this->m_TESOpMode == PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
12742 0 : PartLoadFrac = 0.0;
12743 989127 : } else if (!SensibleLoad) {
12744 0 : PartLoadFrac = 0.0;
12745 : } else {
12746 :
12747 989127 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
12748 9919456 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadRatio) {
12749 2479864 : int CoilIndex = this->m_CoolingCoilIndex;
12750 2479864 : DXCoils::CalcDoe2DXCoil(state, CoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
12751 2479864 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
12752 :
12753 2479864 : return DesOutTemp - OutletAirTemp;
12754 627984 : };
12755 627984 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12756 627984 : this->m_CompPartLoadRatio = PartLoadFrac;
12757 :
12758 361143 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) || (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) {
12759 :
12760 87771 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadFrac) {
12761 16855 : if (this->CoolCoilFluidInletNode > 0) {
12762 0 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = this->MaxCoolCoilFluidFlow * PartLoadFrac;
12763 : }
12764 16855 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(
12765 : state,
12766 : this->m_CoolingCoilIndex,
12767 : FirstHVACIteration,
12768 : HVAC::CompressorOp::On,
12769 : PartLoadFrac,
12770 : HXUnitOn,
12771 : fanOp,
12772 : _,
12773 : _,
12774 16855 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
12775 16855 : 0.0);
12776 16855 : return DesOutTemp - state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
12777 3496 : };
12778 :
12779 3496 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
12780 3496 : if (SolFla == -1) {
12781 :
12782 : // RegulaFalsi may not find sensible PLR when the latent degradation model is used.
12783 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
12784 0 : TempMaxPLR = -0.1;
12785 0 : TempOutletTempDXCoil = state.dataLoopNodes->Node(InletNode).Temp;
12786 0 : while ((TempOutletTempDXCoil - DesOutTemp) > 0.0 && TempMaxPLR <= 1.0) {
12787 : // find upper limit of PLR
12788 0 : TempMaxPLR += 0.1;
12789 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12790 : CompName,
12791 : FirstHVACIteration,
12792 : HVAC::CompressorOp::On,
12793 : TempMaxPLR,
12794 0 : this->m_CoolingCoilIndex,
12795 : fanOp,
12796 : HXUnitOn,
12797 : _,
12798 0 : state.dataUnitarySystems->economizerFlag,
12799 : _,
12800 0 : this->m_DehumidificationMode,
12801 0 : 0.0); // this->CoilSHR);
12802 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
12803 : }
12804 0 : TempMinPLR = TempMaxPLR;
12805 0 : while ((TempOutletTempDXCoil - DesOutTemp) < 0.0 && TempMinPLR >= 0.0) {
12806 : // pull upper limit of PLR DOwn to last valid limit (i.e. outlet temp still exceeds DesOutTemp)
12807 0 : TempMaxPLR = TempMinPLR;
12808 : // find minimum limit of PLR
12809 0 : TempMinPLR -= 0.01;
12810 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
12811 : CompName,
12812 : FirstHVACIteration,
12813 : HVAC::CompressorOp::On,
12814 : TempMinPLR,
12815 0 : this->m_CoolingCoilIndex,
12816 : fanOp,
12817 : HXUnitOn,
12818 : _,
12819 0 : state.dataUnitarySystems->economizerFlag,
12820 : _,
12821 0 : this->m_DehumidificationMode,
12822 0 : 0.0); // this->CoilSHR);
12823 0 : TempOutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
12824 : }
12825 : // Relax boundary slightly to assure a solution can be found using RegulaFalsi (i.e. one boundary may
12826 : // be very near the desired result)
12827 0 : TempMinPLR = max(0.0, (TempMinPLR - 0.01));
12828 0 : TempMaxPLR = min(1.0, (TempMaxPLR + 0.01));
12829 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
12830 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
12831 0 : if (SolFla == -1) {
12832 0 : if (!state.dataGlobal->WarmupFlag) {
12833 0 : if (this->warnIndex.m_HXAssistedSensPLRIter < 1) {
12834 0 : ++this->warnIndex.m_HXAssistedSensPLRIter;
12835 0 : ShowWarningError(
12836 : state,
12837 0 : format("{} - Iteration limit exceeded calculating DX unit sensible part-load ratio for unit = {}",
12838 0 : this->UnitType,
12839 0 : this->Name));
12840 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
12841 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
12842 0 : ShowContinueErrorTimeStamp(
12843 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
12844 : }
12845 0 : ShowRecurringWarningErrorAtEnd(state,
12846 0 : this->UnitType + " \"" + this->Name +
12847 : "\" - Iteration limit exceeded calculating sensible part-load ratio "
12848 : "error continues. Sensible PLR "
12849 : "statistics follow.",
12850 0 : this->warnIndex.m_HXAssistedSensPLRIterIndex,
12851 : PartLoadFrac,
12852 : PartLoadFrac);
12853 : }
12854 0 : } else if (SolFla == -2) {
12855 0 : PartLoadFrac = ReqOutput / FullOutput;
12856 0 : if (!state.dataGlobal->WarmupFlag) {
12857 0 : if (this->warnIndex.m_HXAssistedSensPLRFail < 1) {
12858 0 : ++this->warnIndex.m_HXAssistedSensPLRFail;
12859 0 : ShowWarningError(state,
12860 0 : format("{} - DX unit sensible part-load ratio calculation unexpectedly failed: "
12861 : "part-load ratio limits exceeded, for unit = {}",
12862 0 : this->UnitType,
12863 0 : this->Name));
12864 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
12865 0 : ShowContinueErrorTimeStamp(
12866 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
12867 : }
12868 0 : ShowRecurringWarningErrorAtEnd(state,
12869 0 : this->UnitType + " \"" + this->Name +
12870 : "\" - DX unit sensible part-load ratio calculation unexpectedly "
12871 : "failed error continues. Sensible PLR "
12872 : "statistics follow.",
12873 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex,
12874 : PartLoadFrac,
12875 : PartLoadFrac);
12876 : }
12877 : }
12878 3496 : } else if (SolFla == -2) {
12879 0 : PartLoadFrac = ReqOutput / FullOutput;
12880 0 : if (!state.dataGlobal->WarmupFlag) {
12881 0 : if (this->warnIndex.m_HXAssistedSensPLRFail2 < 1) {
12882 0 : ++this->warnIndex.m_HXAssistedSensPLRFail2;
12883 0 : ShowWarningError(state,
12884 0 : format("{} - DX unit sensible part-load ratio calculation failed: part-load ratio limits "
12885 : "exceeded, for unit = {}",
12886 0 : this->UnitType,
12887 0 : this->Name));
12888 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
12889 0 : ShowContinueErrorTimeStamp(
12890 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
12891 : }
12892 0 : ShowRecurringWarningErrorAtEnd(state,
12893 0 : this->UnitType + " \"" + this->Name +
12894 : "\" - DX unit sensible part-load ratio calculation failed error continues. "
12895 : "Sensible PLR statistics follow.",
12896 0 : this->warnIndex.m_HXAssistedSensPLRFailIndex2,
12897 : PartLoadFrac,
12898 : PartLoadFrac);
12899 : }
12900 : }
12901 3496 : if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) this->m_CompPartLoadRatio = PartLoadFrac;
12902 :
12903 361143 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
12904 311875 : this->m_CoolingSpeedRatio = SpeedRatio;
12905 311875 : if (SpeedRatio == 1.0) {
12906 1718065 : auto f = [&state, this, DesOutTemp](Real64 const SpeedRatio) {
12907 1718065 : int par1 = this->m_CoolingCoilIndex;
12908 1718065 : Real64 par2 = DesOutTemp;
12909 1718065 : int par3 = this->m_UnitarySysNum;
12910 : // 4-7 are not used for TwoSpeed coils, so these shouldn't matter at all
12911 1718065 : Real64 par4_CycRatio = 0.0;
12912 1718065 : int par5_SpeedNum = 0.0;
12913 1718065 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
12914 1718065 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
12915 1718065 : return UnitarySys::DXCoilVarSpeedResidual(
12916 1718065 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
12917 262394 : };
12918 262394 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
12919 262394 : PartLoadFrac = SpeedRatio;
12920 : } else {
12921 183530 : auto f = [&state, this, DesOutTemp, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
12922 : // several pars are not used in two speed coils, so these are just dummy values
12923 183530 : Real64 par4_SpeedRatio = 0.0;
12924 183530 : int par5_SpeedNum = 0.0;
12925 183530 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Invalid;
12926 183530 : HVAC::CompressorOp par7_compressorOp = HVAC::CompressorOp::On;
12927 183530 : return UnitarySys::DXCoilCyclingResidual(state,
12928 : CycRatio,
12929 : this->m_CoolingCoilIndex,
12930 : DesOutTemp,
12931 : this->m_UnitarySysNum,
12932 : par4_SpeedRatio,
12933 : par5_SpeedNum,
12934 : par6_FanOpMode,
12935 : par7_compressorOp,
12936 : AirLoopNum,
12937 183530 : FirstHVACIteration);
12938 49481 : };
12939 49481 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
12940 49481 : PartLoadFrac = CycRatio;
12941 : }
12942 :
12943 45772 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
12944 :
12945 22 : if (this->m_CoolingSpeedNum > 1.0) {
12946 235 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
12947 235 : int par1 = this->m_CoolingCoilIndex;
12948 235 : Real64 par2 = DesOutTemp;
12949 235 : int par3 = this->m_UnitarySysNum;
12950 235 : Real64 par4_CycRatio = CycRatio;
12951 235 : int par5_SpeedNum = this->m_CoolingSpeedNum;
12952 235 : HVAC::FanOp par6_FanOpMode = HVAC::FanOp::Cycling;
12953 235 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
12954 235 : return UnitarySys::DXCoilVarSpeedResidual(
12955 235 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
12956 1 : };
12957 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
12958 1 : PartLoadFrac = SpeedRatio;
12959 : } else {
12960 21 : SpeedRatio = 0.0;
12961 21 : this->m_CoolingSpeedRatio = SpeedRatio;
12962 122 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
12963 122 : return UnitarySys::DXCoilCyclingResidual(state,
12964 : CycRatio,
12965 : this->m_CoolingCoilIndex,
12966 : DesOutTemp,
12967 : this->m_UnitarySysNum,
12968 : SpeedRatio,
12969 : this->m_CoolingSpeedNum,
12970 : HVAC::FanOp::Cycling,
12971 : HVAC::CompressorOp::On,
12972 : AirLoopNum,
12973 122 : FirstHVACIteration);
12974 21 : };
12975 21 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
12976 21 : PartLoadFrac = CycRatio;
12977 : }
12978 :
12979 45750 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
12980 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
12981 :
12982 11316 : CycRatio = 1.0;
12983 11316 : SpeedRatio = 1.0;
12984 :
12985 11316 : if (this->m_CoolingSpeedNum > 1.0) {
12986 8370 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
12987 8370 : int par1 = this->m_CoolingCoilIndex;
12988 8370 : Real64 par2 = DesOutTemp;
12989 8370 : int par3 = this->m_UnitarySysNum;
12990 8370 : Real64 par4_CycRatio = CycRatio;
12991 8370 : int par5_SpeedNum = this->m_CoolingSpeedNum;
12992 8370 : HVAC::FanOp par6_FanOpMode = this->m_FanOpMode;
12993 8370 : HVAC::CompressorOp par7_CompressorOp = HVAC::CompressorOp::On;
12994 8370 : return UnitarySys::DXCoilVarSpeedResidual(
12995 8370 : state, SpeedRatio, par1, par2, par3, par4_CycRatio, par5_SpeedNum, par6_FanOpMode, par7_CompressorOp);
12996 1938 : };
12997 1938 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
12998 1938 : this->m_CoolingCycRatio = CycRatio;
12999 1938 : this->m_CoolingSpeedRatio = SpeedRatio;
13000 1938 : this->m_CoolingPartLoadFrac = SpeedRatio;
13001 1938 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13002 1938 : PartLoadFrac = SpeedRatio;
13003 : } else {
13004 9378 : this->m_CoolingSpeedRatio = SpeedRatio;
13005 37415 : auto f = [&state, this, DesOutTemp, SpeedRatio, AirLoopNum, FirstHVACIteration](Real64 const CycRatio) {
13006 37415 : return UnitarySys::DXCoilCyclingResidual(state,
13007 : CycRatio,
13008 : this->m_CoolingCoilIndex,
13009 : DesOutTemp,
13010 : this->m_UnitarySysNum,
13011 : SpeedRatio,
13012 : this->m_CoolingSpeedNum,
13013 : this->m_FanOpMode,
13014 : HVAC::CompressorOp::On,
13015 : AirLoopNum,
13016 37415 : FirstHVACIteration);
13017 9378 : };
13018 9378 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13019 9378 : SpeedRatio = 0.0;
13020 9378 : this->m_CoolingCycRatio = CycRatio;
13021 9378 : this->m_CoolingPartLoadFrac = CycRatio;
13022 9378 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
13023 9378 : PartLoadFrac = CycRatio;
13024 : }
13025 :
13026 45750 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13027 57964 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13028 14491 : DXCoils::SimDXCoilMultiMode(
13029 14491 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13030 14491 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13031 3715 : };
13032 3715 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13033 3715 : this->m_CompPartLoadRatio = PartLoadFrac;
13034 30719 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13035 943578 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13036 157263 : int CoilIndex = this->m_CoolingCoilIndex;
13037 157263 : int CoolingSpeedNum = this->m_CoolingSpeedNum;
13038 157263 : Real64 CoolingSpeedRatio = this->m_CoolingSpeedRatio;
13039 157263 : bool const singleMode = this->m_SingleMode;
13040 157263 : if (CoolingSpeedNum == 1) {
13041 94083 : state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].simulate(
13042 : state, DehumidMode, PartLoadRatio, CoolingSpeedNum, CoolingSpeedRatio, fanOp, singleMode);
13043 : } else {
13044 63180 : state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].simulate(
13045 : state, DehumidMode, CoolingSpeedRatio, CoolingSpeedNum, PartLoadRatio, fanOp, singleMode);
13046 : }
13047 : Real64 outletCondition =
13048 157263 : state.dataLoopNodes->Node(state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].evapOutletNodeIndex).Temp;
13049 157263 : return DesOutTemp - outletCondition;
13050 25312 : };
13051 :
13052 25312 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13053 25312 : if (this->m_CoolingSpeedNum == 1) {
13054 20127 : this->m_CompPartLoadRatio = PartLoadFrac;
13055 20127 : SpeedRatio = 0.0;
13056 : } else {
13057 5185 : SpeedRatio = PartLoadFrac;
13058 5185 : PartLoadFrac = 1.0;
13059 5185 : this->m_CompPartLoadRatio = 1.0;
13060 : }
13061 5407 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) {
13062 :
13063 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
13064 : maxPartLoadFrac =
13065 18 : min(1.0,
13066 18 : ((mdot / this->MaxCoolCoilFluidFlow) +
13067 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
13068 :
13069 576 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadRatio) {
13070 72 : Real64 mdot = min(state.dataLoopNodes->Node(this->CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13071 72 : this->MaxCoolCoilFluidFlow * PartLoadRatio);
13072 72 : state.dataLoopNodes->Node(this->CoolCoilFluidInletNode).MassFlowRate = mdot;
13073 144 : WaterCoils::SimulateWaterCoilComponents(
13074 72 : state, this->m_CoolingCoilName, FirstHVACIteration, this->m_CoolingCoilIndex, _, _, PartLoadRatio);
13075 72 : return DesOutTemp - state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).Temp;
13076 18 : };
13077 :
13078 18 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
13079 :
13080 5407 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13081 0 : this->m_CoolingCoilSensDemand = ReqOutput;
13082 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
13083 0 : return UnitarySys::coolWatertoAirHPTempResidual(
13084 0 : state, PartLoadRatio, this->m_UnitarySysNum, FirstHVACIteration, DesOutTemp, ReqOutput);
13085 0 : };
13086 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13087 5389 : } else if (CoilType_Num == HVAC::Coil_UserDefined) {
13088 : // do nothing, user defined coil cannot be controlled
13089 :
13090 5389 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13091 108420 : auto f = [&state, this, DesOutTemp](Real64 const PartLoadRatio) {
13092 21684 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13093 43368 : PackagedThermalStorageCoil::SimTESCoil(state,
13094 : thisSys.m_CoolingCoilName,
13095 21684 : thisSys.m_CoolingCoilIndex,
13096 : thisSys.m_FanOpMode,
13097 21684 : thisSys.m_TESOpMode,
13098 : PartLoadRatio);
13099 21684 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp - DesOutTemp;
13100 5389 : };
13101 5389 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13102 : } else {
13103 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
13104 0 : ShowFatalError(state,
13105 0 : format("ControlCoolingSystemToSP: Invalid cooling coil type = {}", HVAC::cAllCoilTypes(CoilType_Num)));
13106 : }
13107 : }
13108 : }
13109 : }
13110 :
13111 : // IF system does not operate to meet sensible load, use no load humidity ratio to test against humidity setpoint,
13112 : // ELSE use operating humidity ratio to test against humidity setpoint
13113 2687987 : if (PartLoadFrac == 0.0) {
13114 1472773 : OutletHumRatDXCoil = NoLoadHumRatOut;
13115 : } else {
13116 1215214 : OutletHumRatDXCoil = state.dataLoopNodes->Node(OutletNode).HumRat;
13117 : }
13118 :
13119 : // IF humidity setpoint is not satisfied and humidity control type is MultiMode,
13120 : // then enable heat exchanger and run to meet sensible load
13121 :
13122 2687987 : if ((OutletHumRatDXCoil > (DesOutHumRat + tempHumRatAcc)) && (!unitSys || PartLoadFrac < 1.0) &&
13123 24876 : (this->m_DehumidControlType_Num == DehumCtrlType::Multimode)) {
13124 :
13125 7528 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13126 : // pass
13127 7528 : } else if ((CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) ||
13128 : (CoilType_Num == HVAC::CoilWater_CoolingHXAssisted)) { // CoilSystem:Cooling:DX:HeatExchangerAssisted,
13129 : // CoilSystem:Cooling:Water:HeatExchangerAssisted
13130 : // Determine required part load when heat exchanger is ON
13131 0 : HXUnitOn = true;
13132 0 : PartLoadFrac = 1.0;
13133 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13134 : CompName,
13135 : FirstHVACIteration,
13136 : HVAC::CompressorOp::On,
13137 : PartLoadFrac,
13138 0 : this->m_CoolingCoilIndex,
13139 : fanOp,
13140 : HXUnitOn,
13141 : _,
13142 0 : state.dataUnitarySystems->economizerFlag,
13143 : _,
13144 0 : this->m_DehumidificationMode,
13145 0 : 0.0); // this->CoilSHR);
13146 :
13147 0 : OutletTempDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13148 :
13149 : // FullOutput will be different than the FullOutput determined above during sensible PLR calculations
13150 0 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13151 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13152 0 : state.dataLoopNodes->Node(OutletNode).HumRat,
13153 0 : state.dataLoopNodes->Node(InletNode).Temp,
13154 0 : state.dataLoopNodes->Node(InletNode).HumRat);
13155 0 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13156 :
13157 : // Check to see if the system can meet the load with the compressor off
13158 : // If NoOutput is lower than (more cooling than required) or very near the ReqOutput, do not run the compressor
13159 0 : if ((NoLoadTempOut - DesOutTemp) < Acc) {
13160 0 : PartLoadFrac = 0.0;
13161 : // OutletTempDXCoil is the full capacity outlet temperature at PartLoadFrac = 1 from the CALL above.
13162 : // if this temp is greater than or very near the desired outlet temp, then run the compressor at PartLoadFrac
13163 : // = 1.
13164 : // ELSEIF ((OutletTempDXCoil > DesOutTemp) .OR. ABS(OutletTempDXCoil - DesOutTemp) .LE. (Acc*2.0d0)) THEN
13165 0 : } else if (OutletTempDXCoil > DesOutTemp - (tempAcc * 2.0)) {
13166 0 : PartLoadFrac = 1.0;
13167 : } else {
13168 0 : auto f = [&state, this, DesOutTemp, FirstHVACIteration, HXUnitOn, fanOp](Real64 const PartLoadRatio) {
13169 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13170 :
13171 0 : if (thisSys.CoolCoilFluidInletNode > 0) {
13172 0 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = thisSys.MaxCoolCoilFluidFlow * PartLoadRatio;
13173 : }
13174 0 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13175 : this->m_CoolingCoilIndex,
13176 : FirstHVACIteration,
13177 : HVAC::CompressorOp::On,
13178 : PartLoadRatio,
13179 : HXUnitOn,
13180 : fanOp,
13181 : _,
13182 : _,
13183 0 : this->m_DehumidificationMode, // double(this->m_DehumidificationMode)
13184 0 : 0.0);
13185 0 : Real64 OutletAirTemp = state.dataHVACAssistedCC->HXAssistedCoilOutletTemp(this->m_CoolingCoilIndex);
13186 0 : return DesOutTemp - OutletAirTemp;
13187 0 : };
13188 :
13189 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13190 : }
13191 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13192 :
13193 7528 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13194 :
13195 : // Get full load result
13196 7528 : PartLoadFrac = 1.0;
13197 7528 : DehumidMode = HVAC::CoilMode::Enhanced;
13198 7528 : this->m_DehumidificationMode = DehumidMode;
13199 7528 : DXCoils::SimDXCoilMultiMode(
13200 7528 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, PartLoadFrac, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13201 7528 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
13202 7528 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
13203 7528 : state.dataLoopNodes->Node(OutletNode).HumRat,
13204 7528 : state.dataLoopNodes->Node(InletNode).Temp,
13205 7528 : state.dataLoopNodes->Node(InletNode).HumRat);
13206 7528 : FullLoadHumRatOut = state.dataLoopNodes->Node(OutletNode).HumRat;
13207 :
13208 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
13209 : // Check that this is the case; IF not set PartLoadFrac = 0.0 (off) and return
13210 : // Calculate the part load fraction
13211 7528 : if (FullOutput >= 0) {
13212 0 : PartLoadFrac = 0.0;
13213 : } else {
13214 7528 : OutletTempDXCoil = state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13215 7528 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13216 : // If sensible load and setpoint cannot be met, set PLR = 1. if no sensible load and
13217 : // latent load exists and setpoint cannot be met, set PLR = 1.
13218 7528 : if ((OutletTempDXCoil > (DesOutTemp - (tempAcc * 2.0)) && SensibleLoad && this->m_RunOnSensibleLoad) ||
13219 589 : (OutletHumRatDXCoil >= (DesOutHumRat - (tempHumRatAcc * 2.0)) && !SensibleLoad && LatentLoad &&
13220 0 : this->m_RunOnLatentLoad)) {
13221 6939 : PartLoadFrac = 1.0;
13222 : // ELSEIF ((SensibleLoad .and. LatentLoad .AND. .NOT. UnitarySystem(UnitarySysNum)%RunOnLatentLoad
13223 : // .AND. &
13224 : // OutletHumRatDXCoil < DesOutHumRat)) THEN
13225 589 : } else if (!SensibleLoad && (OutletHumRatDXCoil < DesOutHumRat && LatentLoad && this->m_RunOnLatentLoad)) {
13226 0 : PartLoadFrac = ReqOutput / FullOutput;
13227 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13228 0 : DXCoils::SimDXCoilMultiMode(
13229 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13230 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13231 0 : };
13232 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13233 0 : } else { // must be a sensible load so find PLR
13234 589 : PartLoadFrac = ReqOutput / FullOutput;
13235 9240 : auto f = [&state, this, DesOutTemp, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13236 2310 : DXCoils::SimDXCoilMultiMode(
13237 2310 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13238 2310 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(this->m_CoolingCoilIndex);
13239 589 : };
13240 589 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13241 : }
13242 : }
13243 7528 : this->m_CompPartLoadRatio = PartLoadFrac;
13244 :
13245 0 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13246 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Enhanced;
13247 0 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
13248 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
13249 : }
13250 0 : if (this->m_CoolingSpeedNum == 0) this->m_CoolingSpeedNum = 1;
13251 0 : bool const singleMode = (this->m_SingleMode == 1);
13252 0 : PartLoadFrac = 1.0;
13253 0 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13254 0 : this->m_CoolingSpeedNum = speedNum;
13255 0 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13256 : state, coilMode, PartLoadFrac, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13257 : // Cooling: break if outlet temp is lower than DesOutTemp or approaches DesOutTemp to within Acc from above
13258 0 : if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc) break;
13259 : }
13260 :
13261 : // make sure outlet temp is below set point before calling SolveRoot
13262 : // Cooling: iterate only when outlet temp is below DesOutTemp by at least Acc
13263 0 : if ((DesOutTemp - state.dataLoopNodes->Node(OutletNode).Temp) > Acc) {
13264 :
13265 0 : auto f = [&state, this, DesOutTemp, fanOp](Real64 const PartLoadFrac) {
13266 0 : int CoilIndex = this->m_CoolingCoilIndex;
13267 0 : int CoolingSpeedNum = this->m_CoolingSpeedNum;
13268 0 : Real64 CoolingSpeedRatio = 1.0;
13269 0 : bool const singleMode = false;
13270 0 : if (CoolingSpeedNum == 1) {
13271 0 : state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].simulate(
13272 : state, HVAC::CoilMode::Enhanced, PartLoadFrac, CoolingSpeedNum, CoolingSpeedRatio, fanOp, singleMode);
13273 : } else {
13274 0 : state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].simulate(
13275 : state, HVAC::CoilMode::Enhanced, CoolingSpeedRatio, CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13276 : }
13277 : Real64 outletCondition =
13278 0 : state.dataLoopNodes->Node(state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].evapOutletNodeIndex).Temp;
13279 :
13280 0 : return DesOutTemp - outletCondition;
13281 0 : };
13282 :
13283 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13284 : }
13285 0 : if (this->m_CoolingSpeedNum == 1) {
13286 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13287 0 : SpeedRatio = 0.0;
13288 : } else {
13289 0 : SpeedRatio = PartLoadFrac;
13290 0 : PartLoadFrac = 1.0;
13291 0 : this->m_CompPartLoadRatio = 1.0;
13292 : }
13293 :
13294 : } else {
13295 : }
13296 : } // END IF humidity ratio setpoint not met - Multimode humidity control
13297 :
13298 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13299 : // then overcool to meet moisture load
13300 2687987 : if (this->m_EMSOverrideCoilSpeedNumOn) {
13301 : // pass
13302 2648058 : } else if ((OutletHumRatDXCoil > DesOutHumRat) && (!unitSys || PartLoadFrac < 1.0) && LatentLoad &&
13303 24533 : (this->m_DehumidControlType_Num == DehumCtrlType::CoolReheat)) {
13304 :
13305 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13306 : // do not run the compressor
13307 17348 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc) {
13308 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13309 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the DesOutHumRat,
13310 : // run the compressor at PartLoadFrac = 1.
13311 : // ELSEIF ((DesOutHumRat-FullLoadHumRatOut) .LT. HumRatAcc) THEN
13312 17348 : } else if (FullLoadHumRatOut > (DesOutHumRat - tempHumRatAcc)) {
13313 13054 : PartLoadFrac = 1.0;
13314 13054 : SpeedRatio = 1.0; // #8849, need to set properties of multi-speed/2-speed coils
13315 13054 : if (this->m_IsDXCoil) {
13316 13054 : this->m_CompPartLoadRatio = PartLoadFrac;
13317 : }
13318 : // ELSE find the PLR to meet the load
13319 :
13320 : } else {
13321 :
13322 4294 : if (CoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
13323 26160 : auto f = [&state, this, DesOutHumRat, fanOp](Real64 const PartLoadRatio) {
13324 5232 : DXCoils::CalcDoe2DXCoil(state, this->m_CoolingCoilIndex, HVAC::CompressorOp::On, true, PartLoadRatio, fanOp);
13325 5232 : Real64 OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13326 5232 : return DesOutHumRat - OutletAirHumRat;
13327 546 : };
13328 546 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13329 546 : this->m_CompPartLoadRatio = PartLoadFrac;
13330 3748 : } else if (CoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
13331 :
13332 : // IF NoLoadHumRatOut is lower than (more dehumidification than required) or very near the DesOutHumRat,
13333 : // do not run the compressor
13334 918 : if ((NoLoadHumRatOut - DesOutHumRat) < tempHumRatAcc * 2.0) {
13335 : // PartLoadFrac = PartLoadFrac; // keep part-load fraction from sensible calculation // Self-assignment commented out
13336 : // If the FullLoadHumRatOut is greater than (insufficient dehumidification) or very near the
13337 : // DesOutHumRat, run the compressor at PartLoadFrac = 1.
13338 918 : } else if ((DesOutHumRat - FullLoadHumRatOut) < tempHumRatAcc * 2.0) {
13339 6 : PartLoadFrac = 1.0;
13340 : // ELSE find the PLR to meet the load
13341 : } else {
13342 21127 : auto f = [&state, this, FirstHVACIteration, HXUnitOn, fanOp, DesOutHumRat](Real64 const PartLoadRatio) {
13343 4043 : HVACHXAssistedCoolingCoil::CalcHXAssistedCoolingCoil(state,
13344 : this->m_CoolingCoilIndex,
13345 : FirstHVACIteration,
13346 : HVAC::CompressorOp::On,
13347 : PartLoadRatio,
13348 : HXUnitOn,
13349 : fanOp,
13350 : _,
13351 4043 : state.dataUnitarySystems->economizerFlag,
13352 8086 : HVAC::CoilMode::Normal,
13353 4043 : 0.0);
13354 4043 : return DesOutHumRat - state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13355 912 : };
13356 912 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13357 912 : if (SolFla == -1) {
13358 :
13359 : // RegulaFalsi may not find latent PLR when the latent degradation model is used.
13360 : // IF iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
13361 0 : TempMaxPLR = -0.1;
13362 0 : while ((OutletHumRatDXCoil - DesOutHumRat) >= 0.0 && TempMaxPLR <= 1.0) {
13363 : // find upper limit of LatentPLR
13364 0 : TempMaxPLR += 0.1;
13365 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13366 : CompName,
13367 : FirstHVACIteration,
13368 : HVAC::CompressorOp::On,
13369 : TempMaxPLR,
13370 0 : this->m_CoolingCoilIndex,
13371 : fanOp,
13372 : HXUnitOn,
13373 : _,
13374 0 : state.dataUnitarySystems->economizerFlag,
13375 : _,
13376 0 : this->m_DehumidificationMode,
13377 0 : 0.0); // this->CoilSHR);
13378 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13379 : }
13380 0 : TempMaxPLR = min(1.0, TempMaxPLR + 0.1);
13381 0 : TempMinPLR = TempMaxPLR;
13382 0 : while ((OutletHumRatDXCoil - DesOutHumRat) <= 0.0 && TempMinPLR >= 0.0) {
13383 : // pull upper limit of LatentPLR DOwn to last valid limit (i.e. latent output still
13384 : // exceeds SystemMoisuterLoad)
13385 : // find minimum limit of Latent PLR
13386 0 : TempMinPLR -= 0.02;
13387 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
13388 : CompName,
13389 : FirstHVACIteration,
13390 : HVAC::CompressorOp::On,
13391 : TempMinPLR,
13392 0 : this->m_CoolingCoilIndex,
13393 : fanOp,
13394 : HXUnitOn,
13395 : _,
13396 0 : state.dataUnitarySystems->economizerFlag,
13397 : _,
13398 0 : this->m_DehumidificationMode,
13399 0 : 0.0); // this->CoilSHR);
13400 0 : OutletHumRatDXCoil = state.dataHVACAssistedCC->HXAssistedCoilOutletHumRat(this->m_CoolingCoilIndex);
13401 : }
13402 0 : TempMinPLR = max(0.0, TempMinPLR - 0.1);
13403 : // tighter boundary of solution has been found, CALL RegulaFalsi a second time
13404 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, TempMinPLR, TempMaxPLR);
13405 0 : if (SolFla == -1) {
13406 0 : if (!state.dataGlobal->WarmupFlag) {
13407 0 : if (this->warnIndex.m_HXAssistedCRLatPLRIter < 1) {
13408 0 : ++this->warnIndex.m_HXAssistedCRLatPLRIter;
13409 0 : ShowWarningError(
13410 : state,
13411 0 : format("{} - Iteration limit exceeded calculating DX unit latent part-load ratio for unit = {}",
13412 0 : this->UnitType,
13413 0 : this->Name));
13414 0 : ShowContinueError(state, format("Estimated latent part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13415 0 : ShowContinueError(state, format("Calculated latent part-load ratio = {:.3R}", PartLoadFrac));
13416 0 : ShowContinueErrorTimeStamp(state,
13417 : "The calculated latent part-load ratio will be used and the simulation "
13418 : "continues. Occurrence info:");
13419 : }
13420 0 : ShowRecurringWarningErrorAtEnd(state,
13421 0 : this->UnitType + " \"" + this->Name +
13422 : "\" - Iteration limit exceeded calculating latent part-load ratio "
13423 : "error continues. Latent PLR "
13424 : "statistics follow.",
13425 0 : this->warnIndex.m_HXAssistedCRLatPLRIterIndex,
13426 : PartLoadFrac,
13427 : PartLoadFrac);
13428 : }
13429 :
13430 0 : } else if (SolFla == -2) {
13431 :
13432 0 : PartLoadFrac = ReqOutput / FullOutput;
13433 0 : if (!state.dataGlobal->WarmupFlag) {
13434 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail < 1) {
13435 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail;
13436 0 : ShowWarningError(state,
13437 0 : format("{} - DX unit latent part-load ratio calculation failed unexpectedly: part-load "
13438 : "ratio limits exceeded, for unit = {}",
13439 0 : this->UnitType,
13440 0 : this->Name));
13441 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13442 0 : ShowContinueErrorTimeStamp(
13443 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13444 : }
13445 0 : ShowRecurringWarningErrorAtEnd(state,
13446 0 : this->UnitType + " \"" + this->Name +
13447 : "\" - DX unit latent part-load ratio calculation failed "
13448 : "unexpectedly error continues. Latent PLR "
13449 : "statistics follow.",
13450 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex,
13451 : PartLoadFrac,
13452 : PartLoadFrac);
13453 : }
13454 : }
13455 912 : } else if (SolFla == -2) {
13456 0 : PartLoadFrac = ReqOutput / FullOutput;
13457 0 : if (!state.dataGlobal->WarmupFlag) {
13458 0 : if (this->warnIndex.m_HXAssistedCRLatPLRFail2 < 1) {
13459 0 : ++this->warnIndex.m_HXAssistedCRLatPLRFail2;
13460 0 : ShowWarningError(state,
13461 0 : format("{} - DX unit latent part-load ratio calculation failed: part-load ratio limits "
13462 : "exceeded, for unit = {}",
13463 0 : this->UnitType,
13464 0 : this->Name));
13465 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13466 0 : ShowContinueErrorTimeStamp(
13467 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13468 : }
13469 0 : ShowRecurringWarningErrorAtEnd(
13470 : state,
13471 0 : this->UnitType + " \"" + this->Name +
13472 : "\" - DX unit latent part-load ratio calculation failed error continues. Latent PLR statistics "
13473 : "follow.",
13474 0 : this->warnIndex.m_HXAssistedCRLatPLRFailIndex2,
13475 : PartLoadFrac,
13476 : PartLoadFrac);
13477 : }
13478 : }
13479 : }
13480 918 : this->m_CompPartLoadRatio = PartLoadFrac;
13481 :
13482 2830 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
13483 :
13484 : // Simulate MultiSpeed DX coil at sensible result
13485 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13486 :
13487 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13488 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13489 : // then overcool to meet moisture load
13490 :
13491 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13492 :
13493 0 : CycRatio = 0.0;
13494 0 : SpeedRatio = 0.0;
13495 :
13496 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13497 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13498 0 : if (OutletHumRatLS > DesOutHumRat) {
13499 0 : CycRatio = 1.0;
13500 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13501 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13502 0 : if (OutletHumRatHS < DesOutHumRat) {
13503 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13504 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13505 : SpeedRatio,
13506 : this->m_CoolingCoilIndex,
13507 : DesOutHumRat,
13508 : this->m_UnitarySysNum, // int UnitarySysNum,
13509 : 0.0, // Real64 CycRatio,
13510 : 0, // int SpeedNum,
13511 : HVAC::FanOp::Invalid, // int FanOpMode,
13512 0 : HVAC::CompressorOp::On);
13513 0 : };
13514 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13515 : } else {
13516 0 : SpeedRatio = 1.0;
13517 : }
13518 0 : PartLoadFrac = SpeedRatio;
13519 : } else {
13520 0 : SpeedRatio = 0.0;
13521 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13522 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13523 : state,
13524 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13525 : this->m_CoolingCoilIndex,
13526 : DesOutHumRat,
13527 : this->m_UnitarySysNum, // int UnitarySysNum,
13528 : 1.0, // Real64 CycRatio,
13529 : this->m_CoolingSpeedNum,
13530 : this->m_FanOpMode, // int FanOpMode,
13531 0 : HVAC::CompressorOp::On);
13532 0 : };
13533 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13534 0 : PartLoadFrac = CycRatio;
13535 : }
13536 : }
13537 :
13538 2830 : } else if (CoilType_Num == HVAC::CoilDX_MultiSpeedCooling) {
13539 :
13540 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, SpeedRatio, CycRatio, this->m_CoolingCoilIndex);
13541 0 : OutletHumRatDXCoil = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13542 :
13543 : // IF humidity setpoint is not satisfied and humidity control type is CoolReheat,
13544 : // then overcool to meet moisture load
13545 :
13546 0 : if (OutletHumRatDXCoil > DesOutHumRat) {
13547 :
13548 0 : CycRatio = 0.0;
13549 0 : SpeedRatio = 0.0;
13550 :
13551 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 0.0, 1.0, this->m_CoolingCoilIndex);
13552 0 : OutletHumRatLS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13553 0 : if (OutletHumRatLS > DesOutHumRat) {
13554 0 : CycRatio = 1.0;
13555 0 : DXCoils::SimDXCoilMultiSpeed(state, CompName, 1.0, 1.0, this->m_CoolingCoilIndex);
13556 0 : OutletHumRatHS = state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13557 0 : if (OutletHumRatHS < DesOutHumRat) {
13558 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13559 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13560 : SpeedRatio,
13561 : this->m_CoolingCoilIndex,
13562 : DesOutHumRat,
13563 : this->m_UnitarySysNum, // int UnitarySysNum,
13564 : 0.0, // Real64 CycRatio,
13565 : 0, // int SpeedNum,
13566 : HVAC::FanOp::Invalid, // int FanOpMode,
13567 0 : HVAC::CompressorOp::On);
13568 0 : };
13569 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13570 : } else {
13571 0 : SpeedRatio = 1.0;
13572 : }
13573 : } else {
13574 0 : SpeedRatio = 0.0;
13575 0 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13576 0 : return UnitarySys::DXCoilCyclingHumRatResidual(
13577 : state,
13578 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13579 : this->m_CoolingCoilIndex,
13580 : DesOutHumRat,
13581 : this->m_UnitarySysNum, // int UnitarySysNum,
13582 : 0.0, // Real64 CycRatio,
13583 : 0,
13584 : HVAC::FanOp::Invalid, // int FanOpMode,
13585 0 : HVAC::CompressorOp::On);
13586 0 : };
13587 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13588 : }
13589 : }
13590 2830 : } else if ((CoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) ||
13591 : (CoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
13592 968 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13593 : CompName,
13594 968 : this->m_CoolingCoilIndex,
13595 : this->m_FanOpMode,
13596 : HVAC::CompressorOp::On,
13597 : CycRatio,
13598 : this->m_CoolingSpeedNum,
13599 : SpeedRatio,
13600 : ReqOutput,
13601 : dummy,
13602 : OnOffAirFlowRatio);
13603 968 : OutletHumRatLS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13604 :
13605 968 : if (OutletHumRatLS > DesOutHumRat) {
13606 968 : CycRatio = 1.0;
13607 :
13608 968 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; ++speedNum) {
13609 968 : VariableSpeedCoils::SimVariableSpeedCoils(state,
13610 : CompName,
13611 968 : this->m_CoolingCoilIndex,
13612 : this->m_FanOpMode,
13613 : HVAC::CompressorOp::On,
13614 : 1.0,
13615 : speedNum,
13616 : 1.0,
13617 : ReqOutput,
13618 : dummy,
13619 : OnOffAirFlowRatio);
13620 968 : OutletHumRatHS = state.dataLoopNodes->Node(this->CoolCoilOutletNodeNum).HumRat;
13621 968 : if (OutletHumRatHS < DesOutHumRat || speedNum == this->m_NumOfSpeedCooling) {
13622 968 : this->m_CoolingSpeedNum = speedNum;
13623 968 : break;
13624 : }
13625 : }
13626 :
13627 968 : if (OutletHumRatHS < DesOutHumRat) {
13628 968 : if (this->m_CoolingSpeedNum == 1) {
13629 2904 : auto f = [&state, this, DesOutHumRat](Real64 const CycRatio) {
13630 2904 : return UnitarySys::DXCoilCyclingHumRatResidual(
13631 : state,
13632 : CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
13633 : this->m_CoolingCoilIndex,
13634 : DesOutHumRat,
13635 : this->m_UnitarySysNum, // int UnitarySysNum,
13636 : 1.0, // Real64 CycRatio,
13637 : this->m_CoolingSpeedNum,
13638 : this->m_FanOpMode, // int FanOpMode,
13639 2904 : HVAC::CompressorOp::On);
13640 968 : };
13641 968 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13642 : } else {
13643 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13644 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13645 : SpeedRatio,
13646 : this->m_CoolingCoilIndex,
13647 : DesOutHumRat,
13648 : this->m_UnitarySysNum, // int UnitarySysNum,
13649 : 1.0, // Real64 CycRatio,
13650 : this->m_CoolingSpeedNum,
13651 : this->m_FanOpMode, // int FanOpMode,
13652 0 : HVAC::CompressorOp::On);
13653 0 : };
13654 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
13655 : }
13656 : } else {
13657 0 : if (this->m_CoolingSpeedNum == 1) {
13658 0 : CycRatio = 1.0;
13659 : } else {
13660 0 : SpeedRatio = 1.0;
13661 : }
13662 : }
13663 : } else {
13664 0 : SpeedRatio = 0.0;
13665 0 : auto f = [&state, this, DesOutHumRat](Real64 const SpeedRatio) {
13666 0 : return UnitarySys::DXCoilVarSpeedHumRatResidual(state,
13667 : SpeedRatio,
13668 : this->m_CoolingCoilIndex,
13669 : DesOutHumRat,
13670 : this->m_UnitarySysNum, // int UnitarySysNum,
13671 : 0.0, // Real64 CycRatio,
13672 : 0, // int SpeedNum
13673 : HVAC::FanOp::Invalid, // int FanOpMode,
13674 0 : HVAC::CompressorOp::On);
13675 0 : };
13676 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
13677 : }
13678 2830 : } else if (CoilType_Num == HVAC::CoilDX_CoolingTwoStageWHumControl) {
13679 0 : auto f = [&state, this, DesOutHumRat, DehumidMode, fanOp](Real64 const PartLoadRatio) {
13680 0 : DXCoils::SimDXCoilMultiMode(
13681 0 : state, "", HVAC::CompressorOp::On, false, PartLoadRatio, DehumidMode, this->m_CoolingCoilIndex, fanOp);
13682 0 : return DesOutHumRat - state.dataDXCoils->DXCoilOutletHumRat(this->m_CoolingCoilIndex);
13683 0 : };
13684 0 : General::SolveRoot(state, Acc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13685 0 : this->m_CompPartLoadRatio = PartLoadFrac;
13686 1862 : } else if (CoilType_Num == HVAC::CoilDX_Cooling) { // CoilCoolingDX
13687 1858 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
13688 1858 : if (this->m_CoolingSpeedNum == 0) this->m_CoolingSpeedNum = 1;
13689 1858 : bool const singleMode = (this->m_SingleMode == 1);
13690 1858 : PartLoadFrac = 1.0;
13691 1858 : for (int speedNum = this->m_CoolingSpeedNum; speedNum <= this->m_NumOfSpeedCooling; speedNum++) {
13692 1858 : this->m_CoolingSpeedNum = speedNum;
13693 1858 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
13694 : state, coilMode, PartLoadFrac, this->m_CoolingSpeedNum, this->m_CoolingSpeedRatio, this->m_FanOpMode, singleMode);
13695 : // Cooling: break if outlet humrat is lower than DesOutHumRat or approaches DesOutHumRat to within HumRatAcc from above
13696 1858 : if ((state.dataLoopNodes->Node(OutletNode).HumRat - DesOutHumRat) < HumRatAcc) break;
13697 : }
13698 : // make sure outlet HumRat is below set point before calling SolveRoot
13699 : // Cooling: iterate only when outlet humrat is below DesOutHumRat by at least HumRatAcc
13700 1858 : if ((DesOutHumRat - state.dataLoopNodes->Node(OutletNode).HumRat) > HumRatAcc) {
13701 :
13702 8853 : auto f = [&state,
13703 : this, // 0
13704 : DesOutHumRat, // 1
13705 : fanOp // 3
13706 53118 : ](Real64 const PartLoadFrac) {
13707 8853 : int CoilIndex = this->m_CoolingCoilIndex;
13708 8853 : int CoolingSpeedNum = this->m_CoolingSpeedNum;
13709 8853 : Real64 CoolingSpeedRatio = 1.0;
13710 8853 : bool const singleMode = false;
13711 8853 : if (CoolingSpeedNum == 1) {
13712 8853 : state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].simulate(
13713 : state, HVAC::CoilMode::Normal, PartLoadFrac, CoolingSpeedNum, CoolingSpeedRatio, fanOp, singleMode);
13714 : } else {
13715 0 : state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].simulate(
13716 : state, HVAC::CoilMode::Normal, CoolingSpeedRatio, CoolingSpeedNum, PartLoadFrac, fanOp, singleMode);
13717 : }
13718 : Real64 outletCondition =
13719 8853 : state.dataLoopNodes->Node(state.dataCoilCooingDX->coilCoolingDXs[CoilIndex].evapOutletNodeIndex).HumRat;
13720 8853 : return DesOutHumRat - outletCondition;
13721 1858 : };
13722 :
13723 1858 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13724 : }
13725 1858 : if (this->m_CoolingSpeedNum == 1) {
13726 1858 : this->m_CompPartLoadRatio = PartLoadFrac;
13727 1858 : SpeedRatio = 0.0;
13728 : } else {
13729 0 : SpeedRatio = PartLoadFrac;
13730 0 : PartLoadFrac = 1.0;
13731 0 : this->m_CompPartLoadRatio = 1.0;
13732 : }
13733 :
13734 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWater) || (CoilType_Num == HVAC::Coil_CoolingWaterDetailed)) { // COIL:COOLING:WATER
13735 :
13736 224 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat](Real64 const PartLoadRatio) {
13737 32 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13738 32 : Real64 mdot = min(state.dataLoopNodes->Node(thisSys.CoolCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
13739 32 : thisSys.MaxCoolCoilFluidFlow * PartLoadRatio);
13740 32 : state.dataLoopNodes->Node(thisSys.CoolCoilFluidInletNode).MassFlowRate = mdot;
13741 64 : WaterCoils::SimulateWaterCoilComponents(
13742 32 : state, thisSys.m_CoolingCoilName, FirstHVACIteration, thisSys.m_CoolingCoilIndex, _, _, PartLoadRatio);
13743 32 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
13744 4 : };
13745 :
13746 4 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13747 :
13748 4 : } else if ((CoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) || (CoilType_Num == HVAC::Coil_CoolingWaterToAirHP)) {
13749 :
13750 0 : auto f = [&state, this, FirstHVACIteration, DesOutHumRat, ReqOutput](Real64 const PartLoadRatio) {
13751 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13752 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
13753 0 : Real64 dummy = 0.0;
13754 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
13755 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
13756 : blankString,
13757 0 : thisSys.m_CoolingCoilIndex,
13758 : ReqOutput,
13759 : dummy,
13760 : thisSys.m_FanOpMode,
13761 : HVAC::CompressorOp::Off,
13762 : PartLoadRatio,
13763 : FirstHVACIteration);
13764 : } else {
13765 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
13766 : blankString,
13767 0 : thisSys.m_CoolingCoilIndex,
13768 : thisSys.MaxCoolAirMassFlow,
13769 : thisSys.m_FanOpMode,
13770 : FirstHVACIteration,
13771 0 : thisSys.m_InitHeatPump,
13772 : ReqOutput,
13773 : dummy,
13774 : HVAC::CompressorOp::Off,
13775 : PartLoadRatio);
13776 : }
13777 0 : return DesOutHumRat - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
13778 0 : };
13779 0 : General::SolveRoot(state, HumRatAcc, MaxIte, SolFlaLat, PartLoadFrac, f, 0.0, 1.0);
13780 :
13781 0 : } else if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling) {
13782 :
13783 0 : if (CoilType_Num == HVAC::CoilDX_PackagedThermalStorageCooling &&
13784 0 : (this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::Off &&
13785 0 : this->m_TESOpMode != PackagedThermalStorageCoil::PTSCOperatingMode::ChargeOnly)) {
13786 0 : auto f = [&state, this, DesOutHumRat](Real64 const PartLoadRatio) {
13787 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[this->m_UnitarySysNum];
13788 0 : PackagedThermalStorageCoil::SimTESCoil(state,
13789 : thisSys.m_CoolingCoilName,
13790 0 : thisSys.m_CoolingCoilIndex,
13791 : thisSys.m_FanOpMode,
13792 0 : thisSys.m_TESOpMode,
13793 : PartLoadRatio);
13794 0 : return state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat - DesOutHumRat;
13795 0 : };
13796 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
13797 : }
13798 :
13799 : } else {
13800 : }
13801 : }
13802 : }
13803 : }
13804 3601299 : if (SolFla == -1) {
13805 4553 : if (!state.dataGlobal->WarmupFlag) {
13806 412 : if (this->warnIndex.m_SensPLRIter < 1) {
13807 1 : ++this->warnIndex.m_SensPLRIter;
13808 2 : ShowWarningError(state,
13809 2 : format("{} - Iteration limit exceeded calculating part-load ratio for unit = {}", this->UnitType, this->Name));
13810 1 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13811 1 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13812 1 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13813 : } else {
13814 1233 : ShowRecurringWarningErrorAtEnd(
13815 : state,
13816 822 : this->UnitType + " \"" + this->Name +
13817 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. Sensible PLR statistics follow.",
13818 411 : this->warnIndex.m_SensPLRIterIndex,
13819 : PartLoadFrac,
13820 : PartLoadFrac);
13821 : }
13822 : }
13823 3596746 : } else if (SolFla == -2) {
13824 0 : PartLoadFrac = ReqOutput / FullOutput;
13825 0 : if (!state.dataGlobal->WarmupFlag) {
13826 0 : if (this->warnIndex.m_SensPLRFail < 1) {
13827 0 : ++this->warnIndex.m_SensPLRFail;
13828 0 : ShowWarningError(state,
13829 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
13830 0 : this->UnitType,
13831 0 : this->Name));
13832 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13833 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13834 : } else {
13835 0 : ShowRecurringWarningErrorAtEnd(
13836 : state,
13837 0 : this->UnitType + " \"" + this->Name +
13838 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
13839 0 : this->warnIndex.m_SensPLRFailIndex,
13840 : PartLoadFrac,
13841 : PartLoadFrac);
13842 : }
13843 : }
13844 : }
13845 :
13846 3601299 : if (SolFlaLat == -1 && SolFla != -1) {
13847 0 : if (!state.dataGlobal->WarmupFlag) {
13848 0 : if (this->warnIndex.m_LatPLRIter < 1) {
13849 0 : ++this->warnIndex.m_LatPLRIter;
13850 0 : ShowWarningError(
13851 0 : state, format("{} - Iteration limit exceeded calculating latent part-load ratio for unit = {}", this->UnitType, this->Name));
13852 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
13853 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
13854 0 : ShowContinueErrorTimeStamp(state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
13855 : }
13856 0 : ShowRecurringWarningErrorAtEnd(
13857 : state,
13858 0 : this->UnitType + " \"" + this->Name +
13859 : "\" - Iteration limit exceeded calculating latent part-load ratio error continues. Latent PLR statistics follow.",
13860 0 : this->warnIndex.m_LatPLRIterIndex,
13861 : PartLoadFrac,
13862 : PartLoadFrac);
13863 : }
13864 3601299 : } else if (SolFlaLat == -2 && SolFla != -2) {
13865 : // RegulaFalsi returns PLR = minPLR when a solution cannot be found, recalculate PartLoadFrac.
13866 0 : if (NoLoadHumRatOut - FullLoadHumRatOut != 0.0) {
13867 0 : PartLoadFrac = (NoLoadHumRatOut - DesOutHumRat) / (NoLoadHumRatOut - FullLoadHumRatOut);
13868 : } else {
13869 0 : PartLoadFrac = 1.0;
13870 : }
13871 0 : if (!state.dataGlobal->WarmupFlag) {
13872 0 : if (this->warnIndex.m_LatPLRFail < 1) {
13873 0 : ++this->warnIndex.m_LatPLRFail;
13874 0 : ShowWarningError(state,
13875 0 : format("{} - latent part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
13876 0 : this->UnitType,
13877 0 : this->Name));
13878 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
13879 0 : ShowContinueErrorTimeStamp(state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
13880 : }
13881 0 : ShowRecurringWarningErrorAtEnd(state,
13882 0 : this->UnitType + " \"" + this->Name +
13883 : "\" - latent part-load ratio calculation failed error continues. Latent PLR statistics follow.",
13884 0 : this->warnIndex.m_LatPLRFailIndex,
13885 : PartLoadFrac,
13886 : PartLoadFrac);
13887 : }
13888 : }
13889 : // Set the final results
13890 :
13891 3601299 : if (PartLoadFrac > 1.0) {
13892 0 : PartLoadFrac = 1.0;
13893 3601299 : } else if (PartLoadFrac < 0.0) {
13894 0 : PartLoadFrac = 0.0;
13895 : }
13896 :
13897 3601299 : this->m_CoolingPartLoadFrac = PartLoadFrac;
13898 3601299 : this->m_CoolingSpeedRatio = SpeedRatio;
13899 3601299 : this->m_CoolingCycRatio = CycRatio;
13900 3601299 : this->m_DehumidificationMode = DehumidMode;
13901 :
13902 3723831 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
13903 122532 : this->m_sysType != SysType::PackagedWSHP) {
13904 122532 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
13905 122532 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
13906 : }
13907 :
13908 3601299 : if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWater || this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) {
13909 76032 : mdot = PartLoadFrac * this->MaxCoolCoilFluidFlow;
13910 76032 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CoolCoilFluidInletNode, this->CoolCoilFluidOutletNodeNum, this->CoolCoilPlantLoc);
13911 : }
13912 3601299 : } // namespace UnitarySystems
13913 :
13914 104850 : void UnitarySys::controlHeatingSystemToSP(EnergyPlusData &state,
13915 : int const AirLoopNum, // index to air loop
13916 : bool const FirstHVACIteration, // First HVAC iteration flag
13917 : HVAC::CompressorOp &compressorOp, // compressor on/off control
13918 : Real64 &HeatCoilLoad // load met by heating coil
13919 : )
13920 : {
13921 : // SUBROUTINE INFORMATION:
13922 : // AUTHOR Richard Raustad, FSEC
13923 : // DATE WRITTEN February 2013
13924 :
13925 : // PURPOSE OF THIS SUBROUTINE:
13926 : // Simulate the coil object at the required PLR.
13927 :
13928 : // METHODOLOGY EMPLOYED:
13929 : // Calculate operating PLR and adjust speed when using multispeed coils.
13930 :
13931 : // SUBROUTINE PARAMETER DEFINITIONS:
13932 104850 : int constexpr MaxIte(500); // Maximum number of iterations for solver
13933 104850 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
13934 104850 : bool constexpr SuppHeatingCoilFlag(false);
13935 :
13936 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
13937 104850 : Real64 FullOutput = 0; // Sensible capacity (outlet - inlet) when the compressor is on
13938 104850 : Real64 ReqOutput = 0; // Sensible capacity (outlet - inlet) required to meet load or set point temperature
13939 :
13940 104850 : Real64 OutdoorDryBulb = 0.0; // local variable for OutDryBulbTemp
13941 104850 : Real64 OutdoorHumRat = 0.0; // local variable for OutHumRat
13942 104850 : Real64 OutdoorPressure = 0.0; // local variable for OutBaroPress
13943 104850 : Real64 OutdoorWetBulb = 0.0; // local variable for OutWetBulbTemp
13944 104850 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
13945 104850 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
13946 :
13947 : // Set local variables
13948 : // Retrieve the load on the controlled zone
13949 104850 : int InletNode = this->HeatCoilInletNodeNum;
13950 104850 : int OutletNode = this->HeatCoilOutletNodeNum;
13951 104850 : std::string CompName = this->m_HeatingCoilName;
13952 104850 : int CompIndex = this->m_HeatingCoilIndex;
13953 104850 : HVAC::FanOp fanOp = this->m_FanOpMode;
13954 104850 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
13955 :
13956 104850 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
13957 104850 : Real64 LoopDXCoilMaxRTFSave = 0.0;
13958 104850 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
13959 0 : this->m_sysType != SysType::PackagedWSHP) {
13960 0 : LoopHeatingCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF;
13961 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
13962 0 : LoopDXCoilMaxRTFSave = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF;
13963 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF = 0.0;
13964 : }
13965 :
13966 104850 : Real64 PartLoadFrac = 0.0;
13967 104850 : Real64 SpeedRatio = 0.0;
13968 104850 : Real64 CycRatio = 0.0;
13969 104850 : Real64 dummy = 0.0;
13970 104850 : int SolFla = 0;
13971 104850 : Real64 SensLoad = 0.0;
13972 104850 : Real64 OutletTemp = 0.0;
13973 :
13974 104850 : if (this->m_CondenserNodeNum != 0) {
13975 68625 : OutdoorDryBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Temp;
13976 68625 : if (this->m_CondenserType == DataHeatBalance::RefrigCondenserType::Water) {
13977 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13978 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13979 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
13980 : } else {
13981 68625 : OutdoorPressure = state.dataLoopNodes->Node(this->m_CondenserNodeNum).Press;
13982 : // IF node is not connected to anything, pressure = default, use weather data
13983 68625 : if (OutdoorPressure == state.dataLoopNodes->DefaultNodeValues.Press) {
13984 0 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13985 0 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13986 0 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13987 0 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
13988 : } else {
13989 68625 : OutdoorHumRat = state.dataLoopNodes->Node(this->m_CondenserNodeNum).HumRat;
13990 : // this should use Node%WetBulbTemp or a PSYC function, not OAWB
13991 68625 : OutdoorWetBulb = state.dataLoopNodes->Node(this->m_CondenserNodeNum).OutAirWetBulb;
13992 : }
13993 : }
13994 : } else {
13995 36225 : OutdoorDryBulb = state.dataEnvrn->OutDryBulbTemp;
13996 36225 : OutdoorHumRat = state.dataEnvrn->OutHumRat;
13997 36225 : OutdoorPressure = state.dataEnvrn->OutBaroPress;
13998 36225 : OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp;
13999 : }
14000 :
14001 : // IF there is a fault of coil SAT Sensor
14002 104850 : if (this->m_FaultyCoilSATFlag) {
14003 : // calculate the sensor offset using fault information
14004 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14005 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14006 : // update the DesOutTemp
14007 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14008 : }
14009 :
14010 : // IF DXHeatingSystem is scheduled on and there is flow
14011 104850 : if (ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0 &&
14012 209676 : ScheduleManager::GetCurrentScheduleValue(state, this->m_HeatingCoilAvailSchPtr) > 0.0 &&
14013 104826 : state.dataLoopNodes->Node(InletNode).MassFlowRate > HVAC::SmallAirVolFlow) {
14014 :
14015 100748 : bool SensibleLoad = false;
14016 : // Determine if there is a sensible load on this system
14017 100748 : if (DesOutTemp - state.dataLoopNodes->Node(InletNode).Temp > HVAC::TempControlTol) SensibleLoad = true;
14018 : // if a heat pump and other coil is on, disable this coil
14019 100748 : if (this->m_HeatPump && this->m_CoolingPartLoadFrac > 0.0) SensibleLoad = false;
14020 :
14021 : // disable compressor if OAT is below minimum outdoor temperature
14022 100748 : if (OutdoorDryBulb < this->m_MinOATCompressorHeating) {
14023 1025 : SensibleLoad = false;
14024 : }
14025 :
14026 : // IF DXHeatingSystem runs with a heating load then set PartLoadFrac on Heating System
14027 100748 : if (SensibleLoad) {
14028 :
14029 28886 : ReqOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14030 86658 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp,
14031 28886 : state.dataLoopNodes->Node(InletNode).HumRat,
14032 28886 : state.dataLoopNodes->Node(InletNode).Temp,
14033 28886 : state.dataLoopNodes->Node(InletNode).HumRat);
14034 28886 : ReqOutput = max(0.0, ReqOutput);
14035 :
14036 : // Get no load result
14037 28886 : PartLoadFrac = 0.0;
14038 28886 : compressorOp = HVAC::CompressorOp::Off;
14039 :
14040 28886 : switch (this->m_HeatingCoilType_Num) {
14041 0 : case HVAC::CoilDX_HeatingEmpirical: {
14042 0 : DXCoils::SimDXCoil(state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, CompIndex, fanOp, PartLoadFrac);
14043 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14044 0 : } break;
14045 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
14046 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14047 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14048 0 : UserDefinedComponents::SimCoilUserDefined(state, CompName, CompIndex, AirLoopNum, HeatingActive, CoolingActive);
14049 0 : if (HeatingActive) PartLoadFrac = 1.0;
14050 :
14051 0 : } break;
14052 2247 : case HVAC::CoilDX_MultiSpeedHeating:
14053 : case HVAC::Coil_HeatingElectric_MultiStage:
14054 : case HVAC::Coil_HeatingGas_MultiStage: {
14055 2247 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14056 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14057 0 : this->m_SpeedNum = this->m_HeatingSpeedNum;
14058 0 : bool useMaxedSpeed = false;
14059 0 : if (this->m_SpeedNum > this->m_NumOfSpeedHeating) {
14060 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14061 0 : this->m_SpeedNum = this->m_NumOfSpeedHeating;
14062 0 : this->m_CoilSpeedErrIdx++;
14063 0 : useMaxedSpeed = true;
14064 0 : ShowRecurringWarningErrorAtEnd(
14065 : state,
14066 0 : "Wrong coil speed EMS override value, for unit=\"" + this->m_HeatingCoilName +
14067 : "\". Exceeding maximum coil speed level. Speed level is set to the maximum coil speed level allowed.",
14068 0 : this->m_CoilSpeedErrIdx,
14069 0 : this->m_EMSOverrideCoilSpeedNumValue,
14070 0 : this->m_EMSOverrideCoilSpeedNumValue,
14071 : _,
14072 : "",
14073 : "");
14074 : }
14075 0 : if (this->m_HeatingSpeedNum == 1) {
14076 0 : this->m_HeatingSpeedRatio = 0.0;
14077 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14078 0 : this->m_HeatingCycRatio = CycRatio;
14079 0 : if (useMaxedSpeed || CycRatio == 0) {
14080 0 : this->m_HeatingCycRatio = 1;
14081 : } else {
14082 0 : this->m_HeatingCycRatio = CycRatio;
14083 : }
14084 : } else {
14085 0 : this->m_HeatingCycRatio = 1.0;
14086 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14087 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14088 0 : if (useMaxedSpeed || SpeedRatio == 0) {
14089 0 : this->m_HeatingSpeedRatio = 1;
14090 : } else {
14091 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14092 : }
14093 : }
14094 : }
14095 2247 : bool LatentLoad = false;
14096 2247 : this->simMultiSpeedCoils(
14097 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, this->m_SpeedNum);
14098 2247 : } break;
14099 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14100 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14101 0 : int SpeedNum = 0;
14102 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14103 0 : VariableSpeedCoils::SimVariableSpeedCoils(
14104 0 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14105 0 : } break;
14106 26639 : case HVAC::Coil_HeatingGasOrOtherFuel:
14107 : case HVAC::Coil_HeatingElectric:
14108 : case HVAC::Coil_HeatingDesuperheater: {
14109 26639 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, PartLoadFrac, CompIndex, _, _, fanOp);
14110 26639 : } break;
14111 0 : case HVAC::Coil_HeatingWater: {
14112 0 : WaterCoils::SimulateWaterCoilComponents(
14113 0 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14114 0 : } break;
14115 0 : case HVAC::Coil_HeatingSteam: {
14116 0 : SteamCoils::SimulateSteamCoilComponents(state,
14117 : CompName,
14118 : FirstHVACIteration,
14119 0 : this->m_HeatingCoilIndex,
14120 0 : 1.0,
14121 : _,
14122 0 : this->m_FanOpMode,
14123 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14124 0 : } break;
14125 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14126 0 : if (FirstHVACIteration) this->m_CompPartLoadRatio = 1;
14127 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14128 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::Off, PartLoadFrac, FirstHVACIteration);
14129 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14130 0 : this->m_HeatingCoilSensDemand = 0.0;
14131 0 : } break;
14132 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14133 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14134 : blankString,
14135 : CompIndex,
14136 : this->MaxHeatAirMassFlow,
14137 : fanOp,
14138 : FirstHVACIteration,
14139 0 : this->m_InitHeatPump,
14140 : ReqOutput,
14141 : dummy,
14142 : HVAC::CompressorOp::Off,
14143 : PartLoadFrac);
14144 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14145 0 : } break;
14146 0 : default:
14147 0 : break;
14148 : }
14149 :
14150 : // IF outlet temp at no load is within ACC of set point, do not run the coil
14151 :
14152 57772 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14153 28886 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14154 : // do nothing, coil is at the set point.
14155 28886 : } else if ((state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) > Acc) { // IF outlet temp is above set point turn off coil
14156 0 : PartLoadFrac = 0.0;
14157 : } else { // ELSE get full load result
14158 :
14159 : // Get full load result
14160 28886 : PartLoadFrac = 1.0;
14161 28886 : compressorOp = HVAC::CompressorOp::On;
14162 :
14163 28886 : switch (this->m_HeatingCoilType_Num) {
14164 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14165 0 : DXCoils::SimDXCoil(
14166 0 : state, CompName, HVAC::CompressorOp::On, FirstHVACIteration, this->m_HeatingCoilIndex, fanOp, PartLoadFrac);
14167 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14168 0 : } break;
14169 0 : case HVAC::Coil_UserDefined: {
14170 : // should never get here, coil cannot be controlled and has already been simulated
14171 0 : } break;
14172 2247 : case HVAC::CoilDX_MultiSpeedHeating: {
14173 2247 : CycRatio = 1.0;
14174 2247 : SpeedRatio = 0.0;
14175 2247 : int SpeedNum = 0;
14176 2247 : bool LatentLoad = false;
14177 2247 : if (this->m_EMSOverrideCoilSpeedNumOn) {
14178 0 : this->m_HeatingSpeedNum = ceil(this->m_EMSOverrideCoilSpeedNumValue);
14179 0 : SpeedNum = this->m_HeatingSpeedNum;
14180 0 : if (this->m_HeatingSpeedNum == 1) {
14181 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14182 0 : CycRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14183 0 : this->m_HeatingCycRatio = CycRatio;
14184 0 : if (CycRatio == 0) {
14185 0 : this->m_HeatingCycRatio = 1;
14186 : } else {
14187 0 : this->m_HeatingCycRatio = CycRatio;
14188 : }
14189 : } else {
14190 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14191 0 : SpeedRatio = this->m_EMSOverrideCoilSpeedNumValue - floor(this->m_EMSOverrideCoilSpeedNumValue);
14192 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14193 0 : if (SpeedRatio == 0) {
14194 0 : this->m_HeatingSpeedRatio = 1;
14195 : } else {
14196 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14197 : }
14198 : }
14199 0 : if (SpeedNum > this->m_NumOfSpeedHeating) {
14200 0 : this->m_HeatingSpeedNum = this->m_NumOfSpeedHeating;
14201 0 : SpeedNum = this->m_NumOfSpeedHeating;
14202 0 : this->m_HeatingCycRatio = CycRatio = 1.0;
14203 0 : if (this->m_HeatingSpeedNum == 1) {
14204 0 : this->m_HeatingSpeedRatio = SpeedRatio = 0.0;
14205 : } else {
14206 0 : this->m_HeatingSpeedRatio = SpeedRatio = 1.0;
14207 : }
14208 : }
14209 0 : this->simMultiSpeedCoils(
14210 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14211 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14212 : } else {
14213 6737 : for (SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14214 4492 : if (SpeedNum > 1) {
14215 2245 : CycRatio = 0.0;
14216 2245 : SpeedRatio = 1.0;
14217 : }
14218 4492 : this->m_HeatingSpeedNum = SpeedNum;
14219 4492 : this->simMultiSpeedCoils(state,
14220 : AirLoopNum,
14221 : FirstHVACIteration,
14222 : compressorOp,
14223 : SensibleLoad,
14224 : LatentLoad,
14225 : PartLoadFrac,
14226 : HeatingCoil,
14227 : SpeedNum);
14228 4492 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14229 4492 : if (OutletTemp > DesOutTemp && SensibleLoad) break;
14230 : }
14231 : }
14232 2247 : } break;
14233 0 : case HVAC::Coil_HeatingElectric_MultiStage:
14234 : case HVAC::Coil_HeatingGas_MultiStage: {
14235 0 : bool LatentLoad = false;
14236 0 : CycRatio = 1.0;
14237 0 : SpeedRatio = 1.0;
14238 0 : SensLoad = 1.0; // turns on coil
14239 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14240 0 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14241 0 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14242 0 : this->m_HeatingSpeedNum = SpeedNum;
14243 0 : this->simMultiSpeedCoils(
14244 : state, AirLoopNum, FirstHVACIteration, compressorOp, SensibleLoad, LatentLoad, PartLoadFrac, HeatingCoil, SpeedNum);
14245 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14246 0 : SpeedRatio = double(SpeedNum) - 1.0;
14247 0 : if (OutletTemp > DesOutTemp && SensibleLoad) break;
14248 : }
14249 0 : } break;
14250 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14251 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
14252 0 : CycRatio = 1.0;
14253 0 : SpeedRatio = 1.0;
14254 0 : SensLoad = 1.0; // turns on coil
14255 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14256 0 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14257 0 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedHeating; ++SpeedNum) {
14258 0 : this->m_HeatingSpeedNum = SpeedNum;
14259 0 : VariableSpeedCoils::SimVariableSpeedCoils(
14260 0 : state, "", this->m_HeatingCoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy);
14261 0 : OutletTemp = state.dataLoopNodes->Node(OutletNode).Temp;
14262 0 : if (OutletTemp > DesOutTemp && SensibleLoad) break;
14263 : }
14264 0 : } break;
14265 26639 : case HVAC::Coil_HeatingGasOrOtherFuel:
14266 : case HVAC::Coil_HeatingElectric: {
14267 53278 : HeatingCoils::SimulateHeatingCoilComponents(
14268 26639 : state, CompName, FirstHVACIteration, this->m_DesignHeatingCapacity, CompIndex, _, _, fanOp);
14269 26639 : } break;
14270 0 : case HVAC::Coil_HeatingDesuperheater: {
14271 0 : HeatingCoils::SimulateHeatingCoilComponents(state, CompName, FirstHVACIteration, ReqOutput, CompIndex, _, _, fanOp);
14272 0 : } break;
14273 0 : case HVAC::Coil_HeatingWater: {
14274 0 : mdot = this->MaxHeatCoilFluidFlow;
14275 0 : PlantUtilities::SetComponentFlowRate(
14276 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14277 :
14278 0 : WaterCoils::SimulateWaterCoilComponents(
14279 0 : state, CompName, FirstHVACIteration, this->m_HeatingCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14280 0 : } break;
14281 0 : case HVAC::Coil_HeatingSteam: {
14282 0 : mdot = this->MaxHeatCoilFluidFlow;
14283 0 : PlantUtilities::SetComponentFlowRate(
14284 0 : state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14285 :
14286 0 : SteamCoils::SimulateSteamCoilComponents(state,
14287 : CompName,
14288 : FirstHVACIteration,
14289 0 : this->m_HeatingCoilIndex,
14290 0 : 1.0,
14291 : _,
14292 0 : this->m_FanOpMode,
14293 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14294 0 : } break;
14295 0 : case HVAC::Coil_HeatingWaterToAirHPSimple: {
14296 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(
14297 : state, blankString, CompIndex, ReqOutput, dummy, fanOp, HVAC::CompressorOp::On, PartLoadFrac, FirstHVACIteration);
14298 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14299 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14300 0 : } break;
14301 0 : case HVAC::Coil_HeatingWaterToAirHP: {
14302 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14303 : blankString,
14304 : CompIndex,
14305 : this->MaxHeatAirMassFlow,
14306 : fanOp,
14307 : FirstHVACIteration,
14308 0 : this->m_InitHeatPump,
14309 : ReqOutput,
14310 : dummy,
14311 : HVAC::CompressorOp::Off,
14312 : PartLoadFrac);
14313 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14314 0 : } break;
14315 0 : default:
14316 0 : break;
14317 : }
14318 :
14319 28886 : FullOutput = state.dataLoopNodes->Node(InletNode).MassFlowRate *
14320 28886 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
14321 28886 : state.dataLoopNodes->Node(OutletNode).HumRat,
14322 28886 : state.dataLoopNodes->Node(InletNode).Temp,
14323 28886 : state.dataLoopNodes->Node(InletNode).HumRat);
14324 : // If the outlet temp is within ACC of set point,
14325 57772 : if (std::abs(state.dataLoopNodes->Node(OutletNode).Temp - DesOutTemp) < Acc ||
14326 28886 : this->m_HeatingCoilType_Num == HVAC::Coil_UserDefined) {
14327 : // do nothing, coil is at set point
14328 28886 : } else if (state.dataLoopNodes->Node(OutletNode).Temp < (DesOutTemp - Acc)) { // IF outlet temp is below set point coil must be on
14329 7719 : PartLoadFrac = 1.0;
14330 : } else { // ELSE find the PLR to meet the set point
14331 :
14332 21167 : switch (this->m_HeatingCoilType_Num) {
14333 0 : case HVAC::CoilDX_HeatingEmpirical: { // Coil:Heating:DX:SingleSpeed
14334 0 : auto f = [&state, CompIndex, DesOutTemp](Real64 const PartLoadFrac) {
14335 0 : DXCoils::CalcDXHeatingCoil(state, CompIndex, PartLoadFrac, HVAC::FanOp::Continuous, 1.0);
14336 0 : return DesOutTemp - state.dataDXCoils->DXCoilOutletTemp(CompIndex);
14337 0 : };
14338 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14339 0 : this->m_CompPartLoadRatio = PartLoadFrac;
14340 0 : } break;
14341 2 : case HVAC::CoilDX_MultiSpeedHeating:
14342 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
14343 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
14344 : case HVAC::Coil_HeatingElectric_MultiStage:
14345 : case HVAC::Coil_HeatingGas_MultiStage: {
14346 2 : if (this->m_HeatingSpeedNum > 1.0) {
14347 0 : auto f = [&state, this, DesOutTemp, CycRatio, fanOp](Real64 const SpeedRatio) {
14348 0 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14349 : SpeedRatio,
14350 : this->m_HeatingCoilIndex,
14351 : DesOutTemp,
14352 : this->m_UnitarySysNum,
14353 : CycRatio,
14354 : this->m_HeatingSpeedNum,
14355 : fanOp,
14356 : HVAC::CompressorOp::On,
14357 0 : false);
14358 0 : };
14359 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14360 0 : this->m_HeatingCycRatio = CycRatio;
14361 0 : this->m_HeatingSpeedRatio = SpeedRatio;
14362 0 : this->m_HeatingPartLoadFrac = SpeedRatio;
14363 0 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14364 0 : PartLoadFrac = SpeedRatio;
14365 : } else {
14366 2 : SpeedRatio = 0.0;
14367 2 : this->m_HeatingSpeedRatio = SpeedRatio;
14368 6 : auto f = [&state, this, DesOutTemp, SpeedRatio, fanOp](Real64 const CycRatio) {
14369 6 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14370 : CycRatio,
14371 : this->m_HeatingCoilIndex,
14372 : DesOutTemp,
14373 : this->m_UnitarySysNum,
14374 : SpeedRatio,
14375 : this->m_HeatingSpeedNum,
14376 : fanOp,
14377 : HVAC::CompressorOp::On,
14378 6 : false);
14379 2 : };
14380 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14381 2 : this->m_HeatingCycRatio = CycRatio;
14382 2 : this->m_HeatingPartLoadFrac = CycRatio;
14383 2 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
14384 2 : PartLoadFrac = CycRatio;
14385 : }
14386 2 : } break;
14387 21165 : case HVAC::Coil_HeatingGasOrOtherFuel: {
14388 63495 : HeatingCoils::SimulateHeatingCoilComponents(
14389 42330 : state, this->m_HeatingCoilName, FirstHVACIteration, ReqOutput, CompIndex, _, true, fanOp, PartLoadFrac);
14390 21165 : PartLoadFrac = ReqOutput / FullOutput;
14391 21165 : HeatCoilLoad = ReqOutput;
14392 21165 : } break;
14393 0 : case HVAC::Coil_HeatingElectric:
14394 : case HVAC::Coil_HeatingDesuperheater: {
14395 0 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14396 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, fanOp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14397 0 : return this->gasElecHeatingCoilResidual(state,
14398 : PartLoadFrac,
14399 : this->m_UnitarySysNum,
14400 : FirstHVACIteration,
14401 : DesOutTemp,
14402 : tmpSuppHeatingCoilFlag,
14403 : fanOp,
14404 0 : this->m_DesignHeatingCapacity);
14405 0 : };
14406 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14407 0 : } break;
14408 0 : case HVAC::Coil_HeatingWater: {
14409 :
14410 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14411 : maxPartLoadFrac =
14412 0 : min(1.0,
14413 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14414 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14415 :
14416 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const maxPartLoadFrac) {
14417 : Real64 OutletAirTemp; // Outlet air temperature [C]
14418 :
14419 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14420 0 : this->MaxHeatCoilFluidFlow * maxPartLoadFrac);
14421 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14422 0 : WaterCoils::SimulateWaterCoilComponents(state,
14423 : this->m_HeatingCoilName,
14424 : FirstHVACIteration,
14425 0 : this->m_HeatingCoilIndex,
14426 0 : 0.0, // QActual
14427 0 : this->m_FanOpMode,
14428 : maxPartLoadFrac);
14429 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14430 0 : return DesOutTemp - OutletAirTemp;
14431 0 : };
14432 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14433 0 : } break;
14434 0 : case HVAC::Coil_HeatingSteam: {
14435 :
14436 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14437 : maxPartLoadFrac =
14438 0 : min(1.0,
14439 0 : ((mdot / this->MaxHeatCoilFluidFlow) +
14440 : 0.001)); // plant can limit flow and RegulaFalsi could hit max iteration limit (leave a little slop, 0.001)
14441 :
14442 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14443 : Real64 OutletAirTemp; // Outlet air temperature [C]
14444 : Real64 mdot;
14445 :
14446 0 : mdot = min(state.dataLoopNodes->Node(this->HeatCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14447 0 : this->MaxHeatCoilFluidFlow * PartLoadFrac);
14448 0 : state.dataLoopNodes->Node(this->HeatCoilFluidInletNode).MassFlowRate = mdot;
14449 0 : SteamCoils::SimulateSteamCoilComponents(state,
14450 : this->m_HeatingCoilName,
14451 : FirstHVACIteration,
14452 0 : this->m_HeatingCoilIndex,
14453 0 : 1.0,
14454 : _,
14455 0 : this->m_FanOpMode,
14456 : PartLoadFrac);
14457 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp; // RR this should be supp coil
14458 0 : return DesOutTemp - OutletAirTemp;
14459 0 : };
14460 :
14461 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14462 0 : } break;
14463 0 : case HVAC::Coil_HeatingWaterToAirHPSimple:
14464 : case HVAC::Coil_HeatingWaterToAirHP: {
14465 0 : this->m_HeatingCoilSensDemand = ReqOutput;
14466 :
14467 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, ReqOutput](Real64 const PartLoadRatio) {
14468 : Real64 OutletAirTemp; // outlet air humidity ratio [kg/kg]
14469 : Real64 dummy;
14470 :
14471 0 : this->m_CompPartLoadRatio = PartLoadRatio;
14472 :
14473 0 : dummy = 0.0;
14474 0 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
14475 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
14476 : blankString,
14477 0 : this->m_HeatingCoilIndex,
14478 : ReqOutput,
14479 : dummy,
14480 : this->m_FanOpMode,
14481 : HVAC::CompressorOp::On,
14482 : PartLoadRatio,
14483 : FirstHVACIteration);
14484 : } else {
14485 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
14486 : blankString,
14487 0 : this->m_HeatingCoilIndex,
14488 : this->MaxHeatAirMassFlow,
14489 : this->m_FanOpMode,
14490 : FirstHVACIteration,
14491 0 : this->m_InitHeatPump,
14492 : ReqOutput,
14493 : dummy,
14494 : HVAC::CompressorOp::Off,
14495 : PartLoadRatio);
14496 : }
14497 :
14498 0 : OutletAirTemp = state.dataLoopNodes->Node(this->HeatCoilOutletNodeNum).Temp;
14499 0 : return DesOutTemp - OutletAirTemp;
14500 0 : };
14501 :
14502 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14503 0 : } break;
14504 0 : case HVAC::Coil_UserDefined: {
14505 : // should never get here, user defined coil cannot be controlled and has already been simulated
14506 0 : } break;
14507 0 : default: {
14508 0 : ShowMessage(state, format(" For :{}=\"{}\"", this->UnitType, this->Name));
14509 0 : ShowFatalError(
14510 : state,
14511 0 : format("ControlHeatingSystemToSP: Invalid heating coil type = {}", HVAC::cAllCoilTypes(this->m_HeatingCoilType_Num)));
14512 0 : } break;
14513 : }
14514 : }
14515 : }
14516 : }
14517 : }
14518 :
14519 104850 : if (PartLoadFrac > 1.0) {
14520 0 : PartLoadFrac = 1.0;
14521 104850 : } else if (PartLoadFrac < 0.0) {
14522 0 : PartLoadFrac = 0.0;
14523 : }
14524 :
14525 104850 : if (SolFla < 0) {
14526 0 : if (SolFla == -1) {
14527 0 : if (!state.dataGlobal->WarmupFlag) {
14528 0 : if (this->warnIndex.m_HeatCoilSensPLRIter < 1) {
14529 0 : ++this->warnIndex.m_HeatCoilSensPLRIter;
14530 0 : ShowWarningError(
14531 : state,
14532 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}", this->UnitType, this->Name));
14533 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14534 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14535 0 : ShowContinueErrorTimeStamp(state,
14536 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14537 : } else {
14538 0 : ShowRecurringWarningErrorAtEnd(state,
14539 0 : this->UnitType + " \"" + this->Name +
14540 : "\" - Iteration limit exceeded calculating sensible part-load ratio error continues. "
14541 : "Sensible PLR statistics follow.",
14542 0 : this->warnIndex.m_HeatCoilSensPLRIterIndex,
14543 : PartLoadFrac,
14544 : PartLoadFrac);
14545 : }
14546 : }
14547 0 : } else if (SolFla == -2) {
14548 0 : PartLoadFrac = ReqOutput / FullOutput;
14549 0 : if (!state.dataGlobal->WarmupFlag) {
14550 0 : if (this->warnIndex.m_HeatCoilSensPLRFail < 1) {
14551 0 : ++this->warnIndex.m_HeatCoilSensPLRFail;
14552 0 : ShowWarningError(state,
14553 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14554 0 : this->UnitType,
14555 0 : this->Name));
14556 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14557 0 : ShowContinueErrorTimeStamp(state,
14558 : "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14559 : } else {
14560 0 : ShowRecurringWarningErrorAtEnd(
14561 : state,
14562 0 : this->UnitType + " \"" + this->Name +
14563 : "\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14564 0 : this->warnIndex.m_HeatCoilSensPLRFailIndex,
14565 : PartLoadFrac,
14566 : PartLoadFrac);
14567 : }
14568 : }
14569 : }
14570 : }
14571 :
14572 : // Set the final results
14573 104850 : this->m_HeatingPartLoadFrac = PartLoadFrac;
14574 104850 : this->m_HeatingSpeedRatio = SpeedRatio;
14575 104850 : this->m_HeatingCycRatio = CycRatio;
14576 104850 : HeatCoilLoad = ReqOutput;
14577 :
14578 104850 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14579 0 : this->m_sysType != SysType::PackagedWSHP) {
14580 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF =
14581 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14582 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF =
14583 0 : max(state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14584 : }
14585 :
14586 104850 : if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWater || this->m_HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
14587 0 : mdot = PartLoadFrac * this->MaxHeatCoilFluidFlow;
14588 0 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatCoilFluidInletNode, this->HeatCoilFluidOutletNodeNum, this->HeatCoilPlantLoc);
14589 : }
14590 104850 : }
14591 :
14592 98727 : void UnitarySys::controlSuppHeatSystemToSP(EnergyPlusData &state,
14593 : int const AirLoopNum, // index to air loop
14594 : bool const FirstHVACIteration // First HVAC iteration flag
14595 : )
14596 : {
14597 : // SUBROUTINE INFORMATION:
14598 : // AUTHOR Richard Raustad, FSEC
14599 : // DATE WRITTEN February 2013
14600 : // MODIFIED Nov. 2016, R. Zhang, LBNL. Applied the coil supply air temperature sensor offset fault model
14601 :
14602 : // PURPOSE OF THIS SUBROUTINE:
14603 : // This subroutine updates the System outlet nodes.
14604 :
14605 : // METHODOLOGY EMPLOYED:
14606 : // Data is moved from the System data structure to the System outlet nodes.
14607 :
14608 : // SUBROUTINE PARAMETER DEFINITIONS:
14609 98727 : int constexpr MaxIte(500); // Maximum number of iterations for solver
14610 98727 : Real64 constexpr Acc(1.0e-3); // Accuracy of solver result
14611 98727 : int constexpr SolveMaxIter(50);
14612 98727 : constexpr bool SuppHeatingCoilFlag(true);
14613 :
14614 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
14615 98727 : Real64 QCoilActual = 0.0; // Heating coil operating capacity [W]
14616 98727 : Real64 mdot = 0.0; // water coil water flow rate [kg/s]
14617 98727 : Real64 maxPartLoadFrac = 0.0; // calculated maximum water side PLR for RegulaFalsi call (when plant limits flow max PLR != 1)
14618 98727 : Real64 PartLoadFrac = 0.0;
14619 98727 : Real64 SpeedRatio = 0.0;
14620 98727 : Real64 CycRatio = 0.0;
14621 :
14622 : // Set local variables
14623 98727 : auto &inletNode = state.dataLoopNodes->Node(this->m_SuppCoilAirInletNode);
14624 98727 : auto &outletNode = state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum);
14625 98727 : Real64 DesOutTemp = this->m_DesiredOutletTemp;
14626 98727 : std::string_view CompName = this->m_SuppHeatCoilName;
14627 :
14628 98727 : Real64 LoopHeatingCoilMaxRTFSave = 0.0;
14629 98727 : Real64 LoopDXCoilMaxRTFSave = 0.0;
14630 98727 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14631 0 : this->m_sysType != SysType::PackagedWSHP) {
14632 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14633 0 : LoopHeatingCoilMaxRTFSave = afnInfo.AFNLoopHeatingCoilMaxRTF;
14634 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = 0.0;
14635 0 : LoopDXCoilMaxRTFSave = afnInfo.AFNLoopDXCoilRTF;
14636 0 : afnInfo.AFNLoopDXCoilRTF = 0.0;
14637 : }
14638 :
14639 : // IF there is a fault of coil SAT Sensor
14640 98727 : if (this->m_FaultyCoilSATFlag) {
14641 : // calculate the sensor offset using fault information
14642 0 : int FaultIndex = this->m_FaultyCoilSATIndex;
14643 0 : this->m_FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
14644 : // update the DesOutTemp
14645 0 : DesOutTemp -= this->m_FaultyCoilSATOffset;
14646 : }
14647 :
14648 98727 : if ((ScheduleManager::GetCurrentScheduleValue(state, this->m_SysAvailSchedPtr) > 0.0) && (inletNode.MassFlowRate > HVAC::SmallAirVolFlow)) {
14649 :
14650 98709 : if (inletNode.Temp < (DesOutTemp - HVAC::TempControlTol)) {
14651 7709 : if (this->m_EMSOverrideSuppCoilSpeedNumOn) {
14652 0 : this->setEMSSuppCoilStagePLR(state);
14653 : } else {
14654 : // Get no load result at PartLoadFrac = 0.0
14655 :
14656 7709 : switch (this->m_SuppHeatCoilType_Num) {
14657 5466 : case HVAC::Coil_HeatingGasOrOtherFuel:
14658 : case HVAC::Coil_HeatingElectric:
14659 : case HVAC::Coil_HeatingDesuperheater: {
14660 16398 : HeatingCoils::SimulateHeatingCoilComponents(state,
14661 : CompName,
14662 : FirstHVACIteration,
14663 : PartLoadFrac,
14664 5466 : this->m_SuppHeatCoilIndex,
14665 : QCoilActual,
14666 : SuppHeatingCoilFlag,
14667 5466 : this->m_FanOpMode,
14668 : PartLoadFrac); // QCoilReq=PartLoadFrac 0.0 for this call
14669 5466 : } break;
14670 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
14671 : // SpeedRatio = 0.0;
14672 8972 : HeatingCoils::SimulateHeatingCoilComponents(state,
14673 : CompName,
14674 : FirstHVACIteration,
14675 : DataLoopNode::SensedLoadFlagValue,
14676 2243 : this->m_SuppHeatCoilIndex,
14677 : QCoilActual,
14678 : SuppHeatingCoilFlag,
14679 2243 : this->m_FanOpMode,
14680 : PartLoadFrac,
14681 4486 : 0,
14682 : SpeedRatio);
14683 2243 : } break;
14684 0 : case HVAC::Coil_HeatingWater: {
14685 0 : WaterCoils::SimulateWaterCoilComponents(
14686 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14687 0 : } break;
14688 0 : case HVAC::Coil_HeatingSteam: {
14689 0 : SteamCoils::SimulateSteamCoilComponents(state,
14690 : CompName,
14691 : FirstHVACIteration,
14692 0 : this->m_SuppHeatCoilIndex,
14693 0 : 1.0,
14694 : _,
14695 0 : this->m_FanOpMode,
14696 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14697 0 : } break;
14698 0 : case HVAC::Coil_UserDefined: { // do nothing, user defined coil cannot be controlled
14699 0 : bool HeatingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14700 0 : bool CoolingActive = false; // dummy variable for UserDefined coil which are passed back indicating if coil is on or off.
14701 0 : UserDefinedComponents::SimCoilUserDefined(
14702 0 : state, CompName, this->m_SuppHeatCoilIndex, AirLoopNum, HeatingActive, CoolingActive);
14703 0 : if (HeatingActive) PartLoadFrac = 1.0;
14704 0 : } break;
14705 0 : default:
14706 0 : break;
14707 : }
14708 :
14709 7709 : int SolFla = 0;
14710 : // If OutletTemp is within ACC of set point coil operation is not needed or UserDefined already met load.
14711 7709 : if (outletNode.Temp > (DesOutTemp - Acc) || this->m_SuppHeatCoilType_Num == HVAC::Coil_UserDefined) {
14712 : // do nothing, coil is at or above set point
14713 : } else {
14714 : // outlet temp too low, turn on coil
14715 : // Get full load result
14716 7709 : PartLoadFrac = 1.0;
14717 :
14718 7709 : switch (this->m_SuppHeatCoilType_Num) {
14719 5466 : case HVAC::Coil_HeatingGasOrOtherFuel:
14720 : case HVAC::Coil_HeatingElectric: {
14721 16398 : HeatingCoils::SimulateHeatingCoilComponents(state,
14722 : CompName,
14723 : FirstHVACIteration,
14724 5466 : this->m_DesignSuppHeatingCapacity,
14725 5466 : this->m_SuppHeatCoilIndex,
14726 : QCoilActual,
14727 : SuppHeatingCoilFlag,
14728 5466 : this->m_FanOpMode,
14729 : PartLoadFrac);
14730 5466 : if (this->m_DesignSuppHeatingCapacity > 0.0) {
14731 5466 : PartLoadFrac = QCoilActual / this->m_DesignSuppHeatingCapacity;
14732 : }
14733 5466 : } break;
14734 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
14735 2243 : CycRatio = 1.0;
14736 2243 : SpeedRatio = 1.0;
14737 6336 : for (int SpeedNum = 1; SpeedNum <= this->m_NumOfSpeedSuppHeating; ++SpeedNum) {
14738 6336 : this->m_SuppHeatingSpeedNum = SpeedNum;
14739 19008 : HeatingCoils::SimulateHeatingCoilComponents(state,
14740 : CompName,
14741 : FirstHVACIteration,
14742 : DataLoopNode::SensedLoadFlagValue,
14743 6336 : this->m_SuppHeatCoilIndex,
14744 : QCoilActual,
14745 : SuppHeatingCoilFlag,
14746 6336 : this->m_FanOpMode,
14747 : PartLoadFrac,
14748 : SpeedNum,
14749 : SpeedRatio);
14750 6336 : if (outletNode.Temp > DesOutTemp) break;
14751 : }
14752 2243 : } break;
14753 0 : case HVAC::Coil_HeatingDesuperheater: {
14754 0 : HeatingCoils::SimulateHeatingCoilComponents(state,
14755 : CompName,
14756 : FirstHVACIteration,
14757 0 : this->m_DesignSuppHeatingCapacity,
14758 0 : this->m_SuppHeatCoilIndex,
14759 : _,
14760 : SuppHeatingCoilFlag,
14761 0 : this->m_FanOpMode);
14762 0 : } break;
14763 0 : case HVAC::Coil_HeatingWater: {
14764 0 : mdot = this->m_MaxSuppCoilFluidFlow;
14765 0 : PlantUtilities::SetComponentFlowRate(
14766 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
14767 :
14768 0 : WaterCoils::SimulateWaterCoilComponents(
14769 0 : state, CompName, FirstHVACIteration, this->m_SuppHeatCoilIndex, _, this->m_FanOpMode, PartLoadFrac);
14770 0 : } break;
14771 0 : case HVAC::Coil_HeatingSteam: {
14772 0 : mdot = this->m_MaxSuppCoilFluidFlow;
14773 0 : PlantUtilities::SetComponentFlowRate(
14774 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
14775 :
14776 0 : SteamCoils::SimulateSteamCoilComponents(state,
14777 : CompName,
14778 : FirstHVACIteration,
14779 0 : this->m_SuppHeatCoilIndex,
14780 0 : 1.0,
14781 : _,
14782 0 : this->m_FanOpMode,
14783 : PartLoadFrac); // QCoilReq, simulate any load > 0 to get max capacity
14784 0 : } break;
14785 0 : case HVAC::Coil_UserDefined: {
14786 : // should never get here, coil has already been simulated
14787 0 : } break;
14788 0 : default:
14789 0 : break;
14790 : }
14791 :
14792 : // run the coil at PartLoadFrac = 1.
14793 7709 : if (outletNode.Temp < (DesOutTemp + Acc)) {
14794 0 : PartLoadFrac = 1.0; // these have already been set, leave as is for now
14795 0 : CycRatio = 1.0; // change to outletNode.Temp > and removed these vars and the "} else {"
14796 0 : SpeedRatio = 1.0;
14797 : } else {
14798 7709 : switch (this->m_SuppHeatCoilType_Num) {
14799 5466 : case HVAC::Coil_HeatingGasOrOtherFuel:
14800 : case HVAC::Coil_HeatingElectric:
14801 : case HVAC::Coil_HeatingDesuperheater: {
14802 5466 : bool tmpSuppHeatingCoilFlag = SuppHeatingCoilFlag; // CONST_LAMBDA_CAPTURE
14803 16398 : auto f = [&state, this, FirstHVACIteration, DesOutTemp, tmpSuppHeatingCoilFlag](Real64 const PartLoadFrac) {
14804 16398 : return this->gasElecHeatingCoilResidual(state,
14805 : PartLoadFrac,
14806 : this->m_UnitarySysNum,
14807 : FirstHVACIteration,
14808 : DesOutTemp,
14809 : tmpSuppHeatingCoilFlag,
14810 : this->m_FanOpMode,
14811 16398 : this->m_DesignSuppHeatingCapacity);
14812 5466 : };
14813 5466 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
14814 5466 : } break;
14815 2243 : case HVAC::Coil_HeatingElectric_MultiStage: {
14816 2243 : if (this->m_SuppHeatingSpeedNum > 1) {
14817 6726 : auto f = [&state, this, DesOutTemp, CycRatio](Real64 const SpeedRatio) {
14818 6726 : return UnitarySys::heatingCoilVarSpeedResidual(state,
14819 : SpeedRatio,
14820 : this->m_SuppHeatCoilIndex,
14821 : DesOutTemp,
14822 : this->m_UnitarySysNum,
14823 : CycRatio,
14824 : this->m_SuppHeatingSpeedNum,
14825 : this->m_FanOpMode,
14826 : HVAC::CompressorOp::On,
14827 6726 : true);
14828 2242 : };
14829 2242 : General::SolveRoot(state, Acc, MaxIte, SolFla, SpeedRatio, f, 0.0, 1.0);
14830 2242 : PartLoadFrac = SpeedRatio;
14831 : } else {
14832 1 : SpeedRatio = 0.0;
14833 1 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
14834 3 : auto f = [&state, this, DesOutTemp, SpeedRatio](Real64 const CycRatio) {
14835 3 : return UnitarySys::heatingCoilVarSpeedCycResidual(state,
14836 : CycRatio,
14837 : this->m_SuppHeatCoilIndex,
14838 : DesOutTemp,
14839 : this->m_UnitarySysNum,
14840 : SpeedRatio,
14841 : this->m_SuppHeatingSpeedNum,
14842 : this->m_FanOpMode,
14843 : HVAC::CompressorOp::On,
14844 3 : true);
14845 1 : };
14846 1 : General::SolveRoot(state, Acc, MaxIte, SolFla, CycRatio, f, 0.0, 1.0);
14847 1 : PartLoadFrac = CycRatio;
14848 : }
14849 2243 : } break;
14850 0 : case HVAC::Coil_HeatingWater: {
14851 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14852 : maxPartLoadFrac =
14853 0 : min(1.0,
14854 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
14855 : // max iteration limit (leave a little slop, 0.001)
14856 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14857 0 : Real64 mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14858 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
14859 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
14860 0 : WaterCoils::SimulateWaterCoilComponents(state,
14861 : this->m_SuppHeatCoilName,
14862 : FirstHVACIteration,
14863 0 : this->m_SuppHeatCoilIndex,
14864 0 : 0.0, // QActual
14865 0 : this->m_FanOpMode,
14866 : PartLoadFrac);
14867 :
14868 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
14869 0 : };
14870 :
14871 0 : General::SolveRoot(state, Acc, SolveMaxIter, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14872 0 : } break;
14873 0 : case HVAC::Coil_HeatingSteam: {
14874 :
14875 : // calculate max waterside PLR from mdot request above in case plant chokes water flow
14876 : maxPartLoadFrac =
14877 0 : min(1.0,
14878 0 : ((mdot / this->m_MaxSuppCoilFluidFlow) + 0.001)); // plant can limit flow and RegulaFalsi could hit
14879 : // max iteration limit (leave a little slop, 0.001)
14880 :
14881 0 : auto f = [&state, this, FirstHVACIteration, DesOutTemp](Real64 const PartLoadFrac) {
14882 : Real64 mdot;
14883 :
14884 0 : mdot = min(state.dataLoopNodes->Node(this->m_SuppCoilFluidOutletNodeNum).MassFlowRateMaxAvail,
14885 0 : this->m_MaxSuppCoilFluidFlow * PartLoadFrac);
14886 0 : state.dataLoopNodes->Node(this->m_SuppCoilFluidInletNode).MassFlowRate = mdot;
14887 0 : SteamCoils::SimulateSteamCoilComponents(state,
14888 : this->m_SuppHeatCoilName,
14889 : FirstHVACIteration,
14890 0 : this->m_SuppHeatCoilIndex,
14891 0 : 1.0,
14892 : _,
14893 0 : this->m_FanOpMode,
14894 : PartLoadFrac);
14895 0 : return (DesOutTemp - state.dataLoopNodes->Node(this->SuppCoilOutletNodeNum).Temp);
14896 0 : };
14897 :
14898 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, PartLoadFrac, f, 0.0, maxPartLoadFrac);
14899 0 : } break;
14900 0 : case HVAC::Coil_UserDefined: {
14901 : // do nothing, coil has already been simulated
14902 0 : } break;
14903 0 : default:
14904 0 : break;
14905 : }
14906 : }
14907 : } // IF (outletNode.Temp < (DesOutTemp + Acc)) THEN
14908 :
14909 7709 : if (PartLoadFrac > 1.0) {
14910 0 : PartLoadFrac = 1.0;
14911 7709 : } else if (PartLoadFrac < 0.0) {
14912 0 : PartLoadFrac = 0.0;
14913 : }
14914 :
14915 7709 : if (SolFla == -1) {
14916 0 : if (!state.dataGlobal->WarmupFlag) {
14917 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRIter < 1) {
14918 0 : Real64 ReqOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
14919 0 : DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14920 : Real64 FullOutput =
14921 0 : inletNode.MassFlowRate *
14922 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14923 :
14924 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRIter;
14925 0 : ShowWarningError(state,
14926 0 : format("{} - Iteration limit exceeded calculating sensible part-load ratio for unit = {}",
14927 0 : this->UnitType,
14928 0 : this->Name));
14929 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", (ReqOutput / FullOutput)));
14930 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
14931 0 : ShowContinueErrorTimeStamp(
14932 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
14933 : } else {
14934 0 : ShowRecurringWarningErrorAtEnd(state,
14935 0 : format("{} \"{}\" - Iteration limit exceeded calculating sensible part-load ratio "
14936 : "error continues. Sensible PLR statistics follow.",
14937 0 : this->UnitType,
14938 0 : this->Name),
14939 0 : this->warnIndex.m_SuppHeatCoilSensPLRIterIndex,
14940 : PartLoadFrac,
14941 : PartLoadFrac);
14942 : }
14943 : } // IF(.NOT. WarmupFlag)THEN
14944 7709 : } else if (SolFla == -2) {
14945 0 : Real64 ReqOutput = inletNode.MassFlowRate *
14946 0 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(DesOutTemp, inletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14947 0 : Real64 FullOutput = inletNode.MassFlowRate * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(
14948 0 : outletNode.Temp, outletNode.HumRat, inletNode.Temp, inletNode.HumRat);
14949 :
14950 0 : PartLoadFrac = ReqOutput / FullOutput;
14951 0 : if (!state.dataGlobal->WarmupFlag) {
14952 0 : if (this->warnIndex.m_SuppHeatCoilSensPLRFail < 1) {
14953 0 : ++this->warnIndex.m_SuppHeatCoilSensPLRFail;
14954 0 : ShowWarningError(
14955 : state,
14956 0 : format("{} - sensible part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
14957 0 : this->UnitType,
14958 0 : this->Name));
14959 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
14960 0 : ShowContinueErrorTimeStamp(
14961 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
14962 : } else {
14963 0 : ShowRecurringWarningErrorAtEnd(
14964 : state,
14965 0 : format("{} \"{}\" - sensible part-load ratio calculation failed error continues. Sensible PLR statistics follow.",
14966 0 : this->UnitType,
14967 0 : this->Name),
14968 0 : this->warnIndex.m_SuppHeatCoilSensPLRFailIndex,
14969 : PartLoadFrac,
14970 : PartLoadFrac);
14971 : }
14972 : }
14973 : } // IF (SolFla == -1) THEN
14974 :
14975 7709 : this->m_SuppHeatPartLoadFrac = PartLoadFrac;
14976 7709 : this->m_SuppHeatingCycRatio = CycRatio;
14977 7709 : this->m_SuppHeatingSpeedRatio = SpeedRatio;
14978 : } // IF (NOT EMS OVERRIDE) THEN
14979 :
14980 : } // IF SENSIBLE LOAD
14981 : } // IF((GetCurrentScheduleValue(state, UnitarySystem(UnitarySysNum)%m_SysAvailSchedPtr) > 0.0d0) .AND. &
14982 :
14983 : // LoopHeatingCoilMaxRTF used for AirflowNetwork gets set in child components (gas and fuel)
14984 98727 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
14985 0 : this->m_sysType != SysType::PackagedWSHP) {
14986 0 : auto &afnInfo = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum);
14987 0 : afnInfo.AFNLoopHeatingCoilMaxRTF = max(afnInfo.AFNLoopHeatingCoilMaxRTF, LoopHeatingCoilMaxRTFSave);
14988 0 : afnInfo.AFNLoopDXCoilRTF = max(afnInfo.AFNLoopDXCoilRTF, LoopDXCoilMaxRTFSave);
14989 : }
14990 :
14991 98727 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingWater || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
14992 0 : mdot = PartLoadFrac * this->m_MaxSuppCoilFluidFlow;
14993 0 : PlantUtilities::SetComponentFlowRate(
14994 0 : state, mdot, this->m_SuppCoilFluidInletNode, this->m_SuppCoilFluidOutletNodeNum, this->m_SuppCoilPlantLoc);
14995 : }
14996 98727 : }
14997 :
14998 22255 : void UnitarySys::simMultiSpeedCoils(EnergyPlusData &state,
14999 : int const AirLoopNum, // Index to air loop
15000 : bool const FirstHVACIteration, // True when first HVAC iteration
15001 : HVAC::CompressorOp &CompressorOn, // compressor on/off control
15002 : bool const SensibleLoad,
15003 : bool const LatentLoad,
15004 : Real64 const PartLoadFrac,
15005 : int const CoilType,
15006 : int const SpeedNumber)
15007 : {
15008 :
15009 : // SUBROUTINE INFORMATION:
15010 : // AUTHOR Chandan Sharma, FSEC
15011 : // DATE WRITTEN March 2013
15012 :
15013 : // PURPOSE OF THIS SUBROUTINE:
15014 : // This subroutine manages multispeed and variable speed cooling coil simulation.
15015 :
15016 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15017 22255 : std::string CompName; // Name of Unitary System object
15018 22255 : Real64 SensLoad = 0.0;
15019 22255 : Real64 LatLoad = 0.0;
15020 22255 : int CoilTypeNum = 0;
15021 22255 : int CompIndex = 0;
15022 22255 : Real64 SpeedRatio = 0.0;
15023 22255 : Real64 CycRatio = 0.0;
15024 22255 : Real64 dummy = 0.0;
15025 :
15026 22255 : if (CoilType == CoolingCoil) {
15027 :
15028 15516 : CompName = this->m_CoolingCoilName;
15029 15516 : CompIndex = this->m_CoolingCoilIndex;
15030 15516 : CoilTypeNum = this->m_CoolingCoilType_Num;
15031 15516 : if (SensibleLoad) {
15032 15516 : SensLoad = -1.0;
15033 15516 : state.dataUnitarySystems->CoolingLoad = true;
15034 15516 : state.dataUnitarySystems->HeatingLoad = false;
15035 : }
15036 15516 : if (LatentLoad) LatLoad = -1.0;
15037 :
15038 : } else {
15039 :
15040 6739 : CompName = this->m_HeatingCoilName;
15041 6739 : CompIndex = this->m_HeatingCoilIndex;
15042 6739 : CoilTypeNum = this->m_HeatingCoilType_Num;
15043 :
15044 6739 : if (SensibleLoad) {
15045 6739 : SensLoad = 1.0;
15046 6739 : state.dataUnitarySystems->CoolingLoad = false;
15047 6739 : state.dataUnitarySystems->HeatingLoad = true;
15048 : } else {
15049 0 : SensLoad = 0.0;
15050 0 : state.dataUnitarySystems->HeatingLoad = false;
15051 : }
15052 6739 : LatLoad = 0.0;
15053 : }
15054 :
15055 22255 : Real64 OnOffAirFlowRatio = 1.0;
15056 22255 : this->setOnOffMassFlowRate(state, OnOffAirFlowRatio, PartLoadFrac); // 1.0d0 = PartLoadRatio
15057 :
15058 22255 : this->calcPassiveSystem(state, AirLoopNum, FirstHVACIteration);
15059 :
15060 22255 : if ((CoilTypeNum == HVAC::CoilDX_MultiSpeedCooling) || (CoilTypeNum == HVAC::CoilDX_MultiSpeedHeating)) {
15061 :
15062 : // TODO: THIS IF SECTION DOES NOTHING
15063 22255 : if (CoilType == HVAC::Cooling) {
15064 0 : if (this->m_CoolingSpeedNum <= 1.0) {
15065 0 : SpeedRatio = 0.0;
15066 0 : CycRatio = PartLoadFrac;
15067 : } else {
15068 0 : if (this->m_SingleMode == 0) {
15069 0 : SpeedRatio = PartLoadFrac;
15070 0 : CycRatio = 0.0;
15071 : } else {
15072 0 : SpeedRatio = 1.0;
15073 0 : CycRatio = PartLoadFrac;
15074 : }
15075 : }
15076 : } else {
15077 22255 : if (this->m_HeatingSpeedNum <= 1.0) {
15078 20010 : SpeedRatio = 0.0;
15079 20010 : CycRatio = PartLoadFrac;
15080 : } else {
15081 2245 : if (this->m_SingleMode == 0) {
15082 2245 : SpeedRatio = PartLoadFrac;
15083 2245 : CycRatio = 0.0;
15084 : } else {
15085 0 : SpeedRatio = 1.0;
15086 0 : CycRatio = PartLoadFrac;
15087 : }
15088 : }
15089 : }
15090 22255 : DXCoils::SimDXCoilMultiSpeed(
15091 22255 : state, CompName, 0.0, PartLoadFrac, CompIndex, SpeedNumber, this->m_FanOpMode, HVAC::CompressorOp::On, this->m_SingleMode);
15092 :
15093 0 : } else if (CoilTypeNum == HVAC::CoilDX_Cooling) {
15094 :
15095 0 : if (CoilType == HVAC::Cooling) {
15096 0 : if (this->m_CoolingSpeedNum <= 1.0) {
15097 0 : SpeedRatio = 0.0;
15098 0 : CycRatio = PartLoadFrac;
15099 : } else {
15100 0 : if (this->m_SingleMode == 0) {
15101 0 : SpeedRatio = PartLoadFrac;
15102 0 : CycRatio = 0.0;
15103 : } else {
15104 0 : SpeedRatio = 1.0;
15105 0 : CycRatio = PartLoadFrac;
15106 : }
15107 : }
15108 : }
15109 0 : bool const singleMode = (this->m_SingleMode == 1);
15110 0 : HVAC::CoilMode coilMode = HVAC::CoilMode::Normal;
15111 0 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15112 0 : coilMode = HVAC::CoilMode::SubcoolReheat;
15113 0 : } else if (this->m_DehumidificationMode == HVAC::CoilMode::Enhanced) {
15114 0 : coilMode = HVAC::CoilMode::Enhanced;
15115 : }
15116 :
15117 0 : state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].simulate(
15118 : state, coilMode, CycRatio, this->m_CoolingSpeedNum, SpeedRatio, this->m_FanOpMode, singleMode, this->CoilSHR);
15119 :
15120 0 : } else if (CoilTypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
15121 :
15122 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15123 : CompName,
15124 : CompIndex,
15125 : this->m_FanOpMode,
15126 : CompressorOn,
15127 : PartLoadFrac,
15128 : SpeedNumber,
15129 : this->m_CoolingSpeedRatio,
15130 : SensLoad,
15131 : dummy,
15132 : OnOffAirFlowRatio);
15133 :
15134 0 : } else if (CoilTypeNum == HVAC::Coil_HeatingAirToAirVariableSpeed) {
15135 :
15136 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15137 : CompName,
15138 : CompIndex,
15139 : this->m_FanOpMode,
15140 : CompressorOn,
15141 : PartLoadFrac,
15142 : SpeedNumber,
15143 : this->m_HeatingSpeedRatio,
15144 : SensLoad,
15145 : dummy,
15146 : OnOffAirFlowRatio);
15147 :
15148 0 : } else if (CoilTypeNum == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
15149 :
15150 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15151 : CompName,
15152 : CompIndex,
15153 : this->m_FanOpMode,
15154 : CompressorOn,
15155 : PartLoadFrac,
15156 : SpeedNumber,
15157 : this->m_CoolingSpeedRatio,
15158 : SensLoad,
15159 : dummy,
15160 : OnOffAirFlowRatio);
15161 :
15162 0 : } else if (CoilTypeNum == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
15163 :
15164 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
15165 : CompName,
15166 : CompIndex,
15167 : this->m_FanOpMode,
15168 : CompressorOn,
15169 : PartLoadFrac,
15170 : SpeedNumber,
15171 : this->m_HeatingSpeedRatio,
15172 : SensLoad,
15173 : dummy,
15174 : OnOffAirFlowRatio);
15175 :
15176 0 : } else if ((CoilTypeNum == HVAC::Coil_HeatingElectric_MultiStage) || (CoilTypeNum == HVAC::Coil_HeatingGas_MultiStage)) {
15177 :
15178 0 : HeatingCoils::SimulateHeatingCoilComponents(
15179 0 : state, CompName, FirstHVACIteration, _, CompIndex, _, _, this->m_FanOpMode, PartLoadFrac, SpeedNumber, this->m_HeatingSpeedRatio);
15180 : } else {
15181 : }
15182 22255 : }
15183 :
15184 33695 : void UnitarySys::calcPassiveSystem(EnergyPlusData &state,
15185 : int const AirLoopNum, // index to air loop
15186 : bool const FirstHVACIteration // True when first HVAC iteration
15187 : )
15188 : {
15189 :
15190 : // SUBROUTINE INFORMATION:
15191 : // AUTHOR Richard Raustad, FSEC
15192 : // DATE WRITTEN February 2013
15193 :
15194 : // PURPOSE OF THIS SUBROUTINE:
15195 : // This subroutine calculates the set point based output of the unitary system.
15196 :
15197 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15198 33695 : Real64 PartLoadRatio = 0.0; // coil operating part-load ratio
15199 33695 : HVAC::CompressorOp CompressorOn = HVAC::CompressorOp::Off; // compressor control (0=off, 1=on)
15200 33695 : Real64 OnOffAirFlowRatio = 1.0;
15201 33695 : Real64 CoilCoolHeatRat = 1.0;
15202 33695 : Real64 HeatCoilLoad = 0.0;
15203 : // CALL the series of components that simulate a Unitary System
15204 33695 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::BlowThru) {
15205 28883 : state.dataFans->fans(this->m_FanIndex)
15206 86649 : ->simulate(state,
15207 : FirstHVACIteration,
15208 28883 : state.dataUnitarySystems->FanSpeedRatio,
15209 : _, // Pressure rise
15210 : _, // Flow fraction
15211 28883 : state.dataUnitarySystems->m_massFlow1,
15212 28883 : state.dataUnitarySystems->m_runTimeFraction1,
15213 28883 : state.dataUnitarySystems->m_massFlow2,
15214 28883 : state.dataUnitarySystems->m_runTimeFraction2,
15215 : _);
15216 : }
15217 :
15218 33695 : if (this->m_CoolingCoilUpstream) {
15219 :
15220 33695 : if (this->m_CoolCoilExists) {
15221 33695 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15222 33695 : CompressorOn = HVAC::CompressorOp::Off;
15223 33695 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15224 33695 : bool HXUnitOn = false;
15225 33695 : this->calcUnitaryCoolingSystem(
15226 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15227 : }
15228 33695 : if (this->m_HeatCoilExists) {
15229 28883 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15230 28883 : CompressorOn = HVAC::CompressorOp::Off;
15231 28883 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15232 28883 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15233 : }
15234 :
15235 : } else {
15236 :
15237 0 : if (this->m_HeatCoilExists) {
15238 0 : PartLoadRatio = this->m_HeatingPartLoadFrac;
15239 0 : CompressorOn = HVAC::CompressorOp::Off;
15240 0 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15241 0 : this->calcUnitaryHeatingSystem(state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, HeatCoilLoad);
15242 : }
15243 0 : if (this->m_CoolCoilExists) {
15244 0 : PartLoadRatio = this->m_CoolingPartLoadFrac;
15245 0 : CompressorOn = HVAC::CompressorOp::Off;
15246 0 : if (PartLoadRatio > 0.0) CompressorOn = HVAC::CompressorOp::On;
15247 0 : bool HXUnitOn = false;
15248 0 : this->calcUnitaryCoolingSystem(
15249 : state, AirLoopNum, FirstHVACIteration, PartLoadRatio, CompressorOn, OnOffAirFlowRatio, CoilCoolHeatRat, HXUnitOn);
15250 : }
15251 : }
15252 :
15253 33695 : if (this->m_FanExists && this->m_FanPlace == HVAC::FanPlace::DrawThru) {
15254 0 : state.dataFans->fans(this->m_FanIndex)
15255 0 : ->simulate(state,
15256 : FirstHVACIteration,
15257 0 : state.dataUnitarySystems->FanSpeedRatio,
15258 : _, // Pressure rise
15259 : _, // Flow fraction
15260 0 : state.dataUnitarySystems->m_massFlow1,
15261 0 : state.dataUnitarySystems->m_runTimeFraction1,
15262 0 : state.dataUnitarySystems->m_massFlow2,
15263 0 : state.dataUnitarySystems->m_runTimeFraction2,
15264 : _);
15265 : }
15266 :
15267 : // CALL reheat coils next
15268 33695 : if (this->m_SuppCoilExists) {
15269 28883 : state.dataUnitarySystems->SuppHeatingCoilFlag = true;
15270 28883 : this->calcUnitarySuppSystemToSP(state, FirstHVACIteration);
15271 28883 : state.dataUnitarySystems->SuppHeatingCoilFlag = false;
15272 : }
15273 33695 : }
15274 :
15275 7705441 : void UnitarySys::reportUnitarySystem(EnergyPlusData &state, int const AirLoopNum)
15276 : {
15277 :
15278 : // SUBROUTINE INFORMATION:
15279 : // AUTHOR Chandan Sharma
15280 : // DATE WRITTEN July 2013
15281 :
15282 : // PURPOSE OF THIS SUBROUTINE:
15283 : // This subroutine updates the report variable for the coils.
15284 :
15285 7705441 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15286 :
15287 7705441 : Real64 SensibleOutput = 0.0; // sensible output rate, {W}
15288 7705441 : Real64 LatentOutput = 0.0; // latent output rate, {W}
15289 7705441 : Real64 TotalOutput = 0.0; // total output rate, {W}
15290 7705441 : Real64 QTotUnitOut = 0.0;
15291 7705441 : Real64 QSensUnitOut = 0.0;
15292 7705441 : this->m_PartLoadFrac = 0.0;
15293 7705441 : this->m_CompPartLoadRatio = 0.0;
15294 7705441 : this->m_CycRatio = 0.0;
15295 7705441 : this->m_SpeedRatio = 0.0;
15296 7705441 : this->FanPartLoadRatio = 0.0;
15297 7705441 : this->m_TotalAuxElecPower = 0.0;
15298 7705441 : this->m_HeatingAuxElecConsumption = 0.0;
15299 7705441 : this->m_CoolingAuxElecConsumption = 0.0;
15300 7705441 : this->m_ElecPower = 0.0;
15301 7705441 : this->m_ElecPowerConsumption = 0.0;
15302 :
15303 7705441 : Real64 AirMassFlow = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate;
15304 7705441 : switch (this->m_ControlType) {
15305 : // Noticed that these are calculated differently.
15306 : // That doesn't make sense except that NodeNumOfControlledZone = 0 for set point control because the control zone name is not required.
15307 3607422 : case UnitarySysCtrlType::Setpoint: {
15308 3607422 : if (this->AirOutNode > 0) {
15309 3607422 : int InletNode = this->AirInNode;
15310 14429688 : CalcComponentSensibleLatentOutput(AirMassFlow,
15311 3607422 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15312 3607422 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15313 3607422 : state.dataLoopNodes->Node(InletNode).Temp,
15314 3607422 : state.dataLoopNodes->Node(InletNode).HumRat,
15315 : SensibleOutput,
15316 : LatentOutput,
15317 : TotalOutput);
15318 3607422 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15319 3607422 : QTotUnitOut = TotalOutput;
15320 : }
15321 3607422 : } break;
15322 4098019 : default: {
15323 4098019 : if (this->AirOutNode > 0 && this->NodeNumOfControlledZone > 0) {
15324 : // PTUnit uses old style method of calculating delivered capacity.
15325 : // Also PTUnit always uses inlet node data, which is good when inlet is connected to zone return node
15326 4098019 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15327 1254457 : Real64 SpecHumOut = state.dataLoopNodes->Node(this->AirOutNode).HumRat;
15328 1254457 : Real64 SpecHumIn = state.dataLoopNodes->Node(this->AirInNode).HumRat;
15329 1254457 : LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s (dehumid = negative)
15330 1254457 : SensibleOutput = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirOutNode).Temp,
15331 1254457 : state.dataLoopNodes->Node(this->AirInNode).HumRat) -
15332 1254457 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(this->AirInNode).Temp,
15333 1254457 : state.dataLoopNodes->Node(this->AirInNode).HumRat));
15334 1254457 : TotalOutput =
15335 1254457 : AirMassFlow * (state.dataLoopNodes->Node(this->AirOutNode).Enthalpy - state.dataLoopNodes->Node(this->AirInNode).Enthalpy);
15336 1254457 : } else {
15337 : // air loop systems don't use the Sensible capacity, zone equipment uses this to adjust RemainingOutputRequired
15338 11374248 : CalcZoneSensibleLatentOutput(AirMassFlow,
15339 2843562 : state.dataLoopNodes->Node(this->AirOutNode).Temp,
15340 2843562 : state.dataLoopNodes->Node(this->AirOutNode).HumRat,
15341 2843562 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).Temp,
15342 2843562 : state.dataLoopNodes->Node(this->NodeNumOfControlledZone).HumRat,
15343 : SensibleOutput,
15344 : LatentOutput,
15345 : TotalOutput);
15346 : }
15347 4098019 : QSensUnitOut = SensibleOutput - this->m_SenLoadLoss;
15348 4098019 : QTotUnitOut = TotalOutput;
15349 : }
15350 4098019 : } break;
15351 : }
15352 :
15353 : // set the system part-load ratio report variable
15354 7705441 : this->m_PartLoadFrac = max(this->m_CoolingPartLoadFrac, this->m_HeatingPartLoadFrac);
15355 : // set the compressor part-load ratio report variable
15356 7705441 : this->m_CompPartLoadRatio = max(this->m_CoolCompPartLoadRatio, this->m_HeatCompPartLoadRatio);
15357 :
15358 : // logic difference in PTUnit *Rate reporting vs UnitarySystem. Use PTUnit more compact method for 9093.
15359 7705441 : if (this->m_sysType == SysType::PackagedAC || this->m_sysType == SysType::PackagedHP || this->m_sysType == SysType::PackagedWSHP) {
15360 : // Issue 9093.
15361 : // PTHP reports these differently, seems this is correct. Can't change this now, need an issue to resolve
15362 1254457 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15363 1254457 : this->m_TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
15364 1254457 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15365 1254457 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15366 1254457 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15367 1254457 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15368 : } else {
15369 6450984 : if (state.dataUnitarySystems->HeatingLoad) {
15370 1046304 : if (QTotUnitOut > 0.0) { // heating
15371 571569 : this->m_TotCoolEnergyRate = 0.0;
15372 571569 : this->m_SensCoolEnergyRate = 0.0;
15373 571569 : this->m_LatCoolEnergyRate = 0.0;
15374 571569 : this->m_TotHeatEnergyRate = QTotUnitOut;
15375 571569 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15376 571569 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15377 : } else {
15378 474735 : this->m_TotCoolEnergyRate = std::abs(QTotUnitOut);
15379 474735 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15380 474735 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15381 474735 : this->m_TotHeatEnergyRate = 0.0;
15382 474735 : this->m_SensHeatEnergyRate = 0.0;
15383 474735 : this->m_LatHeatEnergyRate = 0.0;
15384 : }
15385 : } else {
15386 5404680 : if (QTotUnitOut <= 0.0) { // cooling
15387 5188499 : this->m_TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
15388 5188499 : this->m_SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
15389 5188499 : this->m_LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
15390 5188499 : this->m_TotHeatEnergyRate = 0.0;
15391 5188499 : this->m_SensHeatEnergyRate = 0.0;
15392 5188499 : this->m_LatHeatEnergyRate = 0.0;
15393 : } else {
15394 216181 : this->m_TotCoolEnergyRate = 0.0;
15395 216181 : this->m_SensCoolEnergyRate = 0.0;
15396 216181 : this->m_LatCoolEnergyRate = 0.0;
15397 216181 : this->m_TotHeatEnergyRate = QTotUnitOut;
15398 216181 : this->m_SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
15399 216181 : this->m_LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
15400 : }
15401 : }
15402 : }
15403 :
15404 7705441 : this->m_TotHeatEnergy = m_TotHeatEnergyRate * ReportingConstant;
15405 7705441 : this->m_TotCoolEnergy = m_TotCoolEnergyRate * ReportingConstant;
15406 7705441 : this->m_SensHeatEnergy = m_SensHeatEnergyRate * ReportingConstant;
15407 7705441 : this->m_SensCoolEnergy = m_SensCoolEnergyRate * ReportingConstant;
15408 7705441 : this->m_LatHeatEnergy = m_LatHeatEnergyRate * ReportingConstant;
15409 7705441 : this->m_LatCoolEnergy = m_LatCoolEnergyRate * ReportingConstant;
15410 :
15411 7705441 : if (this->m_FanExists && this->AirOutNode > 0) {
15412 4196746 : if (state.dataUnitarySystems->CompOnMassFlow > 0.0) {
15413 3962036 : this->FanPartLoadRatio = state.dataLoopNodes->Node(this->AirOutNode).MassFlowRate / state.dataUnitarySystems->CompOnMassFlow;
15414 : }
15415 4196746 : if (AirLoopNum > 0) {
15416 2759107 : if (this->m_FanOpMode == HVAC::FanOp::Cycling) {
15417 827703 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = this->FanPartLoadRatio;
15418 : } else {
15419 1931404 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0;
15420 : }
15421 : }
15422 : }
15423 :
15424 7705441 : Real64 locFanElecPower = (this->m_FanIndex == 0) ? 0.0 : state.dataFans->fans(this->m_FanIndex)->totalPower;
15425 :
15426 7705441 : Real64 elecCoolingPower = 0.0;
15427 7705441 : Real64 elecHeatingPower = 0.0;
15428 7705441 : Real64 suppHeatingPower = 0.0;
15429 7705441 : Real64 defrostElecPower = 0.0;
15430 :
15431 7705441 : switch (this->m_CoolingCoilType_Num) {
15432 1032924 : case HVAC::CoilDX_CoolingTwoSpeed: {
15433 : // need to make sure these are 0 for non-variable speed coils (or not report these variables)
15434 1032924 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15435 1032924 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15436 1032924 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15437 : // see :setSpeedVariables
15438 1032924 : if (state.dataUnitarySystems->CoolingLoad && this->m_SpeedNum <= 1) {
15439 17035 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15440 17035 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15441 : }
15442 1032924 : if (this->m_LastMode == CoolingMode) {
15443 1032924 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15444 : }
15445 1032924 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15446 1032924 : } break;
15447 675227 : case HVAC::CoilDX_MultiSpeedCooling: {
15448 675227 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15449 675227 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15450 675227 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15451 :
15452 675227 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15453 675227 : if (state.dataUnitarySystems->CoolingLoad) {
15454 189351 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15455 189351 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15456 : }
15457 675227 : if (this->m_LastMode == CoolingMode) {
15458 260470 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15459 : }
15460 675227 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15461 675227 : } break;
15462 272541 : case HVAC::Coil_CoolingWater:
15463 : case HVAC::Coil_CoolingWaterDetailed: {
15464 272541 : if (this->m_DiscreteSpeedCoolingCoil) {
15465 14902 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15466 14902 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15467 14902 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15468 14902 : if (state.dataUnitarySystems->CoolingLoad) {
15469 : // if discrete, the coil cycles on and off
15470 5174 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * this->m_CycRatio + this->m_AncillaryOffPower * (1.0 - this->m_CycRatio);
15471 5174 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_CycRatio * ReportingConstant;
15472 : }
15473 14902 : if (this->m_LastMode == CoolingMode) {
15474 7212 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_CycRatio) * ReportingConstant;
15475 : }
15476 : } else {
15477 257639 : if (state.dataUnitarySystems->CoolingLoad) {
15478 : // if not discrete, the coil runs the entire time step.
15479 20954 : this->m_TotalAuxElecPower =
15480 20954 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15481 20954 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15482 : }
15483 257639 : if (this->m_LastMode == CoolingMode) {
15484 106945 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15485 : }
15486 : }
15487 272541 : this->m_ElecPower = locFanElecPower;
15488 272541 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15489 272541 : } break;
15490 : // May not need
15491 109034 : case HVAC::Coil_CoolingWaterToAirHPSimple: {
15492 109034 : if (this->m_NumOfSpeedCooling > 1) {
15493 7334 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15494 7334 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15495 7334 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15496 : }
15497 109034 : if (state.dataUnitarySystems->CoolingLoad) {
15498 42799 : this->m_TotalAuxElecPower =
15499 42799 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15500 42799 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15501 : }
15502 109034 : if (this->m_LastMode == CoolingMode) {
15503 55099 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15504 : }
15505 109034 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15506 109034 : } break;
15507 1626901 : case HVAC::CoilDX_Cooling: {
15508 1626901 : if (this->m_NumOfSpeedCooling > 1) {
15509 1496205 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15510 1496205 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15511 1496205 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15512 :
15513 1496205 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15514 1496205 : if (state.dataUnitarySystems->CoolingLoad) {
15515 664464 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15516 664464 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15517 : }
15518 1496205 : if (this->m_LastMode == CoolingMode) {
15519 1001184 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15520 : }
15521 1496205 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15522 : } else {
15523 130696 : if (state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag) {
15524 8766 : if (state.dataUnitarySystems->CoolingLoad && this->LoadSHR == 0.0) {
15525 2324 : this->LoadSHR = 1.0;
15526 2324 : this->CoilSHR = state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].performance.NormalSHR;
15527 : }
15528 : }
15529 130696 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15530 130696 : if (state.dataUnitarySystems->CoolingLoad) {
15531 41816 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15532 41816 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15533 : }
15534 130696 : if (this->m_LastMode == CoolingMode) {
15535 70849 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15536 : }
15537 130696 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15538 : }
15539 1626901 : } break;
15540 28852 : case HVAC::Coil_UserDefined:
15541 : case HVAC::CoilWater_CoolingHXAssisted:
15542 : case HVAC::CoilDX_PackagedThermalStorageCooling: {
15543 28852 : if (state.dataUnitarySystems->CoolingLoad) {
15544 0 : this->m_TotalAuxElecPower =
15545 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15546 0 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15547 : }
15548 28852 : if (this->m_LastMode == CoolingMode) {
15549 28852 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15550 : }
15551 : // these coil types do not consume electricity or report electricity at the plant
15552 28852 : } break;
15553 3959962 : default: { // all other DX cooling coils
15554 3959962 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15555 3959962 : if (state.dataUnitarySystems->CoolingLoad) {
15556 803557 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15557 803557 : this->m_CoolingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15558 : }
15559 3959962 : if (this->m_LastMode == CoolingMode) {
15560 3095435 : this->m_CoolingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15561 : }
15562 3959962 : elecCoolingPower = state.dataHVACGlobal->DXElecCoolingPower;
15563 3959962 : } break;
15564 : }
15565 :
15566 7705441 : switch (this->m_HeatingCoilType_Num) {
15567 793759 : case HVAC::CoilDX_MultiSpeedHeating: {
15568 793759 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15569 793759 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15570 793759 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15571 :
15572 793759 : Real64 CompPartLoadFrac = this->m_CompPartLoadRatio;
15573 793759 : if (state.dataUnitarySystems->HeatingLoad) {
15574 289385 : this->m_TotalAuxElecPower = this->m_AncillaryOnPower * CompPartLoadFrac + this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac);
15575 289385 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * CompPartLoadFrac * ReportingConstant;
15576 : }
15577 793759 : if (this->m_LastMode == HeatingMode) {
15578 454787 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - CompPartLoadFrac) * ReportingConstant;
15579 : }
15580 793759 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15581 793759 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15582 793759 : } break;
15583 0 : case HVAC::Coil_HeatingGas_MultiStage:
15584 : case HVAC::Coil_HeatingElectric_MultiStage: {
15585 0 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15586 0 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15587 :
15588 0 : if (state.dataUnitarySystems->HeatingLoad) {
15589 0 : this->m_TotalAuxElecPower =
15590 0 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15591 0 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15592 : }
15593 0 : if (this->m_LastMode == HeatingMode) {
15594 0 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15595 : }
15596 :
15597 0 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15598 0 : } break;
15599 461406 : case HVAC::CoilDX_HeatingEmpirical:
15600 : case HVAC::Coil_HeatingWaterToAirHP:
15601 : case HVAC::Coil_HeatingWaterToAirHPSimple:
15602 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15603 461406 : if (this->m_NumOfSpeedHeating > 1) {
15604 27128 : this->m_CycRatio = max(this->m_CoolingCycRatio, this->m_HeatingCycRatio);
15605 27128 : this->m_SpeedRatio = max(this->m_CoolingSpeedRatio, this->m_HeatingSpeedRatio);
15606 27128 : this->m_SpeedNum = max(this->m_CoolingSpeedNum, this->m_HeatingSpeedNum);
15607 : }
15608 461406 : if (state.dataUnitarySystems->HeatingLoad) {
15609 174459 : this->m_TotalAuxElecPower =
15610 174459 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15611 174459 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15612 : }
15613 461406 : if (this->m_LastMode == HeatingMode) {
15614 185914 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15615 : }
15616 461406 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15617 461406 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15618 461406 : } break;
15619 8895 : case HVAC::Coil_HeatingAirToAirVariableSpeed: {
15620 8895 : if (state.dataUnitarySystems->HeatingLoad) {
15621 3402 : this->m_TotalAuxElecPower =
15622 3402 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15623 3402 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15624 : }
15625 8895 : if (this->m_LastMode == HeatingMode) {
15626 4130 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15627 : }
15628 :
15629 8895 : elecHeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
15630 8895 : defrostElecPower = state.dataHVACGlobal->DefrostElecPower;
15631 8895 : } break;
15632 78594 : case HVAC::Coil_UserDefined:
15633 : case HVAC::Coil_HeatingWater:
15634 : case HVAC::Coil_HeatingSteam:
15635 : case HVAC::Coil_HeatingDesuperheater: {
15636 78594 : if (state.dataUnitarySystems->HeatingLoad) {
15637 34626 : this->m_TotalAuxElecPower =
15638 34626 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15639 34626 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15640 : }
15641 78594 : if (this->m_LastMode == HeatingMode) {
15642 40278 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15643 : }
15644 78594 : } break;
15645 6362787 : default: {
15646 6362787 : if (this->m_HeatCoilExists) {
15647 2699430 : if (state.dataUnitarySystems->HeatingLoad) {
15648 : // if discrete, the coil cycles on and off
15649 970294 : this->m_TotalAuxElecPower =
15650 970294 : this->m_AncillaryOnPower * this->m_PartLoadFrac + this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac);
15651 970294 : this->m_HeatingAuxElecConsumption = this->m_AncillaryOnPower * this->m_PartLoadFrac * ReportingConstant;
15652 : }
15653 2699430 : if (this->m_LastMode == HeatingMode) {
15654 1213389 : this->m_HeatingAuxElecConsumption += this->m_AncillaryOffPower * (1.0 - this->m_PartLoadFrac) * ReportingConstant;
15655 : }
15656 2699430 : elecHeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
15657 : }
15658 6362787 : } break;
15659 : }
15660 :
15661 7705441 : if (!state.dataUnitarySystems->HeatingLoad && !state.dataUnitarySystems->CoolingLoad) {
15662 4266354 : this->m_TotalAuxElecPower = this->m_AncillaryOffPower;
15663 : }
15664 :
15665 7705441 : if (this->m_SuppCoilExists) {
15666 1352904 : if (this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric || this->m_SuppHeatCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
15667 1069582 : suppHeatingPower = state.dataHVACGlobal->SuppHeatingCoilPower;
15668 : }
15669 : }
15670 :
15671 7705441 : this->m_ElecPower = locFanElecPower + elecCoolingPower + elecHeatingPower + suppHeatingPower + defrostElecPower + this->m_TotalAuxElecPower;
15672 7705441 : this->m_ElecPowerConsumption = this->m_ElecPower * ReportingConstant;
15673 :
15674 7841253 : if (state.afn->distribution_simulated && this->m_sysType != SysType::PackagedAC && this->m_sysType != SysType::PackagedHP &&
15675 135812 : this->m_sysType != SysType::PackagedWSHP) {
15676 135812 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataUnitarySystems->CompOnMassFlow;
15677 135812 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataUnitarySystems->CompOffMassFlow;
15678 135812 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = this->m_FanOpMode;
15679 135812 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = this->FanPartLoadRatio;
15680 135812 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopCompCycRatio = this->m_CycRatio;
15681 : }
15682 7705441 : if (this->m_FirstPass) {
15683 840 : if (AirLoopNum > -1) {
15684 832 : if (!state.dataGlobal->SysSizingCalc) {
15685 :
15686 614 : int const CurOASysNum = state.dataSize->CurOASysNum;
15687 614 : if (CurOASysNum > 0) {
15688 2 : auto &thisOASysEqSizing = state.dataSize->OASysEqSizing(CurOASysNum);
15689 2 : thisOASysEqSizing.AirFlow = false;
15690 2 : thisOASysEqSizing.CoolingAirFlow = false;
15691 2 : thisOASysEqSizing.HeatingAirFlow = false;
15692 2 : thisOASysEqSizing.Capacity = false;
15693 2 : thisOASysEqSizing.CoolingCapacity = false;
15694 2 : thisOASysEqSizing.HeatingCapacity = false;
15695 2 : this->m_FirstPass = false;
15696 612 : } else if (state.dataSize->CurSysNum > 0) {
15697 394 : if (state.dataSize->CurSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
15698 394 : state.dataAirLoop->AirLoopControlInfo(state.dataSize->CurSysNum).UnitarySysSimulating = false;
15699 : }
15700 394 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
15701 218 : } else if (state.dataSize->CurZoneEqNum > 0) {
15702 218 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, this->m_FirstPass);
15703 : } else {
15704 0 : this->m_FirstPass = false;
15705 : }
15706 : }
15707 : } else {
15708 8 : this->m_FirstPass = false;
15709 : }
15710 : // reset the global system type flags
15711 840 : state.dataSize->ZoneEqDXCoil = false;
15712 : }
15713 :
15714 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
15715 7705441 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
15716 7705441 : state.dataSize->ZoneEqUnitarySys = false;
15717 7705441 : }
15718 :
15719 0 : void UnitarySys::unitarySystemHeatRecovery(EnergyPlusData &state)
15720 : {
15721 :
15722 : // SUBROUTINE INFORMATION:
15723 : // AUTHOR: Chandan Sharma
15724 : // DATE WRITTEN: May 2013
15725 :
15726 : // PURPOSE OF THIS SUBROUTINE:
15727 : // Calculate the heat recovered from UnitarySystem
15728 :
15729 : // SUBROUTINE PARAMETER DEFINITIONS:
15730 : static constexpr std::string_view routineName("UnitarySystemHeatRecovery");
15731 :
15732 0 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
15733 :
15734 0 : Real64 HeatRecInletTemp = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).Temp;
15735 0 : Real64 HeatRecOutletTemp = 0.0;
15736 0 : Real64 HeatRecMassFlowRate = state.dataLoopNodes->Node(this->m_HeatRecoveryInletNodeNum).MassFlowRate;
15737 :
15738 0 : Real64 QHeatRec = state.dataHVACGlobal->MSHPWasteHeat;
15739 :
15740 0 : if (HeatRecMassFlowRate > 0.0) {
15741 :
15742 0 : Real64 CpHeatRec = FluidProperties::GetSpecificHeatGlycol(state,
15743 0 : state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).FluidName,
15744 : HeatRecInletTemp,
15745 0 : state.dataPlnt->PlantLoop(this->m_HRPlantLoc.loopNum).FluidIndex,
15746 : routineName);
15747 :
15748 0 : HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + HeatRecInletTemp;
15749 : // coil model should be handling max outlet water temp (via limit to heat transfer) since heat rejection needs to be accounted for by the
15750 : // coil
15751 0 : if (HeatRecOutletTemp > this->m_MaxHROutletWaterTemp) {
15752 0 : HeatRecOutletTemp = max(HeatRecInletTemp, this->m_MaxHROutletWaterTemp);
15753 0 : QHeatRec = HeatRecMassFlowRate * CpHeatRec * (HeatRecOutletTemp - HeatRecInletTemp);
15754 : }
15755 : } else {
15756 0 : HeatRecOutletTemp = HeatRecInletTemp;
15757 0 : QHeatRec = 0.0;
15758 : }
15759 :
15760 0 : PlantUtilities::SafeCopyPlantNode(state, this->m_HeatRecoveryInletNodeNum, this->m_HeatRecoveryOutletNodeNum);
15761 :
15762 0 : state.dataLoopNodes->Node(this->m_HeatRecoveryOutletNodeNum).Temp = HeatRecOutletTemp;
15763 :
15764 0 : this->m_HeatRecoveryRate = QHeatRec;
15765 0 : this->m_HeatRecoveryEnergy = this->m_HeatRecoveryRate * ReportingConstant;
15766 0 : this->m_HeatRecoveryInletTemp = HeatRecInletTemp;
15767 0 : this->m_HeatRecoveryOutletTemp = HeatRecOutletTemp;
15768 0 : this->m_HeatRecoveryMassFlowRate = HeatRecMassFlowRate;
15769 0 : }
15770 :
15771 9505222 : Real64 UnitarySys::calcUnitarySystemLoadResidual(EnergyPlusData &state,
15772 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
15773 : int UnitarySysNum,
15774 : bool FirstHVACIteration,
15775 : // par 3 not used?
15776 : HVAC::CompressorOp compressorOp,
15777 : Real64 LoadToBeMet,
15778 : Real64 coolHeatFlag, // make bool?
15779 : Real64 SensibleLoad,
15780 : Real64 OnOffAirFlowRatio,
15781 : bool HXUnitOn,
15782 : // par 10 not used
15783 : int AirLoopNum)
15784 : {
15785 :
15786 : // FUNCTION INFORMATION:
15787 : // AUTHOR Richard Raustad, FSEC
15788 : // DATE WRITTEN February 2013
15789 :
15790 : // PURPOSE OF THIS SUBROUTINE:
15791 : // To calculate the part-load ratio for the unitary system
15792 :
15793 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
15794 : Real64 SensOutput; // sensible output of system
15795 : Real64 LatOutput; // latent output of system
15796 9505222 : Real64 HeatCoilLoad = 0.0;
15797 9505222 : Real64 SupHeaterLoad = 0.0;
15798 9505222 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15799 9505222 : Real64 CoolPLR = coolHeatFlag == 1.0 ? PartLoadRatio : 0.0;
15800 9505222 : Real64 HeatPLR = coolHeatFlag == 1.0 ? 0.0 : PartLoadRatio;
15801 9505222 : thisSys.setSpeedVariables(state, SensibleLoad, PartLoadRatio);
15802 9505222 : thisSys.calcUnitarySystemToLoad(state,
15803 : AirLoopNum,
15804 : FirstHVACIteration,
15805 : CoolPLR,
15806 : HeatPLR,
15807 : OnOffAirFlowRatio,
15808 : SensOutput,
15809 : LatOutput,
15810 : HXUnitOn,
15811 : HeatCoilLoad,
15812 : SupHeaterLoad,
15813 : compressorOp);
15814 : // Calculate residual based on output calculation flag
15815 9505222 : Real64 baselineLoad = SensibleLoad == 1.0 ? SensOutput : LatOutput;
15816 9505222 : Real64 divisor = std::abs(LoadToBeMet) == 0.0 ? 100.0 : LoadToBeMet;
15817 9505222 : return (baselineLoad - LoadToBeMet) / divisor;
15818 : }
15819 :
15820 1726670 : Real64 UnitarySys::DXCoilVarSpeedResidual(EnergyPlusData &state,
15821 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
15822 : int CoilIndex,
15823 : Real64 DesOutTemp,
15824 : int UnitarySysNum,
15825 : Real64 CycRatio,
15826 : int SpeedNum,
15827 : HVAC::FanOp const fanOp,
15828 : HVAC::CompressorOp compressorOp)
15829 : {
15830 : // FUNCTION INFORMATION:
15831 : // AUTHOR Fred Buhl
15832 : // DATE WRITTEN September 2002
15833 :
15834 : // PURPOSE OF THIS FUNCTION:
15835 : // Calculates residual function (desired outlet temp - actual outlet temp).
15836 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
15837 :
15838 : // METHODOLOGY EMPLOYED:
15839 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given compressor speed
15840 : // and calculates the residual as defined above
15841 :
15842 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15843 1726670 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
15844 :
15845 : Real64 dummy;
15846 : Real64 OnOffAirFlowRatio;
15847 : Real64 SensLoad;
15848 :
15849 1726670 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15850 1726670 : switch (thisSys.m_CoolingCoilType_Num) {
15851 1718065 : case HVAC::CoilDX_CoolingTwoSpeed: {
15852 1718065 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
15853 1718065 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15854 1718065 : } break;
15855 235 : case HVAC::CoilDX_MultiSpeedCooling: {
15856 235 : OnOffAirFlowRatio = 1.0;
15857 235 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
15858 235 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
15859 235 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15860 235 : } break;
15861 8370 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
15862 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
15863 8370 : dummy = 0.0;
15864 8370 : SensLoad = -1.0;
15865 8370 : OnOffAirFlowRatio = 1.0;
15866 8370 : VariableSpeedCoils::SimVariableSpeedCoils(
15867 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
15868 :
15869 8370 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
15870 8370 : } break;
15871 0 : default: {
15872 0 : assert(false);
15873 : } break;
15874 : }
15875 1726670 : return DesOutTemp - OutletAirTemp;
15876 : }
15877 :
15878 6726 : Real64 UnitarySys::heatingCoilVarSpeedResidual(EnergyPlusData &state,
15879 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
15880 : int CoilIndex,
15881 : Real64 DesOutTemp,
15882 : int UnitarySysNum,
15883 : Real64 CycRatio,
15884 : int SpeedNum,
15885 : HVAC::FanOp const fanOp,
15886 : HVAC::CompressorOp compressorOp,
15887 : bool SuppHeat
15888 :
15889 : )
15890 : {
15891 : // FUNCTION INFORMATION:
15892 : // AUTHOR Fred Buhl
15893 : // DATE WRITTEN September 2002
15894 :
15895 : // PURPOSE OF THIS FUNCTION:
15896 : // Calculates residual function (desired outlet temp - actual outlet temp).
15897 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
15898 :
15899 : // METHODOLOGY EMPLOYED:
15900 : // Calls calc routines of multi Speed or variable Coil to get outlet temperature at the given compressor speed
15901 : // and calculates the residual as defined above
15902 :
15903 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15904 6726 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
15905 : Real64 OnOffAirFlowRatio;
15906 : Real64 SensLoad;
15907 : Real64 LatLoad;
15908 : Real64 QActual;
15909 :
15910 6726 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15911 :
15912 6726 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
15913 6726 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
15914 6726 : if (SuppHeat) {
15915 6726 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
15916 6726 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
15917 : }
15918 :
15919 6726 : switch (heatCoilType) {
15920 0 : case HVAC::CoilDX_MultiSpeedHeating: {
15921 0 : OnOffAirFlowRatio = 1.0;
15922 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
15923 0 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
15924 0 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
15925 0 : } break;
15926 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
15927 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
15928 0 : OnOffAirFlowRatio = 1.0;
15929 0 : SensLoad = 1.0;
15930 0 : LatLoad = -1.0;
15931 : // can't call only the calc routine with these coil types since Init sets air flow rate based on speed num and cycling ratio
15932 0 : VariableSpeedCoils::SimVariableSpeedCoils(
15933 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
15934 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
15935 0 : } break;
15936 6726 : case HVAC::Coil_HeatingElectric_MultiStage: {
15937 6726 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
15938 6726 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
15939 6726 : } break;
15940 0 : case HVAC::Coil_HeatingGas_MultiStage: {
15941 0 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
15942 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
15943 0 : } break;
15944 0 : default: {
15945 0 : assert(false);
15946 : } break;
15947 : }
15948 6726 : return DesOutTemp - OutletAirTemp;
15949 : }
15950 :
15951 0 : Real64 UnitarySys::DXCoilVarSpeedHumRatResidual(EnergyPlusData &state,
15952 : Real64 const SpeedRatio, // compressor speed ratio (1.0 is max, 0.0 is min)
15953 : int CoilIndex,
15954 : Real64 DesOutHumRat,
15955 : int UnitarySysNum,
15956 : Real64 CycRatio,
15957 : int SpeedNum,
15958 : HVAC::FanOp const fanOp,
15959 : HVAC::CompressorOp compressorOp)
15960 : {
15961 : // FUNCTION INFORMATION:
15962 : // AUTHOR Richard Raustad
15963 : // DATE WRITTEN January 2008
15964 :
15965 : // PURPOSE OF THIS FUNCTION:
15966 : // Calculates residual function (desired outlet humrat - actual outlet humrat).
15967 : // DX Coil output depends on the compressor speed which is being varied to zero the residual.
15968 :
15969 : // METHODOLOGY EMPLOYED:
15970 : // Calls calc routines of multi speed or variable speed coils to get outlet humidity ratio at the given compressor speed
15971 : // and calculates the residual as defined above
15972 :
15973 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
15974 0 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio
15975 : Real64 SensLoad;
15976 : Real64 LatLoad;
15977 : Real64 OnOffAirFlowRatio;
15978 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
15979 0 : switch (thisSys.m_CoolingCoilType_Num) {
15980 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
15981 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, SpeedRatio, 1.0);
15982 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
15983 0 : } break;
15984 0 : case HVAC::CoilDX_MultiSpeedCooling: {
15985 0 : OnOffAirFlowRatio = 1.0;
15986 0 : thisSys.setAverageAirFlow(state, SpeedRatio, OnOffAirFlowRatio);
15987 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
15988 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
15989 0 : } break;
15990 0 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
15991 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
15992 0 : SensLoad = -1.0;
15993 0 : LatLoad = 0.0;
15994 0 : OnOffAirFlowRatio = 1.0;
15995 0 : VariableSpeedCoils::SimVariableSpeedCoils(
15996 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
15997 0 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
15998 0 : } break;
15999 0 : default: {
16000 0 : assert(false);
16001 : } break;
16002 : }
16003 0 : return DesOutHumRat - OutletAirHumRat;
16004 : }
16005 :
16006 221067 : Real64 UnitarySys::DXCoilCyclingResidual(EnergyPlusData &state,
16007 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16008 : int CoilIndex,
16009 : Real64 DesOutTemp,
16010 : int UnitarySysNum,
16011 : Real64 SpeedRatio,
16012 : int SpeedNum,
16013 : HVAC::FanOp const fanOp,
16014 : HVAC::CompressorOp compressorOp,
16015 : int AirloopNum,
16016 : bool FirstHVACIteration
16017 :
16018 : )
16019 : {
16020 : // FUNCTION INFORMATION:
16021 : // AUTHOR Fred Buhl
16022 : // DATE WRITTEN September 2002
16023 :
16024 : // PURPOSE OF THIS FUNCTION:
16025 : // Calculates residual function (desired outlet temp - actual outlet temp)
16026 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16027 :
16028 : // METHODOLOGY EMPLOYED:
16029 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16030 : // and calculates the residual as defined above
16031 :
16032 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16033 221067 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16034 : Real64 OnOffAirFlowRatio;
16035 :
16036 221067 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16037 221067 : switch (thisSys.m_CoolingCoilType_Num) {
16038 183530 : case HVAC::CoilDX_CoolingTwoSpeed: {
16039 183530 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16040 0 : thisSys.m_CoolingCycRatio = CycRatio;
16041 0 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16042 0 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16043 : } else {
16044 183530 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16045 : }
16046 183530 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16047 183530 : } break;
16048 122 : case HVAC::CoilDX_MultiSpeedCooling: {
16049 122 : OnOffAirFlowRatio = 1.0;
16050 122 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16051 122 : if (thisSys.m_FanPlace == HVAC::FanPlace::BlowThru) { // must simulate fan if blow through since OnOffFanPartLoadFrac affects fan heat
16052 122 : thisSys.m_CoolingCycRatio = CycRatio;
16053 122 : thisSys.m_CoolingPartLoadFrac = CycRatio;
16054 122 : thisSys.calcPassiveSystem(state, AirloopNum, FirstHVACIteration);
16055 : } else {
16056 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16057 : }
16058 122 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16059 122 : } break;
16060 37415 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16061 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16062 37415 : if (CycRatio == 0.0) compressorOp = HVAC::CompressorOp::Off;
16063 37415 : Real64 dummy = 0.0;
16064 37415 : OnOffAirFlowRatio = 1.0;
16065 37415 : Real64 SensLoad = -1.0;
16066 37415 : VariableSpeedCoils::SimVariableSpeedCoils(
16067 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, dummy, OnOffAirFlowRatio);
16068 37415 : OutletAirTemp = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16069 37415 : } break;
16070 0 : default: {
16071 0 : assert(false);
16072 : } break;
16073 : }
16074 221067 : return DesOutTemp - OutletAirTemp;
16075 : }
16076 :
16077 2904 : Real64 UnitarySys::DXCoilCyclingHumRatResidual(EnergyPlusData &state,
16078 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16079 : int CoilIndex,
16080 : Real64 DesOutHumRat,
16081 : int UnitarySysNum,
16082 : Real64 SpeedRatio,
16083 : int SpeedNum,
16084 : HVAC::FanOp const fanOp,
16085 : HVAC::CompressorOp compressorOp)
16086 : {
16087 :
16088 : // FUNCTION INFORMATION:
16089 : // AUTHOR Fred Buhl
16090 : // DATE WRITTEN September 2002
16091 :
16092 : // PURPOSE OF THIS FUNCTION:
16093 : // Calculates residual function (desired outlet temp - actual outlet temp)
16094 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16095 :
16096 : // METHODOLOGY EMPLOYED:
16097 : // Calls CalcMultiSpeedDXCoil to get outlet temperature at the given cycling ratio
16098 : // and calculates the residual as defined above
16099 :
16100 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16101 2904 : Real64 OutletAirHumRat(0.0); // outlet air humidity ratio [kg/kg]
16102 : Real64 SensLoad;
16103 : Real64 LatLoad;
16104 : Real64 OnOffAirFlowRatio;
16105 :
16106 2904 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16107 2904 : switch (thisSys.m_CoolingCoilType_Num) {
16108 0 : case HVAC::CoilDX_CoolingTwoSpeed: {
16109 0 : DXCoils::CalcMultiSpeedDXCoil(state, CoilIndex, 0.0, CycRatio);
16110 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16111 0 : } break;
16112 0 : case HVAC::CoilDX_MultiSpeedCooling: {
16113 0 : OnOffAirFlowRatio = 1.0;
16114 0 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16115 0 : DXCoils::CalcMultiSpeedDXCoilCooling(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, compressorOp, 0);
16116 0 : OutletAirHumRat = state.dataDXCoils->DXCoilOutletHumRat(CoilIndex);
16117 0 : } break;
16118 2904 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16119 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit: {
16120 2904 : SensLoad = -1.0;
16121 2904 : LatLoad = 0.0;
16122 2904 : OnOffAirFlowRatio = 1.0;
16123 2904 : VariableSpeedCoils::SimVariableSpeedCoils(
16124 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16125 2904 : OutletAirHumRat = state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).HumRat;
16126 2904 : } break;
16127 0 : default: {
16128 0 : assert(false);
16129 : } break;
16130 : }
16131 2904 : return DesOutHumRat - OutletAirHumRat;
16132 : }
16133 :
16134 9 : Real64 UnitarySys::heatingCoilVarSpeedCycResidual(EnergyPlusData &state,
16135 : Real64 const CycRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16136 : int CoilIndex,
16137 : Real64 DesOutTemp,
16138 : int UnitarySysNum,
16139 : Real64 SpeedRatio,
16140 : int SpeedNum,
16141 : HVAC::FanOp const fanOp,
16142 : HVAC::CompressorOp compressorOp,
16143 : bool SuppHeat)
16144 : {
16145 :
16146 : // FUNCTION INFORMATION:
16147 : // AUTHOR Fred Buhl
16148 : // DATE WRITTEN September 2002
16149 :
16150 : // PURPOSE OF THIS FUNCTION:
16151 : // Calculates residual function (desired outlet temp - actual outlet temp)
16152 : // DX Coil output depends on the cycling ratio which is being varied to zero the residual.
16153 :
16154 : // METHODOLOGY EMPLOYED:
16155 : // Calls multi or variable speed coil to get outlet temperature at the given cycling ratio
16156 : // and calculates the residual as defined above
16157 :
16158 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16159 9 : Real64 OutletAirTemp(0.0); // outlet air temperature [C]
16160 : Real64 SensLoad;
16161 : Real64 LatLoad;
16162 : Real64 OnOffAirFlowRatio;
16163 : Real64 QActual;
16164 :
16165 9 : auto &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16166 :
16167 9 : int heatCoilType = thisSys.m_HeatingCoilType_Num;
16168 9 : int heatingCoilOutletNode = thisSys.HeatCoilOutletNodeNum;
16169 9 : if (SuppHeat) {
16170 3 : heatCoilType = thisSys.m_SuppHeatCoilType_Num;
16171 3 : heatingCoilOutletNode = thisSys.SuppCoilOutletNodeNum;
16172 : }
16173 :
16174 9 : switch (heatCoilType) {
16175 6 : case HVAC::CoilDX_MultiSpeedHeating: {
16176 6 : OnOffAirFlowRatio = 1.0;
16177 6 : thisSys.setAverageAirFlow(state, CycRatio, OnOffAirFlowRatio);
16178 6 : DXCoils::CalcMultiSpeedDXCoilHeating(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, 0);
16179 6 : OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(CoilIndex);
16180 6 : } break;
16181 0 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
16182 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit: {
16183 0 : if (CycRatio == 0.0) compressorOp = HVAC::CompressorOp::Off;
16184 0 : SensLoad = -1.0;
16185 0 : LatLoad = 0.0;
16186 0 : OnOffAirFlowRatio = 1.0;
16187 0 : VariableSpeedCoils::SimVariableSpeedCoils(
16188 : state, "", CoilIndex, fanOp, compressorOp, CycRatio, SpeedNum, SpeedRatio, SensLoad, LatLoad, OnOffAirFlowRatio);
16189 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16190 0 : } break;
16191 3 : case HVAC::Coil_HeatingElectric_MultiStage: {
16192 3 : HeatingCoils::CalcMultiStageElectricHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp, QActual, SuppHeat);
16193 3 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16194 3 : } break;
16195 0 : case HVAC::Coil_HeatingGas_MultiStage: {
16196 0 : HeatingCoils::CalcMultiStageGasHeatingCoil(state, CoilIndex, SpeedRatio, CycRatio, SpeedNum, fanOp);
16197 0 : OutletAirTemp = state.dataLoopNodes->Node(heatingCoilOutletNode).Temp;
16198 0 : } break;
16199 0 : default: {
16200 0 : assert(false);
16201 : } break;
16202 : }
16203 :
16204 9 : return DesOutTemp - OutletAirTemp;
16205 : }
16206 :
16207 16398 : Real64 UnitarySys::gasElecHeatingCoilResidual(EnergyPlusData &state,
16208 : Real64 const PartLoadFrac, // Compressor cycling ratio (1.0 is continuous, 0.0 is off)
16209 : int UnitarySysNum,
16210 : bool FirstHVACIteration,
16211 : Real64 desTemp,
16212 : bool SuppHeatingCoilFlag,
16213 : HVAC::FanOp const fanOp,
16214 : Real64 HeatingLoadArg)
16215 : {
16216 :
16217 : // FUNCTION INFORMATION:
16218 : // AUTHOR Chandan Sharma, FSEC
16219 : // DATE WRITTEN February 2013
16220 :
16221 : // PURPOSE OF THIS FUNCTION:
16222 : // Calculates residual function (desired outlet temp - actual outlet temp)
16223 : // hot water Coil output depends on the part load ratio which is being varied to zero the residual.
16224 :
16225 : // METHODOLOGY EMPLOYED:
16226 : // Calls SimulateHeatingCoilComponents to get outlet temperature at the given part load ratio
16227 : // and calculates the residual as defined above
16228 :
16229 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
16230 16398 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16231 16398 : Real64 HeatingLoad = HeatingLoadArg * PartLoadFrac;
16232 : // heating coils using set point control pass DataLoopNode::SensedLoadFlagValue as QCoilReq to indicate temperature control
16233 16398 : if (!SuppHeatingCoilFlag) {
16234 0 : HeatingCoils::SimulateHeatingCoilComponents(
16235 0 : state, thisSys.m_HeatingCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_HeatingCoilIndex, _, _, fanOp, PartLoadFrac);
16236 0 : return desTemp - state.dataLoopNodes->Node(thisSys.HeatCoilOutletNodeNum).Temp;
16237 : } else {
16238 65592 : HeatingCoils::SimulateHeatingCoilComponents(
16239 49194 : state, thisSys.m_SuppHeatCoilName, FirstHVACIteration, HeatingLoad, thisSys.m_SuppHeatCoilIndex, _, true, fanOp, PartLoadFrac);
16240 16398 : return desTemp - state.dataLoopNodes->Node(thisSys.SuppCoilOutletNodeNum).Temp;
16241 : }
16242 : }
16243 :
16244 0 : Real64 UnitarySys::coolWatertoAirHPTempResidual(EnergyPlusData &state,
16245 : Real64 const PartLoadRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
16246 : int UnitarySysNum,
16247 : bool FirstHVACIteration,
16248 : Real64 DesOutTemp,
16249 : Real64 ReqOutput)
16250 : {
16251 :
16252 : // FUNCTION INFORMATION:
16253 : // AUTHOR Chandan Sharma, FSEC
16254 : // DATE WRITTEN January 2013
16255 :
16256 : // PURPOSE OF THIS FUNCTION:
16257 : // Calculates residual function (desired outlet temp - actual outlet temp)
16258 : // Cool water coil output depends on the part load ratio which is being varied to zero the residual.
16259 :
16260 : // METHODOLOGY EMPLOYED:
16261 : // Calls SimWatertoAirHP or SimWatertoAirHPSimple to get outlet humidity ratio at the given cycling ratio
16262 : // and calculates the residual as defined above
16263 :
16264 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16265 :
16266 0 : thisSys.m_CompPartLoadRatio = PartLoadRatio;
16267 :
16268 0 : Real64 dummy = 0.0;
16269 0 : if (thisSys.m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
16270 0 : WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
16271 : blankString,
16272 0 : thisSys.m_CoolingCoilIndex,
16273 : ReqOutput,
16274 : dummy,
16275 : thisSys.m_FanOpMode,
16276 : HVAC::CompressorOp::On,
16277 : PartLoadRatio,
16278 : FirstHVACIteration);
16279 : } else {
16280 0 : WaterToAirHeatPump::SimWatertoAirHP(state,
16281 : blankString,
16282 0 : thisSys.m_CoolingCoilIndex,
16283 : thisSys.MaxCoolAirMassFlow,
16284 : thisSys.m_FanOpMode,
16285 : FirstHVACIteration,
16286 0 : thisSys.m_InitHeatPump,
16287 : ReqOutput,
16288 : dummy,
16289 : HVAC::CompressorOp::Off,
16290 : PartLoadRatio);
16291 : }
16292 0 : return DesOutTemp - state.dataLoopNodes->Node(thisSys.CoolCoilOutletNodeNum).Temp;
16293 : }
16294 :
16295 0 : Real64 UnitarySys::calcUnitarySystemWaterFlowResidual(EnergyPlusData &state,
16296 : Real64 const PartLoadRatio, // coil part load ratio
16297 : int UnitarySysNum,
16298 : bool FirstHVACIteration,
16299 : Real64 QZnReq,
16300 : int AirControlNode,
16301 : Real64 OnOffAirFlowRat,
16302 : int AirLoopNum,
16303 : int WaterControlNode,
16304 : Real64 highWaterMdot,
16305 : Real64 lowSpeedRatio,
16306 : Real64 airMdot,
16307 : Real64 par13_SATempTarget,
16308 : Real64 systemMaxAirFlowRate,
16309 : Real64 par15_LoadType,
16310 : Real64 par16_IterationMethod)
16311 : {
16312 :
16313 : // FUNCTION INFORMATION:
16314 : // AUTHOR Richard Raustad, FSEC
16315 : // DATE WRITTEN January 2017
16316 :
16317 : // PURPOSE OF THIS SUBROUTINE:
16318 : // To calculate the part-load ratio for the UnitarySystem coil with varying part load ratio
16319 :
16320 : // METHODOLOGY EMPLOYED:
16321 : // Use SolveRoot to CALL this Function to converge on a solution
16322 :
16323 0 : Real64 HeatCoilLoad = 0.0;
16324 0 : Real64 SupHeaterLoad = 0.0;
16325 :
16326 : // Convert parameters to usable variables
16327 0 : UnitarySys &thisSys = state.dataUnitarySystems->unitarySys[UnitarySysNum];
16328 0 : Real64 SATempTarget = 0.0;
16329 0 : bool LoadIsTarget = false;
16330 0 : if (par13_SATempTarget == 0.0) {
16331 0 : LoadIsTarget = true;
16332 : } else {
16333 0 : SATempTarget = par13_SATempTarget;
16334 : }
16335 0 : bool iterateOnAirOnly = (par16_IterationMethod > 1.0);
16336 0 : bool coolingLoad = (par15_LoadType > 0.0);
16337 :
16338 0 : bool HXUnitOn = true;
16339 :
16340 0 : if (iterateOnAirOnly) {
16341 :
16342 : // set air flow rate bounded by low speed and high speed air flow rates
16343 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot * (lowSpeedRatio + (PartLoadRatio * (1.0 - lowSpeedRatio)));
16344 : // FanPartLoadRatio is used to pass info over to function SetAverageAirFlow since air and coil PLR are disassociated in the model
16345 : // FanPartLoadRatio is a report variable that is updated (overwritten) in ReportUnitarySystem
16346 0 : thisSys.FanPartLoadRatio = PartLoadRatio;
16347 : // if( WaterControlNode > 0 ) Node( WaterControlNode ).MassFlowRate = highWaterMdot;
16348 :
16349 : } else {
16350 :
16351 0 : state.dataLoopNodes->Node(AirControlNode).MassFlowRate = airMdot;
16352 0 : if (lowSpeedRatio != 1.0) {
16353 : // division by zero when lowSpeedRatio == 1.0
16354 0 : thisSys.FanPartLoadRatio =
16355 0 : max(0.0, ((airMdot - (systemMaxAirFlowRate * lowSpeedRatio)) / ((1.0 - lowSpeedRatio) * systemMaxAirFlowRate)));
16356 : } else {
16357 0 : thisSys.FanPartLoadRatio = 1.0;
16358 : }
16359 0 : if (WaterControlNode > 0) {
16360 0 : Real64 waterMdot = highWaterMdot * PartLoadRatio;
16361 0 : state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = waterMdot;
16362 : }
16363 : }
16364 :
16365 0 : Real64 coolingPLR = 0.0;
16366 0 : Real64 heatingPLR = 0.0;
16367 :
16368 0 : if (WaterControlNode > 0 && WaterControlNode == thisSys.CoolCoilFluidInletNode) {
16369 : // cooling load using water cooling coil
16370 0 : coolingPLR = PartLoadRatio;
16371 0 : thisSys.m_CoolingPartLoadFrac = PartLoadRatio;
16372 0 : if (thisSys.MaxCoolCoilFluidFlow > 0.0)
16373 0 : thisSys.CoolCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxCoolCoilFluidFlow;
16374 0 : } else if (WaterControlNode > 0 && WaterControlNode == thisSys.HeatCoilFluidInletNode) {
16375 : // heating load using water heating coil
16376 0 : heatingPLR = PartLoadRatio;
16377 0 : thisSys.m_HeatingPartLoadFrac = PartLoadRatio;
16378 0 : if (thisSys.MaxHeatCoilFluidFlow > 0.0)
16379 0 : thisSys.HeatCoilWaterFlowRatio = state.dataLoopNodes->Node(WaterControlNode).MassFlowRate / thisSys.MaxHeatCoilFluidFlow;
16380 0 : } else if (coolingLoad) { // non-water coil with cooling load
16381 0 : coolingPLR = PartLoadRatio;
16382 0 : thisSys.m_CoolingPartLoadFrac = coolingPLR;
16383 : } else { // must be non-water coil with heating load
16384 0 : heatingPLR = PartLoadRatio;
16385 0 : thisSys.m_HeatingPartLoadFrac = heatingPLR;
16386 : }
16387 :
16388 0 : Real64 SensOutput = 0.0;
16389 0 : Real64 LatOutput = 0.0;
16390 0 : thisSys.calcUnitarySystemToLoad(state,
16391 : AirLoopNum,
16392 : FirstHVACIteration,
16393 : coolingPLR,
16394 : heatingPLR,
16395 : OnOffAirFlowRat,
16396 : SensOutput,
16397 : LatOutput,
16398 : HXUnitOn,
16399 : HeatCoilLoad,
16400 : SupHeaterLoad,
16401 : HVAC::CompressorOp::On);
16402 :
16403 0 : if (LoadIsTarget) {
16404 : // Calculate residual based on output magnitude
16405 0 : if (std::abs(QZnReq) <= 100.0) {
16406 0 : return (SensOutput - QZnReq) / 100.0;
16407 : } else {
16408 0 : return (SensOutput - QZnReq) / QZnReq;
16409 : }
16410 : } else {
16411 : // Calculate residual based on outlet temperature
16412 0 : return (state.dataLoopNodes->Node(thisSys.AirOutNode).Temp - SATempTarget) * 10.0;
16413 : }
16414 : }
16415 :
16416 9508396 : void UnitarySys::setSpeedVariables(EnergyPlusData &state,
16417 : bool const SensibleLoad, // True when meeting a sensible load (not a moisture load)
16418 : Real64 const PartLoadRatio // operating PLR
16419 : )
16420 : {
16421 :
16422 : // SUBROUTINE INFORMATION:
16423 : // AUTHOR Richard Raustad, FSEC
16424 : // DATE WRITTEN February 2013
16425 :
16426 : // PURPOSE OF THIS SUBROUTINE:
16427 : // This subroutine determines operating PLR and calculates the load based system output.
16428 :
16429 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16430 9508396 : Real64 OnOffAirFlowRatio = 0.0; // compressor on to average flow rate
16431 :
16432 9508396 : if (state.dataUnitarySystems->HeatingLoad && SensibleLoad) {
16433 4104647 : this->m_CoolingSpeedRatio = 0.0;
16434 4104647 : this->m_CoolingCycRatio = 0.0;
16435 4104647 : if (this->m_MultiSpeedHeatingCoil || this->m_VarSpeedHeatingCoil) {
16436 288741 : if (this->m_HeatingSpeedNum <= 1) {
16437 151293 : this->m_HeatingSpeedRatio = 0.0;
16438 151293 : this->m_HeatingCycRatio = PartLoadRatio;
16439 151293 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16440 : } else {
16441 137448 : if (this->m_SingleMode == 0) {
16442 137448 : this->m_HeatingSpeedRatio = PartLoadRatio;
16443 137448 : this->m_HeatingCycRatio = 1.0;
16444 : } else {
16445 0 : this->m_HeatingSpeedRatio = 1.0;
16446 0 : this->m_HeatingCycRatio = PartLoadRatio;
16447 : }
16448 : }
16449 3815906 : } else if (this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
16450 3686133 : this->m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
16451 211893 : this->m_CompPartLoadRatio = PartLoadRatio;
16452 211893 : this->m_HeatingSpeedNum = 0;
16453 : }
16454 : } else {
16455 5403749 : this->m_HeatingSpeedRatio = 0.0;
16456 5403749 : this->m_HeatingCycRatio = 0.0;
16457 5403749 : if (this->m_DiscreteSpeedCoolingCoil || this->m_ContSpeedCoolingCoil) {
16458 2757605 : if (this->m_CoolingSpeedNum <= 1) {
16459 1195531 : this->m_CoolingSpeedRatio = 0.0;
16460 1195531 : this->m_CoolingCycRatio = PartLoadRatio;
16461 1195531 : state.dataHVACGlobal->MSHPMassFlowRateLow = state.dataUnitarySystems->CompOnMassFlow;
16462 : } else {
16463 1562074 : if (this->m_SingleMode == 0) {
16464 1552930 : this->m_CoolingSpeedRatio = PartLoadRatio;
16465 1552930 : this->m_CoolingCycRatio = 1.0;
16466 : } else {
16467 9144 : this->m_CoolingSpeedRatio = 1.0;
16468 9144 : this->m_CoolingCycRatio = PartLoadRatio;
16469 : }
16470 : }
16471 2646144 : } else if (this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
16472 2507507 : this->m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
16473 194077 : this->m_CompPartLoadRatio = PartLoadRatio;
16474 194077 : this->m_CoolingSpeedNum = 0;
16475 2452067 : } else if (this->m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
16476 0 : if (this->m_CoolingSpeedNum == 1) {
16477 0 : this->m_CoolingSpeedRatio = 0.0;
16478 0 : this->m_CoolingCycRatio = PartLoadRatio;
16479 : } else {
16480 0 : this->m_CoolingSpeedRatio = PartLoadRatio;
16481 0 : this->m_CoolingCycRatio = 1.0;
16482 : }
16483 : } else {
16484 2452067 : this->m_CoolingSpeedNum = 0;
16485 : }
16486 : }
16487 9508396 : OnOffAirFlowRatio = 1.0;
16488 9508396 : this->setAverageAirFlow(state, PartLoadRatio, OnOffAirFlowRatio);
16489 9508396 : }
16490 :
16491 16 : void UnitarySys::checkUnitarySysCoilInOASysExists(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum)
16492 : {
16493 :
16494 : // SUBROUTINE INFORMATION:
16495 : // AUTHOR Chandan Sharma
16496 : // DATE WRITTEN April 2013
16497 :
16498 : // PURPOSE OF THIS SUBROUTINE:
16499 : // After making sure get input is done, checks if the Coil System DX coil is in the
16500 : // OA System. IF exists then the DX cooling coil is 100% DOAS DX coil.
16501 : // METHODOLOGY EMPLOYED:
16502 : // Based on CheckDXCoolingCoilInOASysExists by Bereket Nigusse
16503 :
16504 : // SUBROUTINE PARAMETER DEFINITIONS:
16505 : static constexpr std::string_view RoutineName("CheckUnitarySysCoilInOASysExists: "); // include trailing blank space
16506 :
16507 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
16508 16 : if (state.dataUnitarySystems->getInputOnceFlag) {
16509 2 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16510 2 : state.dataUnitarySystems->getInputOnceFlag = false;
16511 : }
16512 :
16513 16 : if (state.dataUnitarySystems->numUnitarySystems > 0) {
16514 16 : bool UnitarySysFound = false;
16515 40 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16516 40 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16517 16 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten)
16518 8 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16519 16 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ISHundredPercentDOASDXCoil) {
16520 0 : if (!(state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed ||
16521 0 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilType_Num ==
16522 : HVAC::Coil_CoolingWaterToAirHPVSEquationFit)) {
16523 0 : DXCoils::SetDXCoilTypeData(state, state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolingCoilName);
16524 : }
16525 : }
16526 16 : UnitarySysFound = true;
16527 16 : break;
16528 : }
16529 : }
16530 16 : if (!UnitarySysFound) {
16531 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16532 : }
16533 : } else {
16534 0 : ShowSevereError(state, format("{}System not found = UnitarySystem \"{}\"", RoutineName, UnitarySysName));
16535 : }
16536 16 : }
16537 :
16538 217 : void UnitarySys::getUnitarySysHeatCoolCoil(EnergyPlusData &state,
16539 : std::string_view UnitarySysName, // Name of Unitary System object
16540 : bool &CoolingCoil, // Cooling coil exists
16541 : bool &HeatingCoil, // Heating coil exists
16542 : int const ZoneOAUnitNum // index to zone OA unit
16543 : )
16544 : {
16545 :
16546 : // FUNCTION INFORMATION:
16547 : // AUTHOR Chandan Sharma
16548 : // DATE WRITTEN April 2013
16549 :
16550 : // PURPOSE OF THIS FUNCTION:
16551 : // Determined weather Unitary system has heating or cooling coils
16552 :
16553 217 : if (state.dataUnitarySystems->getInputOnceFlag) {
16554 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16555 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16556 : }
16557 :
16558 926 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16559 926 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16560 217 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_ThisSysInputShouldBeGotten)
16561 109 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16562 433 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_CoolCoilExists &&
16563 216 : !state.dataUnitarySystems->unitarySys[UnitarySysNum].m_WaterHRPlantLoopModel) {
16564 216 : CoolingCoil = true;
16565 : }
16566 219 : if (state.dataUnitarySystems->unitarySys[UnitarySysNum].m_HeatCoilExists ||
16567 2 : state.dataUnitarySystems->unitarySys[UnitarySysNum].m_SuppCoilExists) {
16568 215 : HeatingCoil = true;
16569 : }
16570 217 : break;
16571 : }
16572 : }
16573 217 : }
16574 :
16575 0 : int UnitarySys::getAirInNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16576 : {
16577 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16578 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16579 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16580 : }
16581 0 : int airNode = 0;
16582 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16583 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16584 0 : airNode = this->AirInNode;
16585 0 : break;
16586 : }
16587 : }
16588 0 : if (airNode == 0) errFlag = true;
16589 0 : return airNode;
16590 : }
16591 :
16592 6 : int getZoneEqIndex(EnergyPlusData &state, std::string const &UnitarySysName, DataZoneEquipment::ZoneEquipType zoneEquipType, int const OAUnitNum)
16593 : {
16594 :
16595 6 : if (state.dataUnitarySystems->getInputOnceFlag) {
16596 0 : UnitarySystems::UnitarySys::getUnitarySystemInput(state, UnitarySysName, true, OAUnitNum);
16597 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16598 : }
16599 :
16600 6 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16601 6 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16602 6 : if (zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner ||
16603 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump ||
16604 0 : zoneEquipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir ||
16605 : zoneEquipType == DataZoneEquipment::ZoneEquipType::UnitarySystem) {
16606 6 : return UnitarySysNum;
16607 : }
16608 : }
16609 : }
16610 0 : return -1;
16611 : }
16612 :
16613 0 : int UnitarySys::getAirOutNode(EnergyPlusData &state, std::string_view UnitarySysName, int const ZoneOAUnitNum, bool &errFlag)
16614 : {
16615 0 : if (state.dataUnitarySystems->getInputOnceFlag) {
16616 0 : getUnitarySystemInput(state, UnitarySysName, false, ZoneOAUnitNum);
16617 0 : state.dataUnitarySystems->getInputOnceFlag = false;
16618 : }
16619 0 : int airNode = 0;
16620 0 : for (int UnitarySysNum = 0; UnitarySysNum < state.dataUnitarySystems->numUnitarySystems; ++UnitarySysNum) {
16621 0 : if (Util::SameString(UnitarySysName, state.dataUnitarySystems->unitarySys[UnitarySysNum].Name)) {
16622 0 : airNode = this->AirOutNode;
16623 0 : break;
16624 : }
16625 : }
16626 0 : if (airNode == 0) errFlag = true;
16627 0 : return airNode;
16628 : }
16629 :
16630 70540 : int UnitarySys::getAirOutletNode()
16631 : {
16632 70540 : return this->AirOutNode;
16633 : }
16634 :
16635 70540 : int UnitarySys::getMixerOANode()
16636 : {
16637 70540 : return this->m_OAMixerNodes[0];
16638 : }
16639 :
16640 70540 : int UnitarySys::getMixerMixNode()
16641 : {
16642 70540 : return this->m_OAMixerNodes[3];
16643 : }
16644 :
16645 70540 : int UnitarySys::getMixerRetNode()
16646 : {
16647 70540 : return this->m_OAMixerNodes[2];
16648 : }
16649 :
16650 218 : int UnitarySys::getEquipIndex()
16651 : {
16652 218 : return this->m_EquipCompNum;
16653 : }
16654 :
16655 3 : bool searchZoneInletNodes(EnergyPlusData &state, int nodeToFind, int &ZoneEquipConfigIndex, int &InletNodeIndex)
16656 : {
16657 13 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16658 23 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++ZoneInletNum) {
16659 13 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(ZoneInletNum) == nodeToFind) {
16660 3 : ZoneEquipConfigIndex = ControlledZoneNum;
16661 3 : InletNodeIndex = ZoneInletNum;
16662 3 : return true;
16663 : }
16664 : }
16665 : }
16666 0 : return false;
16667 : }
16668 :
16669 215 : bool searchZoneInletNodesByEquipmentIndex(EnergyPlusData &state, int nodeToFind, int zoneEquipmentIndex)
16670 : {
16671 230 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).NumInletNodes; ++ZoneInletNum) {
16672 230 : if (state.dataZoneEquip->ZoneEquipConfig(zoneEquipmentIndex).InletNode(ZoneInletNum) == nodeToFind) {
16673 215 : return true;
16674 : }
16675 : }
16676 0 : return false;
16677 : }
16678 :
16679 202 : bool searchZoneInletNodeAirLoopNum(EnergyPlusData &state, int airLoopNumToFind, int ZoneEquipConfigIndex, int &InletNodeIndex)
16680 : {
16681 202 : for (int ZoneInletNum = 1; ZoneInletNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).NumInletNodes; ++ZoneInletNum) {
16682 202 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigIndex).InletNodeAirLoopNum(ZoneInletNum) == airLoopNumToFind) {
16683 202 : InletNodeIndex = ZoneInletNum;
16684 202 : return true;
16685 : }
16686 : }
16687 0 : return false;
16688 : }
16689 :
16690 218 : bool searchExhaustNodes(EnergyPlusData &state, const int nodeToFind, int &ZoneEquipConfigIndex, int &ExhaustNodeIndex)
16691 : {
16692 4600 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
16693 7548 : for (int ZoneExhNum = 1; ZoneExhNum <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes; ++ZoneExhNum) {
16694 3166 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ExhaustNode(ZoneExhNum) == nodeToFind) {
16695 215 : ZoneEquipConfigIndex = ControlledZoneNum;
16696 215 : ExhaustNodeIndex = ZoneExhNum;
16697 215 : return true;
16698 : }
16699 : }
16700 : }
16701 3 : return false;
16702 : }
16703 :
16704 218 : void UnitarySys::setSystemParams(EnergyPlusData &state, Real64 &TotalFloorAreaOnAirLoop, const std::string &thisObjectName)
16705 : {
16706 218 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum);
16707 218 : this->NodeNumOfControlledZone = zoneEquipConfig.ZoneNode;
16708 218 : TotalFloorAreaOnAirLoop = state.dataHeatBal->Zone(this->ControlZoneNum).FloorArea;
16709 218 : this->m_AirLoopEquipment = false;
16710 218 : if (zoneEquipConfig.EquipListIndex == 0) return;
16711 :
16712 218 : auto &zoneEquipList = state.dataZoneEquip->ZoneEquipList(zoneEquipConfig.EquipListIndex);
16713 474 : for (int EquipNum = 1; EquipNum <= zoneEquipList.NumOfEquipTypes; ++EquipNum) {
16714 298 : if ((zoneEquipList.EquipType(EquipNum) != DataZoneEquipment::ZoneEquipType::UnitarySystem) ||
16715 21 : zoneEquipList.EquipName(EquipNum) != thisObjectName) {
16716 256 : continue;
16717 : }
16718 21 : this->m_ZoneSequenceCoolingNum = zoneEquipList.CoolingPriority(EquipNum);
16719 21 : this->m_ZoneSequenceHeatingNum = zoneEquipList.HeatingPriority(EquipNum);
16720 21 : break;
16721 : }
16722 : }
16723 :
16724 404 : bool searchTotalComponents(EnergyPlusData &state,
16725 : SimAirServingZones::CompType compTypeToFind,
16726 : std::string_view objectNameToFind,
16727 : int &compIndex,
16728 : int &branchIndex,
16729 : int &airLoopIndex)
16730 : {
16731 1201 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
16732 1988 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
16733 4530 : for (int CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
16734 : ++CompNum) {
16735 3733 : if (compTypeToFind != state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).CompType_Num)
16736 2598 : continue;
16737 1135 : if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
16738 : objectNameToFind)) {
16739 394 : compIndex = CompNum;
16740 394 : branchIndex = BranchNum;
16741 394 : airLoopIndex = AirLoopNum;
16742 394 : return true;
16743 : }
16744 : }
16745 : }
16746 : }
16747 10 : return false;
16748 : }
16749 :
16750 16 : bool getUnitarySystemNodeNumber(EnergyPlusData &state, int const nodeNumber)
16751 : {
16752 16 : for (int unitarySysIndex = 0; unitarySysIndex <= state.dataUnitarySystems->numUnitarySystems - 1; ++unitarySysIndex) {
16753 0 : auto &unitarySys = state.dataUnitarySystems->unitarySys[unitarySysIndex];
16754 :
16755 0 : int FanInletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->inletNodeNum;
16756 0 : int FanOutletNodeIndex = state.dataFans->fans(unitarySys.m_FanIndex)->outletNodeNum;
16757 :
16758 0 : bool noUnitarySysOutdoorAir = false;
16759 0 : if (unitarySys.m_CoolOutAirVolFlow == 0 && unitarySys.m_HeatOutAirVolFlow == 0 && unitarySys.m_NoCoolHeatOutAirVolFlow == 0) {
16760 0 : noUnitarySysOutdoorAir = true;
16761 : }
16762 :
16763 0 : if (unitarySys.m_sysType == UnitarySys::SysType::PackagedWSHP || unitarySys.m_sysType == UnitarySys::SysType::PackagedAC ||
16764 0 : unitarySys.m_sysType == UnitarySys::SysType::PackagedHP) {
16765 0 : if (noUnitarySysOutdoorAir && (nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex ||
16766 0 : nodeNumber == unitarySys.AirInNode || nodeNumber == unitarySys.m_OAMixerNodes[0] ||
16767 0 : nodeNumber == unitarySys.m_OAMixerNodes[1] || nodeNumber == unitarySys.m_OAMixerNodes[2]) ||
16768 0 : nodeNumber == unitarySys.m_OAMixerNodes[3] || nodeNumber == unitarySys.CoolCoilOutletNodeNum ||
16769 0 : nodeNumber == unitarySys.HeatCoilOutletNodeNum) {
16770 0 : return true;
16771 : }
16772 : }
16773 : }
16774 16 : return false;
16775 : }
16776 :
16777 165 : void setupAllOutputVars(EnergyPlusData &state, int const numAllSystemTypes)
16778 : {
16779 : // setup reports only once
16780 : // all report variable are set up here after all systems are allocated.
16781 : // UnitarySystem now models other equipment types, any new reports may be setup here.
16782 165 : if (numAllSystemTypes == state.dataUnitarySystems->numUnitarySystems) {
16783 787 : for (int sysNum = 0; sysNum < state.dataUnitarySystems->numUnitarySystems; ++sysNum) {
16784 622 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_sysType) {
16785 130 : case UnitarySys::SysType::Unitary:
16786 : // Setup Report variables for the Unitary System that are not reported in the components themselves
16787 260 : SetupOutputVariable(state,
16788 : "Unitary System Part Load Ratio",
16789 : Constant::Units::None,
16790 130 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
16791 : OutputProcessor::TimeStepType::System,
16792 : OutputProcessor::StoreType::Average,
16793 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16794 260 : SetupOutputVariable(state,
16795 : "Unitary System Total Cooling Rate",
16796 : Constant::Units::W,
16797 130 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
16798 : OutputProcessor::TimeStepType::System,
16799 : OutputProcessor::StoreType::Average,
16800 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16801 260 : SetupOutputVariable(state,
16802 : "Unitary System Sensible Cooling Rate",
16803 : Constant::Units::W,
16804 130 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
16805 : OutputProcessor::TimeStepType::System,
16806 : OutputProcessor::StoreType::Average,
16807 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16808 260 : SetupOutputVariable(state,
16809 : "Unitary System Latent Cooling Rate",
16810 : Constant::Units::W,
16811 130 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
16812 : OutputProcessor::TimeStepType::System,
16813 : OutputProcessor::StoreType::Average,
16814 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16815 260 : SetupOutputVariable(state,
16816 : "Unitary System Total Heating Rate",
16817 : Constant::Units::W,
16818 130 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
16819 : OutputProcessor::TimeStepType::System,
16820 : OutputProcessor::StoreType::Average,
16821 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16822 260 : SetupOutputVariable(state,
16823 : "Unitary System Sensible Heating Rate",
16824 : Constant::Units::W,
16825 130 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
16826 : OutputProcessor::TimeStepType::System,
16827 : OutputProcessor::StoreType::Average,
16828 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16829 260 : SetupOutputVariable(state,
16830 : "Unitary System Latent Heating Rate",
16831 : Constant::Units::W,
16832 130 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
16833 : OutputProcessor::TimeStepType::System,
16834 : OutputProcessor::StoreType::Average,
16835 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16836 260 : SetupOutputVariable(state,
16837 : "Unitary System Ancillary Electricity Rate",
16838 : Constant::Units::W,
16839 130 : state.dataUnitarySystems->unitarySys[sysNum].m_TotalAuxElecPower,
16840 : OutputProcessor::TimeStepType::System,
16841 : OutputProcessor::StoreType::Average,
16842 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16843 130 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolCoilExists) {
16844 258 : SetupOutputVariable(state,
16845 : "Unitary System Cooling Ancillary Electricity Energy",
16846 : Constant::Units::J,
16847 129 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingAuxElecConsumption,
16848 : OutputProcessor::TimeStepType::System,
16849 : OutputProcessor::StoreType::Sum,
16850 129 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16851 : Constant::eResource::Electricity,
16852 : OutputProcessor::Group::HVAC,
16853 : OutputProcessor::EndUseCat::Cooling);
16854 : }
16855 146 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatCoilExists ||
16856 16 : state.dataUnitarySystems->unitarySys[sysNum].m_SuppCoilExists) {
16857 228 : SetupOutputVariable(state,
16858 : "Unitary System Heating Ancillary Electricity Energy",
16859 : Constant::Units::J,
16860 114 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingAuxElecConsumption,
16861 : OutputProcessor::TimeStepType::System,
16862 : OutputProcessor::StoreType::Sum,
16863 114 : state.dataUnitarySystems->unitarySys[sysNum].Name,
16864 : Constant::eResource::Electricity,
16865 : OutputProcessor::Group::HVAC,
16866 : OutputProcessor::EndUseCat::Heating);
16867 : }
16868 :
16869 260 : SetupOutputVariable(state,
16870 : "Unitary System Electricity Rate",
16871 : Constant::Units::W,
16872 130 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
16873 : OutputProcessor::TimeStepType::System,
16874 : OutputProcessor::StoreType::Average,
16875 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16876 260 : SetupOutputVariable(state,
16877 : "Unitary System Electricity Energy",
16878 : Constant::Units::J,
16879 130 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
16880 : OutputProcessor::TimeStepType::System,
16881 : OutputProcessor::StoreType::Sum,
16882 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16883 :
16884 : // report predicted load as determined by Unitary System for load control only
16885 130 : if (state.dataUnitarySystems->unitarySys[sysNum].m_ControlType != UnitarySys::UnitarySysCtrlType::Setpoint) {
16886 244 : SetupOutputVariable(state,
16887 : "Unitary System Predicted Sensible Load to Setpoint Heat Transfer Rate",
16888 : Constant::Units::W,
16889 122 : state.dataUnitarySystems->unitarySys[sysNum].m_SensibleLoadPredicted,
16890 : OutputProcessor::TimeStepType::System,
16891 : OutputProcessor::StoreType::Average,
16892 122 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16893 244 : SetupOutputVariable(state,
16894 : "Unitary System Predicted Moisture Load to Setpoint Heat Transfer Rate",
16895 : Constant::Units::W,
16896 122 : state.dataUnitarySystems->unitarySys[sysNum].m_MoistureLoadPredicted,
16897 : OutputProcessor::TimeStepType::System,
16898 : OutputProcessor::StoreType::Average,
16899 122 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16900 : }
16901 :
16902 : // IF(UnitarySystem(UnitarySysNum)%m_DehumidControlType_Num .EQ. dehumidm_ControlType::CoolReheat)THEN
16903 260 : SetupOutputVariable(state,
16904 : "Unitary System Dehumidification Induced Heating Demand Rate",
16905 : Constant::Units::W,
16906 130 : state.dataUnitarySystems->unitarySys[sysNum].m_DehumidInducedHeatingDemandRate,
16907 : OutputProcessor::TimeStepType::System,
16908 : OutputProcessor::StoreType::Average,
16909 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16910 : // END IF
16911 :
16912 130 : if (state.dataUnitarySystems->unitarySys[sysNum].m_FanExists) {
16913 256 : SetupOutputVariable(state,
16914 : "Unitary System Fan Part Load Ratio",
16915 : Constant::Units::None,
16916 128 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
16917 : OutputProcessor::TimeStepType::System,
16918 : OutputProcessor::StoreType::Average,
16919 128 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16920 : }
16921 :
16922 260 : SetupOutputVariable(state,
16923 : "Unitary System Compressor Part Load Ratio",
16924 : Constant::Units::None,
16925 130 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
16926 : OutputProcessor::TimeStepType::System,
16927 : OutputProcessor::StoreType::Average,
16928 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16929 :
16930 130 : SetupOutputVariable(state,
16931 : "Unitary System Frost Control Status",
16932 : Constant::Units::None,
16933 130 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
16934 : OutputProcessor::TimeStepType::System,
16935 : OutputProcessor::StoreType::Average,
16936 130 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16937 :
16938 130 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num) {
16939 90 : case HVAC::CoilDX_MultiSpeedCooling:
16940 : case HVAC::CoilDX_Cooling: {
16941 90 : if (state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecActive) {
16942 0 : SetupOutputVariable(state,
16943 : "Unitary System Heat Recovery Rate",
16944 : Constant::Units::W,
16945 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryRate,
16946 : OutputProcessor::TimeStepType::System,
16947 : OutputProcessor::StoreType::Average,
16948 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16949 0 : SetupOutputVariable(state,
16950 : "Unitary System Heat Recovery Inlet Temperature",
16951 : Constant::Units::C,
16952 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryInletTemp,
16953 : OutputProcessor::TimeStepType::System,
16954 : OutputProcessor::StoreType::Average,
16955 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16956 0 : SetupOutputVariable(state,
16957 : "Unitary System Heat Recovery Outlet Temperature",
16958 : Constant::Units::C,
16959 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryOutletTemp,
16960 : OutputProcessor::TimeStepType::System,
16961 : OutputProcessor::StoreType::Average,
16962 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16963 0 : SetupOutputVariable(state,
16964 : "Unitary System Heat Recovery Fluid Mass Flow Rate",
16965 : Constant::Units::kg_s,
16966 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryMassFlowRate,
16967 : OutputProcessor::TimeStepType::System,
16968 : OutputProcessor::StoreType::Average,
16969 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16970 0 : SetupOutputVariable(state,
16971 : "Unitary System Heat Recovery Energy",
16972 : Constant::Units::J,
16973 0 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatRecoveryEnergy,
16974 : OutputProcessor::TimeStepType::System,
16975 : OutputProcessor::StoreType::Sum,
16976 0 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16977 : }
16978 90 : } break;
16979 10 : case HVAC::Coil_CoolingAirToAirVariableSpeed:
16980 : case HVAC::Coil_CoolingWaterToAirHPVSEquationFit:
16981 : case HVAC::Coil_CoolingWaterToAirHPSimple:
16982 : case HVAC::Coil_CoolingWaterToAirHP: {
16983 20 : SetupOutputVariable(state,
16984 : "Unitary System Requested Sensible Cooling Rate",
16985 : Constant::Units::W,
16986 10 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilSensDemand,
16987 : OutputProcessor::TimeStepType::System,
16988 : OutputProcessor::StoreType::Average,
16989 10 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16990 20 : SetupOutputVariable(state,
16991 : "Unitary System Requested Latent Cooling Rate",
16992 : Constant::Units::W,
16993 10 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilLatentDemand,
16994 : OutputProcessor::TimeStepType::System,
16995 : OutputProcessor::StoreType::Average,
16996 10 : state.dataUnitarySystems->unitarySys[sysNum].Name);
16997 10 : } break;
16998 30 : default:
16999 30 : break;
17000 : }
17001 :
17002 130 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex >= 0) {
17003 182 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling &&
17004 52 : state.dataCoilCooingDX->coilCoolingDXs[state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilIndex]
17005 52 : .SubcoolReheatFlag) {
17006 2 : SetupOutputVariable(state,
17007 : "Unitary System Zone Load Sensible Heat Ratio",
17008 : Constant::Units::None,
17009 1 : state.dataUnitarySystems->unitarySys[sysNum].LoadSHR,
17010 : OutputProcessor::TimeStepType::System,
17011 : OutputProcessor::StoreType::Average,
17012 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17013 2 : SetupOutputVariable(state,
17014 : "Unitary System Cooling Coil Load Sensible Heat Ratio",
17015 : Constant::Units::None,
17016 1 : state.dataUnitarySystems->unitarySys[sysNum].CoilSHR,
17017 : OutputProcessor::TimeStepType::System,
17018 : OutputProcessor::StoreType::Average,
17019 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17020 : }
17021 : }
17022 :
17023 130 : switch (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num) {
17024 8 : case HVAC::Coil_HeatingAirToAirVariableSpeed:
17025 : case HVAC::Coil_HeatingWaterToAirHPVSEquationFit:
17026 : case HVAC::Coil_HeatingWaterToAirHPSimple:
17027 : case HVAC::Coil_HeatingWaterToAirHP: {
17028 16 : SetupOutputVariable(state,
17029 : "Unitary System Requested Heating Rate",
17030 : Constant::Units::W,
17031 8 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilSensDemand,
17032 : OutputProcessor::TimeStepType::System,
17033 : OutputProcessor::StoreType::Average,
17034 8 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17035 8 : } break;
17036 122 : default:
17037 122 : break;
17038 : }
17039 :
17040 130 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17041 92 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed ||
17042 92 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling ||
17043 40 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17044 261 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage ||
17045 39 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
17046 182 : SetupOutputVariable(state,
17047 : "Unitary System DX Coil Cycling Ratio",
17048 : Constant::Units::None,
17049 91 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17050 : OutputProcessor::TimeStepType::System,
17051 : OutputProcessor::StoreType::Average,
17052 91 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17053 182 : SetupOutputVariable(state,
17054 : "Unitary System DX Coil Speed Ratio",
17055 : Constant::Units::None,
17056 91 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17057 : OutputProcessor::TimeStepType::System,
17058 : OutputProcessor::StoreType::Average,
17059 91 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17060 91 : SetupOutputVariable(state,
17061 : "Unitary System DX Coil Speed Level",
17062 : Constant::Units::None,
17063 91 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17064 : OutputProcessor::TimeStepType::System,
17065 : OutputProcessor::StoreType::Average,
17066 91 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17067 : }
17068 :
17069 130 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWater ||
17070 113 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterDetailed) &&
17071 259 : state.dataUnitarySystems->unitarySys[sysNum].m_DiscreteSpeedCoolingCoil) ||
17072 129 : (state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWater &&
17073 1 : state.dataUnitarySystems->unitarySys[sysNum].m_MultiSpeedHeatingCoil)) {
17074 2 : SetupOutputVariable(state,
17075 : "Unitary System Water Coil Cycling Ratio",
17076 : Constant::Units::None,
17077 1 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17078 : OutputProcessor::TimeStepType::System,
17079 : OutputProcessor::StoreType::Average,
17080 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17081 2 : SetupOutputVariable(state,
17082 : "Unitary System Water Coil Speed Ratio",
17083 : Constant::Units::None,
17084 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17085 : OutputProcessor::TimeStepType::System,
17086 : OutputProcessor::StoreType::Average,
17087 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17088 1 : SetupOutputVariable(state,
17089 : "Unitary System Water Coil Speed Level",
17090 : Constant::Units::None,
17091 1 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17092 : OutputProcessor::TimeStepType::System,
17093 : OutputProcessor::StoreType::Average,
17094 1 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17095 : }
17096 :
17097 130 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
17098 92 : SetupEMSActuator(state,
17099 : "UnitarySystem",
17100 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17101 : "Autosized Supply Air Flow Rate",
17102 : "[m3/s]",
17103 46 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideOn,
17104 46 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignFanVolFlowRateEMSOverrideValue);
17105 92 : SetupEMSActuator(state,
17106 : "UnitarySystem",
17107 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17108 : "Autosized Supply Air Flow Rate During Cooling Operation",
17109 : "[m3/s]",
17110 46 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideOn,
17111 46 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxCoolAirVolFlowEMSOverrideValue);
17112 92 : SetupEMSActuator(state,
17113 : "UnitarySystem",
17114 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17115 : "Autosized Supply Air Flow Rate During Heating Operation",
17116 : "[m3/s]",
17117 46 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideOn,
17118 46 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxHeatAirVolFlowEMSOverrideValue);
17119 92 : SetupEMSActuator(state,
17120 : "UnitarySystem",
17121 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17122 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
17123 : "[m3/s]",
17124 46 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideOn,
17125 46 : state.dataUnitarySystems->unitarySys[sysNum].m_MaxNoCoolHeatAirVolFlowEMSOverrideValue);
17126 46 : SetupEMSInternalVariable(state,
17127 : "Unitary System Control Zone Mass Flow Fraction",
17128 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17129 : "[]",
17130 46 : state.dataUnitarySystems->unitarySys[sysNum].ControlZoneMassFlowFrac);
17131 46 : SetupEMSInternalVariable(state,
17132 : "Unitary HVAC Design Heating Capacity",
17133 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17134 : "[W]",
17135 46 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignHeatingCapacity);
17136 46 : SetupEMSInternalVariable(state,
17137 : "Unitary HVAC Design Cooling Capacity",
17138 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17139 : "[W]",
17140 46 : state.dataUnitarySystems->unitarySys[sysNum].m_DesignCoolingCapacity);
17141 92 : SetupEMSActuator(state,
17142 : "Unitary HVAC",
17143 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17144 : "Sensible Load Request",
17145 : "[W]",
17146 46 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSensZoneLoadRequest,
17147 46 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSSensibleZoneLoadValue);
17148 92 : SetupEMSActuator(state,
17149 : "Unitary HVAC",
17150 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17151 : "Moisture Load Request",
17152 : "[W]",
17153 46 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideMoistZoneLoadRequest,
17154 46 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSMoistureZoneLoadValue);
17155 46 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_MultiSpeedCooling ||
17156 54 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::CoilDX_MultiSpeedHeating ||
17157 8 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_Cooling) {
17158 90 : SetupEMSActuator(state,
17159 : "Coil Speed Control",
17160 45 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17161 : "Unitary System DX Coil Speed Value",
17162 : "[]",
17163 45 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumOn,
17164 45 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideCoilSpeedNumValue);
17165 : }
17166 92 : SetupEMSActuator(state,
17167 : "Coil Speed Control",
17168 46 : state.dataUnitarySystems->unitarySys[sysNum].Name,
17169 : "Unitary System Supplemental Coil Stage Level",
17170 : "[]",
17171 46 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumOn,
17172 46 : state.dataUnitarySystems->unitarySys[sysNum].m_EMSOverrideSuppCoilSpeedNumValue);
17173 : }
17174 : bool anyEMSRan;
17175 130 : EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyEMSRan, ObjexxFCL::Optional_int_const());
17176 622 : break;
17177 292 : case UnitarySys::SysType::CoilCoolingDX:
17178 : // Setup Report variables for the DXCoolingSystem that is not reported in the components themselves
17179 292 : if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::CoilDX_CoolingTwoSpeed) {
17180 134 : SetupOutputVariable(state,
17181 : "Coil System Cycling Ratio",
17182 : Constant::Units::None,
17183 67 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17184 : OutputProcessor::TimeStepType::System,
17185 : OutputProcessor::StoreType::Average,
17186 67 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17187 134 : SetupOutputVariable(state,
17188 : "Coil System Compressor Speed Ratio",
17189 : Constant::Units::None,
17190 67 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17191 : OutputProcessor::TimeStepType::System,
17192 : OutputProcessor::StoreType::Average,
17193 67 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17194 225 : } else if (state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
17195 4 : SetupOutputVariable(state,
17196 : "Coil System Cycling Ratio",
17197 : Constant::Units::None,
17198 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCycRatio,
17199 : OutputProcessor::TimeStepType::System,
17200 : OutputProcessor::StoreType::Average,
17201 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17202 4 : SetupOutputVariable(state,
17203 : "Coil System Compressor Speed Ratio",
17204 : Constant::Units::None,
17205 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedRatio,
17206 : OutputProcessor::TimeStepType::System,
17207 : OutputProcessor::StoreType::Average,
17208 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17209 2 : SetupOutputVariable(state,
17210 : "Coil System Compressor Speed Number",
17211 : Constant::Units::None,
17212 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingSpeedNum,
17213 : OutputProcessor::TimeStepType::System,
17214 : OutputProcessor::StoreType::Average,
17215 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17216 : } else {
17217 446 : SetupOutputVariable(state,
17218 : "Coil System Part Load Ratio",
17219 : Constant::Units::None,
17220 223 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingPartLoadFrac,
17221 : OutputProcessor::TimeStepType::System,
17222 : OutputProcessor::StoreType::Average,
17223 223 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17224 : }
17225 292 : SetupOutputVariable(state,
17226 : "Coil System Frost Control Status",
17227 : Constant::Units::None,
17228 292 : state.dataUnitarySystems->unitarySys[sysNum].m_FrostControlStatus,
17229 : OutputProcessor::TimeStepType::System,
17230 : OutputProcessor::StoreType::Average,
17231 292 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17232 292 : break;
17233 3 : case UnitarySys::SysType::CoilCoolingWater:
17234 : // Setup Report variables for the CoilSystemWater
17235 6 : SetupOutputVariable(state,
17236 : "Coil System Water Part Load Ratio",
17237 : Constant::Units::None,
17238 3 : state.dataUnitarySystems->unitarySys[sysNum].m_PartLoadFrac,
17239 : OutputProcessor::TimeStepType::System,
17240 : OutputProcessor::StoreType::Average,
17241 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17242 6 : SetupOutputVariable(state,
17243 : "Coil System Water Total Cooling Rate",
17244 : Constant::Units::W,
17245 3 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17246 : OutputProcessor::TimeStepType::System,
17247 : OutputProcessor::StoreType::Average,
17248 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17249 6 : SetupOutputVariable(state,
17250 : "Coil System Water Sensible Cooling Rate",
17251 : Constant::Units::W,
17252 3 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17253 : OutputProcessor::TimeStepType::System,
17254 : OutputProcessor::StoreType::Average,
17255 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17256 6 : SetupOutputVariable(state,
17257 : "Coil System Water Latent Cooling Rate",
17258 : Constant::Units::W,
17259 3 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17260 : OutputProcessor::TimeStepType::System,
17261 : OutputProcessor::StoreType::Average,
17262 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17263 :
17264 3 : if (state.dataUnitarySystems->unitarySys[sysNum].m_TemperatureOffsetControlActive) {
17265 3 : SetupOutputVariable(state,
17266 : "Coil System Water Control Status",
17267 : Constant::Units::None,
17268 3 : state.dataUnitarySystems->unitarySys[sysNum].temperatureOffsetControlStatus,
17269 : OutputProcessor::TimeStepType::System,
17270 : OutputProcessor::StoreType::Average,
17271 3 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17272 : }
17273 3 : break;
17274 142 : case UnitarySys::SysType::PackagedAC:
17275 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalAirConditioner'
17276 284 : SetupOutputVariable(state,
17277 : "Zone Packaged Terminal Air Conditioner Total Heating Rate",
17278 : Constant::Units::W,
17279 142 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17280 : OutputProcessor::TimeStepType::System,
17281 : OutputProcessor::StoreType::Average,
17282 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17283 284 : SetupOutputVariable(state,
17284 : "Zone Packaged Terminal Air Conditioner Total Heating Energy",
17285 : Constant::Units::J,
17286 142 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17287 : OutputProcessor::TimeStepType::System,
17288 : OutputProcessor::StoreType::Sum,
17289 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17290 284 : SetupOutputVariable(state,
17291 : "Zone Packaged Terminal Air Conditioner Total Cooling Rate",
17292 : Constant::Units::W,
17293 142 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17294 : OutputProcessor::TimeStepType::System,
17295 : OutputProcessor::StoreType::Average,
17296 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17297 284 : SetupOutputVariable(state,
17298 : "Zone Packaged Terminal Air Conditioner Total Cooling Energy",
17299 : Constant::Units::J,
17300 142 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17301 : OutputProcessor::TimeStepType::System,
17302 : OutputProcessor::StoreType::Sum,
17303 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17304 284 : SetupOutputVariable(state,
17305 : "Zone Packaged Terminal Air Conditioner Sensible Heating Rate",
17306 : Constant::Units::W,
17307 142 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17308 : OutputProcessor::TimeStepType::System,
17309 : OutputProcessor::StoreType::Average,
17310 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17311 284 : SetupOutputVariable(state,
17312 : "Zone Packaged Terminal Air Conditioner Sensible Heating Energy",
17313 : Constant::Units::J,
17314 142 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17315 : OutputProcessor::TimeStepType::System,
17316 : OutputProcessor::StoreType::Sum,
17317 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17318 284 : SetupOutputVariable(state,
17319 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Rate",
17320 : Constant::Units::W,
17321 142 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17322 : OutputProcessor::TimeStepType::System,
17323 : OutputProcessor::StoreType::Average,
17324 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17325 284 : SetupOutputVariable(state,
17326 : "Zone Packaged Terminal Air Conditioner Sensible Cooling Energy",
17327 : Constant::Units::J,
17328 142 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17329 : OutputProcessor::TimeStepType::System,
17330 : OutputProcessor::StoreType::Sum,
17331 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17332 284 : SetupOutputVariable(state,
17333 : "Zone Packaged Terminal Air Conditioner Latent Heating Rate",
17334 : Constant::Units::W,
17335 142 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17336 : OutputProcessor::TimeStepType::System,
17337 : OutputProcessor::StoreType::Average,
17338 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17339 284 : SetupOutputVariable(state,
17340 : "Zone Packaged Terminal Air Conditioner Latent Heating Energy",
17341 : Constant::Units::J,
17342 142 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17343 : OutputProcessor::TimeStepType::System,
17344 : OutputProcessor::StoreType::Sum,
17345 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17346 284 : SetupOutputVariable(state,
17347 : "Zone Packaged Terminal Air Conditioner Latent Cooling Rate",
17348 : Constant::Units::W,
17349 142 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17350 : OutputProcessor::TimeStepType::System,
17351 : OutputProcessor::StoreType::Average,
17352 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17353 284 : SetupOutputVariable(state,
17354 : "Zone Packaged Terminal Air Conditioner Latent Cooling Energy",
17355 : Constant::Units::J,
17356 142 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17357 : OutputProcessor::TimeStepType::System,
17358 : OutputProcessor::StoreType::Sum,
17359 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17360 284 : SetupOutputVariable(state,
17361 : "Zone Packaged Terminal Air Conditioner Electricity Rate",
17362 : Constant::Units::W,
17363 142 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17364 : OutputProcessor::TimeStepType::System,
17365 : OutputProcessor::StoreType::Average,
17366 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17367 284 : SetupOutputVariable(state,
17368 : "Zone Packaged Terminal Air Conditioner Electricity Energy",
17369 : Constant::Units::J,
17370 142 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17371 : OutputProcessor::TimeStepType::System,
17372 : OutputProcessor::StoreType::Sum,
17373 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17374 284 : SetupOutputVariable(state,
17375 : "Zone Packaged Terminal Air Conditioner Fan Part Load Ratio",
17376 : Constant::Units::None,
17377 142 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17378 : OutputProcessor::TimeStepType::System,
17379 : OutputProcessor::StoreType::Average,
17380 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17381 284 : SetupOutputVariable(state,
17382 : "Zone Packaged Terminal Air Conditioner Compressor Part Load Ratio",
17383 : Constant::Units::None,
17384 142 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17385 : OutputProcessor::TimeStepType::System,
17386 : OutputProcessor::StoreType::Average,
17387 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17388 142 : SetupOutputVariable(state,
17389 : "Zone Packaged Terminal Air Conditioner Fan Availability Status",
17390 : Constant::Units::None,
17391 142 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17392 : OutputProcessor::TimeStepType::System,
17393 : OutputProcessor::StoreType::Average,
17394 142 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17395 142 : break;
17396 28 : case UnitarySys::SysType::PackagedHP:
17397 : // CurrentModuleObject = 'ZoneHVAC:PackagedTerminalHeatPump'
17398 56 : SetupOutputVariable(state,
17399 : "Zone Packaged Terminal Heat Pump Total Heating Rate",
17400 : Constant::Units::W,
17401 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17402 : OutputProcessor::TimeStepType::System,
17403 : OutputProcessor::StoreType::Average,
17404 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17405 56 : SetupOutputVariable(state,
17406 : "Zone Packaged Terminal Heat Pump Total Heating Energy",
17407 : Constant::Units::J,
17408 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17409 : OutputProcessor::TimeStepType::System,
17410 : OutputProcessor::StoreType::Sum,
17411 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17412 56 : SetupOutputVariable(state,
17413 : "Zone Packaged Terminal Heat Pump Total Cooling Rate",
17414 : Constant::Units::W,
17415 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17416 : OutputProcessor::TimeStepType::System,
17417 : OutputProcessor::StoreType::Average,
17418 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17419 56 : SetupOutputVariable(state,
17420 : "Zone Packaged Terminal Heat Pump Total Cooling Energy",
17421 : Constant::Units::J,
17422 28 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17423 : OutputProcessor::TimeStepType::System,
17424 : OutputProcessor::StoreType::Sum,
17425 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17426 56 : SetupOutputVariable(state,
17427 : "Zone Packaged Terminal Heat Pump Sensible Heating Rate",
17428 : Constant::Units::W,
17429 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17430 : OutputProcessor::TimeStepType::System,
17431 : OutputProcessor::StoreType::Average,
17432 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17433 56 : SetupOutputVariable(state,
17434 : "Zone Packaged Terminal Heat Pump Sensible Heating Energy",
17435 : Constant::Units::J,
17436 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17437 : OutputProcessor::TimeStepType::System,
17438 : OutputProcessor::StoreType::Sum,
17439 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17440 56 : SetupOutputVariable(state,
17441 : "Zone Packaged Terminal Heat Pump Sensible Cooling Rate",
17442 : Constant::Units::W,
17443 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17444 : OutputProcessor::TimeStepType::System,
17445 : OutputProcessor::StoreType::Average,
17446 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17447 56 : SetupOutputVariable(state,
17448 : "Zone Packaged Terminal Heat Pump Sensible Cooling Energy",
17449 : Constant::Units::J,
17450 28 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17451 : OutputProcessor::TimeStepType::System,
17452 : OutputProcessor::StoreType::Sum,
17453 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17454 56 : SetupOutputVariable(state,
17455 : "Zone Packaged Terminal Heat Pump Latent Heating Rate",
17456 : Constant::Units::W,
17457 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17458 : OutputProcessor::TimeStepType::System,
17459 : OutputProcessor::StoreType::Average,
17460 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17461 56 : SetupOutputVariable(state,
17462 : "Zone Packaged Terminal Heat Pump Latent Heating Energy",
17463 : Constant::Units::J,
17464 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17465 : OutputProcessor::TimeStepType::System,
17466 : OutputProcessor::StoreType::Sum,
17467 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17468 56 : SetupOutputVariable(state,
17469 : "Zone Packaged Terminal Heat Pump Latent Cooling Rate",
17470 : Constant::Units::W,
17471 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17472 : OutputProcessor::TimeStepType::System,
17473 : OutputProcessor::StoreType::Average,
17474 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17475 56 : SetupOutputVariable(state,
17476 : "Zone Packaged Terminal Heat Pump Latent Cooling Energy",
17477 : Constant::Units::J,
17478 28 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17479 : OutputProcessor::TimeStepType::System,
17480 : OutputProcessor::StoreType::Sum,
17481 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17482 56 : SetupOutputVariable(state,
17483 : "Zone Packaged Terminal Heat Pump Electricity Rate",
17484 : Constant::Units::W,
17485 28 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17486 : OutputProcessor::TimeStepType::System,
17487 : OutputProcessor::StoreType::Average,
17488 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17489 56 : SetupOutputVariable(state,
17490 : "Zone Packaged Terminal Heat Pump Electricity Energy",
17491 : Constant::Units::J,
17492 28 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17493 : OutputProcessor::TimeStepType::System,
17494 : OutputProcessor::StoreType::Sum,
17495 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17496 56 : SetupOutputVariable(state,
17497 : "Zone Packaged Terminal Heat Pump Fan Part Load Ratio",
17498 : Constant::Units::None,
17499 28 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17500 : OutputProcessor::TimeStepType::System,
17501 : OutputProcessor::StoreType::Average,
17502 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17503 56 : SetupOutputVariable(state,
17504 : "Zone Packaged Terminal Heat Pump Compressor Part Load Ratio",
17505 : Constant::Units::None,
17506 28 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17507 : OutputProcessor::TimeStepType::System,
17508 : OutputProcessor::StoreType::Average,
17509 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17510 28 : SetupOutputVariable(state,
17511 : "Zone Packaged Terminal Heat Pump Fan Availability Status",
17512 : Constant::Units::None,
17513 28 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17514 : OutputProcessor::TimeStepType::System,
17515 : OutputProcessor::StoreType::Average,
17516 28 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17517 28 : break;
17518 27 : case UnitarySys::SysType::PackagedWSHP:
17519 : // CurrentModuleObject = 'ZoneHVAC:WaterToAirHeatPump'
17520 54 : SetupOutputVariable(state,
17521 : "Zone Water to Air Heat Pump Total Heating Rate",
17522 : Constant::Units::W,
17523 27 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergyRate,
17524 : OutputProcessor::TimeStepType::System,
17525 : OutputProcessor::StoreType::Average,
17526 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17527 54 : SetupOutputVariable(state,
17528 : "Zone Water to Air Heat Pump Total Heating Energy",
17529 : Constant::Units::J,
17530 27 : state.dataUnitarySystems->unitarySys[sysNum].m_TotHeatEnergy,
17531 : OutputProcessor::TimeStepType::System,
17532 : OutputProcessor::StoreType::Sum,
17533 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17534 54 : SetupOutputVariable(state,
17535 : "Zone Water to Air Heat Pump Total Cooling Rate",
17536 : Constant::Units::W,
17537 27 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergyRate,
17538 : OutputProcessor::TimeStepType::System,
17539 : OutputProcessor::StoreType::Average,
17540 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17541 54 : SetupOutputVariable(state,
17542 : "Zone Water to Air Heat Pump Total Cooling Energy",
17543 : Constant::Units::J,
17544 27 : state.dataUnitarySystems->unitarySys[sysNum].m_TotCoolEnergy,
17545 : OutputProcessor::TimeStepType::System,
17546 : OutputProcessor::StoreType::Sum,
17547 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17548 54 : SetupOutputVariable(state,
17549 : "Zone Water to Air Heat Pump Sensible Heating Rate",
17550 : Constant::Units::W,
17551 27 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergyRate,
17552 : OutputProcessor::TimeStepType::System,
17553 : OutputProcessor::StoreType::Average,
17554 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17555 54 : SetupOutputVariable(state,
17556 : "Zone Water to Air Heat Pump Sensible Heating Energy",
17557 : Constant::Units::J,
17558 27 : state.dataUnitarySystems->unitarySys[sysNum].m_SensHeatEnergy,
17559 : OutputProcessor::TimeStepType::System,
17560 : OutputProcessor::StoreType::Sum,
17561 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17562 54 : SetupOutputVariable(state,
17563 : "Zone Water to Air Heat Pump Sensible Cooling Rate",
17564 : Constant::Units::W,
17565 27 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergyRate,
17566 : OutputProcessor::TimeStepType::System,
17567 : OutputProcessor::StoreType::Average,
17568 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17569 54 : SetupOutputVariable(state,
17570 : "Zone Water to Air Heat Pump Sensible Cooling Energy",
17571 : Constant::Units::J,
17572 27 : state.dataUnitarySystems->unitarySys[sysNum].m_SensCoolEnergy,
17573 : OutputProcessor::TimeStepType::System,
17574 : OutputProcessor::StoreType::Sum,
17575 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17576 54 : SetupOutputVariable(state,
17577 : "Zone Water to Air Heat Pump Latent Heating Rate",
17578 : Constant::Units::W,
17579 27 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergyRate,
17580 : OutputProcessor::TimeStepType::System,
17581 : OutputProcessor::StoreType::Average,
17582 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17583 54 : SetupOutputVariable(state,
17584 : "Zone Water to Air Heat Pump Latent Heating Energy",
17585 : Constant::Units::J,
17586 27 : state.dataUnitarySystems->unitarySys[sysNum].m_LatHeatEnergy,
17587 : OutputProcessor::TimeStepType::System,
17588 : OutputProcessor::StoreType::Sum,
17589 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17590 54 : SetupOutputVariable(state,
17591 : "Zone Water to Air Heat Pump Latent Cooling Rate",
17592 : Constant::Units::W,
17593 27 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergyRate,
17594 : OutputProcessor::TimeStepType::System,
17595 : OutputProcessor::StoreType::Average,
17596 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17597 54 : SetupOutputVariable(state,
17598 : "Zone Water to Air Heat Pump Latent Cooling Energy",
17599 : Constant::Units::J,
17600 27 : state.dataUnitarySystems->unitarySys[sysNum].m_LatCoolEnergy,
17601 : OutputProcessor::TimeStepType::System,
17602 : OutputProcessor::StoreType::Sum,
17603 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17604 54 : SetupOutputVariable(state,
17605 : "Zone Water to Air Heat Pump Electricity Rate",
17606 : Constant::Units::W,
17607 27 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPower,
17608 : OutputProcessor::TimeStepType::System,
17609 : OutputProcessor::StoreType::Average,
17610 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17611 54 : SetupOutputVariable(state,
17612 : "Zone Water to Air Heat Pump Electricity Energy",
17613 : Constant::Units::J,
17614 27 : state.dataUnitarySystems->unitarySys[sysNum].m_ElecPowerConsumption,
17615 : OutputProcessor::TimeStepType::System,
17616 : OutputProcessor::StoreType::Sum,
17617 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17618 54 : SetupOutputVariable(state,
17619 : "Zone Water to Air Heat Pump Fan Part Load Ratio",
17620 : Constant::Units::None,
17621 27 : state.dataUnitarySystems->unitarySys[sysNum].FanPartLoadRatio,
17622 : OutputProcessor::TimeStepType::System,
17623 : OutputProcessor::StoreType::Average,
17624 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17625 54 : SetupOutputVariable(state,
17626 : "Zone Water to Air Heat Pump Compressor Part Load Ratio",
17627 : Constant::Units::None,
17628 27 : state.dataUnitarySystems->unitarySys[sysNum].m_CompPartLoadRatio,
17629 : OutputProcessor::TimeStepType::System,
17630 : OutputProcessor::StoreType::Average,
17631 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17632 27 : SetupOutputVariable(state,
17633 : "Zone Water to Air Heat Pump Fan Availability Status",
17634 : Constant::Units::None,
17635 27 : (int &)state.dataUnitarySystems->unitarySys[sysNum].m_AvailStatus,
17636 : OutputProcessor::TimeStepType::System,
17637 : OutputProcessor::StoreType::Average,
17638 27 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17639 27 : if (((state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple ||
17640 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) &&
17641 54 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedCooling > 1) ||
17642 25 : ((state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple ||
17643 1 : state.dataUnitarySystems->unitarySys[sysNum].m_HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) &&
17644 25 : state.dataUnitarySystems->unitarySys[sysNum].m_NumOfSpeedHeating > 1)) {
17645 4 : SetupOutputVariable(state,
17646 : "Unitary System Water Coil Multispeed Fan Cycling Ratio",
17647 : Constant::Units::None,
17648 2 : state.dataUnitarySystems->unitarySys[sysNum].m_CycRatio,
17649 : OutputProcessor::TimeStepType::System,
17650 : OutputProcessor::StoreType::Average,
17651 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17652 4 : SetupOutputVariable(state,
17653 : "Unitary System Water Coil Multispeed Fan Speed Ratio",
17654 : Constant::Units::None,
17655 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedRatio,
17656 : OutputProcessor::TimeStepType::System,
17657 : OutputProcessor::StoreType::Average,
17658 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17659 2 : SetupOutputVariable(state,
17660 : "Unitary System Water Coil Multispeed Fan Speed Level",
17661 : Constant::Units::None,
17662 2 : state.dataUnitarySystems->unitarySys[sysNum].m_SpeedNum,
17663 : OutputProcessor::TimeStepType::System,
17664 : OutputProcessor::StoreType::Average,
17665 2 : state.dataUnitarySystems->unitarySys[sysNum].Name);
17666 : }
17667 27 : break;
17668 0 : default:
17669 0 : ShowFatalError(state,
17670 : "setupAllOutputVar: Developer error. All report variables must be set up here after all systems are read in.");
17671 : }
17672 : }
17673 165 : state.dataUnitarySystems->setupOutputOnce = false;
17674 : } else {
17675 0 : ShowSevereError(state,
17676 : "setupAllOutputVar: Developer error. Should never get here. Remove when comfortable that UnitarySys::allocateUnitarySys "
17677 : "is working as expected.");
17678 0 : ShowFatalError(state, "setupAllOutputVar: Developer error. Conflict in number of UnitarySystems.");
17679 : }
17680 165 : }
17681 :
17682 61 : void isWaterCoilHeatRecoveryType(EnergyPlusData const &state, int const waterCoilNodeNum, bool &nodeNotFound)
17683 : {
17684 61 : if (!nodeNotFound) return;
17685 1 : nodeNotFound = std::none_of(
17686 2 : state.dataUnitarySystems->unitarySys.cbegin(), state.dataUnitarySystems->unitarySys.cend(), [waterCoilNodeNum](auto const &us) {
17687 1 : return us.m_WaterHRPlantLoopModel && us.m_HRcoolCoilFluidInletNode == waterCoilNodeNum;
17688 : });
17689 : }
17690 :
17691 470139 : Real64 UnitarySys::getFanDeltaTemp(EnergyPlusData &state, bool const firstHVACIteration, Real64 const massFlowRate, Real64 const airFlowRatio)
17692 : {
17693 470139 : int FanInletNode = 0;
17694 470139 : int FanOutletNode = 0;
17695 :
17696 470139 : auto *fan = state.dataFans->fans(this->m_FanIndex);
17697 470139 : FanInletNode = fan->inletNodeNum;
17698 470139 : FanOutletNode = fan->outletNodeNum;
17699 470139 : state.dataLoopNodes->Node(FanInletNode).MassFlowRate = massFlowRate;
17700 470139 : fan->simulate(state, firstHVACIteration, airFlowRatio, _, airFlowRatio, _, _, _);
17701 470139 : return state.dataLoopNodes->Node(FanOutletNode).Temp - state.dataLoopNodes->Node(FanInletNode).Temp;
17702 : }
17703 :
17704 175588 : void UnitarySys::setEconomizerStagingOperationSpeed(EnergyPlusData &state, bool const firstHVACIteration, Real64 const zoneLoad)
17705 : {
17706 175588 : this->m_LowSpeedEconOutput = 0;
17707 175588 : this->m_LowSpeedEconRuntime = 0;
17708 175588 : this->m_EconoPartLoadRatio = 0;
17709 175588 : this->m_EconoSpeedNum = 0;
17710 175588 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
17711 175588 : Real64 mixedTempAtMinOA = 0;
17712 175588 : Real64 highSpeedEconMassFlowRate = 0;
17713 175588 : Real64 highSpeedFanDT = 0;
17714 175588 : Real64 econClgOutput = 0;
17715 175588 : Real64 lowSpeedEconMassFlowRate = 0;
17716 175588 : Real64 lowSpeedFanDT = 0;
17717 175588 : Real64 highSpeedEconRuntime = 0;
17718 175588 : Real64 econClgOutputMinOA = 0;
17719 : // determine outdoor air properties
17720 : using Psychrometrics::PsyCpAirFnW;
17721 175588 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
17722 175588 : Real64 outdoorAirTemp = state.dataLoopNodes->Node(outdoorAirController.InletNode).Temp;
17723 175588 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
17724 : // iterate through the unitary system's cooling speed to see at which
17725 : // air flow rate the load can be met at 100% outdoor air fraction
17726 284768 : for (int clgSpd = 1; clgSpd <= this->m_NumOfSpeedCooling; ++clgSpd) {
17727 : // calculations for "high speed" refer to operation at the current
17728 : // cooling speed, "clgSpd", and "low speed" is "clgSpd -1"
17729 284768 : highSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd];
17730 : // determine air temperature difference for across the fan at this air flow rate
17731 284768 : highSpeedFanDT = this->getFanDeltaTemp(state,
17732 : firstHVACIteration,
17733 : highSpeedEconMassFlowRate,
17734 284768 : highSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
17735 284768 : econClgOutput = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + highSpeedFanDT));
17736 : // check if economizer alone can meet the load, or if we have reached the maximum cooling speed
17737 284768 : if (econClgOutput > std::abs(zoneLoad) || clgSpd == this->m_NumOfSpeedCooling) {
17738 : // low speed economizer operation is handled through normal process (i.e., no staging operation)
17739 175588 : if (clgSpd > 1) {
17740 : // check that the system output at the minimum outdoor air flow rate doesn't "overcool" at this speed
17741 84835 : mixedTempAtMinOA = 0;
17742 84835 : if (highSpeedEconMassFlowRate - outdoorAirController.MinOA > 0) {
17743 84835 : mixedTempAtMinOA =
17744 84835 : (outdoorAirTemp * outdoorAirController.MinOA + state.dataLoopNodes->Node(outdoorAirController.RetNode).Temp *
17745 84835 : (highSpeedEconMassFlowRate - outdoorAirController.MinOA)) /
17746 : highSpeedEconMassFlowRate;
17747 : } else {
17748 0 : mixedTempAtMinOA = outdoorAirTemp;
17749 : }
17750 84835 : econClgOutputMinOA = cpAir * highSpeedEconMassFlowRate * (zoneTemp - (mixedTempAtMinOA + highSpeedFanDT));
17751 84835 : if (econClgOutputMinOA < std::abs(zoneLoad)) {
17752 75052 : highSpeedEconRuntime = 1.0;
17753 : } else {
17754 : // if running at this speed would "overcool", we run partly at the lower speed and partly at this speed
17755 9783 : lowSpeedEconMassFlowRate = this->m_CoolMassFlowRate[clgSpd - 1];
17756 9783 : lowSpeedFanDT = this->getFanDeltaTemp(state,
17757 : firstHVACIteration,
17758 : lowSpeedEconMassFlowRate,
17759 9783 : lowSpeedEconMassFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
17760 9783 : this->m_LowSpeedEconOutput = cpAir * lowSpeedEconMassFlowRate * (zoneTemp - (outdoorAirTemp + lowSpeedFanDT));
17761 : // determine this speed's runtime
17762 9783 : highSpeedEconRuntime = (std::abs(zoneLoad) - this->m_LowSpeedEconOutput) / (econClgOutput - this->m_LowSpeedEconOutput);
17763 : }
17764 : } else {
17765 90753 : highSpeedEconRuntime = 1.0;
17766 : }
17767 : // set economizer air flow "speed"
17768 175588 : this->m_EconoSpeedNum = clgSpd;
17769 : // set economizer PLR, a.k.a the system fan part load ratio, and runtime at each speed
17770 175588 : this->m_EconoPartLoadRatio = highSpeedEconRuntime;
17771 175588 : this->m_LowSpeedEconRuntime = 1 - highSpeedEconRuntime;
17772 175588 : break;
17773 : }
17774 : }
17775 175588 : }
17776 :
17777 175588 : void UnitarySys::calcMixedTempAirSPforEconomizerStagingOperation(EnergyPlusData &state,
17778 : int const airLoopNum,
17779 : bool const firstHVACIteration,
17780 : Real64 const zoneLoad)
17781 : {
17782 175588 : auto outdoorAirController = state.dataMixedAir->OAController(this->OAControllerIndex);
17783 : using Psychrometrics::PsyCpAirFnW;
17784 175588 : Real64 cpAir = PsyCpAirFnW(state.dataLoopNodes->Node(outdoorAirController.InletNode).HumRat);
17785 175588 : Real64 zoneTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(this->ControlZoneNum).ZoneNode).Temp;
17786 : // determine and set new air loop mixed air flow rate
17787 175588 : Real64 mixedAirFlowRate = this->m_EconoPartLoadRatio * this->m_CoolMassFlowRate[this->m_EconoSpeedNum] +
17788 175588 : this->m_LowSpeedEconRuntime * this->m_CoolMassFlowRate[this->m_EconoSpeedNum - 1];
17789 175588 : if (airLoopNum > 0) {
17790 : // request fixed mixed flow rate
17791 175588 : state.dataAirLoop->AirLoopControlInfo(airLoopNum).LoopFlowRateSet = true;
17792 175588 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac = mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling];
17793 : // adjust mixed air flow rate for rated air flow rate adjustment (variable speed coils only)
17794 175588 : state.dataAirLoop->AirLoopFlow(airLoopNum).ReqSupplyFrac *=
17795 175588 : this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling] / state.dataAirLoop->AirLoopFlow(airLoopNum).DesSupply;
17796 : }
17797 : // determine air temperature difference across fan based on new mixed air flow rate
17798 175588 : int mixedAirNode = outdoorAirController.MixNode;
17799 175588 : Real64 fanDTAtMixedAirFlowRate = this->getFanDeltaTemp(
17800 175588 : state, firstHVACIteration, mixedAirFlowRate, mixedAirFlowRate / this->m_CoolMassFlowRate[this->m_NumOfSpeedCooling]);
17801 : // determine new mixed air setpoint
17802 175588 : Real64 newMixedAirSP = zoneTemp - std::abs(zoneLoad) / (cpAir * mixedAirFlowRate);
17803 175588 : state.dataLoopNodes->Node(mixedAirNode).TempSetPoint = newMixedAirSP - fanDTAtMixedAirFlowRate;
17804 175588 : }
17805 :
17806 : void
17807 740540 : UnitarySys::manageEconomizerStagingOperation(EnergyPlusData &state, int const airLoopNum, bool const firstHVACIteration, Real64 const zoneLoad)
17808 : {
17809 740540 : if (airLoopNum > 0) {
17810 964148 : if (state.dataAirLoop->AirLoopControlInfo(airLoopNum).EconoActive == true && state.dataGlobal->WarmupFlag == false &&
17811 223608 : state.dataUnitarySystems->CoolingLoad) {
17812 175588 : this->setEconomizerStagingOperationSpeed(state, firstHVACIteration, zoneLoad);
17813 :
17814 : // adjustments are only needed when economizer speed is greater than the lowest speed
17815 175588 : if (this->m_EconoSpeedNum > 0) {
17816 175588 : this->calcMixedTempAirSPforEconomizerStagingOperation(state, airLoopNum, firstHVACIteration, zoneLoad);
17817 :
17818 : // recalculate the outdoor air fraction to meet the new mixed air setpoint at the new mixed air flow rate
17819 351176 : MixedAir::ManageOutsideAirSystem(
17820 175588 : state, state.dataAirLoop->OutsideAirSys(this->OASysIndex).Name, firstHVACIteration, airLoopNum, this->OASysIndex);
17821 : }
17822 : }
17823 : }
17824 740540 : }
17825 :
17826 : } // namespace UnitarySystems
17827 : } // namespace EnergyPlus
|