Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
56 : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
57 : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/DXCoils.hh>
60 : #include <EnergyPlus/Data/EnergyPlusData.hh>
61 : #include <EnergyPlus/DataAirSystems.hh>
62 : #include <EnergyPlus/DataHVACGlobals.hh>
63 : #include <EnergyPlus/DataHeatBalFanSys.hh>
64 : #include <EnergyPlus/DataHeatBalance.hh>
65 : #include <EnergyPlus/DataLoopNode.hh>
66 : #include <EnergyPlus/DataSizing.hh>
67 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
68 : #include <EnergyPlus/DataZoneEquipment.hh>
69 : #include <EnergyPlus/EMSManager.hh>
70 : #include <EnergyPlus/Fans.hh>
71 : #include <EnergyPlus/General.hh>
72 : #include <EnergyPlus/GeneralRoutines.hh>
73 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
74 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
75 : #include <EnergyPlus/MixedAir.hh>
76 : #include <EnergyPlus/NodeInputManager.hh>
77 : #include <EnergyPlus/OutputProcessor.hh>
78 : #include <EnergyPlus/Psychrometrics.hh>
79 : #include <EnergyPlus/ReportCoilSelection.hh>
80 : #include <EnergyPlus/ScheduleManager.hh>
81 : #include <EnergyPlus/UtilityRoutines.hh>
82 : #include <EnergyPlus/VariableSpeedCoils.hh>
83 : #include <EnergyPlus/WindowAC.hh>
84 :
85 : namespace EnergyPlus {
86 :
87 : namespace WindowAC {
88 :
89 : // Module containing the routines dealing window air conditioner units
90 :
91 : // MODULE INFORMATION:
92 : // AUTHOR Fred Buhl
93 : // DATE WRITTEN May 2000
94 : // MODIFIED Richard Raustad, FSEC Oct 2003
95 : // RE-ENGINEERED na
96 :
97 : // PURPOSE OF THIS MODULE:
98 : // To encapsulate the data and algorithms needed to simulate window air
99 : // conditioner units.
100 :
101 : // METHODOLOGY EMPLOYED:
102 : // Units are modeled as a collection of components: outside air mixer,
103 : // fan and DX coil. Control is by means of cycling: either continuous
104 : // air flow with the DX compressor cycling on/off or the entire unit -
105 : // fan and compressor cycling on/off. Cycling behavior is not explicitly
106 : // modeled - instead cycling inefficiencies must be included in the efficiency
107 : // curves of the DX module.
108 :
109 : using namespace DataLoopNode;
110 : using namespace DataSizing;
111 : using HVAC::CoilDX_CoolingHXAssisted;
112 : using HVAC::CoilDX_CoolingSingleSpeed;
113 : using HVAC::SmallAirVolFlow;
114 : using HVAC::SmallLoad;
115 : using HVAC::SmallMassFlow;
116 : using Psychrometrics::PsyCpAirFnW;
117 : using Psychrometrics::PsyHFnTdbW;
118 : using Psychrometrics::PsyRhoAirFnPbTdbW;
119 :
120 131436 : void SimWindowAC(EnergyPlusData &state,
121 : std::string_view CompName, // name of the window AC unit
122 : int const ZoneNum, // number of zone being served
123 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
124 : Real64 &PowerMet, // Sensible power supplied by window AC (W)
125 : Real64 &LatOutputProvided, // Latent add/removal supplied by window AC (kg/s), dehumid = negative
126 : int &CompIndex // component index
127 : )
128 : {
129 :
130 : // SUBROUTINE INFORMATION:
131 : // AUTHOR Fred Buhl
132 : // DATE WRITTEN May 2000
133 : // MODIFIED Don Shirey, Aug 2009 (LatOutputProvided)
134 : // RE-ENGINEERED na
135 :
136 : // PURPOSE OF THIS SUBROUTINE:
137 : // Manages the simulation of a window AC unit. Called from SimZone Equipment
138 :
139 : int WindACNum; // index of window AC unit being simulated
140 : Real64 QZnReq; // zone load (W)
141 : Real64 RemainingOutputToCoolingSP; // - remaining load to cooling setpoint (W)
142 :
143 : // First time SimWindowAC is called, get the input for all the window AC units
144 131436 : if (state.dataWindowAC->GetWindowACInputFlag) {
145 5 : GetWindowAC(state);
146 5 : state.dataWindowAC->GetWindowACInputFlag = false;
147 : }
148 :
149 : // Find the correct Window AC Equipment
150 131436 : if (CompIndex == 0) {
151 21 : WindACNum = Util::FindItemInList(CompName, state.dataWindowAC->WindAC);
152 21 : if (WindACNum == 0) {
153 0 : ShowFatalError(state, format("SimWindowAC: Unit not found={}", CompName));
154 : }
155 21 : CompIndex = WindACNum;
156 : } else {
157 131415 : WindACNum = CompIndex;
158 131415 : if (WindACNum > state.dataWindowAC->NumWindAC || WindACNum < 1) {
159 0 : ShowFatalError(state,
160 0 : format("SimWindowAC: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
161 : WindACNum,
162 0 : state.dataWindowAC->NumWindAC,
163 : CompName));
164 : }
165 131415 : if (state.dataWindowAC->CheckEquipName(WindACNum)) {
166 21 : if (CompName != state.dataWindowAC->WindAC(WindACNum).Name) {
167 0 : ShowFatalError(state,
168 0 : format("SimWindowAC: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
169 : WindACNum,
170 : CompName,
171 0 : state.dataWindowAC->WindAC(WindACNum).Name));
172 : }
173 21 : state.dataWindowAC->CheckEquipName(WindACNum) = false;
174 : }
175 : }
176 :
177 131436 : RemainingOutputToCoolingSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
178 :
179 131436 : if (RemainingOutputToCoolingSP < 0.0 && state.dataHeatBalFanSys->TempControlType(ZoneNum) != HVAC::SetptType::SingleHeat) {
180 78847 : QZnReq = RemainingOutputToCoolingSP;
181 : } else {
182 52589 : QZnReq = 0.0;
183 : }
184 :
185 131436 : state.dataSize->ZoneEqDXCoil = true;
186 131436 : state.dataSize->ZoneCoolingOnlyFan = true;
187 :
188 : // Initialize the window AC unit
189 131436 : InitWindowAC(state, WindACNum, QZnReq, ZoneNum, FirstHVACIteration);
190 :
191 131436 : SimCyclingWindowAC(state, WindACNum, ZoneNum, FirstHVACIteration, PowerMet, QZnReq, LatOutputProvided);
192 :
193 : // Report the result of the simulation
194 131436 : ReportWindowAC(state, WindACNum);
195 :
196 131436 : state.dataSize->ZoneEqDXCoil = false;
197 131436 : state.dataSize->ZoneCoolingOnlyFan = false;
198 131436 : }
199 :
200 7 : void GetWindowAC(EnergyPlusData &state)
201 : {
202 :
203 : // SUBROUTINE INFORMATION:
204 : // AUTHOR Fred Buhl
205 : // DATE WRITTEN May 2000
206 : // MODIFIED Chandan Sharma, FSEC, March 2011: Added zone sys avail manager
207 : // Bereket Nigusse, FSEC, April 2011: eliminated input node names,
208 : // added OA Mixer object type
209 : // and fan object type
210 : // RE-ENGINEERED na
211 :
212 : // PURPOSE OF THIS SUBROUTINE:
213 : // Obtains input data for window AC units and stores it in window AC data structures
214 :
215 : // METHODOLOGY EMPLOYED:
216 : // Uses "Get" routines to read in data.
217 :
218 : using BranchNodeConnections::SetUpCompSets;
219 :
220 : using NodeInputManager::GetOnlySingleNode;
221 7 : auto &GetDXCoilOutletNode(DXCoils::GetCoilOutletNode);
222 7 : auto &GetDXHXAsstdCoilOutletNode(HVACHXAssistedCoolingCoil::GetCoilOutletNode);
223 : using MixedAir::GetOAMixerIndex;
224 : using MixedAir::GetOAMixerNodeNumbers;
225 :
226 : // SUBROUTINE PARAMETER DEFINITIONS:
227 : static constexpr std::string_view RoutineName("GetWindowAC: "); // include trailing blank space
228 : static constexpr std::string_view routineName = "GetWindowAC"; // include trailing blank space
229 :
230 : int WindACIndex; // loop index
231 : int WindACNum; // current window AC number
232 7 : std::string CompSetFanInlet;
233 7 : std::string CompSetCoolInlet;
234 7 : std::string CompSetFanOutlet;
235 7 : std::string CompSetCoolOutlet;
236 : int NumAlphas; // Number of Alphas for each GetObjectItem call
237 : int NumNumbers; // Number of Numbers for each GetObjectItem call
238 7 : Array1D_int OANodeNums(4); // Node numbers of Outdoor air mixer (OA, EA, RA, MA)
239 : int IOStatus; // Used in GetObjectItem
240 7 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
241 : Real64 FanVolFlow; // Fan volumetric flow rate
242 : bool CoilNodeErrFlag; // Used in error messages for mining coil outlet node number
243 7 : std::string CurrentModuleObject; // Object type for getting and error messages
244 7 : Array1D_string Alphas; // Alpha input items for object
245 7 : Array1D_string cAlphaFields; // Alpha field names
246 7 : Array1D_string cNumericFields; // Numeric field names
247 7 : Array1D<Real64> Numbers; // Numeric input items for object
248 7 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
249 7 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
250 7 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
251 : int CtrlZone; // index to loop counter
252 : int NodeNum; // index to loop counter
253 : bool ZoneNodeNotFound; // used in error checking
254 :
255 : // find the number of each type of window AC unit
256 7 : CurrentModuleObject = "ZoneHVAC:WindowAirConditioner";
257 :
258 7 : state.dataWindowAC->NumWindACCyc = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
259 7 : state.dataWindowAC->NumWindAC = state.dataWindowAC->NumWindACCyc;
260 : // allocate the data structures
261 7 : state.dataWindowAC->WindAC.allocate(state.dataWindowAC->NumWindAC);
262 7 : state.dataWindowAC->CheckEquipName.dimension(state.dataWindowAC->NumWindAC, true);
263 7 : state.dataWindowAC->WindACNumericFields.allocate(state.dataWindowAC->NumWindAC);
264 :
265 7 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
266 :
267 7 : Alphas.allocate(NumAlphas);
268 7 : cAlphaFields.allocate(NumAlphas);
269 7 : cNumericFields.allocate(NumNumbers);
270 7 : Numbers.dimension(NumNumbers, 0.0);
271 7 : lAlphaBlanks.dimension(NumAlphas, true);
272 7 : lNumericBlanks.dimension(NumNumbers, true);
273 :
274 : // loop over window AC units; get and load the input data
275 28 : for (WindACIndex = 1; WindACIndex <= state.dataWindowAC->NumWindACCyc; ++WindACIndex) {
276 :
277 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
278 : CurrentModuleObject,
279 : WindACIndex,
280 : Alphas,
281 : NumAlphas,
282 : Numbers,
283 : NumNumbers,
284 : IOStatus,
285 : lNumericBlanks,
286 : lAlphaBlanks,
287 : cAlphaFields,
288 : cNumericFields);
289 :
290 21 : WindACNum = WindACIndex;
291 :
292 21 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
293 :
294 21 : state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames.allocate(NumNumbers);
295 21 : state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames = "";
296 21 : state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames = cNumericFields;
297 21 : Util::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
298 :
299 21 : state.dataWindowAC->WindAC(WindACNum).Name = Alphas(1);
300 21 : state.dataWindowAC->WindAC(WindACNum).UnitType = state.dataWindowAC->WindowAC_UnitType; // 'ZoneHVAC:WindowAirConditioner'
301 :
302 21 : if (lAlphaBlanks(2)) {
303 0 : state.dataWindowAC->WindAC(WindACNum).availSched = Sched::GetScheduleAlwaysOn(state);
304 21 : } else if ((state.dataWindowAC->WindAC(WindACNum).availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
305 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
306 0 : ErrorsFound = true;
307 : }
308 :
309 21 : state.dataWindowAC->WindAC(WindACNum).MaxAirVolFlow = Numbers(1);
310 21 : state.dataWindowAC->WindAC(WindACNum).OutAirVolFlow = Numbers(2);
311 :
312 42 : state.dataWindowAC->WindAC(WindACNum).AirInNode = GetOnlySingleNode(state,
313 21 : Alphas(3),
314 : ErrorsFound,
315 : DataLoopNode::ConnectionObjectType::ZoneHVACWindowAirConditioner,
316 21 : Alphas(1),
317 : DataLoopNode::NodeFluidType::Air,
318 : DataLoopNode::ConnectionType::Inlet,
319 : NodeInputManager::CompFluidStream::Primary,
320 : ObjectIsParent);
321 :
322 42 : state.dataWindowAC->WindAC(WindACNum).AirOutNode = GetOnlySingleNode(state,
323 21 : Alphas(4),
324 : ErrorsFound,
325 : DataLoopNode::ConnectionObjectType::ZoneHVACWindowAirConditioner,
326 21 : Alphas(1),
327 : DataLoopNode::NodeFluidType::Air,
328 : DataLoopNode::ConnectionType::Outlet,
329 : NodeInputManager::CompFluidStream::Primary,
330 : ObjectIsParent);
331 :
332 21 : state.dataWindowAC->WindAC(WindACNum).OAMixType = Alphas(5);
333 21 : state.dataWindowAC->WindAC(WindACNum).OAMixName = Alphas(6);
334 : // Get outdoor air mixer node numbers
335 21 : bool errFlag = false;
336 42 : ValidateComponent(state,
337 21 : state.dataWindowAC->WindAC(WindACNum).OAMixType,
338 21 : state.dataWindowAC->WindAC(WindACNum).OAMixName,
339 : errFlag,
340 : CurrentModuleObject);
341 21 : if (errFlag) {
342 0 : ShowContinueError(state, format("specified in {} = \"{}\".", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
343 0 : ErrorsFound = true;
344 : } else {
345 : // Get outdoor air mixer node numbers
346 21 : OANodeNums = GetOAMixerNodeNumbers(state, state.dataWindowAC->WindAC(WindACNum).OAMixName, errFlag);
347 21 : if (errFlag) {
348 0 : ShowContinueError(state,
349 0 : format("that was specified in {} = \"{}\"", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
350 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
351 0 : ErrorsFound = true;
352 : } else {
353 21 : state.dataWindowAC->WindAC(WindACNum).OutsideAirNode = OANodeNums(1);
354 21 : state.dataWindowAC->WindAC(WindACNum).AirReliefNode = OANodeNums(2);
355 21 : state.dataWindowAC->WindAC(WindACNum).ReturnAirNode = OANodeNums(3);
356 21 : state.dataWindowAC->WindAC(WindACNum).MixedAirNode = OANodeNums(4);
357 : }
358 : }
359 :
360 21 : auto &windAC = state.dataWindowAC->WindAC(WindACNum);
361 :
362 21 : windAC.FanName = Alphas(8);
363 :
364 21 : windAC.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(7)));
365 :
366 21 : if (windAC.fanType != HVAC::FanType::OnOff && windAC.fanType != HVAC::FanType::Constant && windAC.fanType != HVAC::FanType::SystemModel) {
367 0 : ShowSevereInvalidKey(state, eoh, cAlphaFields(8), Alphas(8), "Fan Type must be Fan:OnOff, Fan:ConstantVolume, or Fan:SystemModel.");
368 :
369 21 : } else if ((windAC.FanIndex = Fans::GetFanIndex(state, windAC.FanName)) == 0) {
370 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(8), windAC.FanName);
371 :
372 : } else {
373 21 : auto *fan = state.dataFans->fans(windAC.FanIndex);
374 21 : assert(windAC.fanType == fan->type);
375 :
376 21 : FanVolFlow = fan->maxAirFlowRate;
377 21 : if (FanVolFlow != AutoSize) {
378 6 : if (FanVolFlow < windAC.MaxAirVolFlow) {
379 0 : ShowWarningError(state,
380 0 : format("Air flow rate = {:.7T} in fan object {} is less than the maximum supply air flow "
381 : "rate ({:.7T}) in the {} object.",
382 : FanVolFlow,
383 0 : windAC.FanName,
384 0 : windAC.MaxAirVolFlow,
385 : CurrentModuleObject));
386 0 : ShowContinueError(
387 0 : state, format(" The fan flow rate must be >= to the {} in the {} object.", cNumericFields(1), CurrentModuleObject));
388 0 : ShowContinueError(state, format(" Occurs in {} = {}", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
389 0 : ErrorsFound = true;
390 : }
391 : }
392 21 : windAC.fanAvailSched = fan->availSched;
393 : }
394 :
395 21 : state.dataWindowAC->WindAC(WindACNum).DXCoilName = Alphas(10);
396 :
397 22 : if (Util::SameString(Alphas(9), "Coil:Cooling:DX:SingleSpeed") ||
398 22 : Util::SameString(Alphas(9), "CoilSystem:Cooling:DX:HeatExchangerAssisted") ||
399 22 : Util::SameString(Alphas(9), "Coil:Cooling:DX:VariableSpeed")) {
400 21 : state.dataWindowAC->WindAC(WindACNum).DXCoilType = Alphas(9);
401 21 : CoilNodeErrFlag = false;
402 21 : if (Util::SameString(Alphas(9), "Coil:Cooling:DX:SingleSpeed")) {
403 20 : state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num = CoilDX_CoolingSingleSpeed;
404 20 : state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum = GetDXCoilOutletNode(
405 20 : state, state.dataWindowAC->WindAC(WindACNum).DXCoilType, state.dataWindowAC->WindAC(WindACNum).DXCoilName, CoilNodeErrFlag);
406 1 : } else if (Util::SameString(Alphas(9), "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
407 0 : state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num = CoilDX_CoolingHXAssisted;
408 0 : state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum = GetDXHXAsstdCoilOutletNode(
409 0 : state, state.dataWindowAC->WindAC(WindACNum).DXCoilType, state.dataWindowAC->WindAC(WindACNum).DXCoilName, CoilNodeErrFlag);
410 1 : } else if (Util::SameString(Alphas(9), "Coil:Cooling:DX:VariableSpeed")) {
411 1 : state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
412 1 : state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(
413 1 : state, state.dataWindowAC->WindAC(WindACNum).DXCoilType, state.dataWindowAC->WindAC(WindACNum).DXCoilName, CoilNodeErrFlag);
414 1 : state.dataWindowAC->WindAC(WindACNum).DXCoilNumOfSpeeds =
415 1 : VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, state.dataWindowAC->WindAC(WindACNum).DXCoilName, ErrorsFound);
416 : }
417 21 : if (CoilNodeErrFlag) {
418 0 : ShowContinueError(state,
419 0 : format(" that was specified in {} = \"{}\".", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
420 0 : ErrorsFound = true;
421 : }
422 : } else {
423 0 : ShowWarningError(state, format("Invalid {} = {}", cAlphaFields(9), Alphas(9)));
424 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
425 0 : ErrorsFound = true;
426 : }
427 :
428 21 : if (lAlphaBlanks(11)) {
429 0 : state.dataWindowAC->WindAC(WindACNum).fanOp = HVAC::FanOp::Cycling;
430 21 : } else if ((state.dataWindowAC->WindAC(WindACNum).fanOpModeSched = Sched::GetSchedule(state, Alphas(11))) == nullptr) {
431 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(11), Alphas(11));
432 0 : ErrorsFound = true;
433 : }
434 :
435 21 : state.dataWindowAC->WindAC(WindACNum).fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(12)));
436 21 : assert(state.dataWindowAC->WindAC(WindACNum).fanPlace != HVAC::FanPlace::Invalid);
437 :
438 21 : state.dataWindowAC->WindAC(WindACNum).ConvergenceTol = Numbers(3);
439 :
440 21 : if (!lAlphaBlanks(13)) {
441 0 : state.dataWindowAC->WindAC(WindACNum).AvailManagerListName = Alphas(13);
442 : }
443 :
444 21 : state.dataWindowAC->WindAC(WindACNum).HVACSizingIndex = 0;
445 21 : if (!lAlphaBlanks(14)) {
446 0 : state.dataWindowAC->WindAC(WindACNum).HVACSizingIndex = Util::FindItemInList(Alphas(14), state.dataSize->ZoneHVACSizing);
447 0 : if (state.dataWindowAC->WindAC(WindACNum).HVACSizingIndex == 0) {
448 0 : ShowSevereError(state, format("{} = {} not found.", cAlphaFields(14), Alphas(14)));
449 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
450 0 : ErrorsFound = true;
451 : }
452 : }
453 :
454 : // Add fan to component sets array
455 21 : if (state.dataWindowAC->WindAC(WindACNum).fanPlace == HVAC::FanPlace::BlowThru) {
456 :
457 : // Window AC air inlet node must be the same as a zone exhaust node and the OA Mixer return node
458 : // check that Window AC air inlet node is the same as a zone exhaust node.
459 17 : ZoneNodeNotFound = true;
460 122 : for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
461 105 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
462 0 : continue;
463 : }
464 199 : for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
465 111 : if (state.dataWindowAC->WindAC(WindACNum).AirInNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
466 17 : ZoneNodeNotFound = false;
467 17 : break;
468 : }
469 : }
470 : }
471 17 : if (ZoneNodeNotFound) {
472 0 : ShowSevereError(state,
473 0 : format("{} = \"{}\". Window AC air inlet node name must be the same as a zone exhaust node name.",
474 : CurrentModuleObject,
475 0 : state.dataWindowAC->WindAC(WindACNum).Name));
476 0 : ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
477 0 : ShowContinueError(
478 : state,
479 0 : format("..Window AC air inlet node name = {}", state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirInNode)));
480 0 : ErrorsFound = true;
481 : }
482 : // check that Window AC air outlet node is a zone inlet node.
483 17 : ZoneNodeNotFound = true;
484 122 : for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
485 105 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
486 0 : continue;
487 : }
488 199 : for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
489 111 : if (state.dataWindowAC->WindAC(WindACNum).AirOutNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
490 17 : state.dataWindowAC->WindAC(WindACNum).ZonePtr = CtrlZone;
491 17 : ZoneNodeNotFound = false;
492 17 : break;
493 : }
494 : }
495 : }
496 17 : if (ZoneNodeNotFound) {
497 0 : ShowSevereError(state,
498 0 : format("{} = \"{}\". Window AC air outlet node name must be the same as a zone inlet node name.",
499 : CurrentModuleObject,
500 0 : state.dataWindowAC->WindAC(WindACNum).Name));
501 0 : ShowContinueError(state, "..Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
502 0 : ShowContinueError(state,
503 0 : format("..Window AC air outlet node name = {}",
504 0 : state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode)));
505 0 : ErrorsFound = true;
506 : }
507 17 : CompSetFanInlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).MixedAirNode);
508 17 : CompSetFanOutlet = "UNDEFINED";
509 17 : CompSetCoolInlet = "UNDEFINED";
510 17 : CompSetCoolOutlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode);
511 : } else { // draw through fan from IF (WindAC(WindACNum)%FanPlace == BlowThru) THEN
512 : // check that Window AC air inlet node is the same as a zone exhaust node.
513 4 : ZoneNodeNotFound = true;
514 16 : for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
515 12 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
516 0 : continue;
517 : }
518 22 : for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
519 14 : if (state.dataWindowAC->WindAC(WindACNum).AirInNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
520 4 : ZoneNodeNotFound = false;
521 4 : break;
522 : }
523 : }
524 : }
525 4 : if (ZoneNodeNotFound) {
526 0 : ShowSevereError(state,
527 0 : format("{} = \"{}\". Window AC air inlet node name must be the same as a zone exhaust node name.",
528 : CurrentModuleObject,
529 0 : state.dataWindowAC->WindAC(WindACNum).Name));
530 0 : ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
531 0 : ShowContinueError(
532 : state,
533 0 : format("..Window AC inlet node name = {}", state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirInNode)));
534 0 : ErrorsFound = true;
535 : }
536 : // check that Window AC air outlet node is the same as a zone inlet node.
537 4 : ZoneNodeNotFound = true;
538 16 : for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
539 12 : if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
540 0 : continue;
541 : }
542 22 : for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
543 14 : if (state.dataWindowAC->WindAC(WindACNum).AirOutNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
544 4 : state.dataWindowAC->WindAC(WindACNum).ZonePtr = CtrlZone;
545 4 : ZoneNodeNotFound = false;
546 4 : break;
547 : }
548 : }
549 : }
550 4 : if (ZoneNodeNotFound) {
551 0 : ShowSevereError(state,
552 0 : format("{} = \"{}\". Window AC air outlet node name must be the same as a zone inlet node name.",
553 : CurrentModuleObject,
554 0 : state.dataWindowAC->WindAC(WindACNum).Name));
555 0 : ShowContinueError(state, "..Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
556 0 : ShowContinueError(
557 : state,
558 0 : format("..Window AC outlet node name = {}", state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode)));
559 0 : ErrorsFound = true;
560 : }
561 4 : CompSetFanInlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum);
562 4 : CompSetFanOutlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode);
563 4 : CompSetCoolInlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).MixedAirNode);
564 4 : CompSetCoolOutlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum);
565 : }
566 : // Add fan to component sets array
567 42 : SetUpCompSets(state,
568 21 : state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(WindACNum).UnitType),
569 21 : state.dataWindowAC->WindAC(WindACNum).Name,
570 21 : HVAC::fanTypeNames[(int)state.dataWindowAC->WindAC(WindACNum).fanType],
571 21 : state.dataWindowAC->WindAC(WindACNum).FanName,
572 : CompSetFanInlet,
573 : CompSetFanOutlet);
574 :
575 : // Add cooling coil to component sets array
576 42 : SetUpCompSets(state,
577 21 : state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(WindACNum).UnitType),
578 21 : state.dataWindowAC->WindAC(WindACNum).Name,
579 21 : state.dataWindowAC->WindAC(WindACNum).DXCoilType,
580 21 : state.dataWindowAC->WindAC(WindACNum).DXCoilName,
581 : CompSetCoolInlet,
582 : CompSetCoolOutlet);
583 :
584 : // Set up component set for OA mixer - use OA node and Mixed air node
585 42 : SetUpCompSets(state,
586 21 : state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(WindACNum).UnitType),
587 21 : state.dataWindowAC->WindAC(WindACNum).Name,
588 21 : state.dataWindowAC->WindAC(WindACNum).OAMixType,
589 21 : state.dataWindowAC->WindAC(WindACNum).OAMixName,
590 21 : state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).OutsideAirNode),
591 21 : state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).MixedAirNode));
592 : }
593 :
594 7 : Alphas.deallocate();
595 7 : cAlphaFields.deallocate();
596 7 : cNumericFields.deallocate();
597 7 : Numbers.deallocate();
598 7 : lAlphaBlanks.deallocate();
599 7 : lNumericBlanks.deallocate();
600 :
601 7 : if (ErrorsFound) {
602 0 : ShowFatalError(state,
603 0 : format("{}Errors found in getting {} input. Preceding condition causes termination.", RoutineName, CurrentModuleObject));
604 : }
605 :
606 28 : for (WindACNum = 1; WindACNum <= state.dataWindowAC->NumWindAC; ++WindACNum) {
607 : // Setup Report variables for the Fan Coils
608 42 : SetupOutputVariable(state,
609 : "Zone Window Air Conditioner Total Cooling Rate",
610 : Constant::Units::W,
611 21 : state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate,
612 : OutputProcessor::TimeStepType::System,
613 : OutputProcessor::StoreType::Average,
614 21 : state.dataWindowAC->WindAC(WindACNum).Name);
615 42 : SetupOutputVariable(state,
616 : "Zone Window Air Conditioner Total Cooling Energy",
617 : Constant::Units::J,
618 21 : state.dataWindowAC->WindAC(WindACNum).TotCoolEnergy,
619 : OutputProcessor::TimeStepType::System,
620 : OutputProcessor::StoreType::Sum,
621 21 : state.dataWindowAC->WindAC(WindACNum).Name);
622 42 : SetupOutputVariable(state,
623 : "Zone Window Air Conditioner Sensible Cooling Rate",
624 : Constant::Units::W,
625 21 : state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate,
626 : OutputProcessor::TimeStepType::System,
627 : OutputProcessor::StoreType::Average,
628 21 : state.dataWindowAC->WindAC(WindACNum).Name);
629 42 : SetupOutputVariable(state,
630 : "Zone Window Air Conditioner Sensible Cooling Energy",
631 : Constant::Units::J,
632 21 : state.dataWindowAC->WindAC(WindACNum).SensCoolEnergy,
633 : OutputProcessor::TimeStepType::System,
634 : OutputProcessor::StoreType::Sum,
635 21 : state.dataWindowAC->WindAC(WindACNum).Name);
636 42 : SetupOutputVariable(state,
637 : "Zone Window Air Conditioner Latent Cooling Rate",
638 : Constant::Units::W,
639 21 : state.dataWindowAC->WindAC(WindACNum).LatCoolEnergyRate,
640 : OutputProcessor::TimeStepType::System,
641 : OutputProcessor::StoreType::Average,
642 21 : state.dataWindowAC->WindAC(WindACNum).Name);
643 42 : SetupOutputVariable(state,
644 : "Zone Window Air Conditioner Latent Cooling Energy",
645 : Constant::Units::J,
646 21 : state.dataWindowAC->WindAC(WindACNum).LatCoolEnergy,
647 : OutputProcessor::TimeStepType::System,
648 : OutputProcessor::StoreType::Sum,
649 21 : state.dataWindowAC->WindAC(WindACNum).Name);
650 42 : SetupOutputVariable(state,
651 : "Zone Window Air Conditioner Electricity Rate",
652 : Constant::Units::W,
653 21 : state.dataWindowAC->WindAC(WindACNum).ElecPower,
654 : OutputProcessor::TimeStepType::System,
655 : OutputProcessor::StoreType::Average,
656 21 : state.dataWindowAC->WindAC(WindACNum).Name);
657 42 : SetupOutputVariable(state,
658 : "Zone Window Air Conditioner Electricity Energy",
659 : Constant::Units::J,
660 21 : state.dataWindowAC->WindAC(WindACNum).ElecConsumption,
661 : OutputProcessor::TimeStepType::System,
662 : OutputProcessor::StoreType::Sum,
663 21 : state.dataWindowAC->WindAC(WindACNum).Name);
664 42 : SetupOutputVariable(state,
665 : "Zone Window Air Conditioner Fan Part Load Ratio",
666 : Constant::Units::None,
667 21 : state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio,
668 : OutputProcessor::TimeStepType::System,
669 : OutputProcessor::StoreType::Average,
670 21 : state.dataWindowAC->WindAC(WindACNum).Name);
671 42 : SetupOutputVariable(state,
672 : "Zone Window Air Conditioner Compressor Part Load Ratio",
673 : Constant::Units::None,
674 21 : state.dataWindowAC->WindAC(WindACNum).CompPartLoadRatio,
675 : OutputProcessor::TimeStepType::System,
676 : OutputProcessor::StoreType::Average,
677 21 : state.dataWindowAC->WindAC(WindACNum).Name);
678 21 : SetupOutputVariable(state,
679 : "Zone Window Air Conditioner Fan Availability Status",
680 : Constant::Units::None,
681 21 : (int &)state.dataWindowAC->WindAC(WindACNum).availStatus,
682 : OutputProcessor::TimeStepType::System,
683 : OutputProcessor::StoreType::Average,
684 21 : state.dataWindowAC->WindAC(WindACNum).Name);
685 21 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
686 0 : SetupEMSActuator(state,
687 : "Window Air Conditioner",
688 0 : state.dataWindowAC->WindAC(WindACNum).Name,
689 : "Part Load Ratio",
690 : "[fraction]",
691 0 : state.dataWindowAC->WindAC(WindACNum).EMSOverridePartLoadFrac,
692 0 : state.dataWindowAC->WindAC(WindACNum).EMSValueForPartLoadFrac);
693 : }
694 : }
695 28 : for (WindACNum = 1; WindACNum <= state.dataWindowAC->NumWindAC; ++WindACNum) {
696 21 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
697 21 : state.dataWindowAC->WindAC(WindACNum).DXCoilName,
698 21 : state.dataWindowAC->WindAC(WindACNum).DXCoilType,
699 21 : state.dataWindowAC->WindAC(WindACNum).FanName,
700 21 : state.dataWindowAC->WindAC(WindACNum).fanType,
701 21 : state.dataWindowAC->WindAC(WindACNum).FanIndex);
702 : }
703 7 : }
704 :
705 131436 : void InitWindowAC(EnergyPlusData &state,
706 : int const WindACNum, // number of the current window AC unit being simulated
707 : Real64 &QZnReq, // zone load (modified as needed) (W)
708 : int const ZoneNum, // index to zone
709 : bool const FirstHVACIteration // TRUE when first HVAC iteration
710 : )
711 : {
712 :
713 : // SUBROUTINE INFORMATION:
714 : // AUTHOR Fred Buhl
715 : // DATE WRITTEN May 2000
716 : // MODIFIED Chandan Sharma, FSEC, March 2011: Added zone sys avail manager
717 :
718 : // PURPOSE OF THIS SUBROUTINE:
719 : // This subroutine is for initializations of the Window AC Components.
720 :
721 : // METHODOLOGY EMPLOYED:
722 : // Uses the status flags to trigger initializations.
723 :
724 : // Do the one time initializations
725 131436 : if (state.dataWindowAC->MyOneTimeFlag) {
726 :
727 5 : state.dataWindowAC->MyEnvrnFlag.allocate(state.dataWindowAC->NumWindAC);
728 5 : state.dataWindowAC->MySizeFlag.allocate(state.dataWindowAC->NumWindAC);
729 5 : state.dataWindowAC->MyZoneEqFlag.allocate(state.dataWindowAC->NumWindAC);
730 5 : state.dataWindowAC->MyEnvrnFlag = true;
731 5 : state.dataWindowAC->MySizeFlag = true;
732 5 : state.dataWindowAC->MyZoneEqFlag = true;
733 5 : state.dataWindowAC->MyOneTimeFlag = false;
734 : }
735 :
736 131436 : if (allocated(state.dataAvail->ZoneComp)) {
737 131427 : auto &availMgr = state.dataAvail->ZoneComp(DataZoneEquipment::ZoneEquipType::WindowAirConditioner).ZoneCompAvailMgrs(WindACNum);
738 131427 : if (state.dataWindowAC->MyZoneEqFlag(WindACNum)) { // initialize the name of each availability manager list and zone number
739 21 : availMgr.AvailManagerListName = state.dataWindowAC->WindAC(WindACNum).AvailManagerListName;
740 21 : availMgr.ZoneNum = ZoneNum;
741 21 : state.dataWindowAC->MyZoneEqFlag(WindACNum) = false;
742 : }
743 131427 : state.dataWindowAC->WindAC(WindACNum).availStatus = availMgr.availStatus;
744 : }
745 :
746 : // need to check all Window AC units to see if they are on Zone Equipment List or issue warning
747 131436 : if (!state.dataWindowAC->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
748 5 : state.dataWindowAC->ZoneEquipmentListChecked = true;
749 26 : for (int Loop = 1; Loop <= state.dataWindowAC->NumWindAC; ++Loop) {
750 42 : if (DataZoneEquipment::CheckZoneEquipmentList(state,
751 21 : state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(Loop).UnitType),
752 21 : state.dataWindowAC->WindAC(Loop).Name)) {
753 21 : continue;
754 : }
755 0 : ShowSevereError(state,
756 0 : format("InitWindowAC: Window AC Unit=[{},{}] is not on any ZoneHVAC:EquipmentList. It will not be simulated.",
757 0 : state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(Loop).UnitType),
758 0 : state.dataWindowAC->WindAC(Loop).Name));
759 : }
760 : }
761 :
762 131436 : if (!state.dataGlobal->SysSizingCalc && state.dataWindowAC->MySizeFlag(WindACNum)) {
763 :
764 21 : SizeWindowAC(state, WindACNum);
765 :
766 21 : state.dataWindowAC->MySizeFlag(WindACNum) = false;
767 : }
768 :
769 : // Do the Begin Environment initializations
770 131436 : if (state.dataGlobal->BeginEnvrnFlag && state.dataWindowAC->MyEnvrnFlag(WindACNum)) {
771 135 : int InNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
772 135 : int OutNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
773 135 : int OutsideAirNode = state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
774 135 : Real64 RhoAir = state.dataEnvrn->StdRhoAir;
775 : // set the mass flow rates from the input volume flow rates
776 135 : state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow = RhoAir * state.dataWindowAC->WindAC(WindACNum).MaxAirVolFlow;
777 135 : state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow = RhoAir * state.dataWindowAC->WindAC(WindACNum).OutAirVolFlow;
778 : // set the node max and min mass flow rates
779 135 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
780 135 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
781 135 : state.dataLoopNodes->Node(OutNode).MassFlowRateMax = state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow;
782 135 : state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
783 135 : state.dataLoopNodes->Node(InNode).MassFlowRateMax = state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow;
784 135 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
785 135 : state.dataWindowAC->MyEnvrnFlag(WindACNum) = false;
786 : } // end one time inits
787 :
788 131436 : if (!state.dataGlobal->BeginEnvrnFlag) {
789 130689 : state.dataWindowAC->MyEnvrnFlag(WindACNum) = true;
790 : }
791 :
792 131436 : if (state.dataWindowAC->WindAC(WindACNum).fanOpModeSched != nullptr) {
793 131436 : if (state.dataWindowAC->WindAC(WindACNum).fanOpModeSched->getCurrentVal() == 0.0) {
794 97604 : state.dataWindowAC->WindAC(WindACNum).fanOp = HVAC::FanOp::Cycling;
795 : } else {
796 33832 : state.dataWindowAC->WindAC(WindACNum).fanOp = HVAC::FanOp::Continuous;
797 : }
798 : }
799 :
800 : // These initializations are done every iteration
801 131436 : int InletNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
802 131436 : int OutsideAirNode = state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
803 131436 : int AirRelNode = state.dataWindowAC->WindAC(WindACNum).AirReliefNode;
804 : // Set the inlet node mass flow rate
805 226494 : if (state.dataWindowAC->WindAC(WindACNum).availSched->getCurrentVal() <= 0.0 ||
806 226494 : (state.dataWindowAC->WindAC(WindACNum).fanAvailSched->getCurrentVal() <= 0.0 && !state.dataHVACGlobal->TurnFansOn) ||
807 95058 : state.dataHVACGlobal->TurnFansOff) {
808 36378 : state.dataWindowAC->WindAC(WindACNum).PartLoadFrac = 0.0;
809 36378 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
810 36378 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
811 36378 : state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
812 36378 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
813 36378 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = 0.0;
814 36378 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
815 36378 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
816 36378 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = 0.0;
817 36378 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
818 : } else {
819 95058 : state.dataWindowAC->WindAC(WindACNum).PartLoadFrac = 1.0;
820 95058 : state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow;
821 95058 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
822 95058 : state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
823 95058 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
824 95058 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
825 95058 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
826 95058 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
827 95058 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
828 95058 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
829 : }
830 :
831 : // Original thermostat control logic (works only for cycling fan systems)
832 210275 : if (QZnReq < (-1.0 * HVAC::SmallLoad) && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) &&
833 78839 : state.dataWindowAC->WindAC(WindACNum).PartLoadFrac > 0.0) {
834 71581 : state.dataWindowAC->CoolingLoad = true;
835 : } else {
836 59855 : state.dataWindowAC->CoolingLoad = false;
837 : }
838 :
839 : // Constant fan systems are tested for ventilation load to determine if load to be met changes.
840 181814 : if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Continuous && state.dataWindowAC->WindAC(WindACNum).PartLoadFrac > 0.0 &&
841 181814 : (state.dataWindowAC->WindAC(WindACNum).fanAvailSched->getCurrentVal() > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
842 16546 : !state.dataHVACGlobal->TurnFansOff) {
843 :
844 : Real64 NoCompOutput; // sensible load delivered with compressor off (W)
845 16546 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, state.dataWindowAC->WindAC(WindACNum).fanOp, 0.0, false, NoCompOutput);
846 :
847 16546 : Real64 QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
848 :
849 : // If the unit has a net heating capacity and the zone temp is below the Tstat cooling setpoint
850 16570 : if (NoCompOutput > (-1.0 * HVAC::SmallLoad) && QToCoolSetPt > (-1.0 * HVAC::SmallLoad) &&
851 24 : state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
852 24 : if (NoCompOutput > QToCoolSetPt) {
853 6 : QZnReq = QToCoolSetPt;
854 6 : state.dataWindowAC->CoolingLoad = true;
855 : }
856 : }
857 : }
858 131436 : }
859 :
860 21 : void SizeWindowAC(EnergyPlusData &state, int const WindACNum)
861 : {
862 :
863 : // SUBROUTINE INFORMATION:
864 : // AUTHOR Fred Buhl
865 : // DATE WRITTEN January 2002
866 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
867 : // July 2014, B. Nigusse, added scalable sizing
868 :
869 : // PURPOSE OF THIS SUBROUTINE:
870 : // This subroutine is for sizing Window AC Unit components for which flow rates have not been
871 : // specified in the input.
872 :
873 : // METHODOLOGY EMPLOYED:
874 : // Obtains flow rates from the zone or system sizing arrays
875 :
876 : // Using/Aliasing
877 : using namespace DataSizing;
878 :
879 : // SUBROUTINE PARAMETER DEFINITIONS:
880 : static constexpr std::string_view RoutineName("SizeWindowAC: "); // include trailing blank space
881 :
882 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
883 21 : auto &windowAC = state.dataWindowAC->WindAC(WindACNum);
884 :
885 21 : Real64 MaxAirVolFlowDes = 0.0; // Autosized maximum air flow for reporting
886 21 : Real64 MaxAirVolFlowUser = 0.0; // Hardsized maximum air flow for reporting
887 21 : Real64 OutAirVolFlowDes = 0.0; // Autosized outdoor air flow for reporting
888 21 : Real64 OutAirVolFlowUser = 0.0; // Hardsized outdoor ari flow for reporting
889 21 : bool IsAutoSize = false; // Indicator to autosize
890 21 : std::string const CompType = "ZoneHVAC:WindowAirConditioner"; // component name
891 21 : std::string const CompName = windowAC.Name; // component type
892 21 : Real64 TempSize = AutoSize; // autosized value of coil input field
893 21 : int FieldNum = 2; // IDD numeric field number where input field description is found
894 21 : bool PrintFlag = false; // TRUE when sizing information is reported in the eio file
895 :
896 21 : state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
897 21 : state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
898 21 : state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
899 21 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
900 21 : state.dataSize->DataScalableSizingON = false;
901 21 : state.dataSize->ZoneHeatingOnlyFan = false;
902 21 : state.dataSize->ZoneCoolingOnlyFan = true;
903 21 : state.dataSize->DataScalableCapSizingON = false;
904 21 : state.dataSize->DataZoneNumber = windowAC.ZonePtr;
905 21 : state.dataSize->DataFanType = windowAC.fanType;
906 21 : state.dataSize->DataFanIndex = windowAC.FanIndex;
907 21 : state.dataSize->DataFanPlacement = windowAC.fanPlace;
908 :
909 21 : if (state.dataSize->CurZoneEqNum > 0) {
910 21 : auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
911 :
912 21 : if (windowAC.HVACSizingIndex > 0) {
913 : // N1 , \field Maximum Supply Air Flow Rate
914 0 : auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(windowAC.HVACSizingIndex);
915 :
916 0 : int SizingMethod = HVAC::CoolingAirflowSizing;
917 0 : PrintFlag = true;
918 0 : int const SAFMethod = zoneHVACSizing.CoolingSAFMethod;
919 0 : zoneEqSizing.SizingMethod(SizingMethod) = SAFMethod;
920 0 : if (SAFMethod == None || SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea ||
921 : SAFMethod == FractionOfAutosizedCoolingAirflow) {
922 0 : if (SAFMethod == SupplyAirFlowRate) {
923 0 : if (zoneHVACSizing.MaxCoolAirVolFlow > 0.0) {
924 0 : zoneEqSizing.AirVolFlow = zoneHVACSizing.MaxCoolAirVolFlow;
925 0 : zoneEqSizing.SystemAirFlow = true;
926 : }
927 0 : TempSize = zoneHVACSizing.MaxCoolAirVolFlow;
928 0 : } else if (SAFMethod == FlowPerFloorArea) {
929 0 : zoneEqSizing.SystemAirFlow = true;
930 0 : zoneEqSizing.AirVolFlow =
931 0 : zoneHVACSizing.MaxCoolAirVolFlow * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
932 0 : TempSize = zoneEqSizing.AirVolFlow;
933 0 : state.dataSize->DataScalableSizingON = true;
934 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
935 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = zoneHVACSizing.MaxCoolAirVolFlow;
936 0 : TempSize = AutoSize;
937 0 : state.dataSize->DataScalableSizingON = true;
938 : } else {
939 0 : TempSize = zoneHVACSizing.MaxCoolAirVolFlow;
940 : }
941 0 : bool errorsFound = false;
942 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
943 0 : std::string stringOverride = "Maximum Supply Air Flow Rate [m3/s]";
944 0 : if (state.dataGlobal->isEpJSON) {
945 0 : stringOverride = "maximum_supply_air_flow_rate [m3/s]";
946 : }
947 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
948 : // sizingCoolingAirFlow.setHVACSizingIndexData(windowAC.HVACSizingIndex);
949 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
950 0 : windowAC.MaxAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
951 :
952 0 : } else if (SAFMethod == FlowPerCoolingCapacity) {
953 0 : SizingMethod = HVAC::CoolingCapacitySizing;
954 0 : TempSize = AutoSize;
955 0 : PrintFlag = false;
956 0 : state.dataSize->DataScalableSizingON = true;
957 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
958 0 : if (zoneHVACSizing.CoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
959 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
960 : }
961 0 : bool errorsFound = false;
962 0 : CoolingCapacitySizer sizerCoolingCapacity;
963 0 : sizerCoolingCapacity.overrideSizingString("");
964 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
965 0 : state.dataSize->DataCapacityUsedForSizing = sizerCoolingCapacity.size(state, TempSize, errorsFound);
966 0 : state.dataSize->DataFlowPerCoolingCapacity = zoneHVACSizing.MaxCoolAirVolFlow;
967 0 : PrintFlag = true;
968 0 : TempSize = AutoSize;
969 0 : errorsFound = false;
970 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
971 0 : std::string stringOverride = "Maximum Supply Air Flow Rate [m3/s]";
972 0 : if (state.dataGlobal->isEpJSON) {
973 0 : stringOverride = "maximum_supply_air_flow_rate [m3/s]";
974 : }
975 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
976 : // sizingCoolingAirFlow.setHVACSizingIndexData(windowAC.HVACSizingIndex);
977 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
978 0 : windowAC.MaxAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
979 0 : }
980 : // DataScalableSizingON = false;
981 :
982 : // initialize capacity sizing variables: cooling
983 : // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
984 : // FractionOfAutosizedHeatingCapacity )
985 0 : int const CapSizingMethod = zoneHVACSizing.CoolingCapMethod;
986 0 : zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
987 0 : if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
988 : CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
989 0 : if (CapSizingMethod == CoolingDesignCapacity) {
990 0 : if (zoneHVACSizing.ScaledCoolingCapacity > 0.0) {
991 0 : zoneEqSizing.CoolingCapacity = true;
992 0 : zoneEqSizing.DesCoolingLoad = zoneHVACSizing.ScaledCoolingCapacity;
993 : }
994 0 : } else if (CapSizingMethod == CapacityPerFloorArea) {
995 0 : zoneEqSizing.CoolingCapacity = true;
996 0 : zoneEqSizing.DesCoolingLoad =
997 0 : zoneHVACSizing.ScaledCoolingCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
998 0 : state.dataSize->DataScalableCapSizingON = true;
999 0 : } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
1000 0 : state.dataSize->DataFracOfAutosizedCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
1001 0 : state.dataSize->DataScalableCapSizingON = true;
1002 : }
1003 : }
1004 : } else {
1005 : // no scalable sizing method has been specified. Sizing proceeds using the method
1006 : // specified in the zoneHVAC object
1007 : // N1 , \field Maximum Supply Air Flow Rate
1008 21 : int FieldNum = 1;
1009 21 : PrintFlag = true;
1010 21 : std::string stringOverride = state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames(FieldNum) + " [m3/s]";
1011 21 : TempSize = windowAC.MaxAirVolFlow;
1012 21 : bool errorsFound = false;
1013 21 : SystemAirFlowSizer sizerSystemAirFlow;
1014 21 : sizerSystemAirFlow.overrideSizingString(stringOverride);
1015 : // sizerSystemAirFlow.setHVACSizingIndexData(windowAC.HVACSizingIndex);
1016 21 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1017 21 : windowAC.MaxAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
1018 21 : }
1019 :
1020 21 : if (windowAC.OutAirVolFlow == AutoSize) {
1021 :
1022 15 : CheckZoneSizing(state, state.dataWindowAC->cWindowAC_UnitTypes(windowAC.UnitType), windowAC.Name);
1023 15 : windowAC.OutAirVolFlow = min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, windowAC.MaxAirVolFlow);
1024 15 : if (windowAC.OutAirVolFlow < SmallAirVolFlow) {
1025 0 : windowAC.OutAirVolFlow = 0.0;
1026 : }
1027 30 : BaseSizer::reportSizerOutput(state,
1028 15 : state.dataWindowAC->cWindowAC_UnitTypes(windowAC.UnitType),
1029 : windowAC.Name,
1030 : "Maximum Outdoor Air Flow Rate [m3/s]",
1031 : windowAC.OutAirVolFlow);
1032 : }
1033 :
1034 21 : zoneEqSizing.OAVolFlow = windowAC.OutAirVolFlow;
1035 21 : zoneEqSizing.AirVolFlow = windowAC.MaxAirVolFlow;
1036 : // Make the Fan be sized by this
1037 21 : zoneEqSizing.CoolingAirFlow = true;
1038 21 : zoneEqSizing.CoolingAirVolFlow = windowAC.MaxAirVolFlow;
1039 : }
1040 :
1041 21 : state.dataSize->DataScalableCapSizingON = false;
1042 21 : }
1043 :
1044 131436 : void SimCyclingWindowAC(EnergyPlusData &state,
1045 : int const WindACNum, // number of the current window AC unit being simulated
1046 : [[maybe_unused]] int const ZoneNum, // number of zone being served !unused1208
1047 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
1048 : Real64 &PowerMet, // Sensible power supplied (W)
1049 : Real64 const QZnReq, // Sensible load to be met (W)
1050 : Real64 &LatOutputProvided // Latent power supplied (kg/s), negative = dehumidification
1051 : )
1052 : {
1053 :
1054 : // SUBROUTINE INFORMATION:
1055 : // AUTHOR Fred Buhl
1056 : // DATE WRITTEN May 2000
1057 : // MODIFIED Buhl/Shirey Mar 2001, Shirey Aug 2009 (LatOutputProvided)
1058 :
1059 : // PURPOSE OF THIS SUBROUTINE:
1060 : // Simulate a cycling window air conditioner unit; adjust its output to match the
1061 : // remaining zone load.
1062 :
1063 : // METHODOLOGY EMPLOYED:
1064 : // If unit is on, calls ControlWindACOutput to obtain the desired unit output
1065 :
1066 : Real64 PartLoadFrac; // unit part load fraction
1067 : bool HXUnitOn; // Used to control HX heat recovery as needed
1068 :
1069 : // zero the DX coil electricity consumption
1070 :
1071 131436 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
1072 : // initialize local variables
1073 131436 : bool UnitOn = true;
1074 131436 : bool CoilOn = true;
1075 131436 : Real64 QUnitOut = 0.0; // Dry air sens. cooling provided by AC unit [watts]
1076 131436 : Real64 LatentOutput = 0.0; // Latent (moisture) add/removal rate, negative is dehumidification [kg/s]
1077 131436 : int OutletNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
1078 131436 : int InletNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
1079 131436 : Real64 AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
1080 131436 : Real64 Test = AirMassFlow;
1081 131436 : Real64 CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(InletNode).HumRat); // inlet air specific heat [J/kg-C]
1082 131436 : HVAC::FanOp fanOp = state.dataWindowAC->WindAC(WindACNum).fanOp;
1083 :
1084 : // set the on/off flags
1085 131436 : if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Cycling) {
1086 : // cycling unit: only runs if there is a load.
1087 97604 : if (!state.dataWindowAC->CoolingLoad || AirMassFlow < SmallMassFlow) {
1088 39390 : UnitOn = false;
1089 39390 : CoilOn = false;
1090 : }
1091 33832 : } else if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Continuous) {
1092 : // continuous unit: fan runs if scheduled on; coil runs only if cooling load
1093 33832 : if (AirMassFlow < SmallMassFlow) {
1094 17290 : UnitOn = false;
1095 17290 : CoilOn = false;
1096 16542 : } else if (!state.dataWindowAC->CoolingLoad) {
1097 3184 : CoilOn = false;
1098 : }
1099 : }
1100 :
1101 131436 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
1102 :
1103 131436 : if (UnitOn && CoilOn) {
1104 71572 : HXUnitOn = false;
1105 71572 : ControlCycWindACOutput(state, WindACNum, FirstHVACIteration, fanOp, QZnReq, PartLoadFrac, HXUnitOn);
1106 : } else {
1107 59864 : PartLoadFrac = 0.0;
1108 59864 : HXUnitOn = false;
1109 : }
1110 :
1111 131436 : state.dataWindowAC->WindAC(WindACNum).PartLoadFrac = PartLoadFrac;
1112 :
1113 131436 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, PartLoadFrac, HXUnitOn, QUnitOut);
1114 :
1115 : // Reseting AirMassFlow to inlet node mass flow rate since inlet mass flow rate may be getting
1116 : // manipulated in subroutine CalcWindowACOutput
1117 :
1118 131436 : AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
1119 131436 : Real64 MinHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
1120 131436 : QUnitOut = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
1121 131436 : PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
1122 :
1123 131436 : Real64 SensCoolOut = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
1124 131436 : PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
1125 :
1126 : // CR9155 Remove specific humidity calculations
1127 131436 : Real64 SpecHumOut = state.dataLoopNodes->Node(OutletNode).HumRat;
1128 131436 : Real64 SpecHumIn = state.dataLoopNodes->Node(InletNode).HumRat;
1129 131436 : LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s
1130 :
1131 131436 : Real64 QTotUnitOut = AirMassFlow * (state.dataLoopNodes->Node(OutletNode).Enthalpy - state.dataLoopNodes->Node(InletNode).Enthalpy);
1132 :
1133 : // report variables
1134 131436 : state.dataWindowAC->WindAC(WindACNum).CompPartLoadRatio = state.dataWindowAC->WindAC(WindACNum).PartLoadFrac;
1135 131436 : if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Cycling) {
1136 97604 : state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio = state.dataWindowAC->WindAC(WindACNum).PartLoadFrac;
1137 : } else {
1138 33832 : if (UnitOn) {
1139 16542 : state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio = 1.0;
1140 : } else {
1141 17290 : state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio = 0.0;
1142 : }
1143 : }
1144 131436 : state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate = std::abs(min(0.0, SensCoolOut));
1145 131436 : state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
1146 131436 : state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate =
1147 131436 : min(state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate, state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate);
1148 131436 : state.dataWindowAC->WindAC(WindACNum).LatCoolEnergyRate =
1149 131436 : state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate - state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate;
1150 131436 : Real64 locFanElecPower = state.dataFans->fans(state.dataWindowAC->WindAC(WindACNum).FanIndex)->totalPower;
1151 131436 : state.dataWindowAC->WindAC(WindACNum).ElecPower = locFanElecPower + state.dataHVACGlobal->DXElecCoolingPower;
1152 :
1153 131436 : PowerMet = QUnitOut;
1154 131436 : LatOutputProvided = LatentOutput;
1155 131436 : }
1156 :
1157 131436 : void ReportWindowAC(EnergyPlusData &state, int const WindACNum) // number of the current AC unit being simulated
1158 : {
1159 :
1160 : // SUBROUTINE INFORMATION:
1161 : // AUTHOR Fred Buhl
1162 : // DATE WRITTEN May 2000
1163 :
1164 : // PURPOSE OF THIS SUBROUTINE:
1165 : // Fills some of the report variables for the window AC units
1166 :
1167 131436 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1168 :
1169 131436 : state.dataWindowAC->WindAC(WindACNum).SensCoolEnergy = state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate * TimeStepSysSec;
1170 131436 : state.dataWindowAC->WindAC(WindACNum).TotCoolEnergy = state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate * TimeStepSysSec;
1171 131436 : state.dataWindowAC->WindAC(WindACNum).LatCoolEnergy = state.dataWindowAC->WindAC(WindACNum).LatCoolEnergyRate * TimeStepSysSec;
1172 131436 : state.dataWindowAC->WindAC(WindACNum).ElecConsumption = state.dataWindowAC->WindAC(WindACNum).ElecPower * TimeStepSysSec;
1173 :
1174 131436 : if (state.dataWindowAC->WindAC(WindACNum).FirstPass) { // reset sizing flags so other zone equipment can size normally
1175 42 : if (!state.dataGlobal->SysSizingCalc) {
1176 21 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, state.dataWindowAC->WindAC(WindACNum).FirstPass);
1177 : }
1178 : }
1179 131436 : }
1180 :
1181 466318 : void CalcWindowACOutput(EnergyPlusData &state,
1182 : int const WindACNum, // Unit index in fan coil array
1183 : bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
1184 : HVAC::FanOp const fanOp, // operating mode: FanOp::Cycling | FanOp::Continuous
1185 : Real64 const PartLoadFrac, // unit part load fraction
1186 : bool const HXUnitOn, // Flag to toggle HX heat recovery as needed
1187 : Real64 &LoadMet // load met by unit (watts)
1188 : )
1189 : {
1190 :
1191 : // SUBROUTINE INFORMATION:
1192 : // AUTHOR Fred Buhl
1193 : // DATE WRITTEN May 2000
1194 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
1195 :
1196 : // PURPOSE OF THIS SUBROUTINE:
1197 : // Simulate the components making up the cycling window AC unit.
1198 :
1199 : // METHODOLOGY EMPLOYED:
1200 : // Simulates the unit components sequentially in the air flow direction.
1201 :
1202 466318 : int OutletNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
1203 466318 : int InletNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
1204 466318 : int OutsideAirNode = state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
1205 466318 : int AirRelNode = state.dataWindowAC->WindAC(WindACNum).AirReliefNode;
1206 : // for cycling fans, pretend we have VAV
1207 466318 : if (fanOp == HVAC::FanOp::Cycling) {
1208 370266 : state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRateMax * PartLoadFrac;
1209 : // Don't let the outside air flow be > supply air flow
1210 370266 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate =
1211 370266 : min(state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax, state.dataLoopNodes->Node(InletNode).MassFlowRate);
1212 370266 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
1213 : }
1214 466318 : Real64 AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
1215 466318 : MixedAir::SimOAMixer(state, state.dataWindowAC->WindAC(WindACNum).OAMixName, state.dataWindowAC->WindAC(WindACNum).OAMixIndex);
1216 :
1217 : // if blow through, simulate fan then coil. For draw through, simulate coil then fan.
1218 466318 : if (state.dataWindowAC->WindAC(WindACNum).fanPlace == HVAC::FanPlace::BlowThru) {
1219 418834 : state.dataFans->fans(state.dataWindowAC->WindAC(WindACNum).FanIndex)->simulate(state, FirstHVACIteration, PartLoadFrac);
1220 : }
1221 :
1222 466318 : if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted) {
1223 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
1224 0 : state.dataWindowAC->WindAC(WindACNum).DXCoilName,
1225 : FirstHVACIteration,
1226 : HVAC::CompressorOp::On,
1227 : PartLoadFrac,
1228 0 : state.dataWindowAC->WindAC(WindACNum).DXCoilIndex,
1229 0 : state.dataWindowAC->WindAC(WindACNum).fanOp,
1230 : HXUnitOn);
1231 466318 : } else if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
1232 12723 : Real64 QZnReq(-1.0); // Zone load (W), input to variable-speed DX coil
1233 12723 : Real64 QLatReq(0.0); // Zone latent load, input to variable-speed DX coil
1234 12723 : Real64 OnOffAirFlowRatio(1.0); // ratio of compressor on flow to average flow over time step
1235 :
1236 12723 : VariableSpeedCoils::SimVariableSpeedCoils(state,
1237 12723 : state.dataWindowAC->WindAC(WindACNum).DXCoilName,
1238 12723 : state.dataWindowAC->WindAC(WindACNum).DXCoilIndex,
1239 12723 : state.dataWindowAC->WindAC(WindACNum).fanOp,
1240 : HVAC::CompressorOp::On,
1241 : PartLoadFrac,
1242 12723 : state.dataWindowAC->WindAC(WindACNum).DXCoilNumOfSpeeds,
1243 : 1.0,
1244 : QZnReq,
1245 : QLatReq,
1246 : OnOffAirFlowRatio);
1247 :
1248 : } else {
1249 907190 : DXCoils::SimDXCoil(state,
1250 453595 : state.dataWindowAC->WindAC(WindACNum).DXCoilName,
1251 : HVAC::CompressorOp::On,
1252 : FirstHVACIteration,
1253 453595 : state.dataWindowAC->WindAC(WindACNum).DXCoilIndex,
1254 453595 : state.dataWindowAC->WindAC(WindACNum).fanOp,
1255 : PartLoadFrac);
1256 : }
1257 :
1258 466318 : if (state.dataWindowAC->WindAC(WindACNum).fanPlace == HVAC::FanPlace::DrawThru) {
1259 47484 : state.dataFans->fans(state.dataWindowAC->WindAC(WindACNum).FanIndex)->simulate(state, FirstHVACIteration, PartLoadFrac);
1260 : }
1261 :
1262 466318 : Real64 MinHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
1263 466318 : LoadMet = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
1264 466318 : PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
1265 466318 : }
1266 :
1267 71572 : void ControlCycWindACOutput(EnergyPlusData &state,
1268 : int const WindACNum, // Unit index in fan coil array
1269 : bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
1270 : HVAC::FanOp const fanOp, // operating mode: FanOp::Cycling | FanOp::Continuous
1271 : Real64 const QZnReq, // cooling output needed by zone [W]
1272 : Real64 &PartLoadFrac, // unit part load fraction
1273 : bool &HXUnitOn // Used to control HX heat recovery as needed
1274 : )
1275 : {
1276 :
1277 : // SUBROUTINE INFORMATION:
1278 : // AUTHOR Fred Buhl
1279 : // DATE WRITTEN May 2000
1280 : // MODIFIED Shirey, May 2001
1281 :
1282 : // PURPOSE OF THIS SUBROUTINE:
1283 : // Determine the part load fraction of the air conditioner for this time step
1284 :
1285 : // METHODOLOGY EMPLOYED:
1286 : // Linear interpolation between max and min outputs
1287 :
1288 71572 : int constexpr MaxIter(50); // maximum number of iterations
1289 71572 : Real64 constexpr MinPLF(0.0); // minimum part load factor allowed
1290 :
1291 : Real64 FullOutput; // unit full output [W]
1292 : Real64 NoCoolOutput; // output when no active cooling [W]
1293 : Real64 ActualOutput; // output at current partloadfrac [W]
1294 :
1295 : // DX Cooling HX assisted coils can cycle the heat exchanger, see if coil ON, HX OFF can meet humidity setpoint if one exists
1296 71572 : if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted) {
1297 : // Check for a setpoint at the HX outlet node, if it doesn't exist always run the HX
1298 0 : if (state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax == SensedNodeFlagValue) {
1299 0 : HXUnitOn = true;
1300 : } else {
1301 0 : HXUnitOn = false;
1302 : }
1303 : } else {
1304 71572 : HXUnitOn = false;
1305 : }
1306 :
1307 71572 : if (state.dataWindowAC->WindAC(WindACNum).EMSOverridePartLoadFrac) {
1308 :
1309 0 : PartLoadFrac = state.dataWindowAC->WindAC(WindACNum).EMSValueForPartLoadFrac;
1310 : }
1311 :
1312 : // Get result when DX coil is off
1313 71572 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, 0.0, HXUnitOn, NoCoolOutput);
1314 :
1315 : // If NoCoolOutput < QZnReq, the coil needs to be off
1316 71572 : if (NoCoolOutput < QZnReq) {
1317 0 : PartLoadFrac = 0.0;
1318 176 : return;
1319 : }
1320 :
1321 : // Get full load result
1322 71572 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, 1.0, HXUnitOn, FullOutput);
1323 :
1324 : // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
1325 : // Check that this is the case; if not set PartLoadFrac = 0.0 (off) and return
1326 71572 : if (FullOutput >= 0.0 || FullOutput >= NoCoolOutput) {
1327 0 : PartLoadFrac = 0.0;
1328 0 : return;
1329 : }
1330 :
1331 : // If the QZnReq <= FullOutput the unit needs to run full out
1332 71572 : if (QZnReq <= FullOutput && state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num != CoilDX_CoolingHXAssisted) {
1333 176 : PartLoadFrac = 1.0;
1334 176 : return;
1335 : }
1336 :
1337 : // If the QZnReq <= FullOutput and a HXAssisted coil is used, check the node setpoint for a maximum humidity ratio set point
1338 : // HumRatMax will be equal to -999 if no setpoint exists or some set point managers may still use 0 as a no moisture load indicator
1339 71396 : if (QZnReq <= FullOutput && state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted &&
1340 0 : state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax <= 0.0) {
1341 0 : PartLoadFrac = 1.0;
1342 0 : return;
1343 : }
1344 :
1345 : // QZnReq should now be greater than FullOutput and less than NoCoolOutput)
1346 : // Calculate the part load fraction
1347 :
1348 71396 : PartLoadFrac = max(MinPLF, std::abs(QZnReq - NoCoolOutput) / std::abs(FullOutput - NoCoolOutput));
1349 :
1350 71396 : Real64 ErrorToler = state.dataWindowAC->WindAC(WindACNum).ConvergenceTol; // Error tolerance for convergence from input deck
1351 71396 : Real64 Error = 1.0; // initialize error value for comparison against tolerance
1352 71396 : int Iter = 0; // initialize iteration counter
1353 71396 : Real64 Relax = 1.0;
1354 :
1355 246588 : while ((std::abs(Error) > ErrorToler) && (Iter <= MaxIter) && PartLoadFrac > MinPLF) {
1356 : // Get result when DX coil is operating at partloadfrac
1357 175192 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, PartLoadFrac, HXUnitOn, ActualOutput);
1358 175192 : Error = (QZnReq - ActualOutput) / QZnReq;
1359 175192 : Real64 DelPLF = (QZnReq - ActualOutput) / FullOutput;
1360 175192 : PartLoadFrac += Relax * DelPLF;
1361 175192 : PartLoadFrac = max(MinPLF, min(1.0, PartLoadFrac));
1362 175192 : ++Iter;
1363 175192 : if (Iter == 16) {
1364 10 : Relax = 0.5;
1365 : }
1366 : }
1367 71396 : if (Iter > MaxIter) {
1368 0 : if (state.dataWindowAC->WindAC(WindACNum).MaxIterIndex1 == 0) {
1369 0 : ShowWarningMessage(state,
1370 0 : format("ZoneHVAC:WindowAirConditioner=\"{}\" -- Exceeded max iterations while adjusting compressor sensible "
1371 : "runtime to meet the zone load within the cooling convergence tolerance.",
1372 0 : state.dataWindowAC->WindAC(WindACNum).Name));
1373 0 : ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIter));
1374 : }
1375 0 : ShowRecurringWarningErrorAtEnd(state,
1376 0 : "ZoneHVAC:WindowAirConditioner=\"" + state.dataWindowAC->WindAC(WindACNum).Name +
1377 : "\" -- Exceeded max iterations error (sensible runtime) continues...",
1378 0 : state.dataWindowAC->WindAC(WindACNum).MaxIterIndex1);
1379 : }
1380 :
1381 : // HX is off up until this point where the outlet air humidity ratio is tested to see if HX needs to be turned on
1382 71396 : if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted &&
1383 0 : state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax <
1384 71396 : state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRat &&
1385 0 : state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax > 0.0) {
1386 :
1387 : // Run the HX to recovery energy and improve latent performance
1388 0 : HXUnitOn = true;
1389 :
1390 : // Get full load result
1391 0 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, 1.0, HXUnitOn, FullOutput);
1392 :
1393 0 : if (state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax <
1394 0 : state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRat ||
1395 0 : QZnReq <= FullOutput) {
1396 0 : PartLoadFrac = 1.0;
1397 0 : return;
1398 : }
1399 :
1400 0 : Error = 1.0; // initialize error value for comparison against tolerance
1401 0 : Iter = 0; // initialize iteration counter
1402 0 : Relax = 1.0;
1403 :
1404 0 : while ((std::abs(Error) > ErrorToler) && (Iter <= MaxIter) && PartLoadFrac > MinPLF) {
1405 : // Get result when DX coil is operating at partloadfrac
1406 0 : CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, PartLoadFrac, HXUnitOn, ActualOutput);
1407 0 : Error = (QZnReq - ActualOutput) / QZnReq;
1408 0 : Real64 DelPLF = (QZnReq - ActualOutput) / FullOutput;
1409 0 : PartLoadFrac += Relax * DelPLF;
1410 0 : PartLoadFrac = max(MinPLF, min(1.0, PartLoadFrac));
1411 0 : ++Iter;
1412 0 : if (Iter == 16) {
1413 0 : Relax = 0.5;
1414 : }
1415 : }
1416 0 : if (Iter > MaxIter) {
1417 0 : if (state.dataWindowAC->WindAC(WindACNum).MaxIterIndex2 == 0) {
1418 0 : ShowWarningMessage(state,
1419 0 : format("ZoneHVAC:WindowAirConditioner=\"{}\" -- Exceeded max iterations while adjusting compressor latent "
1420 : "runtime to meet the zone load within the cooling convergence tolerance.",
1421 0 : state.dataWindowAC->WindAC(WindACNum).Name));
1422 0 : ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIter));
1423 : }
1424 0 : ShowRecurringWarningErrorAtEnd(state,
1425 0 : "ZoneHVAC:WindowAirConditioner=\"" + state.dataWindowAC->WindAC(WindACNum).Name +
1426 : "\" -- Exceeded max iterations error (latent runtime) continues...",
1427 0 : state.dataWindowAC->WindAC(WindACNum).MaxIterIndex2);
1428 : }
1429 :
1430 : } // WindAC(WindACNum)%DXCoilType_Num == CoilDX_CoolingHXAssisted && *
1431 : }
1432 :
1433 16 : bool getWindowACNodeNumber(EnergyPlusData &state, int const nodeNumber)
1434 : {
1435 16 : if (state.dataWindowAC->GetWindowACInputFlag) {
1436 2 : GetWindowAC(state);
1437 2 : state.dataWindowAC->GetWindowACInputFlag = false;
1438 : }
1439 :
1440 16 : for (int windowACIndex = 1; windowACIndex <= state.dataWindowAC->NumWindAC; ++windowACIndex) {
1441 0 : auto &windowAC = state.dataWindowAC->WindAC(windowACIndex);
1442 0 : int FanInletNodeIndex = state.dataFans->fans(windowAC.FanIndex)->inletNodeNum;
1443 0 : int FanOutletNodeIndex = state.dataFans->fans(windowAC.FanIndex)->outletNodeNum;
1444 :
1445 0 : if (windowAC.OutAirVolFlow == 0 &&
1446 0 : (nodeNumber == windowAC.OutsideAirNode || nodeNumber == windowAC.MixedAirNode || nodeNumber == windowAC.AirReliefNode ||
1447 0 : nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex || nodeNumber == windowAC.AirInNode ||
1448 0 : nodeNumber == windowAC.CoilOutletNodeNum || nodeNumber == windowAC.AirOutNode || nodeNumber == windowAC.ReturnAirNode)) {
1449 0 : return true;
1450 : }
1451 : }
1452 16 : return false;
1453 : }
1454 :
1455 16914 : int GetWindowACZoneInletAirNode(EnergyPlusData &state, int const WindACNum)
1456 : {
1457 :
1458 : // FUNCTION INFORMATION:
1459 : // AUTHOR B Griffith
1460 : // DATE WRITTEN Dec 2006
1461 :
1462 : // PURPOSE OF THIS FUNCTION:
1463 : // lookup function for zone inlet node
1464 :
1465 : // Return value
1466 : int GetWindowACZoneInletAirNode;
1467 :
1468 16914 : if (state.dataWindowAC->GetWindowACInputFlag) {
1469 0 : GetWindowAC(state);
1470 0 : state.dataWindowAC->GetWindowACInputFlag = false;
1471 : }
1472 :
1473 16914 : GetWindowACZoneInletAirNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
1474 :
1475 16914 : return GetWindowACZoneInletAirNode;
1476 : }
1477 :
1478 16914 : int GetWindowACOutAirNode(EnergyPlusData &state, int const WindACNum)
1479 : {
1480 :
1481 : // FUNCTION INFORMATION:
1482 : // AUTHOR B Griffith
1483 : // DATE WRITTEN Dec 2006
1484 :
1485 : // PURPOSE OF THIS FUNCTION:
1486 : // lookup function for OA inlet node
1487 :
1488 16914 : if (state.dataWindowAC->GetWindowACInputFlag) {
1489 0 : GetWindowAC(state);
1490 0 : state.dataWindowAC->GetWindowACInputFlag = false;
1491 : }
1492 :
1493 16914 : return state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
1494 : }
1495 :
1496 16914 : int GetWindowACReturnAirNode(EnergyPlusData &state, int const WindACNum)
1497 : {
1498 :
1499 : // FUNCTION INFORMATION:
1500 : // AUTHOR B Griffith
1501 : // DATE WRITTEN Dec 2006
1502 :
1503 : // PURPOSE OF THIS FUNCTION:
1504 : // lookup function for mixer return air node for ventilation load reporting
1505 :
1506 : // Return value
1507 : int GetWindowACReturnAirNode;
1508 :
1509 16914 : if (state.dataWindowAC->GetWindowACInputFlag) {
1510 0 : GetWindowAC(state);
1511 0 : state.dataWindowAC->GetWindowACInputFlag = false;
1512 : }
1513 :
1514 16914 : if (WindACNum > 0 && WindACNum <= state.dataWindowAC->NumWindAC) {
1515 16914 : if (state.dataWindowAC->WindAC(WindACNum).OAMixIndex > 0) {
1516 16914 : GetWindowACReturnAirNode = MixedAir::GetOAMixerReturnNodeNumber(state, state.dataWindowAC->WindAC(WindACNum).OAMixIndex);
1517 : } else {
1518 0 : GetWindowACReturnAirNode = 0;
1519 : }
1520 : } else {
1521 0 : GetWindowACReturnAirNode = 0;
1522 : }
1523 :
1524 16914 : return GetWindowACReturnAirNode;
1525 : }
1526 :
1527 16914 : int GetWindowACMixedAirNode(EnergyPlusData &state, int const WindACNum)
1528 : {
1529 :
1530 : // FUNCTION INFORMATION:
1531 : // AUTHOR B Griffith
1532 : // DATE WRITTEN Dec 2006
1533 :
1534 : // PURPOSE OF THIS FUNCTION:
1535 : // lookup function for mixed air node for ventilation rate reporting
1536 :
1537 : // Return value
1538 : int GetWindowACMixedAirNode;
1539 :
1540 16914 : if (state.dataWindowAC->GetWindowACInputFlag) {
1541 0 : GetWindowAC(state);
1542 0 : state.dataWindowAC->GetWindowACInputFlag = false;
1543 : }
1544 :
1545 16914 : if (WindACNum > 0 && WindACNum <= state.dataWindowAC->NumWindAC) {
1546 16914 : if (state.dataWindowAC->WindAC(WindACNum).OAMixIndex > 0) {
1547 16914 : GetWindowACMixedAirNode = MixedAir::GetOAMixerMixedNodeNumber(state, state.dataWindowAC->WindAC(WindACNum).OAMixIndex);
1548 : } else {
1549 0 : GetWindowACMixedAirNode = 0;
1550 : }
1551 : } else {
1552 0 : GetWindowACMixedAirNode = 0;
1553 : }
1554 :
1555 16914 : return GetWindowACMixedAirNode;
1556 : }
1557 :
1558 0 : int getWindowACIndex(EnergyPlusData &state, std::string_view CompName)
1559 : {
1560 0 : if (state.dataWindowAC->GetWindowACInputFlag) {
1561 0 : GetWindowAC(state);
1562 0 : state.dataWindowAC->GetWindowACInputFlag = false;
1563 : }
1564 :
1565 0 : for (int WindACIndex = 1; WindACIndex <= state.dataWindowAC->NumWindAC; ++WindACIndex) {
1566 0 : if (Util::SameString(state.dataWindowAC->WindAC(WindACIndex).Name, CompName)) {
1567 0 : return WindACIndex;
1568 : }
1569 : }
1570 :
1571 0 : return 0;
1572 : }
1573 :
1574 : } // namespace WindowAC
1575 :
1576 : } // namespace EnergyPlus
|