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 <algorithm>
50 : #include <cmath>
51 : #include <limits>
52 :
53 : // ObjexxFCL Headers
54 : #include <ObjexxFCL/Array.functions.hh>
55 : #include <ObjexxFCL/Array1D.hh>
56 : #include <ObjexxFCL/Array2D.hh>
57 : // #include <ObjexxFCL/Fmath.hh>
58 :
59 : // EnergyPlus Headers
60 : #include <AirflowNetwork/Solver.hpp>
61 : #include <EnergyPlus/BaseboardElectric.hh>
62 : #include <EnergyPlus/CrossVentMgr.hh>
63 : #include <EnergyPlus/Data/EnergyPlusData.hh>
64 : #include <EnergyPlus/DataEnvironment.hh>
65 : #include <EnergyPlus/DataErrorTracking.hh>
66 : #include <EnergyPlus/DataHVACGlobals.hh>
67 : #include <EnergyPlus/DataHeatBalFanSys.hh>
68 : #include <EnergyPlus/DataHeatBalance.hh>
69 : #include <EnergyPlus/DataIPShortCuts.hh>
70 : #include <EnergyPlus/DataLoopNode.hh>
71 : #include <EnergyPlus/DataRoomAirModel.hh>
72 : #include <EnergyPlus/DataSurfaces.hh>
73 : #include <EnergyPlus/DataZoneEquipment.hh>
74 : #include <EnergyPlus/DisplacementVentMgr.hh>
75 : #include <EnergyPlus/FanCoilUnits.hh>
76 : #include <EnergyPlus/Fans.hh>
77 : #include <EnergyPlus/General.hh>
78 : #include <EnergyPlus/HVACStandAloneERV.hh>
79 : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
80 : #include <EnergyPlus/HybridUnitaryAirConditioners.hh>
81 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
82 : #include <EnergyPlus/InternalHeatGains.hh>
83 : #include <EnergyPlus/MundtSimMgr.hh>
84 : #include <EnergyPlus/OutdoorAirUnit.hh>
85 : #include <EnergyPlus/OutputProcessor.hh>
86 : #include <EnergyPlus/Psychrometrics.hh>
87 : #include <EnergyPlus/PurchasedAirManager.hh>
88 : #include <EnergyPlus/RoomAirModelAirflowNetwork.hh>
89 : #include <EnergyPlus/RoomAirModelManager.hh>
90 : #include <EnergyPlus/RoomAirModelUserTempPattern.hh>
91 : #include <EnergyPlus/ScheduleManager.hh>
92 : #include <EnergyPlus/UFADManager.hh>
93 : #include <EnergyPlus/UnitHeater.hh>
94 : #include <EnergyPlus/UnitVentilator.hh>
95 : #include <EnergyPlus/UtilityRoutines.hh>
96 : #include <EnergyPlus/VentilatedSlab.hh>
97 : #include <EnergyPlus/WaterThermalTanks.hh>
98 : #include <EnergyPlus/WindowAC.hh>
99 : #include <EnergyPlus/ZoneDehumidifier.hh>
100 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
101 :
102 : namespace EnergyPlus {
103 :
104 : namespace RoomAir {
105 :
106 : // MODULE INFORMATION
107 : // AUTHOR Weixiu Kong
108 : // DATE WRITTEN March 2003
109 : // MODIFIED July 2003, CC
110 : // Aug, 2005, BG
111 :
112 : // PURPOSE OF THIS MODULE:
113 : // Contains subroutines for managing the room air models
114 :
115 : constexpr std::array<std::string_view, (int)RoomAirModel::Num> roomAirModelNamesUC = {
116 : "USERDEFINED", "MIXING", "MUNDT", "UCSD_DV", "UCSD_CV", "UCSD_UFI", "UCSD_UFE", "AIRFLOWNETWORK"};
117 :
118 : constexpr std::array<std::string_view, (int)AirNodeType::Num> airNodeTypeNamesUC = {
119 : "INLET", "FLOOR", "CONTROL", "CEILING", "MUNDTROOM", "RETURN", "AIRFLOWNETWORK", "PLUME", "REESROOM"};
120 :
121 : constexpr std::array<std::string_view, (int)Comfort::Num> comfortNamesUC = {"JET", "RECIRCULATION"};
122 :
123 : constexpr std::array<std::string_view, (int)Diffuser::Num> diffuserNamesUC = {
124 : "SWIRL", "VARIABLEAREA", "HORIZONTALSWIRL", "LINEARBARGRILLE", "CUSTOM"};
125 :
126 : constexpr std::array<std::string_view, (int)UserDefinedPatternMode::Num> userDefinedPatternModeNamesUC = {
127 : "OUTDOORDRYBULBTEMPERATURE", "SENSIBLECOOLINGLOAD", "SENSIBLEHEATINGLOAD", "ZONEDRYBULBTEMPERATURE", "ZONEANDOUTDOORTEMPERATUREDIFFERENCE"};
128 :
129 418332 : void ManageAirModel(EnergyPlusData &state, int const ZoneNum)
130 : {
131 :
132 : // SUBROUTINE INFORMATION:
133 : // AUTHOR Weixiu Kong
134 : // DATE WRITTEN April 2003
135 : // MODIFIED July 2003, CC
136 : // Jan 2004, CC
137 :
138 : // PURPOSE OF THIS SUBROUTINE:
139 : // manage room air models.
140 :
141 418332 : if (state.dataRoomAir->GetAirModelData) {
142 88 : GetAirModelDatas(state);
143 88 : state.dataRoomAir->GetAirModelData = false;
144 : }
145 :
146 418332 : if (!state.dataRoomAir->anyNonMixingRoomAirModel) return;
147 :
148 0 : if (state.dataRoomAir->UCSDModelUsed) {
149 0 : SharedDVCVUFDataInit(state, ZoneNum);
150 : }
151 :
152 0 : switch (state.dataRoomAir->AirModel(ZoneNum).AirModel) {
153 0 : case RoomAirModel::UserDefined:
154 0 : ManageUserDefinedPatterns(state, ZoneNum);
155 0 : break;
156 :
157 0 : case RoomAirModel::Mixing: // Mixing air model
158 0 : break; // do nothing
159 :
160 0 : case RoomAirModel::DispVent1Node: // Mundt air model
161 : // simulate room airflow using Mundt model
162 0 : ManageDispVent1Node(state, ZoneNum);
163 0 : break;
164 :
165 0 : case RoomAirModel::DispVent3Node: // UCDV Displacement Ventilation model
166 : // simulate room airflow using UCSDDV model
167 0 : ManageDispVent3Node(state, ZoneNum);
168 0 : break;
169 :
170 0 : case RoomAirModel::CrossVent: // UCSD Cross Ventilation model
171 : // simulate room airflow using UCSDDV model
172 0 : ManageCrossVent(state, ZoneNum);
173 0 : break;
174 :
175 0 : case RoomAirModel::UFADInt: // UCSD UFAD interior zone model
176 : // simulate room airflow using the UCSDUFI model
177 0 : ManageUFAD(state, ZoneNum, RoomAirModel::UFADInt);
178 0 : break;
179 :
180 0 : case RoomAirModel::UFADExt: // UCSD UFAD exterior zone model
181 : // simulate room airflow using the UCSDUFE model
182 0 : ManageUFAD(state, ZoneNum, RoomAirModel::UFADExt);
183 0 : break;
184 :
185 0 : case RoomAirModel::AirflowNetwork: // RoomAirflowNetwork zone model
186 : // simulate room airflow using the AirflowNetwork - based model
187 0 : SimRoomAirModelAFN(state, ZoneNum);
188 0 : break;
189 :
190 0 : default: // mixing air model
191 0 : break; // do nothing
192 : }
193 : }
194 :
195 : //*****************************************************************************************
196 :
197 89 : void GetAirModelDatas(EnergyPlusData &state)
198 : {
199 :
200 : // SUBROUTINE INFORMATION:
201 : // AUTHOR Linda Lawrie
202 : // DATE WRITTEN March 2005
203 : // MODIFIED na
204 : // RE-ENGINEERED na
205 :
206 : // PURPOSE OF THIS SUBROUTINE:
207 : // This routine "gets" all the data for the "RoomAir" models by calling individual
208 : // routines.
209 :
210 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
211 : bool ErrorsFound;
212 :
213 89 : ErrorsFound = false;
214 : // get air node input data for all zones
215 89 : GetAirNodeData(state, ErrorsFound);
216 :
217 : // get mundt model controls for all zones
218 89 : GetMundtData(state, ErrorsFound);
219 :
220 : // get airflow network model info for all zones
221 89 : GetRoomAirflowNetworkData(state, ErrorsFound);
222 :
223 : // get UCSDDV model controls for all zones
224 89 : GetDisplacementVentData(state, ErrorsFound);
225 :
226 : // get UCSDCV model controls for all zones
227 89 : GetCrossVentData(state, ErrorsFound);
228 :
229 : // get BTG's user-defined patterns for all zones
230 89 : GetUserDefinedPatternData(state, ErrorsFound);
231 :
232 : // get UCSD UFAD interior zone model controls for all zones
233 : // get UCSD UFAD exterior zone model controls for all zones
234 89 : GetUFADZoneData(state, ErrorsFound);
235 :
236 89 : if (ErrorsFound) {
237 0 : ShowFatalError(state, "GetAirModelData: Errors found getting air model input. Program terminates.");
238 : }
239 89 : }
240 :
241 89 : void GetUserDefinedPatternData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
242 : {
243 : // SUBROUTINE INFORMATION:
244 : // AUTHOR Brent Griffith
245 : // DATE WRITTEN Aug 2005
246 : // MODIFIED na
247 : // RE-ENGINEERED na
248 :
249 : // PURPOSE OF THIS SUBROUTINE:
250 : // This routine "gets" all the data for the "User-Defined RoomAir"
251 :
252 : // METHODOLOGY EMPLOYED:
253 : // usual energyplus input routines
254 : // for the actual patterns, a single structure array holds
255 : // different patterns in nested derived types.
256 :
257 : // Using/Aliasing
258 : using DataZoneEquipment::EquipConfiguration;
259 :
260 : // SUBROUTINE PARAMETER DEFINITIONS:
261 : static constexpr std::string_view routineName = "GetUserDefinedPatternData: ";
262 :
263 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
264 : int NumAlphas; // number of alphas
265 : int NumNumbers; // Number of numbers encountered
266 : int Status; // Notes if there was an error in processing the input
267 :
268 89 : auto &ipsc = state.dataIPShortCut;
269 :
270 : // access input file and setup
271 89 : state.dataRoomAir->numTempDistContrldZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cUserDefinedControlObject);
272 :
273 178 : state.dataRoomAir->NumConstantGradient =
274 89 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cTempPatternConstGradientObject);
275 89 : state.dataRoomAir->NumTwoGradientInterp = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cTempPatternTwoGradientObject);
276 89 : state.dataRoomAir->NumNonDimensionalHeight = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cTempPatternNDHeightObject);
277 89 : state.dataRoomAir->NumSurfaceMapping = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cTempPatternSurfMapObject);
278 :
279 89 : state.dataRoomAir->NumAirTempPatterns = state.dataRoomAir->NumConstantGradient + state.dataRoomAir->NumTwoGradientInterp +
280 89 : state.dataRoomAir->NumNonDimensionalHeight + state.dataRoomAir->NumSurfaceMapping;
281 89 : ipsc->cCurrentModuleObject = cUserDefinedControlObject;
282 89 : if (state.dataRoomAir->numTempDistContrldZones == 0) {
283 89 : if (state.dataRoomAir->NumAirTempPatterns != 0) { // user may have missed control object
284 0 : ShowWarningError(state, format("Missing {} object needed to use roomair temperature patterns", ipsc->cCurrentModuleObject));
285 : // ErrorsFound = .TRUE.
286 : }
287 89 : return;
288 : }
289 :
290 : // now allocate AirPatternZoneInfo to length of all zones for easy indexing
291 0 : if (!allocated(state.dataRoomAir->AirPatternZoneInfo)) {
292 0 : state.dataRoomAir->AirPatternZoneInfo.allocate(state.dataGlobal->NumOfZones);
293 : }
294 :
295 0 : for (int ObjNum = 1; ObjNum <= state.dataRoomAir->numTempDistContrldZones; ++ObjNum) {
296 :
297 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
298 0 : ipsc->cCurrentModuleObject,
299 : ObjNum,
300 0 : ipsc->cAlphaArgs,
301 : NumAlphas,
302 0 : ipsc->rNumericArgs,
303 : NumNumbers,
304 : Status,
305 : _,
306 0 : ipsc->lAlphaFieldBlanks,
307 0 : ipsc->cAlphaFieldNames,
308 0 : ipsc->cNumericFieldNames);
309 :
310 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
311 : // first get zone ID
312 0 : int ZoneNum = Util::FindItemInList(ipsc->cAlphaArgs(2), state.dataHeatBal->Zone);
313 0 : if (ZoneNum == 0) { // throw error
314 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
315 0 : ErrorsFound = true;
316 0 : return; // halt to avoid hard crash
317 : }
318 :
319 0 : auto &airPatternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
320 0 : airPatternZoneInfo.IsUsed = true;
321 0 : airPatternZoneInfo.Name = ipsc->cAlphaArgs(1); // Name of this Control Object
322 0 : airPatternZoneInfo.ZoneName = ipsc->cAlphaArgs(2); // Zone Name
323 :
324 0 : if (ipsc->lAlphaFieldBlanks(3)) {
325 0 : airPatternZoneInfo.availSched = Sched::GetScheduleAlwaysOn(state);
326 0 : } else if ((airPatternZoneInfo.availSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(3))) == nullptr) {
327 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(3), ipsc->cAlphaArgs(3));
328 0 : ErrorsFound = true;
329 : }
330 :
331 0 : if (ipsc->lAlphaFieldBlanks(4)) {
332 0 : } else if ((airPatternZoneInfo.patternSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(4))) == nullptr) {
333 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(4), ipsc->cAlphaArgs(4));
334 0 : ErrorsFound = true;
335 : }
336 :
337 0 : airPatternZoneInfo.ZoneID = ZoneNum;
338 :
339 : // figure number of surfaces for this zone
340 0 : airPatternZoneInfo.totNumSurfs = 0;
341 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
342 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
343 0 : airPatternZoneInfo.totNumSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1;
344 : }
345 : // allocate nested derived type for surface info
346 0 : airPatternZoneInfo.Surf.allocate(airPatternZoneInfo.totNumSurfs);
347 :
348 : // Fill in what we know for nested structure for surfaces
349 0 : int thisSurfinZone = 0;
350 0 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
351 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
352 0 : for (int thisHBsurfID = thisSpace.HTSurfaceFirst; thisHBsurfID <= thisSpace.HTSurfaceLast; ++thisHBsurfID) {
353 0 : ++thisSurfinZone;
354 0 : if (state.dataSurface->Surface(thisHBsurfID).Class == DataSurfaces::SurfaceClass::IntMass) {
355 0 : airPatternZoneInfo.Surf(thisSurfinZone).SurfID = thisHBsurfID;
356 0 : airPatternZoneInfo.Surf(thisSurfinZone).Zeta = 0.5;
357 0 : continue;
358 : }
359 :
360 0 : airPatternZoneInfo.Surf(thisSurfinZone).SurfID = thisHBsurfID;
361 :
362 0 : airPatternZoneInfo.Surf(thisSurfinZone).Zeta = FigureNDheightInZone(state, thisHBsurfID);
363 : }
364 : } // loop through surfaces in this zone
365 :
366 : } // loop through number of 'RoomAir:TemperaturePattern:UserDefined' objects
367 :
368 : // Check against AirModel. Make sure there is a match here.
369 0 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
370 0 : if (state.dataRoomAir->AirModel(iZone).AirModel != RoomAirModel::UserDefined) continue;
371 0 : if (state.dataRoomAir->AirPatternZoneInfo(iZone).IsUsed) continue; // There is a Room Air Temperatures object for this zone
372 0 : ShowSevereError(state,
373 0 : format("{}AirModel for Zone=[{}] is indicated as \"User Defined\".", routineName, state.dataHeatBal->Zone(iZone).Name));
374 0 : ShowContinueError(state, format("...but missing a {} object for control.", ipsc->cCurrentModuleObject));
375 0 : ErrorsFound = true;
376 : }
377 :
378 : // now get user defined temperature patterns
379 0 : if (!allocated(state.dataRoomAir->AirPattern)) {
380 0 : state.dataRoomAir->AirPattern.allocate(state.dataRoomAir->NumAirTempPatterns);
381 : }
382 :
383 : // Four different objects to get
384 0 : ipsc->cCurrentModuleObject = cTempPatternConstGradientObject;
385 0 : for (int ObjNum = 1; ObjNum <= state.dataRoomAir->NumConstantGradient; ++ObjNum) {
386 0 : int thisPattern = ObjNum;
387 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
388 0 : ipsc->cCurrentModuleObject,
389 : ObjNum,
390 0 : ipsc->cAlphaArgs,
391 : NumAlphas,
392 0 : ipsc->rNumericArgs,
393 : NumNumbers,
394 : Status,
395 : _,
396 : _,
397 0 : ipsc->cAlphaFieldNames,
398 0 : ipsc->cNumericFieldNames);
399 :
400 0 : auto &roomAirPattern = state.dataRoomAir->AirPattern(thisPattern);
401 0 : roomAirPattern.Name = ipsc->cAlphaArgs(1);
402 0 : roomAirPattern.PatrnID = ipsc->rNumericArgs(1);
403 0 : roomAirPattern.PatternMode = UserDefinedPatternType::ConstGradTemp;
404 0 : roomAirPattern.DeltaTstat = ipsc->rNumericArgs(2);
405 0 : roomAirPattern.DeltaTleaving = ipsc->rNumericArgs(3);
406 0 : roomAirPattern.DeltaTexhaust = ipsc->rNumericArgs(4);
407 0 : roomAirPattern.GradPatrn.Gradient = ipsc->rNumericArgs(5);
408 : }
409 :
410 0 : ipsc->cCurrentModuleObject = cTempPatternTwoGradientObject;
411 0 : for (int ObjNum = 1; ObjNum <= state.dataRoomAir->NumTwoGradientInterp; ++ObjNum) {
412 0 : int thisPattern = state.dataRoomAir->NumConstantGradient + ObjNum;
413 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
414 0 : ipsc->cCurrentModuleObject,
415 : ObjNum,
416 0 : ipsc->cAlphaArgs,
417 : NumAlphas,
418 0 : ipsc->rNumericArgs,
419 : NumNumbers,
420 : Status,
421 : _,
422 : _,
423 0 : ipsc->cAlphaFieldNames,
424 0 : ipsc->cNumericFieldNames);
425 :
426 0 : auto &roomAirPattern = state.dataRoomAir->AirPattern(thisPattern);
427 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
428 0 : roomAirPattern.PatternMode = UserDefinedPatternType::TwoGradInterp;
429 0 : roomAirPattern.Name = ipsc->cAlphaArgs(1);
430 0 : roomAirPattern.PatrnID = ipsc->rNumericArgs(1);
431 0 : roomAirPattern.TwoGradPatrn.TstatHeight = ipsc->rNumericArgs(2);
432 0 : roomAirPattern.TwoGradPatrn.TleavingHeight = ipsc->rNumericArgs(3);
433 0 : roomAirPattern.TwoGradPatrn.TexhaustHeight = ipsc->rNumericArgs(4);
434 0 : roomAirPattern.TwoGradPatrn.LowGradient = ipsc->rNumericArgs(5);
435 0 : roomAirPattern.TwoGradPatrn.HiGradient = ipsc->rNumericArgs(6);
436 :
437 0 : roomAirPattern.TwoGradPatrn.InterpolationMode =
438 0 : static_cast<UserDefinedPatternMode>(getEnumValue(userDefinedPatternModeNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(2))));
439 0 : if (roomAirPattern.TwoGradPatrn.InterpolationMode == UserDefinedPatternMode::Invalid) {
440 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
441 0 : ErrorsFound = true;
442 : }
443 :
444 0 : roomAirPattern.TwoGradPatrn.UpperBoundTempScale = ipsc->rNumericArgs(7);
445 0 : roomAirPattern.TwoGradPatrn.LowerBoundTempScale = ipsc->rNumericArgs(8);
446 :
447 0 : roomAirPattern.TwoGradPatrn.UpperBoundHeatRateScale = ipsc->rNumericArgs(9);
448 0 : roomAirPattern.TwoGradPatrn.LowerBoundHeatRateScale = ipsc->rNumericArgs(10);
449 :
450 : // now test the input some
451 0 : if (roomAirPattern.TwoGradPatrn.HiGradient == roomAirPattern.TwoGradPatrn.LowGradient) {
452 0 : ShowWarningError(state, format("Upper and lower gradients equal, use {} instead ", cTempPatternConstGradientObject));
453 0 : ShowContinueError(state, format("Entered in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
454 : }
455 0 : if ((roomAirPattern.TwoGradPatrn.UpperBoundTempScale == roomAirPattern.TwoGradPatrn.LowerBoundTempScale) &&
456 0 : ((roomAirPattern.TwoGradPatrn.InterpolationMode == UserDefinedPatternMode::OutdoorDryBulb) ||
457 0 : (roomAirPattern.TwoGradPatrn.InterpolationMode == UserDefinedPatternMode::ZoneAirTemp) ||
458 0 : (roomAirPattern.TwoGradPatrn.InterpolationMode == UserDefinedPatternMode::DeltaOutdoorZone))) {
459 : // throw error, will cause divide by zero when used for scaling
460 0 : ShowSevereError(state, format("Error in temperature scale in {}: {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
461 0 : ErrorsFound = true;
462 : }
463 0 : if ((roomAirPattern.TwoGradPatrn.HiGradient == roomAirPattern.TwoGradPatrn.LowGradient) &&
464 0 : ((roomAirPattern.TwoGradPatrn.InterpolationMode == UserDefinedPatternMode::SensibleCooling) ||
465 0 : (roomAirPattern.TwoGradPatrn.InterpolationMode == UserDefinedPatternMode::SensibleHeating))) {
466 : // throw error, will cause divide by zero when used for scaling
467 0 : ShowSevereError(state, format("Error in load scale in {}: {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
468 0 : ErrorsFound = true;
469 : }
470 : }
471 :
472 0 : ipsc->cCurrentModuleObject = cTempPatternNDHeightObject;
473 0 : for (int ObjNum = 1; ObjNum <= state.dataRoomAir->NumNonDimensionalHeight; ++ObjNum) {
474 0 : int thisPattern = state.dataRoomAir->NumConstantGradient + state.dataRoomAir->NumTwoGradientInterp + ObjNum;
475 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
476 0 : ipsc->cCurrentModuleObject,
477 : ObjNum,
478 0 : ipsc->cAlphaArgs,
479 : NumAlphas,
480 0 : ipsc->rNumericArgs,
481 : NumNumbers,
482 : Status,
483 : _,
484 : _,
485 0 : ipsc->cAlphaFieldNames,
486 0 : ipsc->cNumericFieldNames);
487 0 : auto &roomAirPattern = state.dataRoomAir->AirPattern(thisPattern);
488 0 : roomAirPattern.PatternMode = UserDefinedPatternType::NonDimenHeight;
489 :
490 0 : roomAirPattern.Name = ipsc->cAlphaArgs(1);
491 0 : roomAirPattern.PatrnID = ipsc->rNumericArgs(1);
492 0 : roomAirPattern.DeltaTstat = ipsc->rNumericArgs(2);
493 0 : roomAirPattern.DeltaTleaving = ipsc->rNumericArgs(3);
494 0 : roomAirPattern.DeltaTexhaust = ipsc->rNumericArgs(4);
495 :
496 0 : int NumPairs = std::floor((double(NumNumbers) - 4.0) / 2.0);
497 :
498 : // TODO error checking
499 :
500 0 : roomAirPattern.VertPatrn.ZetaPatrn.allocate(NumPairs);
501 0 : roomAirPattern.VertPatrn.DeltaTaiPatrn.allocate(NumPairs);
502 :
503 : // init these since they can't be in derived type
504 0 : roomAirPattern.VertPatrn.ZetaPatrn = 0.0;
505 0 : roomAirPattern.VertPatrn.DeltaTaiPatrn = 0.0;
506 :
507 0 : for (int i = 0; i <= NumPairs - 1; ++i) {
508 :
509 0 : roomAirPattern.VertPatrn.ZetaPatrn(i + 1) = ipsc->rNumericArgs(2 * i + 5);
510 0 : roomAirPattern.VertPatrn.DeltaTaiPatrn(i + 1) = ipsc->rNumericArgs(2 * i + 6);
511 : }
512 :
513 : // TODO check order (TODO sort ? )
514 0 : for (int i = 2; i <= NumPairs; ++i) {
515 0 : if (roomAirPattern.VertPatrn.ZetaPatrn(i) < roomAirPattern.VertPatrn.ZetaPatrn(i - 1)) {
516 0 : ShowSevereError(state, format("Zeta values not in increasing order in {}: {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
517 0 : ErrorsFound = true;
518 : }
519 : }
520 : }
521 :
522 0 : ipsc->cCurrentModuleObject = cTempPatternSurfMapObject;
523 0 : for (int ObjNum = 1; ObjNum <= state.dataRoomAir->NumSurfaceMapping; ++ObjNum) {
524 0 : int thisPattern = state.dataRoomAir->NumConstantGradient + state.dataRoomAir->NumTwoGradientInterp +
525 0 : state.dataRoomAir->NumNonDimensionalHeight + ObjNum;
526 :
527 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
528 0 : ipsc->cCurrentModuleObject,
529 : ObjNum,
530 0 : ipsc->cAlphaArgs,
531 : NumAlphas,
532 0 : ipsc->rNumericArgs,
533 : NumNumbers,
534 : Status,
535 : _,
536 : _,
537 0 : ipsc->cAlphaFieldNames,
538 0 : ipsc->cNumericFieldNames);
539 :
540 0 : auto &roomAirPattern = state.dataRoomAir->AirPattern(thisPattern);
541 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
542 :
543 0 : roomAirPattern.PatternMode = UserDefinedPatternType::SurfMapTemp;
544 0 : roomAirPattern.Name = ipsc->cAlphaArgs(1);
545 0 : roomAirPattern.PatrnID = ipsc->rNumericArgs(1);
546 0 : roomAirPattern.DeltaTstat = ipsc->rNumericArgs(2);
547 0 : roomAirPattern.DeltaTleaving = ipsc->rNumericArgs(3);
548 0 : roomAirPattern.DeltaTexhaust = ipsc->rNumericArgs(4);
549 :
550 0 : int NumPairs = NumNumbers - 4;
551 :
552 0 : if (NumPairs != (NumAlphas - 1)) {
553 0 : ShowSevereError(state, format("Error in number of entries in {} object: {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
554 0 : ErrorsFound = true;
555 : }
556 0 : roomAirPattern.MapPatrn.SurfName.allocate(NumPairs);
557 0 : roomAirPattern.MapPatrn.DeltaTai.allocate(NumPairs);
558 0 : roomAirPattern.MapPatrn.SurfID.allocate(NumPairs);
559 :
560 : // init just allocated
561 0 : roomAirPattern.MapPatrn.SurfName = "";
562 0 : roomAirPattern.MapPatrn.DeltaTai = 0.0;
563 0 : roomAirPattern.MapPatrn.SurfID = 0;
564 :
565 0 : for (int i = 1; i <= NumPairs; ++i) {
566 0 : roomAirPattern.MapPatrn.SurfName(i) = ipsc->cAlphaArgs(i + 1);
567 0 : roomAirPattern.MapPatrn.DeltaTai(i) = ipsc->rNumericArgs(i + 4);
568 0 : roomAirPattern.MapPatrn.SurfID(i) = Util::FindItemInList(ipsc->cAlphaArgs(i + 1), state.dataSurface->Surface);
569 0 : if (roomAirPattern.MapPatrn.SurfID(i) == 0) {
570 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(i + 1), ipsc->cAlphaArgs(i + 1));
571 0 : ErrorsFound = true;
572 : }
573 : }
574 0 : roomAirPattern.MapPatrn.NumSurfs = NumPairs;
575 : }
576 :
577 0 : if (state.dataErrTracking->TotalRoomAirPatternTooLow > 0) {
578 0 : ShowWarningError(state,
579 0 : format("GetUserDefinedPatternData: RoomAirModelUserTempPattern: {} problem(s) in non-dimensional height calculations, "
580 : "too low surface height(s) in relation to floor height of zone(s).",
581 0 : state.dataErrTracking->TotalRoomAirPatternTooLow));
582 0 : ShowContinueError(state, "...Use OutputDiagnostics,DisplayExtraWarnings; to see details.");
583 0 : state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalRoomAirPatternTooLow;
584 : }
585 0 : if (state.dataErrTracking->TotalRoomAirPatternTooHigh > 0) {
586 0 : ShowWarningError(state,
587 0 : format("GetUserDefinedPatternData: RoomAirModelUserTempPattern: {} problem(s) in non-dimensional height calculations, "
588 : "too high surface height(s) in relation to ceiling height of zone(s).",
589 0 : state.dataErrTracking->TotalRoomAirPatternTooHigh));
590 0 : ShowContinueError(state, "...Use OutputDiagnostics,DisplayExtraWarnings; to see details.");
591 0 : state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalRoomAirPatternTooHigh;
592 : }
593 :
594 : // now do one time setups from and checks on user data
595 :
596 : // Find and set return and exhaust node ids
597 :
598 0 : for (int i = 1; i <= state.dataGlobal->NumOfZones; ++i) {
599 0 : if (state.dataRoomAir->AirPatternZoneInfo(i).IsUsed) {
600 : // first get return and exhaust air node index
601 0 : int found = Util::FindItemInList(
602 0 : state.dataRoomAir->AirPatternZoneInfo(i).ZoneName, state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
603 :
604 0 : if (found != 0) {
605 :
606 0 : state.dataRoomAir->AirPatternZoneInfo(i).ZoneNodeID = state.dataZoneEquip->ZoneEquipConfig(found).ZoneNode;
607 0 : if (allocated(state.dataZoneEquip->ZoneEquipConfig(found).ExhaustNode)) {
608 0 : state.dataRoomAir->AirPatternZoneInfo(i).ExhaustAirNodeID.allocate(
609 0 : state.dataZoneEquip->ZoneEquipConfig(found).NumExhaustNodes);
610 0 : state.dataRoomAir->AirPatternZoneInfo(i).ExhaustAirNodeID = state.dataZoneEquip->ZoneEquipConfig(found).ExhaustNode;
611 : } // exhaust nodes present
612 : } // found ZoneEquipConf
613 :
614 : // second get zone height values
615 0 : state.dataRoomAir->AirPatternZoneInfo(i).ZoneHeight = state.dataHeatBal->Zone(i).CeilingHeight;
616 :
617 : } // air pattern is used
618 : }
619 : }
620 :
621 89 : void GetAirNodeData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
622 : {
623 :
624 : // SUBROUTINE INFORMATION:
625 : // AUTHOR Brent Griffith
626 : // DATE WRITTEN August 2001
627 : // RE-ENGINEERED April 2003, Weixiu Kong
628 : // MODIFIED July 2003, CC
629 : // Jan 2004, CC
630 :
631 : // PURPOSE OF THIS SUBROUTINE:
632 : // Get AirNode data for all zones at once
633 :
634 89 : constexpr std::string_view routineName = "GetAirNodeData";
635 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
636 : int NumAlphas; // States which alpha value to read from a
637 : // "Number" line
638 : int NumNumbers; // Number of numbers encountered
639 : int Status; // Notes if there was an error in processing the input
640 :
641 89 : if (!state.dataRoomAir->DispVent1NodeModelUsed) return;
642 :
643 0 : auto &ipsc = state.dataIPShortCut;
644 :
645 : // Initialize default values for air nodes
646 0 : state.dataRoomAir->TotNumOfZoneAirNodes.allocate(state.dataGlobal->NumOfZones);
647 0 : state.dataRoomAir->TotNumOfAirNodes = 0;
648 0 : state.dataRoomAir->TotNumOfZoneAirNodes = 0;
649 0 : ipsc->cCurrentModuleObject = "RoomAir:Node";
650 0 : state.dataRoomAir->TotNumOfAirNodes = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
651 :
652 0 : if (state.dataRoomAir->TotNumOfAirNodes <= 0) {
653 : // no air node object is found, terminate the program
654 0 : ShowSevereError(state, format("No {} objects found in input.", ipsc->cCurrentModuleObject));
655 0 : ShowContinueError(state, format("The OneNodeDisplacementVentilation model requires {} objects", ipsc->cCurrentModuleObject));
656 0 : ErrorsFound = true;
657 0 : return;
658 : } else {
659 : // air node objects are found so allocate airnode variable
660 0 : state.dataRoomAir->AirNode.allocate(state.dataRoomAir->TotNumOfAirNodes);
661 : }
662 :
663 0 : for (int AirNodeNum = 1; AirNodeNum <= state.dataRoomAir->TotNumOfAirNodes; ++AirNodeNum) {
664 :
665 : // get air node objects
666 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
667 0 : ipsc->cCurrentModuleObject,
668 : AirNodeNum,
669 0 : ipsc->cAlphaArgs,
670 : NumAlphas,
671 0 : ipsc->rNumericArgs,
672 : NumNumbers,
673 : Status,
674 : _,
675 : _,
676 0 : ipsc->cAlphaFieldNames,
677 0 : ipsc->cNumericFieldNames);
678 :
679 0 : auto &airNode = state.dataRoomAir->AirNode(AirNodeNum);
680 0 : airNode.Name = ipsc->cAlphaArgs(1);
681 :
682 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, airNode.Name};
683 :
684 0 : airNode.ZoneName = ipsc->cAlphaArgs(3); // Zone name
685 0 : airNode.ZonePtr = Util::FindItemInList(airNode.ZoneName, state.dataHeatBal->Zone);
686 0 : if (airNode.ZonePtr == 0) {
687 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(3), ipsc->cAlphaArgs(3));
688 0 : ErrorsFound = true;
689 : } else {
690 0 : int NumOfSurfs = 0;
691 0 : for (int spaceNum : state.dataHeatBal->Zone(airNode.ZonePtr).spaceIndexes) {
692 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
693 0 : NumOfSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1;
694 : }
695 0 : airNode.SurfMask.allocate(NumOfSurfs);
696 : }
697 :
698 0 : airNode.ClassType = static_cast<AirNodeType>(getEnumValue(airNodeTypeNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(2))));
699 0 : if (airNode.ClassType == AirNodeType::Invalid) {
700 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
701 0 : ErrorsFound = true;
702 : }
703 :
704 0 : airNode.Height = ipsc->rNumericArgs(1); // Air node height
705 0 : int NumSurfsInvolved = NumAlphas - 3; // Number of surfaces involved with air nodes
706 :
707 : // Initialize
708 0 : airNode.SurfMask = false;
709 :
710 0 : if (NumSurfsInvolved <= 0) {
711 :
712 : // report severe error since the following air nodes require surfaces associated with them
713 0 : if (airNode.ClassType == AirNodeType::Floor || airNode.ClassType == AirNodeType::Ceiling || airNode.ClassType == AirNodeType::Mundt ||
714 0 : airNode.ClassType == AirNodeType::Plume || airNode.ClassType == AirNodeType::Rees) { // Are there really Rees 1-4?
715 : // terminate the program due to a severe error in the specified input
716 0 : ShowSevereError(state,
717 0 : format("GetAirNodeData: {}=\"{}\" invalid air node specification.", ipsc->cCurrentModuleObject, airNode.Name));
718 0 : ShowContinueError(state,
719 0 : format("Mundt Room Air Model: No surface names specified. Air node=\"{} requires surfaces associated with it.",
720 0 : airNode.Name));
721 0 : ErrorsFound = true;
722 : }
723 0 : continue;
724 : }
725 :
726 : // report warning error since the following air nodes do not require surfaces associated with them
727 : // and assign .FALSE. to 'SurfNeeded'
728 0 : if (airNode.ClassType == AirNodeType::Inlet || airNode.ClassType == AirNodeType::Control || airNode.ClassType == AirNodeType::Return ||
729 0 : airNode.ClassType == AirNodeType::Plume) {
730 0 : ShowWarningError(state, format("GetAirNodeData: {}=\"{}\" invalid linkage", ipsc->cCurrentModuleObject, airNode.Name));
731 0 : ShowContinueError(
732 0 : state, format("Mundt Room Air Model: No surface names needed. Air node=\"{} does not relate to any surfaces.", airNode.Name));
733 0 : continue;
734 : }
735 :
736 : // this air node is in this zone; hence, first get name of all surfaces in this zone
737 0 : auto const &zone = state.dataHeatBal->Zone(airNode.ZonePtr);
738 0 : int NumOfSurfs = 0;
739 0 : for (int spaceNum : zone.spaceIndexes) {
740 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
741 0 : NumOfSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1;
742 : }
743 :
744 : // terminate the program due to a severe error in the specified input
745 0 : if (NumSurfsInvolved > NumOfSurfs) {
746 0 : ShowFatalError(
747 : state,
748 0 : format("GetAirNodeData: Mundt Room Air Model: Number of surfaces connected to {} is greater than number of surfaces in {}",
749 0 : airNode.Name,
750 0 : zone.Name));
751 0 : return;
752 : }
753 :
754 : // relate surfaces to this air node and check to see whether surface names are specified correctly or not
755 0 : int SurfCount = 0;
756 0 : for (int ListSurfNum = 4; ListSurfNum <= NumAlphas; ++ListSurfNum) {
757 0 : int thisSurfinZone = 0;
758 0 : for (int spaceNum : zone.spaceIndexes) {
759 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
760 0 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
761 0 : ++thisSurfinZone;
762 0 : if (ipsc->cAlphaArgs(ListSurfNum) == state.dataSurface->Surface(SurfNum).Name) {
763 0 : airNode.SurfMask(thisSurfinZone) = true;
764 0 : ++SurfCount;
765 0 : break;
766 : }
767 : }
768 0 : if (SurfCount > 0) break;
769 : }
770 : }
771 :
772 : // report warning error since surface names are specified correctly
773 0 : if ((NumSurfsInvolved) != SurfCount) {
774 0 : ShowWarningError(
775 : state,
776 0 : format("GetAirNodeData: Mundt Room Air Model: Some surface names specified for {} are not in {}", airNode.Name, zone.Name));
777 : }
778 : } // for (AirNodeNum)
779 :
780 : // get number of air nodes in each zone
781 0 : for (int AirNodeNum = 1; AirNodeNum <= state.dataRoomAir->TotNumOfAirNodes; ++AirNodeNum) {
782 0 : auto const &airNode = state.dataRoomAir->AirNode(AirNodeNum);
783 : // this zone uses other air model so skip the rest
784 0 : if (state.dataRoomAir->AirModel(airNode.ZonePtr).AirModel == RoomAirModel::DispVent1Node)
785 0 : ++state.dataRoomAir->TotNumOfZoneAirNodes(airNode.ZonePtr);
786 : }
787 : }
788 :
789 : //*****************************************************************************************
790 :
791 89 : void GetMundtData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
792 : {
793 :
794 : // SUBROUTINE INFORMATION:
795 : // AUTHOR Brent Griffith
796 : // DATE WRITTEN August 2001
797 : // MODIFIED na
798 : // RE-ENGINEERED April 2003, Weixiu Kong
799 : // July 2003, CC
800 :
801 : // PURPOSE OF THIS SUBROUTINE:
802 : // Get Mundt model controls for all zones at once
803 :
804 : // METHODOLOGY EMPLOYED:
805 : // Use input processer to get input from idf file
806 :
807 : // Using/Aliasing
808 89 : constexpr std::string_view routineName = "GetMundtData";
809 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
810 : int NumAlphas;
811 : int NumNumbers; // Number of numbers encountered
812 : int Status; // Notes if there was an error in processing the input
813 : int NumOfMundtContrl; // Number of Mundt Model Controls
814 :
815 89 : auto &ipsc = state.dataIPShortCut;
816 :
817 89 : if (!state.dataRoomAir->DispVent1NodeModelUsed) return;
818 :
819 : // Initialize default values for Mundt model controls
820 0 : state.dataRoomAir->ConvectiveFloorSplit.allocate(state.dataGlobal->NumOfZones);
821 0 : state.dataRoomAir->InfiltratFloorSplit.allocate(state.dataGlobal->NumOfZones);
822 0 : state.dataRoomAir->ConvectiveFloorSplit = 0.0;
823 0 : state.dataRoomAir->InfiltratFloorSplit = 0.0;
824 0 : auto &cCurrentModuleObject = ipsc->cCurrentModuleObject;
825 0 : cCurrentModuleObject = "RoomAirSettings:OneNodeDisplacementVentilation";
826 0 : NumOfMundtContrl = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
827 0 : if (NumOfMundtContrl > state.dataGlobal->NumOfZones) {
828 0 : ShowSevereError(state, format("Too many {} objects in input file", cCurrentModuleObject));
829 0 : ShowContinueError(state, format("There cannot be more {} objects than number of zones.", cCurrentModuleObject));
830 0 : ErrorsFound = true;
831 : }
832 :
833 0 : if (NumOfMundtContrl == 0) {
834 0 : ShowWarningError(state,
835 0 : format("No {} objects found, program assumes no convection or infiltration gains near floors", cCurrentModuleObject));
836 0 : return;
837 : }
838 :
839 : // this zone uses Mundt model so get Mundt Model Control
840 : // loop through all 'RoomAirSettings:OneNodeDisplacementVentilation' objects
841 0 : for (int ControlNum = 1; ControlNum <= NumOfMundtContrl; ++ControlNum) {
842 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
843 0 : ipsc->cCurrentModuleObject,
844 : ControlNum,
845 0 : ipsc->cAlphaArgs,
846 : NumAlphas,
847 0 : ipsc->rNumericArgs,
848 : NumNumbers,
849 : Status,
850 : _,
851 : _,
852 0 : ipsc->cAlphaFieldNames,
853 0 : ipsc->cNumericFieldNames);
854 :
855 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ""};
856 0 : int ZoneNum = Util::FindItemInList(ipsc->cAlphaArgs(1), state.dataHeatBal->Zone);
857 0 : if (ZoneNum == 0) {
858 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
859 0 : ErrorsFound = true;
860 0 : continue;
861 : }
862 0 : if (state.dataRoomAir->AirModel(ZoneNum).AirModel != RoomAirModel::DispVent1Node) {
863 0 : ShowSevereError(state, format("Zone specified=\"{}\", Air Model type is not OneNodeDisplacementVentilation.", ipsc->cAlphaArgs(1)));
864 0 : ShowContinueError(state,
865 0 : format("Air Model Type for zone={}", roomAirModelNamesUC[(int)state.dataRoomAir->AirModel(ZoneNum).AirModel]));
866 0 : ErrorsFound = true;
867 0 : continue;
868 : }
869 0 : state.dataRoomAir->ConvectiveFloorSplit(ZoneNum) = ipsc->rNumericArgs(1);
870 0 : state.dataRoomAir->InfiltratFloorSplit(ZoneNum) = ipsc->rNumericArgs(2);
871 : }
872 : }
873 :
874 89 : void GetDisplacementVentData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
875 : {
876 :
877 : // SUBROUTINE INFORMATION:
878 : // AUTHOR G. Carrilho da Graca
879 : // DATE WRITTEN January 2004
880 :
881 : // PURPOSE OF THIS SUBROUTINE:
882 : // Get UCSD Displacement ventilation model controls for all zones at once
883 :
884 : // METHODOLOGY EMPLOYED:
885 : // Use input processor to get input from idf file
886 :
887 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
888 89 : constexpr std::string_view routineName = "GetDisplacementVentData";
889 : int IOStat;
890 : int NumAlpha;
891 : int NumNumber;
892 :
893 89 : auto &ipsc = state.dataIPShortCut;
894 :
895 89 : if (!state.dataRoomAir->UCSDModelUsed) return;
896 0 : ipsc->cCurrentModuleObject = "RoomAirSettings:ThreeNodeDisplacementVentilation";
897 0 : state.dataRoomAir->TotDispVent3Node = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
898 :
899 0 : if (state.dataRoomAir->TotDispVent3Node <= 0) return;
900 :
901 0 : state.dataRoomAir->ZoneDispVent3Node.allocate(state.dataRoomAir->TotDispVent3Node);
902 :
903 0 : for (int Loop = 1; Loop <= state.dataRoomAir->TotDispVent3Node; ++Loop) {
904 :
905 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
906 0 : ipsc->cCurrentModuleObject,
907 : Loop,
908 0 : ipsc->cAlphaArgs,
909 : NumAlpha,
910 0 : ipsc->rNumericArgs,
911 : NumNumber,
912 : IOStat,
913 : _,
914 0 : ipsc->lAlphaFieldBlanks,
915 0 : ipsc->cAlphaFieldNames,
916 0 : ipsc->cNumericFieldNames);
917 :
918 0 : auto &zoneDV3N = state.dataRoomAir->ZoneDispVent3Node(Loop);
919 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
920 : // First is Zone Name
921 : // zoneUCSDDV.ZoneName = ipsc->cAlphaArgs(1);
922 0 : zoneDV3N.ZonePtr = Util::FindItemInList(ipsc->cAlphaArgs(1), state.dataHeatBal->Zone);
923 0 : if (zoneDV3N.ZonePtr == 0) {
924 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
925 0 : ErrorsFound = true;
926 : } else {
927 0 : state.dataRoomAir->IsZoneDispVent3Node(zoneDV3N.ZonePtr) = true;
928 : }
929 : // Second Alpha is Schedule Name
930 : // zoneUCSDDV.SchedGainsName = ipsc->cAlphaArgs(2);
931 0 : if (ipsc->lAlphaFieldBlanks(2)) {
932 0 : ShowSevereEmptyField(state, eoh, ipsc->cAlphaFieldNames(2));
933 0 : ErrorsFound = true;
934 0 : } else if ((zoneDV3N.gainsSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(2))) == nullptr) {
935 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
936 0 : ErrorsFound = true;
937 : }
938 :
939 0 : zoneDV3N.NumPlumesPerOcc = ipsc->rNumericArgs(1);
940 0 : zoneDV3N.ThermostatHeight = ipsc->rNumericArgs(2);
941 0 : zoneDV3N.ComfortHeight = ipsc->rNumericArgs(3);
942 0 : zoneDV3N.TempTrigger = ipsc->rNumericArgs(4);
943 : }
944 : }
945 :
946 89 : void GetCrossVentData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
947 : {
948 :
949 : // SUBROUTINE INFORMATION:
950 : // AUTHOR G. Carrilho da Graca
951 : // DATE WRITTEN October 2004
952 :
953 : // PURPOSE OF THIS SUBROUTINE:
954 : // Get UCSD Cross ventilation model controls for all zones at once
955 :
956 : // METHODOLOGY EMPLOYED:
957 : // Use input processor to get input from idf file
958 :
959 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
960 89 : constexpr std::string_view routineName = "GetCrossVentData";
961 :
962 : int IOStat;
963 : int NumAlpha;
964 : int NumNumber;
965 :
966 89 : auto &ipsc = state.dataIPShortCut;
967 89 : if (!state.dataRoomAir->UCSDModelUsed) return;
968 0 : ipsc->cCurrentModuleObject = "RoomAirSettings:CrossVentilation";
969 0 : state.dataRoomAir->TotCrossVent = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
970 :
971 0 : if (state.dataRoomAir->TotCrossVent <= 0) return;
972 :
973 0 : state.dataRoomAir->ZoneCrossVent.allocate(state.dataRoomAir->TotCrossVent);
974 :
975 0 : for (int Loop = 1; Loop <= state.dataRoomAir->TotCrossVent; ++Loop) {
976 :
977 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
978 0 : ipsc->cCurrentModuleObject,
979 : Loop,
980 0 : ipsc->cAlphaArgs,
981 : NumAlpha,
982 0 : ipsc->rNumericArgs,
983 : NumNumber,
984 : IOStat,
985 : _,
986 0 : ipsc->lAlphaFieldBlanks,
987 0 : ipsc->cAlphaFieldNames,
988 0 : ipsc->cNumericFieldNames);
989 :
990 0 : auto &zoneCV = state.dataRoomAir->ZoneCrossVent(Loop);
991 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
992 : // First is Zone Name
993 : // state.dataRoomAir->ZoneUCSDCV(Loop).ZoneName = ipsc->cAlphaArgs(1);
994 0 : if ((zoneCV.ZonePtr = Util::FindItemInList(ipsc->cAlphaArgs(1), state.dataHeatBal->Zone)) == 0) {
995 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
996 0 : ErrorsFound = true;
997 : } else {
998 0 : state.dataRoomAir->IsZoneCrossVent(zoneCV.ZonePtr) = true;
999 : }
1000 : // Second Alpha is Schedule Name
1001 : // zoneUCSDCV.SchedGainsName = ipsc->cAlphaArgs(2);
1002 0 : if (ipsc->lAlphaFieldBlanks(2)) {
1003 0 : ShowSevereEmptyField(state, eoh, ipsc->cAlphaFieldNames(2));
1004 0 : ErrorsFound = true;
1005 0 : } else if ((zoneCV.gainsSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(2))) == nullptr) {
1006 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
1007 0 : ErrorsFound = true;
1008 : }
1009 :
1010 : // Third Alpha is a string: JET or RECIRCULATION
1011 0 : if (ipsc->lAlphaFieldBlanks(3)) {
1012 0 : for (int Loop2 = 1; Loop2 <= state.dataHeatBal->TotPeople; ++Loop2) {
1013 0 : if (state.dataHeatBal->People(Loop2).ZonePtr != zoneCV.ZonePtr) continue;
1014 0 : if (!state.dataHeatBal->People(Loop2).Fanger) continue;
1015 0 : ShowSevereEmptyField(state, eoh, ipsc->cAlphaFieldNames(3));
1016 0 : ErrorsFound = true;
1017 : }
1018 0 : } else if ((zoneCV.VforComfort = static_cast<Comfort>(getEnumValue(comfortNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(3))))) ==
1019 : Comfort::Invalid) {
1020 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(3), ipsc->cAlphaArgs(3));
1021 0 : ErrorsFound = true;
1022 : }
1023 :
1024 0 : if (zoneCV.ZonePtr == 0) continue;
1025 :
1026 : // Following depend on valid zone
1027 :
1028 0 : if (Util::FindItemInList(
1029 0 : state.dataHeatBal->Zone(zoneCV.ZonePtr).Name, state.afn->MultizoneZoneData, &AirflowNetwork::MultizoneZoneProp::ZoneName) == 0) {
1030 0 : ShowSevereError(state, format("Problem with {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1031 0 : ShowContinueError(state, "AirflowNetwork airflow model must be active in this zone");
1032 0 : ErrorsFound = true;
1033 : }
1034 :
1035 : // If a crack is used it must have an air flow coefficient = 0.5
1036 0 : for (int iLink = 1; iLink <= state.afn->NumOfLinksMultiZone; ++iLink) {
1037 0 : auto const &mzSurfaceData = state.afn->MultizoneSurfaceData(iLink);
1038 0 : int nodeNum1 = mzSurfaceData.NodeNums[0];
1039 0 : int nodeNum2 = mzSurfaceData.NodeNums[1];
1040 0 : if (state.dataSurface->Surface(mzSurfaceData.SurfNum).Zone == zoneCV.ZonePtr ||
1041 0 : (state.afn->AirflowNetworkNodeData(nodeNum2).EPlusZoneNum == zoneCV.ZonePtr &&
1042 0 : state.afn->AirflowNetworkNodeData(nodeNum1).EPlusZoneNum > 0) ||
1043 0 : (state.afn->AirflowNetworkNodeData(nodeNum2).EPlusZoneNum > 0 &&
1044 0 : state.afn->AirflowNetworkNodeData(nodeNum1).EPlusZoneNum == zoneCV.ZonePtr)) {
1045 0 : int compNum = state.afn->AirflowNetworkLinkageData(iLink).CompNum;
1046 0 : int typeNum = state.afn->AirflowNetworkCompData(compNum).TypeNum;
1047 0 : if (state.afn->AirflowNetworkCompData(compNum).CompTypeNum == AirflowNetwork::iComponentTypeNum::SCR) {
1048 0 : if (state.afn->MultizoneSurfaceCrackData(typeNum).exponent != 0.50) {
1049 0 : state.dataRoomAir->AirModel(zoneCV.ZonePtr).AirModel = RoomAirModel::Mixing;
1050 0 : ShowWarningError(state, format("Problem with {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1051 0 : ShowWarningError(state, format("Roomair model will not be applied for Zone={}.", ipsc->cAlphaArgs(1)));
1052 0 : ShowContinueError(
1053 : state,
1054 0 : format("AirflowNetwrok:Multizone:Surface crack object must have an air flow coefficient = 0.5, value was={:.2R}",
1055 0 : state.afn->MultizoneSurfaceCrackData(typeNum).exponent));
1056 : }
1057 : }
1058 : } // if
1059 : } // for (iLink)
1060 : } // for (Loop)
1061 : }
1062 :
1063 89 : void GetUFADZoneData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
1064 : {
1065 :
1066 : // SUBROUTINE INFORMATION:
1067 : // AUTHOR Fred Buhl
1068 : // DATE WRITTEN August 2005
1069 :
1070 : // PURPOSE OF THIS SUBROUTINE:
1071 : // Get UCSD UFAD interior zone model controls for all zones at once
1072 :
1073 : // METHODOLOGY EMPLOYED:
1074 : // Use input processor to get input from idf file
1075 :
1076 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1077 89 : constexpr std::string_view routineName = "GetUFADZoneData";
1078 :
1079 : int IOStat;
1080 : int NumAlpha;
1081 : int NumNumber;
1082 :
1083 89 : if (!state.dataRoomAir->UCSDModelUsed) {
1084 89 : state.dataRoomAir->TotUFADInt = 0;
1085 89 : state.dataRoomAir->TotUFADExt = 0;
1086 89 : return;
1087 : }
1088 :
1089 0 : auto &ipsc = state.dataIPShortCut;
1090 :
1091 0 : ipsc->cCurrentModuleObject = "RoomAirSettings:UnderFloorAirDistributionInterior";
1092 0 : state.dataRoomAir->TotUFADInt = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
1093 0 : ipsc->cCurrentModuleObject = "RoomAirSettings:UnderFloorAirDistributionExterior";
1094 0 : state.dataRoomAir->TotUFADExt = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
1095 :
1096 0 : if (state.dataRoomAir->TotUFADInt <= 0 && state.dataRoomAir->TotUFADExt <= 0) return;
1097 :
1098 0 : state.dataRoomAir->ZoneUFAD.allocate(state.dataRoomAir->TotUFADInt + state.dataRoomAir->TotUFADExt);
1099 0 : state.dataRoomAir->ZoneUFADPtr.dimension(state.dataGlobal->NumOfZones, 0);
1100 :
1101 0 : ipsc->cCurrentModuleObject = "RoomAirSettings:UnderFloorAirDistributionInterior";
1102 0 : for (int Loop = 1; Loop <= state.dataRoomAir->TotUFADInt; ++Loop) {
1103 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1104 0 : ipsc->cCurrentModuleObject,
1105 : Loop,
1106 0 : ipsc->cAlphaArgs,
1107 : NumAlpha,
1108 0 : ipsc->rNumericArgs,
1109 : NumNumber,
1110 : IOStat,
1111 : _,
1112 0 : ipsc->lAlphaFieldBlanks,
1113 0 : ipsc->cAlphaFieldNames,
1114 0 : ipsc->cNumericFieldNames);
1115 : // First is Zone Name
1116 0 : auto &zoneUI = state.dataRoomAir->ZoneUFAD(Loop);
1117 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
1118 :
1119 0 : zoneUI.ZoneName = ipsc->cAlphaArgs(1);
1120 0 : zoneUI.ZonePtr = Util::FindItemInList(ipsc->cAlphaArgs(1), state.dataHeatBal->Zone);
1121 0 : state.dataRoomAir->ZoneUFADPtr(zoneUI.ZonePtr) = Loop;
1122 0 : if (zoneUI.ZonePtr == 0) {
1123 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
1124 0 : ErrorsFound = true;
1125 : } else {
1126 0 : state.dataRoomAir->IsZoneUFAD(zoneUI.ZonePtr) = true;
1127 0 : state.dataRoomAir->ZoneUFADPtr(zoneUI.ZonePtr) = Loop;
1128 : }
1129 :
1130 : // 2nd alpha is diffuser type
1131 0 : zoneUI.DiffuserType = static_cast<Diffuser>(getEnumValue(diffuserNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(2))));
1132 0 : if (zoneUI.DiffuserType == Diffuser::Invalid) {
1133 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
1134 0 : ErrorsFound = true;
1135 : }
1136 : // 1st number is Number of Diffusers per Zone
1137 0 : zoneUI.DiffusersPerZone = ipsc->rNumericArgs(1);
1138 : // 2nd number is Power per Plume
1139 0 : zoneUI.PowerPerPlume = ipsc->rNumericArgs(2);
1140 : // 3rd number is Design Effective Area of Diffuser
1141 0 : zoneUI.DiffArea = ipsc->rNumericArgs(3);
1142 : // 4th number is Diffuser Slot Angle from Vertical
1143 0 : zoneUI.DiffAngle = ipsc->rNumericArgs(4);
1144 : // 5th number is Thermostat Height
1145 0 : zoneUI.ThermostatHeight = ipsc->rNumericArgs(5);
1146 : // 6th number is Comfort Height
1147 0 : zoneUI.ComfortHeight = ipsc->rNumericArgs(6);
1148 : // 7th number is Temperature Difference Threshold for Reporting
1149 0 : zoneUI.TempTrigger = ipsc->rNumericArgs(7);
1150 : // 8th number user-specified transition height
1151 0 : zoneUI.TransHeight = ipsc->rNumericArgs(8);
1152 : // 9th number is Coefficient A in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1153 0 : zoneUI.A_Kc = ipsc->rNumericArgs(9);
1154 : // 10th number is Coefficient B in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1155 0 : zoneUI.B_Kc = ipsc->rNumericArgs(10);
1156 : // 11th number is Coefficient C in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1157 0 : zoneUI.C_Kc = ipsc->rNumericArgs(11);
1158 : // 12th number is Coefficient D in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1159 0 : zoneUI.D_Kc = ipsc->rNumericArgs(12);
1160 : // 13th number is Coefficient E in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1161 0 : zoneUI.E_Kc = ipsc->rNumericArgs(13);
1162 : }
1163 :
1164 0 : ipsc->cCurrentModuleObject = "RoomAirSettings:UnderFloorAirDistributionExterior";
1165 0 : for (int Loop = 1; Loop <= state.dataRoomAir->TotUFADExt; ++Loop) {
1166 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1167 0 : ipsc->cCurrentModuleObject,
1168 : Loop,
1169 0 : ipsc->cAlphaArgs,
1170 : NumAlpha,
1171 0 : ipsc->rNumericArgs,
1172 : NumNumber,
1173 : IOStat,
1174 : _,
1175 0 : ipsc->lAlphaFieldBlanks,
1176 0 : ipsc->cAlphaFieldNames,
1177 0 : ipsc->cNumericFieldNames);
1178 : // First is Zone Name
1179 0 : auto &zoneUE = state.dataRoomAir->ZoneUFAD(Loop + state.dataRoomAir->TotUFADInt);
1180 0 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
1181 0 : zoneUE.ZoneName = ipsc->cAlphaArgs(1);
1182 0 : zoneUE.ZonePtr = Util::FindItemInList(ipsc->cAlphaArgs(1), state.dataHeatBal->Zone);
1183 0 : if (zoneUE.ZonePtr == 0) {
1184 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
1185 0 : ErrorsFound = true;
1186 : } else {
1187 0 : state.dataRoomAir->IsZoneUFAD(zoneUE.ZonePtr) = true;
1188 0 : state.dataRoomAir->ZoneUFADPtr(zoneUE.ZonePtr) = Loop + state.dataRoomAir->TotUFADInt;
1189 : }
1190 0 : zoneUE.DiffuserType = static_cast<Diffuser>(getEnumValue(diffuserNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(2))));
1191 0 : if (zoneUE.DiffuserType == Diffuser::Invalid) {
1192 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
1193 0 : ErrorsFound = true;
1194 : }
1195 : // 1st number is Number of Diffusers per Zone
1196 0 : zoneUE.DiffusersPerZone = ipsc->rNumericArgs(1);
1197 : // 2nd number is Power per Plume
1198 0 : zoneUE.PowerPerPlume = ipsc->rNumericArgs(2);
1199 : // 3rd number is Design Effective Area of Diffuser
1200 0 : zoneUE.DiffArea = ipsc->rNumericArgs(3);
1201 : // 4th number is Diffuser Slot Angle from Vertical
1202 0 : zoneUE.DiffAngle = ipsc->rNumericArgs(4);
1203 : // 5th number is Thermostat Height
1204 0 : zoneUE.ThermostatHeight = ipsc->rNumericArgs(5);
1205 : // 6th number is Comfort Height
1206 0 : zoneUE.ComfortHeight = ipsc->rNumericArgs(6);
1207 : // 7th number is Temperature Difference Threshold for Reporting
1208 0 : zoneUE.TempTrigger = ipsc->rNumericArgs(7);
1209 : // 8th number user-specified transition height
1210 0 : zoneUE.TransHeight = ipsc->rNumericArgs(8);
1211 : // 9th number is Coefficient A in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1212 0 : zoneUE.A_Kc = ipsc->rNumericArgs(9);
1213 : // 10th number is Coefficient B in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1214 0 : zoneUE.B_Kc = ipsc->rNumericArgs(10);
1215 : // 11th number is Coefficient C in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1216 0 : zoneUE.C_Kc = ipsc->rNumericArgs(11);
1217 : // 12th number is Coefficient D in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1218 0 : zoneUE.D_Kc = ipsc->rNumericArgs(12);
1219 : // 13th number is Coefficient E in formula Kc = A*Gamma**B + C + D*Gamma + E*Gamma**2
1220 0 : zoneUE.E_Kc = ipsc->rNumericArgs(13);
1221 : }
1222 : }
1223 :
1224 90 : void GetRoomAirflowNetworkData(EnergyPlusData &state, bool &ErrorsFound) // True if errors found during this get input routine
1225 : {
1226 :
1227 : // SUBROUTINE INFORMATION:
1228 : // AUTHOR Brent Griffith
1229 : // DATE WRITTEN November 2009
1230 :
1231 : // PURPOSE OF THIS SUBROUTINE:
1232 : // Get RoomAirflowNetwork data for all zones at once
1233 :
1234 : // METHODOLOGY EMPLOYED:
1235 : // Use input processor to get input from idf file
1236 :
1237 : // Using/Aliasing
1238 : using InternalHeatGains::GetInternalGainDeviceIndex;
1239 :
1240 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1241 90 : constexpr std::string_view routineName = "GetRoomAirflowNetworkData";
1242 : int NumAlphas;
1243 : int NumNumbers;
1244 : int status;
1245 : int TotNumOfRAFNNodeSurfLists;
1246 : int TotNumOfRAFNNodeGainsLists;
1247 : int TotNumOfRAFNNodeHVACLists;
1248 : int TotNumEquip;
1249 : bool IntEquipFound;
1250 :
1251 90 : auto &ipsc = state.dataIPShortCut;
1252 90 : ipsc->cCurrentModuleObject = "RoomAirSettings:AirflowNetwork";
1253 90 : state.dataRoomAir->NumOfRoomAFNControl = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
1254 91 : if (state.dataRoomAir->NumOfRoomAFNControl == 0) return;
1255 2 : if (state.dataRoomAir->NumOfRoomAFNControl > state.dataGlobal->NumOfZones) {
1256 0 : ShowSevereError(state, format("Too many {} objects in input file", ipsc->cCurrentModuleObject));
1257 0 : ShowContinueError(state, format("There cannot be more {} objects than number of zones.", ipsc->cCurrentModuleObject));
1258 0 : ErrorsFound = true;
1259 : }
1260 :
1261 2 : if (!allocated(state.dataRoomAir->AFNZoneInfo)) {
1262 2 : state.dataRoomAir->AFNZoneInfo.allocate(state.dataGlobal->NumOfZones);
1263 : }
1264 4 : for (int Loop = 1; Loop <= state.dataRoomAir->NumOfRoomAFNControl; ++Loop) {
1265 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1266 2 : ipsc->cCurrentModuleObject,
1267 : Loop,
1268 2 : ipsc->cAlphaArgs,
1269 : NumAlphas,
1270 2 : ipsc->rNumericArgs,
1271 : NumNumbers,
1272 : status,
1273 : _,
1274 2 : ipsc->lAlphaFieldBlanks,
1275 2 : ipsc->cAlphaFieldNames,
1276 2 : ipsc->cNumericFieldNames);
1277 :
1278 2 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
1279 2 : int ZoneNum = Util::FindItemInList(ipsc->cAlphaArgs(2), state.dataHeatBal->Zone, state.dataGlobal->NumOfZones);
1280 :
1281 2 : if (ZoneNum == 0) {
1282 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
1283 0 : ErrorsFound = true;
1284 0 : continue;
1285 : }
1286 2 : if (state.dataRoomAir->AirModel(ZoneNum).AirModel != RoomAirModel::AirflowNetwork) {
1287 0 : ShowSevereError(state,
1288 0 : format("GetRoomAirflowNetworkData: Zone specified='{}', Air Model type is not AirflowNetwork.", ipsc->cAlphaArgs(1)));
1289 0 : ShowContinueError(state,
1290 0 : format("Air Model Type for zone ={}", roomAirModelNamesUC[(int)state.dataRoomAir->AirModel(ZoneNum).AirModel]));
1291 0 : ErrorsFound = true;
1292 0 : continue;
1293 : }
1294 :
1295 2 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(ZoneNum);
1296 2 : roomAFNZoneInfo.ZoneID = ZoneNum;
1297 2 : roomAFNZoneInfo.IsUsed = true;
1298 2 : roomAFNZoneInfo.Name = ipsc->cAlphaArgs(1);
1299 2 : roomAFNZoneInfo.ZoneName = ipsc->cAlphaArgs(2); // Zone Name
1300 :
1301 2 : roomAFNZoneInfo.NumOfAirNodes = (NumAlphas - 3);
1302 :
1303 2 : if (roomAFNZoneInfo.NumOfAirNodes > 0) {
1304 2 : roomAFNZoneInfo.Node.allocate(roomAFNZoneInfo.NumOfAirNodes);
1305 : } else {
1306 0 : ShowSevereError(state,
1307 0 : format("GetRoomAirflowNetworkData: Incomplete input in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1308 0 : ErrorsFound = true;
1309 : }
1310 :
1311 9 : for (int iAirNode = 1; iAirNode <= roomAFNZoneInfo.NumOfAirNodes; ++iAirNode) {
1312 7 : roomAFNZoneInfo.Node(iAirNode).Name = ipsc->cAlphaArgs(iAirNode + 3);
1313 : }
1314 : // control point node
1315 :
1316 2 : roomAFNZoneInfo.ControlAirNodeID = Util::FindItemInList(ipsc->cAlphaArgs(3), roomAFNZoneInfo.Node, roomAFNZoneInfo.NumOfAirNodes);
1317 2 : if (roomAFNZoneInfo.ControlAirNodeID == 0) {
1318 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(3), ipsc->cAlphaArgs(3));
1319 0 : ErrorsFound = true;
1320 0 : continue;
1321 : }
1322 :
1323 2 : roomAFNZoneInfo.totNumSurfs = 0;
1324 4 : for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
1325 2 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
1326 2 : roomAFNZoneInfo.totNumSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1;
1327 : }
1328 : } // for (Loop)
1329 :
1330 2 : ipsc->cCurrentModuleObject = "RoomAir:Node:AirflowNetwork";
1331 2 : state.dataRoomAir->TotNumOfRoomAFNNodes = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
1332 9 : for (int Loop = 1; Loop <= state.dataRoomAir->TotNumOfRoomAFNNodes; ++Loop) {
1333 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1334 7 : ipsc->cCurrentModuleObject,
1335 : Loop,
1336 7 : ipsc->cAlphaArgs,
1337 : NumAlphas,
1338 7 : ipsc->rNumericArgs,
1339 : NumNumbers,
1340 : status,
1341 : _,
1342 7 : ipsc->lAlphaFieldBlanks,
1343 7 : ipsc->cAlphaFieldNames,
1344 7 : ipsc->cNumericFieldNames);
1345 :
1346 7 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
1347 7 : int ZoneNum = Util::FindItemInList(ipsc->cAlphaArgs(2), state.dataHeatBal->Zone, state.dataGlobal->NumOfZones);
1348 7 : if (ZoneNum == 0) {
1349 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(2), ipsc->cAlphaArgs(2));
1350 0 : ErrorsFound = true;
1351 0 : continue;
1352 : }
1353 :
1354 7 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(ZoneNum);
1355 7 : int RAFNNodeNum = Util::FindItemInList(ipsc->cAlphaArgs(1), roomAFNZoneInfo.Node, roomAFNZoneInfo.NumOfAirNodes);
1356 7 : if (RAFNNodeNum == 0) {
1357 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1));
1358 0 : ErrorsFound = true;
1359 0 : continue;
1360 : }
1361 :
1362 7 : auto &roomAFNZoneNode = roomAFNZoneInfo.Node(RAFNNodeNum);
1363 7 : roomAFNZoneNode.ZoneVolumeFraction = ipsc->rNumericArgs(1);
1364 7 : if (!ipsc->lAlphaFieldBlanks(3)) {
1365 7 : roomAFNZoneNode.NodeSurfListName = ipsc->cAlphaArgs(3);
1366 : } else {
1367 0 : roomAFNZoneNode.HasSurfacesAssigned = false;
1368 : }
1369 7 : if (!ipsc->lAlphaFieldBlanks(4)) {
1370 7 : roomAFNZoneNode.NodeIntGainsListName = ipsc->cAlphaArgs(4);
1371 : } else {
1372 0 : roomAFNZoneNode.HasIntGainsAssigned = false;
1373 : }
1374 7 : if (!ipsc->lAlphaFieldBlanks(5)) {
1375 7 : roomAFNZoneNode.NodeHVACListName = ipsc->cAlphaArgs(5);
1376 : } else {
1377 0 : roomAFNZoneNode.HasHVACAssigned = false;
1378 : }
1379 :
1380 : } // loop thru TotNumOfRoomAFNNodes
1381 :
1382 2 : ipsc->cCurrentModuleObject = "RoomAir:Node:AirflowNetwork:AdjacentSurfaceList";
1383 2 : TotNumOfRAFNNodeSurfLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
1384 9 : for (int Loop = 1; Loop <= TotNumOfRAFNNodeSurfLists; ++Loop) {
1385 7 : bool foundList = false;
1386 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1387 7 : ipsc->cCurrentModuleObject,
1388 : Loop,
1389 7 : ipsc->cAlphaArgs,
1390 : NumAlphas,
1391 7 : ipsc->rNumericArgs,
1392 : NumNumbers,
1393 : status,
1394 : _,
1395 : _,
1396 7 : ipsc->cAlphaFieldNames,
1397 7 : ipsc->cNumericFieldNames);
1398 :
1399 38 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1400 : // find surface list
1401 31 : int RAFNNodeNum = 0;
1402 31 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
1403 31 : if (roomAFNZoneInfo.NumOfAirNodes > 0) {
1404 7 : RAFNNodeNum = Util::FindItemInList(
1405 7 : ipsc->cAlphaArgs(1), roomAFNZoneInfo.Node, &AFNAirNodeNested::NodeSurfListName, roomAFNZoneInfo.NumOfAirNodes);
1406 : }
1407 :
1408 31 : if (RAFNNodeNum == 0) continue;
1409 :
1410 : // found it
1411 7 : foundList = true;
1412 7 : int NumSurfsThisNode = NumAlphas - 1;
1413 7 : int NumOfSurfs = 0; // What is this used for?
1414 14 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
1415 7 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
1416 7 : NumOfSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1;
1417 : }
1418 :
1419 7 : auto &roomAFNZoneNode = roomAFNZoneInfo.Node(RAFNNodeNum);
1420 7 : if (allocated(roomAFNZoneNode.SurfMask)) {
1421 : // throw error found twice
1422 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: Invalid {} = {}", ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1)));
1423 0 : ShowContinueError(state, format("Entered in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1424 0 : ShowContinueError(state, "Duplicate RoomAir:Node:AirflowNetwork:AdjacentSurfaceList name.");
1425 0 : ErrorsFound = true;
1426 0 : continue;
1427 : }
1428 :
1429 7 : roomAFNZoneNode.SurfMask.allocate(roomAFNZoneInfo.totNumSurfs);
1430 7 : roomAFNZoneNode.SurfMask = false; // init
1431 7 : roomAFNZoneNode.HasSurfacesAssigned = true;
1432 : // relate surfaces to this air node and check to see whether surface names are specified correctly or not
1433 7 : int SurfCount = 0;
1434 7 : int thisSurfinZone = 0;
1435 14 : for (int ListSurfNum = 2; ListSurfNum <= NumAlphas; ++ListSurfNum) {
1436 7 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
1437 7 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
1438 49 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
1439 49 : ++thisSurfinZone;
1440 49 : if (ipsc->cAlphaArgs(ListSurfNum) == state.dataSurface->Surface(SurfNum).Name) {
1441 7 : roomAFNZoneNode.SurfMask(thisSurfinZone) = true;
1442 7 : ++SurfCount;
1443 7 : break;
1444 : }
1445 : }
1446 7 : if (SurfCount > 0) break;
1447 : }
1448 : }
1449 7 : if (NumSurfsThisNode != SurfCount) {
1450 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: Invalid {} = {}", ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1)));
1451 0 : ShowContinueError(state, format("Entered in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1452 0 : ShowContinueError(state, "Some surface names were not found in the zone");
1453 0 : ErrorsFound = true;
1454 : }
1455 : } // for (iZone)
1456 :
1457 7 : if (!foundList) { // throw error
1458 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: Invalid {} = {}", ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1)));
1459 0 : ShowContinueError(state, format("Entered in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1460 0 : ShowContinueError(state, "Did not find a RoomAir:Node:AirflowNetwork object that references this object");
1461 0 : ErrorsFound = true;
1462 : }
1463 : } // loop thru TotNumOfRAFNNodeSurfLists
1464 :
1465 2 : ipsc->cCurrentModuleObject = "RoomAir:Node:AirflowNetwork:InternalGains";
1466 2 : TotNumOfRAFNNodeGainsLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cCurrentModuleObject);
1467 9 : for (int Loop = 1; Loop <= TotNumOfRAFNNodeGainsLists; ++Loop) {
1468 7 : int foundList = false;
1469 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1470 7 : ipsc->cCurrentModuleObject,
1471 : Loop,
1472 7 : ipsc->cAlphaArgs,
1473 : NumAlphas,
1474 7 : ipsc->rNumericArgs,
1475 : NumNumbers,
1476 : status,
1477 : _,
1478 : _,
1479 7 : ipsc->cAlphaFieldNames,
1480 7 : ipsc->cNumericFieldNames);
1481 :
1482 7 : ErrorObjectHeader eoh{routineName, ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)};
1483 :
1484 7 : if (mod((NumAlphas + NumNumbers - 1), 3) != 0) {
1485 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: For {}: {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1486 0 : ShowContinueError(
1487 0 : state, format("Extensible field set are not evenly divisable by 3. Number of data entries = {}", NumAlphas + NumNumbers - 1));
1488 0 : ErrorsFound = true;
1489 0 : break;
1490 : }
1491 :
1492 38 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1493 31 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
1494 : // find surface list
1495 31 : int RAFNNodeNum = 0;
1496 31 : if (roomAFNZoneInfo.NumOfAirNodes > 0) {
1497 7 : RAFNNodeNum = Util::FindItemInList(
1498 7 : ipsc->cAlphaArgs(1), roomAFNZoneInfo.Node, &AFNAirNodeNested::NodeIntGainsListName, roomAFNZoneInfo.NumOfAirNodes);
1499 : }
1500 31 : if (RAFNNodeNum == 0) continue;
1501 :
1502 : // found it
1503 7 : foundList = true;
1504 7 : int numInputGains = (NumAlphas + NumNumbers - 1) / 3;
1505 7 : int numSpacesInZone = state.dataHeatBal->Zone(iZone).numSpaces;
1506 7 : int maxNumGains = numInputGains * numSpacesInZone;
1507 7 : auto &roomAFNZoneNode = roomAFNZoneInfo.Node(RAFNNodeNum);
1508 7 : if (allocated(roomAFNZoneNode.IntGain)) {
1509 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: Invalid {} = {}", ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1)));
1510 0 : ShowContinueError(state, format("Entered in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1511 0 : ShowContinueError(state, format("Duplicate {} name.", ipsc->cCurrentModuleObject));
1512 0 : ErrorsFound = true;
1513 0 : continue;
1514 : }
1515 :
1516 7 : roomAFNZoneNode.IntGain.allocate(maxNumGains);
1517 7 : roomAFNZoneNode.IntGainsDeviceIndices.allocate(maxNumGains);
1518 7 : roomAFNZoneNode.intGainsDeviceSpaces.allocate(maxNumGains);
1519 7 : roomAFNZoneNode.IntGainsFractions.allocate(maxNumGains);
1520 7 : roomAFNZoneNode.HasIntGainsAssigned = true;
1521 7 : int numGainsFound = 0;
1522 28 : for (int gainsLoop = 1; gainsLoop <= numInputGains; ++gainsLoop) {
1523 21 : auto &intGain = roomAFNZoneNode.IntGain(gainsLoop);
1524 21 : intGain.type = static_cast<DataHeatBalance::IntGainType>(
1525 21 : getEnumValue(DataHeatBalance::IntGainTypeNamesUC, Util::makeUPPER(ipsc->cAlphaArgs(gainsLoop * 2))));
1526 :
1527 21 : if (intGain.type == DataHeatBalance::IntGainType::Invalid) {
1528 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(gainsLoop * 2), ipsc->cAlphaArgs(gainsLoop * 2));
1529 0 : ErrorsFound = true;
1530 0 : continue;
1531 : }
1532 21 : intGain.Name = ipsc->cAlphaArgs(gainsLoop * 2 + 1);
1533 :
1534 21 : bool gainFound = false;
1535 : // check all spaces in this zone for matching gains
1536 42 : for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
1537 : // verify type and name and get pointer to device in internal gains structure array
1538 21 : int intGainIndex = GetInternalGainDeviceIndex(state, spaceNum, intGain.type, intGain.Name);
1539 21 : if (intGainIndex >= 0) {
1540 18 : gainFound = true;
1541 18 : ++numGainsFound;
1542 18 : roomAFNZoneNode.intGainsDeviceSpaces(numGainsFound) = spaceNum;
1543 18 : roomAFNZoneNode.IntGainsDeviceIndices(numGainsFound) = intGainIndex;
1544 18 : roomAFNZoneNode.IntGainsFractions(numGainsFound) = ipsc->rNumericArgs(gainsLoop);
1545 : }
1546 : }
1547 21 : if (gainFound) {
1548 18 : roomAFNZoneNode.NumIntGains = numGainsFound;
1549 : } else {
1550 6 : ShowSevereError(state,
1551 6 : format("GetRoomAirflowNetworkData: Invalid {} = {}",
1552 3 : ipsc->cAlphaFieldNames(gainsLoop * 2 + 1),
1553 3 : ipsc->cAlphaArgs(gainsLoop * 2 + 1)));
1554 3 : ShowContinueError(state, format("Entered in {} = {}", ipsc->cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1555 6 : ShowContinueError(state, "Internal gain did not match correctly");
1556 3 : ErrorsFound = true;
1557 : }
1558 : } // for (gainsLoop)
1559 : } // for (iZone)
1560 : } // loop thru TotNumOfRAFNNodeGainsLists
1561 :
1562 : // Get data of HVAC equipment
1563 2 : std::string const cCurrentModuleObject = "RoomAir:Node:AirflowNetwork:HVACEquipment";
1564 2 : TotNumOfRAFNNodeHVACLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1565 8 : for (int Loop = 1; Loop <= TotNumOfRAFNNodeHVACLists; ++Loop) {
1566 18 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1567 : cCurrentModuleObject,
1568 : Loop,
1569 6 : ipsc->cAlphaArgs,
1570 : NumAlphas,
1571 6 : ipsc->rNumericArgs,
1572 : NumNumbers,
1573 : status,
1574 : _,
1575 : _,
1576 6 : ipsc->cAlphaFieldNames,
1577 6 : ipsc->cNumericFieldNames);
1578 :
1579 6 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)};
1580 :
1581 6 : if (mod((NumAlphas + NumNumbers - 1), 4) != 0) {
1582 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: For {}: {}", cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1583 0 : ShowContinueError(state,
1584 0 : format("Extensible field set are not evenly divisable by 4. Number of data entries = {}",
1585 0 : fmt::to_string(NumAlphas + NumNumbers - 1)));
1586 0 : ErrorsFound = true;
1587 0 : break;
1588 : }
1589 :
1590 36 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1591 30 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
1592 : // find surface list
1593 30 : int RAFNNodeNum = 0;
1594 30 : if (roomAFNZoneInfo.NumOfAirNodes > 0) {
1595 6 : RAFNNodeNum = Util::FindItemInList(
1596 6 : ipsc->cAlphaArgs(1), roomAFNZoneInfo.Node, &AFNAirNodeNested::NodeHVACListName, roomAFNZoneInfo.NumOfAirNodes);
1597 : }
1598 :
1599 30 : if (RAFNNodeNum == 0) continue;
1600 :
1601 : // found it
1602 6 : auto &roomAFNNode = roomAFNZoneInfo.Node(RAFNNodeNum);
1603 6 : if (allocated(roomAFNNode.HVAC)) {
1604 0 : ShowSevereError(state, format("GetRoomAirflowNetworkData: Invalid {} = {}", ipsc->cAlphaFieldNames(1), ipsc->cAlphaArgs(1)));
1605 0 : ShowContinueError(state, format("Entered in {} = {}", cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1606 0 : ShowContinueError(state, format("Duplicate {} name.", cCurrentModuleObject));
1607 0 : ErrorsFound = true;
1608 0 : continue;
1609 : }
1610 :
1611 6 : roomAFNNode.NumHVACs = (NumAlphas + NumNumbers - 1) / 4;
1612 6 : roomAFNNode.HVAC.allocate(roomAFNNode.NumHVACs);
1613 6 : roomAFNNode.HasHVACAssigned = true;
1614 12 : for (int iEquip = 1; iEquip <= roomAFNNode.NumHVACs; ++iEquip) {
1615 6 : int iEquipArg = 2 + (iEquip - 1) * 2;
1616 6 : auto &roomAFNNodeHVAC = roomAFNNode.HVAC(iEquip);
1617 6 : roomAFNNodeHVAC.zoneEquipType = static_cast<DataZoneEquipment::ZoneEquipType>(
1618 6 : getEnumValue(DataZoneEquipment::zoneEquipTypeNamesUC, ipsc->cAlphaArgs(iEquipArg)));
1619 6 : if (roomAFNNodeHVAC.zoneEquipType == DataZoneEquipment::ZoneEquipType::Invalid) {
1620 0 : ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(iEquipArg), ipsc->cAlphaArgs(iEquipArg));
1621 0 : ErrorsFound = true;
1622 : }
1623 6 : roomAFNNodeHVAC.Name = ipsc->cAlphaArgs(3 + (iEquip - 1) * 2);
1624 :
1625 : // verify type and name and get pointer to device in HVAC equipment type and name structure array
1626 6 : TotNumEquip = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, ipsc->cAlphaArgs(iEquipArg));
1627 6 : if (TotNumEquip == 0) {
1628 0 : ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(iEquipArg), ipsc->cAlphaArgs(iEquipArg));
1629 0 : ErrorsFound = true;
1630 : }
1631 6 : roomAFNNodeHVAC.SupplyFraction = ipsc->rNumericArgs(iEquipArg);
1632 6 : roomAFNNodeHVAC.ReturnFraction = ipsc->rNumericArgs(iEquipArg);
1633 :
1634 : // get equipment type
1635 6 : for (int thisZoneEquipNum = 1; thisZoneEquipNum <= state.dataZoneEquip->ZoneEquipList(iZone).NumOfEquipTypes;
1636 : ++thisZoneEquipNum) {
1637 12 : if (Util::SameString(state.dataZoneEquip->ZoneEquipList(iZone).EquipName(thisZoneEquipNum), roomAFNNodeHVAC.Name) &&
1638 6 : roomAFNNodeHVAC.zoneEquipType == state.dataZoneEquip->ZoneEquipList(iZone).EquipType(thisZoneEquipNum)) {
1639 6 : break;
1640 : }
1641 : }
1642 12 : IntEquipFound = CheckEquipName(
1643 6 : state, roomAFNNodeHVAC.Name, roomAFNNodeHVAC.SupplyNodeName, roomAFNNodeHVAC.ReturnNodeName, roomAFNNodeHVAC.zoneEquipType);
1644 :
1645 6 : if (!IntEquipFound) {
1646 0 : ShowSevereError(state,
1647 0 : format("GetRoomAirflowNetworkData: Invalid {} = {}",
1648 0 : ipsc->cAlphaFieldNames(3 + (iEquip - 1) * 2),
1649 0 : ipsc->cAlphaArgs(2 + (iEquip - 1) * 2)));
1650 0 : ShowContinueError(state, format("Entered in {} = {}", cCurrentModuleObject, ipsc->cAlphaArgs(1)));
1651 0 : ShowContinueError(state, "Internal gain did not match correctly");
1652 0 : ErrorsFound = true;
1653 : }
1654 : //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1655 : // TYPE RoomAirflowNetworkHVACStruct
1656 : // INTEGER::EquipConfigIndex = 0
1657 : } // for (iEquip)
1658 : } // for (Zone)
1659 : } // loop thru TotNumOfRAFNNodeHVACLists
1660 :
1661 : // do some checks on input data
1662 8 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1663 6 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
1664 6 : if (roomAFNZoneInfo.NumOfAirNodes == 0) continue;
1665 :
1666 : // Check zone volume fraction
1667 2 : Real64 SumFraction = 0.0;
1668 9 : for (int iRoomAFNNode = 1; iRoomAFNNode <= roomAFNZoneInfo.NumOfAirNodes; ++iRoomAFNNode) {
1669 7 : SumFraction += roomAFNZoneInfo.Node(iRoomAFNNode).ZoneVolumeFraction;
1670 : }
1671 2 : if (std::abs(SumFraction - 1.0) > 0.001) {
1672 0 : ShowSevereError(state, "GetRoomAirflowNetworkData: Invalid, zone volume fractions do not sum to 1.0");
1673 0 : ShowContinueError(state, format("Entered in RoomAir:Node:AirflowNetwork with Zone Name = {}", state.dataHeatBal->Zone(iZone).Name));
1674 0 : ShowContinueError(state, "The Fraction of Zone Air Volume values across all the nodes needs to sum to 1.0.");
1675 0 : ShowContinueError(state, format("The sum of fractions entered = {:.3R}", SumFraction));
1676 0 : ErrorsFound = true;
1677 : }
1678 :
1679 : // Check internal gain fraction
1680 9 : for (int iRoomAFNNode = 1; iRoomAFNNode <= roomAFNZoneInfo.NumOfAirNodes; ++iRoomAFNNode) {
1681 7 : auto &roomAFNNode = roomAFNZoneInfo.Node(iRoomAFNNode);
1682 25 : for (int iGain = 1; iGain <= roomAFNNode.NumIntGains; ++iGain) {
1683 18 : auto &intGain = roomAFNNode.IntGain(iGain);
1684 18 : if (intGain.FractionCheck) continue;
1685 3 : SumFraction = roomAFNNode.IntGainsFractions(iGain);
1686 3 : intGain.FractionCheck = true;
1687 :
1688 21 : for (int iRoomAFNNode2 = 1; iRoomAFNNode2 <= roomAFNZoneInfo.NumOfAirNodes; ++iRoomAFNNode2) {
1689 18 : auto &roomAFNNode2 = roomAFNZoneInfo.Node(iRoomAFNNode2);
1690 72 : for (int iGain2 = 1; iGain2 <= roomAFNNode2.NumIntGains; ++iGain2) {
1691 54 : auto &intGain2 = roomAFNNode2.IntGain(iGain2);
1692 54 : if (intGain2.FractionCheck) continue;
1693 33 : if (intGain.type == intGain2.type && Util::SameString(intGain.Name, intGain2.Name)) {
1694 15 : SumFraction += roomAFNNode2.IntGainsFractions(iGain2);
1695 15 : intGain2.FractionCheck = true;
1696 : }
1697 : }
1698 : }
1699 3 : if (std::abs(SumFraction - 1.0) > 0.001) {
1700 0 : ShowSevereError(state, "GetRoomAirflowNetworkData: Invalid, internal gain fractions do not sum to 1.0");
1701 0 : ShowContinueError(state,
1702 0 : format("Entered in RoomAir:Node:AirflowNetwork with Zone Name = {}, Intrnal gain name = {}",
1703 0 : state.dataHeatBal->Zone(iZone).Name,
1704 0 : intGain.Name));
1705 0 : ShowContinueError(state, "The Fraction of internal gain across all the nodes needs to sum to 1.0.");
1706 0 : ShowContinueError(state, format("The sum of fractions entered = {:.3R}", SumFraction));
1707 0 : ErrorsFound = true;
1708 : }
1709 : } // for (iGain)
1710 : } // for (iRoomAFNNode)
1711 : } // for (iZone)
1712 :
1713 2 : if (ErrorsFound) return;
1714 :
1715 6 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1716 5 : auto &roomAFNZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
1717 5 : if (!roomAFNZoneInfo.IsUsed || roomAFNZoneInfo.NumOfAirNodes == 0) continue;
1718 :
1719 7 : for (int iAirNode = 1; iAirNode <= roomAFNZoneInfo.NumOfAirNodes; ++iAirNode) {
1720 6 : auto &roomAFNZoneNode = roomAFNZoneInfo.Node(iAirNode);
1721 12 : SetupOutputVariable(state,
1722 : "RoomAirflowNetwork Node Temperature",
1723 : Constant::Units::C,
1724 6 : roomAFNZoneNode.AirTemp,
1725 : OutputProcessor::TimeStepType::System,
1726 : OutputProcessor::StoreType::Average,
1727 6 : roomAFNZoneNode.Name);
1728 12 : SetupOutputVariable(state,
1729 : "RoomAirflowNetwork Node Humidity Ratio",
1730 : Constant::Units::kgWater_kgDryAir,
1731 6 : roomAFNZoneNode.HumRat,
1732 : OutputProcessor::TimeStepType::System,
1733 : OutputProcessor::StoreType::Average,
1734 6 : roomAFNZoneNode.Name);
1735 12 : SetupOutputVariable(state,
1736 : "RoomAirflowNetwork Node Relative Humidity",
1737 : Constant::Units::Perc,
1738 6 : roomAFNZoneNode.RelHumidity,
1739 : OutputProcessor::TimeStepType::System,
1740 : OutputProcessor::StoreType::Average,
1741 6 : roomAFNZoneNode.Name);
1742 : } // for (iAirNodE)
1743 : } // for (iZone)
1744 2 : }
1745 :
1746 0 : void SharedDVCVUFDataInit(EnergyPlusData &state, int const ZoneNum)
1747 : {
1748 :
1749 : // SUBROUTINE INFORMATION:
1750 : // AUTHOR Linda Lawrie
1751 : // DATE WRITTEN March 2005
1752 : // MODIFIED Aug, 2013, Sam Brunswick -- for RoomAirCrossCrossVent modifications
1753 :
1754 : // PURPOSE OF THIS SUBROUTINE:
1755 : // This routine allocates and initializes(?) the data that is shared between the
1756 : // UCSD models (DV and CV)
1757 :
1758 : // Using/Aliasing
1759 : using namespace DataEnvironment;
1760 : using namespace DataSurfaces;
1761 : using Psychrometrics::PsyRhoAirFnPbTdbW;
1762 :
1763 : // SUBROUTINE PARAMETER DEFINITIONS:
1764 0 : Real64 constexpr BaseDischargeCoef(0.62);
1765 :
1766 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1767 0 : Array1D_int AuxSurf;
1768 0 : Array2D_int AuxAirflowNetworkSurf;
1769 :
1770 : // Do the one time initializations
1771 0 : if (state.dataRoomAir->MyOneTimeFlag) {
1772 :
1773 0 : state.dataRoomAir->MyEnvrnFlag.allocate(state.dataGlobal->NumOfZones);
1774 :
1775 0 : state.dataRoomAir->APos_Wall.allocate(state.dataSurface->TotSurfaces);
1776 0 : state.dataRoomAir->APos_Floor.allocate(state.dataSurface->TotSurfaces);
1777 0 : state.dataRoomAir->APos_Ceiling.allocate(state.dataSurface->TotSurfaces);
1778 0 : state.dataRoomAir->PosZ_Wall.allocate(state.dataGlobal->NumOfZones);
1779 0 : state.dataRoomAir->PosZ_Floor.allocate(state.dataGlobal->NumOfZones);
1780 0 : state.dataRoomAir->PosZ_Ceiling.allocate(state.dataGlobal->NumOfZones);
1781 0 : state.dataRoomAir->APos_Window.allocate(state.dataSurface->TotSurfaces);
1782 0 : state.dataRoomAir->APos_Door.allocate(state.dataSurface->TotSurfaces);
1783 0 : state.dataRoomAir->APos_Internal.allocate(state.dataSurface->TotSurfaces);
1784 0 : state.dataRoomAir->PosZ_Window.allocate(state.dataGlobal->NumOfZones);
1785 0 : state.dataRoomAir->PosZ_Door.allocate(state.dataGlobal->NumOfZones);
1786 0 : state.dataRoomAir->PosZ_Internal.allocate(state.dataGlobal->NumOfZones);
1787 0 : state.dataRoomAir->HCeiling.allocate(state.dataSurface->TotSurfaces);
1788 0 : state.dataRoomAir->HWall.allocate(state.dataSurface->TotSurfaces);
1789 0 : state.dataRoomAir->HFloor.allocate(state.dataSurface->TotSurfaces);
1790 0 : state.dataRoomAir->HInternal.allocate(state.dataSurface->TotSurfaces);
1791 0 : state.dataRoomAir->HWindow.allocate(state.dataSurface->TotSurfaces);
1792 0 : state.dataRoomAir->HDoor.allocate(state.dataSurface->TotSurfaces);
1793 :
1794 0 : AuxSurf.allocate(state.dataGlobal->NumOfZones);
1795 :
1796 0 : state.dataRoomAir->ZoneCeilingHeight1.allocate(state.dataGlobal->NumOfZones);
1797 0 : state.dataRoomAir->ZoneCeilingHeight2.allocate(state.dataGlobal->NumOfZones);
1798 0 : state.dataRoomAir->ZoneCeilingHeight1 = 0.0;
1799 0 : state.dataRoomAir->ZoneCeilingHeight2 = 0.0;
1800 :
1801 : // Arrays initializations
1802 0 : state.dataRoomAir->APos_Wall = 0;
1803 0 : state.dataRoomAir->APos_Floor = 0;
1804 0 : state.dataRoomAir->APos_Ceiling = 0;
1805 0 : std::fill(state.dataRoomAir->PosZ_Wall.begin(), state.dataRoomAir->PosZ_Wall.end(), BegEnd());
1806 0 : std::fill(state.dataRoomAir->PosZ_Floor.begin(), state.dataRoomAir->PosZ_Floor.end(), BegEnd());
1807 0 : std::fill(state.dataRoomAir->PosZ_Ceiling.begin(), state.dataRoomAir->PosZ_Ceiling.end(), BegEnd());
1808 0 : state.dataRoomAir->APos_Window = 0;
1809 0 : state.dataRoomAir->APos_Door = 0;
1810 0 : state.dataRoomAir->APos_Internal = 0;
1811 0 : std::fill(state.dataRoomAir->PosZ_Window.begin(), state.dataRoomAir->PosZ_Window.end(), BegEnd());
1812 0 : std::fill(state.dataRoomAir->PosZ_Door.begin(), state.dataRoomAir->PosZ_Door.end(), BegEnd());
1813 0 : std::fill(state.dataRoomAir->PosZ_Internal.begin(), state.dataRoomAir->PosZ_Internal.end(), BegEnd());
1814 0 : state.dataRoomAir->HCeiling = 0.0;
1815 0 : state.dataRoomAir->HWall = 0.0;
1816 0 : state.dataRoomAir->HFloor = 0.0;
1817 0 : state.dataRoomAir->HInternal = 0.0;
1818 0 : state.dataRoomAir->HWindow = 0.0;
1819 0 : state.dataRoomAir->HDoor = 0.0;
1820 :
1821 0 : int contWall = 0, contFloor = 0, contCeiling = 0, contWindow = 0, contInternal = 0, contDoor = 0;
1822 :
1823 : // Put the surface and zone information in Apos and PosZ arrays
1824 0 : for (int ZNum = 1; ZNum <= state.dataGlobal->NumOfZones; ++ZNum) {
1825 : // advance ONE position in the arrays PosZ because this is a new zone
1826 0 : int contWallBeg = contWall + 1;
1827 0 : int contFloorBeg = contFloor + 1;
1828 0 : int contCeilingBeg = contCeiling + 1;
1829 0 : int contWindowBeg = contWindow + 1;
1830 0 : int contInternalBeg = contInternal + 1;
1831 0 : int contDoorBeg = contDoor + 1;
1832 :
1833 0 : Real64 Z1ofZone = std::numeric_limits<Real64>::max();
1834 0 : Real64 Z2ofZone = std::numeric_limits<Real64>::lowest();
1835 :
1836 : // cycle in this zone for all the surfaces
1837 0 : for (int spaceNum : state.dataHeatBal->Zone(ZNum).spaceIndexes) {
1838 0 : auto const &thisSpace = state.dataHeatBal->space(spaceNum);
1839 :
1840 0 : for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
1841 0 : auto const &surf = state.dataSurface->Surface(SurfNum);
1842 0 : if (surf.Class != DataSurfaces::SurfaceClass::IntMass) {
1843 : // Recalculate lowest and highest height for the zone
1844 0 : for (int i = 1, u = surf.Sides; i <= u; ++i) {
1845 0 : Real64 const z_i = surf.Vertex(i).z;
1846 0 : if (z_i < Z1ofZone) {
1847 0 : Z1ofZone = z_i;
1848 : };
1849 0 : if (z_i > Z2ofZone) {
1850 0 : Z2ofZone = z_i;
1851 : };
1852 : }
1853 : }
1854 :
1855 : // Put the reference to this surface in the appropriate array
1856 0 : if (surf.Class == SurfaceClass::Floor) {
1857 0 : ++contFloor;
1858 0 : state.dataRoomAir->APos_Floor(contFloor) = SurfNum;
1859 0 : } else if (surf.Class == SurfaceClass::Wall) {
1860 0 : ++contWall;
1861 0 : state.dataRoomAir->APos_Wall(contWall) = SurfNum;
1862 0 : } else if (surf.Class == SurfaceClass::Window) {
1863 0 : ++contWindow;
1864 0 : state.dataRoomAir->APos_Window(contWindow) = SurfNum;
1865 0 : } else if (surf.Class == SurfaceClass::IntMass) {
1866 0 : ++contInternal;
1867 0 : state.dataRoomAir->APos_Internal(contInternal) = SurfNum;
1868 0 : } else if (surf.Class == SurfaceClass::Door) {
1869 0 : ++contDoor;
1870 0 : state.dataRoomAir->APos_Door(contDoor) = SurfNum;
1871 : } else {
1872 0 : ++contCeiling;
1873 0 : state.dataRoomAir->APos_Ceiling(contCeiling) = SurfNum;
1874 : }
1875 : }
1876 : } // for (SurfNum)
1877 :
1878 0 : int contWallLast = contWall;
1879 0 : int contFloorLast = contFloor;
1880 0 : int contCeilingLast = contCeiling;
1881 0 : int contWindowLast = contWindow;
1882 0 : int contDoorLast = contDoor;
1883 0 : int contInternalLast = contInternal;
1884 : // PosZ_Wall (... + 1) has the Begin Wall reference in Apos_Wall for the ZNum
1885 : // PosZ_Wall (... + 2) has the End Wall reference in Apos_Wall for the ZNum
1886 0 : state.dataRoomAir->PosZ_Wall(ZNum).beg = contWallBeg;
1887 0 : state.dataRoomAir->PosZ_Wall(ZNum).end = contWallLast;
1888 0 : state.dataRoomAir->PosZ_Floor(ZNum).beg = contFloorBeg;
1889 0 : state.dataRoomAir->PosZ_Floor(ZNum).end = contFloorLast;
1890 0 : state.dataRoomAir->PosZ_Ceiling(ZNum).beg = contCeilingBeg;
1891 0 : state.dataRoomAir->PosZ_Ceiling(ZNum).end = contCeilingLast;
1892 0 : state.dataRoomAir->PosZ_Window(ZNum).beg = contWindowBeg;
1893 0 : state.dataRoomAir->PosZ_Window(ZNum).end = contWindowLast;
1894 0 : state.dataRoomAir->PosZ_Door(ZNum).beg = contDoorBeg;
1895 0 : state.dataRoomAir->PosZ_Door(ZNum).end = contDoorLast;
1896 0 : state.dataRoomAir->PosZ_Internal(ZNum).beg = contInternalBeg;
1897 0 : state.dataRoomAir->PosZ_Internal(ZNum).end = contInternalLast;
1898 : // Save the highest and lowest height for this zone
1899 0 : state.dataRoomAir->ZoneCeilingHeight1(ZNum) = Z1ofZone;
1900 0 : state.dataRoomAir->ZoneCeilingHeight2(ZNum) = Z2ofZone;
1901 :
1902 0 : constexpr Real64 CeilingHeightDiffMaximum = 0.1;
1903 0 : if (std::abs((Z2ofZone - Z1ofZone) - state.dataHeatBal->Zone(ZNum).CeilingHeight) > CeilingHeightDiffMaximum) {
1904 0 : ShowWarningError(state, format("RoomAirManager: Inconsistent ceiling heights in Zone: {}", state.dataHeatBal->Zone(ZNum).Name));
1905 0 : ShowContinueError(state, format("Lowest height=[{:.3R}].", Z1ofZone));
1906 0 : ShowContinueError(state, format("Highest height=[{:.3R}].", Z2ofZone));
1907 0 : ShowContinueError(state, format("Ceiling height=[{:.3R}].", state.dataHeatBal->Zone(ZNum).CeilingHeight));
1908 : }
1909 : } // for (ZoneNum)
1910 :
1911 0 : AuxSurf = 0;
1912 0 : state.dataRoomAir->CrossVentNumAFNSurfaces = 0;
1913 :
1914 : // calculate maximum number of airflow network surfaces in each zone
1915 0 : for (int iMzLink = 1; iMzLink <= state.afn->NumOfLinksMultiZone; ++iMzLink) {
1916 0 : auto const &mzSurf = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(iMzLink).SurfNum);
1917 0 : ++AuxSurf(mzSurf.Zone);
1918 0 : ++state.dataRoomAir->CrossVentNumAFNSurfaces;
1919 : // Check if this is an interzone airflow network surface
1920 0 : if (mzSurf.ExtBoundCond > 0 && (state.afn->MultizoneSurfaceData(iMzLink).SurfNum != mzSurf.ExtBoundCond)) {
1921 0 : ++AuxSurf(state.dataSurface->Surface(mzSurf.ExtBoundCond).Zone);
1922 0 : ++state.dataRoomAir->CrossVentNumAFNSurfaces;
1923 : }
1924 : }
1925 : // calculate maximum number of airflow network surfaces in a single zone
1926 0 : int MaxSurf = AuxSurf(1);
1927 0 : for (int iZone = 2; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1928 0 : if (AuxSurf(iZone) > MaxSurf) MaxSurf = AuxSurf(iZone);
1929 : }
1930 :
1931 0 : if (!allocated(state.dataRoomAir->AFNSurfaceCrossVent)) {
1932 0 : state.dataRoomAir->AFNSurfaceCrossVent.allocate({0, MaxSurf}, state.dataGlobal->NumOfZones);
1933 : }
1934 0 : if (!allocated(state.dataRoomAir->CrossVentJetRecFlows)) {
1935 0 : state.dataRoomAir->CrossVentJetRecFlows.allocate({0, MaxSurf}, state.dataGlobal->NumOfZones);
1936 : }
1937 0 : AuxAirflowNetworkSurf.allocate({0, MaxSurf}, state.dataGlobal->NumOfZones);
1938 : // Width and Height for airflow network surfaces
1939 0 : if (!allocated(state.dataRoomAir->SurfParametersCrossDispVent)) {
1940 0 : state.dataRoomAir->SurfParametersCrossDispVent.allocate(state.afn->NumOfLinksMultiZone);
1941 : }
1942 :
1943 0 : state.dataRoomAir->AFNSurfaceCrossVent = 0;
1944 : // Organize surfaces in vector AirflowNetworkSurfaceUCSDCV(Zone, surface indexes)
1945 0 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
1946 : // the 0 component of the array has the number of relevant AirflowNetwork surfaces for the zone
1947 0 : state.dataRoomAir->AFNSurfaceCrossVent(0, iZone) = AuxSurf(iZone);
1948 0 : if (AuxSurf(iZone) == 0) continue;
1949 :
1950 0 : Real64 const ceilingHeight = state.dataRoomAir->ZoneCeilingHeight1(iZone);
1951 0 : int SurfNum = 1;
1952 :
1953 0 : for (int iMzLink = 1; iMzLink <= state.afn->NumOfLinksMultiZone; ++iMzLink) {
1954 0 : auto const &mzSurf = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(iMzLink).SurfNum);
1955 0 : auto &surfParams = state.dataRoomAir->SurfParametersCrossDispVent(iMzLink);
1956 :
1957 0 : if (mzSurf.Zone == iZone) {
1958 : // SurfNum has the reference surface number relative to AirflowNetworkSurfaceData
1959 0 : state.dataRoomAir->AFNSurfaceCrossVent(SurfNum, iZone) = iMzLink;
1960 : // calculate the surface width and height
1961 0 : int compNum = state.afn->AirflowNetworkLinkageData(iMzLink).CompNum;
1962 0 : int typeNum = state.afn->AirflowNetworkCompData(compNum).TypeNum;
1963 0 : if (state.afn->AirflowNetworkCompData(compNum).CompTypeNum == AirflowNetwork::iComponentTypeNum::DOP) {
1964 0 : Real64 WidthFactMax = 0.0;
1965 0 : Real64 HeightFactMax = 0.0;
1966 :
1967 0 : Real64 WidthFact = 0.0;
1968 0 : Real64 HeightFact = 0.0;
1969 0 : auto const &mzCompDetOpening = state.afn->MultizoneCompDetOpeningData(typeNum);
1970 0 : for (int Loop3 = 1; Loop3 <= mzCompDetOpening.NumFac; ++Loop3) {
1971 0 : if (Loop3 == 1) {
1972 0 : WidthFact = mzCompDetOpening.WidthFac1;
1973 0 : HeightFact = mzCompDetOpening.HeightFac1;
1974 0 : } else if (Loop3 == 2) {
1975 0 : WidthFact = mzCompDetOpening.WidthFac2;
1976 0 : HeightFact = mzCompDetOpening.HeightFac2;
1977 0 : } else if (Loop3 == 3) {
1978 0 : WidthFact = mzCompDetOpening.WidthFac3;
1979 0 : HeightFact = mzCompDetOpening.HeightFac3;
1980 0 : } else if (Loop3 == 4) {
1981 0 : WidthFact = mzCompDetOpening.WidthFac4;
1982 0 : HeightFact = mzCompDetOpening.HeightFac4;
1983 : }
1984 0 : if (WidthFact > WidthFactMax) {
1985 0 : WidthFactMax = WidthFact;
1986 : }
1987 0 : if (HeightFact > HeightFactMax) {
1988 0 : HeightFactMax = HeightFact;
1989 : }
1990 : }
1991 0 : surfParams.Width = WidthFactMax * mzSurf.Width;
1992 0 : surfParams.Height = HeightFactMax * mzSurf.Height;
1993 :
1994 0 : } else if (state.afn->AirflowNetworkCompData(compNum).CompTypeNum ==
1995 : AirflowNetwork::iComponentTypeNum::SCR) { // surface type = CRACK
1996 0 : surfParams.Width = mzSurf.Width / 2;
1997 0 : auto const &zoneHeatBal = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone);
1998 : Real64 AinCV =
1999 0 : state.afn->MultizoneSurfaceCrackData(typeNum).coefficient /
2000 0 : (BaseDischargeCoef *
2001 0 : std::sqrt(2.0 / PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, zoneHeatBal.MAT, zoneHeatBal.airHumRat)));
2002 0 : surfParams.Height = AinCV / surfParams.Width;
2003 : }
2004 :
2005 : // calculate the surface Zmin and Zmax
2006 0 : if (state.afn->AirflowNetworkCompData(compNum).CompTypeNum == AirflowNetwork::iComponentTypeNum::DOP ||
2007 0 : state.afn->AirflowNetworkCompData(compNum).CompTypeNum ==
2008 : AirflowNetwork::iComponentTypeNum::SCR) { // surface type = CRACK
2009 0 : Real64 z_min(std::numeric_limits<Real64>::max()), z_max(std::numeric_limits<Real64>::lowest());
2010 0 : for (int i = 1; i <= mzSurf.Sides; ++i) {
2011 0 : Real64 const z_i = mzSurf.Vertex(i).z;
2012 0 : z_min = std::min(z_min, z_i);
2013 0 : z_max = std::max(z_max, z_i);
2014 : }
2015 0 : surfParams.Zmin = z_min - ceilingHeight;
2016 0 : surfParams.Zmax = z_max - ceilingHeight;
2017 : }
2018 :
2019 0 : ++SurfNum;
2020 : // Check if airflow network Surface is an interzone surface:
2021 :
2022 : } else { // if (mzSurf.Zone == iZone)
2023 0 : int nodeNum1 = state.afn->MultizoneSurfaceData(iMzLink).NodeNums[0];
2024 0 : int nodeNum2 = state.afn->MultizoneSurfaceData(iMzLink).NodeNums[1];
2025 0 : if ((state.afn->AirflowNetworkNodeData(nodeNum2).EPlusZoneNum == iZone &&
2026 0 : state.afn->AirflowNetworkNodeData(nodeNum1).EPlusZoneNum > 0) ||
2027 0 : (state.afn->AirflowNetworkNodeData(nodeNum2).EPlusZoneNum > 0 &&
2028 0 : state.afn->AirflowNetworkNodeData(nodeNum1).EPlusZoneNum == iZone)) {
2029 0 : state.dataRoomAir->AFNSurfaceCrossVent(SurfNum, iZone) = iMzLink;
2030 0 : ++SurfNum;
2031 : }
2032 : }
2033 : } // for (Loop2)
2034 : } // for (iZone)
2035 :
2036 0 : AuxSurf.deallocate();
2037 :
2038 0 : if (any(state.dataRoomAir->IsZoneDispVent3Node) || any(state.dataRoomAir->IsZoneUFAD)) {
2039 0 : state.dataRoomAir->MaxTempGrad.allocate(state.dataGlobal->NumOfZones);
2040 0 : state.dataRoomAir->AvgTempGrad.allocate(state.dataGlobal->NumOfZones);
2041 0 : state.dataRoomAir->TCMF.allocate(state.dataGlobal->NumOfZones);
2042 0 : state.dataRoomAir->FracMinFlow.allocate(state.dataGlobal->NumOfZones);
2043 0 : state.dataRoomAir->ZoneAirSystemON.allocate(state.dataGlobal->NumOfZones);
2044 : // Allocate histories of displacement ventilation temperatures PH 3/5/04
2045 0 : state.dataRoomAir->MATFloor.allocate(state.dataGlobal->NumOfZones);
2046 0 : state.dataRoomAir->XMATFloor.allocate(state.dataGlobal->NumOfZones);
2047 0 : state.dataRoomAir->DSXMATFloor.allocate(state.dataGlobal->NumOfZones);
2048 0 : state.dataRoomAir->MATOC.allocate(state.dataGlobal->NumOfZones);
2049 0 : state.dataRoomAir->XMATOC.allocate(state.dataGlobal->NumOfZones);
2050 0 : state.dataRoomAir->DSXMATOC.allocate(state.dataGlobal->NumOfZones);
2051 0 : state.dataRoomAir->MATMX.allocate(state.dataGlobal->NumOfZones);
2052 0 : state.dataRoomAir->XMATMX.allocate(state.dataGlobal->NumOfZones);
2053 0 : state.dataRoomAir->DSXMATMX.allocate(state.dataGlobal->NumOfZones);
2054 0 : state.dataRoomAir->ZTMFloor.allocate(state.dataGlobal->NumOfZones);
2055 0 : state.dataRoomAir->ZTMOC.allocate(state.dataGlobal->NumOfZones);
2056 0 : state.dataRoomAir->ZTMMX.allocate(state.dataGlobal->NumOfZones);
2057 0 : state.dataRoomAir->AIRRATFloor.allocate(state.dataGlobal->NumOfZones);
2058 0 : state.dataRoomAir->AIRRATOC.allocate(state.dataGlobal->NumOfZones);
2059 0 : state.dataRoomAir->AIRRATMX.allocate(state.dataGlobal->NumOfZones);
2060 0 : state.dataRoomAir->ZTOC.allocate(state.dataGlobal->NumOfZones);
2061 0 : state.dataRoomAir->ZTMX.allocate(state.dataGlobal->NumOfZones);
2062 0 : state.dataRoomAir->ZTFloor.allocate(state.dataGlobal->NumOfZones);
2063 0 : state.dataRoomAir->HeightTransition.allocate(state.dataGlobal->NumOfZones);
2064 0 : state.dataRoomAir->Phi.allocate(state.dataGlobal->NumOfZones);
2065 0 : state.dataRoomAir->Zone1Floor.allocate(state.dataGlobal->NumOfZones);
2066 0 : state.dataRoomAir->ZoneMXFloor.allocate(state.dataGlobal->NumOfZones);
2067 0 : state.dataRoomAir->ZoneM2Floor.allocate(state.dataGlobal->NumOfZones);
2068 0 : state.dataRoomAir->Zone1OC.allocate(state.dataGlobal->NumOfZones);
2069 0 : state.dataRoomAir->ZoneMXOC.allocate(state.dataGlobal->NumOfZones);
2070 0 : state.dataRoomAir->ZoneM2OC.allocate(state.dataGlobal->NumOfZones);
2071 0 : state.dataRoomAir->Zone1MX.allocate(state.dataGlobal->NumOfZones);
2072 0 : state.dataRoomAir->ZoneMXMX.allocate(state.dataGlobal->NumOfZones);
2073 0 : state.dataRoomAir->ZoneM2MX.allocate(state.dataGlobal->NumOfZones);
2074 :
2075 0 : state.dataRoomAir->MaxTempGrad = 0.0;
2076 0 : state.dataRoomAir->AvgTempGrad = 0.0;
2077 0 : state.dataRoomAir->TCMF = 23.0;
2078 0 : state.dataRoomAir->FracMinFlow = 0.0;
2079 : // ZoneDVMixedFlagRep = 0.0
2080 0 : state.dataRoomAir->ZoneAirSystemON = false;
2081 : // ZoneDVMixedFlag=0
2082 0 : state.dataRoomAir->MATFloor = 23.0;
2083 0 : state.dataRoomAir->XMATFloor = {23.0, 23.0, 23.0, 23.0};
2084 0 : state.dataRoomAir->DSXMATFloor = {23.0, 23.0, 23.0, 23.0};
2085 0 : state.dataRoomAir->MATOC = 23.0;
2086 0 : state.dataRoomAir->XMATOC = {23.0, 23.0, 23.0, 23.0};
2087 0 : state.dataRoomAir->DSXMATOC = {23.0, 23.0, 23.0, 23.0};
2088 0 : state.dataRoomAir->MATMX = 23.0;
2089 0 : state.dataRoomAir->XMATMX = {23.0, 23.0, 23.0, 23.0};
2090 0 : state.dataRoomAir->DSXMATMX = {23.0, 23.0, 23.0, 23.0};
2091 0 : state.dataRoomAir->ZTMFloor = {23.0, 23.0, 23.0};
2092 0 : state.dataRoomAir->ZTMOC = {23.0, 23.0, 23.0};
2093 0 : state.dataRoomAir->ZTMMX = {23.0, 23.0, 23.0};
2094 0 : state.dataRoomAir->Zone1Floor = 23.0;
2095 0 : state.dataRoomAir->ZoneMXFloor = 23.0;
2096 0 : state.dataRoomAir->ZoneM2Floor = 23.0;
2097 0 : state.dataRoomAir->Zone1OC = 23.0;
2098 0 : state.dataRoomAir->ZoneMXOC = 23.0;
2099 0 : state.dataRoomAir->ZoneM2OC = 23.0;
2100 0 : state.dataRoomAir->Zone1MX = 23.0;
2101 0 : state.dataRoomAir->ZoneMXMX = 23.0;
2102 0 : state.dataRoomAir->ZoneM2MX = 23.0;
2103 0 : state.dataRoomAir->AIRRATFloor = 0.0;
2104 0 : state.dataRoomAir->AIRRATOC = 0.0;
2105 0 : state.dataRoomAir->AIRRATMX = 0.0;
2106 0 : state.dataRoomAir->ZTOC = 23.0;
2107 0 : state.dataRoomAir->ZTMX = 23.0;
2108 0 : state.dataRoomAir->ZTFloor = 23.0;
2109 0 : state.dataRoomAir->HeightTransition = 0.0;
2110 0 : state.dataRoomAir->Phi = 0.0;
2111 0 : state.dataRoomAir->HCeiling = 0.0;
2112 0 : state.dataRoomAir->HWall = 0.0;
2113 0 : state.dataRoomAir->HFloor = 0.0;
2114 0 : state.dataRoomAir->HInternal = 0.0;
2115 0 : state.dataRoomAir->HWindow = 0.0;
2116 0 : state.dataRoomAir->HDoor = 0.0;
2117 : }
2118 :
2119 0 : if (any(state.dataRoomAir->IsZoneDispVent3Node)) {
2120 :
2121 0 : state.dataRoomAir->DispVent3NodeHcIn.allocate(state.dataSurface->TotSurfaces);
2122 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlagRep.allocate(state.dataGlobal->NumOfZones);
2123 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlag.allocate(state.dataGlobal->NumOfZones);
2124 0 : state.dataRoomAir->DispVent3NodeHcIn = 0.0;
2125 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlagRep = 0.0;
2126 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlag = 0;
2127 : // Output variables and DV zone flag
2128 0 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
2129 0 : if (state.dataRoomAir->AirModel(iZone).AirModel != RoomAirModel::DispVent3Node)
2130 0 : continue; // don't set these up if they don't make sense
2131 : // CurrentModuleObject='RoomAirSettings:ThreeNodeDisplacementVentilation'
2132 0 : SetupOutputVariable(state,
2133 : "Room Air Zone Mixed Subzone Temperature",
2134 : Constant::Units::C,
2135 0 : state.dataRoomAir->ZTMX(iZone),
2136 : OutputProcessor::TimeStepType::System,
2137 : OutputProcessor::StoreType::Average,
2138 0 : state.dataHeatBal->Zone(iZone).Name);
2139 0 : SetupOutputVariable(state,
2140 : "Room Air Zone Occupied Subzone Temperature",
2141 : Constant::Units::C,
2142 0 : state.dataRoomAir->ZTOC(iZone),
2143 : OutputProcessor::TimeStepType::System,
2144 : OutputProcessor::StoreType::Average,
2145 0 : state.dataHeatBal->Zone(iZone).Name);
2146 0 : SetupOutputVariable(state,
2147 : "Room Air Zone Floor Subzone Temperature",
2148 : Constant::Units::C,
2149 0 : state.dataRoomAir->ZTFloor(iZone),
2150 : OutputProcessor::TimeStepType::System,
2151 : OutputProcessor::StoreType::Average,
2152 0 : state.dataHeatBal->Zone(iZone).Name);
2153 0 : SetupOutputVariable(state,
2154 : "Room Air Zone Transition Height",
2155 : Constant::Units::m,
2156 0 : state.dataRoomAir->HeightTransition(iZone),
2157 : OutputProcessor::TimeStepType::System,
2158 : OutputProcessor::StoreType::Average,
2159 0 : state.dataHeatBal->Zone(iZone).Name);
2160 0 : SetupOutputVariable(state,
2161 : "Room Air Zone Recommended Minimum Flow Fraction",
2162 : Constant::Units::None,
2163 0 : state.dataRoomAir->FracMinFlow(iZone),
2164 : OutputProcessor::TimeStepType::System,
2165 : OutputProcessor::StoreType::Average,
2166 0 : state.dataHeatBal->Zone(iZone).Name);
2167 0 : SetupOutputVariable(state,
2168 : "Room Air Zone Is Mixed Status",
2169 : Constant::Units::None,
2170 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlagRep(iZone),
2171 : OutputProcessor::TimeStepType::System,
2172 : OutputProcessor::StoreType::Average,
2173 0 : state.dataHeatBal->Zone(iZone).Name);
2174 0 : SetupOutputVariable(state,
2175 : "Room Air Zone Average Temperature Gradient",
2176 : Constant::Units::K_m,
2177 0 : state.dataRoomAir->AvgTempGrad(iZone),
2178 : OutputProcessor::TimeStepType::System,
2179 : OutputProcessor::StoreType::Average,
2180 0 : state.dataHeatBal->Zone(iZone).Name);
2181 0 : SetupOutputVariable(state,
2182 : "Room Air Zone Maximum Temperature Gradient",
2183 : Constant::Units::K_m,
2184 0 : state.dataRoomAir->MaxTempGrad(iZone),
2185 : OutputProcessor::TimeStepType::System,
2186 : OutputProcessor::StoreType::Average,
2187 0 : state.dataHeatBal->Zone(iZone).Name);
2188 0 : SetupOutputVariable(state,
2189 : "Room Air Zone Thermal Comfort Effective Air Temperature",
2190 : Constant::Units::C,
2191 0 : state.dataRoomAir->TCMF(iZone),
2192 : OutputProcessor::TimeStepType::System,
2193 : OutputProcessor::StoreType::Average,
2194 0 : state.dataHeatBal->Zone(iZone).Name);
2195 0 : SetupOutputVariable(state,
2196 : "Room Air Zone Thermostat Temperature",
2197 : Constant::Units::C,
2198 0 : state.dataHeatBalFanSys->TempTstatAir(iZone),
2199 : OutputProcessor::TimeStepType::System,
2200 : OutputProcessor::StoreType::Average,
2201 0 : state.dataHeatBal->Zone(iZone).Name);
2202 : } // for (iZone)
2203 : } // if (any(IsZoneDV))
2204 :
2205 0 : if (any(state.dataRoomAir->IsZoneUFAD)) {
2206 0 : state.dataRoomAir->ZoneUFADMixedFlag.allocate(state.dataGlobal->NumOfZones);
2207 0 : state.dataRoomAir->ZoneUFADMixedFlagRep.allocate(state.dataGlobal->NumOfZones);
2208 0 : state.dataRoomAir->UFADHcIn.allocate(state.dataSurface->TotSurfaces);
2209 0 : state.dataRoomAir->ZoneUFADGamma.allocate(state.dataGlobal->NumOfZones);
2210 0 : state.dataRoomAir->ZoneUFADPowInPlumes.allocate(state.dataGlobal->NumOfZones);
2211 0 : state.dataRoomAir->ZoneUFADPowInPlumesfromWindows.allocate(state.dataGlobal->NumOfZones);
2212 0 : state.dataRoomAir->ZoneUFADMixedFlag = 0;
2213 0 : state.dataRoomAir->ZoneUFADMixedFlagRep = 0.0;
2214 0 : state.dataRoomAir->UFADHcIn = 0.0;
2215 0 : state.dataRoomAir->ZoneUFADGamma = 0.0;
2216 0 : state.dataRoomAir->ZoneUFADPowInPlumes = 0.0;
2217 0 : state.dataRoomAir->ZoneUFADPowInPlumesfromWindows = 0.0;
2218 :
2219 : // Output variables and UF zone flag
2220 0 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
2221 0 : if (state.dataRoomAir->AirModel(iZone).AirModel != RoomAirModel::UFADInt) continue; // don't set these up if they don't make sense
2222 :
2223 0 : auto &zone = state.dataHeatBal->Zone(iZone);
2224 : // CurrentModuleObject='RoomAirSettings:UnderFloorAirDistributionInterior'
2225 0 : SetupOutputVariable(state,
2226 : "Room Air Zone Mixed Subzone Temperature",
2227 : Constant::Units::C,
2228 0 : state.dataRoomAir->ZTMX(iZone),
2229 : OutputProcessor::TimeStepType::System,
2230 : OutputProcessor::StoreType::Average,
2231 0 : zone.Name);
2232 0 : SetupOutputVariable(state,
2233 : "Room Air Zone Occupied Subzone Temperature",
2234 : Constant::Units::C,
2235 0 : state.dataRoomAir->ZTOC(iZone),
2236 : OutputProcessor::TimeStepType::System,
2237 : OutputProcessor::StoreType::Average,
2238 0 : zone.Name);
2239 0 : SetupOutputVariable(state,
2240 : "Room Air Zone Transition Height",
2241 : Constant::Units::m,
2242 0 : state.dataRoomAir->HeightTransition(iZone),
2243 : OutputProcessor::TimeStepType::System,
2244 : OutputProcessor::StoreType::Average,
2245 0 : zone.Name);
2246 0 : SetupOutputVariable(state,
2247 : "Room Air Zone Is Mixed Status",
2248 : Constant::Units::None,
2249 0 : state.dataRoomAir->ZoneUFADMixedFlagRep(iZone),
2250 : OutputProcessor::TimeStepType::System,
2251 : OutputProcessor::StoreType::Average,
2252 0 : zone.Name);
2253 0 : SetupOutputVariable(state,
2254 : "Room Air Zone Average Temperature Gradient",
2255 : Constant::Units::K_m,
2256 0 : state.dataRoomAir->AvgTempGrad(iZone),
2257 : OutputProcessor::TimeStepType::System,
2258 : OutputProcessor::StoreType::Average,
2259 0 : zone.Name);
2260 0 : SetupOutputVariable(state,
2261 : "Room Air Zone Effective Comfort Air Temperature",
2262 : Constant::Units::C,
2263 0 : state.dataRoomAir->TCMF(iZone),
2264 : OutputProcessor::TimeStepType::System,
2265 : OutputProcessor::StoreType::Average,
2266 0 : zone.Name);
2267 0 : SetupOutputVariable(state,
2268 : "Room Air Zone Thermostat Temperature",
2269 : Constant::Units::C,
2270 0 : state.dataHeatBalFanSys->TempTstatAir(iZone),
2271 : OutputProcessor::TimeStepType::System,
2272 : OutputProcessor::StoreType::Average,
2273 0 : zone.Name);
2274 0 : SetupOutputVariable(state,
2275 : "Room Air Zone Transition Height Gamma Value",
2276 : Constant::Units::None,
2277 0 : state.dataRoomAir->ZoneUFADGamma(iZone),
2278 : OutputProcessor::TimeStepType::System,
2279 : OutputProcessor::StoreType::Average,
2280 0 : zone.Name);
2281 0 : SetupOutputVariable(state,
2282 : "Room Air Zone Plume Heat Transfer Rate",
2283 : Constant::Units::W,
2284 0 : state.dataRoomAir->ZoneUFADPowInPlumes(iZone),
2285 : OutputProcessor::TimeStepType::System,
2286 : OutputProcessor::StoreType::Average,
2287 0 : zone.Name);
2288 0 : SetupOutputVariable(state,
2289 : "Room Air Zone Temperature Stratification Fraction",
2290 : Constant::Units::None,
2291 0 : state.dataRoomAir->Phi(iZone),
2292 : OutputProcessor::TimeStepType::System,
2293 : OutputProcessor::StoreType::Average,
2294 0 : zone.Name);
2295 :
2296 : // set zone equip pointer in the UCSDUI data structure
2297 0 : state.dataRoomAir->ZoneUFAD(state.dataRoomAir->ZoneUFADPtr(iZone)).ZoneEquipPtr = iZone;
2298 : } // for (iZone)
2299 :
2300 0 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
2301 0 : if (state.dataRoomAir->AirModel(iZone).AirModel != RoomAirModel::UFADExt) continue; // don't set these up if they don't make sense
2302 : // CurrentModuleObject='RoomAirSettings:UnderFloorAirDistributionExterior'
2303 0 : auto const &zone = state.dataHeatBal->Zone(iZone);
2304 0 : SetupOutputVariable(state,
2305 : "Room Air Zone Mixed Subzone Temperature",
2306 : Constant::Units::C,
2307 0 : state.dataRoomAir->ZTMX(iZone),
2308 : OutputProcessor::TimeStepType::System,
2309 : OutputProcessor::StoreType::Average,
2310 0 : zone.Name);
2311 0 : SetupOutputVariable(state,
2312 : "Room Air Zone Occupied Subzone Temperature",
2313 : Constant::Units::C,
2314 0 : state.dataRoomAir->ZTOC(iZone),
2315 : OutputProcessor::TimeStepType::System,
2316 : OutputProcessor::StoreType::Average,
2317 0 : zone.Name);
2318 0 : SetupOutputVariable(state,
2319 : "Room Air Zone Transition Height",
2320 : Constant::Units::m,
2321 0 : state.dataRoomAir->HeightTransition(iZone),
2322 : OutputProcessor::TimeStepType::System,
2323 : OutputProcessor::StoreType::Average,
2324 0 : zone.Name);
2325 0 : SetupOutputVariable(state,
2326 : "Room Air Zone Is Mixed Status",
2327 : Constant::Units::None,
2328 0 : state.dataRoomAir->ZoneUFADMixedFlagRep(iZone),
2329 : OutputProcessor::TimeStepType::System,
2330 : OutputProcessor::StoreType::Average,
2331 0 : zone.Name);
2332 0 : SetupOutputVariable(state,
2333 : "Room Air Zone Average Temperature Gradient",
2334 : Constant::Units::K_m,
2335 0 : state.dataRoomAir->AvgTempGrad(iZone),
2336 : OutputProcessor::TimeStepType::System,
2337 : OutputProcessor::StoreType::Average,
2338 0 : zone.Name);
2339 0 : SetupOutputVariable(state,
2340 : "Room Air Zone Effective Comfort Air Temperature",
2341 : Constant::Units::C,
2342 0 : state.dataRoomAir->TCMF(iZone),
2343 : OutputProcessor::TimeStepType::System,
2344 : OutputProcessor::StoreType::Average,
2345 0 : zone.Name);
2346 0 : SetupOutputVariable(state,
2347 : "Room Air Zone Thermostat Temperature",
2348 : Constant::Units::C,
2349 0 : state.dataHeatBalFanSys->TempTstatAir(iZone),
2350 : OutputProcessor::TimeStepType::System,
2351 : OutputProcessor::StoreType::Average,
2352 0 : zone.Name);
2353 0 : SetupOutputVariable(state,
2354 : "Room Air Zone Transition Height Gamma Value",
2355 : Constant::Units::None,
2356 0 : state.dataRoomAir->ZoneUFADGamma(iZone),
2357 : OutputProcessor::TimeStepType::System,
2358 : OutputProcessor::StoreType::Average,
2359 0 : zone.Name);
2360 0 : SetupOutputVariable(state,
2361 : "Room Air Zone Plume Heat Transfer Rate",
2362 : Constant::Units::W,
2363 0 : state.dataRoomAir->ZoneUFADPowInPlumes(iZone),
2364 : OutputProcessor::TimeStepType::System,
2365 : OutputProcessor::StoreType::Average,
2366 0 : zone.Name);
2367 0 : SetupOutputVariable(state,
2368 : "Room Air Zone Window Plume Heat Transfer Rate",
2369 : Constant::Units::W,
2370 0 : state.dataRoomAir->ZoneUFADPowInPlumesfromWindows(iZone),
2371 : OutputProcessor::TimeStepType::System,
2372 : OutputProcessor::StoreType::Average,
2373 0 : zone.Name);
2374 0 : SetupOutputVariable(state,
2375 : "Room Air Zone Temperature Stratification Fraction",
2376 : Constant::Units::None,
2377 0 : state.dataRoomAir->Phi(iZone),
2378 : OutputProcessor::TimeStepType::System,
2379 : OutputProcessor::StoreType::Average,
2380 0 : zone.Name);
2381 : // set zone equip pointer in the UCSDUE data structure
2382 0 : state.dataRoomAir->ZoneUFAD(state.dataRoomAir->ZoneUFADPtr(iZone)).ZoneEquipPtr = iZone;
2383 : }
2384 : }
2385 :
2386 0 : if (any(state.dataRoomAir->IsZoneCrossVent)) {
2387 0 : state.dataRoomAir->CrossVentHcIn.allocate(state.dataSurface->TotSurfaces);
2388 0 : state.dataRoomAir->ZTJET.allocate(state.dataGlobal->NumOfZones);
2389 : // Most ZTJet takes defaults
2390 0 : state.dataRoomAir->ZTREC.allocate(state.dataGlobal->NumOfZones);
2391 0 : state.dataRoomAir->RoomOutflowTemp.allocate(state.dataGlobal->NumOfZones);
2392 : // Most ZTREC takes defaults
2393 0 : state.dataRoomAir->JetRecAreaRatio.allocate(state.dataGlobal->NumOfZones);
2394 0 : state.dataRoomAir->Urec.allocate(state.dataGlobal->NumOfZones);
2395 0 : state.dataRoomAir->Ujet.allocate(state.dataGlobal->NumOfZones);
2396 0 : state.dataRoomAir->Qrec.allocate(state.dataGlobal->NumOfZones);
2397 0 : state.dataRoomAir->Qtot.allocate(state.dataGlobal->NumOfZones);
2398 0 : state.dataRoomAir->RecInflowRatio.allocate(state.dataGlobal->NumOfZones);
2399 0 : state.dataRoomAir->Uhc.allocate(state.dataGlobal->NumOfZones);
2400 0 : state.dataRoomAir->Ain.allocate(state.dataGlobal->NumOfZones);
2401 0 : state.dataRoomAir->Tin.allocate(state.dataGlobal->NumOfZones);
2402 0 : state.dataRoomAir->Droom.allocate(state.dataGlobal->NumOfZones);
2403 0 : state.dataRoomAir->Dstar.allocate(state.dataGlobal->NumOfZones);
2404 0 : state.dataRoomAir->ZoneCrossVentIsMixing.allocate(state.dataGlobal->NumOfZones);
2405 0 : state.dataRoomAir->Rfr.allocate(state.dataGlobal->NumOfZones);
2406 0 : state.dataRoomAir->ZoneCrossVentHasREC.allocate(state.dataGlobal->NumOfZones);
2407 :
2408 0 : state.dataRoomAir->ZTJET = 23.0;
2409 0 : state.dataRoomAir->RoomOutflowTemp = 23.0;
2410 0 : state.dataRoomAir->ZTREC = 23.0;
2411 0 : state.dataRoomAir->CrossVentHcIn = 0.0;
2412 0 : state.dataRoomAir->JetRecAreaRatio = 0.2;
2413 0 : state.dataRoomAir->Urec = 0.2;
2414 0 : state.dataRoomAir->Ujet = 0.2;
2415 0 : state.dataRoomAir->Qrec = 0.2;
2416 0 : state.dataRoomAir->Uhc = 0.2;
2417 0 : state.dataRoomAir->Ain = 1.0;
2418 0 : state.dataRoomAir->Tin = 23.0;
2419 0 : state.dataRoomAir->Droom = 6.0;
2420 0 : state.dataRoomAir->ZoneCrossVentIsMixing = 0.0;
2421 0 : state.dataRoomAir->Rfr = 10.0;
2422 0 : state.dataRoomAir->ZoneCrossVentHasREC = 1.0;
2423 0 : state.dataRoomAir->HCeiling = 0.0;
2424 0 : state.dataRoomAir->HWall = 0.0;
2425 0 : state.dataRoomAir->HFloor = 0.0;
2426 0 : state.dataRoomAir->HInternal = 0.0;
2427 0 : state.dataRoomAir->HWindow = 0.0;
2428 0 : state.dataRoomAir->HDoor = 0.0;
2429 :
2430 0 : for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
2431 0 : if (state.dataRoomAir->AirModel(iZone).AirModel != RoomAirModel::CrossVent)
2432 0 : continue; // don't set these up if they don't make sense
2433 :
2434 0 : int ZoneEquipConfigNum = ZoneNum; // Where does this ZoneNum come from?
2435 :
2436 0 : auto const &zone = state.dataHeatBal->Zone(iZone);
2437 : // check whether this zone is a controlled zone or not
2438 0 : if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).IsControlled) {
2439 0 : state.dataRoomAir->IsZoneCrossVent(iZone) = false;
2440 0 : state.dataRoomAir->AirModel(iZone).SimAirModel = false;
2441 0 : ShowSevereError(state, format("Unmixed Flow: Cross Ventilation cannot be applied for Zone={}", zone.Name));
2442 0 : ShowContinueError(
2443 0 : state, format("An HVAC system is present in the zone. Fully mixed airflow model will be used for Zone={}", zone.Name));
2444 0 : continue;
2445 : }
2446 : // CurrentModuleObject='RoomAirSettings:CrossVentilation'
2447 0 : SetupOutputVariable(state,
2448 : "Room Air Zone Jet Region Temperature",
2449 : Constant::Units::C,
2450 0 : state.dataRoomAir->ZTJET(iZone),
2451 : OutputProcessor::TimeStepType::Zone,
2452 : OutputProcessor::StoreType::Average,
2453 0 : zone.Name);
2454 0 : SetupOutputVariable(state,
2455 : "Room Air Zone Recirculation Region Temperature",
2456 : Constant::Units::C,
2457 0 : state.dataRoomAir->ZTREC(iZone),
2458 : OutputProcessor::TimeStepType::Zone,
2459 : OutputProcessor::StoreType::Average,
2460 0 : zone.Name);
2461 0 : SetupOutputVariable(state,
2462 : "Room Air Zone Jet Region Average Air Velocity",
2463 : Constant::Units::m_s,
2464 0 : state.dataRoomAir->Ujet(iZone),
2465 : OutputProcessor::TimeStepType::Zone,
2466 : OutputProcessor::StoreType::Average,
2467 0 : zone.Name);
2468 0 : SetupOutputVariable(state,
2469 : "Room Air Zone Recirculation Region Average Air Velocity",
2470 : Constant::Units::m_s,
2471 0 : state.dataRoomAir->Urec(iZone),
2472 : OutputProcessor::TimeStepType::Zone,
2473 : OutputProcessor::StoreType::Average,
2474 0 : zone.Name);
2475 0 : SetupOutputVariable(state,
2476 : "Room Air Zone Recirculation and Inflow Rate Ratio",
2477 : Constant::Units::None,
2478 0 : state.dataRoomAir->RecInflowRatio(iZone),
2479 : OutputProcessor::TimeStepType::Zone,
2480 : OutputProcessor::StoreType::Average,
2481 0 : zone.Name);
2482 0 : SetupOutputVariable(state,
2483 : "Room Air Zone Inflow Opening Area",
2484 : Constant::Units::m2,
2485 0 : state.dataRoomAir->Ain(iZone),
2486 : OutputProcessor::TimeStepType::Zone,
2487 : OutputProcessor::StoreType::Average,
2488 0 : zone.Name);
2489 0 : SetupOutputVariable(state,
2490 : "Room Air Zone Room Length",
2491 : Constant::Units::m,
2492 0 : state.dataRoomAir->Dstar(iZone),
2493 : OutputProcessor::TimeStepType::Zone,
2494 : OutputProcessor::StoreType::Average,
2495 0 : zone.Name);
2496 0 : SetupOutputVariable(state,
2497 : "Room Air Zone Is Mixing Status",
2498 : Constant::Units::None,
2499 0 : state.dataRoomAir->ZoneCrossVentIsMixing(iZone),
2500 : OutputProcessor::TimeStepType::Zone,
2501 : OutputProcessor::StoreType::Average,
2502 0 : zone.Name);
2503 0 : SetupOutputVariable(state,
2504 : "Room Air Zone Is Recirculating Status",
2505 : Constant::Units::None,
2506 0 : state.dataRoomAir->ZoneCrossVentHasREC(iZone),
2507 : OutputProcessor::TimeStepType::Zone,
2508 : OutputProcessor::StoreType::Average,
2509 0 : zone.Name);
2510 0 : for (int i = 1; i <= state.dataRoomAir->AFNSurfaceCrossVent(0, ZoneNum); ++i) {
2511 0 : int N = state.afn->AirflowNetworkLinkageData(i).CompNum;
2512 0 : if (state.afn->AirflowNetworkCompData(N).CompTypeNum == AirflowNetwork::iComponentTypeNum::DOP) {
2513 0 : SetupOutputVariable(state,
2514 : "Room Air Window Jet Region Average Air Velocity",
2515 : Constant::Units::m_s,
2516 0 : state.dataRoomAir->CrossVentJetRecFlows(i, iZone).Ujet,
2517 : OutputProcessor::TimeStepType::Zone,
2518 : OutputProcessor::StoreType::Average,
2519 0 : state.afn->MultizoneSurfaceData(i).SurfName);
2520 : }
2521 : }
2522 : } // for (iZone)
2523 : } // if (any(isZoneCV))
2524 :
2525 0 : state.dataRoomAir->MyEnvrnFlag = true;
2526 :
2527 0 : state.dataRoomAir->MyOneTimeFlag = false;
2528 : } // if (myOneTimeFlag)
2529 :
2530 : // Do the Begin Environment initializations
2531 0 : if (state.dataGlobal->BeginEnvrnFlag && state.dataRoomAir->MyEnvrnFlag(ZoneNum)) {
2532 :
2533 0 : if (state.dataRoomAir->IsZoneDispVent3Node(ZoneNum) || state.dataRoomAir->IsZoneUFAD(ZoneNum)) {
2534 :
2535 0 : state.dataRoomAir->MaxTempGrad(ZoneNum) = 0.0;
2536 0 : state.dataRoomAir->AvgTempGrad(ZoneNum) = 0.0;
2537 0 : state.dataRoomAir->TCMF(ZoneNum) = 23.0;
2538 0 : state.dataRoomAir->FracMinFlow(ZoneNum) = 0.0;
2539 0 : state.dataRoomAir->ZoneAirSystemON(ZoneNum) = false;
2540 0 : state.dataRoomAir->MATFloor(ZoneNum) = 23.0;
2541 0 : state.dataRoomAir->XMATFloor(ZoneNum) = {23.0, 23.0, 23.0, 23.0};
2542 0 : state.dataRoomAir->DSXMATFloor(ZoneNum) = {23.0, 23.0, 23.0, 23.0};
2543 0 : state.dataRoomAir->MATOC(ZoneNum) = 23.0;
2544 0 : state.dataRoomAir->XMATOC(ZoneNum) = {23.0, 23.0, 23.0, 23.0};
2545 0 : state.dataRoomAir->DSXMATOC(ZoneNum) = {23.0, 23.0, 23.0, 23.0};
2546 0 : state.dataRoomAir->MATMX(ZoneNum) = 23.0;
2547 0 : state.dataRoomAir->XMATMX(ZoneNum) = {23.0, 23.0, 23.0, 23.0};
2548 0 : state.dataRoomAir->DSXMATMX(ZoneNum) = {23.0, 23.0, 23.0, 23.0};
2549 0 : state.dataRoomAir->ZTMFloor(ZoneNum) = {23.0, 23.0, 23.0};
2550 0 : state.dataRoomAir->Zone1Floor(ZoneNum) = 23.0;
2551 0 : state.dataRoomAir->ZoneMXFloor(ZoneNum) = 23.0;
2552 0 : state.dataRoomAir->ZoneM2Floor(ZoneNum) = 23.0;
2553 0 : state.dataRoomAir->ZTMOC(ZoneNum) = {23.0, 23.0, 23.0};
2554 0 : state.dataRoomAir->Zone1OC(ZoneNum) = 23.0;
2555 0 : state.dataRoomAir->ZoneMXOC(ZoneNum) = 23.0;
2556 0 : state.dataRoomAir->ZoneM2OC(ZoneNum) = 23.0;
2557 0 : state.dataRoomAir->ZTMMX(ZoneNum) = {23.0, 23.0, 23.0};
2558 0 : state.dataRoomAir->Zone1MX(ZoneNum) = 23.0;
2559 0 : state.dataRoomAir->ZoneMXMX(ZoneNum) = 23.0;
2560 0 : state.dataRoomAir->ZoneM2MX(ZoneNum) = 23.0;
2561 0 : state.dataRoomAir->AIRRATFloor(ZoneNum) = 0.0;
2562 0 : state.dataRoomAir->AIRRATOC(ZoneNum) = 0.0;
2563 0 : state.dataRoomAir->AIRRATMX(ZoneNum) = 0.0;
2564 0 : state.dataRoomAir->ZTOC(ZoneNum) = 23.0;
2565 0 : state.dataRoomAir->ZTMX(ZoneNum) = 23.0;
2566 0 : state.dataRoomAir->ZTFloor(ZoneNum) = 23.0;
2567 0 : state.dataRoomAir->HeightTransition(ZoneNum) = 0.0;
2568 0 : state.dataRoomAir->Phi(ZoneNum) = 0.0;
2569 0 : state.dataRoomAir->HCeiling = 0.0;
2570 0 : state.dataRoomAir->HWall = 0.0;
2571 0 : state.dataRoomAir->HFloor = 0.0;
2572 0 : state.dataRoomAir->HInternal = 0.0;
2573 0 : state.dataRoomAir->HWindow = 0.0;
2574 0 : state.dataRoomAir->HDoor = 0.0;
2575 : }
2576 :
2577 0 : if (state.dataRoomAir->IsZoneDispVent3Node(ZoneNum)) {
2578 :
2579 0 : state.dataRoomAir->DispVent3NodeHcIn = 0.0;
2580 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlagRep(ZoneNum) = 0.0;
2581 0 : state.dataRoomAir->ZoneDispVent3NodeMixedFlag(ZoneNum) = 0;
2582 : }
2583 :
2584 0 : if (state.dataRoomAir->IsZoneUFAD(ZoneNum)) {
2585 :
2586 0 : state.dataRoomAir->UFADHcIn = 0.0;
2587 0 : state.dataRoomAir->ZoneUFADMixedFlag(ZoneNum) = 0;
2588 0 : state.dataRoomAir->ZoneUFADMixedFlagRep(ZoneNum) = 0.0;
2589 0 : state.dataRoomAir->ZoneUFADGamma(ZoneNum) = 0.0;
2590 0 : state.dataRoomAir->ZoneUFADPowInPlumes(ZoneNum) = 0.0;
2591 0 : state.dataRoomAir->ZoneUFADPowInPlumesfromWindows(ZoneNum) = 0.0;
2592 : }
2593 :
2594 0 : if (state.dataRoomAir->IsZoneCrossVent(ZoneNum)) {
2595 0 : state.dataRoomAir->ZTJET(ZoneNum) = 23.0;
2596 0 : state.dataRoomAir->RoomOutflowTemp(ZoneNum) = 23.0;
2597 0 : state.dataRoomAir->ZTREC(ZoneNum) = 23.0;
2598 0 : state.dataRoomAir->CrossVentHcIn = 0.0;
2599 0 : state.dataRoomAir->JetRecAreaRatio(ZoneNum) = 0.2;
2600 0 : state.dataRoomAir->Urec(ZoneNum) = 0.2;
2601 0 : state.dataRoomAir->Ujet(ZoneNum) = 0.2;
2602 0 : state.dataRoomAir->Uhc(ZoneNum) = 0.2;
2603 0 : state.dataRoomAir->Ain(ZoneNum) = 1.0;
2604 0 : state.dataRoomAir->Tin(ZoneNum) = 23.0;
2605 0 : state.dataRoomAir->Droom(ZoneNum) = 6.0;
2606 0 : state.dataRoomAir->Dstar(ZoneNum) = 6.0;
2607 0 : state.dataRoomAir->ZoneCrossVentIsMixing(ZoneNum) = 0.0;
2608 0 : state.dataRoomAir->Rfr(ZoneNum) = 10.0;
2609 0 : state.dataRoomAir->ZoneCrossVentHasREC(ZoneNum) = 1.0;
2610 0 : state.dataRoomAir->HCeiling = 0.0;
2611 0 : state.dataRoomAir->HWall = 0.0;
2612 0 : state.dataRoomAir->HFloor = 0.0;
2613 0 : state.dataRoomAir->HInternal = 0.0;
2614 0 : state.dataRoomAir->HWindow = 0.0;
2615 0 : state.dataRoomAir->HDoor = 0.0;
2616 : }
2617 :
2618 0 : state.dataRoomAir->MyEnvrnFlag(ZoneNum) = false;
2619 : } // end one time inits
2620 :
2621 0 : if (!state.dataGlobal->BeginEnvrnFlag) {
2622 0 : state.dataRoomAir->MyEnvrnFlag(ZoneNum) = true;
2623 : }
2624 0 : }
2625 :
2626 6 : void GetRAFNNodeNum(EnergyPlusData &state,
2627 : std::string const &RAFNNodeName, // Name of RoomAir:Node:AirflowNetwork
2628 : int &ZoneNum, // The zone number associate with the node name
2629 : int &RAFNNodeNum, // RoomAir:Node:AirflowNetwork Number
2630 : bool &Errorfound // true if an error is found (TODO: Useless, RAFNodeNum is 0 when Errorfound is true)
2631 : )
2632 : {
2633 :
2634 : // FUNCTION INFORMATION:
2635 : // AUTHOR Lixing Gu
2636 : // DATE WRITTEN November 2014
2637 :
2638 : // PURPOSE OF THIS FUNCTION:
2639 : // This function looks up the given RoomAirNode name and returns the Zone number and RoomAir node
2640 : // number. If incorrect name is given, errorsfound is returned as true and value is returned
2641 : // as zero.
2642 :
2643 : // Obtains and Allocates RoomAirSettings : AirflowNetwork
2644 6 : if (state.dataRoomAir->GetAirModelData) {
2645 1 : GetAirModelDatas(state);
2646 1 : state.dataRoomAir->GetAirModelData = false;
2647 : }
2648 :
2649 6 : Errorfound = false;
2650 6 : RAFNNodeNum = 0;
2651 18 : for (int I = 1; I <= state.dataGlobal->NumOfZones; ++I) {
2652 18 : auto const &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(I);
2653 18 : if (afnZoneInfo.NumOfAirNodes > 0) {
2654 6 : RAFNNodeNum = Util::FindItemInList(RAFNNodeName, afnZoneInfo.Node, afnZoneInfo.NumOfAirNodes);
2655 6 : if (RAFNNodeNum > 0) {
2656 6 : ZoneNum = I;
2657 6 : break;
2658 : }
2659 : }
2660 : }
2661 :
2662 6 : if (RAFNNodeNum == 0) {
2663 0 : Errorfound = true;
2664 0 : ShowSevereError(state,
2665 0 : format("Could not find RoomAir:Node:AirflowNetwork number with AirflowNetwork:IntraZone:Node Name='{}", RAFNNodeName));
2666 : }
2667 6 : }
2668 :
2669 21 : bool CheckEquipName(EnergyPlusData &state,
2670 : std::string const &EquipName, // Equipment Name
2671 : std::string &SupplyNodeName, // Supply node name
2672 : std::string &ReturnNodeName, // Return node name
2673 : DataZoneEquipment::ZoneEquipType zoneEquipType)
2674 : {
2675 :
2676 : // FUNCTION INFORMATION:
2677 : // AUTHOR Lixing Gu
2678 : // DATE WRITTEN March 2014
2679 :
2680 : // PURPOSE OF THIS FUNCTION:
2681 : // This function looks up the given RoomAirNode name and returns the Zone number and RoomAir node
2682 : // number.If incorrect name is given, errorsfound is returned as true and value is returned
2683 : // as zero.
2684 :
2685 : // Return value
2686 21 : bool EquipFind = false; // if true, equip is found
2687 :
2688 21 : int SupplyNodeNum = 0;
2689 21 : int ReturnNodeNum = 0;
2690 :
2691 21 : SupplyNodeName = "";
2692 : int EquipIndex;
2693 :
2694 21 : if (zoneEquipType == DataZoneEquipment::ZoneEquipType::Invalid) return EquipFind;
2695 :
2696 21 : switch (zoneEquipType) {
2697 1 : case DataZoneEquipment::ZoneEquipType::VariableRefrigerantFlowTerminal: { // ZoneHVAC:TerminalUnit : VariableRefrigerantFlow
2698 1 : EquipIndex = HVACVariableRefrigerantFlow::getEqIndex(state, EquipName);
2699 1 : if (EquipIndex == 0) return EquipFind;
2700 1 : SupplyNodeNum = state.dataHVACVarRefFlow->VRFTU(EquipIndex).VRFTUOutletNodeNum;
2701 1 : } break;
2702 1 : case DataZoneEquipment::ZoneEquipType::EnergyRecoveryVentilator: { // ZoneHVAC : EnergyRecoveryVentilator
2703 1 : EquipIndex = HVACStandAloneERV::getEqIndex(state, EquipName);
2704 1 : if (EquipIndex == 0) return EquipFind;
2705 1 : SupplyNodeNum = state.dataHVACStandAloneERV->StandAloneERV(EquipIndex).SupplyAirInletNode;
2706 1 : } break;
2707 1 : case DataZoneEquipment::ZoneEquipType::FourPipeFanCoil: { // ZoneHVAC : FourPipeFanCoil
2708 1 : EquipIndex = FanCoilUnits::getEqIndex(state, EquipName);
2709 1 : if (EquipIndex == 0) return EquipFind;
2710 1 : SupplyNodeNum = state.dataFanCoilUnits->FanCoil(EquipIndex).AirOutNode;
2711 1 : ReturnNodeNum = state.dataFanCoilUnits->FanCoil(EquipIndex).AirInNode;
2712 1 : } break;
2713 1 : case DataZoneEquipment::ZoneEquipType::OutdoorAirUnit: { // ZoneHVAC : OutdoorAirUnit
2714 1 : EquipIndex = OutdoorAirUnit::getOutdoorAirUnitEqIndex(state, EquipName);
2715 1 : if (EquipIndex == 0) return EquipFind;
2716 1 : SupplyNodeNum = state.dataOutdoorAirUnit->OutAirUnit(EquipIndex).AirOutletNode;
2717 1 : ReturnNodeNum = state.dataOutdoorAirUnit->OutAirUnit(EquipIndex).AirInletNode;
2718 1 : } break;
2719 7 : case DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner: { // ZoneHVAC : PackagedTerminalAirConditioner
2720 7 : EquipIndex = UnitarySystems::getZoneEqIndex(state, EquipName, zoneEquipType);
2721 7 : if (EquipIndex == -1) return EquipFind;
2722 7 : SupplyNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex].AirOutNode;
2723 7 : ReturnNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex].AirInNode;
2724 7 : } break;
2725 1 : case DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump: { // ZoneHVAC : PackagedTerminalHeatPump
2726 1 : EquipIndex = UnitarySystems::getZoneEqIndex(state, EquipName, zoneEquipType);
2727 1 : if (EquipIndex == -1) return EquipFind;
2728 1 : SupplyNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex].AirOutNode;
2729 1 : ReturnNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex].AirInNode;
2730 1 : } break;
2731 1 : case DataZoneEquipment::ZoneEquipType::UnitHeater: { // ZoneHVAC : UnitHeater
2732 1 : EquipIndex = UnitHeater::getUnitHeaterIndex(state, EquipName);
2733 1 : if (EquipIndex == 0) return EquipFind;
2734 1 : ReturnNodeNum = state.dataUnitHeaters->UnitHeat(EquipIndex).AirInNode;
2735 1 : SupplyNodeNum = state.dataUnitHeaters->UnitHeat(EquipIndex).AirOutNode;
2736 1 : } break;
2737 1 : case DataZoneEquipment::ZoneEquipType::UnitVentilator: { // ZoneHVAC : UnitVentilator
2738 1 : EquipIndex = UnitVentilator::getUnitVentilatorIndex(state, EquipName);
2739 1 : if (EquipIndex == 0) return EquipFind;
2740 1 : ReturnNodeNum = state.dataUnitVentilators->UnitVent(EquipIndex).AirInNode;
2741 1 : SupplyNodeNum = state.dataUnitVentilators->UnitVent(EquipIndex).AirOutNode;
2742 1 : } break;
2743 1 : case DataZoneEquipment::ZoneEquipType::VentilatedSlab: { // ZoneHVAC : VentilatedSlab
2744 1 : EquipIndex = VentilatedSlab::getVentilatedSlabIndex(state, EquipName);
2745 1 : if (EquipIndex == 0) return EquipFind;
2746 1 : ReturnNodeNum = state.dataVentilatedSlab->VentSlab(EquipIndex).ReturnAirNode;
2747 1 : SupplyNodeNum = state.dataVentilatedSlab->VentSlab(EquipIndex).ZoneAirInNode;
2748 1 : } break;
2749 1 : case DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir: { // ZoneHVAC : WaterToAirHeatPump
2750 1 : EquipIndex = UnitarySystems::getZoneEqIndex(state, EquipName, zoneEquipType);
2751 1 : if (EquipIndex == -1) return EquipFind;
2752 1 : SupplyNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex].AirOutNode;
2753 1 : ReturnNodeNum = state.dataUnitarySystems->unitarySys[EquipIndex].AirInNode;
2754 1 : } break;
2755 1 : case DataZoneEquipment::ZoneEquipType::WindowAirConditioner: { // ZoneHVAC : WindowAirConditioner
2756 1 : EquipIndex = WindowAC::getWindowACIndex(state, EquipName);
2757 1 : if (EquipIndex == 0) return EquipFind;
2758 1 : ReturnNodeNum = state.dataWindowAC->WindAC(EquipIndex).AirInNode;
2759 1 : SupplyNodeNum = state.dataWindowAC->WindAC(EquipIndex).AirOutNode;
2760 1 : } break;
2761 0 : case DataZoneEquipment::ZoneEquipType::BaseboardElectric: { // ZoneHVAC : Baseboard : RadiantConvective : Electric
2762 : // convective equipment without node connection. Will handle later
2763 0 : SupplyNodeName = ""; // convection only
2764 0 : } break;
2765 0 : case DataZoneEquipment::ZoneEquipType::BaseboardWater: { // ZoneHVAC : Baseboard : RadiantConvective : Water
2766 : // convective equipment without node connection. Will handle later
2767 0 : SupplyNodeName = "";
2768 0 : } break;
2769 0 : case DataZoneEquipment::ZoneEquipType::BaseboardSteam: { // ZoneHVAC : Baseboard : RadiantConvective : Steam
2770 : // convective equipment without node connection. Will handle later
2771 0 : SupplyNodeName = "";
2772 0 : } break;
2773 0 : case DataZoneEquipment::ZoneEquipType::BaseboardConvectiveElectric: { // ZoneHVAC : Baseboard : Convective : Electric
2774 : // convective equipment without node connection. Will handle later
2775 0 : SupplyNodeName = "";
2776 0 : } break;
2777 0 : case DataZoneEquipment::ZoneEquipType::BaseboardConvectiveWater: { // ZoneHVAC : Baseboard : Convective : Water
2778 : // convective equipment without node connection. Will handle later
2779 0 : SupplyNodeName = "";
2780 0 : } break;
2781 0 : case DataZoneEquipment::ZoneEquipType::HighTemperatureRadiant: { // ZoneHVAC : HighTemperatureRadiant
2782 : // Radiative equipment without node connection. Will handle later
2783 0 : SupplyNodeName = "";
2784 0 : } break;
2785 1 : case DataZoneEquipment::ZoneEquipType::DehumidifierDX: { // ZoneHVAC : Dehumidifier : DX
2786 1 : EquipIndex = ZoneDehumidifier::getZoneDehumidifierIndex(state, EquipName);
2787 1 : if (EquipIndex == 0) return EquipFind;
2788 1 : ReturnNodeNum = state.dataZoneDehumidifier->ZoneDehumid(EquipIndex).AirInletNodeNum;
2789 1 : SupplyNodeNum = state.dataZoneDehumidifier->ZoneDehumid(EquipIndex).AirOutletNodeNum;
2790 1 : } break;
2791 3 : case DataZoneEquipment::ZoneEquipType::PurchasedAir: { // ZoneHVAC : IdealLoadsAirSystem
2792 3 : EquipIndex = PurchasedAirManager::getPurchasedAirIndex(state, EquipName);
2793 3 : if (EquipIndex == 0) return EquipFind;
2794 3 : ReturnNodeNum = state.dataPurchasedAirMgr->PurchAir(EquipIndex).ZoneExhaustAirNodeNum;
2795 3 : SupplyNodeNum = state.dataPurchasedAirMgr->PurchAir(EquipIndex).ZoneSupplyAirNodeNum;
2796 3 : } break;
2797 0 : case DataZoneEquipment::ZoneEquipType::RefrigerationChillerSet: { // ZoneHVAC : RefrigerationChillerSet
2798 : // May not apply
2799 : // SupplyNodeName = Alphas(5);
2800 : // ReturnNodeName = Alphas(4);
2801 0 : } break;
2802 0 : case DataZoneEquipment::ZoneEquipType::HybridEvaporativeCooler: { // ZoneHVAC : HybridUnitaryAirConditioners
2803 0 : EquipIndex = HybridUnitaryAirConditioners::getHybridUnitaryACIndex(state, EquipName);
2804 0 : if (EquipIndex == 0) return EquipFind;
2805 0 : ReturnNodeNum = state.dataHybridUnitaryAC->ZoneHybridUnitaryAirConditioner(EquipIndex).InletNode;
2806 0 : SupplyNodeNum = state.dataHybridUnitaryAC->ZoneHybridUnitaryAirConditioner(EquipIndex).OutletNode;
2807 0 : } break;
2808 0 : case DataZoneEquipment::ZoneEquipType::ExhaustFan: { // Fan : ZoneExhaust
2809 :
2810 : // SupplyNodeName = ""; // ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? May not use
2811 0 : } break;
2812 0 : case DataZoneEquipment::ZoneEquipType::HeatPumpWaterHeaterPumpedCondenser:
2813 : case DataZoneEquipment::ZoneEquipType::HeatPumpWaterHeaterWrappedCondenser: { // WaterHeater : HeatPump
2814 0 : EquipIndex = WaterThermalTanks::getHeatPumpWaterHeaterIndex(state, EquipName);
2815 0 : if (EquipIndex == 0) return EquipFind;
2816 0 : ReturnNodeNum = state.dataWaterThermalTanks->HPWaterHeater(EquipIndex).HeatPumpAirInletNode;
2817 0 : SupplyNodeNum = state.dataWaterThermalTanks->HPWaterHeater(EquipIndex).HeatPumpAirOutletNode;
2818 : // For AirTerminals, find matching return node later
2819 0 : } break;
2820 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalDualDuctConstantVolume: { // AirTerminal : DualDuct : ConstantVolume
2821 : // Air teminal components are handled later
2822 : // SupplyNodeName = Alphas(1);
2823 : // ReturnNodeName = "";
2824 0 : } break;
2825 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalDualDuctVAV: { // AirTerminal : DualDuct : VAV
2826 : // Air teminal components are handled later
2827 : // SupplyNodeName = Alphas(1);
2828 : // ReturnNodeName = "";
2829 0 : } break;
2830 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctConstantVolumeReheat: { // AirTerminal : SingleDuct : ConstantVolume : Reheat
2831 : // Air teminal components are handled later
2832 : // SupplyNodeName = Alphas(1);
2833 : // ReturnNodeName = "";
2834 0 : } break;
2835 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctConstantVolumeNoReheat: { // AirTerminal : SingleDuct :
2836 : // Air teminal components are handled later
2837 : // SupplyNodeName = Alphas(4);
2838 : // ReturnNodeName = "";
2839 0 : } break;
2840 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctVAVReheat: { // AirTerminal : SingleDuct : VAV : Reheat
2841 : // Air teminal components are handled later
2842 : // SupplyNodeName = Alphas(1);
2843 : // ReturnNodeName = "";
2844 0 : } break;
2845 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctVAVNoReheat: { // AirTerminal : SingleDuct : VAV : NoReheat
2846 : // Air teminal components are handled later
2847 : // SupplyNodeName = Alphas(1);
2848 : // ReturnNodeName = "";
2849 0 : } break;
2850 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctSeriesPIUReheat: { // AirTerminal : SingleDuct : SeriesPIU : Reheat
2851 : // Air teminal components are handled later
2852 : // SupplyNodeName = Alphas(1);
2853 : // ReturnNodeName = "";
2854 0 : } break;
2855 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctParallelPIUReheat: { // AirTerminal : SingleDuct : ParallelPIU : Reheat
2856 : // Air teminal components are handled later
2857 : // SupplyNodeName = Alphas(1);
2858 : // ReturnNodeName = "";
2859 0 : } break;
2860 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctCAVFourPipeInduction: { // AirTerminal : SingleDuct :
2861 : // Air teminal components are handled later
2862 : // ConstantVolume : FourPipeInduction
2863 : // SupplyNodeName = Alphas(1);
2864 : // ReturnNodeName = "";
2865 0 : } break;
2866 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctVAVReheatVariableSpeedFan: { // AirTerminal : SingleDuct : VAV
2867 : // Air teminal components are handled later
2868 : // : Reheat : VariableSpeedFan
2869 : // SupplyNodeName = Alphas(1);
2870 : // ReturnNodeName = "";
2871 0 : } break;
2872 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctVAVHeatAndCoolReheat: { // AirTerminal : SingleDuct : VAV :
2873 : // HeatAndCool : Reheat
2874 : // Air teminal components are handled later
2875 : // SupplyNodeName = Alphas(1);
2876 : // ReturnNodeName = "";
2877 0 : } break;
2878 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctVAVHeatAndCoolNoReheat: { // AirTerminal : SingleDuct : VAV :
2879 : // HeatAndCool : NoReheat
2880 : // Air teminal components are handled later
2881 : // SupplyNodeName = Alphas(1);
2882 : // ReturnNodeName = "";
2883 0 : } break;
2884 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalSingleDuctConstantVolumeCooledBeam: { // AirTerminal : SingleDuct :
2885 : // ConstantVolume : CooledBeam
2886 : // Air teminal components are handled later
2887 : // SupplyNodeName = Alphas(5);
2888 : // ReturnNodeName = "";
2889 0 : } break;
2890 0 : case DataZoneEquipment::ZoneEquipType::AirTerminalDualDuctVAVOutdoorAir: { // AirTerminal : DualDuct : VAV : OutdoorAir
2891 : // Air teminal components are handled later
2892 : // SupplyNodeName = Alphas(3);
2893 : // ReturnNodeName = "";
2894 0 : } break;
2895 0 : case DataZoneEquipment::ZoneEquipType::AirLoopHVACReturnAir: { // AirLoopHVACReturnAir
2896 : // Air teminal components are handled later
2897 : // SupplyNodeName = Alphas(4); //
2898 : // ReturnNodeName = ""; //
2899 0 : } break;
2900 0 : default: {
2901 0 : assert(false);
2902 : } break;
2903 :
2904 : } // switch
2905 :
2906 21 : if (SupplyNodeNum > 0) {
2907 21 : SupplyNodeName = state.dataLoopNodes->NodeID(SupplyNodeNum);
2908 21 : EquipFind = true;
2909 : }
2910 21 : if (ReturnNodeNum > 0) {
2911 19 : ReturnNodeName = state.dataLoopNodes->NodeID(ReturnNodeNum);
2912 : } else {
2913 2 : ReturnNodeName = "";
2914 : }
2915 21 : return EquipFind;
2916 : }
2917 :
2918 : //*****************************************************************************************
2919 :
2920 : } // namespace RoomAir
2921 :
2922 : } // namespace EnergyPlus
|