Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // ObjexxFCL Headers
49 : #include <ObjexxFCL/Array.functions.hh>
50 :
51 : // EnergyPlus Headers
52 : #include <EnergyPlus/Data/EnergyPlusData.hh>
53 : #include <EnergyPlus/DataHeatBalance.hh>
54 : #include <EnergyPlus/DataIPShortCuts.hh>
55 : #include <EnergyPlus/DataRoomAirModel.hh>
56 : #include <EnergyPlus/HeatBalanceManager.hh>
57 : #include <EnergyPlus/HybridModel.hh>
58 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
59 : #include <EnergyPlus/OutputProcessor.hh>
60 : #include <EnergyPlus/ScheduleManager.hh>
61 : #include <EnergyPlus/UtilityRoutines.hh>
62 :
63 : namespace EnergyPlus {
64 :
65 : namespace HybridModel {
66 :
67 : // MODULE INFORMATION:
68 : // AUTHOR Sang Hoon Lee, Tianzhen Hong, Rongpeng Zhang. LBNL
69 : // DATE WRITTEN Oct 2015
70 :
71 : // PURPOSE OF THIS MODULE:
72 : // This module manages hybrid model.
73 :
74 : // METHODOLOGY EMPLOYED:
75 : // The model uses measured zone air temperature to calculate internal thermal mass or infiltration air flow rate.
76 :
77 : // USE STATEMENTS:
78 :
79 : // Using/Aliasing
80 : using namespace DataHeatBalance;
81 :
82 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
83 :
84 : // Object Data
85 :
86 : // Functions
87 :
88 796 : void GetHybridModelZone(EnergyPlusData &state)
89 : {
90 :
91 : using ScheduleManager::GetScheduleIndex;
92 :
93 796 : bool ErrorsFound(false); // If errors detected in input
94 796 : Array1D_bool lAlphaFieldBlanks(16, false);
95 796 : Array1D_bool lNumericFieldBlanks(4, false);
96 : int NumAlphas; // Number of Alphas for each GetobjectItem call
97 : int NumNumbers; // Number of Numbers for each GetobjectItem call
98 : int IOStatus;
99 : int ZonePtr; // Pointer to the zone
100 : int ZoneListPtr; // Pointer to the zone list
101 796 : std::string CurrentModuleObject; // to assist in getting input
102 796 : Array1D_string cAlphaArgs(16); // Alpha input items for object
103 796 : Array1D_string cAlphaFieldNames(16);
104 796 : Array1D_string cNumericFieldNames(16);
105 796 : Array1D<Real64> rNumericArgs(4); // Numeric input items for object
106 796 : int HybridModelStartMonth(0); // Hybrid model start month
107 796 : int HybridModelStartDate(0); // Hybrid model start date of month
108 796 : int HybridModelEndMonth(0); // Hybrid model end month
109 796 : int HybridModelEndDate(0); // Hybrid model end date of month
110 796 : int HMStartDay(0);
111 796 : int HMEndDay(0);
112 :
113 796 : int TemperatureSchPtr(0); // Temperature schedule pointer
114 796 : int HumidityRatioSchPtr(0); // Humidity ratio schedule pointer
115 796 : int CO2ConcentrationSchPtr(0); // CO2 concentration schedule pointer
116 :
117 796 : int PeopleActivityLevelSchPtr(0); // People activity level schedule pointer
118 796 : int PeopleSensibleFractionSchPtr(0); // People sensible heat portion schedule pointer
119 796 : int PeopleRadiantFractionSchPtr(0); // People radiant heat portion (of sensible heat) schedule pointer
120 796 : int PeopleCO2GenRateSchPtr(0); // People CO2 generation rate schedule pointer
121 :
122 796 : int SupplyAirTemperatureSchPtr(0);
123 796 : int SupplyAirMassFlowRateSchPtr(0);
124 796 : int SupplyAirHumidityRatioSchPtr(0);
125 796 : int SupplyAirCO2ConcentrationSchPtr(0);
126 :
127 : // Read hybrid model input
128 796 : CurrentModuleObject = "HybridModel:Zone";
129 796 : state.dataHybridModel->NumOfHybridModelZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
130 :
131 796 : if (state.dataHybridModel->NumOfHybridModelZones > 0) {
132 3 : state.dataHybridModel->HybridModelZone.allocate(state.dataGlobal->NumOfZones);
133 13 : for (int HybridModelNum = 1; HybridModelNum <= state.dataHybridModel->NumOfHybridModelZones; ++HybridModelNum) {
134 :
135 10 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
136 : CurrentModuleObject,
137 : HybridModelNum,
138 : cAlphaArgs,
139 : NumAlphas,
140 : rNumericArgs,
141 : NumNumbers,
142 : IOStatus,
143 : lNumericFieldBlanks,
144 : lAlphaFieldBlanks,
145 : cAlphaFieldNames,
146 : cNumericFieldNames);
147 :
148 10 : ZoneListPtr = 0;
149 10 : ZonePtr = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); // "Zone" is a 1D array, cAlphaArgs(2) is the zone name
150 10 : if (ZonePtr == 0 && state.dataHeatBal->NumOfZoneLists > 0)
151 0 : ZoneListPtr = Util::FindItemInList(cAlphaArgs(2), state.dataHeatBal->ZoneList);
152 10 : if (ZonePtr > 0) {
153 10 : state.dataHybridModel->HybridModelZone(ZonePtr).Name = cAlphaArgs(1); // Zone HybridModel name
154 10 : state.dataHybridModel->FlagHybridModel_TM = Util::SameString(cAlphaArgs(3), "Yes"); // Calculate thermal mass option
155 10 : state.dataHybridModel->FlagHybridModel_AI = Util::SameString(cAlphaArgs(4), "Yes"); // Calculate infiltration rate option
156 10 : state.dataHybridModel->FlagHybridModel_PC = Util::SameString(cAlphaArgs(5), "Yes"); // Calculate people count option
157 :
158 : // Pointers used to help decide which unknown parameter to solve
159 : // Zone Air Infiltration Rate and Zone Internal Thermal Mass calculations cannot be performed simultaneously
160 10 : TemperatureSchPtr = GetScheduleIndex(state, cAlphaArgs(6));
161 10 : HumidityRatioSchPtr = GetScheduleIndex(state, cAlphaArgs(7));
162 10 : CO2ConcentrationSchPtr = GetScheduleIndex(state, cAlphaArgs(8));
163 :
164 : // Not used for now
165 10 : PeopleActivityLevelSchPtr = GetScheduleIndex(state, cAlphaArgs(9));
166 10 : PeopleSensibleFractionSchPtr = GetScheduleIndex(state, cAlphaArgs(10));
167 10 : PeopleRadiantFractionSchPtr = GetScheduleIndex(state, cAlphaArgs(11));
168 10 : PeopleCO2GenRateSchPtr = GetScheduleIndex(state, cAlphaArgs(12));
169 :
170 : // Pointers used to help decide wheather to include system supply terms in the inverse algorithms
171 10 : SupplyAirTemperatureSchPtr = GetScheduleIndex(state, cAlphaArgs(13));
172 10 : SupplyAirMassFlowRateSchPtr = GetScheduleIndex(state, cAlphaArgs(14));
173 10 : SupplyAirHumidityRatioSchPtr = GetScheduleIndex(state, cAlphaArgs(15));
174 10 : SupplyAirCO2ConcentrationSchPtr = GetScheduleIndex(state, cAlphaArgs(16));
175 :
176 : // Note: Internal thermal mass can be calculated only with measured temperature.
177 : // Air infiltration rate can be calculated with either measured temperature, humifity ratio, or CO2
178 : // concentration. People count can be calculated with either measured temperature, humifity ratio, or CO2
179 : // concentration.
180 :
181 : // Initially set all flags to be false
182 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T = false;
183 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T = false;
184 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H = false;
185 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C = false;
186 10 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T = false;
187 10 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H = false;
188 10 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C = false;
189 :
190 : // Scenario 1: Only one unknown parameter to solve
191 : // Scenario 1-1: To solve thermal mass
192 10 : if (state.dataHybridModel->FlagHybridModel_TM) {
193 3 : if (state.dataHybridModel->FlagHybridModel_AI) {
194 0 : ShowSevereError(state,
195 0 : format("Field \"{} and {}\" cannot be both set to YES.", cAlphaFieldNames(3), cAlphaFieldNames(4)));
196 0 : ErrorsFound = true;
197 : }
198 :
199 3 : if (state.dataHybridModel->FlagHybridModel_PC) {
200 0 : ShowSevereError(state,
201 0 : format("Field \"{} and {}\" cannot be both set to YES.", cAlphaFieldNames(3), cAlphaFieldNames(5)));
202 0 : ErrorsFound = true;
203 : }
204 :
205 3 : if (TemperatureSchPtr == 0) {
206 0 : ShowSevereError(state, format("Measured Zone Air Tempearture Schedule is not defined for: {}", CurrentModuleObject));
207 0 : ErrorsFound = true;
208 : } else {
209 3 : state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T = true;
210 : }
211 : }
212 :
213 : // Scenario 1-2: To solve infiltration rate
214 10 : if (state.dataHybridModel->FlagHybridModel_AI) {
215 4 : if (state.dataHybridModel->FlagHybridModel_PC) {
216 0 : ShowSevereError(state,
217 0 : format("Field \"{}\" and \"{}\" cannot be both set to YES.", cAlphaFieldNames(4), cAlphaFieldNames(5)));
218 0 : ErrorsFound = true;
219 : }
220 4 : if (TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0 && CO2ConcentrationSchPtr == 0) {
221 : // Show fatal error if no measurement schedule is provided
222 0 : ShowSevereError(state, format("No measured envrionmental parameter is provided for: {}", CurrentModuleObject));
223 0 : ShowContinueError(state,
224 0 : format("One of the field \"{}\", \"{}\", or {}\" must be provided for the HybridModel:Zone.",
225 : cAlphaFieldNames(6),
226 : cAlphaFieldNames(7),
227 : cAlphaFieldNames(8)));
228 0 : ErrorsFound = true;
229 : } else {
230 4 : if (TemperatureSchPtr > 0 && !state.dataHybridModel->FlagHybridModel_TM) {
231 : // Temperature schedule is provided, igonore humidity ratio and CO2 concentration schedules.
232 2 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T = true;
233 2 : if (HumidityRatioSchPtr > 0) {
234 0 : ShowWarningError(state, format("Field \"{}\" is provided.", cAlphaFieldNames(6)));
235 0 : ShowContinueError(state, format("Field \"{}\" will not be used.", cAlphaFieldNames(7)));
236 : }
237 2 : if (CO2ConcentrationSchPtr > 0) {
238 0 : ShowWarningError(state, format("Field \"{}\" is provided.", cAlphaFieldNames(6)));
239 0 : ShowContinueError(state, format("Field \"{}\" will not be used.", cAlphaFieldNames(8)));
240 : }
241 : }
242 4 : if (HumidityRatioSchPtr > 0 && TemperatureSchPtr == 0) {
243 : // Humidity ratio schedule is provided, ignore CO2 concentration schedule.
244 1 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H = true;
245 1 : if (CO2ConcentrationSchPtr > 0) {
246 0 : ShowWarningError(state, format("Field \"{}\" is provided.", cAlphaFieldNames(7)));
247 0 : ShowContinueError(state, format("Field \"{}\" will not be used.", cAlphaFieldNames(8)));
248 : }
249 : }
250 4 : if (CO2ConcentrationSchPtr > 0 && TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0) {
251 : // Only CO2 concentration schedule is provided.
252 1 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C = true;
253 : }
254 : }
255 : }
256 :
257 : // Scenario 1-3: To solve people count
258 10 : if (state.dataHybridModel->FlagHybridModel_PC) {
259 3 : if (TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0 && CO2ConcentrationSchPtr == 0) {
260 : // Show fatal error if no measurement schedule is provided
261 0 : ShowSevereError(state, format("No measured envrionmental parameter is provided for: {}", CurrentModuleObject));
262 0 : ShowContinueError(state,
263 0 : format("One of the field \"{}\", \"{}\", or {}\" must be provided for the HybridModel:Zone.",
264 : cAlphaFieldNames(6),
265 : cAlphaFieldNames(7),
266 : cAlphaFieldNames(8)));
267 0 : ErrorsFound = true;
268 : } else {
269 3 : if (TemperatureSchPtr > 0 && !state.dataHybridModel->FlagHybridModel_TM) {
270 : // Temperature schedule is provided, igonore humidity ratio and CO2 concentration schedules.
271 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T = true;
272 1 : if (HumidityRatioSchPtr > 0) {
273 0 : ShowWarningError(
274 : state,
275 : "The meausured air humidity ratio schedule will not be used since measured air temperature is provided.");
276 : }
277 1 : if (CO2ConcentrationSchPtr > 0) {
278 0 : ShowWarningError(
279 : state,
280 : "The meausured air CO2 concentration schedule will not be used since measured air temperature is provided.");
281 : }
282 : }
283 3 : if (HumidityRatioSchPtr > 0 && TemperatureSchPtr == 0) {
284 : // Humidity ratio schedule is provided, ignore CO2 concentration schedule.
285 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H = true;
286 1 : if (CO2ConcentrationSchPtr > 0) {
287 0 : ShowWarningError(state,
288 : "The meausured air CO2 concentration schedule will not be used since measured air humidity "
289 : "ratio is provided.");
290 : }
291 : }
292 3 : if (CO2ConcentrationSchPtr > 0 && TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0) {
293 : // Only CO2 concentration schedule is provided.
294 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C = true;
295 : }
296 : }
297 : }
298 :
299 : // Decide if system supply terms are valid to be included in the inverse solution
300 10 : if (SupplyAirTemperatureSchPtr > 0 && SupplyAirMassFlowRateSchPtr > 0 && SupplyAirHumidityRatioSchPtr) {
301 0 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
302 0 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T) {
303 0 : state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters = true;
304 : } else {
305 0 : ShowWarningError(state,
306 0 : format("Field \"{}\", {}, and \"{}\" will not be used in the inverse balance euqation.",
307 : cAlphaFieldNames(13),
308 : cAlphaFieldNames(14),
309 : cAlphaFieldNames(15)));
310 : }
311 : }
312 :
313 10 : if (SupplyAirHumidityRatioSchPtr && SupplyAirMassFlowRateSchPtr > 0) {
314 2 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
315 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H) {
316 1 : state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters = true;
317 : } else {
318 0 : ShowWarningError(state,
319 0 : format("Field \"{}\" and \"{}\" will not be used in the inverse balance euqation.",
320 : cAlphaFieldNames(15),
321 : cAlphaFieldNames(14)));
322 : }
323 : }
324 :
325 10 : if (SupplyAirCO2ConcentrationSchPtr > 0 && SupplyAirMassFlowRateSchPtr > 0) {
326 2 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C ||
327 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
328 1 : state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters = true;
329 : } else {
330 0 : ShowWarningError(state,
331 0 : format("Field \"{}\" and \"{}\" will not be used in the inverse balance euqation.",
332 : cAlphaFieldNames(16),
333 : cAlphaFieldNames(14)));
334 : }
335 : }
336 :
337 : // Flags showing Hybrid Modeling settings
338 20 : state.dataHybridModel->FlagHybridModel = state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T ||
339 7 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
340 5 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
341 4 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C ||
342 3 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T ||
343 18 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H ||
344 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C;
345 :
346 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T ||
347 15 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
348 5 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T) {
349 6 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureSchedulePtr = GetScheduleIndex(state, cAlphaArgs(6));
350 : }
351 :
352 19 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
353 9 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H) {
354 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredHumidityRatioSchedulePtr = GetScheduleIndex(state, cAlphaArgs(7));
355 : }
356 :
357 19 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C ||
358 9 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
359 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredCO2ConcentrationSchedulePtr =
360 2 : GetScheduleIndex(state, cAlphaArgs(8));
361 : }
362 :
363 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters) {
364 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirTemperatureSchedulePtr = GetScheduleIndex(state, cAlphaArgs(13));
365 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirMassFlowRateSchedulePtr =
366 2 : GetScheduleIndex(state, cAlphaArgs(14));
367 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirHumidityRatioSchedulePtr =
368 2 : GetScheduleIndex(state, cAlphaArgs(15));
369 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirCO2ConcentrationSchedulePtr =
370 2 : GetScheduleIndex(state, cAlphaArgs(16));
371 : }
372 :
373 : // Get optional people related schedules
374 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T ||
375 18 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H ||
376 8 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
377 3 : if (PeopleActivityLevelSchPtr > 0) {
378 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleActivityLevelSchedulePtr =
379 3 : GetScheduleIndex(state, cAlphaArgs(9));
380 : } else {
381 0 : ShowWarningError(
382 : state,
383 0 : format("Field \"{}\": default people activity level is not provided, default value of 130W/person will be used.",
384 : cAlphaFieldNames(9)));
385 : }
386 3 : if (PeopleSensibleFractionSchPtr > 0) {
387 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleSensibleFractionSchedulePtr =
388 3 : GetScheduleIndex(state, cAlphaArgs(10));
389 : } else {
390 0 : ShowWarningError(
391 : state,
392 0 : format("Field \"{}\": default people sensible heat rate is not provided, default value of 0.6 will be used.",
393 : cAlphaFieldNames(10)));
394 : }
395 3 : if (PeopleRadiantFractionSchPtr > 0) {
396 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleRadiationFractionSchedulePtr =
397 3 : GetScheduleIndex(state, cAlphaArgs(11));
398 : } else {
399 0 : ShowWarningError(state,
400 0 : format("Field \"{}\": default people radiant heat portion (of sensible heat) is not provided, default "
401 : "value of 0.7 will be used.",
402 : cAlphaFieldNames(11)));
403 : }
404 3 : if (PeopleCO2GenRateSchPtr > 0) {
405 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleCO2GenRateSchedulePtr = GetScheduleIndex(state, cAlphaArgs(12));
406 : } else {
407 0 : ShowWarningError(state,
408 0 : format("Field \"{}\": default people CO2 generation rate is not provided, default value of 0.0000000382 "
409 : "kg/W will be used.",
410 : cAlphaFieldNames(12)));
411 : }
412 : }
413 :
414 10 : if (state.dataHybridModel->FlagHybridModel) {
415 : // prepare start and end date for Hybrid Modeling
416 10 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartMonth = rNumericArgs(1);
417 10 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartDate = rNumericArgs(2);
418 10 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndMonth = rNumericArgs(3);
419 10 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndDate = rNumericArgs(4);
420 : {
421 10 : int HMDayArr[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
422 :
423 10 : HybridModelStartMonth = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartMonth;
424 10 : HybridModelStartDate = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartDate;
425 10 : HybridModelEndMonth = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndMonth;
426 10 : HybridModelEndDate = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndDate;
427 :
428 10 : if (HybridModelStartMonth >= 1 && HybridModelStartMonth <= 12) {
429 10 : HMStartDay = HMDayArr[HybridModelStartMonth - 1];
430 : } else {
431 0 : HMStartDay = 0;
432 : }
433 :
434 10 : if (HybridModelEndMonth >= 1 && HybridModelEndMonth <= 12) {
435 10 : HMEndDay = HMDayArr[HybridModelEndMonth - 1];
436 : } else {
437 0 : HMEndDay = 0;
438 : }
439 :
440 10 : state.dataHybridModel->HybridModelZone(ZonePtr).HybridStartDayOfYear = HMStartDay + HybridModelStartDate;
441 10 : state.dataHybridModel->HybridModelZone(ZonePtr).HybridEndDayOfYear = HMEndDay + HybridModelEndDate;
442 : }
443 : }
444 :
445 : // Output variable
446 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
447 17 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
448 7 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C) {
449 8 : SetupOutputVariable(state,
450 : "Zone Infiltration Hybrid Model Air Change Rate",
451 : Constant::Units::ach,
452 4 : state.dataHeatBal->Zone(ZonePtr).InfilOAAirChangeRateHM,
453 : OutputProcessor::TimeStepType::Zone,
454 : OutputProcessor::StoreType::Average,
455 4 : state.dataHeatBal->Zone(ZonePtr).Name);
456 8 : SetupOutputVariable(state,
457 : "Zone Infiltration Hybrid Model Mass Flow Rate",
458 : Constant::Units::kg_s,
459 4 : state.dataHeatBal->Zone(ZonePtr).MCPIHM,
460 : OutputProcessor::TimeStepType::Zone,
461 : OutputProcessor::StoreType::Average,
462 4 : state.dataHeatBal->Zone(ZonePtr).Name);
463 : }
464 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T ||
465 18 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H ||
466 8 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
467 6 : SetupOutputVariable(state,
468 : "Zone Hybrid Model People Count",
469 : Constant::Units::None,
470 3 : state.dataHeatBal->Zone(ZonePtr).NumOccHM,
471 : OutputProcessor::TimeStepType::Zone,
472 : OutputProcessor::StoreType::Average,
473 3 : state.dataHeatBal->Zone(ZonePtr).Name);
474 : }
475 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T) {
476 6 : SetupOutputVariable(state,
477 : "Zone Hybrid Model Thermal Mass Multiplier",
478 : Constant::Units::None,
479 3 : state.dataHeatBal->Zone(ZonePtr).ZoneVolCapMultpSensHM,
480 : OutputProcessor::TimeStepType::Zone,
481 : OutputProcessor::StoreType::Average,
482 3 : state.dataHeatBal->Zone(ZonePtr).Name);
483 : }
484 : } else {
485 0 : ShowSevereError(
486 : state,
487 0 : format("{}=\"{}\" invalid {}=\"{}\" not found.", CurrentModuleObject, cAlphaArgs(1), cAlphaFieldNames(2), cAlphaArgs(2)));
488 0 : ErrorsFound = true;
489 : }
490 : }
491 :
492 : // ZoneAirMassFlowConservation should not be activated during the Hybrid Modeling infiltration calculations
493 3 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T && state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
494 0 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = false;
495 0 : ShowWarningError(state, "ZoneAirMassFlowConservation is deactivated when Hybrid Modeling is performed.");
496 : }
497 :
498 : // RoomAirModelType should be Mixing if Hybrid Modeling is performed for the zone
499 3 : if (state.dataHybridModel->FlagHybridModel) {
500 15 : for (ZonePtr = 1; ZonePtr <= state.dataGlobal->NumOfZones; ZonePtr++) {
501 12 : if ((state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T ||
502 17 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T) &&
503 5 : (state.dataRoomAir->AirModel(ZonePtr).AirModel != RoomAir::RoomAirModel::Mixing)) {
504 0 : state.dataRoomAir->AirModel(ZonePtr).AirModel = RoomAir::RoomAirModel::Mixing;
505 0 : ShowWarningError(state, "Room Air Model Type should be Mixing if Hybrid Modeling is performed for the zone.");
506 : }
507 : }
508 3 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) {
509 0 : ShowSevereError(state, "Hybrid Modeling is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance.");
510 0 : ErrorsFound = true;
511 : }
512 : }
513 :
514 3 : if (ErrorsFound) {
515 0 : ShowFatalError(state, "Errors getting Hybrid Model input data. Preceding condition(s) cause termination.");
516 : }
517 : }
518 796 : }
519 :
520 : // Needed for unit tests, should not be normally called.
521 :
522 : } // namespace HybridModel
523 :
524 : } // namespace EnergyPlus
|