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 : // 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 : using namespace DataRoomAirModel;
82 :
83 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
84 :
85 : // Object Data
86 :
87 : // Functions
88 :
89 771 : void GetHybridModelZone(EnergyPlusData &state)
90 : {
91 :
92 : using ScheduleManager::GetScheduleIndex;
93 :
94 771 : bool ErrorsFound(false); // If errors detected in input
95 1542 : Array1D_bool lAlphaFieldBlanks(16, false);
96 1542 : Array1D_bool lNumericFieldBlanks(4, false);
97 : int NumAlphas; // Number of Alphas for each GetobjectItem call
98 : int NumNumbers; // Number of Numbers for each GetobjectItem call
99 : int IOStatus;
100 : int ZonePtr; // Pointer to the zone
101 : int ZoneListPtr; // Pointer to the zone list
102 1542 : std::string CurrentModuleObject; // to assist in getting input
103 1542 : Array1D_string cAlphaArgs(16); // Alpha input items for object
104 1542 : Array1D_string cAlphaFieldNames(16);
105 1542 : Array1D_string cNumericFieldNames(16);
106 1542 : Array1D<Real64> rNumericArgs(4); // Numeric input items for object
107 771 : int HybridModelStartMonth(0); // Hybrid model start month
108 771 : int HybridModelStartDate(0); // Hybrid model start date of month
109 771 : int HybridModelEndMonth(0); // Hybrid model end month
110 771 : int HybridModelEndDate(0); // Hybrid model end date of month
111 771 : int HMStartDay(0);
112 771 : int HMEndDay(0);
113 :
114 771 : int TemperatureSchPtr(0); // Temperature schedule pointer
115 771 : int HumidityRatioSchPtr(0); // Humidity ratio schedule pointer
116 771 : int CO2ConcentrationSchPtr(0); // CO2 concentration schedule pointer
117 :
118 771 : int PeopleActivityLevelSchPtr(0); // People activity level schedule pointer
119 771 : int PeopleSensibleFractionSchPtr(0); // People sensible heat portion schedule pointer
120 771 : int PeopleRadiantFractionSchPtr(0); // People radiant heat portion (of sensible heat) schedule pointer
121 771 : int PeopleCO2GenRateSchPtr(0); // People CO2 generation rate schedule pointer
122 :
123 771 : int SupplyAirTemperatureSchPtr(0);
124 771 : int SupplyAirMassFlowRateSchPtr(0);
125 771 : int SupplyAirHumidityRatioSchPtr(0);
126 771 : int SupplyAirCO2ConcentrationSchPtr(0);
127 :
128 : // Read hybrid model input
129 771 : CurrentModuleObject = "HybridModel:Zone";
130 771 : state.dataHybridModel->NumOfHybridModelZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
131 :
132 771 : if (state.dataHybridModel->NumOfHybridModelZones > 0) {
133 3 : state.dataHybridModel->HybridModelZone.allocate(state.dataGlobal->NumOfZones);
134 13 : for (int HybridModelNum = 1; HybridModelNum <= state.dataHybridModel->NumOfHybridModelZones; ++HybridModelNum) {
135 :
136 10 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
137 : CurrentModuleObject,
138 : HybridModelNum,
139 : cAlphaArgs,
140 : NumAlphas,
141 : rNumericArgs,
142 : NumNumbers,
143 : IOStatus,
144 : lNumericFieldBlanks,
145 : lAlphaFieldBlanks,
146 : cAlphaFieldNames,
147 : cNumericFieldNames);
148 :
149 10 : ZoneListPtr = 0;
150 10 : ZonePtr =
151 10 : UtilityRoutines::FindItemInList(cAlphaArgs(2), state.dataHeatBal->Zone); // "Zone" is a 1D array, cAlphaArgs(2) is the zone name
152 10 : if (ZonePtr == 0 && state.dataHeatBal->NumOfZoneLists > 0)
153 0 : ZoneListPtr = UtilityRoutines::FindItemInList(cAlphaArgs(2), state.dataHeatBal->ZoneList);
154 10 : if (ZonePtr > 0) {
155 10 : state.dataHybridModel->HybridModelZone(ZonePtr).Name = cAlphaArgs(1); // Zone HybridModel name
156 10 : state.dataHybridModel->FlagHybridModel_TM = UtilityRoutines::SameString(cAlphaArgs(3), "Yes"); // Calculate thermal mass option
157 10 : state.dataHybridModel->FlagHybridModel_AI =
158 20 : UtilityRoutines::SameString(cAlphaArgs(4), "Yes"); // Calculate infiltration rate option
159 10 : state.dataHybridModel->FlagHybridModel_PC = UtilityRoutines::SameString(cAlphaArgs(5), "Yes"); // Calculate people count option
160 :
161 : // Pointers used to help decide which unknown parameter to solve
162 : // Zone Air Infiltration Rate and Zone Internal Thermal Mass calculations cannot be performed simultaneously
163 10 : TemperatureSchPtr = GetScheduleIndex(state, cAlphaArgs(6));
164 10 : HumidityRatioSchPtr = GetScheduleIndex(state, cAlphaArgs(7));
165 10 : CO2ConcentrationSchPtr = GetScheduleIndex(state, cAlphaArgs(8));
166 :
167 : // Not used for now
168 10 : PeopleActivityLevelSchPtr = GetScheduleIndex(state, cAlphaArgs(9));
169 10 : PeopleSensibleFractionSchPtr = GetScheduleIndex(state, cAlphaArgs(10));
170 10 : PeopleRadiantFractionSchPtr = GetScheduleIndex(state, cAlphaArgs(11));
171 10 : PeopleCO2GenRateSchPtr = GetScheduleIndex(state, cAlphaArgs(12));
172 :
173 : // Pointers used to help decide wheather to include system supply terms in the inverse algorithms
174 10 : SupplyAirTemperatureSchPtr = GetScheduleIndex(state, cAlphaArgs(13));
175 10 : SupplyAirMassFlowRateSchPtr = GetScheduleIndex(state, cAlphaArgs(14));
176 10 : SupplyAirHumidityRatioSchPtr = GetScheduleIndex(state, cAlphaArgs(15));
177 10 : SupplyAirCO2ConcentrationSchPtr = GetScheduleIndex(state, cAlphaArgs(16));
178 :
179 : // Note: Internal thermal mass can be calculated only with measured temperature.
180 : // Air infiltration rate can be calculated with either measured temperature, humifity ratio, or CO2
181 : // concentration. People count can be calculated with either measured temperature, humifity ratio, or CO2
182 : // concentration.
183 :
184 : // Initially set all flags to be false
185 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T = false;
186 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T = false;
187 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H = false;
188 10 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C = false;
189 10 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T = false;
190 10 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H = false;
191 10 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C = false;
192 :
193 : // Scenario 1: Only one unknown parameter to solve
194 : // Scenario 1-1: To solve thermal mass
195 10 : if (state.dataHybridModel->FlagHybridModel_TM) {
196 2 : if (state.dataHybridModel->FlagHybridModel_AI) {
197 0 : ShowSevereError(state,
198 0 : "Field \"" + cAlphaFieldNames(3) + " and " + cAlphaFieldNames(4) + "\" cannot be both set to YES.");
199 0 : ErrorsFound = true;
200 : }
201 :
202 2 : if (state.dataHybridModel->FlagHybridModel_PC) {
203 0 : ShowSevereError(state,
204 0 : "Field \"" + cAlphaFieldNames(3) + " and " + cAlphaFieldNames(5) + "\" cannot be both set to YES.");
205 0 : ErrorsFound = true;
206 : }
207 :
208 2 : if (TemperatureSchPtr == 0) {
209 0 : ShowSevereError(state, "Measured Zone Air Tempearture Schedule is not defined for: " + CurrentModuleObject);
210 0 : ErrorsFound = true;
211 : } else {
212 2 : state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T = true;
213 : }
214 : }
215 :
216 : // Scenario 1-2: To solve infiltration rate
217 10 : if (state.dataHybridModel->FlagHybridModel_AI) {
218 4 : if (state.dataHybridModel->FlagHybridModel_PC) {
219 0 : ShowSevereError(state,
220 0 : "Field \"" + cAlphaFieldNames(4) + "\" and \"" + cAlphaFieldNames(5) + "\" cannot be both set to YES.");
221 0 : ErrorsFound = true;
222 : }
223 4 : if (TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0 && CO2ConcentrationSchPtr == 0) {
224 : // Show fatal error if no measurement schedule is provided
225 0 : ShowSevereError(state, "No measured envrionmental parameter is provided for: " + CurrentModuleObject);
226 0 : ShowContinueError(state,
227 0 : "One of the field \"" + cAlphaFieldNames(6) + "\", \"" + cAlphaFieldNames(7) + "\", or " +
228 0 : cAlphaFieldNames(8) + "\" must be provided for the HybridModel:Zone.");
229 0 : ErrorsFound = true;
230 : } else {
231 4 : if (TemperatureSchPtr > 0 && !state.dataHybridModel->FlagHybridModel_TM) {
232 : // Temperature schedule is provided, igonore humidity ratio and CO2 concentration schedules.
233 2 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T = true;
234 2 : if (HumidityRatioSchPtr > 0) {
235 0 : ShowWarningError(state, "Field \"" + cAlphaFieldNames(6) + "\" is provided.");
236 0 : ShowContinueError(state, "Field \"" + cAlphaFieldNames(7) + "\" will not be used.");
237 : }
238 2 : if (CO2ConcentrationSchPtr > 0) {
239 0 : ShowWarningError(state, "Field \"" + cAlphaFieldNames(6) + "\" is provided.");
240 0 : ShowContinueError(state, "Field \"" + cAlphaFieldNames(8) + "\" will not be used.");
241 : }
242 : }
243 4 : if (HumidityRatioSchPtr > 0 && TemperatureSchPtr == 0) {
244 : // Humidity ratio schedule is provided, ignore CO2 concentration schedule.
245 1 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H = true;
246 1 : if (CO2ConcentrationSchPtr > 0) {
247 0 : ShowWarningError(state, "Field \"" + cAlphaFieldNames(7) + "\" is provided.");
248 0 : ShowContinueError(state, "Field \"" + cAlphaFieldNames(8) + "\" will not be used.");
249 : }
250 : }
251 4 : if (CO2ConcentrationSchPtr > 0 && TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0) {
252 : // Only CO2 concentration schedule is provided.
253 1 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C = true;
254 : }
255 : }
256 : }
257 :
258 : // Scenario 1-3: To solve people count
259 10 : if (state.dataHybridModel->FlagHybridModel_PC) {
260 3 : if (TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0 && CO2ConcentrationSchPtr == 0) {
261 : // Show fatal error if no measurement schedule is provided
262 0 : ShowSevereError(state, "No measured envrionmental parameter is provided for: " + CurrentModuleObject);
263 0 : ShowContinueError(state,
264 0 : "One of the field \"" + cAlphaFieldNames(6) + "\", \"" + cAlphaFieldNames(7) + "\", or " +
265 0 : cAlphaFieldNames(8) + "\" must be provided for the HybridModel:Zone.");
266 0 : ErrorsFound = true;
267 : } else {
268 3 : if (TemperatureSchPtr > 0 && !state.dataHybridModel->FlagHybridModel_TM) {
269 : // Temperature schedule is provided, igonore humidity ratio and CO2 concentration schedules.
270 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T = true;
271 1 : if (HumidityRatioSchPtr > 0) {
272 0 : ShowWarningError(
273 : state,
274 : "The meausured air humidity ratio schedule will not be used since measured air temperature is provided.");
275 : }
276 1 : if (CO2ConcentrationSchPtr > 0) {
277 0 : ShowWarningError(
278 : state,
279 : "The meausured air CO2 concentration schedule will not be used since measured air temperature is provided.");
280 : }
281 : }
282 3 : if (HumidityRatioSchPtr > 0 && TemperatureSchPtr == 0) {
283 : // Humidity ratio schedule is provided, ignore CO2 concentration schedule.
284 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H = true;
285 1 : if (CO2ConcentrationSchPtr > 0) {
286 0 : ShowWarningError(state,
287 : "The meausured air CO2 concentration schedule will not be used since measured air humidity "
288 : "ratio is provided.");
289 : }
290 : }
291 3 : if (CO2ConcentrationSchPtr > 0 && TemperatureSchPtr == 0 && HumidityRatioSchPtr == 0) {
292 : // Only CO2 concentration schedule is provided.
293 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C = true;
294 : }
295 : }
296 : }
297 :
298 : // Decide if system supply terms are valid to be included in the inverse solution
299 10 : if (SupplyAirTemperatureSchPtr > 0 && SupplyAirMassFlowRateSchPtr > 0 && SupplyAirHumidityRatioSchPtr) {
300 0 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
301 0 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T) {
302 0 : state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters = true;
303 : } else {
304 0 : ShowWarningError(state,
305 0 : "Field \"" + cAlphaFieldNames(13) + "\", " + cAlphaFieldNames(14) + ", and \"" + cAlphaFieldNames(15) +
306 : "\" will not be used in the inverse balance euqation.");
307 : }
308 : }
309 :
310 10 : if (SupplyAirHumidityRatioSchPtr && SupplyAirMassFlowRateSchPtr > 0) {
311 2 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
312 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H) {
313 1 : state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters = true;
314 : } else {
315 0 : ShowWarningError(state,
316 0 : "Field \"" + cAlphaFieldNames(15) + "\" and \"" + cAlphaFieldNames(14) +
317 : "\" will not be used in the inverse balance euqation.");
318 : }
319 : }
320 :
321 10 : if (SupplyAirCO2ConcentrationSchPtr > 0 && SupplyAirMassFlowRateSchPtr > 0) {
322 2 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C ||
323 1 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
324 1 : state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters = true;
325 : } else {
326 0 : ShowWarningError(state,
327 0 : "Field \"" + cAlphaFieldNames(16) + "\" and \"" + cAlphaFieldNames(14) +
328 : "\" will not be used in the inverse balance euqation.");
329 : }
330 : }
331 :
332 : // Flags showing Hybrid Modeling settings
333 28 : state.dataHybridModel->FlagHybridModel = state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T ||
334 14 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
335 11 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
336 9 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C ||
337 7 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T ||
338 15 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H ||
339 2 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C;
340 :
341 28 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T ||
342 16 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
343 6 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T) {
344 5 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureSchedulePtr = GetScheduleIndex(state, cAlphaArgs(6));
345 : }
346 :
347 19 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
348 9 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H) {
349 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredHumidityRatioSchedulePtr = GetScheduleIndex(state, cAlphaArgs(7));
350 : }
351 :
352 19 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C ||
353 9 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
354 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredCO2ConcentrationSchedulePtr =
355 2 : GetScheduleIndex(state, cAlphaArgs(8));
356 : }
357 :
358 10 : if (state.dataHybridModel->HybridModelZone(ZonePtr).IncludeSystemSupplyParameters) {
359 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirTemperatureSchedulePtr = GetScheduleIndex(state, cAlphaArgs(13));
360 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirMassFlowRateSchedulePtr =
361 2 : GetScheduleIndex(state, cAlphaArgs(14));
362 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirHumidityRatioSchedulePtr =
363 2 : GetScheduleIndex(state, cAlphaArgs(15));
364 2 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneSupplyAirCO2ConcentrationSchedulePtr =
365 2 : GetScheduleIndex(state, cAlphaArgs(16));
366 : }
367 :
368 : // Get optional people related schedules
369 29 : if (state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T ||
370 18 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H ||
371 8 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
372 3 : if (PeopleActivityLevelSchPtr > 0) {
373 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleActivityLevelSchedulePtr =
374 3 : GetScheduleIndex(state, cAlphaArgs(9));
375 : } else {
376 0 : ShowWarningError(state,
377 0 : "Field \"" + cAlphaFieldNames(9) +
378 : "\": default people activity level is not provided, default value of 130W/person will be used.");
379 : }
380 3 : if (PeopleSensibleFractionSchPtr > 0) {
381 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleSensibleFractionSchedulePtr =
382 3 : GetScheduleIndex(state, cAlphaArgs(10));
383 : } else {
384 0 : ShowWarningError(state,
385 0 : "Field \"" + cAlphaFieldNames(10) +
386 : "\": default people sensible heat rate is not provided, default value of 0.6 will be used.");
387 : }
388 3 : if (PeopleRadiantFractionSchPtr > 0) {
389 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleRadiationFractionSchedulePtr =
390 3 : GetScheduleIndex(state, cAlphaArgs(11));
391 : } else {
392 0 : ShowWarningError(
393 : state,
394 0 : "Field \"" + cAlphaFieldNames(11) +
395 : "\": default people radiant heat portion (of sensible heat) is not provided, default value of 0.7 will be used.");
396 : }
397 3 : if (PeopleCO2GenRateSchPtr > 0) {
398 3 : state.dataHybridModel->HybridModelZone(ZonePtr).ZonePeopleCO2GenRateSchedulePtr = GetScheduleIndex(state, cAlphaArgs(12));
399 : } else {
400 0 : ShowWarningError(
401 : state,
402 0 : "Field \"" + cAlphaFieldNames(12) +
403 : "\": default people CO2 generation rate is not provided, default value of 0.0000000382 kg/W will be used.");
404 : }
405 : }
406 :
407 10 : if (state.dataHybridModel->FlagHybridModel) {
408 : // prepare start and end date for Hybrid Modeling
409 9 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartMonth = rNumericArgs(1);
410 9 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartDate = rNumericArgs(2);
411 9 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndMonth = rNumericArgs(3);
412 9 : state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndDate = rNumericArgs(4);
413 : {
414 9 : int HMDayArr[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
415 :
416 9 : HybridModelStartMonth = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartMonth;
417 9 : HybridModelStartDate = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureStartDate;
418 9 : HybridModelEndMonth = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndMonth;
419 9 : HybridModelEndDate = state.dataHybridModel->HybridModelZone(ZonePtr).ZoneMeasuredTemperatureEndDate;
420 :
421 9 : if (HybridModelStartMonth >= 1 && HybridModelStartMonth <= 12) {
422 9 : HMStartDay = HMDayArr[HybridModelStartMonth - 1];
423 : } else {
424 0 : HMStartDay = 0;
425 : }
426 :
427 9 : if (HybridModelEndMonth >= 1 && HybridModelEndMonth <= 12) {
428 9 : HMEndDay = HMDayArr[HybridModelEndMonth - 1];
429 : } else {
430 0 : HMEndDay = 0;
431 : }
432 :
433 9 : state.dataHybridModel->HybridModelZone(ZonePtr).HybridStartDayOfYear = HMStartDay + HybridModelStartDate;
434 9 : state.dataHybridModel->HybridModelZone(ZonePtr).HybridEndDayOfYear = HMEndDay + HybridModelEndDate;
435 : }
436 : }
437 :
438 : // Output variable
439 28 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T ||
440 17 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_H ||
441 7 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_C) {
442 16 : SetupOutputVariable(state,
443 : "Zone Infiltration Hybrid Model Air Change Rate",
444 : OutputProcessor::Unit::ach,
445 4 : state.dataHeatBal->Zone(ZonePtr).InfilOAAirChangeRateHM,
446 : OutputProcessor::SOVTimeStepType::Zone,
447 : OutputProcessor::SOVStoreType::Average,
448 8 : state.dataHeatBal->Zone(ZonePtr).Name);
449 16 : SetupOutputVariable(state,
450 : "Zone Infiltration Hybrid Model Mass Flow Rate",
451 : OutputProcessor::Unit::kg_s,
452 4 : state.dataHeatBal->Zone(ZonePtr).MCPIHM,
453 : OutputProcessor::SOVTimeStepType::Zone,
454 : OutputProcessor::SOVStoreType::Average,
455 8 : state.dataHeatBal->Zone(ZonePtr).Name);
456 : }
457 29 : if (state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_T ||
458 18 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_H ||
459 8 : state.dataHybridModel->HybridModelZone(ZonePtr).PeopleCountCalc_C) {
460 12 : SetupOutputVariable(state,
461 : "Zone Hybrid Model People Count",
462 : OutputProcessor::Unit::None,
463 3 : state.dataHeatBal->Zone(ZonePtr).NumOccHM,
464 : OutputProcessor::SOVTimeStepType::Zone,
465 : OutputProcessor::SOVStoreType::Average,
466 6 : state.dataHeatBal->Zone(ZonePtr).Name);
467 : }
468 :
469 : } else {
470 0 : ShowSevereError(state,
471 0 : CurrentModuleObject + "=\"" + cAlphaArgs(1) + "\" invalid " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) +
472 : "\" not found.");
473 0 : ErrorsFound = true;
474 : }
475 : }
476 :
477 : // ZoneAirMassFlowConservation should not be activated during the Hybrid Modeling infiltration calculations
478 3 : if (state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T && state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance) {
479 0 : state.dataHeatBal->ZoneAirMassFlow.EnforceZoneMassBalance = false;
480 0 : ShowWarningError(state, "ZoneAirMassFlowConservation is deactivated when Hybrid Modeling is performed.");
481 : }
482 :
483 : // RoomAirModelType should be Mixing if Hybrid Modeling is performed for the zone
484 3 : if (state.dataHybridModel->FlagHybridModel) {
485 15 : for (ZonePtr = 1; ZonePtr <= state.dataGlobal->NumOfZones; ZonePtr++) {
486 34 : if ((state.dataHybridModel->HybridModelZone(ZonePtr).InternalThermalMassCalc_T ||
487 16 : state.dataHybridModel->HybridModelZone(ZonePtr).InfiltrationCalc_T) &&
488 4 : (state.dataRoomAirMod->AirModel(ZonePtr).AirModelType != DataRoomAirModel::RoomAirModel::Mixing)) {
489 0 : state.dataRoomAirMod->AirModel(ZonePtr).AirModelType = DataRoomAirModel::RoomAirModel::Mixing;
490 0 : ShowWarningError(state, "Room Air Model Type should be Mixing if Hybrid Modeling is performed for the zone.");
491 : }
492 : }
493 3 : if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) {
494 0 : ShowSevereError(state, "Hybrid Modeling is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance.");
495 0 : ErrorsFound = true;
496 : }
497 : }
498 :
499 3 : if (ErrorsFound) {
500 0 : ShowFatalError(state, "Errors getting Hybrid Model input data. Preceding condition(s) cause termination.");
501 : }
502 : }
503 771 : }
504 :
505 : // Needed for unit tests, should not be normally called.
506 :
507 : } // namespace HybridModel
508 :
509 2313 : } // namespace EnergyPlus
|