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