diff --git a/resources/energyplus/ProposedEnergy+.idd b/resources/energyplus/ProposedEnergy+.idd index 00a56b4725..62e02ad971 100644 --- a/resources/energyplus/ProposedEnergy+.idd +++ b/resources/energyplus/ProposedEnergy+.idd @@ -22428,8 +22428,8 @@ Sizing:Zone, \note Only No Latent Load or a zone humidistat is present. \note A default of 50.0 will be used if no schedule is provided and \note no humidistat is associated with this zone. - \type alpha - \units percent + \type object-list + \object-list ScheduleNames A14;\field Zone Humidistat Humidification Set Point Schedule Name \note Enter the zone relative humidity schedule used for zone latent \note heating calculations. @@ -22438,8 +22438,8 @@ Sizing:Zone, \note Only No Latent Load or a zone humidistat is present. \note A default of 50.0 will be used if no schedule is provided and \note no humidistat is associated with this zone. - \type alpha - \units percent + \type object-list + \object-list ScheduleNames DesignSpecification:ZoneHVAC:Sizing, \min-fields 1 diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index f3e89d6eba..2cc77bb476 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -17787,7 +17787,7 @@ OS:Coil:Heating:DX:SingleSpeed, \required-field N5 , \field Rated Supply Fan Power Per Volume Flow Rate 2023 \note Enter the supply fan power per air volume flow rate at the rated test conditions. - \note as defined in the 2017 version of ANSI/AHRI Standard 210/240. + \note as defined in the 2017 version of ANSI/AHRI Standard 210/240. \note The test conditions vary external static pressure based on heating capacity. \note This value is only used to calculate Heating Seasonal Performance Factor(HSPF). \note This value is not used for modeling the supply (condenser) fan during simulations. @@ -25763,47 +25763,145 @@ OS:Sizing:Zone, \type real \minimum 0 \default 0.3 - A6, \field Account for Dedicated Outdoor Air System - \note account for effect of dedicated outdoor air system supplying air directly to the zone - \type choice - \key Yes - \key No + A6, \field Account for Dedicated Outdoor Air System + \note account for effect of dedicated outdoor air system supplying air directly to the zone + \type choice + \key Yes + \key No \required-field - A7, \field Dedicated Outdoor Air System Control Strategy - \note 1)supply neutral ventilation air; 2)supply neutral dehumidified and reheated - \note ventilation air; 3)supply cold ventilation air - \type choice - \key NeutralSupplyAir - \key NeutralDehumidifiedSupplyAir - \key ColdSupplyAir + A7, \field Dedicated Outdoor Air System Control Strategy + \note 1)supply neutral ventilation air; 2)supply neutral dehumidified and reheated + \note ventilation air; 3)supply cold ventilation air + \type choice + \key NeutralSupplyAir + \key NeutralDehumidifiedSupplyAir + \key ColdSupplyAir \required-field - N17,\field Dedicated Outdoor Air Low Setpoint Temperature for Design - \type real - \units C - \autosizable + N17, \field Dedicated Outdoor Air Low Setpoint Temperature for Design + \type real + \units C + \autosizable \required-field - N18,\field Dedicated Outdoor Air High Setpoint Temperature for Design - \type real - \units C - \autosizable + N18, \field Dedicated Outdoor Air High Setpoint Temperature for Design + \type real + \units C + \autosizable \required-field - N19, \field Design Zone Air Distribution Effectiveness in Cooling Mode + A8, \field Zone Load Sizing Method + \note Specifies the basis for sizing the zone supply air flow rate. + \note Zone latent loads will not be used during sizing only when + \note Zone Load Sizing Method = Sensible Load Only No Latent Load. + \note For this case the zone humidity level will float according to + \note the fields Cooling and Heating Design Supply Air Humidity Ratio. + \note For all other choices the zone humidity level will be controlled. + \note Sensible Load will use zone sensible air flow rate for zone + \note component sizing. Latent loads will also be reported during sizing. + \note Latent Load will use zone latent air flow rate for zone + \note component sizing. Sensible loads will also be reported during sizing. + \note Sensible and Latent Load will use the larger of sensible and + \note latent load to choose air flow rate for zone component sizing. + \note Sensible Load Only No Latent Load or leaving this field blank + \note will disable zone latent sizing and reporting. Latent loads will + \note not be reported during sizing (reported as 0's). + \type choice + \key Sensible Load + \key Latent Load + \key Sensible And Latent Load + \key Sensible Load Only No Latent Load + \required-field + A9, \field Zone Latent Cooling Design Supply Air Humidity Ratio Input Method + \note Use SupplyAirHumidityRatio to enter the humidity ratio when zone dehumidification + \note is required. The supply air humidity ratio should be less than the zone humidity + \note ratio at the zone thermostat and humidistat set point condition. + \note Use HumidityRatioDifference to enter the difference in humidity ratio from the + \note zone thermostat and humidistat set point condition. + \type choice + \key SupplyAirHumidityRatio + \key HumidityRatioDifference + \required-field + N19, \field Zone Dehumidification Design Supply Air Humidity Ratio + \note Zone Dehumidification Design Supply Air Humidity Ratio is only used when Zone Latent + \note Cooling Design Supply Air Humidity Ratio Input Method = SupplyAirHumidityRatio. + \note This input must be less than the zone humidity ratio at the + \note humidistat set point so that dehumidification can occur. + \minimum> 0.0 + \type real + \units kgWater/kgDryAir + N20, \field Zone Cooling Design Supply Air Humidity Ratio Difference + \note Zone Dehumidification Design Supply Air Humidity Ratio Difference is only used when + \note Zone Latent Cooling Design Supply Air Humidity Ratio Input Method = HumidityRatioDifference. + \note This input is a positive value and defines the difference between the zone humidity + \note ratio at the thermostat and humidistat set point condition and the supply air + \note humidity ratio entering the zone. + \minimum> 0.0 + \type real + \required-field + \units kgWater/kgDryAir + A10, \field Zone Latent Heating Design Supply Air Humidity Ratio Input Method + \note Use SupplyAirHumidityRatio to enter the humidity ratio when zone humidification + \note is required. The supply air humidity ratio should be greater than the zone humidity + \note ratio at the zone thermostat and humidistat set point condition. + \note Use HumidityRatioDifference to enter the difference in humidity ratio from the + \note zone thermostat and humidistat set point condition. + \type choice + \key SupplyAirHumidityRatio + \key HumidityRatioDifference + \required-field + N21, \field Zone Humidification Design Supply Air Humidity Ratio + \note Zone Humidification Design Supply Air Humidity Ratio is only used when Zone Latent + \note Heating Design Supply Air Humidity Ratio Input Method = SupplyAirHumidityRatio. + \note This input must be greater than the zone humidity ratio at the + \note humidistat set point so that humidification can occur. + \minimum> 0.0 + \type real + \units kgWater/kgDryAir + N22, \field Zone Humidification Design Supply Air Humidity Ratio Difference + \note Zone Humidification Design Supply Air Humidity Ratio is only used when Zone Latent + \note Heating Design Supply Air Humidity Ratio Input Method = HumidityRatioDifference. + \note This input is a positive value and defines the difference between the zone humidity + \note ratio at the thermostat and humidistat set point condition and the supply air + \note humidity ratio entering the zone. + \minimum 0.0 + \type real + \required-field + \units kgWater/kgDryAir + A11, \field Zone Humidistat Dehumidification Set Point Schedule Name + \note Enter the zone relative humidity schedule used for zone latent + \note cooling calculations. + \note A zone humidistat will take priority over this input. + \note This field is not used if Zone Load Sizing Method = Sensible Load + \note Only No Latent Load or a zone humidistat is present. + \note A default of 50.0 will be used if no schedule is provided and + \note no humidistat is associated with this zone. + \type object-list + \object-list ScheduleNames + A12, \field Zone Humidistat Humidification Set Point Schedule Name + \note Enter the zone relative humidity schedule used for zone latent + \note heating calculations. + \note A zone humidistat will take priority over this input. + \note This field is not used if Zone Load Sizing Method = Sensible Load + \note Only No Latent Load or a zone humidistat is present. + \note A default of 50.0 will be used if no schedule is provided and + \note no humidistat is associated with this zone. + \type object-list + \object-list ScheduleNames + N23, \field Design Zone Air Distribution Effectiveness in Cooling Mode \note this field is from the DesignSpecification:ZoneAirDistribution \type real \minimum> 0 \default 1.0 - N20, \field Design Zone Air Distribution Effectiveness in Heating Mode + N24, \field Design Zone Air Distribution Effectiveness in Heating Mode \note this field is from the DesignSpecification:ZoneAirDistribution \type real \minimum> 0 \default 1.0 - N21,\field Design Zone Secondary Recirculation Fraction + N25, \field Design Zone Secondary Recirculation Fraction \note this field is from the DesignSpecification:ZoneAirDistribution \type real \default 0.0 \minimum 0.0 \units dimensionless - N22;\field Design Minimum Zone Ventilation Efficiency + N26; \field Design Minimum Zone Ventilation Efficiency \note this field is from the DesignSpecification:ZoneAirDistribution \type real \default 0.0 diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateSizingZone.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateSizingZone.cpp index bf4306920f..44a4304a42 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateSizingZone.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateSizingZone.cpp @@ -43,6 +43,8 @@ #include "../../model/DesignSpecificationOutdoorAir_Impl.hpp" #include "../../model/ThermalZone.hpp" #include "../../model/ThermalZone_Impl.hpp" +#include "../../model/Schedule.hpp" + #include "../../utilities/core/Logger.hpp" #include "../../utilities/core/Assert.hpp" #include @@ -52,6 +54,7 @@ #include #include #include "../../utilities/idf/IdfExtensibleGroup.hpp" +#include "utilities/core/Compare.hpp" using namespace openstudio::model; @@ -278,7 +281,7 @@ namespace energyplus { // DesignSpecificationOutdoorAir std::vector spaces = thermalZone.spaces(); - if (spaces.size() > 0) { + if (!spaces.empty()) { if (boost::optional designOASpec = spaces.front().designSpecificationOutdoorAir()) { if (boost::optional _designOASpec = translateAndMapModelObject(designOASpec.get())) { eg.setString(Controller_MechanicalVentilationExtensibleFields::DesignSpecificationOutdoorAirObjectName, _designOASpec->name().get()); @@ -321,6 +324,74 @@ namespace energyplus { idfObject.setString(Sizing_ZoneFields::AccountforDedicatedOutdoorAirSystem, "No"); } + // Zone Load Sizing Method: Optional String + std::string zoneLoadSizingMethod = modelObject.zoneLoadSizingMethod(); + idfObject.setString(Sizing_ZoneFields::ZoneLoadSizingMethod, zoneLoadSizingMethod); + + // Zone Latent Cooling Design Supply Air Humidity Ratio Input Method: Optional String + std::string zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod = modelObject.zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod(); + idfObject.setString(Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod, + zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod); + if (openstudio::istringEqual(zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod, "SupplyAirHumidityRatio")) { + + // Zone Dehumidification Design Supply Air Humidity Ratio: boost::optional + if (boost::optional _zoneDehumidificationDesignSupplyAirHumidityRatio = + modelObject.zoneDehumidificationDesignSupplyAirHumidityRatio()) { + idfObject.setDouble(Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio, + _zoneDehumidificationDesignSupplyAirHumidityRatio.get()); + } else { + LOG(Error, "For " << modelObject.briefDescription() + << ", when 'Zone Latent Cooling Design Supply Air Humidity Ratio Input Method' is 'SupplyAirHumidityRatio', you must enter " + "a 'Zone Dehumidification Design Supply Air Humidity Ratio'."); + } + } else if (openstudio::istringEqual(zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod, "HumidityRatioDifference")) { + // Zone Cooling Design Supply Air Humidity Ratio Difference: Optional Double + double zoneCoolingDesignSupplyAirHumidityRatioDifference = modelObject.zoneCoolingDesignSupplyAirHumidityRatioDifference(); + idfObject.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference, zoneCoolingDesignSupplyAirHumidityRatioDifference); + } else { + OS_ASSERT(false); + } + + // Zone Latent Heating Design Supply Air Humidity Ratio Input Method: Optional String + std::string zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod = modelObject.zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod(); + idfObject.setString(Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod, + zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod); + + if (openstudio::istringEqual(zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod, "SupplyAirHumidityRatio")) { + + // Zone Humidification Design Supply Air Humidity Ratio: boost::optional + if (boost::optional d_ = modelObject.zoneHumidificationDesignSupplyAirHumidityRatio()) { + idfObject.setDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio, d_.get()); + } else { + LOG(Error, "For " << modelObject.briefDescription() + << ", when 'Zone Latent Heating Design Supply Air Humidity Ratio Input Method' is 'SupplyAirHumidityRatio', you must enter " + "a 'Zone Dehumidification Design Supply Air Humidity Ratio'."); + } + } else if (openstudio::istringEqual(zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod, "HumidityRatioDifference")) { + // Zone Humidification Design Supply Air Humidity Ratio Difference: Optional Double + idfObject.setDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference, + modelObject.zoneHumidificationDesignSupplyAirHumidityRatioDifference()); + } else { + OS_ASSERT(false); + } + + if (!openstudio::istringEqual(zoneLoadSizingMethod, "Sensible Load Only No Latent Load")) { + // Zone Humidistat Dehumidification Set Point Schedule Name + if (boost::optional sch_ = modelObject.zoneHumidistatDehumidificationSetPointSchedule()) { + if (auto idf_sch_ = translateAndMapModelObject(sch_.get())) { + idfObject.setString(Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName, idf_sch_->nameString()); + } + } + + // Zone Humidistat Humidification Set Point Schedule Name + if (boost::optional sch_ = modelObject.zoneHumidistatHumidificationSetPointSchedule()) { + if (auto idf_sch_ = translateAndMapModelObject(sch_.get())) { + + idfObject.setString(Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName, idf_sch_->nameString()); + } + } + } + return idfObject; } diff --git a/src/energyplus/ReverseTranslator/ReverseTranslateSizingZone.cpp b/src/energyplus/ReverseTranslator/ReverseTranslateSizingZone.cpp index c1d4b75d51..fef89e39c7 100644 --- a/src/energyplus/ReverseTranslator/ReverseTranslateSizingZone.cpp +++ b/src/energyplus/ReverseTranslator/ReverseTranslateSizingZone.cpp @@ -36,6 +36,8 @@ #include "../../model/Space_Impl.hpp" #include "../../model/DesignSpecificationOutdoorAir.hpp" #include "../../model/DesignSpecificationOutdoorAir_Impl.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/Schedule_Impl.hpp" #include "../../utilities/idf/WorkspaceExtensibleGroup.hpp" #include @@ -281,6 +283,11 @@ namespace energyplus { sizingZone.setDesignZoneAirDistributionEffectivenessinHeatingMode(value.get()); } + value = _designSpecification->getDouble(DesignSpecification_ZoneAirDistributionFields::ZoneSecondaryRecirculationFraction); + if (value) { + sizingZone.setDesignZoneSecondaryRecirculationFraction(value.get()); + } + // MinimumZoneVentilationEfficiency value = _designSpecification->getDouble(DesignSpecification_ZoneAirDistributionFields::MinimumZoneVentilationEfficiency); @@ -296,6 +303,97 @@ namespace energyplus { << ", field Zone Air Distribution Effectiveness Schedule Name (='" << s.get() << "') isn't translated back to OS:Sizing:Zone"); } } + + // Account for Dedicated Outdoor Air System: Optional Boolean + if (boost::optional _accountforDedicatedOutdoorAirSystem = + workspaceObject.getString(Sizing_ZoneFields::AccountforDedicatedOutdoorAirSystem, true)) { + if (istringEqual("Yes", _accountforDedicatedOutdoorAirSystem.get())) { + sizingZone.setAccountforDedicatedOutdoorAirSystem(true); + } else { + sizingZone.setAccountforDedicatedOutdoorAirSystem(false); + } + } + + // Dedicated Outdoor Air System Control Strategy: Optional String + if (boost::optional _dedicatedOutdoorAirSystemControlStrategy = + workspaceObject.getString(Sizing_ZoneFields::DedicatedOutdoorAirSystemControlStrategy)) { + sizingZone.setDedicatedOutdoorAirSystemControlStrategy(_dedicatedOutdoorAirSystemControlStrategy.get()); + } + + // Dedicated Outdoor Air Low Setpoint Temperature for Design: Optional Double + if (boost::optional _dedicatedOutdoorAirLowSetpointTemperatureforDesign = + workspaceObject.getDouble(Sizing_ZoneFields::DedicatedOutdoorAirLowSetpointTemperatureforDesign)) { + sizingZone.setDedicatedOutdoorAirLowSetpointTemperatureforDesign(_dedicatedOutdoorAirLowSetpointTemperatureforDesign.get()); + } + + // Dedicated Outdoor Air High Setpoint Temperature for Design: Optional Double + if (boost::optional _dedicatedOutdoorAirHighSetpointTemperatureforDesign = + workspaceObject.getDouble(Sizing_ZoneFields::DedicatedOutdoorAirHighSetpointTemperatureforDesign)) { + sizingZone.setDedicatedOutdoorAirHighSetpointTemperatureforDesign(_dedicatedOutdoorAirHighSetpointTemperatureforDesign.get()); + } + + // Zone Load Sizing Method: Optional String + if (boost::optional _zoneLoadSizingMethod = workspaceObject.getString(Sizing_ZoneFields::ZoneLoadSizingMethod)) { + sizingZone.setZoneLoadSizingMethod(_zoneLoadSizingMethod.get()); + } + + // Zone Latent Cooling Design Supply Air Humidity Ratio Input Method: Optional String + if (boost::optional _zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod = + workspaceObject.getString(Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod)) { + sizingZone.setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod(_zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod.get()); + } + + // Zone Dehumidification Design Supply Air Humidity Ratio: Optional Double + if (boost::optional _zoneDehumidificationDesignSupplyAirHumidityRatio = + workspaceObject.getDouble(Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio)) { + sizingZone.setZoneDehumidificationDesignSupplyAirHumidityRatio(_zoneDehumidificationDesignSupplyAirHumidityRatio.get()); + } + + // Zone Cooling Design Supply Air Humidity Ratio Difference: Optional Double + if (boost::optional _zoneCoolingDesignSupplyAirHumidityRatioDifference = + workspaceObject.getDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference)) { + sizingZone.setZoneCoolingDesignSupplyAirHumidityRatioDifference(_zoneCoolingDesignSupplyAirHumidityRatioDifference.get()); + } + + // Zone Latent Heating Design Supply Air Humidity Ratio Input Method: Optional String + if (boost::optional _zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod = + workspaceObject.getString(Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod)) { + sizingZone.setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod(_zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod.get()); + } + + // Zone Humidification Design Supply Air Humidity Ratio: Optional Double + if (boost::optional _zoneHumidificationDesignSupplyAirHumidityRatio = + workspaceObject.getDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio)) { + sizingZone.setZoneHumidificationDesignSupplyAirHumidityRatio(_zoneHumidificationDesignSupplyAirHumidityRatio.get()); + } + + // Zone Humidification Design Supply Air Humidity Ratio Difference: Optional Double + if (boost::optional _zoneHumidificationDesignSupplyAirHumidityRatioDifference = + workspaceObject.getDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference)) { + sizingZone.setZoneHumidificationDesignSupplyAirHumidityRatioDifference(_zoneHumidificationDesignSupplyAirHumidityRatioDifference.get()); + } + + // Zone Humidistat Dehumidification Set Point Schedule Name: Optional String + if (auto _wo = workspaceObject.getTarget(Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName)) { + if (auto _mo = translateAndMapWorkspaceObject(_wo.get())) { + if (auto sch_ = _mo->optionalCast()) { + sizingZone.setZoneHumidistatDehumidificationSetPointSchedule(sch_.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Zone Humidistat Dehumidification Set Point Schedule Name'"); + } + } + } + + // Zone Humidistat Humidification Set Point Schedule Name: Optional String + if (auto _wo = workspaceObject.getTarget(Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName)) { + if (auto _mo = translateAndMapWorkspaceObject(_wo.get())) { + if (auto sch_ = _mo->optionalCast()) { + sizingZone.setZoneHumidistatHumidificationSetPointSchedule(sch_.get()); + } else { + LOG(Warn, workspaceObject.briefDescription() << " has a wrong type for 'Zone Humidistat Huumidification Set Point Schedule Name'"); + } + } + } } return result; diff --git a/src/energyplus/Test/SizingZone_GTest.cpp b/src/energyplus/Test/SizingZone_GTest.cpp index f4e8a5ab33..c1c08aef49 100644 --- a/src/energyplus/Test/SizingZone_GTest.cpp +++ b/src/energyplus/Test/SizingZone_GTest.cpp @@ -38,8 +38,10 @@ #include "../../model/SizingZone_Impl.hpp" #include "../../model/ThermalZone.hpp" +#include "../../model/ThermalZone_Impl.hpp" #include "../../model/Space.hpp" #include "../../model/DesignDay.hpp" +#include "../../model/ScheduleConstant.hpp" #include "../../utilities/idf/IdfFile.hpp" #include "../../utilities/idf/Workspace.hpp" @@ -50,6 +52,8 @@ #include #include +#include +#include #include @@ -133,5 +137,235 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_SizingZone) { EXPECT_EQ(0.7, _i_dszad->getDouble(DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinHeatingMode).get()); EXPECT_EQ(0.6, _i_dszad->getDouble(DesignSpecification_ZoneAirDistributionFields::ZoneSecondaryRecirculationFraction).get()); EXPECT_EQ(0.5, _i_dszad->getDouble(DesignSpecification_ZoneAirDistributionFields::MinimumZoneVentilationEfficiency).get()); + + // New E+ 22.2.0 fields: getting the defaults + EXPECT_EQ("Sensible Load Only No Latent Load", idf_sz.getString(Sizing_ZoneFields::ZoneLoadSizingMethod).get()); + EXPECT_EQ("HumidityRatioDifference", idf_sz.getString(Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio)); + EXPECT_EQ(0.005, idf_sz.getDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference).get()); + EXPECT_EQ("HumidityRatioDifference", idf_sz.getString(Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio)); + EXPECT_EQ(0.005, idf_sz.getDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName)); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName)); + } + + EXPECT_TRUE(sz.setZoneLoadSizingMethod("Sensible Load Only No Latent Load")); + EXPECT_TRUE(sz.setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod("SupplyAirHumidityRatio")); + EXPECT_TRUE(sz.setZoneDehumidificationDesignSupplyAirHumidityRatio(0.008)); + EXPECT_TRUE(sz.setZoneCoolingDesignSupplyAirHumidityRatioDifference(0.0051)); + EXPECT_TRUE(sz.setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod("SupplyAirHumidityRatio")); + EXPECT_TRUE(sz.setZoneHumidificationDesignSupplyAirHumidityRatio(0.004)); + EXPECT_TRUE(sz.setZoneHumidificationDesignSupplyAirHumidityRatioDifference(0.0049)); + + ScheduleConstant dehumSch(m); + EXPECT_TRUE(sz.setZoneHumidistatDehumidificationSetPointSchedule(dehumSch)); + + ScheduleConstant humSch(m); + EXPECT_TRUE(sz.setZoneHumidistatHumidificationSetPointSchedule(humSch)); + + { + Workspace w = ft.translateModel(m); + + WorkspaceObjectVector idfObjs = w.getObjectsByType(IddObjectType::Sizing_Zone); + ASSERT_EQ(1u, idfObjs.size()); + WorkspaceObject idf_sz(idfObjs[0]); + + EXPECT_EQ("Sensible Load Only No Latent Load", idf_sz.getString(Sizing_ZoneFields::ZoneLoadSizingMethod).get()); + // SupplyAirHumidityRatio: the Difference field isn't used + EXPECT_EQ("SupplyAirHumidityRatio", idf_sz.getString(Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod).get()); + EXPECT_EQ(0.008, idf_sz.getDouble(Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference)); + EXPECT_EQ("SupplyAirHumidityRatio", idf_sz.getString(Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod).get()); + EXPECT_EQ(0.004, idf_sz.getDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference)); + + // Sensible Load Only No Latent Load -> Hum/dehum schedules are ignored + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName)); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName)); } + + EXPECT_TRUE(sz.setZoneLoadSizingMethod("Sensible And Latent Load")); + EXPECT_TRUE(sz.setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod("HumidityRatioDifference")); + EXPECT_TRUE(sz.setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod("HumidityRatioDifference")); + + { + Workspace w = ft.translateModel(m); + + WorkspaceObjectVector idfObjs = w.getObjectsByType(IddObjectType::Sizing_Zone); + ASSERT_EQ(1u, idfObjs.size()); + WorkspaceObject idf_sz(idfObjs[0]); + + EXPECT_EQ("Sensible And Latent Load", idf_sz.getString(Sizing_ZoneFields::ZoneLoadSizingMethod).get()); + + // HumidityRatioDifference: the Ratio field isn't used + EXPECT_EQ("HumidityRatioDifference", idf_sz.getString(Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio)); + EXPECT_EQ(0.0051, idf_sz.getDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference).get()); + EXPECT_EQ("HumidityRatioDifference", idf_sz.getString(Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod).get()); + EXPECT_TRUE(idf_sz.isEmpty(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio)); + EXPECT_EQ(0.0049, idf_sz.getDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference).get()); + EXPECT_EQ(dehumSch.nameString(), idf_sz.getString(Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName).get()); + EXPECT_EQ(humSch.nameString(), idf_sz.getString(Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName).get()); + } +} + +TEST_F(EnergyPlusFixture, ReverseTranslator_SizingZone) { + + ReverseTranslator rt; + + Workspace w(StrictnessLevel::Minimal, IddFileType::EnergyPlus); + + auto wo_zone = w.addObject(IdfObject(IddObjectType::Zone)).get(); + wo_zone.setName("Zone1"); + + auto wo_sz = w.addObject(IdfObject(IddObjectType::Sizing_Zone)).get(); + wo_sz.setName("Zone1 SizingZone"); + EXPECT_TRUE(wo_sz.setPointer(Sizing_ZoneFields::ZoneorZoneListName, wo_zone.handle())); + + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirTemperatureInputMethod, "SupplyAirTemperature")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirTemperature, 14.0)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirTemperatureDifference, 11.11)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperatureInputMethod, "SupplyAirTemperature")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperature, 40.0)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperatureDifference, 11.11)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatio, 0.0085)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneHeatingDesignSupplyAirHumidityRatio, 0.008)); + + auto wo_dsoa = w.addObject(IdfObject(IddObjectType::DesignSpecification_OutdoorAir)).get(); + wo_dsoa.setName("Thermal Zone 1 Zero air DSOA"); + EXPECT_TRUE(wo_dsoa.setString(DesignSpecification_OutdoorAirFields::OutdoorAirMethod, "Sum")); + EXPECT_TRUE(wo_dsoa.setDouble(DesignSpecification_OutdoorAirFields::OutdoorAirFlowperPerson, 0.0)); + EXPECT_TRUE(wo_dsoa.setDouble(DesignSpecification_OutdoorAirFields::OutdoorAirFlowperZoneFloorArea, 0.0)); + EXPECT_TRUE(wo_dsoa.setDouble(DesignSpecification_OutdoorAirFields::OutdoorAirFlowperZone, 0.0)); + EXPECT_TRUE(wo_dsoa.setDouble(DesignSpecification_OutdoorAirFields::OutdoorAirFlowAirChangesperHour, 0.0)); + EXPECT_TRUE(wo_dsoa.setString(DesignSpecification_OutdoorAirFields::OutdoorAirScheduleName, "")); + EXPECT_TRUE(wo_dsoa.setString(DesignSpecification_OutdoorAirFields::ProportionalControlMinimumOutdoorAirFlowRateScheduleName, "")); + EXPECT_TRUE(wo_sz.setPointer(Sizing_ZoneFields::DesignSpecificationOutdoorAirObjectName, wo_dsoa.handle())); + + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneHeatingSizingFactor, 1.1)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneCoolingSizingFactor, "")); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::CoolingDesignAirFlowMethod, "DesignDay")); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::CoolingDesignAirFlowRate, "")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::CoolingMinimumAirFlowperZoneFloorArea, 0.00081)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::CoolingMinimumAirFlow, "")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::CoolingMinimumAirFlowFraction, 0.1)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::HeatingDesignAirFlowMethod, "DesignDay")); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::HeatingDesignAirFlowRate, "")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlowperZoneFloorArea, 0.0024)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlow, 0.145)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlowFraction, 0.3)); + + auto wo_dszad = w.addObject(IdfObject(IddObjectType::DesignSpecification_ZoneAirDistribution)).get(); + EXPECT_TRUE(wo_dszad.setDouble(DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinCoolingMode, 0.8)); + EXPECT_TRUE(wo_dszad.setDouble(DesignSpecification_ZoneAirDistributionFields::ZoneAirDistributionEffectivenessinHeatingMode, 0.7)); + EXPECT_TRUE(wo_dszad.setDouble(DesignSpecification_ZoneAirDistributionFields::ZoneSecondaryRecirculationFraction, 0.6)); + EXPECT_TRUE(wo_dszad.setDouble(DesignSpecification_ZoneAirDistributionFields::MinimumZoneVentilationEfficiency, 0.5)); + EXPECT_TRUE(wo_sz.setPointer(Sizing_ZoneFields::DesignSpecificationZoneAirDistributionObjectName, wo_dszad.handle())); + + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::AccountforDedicatedOutdoorAirSystem, "No")); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::DedicatedOutdoorAirSystemControlStrategy, "NeutralSupplyAir")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::DedicatedOutdoorAirLowSetpointTemperatureforDesign, 18.0)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::DedicatedOutdoorAirHighSetpointTemperatureforDesign, 19.0)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneLoadSizingMethod, "Sensible And Latent Load")); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod, "HumidityRatioDifference")); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio, "")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference, 0.0051)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod, "SupplyAirHumidityRatio")); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio, 0.004)); + EXPECT_TRUE(wo_sz.setString(Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference, "")); + + auto wo_dehumSch = w.addObject(IdfObject(IddObjectType::Schedule_Constant)).get(); + wo_dehumSch.setName("dehumSch"); + EXPECT_TRUE(wo_dehumSch.setDouble(Schedule_ConstantFields::HourlyValue, 60.0)); + EXPECT_TRUE(wo_sz.setPointer(Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName, wo_dehumSch.handle())); + + auto wo_humSch = w.addObject(IdfObject(IddObjectType::Schedule_Constant)).get(); + wo_humSch.setName("humSch"); + EXPECT_TRUE(wo_humSch.setDouble(Schedule_ConstantFields::HourlyValue, 40.0)); + EXPECT_TRUE(wo_sz.setPointer(Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName, wo_humSch.handle())); + + // RT + Model m = rt.translateWorkspace(w); + + ASSERT_EQ(1, m.getConcreteModelObjects().size()); + auto szs = m.getConcreteModelObjects(); + ASSERT_EQ(1, szs.size()); + auto& sz = szs[0]; + + EXPECT_EQ("SupplyAirTemperature", sz.zoneCoolingDesignSupplyAirTemperatureInputMethod()); + EXPECT_EQ(14.0, sz.zoneCoolingDesignSupplyAirTemperature()); + EXPECT_EQ(11.11, sz.zoneCoolingDesignSupplyAirTemperatureDifference()); + EXPECT_EQ("SupplyAirTemperature", sz.zoneHeatingDesignSupplyAirTemperatureInputMethod()); + EXPECT_EQ(40.0, sz.zoneHeatingDesignSupplyAirTemperature()); + EXPECT_EQ(11.11, sz.zoneHeatingDesignSupplyAirTemperatureDifference()); + EXPECT_EQ(0.0085, sz.zoneCoolingDesignSupplyAirHumidityRatio()); + EXPECT_EQ(0.008, sz.zoneHeatingDesignSupplyAirHumidityRatio()); + ASSERT_TRUE(sz.zoneHeatingSizingFactor()); + EXPECT_EQ(1.1, sz.zoneHeatingSizingFactor().get()); + EXPECT_FALSE(sz.zoneCoolingSizingFactor()); + + EXPECT_EQ("DesignDay", sz.coolingDesignAirFlowMethod()); + + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlowperZoneFloorArea, 0.0024)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlow, 0.145)); + EXPECT_TRUE(wo_sz.setDouble(Sizing_ZoneFields::HeatingMaximumAirFlowFraction, 0.3)); + + EXPECT_TRUE(sz.isCoolingDesignAirFlowRateDefaulted()); + + EXPECT_FALSE(sz.isCoolingMinimumAirFlowperZoneFloorAreaDefaulted()); + EXPECT_EQ(0.00081, sz.coolingMinimumAirFlowperZoneFloorArea()); + + EXPECT_TRUE(sz.isCoolingMinimumAirFlowDefaulted()); + + EXPECT_FALSE(sz.isCoolingMinimumAirFlowFractionDefaulted()); + EXPECT_EQ(0.1, sz.coolingMinimumAirFlowFraction()); + + EXPECT_EQ("DesignDay", sz.heatingDesignAirFlowMethod()); + + EXPECT_TRUE(sz.isHeatingDesignAirFlowRateDefaulted()); + + EXPECT_FALSE(sz.isHeatingMaximumAirFlowperZoneFloorAreaDefaulted()); + EXPECT_EQ(0.0024, sz.heatingMaximumAirFlowperZoneFloorArea()); + + EXPECT_FALSE(sz.isHeatingMaximumAirFlowDefaulted()); + EXPECT_EQ(0.145, sz.heatingMaximumAirFlow()); + + EXPECT_FALSE(sz.isHeatingMaximumAirFlowFractionDefaulted()); + EXPECT_EQ(0.3, sz.heatingMaximumAirFlowFraction()); + + EXPECT_FALSE(sz.accountforDedicatedOutdoorAirSystem()); + EXPECT_EQ("NeutralSupplyAir", sz.dedicatedOutdoorAirSystemControlStrategy()); + ASSERT_TRUE(sz.dedicatedOutdoorAirLowSetpointTemperatureforDesign()); + EXPECT_EQ(18.0, sz.dedicatedOutdoorAirLowSetpointTemperatureforDesign().get()); + ASSERT_TRUE(sz.dedicatedOutdoorAirHighSetpointTemperatureforDesign()); + EXPECT_EQ(19.0, sz.dedicatedOutdoorAirHighSetpointTemperatureforDesign().get()); + + EXPECT_EQ("Sensible And Latent Load", sz.zoneLoadSizingMethod()); + + EXPECT_EQ("HumidityRatioDifference", sz.zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod()); + EXPECT_FALSE(sz.zoneDehumidificationDesignSupplyAirHumidityRatio()); + EXPECT_EQ(0.0051, sz.zoneCoolingDesignSupplyAirHumidityRatioDifference()); + + EXPECT_EQ("SupplyAirHumidityRatio", sz.zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod()); + ASSERT_TRUE(sz.zoneHumidificationDesignSupplyAirHumidityRatio()); + EXPECT_EQ(0.004, sz.zoneHumidificationDesignSupplyAirHumidityRatio().get()); + + ASSERT_TRUE(sz.zoneHumidistatDehumidificationSetPointSchedule()); + EXPECT_EQ("dehumSch", sz.zoneHumidistatDehumidificationSetPointSchedule()->nameString()); + ASSERT_TRUE(sz.zoneHumidistatHumidificationSetPointSchedule()); + EXPECT_EQ("humSch", sz.zoneHumidistatHumidificationSetPointSchedule()->nameString()); + + // From the ZoneAirDistribution object + EXPECT_FALSE(sz.isDesignZoneAirDistributionEffectivenessinCoolingModeDefaulted()); + EXPECT_EQ(0.8, sz.designZoneAirDistributionEffectivenessinCoolingMode()); + + EXPECT_FALSE(sz.isDesignZoneAirDistributionEffectivenessinHeatingModeDefaulted()); + EXPECT_EQ(0.7, sz.designZoneAirDistributionEffectivenessinHeatingMode()); + + EXPECT_FALSE(sz.isDesignZoneSecondaryRecirculationFractionDefaulted()); + EXPECT_EQ(0.6, sz.designZoneSecondaryRecirculationFraction()); + + EXPECT_FALSE(sz.isDesignMinimumZoneVentilationEfficiencyDefaulted()); + EXPECT_EQ(0.5, sz.designMinimumZoneVentilationEfficiency()); } diff --git a/src/model/ScheduleTypeRegistry.cpp b/src/model/ScheduleTypeRegistry.cpp index c53bd048a0..8a644944c5 100644 --- a/src/model/ScheduleTypeRegistry.cpp +++ b/src/model/ScheduleTypeRegistry.cpp @@ -377,6 +377,8 @@ namespace model { {"SetpointManagerOutdoorAirReset", "Setpoint Manager Outdoor Air Reset", "schedule", true, "", 0.0, OptionalDouble()}, {"ShadingSurface", "Transmittance", "transmittanceSchedule", true, "", 0.0, 1.0}, {"SiteWaterMainsTemperature", "Temperature", "temperatureSchedule", true, "Temperature", OptionalDouble(), OptionalDouble()}, + {"SizingZone", "Zone Humidistat Dehumidification Set Point", "zoneHumidistatDehumidificationSetPointSchedule", true, "Percent", 0.0, 100.0}, + {"SizingZone", "Zone Humidistat Humidification Set Point", "zoneHumidistatHumidificationSetPointSchedule", true, "Percent", 0.0, 100.0}, {"SurfaceControlMovableInsulation", "Resistance Modifier Fraction", "schedule", true, "", 0.0, 1.0}, {"SolarCollectorPerformancePhotovoltaicThermalSimple", "Thermal Conversion Efficiency", "thermalConversionEfficiencySchedule", true, "", 0.0, 1.0}, diff --git a/src/model/SizingZone.cpp b/src/model/SizingZone.cpp index c5a285eb29..2e3e2c5d09 100644 --- a/src/model/SizingZone.cpp +++ b/src/model/SizingZone.cpp @@ -33,6 +33,8 @@ #include "ThermalZone_Impl.hpp" #include "Model.hpp" #include "Model_Impl.hpp" +#include "Schedule.hpp" +#include "Schedule_Impl.hpp" #include #include @@ -67,6 +69,20 @@ namespace model { return SizingZone::iddObjectType(); } + std::vector SizingZone_Impl::getScheduleTypeKeys(const Schedule& schedule) const { + std::vector result; + UnsignedVector fieldIndices = getSourceIndices(schedule.handle()); + UnsignedVector::const_iterator b(fieldIndices.begin()); + UnsignedVector::const_iterator e(fieldIndices.end()); + if (std::find(b, e, OS_Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName) != e) { + result.emplace_back("SizingZone", "Zone Humidistat Dehumidification Set Point"); + } + if (std::find(b, e, OS_Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName) != e) { + result.emplace_back("SizingZone", "Zone Humidistat Humidification Set Point"); + } + return result; + } + ThermalZone SizingZone_Impl::thermalZone() const { boost::optional value = optionalThermalZone(); if (!value) { @@ -568,6 +584,127 @@ namespace model { return result; } + std::string SizingZone_Impl::zoneLoadSizingMethod() const { + boost::optional value = getString(OS_Sizing_ZoneFields::ZoneLoadSizingMethod, true); + OS_ASSERT(value); + return value.get(); + } + + bool SizingZone_Impl::setZoneLoadSizingMethod(const std::string& zoneLoadSizingMethod) { + bool result = setString(OS_Sizing_ZoneFields::ZoneLoadSizingMethod, zoneLoadSizingMethod); + return result; + } + + std::string SizingZone_Impl::zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod() const { + boost::optional value = getString(OS_Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod, true); + OS_ASSERT(value); + return value.get(); + } + + bool SizingZone_Impl::setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod( + const std::string& zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod) { + bool result = setString(OS_Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod, + zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod); + return result; + } + + boost::optional SizingZone_Impl::zoneDehumidificationDesignSupplyAirHumidityRatio() const { + return getDouble(OS_Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio, true); + } + + bool SizingZone_Impl::setZoneDehumidificationDesignSupplyAirHumidityRatio(double zoneDehumidificationDesignSupplyAirHumidityRatio) { + bool result = + setDouble(OS_Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio, zoneDehumidificationDesignSupplyAirHumidityRatio); + return result; + } + + void SizingZone_Impl::resetZoneDehumidificationDesignSupplyAirHumidityRatio() { + bool result = setString(OS_Sizing_ZoneFields::ZoneDehumidificationDesignSupplyAirHumidityRatio, ""); + OS_ASSERT(result); + } + + double SizingZone_Impl::zoneCoolingDesignSupplyAirHumidityRatioDifference() const { + boost::optional value = getDouble(OS_Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference, true); + OS_ASSERT(value); + return value.get(); + } + + bool SizingZone_Impl::setZoneCoolingDesignSupplyAirHumidityRatioDifference(double zoneCoolingDesignSupplyAirHumidityRatioDifference) { + bool result = + setDouble(OS_Sizing_ZoneFields::ZoneCoolingDesignSupplyAirHumidityRatioDifference, zoneCoolingDesignSupplyAirHumidityRatioDifference); + return result; + } + + std::string SizingZone_Impl::zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod() const { + boost::optional value = getString(OS_Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod, true); + OS_ASSERT(value); + return value.get(); + } + + bool SizingZone_Impl::setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod( + const std::string& zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod) { + bool result = setString(OS_Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod, + zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod); + return result; + } + + boost::optional SizingZone_Impl::zoneHumidificationDesignSupplyAirHumidityRatio() const { + return getDouble(OS_Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio, true); + } + + bool SizingZone_Impl::setZoneHumidificationDesignSupplyAirHumidityRatio(double zoneHumidificationDesignSupplyAirHumidityRatio) { + bool result = setDouble(OS_Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio, zoneHumidificationDesignSupplyAirHumidityRatio); + return result; + } + + void SizingZone_Impl::resetZoneHumidificationDesignSupplyAirHumidityRatio() { + bool result = setString(OS_Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatio, ""); + OS_ASSERT(result); + } + + double SizingZone_Impl::zoneHumidificationDesignSupplyAirHumidityRatioDifference() const { + boost::optional value = getDouble(OS_Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference, true); + OS_ASSERT(value); + return value.get(); + } + + bool + SizingZone_Impl::setZoneHumidificationDesignSupplyAirHumidityRatioDifference(double zoneHumidificationDesignSupplyAirHumidityRatioDifference) { + bool result = setDouble(OS_Sizing_ZoneFields::ZoneHumidificationDesignSupplyAirHumidityRatioDifference, + zoneHumidificationDesignSupplyAirHumidityRatioDifference); + return result; + } + + boost::optional SizingZone_Impl::zoneHumidistatDehumidificationSetPointSchedule() const { + return getObject().getModelObjectTarget(OS_Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName); + } + + bool SizingZone_Impl::setZoneHumidistatDehumidificationSetPointSchedule(Schedule& schedule) { + bool result = setSchedule(OS_Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName, "SizingZone", + "Zone Humidistat Dehumidification Set Point", schedule); + return result; + } + + void SizingZone_Impl::resetZoneHumidistatDehumidificationSetPointSchedule() { + bool result = setString(OS_Sizing_ZoneFields::ZoneHumidistatDehumidificationSetPointScheduleName, ""); + OS_ASSERT(result); + } + + boost::optional SizingZone_Impl::zoneHumidistatHumidificationSetPointSchedule() const { + return getObject().getModelObjectTarget(OS_Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName); + } + + bool SizingZone_Impl::setZoneHumidistatHumidificationSetPointSchedule(Schedule& schedule) { + bool result = setSchedule(OS_Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName, "SizingZone", + "Zone Humidistat Humidification Set Point", schedule); + return result; + } + + void SizingZone_Impl::resetZoneHumidistatHumidificationSetPointSchedule() { + bool result = setString(OS_Sizing_ZoneFields::ZoneHumidistatHumidificationSetPointScheduleName, ""); + OS_ASSERT(result); + } + bool SizingZone_Impl::setDedicatedOutdoorAirLowSetpointTemperatureforDesign( boost::optional dedicatedOutdoorAirLowSetpointTemperatureforDesign) { bool result(false); @@ -814,10 +951,17 @@ namespace model { setDedicatedOutdoorAirSystemControlStrategy("NeutralSupplyAir"); autosizeDedicatedOutdoorAirLowSetpointTemperatureforDesign(); autosizeDedicatedOutdoorAirHighSetpointTemperatureforDesign(); + + // New E+ 22.2.0 fields, IDD defaults + setZoneLoadSizingMethod("Sensible Load Only No Latent Load"); + setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod("HumidityRatioDifference"); + setZoneCoolingDesignSupplyAirHumidityRatioDifference(0.005); + setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod("HumidityRatioDifference"); + setZoneHumidificationDesignSupplyAirHumidityRatioDifference(0.005); } IddObjectType SizingZone::iddObjectType() { - return IddObjectType(IddObjectType::OS_Sizing_Zone); + return {IddObjectType::OS_Sizing_Zone}; } std::vector SizingZone::coolingDesignAirFlowMethodValues() { @@ -838,6 +982,18 @@ namespace model { OS_Sizing_ZoneFields::ZoneHeatingDesignSupplyAirTemperatureInputMethod); } + std::vector SizingZone::zoneLoadSizingMethodValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_Sizing_ZoneFields::ZoneLoadSizingMethod); + } + std::vector SizingZone::zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethodValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Sizing_ZoneFields::ZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod); + } + std::vector SizingZone::zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethodValues() { + return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), + OS_Sizing_ZoneFields::ZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod); + } + ThermalZone SizingZone::thermalZone() const { return getImpl()->thermalZone(); } @@ -1210,6 +1366,100 @@ namespace model { getImpl()->autosizeDedicatedOutdoorAirHighSetpointTemperatureforDesign(); } + std::string SizingZone::zoneLoadSizingMethod() const { + return getImpl()->zoneLoadSizingMethod(); + } + + bool SizingZone::setZoneLoadSizingMethod(const std::string& zoneLoadSizingMethod) { + return getImpl()->setZoneLoadSizingMethod(zoneLoadSizingMethod); + } + + std::string SizingZone::zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod() const { + return getImpl()->zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod(); + } + + bool SizingZone::setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod( + const std::string& zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod) { + return getImpl()->setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod( + zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod); + } + + boost::optional SizingZone::zoneDehumidificationDesignSupplyAirHumidityRatio() const { + return getImpl()->zoneDehumidificationDesignSupplyAirHumidityRatio(); + } + + bool SizingZone::setZoneDehumidificationDesignSupplyAirHumidityRatio(double zoneDehumidificationDesignSupplyAirHumidityRatio) { + return getImpl()->setZoneDehumidificationDesignSupplyAirHumidityRatio(zoneDehumidificationDesignSupplyAirHumidityRatio); + } + + void SizingZone::resetZoneDehumidificationDesignSupplyAirHumidityRatio() { + getImpl()->resetZoneDehumidificationDesignSupplyAirHumidityRatio(); + } + + double SizingZone::zoneCoolingDesignSupplyAirHumidityRatioDifference() const { + return getImpl()->zoneCoolingDesignSupplyAirHumidityRatioDifference(); + } + + bool SizingZone::setZoneCoolingDesignSupplyAirHumidityRatioDifference(double zoneCoolingDesignSupplyAirHumidityRatioDifference) { + return getImpl()->setZoneCoolingDesignSupplyAirHumidityRatioDifference( + zoneCoolingDesignSupplyAirHumidityRatioDifference); + } + + std::string SizingZone::zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod() const { + return getImpl()->zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod(); + } + + bool SizingZone::setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod( + const std::string& zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod) { + return getImpl()->setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod( + zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod); + } + + boost::optional SizingZone::zoneHumidificationDesignSupplyAirHumidityRatio() const { + return getImpl()->zoneHumidificationDesignSupplyAirHumidityRatio(); + } + + bool SizingZone::setZoneHumidificationDesignSupplyAirHumidityRatio(double zoneHumidificationDesignSupplyAirHumidityRatio) { + return getImpl()->setZoneHumidificationDesignSupplyAirHumidityRatio(zoneHumidificationDesignSupplyAirHumidityRatio); + } + + void SizingZone::resetZoneHumidificationDesignSupplyAirHumidityRatio() { + getImpl()->resetZoneHumidificationDesignSupplyAirHumidityRatio(); + } + + double SizingZone::zoneHumidificationDesignSupplyAirHumidityRatioDifference() const { + return getImpl()->zoneHumidificationDesignSupplyAirHumidityRatioDifference(); + } + + bool SizingZone::setZoneHumidificationDesignSupplyAirHumidityRatioDifference(double zoneHumidificationDesignSupplyAirHumidityRatioDifference) { + return getImpl()->setZoneHumidificationDesignSupplyAirHumidityRatioDifference( + zoneHumidificationDesignSupplyAirHumidityRatioDifference); + } + + boost::optional SizingZone::zoneHumidistatDehumidificationSetPointSchedule() const { + return getImpl()->zoneHumidistatDehumidificationSetPointSchedule(); + } + + bool SizingZone::setZoneHumidistatDehumidificationSetPointSchedule(Schedule& schedule) { + return getImpl()->setZoneHumidistatDehumidificationSetPointSchedule(schedule); + } + + void SizingZone::resetZoneHumidistatDehumidificationSetPointSchedule() { + getImpl()->resetZoneHumidistatDehumidificationSetPointSchedule(); + } + + boost::optional SizingZone::zoneHumidistatHumidificationSetPointSchedule() const { + return getImpl()->zoneHumidistatHumidificationSetPointSchedule(); + } + + bool SizingZone::setZoneHumidistatHumidificationSetPointSchedule(Schedule& schedule) { + return getImpl()->setZoneHumidistatHumidificationSetPointSchedule(schedule); + } + + void SizingZone::resetZoneHumidistatHumidificationSetPointSchedule() { + getImpl()->resetZoneHumidistatHumidificationSetPointSchedule(); + } + /// @cond SizingZone::SizingZone(std::shared_ptr impl) : ModelObject(std::move(impl)) {} /// @endcond diff --git a/src/model/SizingZone.hpp b/src/model/SizingZone.hpp index 51187e61aa..32f6791f6a 100644 --- a/src/model/SizingZone.hpp +++ b/src/model/SizingZone.hpp @@ -38,6 +38,7 @@ namespace openstudio { namespace model { class ThermalZone; + class Schedule; namespace detail { @@ -64,6 +65,9 @@ namespace model { static std::vector heatingDesignAirFlowMethodValues(); static std::vector zoneCoolingDesignSupplyAirTemperatureInputMethodValues(); static std::vector zoneHeatingDesignSupplyAirTemperatureInputMethodValues(); + static std::vector zoneLoadSizingMethodValues(); + static std::vector zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethodValues(); + static std::vector zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethodValues(); /** @name Getters */ //@{ @@ -142,6 +146,24 @@ namespace model { bool isDedicatedOutdoorAirHighSetpointTemperatureforDesignAutosized() const; + std::string zoneLoadSizingMethod() const; + + std::string zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod() const; + + boost::optional zoneDehumidificationDesignSupplyAirHumidityRatio() const; + + double zoneCoolingDesignSupplyAirHumidityRatioDifference() const; + + std::string zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod() const; + + boost::optional zoneHumidificationDesignSupplyAirHumidityRatio() const; + + double zoneHumidificationDesignSupplyAirHumidityRatioDifference() const; + + boost::optional zoneHumidistatDehumidificationSetPointSchedule() const; + + boost::optional zoneHumidistatHumidificationSetPointSchedule() const; + // Fields from DesignSpecification:ZoneAirDistribution double designZoneAirDistributionEffectivenessinCoolingMode() const; @@ -240,6 +262,28 @@ namespace model { void autosizeDedicatedOutdoorAirHighSetpointTemperatureforDesign(); + bool setZoneLoadSizingMethod(const std::string& zoneLoadSizingMethod); + + bool setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod(const std::string& zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod); + + bool setZoneDehumidificationDesignSupplyAirHumidityRatio(double zoneDehumidificationDesignSupplyAirHumidityRatio); + void resetZoneDehumidificationDesignSupplyAirHumidityRatio(); + + bool setZoneCoolingDesignSupplyAirHumidityRatioDifference(double zoneCoolingDesignSupplyAirHumidityRatioDifference); + + bool setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod(const std::string& zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod); + + bool setZoneHumidificationDesignSupplyAirHumidityRatio(double zoneHumidificationDesignSupplyAirHumidityRatio); + void resetZoneHumidificationDesignSupplyAirHumidityRatio(); + + bool setZoneHumidificationDesignSupplyAirHumidityRatioDifference(double zoneHumidificationDesignSupplyAirHumidityRatioDifference); + + bool setZoneHumidistatDehumidificationSetPointSchedule(Schedule& schedule); + void resetZoneHumidistatDehumidificationSetPointSchedule(); + + bool setZoneHumidistatHumidificationSetPointSchedule(Schedule& schedule); + void resetZoneHumidistatHumidificationSetPointSchedule(); + // Fields from DesignSpecification:ZoneAirDistribution bool setDesignZoneAirDistributionEffectivenessinCoolingMode(double designZoneAirDistributionEffectivenessinCoolingMode); diff --git a/src/model/SizingZone_Impl.hpp b/src/model/SizingZone_Impl.hpp index ecb84af73d..2975285fba 100644 --- a/src/model/SizingZone_Impl.hpp +++ b/src/model/SizingZone_Impl.hpp @@ -37,6 +37,7 @@ namespace openstudio { namespace model { class ThermalZone; + class Schedule; namespace detail { @@ -65,6 +66,8 @@ namespace model { virtual IddObjectType iddObjectType() const override; + virtual std::vector getScheduleTypeKeys(const Schedule& schedule) const override; + virtual std::vector emsActuatorNames() const override; virtual std::vector emsInternalVariableNames() const override; @@ -147,6 +150,24 @@ namespace model { bool isDedicatedOutdoorAirHighSetpointTemperatureforDesignAutosized() const; + std::string zoneLoadSizingMethod() const; + + std::string zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod() const; + + boost::optional zoneDehumidificationDesignSupplyAirHumidityRatio() const; + + double zoneCoolingDesignSupplyAirHumidityRatioDifference() const; + + std::string zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod() const; + + boost::optional zoneHumidificationDesignSupplyAirHumidityRatio() const; + + double zoneHumidificationDesignSupplyAirHumidityRatioDifference() const; + + boost::optional zoneHumidistatDehumidificationSetPointSchedule() const; + + boost::optional zoneHumidistatHumidificationSetPointSchedule() const; + // Fields from DesignSpecification:ZoneAirDistribution double designZoneAirDistributionEffectivenessinCoolingMode() const; @@ -247,6 +268,28 @@ namespace model { void autosizeDedicatedOutdoorAirHighSetpointTemperatureforDesign(); + bool setZoneLoadSizingMethod(const std::string& zoneLoadSizingMethod); + + bool setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod(const std::string& zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod); + + bool setZoneDehumidificationDesignSupplyAirHumidityRatio(double zoneDehumidificationDesignSupplyAirHumidityRatio); + void resetZoneDehumidificationDesignSupplyAirHumidityRatio(); + + bool setZoneCoolingDesignSupplyAirHumidityRatioDifference(double zoneCoolingDesignSupplyAirHumidityRatioDifference); + + bool setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod(const std::string& zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod); + + bool setZoneHumidificationDesignSupplyAirHumidityRatio(double zoneHumidificationDesignSupplyAirHumidityRatio); + void resetZoneHumidificationDesignSupplyAirHumidityRatio(); + + bool setZoneHumidificationDesignSupplyAirHumidityRatioDifference(double zoneHumidificationDesignSupplyAirHumidityRatioDifference); + + bool setZoneHumidistatDehumidificationSetPointSchedule(Schedule& schedule); + void resetZoneHumidistatDehumidificationSetPointSchedule(); + + bool setZoneHumidistatHumidificationSetPointSchedule(Schedule& schedule); + void resetZoneHumidistatHumidificationSetPointSchedule(); + // Fields from DesignSpecification:ZoneAirDistribution bool setDesignZoneAirDistributionEffectivenessinCoolingMode(double designZoneAirDistributionEffectivenessinCoolingMode); diff --git a/src/model/test/SizingZone_GTest.cpp b/src/model/test/SizingZone_GTest.cpp index 949316da25..7b30f01e97 100644 --- a/src/model/test/SizingZone_GTest.cpp +++ b/src/model/test/SizingZone_GTest.cpp @@ -34,6 +34,7 @@ #include "../SizingZone.hpp" #include "../SizingZone_Impl.hpp" #include "../ThermalZone.hpp" +#include "../ScheduleConstant.hpp" using namespace openstudio; using namespace openstudio::model; @@ -343,4 +344,90 @@ TEST_F(ModelFixture, SizingZone_GettersSetters) { EXPECT_FALSE(sz.isDedicatedOutdoorAirHighSetpointTemperatureforDesignAutosized()); sz.autosizeDedicatedOutdoorAirHighSetpointTemperatureforDesign(); EXPECT_TRUE(sz.isDedicatedOutdoorAirHighSetpointTemperatureforDesignAutosized()); + + // Zone Load Sizing Method: String + // Default value from IDD, set in Ctor + EXPECT_EQ("Sensible Load Only No Latent Load", sz.zoneLoadSizingMethod()); + // Set + EXPECT_TRUE(sz.setZoneLoadSizingMethod("Sensible Load")); + EXPECT_EQ("Sensible Load", sz.zoneLoadSizingMethod()); + // Bad Value + EXPECT_FALSE(sz.setZoneLoadSizingMethod("BADENUM")); + EXPECT_EQ("Sensible Load", sz.zoneLoadSizingMethod()); + + // Zone Latent Cooling Design Supply Air Humidity Ratio Input Method: String + // Default value from IDD, set in Ctor + EXPECT_EQ("HumidityRatioDifference", sz.zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod()); + // Set + EXPECT_TRUE(sz.setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod("SupplyAirHumidityRatio")); + EXPECT_EQ("SupplyAirHumidityRatio", sz.zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod()); + // Bad Value + EXPECT_FALSE(sz.setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod("BADENUM")); + EXPECT_EQ("SupplyAirHumidityRatio", sz.zoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod()); + + // Zone Dehumidification Design Supply Air Humidity Ratio: Optional Double + // IDD has no default, I don't have a good one, so empty... + EXPECT_FALSE(sz.zoneDehumidificationDesignSupplyAirHumidityRatio()); + // Set + EXPECT_TRUE(sz.setZoneDehumidificationDesignSupplyAirHumidityRatio(2.9)); + ASSERT_TRUE(sz.zoneDehumidificationDesignSupplyAirHumidityRatio()); + EXPECT_EQ(2.9, sz.zoneDehumidificationDesignSupplyAirHumidityRatio().get()); + // Bad Value + EXPECT_FALSE(sz.setZoneDehumidificationDesignSupplyAirHumidityRatio(-10.0)); + ASSERT_TRUE(sz.zoneDehumidificationDesignSupplyAirHumidityRatio()); + EXPECT_EQ(2.9, sz.zoneDehumidificationDesignSupplyAirHumidityRatio().get()); + + // Zone Cooling Design Supply Air Humidity Ratio Difference: Double + // Default value from IDD, set in Ctor + EXPECT_EQ(0.005, sz.zoneCoolingDesignSupplyAirHumidityRatioDifference()); + // Set + EXPECT_TRUE(sz.setZoneCoolingDesignSupplyAirHumidityRatioDifference(3.0)); + EXPECT_EQ(3.0, sz.zoneCoolingDesignSupplyAirHumidityRatioDifference()); + // Bad Value + EXPECT_FALSE(sz.setZoneCoolingDesignSupplyAirHumidityRatioDifference(-10.0)); + EXPECT_EQ(3.0, sz.zoneCoolingDesignSupplyAirHumidityRatioDifference()); + + // Zone Latent Heating Design Supply Air Humidity Ratio Input Method: Optional String + // Default value from IDD, set in IDD + EXPECT_EQ("HumidityRatioDifference", sz.zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod()); + // Set + EXPECT_TRUE(sz.setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod("SupplyAirHumidityRatio")); + EXPECT_EQ("SupplyAirHumidityRatio", sz.zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod()); + // Bad Value + EXPECT_FALSE(sz.setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod("BADENUM")); + EXPECT_EQ("SupplyAirHumidityRatio", sz.zoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod()); + + // Zone Humidification Design Supply Air Humidity Ratio: Optional Double + // IDD has no default, I don't have a good one, so empty... + EXPECT_FALSE(sz.zoneHumidificationDesignSupplyAirHumidityRatio()); + // Set + EXPECT_TRUE(sz.setZoneHumidificationDesignSupplyAirHumidityRatio(3.2)); + ASSERT_TRUE(sz.zoneHumidificationDesignSupplyAirHumidityRatio()); + EXPECT_EQ(3.2, sz.zoneHumidificationDesignSupplyAirHumidityRatio().get()); + // Bad Value + EXPECT_FALSE(sz.setZoneHumidificationDesignSupplyAirHumidityRatio(-10.0)); + ASSERT_TRUE(sz.zoneHumidificationDesignSupplyAirHumidityRatio()); + EXPECT_EQ(3.2, sz.zoneHumidificationDesignSupplyAirHumidityRatio().get()); + + // Zone Humidification Design Supply Air Humidity Ratio Difference: Double + // Default value from IDD, set in Ctor + EXPECT_EQ(0.005, sz.zoneHumidificationDesignSupplyAirHumidityRatioDifference()); + // Set + EXPECT_TRUE(sz.setZoneHumidificationDesignSupplyAirHumidityRatioDifference(3.3)); + EXPECT_EQ(3.3, sz.zoneHumidificationDesignSupplyAirHumidityRatioDifference()); + // Bad Value + EXPECT_FALSE(sz.setZoneHumidificationDesignSupplyAirHumidityRatioDifference(-10.0)); + EXPECT_EQ(3.3, sz.zoneHumidificationDesignSupplyAirHumidityRatioDifference()); + + // Zone Humidistat Dehumidification Set Point Schedule Name: Optional Object + ScheduleConstant dehumSch(m); + EXPECT_TRUE(sz.setZoneHumidistatDehumidificationSetPointSchedule(dehumSch)); + ASSERT_TRUE(sz.zoneHumidistatDehumidificationSetPointSchedule()); + EXPECT_EQ(dehumSch, sz.zoneHumidistatDehumidificationSetPointSchedule().get()); + + // Zone Humidistat Humidification Set Point Schedule Name: Optional Object + ScheduleConstant humSch(m); + EXPECT_TRUE(sz.setZoneHumidistatHumidificationSetPointSchedule(humSch)); + ASSERT_TRUE(sz.zoneHumidistatHumidificationSetPointSchedule()); + EXPECT_EQ(humSch, sz.zoneHumidistatHumidificationSetPointSchedule().get()); } diff --git a/src/osversion/VersionTranslator.cpp b/src/osversion/VersionTranslator.cpp index 7d184b0f2d..e916b147ab 100644 --- a/src/osversion/VersionTranslator.cpp +++ b/src/osversion/VersionTranslator.cpp @@ -7274,6 +7274,38 @@ namespace osversion { m_refactored.push_back(RefactoredObjectData(object, newObject)); ss << newObject; + } else if (iddname == "OS:Sizing:Zone") { + + // 9 Fields have been added from 3.4.0 to 3.5.0: + // ------------------------------------------------ + // * Zone Load Sizing Method * 26 + // * Zone Latent Cooling Design Supply Air Humidity Ratio Input Method * 27 + // * Zone Dehumidification Design Supply Air Humidity Ratio * 28 + // * Zone Cooling Design Supply Air Humidity Ratio Difference * 29 + // * Zone Latent Heating Design Supply Air Humidity Ratio Input Method * 30 + // * Zone Humidification Design Supply Air Humidity Ratio * 31 + // * Zone Humidification Design Supply Air Humidity Ratio Difference * 32 + // * Zone Humidistat Dehumidification Set Point Schedule Name * 33 + // * Zone Humidistat Humidification Set Point Schedule Name * 34 + auto iddObject = idd_3_5_0.getObject(iddname); + IdfObject newObject(iddObject.get()); + + for (size_t i = 0; i < object.numFields(); ++i) { + auto value = object.getString(i); + if (value) { + if (i < 26) { + // Handle + newObject.setString(i, value.get()); + } else { + // Every other is shifted by 9 fields + newObject.setString(i + 9, value.get()); + } + } + } + + m_refactored.push_back(RefactoredObjectData(object, newObject)); + ss << newObject; + // No-op } else { ss << object; diff --git a/src/osversion/test/3_5_0/test_vt_SizingZone.osm b/src/osversion/test/3_5_0/test_vt_SizingZone.osm new file mode 100644 index 0000000000..14799e8231 --- /dev/null +++ b/src/osversion/test/3_5_0/test_vt_SizingZone.osm @@ -0,0 +1,90 @@ + +OS:Version, + {f73a9925-c006-46f5-aa5e-805888055335}, !- Handle + 3.4.0; !- Version Identifier + +OS:ThermalZone, + {ffae81fe-c5d7-4208-8e34-5175df1b96be}, !- Handle + Thermal Zone 1, !- Name + , !- Multiplier + , !- Ceiling Height {m} + , !- Volume {m3} + , !- Floor Area {m2} + , !- Zone Inside Convection Algorithm + , !- Zone Outside Convection Algorithm + , !- Zone Conditioning Equipment List Name + {d357d678-65fb-47b7-adfc-792e3ecf226b}, !- Zone Air Inlet Port List + {45168e55-82f2-4d60-b503-42eb24dc52c0}, !- Zone Air Exhaust Port List + {e857cf00-7da5-4076-b266-7e875125309a}, !- Zone Air Node Name + {709ad23e-a967-46f5-bc3d-97e6bc6939b8}, !- Zone Return Air Port List + , !- Primary Daylighting Control Name + , !- Fraction of Zone Controlled by Primary Daylighting Control + , !- Secondary Daylighting Control Name + , !- Fraction of Zone Controlled by Secondary Daylighting Control + , !- Illuminance Map Name + , !- Group Rendering Name + , !- Thermostat Name + No; !- Use Ideal Air Loads + +OS:Node, + {f6c1adf1-f123-4532-9edc-6f61baf4e887}, !- Handle + Node 1, !- Name + {e857cf00-7da5-4076-b266-7e875125309a}, !- Inlet Port + ; !- Outlet Port + +OS:Connection, + {e857cf00-7da5-4076-b266-7e875125309a}, !- Handle + {ffae81fe-c5d7-4208-8e34-5175df1b96be}, !- Source Object + 11, !- Outlet Port + {f6c1adf1-f123-4532-9edc-6f61baf4e887}, !- Target Object + 2; !- Inlet Port + +OS:PortList, + {d357d678-65fb-47b7-adfc-792e3ecf226b}, !- Handle + {ffae81fe-c5d7-4208-8e34-5175df1b96be}; !- HVAC Component + +OS:PortList, + {45168e55-82f2-4d60-b503-42eb24dc52c0}, !- Handle + {ffae81fe-c5d7-4208-8e34-5175df1b96be}; !- HVAC Component + +OS:PortList, + {709ad23e-a967-46f5-bc3d-97e6bc6939b8}, !- Handle + {ffae81fe-c5d7-4208-8e34-5175df1b96be}; !- HVAC Component + +OS:Sizing:Zone, + {4b9c67db-f832-4d31-9ceb-9d8d761f3866}, !- Handle + {ffae81fe-c5d7-4208-8e34-5175df1b96be}, !- Zone or ZoneList Name + SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method + 14, !- Zone Cooling Design Supply Air Temperature {C} + 11.11, !- Zone Cooling Design Supply Air Temperature Difference {deltaC} + SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method + 40, !- Zone Heating Design Supply Air Temperature {C} + 11.11, !- Zone Heating Design Supply Air Temperature Difference {deltaC} + 0.0085, !- Zone Cooling Design Supply Air Humidity Ratio {kg-H2O/kg-air} + 0.008, !- Zone Heating Design Supply Air Humidity Ratio {kg-H2O/kg-air} + 1.1, !- Zone Heating Sizing Factor + , !- Zone Cooling Sizing Factor + DesignDay, !- Cooling Design Air Flow Method + , !- Cooling Design Air Flow Rate {m3/s} + 0.00081, !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2} + , !- Cooling Minimum Air Flow {m3/s} + 0.1, !- Cooling Minimum Air Flow Fraction + DesignDay, !- Heating Design Air Flow Method + , !- Heating Design Air Flow Rate {m3/s} + 0.0024, !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2} + 0.145, !- Heating Maximum Air Flow {m3/s} + 0.3, !- Heating Maximum Air Flow Fraction + No, !- Account for Dedicated Outdoor Air System + NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy + 18, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} + 19, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + 0.8, !- Design Zone Air Distribution Effectiveness in Cooling Mode + 0.7, !- Design Zone Air Distribution Effectiveness in Heating Mode + 0.6, !- Design Zone Secondary Recirculation Fraction {dimensionless} + 0.5; !- Design Minimum Zone Ventilation Efficiency {dimensionless} + +OS:ZoneHVAC:EquipmentList, + {0daab78e-70cc-44a8-a530-d8934c40c155}, !- Handle + Zone HVAC Equipment List 1, !- Name + {ffae81fe-c5d7-4208-8e34-5175df1b96be}; !- Thermal Zone + diff --git a/src/osversion/test/3_5_0/test_vt_SizingZone.rb b/src/osversion/test/3_5_0/test_vt_SizingZone.rb new file mode 100644 index 0000000000..90a285fd51 --- /dev/null +++ b/src/osversion/test/3_5_0/test_vt_SizingZone.rb @@ -0,0 +1,49 @@ +#require '/usr/local/openstudio-3.4.0/Ruby/openstudio' + +include OpenStudio::Model + +m = Model.new +z = ThermalZone.new(m) +sz = z.sizingZone + +sz.setZoneCoolingDesignSupplyAirTemperatureInputMethod("SupplyAirTemperature") +sz.setZoneCoolingDesignSupplyAirTemperature(14.0) +sz.setZoneCoolingDesignSupplyAirTemperatureDifference(11.11) +sz.setZoneHeatingDesignSupplyAirTemperatureInputMethod("SupplyAirTemperature") +sz.setZoneHeatingDesignSupplyAirTemperature(40.0) +sz.setZoneHeatingDesignSupplyAirTemperatureDifference(11.11) +sz.setZoneCoolingDesignSupplyAirHumidityRatio(0.0085) +sz.setZoneHeatingDesignSupplyAirHumidityRatio(0.008) +sz.setZoneHeatingSizingFactor(1.1) +sz.setCoolingDesignAirFlowMethod("DesignDay") +sz.setCoolingMinimumAirFlowperZoneFloorArea(0.00081) +sz.setCoolingMinimumAirFlowFraction(0.1) +sz.setHeatingDesignAirFlowMethod("DesignDay") +sz.setHeatingMaximumAirFlowperZoneFloorArea(0.0024) +sz.setHeatingMaximumAirFlow(0.145) +sz.setHeatingMaximumAirFlowFraction(0.3) +sz.setAccountforDedicatedOutdoorAirSystem(false) +sz.setDedicatedOutdoorAirSystemControlStrategy("NeutralSupplyAir") +sz.setDedicatedOutdoorAirLowSetpointTemperatureforDesign(18.0) +sz.setDedicatedOutdoorAirHighSetpointTemperatureforDesign(19.0) + +#sz.setZoneLoadSizingMethod("Sensible And Latent Load") +#sz.setZoneLatentCoolingDesignSupplyAirHumidityRatioInputMethod("HumidityRatioDifference") +#sz.setZoneCoolingDesignSupplyAirHumidityRatioDifference(0.0051) +#sz.setZoneLatentHeatingDesignSupplyAirHumidityRatioInputMethod("SupplyAirHumidityRatio") +#sz.setZoneHumidificationDesignSupplyAirHumidityRatio(0.004) + +#dehumSch = ScheduleConstant.new(m) +#dehumSch.setName("dehumSch") +#sz.setZoneHumidistatDehumidificationSetPointSchedule(dehumSch) + +#humSch = ScheduleConstant.new(m) +#humSch.setName("humSch") +#sz.setZoneHumidistatHumidificationSetPointSchedule(humSch) + +sz.setDesignZoneAirDistributionEffectivenessinCoolingMode(0.8) +sz.setDesignZoneAirDistributionEffectivenessinHeatingMode(0.7) +sz.setDesignZoneSecondaryRecirculationFraction(0.6) +sz.setDesignMinimumZoneVentilationEfficiency(0.5) + +m.save('test_vt_SizingZone.osm', true) diff --git a/src/osversion/test/VersionTranslator_GTest.cpp b/src/osversion/test/VersionTranslator_GTest.cpp index dc3c8571fc..3cce3d1271 100644 --- a/src/osversion/test/VersionTranslator_GTest.cpp +++ b/src/osversion/test/VersionTranslator_GTest.cpp @@ -2142,3 +2142,32 @@ TEST_F(OSVersionFixture, update_3_4_0_to_3_5_0_CoilCoolingWaterToAirHeatPumpEqua EXPECT_EQ(19.0, coil.getDouble(13).get()); // Rated Entering Air Wet-Bulb Temperature EXPECT_TRUE(coil.isEmpty(18)); // Ratio of Initial Moisture Evaporation Rate and Steady State Latent Capacity } + +TEST_F(OSVersionFixture, update_3_4_0_to_3_5_0_SizingZone) { + openstudio::path path = resourcesPath() / toPath("osversion/3_5_0/test_vt_SizingZone.osm"); + osversion::VersionTranslator vt; + boost::optional model = vt.loadModel(path); + ASSERT_TRUE(model) << "Failed to load " << path; + + openstudio::path outPath = resourcesPath() / toPath("osversion/3_3_0/test_vt_SizingZone_updated.osm"); + model->save(outPath, true); + + std::vector szs = model->getObjectsByType("OS:Sizing:Zone"); + ASSERT_EQ(1u, szs.size()); + auto& sz = szs.front(); + + // 9 new fields inserted at position 26, without any harcoding + // Field Before + EXPECT_EQ(18.0, sz.getDouble(24).get()); + EXPECT_EQ(19.0, sz.getDouble(25).get()); + + for (unsigned i = 26; i < 35; ++i) { + EXPECT_TRUE(sz.isEmpty(i)); + } + + // Field after + EXPECT_EQ(0.8, sz.getDouble(35).get()); + EXPECT_EQ(0.7, sz.getDouble(36).get()); + EXPECT_EQ(0.6, sz.getDouble(37).get()); + EXPECT_EQ(0.5, sz.getDouble(38).get()); +}