diff --git a/src/EnergyPlus/HybridEvapCoolingModel.cc b/src/EnergyPlus/HybridEvapCoolingModel.cc index fc8d99bf77e..8ba811e4331 100644 --- a/src/EnergyPlus/HybridEvapCoolingModel.cc +++ b/src/EnergyPlus/HybridEvapCoolingModel.cc @@ -117,11 +117,13 @@ namespace HybridEvapCoolingModel { BLOCK_HEADER_OFFSET_Number = 6; } - bool CMode::InitializeOutdoorAirTemperatureConstraints(Real64 min, Real64 max) + bool CMode::InitializeOutdoorAirTemperatureConstraints(Real64 min, Real64 max, bool minBlank, bool maxBlank) { // note If this field is blank, there should be no lower constraint on outside air temperature Minimum_Outdoor_Air_Temperature = min; Maximum_Outdoor_Air_Temperature = max; + Minimum_Outdoor_Air_Temperature_Blank = minBlank; + Maximum_Outdoor_Air_Temperature_Blank = maxBlank; return true; } bool CMode::InitializeOutdoorAirHumidityRatioConstraints(Real64 min, Real64 max) @@ -399,11 +401,21 @@ namespace HybridEvapCoolingModel { Array1D Numbers, Array1D_string cNumericFields, Array1D lAlphaBlanks, + Array1D lNumericBlanks, std::string cCurrentModuleObject) { CMode newMode; - bool error = newMode.ParseMode( - state, ModeCounter, &OperatingModes, ScalingFactor, Alphas, cAlphaFields, Numbers, cNumericFields, lAlphaBlanks, cCurrentModuleObject); + bool error = newMode.ParseMode(state, + ModeCounter, + &OperatingModes, + ScalingFactor, + Alphas, + cAlphaFields, + Numbers, + cNumericFields, + lAlphaBlanks, + lNumericBlanks, + cCurrentModuleObject); ModeCounter++; return error; } @@ -417,6 +429,7 @@ namespace HybridEvapCoolingModel { Array1D Numbers, Array1D_string cNumericFields, Array1D lAlphaBlanks, + Array1D lNumericBlanks, std::string cCurrentModuleObject) { // SUBROUTINE INFORMATION: @@ -594,7 +607,8 @@ namespace HybridEvapCoolingModel { } // N8, \field Mode1 Minimum Outdoor Air Temperature // N9, \field Mode1 Maximum Outdoor Air Temperature - bool ok = InitializeOutdoorAirTemperatureConstraints(Numbers(inter_Number), Numbers(inter_Number + 1)); + bool ok = InitializeOutdoorAirTemperatureConstraints( + Numbers(inter_Number), Numbers(inter_Number + 1), lNumericBlanks(inter_Number), lNumericBlanks(inter_Number + 1)); if (!ok) { ShowSevereError(state, EnergyPlus::format("Invalid {}Or Invalid{}", cNumericFields(inter_Number), cNumericFields(inter_Number + 1))); ShowContinueError(state, EnergyPlus::format("Entered in {}", cCurrentModuleObject)); @@ -696,7 +710,8 @@ namespace HybridEvapCoolingModel { bool OAHRConstraintmet = false; bool OARHConstraintmet = false; - if (Tosa >= Minimum_Outdoor_Air_Temperature && Tosa <= Maximum_Outdoor_Air_Temperature) { + if ((Minimum_Outdoor_Air_Temperature_Blank || Tosa >= Minimum_Outdoor_Air_Temperature) && + (Maximum_Outdoor_Air_Temperature_Blank || Tosa <= Maximum_Outdoor_Air_Temperature)) { OATempConstraintmet = true; } diff --git a/src/EnergyPlus/HybridEvapCoolingModel.hh b/src/EnergyPlus/HybridEvapCoolingModel.hh index 177473c4788..680f35898b0 100644 --- a/src/EnergyPlus/HybridEvapCoolingModel.hh +++ b/src/EnergyPlus/HybridEvapCoolingModel.hh @@ -135,6 +135,8 @@ namespace HybridEvapCoolingModel { Real64 Max_OAF; Real64 Minimum_Outdoor_Air_Temperature; Real64 Maximum_Outdoor_Air_Temperature; + bool Minimum_Outdoor_Air_Temperature_Blank; + bool Maximum_Outdoor_Air_Temperature_Blank; Real64 Minimum_Outdoor_Air_Humidity_Ratio; Real64 Maximum_Outdoor_Air_Humidity_Ratio; Real64 Minimum_Outdoor_Air_Relative_Humidity; @@ -161,12 +163,13 @@ namespace HybridEvapCoolingModel { Array1D Numbers, Array1D_string cNumericFields, Array1D lAlphaBlanks, + Array1D lNumericBlanks, std::string cCurrentModuleObject); void InitializeCurve(int curveType, int CurveID); Real64 CalculateCurveVal(EnergyPlusData &state, Real64 Tosa, Real64 Wosa, Real64 Tra, Real64 Wra, Real64 Msa, Real64 OSAF, int curveType); bool InitializeOSAFConstraints(Real64 minOSAF, Real64 maxOSAF); bool InitializeMsaRatioConstraints(Real64 minMsa, Real64 maxMsa); - bool InitializeOutdoorAirTemperatureConstraints(Real64 min, Real64 max); + bool InitializeOutdoorAirTemperatureConstraints(Real64 min, Real64 max, bool minBlank, bool maxBlank); bool InitializeOutdoorAirHumidityRatioConstraints(Real64 min, Real64 max); bool InitializeOutdoorAirRelativeHumidityConstraints(Real64 min, Real64 max); bool InitializeReturnAirTemperatureConstraints(Real64 min, Real64 max); @@ -399,6 +402,7 @@ namespace HybridEvapCoolingModel { Array1D Numbers, Array1D_string cNumericFields, Array1D lAlphaBlanks, + Array1D lNumericBlanks, std::string cCurrentModuleObject); void doStep(EnergyPlusData &state, Real64 RequestedLoad, diff --git a/src/EnergyPlus/HybridUnitaryAirConditioners.cc b/src/EnergyPlus/HybridUnitaryAirConditioners.cc index f5ed04062e8..d6de654e0a7 100644 --- a/src/EnergyPlus/HybridUnitaryAirConditioners.cc +++ b/src/EnergyPlus/HybridUnitaryAirConditioners.cc @@ -681,7 +681,8 @@ void GetInputZoneHybridUnitaryAirConditioners(EnergyPlusData &state, bool &Error } for (int modeIter = 0; modeIter <= Numberofoperatingmodes - 1; ++modeIter) { - ErrorsFound = hybridUnitaryAC.ParseMode(state, Alphas, cAlphaFields, Numbers, cNumericFields, lAlphaBlanks, cCurrentModuleObject); + ErrorsFound = hybridUnitaryAC.ParseMode( + state, Alphas, cAlphaFields, Numbers, cNumericFields, lAlphaBlanks, lNumericBlanks, cCurrentModuleObject); if (ErrorsFound) { ShowFatalError(state, EnergyPlus::format("{}: Errors found parsing modes", routineName)); ShowContinueError(state, "... Preceding condition causes termination."); diff --git a/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc b/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc index c07fb4c8952..758b40184f7 100644 --- a/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc +++ b/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc @@ -568,8 +568,8 @@ TEST_F(EnergyPlusFixture, Test_UnitaryHybridAirConditioner_ValidateFieldsParsing ", !- Mode1 System Second Fuel Consumption Lookup Table Name", ", !- Mode1 System Third Fuel Consumption Lookup Table Name", ", !- Mode1 System Water Use Lookup Table Name", - "-20, !- Mode1 Minimum Outside Air Temperature {C}", - "100, !- Mode1 Maximum Outside Air Temperature {C}", + ", !- Mode1 Minimum Outside Air Temperature {C}", + ", !- Mode1 Maximum Outside Air Temperature {C}", "0, !- Mode1 Minimum Outside Air Humidity Ratio {kgWater/kgDryAir}", "0.03, !- Mode1 Maximum Outside Air Humidity Ratio {kgWater/kgDryAir}", "0, !- Mode1 Minimum Outside Air Relative Humidity {percent}", @@ -593,7 +593,6 @@ TEST_F(EnergyPlusFixture, Test_UnitaryHybridAirConditioner_ValidateFieldsParsing unsigned long expectedOperatingModesSize = 2; auto &hybridUnit1 = state->dataHybridUnitaryAC->ZoneHybridUnitaryAirConditioner(1); auto &hybridUnit2 = state->dataHybridUnitaryAC->ZoneHybridUnitaryAirConditioner(2); - // check the number of operating modes EXPECT_EQ(hybridUnit1.OperatingModes.size(), expectedOperatingModesSize); EXPECT_EQ(hybridUnit2.OperatingModes.size(), expectedOperatingModesSize); @@ -603,6 +602,21 @@ TEST_F(EnergyPlusFixture, Test_UnitaryHybridAirConditioner_ValidateFieldsParsing // check that objective function was set or defaulted correctly EXPECT_EQ(hybridUnit1.ObjectiveFunction, HybridEvapCoolingModel::ObjectiveFunctionType::ElectricityUse); EXPECT_EQ(hybridUnit2.ObjectiveFunction, HybridEvapCoolingModel::ObjectiveFunctionType::WaterUse); + // check outdoor air temperature constraints + auto &mode1 = hybridUnit1.OperatingModes[1]; + EXPECT_EQ(mode1.Minimum_Outdoor_Air_Temperature_Blank, false); + EXPECT_EQ(mode1.Minimum_Outdoor_Air_Temperature, -20); + EXPECT_EQ(mode1.Maximum_Outdoor_Air_Temperature_Blank, false); + EXPECT_EQ(mode1.Maximum_Outdoor_Air_Temperature, 100); + EXPECT_EQ(mode1.MeetsOAEnvConstraints(120, 0.01, 30), false); + EXPECT_EQ(mode1.MeetsOAEnvConstraints(20, 0.01, 30), true); + mode1 = hybridUnit2.OperatingModes[1]; + EXPECT_EQ(mode1.Minimum_Outdoor_Air_Temperature_Blank, true); + EXPECT_EQ(mode1.Minimum_Outdoor_Air_Temperature, 0); + EXPECT_EQ(mode1.Maximum_Outdoor_Air_Temperature_Blank, true); + EXPECT_EQ(mode1.Maximum_Outdoor_Air_Temperature, 0); + EXPECT_EQ(mode1.MeetsOAEnvConstraints(120, 0.01, 30), true); + EXPECT_EQ(mode1.MeetsOAEnvConstraints(20, 0.01, 30), true); } TEST_F(EnergyPlusFixture, Test_UnitaryHybridAirConditioner_ValidateMinimumIdfInput)