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