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 <string>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Array1D.hh>
54 : #include <ObjexxFCL/Array2D.hh>
55 : #include <ObjexxFCL/Fmath.hh>
56 :
57 : // EnergyPlus Headers
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataEnvironment.hh>
60 : #include <EnergyPlus/DataHeatBalFanSys.hh>
61 : #include <EnergyPlus/DataHeatBalance.hh>
62 : #include <EnergyPlus/DataIPShortCuts.hh>
63 : #include <EnergyPlus/DataRoomAirModel.hh>
64 : #include <EnergyPlus/DataRuntimeLanguage.hh>
65 : #include <EnergyPlus/DataStringGlobals.hh>
66 : #include <EnergyPlus/DataViewFactorInformation.hh>
67 : #include <EnergyPlus/DataZoneControls.hh>
68 : #include <EnergyPlus/DataZoneEquipment.hh>
69 : #include <EnergyPlus/EMSManager.hh>
70 : #include <EnergyPlus/General.hh>
71 : #include <EnergyPlus/GeneralRoutines.hh>
72 : #include <EnergyPlus/GlobalNames.hh>
73 : #include <EnergyPlus/HVACManager.hh>
74 : #include <EnergyPlus/HeatBalanceAirManager.hh>
75 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
76 : #include <EnergyPlus/InternalHeatGains.hh>
77 : #include <EnergyPlus/OutputProcessor.hh>
78 : #include <EnergyPlus/Psychrometrics.hh>
79 : #include <EnergyPlus/ScheduleManager.hh>
80 : #include <EnergyPlus/SystemAvailabilityManager.hh>
81 : #include <EnergyPlus/UtilityRoutines.hh>
82 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
83 :
84 : namespace EnergyPlus::HeatBalanceAirManager {
85 : // Module containing the air heat balance simulation routines
86 : // calculation (initialization) routines
87 :
88 : // MODULE INFORMATION:
89 : // AUTHOR Richard J. Liesen
90 : // DATE WRITTEN February 1998
91 : // MODIFIED May-July 2000 Joe Huang for Comis Link
92 :
93 : // PURPOSE OF THIS MODULE:
94 : // To encapsulate the data and algorithms required to
95 : // manage the air simluation heat balance on the building.
96 :
97 : // REFERENCES:
98 : // The heat balance method is outlined in the "Tarp Alogorithms Manual"
99 : // The methods are also summarized in many BSO Theses and papers.
100 :
101 : // OTHER NOTES:
102 : // This module was created from IBLAST subroutines
103 :
104 : enum class AirflowSpec
105 : {
106 : Invalid = -1,
107 : Flow,
108 : FlowPerZone,
109 : FlowPerArea,
110 : FlowPerPerson,
111 : AirChanges,
112 : Num
113 : };
114 : constexpr std::array<std::string_view, static_cast<int>(AirflowSpec::Num)> airflowNamesUC = {
115 : "FLOW", "FLOW/ZONE", "FLOW/AREA", "FLOW/PERSON", "AIRCHANGES/HOUR"};
116 :
117 : enum class AirflowSpecAlt
118 : {
119 : Invalid = -1,
120 : Flow,
121 : FlowPerZone,
122 : FlowPerArea,
123 : FlowPerExteriorArea,
124 : FlowPerExteriorWallArea,
125 : AirChanges,
126 : Num
127 : };
128 : constexpr std::array<std::string_view, static_cast<int>(AirflowSpecAlt::Num)> airflowAltNamesUC = {
129 : "FLOW", "FLOW/ZONE", "FLOW/AREA", "FLOW/EXTERIORAREA", "FLOW/EXTERIORWALLAREA", "AIRCHANGES/HOUR"};
130 :
131 : constexpr std::array<std::string_view, static_cast<int>(DataHeatBalance::VentilationType::Num)> ventilationTypeNamesUC = {
132 : "NATURAL", "INTAKE", "EXHAUST", "BALANCED"};
133 :
134 : constexpr std::array<std::string_view, static_cast<int>(RoomAir::RoomAirModel::Num)> roomAirModelNamesUC = {"USERDEFINED",
135 : "MIXING",
136 : "ONENODEDISPLACEMENTVENTILATION",
137 : "THREENODEDISPLACEMENTVENTILATION",
138 : "CROSSVENTILATION",
139 : "UNDERFLOORAIRDISTRIBUTIONINTERIOR",
140 : "UNDERFLOORAIRDISTRIBUTIONEXTERIOR",
141 : "AIRFLOWNETWORK"};
142 :
143 : constexpr std::array<std::string_view, static_cast<int>(RoomAir::CouplingScheme::Num)> couplingSchemeNamesUC = {"DIRECT", "INDIRECT"};
144 :
145 2804482 : void ManageAirHeatBalance(EnergyPlusData &state)
146 : {
147 :
148 : // SUBROUTINE INFORMATION:
149 : // AUTHOR Richard Liesen
150 : // DATE WRITTEN February 1998
151 :
152 : // PURPOSE OF THIS SUBROUTINE:
153 : // This subroutine manages the heat air balance method of calculating
154 : // building thermal loads. It is called from the HeatBalanceManager
155 : // at the time step level. This driver manages the calls to all of
156 : // the other drivers and simulation algorithms.
157 :
158 : // Obtains and Allocates heat balance related parameters from input file
159 2804482 : if (state.dataHeatBalAirMgr->ManageAirHeatBalanceGetInputFlag) {
160 796 : GetAirHeatBalanceInput(state);
161 796 : state.dataHeatBalAirMgr->ManageAirHeatBalanceGetInputFlag = false;
162 : }
163 :
164 2804482 : InitAirHeatBalance(state); // Initialize all heat balance related parameters
165 :
166 : // Solve the zone heat balance 'Detailed' solution
167 : // Call the air surface heat balances
168 2804482 : CalcHeatBalanceAir(state);
169 :
170 2804482 : ReportZoneMeanAirTemp(state);
171 2804482 : }
172 :
173 796 : void GetAirHeatBalanceInput(EnergyPlusData &state)
174 : {
175 :
176 : // SUBROUTINE INFORMATION:
177 : // AUTHOR Richard Liesen
178 : // DATE WRITTEN February 1998
179 :
180 : // PURPOSE OF THIS SUBROUTINE:
181 : // This subroutine is the main routine to call other input routines
182 :
183 : // METHODOLOGY EMPLOYED:
184 : // Uses the status flags to trigger events.
185 :
186 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
187 796 : bool ErrorsFound = false;
188 :
189 796 : GetAirFlowFlag(state, ErrorsFound);
190 :
191 796 : SetZoneMassConservationFlag(state);
192 :
193 : // get input parameters for modeling of room air flow
194 796 : GetRoomAirModelParameters(state, ErrorsFound);
195 :
196 796 : if (ErrorsFound) {
197 0 : ShowFatalError(state, "GetAirHeatBalanceInput: Errors found in getting Air inputs");
198 : }
199 796 : }
200 :
201 796 : void GetAirFlowFlag(EnergyPlusData &state, bool &ErrorsFound) // Set to true if errors found
202 : {
203 :
204 : // SUBROUTINE INFORMATION:
205 : // AUTHOR Garrett Westmacott
206 : // DATE WRITTEN February 2000
207 : // MODIFIED Oct 2003, FCW: Change "Infiltration-Air Change Rate" from Sum to State
208 :
209 : // PURPOSE OF THIS SUBROUTINE:
210 : // This subroutine calls the routine to get simple air flow input data.
211 :
212 : // METHODOLOGY EMPLOYED:
213 : // Modelled after 'Modual Example' in Guide for Module Developers
214 :
215 796 : state.dataHeatBal->AirFlowFlag = true; // UseSimpleAirFlow;
216 :
217 796 : GetSimpleAirModelInputs(state, ErrorsFound);
218 796 : if (state.dataHeatBal->TotInfiltration + state.dataHeatBal->TotVentilation + state.dataHeatBal->TotMixing + state.dataHeatBal->TotCrossMixing +
219 796 : state.dataHeatBal->TotRefDoorMixing >
220 : 0) {
221 : static constexpr std::string_view Format_720("! <AirFlow Model>, Simple\n AirFlow Model, {}\n");
222 437 : print(state.files.eio, Format_720, "Simple");
223 : }
224 796 : }
225 :
226 796 : void SetZoneMassConservationFlag(EnergyPlusData &state)
227 : {
228 :
229 : // SUBROUTINE INFORMATION :
230 : // AUTHOR Bereket Nigusse, FSEC
231 : // DATE WRITTEN February 2014
232 :
233 : // PURPOSE OF THIS SUBROUTINE :
234 : // This subroutine sets the zone mass conservation flag to true.
235 :
236 798 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance &&
237 2 : state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing) {
238 10 : for (int Loop = 1; Loop <= state.dataHeatBal->TotMixing; ++Loop) {
239 8 : state.dataHeatBalFanSys->ZoneMassBalanceFlag(state.dataHeatBal->Mixing(Loop).ZonePtr) = true;
240 8 : state.dataHeatBalFanSys->ZoneMassBalanceFlag(state.dataHeatBal->Mixing(Loop).FromZone) = true;
241 : }
242 : }
243 796 : }
244 :
245 796 : void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF errors found in input
246 : {
247 :
248 : // SUBROUTINE INFORMATION:
249 : // AUTHOR Linda Lawrie
250 : // DATE WRITTEN July 2000
251 : // MODIFIED Oct 2003,FCW: change "Infiltration-Air Change Rate" from Sum to State
252 : // MODIFIED Jan 2008,LG: Allow multiple infiltration and ventilation objects per zone
253 : // May 2009, BG: added calls to setup for possible EMS override
254 : // August 2011, TKS: added refrigeration door mixing
255 :
256 : // PURPOSE OF THIS SUBROUTINE:
257 : // This subroutine gets the input for the "simple" air flow model.
258 :
259 : // SUBROUTINE PARAMETER DEFINITIONS:
260 796 : Real64 constexpr VentilTempLimit = 100.0; // degrees Celsius
261 796 : Real64 constexpr MixingTempLimit = 100.0; // degrees Celsius
262 796 : Real64 constexpr VentilWSLimit = 40.0; // m/s
263 : static constexpr std::string_view RoutineName("GetSimpleAirModelInputs: "); // include trailing blank space
264 : // Refrigeration Door Mixing Protection types, factors used to moderate mixing flow.
265 796 : Real64 constexpr RefDoorNone = 0.0;
266 796 : Real64 constexpr RefDoorAirCurtain = 0.5;
267 796 : Real64 constexpr RefDoorStripCurtain = 0.9;
268 :
269 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
270 : int NumAlpha; // Number of Alphas for each GetobjectItem call
271 : int NumNumber; // Number of Numbers for each GetobjectItem call
272 : int NumArgs;
273 : int IOStat;
274 796 : Array1D_string cAlphaFieldNames;
275 796 : Array1D_string cNumericFieldNames;
276 796 : Array1D_bool lNumericFieldBlanks;
277 796 : Array1D_bool lAlphaFieldBlanks;
278 796 : Array1D_string cAlphaArgs;
279 796 : Array1D<Real64> rNumericArgs;
280 :
281 796 : Array1D_bool RepVarSet;
282 :
283 796 : std::string StringOut;
284 796 : std::string NameThisObject;
285 796 : Array1D<Real64> TotInfilVentFlow;
286 796 : Array1D<Real64> TotMixingFlow;
287 796 : Array1D<Real64> ZoneMixingNum;
288 : int ConnectionNumber;
289 : int ZoneNumA;
290 : int ZoneNumB;
291 :
292 : // Formats
293 : static constexpr std::string_view Format_720(" {} Airflow Stats Nominal, {},{},{},{:.2R},{:.1R},");
294 : static constexpr std::string_view Format_721(
295 : "! <{} Airflow Stats Nominal>,Name,Schedule Name,Zone Name, Zone Floor Area {{m2}}, # Zone Occupants,{}\n");
296 : static constexpr std::string_view Format_722(" {}, {}\n");
297 :
298 796 : RepVarSet.dimension(state.dataGlobal->NumOfZones, true);
299 :
300 : // Following used for reporting
301 796 : state.dataHeatBal->ZnAirRpt.allocate(state.dataGlobal->NumOfZones);
302 796 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
303 2 : state.dataHeatBal->spaceAirRpt.allocate(state.dataGlobal->numSpaces);
304 : }
305 :
306 5852 : for (int Loop = 1; Loop <= state.dataGlobal->NumOfZones; ++Loop) {
307 5056 : std::string const &name = state.dataHeatBal->Zone(Loop).Name;
308 5056 : auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(Loop);
309 5056 : thisZnAirRpt.setUpOutputVars(state, DataStringGlobals::zonePrefix, name);
310 5056 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
311 28 : for (int spaceNum : state.dataHeatBal->Zone(Loop).spaceIndexes) {
312 16 : state.dataHeatBal->spaceAirRpt(spaceNum).setUpOutputVars(
313 16 : state, DataStringGlobals::spacePrefix, state.dataHeatBal->space(spaceNum).Name);
314 12 : }
315 : }
316 :
317 : // CurrentModuleObject='Zone'
318 5056 : if (state.dataGlobal->DisplayAdvancedReportVariables) {
319 120 : SetupOutputVariable(state,
320 : "Zone Phase Change Material Melting Enthalpy",
321 : Constant::Units::J_kg,
322 60 : thisZnAirRpt.SumEnthalpyM,
323 : OutputProcessor::TimeStepType::Zone,
324 : OutputProcessor::StoreType::Average,
325 : name);
326 120 : SetupOutputVariable(state,
327 : "Zone Phase Change Material Freezing Enthalpy",
328 : Constant::Units::J_kg,
329 60 : thisZnAirRpt.SumEnthalpyH,
330 : OutputProcessor::TimeStepType::Zone,
331 : OutputProcessor::StoreType::Average,
332 : name);
333 : }
334 :
335 10112 : SetupOutputVariable(state,
336 : "Zone Exfiltration Heat Transfer Rate",
337 : Constant::Units::W,
338 5056 : thisZnAirRpt.ExfilTotalLoss,
339 : OutputProcessor::TimeStepType::System,
340 : OutputProcessor::StoreType::Average,
341 : name);
342 10112 : SetupOutputVariable(state,
343 : "Zone Exfiltration Sensible Heat Transfer Rate",
344 : Constant::Units::W,
345 5056 : thisZnAirRpt.ExfilSensiLoss,
346 : OutputProcessor::TimeStepType::System,
347 : OutputProcessor::StoreType::Average,
348 : name);
349 10112 : SetupOutputVariable(state,
350 : "Zone Exfiltration Latent Heat Transfer Rate",
351 : Constant::Units::W,
352 5056 : thisZnAirRpt.ExfilLatentLoss,
353 : OutputProcessor::TimeStepType::System,
354 : OutputProcessor::StoreType::Average,
355 : name);
356 10112 : SetupOutputVariable(state,
357 : "Zone Exhaust Air Heat Transfer Rate",
358 : Constant::Units::W,
359 5056 : thisZnAirRpt.ExhTotalLoss,
360 : OutputProcessor::TimeStepType::System,
361 : OutputProcessor::StoreType::Average,
362 : name);
363 10112 : SetupOutputVariable(state,
364 : "Zone Exhaust Air Sensible Heat Transfer Rate",
365 : Constant::Units::W,
366 5056 : thisZnAirRpt.ExhSensiLoss,
367 : OutputProcessor::TimeStepType::System,
368 : OutputProcessor::StoreType::Average,
369 : name);
370 10112 : SetupOutputVariable(state,
371 : "Zone Exhaust Air Latent Heat Transfer Rate",
372 : Constant::Units::W,
373 5056 : thisZnAirRpt.ExhLatentLoss,
374 : OutputProcessor::TimeStepType::System,
375 : OutputProcessor::StoreType::Average,
376 : name);
377 : }
378 :
379 1592 : SetupOutputVariable(state,
380 : "Site Total Zone Exfiltration Heat Loss",
381 : Constant::Units::J,
382 796 : state.dataHeatBal->ZoneTotalExfiltrationHeatLoss,
383 : OutputProcessor::TimeStepType::System,
384 : OutputProcessor::StoreType::Sum,
385 : "Environment");
386 1592 : SetupOutputVariable(state,
387 : "Site Total Zone Exhaust Air Heat Loss",
388 : Constant::Units::J,
389 796 : state.dataHeatBal->ZoneTotalExhaustHeatLoss,
390 : OutputProcessor::TimeStepType::System,
391 : OutputProcessor::StoreType::Sum,
392 : "Environment");
393 :
394 796 : std::string cCurrentModuleObject = "ZoneAirBalance:OutdoorAir";
395 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
396 796 : int maxAlpha = NumAlpha;
397 796 : int maxNumber = NumNumber;
398 796 : cCurrentModuleObject = "ZoneInfiltration:EffectiveLeakageArea";
399 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
400 796 : maxAlpha = max(NumAlpha, maxAlpha);
401 796 : maxNumber = max(NumNumber, maxNumber);
402 796 : cCurrentModuleObject = "ZoneInfiltration:FlowCoefficient";
403 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
404 796 : maxAlpha = max(NumAlpha, maxAlpha);
405 796 : maxNumber = max(NumNumber, maxNumber);
406 796 : cCurrentModuleObject = "ZoneInfiltration:DesignFlowRate";
407 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
408 796 : maxAlpha = max(NumAlpha, maxAlpha);
409 796 : maxNumber = max(NumNumber, maxNumber);
410 796 : cCurrentModuleObject = "ZoneVentilation:DesignFlowRate";
411 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
412 796 : maxAlpha = max(NumAlpha, maxAlpha);
413 796 : maxNumber = max(NumNumber, maxNumber);
414 796 : cCurrentModuleObject = "ZoneVentilation:WindandStackOpenArea";
415 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
416 796 : maxAlpha = max(NumAlpha, maxAlpha);
417 796 : maxNumber = max(NumNumber, maxNumber);
418 796 : cCurrentModuleObject = "ZoneMixing";
419 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
420 796 : maxAlpha = max(NumAlpha, maxAlpha);
421 796 : maxNumber = max(NumNumber, maxNumber);
422 796 : cCurrentModuleObject = "ZoneCrossMixing";
423 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
424 796 : maxAlpha = max(NumAlpha, maxAlpha);
425 796 : maxNumber = max(NumNumber, maxNumber);
426 796 : cCurrentModuleObject = "ZoneRefrigerationDoorMixing";
427 796 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, NumArgs, NumAlpha, NumNumber);
428 796 : maxAlpha = max(NumAlpha, maxAlpha);
429 796 : maxNumber = max(NumNumber, maxNumber);
430 :
431 796 : cAlphaArgs.allocate(maxAlpha);
432 796 : cAlphaFieldNames.allocate(maxAlpha);
433 796 : cNumericFieldNames.allocate(maxNumber);
434 796 : rNumericArgs.dimension(maxNumber, 0.0);
435 796 : lAlphaFieldBlanks.dimension(maxAlpha, true);
436 796 : lNumericFieldBlanks.dimension(maxNumber, true);
437 :
438 796 : cCurrentModuleObject = "ZoneAirBalance:OutdoorAir";
439 796 : state.dataHeatBal->TotZoneAirBalance = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
440 :
441 796 : state.dataHeatBal->ZoneAirBalance.allocate(state.dataHeatBal->TotZoneAirBalance);
442 :
443 797 : for (int Loop = 1; Loop <= state.dataHeatBal->TotZoneAirBalance; ++Loop) {
444 1 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
445 : cCurrentModuleObject,
446 : Loop,
447 : cAlphaArgs,
448 : NumAlpha,
449 : rNumericArgs,
450 : NumNumber,
451 : IOStat,
452 : lNumericFieldBlanks,
453 : lAlphaFieldBlanks,
454 : cAlphaFieldNames,
455 : cNumericFieldNames);
456 1 : bool IsNotOK = false;
457 1 : auto &thisZoneAirBalance = state.dataHeatBal->ZoneAirBalance(Loop);
458 1 : thisZoneAirBalance.Name = cAlphaArgs(1);
459 1 : thisZoneAirBalance.ZoneName = cAlphaArgs(2);
460 1 : thisZoneAirBalance.ZonePtr = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone);
461 1 : if (thisZoneAirBalance.ZonePtr == 0) {
462 0 : ShowSevereError(state,
463 0 : format(R"({}{}="{}", invalid (not found) {}="{}".)",
464 : RoutineName,
465 : cCurrentModuleObject,
466 : cAlphaArgs(1),
467 : cAlphaFieldNames(2),
468 : cAlphaArgs(2)));
469 0 : ErrorsFound = true;
470 : } else {
471 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).zoneOABalanceIndex = Loop;
472 : }
473 1 : GlobalNames::IntraObjUniquenessCheck(
474 2 : state, cAlphaArgs(2), cCurrentModuleObject, cAlphaFieldNames(2), state.dataHeatBalAirMgr->UniqueZoneNames, IsNotOK);
475 1 : if (IsNotOK) {
476 0 : ShowSevereError(state,
477 0 : format(R"({}{}="{}", a duplicated object {}="{}" is found.)",
478 : RoutineName,
479 : cCurrentModuleObject,
480 : cAlphaArgs(1),
481 : cAlphaFieldNames(2),
482 : cAlphaArgs(2)));
483 0 : ShowContinueError(state, format("A zone can only have one {} object.", cCurrentModuleObject));
484 0 : ErrorsFound = true;
485 : }
486 :
487 : {
488 1 : thisZoneAirBalance.BalanceMethod = static_cast<DataHeatBalance::AirBalance>(
489 1 : getEnumValue(DataHeatBalance::AirBalanceTypeNamesUC,
490 2 : Util::makeUPPER(cAlphaArgs(3)))); // Air balance method type character input-->convert to enum
491 1 : if (thisZoneAirBalance.BalanceMethod == DataHeatBalance::AirBalance::Invalid) {
492 0 : thisZoneAirBalance.BalanceMethod = DataHeatBalance::AirBalance::None;
493 0 : ShowWarningError(state,
494 0 : format("{}{} = {} not valid choice for {}={}",
495 : RoutineName,
496 : cAlphaFieldNames(3),
497 : cAlphaArgs(3),
498 : cCurrentModuleObject,
499 : cAlphaArgs(1)));
500 0 : ShowContinueError(state, "The default choice \"NONE\" is assigned");
501 : }
502 : }
503 :
504 1 : thisZoneAirBalance.InducedAirRate = rNumericArgs(1);
505 1 : if (rNumericArgs(1) < 0.0) {
506 0 : ShowSevereError(state,
507 0 : format("{}{}=\"{}\", invalid Induced Outdoor Air Due to Duct Leakage Unbalance specification [<0.0]={:.3R}",
508 : RoutineName,
509 : cCurrentModuleObject,
510 : cAlphaArgs(1),
511 : rNumericArgs(1)));
512 0 : ErrorsFound = true;
513 : }
514 :
515 1 : thisZoneAirBalance.InducedAirSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(4));
516 1 : if (thisZoneAirBalance.InducedAirSchedPtr == 0) {
517 0 : if (lAlphaFieldBlanks(4)) {
518 0 : ShowSevereError(
519 : state,
520 0 : format("{}{}=\"{}\",{} is required but field is blank.", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(4)));
521 : } else {
522 0 : ShowSevereError(state,
523 0 : format(R"({}{}="{}", invalid (not found) {}="{}".)",
524 : RoutineName,
525 : cCurrentModuleObject,
526 : cAlphaArgs(1),
527 : cAlphaFieldNames(4),
528 : cAlphaArgs(4)));
529 : }
530 0 : ErrorsFound = true;
531 : }
532 1 : if (!ScheduleManager::CheckScheduleValueMinMax(state, thisZoneAirBalance.InducedAirSchedPtr, ">=", 0.0, "<=", 1.0)) {
533 0 : ShowSevereError(
534 0 : state, format("{} = {}: Error found in {} = {}", cCurrentModuleObject, thisZoneAirBalance.Name, cAlphaFieldNames(4), cAlphaArgs(4)));
535 0 : ShowContinueError(state, "Schedule values must be (>=0., <=1.)");
536 0 : ErrorsFound = true;
537 : }
538 :
539 : // Check whether this zone is also controleld by hybrid ventilation object with ventilation control option or not
540 1 : bool ControlFlag = Avail::GetHybridVentilationControlStatus(state, thisZoneAirBalance.ZonePtr);
541 1 : if (ControlFlag && thisZoneAirBalance.BalanceMethod == DataHeatBalance::AirBalance::Quadrature) {
542 0 : thisZoneAirBalance.BalanceMethod = DataHeatBalance::AirBalance::None;
543 0 : ShowWarningError(
544 : state,
545 0 : format("{} = {}: This Zone ({}) is controlled by AvailabilityManager:HybridVentilation with Simple Airflow Control Type option.",
546 : cCurrentModuleObject,
547 0 : thisZoneAirBalance.Name,
548 : cAlphaArgs(2)));
549 0 : ShowContinueError(state,
550 : "Air balance method type QUADRATURE and Simple Airflow Control Type cannot co-exist. The NONE method is assigned");
551 : }
552 :
553 1 : if (thisZoneAirBalance.BalanceMethod == DataHeatBalance::AirBalance::Quadrature) {
554 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).zoneOAQuadratureSum = true;
555 2 : SetupOutputVariable(state,
556 : "Zone Combined Outdoor Air Sensible Heat Loss Energy",
557 : Constant::Units::J,
558 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceHeatLoss,
559 : OutputProcessor::TimeStepType::System,
560 : OutputProcessor::StoreType::Sum,
561 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
562 2 : SetupOutputVariable(state,
563 : "Zone Combined Outdoor Air Sensible Heat Gain Energy",
564 : Constant::Units::J,
565 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceHeatGain,
566 : OutputProcessor::TimeStepType::System,
567 : OutputProcessor::StoreType::Sum,
568 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
569 2 : SetupOutputVariable(state,
570 : "Zone Combined Outdoor Air Latent Heat Loss Energy",
571 : Constant::Units::J,
572 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceLatentLoss,
573 : OutputProcessor::TimeStepType::System,
574 : OutputProcessor::StoreType::Sum,
575 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
576 2 : SetupOutputVariable(state,
577 : "Zone Combined Outdoor Air Latent Heat Gain Energy",
578 : Constant::Units::J,
579 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceLatentGain,
580 : OutputProcessor::TimeStepType::System,
581 : OutputProcessor::StoreType::Sum,
582 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
583 2 : SetupOutputVariable(state,
584 : "Zone Combined Outdoor Air Total Heat Loss Energy",
585 : Constant::Units::J,
586 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceTotalLoss,
587 : OutputProcessor::TimeStepType::System,
588 : OutputProcessor::StoreType::Sum,
589 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
590 2 : SetupOutputVariable(state,
591 : "Zone Combined Outdoor Air Total Heat Gain Energy",
592 : Constant::Units::J,
593 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceTotalGain,
594 : OutputProcessor::TimeStepType::System,
595 : OutputProcessor::StoreType::Sum,
596 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
597 2 : SetupOutputVariable(state,
598 : "Zone Combined Outdoor Air Current Density Volume Flow Rate",
599 : Constant::Units::m3_s,
600 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceVdotCurDensity,
601 : OutputProcessor::TimeStepType::System,
602 : OutputProcessor::StoreType::Sum,
603 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
604 2 : SetupOutputVariable(state,
605 : "Zone Combined Outdoor Air Standard Density Volume Flow Rate",
606 : Constant::Units::m3_s,
607 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceVdotStdDensity,
608 : OutputProcessor::TimeStepType::System,
609 : OutputProcessor::StoreType::Sum,
610 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
611 2 : SetupOutputVariable(state,
612 : "Zone Combined Outdoor Air Current Density Volume",
613 : Constant::Units::m3,
614 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceVolumeCurDensity,
615 : OutputProcessor::TimeStepType::System,
616 : OutputProcessor::StoreType::Sum,
617 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
618 2 : SetupOutputVariable(state,
619 : "Zone Combined Outdoor Air Standard Density Volume",
620 : Constant::Units::m3,
621 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceVolumeStdDensity,
622 : OutputProcessor::TimeStepType::System,
623 : OutputProcessor::StoreType::Sum,
624 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
625 2 : SetupOutputVariable(state,
626 : "Zone Combined Outdoor Air Mass",
627 : Constant::Units::kg,
628 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceMass,
629 : OutputProcessor::TimeStepType::System,
630 : OutputProcessor::StoreType::Sum,
631 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
632 2 : SetupOutputVariable(state,
633 : "Zone Combined Outdoor Air Mass Flow Rate",
634 : Constant::Units::kg_s,
635 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceMdot,
636 : OutputProcessor::TimeStepType::System,
637 : OutputProcessor::StoreType::Average,
638 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
639 2 : SetupOutputVariable(state,
640 : "Zone Combined Outdoor Air Changes per Hour",
641 : Constant::Units::ach,
642 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceAirChangeRate,
643 : OutputProcessor::TimeStepType::System,
644 : OutputProcessor::StoreType::Average,
645 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
646 2 : SetupOutputVariable(state,
647 : "Zone Combined Outdoor Air Fan Electricity Energy",
648 : Constant::Units::J,
649 1 : state.dataHeatBal->ZnAirRpt(thisZoneAirBalance.ZonePtr).OABalanceFanElec,
650 : OutputProcessor::TimeStepType::System,
651 : OutputProcessor::StoreType::Sum,
652 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name,
653 : Constant::eResource::Electricity,
654 : OutputProcessor::Group::Building,
655 : OutputProcessor::EndUseCat::Fans,
656 : "Ventilation (simple)",
657 1 : state.dataHeatBal->Zone(thisZoneAirBalance.ZonePtr).Name);
658 : }
659 : }
660 :
661 : // Set up and process ZoneInfiltration:* inputs
662 :
663 796 : cCurrentModuleObject = "ZoneInfiltration:DesignFlowRate";
664 796 : int numDesignFlowInfiltrationObjects = 0;
665 796 : int totDesignFlowInfiltration = 0; // Total ZoneInfiltration:DesignFlowRate instances after expansion to spaces
666 796 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> infiltrationDesignFlowRateObjects;
667 796 : InternalHeatGains::setupIHGZonesAndSpaces(
668 : state, cCurrentModuleObject, infiltrationDesignFlowRateObjects, numDesignFlowInfiltrationObjects, totDesignFlowInfiltration, ErrorsFound);
669 :
670 796 : cCurrentModuleObject = "ZoneInfiltration:EffectiveLeakageArea";
671 796 : int numLeakageAreaInfiltrationObjects = 0;
672 796 : int totLeakageAreaInfiltration = 0; // Total ZoneInfiltration:EffectiveLeakageArea instances after expansion to spaces
673 796 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> infiltrationLeakageAreaObjects;
674 796 : bool const zoneListNotAllowed = true;
675 796 : InternalHeatGains::setupIHGZonesAndSpaces(state,
676 : cCurrentModuleObject,
677 : infiltrationLeakageAreaObjects,
678 : numLeakageAreaInfiltrationObjects,
679 : totLeakageAreaInfiltration,
680 : ErrorsFound,
681 : zoneListNotAllowed);
682 :
683 796 : cCurrentModuleObject = "ZoneInfiltration:FlowCoefficient";
684 796 : int numFlowCoefficientInfiltrationObjects = 0;
685 796 : int totFlowCoefficientInfiltration = 0; // Total ZoneInfiltration:FlowCoefficient instances after expansion to spaces
686 796 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> infiltrationFlowCoefficientObjects;
687 796 : InternalHeatGains::setupIHGZonesAndSpaces(state,
688 : cCurrentModuleObject,
689 : infiltrationFlowCoefficientObjects,
690 : numFlowCoefficientInfiltrationObjects,
691 : totFlowCoefficientInfiltration,
692 : ErrorsFound,
693 : zoneListNotAllowed);
694 :
695 796 : state.dataHeatBal->TotInfiltration = totDesignFlowInfiltration + totLeakageAreaInfiltration + totFlowCoefficientInfiltration;
696 796 : state.dataHeatBal->Infiltration.allocate(state.dataHeatBal->TotInfiltration);
697 796 : state.dataHeatBalAirMgr->UniqueInfiltrationNames.reserve(static_cast<unsigned>(state.dataHeatBal->TotInfiltration));
698 :
699 796 : int infiltrationNum = 0;
700 796 : if (totDesignFlowInfiltration > 0) {
701 429 : cCurrentModuleObject = "ZoneInfiltration:DesignFlowRate";
702 3873 : for (int infilInputNum = 1; infilInputNum <= numDesignFlowInfiltrationObjects; ++infilInputNum) {
703 :
704 3444 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
705 : cCurrentModuleObject,
706 : infilInputNum,
707 : cAlphaArgs,
708 : NumAlpha,
709 : rNumericArgs,
710 : NumNumber,
711 : IOStat,
712 : lNumericFieldBlanks,
713 : lAlphaFieldBlanks,
714 : cAlphaFieldNames,
715 : cNumericFieldNames);
716 :
717 : // Create one Infiltration instance for every space associated with this input object
718 3444 : auto &thisInfiltrationInput = infiltrationDesignFlowRateObjects(infilInputNum);
719 6957 : for (int Item1 = 1; Item1 <= thisInfiltrationInput.numOfSpaces; ++Item1) {
720 3513 : ++infiltrationNum;
721 3513 : auto &thisInfiltration = state.dataHeatBal->Infiltration(infiltrationNum);
722 3513 : thisInfiltration.Name = thisInfiltrationInput.names(Item1);
723 3513 : thisInfiltration.spaceIndex = thisInfiltrationInput.spaceNums(Item1);
724 3513 : auto &thisSpace = state.dataHeatBal->space(thisInfiltration.spaceIndex);
725 3513 : thisInfiltration.ZonePtr = thisSpace.zoneNum;
726 3513 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
727 :
728 3513 : thisInfiltration.ModelType = DataHeatBalance::InfiltrationModelType::DesignFlowRate;
729 3513 : if (lAlphaFieldBlanks(3)) {
730 0 : thisInfiltration.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
731 : } else {
732 3513 : thisInfiltration.SchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
733 3513 : if (thisInfiltration.SchedPtr == 0) {
734 0 : if (Item1 == 1) { // avoid repeated error messages from the same input object
735 0 : ShowSevereError(state,
736 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
737 : RoutineName,
738 : cCurrentModuleObject,
739 : cAlphaArgs(1),
740 : cAlphaFieldNames(3),
741 : cAlphaArgs(3)));
742 0 : ErrorsFound = true;
743 : }
744 : }
745 : }
746 :
747 : // Set space flow fractions
748 : // Infiltration equipment design level calculation method.
749 3513 : AirflowSpecAlt flow = static_cast<AirflowSpecAlt>(getEnumValue(airflowAltNamesUC, cAlphaArgs(4))); // NOLINT(modernize-use-auto)
750 3513 : switch (flow) {
751 1689 : case AirflowSpecAlt::Flow:
752 : case AirflowSpecAlt::FlowPerZone:
753 1689 : if (lNumericFieldBlanks(1)) {
754 0 : ShowWarningError(state,
755 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Infiltration will result.",
756 : RoutineName,
757 : cCurrentModuleObject,
758 0 : thisInfiltration.Name,
759 : cAlphaFieldNames(4),
760 : cNumericFieldNames(1)));
761 : } else {
762 1689 : Real64 spaceFrac = 1.0;
763 1689 : if (!thisInfiltrationInput.spaceListActive && (thisInfiltrationInput.numOfSpaces > 1)) {
764 18 : Real64 const zoneVolume = thisZone.Volume;
765 18 : if (zoneVolume > 0.0) {
766 18 : spaceFrac = thisSpace.Volume / zoneVolume;
767 : } else {
768 0 : ShowSevereError(state, format("{}Zone volume is zero when allocating Infiltration to Spaces.", RoutineName));
769 0 : ShowContinueError(
770 : state,
771 0 : format("Occurs for {}=\"{}\" in Zone=\"{}\".", cCurrentModuleObject, thisInfiltrationInput.Name, thisZone.Name));
772 0 : ErrorsFound = true;
773 : }
774 : }
775 :
776 1689 : thisInfiltration.DesignLevel = rNumericArgs(1) * spaceFrac;
777 : }
778 1689 : break;
779 :
780 2 : case AirflowSpecAlt::FlowPerArea:
781 2 : if (thisInfiltration.ZonePtr != 0) {
782 2 : if (rNumericArgs(2) >= 0.0) {
783 2 : thisInfiltration.DesignLevel = rNumericArgs(2) * thisSpace.FloorArea;
784 2 : if (thisInfiltration.ZonePtr > 0) {
785 2 : if (thisSpace.FloorArea <= 0.0) {
786 0 : ShowWarningError(state,
787 0 : format("{}{}=\"{}\", {} specifies {}, but Space Floor Area = 0. 0 Infiltration will result.",
788 : RoutineName,
789 : cCurrentModuleObject,
790 0 : thisInfiltration.Name,
791 : cAlphaFieldNames(4),
792 : cNumericFieldNames(2)));
793 : }
794 : }
795 : } else {
796 0 : ShowSevereError(state,
797 0 : format("{}{}=\"{}\", invalid flow/area specification [<0.0]={:.3R}",
798 : RoutineName,
799 : cCurrentModuleObject,
800 0 : thisInfiltration.Name,
801 : rNumericArgs(2)));
802 0 : ErrorsFound = true;
803 : }
804 : }
805 2 : if (lNumericFieldBlanks(2)) {
806 0 : ShowWarningError(state,
807 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Infiltration will result.",
808 : RoutineName,
809 : cCurrentModuleObject,
810 0 : thisInfiltration.Name,
811 : cAlphaFieldNames(4),
812 : cNumericFieldNames(2)));
813 : }
814 2 : break;
815 :
816 1228 : case AirflowSpecAlt::FlowPerExteriorArea:
817 1228 : if (thisInfiltration.ZonePtr != 0) {
818 1228 : if (rNumericArgs(3) >= 0.0) {
819 1228 : thisInfiltration.DesignLevel = rNumericArgs(3) * thisSpace.ExteriorTotalSurfArea;
820 1228 : if (thisSpace.ExteriorTotalSurfArea <= 0.0) {
821 40 : ShowWarningError(state,
822 60 : format("{}{}=\"{}\", {} specifies {}, but Exterior Surface Area = 0. 0 Infiltration will result.",
823 : RoutineName,
824 : cCurrentModuleObject,
825 20 : thisInfiltration.Name,
826 : cAlphaFieldNames(4),
827 : cNumericFieldNames(3)));
828 : }
829 : } else {
830 0 : ShowSevereError(state,
831 0 : format("{}{} = \"{}\", invalid flow/exteriorarea specification [<0.0]={:.3R}",
832 : RoutineName,
833 : cCurrentModuleObject,
834 0 : thisInfiltration.Name,
835 : rNumericArgs(3)));
836 0 : ErrorsFound = true;
837 : }
838 : }
839 1228 : if (lNumericFieldBlanks(3)) {
840 0 : ShowWarningError(state,
841 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Infiltration will result.",
842 : RoutineName,
843 : cCurrentModuleObject,
844 0 : thisInfiltration.Name,
845 : cAlphaFieldNames(4),
846 : cNumericFieldNames(3)));
847 : }
848 1228 : break;
849 :
850 475 : case AirflowSpecAlt::FlowPerExteriorWallArea:
851 475 : if (thisInfiltration.ZonePtr != 0) {
852 475 : if (rNumericArgs(3) >= 0.0) {
853 475 : thisInfiltration.DesignLevel = rNumericArgs(3) * thisSpace.ExtGrossWallArea;
854 475 : if (thisSpace.ExtGrossWallArea <= 0.0) {
855 0 : ShowWarningError(state,
856 0 : format("{}{}=\"{}\", {} specifies {}, but Exterior Wall Area = 0. 0 Infiltration will result.",
857 : RoutineName,
858 : cCurrentModuleObject,
859 0 : thisInfiltration.Name,
860 : cAlphaFieldNames(4),
861 : cNumericFieldNames(3)));
862 : }
863 : } else {
864 0 : ShowSevereError(state,
865 0 : format("{}{} = \"{}\", invalid flow/exteriorwallarea specification [<0.0]={:.3R}",
866 : RoutineName,
867 : cCurrentModuleObject,
868 0 : thisInfiltration.Name,
869 : rNumericArgs(3)));
870 0 : ErrorsFound = true;
871 : }
872 : }
873 475 : if (lNumericFieldBlanks(3)) {
874 0 : ShowWarningError(state,
875 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Infiltration will result.",
876 : RoutineName,
877 : cCurrentModuleObject,
878 0 : thisInfiltration.Name,
879 : cAlphaFieldNames(4),
880 : cNumericFieldNames(3)));
881 : }
882 475 : break;
883 :
884 119 : case AirflowSpecAlt::AirChanges:
885 119 : if (thisInfiltration.spaceIndex != 0) {
886 119 : if (rNumericArgs(4) >= 0.0) {
887 119 : thisInfiltration.DesignLevel = rNumericArgs(4) * thisSpace.Volume / Constant::SecInHour;
888 119 : if (thisSpace.Volume <= 0.0) {
889 0 : ShowWarningError(state,
890 0 : format("{}{}=\"{}\", {} specifies {}, but Space Volume = 0. 0 Infiltration will result.",
891 : RoutineName,
892 : cCurrentModuleObject,
893 0 : thisInfiltration.Name,
894 : cAlphaFieldNames(4),
895 : cNumericFieldNames(4)));
896 : }
897 : } else {
898 0 : ShowSevereError(state,
899 0 : format("{}In {} = \"{}\", invalid ACH (air changes per hour) specification [<0.0]={:.3R}",
900 : RoutineName,
901 : cCurrentModuleObject,
902 0 : thisInfiltration.Name,
903 : rNumericArgs(4)));
904 0 : ErrorsFound = true;
905 : }
906 : }
907 119 : if (lNumericFieldBlanks(4)) {
908 0 : ShowWarningError(state,
909 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Infiltration will result.",
910 : RoutineName,
911 : cCurrentModuleObject,
912 0 : thisInfiltrationInput.Name,
913 : cAlphaFieldNames(4),
914 : cNumericFieldNames(4)));
915 : }
916 119 : break;
917 :
918 0 : default:
919 0 : if (Item1 == 1) {
920 0 : ShowSevereError(
921 : state,
922 0 : format("{}{}=\"{}\", invalid calculation method={}", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(4)));
923 0 : ErrorsFound = true;
924 : }
925 : }
926 :
927 3513 : thisInfiltration.ConstantTermCoef = !lNumericFieldBlanks(5) ? rNumericArgs(5) : 1.0;
928 3513 : thisInfiltration.TemperatureTermCoef = !lNumericFieldBlanks(6) ? rNumericArgs(6) : 0.0;
929 3513 : thisInfiltration.VelocityTermCoef = !lNumericFieldBlanks(7) ? rNumericArgs(7) : 0.0;
930 3513 : thisInfiltration.VelocitySQTermCoef = !lNumericFieldBlanks(8) ? rNumericArgs(8) : 0.0;
931 :
932 3513 : if (thisInfiltration.ConstantTermCoef == 0.0 && thisInfiltration.TemperatureTermCoef == 0.0 &&
933 1651 : thisInfiltration.VelocityTermCoef == 0.0 && thisInfiltration.VelocitySQTermCoef == 0.0) {
934 0 : if (Item1 == 1) {
935 0 : ShowWarningError(
936 : state,
937 0 : format(
938 : R"({}{}="{}", in {}="{}".)", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2)));
939 0 : ShowContinueError(state, "Infiltration Coefficients are all zero. No Infiltration will be reported.");
940 : }
941 : }
942 : }
943 : }
944 : }
945 :
946 796 : if (totLeakageAreaInfiltration > 0) {
947 2 : cCurrentModuleObject = "ZoneInfiltration:EffectiveLeakageArea";
948 6 : for (int infilInputNum = 1; infilInputNum <= numLeakageAreaInfiltrationObjects; ++infilInputNum) {
949 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
950 : cCurrentModuleObject,
951 : infilInputNum,
952 : cAlphaArgs,
953 : NumAlpha,
954 : rNumericArgs,
955 : NumNumber,
956 : IOStat,
957 : lNumericFieldBlanks,
958 : lAlphaFieldBlanks,
959 : cAlphaFieldNames,
960 : cNumericFieldNames);
961 : // Create one Infiltration instance for every space associated with this input object
962 4 : auto &thisInfiltrationInput = infiltrationLeakageAreaObjects(infilInputNum);
963 8 : for (int Item1 = 1; Item1 <= thisInfiltrationInput.numOfSpaces; ++Item1) {
964 4 : ++infiltrationNum;
965 4 : auto &thisInfiltration = state.dataHeatBal->Infiltration(infiltrationNum);
966 4 : thisInfiltration.Name = thisInfiltrationInput.names(Item1);
967 4 : thisInfiltration.spaceIndex = thisInfiltrationInput.spaceNums(Item1);
968 4 : auto &thisSpace = state.dataHeatBal->space(thisInfiltration.spaceIndex);
969 4 : thisInfiltration.ZonePtr = thisSpace.zoneNum;
970 4 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
971 :
972 4 : thisInfiltration.ModelType = DataHeatBalance::InfiltrationModelType::ShermanGrimsrud;
973 :
974 4 : if (lAlphaFieldBlanks(3)) {
975 0 : thisInfiltration.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
976 : } else {
977 4 : thisInfiltration.SchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
978 4 : if (thisInfiltration.SchedPtr == 0) {
979 0 : ShowSevereError(state,
980 0 : format(R"({}{}="{}", invalid (not found) {}="{}".)",
981 : RoutineName,
982 : cCurrentModuleObject,
983 : cAlphaArgs(1),
984 : cAlphaFieldNames(3),
985 : cAlphaArgs(3)));
986 0 : ErrorsFound = true;
987 : }
988 : }
989 4 : thisInfiltration.BasicStackCoefficient = rNumericArgs(2);
990 4 : thisInfiltration.BasicWindCoefficient = rNumericArgs(3);
991 :
992 4 : if (lNumericFieldBlanks(1)) {
993 0 : ShowWarningError(state,
994 0 : format("{}{}=\"{}\", field {} is blank. 0 Infiltration will result.",
995 : RoutineName,
996 : cCurrentModuleObject,
997 0 : thisInfiltrationInput.Name,
998 : cNumericFieldNames(1)));
999 : } else {
1000 4 : Real64 spaceFrac = 1.0;
1001 4 : if (!thisInfiltrationInput.spaceListActive && (thisInfiltrationInput.numOfSpaces > 1)) {
1002 0 : Real64 const zoneExteriorTotalSurfArea = thisZone.ExteriorTotalSurfArea;
1003 0 : if (zoneExteriorTotalSurfArea > 0.0) {
1004 0 : spaceFrac = thisSpace.ExteriorTotalSurfArea / zoneExteriorTotalSurfArea;
1005 : } else {
1006 0 : ShowSevereError(state,
1007 0 : format("{}Zone exterior surface area is zero when allocating Infiltration to Spaces.", RoutineName));
1008 0 : ShowContinueError(
1009 : state,
1010 0 : format("Occurs for {}=\"{}\" in Zone=\"{}\".", cCurrentModuleObject, thisInfiltrationInput.Name, thisZone.Name));
1011 0 : ErrorsFound = true;
1012 : }
1013 : }
1014 :
1015 4 : thisInfiltration.LeakageArea = rNumericArgs(1) * spaceFrac;
1016 : }
1017 : // check if space has exterior surfaces
1018 4 : if (thisInfiltration.spaceIndex > 0) {
1019 4 : if (thisSpace.ExteriorTotalSurfArea <= 0.0) {
1020 0 : ShowWarningError(state,
1021 0 : format(R"({}{}="{}", Space="{}" does not have surfaces exposed to outdoors.)",
1022 : RoutineName,
1023 : cCurrentModuleObject,
1024 0 : thisInfiltrationInput.Name,
1025 0 : thisSpace.Name));
1026 0 : ShowContinueError(state, "Infiltration model is appropriate for exterior spaces not interior spaces, simulation continues.");
1027 : }
1028 : }
1029 : }
1030 : }
1031 : }
1032 :
1033 796 : if (totFlowCoefficientInfiltration > 0) {
1034 2 : cCurrentModuleObject = "ZoneInfiltration:FlowCoefficient";
1035 6 : for (int infilInputNum = 1; infilInputNum <= numFlowCoefficientInfiltrationObjects; ++infilInputNum) {
1036 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1037 : cCurrentModuleObject,
1038 : infilInputNum,
1039 : cAlphaArgs,
1040 : NumAlpha,
1041 : rNumericArgs,
1042 : NumNumber,
1043 : IOStat,
1044 : lNumericFieldBlanks,
1045 : lAlphaFieldBlanks,
1046 : cAlphaFieldNames,
1047 : cNumericFieldNames);
1048 : // Create one Infiltration instance for every space associated with this input object
1049 4 : auto &thisInfiltrationInput = infiltrationFlowCoefficientObjects(infilInputNum);
1050 8 : for (int Item1 = 1; Item1 <= thisInfiltrationInput.numOfSpaces; ++Item1) {
1051 4 : ++infiltrationNum;
1052 4 : auto &thisInfiltration = state.dataHeatBal->Infiltration(infiltrationNum);
1053 4 : thisInfiltration.Name = thisInfiltrationInput.names(Item1);
1054 4 : thisInfiltration.spaceIndex = thisInfiltrationInput.spaceNums(Item1);
1055 4 : auto &thisSpace = state.dataHeatBal->space(thisInfiltration.spaceIndex);
1056 4 : thisInfiltration.ZonePtr = thisSpace.zoneNum;
1057 4 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
1058 :
1059 4 : thisInfiltration.ModelType = DataHeatBalance::InfiltrationModelType::AIM2;
1060 :
1061 4 : if (lAlphaFieldBlanks(3)) {
1062 0 : thisInfiltration.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
1063 : } else {
1064 4 : thisInfiltration.SchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
1065 4 : if (thisInfiltration.SchedPtr == 0) {
1066 0 : ShowSevereError(state,
1067 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
1068 : RoutineName,
1069 : cCurrentModuleObject,
1070 : cAlphaArgs(1),
1071 : cAlphaFieldNames(3),
1072 : cAlphaArgs(3)));
1073 0 : ErrorsFound = true;
1074 : }
1075 : }
1076 4 : thisInfiltration.AIM2StackCoefficient = rNumericArgs(2);
1077 4 : thisInfiltration.PressureExponent = rNumericArgs(3);
1078 4 : thisInfiltration.AIM2WindCoefficient = rNumericArgs(4);
1079 4 : thisInfiltration.ShelterFactor = rNumericArgs(5);
1080 :
1081 4 : if (lNumericFieldBlanks(1)) {
1082 0 : ShowWarningError(state,
1083 0 : format("{}{}=\"{}\", field {} is blank. 0 Infiltration will result.",
1084 : RoutineName,
1085 : cCurrentModuleObject,
1086 0 : thisInfiltrationInput.Name,
1087 : cNumericFieldNames(1)));
1088 : } else {
1089 4 : Real64 spaceFrac = 1.0;
1090 4 : if (!thisInfiltrationInput.spaceListActive && (thisInfiltrationInput.numOfSpaces > 1)) {
1091 0 : Real64 const zoneExteriorTotalSurfArea = thisZone.ExteriorTotalSurfArea;
1092 0 : if (zoneExteriorTotalSurfArea > 0.0) {
1093 0 : spaceFrac = thisSpace.ExteriorTotalSurfArea / zoneExteriorTotalSurfArea;
1094 : } else {
1095 0 : ShowSevereError(state,
1096 0 : format("{}Zone exterior surface area is zero when allocating Infiltration to Spaces.", RoutineName));
1097 0 : ShowContinueError(
1098 : state,
1099 0 : format("Occurs for {}=\"{}\" in Zone=\"{}\".", cCurrentModuleObject, thisInfiltrationInput.Name, thisZone.Name));
1100 0 : ErrorsFound = true;
1101 : }
1102 : }
1103 :
1104 4 : thisInfiltration.FlowCoefficient = rNumericArgs(1) * spaceFrac;
1105 : // check if space has exterior surfaces
1106 4 : if (thisInfiltration.spaceIndex > 0) {
1107 4 : if (thisSpace.ExteriorTotalSurfArea <= 0.0) {
1108 0 : ShowWarningError(state,
1109 0 : format(R"({}{}="{}", Space="{}" does not have surfaces exposed to outdoors.)",
1110 : RoutineName,
1111 : cCurrentModuleObject,
1112 0 : thisInfiltrationInput.Name,
1113 0 : thisSpace.Name));
1114 0 : ShowContinueError(state,
1115 : "Infiltration model is appropriate for exterior spaces not interior spaces, simulation continues.");
1116 : }
1117 : }
1118 : }
1119 : }
1120 : }
1121 : }
1122 :
1123 : // setup zone-level infiltration reports
1124 4317 : for (int Loop = 1; Loop <= state.dataHeatBal->TotInfiltration; ++Loop) {
1125 7042 : if (state.dataHeatBal->Infiltration(Loop).ZonePtr > 0 &&
1126 3521 : !state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).zoneOAQuadratureSum) {
1127 : // Object report variables
1128 7040 : SetupOutputVariable(state,
1129 : "Infiltration Sensible Heat Loss Energy",
1130 : Constant::Units::J,
1131 3520 : state.dataHeatBal->Infiltration(Loop).InfilHeatLoss,
1132 : OutputProcessor::TimeStepType::System,
1133 : OutputProcessor::StoreType::Sum,
1134 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1135 7040 : SetupOutputVariable(state,
1136 : "Infiltration Sensible Heat Gain Energy",
1137 : Constant::Units::J,
1138 3520 : state.dataHeatBal->Infiltration(Loop).InfilHeatGain,
1139 : OutputProcessor::TimeStepType::System,
1140 : OutputProcessor::StoreType::Sum,
1141 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1142 7040 : SetupOutputVariable(state,
1143 : "Infiltration Latent Heat Loss Energy",
1144 : Constant::Units::J,
1145 3520 : state.dataHeatBal->Infiltration(Loop).InfilLatentLoss,
1146 : OutputProcessor::TimeStepType::System,
1147 : OutputProcessor::StoreType::Sum,
1148 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1149 7040 : SetupOutputVariable(state,
1150 : "Infiltration Latent Heat Gain Energy",
1151 : Constant::Units::J,
1152 3520 : state.dataHeatBal->Infiltration(Loop).InfilLatentGain,
1153 : OutputProcessor::TimeStepType::System,
1154 : OutputProcessor::StoreType::Sum,
1155 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1156 7040 : SetupOutputVariable(state,
1157 : "Infiltration Total Heat Loss Energy",
1158 : Constant::Units::J,
1159 3520 : state.dataHeatBal->Infiltration(Loop).InfilTotalLoss,
1160 : OutputProcessor::TimeStepType::System,
1161 : OutputProcessor::StoreType::Sum,
1162 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1163 7040 : SetupOutputVariable(state,
1164 : "Infiltration Total Heat Gain Energy",
1165 : Constant::Units::J,
1166 3520 : state.dataHeatBal->Infiltration(Loop).InfilTotalGain,
1167 : OutputProcessor::TimeStepType::System,
1168 : OutputProcessor::StoreType::Sum,
1169 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1170 7040 : SetupOutputVariable(state,
1171 : "Infiltration Current Density Volume Flow Rate",
1172 : Constant::Units::m3_s,
1173 3520 : state.dataHeatBal->Infiltration(Loop).InfilVdotCurDensity,
1174 : OutputProcessor::TimeStepType::System,
1175 : OutputProcessor::StoreType::Average,
1176 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1177 7040 : SetupOutputVariable(state,
1178 : "Infiltration Standard Density Volume Flow Rate",
1179 : Constant::Units::m3_s,
1180 3520 : state.dataHeatBal->Infiltration(Loop).InfilVdotStdDensity,
1181 : OutputProcessor::TimeStepType::System,
1182 : OutputProcessor::StoreType::Average,
1183 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1184 7040 : SetupOutputVariable(state,
1185 : "Infiltration Current Density Volume",
1186 : Constant::Units::m3,
1187 3520 : state.dataHeatBal->Infiltration(Loop).InfilVolumeCurDensity,
1188 : OutputProcessor::TimeStepType::System,
1189 : OutputProcessor::StoreType::Sum,
1190 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1191 7040 : SetupOutputVariable(state,
1192 : "Infiltration Standard Density Volume",
1193 : Constant::Units::m3,
1194 3520 : state.dataHeatBal->Infiltration(Loop).InfilVolumeStdDensity,
1195 : OutputProcessor::TimeStepType::System,
1196 : OutputProcessor::StoreType::Sum,
1197 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1198 7040 : SetupOutputVariable(state,
1199 : "Infiltration Mass",
1200 : Constant::Units::kg,
1201 3520 : state.dataHeatBal->Infiltration(Loop).InfilMass,
1202 : OutputProcessor::TimeStepType::System,
1203 : OutputProcessor::StoreType::Sum,
1204 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1205 7040 : SetupOutputVariable(state,
1206 : "Infiltration Mass Flow Rate",
1207 : Constant::Units::kg_s,
1208 3520 : state.dataHeatBal->Infiltration(Loop).InfilMdot,
1209 : OutputProcessor::TimeStepType::System,
1210 : OutputProcessor::StoreType::Average,
1211 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1212 7040 : SetupOutputVariable(state,
1213 : "Infiltration Air Change Rate",
1214 : Constant::Units::ach,
1215 3520 : state.dataHeatBal->Infiltration(Loop).InfilAirChangeRate,
1216 : OutputProcessor::TimeStepType::System,
1217 : OutputProcessor::StoreType::Average,
1218 3520 : state.dataHeatBal->Infiltration(Loop).Name);
1219 :
1220 3520 : if (RepVarSet(state.dataHeatBal->Infiltration(Loop).ZonePtr)) {
1221 3476 : RepVarSet(state.dataHeatBal->Infiltration(Loop).ZonePtr) = false;
1222 6952 : SetupOutputVariable(state,
1223 : "Zone Infiltration Sensible Heat Loss Energy",
1224 : Constant::Units::J,
1225 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilHeatLoss,
1226 : OutputProcessor::TimeStepType::System,
1227 : OutputProcessor::StoreType::Sum,
1228 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1229 6952 : SetupOutputVariable(state,
1230 : "Zone Infiltration Sensible Heat Gain Energy",
1231 : Constant::Units::J,
1232 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilHeatGain,
1233 : OutputProcessor::TimeStepType::System,
1234 : OutputProcessor::StoreType::Sum,
1235 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1236 6952 : SetupOutputVariable(state,
1237 : "Zone Infiltration Latent Heat Loss Energy",
1238 : Constant::Units::J,
1239 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilLatentLoss,
1240 : OutputProcessor::TimeStepType::System,
1241 : OutputProcessor::StoreType::Sum,
1242 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1243 6952 : SetupOutputVariable(state,
1244 : "Zone Infiltration Latent Heat Gain Energy",
1245 : Constant::Units::J,
1246 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilLatentGain,
1247 : OutputProcessor::TimeStepType::System,
1248 : OutputProcessor::StoreType::Sum,
1249 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1250 6952 : SetupOutputVariable(state,
1251 : "Zone Infiltration Total Heat Loss Energy",
1252 : Constant::Units::J,
1253 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilTotalLoss,
1254 : OutputProcessor::TimeStepType::System,
1255 : OutputProcessor::StoreType::Sum,
1256 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1257 6952 : SetupOutputVariable(state,
1258 : "Zone Infiltration Total Heat Gain Energy",
1259 : Constant::Units::J,
1260 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilTotalGain,
1261 : OutputProcessor::TimeStepType::System,
1262 : OutputProcessor::StoreType::Sum,
1263 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1264 6952 : SetupOutputVariable(state,
1265 : "Zone Infiltration Current Density Volume Flow Rate",
1266 : Constant::Units::m3_s,
1267 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilVdotCurDensity,
1268 : OutputProcessor::TimeStepType::System,
1269 : OutputProcessor::StoreType::Average,
1270 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1271 6952 : SetupOutputVariable(state,
1272 : "Zone Infiltration Standard Density Volume Flow Rate",
1273 : Constant::Units::m3_s,
1274 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilVdotStdDensity,
1275 : OutputProcessor::TimeStepType::System,
1276 : OutputProcessor::StoreType::Average,
1277 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1278 6952 : SetupOutputVariable(state,
1279 : "Zone Infiltration Current Density Volume",
1280 : Constant::Units::m3,
1281 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilVolumeCurDensity,
1282 : OutputProcessor::TimeStepType::System,
1283 : OutputProcessor::StoreType::Sum,
1284 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1285 6952 : SetupOutputVariable(state,
1286 : "Zone Infiltration Standard Density Volume",
1287 : Constant::Units::m3,
1288 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilVolumeStdDensity,
1289 : OutputProcessor::TimeStepType::System,
1290 : OutputProcessor::StoreType::Sum,
1291 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1292 6952 : SetupOutputVariable(state,
1293 : "Zone Infiltration Mass",
1294 : Constant::Units::kg,
1295 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilMass,
1296 : OutputProcessor::TimeStepType::System,
1297 : OutputProcessor::StoreType::Sum,
1298 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1299 6952 : SetupOutputVariable(state,
1300 : "Zone Infiltration Mass Flow Rate",
1301 : Constant::Units::kg_s,
1302 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilMdot,
1303 : OutputProcessor::TimeStepType::System,
1304 : OutputProcessor::StoreType::Average,
1305 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1306 6952 : SetupOutputVariable(state,
1307 : "Zone Infiltration Air Change Rate",
1308 : Constant::Units::ach,
1309 3476 : state.dataHeatBal->ZnAirRpt(state.dataHeatBal->Infiltration(Loop).ZonePtr).InfilAirChangeRate,
1310 : OutputProcessor::TimeStepType::System,
1311 : OutputProcessor::StoreType::Average,
1312 3476 : state.dataHeatBal->Zone(state.dataHeatBal->Infiltration(Loop).ZonePtr).Name);
1313 : }
1314 : }
1315 :
1316 3521 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
1317 1846 : SetupEMSActuator(state,
1318 : "Zone Infiltration",
1319 923 : state.dataHeatBal->Infiltration(Loop).Name,
1320 : "Air Exchange Flow Rate",
1321 : "[m3/s]",
1322 923 : state.dataHeatBal->Infiltration(Loop).EMSOverrideOn,
1323 923 : state.dataHeatBal->Infiltration(Loop).EMSAirFlowRateValue);
1324 : }
1325 : }
1326 :
1327 : // Set up and process ZoneVentilation:* inputs
1328 :
1329 796 : RepVarSet = true;
1330 :
1331 796 : cCurrentModuleObject = "ZoneVentilation:DesignFlowRate";
1332 796 : int numDesignFlowVentilationObjects = 0;
1333 796 : int totDesignFlowVentilation = 0; // Total ZoneVentilation:DesignFlowRate instances after expansion to spaces
1334 1592 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> ventilationDesignFlowRateObjects;
1335 796 : InternalHeatGains::setupIHGZonesAndSpaces(
1336 : state, cCurrentModuleObject, ventilationDesignFlowRateObjects, numDesignFlowVentilationObjects, totDesignFlowVentilation, ErrorsFound);
1337 :
1338 796 : cCurrentModuleObject = "ZoneVentilation:WindandStackOpenArea";
1339 796 : int numWindStackVentilationObjects = 0;
1340 796 : int totWindStackVentilation = 0; // Total ZoneVentilation:WindandStackOpenArea instances after expansion to spaces
1341 1592 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> ventilationWindStackObjects;
1342 796 : InternalHeatGains::setupIHGZonesAndSpaces(state,
1343 : cCurrentModuleObject,
1344 : ventilationWindStackObjects,
1345 : numWindStackVentilationObjects,
1346 : totWindStackVentilation,
1347 : ErrorsFound,
1348 : zoneListNotAllowed);
1349 :
1350 796 : state.dataHeatBal->TotVentilation = totDesignFlowVentilation + totWindStackVentilation;
1351 796 : state.dataHeatBal->Ventilation.allocate(state.dataHeatBal->TotVentilation);
1352 :
1353 796 : int ventilationNum = 0;
1354 796 : if (numDesignFlowVentilationObjects > 0) {
1355 24 : cCurrentModuleObject = "ZoneVentilation:DesignFlowRate";
1356 68 : for (int ventInputNum = 1; ventInputNum <= numDesignFlowVentilationObjects; ++ventInputNum) {
1357 :
1358 44 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1359 : cCurrentModuleObject,
1360 : ventInputNum,
1361 : cAlphaArgs,
1362 : NumAlpha,
1363 : rNumericArgs,
1364 : NumNumber,
1365 : IOStat,
1366 : lNumericFieldBlanks,
1367 : lAlphaFieldBlanks,
1368 : cAlphaFieldNames,
1369 : cNumericFieldNames);
1370 :
1371 44 : auto &thisVentilationInput = ventilationDesignFlowRateObjects(ventInputNum);
1372 89 : for (int Item1 = 1; Item1 <= thisVentilationInput.numOfSpaces; ++Item1) {
1373 45 : ++ventilationNum;
1374 45 : auto &thisVentilation = state.dataHeatBal->Ventilation(ventilationNum);
1375 45 : thisVentilation.Name = thisVentilationInput.names(Item1);
1376 45 : thisVentilation.spaceIndex = thisVentilationInput.spaceNums(Item1);
1377 45 : auto &thisSpace = state.dataHeatBal->space(thisVentilation.spaceIndex);
1378 45 : thisVentilation.ZonePtr = thisSpace.zoneNum;
1379 45 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
1380 :
1381 45 : thisVentilation.ModelType = DataHeatBalance::VentilationModelType::DesignFlowRate;
1382 45 : if (lAlphaFieldBlanks(3)) {
1383 0 : thisVentilation.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
1384 : } else {
1385 45 : thisVentilation.SchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
1386 45 : if (thisVentilation.SchedPtr == 0) {
1387 0 : if (Item1 == 1) {
1388 0 : ShowSevereError(state,
1389 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
1390 : RoutineName,
1391 : cCurrentModuleObject,
1392 : cAlphaArgs(1),
1393 : cAlphaFieldNames(3),
1394 : cAlphaArgs(3)));
1395 : }
1396 0 : ErrorsFound = true;
1397 : }
1398 : }
1399 :
1400 : // Ventilation equipment design level calculation method
1401 45 : AirflowSpec flow = static_cast<AirflowSpec>(getEnumValue(airflowNamesUC, cAlphaArgs(4))); // NOLINT(modernize-use-auto)
1402 45 : switch (flow) {
1403 37 : case AirflowSpec::Flow:
1404 : case AirflowSpec::FlowPerZone:
1405 37 : thisVentilation.DesignLevel = rNumericArgs(1);
1406 37 : if (lNumericFieldBlanks(1)) {
1407 0 : ShowWarningError(state,
1408 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Ventilation will result.",
1409 : RoutineName,
1410 : cCurrentModuleObject,
1411 0 : thisVentilation.Name,
1412 : cAlphaFieldNames(4),
1413 : cNumericFieldNames(1)));
1414 : }
1415 37 : break;
1416 :
1417 1 : case AirflowSpec::FlowPerArea:
1418 1 : if (thisVentilation.spaceIndex != 0) {
1419 1 : if (rNumericArgs(2) >= 0.0) {
1420 1 : thisVentilation.DesignLevel = rNumericArgs(2) * thisSpace.FloorArea;
1421 1 : if (thisSpace.FloorArea <= 0.0) {
1422 0 : ShowWarningError(state,
1423 0 : format("{}{}=\"{}\", {} specifies {}, but Space Floor Area = 0. 0 Ventilation will result.",
1424 : RoutineName,
1425 : cCurrentModuleObject,
1426 0 : thisVentilation.Name,
1427 : cAlphaFieldNames(4),
1428 : cNumericFieldNames(2)));
1429 : }
1430 : } else {
1431 0 : ShowSevereError(state,
1432 0 : format("{}{}=\"{}\", invalid flow/area specification [<0.0]={:.3R}",
1433 : RoutineName,
1434 : cCurrentModuleObject,
1435 0 : thisVentilation.Name,
1436 : rNumericArgs(2)));
1437 0 : ErrorsFound = true;
1438 : }
1439 : }
1440 1 : if (lNumericFieldBlanks(2)) {
1441 0 : ShowWarningError(state,
1442 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Ventilation will result.",
1443 : RoutineName,
1444 : cCurrentModuleObject,
1445 0 : thisVentilation.Name,
1446 : cAlphaFieldNames(4),
1447 : cNumericFieldNames(2)));
1448 : }
1449 1 : break;
1450 :
1451 0 : case AirflowSpec::FlowPerPerson:
1452 0 : if (thisVentilation.spaceIndex != 0) {
1453 0 : if (rNumericArgs(3) >= 0.0) {
1454 0 : thisVentilation.DesignLevel = rNumericArgs(3) * thisSpace.TotOccupants;
1455 0 : if (thisSpace.TotOccupants <= 0.0) {
1456 0 : ShowWarningError(state,
1457 0 : format("{}{}=\"{}\", {} specifies {}, but Zone Total Occupants = 0. 0 Ventilation will result.",
1458 : RoutineName,
1459 : cCurrentModuleObject,
1460 0 : thisVentilation.Name,
1461 : cAlphaFieldNames(4),
1462 : cNumericFieldNames(3)));
1463 : }
1464 : } else {
1465 0 : ShowSevereError(state,
1466 0 : format("{}{}=\"{}\", invalid flow/person specification [<0.0]={:.3R}",
1467 : RoutineName,
1468 : cCurrentModuleObject,
1469 0 : thisVentilation.Name,
1470 : rNumericArgs(3)));
1471 0 : ErrorsFound = true;
1472 : }
1473 : }
1474 0 : if (lNumericFieldBlanks(3)) {
1475 0 : ShowWarningError(state,
1476 0 : format("{}{}=\"{}\", {}specifies {}, but that field is blank. 0 Ventilation will result.",
1477 : RoutineName,
1478 : cCurrentModuleObject,
1479 0 : thisVentilation.Name,
1480 : cAlphaFieldNames(4),
1481 : cNumericFieldNames(3)));
1482 : }
1483 0 : break;
1484 :
1485 7 : case AirflowSpec::AirChanges:
1486 7 : if (thisVentilation.spaceIndex != 0) {
1487 7 : if (rNumericArgs(4) >= 0.0) {
1488 7 : thisVentilation.DesignLevel = rNumericArgs(4) * thisSpace.Volume / Constant::SecInHour;
1489 7 : if (thisSpace.Volume <= 0.0) {
1490 0 : ShowWarningError(state,
1491 0 : format("{}{}=\"{}\", {} specifies {}, but Space Volume = 0. 0 Ventilation will result.",
1492 : RoutineName,
1493 : cCurrentModuleObject,
1494 0 : thisVentilation.Name,
1495 : cAlphaFieldNames(4),
1496 : cNumericFieldNames(4)));
1497 : }
1498 : } else {
1499 0 : ShowSevereError(state,
1500 0 : format("{}{}=\"{}\", invalid ACH (air changes per hour) specification [<0.0]={:.3R}",
1501 : RoutineName,
1502 : cCurrentModuleObject,
1503 0 : thisVentilation.Name,
1504 : rNumericArgs(5)));
1505 0 : ErrorsFound = true;
1506 : }
1507 : }
1508 7 : if (lNumericFieldBlanks(4)) {
1509 0 : ShowWarningError(state,
1510 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Ventilation will result.",
1511 : RoutineName,
1512 : cCurrentModuleObject,
1513 0 : thisVentilation.Name,
1514 : cAlphaFieldNames(4),
1515 : cNumericFieldNames(4)));
1516 : }
1517 7 : break;
1518 :
1519 0 : default:
1520 0 : if (Item1 == 1) {
1521 0 : ShowSevereError(
1522 : state,
1523 0 : format("{}{}=\"{}\", invalid calculation method={}", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(4)));
1524 0 : ErrorsFound = true;
1525 : }
1526 : }
1527 :
1528 45 : if (cAlphaArgs(5).empty()) {
1529 0 : thisVentilation.FanType = DataHeatBalance::VentilationType::Natural;
1530 : } else {
1531 45 : thisVentilation.FanType = static_cast<DataHeatBalance::VentilationType>(getEnumValue(ventilationTypeNamesUC, cAlphaArgs(5)));
1532 45 : if (thisVentilation.FanType == DataHeatBalance::VentilationType::Invalid) {
1533 0 : ShowSevereError(state,
1534 0 : format(R"({}{}="{}". invalid {}="{}".)",
1535 : RoutineName,
1536 : cCurrentModuleObject,
1537 0 : thisVentilation.Name,
1538 : cAlphaFieldNames(5),
1539 : cAlphaArgs(5)));
1540 0 : ErrorsFound = true;
1541 : }
1542 : }
1543 :
1544 45 : thisVentilation.FanPressure = rNumericArgs(5);
1545 45 : if (thisVentilation.FanPressure < 0.0) {
1546 0 : if (Item1 == 1) {
1547 0 : ShowSevereError(
1548 : state,
1549 0 : format("{}{}=\"{}\", {} must be >=0", RoutineName, cCurrentModuleObject, thisVentilation.Name, cNumericFieldNames(5)));
1550 0 : ErrorsFound = true;
1551 : }
1552 : }
1553 :
1554 45 : thisVentilation.FanEfficiency = rNumericArgs(6);
1555 45 : if ((thisVentilation.FanEfficiency <= 0.0) || (thisVentilation.FanEfficiency > 1.0)) {
1556 0 : if (Item1 == 1) {
1557 0 : ShowSevereError(state,
1558 0 : format("{}{}=\"{}\",{} must be in range >0 and <= 1",
1559 : RoutineName,
1560 : cCurrentModuleObject,
1561 0 : thisVentilation.Name,
1562 : cNumericFieldNames(6)));
1563 0 : ErrorsFound = true;
1564 : }
1565 : }
1566 :
1567 : // Override any user input for cases where natural ventilation is being used
1568 45 : if (thisVentilation.FanType == DataHeatBalance::VentilationType::Natural) {
1569 7 : thisVentilation.FanPressure = 0.0;
1570 7 : thisVentilation.FanEfficiency = 1.0;
1571 : }
1572 :
1573 45 : thisVentilation.ConstantTermCoef = !lNumericFieldBlanks(7) ? rNumericArgs(7) : 1.0;
1574 45 : thisVentilation.TemperatureTermCoef = !lNumericFieldBlanks(8) ? rNumericArgs(8) : 0.0;
1575 45 : thisVentilation.VelocityTermCoef = !lNumericFieldBlanks(9) ? rNumericArgs(9) : 0.0;
1576 45 : thisVentilation.VelocitySQTermCoef = !lNumericFieldBlanks(10) ? rNumericArgs(10) : 0.0;
1577 :
1578 45 : if (thisVentilation.ConstantTermCoef == 0.0 && thisVentilation.TemperatureTermCoef == 0.0 &&
1579 2 : thisVentilation.VelocityTermCoef == 0.0 && thisVentilation.VelocitySQTermCoef == 0.0) {
1580 0 : if (Item1 == 1) {
1581 0 : ShowWarningError(
1582 : state,
1583 0 : format(
1584 : "{}{}=\"{}\", in {}=\"{}\".", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2)));
1585 0 : ShowContinueError(state, "Ventilation Coefficients are all zero. No Ventilation will be reported.");
1586 : }
1587 : }
1588 :
1589 45 : if (!lNumericFieldBlanks(11)) {
1590 37 : thisVentilation.MinIndoorTemperature = rNumericArgs(11);
1591 : } else {
1592 8 : thisVentilation.MinIndoorTemperature = -VentilTempLimit;
1593 : }
1594 : // Ventilation(Loop)%MinIndoorTemperature = rNumericArgs(11)
1595 45 : if ((thisVentilation.MinIndoorTemperature < -VentilTempLimit) || (thisVentilation.MinIndoorTemperature > VentilTempLimit)) {
1596 0 : if (Item1 == 1) {
1597 0 : ShowSevereError(state,
1598 0 : format("{}{}=\"{}\" must have {} between -100C and 100C.",
1599 : RoutineName,
1600 : cCurrentModuleObject,
1601 : cAlphaArgs(1),
1602 : cNumericFieldNames(11)));
1603 0 : ShowContinueError(state, format("...value entered=[{:.2R}].", rNumericArgs(11)));
1604 0 : ErrorsFound = true;
1605 : }
1606 : }
1607 :
1608 45 : thisVentilation.MinIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(6));
1609 45 : if (thisVentilation.MinIndoorTempSchedPtr > 0) {
1610 8 : if (Item1 == 1) {
1611 7 : if (!lNumericFieldBlanks(11))
1612 0 : ShowWarningError(state,
1613 0 : format("{}The Minimum Indoor Temperature value and schedule are provided. The scheduled temperature "
1614 : "will be used in the {} object = {}",
1615 : RoutineName,
1616 : cCurrentModuleObject,
1617 : cAlphaArgs(1)));
1618 : // Check min and max values in the schedule to ensure both values are within the range
1619 7 : if (!ScheduleManager::CheckScheduleValueMinMax(
1620 : state, thisVentilation.MinIndoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
1621 0 : ShowSevereError(
1622 : state,
1623 0 : format(
1624 : "{}{} statement = {} must have a minimum indoor temperature between -100C and 100C defined in the schedule = {}",
1625 : RoutineName,
1626 : cCurrentModuleObject,
1627 : cAlphaArgs(1),
1628 : cAlphaArgs(6)));
1629 0 : ErrorsFound = true;
1630 : }
1631 : }
1632 : }
1633 45 : if (thisVentilation.MinIndoorTempSchedPtr == 0 && lNumericFieldBlanks(11) && (!lAlphaFieldBlanks(6))) {
1634 0 : if (Item1 == 1) {
1635 0 : ShowWarningError(
1636 : state,
1637 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
1638 : RoutineName,
1639 : cNumericFieldNames(11),
1640 0 : -VentilTempLimit));
1641 0 : ShowContinueError(state,
1642 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1643 : }
1644 : }
1645 : // Check Minimum indoor temperature value and schedule fields
1646 45 : if (!lNumericFieldBlanks(11) && (!cAlphaArgs(6).empty() && thisVentilation.MinIndoorTempSchedPtr == 0)) {
1647 0 : if (Item1 == 1) {
1648 0 : ShowWarningError(state,
1649 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
1650 : RoutineName,
1651 : cAlphaFieldNames(6),
1652 : cAlphaArgs(6),
1653 : rNumericArgs(11)));
1654 0 : ShowContinueError(state,
1655 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1656 : }
1657 : }
1658 :
1659 45 : thisVentilation.MaxIndoorTemperature = !lNumericFieldBlanks(12) ? rNumericArgs(12) : VentilTempLimit;
1660 45 : if ((thisVentilation.MaxIndoorTemperature < -VentilTempLimit) || (thisVentilation.MaxIndoorTemperature > VentilTempLimit)) {
1661 0 : if (Item1 == 1) {
1662 0 : ShowSevereError(state,
1663 0 : format("{}{} = {} must have a maximum indoor temperature between -100C and 100C",
1664 : RoutineName,
1665 : cCurrentModuleObject,
1666 : cAlphaArgs(1)));
1667 0 : ErrorsFound = true;
1668 : }
1669 : }
1670 :
1671 45 : thisVentilation.MaxIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(7));
1672 45 : if (thisVentilation.MaxIndoorTempSchedPtr > 0) {
1673 8 : if (Item1 == 1) {
1674 7 : if (!lNumericFieldBlanks(12))
1675 0 : ShowWarningError(state,
1676 0 : format("{}The Maximum Indoor Temperature value and schedule are provided. The scheduled temperature "
1677 : "will be used in the {} object = {}",
1678 : RoutineName,
1679 : cCurrentModuleObject,
1680 : cAlphaArgs(1)));
1681 : // Check min and max values in the schedule to ensure both values are within the range
1682 7 : if (!ScheduleManager::CheckScheduleValueMinMax(
1683 : state, thisVentilation.MaxIndoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
1684 0 : ShowSevereError(
1685 : state,
1686 0 : format("{} = {} must have a maximum indoor temperature between -100C and 100C defined in the schedule = {}",
1687 : cCurrentModuleObject,
1688 : cAlphaArgs(1),
1689 : cAlphaArgs(7)));
1690 0 : ErrorsFound = true;
1691 : }
1692 : }
1693 : }
1694 45 : if (thisVentilation.MaxIndoorTempSchedPtr == 0 && lNumericFieldBlanks(12) && (!lAlphaFieldBlanks(7))) {
1695 0 : if (Item1 == 1) {
1696 0 : ShowWarningError(
1697 : state,
1698 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
1699 : RoutineName,
1700 : cNumericFieldNames(12),
1701 : VentilTempLimit));
1702 0 : ShowContinueError(state,
1703 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1704 : }
1705 : }
1706 : // Check Maximum indoor temperature value and schedule fields
1707 45 : if (!lNumericFieldBlanks(12) && ((!lAlphaFieldBlanks(7)) && thisVentilation.MaxIndoorTempSchedPtr == 0)) {
1708 0 : if (Item1 == 1) {
1709 0 : ShowWarningError(state,
1710 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
1711 : RoutineName,
1712 : cAlphaFieldNames(7),
1713 : cAlphaArgs(7),
1714 : rNumericArgs(12)));
1715 0 : ShowContinueError(state,
1716 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1717 : }
1718 : }
1719 :
1720 45 : thisVentilation.DelTemperature = !lNumericFieldBlanks(13) ? rNumericArgs(13) : -VentilTempLimit;
1721 : // Ventilation(Loop)%DelTemperature = rNumericArgs(13) ! 3/12/03 Negative del temp now allowed COP
1722 :
1723 45 : thisVentilation.DeltaTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(8));
1724 45 : if (thisVentilation.DeltaTempSchedPtr > 0) {
1725 8 : if (Item1 == 1) {
1726 7 : if (!lNumericFieldBlanks(13))
1727 0 : ShowWarningError(state,
1728 0 : format("{}The Delta Temperature value and schedule are provided. The scheduled temperature will be used "
1729 : "in the {} object = {}",
1730 : RoutineName,
1731 : cCurrentModuleObject,
1732 : cAlphaArgs(1)));
1733 : // Check min value in the schedule to ensure both values are within the range
1734 7 : if (ScheduleManager::GetScheduleMinValue(state, thisVentilation.DeltaTempSchedPtr) < -VentilTempLimit) {
1735 0 : ShowSevereError(
1736 : state,
1737 0 : format("{}{} statement = {} must have a delta temperature equal to or above -100C defined in the schedule = {}",
1738 : RoutineName,
1739 : cCurrentModuleObject,
1740 : cAlphaArgs(1),
1741 : cAlphaArgs(8)));
1742 0 : ErrorsFound = true;
1743 : }
1744 : }
1745 : }
1746 45 : if (thisVentilation.DeltaTempSchedPtr == 0 && lNumericFieldBlanks(13) && (!lAlphaFieldBlanks(8))) {
1747 0 : if (Item1 == 1) {
1748 0 : ShowWarningError(
1749 : state,
1750 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
1751 : RoutineName,
1752 : cNumericFieldNames(13),
1753 : VentilTempLimit));
1754 0 : ShowContinueError(state,
1755 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1756 : }
1757 : }
1758 :
1759 45 : if (!lNumericFieldBlanks(13) && ((!lAlphaFieldBlanks(8)) && thisVentilation.DeltaTempSchedPtr == 0)) {
1760 0 : if (Item1 == 1) {
1761 0 : ShowWarningError(state,
1762 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
1763 : RoutineName,
1764 : cAlphaFieldNames(8),
1765 : cAlphaArgs(8),
1766 : rNumericArgs(13)));
1767 0 : ShowContinueError(state,
1768 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1769 : }
1770 : }
1771 :
1772 45 : thisVentilation.MinOutdoorTemperature = !lNumericFieldBlanks(14) ? rNumericArgs(14) : -VentilTempLimit;
1773 45 : if ((thisVentilation.MinOutdoorTemperature < -VentilTempLimit) || (thisVentilation.MinOutdoorTemperature > VentilTempLimit)) {
1774 0 : if (Item1 == 1) {
1775 0 : ShowSevereError(state,
1776 0 : format("{}{} statement = {} must have {} between -100C and 100C",
1777 : RoutineName,
1778 : cCurrentModuleObject,
1779 : cAlphaArgs(1),
1780 : cNumericFieldNames(14)));
1781 0 : ErrorsFound = true;
1782 : }
1783 : }
1784 :
1785 45 : thisVentilation.MinOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(9));
1786 45 : if (Item1 == 1) {
1787 44 : if (thisVentilation.MinOutdoorTempSchedPtr > 0) {
1788 7 : if (!lNumericFieldBlanks(14))
1789 0 : ShowWarningError(state,
1790 0 : format("{}The Minimum Outdoor Temperature value and schedule are provided. The scheduled temperature "
1791 : "will be used in the {} object = {}",
1792 : RoutineName,
1793 : cCurrentModuleObject,
1794 : cAlphaArgs(1)));
1795 : // Check min and max values in the schedule to ensure both values are within the range
1796 7 : if (!ScheduleManager::CheckScheduleValueMinMax(
1797 : state, thisVentilation.MinOutdoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
1798 0 : ShowSevereError(
1799 : state,
1800 0 : format(
1801 : "{}{} statement = {} must have a minimum outdoor temperature between -100C and 100C defined in the schedule = {}",
1802 : RoutineName,
1803 : cCurrentModuleObject,
1804 : cAlphaArgs(1),
1805 : cAlphaArgs(9)));
1806 0 : ErrorsFound = true;
1807 : }
1808 : }
1809 44 : if (thisVentilation.MinOutdoorTempSchedPtr == 0 && lNumericFieldBlanks(14) && (!lAlphaFieldBlanks(9))) {
1810 0 : ShowWarningError(state,
1811 0 : format("{}Minimum Outdoor Temperature: the value field is blank and schedule field is invalid. The "
1812 : "default value will be used ({:.1R}) ",
1813 : RoutineName,
1814 0 : -VentilTempLimit));
1815 0 : ShowContinueError(state,
1816 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1817 : }
1818 : // Check Minimum outdoor temperature value and schedule fields
1819 44 : if (!lNumericFieldBlanks(14) && ((!lAlphaFieldBlanks(9)) && thisVentilation.MinOutdoorTempSchedPtr == 0)) {
1820 0 : ShowWarningError(state,
1821 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
1822 : RoutineName,
1823 : cAlphaFieldNames(9),
1824 : cAlphaArgs(9),
1825 : rNumericArgs(14)));
1826 0 : ShowContinueError(state,
1827 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1828 : }
1829 : }
1830 :
1831 45 : thisVentilation.MaxOutdoorTemperature = !lNumericFieldBlanks(15) ? rNumericArgs(15) : VentilTempLimit;
1832 45 : if (Item1 == 1) {
1833 44 : if ((thisVentilation.MaxOutdoorTemperature < -VentilTempLimit) || (thisVentilation.MaxOutdoorTemperature > VentilTempLimit)) {
1834 0 : ShowSevereError(state,
1835 0 : format("{}{} statement = {} must have a {} between -100C and 100C",
1836 : RoutineName,
1837 : cCurrentModuleObject,
1838 : cAlphaArgs(1),
1839 : cNumericFieldNames(15)));
1840 0 : ErrorsFound = true;
1841 : }
1842 : }
1843 :
1844 45 : thisVentilation.MaxOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(10));
1845 45 : if (Item1 == 1) {
1846 44 : if (thisVentilation.MaxOutdoorTempSchedPtr > 0) {
1847 7 : if (!lNumericFieldBlanks(15))
1848 0 : ShowWarningError(state,
1849 0 : format("{}The Maximum Outdoor Temperature value and schedule are provided. The scheduled temperature "
1850 : "will be used in the {} object = {}",
1851 : RoutineName,
1852 : cCurrentModuleObject,
1853 : cAlphaArgs(1)));
1854 7 : if (!ScheduleManager::CheckScheduleValueMinMax(
1855 : state, thisVentilation.MaxOutdoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
1856 0 : ShowSevereError(
1857 : state,
1858 0 : format(
1859 : "{}{} statement = {} must have a maximum outdoor temperature between -100C and 100C defined in the schedule = {}",
1860 : RoutineName,
1861 : cCurrentModuleObject,
1862 : cAlphaArgs(1),
1863 : cAlphaArgs(10)));
1864 0 : ErrorsFound = true;
1865 : }
1866 : }
1867 44 : if (thisVentilation.MaxOutdoorTempSchedPtr == 0 && lNumericFieldBlanks(15) && (!lAlphaFieldBlanks(10))) {
1868 0 : ShowWarningError(
1869 : state,
1870 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
1871 : RoutineName,
1872 : cNumericFieldNames(15),
1873 : VentilTempLimit));
1874 0 : ShowContinueError(state,
1875 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1876 : }
1877 : // Check Maximum outdoor temperature value and schedule fields
1878 44 : if (!lNumericFieldBlanks(15) && ((!lAlphaFieldBlanks(10)) && thisVentilation.MaxOutdoorTempSchedPtr == 0)) {
1879 0 : ShowWarningError(state,
1880 0 : format("{}{} = {}is invalid. The constant value will be used at {:.1R} degrees C ",
1881 : RoutineName,
1882 : cAlphaFieldNames(10),
1883 : cAlphaArgs(10),
1884 : rNumericArgs(15)));
1885 0 : ShowContinueError(state,
1886 0 : format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
1887 : }
1888 : }
1889 :
1890 45 : thisVentilation.MaxWindSpeed = !lNumericFieldBlanks(16) ? rNumericArgs(16) : VentilWSLimit;
1891 45 : if (Item1 == 1) {
1892 44 : if ((thisVentilation.MaxWindSpeed < -VentilWSLimit) || (thisVentilation.MaxWindSpeed > VentilWSLimit)) {
1893 0 : ShowSevereError(state,
1894 0 : format("{}{} statement = {} must have a maximum wind speed between -40 m/s and 40 m/s",
1895 : RoutineName,
1896 : cCurrentModuleObject,
1897 : cAlphaArgs(1)));
1898 0 : ErrorsFound = true;
1899 : }
1900 : }
1901 :
1902 : // Report variables should be added for individual VENTILATION objects, in addition to zone totals below
1903 :
1904 45 : if (thisVentilation.ZonePtr > 0) {
1905 45 : if (RepVarSet(thisVentilation.ZonePtr) && !thisZone.zoneOAQuadratureSum) {
1906 41 : RepVarSet(thisVentilation.ZonePtr) = false;
1907 82 : SetupOutputVariable(state,
1908 : "Zone Ventilation Sensible Heat Loss Energy",
1909 : Constant::Units::J,
1910 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilHeatLoss,
1911 : OutputProcessor::TimeStepType::System,
1912 : OutputProcessor::StoreType::Sum,
1913 41 : thisZone.Name);
1914 82 : SetupOutputVariable(state,
1915 : "Zone Ventilation Sensible Heat Gain Energy",
1916 : Constant::Units::J,
1917 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilHeatGain,
1918 : OutputProcessor::TimeStepType::System,
1919 : OutputProcessor::StoreType::Sum,
1920 41 : thisZone.Name);
1921 82 : SetupOutputVariable(state,
1922 : "Zone Ventilation Latent Heat Loss Energy",
1923 : Constant::Units::J,
1924 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilLatentLoss,
1925 : OutputProcessor::TimeStepType::System,
1926 : OutputProcessor::StoreType::Sum,
1927 41 : thisZone.Name);
1928 82 : SetupOutputVariable(state,
1929 : "Zone Ventilation Latent Heat Gain Energy",
1930 : Constant::Units::J,
1931 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilLatentGain,
1932 : OutputProcessor::TimeStepType::System,
1933 : OutputProcessor::StoreType::Sum,
1934 41 : thisZone.Name);
1935 82 : SetupOutputVariable(state,
1936 : "Zone Ventilation Total Heat Loss Energy",
1937 : Constant::Units::J,
1938 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilTotalLoss,
1939 : OutputProcessor::TimeStepType::System,
1940 : OutputProcessor::StoreType::Sum,
1941 41 : thisZone.Name);
1942 82 : SetupOutputVariable(state,
1943 : "Zone Ventilation Total Heat Gain Energy",
1944 : Constant::Units::J,
1945 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilTotalGain,
1946 : OutputProcessor::TimeStepType::System,
1947 : OutputProcessor::StoreType::Sum,
1948 41 : thisZone.Name);
1949 82 : SetupOutputVariable(state,
1950 : "Zone Ventilation Current Density Volume Flow Rate",
1951 : Constant::Units::m3_s,
1952 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVdotCurDensity,
1953 : OutputProcessor::TimeStepType::System,
1954 : OutputProcessor::StoreType::Average,
1955 41 : thisZone.Name);
1956 82 : SetupOutputVariable(state,
1957 : "Zone Ventilation Standard Density Volume Flow Rate",
1958 : Constant::Units::m3_s,
1959 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVdotStdDensity,
1960 : OutputProcessor::TimeStepType::System,
1961 : OutputProcessor::StoreType::Average,
1962 41 : thisZone.Name);
1963 82 : SetupOutputVariable(state,
1964 : "Zone Ventilation Current Density Volume",
1965 : Constant::Units::m3,
1966 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVolumeCurDensity,
1967 : OutputProcessor::TimeStepType::System,
1968 : OutputProcessor::StoreType::Sum,
1969 41 : thisZone.Name);
1970 82 : SetupOutputVariable(state,
1971 : "Zone Ventilation Standard Density Volume",
1972 : Constant::Units::m3,
1973 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVolumeStdDensity,
1974 : OutputProcessor::TimeStepType::System,
1975 : OutputProcessor::StoreType::Sum,
1976 41 : thisZone.Name);
1977 82 : SetupOutputVariable(state,
1978 : "Zone Ventilation Mass",
1979 : Constant::Units::kg,
1980 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilMass,
1981 : OutputProcessor::TimeStepType::System,
1982 : OutputProcessor::StoreType::Sum,
1983 41 : thisZone.Name);
1984 82 : SetupOutputVariable(state,
1985 : "Zone Ventilation Mass Flow Rate",
1986 : Constant::Units::kg_s,
1987 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilMdot,
1988 : OutputProcessor::TimeStepType::System,
1989 : OutputProcessor::StoreType::Average,
1990 41 : thisZone.Name);
1991 82 : SetupOutputVariable(state,
1992 : "Zone Ventilation Air Change Rate",
1993 : Constant::Units::ach,
1994 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilAirChangeRate,
1995 : OutputProcessor::TimeStepType::System,
1996 : OutputProcessor::StoreType::Average,
1997 41 : thisZone.Name);
1998 82 : SetupOutputVariable(state,
1999 : "Zone Ventilation Fan Electricity Energy",
2000 : Constant::Units::J,
2001 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilFanElec,
2002 : OutputProcessor::TimeStepType::System,
2003 : OutputProcessor::StoreType::Sum,
2004 41 : thisZone.Name,
2005 : Constant::eResource::Electricity,
2006 : OutputProcessor::Group::Building,
2007 : OutputProcessor::EndUseCat::Fans,
2008 : "Ventilation (simple)",
2009 41 : thisZone.Name);
2010 82 : SetupOutputVariable(state,
2011 : "Zone Ventilation Air Inlet Temperature",
2012 : Constant::Units::C,
2013 41 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilAirTemp,
2014 : OutputProcessor::TimeStepType::System,
2015 : OutputProcessor::StoreType::Average,
2016 41 : thisZone.Name);
2017 : }
2018 : }
2019 :
2020 45 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
2021 6 : SetupEMSActuator(state,
2022 : "Zone Ventilation",
2023 : thisVentilation.Name,
2024 : "Air Exchange Flow Rate",
2025 : "[m3/s]",
2026 6 : thisVentilation.EMSSimpleVentOn,
2027 6 : thisVentilation.EMSimpleVentFlowRate);
2028 : }
2029 : }
2030 : }
2031 : }
2032 :
2033 796 : if (numWindStackVentilationObjects > 0) {
2034 5 : cCurrentModuleObject = "ZoneVentilation:WindandStackOpenArea";
2035 138 : for (int ventInputNum = 1; ventInputNum <= numWindStackVentilationObjects; ++ventInputNum) {
2036 :
2037 133 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2038 : cCurrentModuleObject,
2039 : ventInputNum,
2040 : cAlphaArgs,
2041 : NumAlpha,
2042 : rNumericArgs,
2043 : NumNumber,
2044 : IOStat,
2045 : lNumericFieldBlanks,
2046 : lAlphaFieldBlanks,
2047 : cAlphaFieldNames,
2048 : cNumericFieldNames);
2049 :
2050 133 : auto &thisVentilationInput = ventilationWindStackObjects(ventInputNum);
2051 266 : for (int Item1 = 1; Item1 <= thisVentilationInput.numOfSpaces; ++Item1) {
2052 133 : ++ventilationNum;
2053 133 : auto &thisVentilation = state.dataHeatBal->Ventilation(ventilationNum);
2054 133 : thisVentilation.Name = thisVentilationInput.names(Item1);
2055 133 : thisVentilation.spaceIndex = thisVentilationInput.spaceNums(Item1);
2056 133 : auto &thisSpace = state.dataHeatBal->space(thisVentilation.spaceIndex);
2057 133 : thisVentilation.ZonePtr = thisSpace.zoneNum;
2058 133 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
2059 :
2060 133 : thisVentilation.ModelType = DataHeatBalance::VentilationModelType::WindAndStack;
2061 :
2062 133 : thisVentilation.OpenArea = rNumericArgs(1);
2063 133 : if (thisVentilation.OpenArea < 0.0) {
2064 0 : ShowSevereError(
2065 0 : state, format("{}{}=\"{}\", {} must be positive.", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cNumericFieldNames(1)));
2066 0 : ErrorsFound = true;
2067 : }
2068 :
2069 133 : if (lAlphaFieldBlanks(3)) {
2070 0 : thisVentilation.OpenAreaSchedPtr = ScheduleManager::ScheduleAlwaysOn;
2071 : } else {
2072 133 : thisVentilation.OpenAreaSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
2073 133 : if (thisVentilation.OpenAreaSchedPtr == 0) {
2074 0 : ShowSevereError(state,
2075 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
2076 : RoutineName,
2077 : cCurrentModuleObject,
2078 : cAlphaArgs(1),
2079 : cAlphaFieldNames(3),
2080 : cAlphaArgs(3)));
2081 0 : ErrorsFound = true;
2082 : }
2083 : }
2084 :
2085 133 : thisVentilation.OpenEff = rNumericArgs(2);
2086 133 : if (thisVentilation.OpenEff != Constant::AutoCalculate && (thisVentilation.OpenEff < 0.0 || thisVentilation.OpenEff > 1.0)) {
2087 0 : ShowSevereError(
2088 : state,
2089 0 : format("{}{}=\"{}\", {} must be between 0 and 1.", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cNumericFieldNames(2)));
2090 0 : ErrorsFound = true;
2091 : }
2092 :
2093 133 : thisVentilation.EffAngle = rNumericArgs(3);
2094 133 : if (thisVentilation.EffAngle < 0.0 || thisVentilation.EffAngle >= 360.0) {
2095 0 : ShowSevereError(
2096 : state,
2097 0 : format(
2098 : "{}{}=\"{}\", {} must be between 0 and 360.", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cNumericFieldNames(3)));
2099 0 : ErrorsFound = true;
2100 : }
2101 :
2102 133 : thisVentilation.DH = rNumericArgs(4);
2103 133 : if (thisVentilation.DH < 0.0) {
2104 0 : ShowSevereError(
2105 0 : state, format("{}{}=\"{}\", {} must be positive.", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cNumericFieldNames(4)));
2106 0 : ErrorsFound = true;
2107 : }
2108 :
2109 133 : thisVentilation.DiscCoef = rNumericArgs(5);
2110 133 : if (thisVentilation.DiscCoef != Constant::AutoCalculate && (thisVentilation.DiscCoef < 0.0 || thisVentilation.DiscCoef > 1.0)) {
2111 0 : ShowSevereError(
2112 : state,
2113 0 : format("{}{}=\"{}\", {} must be between 0 and 1.", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cNumericFieldNames(5)));
2114 0 : ErrorsFound = true;
2115 : }
2116 :
2117 133 : if (!lNumericFieldBlanks(6)) {
2118 133 : thisVentilation.MinIndoorTemperature = rNumericArgs(6);
2119 : } else {
2120 0 : thisVentilation.MinIndoorTemperature = -VentilTempLimit;
2121 : }
2122 133 : if ((thisVentilation.MinIndoorTemperature < -VentilTempLimit) || (thisVentilation.MinIndoorTemperature > VentilTempLimit)) {
2123 0 : ShowSevereError(state,
2124 0 : format("{}{} statement = {} must have {} between -100C and 100C",
2125 : RoutineName,
2126 : cCurrentModuleObject,
2127 : cAlphaArgs(1),
2128 : cNumericFieldNames(6)));
2129 0 : ErrorsFound = true;
2130 : }
2131 :
2132 133 : thisVentilation.MinIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(4));
2133 133 : if (thisVentilation.MinIndoorTempSchedPtr > 0) {
2134 0 : if (!lNumericFieldBlanks(6))
2135 0 : ShowWarningError(state,
2136 0 : format("{}The Minimum Indoor Temperature value and schedule are provided. The scheduled temperature will be "
2137 : "used in the {} object = {}",
2138 : RoutineName,
2139 : cCurrentModuleObject,
2140 : cAlphaArgs(1)));
2141 : // Check min and max values in the schedule to ensure both values are within the range
2142 0 : if (!ScheduleManager::CheckScheduleValueMinMax(
2143 : state, thisVentilation.MinIndoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
2144 0 : ShowSevereError(
2145 : state,
2146 0 : format("{}{} statement = {} must have a minimum indoor temperature between -100C and 100C defined in the schedule = {}",
2147 : RoutineName,
2148 : cCurrentModuleObject,
2149 : cAlphaArgs(1),
2150 : cAlphaArgs(4)));
2151 0 : ErrorsFound = true;
2152 : }
2153 : }
2154 133 : if (thisVentilation.MinIndoorTempSchedPtr == 0 && lNumericFieldBlanks(6) && (!lAlphaFieldBlanks(4))) {
2155 0 : ShowWarningError(state,
2156 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
2157 : RoutineName,
2158 : cNumericFieldNames(6),
2159 0 : -VentilTempLimit));
2160 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2161 : }
2162 : // Check Minimum indoor temperature value and schedule fields
2163 133 : if (!lNumericFieldBlanks(6) && (!cAlphaArgs(4).empty() && thisVentilation.MinIndoorTempSchedPtr == 0)) {
2164 0 : ShowWarningError(state,
2165 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
2166 : RoutineName,
2167 : cAlphaFieldNames(4),
2168 : cAlphaArgs(4),
2169 : rNumericArgs(11)));
2170 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2171 : }
2172 :
2173 133 : if (!lNumericFieldBlanks(7)) {
2174 132 : thisVentilation.MaxIndoorTemperature = rNumericArgs(7);
2175 : } else {
2176 1 : thisVentilation.MaxIndoorTemperature = VentilTempLimit;
2177 : }
2178 133 : if ((thisVentilation.MaxIndoorTemperature < -VentilTempLimit) || (thisVentilation.MaxIndoorTemperature > VentilTempLimit)) {
2179 0 : ShowSevereError(state,
2180 0 : format("{}{}=\"{}\" must have a maximum indoor temperature between -100C and 100C",
2181 : RoutineName,
2182 : cCurrentModuleObject,
2183 : cAlphaArgs(1)));
2184 0 : ErrorsFound = true;
2185 : }
2186 :
2187 133 : thisVentilation.MaxIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(5));
2188 133 : if (thisVentilation.MaxIndoorTempSchedPtr > 0) {
2189 0 : if (!lNumericFieldBlanks(7))
2190 0 : ShowWarningError(state,
2191 0 : format("{}The Maximum Indoor Temperature value and schedule are provided. The scheduled temperature will be "
2192 : "used in the {} object = {}",
2193 : RoutineName,
2194 : cCurrentModuleObject,
2195 : cAlphaArgs(1)));
2196 : // Check min and max values in the schedule to ensure both values are within the range
2197 0 : if (!ScheduleManager::CheckScheduleValueMinMax(
2198 : state, thisVentilation.MaxIndoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
2199 0 : ShowSevereError(state,
2200 0 : format("{} = {} must have a maximum indoor temperature between -100C and 100C defined in the schedule = {}",
2201 : cCurrentModuleObject,
2202 : cAlphaArgs(1),
2203 : cAlphaArgs(5)));
2204 0 : ErrorsFound = true;
2205 : }
2206 : }
2207 133 : if (thisVentilation.MaxIndoorTempSchedPtr == 0 && lNumericFieldBlanks(7) && (!lAlphaFieldBlanks(5))) {
2208 0 : ShowWarningError(state,
2209 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
2210 : RoutineName,
2211 : cNumericFieldNames(7),
2212 : VentilTempLimit));
2213 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2214 : }
2215 : // Check Maximum indoor temperature value and schedule fields
2216 133 : if (!lNumericFieldBlanks(7) && ((!lAlphaFieldBlanks(5)) && thisVentilation.MaxIndoorTempSchedPtr == 0)) {
2217 0 : ShowWarningError(state,
2218 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
2219 : RoutineName,
2220 : cAlphaFieldNames(7),
2221 : cAlphaArgs(5),
2222 : rNumericArgs(7)));
2223 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2224 : }
2225 :
2226 133 : if (!lNumericFieldBlanks(8)) {
2227 133 : thisVentilation.DelTemperature = rNumericArgs(8);
2228 : } else {
2229 0 : thisVentilation.DelTemperature = -VentilTempLimit;
2230 : }
2231 :
2232 133 : thisVentilation.DeltaTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(6));
2233 133 : if (thisVentilation.DeltaTempSchedPtr > 0) {
2234 0 : if (!lNumericFieldBlanks(8))
2235 0 : ShowWarningError(state,
2236 0 : format("{}The Delta Temperature value and schedule are provided. The scheduled temperature will be used in "
2237 : "the {} object = {}",
2238 : RoutineName,
2239 : cCurrentModuleObject,
2240 : cAlphaArgs(1)));
2241 : // Check min value in the schedule to ensure both values are within the range
2242 0 : if (ScheduleManager::GetScheduleMinValue(state, thisVentilation.DeltaTempSchedPtr) < -VentilTempLimit) {
2243 0 : ShowSevereError(
2244 : state,
2245 0 : format("{}{} statement = {} must have a delta temperature equal to or above -100C defined in the schedule = {}",
2246 : RoutineName,
2247 : cCurrentModuleObject,
2248 : cAlphaArgs(1),
2249 : cAlphaArgs(8)));
2250 0 : ErrorsFound = true;
2251 : }
2252 : }
2253 133 : if (thisVentilation.DeltaTempSchedPtr == 0 && lNumericFieldBlanks(8) && (!lAlphaFieldBlanks(6))) {
2254 0 : ShowWarningError(state,
2255 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
2256 : RoutineName,
2257 : cNumericFieldNames(8),
2258 : VentilTempLimit));
2259 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2260 : }
2261 133 : if (!lNumericFieldBlanks(8) && ((!lAlphaFieldBlanks(6)) && thisVentilation.DeltaTempSchedPtr == 0)) {
2262 0 : ShowWarningError(state,
2263 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
2264 : RoutineName,
2265 : cAlphaFieldNames(6),
2266 : cAlphaArgs(6),
2267 : rNumericArgs(8)));
2268 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2269 : }
2270 :
2271 133 : thisVentilation.MinOutdoorTemperature = !lNumericFieldBlanks(9) ? rNumericArgs(9) : -VentilTempLimit;
2272 133 : if ((thisVentilation.MinOutdoorTemperature < -VentilTempLimit) || (thisVentilation.MinOutdoorTemperature > VentilTempLimit)) {
2273 0 : ShowSevereError(state,
2274 0 : format("{}{} statement = {} must have {} between -100C and 100C",
2275 : RoutineName,
2276 : cCurrentModuleObject,
2277 : cAlphaArgs(1),
2278 : cNumericFieldNames(9)));
2279 0 : ErrorsFound = true;
2280 : }
2281 :
2282 133 : thisVentilation.MinOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(7));
2283 133 : if (thisVentilation.MinOutdoorTempSchedPtr > 0) {
2284 0 : if (!lNumericFieldBlanks(9))
2285 0 : ShowWarningError(state,
2286 0 : format("{}The Minimum Outdoor Temperature value and schedule are provided. The scheduled temperature will "
2287 : "be used in the {} object = {}",
2288 : RoutineName,
2289 : cCurrentModuleObject,
2290 : cAlphaArgs(1)));
2291 : // Check min and max values in the schedule to ensure both values are within the range
2292 0 : if (!ScheduleManager::CheckScheduleValueMinMax(
2293 : state, thisVentilation.MinOutdoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
2294 0 : ShowSevereError(
2295 : state,
2296 0 : format("{}{} statement = {} must have a minimum outdoor temperature between -100C and 100C defined in the schedule = {}",
2297 : RoutineName,
2298 : cCurrentModuleObject,
2299 : cAlphaArgs(1),
2300 : cAlphaArgs(7)));
2301 0 : ErrorsFound = true;
2302 : }
2303 : }
2304 133 : if (thisVentilation.MinOutdoorTempSchedPtr == 0 && lNumericFieldBlanks(9) && (!lAlphaFieldBlanks(7))) {
2305 0 : ShowWarningError(
2306 : state,
2307 0 : format("{}Minimum Outdoor Temperature: the value field is blank and schedule field is invalid. The default value "
2308 : "will be used ({:.1R}) ",
2309 : RoutineName,
2310 0 : -VentilTempLimit));
2311 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2312 : }
2313 : // Check Minimum outdoor temperature value and schedule fields
2314 133 : if (!lNumericFieldBlanks(9) && ((!lAlphaFieldBlanks(7)) && thisVentilation.MinOutdoorTempSchedPtr == 0)) {
2315 0 : ShowWarningError(state,
2316 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
2317 : RoutineName,
2318 : cAlphaFieldNames(7),
2319 : cAlphaArgs(7),
2320 : rNumericArgs(14)));
2321 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2322 : }
2323 :
2324 133 : thisVentilation.MaxOutdoorTemperature = !lNumericFieldBlanks(10) ? rNumericArgs(10) : VentilTempLimit;
2325 133 : if ((thisVentilation.MaxOutdoorTemperature < -VentilTempLimit) || (thisVentilation.MaxOutdoorTemperature > VentilTempLimit)) {
2326 0 : ShowSevereError(state,
2327 0 : format("{}{} statement = {} must have a {} between -100C and 100C",
2328 : RoutineName,
2329 : cCurrentModuleObject,
2330 : cAlphaArgs(1),
2331 : cNumericFieldNames(10)));
2332 0 : ErrorsFound = true;
2333 : }
2334 :
2335 133 : thisVentilation.MaxOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(8));
2336 133 : if (thisVentilation.MaxOutdoorTempSchedPtr > 0) {
2337 0 : if (!lNumericFieldBlanks(10))
2338 0 : ShowWarningError(state,
2339 0 : format("{}The Maximum Outdoor Temperature value and schedule are provided. The scheduled temperature will "
2340 : "be used in the {} object = {}",
2341 : RoutineName,
2342 : cCurrentModuleObject,
2343 : cAlphaArgs(1)));
2344 0 : if (!ScheduleManager::CheckScheduleValueMinMax(
2345 : state, thisVentilation.MaxOutdoorTempSchedPtr, ">=", -VentilTempLimit, "<=", VentilTempLimit)) {
2346 0 : ShowSevereError(
2347 : state,
2348 0 : format("{}{} statement = {} must have a maximum outdoor temperature between -100C and 100C defined in the schedule = {}",
2349 : RoutineName,
2350 : cCurrentModuleObject,
2351 : cAlphaArgs(1),
2352 : cAlphaArgs(8)));
2353 0 : ErrorsFound = true;
2354 : }
2355 : }
2356 133 : if (thisVentilation.MaxOutdoorTempSchedPtr == 0 && lNumericFieldBlanks(10) && (!lAlphaFieldBlanks(8))) {
2357 0 : ShowWarningError(state,
2358 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
2359 : RoutineName,
2360 : cNumericFieldNames(10),
2361 : VentilTempLimit));
2362 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2363 : }
2364 : // Check Maximum outdoor temperature value and schedule fields
2365 133 : if (!lNumericFieldBlanks(10) && ((!lAlphaFieldBlanks(8)) && thisVentilation.MaxOutdoorTempSchedPtr == 0)) {
2366 0 : ShowWarningError(state,
2367 0 : format("{}{} = {}is invalid. The constant value will be used at {:.1R} degrees C ",
2368 : RoutineName,
2369 : cAlphaFieldNames(8),
2370 : cAlphaArgs(8),
2371 : rNumericArgs(10)));
2372 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2373 : }
2374 :
2375 133 : thisVentilation.MaxWindSpeed = !lNumericFieldBlanks(11) ? rNumericArgs(11) : VentilWSLimit;
2376 133 : if ((thisVentilation.MaxWindSpeed < -VentilWSLimit) || (thisVentilation.MaxWindSpeed > VentilWSLimit)) {
2377 0 : ShowSevereError(state,
2378 0 : format("{}{} statement = {} must have a maximum wind speed between 0 m/s and 40 m/s",
2379 : RoutineName,
2380 : cCurrentModuleObject,
2381 : cAlphaArgs(1)));
2382 0 : ErrorsFound = true;
2383 : }
2384 :
2385 : // Report variables should be added for individual VENTILATION objects, in addition to zone totals below
2386 :
2387 133 : if (thisVentilation.ZonePtr > 0) {
2388 133 : if (RepVarSet(thisVentilation.ZonePtr) && !thisZone.zoneOAQuadratureSum) {
2389 132 : RepVarSet(thisVentilation.ZonePtr) = false;
2390 264 : SetupOutputVariable(state,
2391 : "Zone Ventilation Sensible Heat Loss Energy",
2392 : Constant::Units::J,
2393 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilHeatLoss,
2394 : OutputProcessor::TimeStepType::System,
2395 : OutputProcessor::StoreType::Sum,
2396 132 : thisZone.Name);
2397 264 : SetupOutputVariable(state,
2398 : "Zone Ventilation Sensible Heat Gain Energy",
2399 : Constant::Units::J,
2400 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilHeatGain,
2401 : OutputProcessor::TimeStepType::System,
2402 : OutputProcessor::StoreType::Sum,
2403 132 : thisZone.Name);
2404 264 : SetupOutputVariable(state,
2405 : "Zone Ventilation Latent Heat Loss Energy",
2406 : Constant::Units::J,
2407 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilLatentLoss,
2408 : OutputProcessor::TimeStepType::System,
2409 : OutputProcessor::StoreType::Sum,
2410 132 : thisZone.Name);
2411 264 : SetupOutputVariable(state,
2412 : "Zone Ventilation Latent Heat Gain Energy",
2413 : Constant::Units::J,
2414 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilLatentGain,
2415 : OutputProcessor::TimeStepType::System,
2416 : OutputProcessor::StoreType::Sum,
2417 132 : thisZone.Name);
2418 264 : SetupOutputVariable(state,
2419 : "Zone Ventilation Total Heat Loss Energy",
2420 : Constant::Units::J,
2421 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilTotalLoss,
2422 : OutputProcessor::TimeStepType::System,
2423 : OutputProcessor::StoreType::Sum,
2424 132 : thisZone.Name);
2425 264 : SetupOutputVariable(state,
2426 : "Zone Ventilation Total Heat Gain Energy",
2427 : Constant::Units::J,
2428 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilTotalGain,
2429 : OutputProcessor::TimeStepType::System,
2430 : OutputProcessor::StoreType::Sum,
2431 132 : thisZone.Name);
2432 264 : SetupOutputVariable(state,
2433 : "Zone Ventilation Current Density Volume Flow Rate",
2434 : Constant::Units::m3_s,
2435 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVdotCurDensity,
2436 : OutputProcessor::TimeStepType::System,
2437 : OutputProcessor::StoreType::Average,
2438 132 : thisZone.Name);
2439 264 : SetupOutputVariable(state,
2440 : "Zone Ventilation Standard Density Volume Flow Rate",
2441 : Constant::Units::m3_s,
2442 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVdotStdDensity,
2443 : OutputProcessor::TimeStepType::System,
2444 : OutputProcessor::StoreType::Average,
2445 132 : thisZone.Name);
2446 264 : SetupOutputVariable(state,
2447 : "Zone Ventilation Current Density Volume",
2448 : Constant::Units::m3,
2449 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVolumeCurDensity,
2450 : OutputProcessor::TimeStepType::System,
2451 : OutputProcessor::StoreType::Sum,
2452 132 : thisZone.Name);
2453 264 : SetupOutputVariable(state,
2454 : "Zone Ventilation Standard Density Volume",
2455 : Constant::Units::m3,
2456 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilVolumeStdDensity,
2457 : OutputProcessor::TimeStepType::System,
2458 : OutputProcessor::StoreType::Sum,
2459 132 : thisZone.Name);
2460 264 : SetupOutputVariable(state,
2461 : "Zone Ventilation Mass",
2462 : Constant::Units::kg,
2463 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilMass,
2464 : OutputProcessor::TimeStepType::System,
2465 : OutputProcessor::StoreType::Sum,
2466 132 : thisZone.Name);
2467 264 : SetupOutputVariable(state,
2468 : "Zone Ventilation Mass Flow Rate",
2469 : Constant::Units::kg_s,
2470 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilMdot,
2471 : OutputProcessor::TimeStepType::System,
2472 : OutputProcessor::StoreType::Average,
2473 132 : thisZone.Name);
2474 264 : SetupOutputVariable(state,
2475 : "Zone Ventilation Air Change Rate",
2476 : Constant::Units::ach,
2477 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilAirChangeRate,
2478 : OutputProcessor::TimeStepType::System,
2479 : OutputProcessor::StoreType::Average,
2480 132 : thisZone.Name);
2481 264 : SetupOutputVariable(state,
2482 : "Zone Ventilation Fan Electricity Energy",
2483 : Constant::Units::J,
2484 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilFanElec,
2485 : OutputProcessor::TimeStepType::System,
2486 : OutputProcessor::StoreType::Sum,
2487 132 : thisZone.Name,
2488 : Constant::eResource::Electricity,
2489 : OutputProcessor::Group::Building,
2490 : OutputProcessor::EndUseCat::Fans,
2491 : "Ventilation (simple)",
2492 132 : thisZone.Name);
2493 264 : SetupOutputVariable(state,
2494 : "Zone Ventilation Air Inlet Temperature",
2495 : Constant::Units::C,
2496 132 : state.dataHeatBal->ZnAirRpt(thisVentilation.ZonePtr).VentilAirTemp,
2497 : OutputProcessor::TimeStepType::System,
2498 : OutputProcessor::StoreType::Average,
2499 132 : thisZone.Name);
2500 : }
2501 : }
2502 :
2503 133 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
2504 132 : SetupEMSActuator(state,
2505 : "Zone Ventilation",
2506 : thisVentilation.Name,
2507 : "Air Exchange Flow Rate",
2508 : "[m3/s]",
2509 132 : thisVentilation.EMSSimpleVentOn,
2510 132 : thisVentilation.EMSimpleVentFlowRate);
2511 : }
2512 : }
2513 : }
2514 : }
2515 :
2516 : // Set up and process ZoneMixing and ZoneCrossMixing inputs
2517 :
2518 796 : RepVarSet = true;
2519 :
2520 796 : cCurrentModuleObject = "ZoneMixing";
2521 796 : int numZoneMixingInputObjects = 0;
2522 1592 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> zoneMixingInputObjects;
2523 796 : InternalHeatGains::setupIHGZonesAndSpaces(state,
2524 : cCurrentModuleObject,
2525 : zoneMixingInputObjects,
2526 : numZoneMixingInputObjects,
2527 796 : state.dataHeatBal->TotMixing,
2528 : ErrorsFound,
2529 : zoneListNotAllowed);
2530 :
2531 796 : if (state.dataHeatBal->TotMixing > 0) {
2532 17 : cCurrentModuleObject = "ZoneMixing";
2533 17 : state.dataHeatBal->Mixing.allocate(state.dataHeatBal->TotMixing);
2534 17 : int mixingNum = 0;
2535 71 : for (int mixingInputNum = 1; mixingInputNum <= numZoneMixingInputObjects; ++mixingInputNum) {
2536 :
2537 54 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2538 : cCurrentModuleObject,
2539 : mixingInputNum,
2540 : cAlphaArgs,
2541 : NumAlpha,
2542 : rNumericArgs,
2543 : NumNumber,
2544 : IOStat,
2545 : lNumericFieldBlanks,
2546 : lAlphaFieldBlanks,
2547 : cAlphaFieldNames,
2548 : cNumericFieldNames);
2549 :
2550 : // Create one Mixing instance for every space associated with this input object
2551 54 : auto const &thisMixingInput = zoneMixingInputObjects(mixingInputNum);
2552 108 : for (int Item1 = 1; Item1 <= thisMixingInput.numOfSpaces; ++Item1) {
2553 54 : ++mixingNum;
2554 54 : auto &thisMixing = state.dataHeatBal->Mixing(mixingNum);
2555 54 : thisMixing.Name = thisMixingInput.names(Item1);
2556 54 : thisMixing.spaceIndex = thisMixingInput.spaceNums(Item1);
2557 54 : auto const &thisSpace = state.dataHeatBal->space(thisMixing.spaceIndex);
2558 54 : thisMixing.ZonePtr = thisSpace.zoneNum;
2559 54 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
2560 :
2561 54 : if (lAlphaFieldBlanks(3)) {
2562 0 : thisMixing.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
2563 : } else {
2564 54 : thisMixing.SchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
2565 54 : if (thisMixing.SchedPtr == 0) {
2566 0 : ShowWarningError(state,
2567 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\"",
2568 : RoutineName,
2569 : cCurrentModuleObject,
2570 0 : thisMixingInput.Name,
2571 : cAlphaFieldNames(3),
2572 : cAlphaArgs(3)));
2573 0 : ErrorsFound = true;
2574 : }
2575 : }
2576 :
2577 : // Mixing equipment design level calculation method
2578 54 : AirflowSpec flow = static_cast<AirflowSpec>(getEnumValue(airflowNamesUC, cAlphaArgs(4))); // NOLINT(modernize-use-auto)
2579 54 : switch (flow) {
2580 34 : case AirflowSpec::Flow:
2581 : case AirflowSpec::FlowPerZone:
2582 34 : thisMixing.DesignLevel = rNumericArgs(1);
2583 34 : if (lNumericFieldBlanks(1)) {
2584 0 : ShowWarningError(state,
2585 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Mixing will result.",
2586 : RoutineName,
2587 : cCurrentModuleObject,
2588 0 : thisMixingInput.Name,
2589 : cAlphaFieldNames(4),
2590 : cNumericFieldNames(1)));
2591 : } else {
2592 34 : Real64 spaceFrac = 1.0;
2593 34 : if (!thisMixingInput.spaceListActive && (thisMixingInput.numOfSpaces > 1)) {
2594 0 : Real64 const zoneVolume = thisZone.Volume;
2595 0 : if (zoneVolume > 0.0) {
2596 0 : spaceFrac = thisSpace.Volume / zoneVolume;
2597 : } else {
2598 0 : ShowSevereError(state, format("{}Zone volume is zero when allocating Mixing to Spaces.", RoutineName));
2599 0 : ShowContinueError(
2600 0 : state, format("Occurs for {}=\"{}\" in Zone=\"{}\".", cCurrentModuleObject, thisMixingInput.Name, thisZone.Name));
2601 0 : ErrorsFound = true;
2602 : }
2603 : }
2604 :
2605 34 : thisMixing.DesignLevel = rNumericArgs(1) * spaceFrac;
2606 : }
2607 34 : break;
2608 :
2609 20 : case AirflowSpec::FlowPerArea:
2610 20 : if (thisMixing.spaceIndex != 0) {
2611 20 : if (rNumericArgs(2) >= 0.0) {
2612 20 : thisMixing.DesignLevel = rNumericArgs(2) * thisSpace.FloorArea;
2613 20 : if (thisMixing.spaceIndex > 0) {
2614 20 : if (thisZone.FloorArea <= 0.0) {
2615 0 : ShowWarningError(state,
2616 0 : format("{}{}=\"{}\", {} specifies {}, but Space Floor Area = 0. 0 Mixing will result.",
2617 : RoutineName,
2618 : cCurrentModuleObject,
2619 0 : thisMixingInput.Name,
2620 : cAlphaFieldNames(4),
2621 : cNumericFieldNames(2)));
2622 : }
2623 : }
2624 : } else {
2625 0 : ShowSevereError(state,
2626 0 : format("{}{}=\"{}\", invalid flow/area specification [<0.0]={:.3R}",
2627 : RoutineName,
2628 : cCurrentModuleObject,
2629 0 : thisMixingInput.Name,
2630 : rNumericArgs(2)));
2631 0 : ErrorsFound = true;
2632 : }
2633 : }
2634 20 : if (lNumericFieldBlanks(2)) {
2635 0 : ShowWarningError(state,
2636 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Mixing will result.",
2637 : RoutineName,
2638 : cCurrentModuleObject,
2639 0 : thisMixingInput.Name,
2640 : cAlphaFieldNames(4),
2641 : cNumericFieldNames(2)));
2642 : }
2643 20 : break;
2644 :
2645 0 : case AirflowSpec::FlowPerPerson:
2646 0 : if (thisMixing.spaceIndex != 0) {
2647 0 : if (rNumericArgs(3) >= 0.0) {
2648 0 : thisMixing.DesignLevel = rNumericArgs(3) * thisSpace.TotOccupants;
2649 0 : if (thisSpace.TotOccupants <= 0.0) {
2650 0 : ShowWarningError(state,
2651 0 : format("{}{}=\"{}\", {} specifies {}, but Space Total Occupants = 0. 0 Mixing will result.",
2652 : RoutineName,
2653 : cCurrentModuleObject,
2654 0 : thisMixingInput.Name,
2655 : cAlphaFieldNames(4),
2656 : cNumericFieldNames(3)));
2657 : }
2658 : } else {
2659 0 : ShowSevereError(state,
2660 0 : format("{}{}=\"{}\", invalid flow/person specification [<0.0]={:.3R}",
2661 : RoutineName,
2662 : cCurrentModuleObject,
2663 0 : thisMixingInput.Name,
2664 : rNumericArgs(3)));
2665 0 : ErrorsFound = true;
2666 : }
2667 : }
2668 0 : if (lNumericFieldBlanks(3)) {
2669 0 : ShowWarningError(state,
2670 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Mixing will result.",
2671 : RoutineName,
2672 : cCurrentModuleObject,
2673 0 : thisMixingInput.Name,
2674 : cAlphaFieldNames(4),
2675 : cNumericFieldNames(3)));
2676 : }
2677 0 : break;
2678 :
2679 0 : case AirflowSpec::AirChanges:
2680 0 : if (thisMixing.spaceIndex != 0) {
2681 0 : if (rNumericArgs(4) >= 0.0) {
2682 0 : thisMixing.DesignLevel = rNumericArgs(4) * thisSpace.Volume / Constant::SecInHour;
2683 0 : if (thisSpace.Volume <= 0.0) {
2684 0 : ShowWarningError(state,
2685 0 : format("{}{}=\"{}\", {} specifies {}, but Space Volume = 0. 0 Mixing will result.",
2686 : RoutineName,
2687 : cCurrentModuleObject,
2688 0 : thisMixingInput.Name,
2689 : cAlphaFieldNames(4),
2690 : cNumericFieldNames(4)));
2691 : }
2692 : } else {
2693 0 : ShowSevereError(state,
2694 0 : format("{}{}=\"{}\", invalid ACH (air changes per hour) specification [<0.0]={:.3R}",
2695 : RoutineName,
2696 : cCurrentModuleObject,
2697 0 : thisMixingInput.Name,
2698 : rNumericArgs(4)));
2699 0 : ErrorsFound = true;
2700 : }
2701 : }
2702 0 : if (lNumericFieldBlanks(4)) {
2703 0 : ShowWarningError(state,
2704 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Mixing will result.",
2705 : RoutineName,
2706 : cCurrentModuleObject,
2707 0 : thisMixingInput.Name,
2708 : cAlphaFieldNames(4),
2709 : cNumericFieldNames(4)));
2710 : }
2711 0 : break;
2712 :
2713 0 : default:
2714 0 : ShowSevereError(
2715 0 : state, format("{}{}=\"{}\", invalid calculation method={}", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(4)));
2716 0 : ErrorsFound = true;
2717 : }
2718 :
2719 54 : thisMixing.fromSpaceIndex = Util::FindItemInList(cAlphaArgs(5), state.dataHeatBal->space);
2720 54 : if (thisMixing.fromSpaceIndex == 0) {
2721 0 : thisMixing.FromZone = Util::FindItemInList(cAlphaArgs(5), state.dataHeatBal->Zone);
2722 : } else {
2723 54 : thisMixing.FromZone = state.dataHeatBal->space(thisMixing.fromSpaceIndex).zoneNum;
2724 : }
2725 54 : if ((thisMixing.FromZone == 0) && (thisMixing.fromSpaceIndex == 0)) {
2726 0 : ShowSevereError(
2727 : state,
2728 0 : format("{}{} not found={} for {}={}", RoutineName, cAlphaFieldNames(5), cAlphaArgs(5), cCurrentModuleObject, cAlphaArgs(1)));
2729 0 : ErrorsFound = true;
2730 : }
2731 54 : thisMixing.DeltaTemperature = rNumericArgs(5);
2732 :
2733 54 : if (NumAlpha > 5) {
2734 13 : thisMixing.DeltaTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(6));
2735 13 : if (thisMixing.DeltaTempSchedPtr > 0) {
2736 5 : if (!lNumericFieldBlanks(5))
2737 0 : ShowWarningError(state,
2738 0 : format("{}The Delta Temperature value and schedule are provided. The scheduled temperature will be used "
2739 : "in the {} object = {}",
2740 : RoutineName,
2741 : cCurrentModuleObject,
2742 : cAlphaArgs(1)));
2743 5 : if (ScheduleManager::GetScheduleMinValue(state, thisMixing.DeltaTempSchedPtr) < -MixingTempLimit) {
2744 0 : ShowSevereError(
2745 : state,
2746 0 : format("{}{} statement = {} must have a delta temperature equal to or above -100C defined in the schedule = {}",
2747 : RoutineName,
2748 : cCurrentModuleObject,
2749 : cAlphaArgs(1),
2750 : cAlphaArgs(6)));
2751 0 : ErrorsFound = true;
2752 : }
2753 : }
2754 : }
2755 54 : if (thisMixing.DeltaTempSchedPtr == 0 && lNumericFieldBlanks(5) && (!lAlphaFieldBlanks(6))) {
2756 0 : ShowWarningError(state,
2757 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
2758 : RoutineName,
2759 : cNumericFieldNames(5),
2760 : rNumericArgs(5)));
2761 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2762 : }
2763 54 : if (!lNumericFieldBlanks(5) && ((!lAlphaFieldBlanks(6)) && thisMixing.DeltaTempSchedPtr == 0)) {
2764 0 : ShowWarningError(state,
2765 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
2766 : RoutineName,
2767 : cAlphaFieldNames(6),
2768 : cAlphaArgs(6),
2769 : rNumericArgs(5)));
2770 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
2771 : }
2772 :
2773 54 : if (NumAlpha > 6) {
2774 13 : thisMixing.MinIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(7));
2775 13 : if (thisMixing.MinIndoorTempSchedPtr == 0) {
2776 8 : if ((!lAlphaFieldBlanks(7))) {
2777 0 : ShowSevereError(state,
2778 0 : format("{}{} not found={} for {}={}",
2779 : RoutineName,
2780 : cAlphaFieldNames(7),
2781 : cAlphaArgs(7),
2782 : cCurrentModuleObject,
2783 : cAlphaArgs(1)));
2784 0 : ErrorsFound = true;
2785 : }
2786 : }
2787 13 : if (thisMixing.MinIndoorTempSchedPtr > 0) {
2788 : // Check min and max values in the schedule to ensure both values are within the range
2789 5 : if (!ScheduleManager::CheckScheduleValueMinMax(
2790 : state, thisMixing.MinIndoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
2791 0 : ShowSevereError(
2792 : state,
2793 0 : format("{}{} statement = {} must have a minimum zone temperature between -100C and 100C defined in the schedule = {}",
2794 : RoutineName,
2795 : cCurrentModuleObject,
2796 : cAlphaArgs(1),
2797 : cAlphaArgs(7)));
2798 0 : ErrorsFound = true;
2799 : }
2800 : }
2801 : }
2802 :
2803 54 : if (NumAlpha > 7) {
2804 13 : thisMixing.MaxIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(8));
2805 13 : if (thisMixing.MaxIndoorTempSchedPtr == 0) {
2806 8 : if ((!lAlphaFieldBlanks(8))) {
2807 0 : ShowSevereError(state,
2808 0 : format("{}{}=\"{}\", {} not found=\"{}\".",
2809 : RoutineName,
2810 : cCurrentModuleObject,
2811 : cAlphaArgs(1),
2812 : cAlphaFieldNames(8),
2813 : cAlphaArgs(8)));
2814 0 : ErrorsFound = true;
2815 : }
2816 : }
2817 13 : if (thisMixing.MaxIndoorTempSchedPtr > 0) {
2818 : // Check min and max values in the schedule to ensure both values are within the range
2819 5 : if (!ScheduleManager::CheckScheduleValueMinMax(
2820 : state, thisMixing.MaxIndoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
2821 0 : ShowSevereError(
2822 : state,
2823 0 : format("{}{}=\"{}\" must have a maximum zone temperature between -100C and 100C defined in the schedule = {}",
2824 : RoutineName,
2825 : cCurrentModuleObject,
2826 : cAlphaArgs(1),
2827 : cAlphaArgs(8)));
2828 0 : ErrorsFound = true;
2829 : }
2830 : }
2831 : }
2832 :
2833 54 : if (NumAlpha > 8) {
2834 13 : thisMixing.MinSourceTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(9));
2835 13 : if (thisMixing.MinSourceTempSchedPtr == 0) {
2836 8 : if ((!lAlphaFieldBlanks(9))) {
2837 0 : ShowSevereError(state,
2838 0 : format("{}{}=\"{}\", {} not found=\"{}\".",
2839 : RoutineName,
2840 : cCurrentModuleObject,
2841 : cAlphaArgs(1),
2842 : cAlphaFieldNames(9),
2843 : cAlphaArgs(9)));
2844 0 : ErrorsFound = true;
2845 : }
2846 : }
2847 13 : if (thisMixing.MinSourceTempSchedPtr > 0) {
2848 : // Check min and max values in the schedule to ensure both values are within the range
2849 5 : if (!ScheduleManager::CheckScheduleValueMinMax(
2850 : state, thisMixing.MinSourceTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
2851 0 : ShowSevereError(
2852 : state,
2853 0 : format("{}{}=\"{}\" must have a minimum source temperature between -100C and 100C defined in the schedule = {}",
2854 : RoutineName,
2855 : cCurrentModuleObject,
2856 : cAlphaArgs(1),
2857 : cAlphaArgs(9)));
2858 0 : ErrorsFound = true;
2859 : }
2860 : }
2861 : }
2862 :
2863 54 : if (NumAlpha > 9) {
2864 13 : thisMixing.MaxSourceTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(10));
2865 13 : if (thisMixing.MaxSourceTempSchedPtr == 0) {
2866 8 : if ((!lAlphaFieldBlanks(10))) {
2867 0 : ShowSevereError(state,
2868 0 : format("{}{}=\"{}\", {} not found=\"{}\".",
2869 : RoutineName,
2870 : cCurrentModuleObject,
2871 : cAlphaArgs(1),
2872 : cAlphaFieldNames(10),
2873 : cAlphaArgs(10)));
2874 0 : ErrorsFound = true;
2875 : }
2876 : }
2877 13 : if (thisMixing.MaxSourceTempSchedPtr > 0) {
2878 : // Check min and max values in the schedule to ensure both values are within the range
2879 5 : if (!ScheduleManager::CheckScheduleValueMinMax(
2880 : state, thisMixing.MaxSourceTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
2881 0 : ShowSevereError(state,
2882 0 : format("{}{} statement =\"{}\" must have a maximum source temperature between -100C and 100C defined in "
2883 : "the schedule = {}",
2884 : RoutineName,
2885 : cCurrentModuleObject,
2886 : cAlphaArgs(1),
2887 : cAlphaArgs(10)));
2888 0 : ErrorsFound = true;
2889 : }
2890 : }
2891 : }
2892 :
2893 54 : if (NumAlpha > 10) {
2894 13 : thisMixing.MinOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(11));
2895 13 : if (thisMixing.MinOutdoorTempSchedPtr == 0) {
2896 8 : if ((!lAlphaFieldBlanks(11))) {
2897 0 : ShowSevereError(state,
2898 0 : format("{}{}=\"{}\", {} not found=\"{}\".",
2899 : RoutineName,
2900 : cCurrentModuleObject,
2901 : cAlphaArgs(1),
2902 : cAlphaFieldNames(11),
2903 : cAlphaArgs(11)));
2904 0 : ErrorsFound = true;
2905 : }
2906 : }
2907 13 : if (thisMixing.MinOutdoorTempSchedPtr > 0) {
2908 : // Check min and max values in the schedule to ensure both values are within the range
2909 5 : if (!ScheduleManager::CheckScheduleValueMinMax(
2910 : state, thisMixing.MinOutdoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
2911 0 : ShowSevereError(
2912 : state,
2913 0 : format("{}{} =\"{}\" must have a minimum outdoor temperature between -100C and 100C defined in the schedule = {}",
2914 : RoutineName,
2915 : cCurrentModuleObject,
2916 : cAlphaArgs(1),
2917 : cAlphaArgs(11)));
2918 0 : ErrorsFound = true;
2919 : }
2920 : }
2921 : }
2922 :
2923 54 : if (NumAlpha > 11) {
2924 13 : thisMixing.MaxOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(12));
2925 13 : if (thisMixing.MaxOutdoorTempSchedPtr == 0) {
2926 8 : if ((!lAlphaFieldBlanks(12))) {
2927 0 : ShowSevereError(state,
2928 0 : format("{}{}=\"{}\", {} not found=\"{}\".",
2929 : RoutineName,
2930 : cCurrentModuleObject,
2931 : cAlphaArgs(1),
2932 : cAlphaFieldNames(12),
2933 : cAlphaArgs(12)));
2934 0 : ErrorsFound = true;
2935 : }
2936 : }
2937 13 : if (thisMixing.MaxOutdoorTempSchedPtr > 0) {
2938 : // Check min and max values in the schedule to ensure both values are within the range
2939 5 : if (!ScheduleManager::CheckScheduleValueMinMax(
2940 : state, thisMixing.MaxOutdoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
2941 0 : ShowSevereError(
2942 : state,
2943 0 : format("{}{} =\"{}\" must have a maximum outdoor temperature between -100C and 100C defined in the schedule = {}",
2944 : RoutineName,
2945 : cCurrentModuleObject,
2946 : cAlphaArgs(1),
2947 : cAlphaArgs(12)));
2948 0 : ErrorsFound = true;
2949 : }
2950 : }
2951 : }
2952 :
2953 54 : if (thisMixing.ZonePtr > 0) {
2954 54 : if (RepVarSet(thisMixing.ZonePtr)) {
2955 48 : RepVarSet(thisMixing.ZonePtr) = false;
2956 96 : SetupOutputVariable(state,
2957 : "Zone Mixing Volume",
2958 : Constant::Units::m3,
2959 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixVolume,
2960 : OutputProcessor::TimeStepType::System,
2961 : OutputProcessor::StoreType::Sum,
2962 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
2963 96 : SetupOutputVariable(state,
2964 : "Zone Mixing Current Density Volume Flow Rate",
2965 : Constant::Units::m3_s,
2966 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixVdotCurDensity,
2967 : OutputProcessor::TimeStepType::System,
2968 : OutputProcessor::StoreType::Average,
2969 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
2970 96 : SetupOutputVariable(state,
2971 : "Zone Mixing Standard Density Volume Flow Rate",
2972 : Constant::Units::m3_s,
2973 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixVdotStdDensity,
2974 : OutputProcessor::TimeStepType::System,
2975 : OutputProcessor::StoreType::Average,
2976 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
2977 96 : SetupOutputVariable(state,
2978 : "Zone Mixing Mass",
2979 : Constant::Units::kg,
2980 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixMass,
2981 : OutputProcessor::TimeStepType::System,
2982 : OutputProcessor::StoreType::Sum,
2983 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
2984 96 : SetupOutputVariable(state,
2985 : "Zone Mixing Mass Flow Rate",
2986 : Constant::Units::kg_s,
2987 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixMdot,
2988 : OutputProcessor::TimeStepType::System,
2989 : OutputProcessor::StoreType::Average,
2990 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
2991 96 : SetupOutputVariable(state,
2992 : "Zone Mixing Sensible Heat Loss Energy",
2993 : Constant::Units::J,
2994 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixHeatLoss,
2995 : OutputProcessor::TimeStepType::System,
2996 : OutputProcessor::StoreType::Sum,
2997 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
2998 96 : SetupOutputVariable(state,
2999 : "Zone Mixing Sensible Heat Gain Energy",
3000 : Constant::Units::J,
3001 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixHeatGain,
3002 : OutputProcessor::TimeStepType::System,
3003 : OutputProcessor::StoreType::Sum,
3004 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
3005 96 : SetupOutputVariable(state,
3006 : "Zone Mixing Latent Heat Loss Energy",
3007 : Constant::Units::J,
3008 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixLatentLoss,
3009 : OutputProcessor::TimeStepType::System,
3010 : OutputProcessor::StoreType::Sum,
3011 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
3012 96 : SetupOutputVariable(state,
3013 : "Zone Mixing Latent Heat Gain Energy",
3014 : Constant::Units::J,
3015 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixLatentGain,
3016 : OutputProcessor::TimeStepType::System,
3017 : OutputProcessor::StoreType::Sum,
3018 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
3019 96 : SetupOutputVariable(state,
3020 : "Zone Mixing Total Heat Loss Energy",
3021 : Constant::Units::J,
3022 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixTotalLoss,
3023 : OutputProcessor::TimeStepType::System,
3024 : OutputProcessor::StoreType::Sum,
3025 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
3026 96 : SetupOutputVariable(state,
3027 : "Zone Mixing Total Heat Gain Energy",
3028 : Constant::Units::J,
3029 48 : state.dataHeatBal->ZnAirRpt(thisMixing.ZonePtr).MixTotalGain,
3030 : OutputProcessor::TimeStepType::System,
3031 : OutputProcessor::StoreType::Sum,
3032 48 : state.dataHeatBal->Zone(thisMixing.ZonePtr).Name);
3033 : }
3034 : }
3035 54 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
3036 1 : SetupEMSActuator(state,
3037 : "ZoneMixing",
3038 : thisMixing.Name,
3039 : "Air Exchange Flow Rate",
3040 : "[m3/s]",
3041 1 : thisMixing.EMSSimpleMixingOn,
3042 1 : thisMixing.EMSimpleMixingFlowRate);
3043 : }
3044 : }
3045 : }
3046 : }
3047 :
3048 : // allocate MassConservation
3049 796 : state.dataHeatBal->MassConservation.allocate(state.dataGlobal->NumOfZones);
3050 :
3051 : // added by BAN, 02/14
3052 796 : if (state.dataHeatBal->TotMixing > 0) {
3053 17 : ZoneMixingNum.allocate(state.dataHeatBal->TotMixing);
3054 : // get source zones mixing objects index
3055 385 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
3056 368 : int SourceCount = 0;
3057 4204 : for (int Loop = 1; Loop <= state.dataHeatBal->TotMixing; ++Loop) {
3058 3836 : if (ZoneNum == state.dataHeatBal->Mixing(Loop).FromZone) {
3059 54 : SourceCount += 1;
3060 54 : ZoneMixingNum(SourceCount) = Loop;
3061 : }
3062 : }
3063 : // save mixing objects index for zones which serve as a source zone
3064 368 : state.dataHeatBal->MassConservation(ZoneNum).NumSourceZonesMixingObject = SourceCount;
3065 368 : if (SourceCount > 0) {
3066 47 : state.dataHeatBal->MassConservation(ZoneNum).ZoneMixingSourcesPtr.allocate(SourceCount);
3067 101 : for (int Loop = 1; Loop <= SourceCount; ++Loop) {
3068 54 : state.dataHeatBal->MassConservation(ZoneNum).ZoneMixingSourcesPtr(Loop) = ZoneMixingNum(Loop);
3069 : }
3070 : }
3071 : }
3072 :
3073 : // check zones which are used only as a source zones
3074 385 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
3075 4204 : for (int Loop = 1; Loop <= state.dataHeatBal->TotMixing; ++Loop) {
3076 3836 : if (ZoneNum != state.dataHeatBal->Mixing(Loop).FromZone) continue;
3077 54 : state.dataHeatBal->MassConservation(ZoneNum).IsOnlySourceZone = true;
3078 1004 : for (int Loop1 = 1; Loop1 <= state.dataHeatBal->TotMixing; ++Loop1) {
3079 951 : if (ZoneNum == state.dataHeatBal->Mixing(Loop1).ZonePtr) {
3080 1 : state.dataHeatBal->MassConservation(ZoneNum).IsOnlySourceZone = false;
3081 1 : break;
3082 : }
3083 : }
3084 : }
3085 : }
3086 : // get receiving zones mixing objects index
3087 17 : ZoneMixingNum = 0;
3088 385 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
3089 368 : int ReceivingCount = 0;
3090 4204 : for (int Loop = 1; Loop <= state.dataHeatBal->TotMixing; ++Loop) {
3091 3836 : if (ZoneNum == state.dataHeatBal->Mixing(Loop).ZonePtr) {
3092 54 : ReceivingCount += 1;
3093 54 : ZoneMixingNum(ReceivingCount) = Loop;
3094 : }
3095 : }
3096 : // save mixing objects index for zones which serve as a receiving zone
3097 368 : state.dataHeatBal->MassConservation(ZoneNum).NumReceivingZonesMixingObject = ReceivingCount;
3098 368 : if (ReceivingCount > 0) {
3099 48 : state.dataHeatBal->MassConservation(ZoneNum).ZoneMixingReceivingPtr.allocate(ReceivingCount);
3100 48 : state.dataHeatBal->MassConservation(ZoneNum).ZoneMixingReceivingFr.allocate(ReceivingCount);
3101 48 : state.dataHeatBal->MassConservation(ZoneNum).ZoneMixingReceivingFr = 0.0;
3102 102 : for (int Loop = 1; Loop <= ReceivingCount; ++Loop) {
3103 54 : state.dataHeatBal->MassConservation(ZoneNum).ZoneMixingReceivingPtr(Loop) = ZoneMixingNum(Loop);
3104 : }
3105 : }
3106 : // flag zones used as both source and receiving zone
3107 415 : if (state.dataHeatBal->MassConservation(ZoneNum).NumSourceZonesMixingObject > 0 &&
3108 47 : state.dataHeatBal->MassConservation(ZoneNum).NumReceivingZonesMixingObject > 0) {
3109 1 : state.dataHeatBal->MassConservation(ZoneNum).IsSourceAndReceivingZone = true;
3110 : }
3111 : }
3112 17 : if (allocated(ZoneMixingNum)) ZoneMixingNum.deallocate();
3113 : }
3114 :
3115 : // zone mass conservation calculation order starts with receiving zones
3116 : // and then proceeds to source zones
3117 796 : int Loop2 = 0;
3118 5852 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
3119 10066 : if (!state.dataHeatBal->MassConservation(ZoneNum).IsOnlySourceZone &&
3120 5010 : !state.dataHeatBal->MassConservation(ZoneNum).IsSourceAndReceivingZone) {
3121 5009 : Loop2 += 1;
3122 5009 : state.dataHeatBalFanSys->ZoneReOrder(Loop2) = ZoneNum;
3123 : }
3124 : }
3125 5852 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
3126 5056 : if (state.dataHeatBal->MassConservation(ZoneNum).IsSourceAndReceivingZone) {
3127 1 : Loop2 += 1;
3128 1 : state.dataHeatBalFanSys->ZoneReOrder(Loop2) = ZoneNum;
3129 : }
3130 : }
3131 5852 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
3132 5056 : if (state.dataHeatBal->MassConservation(ZoneNum).IsOnlySourceZone) {
3133 46 : Loop2 += 1;
3134 46 : state.dataHeatBalFanSys->ZoneReOrder(Loop2) = ZoneNum;
3135 : }
3136 : }
3137 :
3138 796 : cCurrentModuleObject = "ZoneCrossMixing";
3139 796 : int numZoneCrossMixingInputObjects = 0;
3140 796 : int totZoneCrossMixing = 0; // Total ZoneCrossMixing instances after expansion to spaces
3141 1592 : EPVector<InternalHeatGains::GlobalInternalGainMiscObject> zoneCrossMixingInputObjects;
3142 796 : InternalHeatGains::setupIHGZonesAndSpaces(state,
3143 : cCurrentModuleObject,
3144 : zoneCrossMixingInputObjects,
3145 : numZoneCrossMixingInputObjects,
3146 : totZoneCrossMixing,
3147 : ErrorsFound,
3148 : zoneListNotAllowed);
3149 796 : state.dataHeatBal->TotCrossMixing = totZoneCrossMixing + state.dataHeatBal->airBoundaryMixing.size();
3150 :
3151 796 : if (state.dataHeatBal->TotCrossMixing > 0) {
3152 4 : cCurrentModuleObject = "ZoneCrossMixing";
3153 4 : state.dataHeatBal->CrossMixing.allocate(state.dataHeatBal->TotCrossMixing);
3154 :
3155 4 : int mixingNum = 0;
3156 8 : for (int mixingInputNum = 1; mixingInputNum <= numZoneCrossMixingInputObjects; ++mixingInputNum) {
3157 :
3158 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3159 : cCurrentModuleObject,
3160 : mixingInputNum,
3161 : cAlphaArgs,
3162 : NumAlpha,
3163 : rNumericArgs,
3164 : NumNumber,
3165 : IOStat,
3166 : lNumericFieldBlanks,
3167 : lAlphaFieldBlanks,
3168 : cAlphaFieldNames,
3169 : cNumericFieldNames);
3170 : // Create one Mixing instance for every space associated with this input object
3171 4 : auto const &thisMixingInput = zoneCrossMixingInputObjects(mixingInputNum);
3172 8 : for (int Item1 = 1; Item1 <= thisMixingInput.numOfSpaces; ++Item1) {
3173 4 : ++mixingNum;
3174 4 : auto &thisMixing = state.dataHeatBal->CrossMixing(mixingNum);
3175 4 : thisMixing.Name = thisMixingInput.names(Item1);
3176 4 : thisMixing.spaceIndex = thisMixingInput.spaceNums(Item1);
3177 4 : auto const &thisSpace = state.dataHeatBal->space(thisMixing.spaceIndex);
3178 4 : thisMixing.ZonePtr = thisSpace.zoneNum;
3179 4 : auto &thisZone = state.dataHeatBal->Zone(thisSpace.zoneNum);
3180 :
3181 4 : if (lAlphaFieldBlanks(3)) {
3182 0 : thisMixing.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
3183 : } else {
3184 4 : thisMixing.SchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(3));
3185 4 : if (thisMixing.SchedPtr == 0) {
3186 0 : ShowWarningError(state,
3187 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\"",
3188 : RoutineName,
3189 : cCurrentModuleObject,
3190 0 : thisMixingInput.Name,
3191 : cAlphaFieldNames(3),
3192 : cAlphaArgs(3)));
3193 0 : ErrorsFound = true;
3194 : }
3195 : }
3196 :
3197 : // Mixing equipment design level calculation method.
3198 4 : AirflowSpec flow = static_cast<AirflowSpec>(getEnumValue(airflowNamesUC, cAlphaArgs(4))); // NOLINT(modernize-use-auto)
3199 4 : switch (flow) {
3200 4 : case AirflowSpec::Flow:
3201 : case AirflowSpec::FlowPerZone:
3202 4 : thisMixing.DesignLevel = rNumericArgs(1);
3203 4 : if (lNumericFieldBlanks(1)) {
3204 0 : ShowWarningError(state,
3205 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Cross Mixing will result.",
3206 : RoutineName,
3207 : cCurrentModuleObject,
3208 0 : thisMixingInput.Name,
3209 : cAlphaFieldNames(4),
3210 : cNumericFieldNames(1)));
3211 : } else {
3212 4 : Real64 spaceFrac = 1.0;
3213 4 : if (!thisMixingInput.spaceListActive && (thisMixingInput.numOfSpaces > 1)) {
3214 0 : Real64 const zoneVolume = thisZone.Volume;
3215 0 : if (zoneVolume > 0.0) {
3216 0 : spaceFrac = thisSpace.Volume / zoneVolume;
3217 : } else {
3218 0 : ShowSevereError(state, format("{}Zone volume is zero when allocating Cross Mixing to Spaces.", RoutineName));
3219 0 : ShowContinueError(
3220 0 : state, format("Occurs for {}=\"{}\" in Zone=\"{}\".", cCurrentModuleObject, thisMixingInput.Name, thisZone.Name));
3221 0 : ErrorsFound = true;
3222 : }
3223 : }
3224 :
3225 4 : thisMixing.DesignLevel = rNumericArgs(1) * spaceFrac;
3226 : }
3227 4 : break;
3228 :
3229 0 : case AirflowSpec::FlowPerArea:
3230 0 : if (thisMixing.spaceIndex != 0) {
3231 0 : if (rNumericArgs(2) >= 0.0) {
3232 0 : thisMixing.DesignLevel = rNumericArgs(2) * thisSpace.FloorArea;
3233 0 : if (thisMixing.spaceIndex > 0) {
3234 0 : if (thisZone.FloorArea <= 0.0) {
3235 0 : ShowWarningError(state,
3236 0 : format("{}{}=\"{}\", {} specifies {}, but Space Floor Area = 0. 0 Cross Mixing will result.",
3237 : RoutineName,
3238 : cCurrentModuleObject,
3239 0 : thisMixingInput.Name,
3240 : cAlphaFieldNames(4),
3241 : cNumericFieldNames(2)));
3242 : }
3243 : }
3244 : } else {
3245 0 : ShowSevereError(state,
3246 0 : format("{}{}=\"{}\", invalid flow/area specification [<0.0]={:.3R}",
3247 : RoutineName,
3248 : cCurrentModuleObject,
3249 0 : thisMixingInput.Name,
3250 : rNumericArgs(2)));
3251 0 : ErrorsFound = true;
3252 : }
3253 : }
3254 0 : if (lNumericFieldBlanks(2)) {
3255 0 : ShowWarningError(state,
3256 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Cross Mixing will result.",
3257 : RoutineName,
3258 : cCurrentModuleObject,
3259 0 : thisMixingInput.Name,
3260 : cAlphaFieldNames(4),
3261 : cNumericFieldNames(2)));
3262 : }
3263 0 : break;
3264 :
3265 0 : case AirflowSpec::FlowPerPerson:
3266 0 : if (thisMixing.spaceIndex != 0) {
3267 0 : if (rNumericArgs(3) >= 0.0) {
3268 0 : thisMixing.DesignLevel = rNumericArgs(3) * thisSpace.TotOccupants;
3269 0 : if (thisSpace.TotOccupants <= 0.0) {
3270 0 : ShowWarningError(state,
3271 0 : format("{}{}=\"{}\", {} specifies {}, but Space Total Occupants = 0. 0 Cross Mixing will result.",
3272 : RoutineName,
3273 : cCurrentModuleObject,
3274 0 : thisMixingInput.Name,
3275 : cAlphaFieldNames(4),
3276 : cNumericFieldNames(3)));
3277 : }
3278 : } else {
3279 0 : ShowSevereError(state,
3280 0 : format("{}{}=\"{}\", invalid flow/person specification [<0.0]={:.3R}",
3281 : RoutineName,
3282 : cCurrentModuleObject,
3283 0 : thisMixingInput.Name,
3284 : rNumericArgs(3)));
3285 0 : ErrorsFound = true;
3286 : }
3287 : }
3288 0 : if (lNumericFieldBlanks(3)) {
3289 0 : ShowWarningError(state,
3290 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Cross Mixing will result.",
3291 : RoutineName,
3292 : cCurrentModuleObject,
3293 0 : thisMixingInput.Name,
3294 : cAlphaFieldNames(4),
3295 : cNumericFieldNames(3)));
3296 : }
3297 0 : break;
3298 :
3299 0 : case AirflowSpec::AirChanges:
3300 0 : if (thisMixing.spaceIndex != 0) {
3301 0 : if (rNumericArgs(4) >= 0.0) {
3302 0 : thisMixing.DesignLevel = rNumericArgs(4) * thisSpace.Volume / Constant::SecInHour;
3303 0 : if (thisSpace.Volume <= 0.0) {
3304 0 : ShowWarningError(state,
3305 0 : format("{}{}=\"{}\", {} specifies {}, but Space Volume = 0. 0 Cross Mixing will result.",
3306 : RoutineName,
3307 : cCurrentModuleObject,
3308 0 : thisMixingInput.Name,
3309 : cAlphaFieldNames(4),
3310 : cNumericFieldNames(4)));
3311 : }
3312 : } else {
3313 0 : ShowSevereError(state,
3314 0 : format("{}{}=\"{}\", invalid ACH (air changes per hour) specification [<0.0]={:.3R}",
3315 : RoutineName,
3316 : cCurrentModuleObject,
3317 0 : thisMixingInput.Name,
3318 : rNumericArgs(4)));
3319 0 : ErrorsFound = true;
3320 : }
3321 : }
3322 0 : if (lNumericFieldBlanks(4)) {
3323 0 : ShowWarningError(state,
3324 0 : format("{}{}=\"{}\", {} specifies {}, but that field is blank. 0 Cross Mixing will result.",
3325 : RoutineName,
3326 : cCurrentModuleObject,
3327 0 : thisMixingInput.Name,
3328 : cAlphaFieldNames(4),
3329 : cNumericFieldNames(4)));
3330 : }
3331 0 : break;
3332 :
3333 0 : default:
3334 0 : ShowSevereError(
3335 0 : state, format("{}{}=\"{}\", invalid calculation method={}", RoutineName, cCurrentModuleObject, cAlphaArgs(1), cAlphaArgs(4)));
3336 0 : ErrorsFound = true;
3337 : }
3338 :
3339 4 : thisMixing.fromSpaceIndex = Util::FindItemInList(cAlphaArgs(5), state.dataHeatBal->space);
3340 4 : if (thisMixing.fromSpaceIndex == 0) {
3341 0 : thisMixing.FromZone = Util::FindItemInList(cAlphaArgs(5), state.dataHeatBal->Zone);
3342 : } else {
3343 4 : thisMixing.FromZone = state.dataHeatBal->space(thisMixing.fromSpaceIndex).zoneNum;
3344 : }
3345 4 : if ((thisMixing.FromZone == 0) && (thisMixing.fromSpaceIndex == 0)) {
3346 0 : ShowSevereError(state,
3347 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
3348 : RoutineName,
3349 : cCurrentModuleObject,
3350 : cAlphaArgs(1),
3351 : cAlphaFieldNames(5),
3352 : cAlphaArgs(5)));
3353 0 : ErrorsFound = true;
3354 : }
3355 4 : thisMixing.DeltaTemperature = rNumericArgs(5);
3356 :
3357 4 : if (NumAlpha > 5) {
3358 2 : thisMixing.DeltaTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(6));
3359 2 : if (thisMixing.DeltaTempSchedPtr > 0) {
3360 0 : if (!lNumericFieldBlanks(5))
3361 0 : ShowWarningError(state,
3362 0 : format("{}The Delta Temperature value and schedule are provided. The scheduled temperature will be used "
3363 : "in the {} object = {}",
3364 : RoutineName,
3365 : cCurrentModuleObject,
3366 : cAlphaArgs(1)));
3367 0 : if (ScheduleManager::GetScheduleMinValue(state, thisMixing.DeltaTempSchedPtr) < 0.0) {
3368 0 : ShowSevereError(state,
3369 0 : format("{}{} = {} must have a delta temperature equal to or above 0 C defined in the schedule = {}",
3370 : RoutineName,
3371 : cCurrentModuleObject,
3372 : cAlphaArgs(1),
3373 : cAlphaArgs(6)));
3374 0 : ErrorsFound = true;
3375 : }
3376 : }
3377 : }
3378 4 : if (thisMixing.DeltaTempSchedPtr == 0 && lNumericFieldBlanks(5) && (!lAlphaFieldBlanks(6))) {
3379 0 : ShowWarningError(state,
3380 0 : format("{}{}: the value field is blank and schedule field is invalid. The default value will be used ({:.1R}) ",
3381 : RoutineName,
3382 : cNumericFieldNames(5),
3383 : rNumericArgs(5)));
3384 0 : ShowContinueError(state, format("in {} = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
3385 : }
3386 4 : if (!lNumericFieldBlanks(5) && ((!lAlphaFieldBlanks(6)) && thisMixing.DeltaTempSchedPtr == 0)) {
3387 0 : ShowWarningError(state,
3388 0 : format("{}{} = {} is invalid. The constant value will be used at {:.1R} degrees C ",
3389 : RoutineName,
3390 : cAlphaFieldNames(6),
3391 : cAlphaArgs(6),
3392 : rNumericArgs(5)));
3393 0 : ShowContinueError(state, format("in the {} object = {} and the simulation continues...", cCurrentModuleObject, cAlphaArgs(1)));
3394 : }
3395 :
3396 4 : if (NumAlpha > 6) {
3397 2 : thisMixing.MinIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(7));
3398 2 : if (thisMixing.MinIndoorTempSchedPtr == 0) {
3399 0 : if ((!lAlphaFieldBlanks(7))) {
3400 0 : ShowSevereError(state,
3401 0 : format("{}{}=\"{}\",{} not found={}\".",
3402 : RoutineName,
3403 : cCurrentModuleObject,
3404 : cAlphaArgs(1),
3405 : cAlphaFieldNames(7),
3406 : cAlphaArgs(7)));
3407 0 : ErrorsFound = true;
3408 : }
3409 : }
3410 2 : if (thisMixing.MinIndoorTempSchedPtr > 0) {
3411 : // Check min and max values in the schedule to ensure both values are within the range
3412 2 : if (!ScheduleManager::CheckScheduleValueMinMax(
3413 : state, thisMixing.MinIndoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
3414 0 : ShowSevereError(
3415 : state,
3416 0 : format("{}{} = {} must have a minimum zone temperature between -100C and 100C defined in the schedule = {}",
3417 : RoutineName,
3418 : cCurrentModuleObject,
3419 : cAlphaArgs(1),
3420 : cAlphaArgs(7)));
3421 0 : ErrorsFound = true;
3422 : }
3423 : }
3424 : }
3425 :
3426 4 : if (NumAlpha > 7) {
3427 2 : thisMixing.MaxIndoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(8));
3428 2 : if (thisMixing.MaxIndoorTempSchedPtr == 0) {
3429 0 : if ((!lAlphaFieldBlanks(8))) {
3430 0 : ShowSevereError(state,
3431 0 : format("{}{}=\"{}\",{} not found=\"{}\".",
3432 : RoutineName,
3433 : cCurrentModuleObject,
3434 : cAlphaArgs(1),
3435 : cAlphaFieldNames(8),
3436 : cAlphaArgs(8)));
3437 0 : ErrorsFound = true;
3438 : }
3439 : }
3440 2 : if (thisMixing.MaxIndoorTempSchedPtr > 0) {
3441 : // Check min and max values in the schedule to ensure both values are within the range
3442 2 : if (!ScheduleManager::CheckScheduleValueMinMax(
3443 : state, thisMixing.MaxIndoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
3444 0 : ShowSevereError(
3445 : state,
3446 0 : format("{}{} = {} must have a maximum zone temperature between -100C and 100C defined in the schedule = {}",
3447 : RoutineName,
3448 : cCurrentModuleObject,
3449 : cAlphaArgs(1),
3450 : cAlphaArgs(8)));
3451 0 : ErrorsFound = true;
3452 : }
3453 : }
3454 : }
3455 :
3456 4 : if (NumAlpha > 8) {
3457 2 : thisMixing.MinSourceTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(9));
3458 2 : if (thisMixing.MinSourceTempSchedPtr == 0) {
3459 0 : if ((!lAlphaFieldBlanks(9))) {
3460 0 : ShowSevereError(state,
3461 0 : format("{}{}=\"{}\",{} not found=\"{}\".",
3462 : RoutineName,
3463 : cCurrentModuleObject,
3464 : cAlphaArgs(1),
3465 : cAlphaFieldNames(9),
3466 : cAlphaArgs(9)));
3467 0 : ErrorsFound = true;
3468 : }
3469 : }
3470 2 : if (thisMixing.MinSourceTempSchedPtr > 0) {
3471 : // Check min and max values in the schedule to ensure both values are within the range
3472 2 : if (!ScheduleManager::CheckScheduleValueMinMax(
3473 : state, thisMixing.MinSourceTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
3474 0 : ShowSevereError(
3475 : state,
3476 0 : format("{}{} = {} must have a minimum source temperature between -100C and 100C defined in the schedule = {}",
3477 : RoutineName,
3478 : cCurrentModuleObject,
3479 : cAlphaArgs(1),
3480 : cAlphaArgs(9)));
3481 0 : ErrorsFound = true;
3482 : }
3483 : }
3484 : }
3485 :
3486 4 : if (NumAlpha > 9) {
3487 2 : thisMixing.MaxSourceTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(10));
3488 2 : if (thisMixing.MaxSourceTempSchedPtr == 0) {
3489 0 : if ((!lAlphaFieldBlanks(10))) {
3490 0 : ShowSevereError(state,
3491 0 : format("{}{}=\"{}\",{} not found=\"{}\".",
3492 : RoutineName,
3493 : cCurrentModuleObject,
3494 : cAlphaArgs(1),
3495 : cAlphaFieldNames(10),
3496 : cAlphaArgs(9)));
3497 0 : ErrorsFound = true;
3498 : }
3499 : }
3500 2 : if (thisMixing.MaxSourceTempSchedPtr > 0) {
3501 : // Check min and max values in the schedule to ensure both values are within the range
3502 2 : if (!ScheduleManager::CheckScheduleValueMinMax(
3503 : state, thisMixing.MaxSourceTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
3504 0 : ShowSevereError(
3505 : state,
3506 0 : format("{}{} = {} must have a maximum source temperature between -100C and 100C defined in the schedule = {}",
3507 : RoutineName,
3508 : cCurrentModuleObject,
3509 : cAlphaArgs(1),
3510 : cAlphaArgs(10)));
3511 0 : ErrorsFound = true;
3512 : }
3513 : }
3514 : }
3515 :
3516 4 : if (NumAlpha > 10) {
3517 2 : thisMixing.MinOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(11));
3518 2 : if (thisMixing.MinOutdoorTempSchedPtr == 0) {
3519 0 : if ((!lAlphaFieldBlanks(11))) {
3520 0 : ShowSevereError(state,
3521 0 : format("{}{}=\"{}\",{} not found=\"{}\".",
3522 : RoutineName,
3523 : cCurrentModuleObject,
3524 : cAlphaArgs(1),
3525 : cAlphaFieldNames(11),
3526 : cAlphaArgs(9)));
3527 0 : ErrorsFound = true;
3528 : }
3529 : }
3530 2 : if (thisMixing.MinOutdoorTempSchedPtr > 0) {
3531 : // Check min and max values in the schedule to ensure both values are within the range
3532 2 : if (!ScheduleManager::CheckScheduleValueMinMax(
3533 : state, thisMixing.MinOutdoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
3534 0 : ShowSevereError(
3535 : state,
3536 0 : format("{}{} = {} must have a minimum outdoor temperature between -100C and 100C defined in the schedule = {}",
3537 : RoutineName,
3538 : cCurrentModuleObject,
3539 : cAlphaArgs(1),
3540 : cAlphaArgs(11)));
3541 0 : ErrorsFound = true;
3542 : }
3543 : }
3544 : }
3545 :
3546 4 : if (NumAlpha > 11) {
3547 2 : thisMixing.MaxOutdoorTempSchedPtr = ScheduleManager::GetScheduleIndex(state, cAlphaArgs(12));
3548 2 : if (thisMixing.MaxOutdoorTempSchedPtr == 0) {
3549 0 : if ((!lAlphaFieldBlanks(12))) {
3550 0 : ShowSevereError(state,
3551 0 : format("{}{}=\"{}\",{} not found=\"{}\".",
3552 : RoutineName,
3553 : cCurrentModuleObject,
3554 : cAlphaArgs(1),
3555 : cAlphaFieldNames(12),
3556 : cAlphaArgs(9)));
3557 0 : ErrorsFound = true;
3558 : }
3559 : }
3560 2 : if (thisMixing.MaxOutdoorTempSchedPtr > 0) {
3561 : // Check min and max values in the schedule to ensure both values are within the range
3562 2 : if (!ScheduleManager::CheckScheduleValueMinMax(
3563 : state, thisMixing.MaxOutdoorTempSchedPtr, ">=", -MixingTempLimit, "<=", MixingTempLimit)) {
3564 0 : ShowSevereError(
3565 : state,
3566 0 : format("{}{} = {} must have a maximum outdoor temperature between -100C and 100C defined in the schedule = {}",
3567 : RoutineName,
3568 : cCurrentModuleObject,
3569 : cAlphaArgs(1),
3570 : cAlphaArgs(12)));
3571 0 : ErrorsFound = true;
3572 : }
3573 : }
3574 : }
3575 : }
3576 : }
3577 : // Create CrossMixing objects from air boundary info
3578 10 : for (auto const &thisAirBoundaryMixing : state.dataHeatBal->airBoundaryMixing) {
3579 6 : ++mixingNum;
3580 : // Create CrossMixing object from air boundary info
3581 6 : int space1 = thisAirBoundaryMixing.space1;
3582 6 : int space2 = thisAirBoundaryMixing.space2;
3583 6 : int zone1 = state.dataHeatBal->space(space1).zoneNum;
3584 6 : int zone2 = state.dataHeatBal->space(space2).zoneNum;
3585 6 : auto &thisCrossMizing = state.dataHeatBal->CrossMixing(mixingNum);
3586 6 : thisCrossMizing.Name = fmt::format("Air Boundary Mixing Zones {} and {}", zone1, zone2);
3587 6 : thisCrossMizing.spaceIndex = space1;
3588 6 : thisCrossMizing.ZonePtr = zone1;
3589 6 : thisCrossMizing.SchedPtr = thisAirBoundaryMixing.scheduleIndex;
3590 6 : thisCrossMizing.DesignLevel = thisAirBoundaryMixing.mixingVolumeFlowRate;
3591 6 : thisCrossMizing.FromZone = zone2;
3592 6 : thisCrossMizing.fromSpaceIndex = space2;
3593 4 : }
3594 4 : assert(mixingNum == state.dataHeatBal->TotCrossMixing);
3595 14 : for (int mixingRepNum = 1; mixingRepNum <= state.dataHeatBal->TotCrossMixing; ++mixingRepNum) {
3596 10 : int zoneNum = state.dataHeatBal->CrossMixing(mixingRepNum).ZonePtr;
3597 10 : if (zoneNum > 0) {
3598 10 : std::string const &zoneName = state.dataHeatBal->Zone(zoneNum).Name;
3599 10 : auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(zoneNum);
3600 10 : if (RepVarSet(zoneNum)) {
3601 4 : RepVarSet(zoneNum) = false;
3602 8 : SetupOutputVariable(state,
3603 : "Zone Mixing Volume",
3604 : Constant::Units::m3,
3605 4 : thisZnAirRpt.MixVolume,
3606 : OutputProcessor::TimeStepType::System,
3607 : OutputProcessor::StoreType::Sum,
3608 : zoneName);
3609 8 : SetupOutputVariable(state,
3610 : "Zone Mixing Current Density Volume Flow Rate",
3611 : Constant::Units::m3_s,
3612 4 : thisZnAirRpt.MixVdotCurDensity,
3613 : OutputProcessor::TimeStepType::System,
3614 : OutputProcessor::StoreType::Average,
3615 : zoneName);
3616 8 : SetupOutputVariable(state,
3617 : "Zone Mixing Standard Density Volume Flow Rate",
3618 : Constant::Units::m3_s,
3619 4 : thisZnAirRpt.MixVdotStdDensity,
3620 : OutputProcessor::TimeStepType::System,
3621 : OutputProcessor::StoreType::Average,
3622 : zoneName);
3623 8 : SetupOutputVariable(state,
3624 : "Zone Mixing Mass",
3625 : Constant::Units::kg,
3626 4 : thisZnAirRpt.MixMass,
3627 : OutputProcessor::TimeStepType::System,
3628 : OutputProcessor::StoreType::Sum,
3629 : zoneName);
3630 8 : SetupOutputVariable(state,
3631 : "Zone Mixing Mass Flow Rate",
3632 : Constant::Units::kg_s,
3633 4 : thisZnAirRpt.MixMdot,
3634 : OutputProcessor::TimeStepType::System,
3635 : OutputProcessor::StoreType::Average,
3636 : zoneName);
3637 8 : SetupOutputVariable(state,
3638 : "Zone Mixing Sensible Heat Loss Energy",
3639 : Constant::Units::J,
3640 4 : thisZnAirRpt.MixHeatLoss,
3641 : OutputProcessor::TimeStepType::System,
3642 : OutputProcessor::StoreType::Sum,
3643 : zoneName);
3644 8 : SetupOutputVariable(state,
3645 : "Zone Mixing Sensible Heat Gain Energy",
3646 : Constant::Units::J,
3647 4 : thisZnAirRpt.MixHeatGain,
3648 : OutputProcessor::TimeStepType::System,
3649 : OutputProcessor::StoreType::Sum,
3650 : zoneName);
3651 8 : SetupOutputVariable(state,
3652 : "Zone Mixing Latent Heat Loss Energy",
3653 : Constant::Units::J,
3654 4 : thisZnAirRpt.MixLatentLoss,
3655 : OutputProcessor::TimeStepType::System,
3656 : OutputProcessor::StoreType::Sum,
3657 : zoneName);
3658 8 : SetupOutputVariable(state,
3659 : "Zone Mixing Latent Heat Gain Energy",
3660 : Constant::Units::J,
3661 4 : thisZnAirRpt.MixLatentGain,
3662 : OutputProcessor::TimeStepType::System,
3663 : OutputProcessor::StoreType::Sum,
3664 : zoneName);
3665 8 : SetupOutputVariable(state,
3666 : "Zone Mixing Total Heat Loss Energy",
3667 : Constant::Units::J,
3668 4 : thisZnAirRpt.MixTotalLoss,
3669 : OutputProcessor::TimeStepType::System,
3670 : OutputProcessor::StoreType::Sum,
3671 : zoneName);
3672 8 : SetupOutputVariable(state,
3673 : "Zone Mixing Total Heat Gain Energy",
3674 : Constant::Units::J,
3675 4 : thisZnAirRpt.MixTotalGain,
3676 : OutputProcessor::TimeStepType::System,
3677 : OutputProcessor::StoreType::Sum,
3678 : zoneName);
3679 : }
3680 : }
3681 10 : int fromZoneNum = state.dataHeatBal->CrossMixing(mixingRepNum).FromZone;
3682 10 : if (fromZoneNum > 0) {
3683 10 : if (RepVarSet(fromZoneNum)) {
3684 6 : RepVarSet(fromZoneNum) = false;
3685 6 : std::string const &fromZoneName = state.dataHeatBal->Zone(fromZoneNum).Name;
3686 6 : auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(fromZoneNum);
3687 12 : SetupOutputVariable(state,
3688 : "Zone Mixing Volume",
3689 : Constant::Units::m3,
3690 6 : thisZnAirRpt.MixVolume,
3691 : OutputProcessor::TimeStepType::System,
3692 : OutputProcessor::StoreType::Sum,
3693 : fromZoneName);
3694 12 : SetupOutputVariable(state,
3695 : "Zone Mixing Current Density Volume Flow Rate",
3696 : Constant::Units::m3_s,
3697 6 : thisZnAirRpt.MixVdotCurDensity,
3698 : OutputProcessor::TimeStepType::System,
3699 : OutputProcessor::StoreType::Average,
3700 : fromZoneName);
3701 12 : SetupOutputVariable(state,
3702 : "Zone Mixing Standard Density Volume Flow Rate",
3703 : Constant::Units::m3_s,
3704 6 : thisZnAirRpt.MixVdotStdDensity,
3705 : OutputProcessor::TimeStepType::System,
3706 : OutputProcessor::StoreType::Average,
3707 : fromZoneName);
3708 12 : SetupOutputVariable(state,
3709 : "Zone Mixing Mass",
3710 : Constant::Units::kg,
3711 6 : thisZnAirRpt.MixMass,
3712 : OutputProcessor::TimeStepType::System,
3713 : OutputProcessor::StoreType::Sum,
3714 : fromZoneName);
3715 12 : SetupOutputVariable(state,
3716 : "Zone Mixing Mass Flow Rate",
3717 : Constant::Units::kg_s,
3718 6 : thisZnAirRpt.MixMdot,
3719 : OutputProcessor::TimeStepType::System,
3720 : OutputProcessor::StoreType::Average,
3721 : fromZoneName);
3722 12 : SetupOutputVariable(state,
3723 : "Zone Mixing Sensible Heat Loss Energy",
3724 : Constant::Units::J,
3725 6 : thisZnAirRpt.MixHeatLoss,
3726 : OutputProcessor::TimeStepType::System,
3727 : OutputProcessor::StoreType::Sum,
3728 : fromZoneName);
3729 12 : SetupOutputVariable(state,
3730 : "Zone Mixing Sensible Heat Gain Energy",
3731 : Constant::Units::J,
3732 6 : thisZnAirRpt.MixHeatGain,
3733 : OutputProcessor::TimeStepType::System,
3734 : OutputProcessor::StoreType::Sum,
3735 : fromZoneName);
3736 12 : SetupOutputVariable(state,
3737 : "Zone Mixing Latent Heat Loss Energy",
3738 : Constant::Units::J,
3739 6 : thisZnAirRpt.MixLatentLoss,
3740 : OutputProcessor::TimeStepType::System,
3741 : OutputProcessor::StoreType::Sum,
3742 : fromZoneName);
3743 12 : SetupOutputVariable(state,
3744 : "Zone Mixing Latent Heat Gain Energy",
3745 : Constant::Units::J,
3746 6 : thisZnAirRpt.MixLatentGain,
3747 : OutputProcessor::TimeStepType::System,
3748 : OutputProcessor::StoreType::Sum,
3749 : fromZoneName);
3750 12 : SetupOutputVariable(state,
3751 : "Zone Mixing Total Heat Loss Energy",
3752 : Constant::Units::J,
3753 6 : thisZnAirRpt.MixTotalLoss,
3754 : OutputProcessor::TimeStepType::System,
3755 : OutputProcessor::StoreType::Sum,
3756 : fromZoneName);
3757 12 : SetupOutputVariable(state,
3758 : "Zone Mixing Total Heat Gain Energy",
3759 : Constant::Units::J,
3760 6 : thisZnAirRpt.MixTotalGain,
3761 : OutputProcessor::TimeStepType::System,
3762 : OutputProcessor::StoreType::Sum,
3763 : fromZoneName);
3764 : }
3765 : }
3766 :
3767 10 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
3768 0 : SetupEMSActuator(state,
3769 : "ZoneCrossMixing",
3770 0 : state.dataHeatBal->CrossMixing(mixingRepNum).Name,
3771 : "Air Exchange Flow Rate",
3772 : "[m3/s]",
3773 0 : state.dataHeatBal->CrossMixing(mixingRepNum).EMSSimpleMixingOn,
3774 0 : state.dataHeatBal->CrossMixing(mixingRepNum).EMSimpleMixingFlowRate);
3775 : }
3776 : }
3777 : }
3778 :
3779 796 : cCurrentModuleObject = "ZoneRefrigerationDoorMixing";
3780 796 : state.dataHeatBal->TotRefDoorMixing = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
3781 796 : if (state.dataHeatBal->TotRefDoorMixing > 0) {
3782 1 : state.dataHeatBal->RefDoorMixing.allocate(state.dataGlobal->NumOfZones);
3783 15 : for (auto &e : state.dataHeatBal->RefDoorMixing)
3784 15 : e.NumRefDoorConnections = 0;
3785 :
3786 4 : for (int Loop = 1; Loop <= state.dataHeatBal->TotRefDoorMixing; ++Loop) {
3787 :
3788 3 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3789 : cCurrentModuleObject,
3790 : Loop,
3791 : cAlphaArgs,
3792 : NumAlpha,
3793 : rNumericArgs,
3794 : NumNumber,
3795 : IOStat,
3796 : lNumericFieldBlanks,
3797 : lAlphaFieldBlanks,
3798 : cAlphaFieldNames,
3799 : cNumericFieldNames);
3800 :
3801 3 : NameThisObject = cAlphaArgs(1);
3802 :
3803 3 : int AlphaNum = 2;
3804 3 : int Zone1Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->Zone);
3805 3 : int space1Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->space);
3806 3 : if ((Zone1Num == 0) && (space1Num == 0)) {
3807 0 : ShowSevereError(state,
3808 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
3809 : RoutineName,
3810 : cCurrentModuleObject,
3811 : cAlphaArgs(1),
3812 : cAlphaFieldNames(AlphaNum),
3813 : cAlphaArgs(AlphaNum)));
3814 0 : ErrorsFound = true;
3815 3 : } else if (Zone1Num == 0) {
3816 0 : Zone1Num = state.dataHeatBal->space(space1Num).zoneNum;
3817 : }
3818 :
3819 3 : ++AlphaNum; // 3
3820 3 : int Zone2Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->Zone);
3821 3 : int space2Num = Util::FindItemInList(cAlphaArgs(AlphaNum), state.dataHeatBal->space);
3822 3 : if ((Zone2Num == 0) && (space2Num == 0)) {
3823 0 : ShowSevereError(state,
3824 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
3825 : RoutineName,
3826 : cCurrentModuleObject,
3827 : cAlphaArgs(1),
3828 : cAlphaFieldNames(AlphaNum),
3829 : cAlphaArgs(AlphaNum)));
3830 0 : ErrorsFound = true;
3831 3 : } else if (Zone2Num == 0) {
3832 0 : Zone2Num = state.dataHeatBal->space(space2Num).zoneNum;
3833 : }
3834 :
3835 3 : int spaceNumA = 0;
3836 3 : int spaceNumB = 0;
3837 3 : if (Zone1Num == Zone2Num) {
3838 0 : ShowSevereError(state,
3839 0 : format("{}{}=\"{}\", The same zone name has been entered for both sides of a refrigerated door {}=\"{}\".",
3840 : RoutineName,
3841 : cCurrentModuleObject,
3842 : cAlphaArgs(1),
3843 : cAlphaFieldNames(AlphaNum),
3844 : cAlphaArgs(AlphaNum)));
3845 0 : ErrorsFound = true;
3846 3 : } else if (Zone1Num < Zone2Num) { // zone 1 will come first in soln loop, id zone 2 as mate zone
3847 1 : ZoneNumA = Zone1Num;
3848 1 : ZoneNumB = Zone2Num;
3849 1 : spaceNumA = space1Num;
3850 1 : spaceNumB = space2Num;
3851 : } else { // zone 2 will come first in soln loop, id zone 1 as mate zone
3852 2 : ZoneNumA = Zone2Num;
3853 2 : ZoneNumB = Zone1Num;
3854 2 : spaceNumA = space2Num;
3855 2 : spaceNumB = space1Num;
3856 : }
3857 :
3858 3 : if (!allocated(state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr)) {
3859 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorMixingObjectName.allocate(state.dataGlobal->NumOfZones);
3860 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr.allocate(state.dataGlobal->NumOfZones);
3861 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight.allocate(state.dataGlobal->NumOfZones);
3862 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea.allocate(state.dataGlobal->NumOfZones);
3863 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Protection.allocate(state.dataGlobal->NumOfZones);
3864 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr.allocate(state.dataGlobal->NumOfZones);
3865 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorMixingOn.allocate(state.dataGlobal->NumOfZones);
3866 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorFlowRate.allocate(state.dataGlobal->NumOfZones);
3867 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).VolRefDoorFlowRate.allocate(state.dataGlobal->NumOfZones);
3868 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName.allocate(state.dataGlobal->NumOfZones);
3869 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorMixingObjectName = "";
3870 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr = 0;
3871 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight = 0.0;
3872 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea = 0.0;
3873 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Protection = RefDoorNone;
3874 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr = 0;
3875 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorMixingOn = false;
3876 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorFlowRate = 0.0;
3877 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).VolRefDoorFlowRate = 0.0;
3878 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName = "";
3879 : } // First refrigeration mixing in this zone
3880 :
3881 3 : if (!allocated(state.dataHeatBal->RefDoorMixing(ZoneNumB).OpenSchedPtr)) {
3882 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorMixingObjectName.allocate(state.dataGlobal->NumOfZones);
3883 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).OpenSchedPtr.allocate(state.dataGlobal->NumOfZones);
3884 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorHeight.allocate(state.dataGlobal->NumOfZones);
3885 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorArea.allocate(state.dataGlobal->NumOfZones);
3886 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).Protection.allocate(state.dataGlobal->NumOfZones);
3887 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).MateZonePtr.allocate(state.dataGlobal->NumOfZones);
3888 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).EMSRefDoorMixingOn.allocate(state.dataGlobal->NumOfZones);
3889 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).EMSRefDoorFlowRate.allocate(state.dataGlobal->NumOfZones);
3890 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).VolRefDoorFlowRate.allocate(state.dataGlobal->NumOfZones);
3891 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorProtTypeName.allocate(state.dataGlobal->NumOfZones);
3892 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorMixingObjectName = "";
3893 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).OpenSchedPtr = 0;
3894 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorHeight = 0.0;
3895 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorArea = 0.0;
3896 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).Protection = RefDoorNone;
3897 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).MateZonePtr = 0;
3898 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).EMSRefDoorMixingOn = false;
3899 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).EMSRefDoorFlowRate = 0.0;
3900 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).VolRefDoorFlowRate = 0.0;
3901 2 : state.dataHeatBal->RefDoorMixing(ZoneNumB).DoorProtTypeName = "";
3902 : } // First refrigeration mixing in this zone
3903 :
3904 3 : ConnectionNumber = state.dataHeatBal->RefDoorMixing(ZoneNumA).NumRefDoorConnections + 1;
3905 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).NumRefDoorConnections = ConnectionNumber;
3906 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).ZonePtr = ZoneNumA;
3907 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).spaceIndex = spaceNumA;
3908 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).fromSpaceIndex = spaceNumB;
3909 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr(ConnectionNumber) = ZoneNumB;
3910 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorMixingObjectName(ConnectionNumber) = NameThisObject;
3911 : // need to make sure same pair of zones is only entered once.
3912 3 : if (state.dataHeatBal->RefDoorMixing(ZoneNumA).RefDoorMixFlag && state.dataHeatBal->RefDoorMixing(ZoneNumB).RefDoorMixFlag) {
3913 0 : if (state.dataHeatBal->RefDoorMixing(ZoneNumA).NumRefDoorConnections > 1) {
3914 0 : for (int ConnectTest = 1; ConnectTest <= (ConnectionNumber - 1); ++ConnectTest) {
3915 0 : if (state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr(ConnectTest) !=
3916 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr(ConnectionNumber))
3917 0 : continue;
3918 0 : ShowSevereError(state,
3919 0 : format("{}{}=\"{}\", and {}",
3920 : RoutineName,
3921 : cCurrentModuleObject,
3922 : cAlphaArgs(1),
3923 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorMixingObjectName(ConnectTest)));
3924 0 : ShowContinueError(state,
3925 0 : format(" Share same pair of zones: \"{}\" and \"{}\". Only one RefrigerationDoorMixing object is allowed "
3926 : "for any unique pair of zones.",
3927 0 : state.dataHeatBal->Zone(ZoneNumA).Name,
3928 0 : state.dataHeatBal->Zone(ZoneNumB).Name));
3929 0 : ErrorsFound = true;
3930 : } // ConnectTest
3931 : } // NumRefDoorconnections > 1
3932 : } else { // Both zones need to be flagged with ref doors
3933 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).RefDoorMixFlag = true;
3934 3 : state.dataHeatBal->RefDoorMixing(ZoneNumB).RefDoorMixFlag = true;
3935 : } // Both zones already flagged with ref doors
3936 :
3937 3 : ++AlphaNum; // 4
3938 3 : if (lAlphaFieldBlanks(AlphaNum)) {
3939 0 : ShowSevereError(state,
3940 0 : format("{}{}=\"{}\",{} is required but field is blank.",
3941 : RoutineName,
3942 : cCurrentModuleObject,
3943 : cAlphaArgs(1),
3944 : cAlphaFieldNames(AlphaNum)));
3945 0 : ErrorsFound = true;
3946 : } else { //(lAlphaFieldBlanks(AlphaNum)) THEN
3947 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr(ConnectionNumber) =
3948 3 : ScheduleManager::GetScheduleIndex(state, cAlphaArgs(AlphaNum));
3949 3 : if (state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr(ConnectionNumber) == 0) {
3950 0 : ShowSevereError(state,
3951 0 : format("{}{}=\"{}\", invalid (not found) {}=\"{}\".",
3952 : RoutineName,
3953 : cCurrentModuleObject,
3954 : cAlphaArgs(1),
3955 : cAlphaFieldNames(AlphaNum),
3956 : cAlphaArgs(AlphaNum)));
3957 0 : ErrorsFound = true;
3958 : } else { // OpenSchedPtr(ConnectionNumber) ne 0)
3959 6 : if (!ScheduleManager::CheckScheduleValueMinMax(
3960 3 : state, state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr(ConnectionNumber), ">=", 0.0, "<=", 1.0)) {
3961 0 : ShowSevereError(state,
3962 0 : format("{}{}=\"{}\",{}=\"{}\" has schedule values < 0 or > 1.",
3963 : RoutineName,
3964 : cCurrentModuleObject,
3965 : cAlphaArgs(1),
3966 : cAlphaFieldNames(AlphaNum),
3967 : cAlphaArgs(AlphaNum)));
3968 0 : ErrorsFound = true;
3969 : } // check door opening schedule values between 0 and 1
3970 : } // OpenSchedPtr(ConnectionNumber) == 0)
3971 : } //(lAlphaFieldBlanks(AlphaNum)) THEN
3972 :
3973 3 : int NumbNum = 1;
3974 3 : if (lAlphaFieldBlanks(NumbNum)) {
3975 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight(ConnectionNumber) = 3.0; // default height of 3 meters
3976 0 : ShowWarningError(state,
3977 0 : format("{}{}=\"{}{} is blank and the default value of 3.0 will be used.",
3978 : RoutineName,
3979 : cCurrentModuleObject,
3980 : cAlphaArgs(1),
3981 : cNumericFieldNames(NumbNum)));
3982 : } else {
3983 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight(ConnectionNumber) = rNumericArgs(NumbNum);
3984 6 : if ((state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight(ConnectionNumber) < 0) ||
3985 3 : (state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight(ConnectionNumber) > 50.0)) {
3986 0 : ShowSevereError(
3987 : state,
3988 0 : format("{}{} = {} must have a door height between 0 and 50 meters. ", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
3989 0 : ErrorsFound = true;
3990 : }
3991 : }
3992 :
3993 3 : ++NumbNum; // 2
3994 3 : if (lAlphaFieldBlanks(NumbNum)) {
3995 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea(ConnectionNumber) = 9.0; // default area of 9 m2
3996 0 : ShowWarningError(state,
3997 0 : format("{}{}=\"{}{} is blank and the default value of 9 m2 will be used.",
3998 : RoutineName,
3999 : cCurrentModuleObject,
4000 : cAlphaArgs(1),
4001 : cNumericFieldNames(NumbNum)));
4002 : } else {
4003 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea(ConnectionNumber) = rNumericArgs(NumbNum);
4004 6 : if ((state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea(ConnectionNumber) < 0) ||
4005 3 : (state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea(ConnectionNumber) > 400.0)) {
4006 0 : ShowSevereError(
4007 : state,
4008 0 : format(
4009 : "{}{} = {} must have a door height between 0 and 400 square meters. ", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
4010 0 : ErrorsFound = true;
4011 : }
4012 : }
4013 :
4014 3 : ++AlphaNum; // 5
4015 : // Door protection type.
4016 3 : if (lAlphaFieldBlanks(AlphaNum)) {
4017 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Protection(ConnectionNumber) = RefDoorNone; // Default
4018 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName(ConnectionNumber) = "None"; // Default
4019 0 : ShowWarningError(state,
4020 0 : format("{}{}=\"{}\" {} is blank. Default of no door protection will be used",
4021 : RoutineName,
4022 : cCurrentModuleObject,
4023 : cAlphaArgs(1),
4024 : cAlphaFieldNames(AlphaNum)));
4025 : } else {
4026 3 : if (cAlphaArgs(AlphaNum) == "NONE") {
4027 1 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Protection(ConnectionNumber) = RefDoorNone;
4028 1 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName(ConnectionNumber) = "None";
4029 2 : } else if (cAlphaArgs(AlphaNum) == "AIRCURTAIN") {
4030 1 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Protection(ConnectionNumber) = RefDoorAirCurtain;
4031 1 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName(ConnectionNumber) = "AirCurtain";
4032 1 : } else if (cAlphaArgs(AlphaNum) == "STRIPCURTAIN") {
4033 1 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Protection(ConnectionNumber) = RefDoorStripCurtain;
4034 1 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName(ConnectionNumber) = "StripCurtain";
4035 : } else {
4036 0 : ShowSevereError(state,
4037 0 : format("{}{}=\"{}\", invalid calculation method={} with alphanum of 5: {}",
4038 : RoutineName,
4039 : cCurrentModuleObject,
4040 : cAlphaArgs(1),
4041 : cAlphaArgs(AlphaNum),
4042 : cAlphaArgs(5)));
4043 0 : ErrorsFound = true;
4044 : } // =none, etc.
4045 : } // Blank
4046 :
4047 3 : if (ZoneNumA > 0) {
4048 3 : if (RepVarSet(ZoneNumA)) {
4049 3 : RepVarSet(ZoneNumA) = false;
4050 6 : SetupOutputVariable(state,
4051 : "Zone Mixing Volume",
4052 : Constant::Units::m3,
4053 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixVolume,
4054 : OutputProcessor::TimeStepType::System,
4055 : OutputProcessor::StoreType::Sum,
4056 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4057 6 : SetupOutputVariable(state,
4058 : "Zone Mixing Current Density Volume Flow Rate",
4059 : Constant::Units::m3_s,
4060 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixVdotCurDensity,
4061 : OutputProcessor::TimeStepType::System,
4062 : OutputProcessor::StoreType::Average,
4063 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4064 6 : SetupOutputVariable(state,
4065 : "Zone Mixing Standard Density Volume Flow Rate",
4066 : Constant::Units::m3_s,
4067 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixVdotStdDensity,
4068 : OutputProcessor::TimeStepType::System,
4069 : OutputProcessor::StoreType::Average,
4070 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4071 6 : SetupOutputVariable(state,
4072 : "Zone Mixing Mass",
4073 : Constant::Units::kg,
4074 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixMass,
4075 : OutputProcessor::TimeStepType::System,
4076 : OutputProcessor::StoreType::Sum,
4077 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4078 6 : SetupOutputVariable(state,
4079 : "Zone Mixing Mass Flow Rate",
4080 : Constant::Units::kg_s,
4081 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixMdot,
4082 : OutputProcessor::TimeStepType::System,
4083 : OutputProcessor::StoreType::Average,
4084 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4085 6 : SetupOutputVariable(state,
4086 : "Zone Mixing Sensible Heat Loss Energy",
4087 : Constant::Units::J,
4088 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixHeatLoss,
4089 : OutputProcessor::TimeStepType::System,
4090 : OutputProcessor::StoreType::Sum,
4091 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4092 6 : SetupOutputVariable(state,
4093 : "Zone Mixing Sensible Heat Gain Energy",
4094 : Constant::Units::J,
4095 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixHeatGain,
4096 : OutputProcessor::TimeStepType::System,
4097 : OutputProcessor::StoreType::Sum,
4098 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4099 6 : SetupOutputVariable(state,
4100 : "Zone Mixing Latent Heat Loss Energy",
4101 : Constant::Units::J,
4102 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixLatentLoss,
4103 : OutputProcessor::TimeStepType::System,
4104 : OutputProcessor::StoreType::Sum,
4105 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4106 6 : SetupOutputVariable(state,
4107 : "Zone Mixing Latent Heat Gain Energy",
4108 : Constant::Units::J,
4109 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixLatentGain,
4110 : OutputProcessor::TimeStepType::System,
4111 : OutputProcessor::StoreType::Sum,
4112 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4113 6 : SetupOutputVariable(state,
4114 : "Zone Mixing Total Heat Loss Energy",
4115 : Constant::Units::J,
4116 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixTotalLoss,
4117 : OutputProcessor::TimeStepType::System,
4118 : OutputProcessor::StoreType::Sum,
4119 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4120 6 : SetupOutputVariable(state,
4121 : "Zone Mixing Total Heat Gain Energy",
4122 : Constant::Units::J,
4123 3 : state.dataHeatBal->ZnAirRpt(ZoneNumA).MixTotalGain,
4124 : OutputProcessor::TimeStepType::System,
4125 : OutputProcessor::StoreType::Sum,
4126 3 : state.dataHeatBal->Zone(ZoneNumA).Name);
4127 : }
4128 : }
4129 3 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4130 0 : SetupEMSActuator(state,
4131 : "ZoneRefDoorMixing",
4132 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).Name,
4133 : "Air Exchange Flow Rate",
4134 : "[m3/s]",
4135 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorMixingOn(ConnectionNumber),
4136 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorFlowRate(ConnectionNumber));
4137 : }
4138 :
4139 3 : if (ZoneNumB > 0) {
4140 3 : if (RepVarSet(ZoneNumB)) {
4141 2 : RepVarSet(ZoneNumB) = false;
4142 4 : SetupOutputVariable(state,
4143 : "Zone Mixing Volume",
4144 : Constant::Units::m3,
4145 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixVolume,
4146 : OutputProcessor::TimeStepType::System,
4147 : OutputProcessor::StoreType::Sum,
4148 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4149 4 : SetupOutputVariable(state,
4150 : "Zone Mixing Current Density Volume Flow Rate",
4151 : Constant::Units::m3_s,
4152 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixVdotCurDensity,
4153 : OutputProcessor::TimeStepType::System,
4154 : OutputProcessor::StoreType::Average,
4155 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4156 4 : SetupOutputVariable(state,
4157 : "Zone Mixing Standard Density Volume Flow Rate",
4158 : Constant::Units::m3_s,
4159 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixVdotStdDensity,
4160 : OutputProcessor::TimeStepType::System,
4161 : OutputProcessor::StoreType::Average,
4162 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4163 4 : SetupOutputVariable(state,
4164 : "Zone Mixing Mass",
4165 : Constant::Units::kg,
4166 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixMass,
4167 : OutputProcessor::TimeStepType::System,
4168 : OutputProcessor::StoreType::Sum,
4169 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4170 4 : SetupOutputVariable(state,
4171 : "Zone Mixing Mass Flow Rate",
4172 : Constant::Units::kg_s,
4173 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixMdot,
4174 : OutputProcessor::TimeStepType::System,
4175 : OutputProcessor::StoreType::Average,
4176 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4177 4 : SetupOutputVariable(state,
4178 : "Zone Mixing Sensible Heat Loss Energy",
4179 : Constant::Units::J,
4180 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixHeatLoss,
4181 : OutputProcessor::TimeStepType::System,
4182 : OutputProcessor::StoreType::Sum,
4183 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4184 4 : SetupOutputVariable(state,
4185 : "Zone Mixing Sensible Heat Gain Energy",
4186 : Constant::Units::J,
4187 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixHeatGain,
4188 : OutputProcessor::TimeStepType::System,
4189 : OutputProcessor::StoreType::Sum,
4190 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4191 4 : SetupOutputVariable(state,
4192 : "Zone Mixing Latent Heat Loss Energy",
4193 : Constant::Units::J,
4194 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixLatentLoss,
4195 : OutputProcessor::TimeStepType::System,
4196 : OutputProcessor::StoreType::Sum,
4197 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4198 4 : SetupOutputVariable(state,
4199 : "Zone Mixing Latent Heat Gain Energy",
4200 : Constant::Units::J,
4201 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixLatentGain,
4202 : OutputProcessor::TimeStepType::System,
4203 : OutputProcessor::StoreType::Sum,
4204 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4205 4 : SetupOutputVariable(state,
4206 : "Zone Mixing Total Heat Loss Energy",
4207 : Constant::Units::J,
4208 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixTotalLoss,
4209 : OutputProcessor::TimeStepType::System,
4210 : OutputProcessor::StoreType::Sum,
4211 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4212 4 : SetupOutputVariable(state,
4213 : "Zone Mixing Total Heat Gain Energy",
4214 : Constant::Units::J,
4215 2 : state.dataHeatBal->ZnAirRpt(ZoneNumB).MixTotalGain,
4216 : OutputProcessor::TimeStepType::System,
4217 : OutputProcessor::StoreType::Sum,
4218 2 : state.dataHeatBal->Zone(ZoneNumB).Name);
4219 : }
4220 : }
4221 3 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4222 0 : SetupEMSActuator(state,
4223 : "ZoneRefDoorMixing",
4224 0 : state.dataHeatBal->RefDoorMixing(ZoneNumB).Name,
4225 : "Air Exchange Flow Rate",
4226 : "[m3/s]",
4227 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorMixingOn(ConnectionNumber),
4228 0 : state.dataHeatBal->RefDoorMixing(ZoneNumA).EMSRefDoorFlowRate(ConnectionNumber));
4229 : }
4230 :
4231 : } // DO Loop=1,TotRefDoorMixing
4232 : } // TotRefDoorMixing > 0)
4233 :
4234 796 : RepVarSet.deallocate();
4235 796 : cAlphaArgs.deallocate();
4236 796 : cAlphaFieldNames.deallocate();
4237 796 : cNumericFieldNames.deallocate();
4238 796 : rNumericArgs.deallocate();
4239 796 : lAlphaFieldBlanks.deallocate();
4240 796 : lNumericFieldBlanks.deallocate();
4241 :
4242 796 : TotInfilVentFlow.dimension(state.dataGlobal->NumOfZones, 0.0);
4243 :
4244 11289 : auto divide_and_print_if_greater_than_zero = [&](const Real64 denominator, const Real64 numerator) {
4245 11289 : if (denominator > 0.0) {
4246 10984 : print(state.files.eio, "{:.3R},", numerator / denominator);
4247 : } else {
4248 305 : print(state.files.eio, "N/A,");
4249 : }
4250 11289 : };
4251 :
4252 4317 : for (int Loop = 1; Loop <= state.dataHeatBal->TotInfiltration; ++Loop) {
4253 3521 : if (Loop == 1)
4254 431 : print(state.files.eio,
4255 : Format_721,
4256 : "ZoneInfiltration",
4257 : "Design Volume Flow Rate {m3/s},Volume Flow Rate/Floor Area {m3/s-m2},Volume Flow Rate/Exterior Surface Area {m3/s-m2},ACH - "
4258 : "Air Changes per Hour,Equation A - Constant Term Coefficient {},Equation B - Temperature Term Coefficient {1/C},Equation C - "
4259 : "Velocity Term Coefficient {s/m}, Equation D - Velocity Squared Term Coefficient {s2/m2}");
4260 :
4261 3521 : int ZoneNum = state.dataHeatBal->Infiltration(Loop).ZonePtr;
4262 3521 : if (ZoneNum == 0) {
4263 0 : print(state.files.eio, Format_722, "Infiltration-Illegal Zone specified", state.dataHeatBal->Infiltration(Loop).Name);
4264 0 : continue;
4265 : }
4266 3521 : TotInfilVentFlow(ZoneNum) += state.dataHeatBal->Infiltration(Loop).DesignLevel;
4267 3521 : print(state.files.eio,
4268 : Format_720,
4269 : "ZoneInfiltration",
4270 3521 : state.dataHeatBal->Infiltration(Loop).Name,
4271 7042 : ScheduleManager::GetScheduleName(state, state.dataHeatBal->Infiltration(Loop).SchedPtr),
4272 3521 : state.dataHeatBal->Zone(ZoneNum).Name,
4273 3521 : state.dataHeatBal->Zone(ZoneNum).FloorArea,
4274 3521 : state.dataHeatBal->Zone(ZoneNum).TotOccupants);
4275 3521 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Infiltration(Loop).DesignLevel);
4276 :
4277 3521 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).FloorArea, state.dataHeatBal->Infiltration(Loop).DesignLevel);
4278 3521 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).ExteriorTotalSurfArea,
4279 3521 : state.dataHeatBal->Infiltration(Loop).DesignLevel);
4280 3521 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).Volume,
4281 3521 : state.dataHeatBal->Infiltration(Loop).DesignLevel * Constant::SecInHour);
4282 :
4283 3521 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Infiltration(Loop).ConstantTermCoef);
4284 3521 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Infiltration(Loop).TemperatureTermCoef);
4285 3521 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Infiltration(Loop).VelocityTermCoef);
4286 3521 : print(state.files.eio, "{:.3R}\n", state.dataHeatBal->Infiltration(Loop).VelocitySQTermCoef);
4287 : }
4288 :
4289 796 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
4290 10 : for (int Loop = 1; Loop <= state.dataHeatBal->TotInfiltration; ++Loop) {
4291 8 : int ZoneNum = state.dataHeatBal->Infiltration(Loop).ZonePtr;
4292 8 : state.dataHeatBal->MassConservation(ZoneNum).InfiltrationPtr = Loop;
4293 : }
4294 : }
4295 :
4296 974 : for (int Loop = 1; Loop <= state.dataHeatBal->TotVentilation; ++Loop) {
4297 178 : if (Loop == 1) {
4298 28 : print(state.files.eio,
4299 : Format_721,
4300 : "ZoneVentilation",
4301 : "Design Volume Flow Rate {m3/s},Volume Flow Rate/Floor Area {m3/s-m2},Volume Flow Rate/person Area {m3/s-person},ACH - Air "
4302 : "Changes per Hour,Fan Type {Exhaust;Intake;Natural},Fan Pressure Rise {Pa},Fan Efficiency {},Equation A - Constant Term "
4303 : "Coefficient {},Equation B - Temperature Term Coefficient {1/C},Equation C - Velocity Term Coefficient {s/m}, Equation D - "
4304 : "Velocity Squared Term Coefficient {s2/m2},Minimum Indoor Temperature{C}/Schedule,Maximum Indoor "
4305 : "Temperature{C}/Schedule,Delta Temperature{C}/Schedule,Minimum Outdoor Temperature{C}/Schedule,Maximum Outdoor "
4306 : "Temperature{C}/Schedule,Maximum WindSpeed{m/s}");
4307 : }
4308 :
4309 178 : int ZoneNum = state.dataHeatBal->Ventilation(Loop).ZonePtr;
4310 178 : if (ZoneNum == 0) {
4311 0 : print(state.files.eio, Format_722, "Ventilation-Illegal Zone specified", state.dataHeatBal->Ventilation(Loop).Name);
4312 0 : continue;
4313 : }
4314 178 : TotInfilVentFlow(ZoneNum) += state.dataHeatBal->Ventilation(Loop).DesignLevel;
4315 178 : print(state.files.eio,
4316 : Format_720,
4317 : "ZoneVentilation",
4318 178 : state.dataHeatBal->Ventilation(Loop).Name,
4319 356 : ScheduleManager::GetScheduleName(state, state.dataHeatBal->Ventilation(Loop).SchedPtr),
4320 178 : state.dataHeatBal->Zone(ZoneNum).Name,
4321 178 : state.dataHeatBal->Zone(ZoneNum).FloorArea,
4322 178 : state.dataHeatBal->Zone(ZoneNum).TotOccupants);
4323 :
4324 178 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Ventilation(Loop).DesignLevel);
4325 :
4326 178 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).FloorArea, state.dataHeatBal->Ventilation(Loop).DesignLevel);
4327 178 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).TotOccupants, state.dataHeatBal->Ventilation(Loop).DesignLevel);
4328 178 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).Volume,
4329 178 : state.dataHeatBal->Ventilation(Loop).DesignLevel * Constant::SecInHour);
4330 :
4331 178 : if (state.dataHeatBal->Ventilation(Loop).FanType == DataHeatBalance::VentilationType::Exhaust) {
4332 14 : print(state.files.eio, "Exhaust,");
4333 164 : } else if (state.dataHeatBal->Ventilation(Loop).FanType == DataHeatBalance::VentilationType::Intake) {
4334 16 : print(state.files.eio, "Intake,");
4335 148 : } else if (state.dataHeatBal->Ventilation(Loop).FanType == DataHeatBalance::VentilationType::Natural) {
4336 140 : print(state.files.eio, "Natural,");
4337 8 : } else if (state.dataHeatBal->Ventilation(Loop).FanType == DataHeatBalance::VentilationType::Balanced) {
4338 8 : print(state.files.eio, "Balanced,");
4339 : } else {
4340 0 : print(state.files.eio, "UNKNOWN,");
4341 : }
4342 178 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Ventilation(Loop).FanPressure);
4343 178 : print(state.files.eio, "{:.1R},", state.dataHeatBal->Ventilation(Loop).FanEfficiency);
4344 178 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Ventilation(Loop).ConstantTermCoef);
4345 178 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Ventilation(Loop).TemperatureTermCoef);
4346 178 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Ventilation(Loop).VelocityTermCoef);
4347 178 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Ventilation(Loop).VelocitySQTermCoef);
4348 :
4349 : // TODO Should this also be prefixed with "Schedule: " like the following ones are?
4350 178 : if (state.dataHeatBal->Ventilation(Loop).MinIndoorTempSchedPtr > 0) {
4351 8 : print(state.files.eio, "{},", ScheduleManager::GetScheduleName(state, state.dataHeatBal->Ventilation(Loop).MinIndoorTempSchedPtr));
4352 : } else {
4353 170 : print(state.files.eio, "{:.2R},", state.dataHeatBal->Ventilation(Loop).MinIndoorTemperature);
4354 : }
4355 :
4356 712 : const auto print_temperature = [&](const int ptr, const Real64 value) {
4357 712 : if (ptr > 0) {
4358 32 : print(state.files.eio, "Schedule: {},", ScheduleManager::GetScheduleName(state, ptr));
4359 : } else {
4360 680 : print(state.files.eio, "{:.2R},", value);
4361 : }
4362 712 : };
4363 :
4364 178 : print_temperature(state.dataHeatBal->Ventilation(Loop).MaxIndoorTempSchedPtr, state.dataHeatBal->Ventilation(Loop).MaxIndoorTemperature);
4365 178 : print_temperature(state.dataHeatBal->Ventilation(Loop).DeltaTempSchedPtr, state.dataHeatBal->Ventilation(Loop).DelTemperature);
4366 178 : print_temperature(state.dataHeatBal->Ventilation(Loop).MinOutdoorTempSchedPtr, state.dataHeatBal->Ventilation(Loop).MinOutdoorTemperature);
4367 178 : print_temperature(state.dataHeatBal->Ventilation(Loop).MaxOutdoorTempSchedPtr, state.dataHeatBal->Ventilation(Loop).MaxOutdoorTemperature);
4368 :
4369 178 : print(state.files.eio, "{:.2R}\n", state.dataHeatBal->Ventilation(Loop).MaxWindSpeed);
4370 : }
4371 :
4372 796 : TotMixingFlow.dimension(state.dataGlobal->NumOfZones, 0.0);
4373 850 : for (int Loop = 1; Loop <= state.dataHeatBal->TotMixing; ++Loop) {
4374 54 : if (Loop == 1)
4375 17 : print(state.files.eio,
4376 : Format_721,
4377 : "Mixing",
4378 : "Design Volume Flow Rate {m3/s},Volume Flow Rate/Floor Area {m3/s-m2},Volume Flow Rate/person Area {m3/s-person},ACH - Air "
4379 : "Changes per Hour,From/Source Zone,Delta Temperature {C}");
4380 :
4381 54 : int ZoneNum = state.dataHeatBal->Mixing(Loop).ZonePtr;
4382 54 : if (ZoneNum == 0) {
4383 0 : print(state.files.eio, Format_722, "Mixing-Illegal Zone specified", state.dataHeatBal->Mixing(Loop).Name);
4384 0 : continue;
4385 : }
4386 54 : TotMixingFlow(ZoneNum) += state.dataHeatBal->Mixing(Loop).DesignLevel;
4387 54 : print(state.files.eio,
4388 : Format_720,
4389 : "Mixing",
4390 54 : state.dataHeatBal->Mixing(Loop).Name,
4391 108 : ScheduleManager::GetScheduleName(state, state.dataHeatBal->Mixing(Loop).SchedPtr),
4392 54 : state.dataHeatBal->Zone(ZoneNum).Name,
4393 54 : state.dataHeatBal->Zone(ZoneNum).FloorArea,
4394 54 : state.dataHeatBal->Zone(ZoneNum).TotOccupants);
4395 54 : print(state.files.eio, "{:.3R},", state.dataHeatBal->Mixing(Loop).DesignLevel);
4396 54 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).FloorArea, state.dataHeatBal->Mixing(Loop).DesignLevel);
4397 54 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).TotOccupants, state.dataHeatBal->Mixing(Loop).DesignLevel);
4398 54 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).Volume,
4399 54 : state.dataHeatBal->Mixing(Loop).DesignLevel * Constant::SecInHour);
4400 :
4401 54 : print(state.files.eio, "{},", state.dataHeatBal->Zone(state.dataHeatBal->Mixing(Loop).FromZone).Name);
4402 54 : print(state.files.eio, "{:.2R}\n", state.dataHeatBal->Mixing(Loop).DeltaTemperature);
4403 : }
4404 :
4405 806 : for (int Loop = 1; Loop <= state.dataHeatBal->TotCrossMixing; ++Loop) {
4406 10 : if (Loop == 1) {
4407 4 : print(state.files.eio,
4408 : Format_721,
4409 : "CrossMixing",
4410 : "Design Volume Flow Rate {m3/s},Volume Flow Rate/Floor Area {m3/s-m2},Volume Flow Rate/person Area {m3/s-person},ACH - Air "
4411 : "Changes per Hour,From/Source Zone,Delta Temperature {C}");
4412 : }
4413 :
4414 10 : int ZoneNum = state.dataHeatBal->CrossMixing(Loop).ZonePtr;
4415 10 : if (ZoneNum == 0) {
4416 0 : print(state.files.eio, Format_722, "CrossMixing-Illegal Zone specified", state.dataHeatBal->CrossMixing(Loop).Name);
4417 0 : continue;
4418 : }
4419 10 : TotMixingFlow(ZoneNum) += state.dataHeatBal->CrossMixing(Loop).DesignLevel;
4420 10 : print(state.files.eio,
4421 : Format_720,
4422 : "CrossMixing",
4423 10 : state.dataHeatBal->CrossMixing(Loop).Name,
4424 20 : ScheduleManager::GetScheduleName(state, state.dataHeatBal->CrossMixing(Loop).SchedPtr),
4425 10 : state.dataHeatBal->Zone(ZoneNum).Name,
4426 10 : state.dataHeatBal->Zone(ZoneNum).FloorArea,
4427 10 : state.dataHeatBal->Zone(ZoneNum).TotOccupants);
4428 :
4429 10 : print(state.files.eio, "{:.3R},", state.dataHeatBal->CrossMixing(Loop).DesignLevel);
4430 :
4431 10 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).FloorArea, state.dataHeatBal->CrossMixing(Loop).DesignLevel);
4432 10 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).TotOccupants, state.dataHeatBal->CrossMixing(Loop).DesignLevel);
4433 10 : divide_and_print_if_greater_than_zero(state.dataHeatBal->Zone(ZoneNum).Volume,
4434 10 : state.dataHeatBal->CrossMixing(Loop).DesignLevel * Constant::SecInHour);
4435 :
4436 10 : print(state.files.eio, "{},", state.dataHeatBal->Zone(state.dataHeatBal->CrossMixing(Loop).FromZone).Name);
4437 10 : print(state.files.eio, "{:.2R}\n", state.dataHeatBal->CrossMixing(Loop).DeltaTemperature);
4438 : }
4439 :
4440 796 : if (state.dataHeatBal->TotRefDoorMixing > 0) {
4441 : static constexpr std::string_view Format_724("! <{} Airflow Stats Nominal>, {}\n");
4442 1 : print(state.files.eio,
4443 : Format_724,
4444 : "RefrigerationDoorMixing ",
4445 : "Name, Zone 1 Name,Zone 2 Name,Door Opening Schedule Name,Door Height {m},Door Area {m2},Door Protection Type");
4446 14 : for (ZoneNumA = 1; ZoneNumA <= (state.dataGlobal->NumOfZones - 1); ++ZoneNumA) {
4447 13 : if (!state.dataHeatBal->RefDoorMixing(ZoneNumA).RefDoorMixFlag) continue;
4448 8 : for (ConnectionNumber = 1; ConnectionNumber <= state.dataHeatBal->RefDoorMixing(ZoneNumA).NumRefDoorConnections; ++ConnectionNumber) {
4449 3 : ZoneNumB = state.dataHeatBal->RefDoorMixing(ZoneNumA).MateZonePtr(ConnectionNumber);
4450 : // TotMixingFlow(ZoneNum)=TotMixingFlow(ZoneNum)+RefDoorMixing(Loop)%!DesignLevel
4451 : static constexpr std::string_view Format_723(" {} Airflow Stats Nominal, {},{},{},{},{:.3R},{:.3R},{}\n");
4452 3 : print(state.files.eio,
4453 : Format_723,
4454 : "RefrigerationDoorMixing",
4455 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorMixingObjectName(ConnectionNumber),
4456 3 : state.dataHeatBal->Zone(ZoneNumA).Name,
4457 3 : state.dataHeatBal->Zone(ZoneNumB).Name,
4458 6 : ScheduleManager::GetScheduleName(state, state.dataHeatBal->RefDoorMixing(ZoneNumA).OpenSchedPtr(ConnectionNumber)),
4459 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorHeight(ConnectionNumber),
4460 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorArea(ConnectionNumber),
4461 3 : state.dataHeatBal->RefDoorMixing(ZoneNumA).DoorProtTypeName(ConnectionNumber));
4462 : } // ConnectionNumber
4463 : } // ZoneNumA
4464 : } //(TotRefDoorMixing .GT. 0)
4465 :
4466 5852 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
4467 5056 : state.dataHeatBal->Zone(ZoneNum).NominalInfilVent = TotInfilVentFlow(ZoneNum);
4468 5056 : state.dataHeatBal->Zone(ZoneNum).NominalMixing = TotMixingFlow(ZoneNum);
4469 : }
4470 :
4471 796 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
4472 : // Check for infiltration in zone which are only a mixing source zone
4473 14 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
4474 12 : if ((state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing &&
4475 20 : state.dataHeatBal->MassConservation(ZoneNum).IsOnlySourceZone) &&
4476 8 : (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment != DataHeatBalance::InfiltrationFlow::No)) {
4477 8 : if (state.dataHeatBal->MassConservation(ZoneNum).InfiltrationPtr == 0) {
4478 0 : ShowSevereError(
4479 0 : state, format("{}: Infiltration object is not defined for zone = {}", RoutineName, state.dataHeatBal->Zone(ZoneNum).Name));
4480 0 : ShowContinueError(state, "Zone air mass flow balance requires infiltration object for source zones of mixing objects");
4481 : }
4482 : }
4483 : }
4484 : // Set up zone air mass balance output variables
4485 14 : for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
4486 24 : SetupOutputVariable(state,
4487 : "Zone Air Mass Balance Supply Mass Flow Rate",
4488 : Constant::Units::kg_s,
4489 12 : state.dataHeatBal->MassConservation(ZoneNum).InMassFlowRate,
4490 : OutputProcessor::TimeStepType::System,
4491 : OutputProcessor::StoreType::Average,
4492 12 : state.dataHeatBal->Zone(ZoneNum).Name);
4493 24 : SetupOutputVariable(state,
4494 : "Zone Air Mass Balance Exhaust Mass Flow Rate",
4495 : Constant::Units::kg_s,
4496 12 : state.dataHeatBal->MassConservation(ZoneNum).ExhMassFlowRate,
4497 : OutputProcessor::TimeStepType::System,
4498 : OutputProcessor::StoreType::Average,
4499 12 : state.dataHeatBal->Zone(ZoneNum).Name);
4500 24 : SetupOutputVariable(state,
4501 : "Zone Air Mass Balance Return Mass Flow Rate",
4502 : Constant::Units::kg_s,
4503 12 : state.dataHeatBal->MassConservation(ZoneNum).RetMassFlowRate,
4504 : OutputProcessor::TimeStepType::System,
4505 : OutputProcessor::StoreType::Average,
4506 12 : state.dataHeatBal->Zone(ZoneNum).Name);
4507 24 : if ((state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing) &&
4508 12 : ((state.dataHeatBal->MassConservation(ZoneNum).NumSourceZonesMixingObject +
4509 12 : state.dataHeatBal->MassConservation(ZoneNum).NumReceivingZonesMixingObject) > 0)) {
4510 20 : SetupOutputVariable(state,
4511 : "Zone Air Mass Balance Mixing Receiving Mass Flow Rate",
4512 : Constant::Units::kg_s,
4513 10 : state.dataHeatBal->MassConservation(ZoneNum).MixingMassFlowRate,
4514 : OutputProcessor::TimeStepType::System,
4515 : OutputProcessor::StoreType::Average,
4516 10 : state.dataHeatBal->Zone(ZoneNum).Name);
4517 20 : SetupOutputVariable(state,
4518 : "Zone Air Mass Balance Mixing Source Mass Flow Rate",
4519 : Constant::Units::kg_s,
4520 10 : state.dataHeatBal->MassConservation(ZoneNum).MixingSourceMassFlowRate,
4521 : OutputProcessor::TimeStepType::System,
4522 : OutputProcessor::StoreType::Average,
4523 10 : state.dataHeatBal->Zone(ZoneNum).Name);
4524 : }
4525 12 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment != DataHeatBalance::InfiltrationFlow::No) {
4526 18 : if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationForZones == DataHeatBalance::InfiltrationZoneType::AllZones ||
4527 6 : (state.dataHeatBal->MassConservation(ZoneNum).NumSourceZonesMixingObject > 0)) {
4528 10 : if (state.dataHeatBal->MassConservation(ZoneNum).InfiltrationPtr > 0) {
4529 16 : SetupOutputVariable(state,
4530 : "Zone Air Mass Balance Infiltration Mass Flow Rate",
4531 : Constant::Units::kg_s,
4532 8 : state.dataHeatBal->MassConservation(ZoneNum).InfiltrationMassFlowRate,
4533 : OutputProcessor::TimeStepType::System,
4534 : OutputProcessor::StoreType::Average,
4535 8 : state.dataHeatBal->Zone(ZoneNum).Name);
4536 8 : SetupOutputVariable(state,
4537 : "Zone Air Mass Balance Infiltration Status",
4538 : Constant::Units::None,
4539 8 : state.dataHeatBal->MassConservation(ZoneNum).IncludeInfilToZoneMassBal,
4540 : OutputProcessor::TimeStepType::System,
4541 : OutputProcessor::StoreType::Average,
4542 8 : state.dataHeatBal->Zone(ZoneNum).Name);
4543 : }
4544 : }
4545 : }
4546 : }
4547 : }
4548 :
4549 796 : TotInfilVentFlow.deallocate();
4550 796 : TotMixingFlow.deallocate();
4551 : // ' Area per Occupant {m2/person}, Occupant per Area {person/m2}, Interior Lighting {W/m2}, ', &
4552 : // 'Electric Load {W/m2}, Gas Load {W/m2}, Other Load {W/m2}, Hot Water Eq {W/m2}, Outdoor Controlled Baseboard Heat')
4553 796 : }
4554 :
4555 796 : void GetRoomAirModelParameters(EnergyPlusData &state, bool &errFlag) // True if errors found during this input routine
4556 : {
4557 :
4558 : // SUBROUTINE INFORMATION:
4559 : // AUTHOR Brent Griffith
4560 : // DATE WRITTEN August 2001
4561 : // RE-ENGINEERED April 2003, Weixiu Kong
4562 : // December 2003, CC
4563 :
4564 : // PURPOSE OF THIS SUBROUTINE:
4565 : // Get room air model parameters for all zones at once
4566 :
4567 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4568 : int NumAlphas; // States which alpha value to read from a
4569 : // "Number" line
4570 : int NumNumbers; // Number of numbers encountered
4571 : int Status; // Notes if there was an error in processing the input
4572 : int AirModelNum;
4573 : int NumOfAirModels;
4574 : int ZoneNum;
4575 : bool IsNotOK;
4576 :
4577 : // Initialize default values for air model parameters
4578 796 : state.dataRoomAir->AirModel.allocate(state.dataGlobal->NumOfZones);
4579 :
4580 796 : bool ErrorsFound = false;
4581 796 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
4582 :
4583 796 : cCurrentModuleObject = "RoomAirModelType";
4584 796 : NumOfAirModels = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
4585 796 : if (NumOfAirModels > state.dataGlobal->NumOfZones) {
4586 0 : ShowSevereError(state, format("Too many {}. Cannot exceed the number of Zones.", cCurrentModuleObject));
4587 0 : ErrorsFound = true;
4588 : }
4589 796 : if (NumOfAirModels > 0) {
4590 11 : state.dataRoomAir->IsZoneDispVent3Node.dimension(state.dataGlobal->NumOfZones, false);
4591 11 : state.dataRoomAir->IsZoneCrossVent.dimension(state.dataGlobal->NumOfZones, false);
4592 11 : state.dataRoomAir->IsZoneUFAD.dimension(state.dataGlobal->NumOfZones, false);
4593 : }
4594 :
4595 825 : for (AirModelNum = 1; AirModelNum <= NumOfAirModels; ++AirModelNum) {
4596 87 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
4597 : cCurrentModuleObject,
4598 : AirModelNum,
4599 29 : state.dataIPShortCut->cAlphaArgs,
4600 : NumAlphas,
4601 29 : state.dataIPShortCut->rNumericArgs,
4602 : NumNumbers,
4603 : Status,
4604 : _,
4605 : _,
4606 29 : state.dataIPShortCut->cAlphaFieldNames,
4607 29 : state.dataIPShortCut->cNumericFieldNames);
4608 29 : ZoneNum = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataHeatBal->Zone);
4609 29 : if (ZoneNum != 0) {
4610 29 : if (!state.dataRoomAir->AirModel(ZoneNum).Name.empty()) {
4611 0 : ShowSevereError(state, format("Invalid {} = {}", state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2)));
4612 0 : ShowContinueError(state, format("Entered in {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4613 0 : ShowContinueError(state, "Duplicate zone name, only one type of roomair model is allowed per zone");
4614 0 : ShowContinueError(state,
4615 0 : format("Zone {} was already assigned a roomair model by {} = {}",
4616 0 : state.dataIPShortCut->cAlphaArgs(2),
4617 : cCurrentModuleObject,
4618 0 : roomAirModelNamesUC[(int)state.dataRoomAir->AirModel(ZoneNum).AirModel]));
4619 0 : ShowContinueError(
4620 : state,
4621 0 : format("Air Model Type for zone already set to {}", roomAirModelNamesUC[(int)state.dataRoomAir->AirModel(ZoneNum).AirModel]));
4622 0 : ShowContinueError(state, format("Trying to overwrite with model type = {}", state.dataIPShortCut->cAlphaArgs(3)));
4623 0 : ErrorsFound = true;
4624 : }
4625 29 : state.dataRoomAir->AirModel(ZoneNum).ZoneName = state.dataIPShortCut->cAlphaArgs(2);
4626 :
4627 : // state.dataRoomAir->AirModel(ZoneNum).AirModelName = state.dataIPShortCut->cAlphaArgs(1);
4628 29 : state.dataRoomAir->AirModel(ZoneNum).AirModel =
4629 29 : static_cast<RoomAir::RoomAirModel>(getEnumValue(roomAirModelNamesUC, state.dataIPShortCut->cAlphaArgs(3))); // is this arg1 or arg3?
4630 29 : switch (state.dataRoomAir->AirModel(ZoneNum).AirModel) {
4631 4 : case RoomAir::RoomAirModel::Mixing:
4632 : // nothing to do here actually
4633 4 : break;
4634 :
4635 4 : case RoomAir::RoomAirModel::DispVent1Node:
4636 4 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4637 4 : state.dataRoomAir->DispVent1NodeModelUsed = true;
4638 4 : IsNotOK = false;
4639 8 : ValidateComponent(state,
4640 : "RoomAirSettings:OneNodeDisplacementVentilation",
4641 : "zone_name",
4642 4 : state.dataIPShortCut->cAlphaArgs(2),
4643 : IsNotOK,
4644 : "GetRoomAirModelParameters");
4645 4 : if (IsNotOK) {
4646 0 : ShowContinueError(state, format("In {}={}.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4647 0 : ErrorsFound = true;
4648 : }
4649 4 : break;
4650 :
4651 4 : case RoomAir::RoomAirModel::DispVent3Node:
4652 4 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4653 4 : state.dataRoomAir->UCSDModelUsed = true;
4654 4 : IsNotOK = false;
4655 8 : ValidateComponent(state,
4656 : "RoomAirSettings:ThreeNodeDisplacementVentilation",
4657 : "zone_name",
4658 4 : state.dataIPShortCut->cAlphaArgs(2),
4659 : IsNotOK,
4660 : "GetRoomAirModelParameters");
4661 4 : if (IsNotOK) {
4662 0 : ShowContinueError(state, format("In {}={}.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4663 0 : ErrorsFound = true;
4664 : }
4665 4 : break;
4666 :
4667 2 : case RoomAir::RoomAirModel::CrossVent:
4668 2 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4669 2 : state.dataRoomAir->UCSDModelUsed = true;
4670 2 : IsNotOK = false;
4671 4 : ValidateComponent(state,
4672 : "RoomAirSettings:CrossVentilation",
4673 : "zone_name",
4674 2 : state.dataIPShortCut->cAlphaArgs(2),
4675 : IsNotOK,
4676 : "GetRoomAirModelParameters");
4677 2 : if (IsNotOK) {
4678 0 : ShowContinueError(state, format("In {}={}.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4679 0 : ErrorsFound = true;
4680 : }
4681 2 : break;
4682 :
4683 1 : case RoomAir::RoomAirModel::UFADInt:
4684 1 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4685 1 : state.dataRoomAir->UCSDModelUsed = true;
4686 2 : ValidateComponent(state,
4687 : "RoomAirSettings:UnderFloorAirDistributionInterior",
4688 : "zone_name",
4689 1 : state.dataIPShortCut->cAlphaArgs(2),
4690 : IsNotOK,
4691 : "GetRoomAirModelParameters");
4692 1 : if (IsNotOK) {
4693 0 : ShowContinueError(state, format("In {}={}.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4694 0 : ErrorsFound = true;
4695 : }
4696 1 : break;
4697 :
4698 4 : case RoomAir::RoomAirModel::UFADExt:
4699 4 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4700 4 : state.dataRoomAir->UCSDModelUsed = true;
4701 8 : ValidateComponent(state,
4702 : "RoomAirSettings:UnderFloorAirDistributionExterior",
4703 : "zone_name",
4704 4 : state.dataIPShortCut->cAlphaArgs(2),
4705 : IsNotOK,
4706 : "GetRoomAirModelParameters");
4707 4 : if (IsNotOK) {
4708 0 : ShowContinueError(state, format("In {}={}.", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4709 0 : ErrorsFound = true;
4710 : }
4711 4 : break;
4712 :
4713 9 : case RoomAir::RoomAirModel::UserDefined:
4714 9 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4715 9 : state.dataRoomAir->UserDefinedUsed = true;
4716 9 : break;
4717 :
4718 1 : case RoomAir::RoomAirModel::AirflowNetwork:
4719 1 : state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
4720 1 : if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirflowNetwork:SimulationControl") == 0) {
4721 0 : ShowSevereError(state,
4722 0 : format("In {} = {}: {} = AIRFLOWNETWORK.",
4723 : cCurrentModuleObject,
4724 0 : state.dataIPShortCut->cAlphaArgs(1),
4725 0 : state.dataIPShortCut->cAlphaFieldNames(3)));
4726 0 : ShowContinueError(state,
4727 : "This model requires AirflowNetwork:* objects to form a complete network, including "
4728 : "AirflowNetwork:Intrazone:Node and AirflowNetwork:Intrazone:Linkage.");
4729 0 : ShowContinueError(state, "AirflowNetwork:SimulationControl not found.");
4730 0 : ErrorsFound = true;
4731 : }
4732 1 : break;
4733 :
4734 0 : default:
4735 0 : ShowWarningError(state, format("Invalid {} = {}", state.dataIPShortCut->cAlphaFieldNames(3), state.dataIPShortCut->cAlphaArgs(3)));
4736 0 : ShowContinueError(state, format("Entered in {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4737 0 : ShowContinueError(state, format("The mixing air model will be used for Zone ={}", state.dataIPShortCut->cAlphaArgs(2)));
4738 0 : state.dataRoomAir->AirModel(ZoneNum).AirModel = RoomAir::RoomAirModel::Mixing;
4739 : }
4740 :
4741 29 : state.dataRoomAir->AirModel(ZoneNum).TempCoupleScheme =
4742 29 : static_cast<RoomAir::CouplingScheme>(getEnumValue(couplingSchemeNamesUC, state.dataIPShortCut->cAlphaArgs(4)));
4743 29 : if (state.dataRoomAir->AirModel(ZoneNum).TempCoupleScheme == RoomAir::CouplingScheme::Invalid) {
4744 0 : ShowWarningError(state, format("Invalid {} = {}", state.dataIPShortCut->cAlphaFieldNames(4), state.dataIPShortCut->cAlphaArgs(4)));
4745 0 : ShowContinueError(state, format("Entered in {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4746 0 : ShowContinueError(state, format("The direct coupling scheme will be used for Zone ={}", state.dataIPShortCut->cAlphaArgs(2)));
4747 0 : state.dataRoomAir->AirModel(ZoneNum).TempCoupleScheme = RoomAir::CouplingScheme::Direct;
4748 : }
4749 :
4750 : } else { // Zone Not Found
4751 0 : ShowSevereError(state, format("{}, Zone not found={}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(2)));
4752 0 : ShowContinueError(state, format("occurs in {}={}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4753 0 : ErrorsFound = true;
4754 : }
4755 : } // AirModel_Param_Loop
4756 :
4757 5852 : for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
4758 : // this used to be an if (NumOfAirModels == 0) block, but both the IF and the ELSE had the same content, these two lines:
4759 5056 : state.dataRoomAir->AirModel(ZoneNum).Name = "MIXING AIR MODEL FOR " + state.dataHeatBal->Zone(ZoneNum).Name;
4760 5056 : state.dataRoomAir->AirModel(ZoneNum).ZoneName = state.dataHeatBal->Zone(ZoneNum).Name;
4761 : // set global flag for non-mixing model
4762 5056 : if (state.dataRoomAir->AirModel(ZoneNum).AirModel != RoomAir::RoomAirModel::Mixing) {
4763 25 : state.dataRoomAir->anyNonMixingRoomAirModel = true;
4764 : }
4765 : }
4766 :
4767 796 : if (state.dataRoomAir->anyNonMixingRoomAirModel) {
4768 11 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) {
4769 0 : ShowSevereError(state, "Non-Mixing RoomAirModelType is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance.");
4770 0 : ErrorsFound = true;
4771 : }
4772 : }
4773 :
4774 : // Write RoomAir Model details onto EIO file
4775 : static constexpr std::string_view RoomAirHeader("! <RoomAir Model>, Zone Name, Mixing/Mundt/UCSDDV/UCSDCV/UCSDUFI/UCSDUFE/User Defined\n");
4776 796 : print(state.files.eio, RoomAirHeader);
4777 5852 : for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
4778 : static constexpr std::array<std::string_view, (int)RoomAir::RoomAirModel::Num> roomAirModelStrings = {"UserDefined",
4779 : "Mixing/Well-Stirred",
4780 : "OneNodeDisplacementVentilation",
4781 : "ThreeNodeDisplacementVentilation",
4782 : "CrossVentilation",
4783 : "UnderFloorAirDistributionInterior",
4784 : "UnderFloorAirDistributionExterior",
4785 : "AirflowNetwork"};
4786 :
4787 5056 : print(state.files.eio,
4788 : "RoomAir Model,{},{}\n",
4789 5056 : state.dataHeatBal->Zone(ZoneNum).Name,
4790 5056 : roomAirModelStrings[(int)state.dataRoomAir->AirModel(ZoneNum).AirModel]);
4791 : }
4792 :
4793 796 : if (ErrorsFound) {
4794 0 : ShowSevereError(state, format("Errors found in processing input for {}", cCurrentModuleObject));
4795 0 : errFlag = true;
4796 : }
4797 796 : }
4798 :
4799 2804678 : void InitAirHeatBalance(EnergyPlusData &state)
4800 : {
4801 :
4802 : // SUBROUTINE INFORMATION:
4803 : // AUTHOR Richard J. Liesen
4804 : // DATE WRITTEN February 1998
4805 :
4806 : // PURPOSE OF THIS SUBROUTINE:
4807 : // This subroutine is for initializations within the
4808 : // air heat balance.
4809 :
4810 : // Do the following initializations (every time step):
4811 2804678 : InitSimpleMixingConvectiveHeatGains(state);
4812 2804678 : }
4813 :
4814 2804678 : void InitSimpleMixingConvectiveHeatGains(EnergyPlusData &state)
4815 : {
4816 : // SUBROUTINE INFORMATION:
4817 : // AUTHOR Richard Liesen
4818 : // DATE WRITTEN February 1998
4819 : // MODIFIED March 2003, FCW: allow individual window/door venting control
4820 : // DATE MODIFIED April 2000
4821 : // May 2009, Brent Griffith added EMS override to mixing and cross mixing flows
4822 : // renamed routine and did some cleanup
4823 : // August 2011, Therese Stovall added refrigeration door mixing flows
4824 :
4825 : // PURPOSE OF THIS SUBROUTINE:
4826 : // This subroutine sets up the mixing and cross mixing flows
4827 :
4828 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4829 : Real64 ZoneMixingFlowSum; // sum of zone mixing flows for a zone
4830 :
4831 : // Select type of airflow calculation
4832 2804678 : if (state.dataHeatBal->AirFlowFlag) { // Simplified airflow calculation
4833 : // Process the scheduled Mixing for air heat balance
4834 3107405 : for (auto &thisMixing : state.dataHeatBal->Mixing) {
4835 302727 : thisMixing.DesiredAirFlowRate = thisMixing.DesignLevel * ScheduleManager::GetCurrentScheduleValue(state, thisMixing.SchedPtr);
4836 302727 : if (thisMixing.EMSSimpleMixingOn) thisMixing.DesiredAirFlowRate = thisMixing.EMSimpleMixingFlowRate;
4837 302727 : thisMixing.DesiredAirFlowRateSaved = thisMixing.DesiredAirFlowRate;
4838 2804678 : }
4839 :
4840 : // if zone air mass flow balance enforced calculate the fraction of
4841 : // contribution of each mixing object to a zone mixed flow rate, BAN Feb 2014
4842 2804678 : if (state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
4843 56700 : for (auto &massConservZone : state.dataHeatBal->MassConservation) {
4844 48600 : ZoneMixingFlowSum = 0.0;
4845 48600 : int NumOfMixingObjects = massConservZone.NumReceivingZonesMixingObject;
4846 81000 : for (int Loop = 1; Loop <= NumOfMixingObjects; ++Loop) {
4847 32400 : ZoneMixingFlowSum += state.dataHeatBal->Mixing(Loop).DesignLevel;
4848 32400 : massConservZone.ZoneMixingReceivingFr(Loop) = 0.0;
4849 : }
4850 48600 : if (ZoneMixingFlowSum > 0.0) {
4851 40500 : for (int Loop = 1; Loop <= NumOfMixingObjects; ++Loop) {
4852 32400 : massConservZone.ZoneMixingReceivingFr(Loop) = state.dataHeatBal->Mixing(Loop).DesignLevel / ZoneMixingFlowSum;
4853 : }
4854 : }
4855 8100 : }
4856 : }
4857 :
4858 : // Process the scheduled CrossMixing for air heat balance
4859 2838719 : for (auto &thisCrossMix : state.dataHeatBal->CrossMixing) {
4860 34041 : thisCrossMix.DesiredAirFlowRate = thisCrossMix.DesignLevel * ScheduleManager::GetCurrentScheduleValue(state, thisCrossMix.SchedPtr);
4861 34041 : if (thisCrossMix.EMSSimpleMixingOn) thisCrossMix.DesiredAirFlowRate = thisCrossMix.EMSimpleMixingFlowRate;
4862 2804678 : }
4863 :
4864 : // Note - do each Pair a Single time, so must do increment reports for both zones
4865 : // Can't have a pair that has ZoneA zone number = NumOfZones because organized
4866 : // in input with lowest zone # first no matter how input in idf
4867 :
4868 : // Process the scheduled Refrigeration Door mixing for air heat balance
4869 2804678 : if (state.dataHeatBal->TotRefDoorMixing > 0) {
4870 40488 : for (int NZ = 1; NZ <= (state.dataGlobal->NumOfZones - 1);
4871 : ++NZ) { // Can't have %ZonePtr==NumOfZones because lesser zone # of pair placed in ZonePtr in input
4872 37596 : auto &thisRefDoor = state.dataHeatBal->RefDoorMixing(NZ);
4873 37596 : if (!thisRefDoor.RefDoorMixFlag) continue;
4874 14460 : if (thisRefDoor.ZonePtr == NZ) {
4875 17352 : for (int J = 1; J <= thisRefDoor.NumRefDoorConnections; ++J) {
4876 8676 : thisRefDoor.VolRefDoorFlowRate(J) = 0.0;
4877 8676 : if (thisRefDoor.EMSRefDoorMixingOn(J)) thisRefDoor.VolRefDoorFlowRate(J) = thisRefDoor.EMSRefDoorFlowRate(J);
4878 : }
4879 : }
4880 : }
4881 : } // TotRefDoorMixing
4882 :
4883 : // Infiltration and ventilation calculations have been moved to a subroutine of CalcAirFlowSimple in HVAC Manager
4884 : }
4885 2804678 : }
4886 :
4887 2804482 : void CalcHeatBalanceAir(EnergyPlusData &state)
4888 : {
4889 :
4890 : // PURPOSE OF THIS SUBROUTINE:
4891 : // This subroutine calculates the air component of the heat balance.
4892 :
4893 2804482 : if (state.dataGlobal->externalHVACManager) {
4894 0 : if (!state.dataGlobal->externalHVACManagerInitialized) {
4895 0 : initializeForExternalHVACManager(state);
4896 : }
4897 0 : state.dataGlobal->externalHVACManager(&state);
4898 : } else {
4899 2804482 : HVACManager::ManageHVAC(state);
4900 : }
4901 2804482 : }
4902 :
4903 : // END Algorithm Section of the Module
4904 :
4905 0 : void initializeForExternalHVACManager(EnergyPlusData &state)
4906 : {
4907 : // this function will ultimately provide a nice series of calls that initialize all the hvac stuff needed
4908 : // to allow an external hvac manager to play nice with E+
4909 0 : EnergyPlus::ZoneTempPredictorCorrector::InitZoneAirSetPoints(state);
4910 0 : }
4911 :
4912 2804482 : void ReportZoneMeanAirTemp(EnergyPlusData &state)
4913 : {
4914 : // SUBROUTINE INFORMATION:
4915 : // AUTHOR Linda Lawrie
4916 : // DATE WRITTEN July 2000
4917 :
4918 : // PURPOSE OF THIS SUBROUTINE:
4919 : // This subroutine updates the report variables for the AirHeatBalance.
4920 2804482 : if (state.dataHeatBalAirMgr->CalcExtraReportVarMyOneTimeFlag) {
4921 22338 : for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
4922 21542 : if (reqVar->name == "ZONE WETBULB GLOBE TEMPERATURE") {
4923 2 : if (reqVar->key.empty()) {
4924 7 : for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) {
4925 6 : auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(ZoneLoop);
4926 6 : thisZnAirRpt.ReportWBGT = true;
4927 : }
4928 : } else {
4929 1 : int ZoneLoop = Util::FindItemInList(Util::makeUPPER(reqVar->key), state.dataHeatBal->Zone);
4930 1 : if (ZoneLoop > 0) {
4931 1 : auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(ZoneLoop);
4932 1 : thisZnAirRpt.ReportWBGT = true;
4933 : }
4934 : }
4935 21540 : } else if (reqVar->name == "SPACE WETBULB GLOBE TEMPERATURE") {
4936 1 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
4937 1 : if (reqVar->key.empty()) {
4938 0 : for (int spaceNum = 1; spaceNum <= state.dataGlobal->numSpaces; ++spaceNum) {
4939 0 : auto &thisSpaceAirRpt = state.dataHeatBal->spaceAirRpt(spaceNum);
4940 0 : thisSpaceAirRpt.ReportWBGT = true;
4941 : }
4942 : } else {
4943 1 : int spaceNum = Util::FindItemInList(Util::makeUPPER(reqVar->key), state.dataHeatBal->space);
4944 1 : if (spaceNum > 0) {
4945 1 : auto &thisSpaceAirRpt = state.dataHeatBal->spaceAirRpt(spaceNum);
4946 1 : thisSpaceAirRpt.ReportWBGT = true;
4947 : }
4948 : }
4949 : }
4950 : }
4951 796 : }
4952 :
4953 : // EMS sensor request WBGT check
4954 2600 : for (int loop = 1; loop <= state.dataRuntimeLang->NumSensors; ++loop) {
4955 1804 : if (state.dataRuntimeLang->Sensor(loop).OutputVarName == "ZONE WETBULB GLOBE TEMPERATURE") {
4956 1 : int ZoneLoop = Util::FindItemInList(state.dataRuntimeLang->Sensor(loop).UniqueKeyName, state.dataHeatBal->Zone);
4957 1 : if (ZoneLoop > 0) {
4958 1 : auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(ZoneLoop);
4959 1 : thisZnAirRpt.ReportWBGT = true;
4960 : }
4961 1803 : } else if (state.dataRuntimeLang->Sensor(loop).OutputVarName == "SPACE WETBULB GLOBE TEMPERATURE") {
4962 1 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
4963 1 : int spaceNum = Util::FindItemInList(state.dataRuntimeLang->Sensor(loop).UniqueKeyName, state.dataHeatBal->space);
4964 1 : if (spaceNum > 0) {
4965 1 : auto &thisSpaceAirRpt = state.dataHeatBal->spaceAirRpt(spaceNum);
4966 1 : thisSpaceAirRpt.ReportWBGT = true;
4967 : }
4968 : }
4969 : }
4970 : }
4971 796 : state.dataHeatBalAirMgr->CalcExtraReportVarMyOneTimeFlag = false;
4972 : }
4973 22670650 : for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) {
4974 19866168 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop);
4975 19866168 : calcMeanAirTemps(state, thisZoneHB.ZTAV, thisZoneHB.airHumRatAvg, thisZoneHB.MRT, state.dataHeatBal->ZnAirRpt(ZoneLoop), ZoneLoop);
4976 19866168 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation) {
4977 113364 : for (int spaceNum : state.dataHeatBal->Zone(ZoneLoop).spaceIndexes) {
4978 64782 : auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum);
4979 64782 : calcMeanAirTemps(
4980 64782 : state, thisSpaceHB.ZTAV, thisSpaceHB.airHumRatAvg, thisSpaceHB.MRT, state.dataHeatBal->spaceAirRpt(spaceNum), ZoneLoop);
4981 48582 : }
4982 : }
4983 : }
4984 2804482 : }
4985 :
4986 19930950 : void calcMeanAirTemps(EnergyPlusData &state,
4987 : Real64 const ZTAV,
4988 : Real64 const airHumRatAvg,
4989 : Real64 const MRT,
4990 : DataHeatBalance::AirReportVars &thisAirRpt,
4991 : int const zoneNum)
4992 : {
4993 : // The mean air temperature is actually ZTAV which is the average
4994 : // temperature of the air temperatures at the system time step for the
4995 : // entire zone time step.
4996 19930950 : thisAirRpt.MeanAirTemp = ZTAV;
4997 19930950 : thisAirRpt.MeanAirHumRat = airHumRatAvg;
4998 19930950 : thisAirRpt.OperativeTemp = 0.5 * (ZTAV + MRT);
4999 19930950 : thisAirRpt.MeanAirDewPointTemp = Psychrometrics::PsyTdpFnWPb(state, thisAirRpt.MeanAirHumRat, state.dataEnvrn->OutBaroPress);
5000 :
5001 : // if operative temperature control is being used, then radiative fraction/weighting
5002 : // might be defined by user to be something different than 0.5, even scheduled over simulation period
5003 19930950 : if (state.dataZoneCtrls->AnyOpTempControl) { // dig further...
5004 : // find TempControlledZoneID from ZoneLoop index
5005 38520 : int TempControlledZoneID = state.dataHeatBal->Zone(zoneNum).TempControlledZoneIndex;
5006 38520 : if (state.dataHeatBal->Zone(zoneNum).IsControlled) {
5007 33114 : if ((state.dataZoneCtrls->TempControlledZone(TempControlledZoneID).OperativeTempControl)) {
5008 : Real64 thisMRTFraction; // temp working value for radiative fraction/weight
5009 : // is operative temp radiative fraction scheduled or fixed?
5010 18246 : if (state.dataZoneCtrls->TempControlledZone(TempControlledZoneID).OpTempCntrlModeScheduled) {
5011 0 : thisMRTFraction = ScheduleManager::GetCurrentScheduleValue(
5012 0 : state, state.dataZoneCtrls->TempControlledZone(TempControlledZoneID).OpTempRadiativeFractionSched);
5013 : } else {
5014 18246 : thisMRTFraction = state.dataZoneCtrls->TempControlledZone(TempControlledZoneID).FixedRadiativeFraction;
5015 : }
5016 18246 : thisAirRpt.OperativeTemp = 0.5 * (ZTAV + MRT);
5017 18246 : thisAirRpt.ThermOperativeTemp = (1.0 - thisMRTFraction) * ZTAV + thisMRTFraction * MRT;
5018 : }
5019 : }
5020 : }
5021 19930950 : if (thisAirRpt.ReportWBGT) {
5022 : // note that the WetBulbTemp here is for temporary verification, it will not be another added reporting variable
5023 32199 : thisAirRpt.WetbulbGlobeTemp =
5024 32199 : 0.7 * Psychrometrics::PsyTwbFnTdbWPb(state, ZTAV, airHumRatAvg, state.dataEnvrn->OutBaroPress) + 0.3 * thisAirRpt.OperativeTemp;
5025 : }
5026 19930950 : }
5027 :
5028 : } // namespace EnergyPlus::HeatBalanceAirManager
|