LCOV - code coverage report
Current view: top level - EnergyPlus - HybridModel.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 179 237 75.5 %
Date: 2024-08-24 18:31:18 Functions: 1 1 100.0 %

          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

Generated by: LCOV version 1.14