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