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 : // ObjexxFCL Headers
49 : #include <ObjexxFCL/Array1D.hh>
50 : #include <ObjexxFCL/Fmath.hh>
51 :
52 : // EnergyPlus Headers
53 : #include <EnergyPlus/AirTerminalUnit.hh>
54 : #include <EnergyPlus/BranchNodeConnections.hh>
55 : #include <EnergyPlus/Data/EnergyPlusData.hh>
56 : #include <EnergyPlus/DataAirLoop.hh>
57 : #include <EnergyPlus/DataDefineEquip.hh>
58 : #include <EnergyPlus/DataHeatBalance.hh>
59 : #include <EnergyPlus/DataLoopNode.hh>
60 : #include <EnergyPlus/DataSizing.hh>
61 : #include <EnergyPlus/DataZoneEquipment.hh>
62 : #include <EnergyPlus/DualDuct.hh>
63 : #include <EnergyPlus/GeneralRoutines.hh>
64 : #include <EnergyPlus/HVACCooledBeam.hh>
65 : #include <EnergyPlus/HVACFourPipeBeam.hh>
66 : #include <EnergyPlus/HVACSingleDuctInduc.hh>
67 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
68 : #include <EnergyPlus/NodeInputManager.hh>
69 : #include <EnergyPlus/OutputProcessor.hh>
70 : #include <EnergyPlus/PoweredInductionUnits.hh>
71 : #include <EnergyPlus/Psychrometrics.hh>
72 : #include <EnergyPlus/SingleDuct.hh>
73 : #include <EnergyPlus/UserDefinedComponents.hh>
74 : #include <EnergyPlus/UtilityRoutines.hh>
75 : #include <EnergyPlus/ZoneAirLoopEquipmentManager.hh>
76 :
77 : namespace EnergyPlus {
78 :
79 : namespace ZoneAirLoopEquipmentManager {
80 : // Module containing the routines dealing with the ZoneAirLoopEquipmentManager
81 :
82 : // MODULE INFORMATION:
83 : // AUTHOR Russ Taylor
84 : // DATE WRITTEN May 1997
85 :
86 : using namespace DataDefineEquip;
87 :
88 : // constexpr std::array<std::string_view, static_cast<int>(ZnAirLoopEquipType::Num)> ZnAirLoopEquipTypeNames = {
89 : // "AirTerminal:DualDuct:ConstantVolume",
90 : // "AirTerminal:DualDuct:VAV",
91 : // "AirTerminal:SingleDuct:VAV:Reheat",
92 : // "AirTerminal:SingleDuct:VAV:NoReheat",
93 : // "AirTerminal:SingleDuct:ConstantVolume:Reheat",
94 : // "AirTerminal:SingleDuct:ConstantVolume:NoReheat",
95 : // "AirTerminal:SingleDuct:SeriesPIU:Reheat",
96 : // "AirTerminal:SingleDuct:ParallelPIU:Reheat",
97 : // "AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction",
98 : // "AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan",
99 : // "AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat",
100 : // "AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat",
101 : // "AirTerminal:SingleDuct:ConstantVolume:CooledBeam",
102 : // "AirTerminal:DualDuct:VAV:OutdoorAir",
103 : // "AirTerminal:SingleDuct:UserDefined",
104 : // "AirTerminal:SingleDuct:Mixer",
105 : // "AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam"};
106 :
107 : constexpr std::array<std::string_view, static_cast<int>(ZnAirLoopEquipType::Num)> ZnAirLoopEquipTypeNamesUC = {
108 : "AIRTERMINAL:DUALDUCT:CONSTANTVOLUME",
109 : "AIRTERMINAL:DUALDUCT:VAV",
110 : "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT",
111 : "AIRTERMINAL:SINGLEDUCT:VAV:NOREHEAT",
112 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:REHEAT",
113 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:NOREHEAT",
114 : "AIRTERMINAL:SINGLEDUCT:SERIESPIU:REHEAT",
115 : "AIRTERMINAL:SINGLEDUCT:PARALLELPIU:REHEAT",
116 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:FOURPIPEINDUCTION",
117 : "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT:VARIABLESPEEDFAN",
118 : "AIRTERMINAL:SINGLEDUCT:VAV:HEATANDCOOL:REHEAT",
119 : "AIRTERMINAL:SINGLEDUCT:VAV:HEATANDCOOL:NOREHEAT",
120 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:COOLEDBEAM",
121 : "AIRTERMINAL:DUALDUCT:VAV:OUTDOORAIR",
122 : "AIRTERMINAL:SINGLEDUCT:USERDEFINED",
123 : "AIRTERMINAL:SINGLEDUCT:MIXER",
124 : "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:FOURPIPEBEAM"};
125 :
126 36090602 : void ManageZoneAirLoopEquipment(EnergyPlusData &state,
127 : std::string const &ZoneAirLoopEquipName,
128 : bool const FirstHVACIteration,
129 : Real64 &SysOutputProvided,
130 : Real64 &NonAirSysOutput,
131 : Real64 &LatOutputProvided, // Latent add/removal supplied by air dist unit (kg/s), dehumid = negative
132 : int const ControlledZoneNum,
133 : int &CompIndex)
134 : {
135 : // SUBROUTINE INFORMATION:
136 : // AUTHOR Russ Taylor
137 : // DATE WRITTEN May 1997
138 : // MODIFIED Don Shirey, Aug 2009 (LatOutputProvided)
139 :
140 : // PURPOSE OF THIS SUBROUTINE:
141 : // Calls the zone thermal control simulations and the interfaces
142 : // (water-air, refrigerant-air, steam-air, electric-electric,
143 : // water-water, etc)
144 :
145 : int AirDistUnitNum;
146 :
147 : // Beginning of Code
148 :
149 : // make sure the input data is read in only once
150 36090602 : if (state.dataZoneAirLoopEquipmentManager->GetAirDistUnitsFlag) {
151 537 : GetZoneAirLoopEquipment(state);
152 537 : state.dataZoneAirLoopEquipmentManager->GetAirDistUnitsFlag = false;
153 : }
154 :
155 : // Find the correct Zone Air Distribution Unit Equipment
156 36090602 : if (CompIndex == 0) {
157 3664 : AirDistUnitNum = Util::FindItemInList(ZoneAirLoopEquipName, state.dataDefineEquipment->AirDistUnit);
158 3664 : if (AirDistUnitNum == 0) {
159 0 : ShowFatalError(state, format("ManageZoneAirLoopEquipment: Unit not found={}", ZoneAirLoopEquipName));
160 : }
161 3664 : CompIndex = AirDistUnitNum;
162 : } else {
163 36086938 : AirDistUnitNum = CompIndex;
164 36086938 : if (AirDistUnitNum > (int)state.dataDefineEquipment->AirDistUnit.size() || AirDistUnitNum < 1) {
165 0 : ShowFatalError(state,
166 0 : format("ManageZoneAirLoopEquipment: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
167 : AirDistUnitNum,
168 0 : (int)state.dataDefineEquipment->AirDistUnit.size(),
169 : ZoneAirLoopEquipName));
170 : }
171 36086938 : if (ZoneAirLoopEquipName != state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).Name) {
172 0 : ShowFatalError(state,
173 0 : format("ManageZoneAirLoopEquipment: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
174 : AirDistUnitNum,
175 : ZoneAirLoopEquipName,
176 0 : state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).Name));
177 : }
178 : }
179 36090602 : state.dataSize->CurTermUnitSizingNum = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).TermUnitSizingNum;
180 36090602 : InitZoneAirLoopEquipment(state, AirDistUnitNum, ControlledZoneNum);
181 36090602 : InitZoneAirLoopEquipmentTimeStep(state, AirDistUnitNum);
182 :
183 36090602 : SimZoneAirLoopEquipment(state, AirDistUnitNum, SysOutputProvided, NonAirSysOutput, LatOutputProvided, FirstHVACIteration, ControlledZoneNum);
184 :
185 : // Call one-time init to fill termunit sizing and other data for the ADU - can't do this until the actual terminal unit nodes have been
186 : // matched to zone euqip config nodes
187 36090602 : InitZoneAirLoopEquipment(state, AirDistUnitNum, ControlledZoneNum);
188 36090602 : }
189 :
190 579 : void GetZoneAirLoopEquipment(EnergyPlusData &state)
191 : {
192 :
193 : // SUBROUTINE INFORMATION:
194 : // AUTHOR Russ Taylor
195 : // DATE WRITTEN June 1997
196 : // MODIFIED na
197 : // RE-ENGINEERED na
198 :
199 : // PURPOSE OF THIS SUBROUTINE:
200 : // Get all the system related equipment which may be attached to
201 : // a zone
202 :
203 : // METHODOLOGY EMPLOYED:
204 : // Needs description, as appropriate.
205 :
206 : // REFERENCES:
207 : // na
208 :
209 : // Using/Aliasing
210 : using NodeInputManager::GetOnlySingleNode;
211 : using namespace DataLoopNode;
212 : using BranchNodeConnections::SetUpCompSets;
213 : using DualDuct::GetDualDuctOutdoorAirRecircUse;
214 :
215 : // SUBROUTINE PARAMETER DEFINITIONS:
216 : static constexpr std::string_view RoutineName("GetZoneAirLoopEquipment: "); // include trailing blank space
217 579 : static std::string const CurrentModuleObject("ZoneHVAC:AirDistributionUnit"); // Object type for getting and error messages
218 :
219 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
220 : int AirDistUnitNum;
221 : int AirDistCompUnitNum;
222 : int NumAlphas;
223 : int NumNums;
224 : int IOStat;
225 579 : bool ErrorsFound(false); // If errors detected in input
226 : bool IsNotOK; // Flag to verify name
227 579 : Array1D_string AlphArray(5);
228 579 : Array1D<Real64> NumArray(2);
229 579 : Array1D_string cAlphaFields(5); // Alpha field names
230 579 : Array1D_string cNumericFields(2); // Numeric field names
231 579 : Array1D_bool lAlphaBlanks(5); // Logical array, alpha field input BLANK = .TRUE.
232 579 : Array1D_bool lNumericBlanks(2); // Logical array, numeric field input BLANK = .TRUE.
233 : bool DualDuctRecircIsUsed; // local temporary for deciding if recirc side used by dual duct terminal
234 :
235 579 : int NumAirDistUnits = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
236 :
237 579 : state.dataDefineEquipment->AirDistUnit.allocate(NumAirDistUnits);
238 :
239 579 : if (NumAirDistUnits > 0) {
240 :
241 4206 : for (AirDistUnitNum = 1; AirDistUnitNum <= NumAirDistUnits; ++AirDistUnitNum) {
242 3664 : auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum);
243 3664 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
244 : CurrentModuleObject,
245 : AirDistUnitNum,
246 : AlphArray,
247 : NumAlphas,
248 : NumArray,
249 : NumNums,
250 : IOStat,
251 : lNumericBlanks,
252 : lAlphaBlanks,
253 : cAlphaFields,
254 : cNumericFields); // data for one zone
255 3664 : Util::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
256 :
257 3664 : airDistUnit.Name = AlphArray(1);
258 : // Input Outlet Node Num
259 3664 : airDistUnit.OutletNodeNum = GetOnlySingleNode(state,
260 3664 : AlphArray(2),
261 : ErrorsFound,
262 : DataLoopNode::ConnectionObjectType::ZoneHVACAirDistributionUnit,
263 3664 : AlphArray(1),
264 : DataLoopNode::NodeFluidType::Air,
265 : DataLoopNode::ConnectionType::Outlet,
266 : NodeInputManager::CompFluidStream::Primary,
267 : ObjectIsParent);
268 3664 : airDistUnit.InletNodeNum = 0;
269 3664 : airDistUnit.NumComponents = 1;
270 3664 : AirDistCompUnitNum = 1;
271 : // Load the air Distribution Unit Equip and Name
272 3664 : airDistUnit.EquipType(AirDistCompUnitNum) = AlphArray(3);
273 3664 : airDistUnit.EquipName(AirDistCompUnitNum) = AlphArray(4);
274 3664 : ValidateComponent(state, AlphArray(3), AlphArray(4), IsNotOK, CurrentModuleObject);
275 3664 : if (IsNotOK) {
276 0 : ShowContinueError(state, format("In {} = {}", CurrentModuleObject, AlphArray(1)));
277 0 : ErrorsFound = true;
278 : }
279 3664 : airDistUnit.UpStreamLeakFrac = NumArray(1);
280 3664 : airDistUnit.DownStreamLeakFrac = NumArray(2);
281 3664 : if (airDistUnit.DownStreamLeakFrac <= 0.0) {
282 3614 : airDistUnit.LeakLoadMult = 1.0;
283 50 : } else if (airDistUnit.DownStreamLeakFrac < 1.0 && airDistUnit.DownStreamLeakFrac > 0.0) {
284 50 : airDistUnit.LeakLoadMult = 1.0 / (1.0 - airDistUnit.DownStreamLeakFrac);
285 : } else {
286 0 : ShowSevereError(state, format("Error found in {} = {}", CurrentModuleObject, airDistUnit.Name));
287 0 : ShowContinueError(state, format("{} must be less than 1.0", cNumericFields(2)));
288 0 : ErrorsFound = true;
289 : }
290 3664 : if (airDistUnit.UpStreamLeakFrac > 0.0) {
291 50 : airDistUnit.UpStreamLeak = true;
292 : } else {
293 3614 : airDistUnit.UpStreamLeak = false;
294 : }
295 3664 : if (airDistUnit.DownStreamLeakFrac > 0.0) {
296 50 : airDistUnit.DownStreamLeak = true;
297 : } else {
298 3614 : airDistUnit.DownStreamLeak = false;
299 : }
300 :
301 : // DesignSpecification:AirTerminal:Sizing name
302 3664 : airDistUnit.AirTerminalSizingSpecIndex = 0;
303 3664 : if (!lAlphaBlanks(5)) {
304 40 : airDistUnit.AirTerminalSizingSpecIndex = Util::FindItemInList(AlphArray(5), state.dataSize->AirTerminalSizingSpec);
305 40 : if (airDistUnit.AirTerminalSizingSpecIndex == 0) {
306 0 : ShowSevereError(state, format("{} = {} not found.", cAlphaFields(5), AlphArray(5)));
307 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, airDistUnit.Name));
308 0 : ErrorsFound = true;
309 : }
310 : }
311 :
312 3664 : const std::string typeNameUC = Util::makeUPPER(airDistUnit.EquipType(AirDistCompUnitNum));
313 3664 : airDistUnit.EquipTypeEnum(AirDistCompUnitNum) = static_cast<ZnAirLoopEquipType>(getEnumValue(ZnAirLoopEquipTypeNamesUC, typeNameUC));
314 : // Validate EquipType for Air Distribution Unit
315 3664 : switch (airDistUnit.EquipTypeEnum(AirDistCompUnitNum)) {
316 177 : case DataDefineEquip::ZnAirLoopEquipType::DualDuctConstVolume:
317 : case DataDefineEquip::ZnAirLoopEquipType::DualDuctVAV:
318 : case DataDefineEquip::ZnAirLoopEquipType::DualDuctVAVOutdoorAir:
319 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuct_SeriesPIU_Reheat:
320 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuct_ParallelPIU_Reheat:
321 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuct_ConstVol_4PipeInduc:
322 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVReheatVSFan:
323 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolCooledBeam:
324 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctUserDefined:
325 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctATMixer:
326 177 : if (airDistUnit.UpStreamLeak || airDistUnit.DownStreamLeak) {
327 0 : ShowSevereError(state, format("Error found in {} = {}", CurrentModuleObject, airDistUnit.Name));
328 0 : ShowContinueError(state,
329 0 : format("Simple duct leakage model not available for {} = {}",
330 : cAlphaFields(3),
331 : airDistUnit.EquipType(AirDistCompUnitNum)));
332 0 : ErrorsFound = true;
333 : }
334 177 : break;
335 30 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolFourPipeBeam:
336 30 : airDistUnit.airTerminalPtr = FourPipeBeam::HVACFourPipeBeam::fourPipeBeamFactory(state, airDistUnit.EquipName(1));
337 30 : if (airDistUnit.UpStreamLeak || airDistUnit.DownStreamLeak) {
338 0 : ShowSevereError(state, format("Error found in {} = {}", CurrentModuleObject, airDistUnit.Name));
339 0 : ShowContinueError(state,
340 0 : format("Simple duct leakage model not available for {} = {}",
341 : cAlphaFields(3),
342 : airDistUnit.EquipType(AirDistCompUnitNum)));
343 0 : ErrorsFound = true;
344 : }
345 30 : break;
346 1126 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolReheat:
347 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolNoReheat:
348 1126 : break;
349 2331 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVReheat:
350 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVNoReheat:
351 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctCBVAVReheat:
352 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctCBVAVNoReheat:
353 2331 : airDistUnit.IsConstLeakageRate = true;
354 2331 : break;
355 0 : default:
356 0 : ShowSevereError(state, format("Error found in {} = {}", CurrentModuleObject, airDistUnit.Name));
357 0 : ShowContinueError(state, format("Invalid {} = {}", cAlphaFields(3), airDistUnit.EquipType(AirDistCompUnitNum)));
358 0 : ErrorsFound = true;
359 0 : break;
360 : } // end switch
361 :
362 : // Set up component set for air terminal unit
363 7308 : if ((airDistUnit.EquipTypeEnum(AirDistCompUnitNum) == DataDefineEquip::ZnAirLoopEquipType::DualDuctConstVolume) ||
364 3644 : (airDistUnit.EquipTypeEnum(AirDistCompUnitNum) == DataDefineEquip::ZnAirLoopEquipType::DualDuctVAV)) {
365 : // For dual duct units, set up two component sets, one for heat and one for cool
366 69 : SetUpCompSets(state,
367 : CurrentModuleObject,
368 : airDistUnit.Name,
369 46 : airDistUnit.EquipType(AirDistCompUnitNum) + ":HEAT",
370 23 : airDistUnit.EquipName(AirDistCompUnitNum),
371 : "UNDEFINED",
372 23 : AlphArray(2));
373 69 : SetUpCompSets(state,
374 : CurrentModuleObject,
375 : airDistUnit.Name,
376 46 : airDistUnit.EquipType(AirDistCompUnitNum) + ":COOL",
377 23 : airDistUnit.EquipName(AirDistCompUnitNum),
378 : "UNDEFINED",
379 23 : AlphArray(2));
380 : // For dual duct units with decoupled OA and RA, set up two component sets, one for OA (Outdoor Air)
381 : // and one for RA (Recirculated Air)
382 3641 : } else if (airDistUnit.EquipTypeEnum(AirDistCompUnitNum) == DataDefineEquip::ZnAirLoopEquipType::DualDuctVAVOutdoorAir) {
383 33 : SetUpCompSets(state,
384 : CurrentModuleObject,
385 : airDistUnit.Name,
386 22 : airDistUnit.EquipType(AirDistCompUnitNum) + ":OutdoorAir",
387 11 : airDistUnit.EquipName(AirDistCompUnitNum),
388 : "UNDEFINED",
389 11 : AlphArray(2));
390 22 : GetDualDuctOutdoorAirRecircUse(
391 11 : state, airDistUnit.EquipType(AirDistCompUnitNum), airDistUnit.EquipName(AirDistCompUnitNum), DualDuctRecircIsUsed);
392 11 : if (DualDuctRecircIsUsed) {
393 18 : SetUpCompSets(state,
394 : CurrentModuleObject,
395 : airDistUnit.Name,
396 12 : airDistUnit.EquipType(AirDistCompUnitNum) + ":RecirculatedAir",
397 6 : airDistUnit.EquipName(AirDistCompUnitNum),
398 : "UNDEFINED",
399 6 : AlphArray(2));
400 : }
401 : } else {
402 10890 : SetUpCompSets(state,
403 : CurrentModuleObject,
404 : airDistUnit.Name,
405 3630 : airDistUnit.EquipType(AirDistCompUnitNum),
406 3630 : airDistUnit.EquipName(AirDistCompUnitNum),
407 : "UNDEFINED",
408 3630 : AlphArray(2));
409 : }
410 :
411 3664 : } // End of Air Dist Do Loop
412 4206 : for (AirDistUnitNum = 1; AirDistUnitNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++AirDistUnitNum) {
413 3664 : auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum);
414 7328 : SetupOutputVariable(state,
415 : "Zone Air Terminal Sensible Heating Energy",
416 : Constant::Units::J,
417 3664 : airDistUnit.HeatGain,
418 : OutputProcessor::TimeStepType::System,
419 : OutputProcessor::StoreType::Sum,
420 3664 : airDistUnit.Name);
421 7328 : SetupOutputVariable(state,
422 : "Zone Air Terminal Sensible Cooling Energy",
423 : Constant::Units::J,
424 3664 : airDistUnit.CoolGain,
425 : OutputProcessor::TimeStepType::System,
426 : OutputProcessor::StoreType::Sum,
427 3664 : airDistUnit.Name);
428 7328 : SetupOutputVariable(state,
429 : "Zone Air Terminal Sensible Heating Rate",
430 : Constant::Units::W,
431 3664 : airDistUnit.HeatRate,
432 : OutputProcessor::TimeStepType::System,
433 : OutputProcessor::StoreType::Average,
434 3664 : airDistUnit.Name);
435 7328 : SetupOutputVariable(state,
436 : "Zone Air Terminal Sensible Cooling Rate",
437 : Constant::Units::W,
438 3664 : airDistUnit.CoolRate,
439 : OutputProcessor::TimeStepType::System,
440 : OutputProcessor::StoreType::Average,
441 3664 : airDistUnit.Name);
442 : }
443 : }
444 579 : if (ErrorsFound) {
445 0 : ShowFatalError(state, format("{}Errors found in getting {} Input", RoutineName, CurrentModuleObject));
446 : }
447 579 : }
448 :
449 72181204 : void InitZoneAirLoopEquipment(EnergyPlusData &state, int const AirDistUnitNum, int const ControlledZoneNum)
450 : {
451 : // SUBROUTINE INFORMATION:
452 : // AUTHOR Russ Taylor
453 : // DATE WRITTEN Nov 1997
454 :
455 : // PURPOSE OF THIS SUBROUTINE:
456 : // This subroutine is left for Module format consistency -- not needed in this module.
457 :
458 : // Do the Begin Simulation initializations
459 72181204 : if (!state.dataZoneAirLoopEquipmentManager->InitAirDistUnitsFlag) {
460 72174291 : return;
461 : }
462 11197 : if (state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).EachOnceFlag &&
463 4284 : (state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).TermUnitSizingNum > 0)) {
464 :
465 : {
466 3664 : auto &thisADU = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum);
467 : {
468 3664 : auto &thisZoneEqConfig(state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum));
469 3664 : thisADU.ZoneNum = ControlledZoneNum;
470 7578 : for (int inletNum = 1; inletNum <= thisZoneEqConfig.NumInletNodes; ++inletNum) {
471 3914 : if (thisZoneEqConfig.InletNode(inletNum) == thisADU.OutletNodeNum)
472 3629 : thisZoneEqConfig.InletNodeADUNum(inletNum) = AirDistUnitNum;
473 : }
474 : }
475 :
476 : // Fill TermUnitSizing with specs from DesignSpecification:AirTerminal:Sizing
477 : {
478 3664 : auto &thisTermUnitSizingData(state.dataSize->TermUnitSizing(thisADU.TermUnitSizingNum));
479 3664 : thisTermUnitSizingData.ADUName = thisADU.Name;
480 3664 : if (thisADU.AirTerminalSizingSpecIndex > 0) {
481 : {
482 40 : auto const &thisAirTermSizingSpec(state.dataSize->AirTerminalSizingSpec(thisADU.AirTerminalSizingSpecIndex));
483 40 : thisTermUnitSizingData.SpecDesCoolSATRatio = thisAirTermSizingSpec.DesCoolSATRatio;
484 40 : thisTermUnitSizingData.SpecDesHeatSATRatio = thisAirTermSizingSpec.DesHeatSATRatio;
485 40 : thisTermUnitSizingData.SpecDesSensCoolingFrac = thisAirTermSizingSpec.DesSensCoolingFrac;
486 40 : thisTermUnitSizingData.SpecDesSensHeatingFrac = thisAirTermSizingSpec.DesSensHeatingFrac;
487 40 : thisTermUnitSizingData.SpecMinOAFrac = thisAirTermSizingSpec.MinOAFrac;
488 : }
489 : }
490 : }
491 : }
492 :
493 7328 : if (state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).ZoneNum != 0 &&
494 3664 : state.dataHeatBal->Zone(state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).ZoneNum).HasAdjustedReturnTempByITE) {
495 8 : for (int AirDistCompNum = 1; AirDistCompNum <= state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).NumComponents;
496 : ++AirDistCompNum) {
497 4 : if (state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).EquipTypeEnum(AirDistCompNum) !=
498 8 : DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVReheat &&
499 4 : state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).EquipTypeEnum(AirDistCompNum) !=
500 : DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVNoReheat) {
501 0 : ShowSevereError(state,
502 : "The FlowControlWithApproachTemperatures only works with ITE zones with single duct VAV terminal unit.");
503 0 : ShowContinueError(state, "The return air temperature of the ITE will not be overwritten.");
504 0 : ShowFatalError(state, "Preceding condition causes termination.");
505 : }
506 : }
507 : }
508 3664 : state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).EachOnceFlag = false;
509 3664 : ++state.dataZoneAirLoopEquipmentManager->numADUInitialized;
510 3664 : if (state.dataZoneAirLoopEquipmentManager->numADUInitialized == (int)state.dataDefineEquipment->AirDistUnit.size()) {
511 : // If all ADUs are initialized, set InitAirDistUnitsFlag to false
512 542 : state.dataZoneAirLoopEquipmentManager->InitAirDistUnitsFlag = false;
513 : }
514 : }
515 : }
516 :
517 36090602 : void InitZoneAirLoopEquipmentTimeStep(EnergyPlusData &state, int const AirDistUnitNum)
518 : {
519 36090602 : auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum);
520 : // every time step
521 36090602 : airDistUnit.MassFlowRateDnStrLk = 0.0;
522 36090602 : airDistUnit.MassFlowRateUpStrLk = 0.0;
523 36090602 : airDistUnit.MassFlowRateTU = 0.0;
524 36090602 : airDistUnit.MassFlowRateZSup = 0.0;
525 36090602 : airDistUnit.MassFlowRateSup = 0.0;
526 36090602 : airDistUnit.HeatRate = 0.0;
527 36090602 : airDistUnit.CoolRate = 0.0;
528 36090602 : airDistUnit.HeatGain = 0.0;
529 36090602 : airDistUnit.CoolGain = 0.0;
530 36090602 : }
531 :
532 36090602 : void SimZoneAirLoopEquipment(EnergyPlusData &state,
533 : int const AirDistUnitNum,
534 : Real64 &SysOutputProvided,
535 : Real64 &NonAirSysOutput,
536 : Real64 &LatOutputProvided, // Latent add/removal provided by this unit (kg/s), dehumidify = negative
537 : bool const FirstHVACIteration,
538 : int const ControlledZoneNum)
539 : {
540 : // SUBROUTINE INFORMATION:
541 : // AUTHOR Russ Taylor
542 : // DATE WRITTEN May 1997
543 : // MODIFIED Don Shirey, Aug 2009 (LatOutputProvided)
544 :
545 : // PURPOSE OF THIS SUBROUTINE:
546 : // Simulates primary system air supplied to a zone and calculates
547 : // airflow requirements
548 :
549 : using DualDuct::SimulateDualDuct;
550 : using HVACCooledBeam::SimCoolBeam;
551 : using HVACSingleDuctInduc::SimIndUnit;
552 : using PoweredInductionUnits::SimPIU;
553 : using Psychrometrics::PsyCpAirFnW;
554 : using SingleDuct::GetATMixers;
555 : using SingleDuct::SimulateSingleDuct;
556 : using UserDefinedComponents::SimAirTerminalUserDefined;
557 :
558 : bool ProvideSysOutput;
559 : int AirDistCompNum;
560 : int InNodeNum; // air distribution unit inlet node
561 : int OutNodeNum; // air distribution unit outlet node
562 36090602 : int AirLoopNum(0); // index of air loop
563 : Real64 MassFlowRateMaxAvail; // max avail mass flow rate excluding leaks [kg/s]
564 : Real64 MassFlowRateMinAvail; // min avail mass flow rate excluding leaks [kg/s]
565 : Real64 MassFlowRateUpStreamLeakMax; // max upstream leak flow rate [kg/s]
566 36090602 : Real64 DesFlowRatio(0.0); // ratio of system to sum of zones design flow rate
567 36090602 : Real64 SpecHumOut(0.0); // Specific humidity ratio of outlet air (kg moisture / kg moist air)
568 36090602 : Real64 SpecHumIn(0.0); // Specific humidity ratio of inlet air (kg moisture / kg moist air)
569 :
570 36090602 : auto &controlledZoneAirNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
571 :
572 36090602 : ProvideSysOutput = true;
573 72181204 : for (AirDistCompNum = 1; AirDistCompNum <= state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).NumComponents; ++AirDistCompNum) {
574 36090602 : NonAirSysOutput = 0.0;
575 :
576 36090602 : auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum);
577 36090602 : InNodeNum = airDistUnit.InletNodeNum;
578 36090602 : OutNodeNum = airDistUnit.OutletNodeNum;
579 36090602 : MassFlowRateMaxAvail = 0.0;
580 36090602 : MassFlowRateMinAvail = 0.0;
581 : // check for no plenum
582 : // set the max and min avail flow rates taking into acount the upstream leak
583 36090602 : if (airDistUnit.UpStreamLeak) {
584 253875 : if (InNodeNum > 0) {
585 253865 : MassFlowRateMaxAvail = state.dataLoopNodes->Node(InNodeNum).MassFlowRateMaxAvail;
586 253865 : MassFlowRateMinAvail = state.dataLoopNodes->Node(InNodeNum).MassFlowRateMinAvail;
587 253865 : if (airDistUnit.IsConstLeakageRate) {
588 203923 : AirLoopNum = airDistUnit.AirLoopNum;
589 203923 : if (AirLoopNum > 0) {
590 203860 : DesFlowRatio = state.dataAirLoop->AirLoopFlow(AirLoopNum).SysToZoneDesFlowRatio;
591 : } else {
592 63 : DesFlowRatio = 1.0;
593 : }
594 : MassFlowRateUpStreamLeakMax =
595 203923 : max(airDistUnit.UpStreamLeakFrac * state.dataLoopNodes->Node(InNodeNum).MassFlowRateMax * DesFlowRatio, 0.0);
596 : } else {
597 49942 : MassFlowRateUpStreamLeakMax = max(airDistUnit.UpStreamLeakFrac * MassFlowRateMaxAvail, 0.0);
598 : }
599 253865 : if (MassFlowRateMaxAvail > MassFlowRateUpStreamLeakMax) {
600 253425 : airDistUnit.MassFlowRateUpStrLk = MassFlowRateUpStreamLeakMax;
601 253425 : state.dataLoopNodes->Node(InNodeNum).MassFlowRateMaxAvail = MassFlowRateMaxAvail - MassFlowRateUpStreamLeakMax;
602 : } else {
603 440 : airDistUnit.MassFlowRateUpStrLk = MassFlowRateMaxAvail;
604 440 : state.dataLoopNodes->Node(InNodeNum).MassFlowRateMaxAvail = 0.0;
605 : }
606 253865 : state.dataLoopNodes->Node(InNodeNum).MassFlowRateMinAvail = max(0.0, MassFlowRateMinAvail - airDistUnit.MassFlowRateUpStrLk);
607 : }
608 : }
609 :
610 36090602 : switch (airDistUnit.EquipTypeEnum(AirDistCompNum)) {
611 122091 : case DataDefineEquip::ZnAirLoopEquipType::DualDuctConstVolume: {
612 244182 : SimulateDualDuct(state,
613 122091 : airDistUnit.EquipName(AirDistCompNum),
614 : FirstHVACIteration,
615 : ControlledZoneNum,
616 : controlledZoneAirNode,
617 : airDistUnit.EquipIndex(AirDistCompNum));
618 122091 : } break;
619 16275 : case DataDefineEquip::ZnAirLoopEquipType::DualDuctVAV: {
620 32550 : SimulateDualDuct(state,
621 16275 : airDistUnit.EquipName(AirDistCompNum),
622 : FirstHVACIteration,
623 : ControlledZoneNum,
624 : controlledZoneAirNode,
625 : airDistUnit.EquipIndex(AirDistCompNum));
626 16275 : } break;
627 67628 : case DataDefineEquip::ZnAirLoopEquipType::DualDuctVAVOutdoorAir: {
628 135256 : SimulateDualDuct(state,
629 67628 : airDistUnit.EquipName(AirDistCompNum),
630 : FirstHVACIteration,
631 : ControlledZoneNum,
632 : controlledZoneAirNode,
633 : airDistUnit.EquipIndex(AirDistCompNum));
634 67628 : } break;
635 24113507 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVReheat: {
636 48227014 : SimulateSingleDuct(state,
637 24113507 : airDistUnit.EquipName(AirDistCompNum),
638 : FirstHVACIteration,
639 : ControlledZoneNum,
640 : controlledZoneAirNode,
641 : airDistUnit.EquipIndex(AirDistCompNum));
642 24113507 : } break;
643 46050 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctCBVAVReheat: {
644 92100 : SimulateSingleDuct(state,
645 46050 : airDistUnit.EquipName(AirDistCompNum),
646 : FirstHVACIteration,
647 : ControlledZoneNum,
648 : controlledZoneAirNode,
649 : airDistUnit.EquipIndex(AirDistCompNum));
650 46050 : } break;
651 361786 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVNoReheat: {
652 723572 : SimulateSingleDuct(state,
653 361786 : airDistUnit.EquipName(AirDistCompNum),
654 : FirstHVACIteration,
655 : ControlledZoneNum,
656 : controlledZoneAirNode,
657 : airDistUnit.EquipIndex(AirDistCompNum));
658 361786 : } break;
659 21224 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctCBVAVNoReheat: {
660 42448 : SimulateSingleDuct(state,
661 21224 : airDistUnit.EquipName(AirDistCompNum),
662 : FirstHVACIteration,
663 : ControlledZoneNum,
664 : controlledZoneAirNode,
665 : airDistUnit.EquipIndex(AirDistCompNum));
666 21224 : } break;
667 1656536 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolReheat: {
668 3313072 : SimulateSingleDuct(state,
669 1656536 : airDistUnit.EquipName(AirDistCompNum),
670 : FirstHVACIteration,
671 : ControlledZoneNum,
672 : controlledZoneAirNode,
673 : airDistUnit.EquipIndex(AirDistCompNum));
674 1656536 : } break;
675 8514131 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolNoReheat: {
676 17028262 : SimulateSingleDuct(state,
677 8514131 : airDistUnit.EquipName(AirDistCompNum),
678 : FirstHVACIteration,
679 : ControlledZoneNum,
680 : controlledZoneAirNode,
681 : airDistUnit.EquipIndex(AirDistCompNum));
682 8514131 : } break;
683 287202 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuct_SeriesPIU_Reheat: {
684 574404 : SimPIU(state,
685 287202 : airDistUnit.EquipName(AirDistCompNum),
686 : FirstHVACIteration,
687 : ControlledZoneNum,
688 : controlledZoneAirNode,
689 : airDistUnit.EquipIndex(AirDistCompNum));
690 287202 : } break;
691 21546 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuct_ParallelPIU_Reheat: {
692 43092 : SimPIU(state,
693 21546 : airDistUnit.EquipName(AirDistCompNum),
694 : FirstHVACIteration,
695 : ControlledZoneNum,
696 : controlledZoneAirNode,
697 : airDistUnit.EquipIndex(AirDistCompNum));
698 21546 : } break;
699 11976 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuct_ConstVol_4PipeInduc: {
700 23952 : SimIndUnit(state,
701 11976 : airDistUnit.EquipName(AirDistCompNum),
702 : FirstHVACIteration,
703 : ControlledZoneNum,
704 : controlledZoneAirNode,
705 : airDistUnit.EquipIndex(AirDistCompNum));
706 11976 : } break;
707 30864 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctVAVReheatVSFan: {
708 61728 : SimulateSingleDuct(state,
709 30864 : airDistUnit.EquipName(AirDistCompNum),
710 : FirstHVACIteration,
711 : ControlledZoneNum,
712 : controlledZoneAirNode,
713 : airDistUnit.EquipIndex(AirDistCompNum));
714 30864 : } break;
715 36725 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolCooledBeam: {
716 73450 : SimCoolBeam(state,
717 36725 : airDistUnit.EquipName(AirDistCompNum),
718 : FirstHVACIteration,
719 : ControlledZoneNum,
720 : controlledZoneAirNode,
721 : airDistUnit.EquipIndex(AirDistCompNum),
722 : NonAirSysOutput);
723 36725 : } break;
724 428235 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctConstVolFourPipeBeam: {
725 428235 : airDistUnit.airTerminalPtr->simulate(state, FirstHVACIteration, NonAirSysOutput);
726 428235 : } break;
727 119360 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctUserDefined: {
728 238720 : SimAirTerminalUserDefined(state,
729 119360 : airDistUnit.EquipName(AirDistCompNum),
730 : FirstHVACIteration,
731 : ControlledZoneNum,
732 : controlledZoneAirNode,
733 : airDistUnit.EquipIndex(AirDistCompNum));
734 119360 : } break;
735 235466 : case DataDefineEquip::ZnAirLoopEquipType::SingleDuctATMixer: {
736 235466 : GetATMixers(state); // Needed here if mixer used only with unitarysystem which gets its input late
737 235466 : ProvideSysOutput = false;
738 235466 : } break;
739 0 : default: {
740 0 : ShowSevereError(state, format("Error found in ZoneHVAC:AirDistributionUnit={}", airDistUnit.Name));
741 0 : ShowContinueError(state, format("Invalid Component={}", airDistUnit.EquipType(AirDistCompNum)));
742 0 : ShowFatalError(state, "Preceding condition causes termination.");
743 0 : } break;
744 : }
745 :
746 : // do leak mass flow calcs
747 36090602 : if (InNodeNum > 0) { // InNodeNum is not always known when this is called, eg FPIU
748 35958713 : InNodeNum = airDistUnit.InletNodeNum;
749 35958713 : if (airDistUnit.UpStreamLeak) {
750 253865 : state.dataLoopNodes->Node(InNodeNum).MassFlowRateMaxAvail = MassFlowRateMaxAvail;
751 253865 : state.dataLoopNodes->Node(InNodeNum).MassFlowRateMinAvail = MassFlowRateMinAvail;
752 : }
753 35958713 : if ((airDistUnit.UpStreamLeak || airDistUnit.DownStreamLeak) && MassFlowRateMaxAvail > 0.0) {
754 253425 : airDistUnit.MassFlowRateTU = state.dataLoopNodes->Node(InNodeNum).MassFlowRate;
755 253425 : airDistUnit.MassFlowRateZSup = airDistUnit.MassFlowRateTU * (1.0 - airDistUnit.DownStreamLeakFrac);
756 253425 : airDistUnit.MassFlowRateDnStrLk = airDistUnit.MassFlowRateTU * airDistUnit.DownStreamLeakFrac;
757 253425 : airDistUnit.MassFlowRateSup = airDistUnit.MassFlowRateTU + airDistUnit.MassFlowRateUpStrLk;
758 253425 : state.dataLoopNodes->Node(InNodeNum).MassFlowRate = airDistUnit.MassFlowRateSup;
759 253425 : state.dataLoopNodes->Node(OutNodeNum).MassFlowRate = airDistUnit.MassFlowRateZSup;
760 253425 : state.dataLoopNodes->Node(OutNodeNum).MassFlowRateMaxAvail =
761 253425 : max(0.0, MassFlowRateMaxAvail - airDistUnit.MassFlowRateDnStrLk - airDistUnit.MassFlowRateUpStrLk);
762 253425 : state.dataLoopNodes->Node(OutNodeNum).MassFlowRateMinAvail =
763 253425 : max(0.0, MassFlowRateMinAvail - airDistUnit.MassFlowRateDnStrLk - airDistUnit.MassFlowRateUpStrLk);
764 253425 : airDistUnit.MaxAvailDelta = MassFlowRateMaxAvail - state.dataLoopNodes->Node(OutNodeNum).MassFlowRateMaxAvail;
765 253425 : airDistUnit.MinAvailDelta = MassFlowRateMinAvail - state.dataLoopNodes->Node(OutNodeNum).MassFlowRateMinAvail;
766 : } else {
767 : // if no leaks, or a terminal unit type not supported for leaks
768 35705288 : DataDefineEquip::ZnAirLoopEquipType termUnitType = airDistUnit.EquipTypeEnum(AirDistCompNum);
769 35705288 : if ((termUnitType == DataDefineEquip::ZnAirLoopEquipType::DualDuctConstVolume) ||
770 35566929 : (termUnitType == DataDefineEquip::ZnAirLoopEquipType::DualDuctVAV) ||
771 : (termUnitType == DataDefineEquip::ZnAirLoopEquipType::DualDuctVAVOutdoorAir)) {
772 : // Use ADU outlet node flow for dual duct terminal units (which don't support leaks)
773 205986 : airDistUnit.MassFlowRateTU = state.dataLoopNodes->Node(OutNodeNum).MassFlowRate;
774 205986 : airDistUnit.MassFlowRateZSup = state.dataLoopNodes->Node(OutNodeNum).MassFlowRate;
775 205986 : airDistUnit.MassFlowRateSup = state.dataLoopNodes->Node(OutNodeNum).MassFlowRate;
776 : } else {
777 35499302 : airDistUnit.MassFlowRateTU = state.dataLoopNodes->Node(InNodeNum).MassFlowRate;
778 35499302 : airDistUnit.MassFlowRateZSup = state.dataLoopNodes->Node(InNodeNum).MassFlowRate;
779 35499302 : airDistUnit.MassFlowRateSup = state.dataLoopNodes->Node(InNodeNum).MassFlowRate;
780 : }
781 : }
782 : }
783 : }
784 36090602 : if (ProvideSysOutput) {
785 35855136 : int OutletNodeNum = state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).OutletNodeNum;
786 35855136 : SpecHumOut = state.dataLoopNodes->Node(OutletNodeNum).HumRat;
787 35855136 : SpecHumIn = state.dataLoopNodes->Node(controlledZoneAirNode).HumRat;
788 : // Sign convention: SysOutputProvided <0 Zone is cooled
789 : // SysOutputProvided >0 Zone is heated
790 35855136 : SysOutputProvided = state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate *
791 35855136 : Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNodeNum).Temp,
792 : SpecHumOut,
793 35855136 : state.dataLoopNodes->Node(controlledZoneAirNode).Temp,
794 : SpecHumIn); // sensible {W};
795 : // Sign convention: LatOutputProvided <0 Zone is dehumidified
796 : // LatOutputProvided >0 Zone is humidified
797 : // CR9155 Remove specific humidity calculations
798 35855136 : LatOutputProvided =
799 35855136 : state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
800 : } else {
801 235466 : SysOutputProvided = 0.0;
802 235466 : LatOutputProvided = 0.0;
803 : }
804 36090602 : }
805 :
806 : } // namespace ZoneAirLoopEquipmentManager
807 :
808 : } // namespace EnergyPlus
|