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