From 3f8f61f3ac02ab0f3fafe5f41bfc58baa4099f1a Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Wed, 9 Jul 2025 11:53:56 -0700 Subject: [PATCH 01/25] Stub hvac.rb code for water-to-water configuration. --- HPXMLtoOpenStudio/resources/hvac.rb | 240 +++++++++++++++++++++------- 1 file changed, 182 insertions(+), 58 deletions(-) diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 795db89639..5b988914db 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -537,6 +537,7 @@ def self.apply_evaporative_cooler(model, hpxml_bldg, cooling_system, hvac_sequen # @return [OpenStudio::Model::AirLoopHVAC] The newly created air loop hvac object def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, hvac_sequential_load_fracs, control_zone, hvac_unavailable_periods) + ground_to_air = false # FIXME: this is the switch to try out ground-to-water unit_multiplier = hpxml_bldg.building_construction.number_of_units if unit_multiplier > 1 @@ -566,54 +567,63 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml if [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard].include? hpxml_header.ground_to_air_heat_pump_model_type # Cooling Coil - clg_total_cap_curve = Model.add_curve_quad_linear( - model, - name: "#{obj_name} clg total cap curve", - coeff: hp_ap.cool_cap_curve_spec[0] - ) - clg_sens_cap_curve = Model.add_curve_quint_linear( - model, - name: "#{obj_name} clg sens cap curve", - coeff: hp_ap.cool_sh_curve_spec[0] - ) - clg_power_curve = Model.add_curve_quad_linear( - model, - name: "#{obj_name} clg power curve", - coeff: hp_ap.cool_power_curve_spec[0] - ) - clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(model, clg_total_cap_curve, clg_sens_cap_curve, clg_power_curve) - clg_coil.setName(obj_name + ' clg coil') - clg_coil.setRatedCoolingCoefficientofPerformance(hp_ap.cool_rated_cops[0]) - clg_coil.setNominalTimeforCondensateRemovaltoBegin(1000) - clg_coil.setRatioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity(1.5) - clg_coil.setRatedAirFlowRate(clg_air_flow_rated) - clg_coil.setRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) - clg_coil.setRatedEnteringWaterTemperature(UnitConversions.convert(80, 'F', 'C')) - clg_coil.setRatedEnteringAirDryBulbTemperature(UnitConversions.convert(80, 'F', 'C')) - clg_coil.setRatedEnteringAirWetBulbTemperature(UnitConversions.convert(67, 'F', 'C')) - # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 - clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) - clg_coil.setRatedSensibleCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity * hp_ap.cool_rated_shr_gross, 'Btu/hr', 'W')) - # Heating Coil - htg_cap_curve = Model.add_curve_quad_linear( - model, - name: "#{obj_name} htg cap curve", - coeff: hp_ap.heat_cap_curve_spec[0] - ) - htg_power_curve = Model.add_curve_quad_linear( - model, - name: "#{obj_name} htg power curve", - coeff: hp_ap.heat_power_curve_spec[0] - ) - htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(model, htg_cap_curve, htg_power_curve) - htg_coil.setName(obj_name + ' htg coil') - htg_coil.setRatedHeatingCoefficientofPerformance(hp_ap.heat_rated_cops[0]) - htg_coil.setRatedAirFlowRate(htg_air_flow_rated) - htg_coil.setRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) - htg_coil.setRatedEnteringWaterTemperature(UnitConversions.convert(60, 'F', 'C')) - htg_coil.setRatedEnteringAirDryBulbTemperature(UnitConversions.convert(70, 'F', 'C')) - # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 - htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + if ground_to_air + clg_total_cap_curve = Model.add_curve_quad_linear( + model, + name: "#{obj_name} clg total cap curve", + coeff: hp_ap.cool_cap_curve_spec[0] + ) + clg_sens_cap_curve = Model.add_curve_quint_linear( + model, + name: "#{obj_name} clg sens cap curve", + coeff: hp_ap.cool_sh_curve_spec[0] + ) + clg_power_curve = Model.add_curve_quad_linear( + model, + name: "#{obj_name} clg power curve", + coeff: hp_ap.cool_power_curve_spec[0] + ) + clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(model, clg_total_cap_curve, clg_sens_cap_curve, clg_power_curve) + clg_coil.setName(obj_name + ' clg coil') + clg_coil.setRatedCoolingCoefficientofPerformance(hp_ap.cool_rated_cops[0]) + clg_coil.setNominalTimeforCondensateRemovaltoBegin(1000) + clg_coil.setRatioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity(1.5) + clg_coil.setRatedAirFlowRate(clg_air_flow_rated) + clg_coil.setRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) + clg_coil.setRatedEnteringWaterTemperature(UnitConversions.convert(80, 'F', 'C')) + clg_coil.setRatedEnteringAirDryBulbTemperature(UnitConversions.convert(80, 'F', 'C')) + clg_coil.setRatedEnteringAirWetBulbTemperature(UnitConversions.convert(67, 'F', 'C')) + # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 + clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + clg_coil.setRatedSensibleCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity * hp_ap.cool_rated_shr_gross, 'Btu/hr', 'W')) + # Heating Coil + htg_cap_curve = Model.add_curve_quad_linear( + model, + name: "#{obj_name} htg cap curve", + coeff: hp_ap.heat_cap_curve_spec[0] + ) + htg_power_curve = Model.add_curve_quad_linear( + model, + name: "#{obj_name} htg power curve", + coeff: hp_ap.heat_power_curve_spec[0] + ) + htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(model, htg_cap_curve, htg_power_curve) + htg_coil.setName(obj_name + ' htg coil') + htg_coil.setRatedHeatingCoefficientofPerformance(hp_ap.heat_rated_cops[0]) + htg_coil.setRatedAirFlowRate(htg_air_flow_rated) + htg_coil.setRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) + htg_coil.setRatedEnteringWaterTemperature(UnitConversions.convert(60, 'F', 'C')) + htg_coil.setRatedEnteringAirDryBulbTemperature(UnitConversions.convert(70, 'F', 'C')) + # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 + htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + else + htg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating.new(model) + htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + clg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling.new(model) + clg_coil.setRatedCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + htg_coil.setCompanionCoolingHeatPump(clg_coil) + clg_coil.setCompanionHeatingHeatPump(htg_coil) + end elsif [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental].include? hpxml_header.ground_to_air_heat_pump_model_type num_speeds = hp_ap.cool_capacity_ratios.size if heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed @@ -876,11 +886,117 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml fan = create_supply_fan(model, obj_name, heat_pump.fan_watts_per_cfm, fan_cfms, heat_pump) add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) - # Unitary System - air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, 40.0) - add_pump_power_ems_program(model, pump, air_loop_unitary, heat_pump) - if (heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed) && (hpxml_header.ground_to_air_heat_pump_model_type == HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental) - add_ghp_pump_mass_flow_rate_ems_program(model, pump, control_zone, htg_coil, clg_coil) + if ground_to_air + # Unitary System + air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, 40.0) + add_pump_power_ems_program(model, pump, air_loop_unitary, heat_pump) + if (heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed) && (hpxml_header.ground_to_air_heat_pump_model_type == HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental) + add_ghp_pump_mass_flow_rate_ems_program(model, pump, control_zone, htg_coil, clg_coil) + end + else + max_water_flow = UnitConversions.convert([heat_pump.heating_capacity, heat_pump.cooling_capacity].max, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s + + plant_loop.addDemandBranchForComponent(htg_coil) + plant_loop.addDemandBranchForComponent(clg_coil) + + hw_loop = Model.add_plant_loop( + model, + name: "#{obj_name} hot water" + ) + + chw_loop = Model.add_plant_loop( + model, + name: "#{obj_name} chilled water" + ) + + hw_loop.addSupplyBranchForComponent(htg_coil) + # hw_loop.addSupplyBranchForComponent(clg_coil) # FIXME: heatpump_plantloop_eir.rb does this + + # chw_loop.addSupplyBranchForComponent(htg_coil) # FIXME: heatpump_plantloop_eir.rb does this + chw_loop.addSupplyBranchForComponent(clg_coil) + + supply_setpoint = Model.add_schedule_constant( + model, + name: "#{obj_name} hot water supply setpoint", + value: 60.000, + limits: EPlus::ScheduleTypeLimitsTemperature + ) + + setpoint_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, supply_setpoint) + setpoint_manager.setName(obj_name + ' hot water setpoint manager') + setpoint_manager.setControlVariable('Temperature') + setpoint_manager.addToNode(hw_loop.supplyOutletNode) + + loop_sizing = hw_loop.sizingPlant + loop_sizing.setLoopType('Heating') + loop_sizing.setDesignLoopExitTemperature(60.000) + loop_sizing.setLoopDesignTemperatureDifference(11.111) + + htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) + htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + bb_ua = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'deltaF', 'deltaC') * 3.0 # W/K + htg_coil.setUFactorTimesAreaValue(bb_ua) + htg_coil.setMaximumWaterFlowRate(max_water_flow) + htg_coil.setPerformanceInputMethod('NominalCapacity') + htg_coil.setName(obj_name + ' htg coil') + + hw_loop.addDemandBranchForComponent(htg_coil) + + pump = Model.add_pump_variable_speed( + model, + name: "#{obj_name} hot water pump", + rated_power: pump_w + ) + pump.addToNode(hw_loop.supplyInletNode) + + supply_setpoint = Model.add_schedule_constant( + model, + name: "#{obj_name} chilled water supply setpoint", + value: 6.666, + limits: EPlus::ScheduleTypeLimitsTemperature + ) + + setpoint_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, supply_setpoint) + setpoint_manager.setName(obj_name + ' chilled water setpoint manager') + setpoint_manager.setControlVariable('Temperature') + setpoint_manager.addToNode(chw_loop.supplyOutletNode) + + loop_sizing = chw_loop.sizingPlant + loop_sizing.setLoopType('Cooling') + loop_sizing.setDesignLoopExitTemperature(6.666) + loop_sizing.setLoopDesignTemperatureDifference(5.611) + + clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) + clg_coil.setName(obj_name + ' clg coil') + clg_coil.setDesignWaterFlowRate(0.0022) + clg_coil.setDesignAirFlowRate(1.45) + clg_coil.setDesignInletWaterTemperature(6.1) + clg_coil.setDesignInletAirTemperature(25.0) + clg_coil.setDesignOutletAirTemperature(10.0) + clg_coil.setDesignInletAirHumidityRatio(0.012) + clg_coil.setDesignOutletAirHumidityRatio(0.008) + + chw_loop.addDemandBranchForComponent(clg_coil) + + pump = Model.add_pump_variable_speed( + model, + name: "#{obj_name} chilled water pump", + rated_power: pump_w + ) + pump.addToNode(chw_loop.supplyInletNode) + + zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) + zone_hvac.setCapacityControlMethod('CyclingFan') + zone_hvac.setName(obj_name + ' fan coil') + zone_hvac.setMaximumSupplyAirTemperatureInHeatingMode(UnitConversions.convert(120.0, 'F', 'C')) + zone_hvac.setHeatingConvergenceTolerance(0.001) + zone_hvac.setMinimumSupplyAirTemperatureInCoolingMode(UnitConversions.convert(55.0, 'F', 'C')) + zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) + zone_hvac.setCoolingConvergenceTolerance(0.001) + zone_hvac.setMaximumOutdoorAirFlowRate(0.0) + zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert([htg_cfm, clg_cfm].max, 'cfm', 'm^3/s')) + zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) + zone_hvac.addToThermalZone(control_zone) end if heat_pump.is_shared_system @@ -901,13 +1017,17 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml equip.additionalProperties.setFeature('HPXML_ID', heat_pump.id) # Used by reporting measure end - # Air Loop - air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, hvac_sequential_load_fracs, [htg_cfm, clg_cfm].max, heat_pump, hvac_unavailable_periods) + if ground_to_air + # Air Loop + air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, hvac_sequential_load_fracs, [htg_cfm, clg_cfm].max, heat_pump, hvac_unavailable_periods) - # HVAC Installation Quality - apply_installation_quality_ems_program(model, heat_pump, heat_pump, air_loop_unitary, htg_coil, clg_coil, control_zone) + # HVAC Installation Quality + apply_installation_quality_ems_program(model, heat_pump, heat_pump, air_loop_unitary, htg_coil, clg_coil, control_zone) - return air_loop + return air_loop + else + return zone_hvac + end end # Adds the HPXML water-loop heat pump system to the OpenStudio model. @@ -2111,6 +2231,8 @@ def self.add_fan_pump_disaggregation_ems_program(model, fan_or_pump, htg_object, else if clg_object.is_a? OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial var = 'Evaporative Cooler Water Volume' + elsif clg_object.is_a? OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling + var = 'Heat Pump Electricity Energy' else var = 'Cooling Coil Total Cooling Energy' end @@ -2130,6 +2252,8 @@ def self.add_fan_pump_disaggregation_ems_program(model, fan_or_pump, htg_object, var = 'Baseboard Total Heating Energy' elsif htg_object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil var = 'Fan Coil Heating Energy' + elsif htg_object.is_a? OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating + var = 'Heat Pump Electricity Energy' else var = 'Heating Coil Heating Energy' end From ee3086d0253c6ed9a76449d1ae4c2effa0237823 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Wed, 9 Jul 2025 11:54:33 -0700 Subject: [PATCH 02/25] Update simulation output reporting measure for new water-to-water objects. --- ReportSimulationOutput/measure.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ReportSimulationOutput/measure.rb b/ReportSimulationOutput/measure.rb index 7de761ae35..19d7dd0d31 100644 --- a/ReportSimulationOutput/measure.rb +++ b/ReportSimulationOutput/measure.rb @@ -2999,6 +2999,9 @@ def get_object_outputs_by_key(model, object, class_name) elsif object.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized return { [FT::Elec, EUT::Heating] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy"] } + elsif object.to_HeatPumpWaterToWaterEquationFitHeating.is_initialized + return { [FT::Elec, EUT::Heating] => ["Heat Pump #{EPlus::FuelTypeElectricity} Energy"] } + elsif object.to_ZoneHVACBaseboardConvectiveElectric.is_initialized if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get return { [FT::Elec, EUT::HeatingHeatPumpBackup] => ["Baseboard #{EPlus::FuelTypeElectricity} Energy"] } @@ -3048,6 +3051,9 @@ def get_object_outputs_by_key(model, object, class_name) elsif object.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized return { [FT::Elec, EUT::Cooling] => ["Cooling Coil #{EPlus::FuelTypeElectricity} Energy"] } + elsif object.to_HeatPumpWaterToWaterEquationFitCooling.is_initialized + return { [FT::Elec, EUT::Cooling] => ["Heat Pump #{EPlus::FuelTypeElectricity} Energy"] } + elsif object.to_EvaporativeCoolerDirectResearchSpecial.is_initialized return { [FT::Elec, EUT::Cooling] => ["Evaporative Cooler #{EPlus::FuelTypeElectricity} Energy"] } From beee1c6a1d17e75bc13dd85e50388076f8a5b293 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Wed, 9 Jul 2025 11:55:11 -0700 Subject: [PATCH 03/25] Apply rubocop. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/resources/hvac.rb | 18 +++++++++--------- ReportSimulationOutput/measure.xml | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 2131a640bb..416337630f 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - e3931754-a1ea-4eca-9b57-1616feee2370 - 2025-06-30T17:13:22Z + 58777891-f52c-4cac-aced-22b7ad318aaa + 2025-07-09T18:54:53Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -414,7 +414,7 @@ hvac.rb rb resource - 7475293B + 3E65E254 hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 5b988914db..6d1d065b30 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -895,7 +895,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml end else max_water_flow = UnitConversions.convert([heat_pump.heating_capacity, heat_pump.cooling_capacity].max, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s - + plant_loop.addDemandBranchForComponent(htg_coil) plant_loop.addDemandBranchForComponent(clg_coil) @@ -908,7 +908,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml model, name: "#{obj_name} chilled water" ) - + hw_loop.addSupplyBranchForComponent(htg_coil) # hw_loop.addSupplyBranchForComponent(clg_coil) # FIXME: heatpump_plantloop_eir.rb does this @@ -926,12 +926,12 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml setpoint_manager.setName(obj_name + ' hot water setpoint manager') setpoint_manager.setControlVariable('Temperature') setpoint_manager.addToNode(hw_loop.supplyOutletNode) - + loop_sizing = hw_loop.sizingPlant loop_sizing.setLoopType('Heating') loop_sizing.setDesignLoopExitTemperature(60.000) loop_sizing.setLoopDesignTemperatureDifference(11.111) - + htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) bb_ua = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'deltaF', 'deltaC') * 3.0 # W/K @@ -939,7 +939,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml htg_coil.setMaximumWaterFlowRate(max_water_flow) htg_coil.setPerformanceInputMethod('NominalCapacity') htg_coil.setName(obj_name + ' htg coil') - + hw_loop.addDemandBranchForComponent(htg_coil) pump = Model.add_pump_variable_speed( @@ -960,12 +960,12 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml setpoint_manager.setName(obj_name + ' chilled water setpoint manager') setpoint_manager.setControlVariable('Temperature') setpoint_manager.addToNode(chw_loop.supplyOutletNode) - + loop_sizing = chw_loop.sizingPlant loop_sizing.setLoopType('Cooling') loop_sizing.setDesignLoopExitTemperature(6.666) loop_sizing.setLoopDesignTemperatureDifference(5.611) - + clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) clg_coil.setName(obj_name + ' clg coil') clg_coil.setDesignWaterFlowRate(0.0022) @@ -975,7 +975,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml clg_coil.setDesignOutletAirTemperature(10.0) clg_coil.setDesignInletAirHumidityRatio(0.012) clg_coil.setDesignOutletAirHumidityRatio(0.008) - + chw_loop.addDemandBranchForComponent(clg_coil) pump = Model.add_pump_variable_speed( @@ -983,7 +983,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml name: "#{obj_name} chilled water pump", rated_power: pump_w ) - pump.addToNode(chw_loop.supplyInletNode) + pump.addToNode(chw_loop.supplyInletNode) zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) zone_hvac.setCapacityControlMethod('CyclingFan') diff --git a/ReportSimulationOutput/measure.xml b/ReportSimulationOutput/measure.xml index da41d2ff8c..6c9eb3c43a 100644 --- a/ReportSimulationOutput/measure.xml +++ b/ReportSimulationOutput/measure.xml @@ -3,8 +3,8 @@ 3.1 report_simulation_output df9d170c-c21a-4130-866d-0d46b06073fd - d3ac5a9d-8471-4bdb-9d74-ed180340e4cb - 2025-06-06T21:50:10Z + 7fd2681c-599e-48b9-a98e-60041bea7496 + 2025-07-09T18:54:55Z 9BF1E6AC ReportSimulationOutput HPXML Simulation Output Report @@ -1991,7 +1991,7 @@ measure.rb rb script - 41995180 + D6F39612 test_report_sim_output.rb From 2ca6b4fbdafab28f681f2d665e0bee4ac8eb27ad Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Wed, 9 Jul 2025 14:53:17 -0700 Subject: [PATCH 04/25] Try the eir-formulation objects with fields for curves. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/resources/hvac.rb | 23 ++++++++++++++--------- ReportSimulationOutput/measure.rb | 4 ++-- ReportSimulationOutput/measure.xml | 6 +++--- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 416337630f..bd1c287c22 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 58777891-f52c-4cac-aced-22b7ad318aaa - 2025-07-09T18:54:53Z + b4862e6c-fefa-4a2b-92f6-2aa66b452d0e + 2025-07-09T21:30:14Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -414,7 +414,7 @@ hvac.rb rb resource - 3E65E254 + A0001A93 hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 6d1d065b30..0002d5403e 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -538,6 +538,7 @@ def self.apply_evaporative_cooler(model, hpxml_bldg, cooling_system, hvac_sequen def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, hvac_sequential_load_fracs, control_zone, hvac_unavailable_periods) ground_to_air = false # FIXME: this is the switch to try out ground-to-water + equation_fit = false # FIXME: equation fit vs eir-formulated unit_multiplier = hpxml_bldg.building_construction.number_of_units if unit_multiplier > 1 @@ -617,10 +618,17 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) else - htg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating.new(model) - htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - clg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling.new(model) - clg_coil.setRatedCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + if equation_fit + htg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating.new(model) + htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + clg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling.new(model) + clg_coil.setRatedCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + else + htg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRHeating.new(model) + htg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + clg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRCooling.new(model) + clg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + end htg_coil.setCompanionCoolingHeatPump(clg_coil) clg_coil.setCompanionHeatingHeatPump(htg_coil) end @@ -910,9 +918,6 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml ) hw_loop.addSupplyBranchForComponent(htg_coil) - # hw_loop.addSupplyBranchForComponent(clg_coil) # FIXME: heatpump_plantloop_eir.rb does this - - # chw_loop.addSupplyBranchForComponent(htg_coil) # FIXME: heatpump_plantloop_eir.rb does this chw_loop.addSupplyBranchForComponent(clg_coil) supply_setpoint = Model.add_schedule_constant( @@ -2231,7 +2236,7 @@ def self.add_fan_pump_disaggregation_ems_program(model, fan_or_pump, htg_object, else if clg_object.is_a? OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial var = 'Evaporative Cooler Water Volume' - elsif clg_object.is_a? OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling + elsif clg_object.is_a?(OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling) || clg_object.is_a?(OpenStudio::Model::HeatPumpPlantLoopEIRCooling) var = 'Heat Pump Electricity Energy' else var = 'Cooling Coil Total Cooling Energy' @@ -2252,7 +2257,7 @@ def self.add_fan_pump_disaggregation_ems_program(model, fan_or_pump, htg_object, var = 'Baseboard Total Heating Energy' elsif htg_object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil var = 'Fan Coil Heating Energy' - elsif htg_object.is_a? OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating + elsif htg_object.is_a?(OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating) || htg_object.is_a?(OpenStudio::Model::HeatPumpPlantLoopEIRHeating) var = 'Heat Pump Electricity Energy' else var = 'Heating Coil Heating Energy' diff --git a/ReportSimulationOutput/measure.rb b/ReportSimulationOutput/measure.rb index 19d7dd0d31..b942e2508a 100644 --- a/ReportSimulationOutput/measure.rb +++ b/ReportSimulationOutput/measure.rb @@ -2999,7 +2999,7 @@ def get_object_outputs_by_key(model, object, class_name) elsif object.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized return { [FT::Elec, EUT::Heating] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy"] } - elsif object.to_HeatPumpWaterToWaterEquationFitHeating.is_initialized + elsif object.to_HeatPumpWaterToWaterEquationFitHeating.is_initialized || object.to_HeatPumpPlantLoopEIRHeating.is_initialized return { [FT::Elec, EUT::Heating] => ["Heat Pump #{EPlus::FuelTypeElectricity} Energy"] } elsif object.to_ZoneHVACBaseboardConvectiveElectric.is_initialized @@ -3051,7 +3051,7 @@ def get_object_outputs_by_key(model, object, class_name) elsif object.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized return { [FT::Elec, EUT::Cooling] => ["Cooling Coil #{EPlus::FuelTypeElectricity} Energy"] } - elsif object.to_HeatPumpWaterToWaterEquationFitCooling.is_initialized + elsif object.to_HeatPumpWaterToWaterEquationFitCooling.is_initialized || object.to_HeatPumpPlantLoopEIRCooling.is_initialized return { [FT::Elec, EUT::Cooling] => ["Heat Pump #{EPlus::FuelTypeElectricity} Energy"] } elsif object.to_EvaporativeCoolerDirectResearchSpecial.is_initialized diff --git a/ReportSimulationOutput/measure.xml b/ReportSimulationOutput/measure.xml index 6c9eb3c43a..05024ca686 100644 --- a/ReportSimulationOutput/measure.xml +++ b/ReportSimulationOutput/measure.xml @@ -3,8 +3,8 @@ 3.1 report_simulation_output df9d170c-c21a-4130-866d-0d46b06073fd - 7fd2681c-599e-48b9-a98e-60041bea7496 - 2025-07-09T18:54:55Z + aab3b033-2f19-43ae-8a3c-8b8f3ce14390 + 2025-07-09T21:30:17Z 9BF1E6AC ReportSimulationOutput HPXML Simulation Output Report @@ -1991,7 +1991,7 @@ measure.rb rb script - D6F39612 + A07F3745 test_report_sim_output.rb From 8d2047ce38f63519d282af03c109ebed0c8a1fb7 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 17 Jul 2025 15:43:42 -0700 Subject: [PATCH 05/25] Avoid using blower fan inputs for fan coil. --- HPXMLtoOpenStudio/resources/hvac.rb | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 0002d5403e..1473d6c82f 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -884,14 +884,25 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml demand_outlet_pipe.addToNode(plant_loop.demandOutletNode) # Fan - fan_cfms = [] - hp_ap.cool_capacity_ratios.each do |capacity_ratio| - fan_cfms << clg_cfm * capacity_ratio - end - hp_ap.heat_capacity_ratios.each do |capacity_ratio| - fan_cfms << htg_cfm * capacity_ratio + if ground_to_air + fan_cfms = [] + hp_ap.cool_capacity_ratios.each do |capacity_ratio| + fan_cfms << clg_cfm * capacity_ratio + end + hp_ap.heat_capacity_ratios.each do |capacity_ratio| + fan_cfms << htg_cfm * capacity_ratio + end + fan_watts_per_cfm = heat_pump.fan_watts_per_cfm + else + if heat_pump.cooling_capacity > 1.0 + fan_cfm = RatedCFMPerTon * UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'ton') # CFM + else + fan_cfm = RatedCFMPerTon * UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'ton') # CFM + end + fan_watts_per_cfm = 0.0 + fan_cfms = [fan_cfm] end - fan = create_supply_fan(model, obj_name, heat_pump.fan_watts_per_cfm, fan_cfms, heat_pump) + fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) if ground_to_air From 0abb029f36852437cacf2ef4eaca09868317e7f8 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 22 Jul 2025 09:55:19 -0700 Subject: [PATCH 06/25] Add a switch for fan coil vs baseboard/panel zone hvac. --- HPXMLtoOpenStudio/measure.xml | 6 +-- HPXMLtoOpenStudio/resources/hvac.rb | 84 +++++++++++++++++++---------- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index b79772d82a..b9644f07cb 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - a16b2d55-6873-4e13-8e46-16ff2d5f6f0b - 2025-07-17T22:44:41Z + 38ca05ce-62bc-47a2-82b6-56c3fbaaa286 + 2025-07-22T16:54:47Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -414,7 +414,7 @@ hvac.rb rb resource - 5680F49F + 90E8CC40 hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 1473d6c82f..15e5dd30ec 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -539,6 +539,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml hvac_sequential_load_fracs, control_zone, hvac_unavailable_periods) ground_to_air = false # FIXME: this is the switch to try out ground-to-water equation_fit = false # FIXME: equation fit vs eir-formulated + fan_coil = false # FIXME: fan coil vs baseboard/panel unit_multiplier = hpxml_bldg.building_construction.number_of_units if unit_multiplier > 1 @@ -902,8 +903,11 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml fan_watts_per_cfm = 0.0 fan_cfms = [fan_cfm] end - fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) - add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) + + if ground_to_air || fan_coil + fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) + add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) + end if ground_to_air # Unitary System @@ -948,14 +952,21 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml loop_sizing.setDesignLoopExitTemperature(60.000) loop_sizing.setLoopDesignTemperatureDifference(11.111) - htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) - htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + if fan_coil + htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) + htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + htg_coil.setPerformanceInputMethod('NominalCapacity') + else + htg_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model) + htg_coil.setConvergenceTolerance(0.001) + htg_coil.setHeatingDesignCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + htg_coil.setHeatingDesignCapacityMethod('HeatingDesignCapacity') + end + bb_ua = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'deltaF', 'deltaC') * 3.0 # W/K htg_coil.setUFactorTimesAreaValue(bb_ua) htg_coil.setMaximumWaterFlowRate(max_water_flow) - htg_coil.setPerformanceInputMethod('NominalCapacity') htg_coil.setName(obj_name + ' htg coil') - hw_loop.addDemandBranchForComponent(htg_coil) pump = Model.add_pump_variable_speed( @@ -982,16 +993,24 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml loop_sizing.setDesignLoopExitTemperature(6.666) loop_sizing.setLoopDesignTemperatureDifference(5.611) - clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) - clg_coil.setName(obj_name + ' clg coil') - clg_coil.setDesignWaterFlowRate(0.0022) - clg_coil.setDesignAirFlowRate(1.45) - clg_coil.setDesignInletWaterTemperature(6.1) - clg_coil.setDesignInletAirTemperature(25.0) - clg_coil.setDesignOutletAirTemperature(10.0) - clg_coil.setDesignInletAirHumidityRatio(0.012) - clg_coil.setDesignOutletAirHumidityRatio(0.008) + if fan_coil + clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) + clg_coil.setDesignWaterFlowRate(0.0022) + clg_coil.setDesignAirFlowRate(1.45) + clg_coil.setDesignInletWaterTemperature(6.1) + clg_coil.setDesignInletAirTemperature(25.0) + clg_coil.setDesignOutletAirTemperature(10.0) + clg_coil.setDesignInletAirHumidityRatio(0.012) + clg_coil.setDesignOutletAirHumidityRatio(0.008) + else + clg_coil = OpenStudio::Model::CoilCoolingWaterPanelRadiant.new(model) + # clg_coil.setCoolingDesignCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + clg_coil.setCoolingDesignCapacity(100.0) + clg_coil.setCoolingDesignCapacityMethod('CoolingDesignCapacity') + # clg_coil.setMaximumChilledWaterFlowRate(0.0022) + end + clg_coil.setName(obj_name + ' clg coil') chw_loop.addDemandBranchForComponent(clg_coil) pump = Model.add_pump_variable_speed( @@ -1001,18 +1020,29 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml ) pump.addToNode(chw_loop.supplyInletNode) - zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) - zone_hvac.setCapacityControlMethod('CyclingFan') - zone_hvac.setName(obj_name + ' fan coil') - zone_hvac.setMaximumSupplyAirTemperatureInHeatingMode(UnitConversions.convert(120.0, 'F', 'C')) - zone_hvac.setHeatingConvergenceTolerance(0.001) - zone_hvac.setMinimumSupplyAirTemperatureInCoolingMode(UnitConversions.convert(55.0, 'F', 'C')) - zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) - zone_hvac.setCoolingConvergenceTolerance(0.001) - zone_hvac.setMaximumOutdoorAirFlowRate(0.0) - zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert([htg_cfm, clg_cfm].max, 'cfm', 'm^3/s')) - zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) - zone_hvac.addToThermalZone(control_zone) + if fan_coil + zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) + zone_hvac.setCapacityControlMethod('CyclingFan') + zone_hvac.setName(obj_name + ' fan coil') + zone_hvac.setMaximumSupplyAirTemperatureInHeatingMode(UnitConversions.convert(120.0, 'F', 'C')) + zone_hvac.setHeatingConvergenceTolerance(0.001) + zone_hvac.setMinimumSupplyAirTemperatureInCoolingMode(UnitConversions.convert(55.0, 'F', 'C')) + zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) + zone_hvac.setCoolingConvergenceTolerance(0.001) + zone_hvac.setMaximumOutdoorAirFlowRate(0.0) + zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert([htg_cfm, clg_cfm].max, 'cfm', 'm^3/s')) + zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) + zone_hvac.addToThermalZone(control_zone) + else + zone_hvac_htg = OpenStudio::Model::ZoneHVACBaseboardConvectiveWater.new(model, model.alwaysOnDiscreteSchedule, htg_coil) + zone_hvac_htg.setName(obj_name + ' baseboard') + zone_hvac_htg.addToThermalZone(control_zone) + + zone_hvac_clg = OpenStudio::Model::ZoneHVACCoolingPanelRadiantConvectiveWater.new(model) + zone_hvac_clg.setCoolingCoil(clg_coil) + zone_hvac_clg.setName(obj_name + ' panel') + zone_hvac_clg.addToThermalZone(control_zone) + end end if heat_pump.is_shared_system From 4847177aac1b785c898bfbe63fb7b09b1da70700 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 11:44:04 -0700 Subject: [PATCH 07/25] Update the build measure for new ground-to-water heat pump type. --- BuildResidentialHPXML/README.md | 34 +++++++++++------------ BuildResidentialHPXML/measure.rb | 46 +++++++++++++++++++------------ BuildResidentialHPXML/measure.xml | 44 +++++++++++++++-------------- 3 files changed, 70 insertions(+), 54 deletions(-) diff --git a/BuildResidentialHPXML/README.md b/BuildResidentialHPXML/README.md index ca91d3caac..72dd74dfa2 100644 --- a/BuildResidentialHPXML/README.md +++ b/BuildResidentialHPXML/README.md @@ -2544,7 +2544,7 @@ The type of heat pump. Use 'none' if there is no heat pump. - **Required:** ``true`` -- **Choices:** `none`, `air-to-air`, `mini-split`, `ground-to-air`, `packaged terminal heat pump`, `room air conditioner with reverse cycle` +- **Choices:** `none`, `air-to-air`, `mini-split`, `ground-to-air`, `ground-to-water w/ Ductless Fan Coil`, `packaged terminal heat pump`, `room air conditioner with reverse cycle` - **Default:** `none` @@ -2567,7 +2567,7 @@ The compressor type of the heat pump. Required for air-to-air, mini-split and gr **Heat Pump: Heating Efficiency Type** -The heating efficiency type of heat pump. System types air-to-air and mini-split use HSPF or HSPF2. System types ground-to-air, packaged terminal heat pump and room air conditioner with reverse cycle use COP. +The heating efficiency type of heat pump. System types air-to-air and mini-split use HSPF or HSPF2. System types ground-to-air, ground-to-water, packaged terminal heat pump and room air conditioner with reverse cycle use COP. - **Name:** ``heat_pump_heating_efficiency_type`` - **Type:** ``Choice`` @@ -2597,7 +2597,7 @@ The rated heating efficiency value of the heat pump. **Heat Pump: Cooling Efficiency Type** -The cooling efficiency type of heat pump. System types air-to-air and mini-split use SEER or SEER2. System types ground-to-air, packaged terminal heat pump and room air conditioner with reverse cycle use EER. +The cooling efficiency type of heat pump. System types air-to-air and mini-split use SEER or SEER2. System types ground-to-air, ground-to-water, packaged terminal heat pump and room air conditioner with reverse cycle use EER. - **Name:** ``heat_pump_cooling_efficiency_type`` - **Type:** ``Choice`` @@ -2667,7 +2667,7 @@ The maximum capacity limit applied to the auto-sizing methodology. If not provid **Heat Pump: Heating Capacity Fraction at 17F** -The output heating capacity of the heat pump at 17F divided by the above nominal heating capacity at 47F. Applies to all heat pump types except ground-to-air. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. +The output heating capacity of the heat pump at 17F divided by the above nominal heating capacity at 47F. Applies to all heat pump types except ground-to-air and ground-to-water. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. - **Name:** ``heat_pump_heating_capacity_fraction_17_f`` - **Type:** ``Double`` @@ -2753,7 +2753,7 @@ The cooling load served by the heat pump. **Heat Pump: Compressor Lockout Temperature** -The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. +The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air and ground-to-water. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. - **Name:** ``heat_pump_compressor_lockout_temp`` - **Type:** ``Double`` @@ -2895,7 +2895,7 @@ The auto-sizing methodology to use when the heat pump backup capacity is not pro **Heat Pump: Is Ducted** -Whether the heat pump is ducted or not. Only used for mini-split. It's assumed that air-to-air and ground-to-air are ducted, and packaged terminal heat pump and room air conditioner with reverse cycle are not ducted. If not provided, assumes not ducted. +Whether the heat pump is ducted or not. Only used for mini-split. It's assumed that air-to-air and ground-to-air are ducted, and packaged terminal heat pump, room air conditioner with reverse cycle, and ground-to-water are not ducted. If not provided, assumes not ducted. - **Name:** ``heat_pump_is_ducted`` - **Type:** ``Boolean`` @@ -3159,7 +3159,7 @@ Maximum speed efficiency COP values of cooling detailed performance data if avai **Geothermal Loop: Configuration** -Configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see Ground-to-Air Heat Pump) is used. +Configuration of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see Ground-to-Air Heat Pump) is used. - **Name:** ``geothermal_loop_configuration`` - **Type:** ``Choice`` @@ -3173,7 +3173,7 @@ Configuration of the geothermal loop. Only applies to ground-to-air heat pump ty **Geothermal Loop: Borefield Configuration** -Borefield configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Borefield configuration of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_borefield_configuration`` - **Type:** ``Choice`` @@ -3187,7 +3187,7 @@ Borefield configuration of the geothermal loop. Only applies to ground-to-air he **Geothermal Loop: Loop Flow** -Water flow rate through the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. +Water flow rate through the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_loop_flow`` - **Type:** ``Double`` @@ -3201,7 +3201,7 @@ Water flow rate through the geothermal loop. Only applies to ground-to-air heat **Geothermal Loop: Boreholes Count** -Number of boreholes. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. +Number of boreholes. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_count`` - **Type:** ``Integer`` @@ -3215,7 +3215,7 @@ Number of boreholes. Only applies to ground-to-air heat pump type. If not provid **Geothermal Loop: Boreholes Length** -Average length of each borehole (vertical). Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. +Average length of each borehole (vertical). Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_length`` - **Type:** ``Double`` @@ -3229,7 +3229,7 @@ Average length of each borehole (vertical). Only applies to ground-to-air heat p **Geothermal Loop: Boreholes Spacing** -Distance between bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Distance between bores. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_spacing`` - **Type:** ``Double`` @@ -3243,7 +3243,7 @@ Distance between bores. Only applies to ground-to-air heat pump type. If not pro **Geothermal Loop: Boreholes Diameter** -Diameter of bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Diameter of bores. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_diameter`` - **Type:** ``Double`` @@ -3257,7 +3257,7 @@ Diameter of bores. Only applies to ground-to-air heat pump type. If not provided **Geothermal Loop: Grout Type** -Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Grout type of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_grout_type`` - **Type:** ``Choice`` @@ -3271,7 +3271,7 @@ Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. **Geothermal Loop: Pipe Type** -Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Pipe type of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_pipe_type`` - **Type:** ``Choice`` @@ -3285,7 +3285,7 @@ Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. **Geothermal Loop: Pipe Diameter** -Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Pipe diameter of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_pipe_diameter`` - **Type:** ``Choice`` @@ -4433,7 +4433,7 @@ Number of bedrooms served (directly or indirectly) by the water heater. Only nee **Water Heater: Uses Desuperheater** -Requires that the dwelling unit has a air-to-air, mini-split, or ground-to-air heat pump or a central air conditioner or mini-split air conditioner. If not provided, assumes no desuperheater. +Requires that the dwelling unit has a air-to-air, mini-split, ground-to-air, or ground-to-water heat pump or a central air conditioner or mini-split air conditioner. If not provided, assumes no desuperheater. - **Name:** ``water_heater_uses_desuperheater`` - **Type:** ``Boolean`` diff --git a/BuildResidentialHPXML/measure.rb b/BuildResidentialHPXML/measure.rb index fec02ea5d6..719eae93dc 100644 --- a/BuildResidentialHPXML/measure.rb +++ b/BuildResidentialHPXML/measure.rb @@ -1358,6 +1358,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument heat_pump_type_choices << HPXML::HVACTypeHeatPumpAirToAir heat_pump_type_choices << HPXML::HVACTypeHeatPumpMiniSplit heat_pump_type_choices << HPXML::HVACTypeHeatPumpGroundToAir + heat_pump_type_choices << "#{HPXML::HVACTypeHeatPumpGroundToWater} w/ Ductless Fan Coil" heat_pump_type_choices << HPXML::HVACTypeHeatPumpPTHP heat_pump_type_choices << HPXML::HVACTypeHeatPumpRoom @@ -1399,7 +1400,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_heating_efficiency_type', heat_pump_heating_efficiency_type_choices, true) arg.setDisplayName('Heat Pump: Heating Efficiency Type') - arg.setDescription("The heating efficiency type of heat pump. System types #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit} use #{HPXML::UnitsHSPF} or #{HPXML::UnitsHSPF2}. System types #{HPXML::HVACTypeHeatPumpGroundToAir}, #{HPXML::HVACTypeHeatPumpPTHP} and #{HPXML::HVACTypeHeatPumpRoom} use #{HPXML::UnitsCOP}.") + arg.setDescription("The heating efficiency type of heat pump. System types #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit} use #{HPXML::UnitsHSPF} or #{HPXML::UnitsHSPF2}. System types #{HPXML::HVACTypeHeatPumpGroundToAir}, #{HPXML::HVACTypeHeatPumpGroundToWater}, #{HPXML::HVACTypeHeatPumpPTHP} and #{HPXML::HVACTypeHeatPumpRoom} use #{HPXML::UnitsCOP}.") arg.setDefaultValue(HPXML::UnitsHSPF) args << arg @@ -1411,7 +1412,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('heat_pump_cooling_efficiency_type', cooling_efficiency_type_choices, true) arg.setDisplayName('Heat Pump: Cooling Efficiency Type') - arg.setDescription("The cooling efficiency type of heat pump. System types #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit} use #{HPXML::UnitsSEER} or #{HPXML::UnitsSEER2}. System types #{HPXML::HVACTypeHeatPumpGroundToAir}, #{HPXML::HVACTypeHeatPumpPTHP} and #{HPXML::HVACTypeHeatPumpRoom} use #{HPXML::UnitsEER}.") + arg.setDescription("The cooling efficiency type of heat pump. System types #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpMiniSplit} use #{HPXML::UnitsSEER} or #{HPXML::UnitsSEER2}. System types #{HPXML::HVACTypeHeatPumpGroundToAir}, #{HPXML::HVACTypeHeatPumpGroundToWater}, #{HPXML::HVACTypeHeatPumpPTHP} and #{HPXML::HVACTypeHeatPumpRoom} use #{HPXML::UnitsEER}.") arg.setDefaultValue(HPXML::UnitsSEER) args << arg @@ -1440,7 +1441,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_heating_capacity_fraction_17_f', false) arg.setDisplayName('Heat Pump: Heating Capacity Fraction at 17F') - arg.setDescription("The output heating capacity of the heat pump at 17F divided by the above nominal heating capacity at 47F. Applies to all heat pump types except #{HPXML::HVACTypeHeatPumpGroundToAir}. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used.") + arg.setDescription("The output heating capacity of the heat pump at 17F divided by the above nominal heating capacity at 47F. Applies to all heat pump types except #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater}. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used.") arg.setUnits('Frac') args << arg @@ -1477,7 +1478,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_compressor_lockout_temp', false) arg.setDisplayName('Heat Pump: Compressor Lockout Temperature') - arg.setDescription("The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than #{HPXML::HVACTypeHeatPumpGroundToAir}. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used.") + arg.setDescription("The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater}. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used.") arg.setUnits('F') args << arg @@ -1534,7 +1535,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeBoolArgument('heat_pump_is_ducted', false) arg.setDisplayName('Heat Pump: Is Ducted') - arg.setDescription("Whether the heat pump is ducted or not. Only used for #{HPXML::HVACTypeHeatPumpMiniSplit}. It's assumed that #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpGroundToAir} are ducted, and #{HPXML::HVACTypeHeatPumpPTHP} and #{HPXML::HVACTypeHeatPumpRoom} are not ducted. If not provided, assumes not ducted.") + arg.setDescription("Whether the heat pump is ducted or not. Only used for #{HPXML::HVACTypeHeatPumpMiniSplit}. It's assumed that #{HPXML::HVACTypeHeatPumpAirToAir} and #{HPXML::HVACTypeHeatPumpGroundToAir} are ducted, and #{HPXML::HVACTypeHeatPumpPTHP}, #{HPXML::HVACTypeHeatPumpRoom}, and #{HPXML::HVACTypeHeatPumpGroundToWater} are not ducted. If not provided, assumes not ducted.") args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('heat_pump_airflow_defect_ratio', false) @@ -1673,7 +1674,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geothermal_loop_configuration', geothermal_loop_configuration_choices, false) arg.setDisplayName('Geothermal Loop: Configuration') - arg.setDescription("Configuration of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see Ground-to-Air Heat Pump) is used.") + arg.setDescription("Configuration of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see Ground-to-Air Heat Pump) is used.") args << arg geothermal_loop_borefield_configuration_choices = OpenStudio::StringVector.new @@ -1684,36 +1685,36 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geothermal_loop_borefield_configuration', geothermal_loop_borefield_configuration_choices, false) arg.setDisplayName('Geothermal Loop: Borefield Configuration') - arg.setDescription("Borefield configuration of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Borefield configuration of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geothermal_loop_loop_flow', false) arg.setDisplayName('Geothermal Loop: Loop Flow') - arg.setDescription("Water flow rate through the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Water flow rate through the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used.") arg.setUnits('gpm') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('geothermal_loop_boreholes_count', false) arg.setDisplayName('Geothermal Loop: Boreholes Count') - arg.setDescription("Number of boreholes. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Number of boreholes. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used.") arg.setUnits('#') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geothermal_loop_boreholes_length', false) arg.setDisplayName('Geothermal Loop: Boreholes Length') - arg.setDescription("Average length of each borehole (vertical). Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Average length of each borehole (vertical). Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used.") arg.setUnits('ft') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geothermal_loop_boreholes_spacing', false) arg.setDisplayName('Geothermal Loop: Boreholes Spacing') - arg.setDescription("Distance between bores. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Distance between bores. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") arg.setUnits('ft') args << arg arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geothermal_loop_boreholes_diameter', false) arg.setDisplayName('Geothermal Loop: Boreholes Diameter') - arg.setDescription("Diameter of bores. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Diameter of bores. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") arg.setUnits('in') args << arg @@ -1723,12 +1724,12 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geothermal_loop_grout_type', geothermal_loop_grout_or_pipe_type_choices, false) arg.setDisplayName('Geothermal Loop: Grout Type') - arg.setDescription("Grout type of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Grout type of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") args << arg arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geothermal_loop_pipe_type', geothermal_loop_grout_or_pipe_type_choices, false) arg.setDisplayName('Geothermal Loop: Pipe Type') - arg.setDescription("Pipe type of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Pipe type of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") args << arg geothermal_loop_pipe_diameter_choices = OpenStudio::StringVector.new @@ -1738,7 +1739,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('geothermal_loop_pipe_diameter', geothermal_loop_pipe_diameter_choices, false) arg.setDisplayName('Geothermal Loop: Pipe Diameter') - arg.setDescription("Pipe diameter of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") + arg.setDescription("Pipe diameter of the geothermal loop. Only applies to #{HPXML::HVACTypeHeatPumpGroundToAir} and #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump types. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used.") arg.setUnits('in') args << arg @@ -2331,7 +2332,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeBoolArgument('water_heater_uses_desuperheater', false) arg.setDisplayName('Water Heater: Uses Desuperheater') - arg.setDescription("Requires that the dwelling unit has a #{HPXML::HVACTypeHeatPumpAirToAir}, #{HPXML::HVACTypeHeatPumpMiniSplit}, or #{HPXML::HVACTypeHeatPumpGroundToAir} heat pump or a #{HPXML::HVACTypeCentralAirConditioner} or #{HPXML::HVACTypeMiniSplitAirConditioner} air conditioner. If not provided, assumes no desuperheater.") + arg.setDescription("Requires that the dwelling unit has a #{HPXML::HVACTypeHeatPumpAirToAir}, #{HPXML::HVACTypeHeatPumpMiniSplit}, #{HPXML::HVACTypeHeatPumpGroundToAir}, or #{HPXML::HVACTypeHeatPumpGroundToWater} heat pump or a #{HPXML::HVACTypeCentralAirConditioner} or #{HPXML::HVACTypeMiniSplitAirConditioner} air conditioner. If not provided, assumes no desuperheater.") args << arg water_heater_tank_model_type_choices = OpenStudio::StringVector.new @@ -4028,7 +4029,7 @@ def argument_warnings(args) warning = (args[:geometry_attic_type] == HPXML::AtticTypeConditioned) && (args[:ceiling_assembly_r] > max_uninsulated_ceiling_rvalue) warnings << 'Home with conditioned attic has ceiling insulation.' if warning - warning = (args[:heat_pump_type] != HPXML::HVACTypeHeatPumpGroundToAir) && (!args[:geothermal_loop_configuration].nil? && args[:geothermal_loop_configuration] != Constants::None) + warning = (args[:heat_pump_type] != HPXML::HVACTypeHeatPumpGroundToAir) && (args[:heat_pump_type] != HPXML::HVACTypeHeatPumpGroundToWater) && (!args[:geothermal_loop_configuration].nil? && args[:geothermal_loop_configuration] != Constants::None) warnings << 'Specified an attached geothermal loop but home has no ground source heat pump.' if warning return warnings @@ -6232,6 +6233,10 @@ def self.set_heat_pumps(hpxml_bldg, args) heat_pump_pan_heater_control_type = args[:heat_pump_pan_heater_control_type] end + if heat_pump_type.include?(HPXML::HVACTypeHeatPumpGroundToWater) + heat_pump_type = HPXML::HVACTypeHeatPumpGroundToWater + end + hpxml_bldg.heat_pumps.add(id: "HeatPump#{hpxml_bldg.heat_pumps.size + 1}", heat_pump_type: heat_pump_type, heat_pump_fuel: HPXML::FuelTypeElectricity, @@ -6511,6 +6516,13 @@ def self.set_hvac_distribution(hpxml_bldg, args) fan_coil_distribution_systems << heating_system end end + hpxml_bldg.heat_pumps.each do |heat_pump| + next unless heat_pump.primary_system + + if args[:heat_pump_type].include?('Fan Coil') + fan_coil_distribution_systems << heat_pump + end + end # HydronicDistribution? hpxml_bldg.heating_systems.each do |heating_system| diff --git a/BuildResidentialHPXML/measure.xml b/BuildResidentialHPXML/measure.xml index 3d6aab7333..344e4ea70f 100644 --- a/BuildResidentialHPXML/measure.xml +++ b/BuildResidentialHPXML/measure.xml @@ -3,8 +3,8 @@ 3.1 build_residential_hpxml a13a8983-2b01-4930-8af2-42030b6e4233 - 6e33a723-8fe3-4382-be64-1ba9beb5dfb6 - 2025-08-26T22:05:09Z + 52e24cb7-172f-4894-96c2-a46c2e02e526 + 2025-08-28T18:43:31Z 2C38F48B BuildResidentialHPXML HPXML Builder @@ -2824,6 +2824,10 @@ ground-to-air ground-to-air + + ground-to-water w/ Ductless Fan Coil + ground-to-water w/ Ductless Fan Coil + packaged terminal heat pump packaged terminal heat pump @@ -2859,7 +2863,7 @@ heat_pump_heating_efficiency_type Heat Pump: Heating Efficiency Type - The heating efficiency type of heat pump. System types air-to-air and mini-split use HSPF or HSPF2. System types ground-to-air, packaged terminal heat pump and room air conditioner with reverse cycle use COP. + The heating efficiency type of heat pump. System types air-to-air and mini-split use HSPF or HSPF2. System types ground-to-air, ground-to-water, packaged terminal heat pump and room air conditioner with reverse cycle use COP. Choice true false @@ -2891,7 +2895,7 @@ heat_pump_cooling_efficiency_type Heat Pump: Cooling Efficiency Type - The cooling efficiency type of heat pump. System types air-to-air and mini-split use SEER or SEER2. System types ground-to-air, packaged terminal heat pump and room air conditioner with reverse cycle use EER. + The cooling efficiency type of heat pump. System types air-to-air and mini-split use SEER or SEER2. System types ground-to-air, ground-to-water, packaged terminal heat pump and room air conditioner with reverse cycle use EER. Choice true false @@ -2953,7 +2957,7 @@ heat_pump_heating_capacity_fraction_17_f Heat Pump: Heating Capacity Fraction at 17F - The output heating capacity of the heat pump at 17F divided by the above nominal heating capacity at 47F. Applies to all heat pump types except ground-to-air. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. + The output heating capacity of the heat pump at 17F divided by the above nominal heating capacity at 47F. Applies to all heat pump types except ground-to-air and ground-to-water. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. Double Frac false @@ -3008,7 +3012,7 @@ heat_pump_compressor_lockout_temp Heat Pump: Compressor Lockout Temperature - The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. + The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air and ground-to-water. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. Double F false @@ -3151,7 +3155,7 @@ heat_pump_is_ducted Heat Pump: Is Ducted - Whether the heat pump is ducted or not. Only used for mini-split. It's assumed that air-to-air and ground-to-air are ducted, and packaged terminal heat pump and room air conditioner with reverse cycle are not ducted. If not provided, assumes not ducted. + Whether the heat pump is ducted or not. Only used for mini-split. It's assumed that air-to-air and ground-to-air are ducted, and packaged terminal heat pump, room air conditioner with reverse cycle, and ground-to-water are not ducted. If not provided, assumes not ducted. Boolean false false @@ -3368,7 +3372,7 @@ geothermal_loop_configuration Geothermal Loop: Configuration - Configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. + Configuration of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. Choice false false @@ -3386,7 +3390,7 @@ geothermal_loop_borefield_configuration Geothermal Loop: Borefield Configuration - Borefield configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Borefield configuration of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice false false @@ -3420,7 +3424,7 @@ geothermal_loop_loop_flow Geothermal Loop: Loop Flow - Water flow rate through the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Water flow rate through the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double gpm false @@ -3429,7 +3433,7 @@ geothermal_loop_boreholes_count Geothermal Loop: Boreholes Count - Number of boreholes. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Number of boreholes. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Integer # false @@ -3438,7 +3442,7 @@ geothermal_loop_boreholes_length Geothermal Loop: Boreholes Length - Average length of each borehole (vertical). Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Average length of each borehole (vertical). Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double ft false @@ -3447,7 +3451,7 @@ geothermal_loop_boreholes_spacing Geothermal Loop: Boreholes Spacing - Distance between bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Distance between bores. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double ft false @@ -3456,7 +3460,7 @@ geothermal_loop_boreholes_diameter Geothermal Loop: Boreholes Diameter - Diameter of bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Diameter of bores. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double in false @@ -3465,7 +3469,7 @@ geothermal_loop_grout_type Geothermal Loop: Grout Type - Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Grout type of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice false false @@ -3483,7 +3487,7 @@ geothermal_loop_pipe_type Geothermal Loop: Pipe Type - Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Pipe type of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice false false @@ -3501,7 +3505,7 @@ geothermal_loop_pipe_diameter Geothermal Loop: Pipe Diameter - Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Pipe diameter of the geothermal loop. Only applies to ground-to-air and ground-to-water heat pump types. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.11.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice in false @@ -4786,7 +4790,7 @@ water_heater_uses_desuperheater Water Heater: Uses Desuperheater - Requires that the dwelling unit has a air-to-air, mini-split, or ground-to-air heat pump or a central air conditioner or mini-split air conditioner. If not provided, assumes no desuperheater. + Requires that the dwelling unit has a air-to-air, mini-split, ground-to-air, or ground-to-water heat pump or a central air conditioner or mini-split air conditioner. If not provided, assumes no desuperheater. Boolean false false @@ -8396,7 +8400,7 @@ README.md md readme - AFA1C510 + 40625875 README.md.erb @@ -8413,7 +8417,7 @@ measure.rb rb script - 3BF2C51B + 9F0AC5D1 constants.rb From 6b8d3f8180c910190250ae15e37d6e67093ee719 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 11:44:24 -0700 Subject: [PATCH 08/25] Create a single ground-to-water sample file. --- workflow/hpxml_inputs.json | 4 + .../base-hvac-ground-to-water-heat-pump.xml | 477 ++++++++++++++++++ 2 files changed, 481 insertions(+) create mode 100644 workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml diff --git a/workflow/hpxml_inputs.json b/workflow/hpxml_inputs.json index acfab30dcd..4d4b756ae8 100644 --- a/workflow/hpxml_inputs.json +++ b/workflow/hpxml_inputs.json @@ -2724,6 +2724,10 @@ "parent_hpxml": "sample_files/base-hvac-ground-to-air-heat-pump-1-speed.xml", "simulation_control_ground_to_air_heat_pump_model_type": "experimental" }, + "sample_files/base-hvac-ground-to-water-heat-pump.xml": { + "parent_hpxml": "sample_files/base-hvac-ground-to-air-heat-pump-1-speed.xml", + "heat_pump_type": "ground-to-water w/ Ductless Fan Coil" + }, "sample_files/base-hvac-ground-to-air-heat-pump-2-speed.xml": { "parent_hpxml": "sample_files/base-hvac-ground-to-air-heat-pump-1-speed.xml", "heat_pump_heating_efficiency": 4.0, diff --git a/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml b/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml new file mode 100644 index 0000000000..cae878178d --- /dev/null +++ b/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml @@ -0,0 +1,477 @@ + + + + HPXML + tasks.rb + 2000-01-01T00:00:00-07:00 + create + + + + + + Default + + + + + + + + +
+ CO +
+
+ + proposed workscope + + + + + stand-alone + no units above or below + 180 + + electricity + natural gas + + + + single-family detached + 2.0 + 1.0 + 8.0 + 3 + 2 + 2700.0 + 21600.0 + + + + + 2006 + 5B + + + + USA_CO_Denver.Intl.AP.725650_TMY3 + + USA_CO_Denver.Intl.AP.725650_TMY3.epw + + + + + + + + 50.0 + + ACH + 3.0 + + 21600.0 + + + + + + + + false + + + false + + + + + + + + + + + true + + + + + + + + + + + attic - unvented + 1509.3 + asphalt or fiberglass shingles + 0.7 + 0.92 + 6.0 + + + 2.3 + + + + + + + outside + basement - conditioned + 115.6 + wood siding + 0.7 + 0.92 + + + 13.9 + + + + + + + outside + conditioned space + + + + 1200.0 + wood siding + 0.7 + 0.92 + + gypsum board + + + + 22.7 + + + + + outside + attic - unvented + gable + + + + 225.0 + wood siding + 0.7 + 0.92 + + + 4.0 + + + + + + + ground + basement - conditioned + solid concrete + 8.0 + 1200.0 + 7.0 + + gypsum board + + + + + continuous - exterior + 10.0 + + + continuous - interior + 0.0 + + + + + + + + attic - unvented + conditioned space + ceiling + + + + 1350.0 + + gypsum board + + + + 39.6 + + + + + + + basement - conditioned + 1350.0 + 150.0 + + + + 0.0 + 0.0 + + + + + + 0.0 + 0.0 + + + + 0.0 + 0.0 + + + + + + + 108.0 + 0 + 0.35 + 0.44 + + + light curtains + + 0.67 + + + + + 72.0 + 90 + 0.35 + 0.44 + + + light curtains + + 0.67 + + + + + 108.0 + 180 + 0.35 + 0.44 + + + light curtains + + 0.67 + + + + + 72.0 + 270 + 0.35 + 0.44 + + + light curtains + + 0.67 + + + + + + + + 40.0 + 180 + 4.4 + + + + + + + + + + + + + + ground-to-water + electricity + 36000.0 + 36000.0 + 1.0 + 1.0 + + EER + 16.6 + + + COP + 3.6 + + + + + + 68.0 + 78.0 + + + + + + fan coil + + + + + + + + electricity + storage water heater + conditioned space + 1.0 + 0.94 + + + + + + + + 0.0 + + + + + shower head + false + + + + faucet + false + + + + + + + 1.21 + 380.0 + 0.12 + 1.09 + 27.0 + 6.0 + 3.2 + + + + electricity + conventional + 3.73 + + + + 307.0 + 12 + 0.12 + 1.09 + 22.32 + 4.0 + + + + 650.0 + + + + electricity + false + + + + false + + + + + + interior + 0.4 + + + + + + + interior + 0.1 + + + + + + + interior + 0.25 + + + + + + + exterior + 0.4 + + + + + + + exterior + 0.1 + + + + + + + exterior + 0.25 + + + + + + + + + TV other + + + + other + + + +
+
\ No newline at end of file From 7178f91f256442174cf10f6a801a01d2f9848353 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 11:44:54 -0700 Subject: [PATCH 09/25] Add a ground-to-water schematron entry. --- .../resources/hpxml_schematron/EPvalidator.sch | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch index 127cea9d40..ee4fd94ef9 100644 --- a/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch +++ b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch @@ -1484,8 +1484,8 @@ Expected 0 or 1 element(s) for xpath: AttachedToZone Expected 1 element(s) for xpath: ../../HVACControl - Expected 1 element(s) for xpath: HeatPumpType - Expected HeatPumpType to be 'air-to-air' or 'mini-split' or 'ground-to-air' or 'water-loop-to-air' or 'packaged terminal heat pump' or 'room air conditioner with reverse cycle' + Expected 1 element(s) for xpath: HeatPumpType + Expected HeatPumpType to be 'air-to-air' or 'mini-split' or 'ground-to-air' or 'water-loop-to-air' or 'packaged terminal heat pump' or 'room air conditioner with reverse cycle' Expected 0 or 1 element(s) for xpath: extension/CoolingAutosizingFactor Expected 0 or 1 element(s) for xpath: extension/HeatingAutosizingFactor CoolingAutosizingFactor should be greater than 0.0 @@ -1628,7 +1628,7 @@ - [HeatPumpType=GroundSource] + [HeatPumpType=GroundSourceToAir] Expected 1 or more element(s) for xpath: ../../HVACDistribution/DistributionSystemType/AirDistribution/AirDistributionType[text()="regular velocity"] | ../../HVACDistribution/DistributionSystemType/Other[text()="DSE"] Expected 0 or 1 element(s) for xpath: UnitLocation @@ -1673,6 +1673,13 @@ + + [HeatPumpType=GroundSourceToWater] + + Expected 1 element(s) for xpath: ../../HVACDistribution/DistributionSystemType/AirDistribution/AirDistributionType[text()="fan coil"] + + + [HeatPumpType=GroundSourceWithSharedLoop] From a992ed0d62e27cc13cf4275f95ac2f1369f0c364 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 11:45:23 -0700 Subject: [PATCH 10/25] Add a ground-to-water hpxml heat pump type enum. --- HPXMLtoOpenStudio/resources/hpxml.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/HPXMLtoOpenStudio/resources/hpxml.rb b/HPXMLtoOpenStudio/resources/hpxml.rb index 6be98943da..d98dc66533 100644 --- a/HPXMLtoOpenStudio/resources/hpxml.rb +++ b/HPXMLtoOpenStudio/resources/hpxml.rb @@ -252,6 +252,7 @@ class HPXML < Object HVACTypeFurnace = 'Furnace' HVACTypeHeatPumpAirToAir = 'air-to-air' HVACTypeHeatPumpGroundToAir = 'ground-to-air' + HVACTypeHeatPumpGroundToWater = 'ground-to-water' HVACTypeHeatPumpMiniSplit = 'mini-split' HVACTypeHeatPumpWaterLoopToAir = 'water-loop-to-air' HVACTypeHeatPumpPTHP = 'packaged terminal heat pump' From a2098f4f2f812cce53d823f60e8527a346328bf3 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 11:46:57 -0700 Subject: [PATCH 11/25] Extend defaults, hvac, hvac_sizing resources for ground-to-water; several instances of borrowed ground-to-air placeholder code and comments for TODOs. --- HPXMLtoOpenStudio/measure.xml | 14 +- HPXMLtoOpenStudio/resources/defaults.rb | 368 ++++++++++------- HPXMLtoOpenStudio/resources/hvac.rb | 453 ++++++++++----------- HPXMLtoOpenStudio/resources/hvac_sizing.rb | 64 ++- 4 files changed, 509 insertions(+), 390 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 004d088903..8215e806cc 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 4951e9c1-25c4-40e1-b32b-5f8b64bf49e5 - 2025-08-27T20:55:29Z + e86ae8c1-3fec-48d3-af90-b42d40e5b91b + 2025-08-28T18:43:32Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -348,7 +348,7 @@ defaults.rb rb resource - 8A081587 + C35C7C11
electric_panel.rb @@ -384,7 +384,7 @@ hpxml.rb rb resource - 0F94A077 + 21EB950B hpxml_schema/HPXML.xsd @@ -402,7 +402,7 @@ hpxml_schematron/EPvalidator.sch sch resource - 4BBE1448 + A431C069 hpxml_schematron/iso-schematron.xsd @@ -414,13 +414,13 @@ hvac.rb rb resource - EB030728 + 0997719B hvac_sizing.rb rb resource - 30537BFF + F3DFE229 internal_gains.rb diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 3c7b8d628b..5826c2eb9f 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -2015,7 +2015,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu hpxml_bldg.heat_pumps.each do |heat_pump| next unless heat_pump.compressor_lockout_temp.nil? next unless heat_pump.backup_heating_switchover_temp.nil? - next if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + next if [HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include?(heat_pump.heat_pump_type) if heat_pump.backup_type == HPXML::HeatPumpBackupTypeIntegrated hp_backup_fuel = heat_pump.backup_heating_fuel @@ -2042,7 +2042,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu next if heat_pump.backup_type.nil? next unless heat_pump.backup_heating_lockout_temp.nil? next unless heat_pump.backup_heating_switchover_temp.nil? - next if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + next if [HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include?(heat_pump.heat_pump_type) if heat_pump.backup_type == HPXML::HeatPumpBackupTypeIntegrated hp_backup_fuel = heat_pump.backup_heating_fuel @@ -2080,7 +2080,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu # GSHP pump power hpxml_bldg.heat_pumps.each do |heat_pump| - next unless heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + next unless [HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include?(heat_pump.heat_pump_type) next unless heat_pump.pump_watts_per_ton.nil? heat_pump.pump_watts_per_ton = get_gshp_pump_power() @@ -2099,7 +2099,8 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu hpxml_bldg.heat_pumps.each do |heat_pump| next unless [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit, - HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type + HPXML::HVACTypeHeatPumpGroundToAir, + HPXML::HVACTypeHeatPumpGroundToWater].include? heat_pump.heat_pump_type next unless heat_pump.charge_defect_ratio.nil? heat_pump.charge_defect_ratio = 0.0 @@ -2343,7 +2344,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu set_hvac_cooling_performance(heat_pump, hpxml_header) set_hvac_heating_performance(heat_pump, hpxml_header) - when HPXML::HVACTypeHeatPumpGroundToAir + when HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater set_heat_pump_control_temperatures(heat_pump, runner) set_hvac_cooling_performance(heat_pump, hpxml_header) set_hvac_heating_performance(heat_pump, hpxml_header) @@ -7763,6 +7764,31 @@ def self.set_ground_to_air_heat_pump_cops(heat_pump, cop_ratios, mode) end end + # TODO + def self.set_ground_to_water_heat_pump_cops(heat_pump, cop_ratios, mode) + hp_ap = heat_pump.additional_properties + # Fan/pump adjustments calculations + # Fan power to overcome the static pressure adjustment + # rated_fan_watts_per_cfm = 0.5 * heat_pump.fan_watts_per_cfm # Calculate rated fan power by assuming the power to overcome the ductwork is approximately 50% of the total fan power (ANSI/RESNET/ICC 301 says 0.2 W/cfm is the fan power associated with ductwork, but we don't know if that was a PSC or BPM fan) + rated_fan_watts_per_cfm = 0.25 # FIXME + power_f = rated_fan_watts_per_cfm * HVAC::RatedCFMPerTon / UnitConversions.convert(1.0, 'ton', 'Btu/hr') # W per Btu/hr of capacity + rated_pump_watts_per_ton = 30.0 # ANSI/RESNET/ICC 301, estimated pump power required to overcome the internal resistance of the ground-water heat exchanger under AHRI test conditions for a closed loop system + power_p = rated_pump_watts_per_ton / UnitConversions.convert(1.0, 'ton', 'Btu/hr') # result is in W per Btu/hr of capacity + if mode == :clg + eir_rated = UnitConversions.convert(((1 - UnitConversions.convert(power_f, 'Wh', 'Btu')) / heat_pump.cooling_efficiency_eer - power_f - power_p), 'Wh', 'Btu') + hp_ap.cool_rated_cops = [] + for i in 0..(cop_ratios.size - 1) + hp_ap.cool_rated_cops << 1.0 / eir_rated * cop_ratios[i] + end + elsif mode == :htg + eir_rated = (1 + UnitConversions.convert(power_f, 'Wh', 'Btu')) / heat_pump.heating_efficiency_cop - UnitConversions.convert(power_f + power_p, 'Wh', 'Btu') + hp_ap.heat_rated_cops = [] + for i in 0..(cop_ratios.size - 1) + hp_ap.heat_rated_cops << 1.0 / eir_rated * cop_ratios[i] + end + end + end + # Sets default HVAC cooling performance values. # # @param cooling_system [HPXML::CoolingSystem or HPXML::HeatPump] The HPXML cooling system or heat pump of interest @@ -7799,13 +7825,103 @@ def self.interpolate_seer2(seer2, eer2, seer2_array, seer2_eer2_ratio_array, cop clg_ap.cool_cap_fflow_spec_iq = [0.718664047, 0.41797409, -0.136638137] clg_ap.cool_eir_fflow_spec_iq = [1.143487507, -0.13943972, -0.004047787] - if cooling_system.is_a?(HPXML::HeatPump) && cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir - # Based on RESNET HERS Addendum 82 - clg_ap.cool_rated_shr_gross = 0.708 - clg_ap.cool_rated_cfm_per_ton = HVAC::RatedCFMPerTon + if cooling_system.is_a?(HPXML::HeatPump) + if cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + # Based on RESNET HERS Addendum 82 + clg_ap.cool_rated_shr_gross = 0.708 + clg_ap.cool_rated_cfm_per_ton = HVAC::RatedCFMPerTon + + case hpxml_header.ground_to_air_heat_pump_model_type + when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard + clg_ap.cool_capacity_ratios = [1.0] + + # E+ equation fit coil coefficients generated following approach in Tang's thesis: + # See Appendix B of https://shareok.org/bitstream/handle/11244/10075/Tang_okstate_0664M_1318.pdf?sequence=1&isAllowed=y + # Coefficients generated by catalog data: https://files.climatemaster.com/Genesis-GS-Series-Product-Catalog.pdf, p180 + # Data point taken as rated condition: + # EWT: 80F EAT:80/67F, AFR: 1200cfm, WFR: 4.5gpm + + # Cooling Curves + clg_ap.cool_cap_curve_spec = [[-5.45013866666657, 7.42301402824225, -1.43760846638838, 0.249103937703341, 0.0378875477019811]] + clg_ap.cool_power_curve_spec = [[-4.21572180554818, 0.322682268675807, 4.56870615863483, 0.154605773589744, -0.167531037948482]] + clg_ap.cool_sh_curve_spec = [[0.56143829895505, 18.7079597251858, -19.1482655264078, -0.138154731772664, 0.4823357726442, -0.00164644360129174]] + + cool_cop_ratios = [1.0] + + when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental + case cooling_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage + clg_ap.cool_capacity_ratios = [1.0] + # Cooling Curves + # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool + # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool + # Catalog data from : https://files.climatemaster.com/Genesis-GS-Series-Product-Catalog.pdf, p180 + # Using E+ rated conditions: + # Cooling: Indoor air at 67F WB, 80F DB; Entering water temperature: 85F + clg_ap.cool_cap_ft_spec = [[0.3926140238, 0.0297981297, 0.0000000582, 0.0123906803, -0.0003014284, -0.0001113698]] + clg_ap.cool_eir_ft_spec = [[1.1828664909, -0.0450835550, 0.0009273315, 0.0056194113, 0.0006683467, -0.0007256237]] + clg_ap.cool_cap_fflow_spec = [[0.5068, 0.8099, -0.3165]] + clg_ap.cool_eir_fflow_spec = [[2.0184, -1.6182, 0.5789]] + clg_ap.cool_cap_fwf_spec = [[1.0, 0.0, 0.0]] + clg_ap.cool_eir_fwf_spec = [[1.0, 0.0, 0.0]] + cool_cop_ratios = [1.0] + when HPXML::HVACCompressorTypeTwoStage + clg_ap.cool_capacity_ratios = [0.7353, 1.0] + # Cooling Curves + # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool + # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool + # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf + # Using E+ rated conditions: + # Cooling: Indoor air at 67F WB, 80F DB; Entering water temperature: 85F + clg_ap.cool_cap_ft_spec = [[0.4091067504, 0.0387481208, -0.0000003491, 0.0039166842, -0.0001299475, -0.0002883229], + [0.4423161030, 0.0346534683, 0.0000043691, 0.0046060534, -0.0001393465, -0.0002316000]] + clg_ap.cool_eir_ft_spec = [[1.0242580586, -0.0549907581, 0.0017735749, 0.0186562274, 0.0008900852, -0.0016973518], + [1.0763155558, -0.0396246303, 0.0010677382, 0.0074160145, 0.0006781567, -0.0009009811]] + clg_ap.cool_cap_fflow_spec = [[0.9064, 0.0793, 0.0143], + [0.8551, 0.1688, -0.0238]] + clg_ap.cool_eir_fflow_spec = [[0.7931, 0.2623, -0.0552], + [0.8241, 0.1523, 0.0234]] + clg_ap.cool_cap_fwf_spec = [[0.8387, 0.2903, -0.129], + [0.815, 0.325, -0.14]] + clg_ap.cool_eir_fwf_spec = [[1.7131, -1.3055, 0.5924], + [1.5872, -1.055, 0.4678]] + + # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf + cool_cop_ratios = [1.102827763, 1.0] + when HPXML::HVACCompressorTypeVariableSpeed + clg_ap.cool_capacity_ratios = [0.4802, 1.0] + # Cooling Curves + # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool + # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool + # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf + # Using E+ rated conditions: + # Cooling: Indoor air at 67F WB, 80F DB; Entering water temperature: 85F + clg_ap.cool_cap_ft_spec = [[1.3397293008, -0.0474800765, 0.0021636831, 0.0055773535, -0.0002350114, -0.0002458509], + [1.2143128834, -0.0459226877, 0.0020331628, 0.0086998093, -0.0002669140, -0.0001763187]] + clg_ap.cool_eir_ft_spec = [[-0.0049682877, 0.0554193005, -0.0015790347, -0.0010670650, 0.0011493038, -0.0008236210], + [0.0569949694, 0.0527820535, -0.0015763180, 0.0077339260, 0.0008175629, -0.0007157989]] + clg_ap.cool_cap_fflow_spec = [[1.1092, -0.5299, 0.4312], + [0.9216, -0.1021, 0.1874]] + clg_ap.cool_eir_fflow_spec = [[2.2938, -2.2648, 0.9631], + [1.9175, -1.374, 0.4646]] + clg_ap.cool_cap_fwf_spec = [[1.0386, -0.2037, 0.1651], + [0.8606, 0.2687, -0.1293]] + clg_ap.cool_eir_fwf_spec = [[1.066, 0.052, -0.118], + [1.2961, -0.4762, 0.18]] + + # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf + cool_cop_ratios = [1.059467645, 1.0] + end + end + + set_ground_to_air_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + elsif cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater + # FIXME + + # Based on RESNET HERS Addendum 82 + clg_ap.cool_rated_shr_gross = 0.708 + clg_ap.cool_rated_cfm_per_ton = HVAC::RatedCFMPerTon - case hpxml_header.ground_to_air_heat_pump_model_type - when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard clg_ap.cool_capacity_ratios = [1.0] # E+ equation fit coil coefficients generated following approach in Tang's thesis: @@ -7821,73 +7937,9 @@ def self.interpolate_seer2(seer2, eer2, seer2_array, seer2_eer2_ratio_array, cop cool_cop_ratios = [1.0] - when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental - case cooling_system.compressor_type - when HPXML::HVACCompressorTypeSingleStage - clg_ap.cool_capacity_ratios = [1.0] - # Cooling Curves - # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool - # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool - # Catalog data from : https://files.climatemaster.com/Genesis-GS-Series-Product-Catalog.pdf, p180 - # Using E+ rated conditions: - # Cooling: Indoor air at 67F WB, 80F DB; Entering water temperature: 85F - clg_ap.cool_cap_ft_spec = [[0.3926140238, 0.0297981297, 0.0000000582, 0.0123906803, -0.0003014284, -0.0001113698]] - clg_ap.cool_eir_ft_spec = [[1.1828664909, -0.0450835550, 0.0009273315, 0.0056194113, 0.0006683467, -0.0007256237]] - clg_ap.cool_cap_fflow_spec = [[0.5068, 0.8099, -0.3165]] - clg_ap.cool_eir_fflow_spec = [[2.0184, -1.6182, 0.5789]] - clg_ap.cool_cap_fwf_spec = [[1.0, 0.0, 0.0]] - clg_ap.cool_eir_fwf_spec = [[1.0, 0.0, 0.0]] - cool_cop_ratios = [1.0] - when HPXML::HVACCompressorTypeTwoStage - clg_ap.cool_capacity_ratios = [0.7353, 1.0] - # Cooling Curves - # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool - # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool - # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf - # Using E+ rated conditions: - # Cooling: Indoor air at 67F WB, 80F DB; Entering water temperature: 85F - clg_ap.cool_cap_ft_spec = [[0.4091067504, 0.0387481208, -0.0000003491, 0.0039166842, -0.0001299475, -0.0002883229], - [0.4423161030, 0.0346534683, 0.0000043691, 0.0046060534, -0.0001393465, -0.0002316000]] - clg_ap.cool_eir_ft_spec = [[1.0242580586, -0.0549907581, 0.0017735749, 0.0186562274, 0.0008900852, -0.0016973518], - [1.0763155558, -0.0396246303, 0.0010677382, 0.0074160145, 0.0006781567, -0.0009009811]] - clg_ap.cool_cap_fflow_spec = [[0.9064, 0.0793, 0.0143], - [0.8551, 0.1688, -0.0238]] - clg_ap.cool_eir_fflow_spec = [[0.7931, 0.2623, -0.0552], - [0.8241, 0.1523, 0.0234]] - clg_ap.cool_cap_fwf_spec = [[0.8387, 0.2903, -0.129], - [0.815, 0.325, -0.14]] - clg_ap.cool_eir_fwf_spec = [[1.7131, -1.3055, 0.5924], - [1.5872, -1.055, 0.4678]] - - # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf - cool_cop_ratios = [1.102827763, 1.0] - when HPXML::HVACCompressorTypeVariableSpeed - clg_ap.cool_capacity_ratios = [0.4802, 1.0] - # Cooling Curves - # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool - # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool - # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf - # Using E+ rated conditions: - # Cooling: Indoor air at 67F WB, 80F DB; Entering water temperature: 85F - clg_ap.cool_cap_ft_spec = [[1.3397293008, -0.0474800765, 0.0021636831, 0.0055773535, -0.0002350114, -0.0002458509], - [1.2143128834, -0.0459226877, 0.0020331628, 0.0086998093, -0.0002669140, -0.0001763187]] - clg_ap.cool_eir_ft_spec = [[-0.0049682877, 0.0554193005, -0.0015790347, -0.0010670650, 0.0011493038, -0.0008236210], - [0.0569949694, 0.0527820535, -0.0015763180, 0.0077339260, 0.0008175629, -0.0007157989]] - clg_ap.cool_cap_fflow_spec = [[1.1092, -0.5299, 0.4312], - [0.9216, -0.1021, 0.1874]] - clg_ap.cool_eir_fflow_spec = [[2.2938, -2.2648, 0.9631], - [1.9175, -1.374, 0.4646]] - clg_ap.cool_cap_fwf_spec = [[1.0386, -0.2037, 0.1651], - [0.8606, 0.2687, -0.1293]] - clg_ap.cool_eir_fwf_spec = [[1.066, 0.052, -0.118], - [1.2961, -0.4762, 0.18]] - - # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf - cool_cop_ratios = [1.059467645, 1.0] - end - end - - set_ground_to_air_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + set_ground_to_water_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + end + return end @@ -8006,12 +8058,93 @@ def self.interpolate_hspf2(hspf2, qm17full, hspf2_array, qm17full_array, cop47fu htg_ap.heat_cap_fflow_spec_iq = [0.694045465, 0.474207981, -0.168253446] htg_ap.heat_eir_fflow_spec_iq = [2.185418751, -1.942827919, 0.757409168] - if heating_system.is_a?(HPXML::HeatPump) && heating_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir - # Based on RESNET HERS Addendum 82 - htg_ap.heat_rated_cfm_per_ton = HVAC::RatedCFMPerTon + if heating_system.is_a?(HPXML::HeatPump) + if heating_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + # Based on RESNET HERS Addendum 82 + htg_ap.heat_rated_cfm_per_ton = HVAC::RatedCFMPerTon + + case hpxml_header.ground_to_air_heat_pump_model_type + when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard + htg_ap.heat_capacity_ratios = [1.0] + # E+ equation fit coil coefficients following approach from Tang's thesis: + # See Appendix B Figure B.3 of https://shareok.org/bitstream/handle/11244/10075/Tang_okstate_0664M_1318.pdf?sequence=1&isAllowed=y + # Coefficients generated by catalog data: https://www.climatemaster.com/download/18.274be999165850ccd5b5b73/1535543867815/lc377-climatemaster-commercial-tranquility-20-single-stage-ts-series-water-source-heat-pump-submittal-set.pdf + # Data point taken as rated condition: + # EWT: 60F EAT: 70F AFR: 1200 cfm, WFR: 4.5 gpm + + # Heating Curves + htg_ap.heat_cap_curve_spec = [[-3.75031847962047, -2.18062040443483, 6.8363364819032, 0.188376814356582, 0.0869274802923634]] + htg_ap.heat_power_curve_spec = [[-8.4754723813072, 8.10952801956388, 1.38771494628738, -0.33766445915032, 0.0223085217874051]] + heat_cop_ratios = [1.0] + when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental + case heating_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage + htg_ap.heat_capacity_ratios = [1.0] + # Heating Curves + # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool + # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool + # Catalog data from : https://files.climatemaster.com/Genesis-GS-Series-Product-Catalog.pdf, p180 + # Using E+ rated conditions: + # Heating: Indoor air at 70F DB; Entering water temperature: 70F + htg_ap.heat_cap_ft_spec = [[0.7353127278, -0.0035056759, -0.0000439615, 0.0204411095, -0.0000320781, -0.0001322685]] + htg_ap.heat_eir_ft_spec = [[0.6273820540, 0.0124891750, 0.0012720188, -0.0151581268, 0.0004164343, -0.0007259611]] + htg_ap.heat_cap_fflow_spec = [[0.7594, 0.3642, -0.1234]] + htg_ap.heat_eir_fflow_spec = [[2.796, -3.0886, 1.3858]] + htg_ap.heat_cap_fwf_spec = [[1.0, 0.0, 0.0]] + htg_ap.heat_eir_fwf_spec = [[1.0, 0.0, 0.0]] + heat_cop_ratios = [1.0] + when HPXML::HVACCompressorTypeTwoStage + htg_ap.heat_capacity_ratios = [0.7374, 1.0] + # Heating Curves + # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool + # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool + # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf + # Using E+ rated conditions: + # Heating: Indoor air at 70F DB; Entering water temperature: 70F + htg_ap.heat_cap_ft_spec = [[0.6523957849, -0.0011387222, 0.0000000000, 0.0191295958, -0.0000411533, -0.0000311030], + [0.6668920089, -0.0015817909, 0.0000027692, 0.0189198107, -0.0000372655, -0.0000393615]] + htg_ap.heat_eir_ft_spec = [[0.8057698794, 0.0316014252, 0.0000380531, -0.0228123504, 0.0004336379, -0.0004522084], + [0.8046419585, 0.0233384227, 0.0000376912, -0.0170224134, 0.0003382804, -0.0002368130]] + htg_ap.heat_cap_fflow_spec = [[0.8649, 0.1112, 0.0238], + [0.8264, 0.1593, 0.0143]] + htg_ap.heat_eir_fflow_spec = [[1.2006, -0.1943, -0.0062], + [1.2568, -0.2856, 0.0288]] + htg_ap.heat_cap_fwf_spec = [[0.7112, 0.5027, -0.2139], + [0.769, 0.399, -0.168]] + htg_ap.heat_eir_fwf_spec = [[1.3457, -0.6658, 0.3201], + [1.1679, -0.3215, 0.1535]] + # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf + heat_cop_ratios = [1.161791639, 1.0] + when HPXML::HVACCompressorTypeVariableSpeed + htg_ap.heat_capacity_ratios = [0.4473, 1.0] + # Heating Curves + # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool + # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool + # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf + # Using E+ rated conditions: + # Heating: Indoor air at 70F DB; Entering water temperature: 70F + htg_ap.heat_cap_ft_spec = [[0.6955336002, -0.0028528869, -0.0000005012, 0.0201138223, -0.0000590002, -0.0000749701], + [0.6975737864, -0.0028810803, -0.0000005015, 0.0206468583, -0.0000891526, -0.0000733087]] + htg_ap.heat_eir_ft_spec = [[0.8755777079, 0.0309984461, 0.0001099592, -0.0174543325, 0.0001819203, -0.0004948405], + [0.7627294076, 0.0273612308, 0.0001023412, -0.0145638547, 0.0001886431, -0.0003647958]] + htg_ap.heat_cap_fflow_spec = [[0.8676, 0.1122, 0.0195], + [0.9498, -0.0298, 0.0812]] + htg_ap.heat_eir_fflow_spec = [[1.4426, -0.4465, 0.0064], + [1.1158, 0.282, -0.4071]] + htg_ap.heat_cap_fwf_spec = [[0.8364, 0.197, -0.0333], + [0.727, 0.55, -0.277]] + htg_ap.heat_eir_fwf_spec = [[1.3491, -0.7744, 0.4253], + [1.0833, -0.1351, 0.0517]] + # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf + heat_cop_ratios = [1.15012987, 1.0] + end + end + + set_ground_to_air_heat_pump_cops(heating_system, heat_cop_ratios, :htg) + elsif heating_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater + # Based on RESNET HERS Addendum 82 + htg_ap.heat_rated_cfm_per_ton = HVAC::RatedCFMPerTon - case hpxml_header.ground_to_air_heat_pump_model_type - when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard htg_ap.heat_capacity_ratios = [1.0] # E+ equation fit coil coefficients following approach from Tang's thesis: # See Appendix B Figure B.3 of https://shareok.org/bitstream/handle/11244/10075/Tang_okstate_0664M_1318.pdf?sequence=1&isAllowed=y @@ -8023,71 +8156,10 @@ def self.interpolate_hspf2(hspf2, qm17full, hspf2_array, qm17full_array, cop47fu htg_ap.heat_cap_curve_spec = [[-3.75031847962047, -2.18062040443483, 6.8363364819032, 0.188376814356582, 0.0869274802923634]] htg_ap.heat_power_curve_spec = [[-8.4754723813072, 8.10952801956388, 1.38771494628738, -0.33766445915032, 0.0223085217874051]] heat_cop_ratios = [1.0] - when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental - case heating_system.compressor_type - when HPXML::HVACCompressorTypeSingleStage - htg_ap.heat_capacity_ratios = [1.0] - # Heating Curves - # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool - # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool - # Catalog data from : https://files.climatemaster.com/Genesis-GS-Series-Product-Catalog.pdf, p180 - # Using E+ rated conditions: - # Heating: Indoor air at 70F DB; Entering water temperature: 70F - htg_ap.heat_cap_ft_spec = [[0.7353127278, -0.0035056759, -0.0000439615, 0.0204411095, -0.0000320781, -0.0001322685]] - htg_ap.heat_eir_ft_spec = [[0.6273820540, 0.0124891750, 0.0012720188, -0.0151581268, 0.0004164343, -0.0007259611]] - htg_ap.heat_cap_fflow_spec = [[0.7594, 0.3642, -0.1234]] - htg_ap.heat_eir_fflow_spec = [[2.796, -3.0886, 1.3858]] - htg_ap.heat_cap_fwf_spec = [[1.0, 0.0, 0.0]] - htg_ap.heat_eir_fwf_spec = [[1.0, 0.0, 0.0]] - heat_cop_ratios = [1.0] - when HPXML::HVACCompressorTypeTwoStage - htg_ap.heat_capacity_ratios = [0.7374, 1.0] - # Heating Curves - # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool - # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool - # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf - # Using E+ rated conditions: - # Heating: Indoor air at 70F DB; Entering water temperature: 70F - htg_ap.heat_cap_ft_spec = [[0.6523957849, -0.0011387222, 0.0000000000, 0.0191295958, -0.0000411533, -0.0000311030], - [0.6668920089, -0.0015817909, 0.0000027692, 0.0189198107, -0.0000372655, -0.0000393615]] - htg_ap.heat_eir_ft_spec = [[0.8057698794, 0.0316014252, 0.0000380531, -0.0228123504, 0.0004336379, -0.0004522084], - [0.8046419585, 0.0233384227, 0.0000376912, -0.0170224134, 0.0003382804, -0.0002368130]] - htg_ap.heat_cap_fflow_spec = [[0.8649, 0.1112, 0.0238], - [0.8264, 0.1593, 0.0143]] - htg_ap.heat_eir_fflow_spec = [[1.2006, -0.1943, -0.0062], - [1.2568, -0.2856, 0.0288]] - htg_ap.heat_cap_fwf_spec = [[0.7112, 0.5027, -0.2139], - [0.769, 0.399, -0.168]] - htg_ap.heat_eir_fwf_spec = [[1.3457, -0.6658, 0.3201], - [1.1679, -0.3215, 0.1535]] - # Catalog data from ClimateMaster residential tranquility 30 premier two-stage series Model SE036: https://files.climatemaster.com/RP3001-Residential-SE-Product-Catalog.pdf - heat_cop_ratios = [1.161791639, 1.0] - when HPXML::HVACCompressorTypeVariableSpeed - htg_ap.heat_capacity_ratios = [0.4473, 1.0] - # Heating Curves - # E+ Capacity and EIR as function of temperature curves(bi-quadratic) generated using E+ HVACCurveFitTool - # See: https://bigladdersoftware.com/epx/docs/24-2/auxiliary-programs/hvac-performance-curve-fit-tool.html#hvac-performance-curve-fit-tool - # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf - # Using E+ rated conditions: - # Heating: Indoor air at 70F DB; Entering water temperature: 70F - htg_ap.heat_cap_ft_spec = [[0.6955336002, -0.0028528869, -0.0000005012, 0.0201138223, -0.0000590002, -0.0000749701], - [0.6975737864, -0.0028810803, -0.0000005015, 0.0206468583, -0.0000891526, -0.0000733087]] - htg_ap.heat_eir_ft_spec = [[0.8755777079, 0.0309984461, 0.0001099592, -0.0174543325, 0.0001819203, -0.0004948405], - [0.7627294076, 0.0273612308, 0.0001023412, -0.0145638547, 0.0001886431, -0.0003647958]] - htg_ap.heat_cap_fflow_spec = [[0.8676, 0.1122, 0.0195], - [0.9498, -0.0298, 0.0812]] - htg_ap.heat_eir_fflow_spec = [[1.4426, -0.4465, 0.0064], - [1.1158, 0.282, -0.4071]] - htg_ap.heat_cap_fwf_spec = [[0.8364, 0.197, -0.0333], - [0.727, 0.55, -0.277]] - htg_ap.heat_eir_fwf_spec = [[1.3491, -0.7744, 0.4253], - [1.0833, -0.1351, 0.0517]] - # Catalog data from WaterFurnace 7 Series 700A11: https://www.waterfurnace.com/literature/7series/SDW7-0018W.pdf - heat_cop_ratios = [1.15012987, 1.0] - end - end - - set_ground_to_air_heat_pump_cops(heating_system, heat_cop_ratios, :htg) + + set_ground_to_water_heat_pump_cops(heating_system, heat_cop_ratios, :htg) + end + return end diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index b4bb886e02..9f8d0f0d01 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -221,7 +221,7 @@ def self.apply_heat_pump(runner, model, weather, spaces, hpxml_bldg, hpxml_heade HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom airloop_map[sys_id] = apply_air_source_hvac_systems(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, heat_pump, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods, schedules_file) - when HPXML::HVACTypeHeatPumpGroundToAir + when HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater airloop_map[sys_id] = apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods) end @@ -537,9 +537,9 @@ def self.apply_evaporative_cooler(model, hpxml_bldg, cooling_system, hvac_sequen # @return [OpenStudio::Model::AirLoopHVAC] The newly created air loop hvac object def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, hvac_sequential_load_fracs, control_zone, hvac_unavailable_periods) - ground_to_air = false # FIXME: this is the switch to try out ground-to-water - equation_fit = false # FIXME: equation fit vs eir-formulated - fan_coil = false # FIXME: fan coil vs baseboard/panel + # ground_to_air = false # FIXME: this is the switch to try out ground-to-water + # equation_fit = false # FIXME: equation fit vs eir-formulated + # fan_coil = false # FIXME: fan coil vs baseboard/panel unit_multiplier = hpxml_bldg.building_construction.number_of_units if unit_multiplier > 1 @@ -567,9 +567,10 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml geothermal_loop.loop_flow *= unit_multiplier geothermal_loop.num_bore_holes *= unit_multiplier - if [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard].include? hpxml_header.ground_to_air_heat_pump_model_type - # Cooling Coil - if ground_to_air + if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpAirToAir + + if [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard].include? hpxml_header.ground_to_air_heat_pump_model_type + # Cooling Coil clg_total_cap_curve = Model.add_curve_quad_linear( model, name: "#{obj_name} clg total cap curve", @@ -618,177 +619,188 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml htg_coil.setRatedEnteringAirDryBulbTemperature(UnitConversions.convert(70, 'F', 'C')) # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - else - if equation_fit - htg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating.new(model) - htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - clg_coil = OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling.new(model) - clg_coil.setRatedCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + elsif [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental].include? hpxml_header.ground_to_air_heat_pump_model_type + num_speeds = hp_ap.cool_capacity_ratios.size + if heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + plf_fplr_curve = Model.add_curve_quadratic( + model, + name: 'Cool-PLF-fPLR', + coeff: [1.0, 0.0, 0.0], + min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 + ) else - htg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRHeating.new(model) - htg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - clg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRCooling.new(model) - clg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + # Derived from: https://www.e3s-conferences.org/articles/e3sconf/pdf/2018/19/e3sconf_eko-dok2018_00139.pdf + plf_fplr_curve = Model.add_curve_cubic( + model, + name: 'Cool-PLF-fPLR', + coeff: [0.4603, 1.6416, -1.8588, 0.7605], + min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 + ) end - htg_coil.setCompanionCoolingHeatPump(clg_coil) - clg_coil.setCompanionHeatingHeatPump(htg_coil) - end - elsif [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental].include? hpxml_header.ground_to_air_heat_pump_model_type - num_speeds = hp_ap.cool_capacity_ratios.size - if heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed - plf_fplr_curve = Model.add_curve_quadratic( - model, - name: 'Cool-PLF-fPLR', - coeff: [1.0, 0.0, 0.0], - min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 - ) - else - # Derived from: https://www.e3s-conferences.org/articles/e3sconf/pdf/2018/19/e3sconf_eko-dok2018_00139.pdf - plf_fplr_curve = Model.add_curve_cubic( - model, - name: 'Cool-PLF-fPLR', - coeff: [0.4603, 1.6416, -1.8588, 0.7605], - min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 - ) - end - clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.new(model, plf_fplr_curve) - clg_coil.setName(obj_name + ' clg coil') - clg_coil.setNominalTimeforCondensatetoBeginLeavingtheCoil(1000) - clg_coil.setInitialMoistureEvaporationRateDividedbySteadyStateACLatentCapacity(1.5) - clg_coil.setNominalSpeedLevel(num_speeds) - clg_coil.setRatedAirFlowRateAtSelectedNominalSpeedLevel(clg_air_flow_rated) - clg_coil.setRatedWaterFlowRateAtSelectedNominalSpeedLevel(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) - # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 - clg_coil.setGrossRatedTotalCoolingCapacityAtSelectedNominalSpeedLevel(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) - for i in 0..(num_speeds - 1) - cap_ft_curve = Model.add_curve_biquadratic( - model, - name: "Cool-CAP-fT#{i + 1}", - coeff: hp_ap.cool_cap_ft_spec[i], - min_x: -100, max_x: 100, min_y: -100, max_y: 100 - ) - cap_faf_curve = Model.add_curve_quadratic( - model, - name: "Cool-CAP-fAF#{i + 1}", - coeff: hp_ap.cool_cap_fflow_spec[i], - min_x: 0, max_x: 2, min_y: 0, max_y: 2 - ) - cap_fwf_curve = Model.add_curve_quadratic( - model, - name: "Cool-CAP-fWF#{i + 1}", - coeff: hp_ap.cool_cap_fwf_spec[i], - min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 - ) - eir_ft_curve = Model.add_curve_biquadratic( - model, - name: "Cool-EIR-fT#{i + 1}", - coeff: hp_ap.cool_eir_ft_spec[i], - min_x: -100, max_x: 100, min_y: -100, max_y: 100 - ) - eir_faf_curve = Model.add_curve_quadratic( - model, - name: "Cool-EIR-fAF#{i + 1}", - coeff: hp_ap.cool_eir_fflow_spec[i], - min_x: 0, max_x: 2, min_y: 0, max_y: 2 - ) - eir_fwf_curve = Model.add_curve_quadratic( - model, - name: "Cool-EIR-fWF#{i + 1}", - coeff: hp_ap.cool_eir_fwf_spec[i], - min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 - ) - # Recoverable heat modifier as a function of indoor wet-bulb and water entering temperatures. - waste_heat_ft = Model.add_curve_biquadratic( - model, - name: "WasteHeat-FT#{i + 1}", - coeff: [1, 0, 0, 0, 0, 0] - ) - speed = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.new(model, cap_ft_curve, cap_faf_curve, cap_fwf_curve, eir_ft_curve, eir_faf_curve, eir_fwf_curve, waste_heat_ft) + clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.new(model, plf_fplr_curve) + clg_coil.setName(obj_name + ' clg coil') + clg_coil.setNominalTimeforCondensatetoBeginLeavingtheCoil(1000) + clg_coil.setInitialMoistureEvaporationRateDividedbySteadyStateACLatentCapacity(1.5) + clg_coil.setNominalSpeedLevel(num_speeds) + clg_coil.setRatedAirFlowRateAtSelectedNominalSpeedLevel(clg_air_flow_rated) + clg_coil.setRatedWaterFlowRateAtSelectedNominalSpeedLevel(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 - speed.setReferenceUnitGrossRatedTotalCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W') * hp_ap.cool_capacity_ratios[i]) - speed.setReferenceUnitGrossRatedSensibleHeatRatio(hp_ap.cool_rated_shr_gross) - speed.setReferenceUnitGrossRatedCoolingCOP(hp_ap.cool_rated_cops[i]) - speed.setReferenceUnitRatedAirFlowRate(UnitConversions.convert(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'ton') * hp_ap.cool_capacity_ratios[i] * hp_ap.cool_rated_cfm_per_ton, 'cfm', 'm^3/s')) - speed.setReferenceUnitRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s') * hp_ap.cool_capacity_ratios[i]) - speed.setReferenceUnitWasteHeatFractionofInputPowerAtRatedConditions(0.0) - clg_coil.addSpeed(speed) - end - if heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed - plf_fplr_curve = Model.add_curve_quadratic( - model, - name: 'Heat-PLF-fPLR', - coeff: [1.0, 0.0, 0.0], - min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 - ) - else - # Derived from: https://www.e3s-conferences.org/articles/e3sconf/pdf/2018/19/e3sconf_eko-dok2018_00139.pdf - plf_fplr_curve = Model.add_curve_cubic( - model, - name: 'Heat-PLF-fPLR', - coeff: [0.4603, 1.6416, -1.8588, 0.7605], - min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 - ) - end - htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.new(model, plf_fplr_curve) - htg_coil.setName(obj_name + ' htg coil') - htg_coil.setNominalSpeedLevel(num_speeds) - htg_coil.setRatedAirFlowRateAtSelectedNominalSpeedLevel(htg_air_flow_rated) - htg_coil.setRatedWaterFlowRateAtSelectedNominalSpeedLevel(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) - # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 - htg_coil.setRatedHeatingCapacityAtSelectedNominalSpeedLevel(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - for i in 0..(num_speeds - 1) - cap_ft_curve = Model.add_curve_biquadratic( - model, - name: "Heat-CAP-fT#{i + 1}", - coeff: hp_ap.heat_cap_ft_spec[i], - min_x: -100, max_x: 100, min_y: -100, max_y: 100 - ) - cap_faf_curve = Model.add_curve_quadratic( - model, - name: "Heat-CAP-fAF#{i + 1}", - coeff: hp_ap.heat_cap_fflow_spec[i], - min_x: 0, max_x: 2, min_y: 0, max_y: 2 - ) - cap_fwf_curve = Model.add_curve_quadratic( - model, - name: "Heat-CAP-fWF#{i + 1}", - coeff: hp_ap.heat_cap_fwf_spec[i], - min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 - ) - eir_ft_curve = Model.add_curve_biquadratic( - model, - name: "Heat-EIR-fT#{i + 1}", - coeff: hp_ap.heat_eir_ft_spec[i], - min_x: -100, max_x: 100, min_y: -100, max_y: 100 - ) - eir_faf_curve = Model.add_curve_quadratic( - model, - name: "Heat-EIR-fAF#{i + 1}", - coeff: hp_ap.heat_eir_fflow_spec[i], - min_x: 0, max_x: 2, min_y: 0, max_y: 2 - ) - eir_fwf_curve = Model.add_curve_quadratic( - model, - name: "Heat-EIR-fWF#{i + 1}", - coeff: hp_ap.heat_eir_fwf_spec[i], - min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 - ) - # Recoverable heat modifier as a function of indoor wet-bulb and water entering temperatures. - waste_heat_ft = Model.add_curve_biquadratic( - model, - name: "WasteHeat-FT#{i + 1}", - coeff: [1, 0, 0, 0, 0, 0] - ) - speed = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.new(model, cap_ft_curve, cap_faf_curve, cap_fwf_curve, eir_ft_curve, eir_faf_curve, eir_fwf_curve, waste_heat_ft) + clg_coil.setGrossRatedTotalCoolingCapacityAtSelectedNominalSpeedLevel(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + for i in 0..(num_speeds - 1) + cap_ft_curve = Model.add_curve_biquadratic( + model, + name: "Cool-CAP-fT#{i + 1}", + coeff: hp_ap.cool_cap_ft_spec[i], + min_x: -100, max_x: 100, min_y: -100, max_y: 100 + ) + cap_faf_curve = Model.add_curve_quadratic( + model, + name: "Cool-CAP-fAF#{i + 1}", + coeff: hp_ap.cool_cap_fflow_spec[i], + min_x: 0, max_x: 2, min_y: 0, max_y: 2 + ) + cap_fwf_curve = Model.add_curve_quadratic( + model, + name: "Cool-CAP-fWF#{i + 1}", + coeff: hp_ap.cool_cap_fwf_spec[i], + min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 + ) + eir_ft_curve = Model.add_curve_biquadratic( + model, + name: "Cool-EIR-fT#{i + 1}", + coeff: hp_ap.cool_eir_ft_spec[i], + min_x: -100, max_x: 100, min_y: -100, max_y: 100 + ) + eir_faf_curve = Model.add_curve_quadratic( + model, + name: "Cool-EIR-fAF#{i + 1}", + coeff: hp_ap.cool_eir_fflow_spec[i], + min_x: 0, max_x: 2, min_y: 0, max_y: 2 + ) + eir_fwf_curve = Model.add_curve_quadratic( + model, + name: "Cool-EIR-fWF#{i + 1}", + coeff: hp_ap.cool_eir_fwf_spec[i], + min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 + ) + # Recoverable heat modifier as a function of indoor wet-bulb and water entering temperatures. + waste_heat_ft = Model.add_curve_biquadratic( + model, + name: "WasteHeat-FT#{i + 1}", + coeff: [1, 0, 0, 0, 0, 0] + ) + speed = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.new(model, cap_ft_curve, cap_faf_curve, cap_fwf_curve, eir_ft_curve, eir_faf_curve, eir_fwf_curve, waste_heat_ft) + # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 + speed.setReferenceUnitGrossRatedTotalCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W') * hp_ap.cool_capacity_ratios[i]) + speed.setReferenceUnitGrossRatedSensibleHeatRatio(hp_ap.cool_rated_shr_gross) + speed.setReferenceUnitGrossRatedCoolingCOP(hp_ap.cool_rated_cops[i]) + speed.setReferenceUnitRatedAirFlowRate(UnitConversions.convert(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'ton') * hp_ap.cool_capacity_ratios[i] * hp_ap.cool_rated_cfm_per_ton, 'cfm', 'm^3/s')) + speed.setReferenceUnitRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s') * hp_ap.cool_capacity_ratios[i]) + speed.setReferenceUnitWasteHeatFractionofInputPowerAtRatedConditions(0.0) + clg_coil.addSpeed(speed) + end + if heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + plf_fplr_curve = Model.add_curve_quadratic( + model, + name: 'Heat-PLF-fPLR', + coeff: [1.0, 0.0, 0.0], + min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 + ) + else + # Derived from: https://www.e3s-conferences.org/articles/e3sconf/pdf/2018/19/e3sconf_eko-dok2018_00139.pdf + plf_fplr_curve = Model.add_curve_cubic( + model, + name: 'Heat-PLF-fPLR', + coeff: [0.4603, 1.6416, -1.8588, 0.7605], + min_x: 0, max_x: 1, min_y: 0.7, max_y: 1 + ) + end + htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.new(model, plf_fplr_curve) + htg_coil.setName(obj_name + ' htg coil') + htg_coil.setNominalSpeedLevel(num_speeds) + htg_coil.setRatedAirFlowRateAtSelectedNominalSpeedLevel(htg_air_flow_rated) + htg_coil.setRatedWaterFlowRateAtSelectedNominalSpeedLevel(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 - speed.setReferenceUnitGrossRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') * hp_ap.heat_capacity_ratios[i]) - speed.setReferenceUnitGrossRatedHeatingCOP(hp_ap.heat_rated_cops[i]) - speed.setReferenceUnitRatedAirFlow(UnitConversions.convert(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'ton') * hp_ap.heat_capacity_ratios[i] * hp_ap.heat_rated_cfm_per_ton, 'cfm', 'm^3/s')) - speed.setReferenceUnitRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s') * hp_ap.heat_capacity_ratios[i]) - speed.setReferenceUnitWasteHeatFractionofInputPowerAtRatedConditions(0.0) - htg_coil.addSpeed(speed) + htg_coil.setRatedHeatingCapacityAtSelectedNominalSpeedLevel(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + for i in 0..(num_speeds - 1) + cap_ft_curve = Model.add_curve_biquadratic( + model, + name: "Heat-CAP-fT#{i + 1}", + coeff: hp_ap.heat_cap_ft_spec[i], + min_x: -100, max_x: 100, min_y: -100, max_y: 100 + ) + cap_faf_curve = Model.add_curve_quadratic( + model, + name: "Heat-CAP-fAF#{i + 1}", + coeff: hp_ap.heat_cap_fflow_spec[i], + min_x: 0, max_x: 2, min_y: 0, max_y: 2 + ) + cap_fwf_curve = Model.add_curve_quadratic( + model, + name: "Heat-CAP-fWF#{i + 1}", + coeff: hp_ap.heat_cap_fwf_spec[i], + min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 + ) + eir_ft_curve = Model.add_curve_biquadratic( + model, + name: "Heat-EIR-fT#{i + 1}", + coeff: hp_ap.heat_eir_ft_spec[i], + min_x: -100, max_x: 100, min_y: -100, max_y: 100 + ) + eir_faf_curve = Model.add_curve_quadratic( + model, + name: "Heat-EIR-fAF#{i + 1}", + coeff: hp_ap.heat_eir_fflow_spec[i], + min_x: 0, max_x: 2, min_y: 0, max_y: 2 + ) + eir_fwf_curve = Model.add_curve_quadratic( + model, + name: "Heat-EIR-fWF#{i + 1}", + coeff: hp_ap.heat_eir_fwf_spec[i], + min_x: 0.45, max_x: 2, min_y: 0, max_y: 2 + ) + # Recoverable heat modifier as a function of indoor wet-bulb and water entering temperatures. + waste_heat_ft = Model.add_curve_biquadratic( + model, + name: "WasteHeat-FT#{i + 1}", + coeff: [1, 0, 0, 0, 0, 0] + ) + speed = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.new(model, cap_ft_curve, cap_faf_curve, cap_fwf_curve, eir_ft_curve, eir_faf_curve, eir_fwf_curve, waste_heat_ft) + # TODO: Add net to gross conversion after RESNET PR: https://github.com/NREL/OpenStudio-HPXML/pull/1879 + speed.setReferenceUnitGrossRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') * hp_ap.heat_capacity_ratios[i]) + speed.setReferenceUnitGrossRatedHeatingCOP(hp_ap.heat_rated_cops[i]) + speed.setReferenceUnitRatedAirFlow(UnitConversions.convert(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'ton') * hp_ap.heat_capacity_ratios[i] * hp_ap.heat_rated_cfm_per_ton, 'cfm', 'm^3/s')) + speed.setReferenceUnitRatedWaterFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s') * hp_ap.heat_capacity_ratios[i]) + speed.setReferenceUnitWasteHeatFractionofInputPowerAtRatedConditions(0.0) + htg_coil.addSpeed(speed) + end end + + elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater + htg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRHeating.new(model) + htg_coil.setName(obj_name + ' htg coil') + htg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + # htg_coil.setSourceSideReferenceFlowRate() # ComStock autosizes + # htg_coil.setLoadSideReferenceFlowRate() # ComStock autosizes + # htg_coil.setCapacityModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_61WG_Glycol_90kW_htg.csv + # htg_coil.setElectricInputtoOutputRatioModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_61WG_Glycol_90kW_htg.csv + # htg_coil.setElectricInputtoOutputRatioModifierFunctionofPartLoadRatioCurve() # ComStock assumes a standard EIR vs. PLR line + # htg_coil.setReferenceCoefficientofPerformance() # ComStock uses 1 / rated_heating_eir + + clg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRCooling.new(model) + clg_coil.setName(obj_name + ' clg coil') + clg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) + # clg_coil.setSourceSideReferenceFlowRate() # ComStock autosizes + # clg_coil.setLoadSideReferenceFlowRate() # ComStock autosizes + # clg_coil.setCapacityModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_30WG_90kW_clg.csv + # clg_coil.setElectricInputtoOutputRatioModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_30WG_90kW_clg.csv + # clg_coil.setElectricInputtoOutputRatioModifierFunctionofPartLoadRatioCurve() # ComStock assumes a standard EIR vs. PLR line + # clg_coil.setReferenceCoefficientofPerformance() # ComStock uses 1 / rated_cooling_eir + + htg_coil.setCompanionCoolingHeatPump(clg_coil) + clg_coil.setCompanionHeatingHeatPump(htg_coil) end + clg_coil.additionalProperties.setFeature('HPXML_ID', heat_pump.id) # Used by reporting measure htg_coil.additionalProperties.setFeature('HPXML_ID', heat_pump.id) # Used by reporting measure @@ -886,7 +898,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml demand_outlet_pipe.addToNode(plant_loop.demandOutletNode) # Fan - if ground_to_air + if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir fan_cfms = [] hp_ap.cool_capacity_ratios.each do |capacity_ratio| fan_cfms << clg_cfm * capacity_ratio @@ -895,7 +907,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml fan_cfms << htg_cfm * capacity_ratio end fan_watts_per_cfm = heat_pump.fan_watts_per_cfm - else + elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater if heat_pump.cooling_capacity > 1.0 fan_cfm = RatedCFMPerTon * UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'ton') # CFM else @@ -905,19 +917,17 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml fan_cfms = [fan_cfm] end - if ground_to_air || fan_coil - fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) - add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) - end + fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) + add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) - if ground_to_air + if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir # Unitary System air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, 40.0) add_pump_power_ems_program(model, pump, air_loop_unitary, heat_pump) if (heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed) && (hpxml_header.ground_to_air_heat_pump_model_type == HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeExperimental) add_ghp_pump_mass_flow_rate_ems_program(model, pump, control_zone, htg_coil, clg_coil) end - else + elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater max_water_flow = UnitConversions.convert([heat_pump.heating_capacity, heat_pump.cooling_capacity].max, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s plant_loop.addDemandBranchForComponent(htg_coil) @@ -950,19 +960,12 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml loop_sizing = hw_loop.sizingPlant loop_sizing.setLoopType('Heating') - loop_sizing.setDesignLoopExitTemperature(60.000) + loop_sizing.setDesignLoopExitTemperature(60.000) # ComStock uses this value (140F) loop_sizing.setLoopDesignTemperatureDifference(11.111) - if fan_coil - htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) - htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - htg_coil.setPerformanceInputMethod('NominalCapacity') - else - htg_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model) - htg_coil.setConvergenceTolerance(0.001) - htg_coil.setHeatingDesignCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - htg_coil.setHeatingDesignCapacityMethod('HeatingDesignCapacity') - end + htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) + htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + htg_coil.setPerformanceInputMethod('NominalCapacity') bb_ua = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'deltaF', 'deltaC') * 3.0 # W/K htg_coil.setUFactorTimesAreaValue(bb_ua) @@ -991,25 +994,17 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml loop_sizing = chw_loop.sizingPlant loop_sizing.setLoopType('Cooling') - loop_sizing.setDesignLoopExitTemperature(6.666) + loop_sizing.setDesignLoopExitTemperature(6.666) # ComStock uses this value (44F) loop_sizing.setLoopDesignTemperatureDifference(5.611) - if fan_coil - clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) - clg_coil.setDesignWaterFlowRate(0.0022) - clg_coil.setDesignAirFlowRate(1.45) - clg_coil.setDesignInletWaterTemperature(6.1) - clg_coil.setDesignInletAirTemperature(25.0) - clg_coil.setDesignOutletAirTemperature(10.0) - clg_coil.setDesignInletAirHumidityRatio(0.012) - clg_coil.setDesignOutletAirHumidityRatio(0.008) - else - clg_coil = OpenStudio::Model::CoilCoolingWaterPanelRadiant.new(model) - # clg_coil.setCoolingDesignCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) - clg_coil.setCoolingDesignCapacity(100.0) - clg_coil.setCoolingDesignCapacityMethod('CoolingDesignCapacity') - # clg_coil.setMaximumChilledWaterFlowRate(0.0022) - end + clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) + clg_coil.setDesignWaterFlowRate(0.0022) + clg_coil.setDesignAirFlowRate(1.45) + clg_coil.setDesignInletWaterTemperature(6.1) + clg_coil.setDesignInletAirTemperature(25.0) + clg_coil.setDesignOutletAirTemperature(10.0) + clg_coil.setDesignInletAirHumidityRatio(0.012) + clg_coil.setDesignOutletAirHumidityRatio(0.008) clg_coil.setName(obj_name + ' clg coil') chw_loop.addDemandBranchForComponent(clg_coil) @@ -1021,29 +1016,18 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml ) pump.addToNode(chw_loop.supplyInletNode) - if fan_coil - zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) - zone_hvac.setCapacityControlMethod('CyclingFan') - zone_hvac.setName(obj_name + ' fan coil') - zone_hvac.setMaximumSupplyAirTemperatureInHeatingMode(UnitConversions.convert(120.0, 'F', 'C')) - zone_hvac.setHeatingConvergenceTolerance(0.001) - zone_hvac.setMinimumSupplyAirTemperatureInCoolingMode(UnitConversions.convert(55.0, 'F', 'C')) - zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) - zone_hvac.setCoolingConvergenceTolerance(0.001) - zone_hvac.setMaximumOutdoorAirFlowRate(0.0) - zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert([htg_cfm, clg_cfm].max, 'cfm', 'm^3/s')) - zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) - zone_hvac.addToThermalZone(control_zone) - else - zone_hvac_htg = OpenStudio::Model::ZoneHVACBaseboardConvectiveWater.new(model, model.alwaysOnDiscreteSchedule, htg_coil) - zone_hvac_htg.setName(obj_name + ' baseboard') - zone_hvac_htg.addToThermalZone(control_zone) - - zone_hvac_clg = OpenStudio::Model::ZoneHVACCoolingPanelRadiantConvectiveWater.new(model) - zone_hvac_clg.setCoolingCoil(clg_coil) - zone_hvac_clg.setName(obj_name + ' panel') - zone_hvac_clg.addToThermalZone(control_zone) - end + zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) + zone_hvac.setCapacityControlMethod('CyclingFan') + zone_hvac.setName(obj_name + ' fan coil') + zone_hvac.setMaximumSupplyAirTemperatureInHeatingMode(UnitConversions.convert(120.0, 'F', 'C')) + zone_hvac.setHeatingConvergenceTolerance(0.001) + zone_hvac.setMinimumSupplyAirTemperatureInCoolingMode(UnitConversions.convert(55.0, 'F', 'C')) + zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) + zone_hvac.setCoolingConvergenceTolerance(0.001) + zone_hvac.setMaximumOutdoorAirFlowRate(0.0) + zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert([htg_cfm, clg_cfm].max, 'cfm', 'm^3/s')) + zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) + zone_hvac.addToThermalZone(control_zone) end if heat_pump.is_shared_system @@ -1064,7 +1048,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml equip.additionalProperties.setFeature('HPXML_ID', heat_pump.id) # Used by reporting measure end - if ground_to_air + if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir # Air Loop air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, hvac_sequential_load_fracs, [htg_cfm, clg_cfm].max, heat_pump, hvac_unavailable_periods) @@ -1072,7 +1056,9 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml apply_installation_quality_ems_program(model, heat_pump, heat_pump, air_loop_unitary, htg_coil, clg_coil, control_zone) return air_loop - else + elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater + set_sequential_load_fractions(model, control_zone, zone_hvac, hvac_sequential_load_fracs, hvac_unavailable_periods, heat_pump) + return zone_hvac end end @@ -5413,6 +5399,7 @@ def self.check_distribution_system(hvac_system, system_type) HPXML::HVACTypeHeatPumpAirToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE], HPXML::HVACTypeHeatPumpMiniSplit => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE], HPXML::HVACTypeHeatPumpGroundToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE], + HPXML::HVACTypeHeatPumpGroundToWater => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE], HPXML::HVACTypeHeatPumpWaterLoopToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE], HPXML::HVACTypeHeatPumpPTHP => [HPXML::HVACDistributionTypeDSE], HPXML::HVACTypeHeatPumpRoom => [HPXML::HVACDistributionTypeDSE], diff --git a/HPXMLtoOpenStudio/resources/hvac_sizing.rb b/HPXMLtoOpenStudio/resources/hvac_sizing.rb index 4f0b88e4c5..232def9aec 100644 --- a/HPXMLtoOpenStudio/resources/hvac_sizing.rb +++ b/HPXMLtoOpenStudio/resources/hvac_sizing.rb @@ -2818,6 +2818,36 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva total_cap_curve_value = MathTools.biquadratic(UnitConversions.convert(mj.cool_indoor_wetbulb, 'F', 'C'), UnitConversions.convert(entering_temp, 'F', 'C'), clg_ap.cool_cap_ft_spec[hvac_cooling_speed]) calculate_cooling_capacities(mj, clg_ap, hvac_sizings, hpxml_bldg.header.manualj_humidity_setpoint, total_cap_curve_value, undersize_limit, oversize_limit, HVAC::GroundSourceCoolRatedIDB, HVAC::GroundSourceCoolRatedIWB, hvac_cooling, hpxml_bldg) end + elsif HPXML::HVACTypeHeatPumpGroundToWater == cooling_type + + # FIXME + entering_temp = clg_ap.design_chw + hvac_cooling_speed = get_nominal_speed(clg_ap, true) + + gshp_coil_bf = 0.0806 + gshp_coil_bf_ft_spec = [1.21005458, -0.00664200, 0.00000000, 0.00348246, 0.00000000, 0.00000000] + bypass_factor_curve_value = MathTools.biquadratic(mj.cool_indoor_wetbulb, mj.cool_setpoint, gshp_coil_bf_ft_spec) + total_cap_curve_value, sensible_cap_curve_value = calc_gshp_clg_curve_value(clg_ap, mj.cool_indoor_wetbulb, mj.cool_setpoint, entering_temp, hvac_cooling_speed) + + cool_cap_rated = hvac_sizings.Cool_Load_Tot / total_cap_curve_value # Note: cool_cap_design = hvac_sizings.Cool_Load_Tot + cool_sens_cap_rated = cool_cap_rated * clg_ap.cool_rated_shr_gross + curve_sens_cap_at_design = cool_sens_cap_rated * sensible_cap_curve_value + cool_load_sens_cap_design = (curve_sens_cap_at_design / \ + (1.0 + (1.0 - gshp_coil_bf * bypass_factor_curve_value) * + (80.0 - mj.cool_setpoint) / cooling_delta_t)) + cool_load_lat_cap_design = hvac_sizings.Cool_Load_Tot - cool_load_sens_cap_design + + # Adjust Sizing so that coil sensible at design >= CoolingLoad_Sens, and coil latent at design >= CoolingLoad_Lat, and equipment SHRRated is maintained. + cool_load_sens_cap_design = [cool_load_sens_cap_design, hvac_sizings.Cool_Load_Sens].max + cool_load_lat_cap_design = [cool_load_lat_cap_design, hvac_sizings.Cool_Load_Lat].max + cool_cap_design = cool_load_sens_cap_design + cool_load_lat_cap_design + + # Limit total capacity via oversizing limit + cool_cap_design = [cool_cap_design, oversize_limit * hvac_sizings.Cool_Load_Tot].min + hvac_sizings.Cool_Capacity = cool_cap_design / total_cap_curve_value + hvac_sizings.Cool_Capacity_Sens = hvac_sizings.Cool_Capacity * clg_ap.cool_rated_shr_gross + hvac_sizings.Cool_Airflow = calc_airflow_rate(:clg, hvac_cooling, hvac_sizings.Cool_Capacity, hpxml_bldg) + elsif HPXML::HVACTypeEvaporativeCooler == cooling_type hvac_sizings.Cool_Capacity = hvac_sizings.Cool_Load_Tot @@ -2851,7 +2881,8 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva htg_ap = hvac_heating.additional_properties if hvac_heating.is_a?(HPXML::HeatingSystem) && hvac_heating.is_heat_pump_backup_system hvac_hp = hvac_heating.primary_heat_pump - if hvac_hp.heat_pump_type != HPXML::HVACTypeHeatPumpGroundToAir + if (hvac_hp.heat_pump_type != HPXML::HVACTypeHeatPumpGroundToAir) && + (hvac_hp.heat_pump_type != HPXML::HVACTypeHeatPumpGroundToWater) # Adjust heating load using the HP backup calculation hp_sizing_values = @all_hvac_sizings[{ heating: hvac_hp, cooling: hvac_hp }] if hp_sizing_values.nil? @@ -2898,6 +2929,35 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva end hvac_sizings.Heat_Airflow = calc_airflow_rate(:htg, hvac_heating, hvac_sizings.Heat_Capacity, hpxml_bldg) + elsif [HPXML::HVACTypeHeatPumpGroundToWater].include? heating_type + hvac_heating_speed = get_nominal_speed(htg_ap, false) + + # htg_cap_curve_value = calc_gshp_htg_curve_value(htg_ap, hpxml_header, mj.heat_setpoint, htg_ap.design_hw, hvac_heating_speed) + # Reference conditions in thesis with largest capacity: + # See Appendix B Figure B.3 of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf + ref_temp = 283 # K + + db_temp = UnitConversions.convert(mj.heat_setpoint, 'F', 'K') + w_temp = UnitConversions.convert(htg_ap.design_hw, 'F', 'K') + + htg_cap_curve_value = MathTools.quadlinear(db_temp / ref_temp, w_temp / ref_temp, 1.0, 1.0, htg_ap.heat_cap_curve_spec[hvac_heating_speed]) + + hvac_sizings.Heat_Capacity = hvac_sizings.Heat_Load / htg_cap_curve_value + hvac_sizings.Heat_Capacity_Supp = hvac_sizings.Heat_Load_Supp + if hvac_sizings.Cool_Capacity > 0 + # if (hpxml_header.ground_to_air_heat_pump_model_type == HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard) && (hvac_heating.compressor_type == HPXML::HVACCompressorTypeSingleStage) + # For single stage compressor, when heating capacity is much larger than cooling capacity, + # in order to avoid frequent cycling in cooling mode, heating capacity is derated to 75%. + # Currently only keep it for standard ghp models + hvac_sizings.Heat_Capacity *= 0.75 if (hvac_sizings.Heat_Capacity >= 1.5 * hvac_sizings.Cool_Capacity) + # end + hvac_sizings.Cool_Capacity = [hvac_sizings.Cool_Capacity, hvac_sizings.Heat_Capacity].max + hvac_sizings.Cool_Capacity_Sens = hvac_sizings.Cool_Capacity * clg_ap.cool_rated_shr_gross + hvac_sizings.Cool_Airflow = calc_airflow_rate(:clg, hvac_cooling, hvac_sizings.Cool_Capacity, hpxml_bldg) + hvac_sizings.Heat_Capacity = hvac_sizings.Cool_Capacity + end + hvac_sizings.Heat_Airflow = calc_airflow_rate(:htg, hvac_heating, hvac_sizings.Heat_Capacity, hpxml_bldg) + elsif [HPXML::HVACTypeHeatPumpWaterLoopToAir].include? heating_type hvac_sizings.Heat_Capacity = hvac_sizings.Heat_Load @@ -3283,7 +3343,7 @@ def self.apply_hvac_final_capacities(hvac_sizings, hvac_heating, hvac_cooling, h def self.apply_hvac_ground_loop(mj, runner, hvac_sizings, weather, hvac_cooling, hpxml_bldg) cooling_type = get_hvac_cooling_type(hvac_cooling) - return if cooling_type != HPXML::HVACTypeHeatPumpGroundToAir + return unless [HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include? cooling_type geothermal_loop = hvac_cooling.geothermal_loop From fffab1065606a6103a7bea9741eb694a42ee05b8 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 15:05:26 -0700 Subject: [PATCH 12/25] Move returns, and skip writing design airflow cfm. --- HPXMLtoOpenStudio/measure.xml | 10 +++++----- HPXMLtoOpenStudio/resources/defaults.rb | 8 ++++---- HPXMLtoOpenStudio/resources/hvac.rb | 10 +++++----- HPXMLtoOpenStudio/resources/hvac_sizing.rb | 21 +++++++++++++-------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 08f00766d6..3c13e29b93 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 2df96644-c687-4923-976a-e80c0f9d2971 - 2025-08-28T18:47:47Z + 7bb351ad-c248-4f16-a51a-01247c205477 + 2025-08-28T21:35:09Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -348,7 +348,7 @@ defaults.rb rb resource - 7AACD9D0 + 595F0928 electric_panel.rb @@ -414,13 +414,13 @@ hvac.rb rb resource - 0997719B + 3813BBE5 hvac_sizing.rb rb resource - F3DFE229 + EEF8EC23 internal_gains.rb diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 75b787baef..f81c3d1dd0 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -7920,6 +7920,7 @@ def self.interpolate_seer2(seer2, eer2, seer2_array, seer2_eer2_ratio_array, cop end set_ground_to_air_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + return elsif cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater # FIXME @@ -7943,9 +7944,8 @@ def self.interpolate_seer2(seer2, eer2, seer2_array, seer2_eer2_ratio_array, cop cool_cop_ratios = [1.0] set_ground_to_water_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + return end - - return end # Based on RESNET HERS Addendum 82 @@ -8146,6 +8146,7 @@ def self.interpolate_hspf2(hspf2, qm17full, hspf2_array, qm17full_array, cop47fu end set_ground_to_air_heat_pump_cops(heating_system, heat_cop_ratios, :htg) + return elsif heating_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater # Based on RESNET HERS Addendum 82 htg_ap.heat_rated_cfm_per_ton = HVAC::RatedCFMPerTon @@ -8163,9 +8164,8 @@ def self.interpolate_hspf2(hspf2, qm17full, hspf2_array, qm17full_array, cop47fu heat_cop_ratios = [1.0] set_ground_to_water_heat_pump_cops(heating_system, heat_cop_ratios, :htg) + return end - - return end htg_ap.heat_cap_fflow_spec = htg_ap.heat_cap_fflow_spec_iq diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 9f8d0f0d01..8c48615bf5 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -567,7 +567,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml geothermal_loop.loop_flow *= unit_multiplier geothermal_loop.num_bore_holes *= unit_multiplier - if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpAirToAir + if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir if [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard].include? hpxml_header.ground_to_air_heat_pump_model_type # Cooling Coil @@ -5183,11 +5183,11 @@ def self.apply_unit_multiplier(hpxml_bldg, hpxml_header) hpxml_bldg.heat_pumps.each do |hp_sys| hp_ap = hp_sys.additional_properties hp_sys.cooling_capacity *= unit_multiplier - hp_sys.cooling_design_airflow_cfm *= unit_multiplier - hp_ap.cooling_actual_airflow_cfm *= unit_multiplier + hp_sys.cooling_design_airflow_cfm *= unit_multiplier unless hp_sys.cooling_design_airflow_cfm.nil? + hp_ap.cooling_actual_airflow_cfm *= unit_multiplier unless hp_ap.cooling_actual_airflow_cfm.nil? hp_sys.heating_capacity *= unit_multiplier - hp_sys.heating_design_airflow_cfm *= unit_multiplier - hp_ap.heating_actual_airflow_cfm *= unit_multiplier + hp_sys.heating_design_airflow_cfm *= unit_multiplier unless hp_sys.heating_design_airflow_cfm.nil? + hp_ap.heating_actual_airflow_cfm *= unit_multiplier unless hp_ap.heating_actual_airflow_cfm.nil? hp_sys.heating_capacity_17F *= unit_multiplier unless hp_sys.heating_capacity_17F.nil? hp_sys.backup_heating_capacity *= unit_multiplier unless hp_sys.backup_heating_capacity.nil? hp_sys.crankcase_heater_watts *= unit_multiplier unless hp_sys.crankcase_heater_watts.nil? diff --git a/HPXMLtoOpenStudio/resources/hvac_sizing.rb b/HPXMLtoOpenStudio/resources/hvac_sizing.rb index 232def9aec..ac44f083f5 100644 --- a/HPXMLtoOpenStudio/resources/hvac_sizing.rb +++ b/HPXMLtoOpenStudio/resources/hvac_sizing.rb @@ -2846,7 +2846,7 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva cool_cap_design = [cool_cap_design, oversize_limit * hvac_sizings.Cool_Load_Tot].min hvac_sizings.Cool_Capacity = cool_cap_design / total_cap_curve_value hvac_sizings.Cool_Capacity_Sens = hvac_sizings.Cool_Capacity * clg_ap.cool_rated_shr_gross - hvac_sizings.Cool_Airflow = calc_airflow_rate(:clg, hvac_cooling, hvac_sizings.Cool_Capacity, hpxml_bldg) + hvac_sizings.Cool_Airflow = 0.0 elsif HPXML::HVACTypeEvaporativeCooler == cooling_type @@ -2953,10 +2953,10 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva # end hvac_sizings.Cool_Capacity = [hvac_sizings.Cool_Capacity, hvac_sizings.Heat_Capacity].max hvac_sizings.Cool_Capacity_Sens = hvac_sizings.Cool_Capacity * clg_ap.cool_rated_shr_gross - hvac_sizings.Cool_Airflow = calc_airflow_rate(:clg, hvac_cooling, hvac_sizings.Cool_Capacity, hpxml_bldg) + hvac_sizings.Cool_Airflow = 0.0 hvac_sizings.Heat_Capacity = hvac_sizings.Cool_Capacity end - hvac_sizings.Heat_Airflow = calc_airflow_rate(:htg, hvac_heating, hvac_sizings.Heat_Capacity, hpxml_bldg) + hvac_sizings.Heat_Airflow = 0.0 elsif [HPXML::HVACTypeHeatPumpWaterLoopToAir].include? heating_type @@ -5282,9 +5282,11 @@ def self.assign_to_hpxml_system(hvac_heating, hvac_cooling, hvac_sizings) end # Heating design airflow rate - if not (hvac_heating.is_a?(HPXML::HeatingSystem) && + if not ((hvac_heating.is_a?(HPXML::HeatingSystem) && [HPXML::HVACTypeBoiler, - HPXML::HVACTypeElectricResistance].include?(hvac_heating.heating_system_type)) + HPXML::HVACTypeElectricResistance].include?(hvac_heating.heating_system_type))) || + ((hvac_heating.is_a?(HPXML::HeatPump) && + [HPXML::HVACTypeHeatPumpGroundToWater].include?(hvac_heating.heat_pump_type))) if hvac_heating.heating_design_airflow_cfm.nil? || ((hvac_heating.heating_design_airflow_cfm - hvac_sizings.Heat_Airflow).abs >= 1.0) hvac_heating.heating_design_airflow_cfm = Float(hvac_sizings.Heat_Airflow.round) hvac_heating.heating_design_airflow_cfm_isdefaulted = true @@ -5358,9 +5360,12 @@ def self.assign_to_hpxml_system(hvac_heating, hvac_cooling, hvac_sizings) end # Cooling design airflow rate - if hvac_cooling.cooling_design_airflow_cfm.nil? || ((hvac_cooling.cooling_design_airflow_cfm - hvac_sizings.Cool_Airflow).abs >= 1.0) - hvac_cooling.cooling_design_airflow_cfm = Float(hvac_sizings.Cool_Airflow.round) - hvac_cooling.cooling_design_airflow_cfm_isdefaulted = true + if not (hvac_cooling.is_a?(HPXML::HeatPump) && + [HPXML::HVACTypeHeatPumpGroundToWater].include?(hvac_cooling.heat_pump_type)) + if hvac_cooling.cooling_design_airflow_cfm.nil? || ((hvac_cooling.cooling_design_airflow_cfm - hvac_sizings.Cool_Airflow).abs >= 1.0) + hvac_cooling.cooling_design_airflow_cfm = Float(hvac_sizings.Cool_Airflow.round) + hvac_cooling.cooling_design_airflow_cfm_isdefaulted = true + end end # Cooling installed/actual airflow rate From a5d1b9207e4820d4e293753e2f760db24a19485d Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Thu, 28 Aug 2025 15:23:02 -0700 Subject: [PATCH 13/25] Set fan coil max supply airflow to supply fan cfm; unmet hours go to zero. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/resources/hvac.rb | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 3c13e29b93..a303050bad 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 7bb351ad-c248-4f16-a51a-01247c205477 - 2025-08-28T21:35:09Z + 6e3d1ed4-efbe-4f6d-9ea6-7c1a4ef09fa7 + 2025-08-28T22:21:05Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -414,7 +414,7 @@ hvac.rb rb resource - 3813BBE5 + 521B0611 hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 8c48615bf5..ed953c2db4 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -537,9 +537,6 @@ def self.apply_evaporative_cooler(model, hpxml_bldg, cooling_system, hvac_sequen # @return [OpenStudio::Model::AirLoopHVAC] The newly created air loop hvac object def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, hvac_sequential_load_fracs, control_zone, hvac_unavailable_periods) - # ground_to_air = false # FIXME: this is the switch to try out ground-to-water - # equation_fit = false # FIXME: equation fit vs eir-formulated - # fan_coil = false # FIXME: fan coil vs baseboard/panel unit_multiplier = hpxml_bldg.building_construction.number_of_units if unit_multiplier > 1 @@ -1025,7 +1022,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) zone_hvac.setCoolingConvergenceTolerance(0.001) zone_hvac.setMaximumOutdoorAirFlowRate(0.0) - zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert([htg_cfm, clg_cfm].max, 'cfm', 'm^3/s')) + zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert(fan_cfms[0], 'cfm', 'm^3/s')) zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) zone_hvac.addToThermalZone(control_zone) end From 83f9f64423df1466da5776a74ad5150623d0c786 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 29 Aug 2025 09:28:25 -0700 Subject: [PATCH 14/25] Get SiteGroundTemperatureDeep for ground-to-water. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/resources/location.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index a303050bad..48896b5d7a 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 6e3d1ed4-efbe-4f6d-9ea6-7c1a4ef09fa7 - 2025-08-28T22:21:05Z + 856de56b-3a93-4f55-9be6-a38fe1bf21ed + 2025-08-29T16:27:49Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -438,7 +438,7 @@ location.rb rb resource - 7DB56BD8 + 815CA656 materials.rb diff --git a/HPXMLtoOpenStudio/resources/location.rb b/HPXMLtoOpenStudio/resources/location.rb index 8e0d0e05b7..10ae46ca8f 100644 --- a/HPXMLtoOpenStudio/resources/location.rb +++ b/HPXMLtoOpenStudio/resources/location.rb @@ -92,7 +92,7 @@ def self.apply_ground_temps(model, weather, hpxml_bldg) sgts.resetAllMonths sgts.setAllMonthlyTemperatures(weather.data.ShallowGroundMonthlyTemps.map { |t| UnitConversions.convert(t, 'F', 'C') }) - if hpxml_bldg.heat_pumps.count { |h| h.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir } > 0 + if hpxml_bldg.heat_pumps.count { |h| [HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include?(h.heat_pump_type) } > 0 # Deep ground temperatures used by GSHP setpoint manager dgts = model.getSiteGroundTemperatureDeep dgts.resetAllMonths From be51de426f42ab2a7a6c97f16856cfed66cfb215 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Fri, 29 Aug 2025 10:30:02 -0700 Subject: [PATCH 15/25] Exclude ground-to-water from unit multiplier tests. --- workflow/tests/util.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow/tests/util.rb b/workflow/tests/util.rb index 1345b555ad..7a5acf5a4e 100644 --- a/workflow/tests/util.rb +++ b/workflow/tests/util.rb @@ -43,7 +43,7 @@ def _run_xml(xml, worker_num, apply_unit_multiplier = false, annual_results_1x = if hpxml_bldg.dehumidifiers.size > 0 # FUTURE: Dehumidifiers currently don't give desired results w/ unit multipliers # https://github.com/NREL/OpenStudio-HPXML/issues/1499 - elsif hpxml_bldg.heat_pumps.count { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir } > 0 + elsif hpxml_bldg.heat_pumps.count { |hp| [HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include?(hp.heat_pump_type) } > 0 # FUTURE: GSHPs currently don't give desired results w/ unit multipliers # https://github.com/NREL/OpenStudio-HPXML/issues/1499 elsif hpxml_bldg.batteries.size > 0 @@ -1041,7 +1041,7 @@ def _verify_outputs(rundir, hpxml_path, results, hpxml, unit_multiplier) assert_equal(0, energy_htg) end if htg_backup_fuels.include? fuel - has_ashp = hpxml_bldg.heat_pumps.count { |hp| hp.heat_pump_type != HPXML::HVACTypeHeatPumpGroundToAir } > 0 + has_ashp = hpxml_bldg.heat_pumps.count { |hp| ![HPXML::HVACTypeHeatPumpGroundToAir, HPXML::HVACTypeHeatPumpGroundToWater].include?(hp.heat_pump_type) } > 0 if (not hpxml_path.include? 'autosize') && (not is_warm_climate) && has_ashp assert_operator(energy_hp_backup, :>, 0) end From f04e57487d38ea690721d2a55840b624f8e8f56e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 29 Aug 2025 18:26:11 +0000 Subject: [PATCH 16/25] Latest results. --- workflow/tests/base_results/results_simulations_bills.csv | 1 + workflow/tests/base_results/results_simulations_energy.csv | 1 + workflow/tests/base_results/results_simulations_hvac.csv | 1 + workflow/tests/base_results/results_simulations_loads.csv | 1 + workflow/tests/base_results/results_simulations_misc.csv | 1 + workflow/tests/base_results/results_simulations_panel.csv | 1 + workflow/tests/base_results/results_sizing.csv | 6 ++++++ 7 files changed, 12 insertions(+) diff --git a/workflow/tests/base_results/results_simulations_bills.csv b/workflow/tests/base_results/results_simulations_bills.csv index 6485a33864..5b6c7b5915 100644 --- a/workflow/tests/base_results/results_simulations_bills.csv +++ b/workflow/tests/base_results/results_simulations_bills.csv @@ -298,6 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,1842.25,144.0,169 base-hvac-ground-to-air-heat-pump-heating-only.xml,1630.21,144.0,1486.21,0.0,1630.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,1779.47,144.0,1635.47,0.0,1779.47,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,1695.58,144.0,1551.58,0.0,1695.58,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,1482.41,144.0,1338.41,0.0,1482.41,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,2391.78,144.0,2247.78,0.0,2391.78,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,2306.39,144.0,2162.39,0.0,2306.39,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,2429.04,144.0,2285.04,0.0,2429.04,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_energy.csv b/workflow/tests/base_results/results_simulations_energy.csv index e3f61e2882..c169f8fdb5 100644 --- a/workflow/tests/base_results/results_simulations_energy.csv +++ b/workflow/tests/base_results/results_simulations_energy.csv @@ -298,6 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,46.656,46.656,46. base-hvac-ground-to-air-heat-pump-heating-only.xml,40.831,40.831,40.831,40.831,0.0,0.0,0.0,0.0,0.0,0.0,7.046,1.958,0.0,0.0,0.0,0.0,10.735,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.156,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,44.931,44.931,44.931,44.931,0.0,0.0,0.0,0.0,0.0,0.0,8.555,2.413,0.0,0.0,1.164,1.019,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,42.626,42.626,42.626,42.626,0.0,0.0,0.0,0.0,0.0,0.0,5.977,1.855,0.0,0.0,1.505,1.509,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,36.77,36.77,36.77,36.77,0.0,0.0,0.0,0.0,0.0,0.0,2.412,0.123,0.0,0.0,1.775,0.103,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,61.753,61.753,61.753,61.753,0.0,0.0,0.0,0.0,0.0,0.0,16.67,1.592,5.304,0.182,5.46,0.765,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,59.407,59.407,59.407,59.407,0.0,0.0,0.0,0.0,0.0,0.0,15.431,1.294,5.123,0.17,5.111,0.498,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,62.777,62.777,62.777,62.777,0.0,0.0,0.0,0.0,0.0,0.0,18.165,1.473,3.998,0.107,6.761,0.493,10.77,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_hvac.csv b/workflow/tests/base_results/results_simulations_hvac.csv index dc270b2143..97efea1f69 100644 --- a/workflow/tests/base_results/results_simulations_hvac.csv +++ b/workflow/tests/base_results/results_simulations_hvac.csv @@ -298,6 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,6.8,91.76,36000.0 base-hvac-ground-to-air-heat-pump-heating-only.xml,6.8,91.76,36000.0,0.0,0.0,39372.0,15488.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,14683.0,0.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,6.8,91.76,36000.0,36000.0,0.0,39372.0,15488.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,27993.0,13311.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,265.0,126.0,-661.0,0.0,800.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,6.8,91.76,36000.0,36000.0,0.0,39372.0,15488.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,27993.0,13311.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,265.0,126.0,-661.0,0.0,800.0 +base-hvac-ground-to-water-heat-pump.xml,6.8,91.76,36000.0,36000.0,0.0,23885.0,0.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,14683.0,0.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,6.8,91.76,36000.0,36000.0,34121.0,39372.0,15488.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,27993.0,13311.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,265.0,126.0,-661.0,0.0,800.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,6.8,91.76,36000.0,36000.0,34121.0,39372.0,15488.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,27993.0,13311.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,265.0,126.0,-661.0,0.0,800.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,6.8,91.76,35800.0,36000.0,34121.0,39372.0,15488.0,7963.0,0.0,575.0,6834.0,0.0,0.0,1738.0,2155.0,4620.0,0.0,0.0,27993.0,13311.0,7750.0,0.0,207.0,507.0,0.0,0.0,0.0,2276.0,622.0,0.0,3320.0,0.0,0.0,265.0,126.0,-661.0,0.0,800.0 diff --git a/workflow/tests/base_results/results_simulations_loads.csv b/workflow/tests/base_results/results_simulations_loads.csv index 3145769d29..89476f1bae 100644 --- a/workflow/tests/base_results/results_simulations_loads.csv +++ b/workflow/tests/base_results/results_simulations_loads.csv @@ -298,6 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,32.852,0.0,17.9,9 base-hvac-ground-to-air-heat-pump-heating-only.xml,27.353,0.0,0.0,9.917,0.815,0.0,0.0,0.0,3.518,3.855,0.876,7.002,0.667,11.442,-12.745,0.0,0.0,0.0,8.085,-0.103,5.397,0.0,0.505,0.0,9.53,-8.425,-2.62,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,37.354,0.0,19.792,9.917,0.849,0.0,0.0,0.0,3.138,3.89,0.885,7.023,0.674,11.539,-12.85,0.0,0.0,0.0,8.249,-0.115,5.793,0.0,0.509,0.0,19.369,-8.495,-2.637,0.0,-0.221,-0.253,-0.024,2.483,0.022,-0.335,12.647,0.0,0.0,0.0,-6.374,-0.11,-0.925,-4.124,-0.083,0.0,8.06,7.296,1.87 base-hvac-ground-to-air-heat-pump-var-speed.xml,28.608,0.0,17.431,9.917,0.849,0.0,0.0,0.0,3.504,3.888,0.884,7.016,0.673,11.533,-12.85,0.0,0.0,0.0,8.234,-0.114,5.448,0.0,0.509,0.0,10.65,-8.495,-2.637,0.0,-0.127,-0.254,-0.024,2.481,0.021,-0.336,12.647,0.0,0.0,0.0,-6.379,-0.11,-0.929,-4.118,-0.083,0.0,5.62,7.296,1.87 +base-hvac-ground-to-water-heat-pump.xml,18.196,0.0,12.0,9.917,0.849,0.0,0.0,0.0,4.027,3.883,0.883,7.004,0.673,11.522,-12.85,0.0,0.0,0.0,8.212,-0.116,5.224,0.0,0.509,0.0,0.0,-8.496,-2.637,0.0,0.11,-0.256,-0.024,2.476,0.021,-0.34,12.647,0.0,0.0,0.0,-6.385,-0.112,-0.946,-4.109,-0.083,0.0,0.0,7.295,1.87 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,35.979,4.268,18.804,9.917,0.849,0.0,0.0,0.0,3.209,3.89,0.885,7.023,0.674,11.54,-12.85,0.0,0.0,0.0,8.249,-0.115,5.986,0.0,0.509,0.0,17.725,-8.495,-2.637,0.0,-0.184,-0.253,-0.024,2.482,0.021,-0.336,12.647,0.0,0.0,0.0,-6.376,-0.11,-0.924,-4.124,-0.083,0.0,7.038,7.296,1.87 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,38.514,3.982,20.276,9.917,0.849,0.0,0.0,0.0,3.101,3.891,0.885,7.025,0.674,11.541,-12.85,0.0,0.0,0.0,8.253,-0.115,6.041,0.0,0.509,0.0,20.302,-8.495,-2.637,0.0,-0.241,-0.253,-0.024,2.483,0.022,-0.334,12.647,0.0,0.0,0.0,-6.374,-0.11,-0.921,-4.127,-0.083,0.0,8.557,7.296,1.87 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,42.352,2.65,22.381,9.917,0.849,0.0,0.0,0.0,2.927,3.89,0.885,7.022,0.674,11.537,-12.85,0.0,0.0,0.0,8.249,-0.115,6.074,0.0,0.508,0.0,24.291,-8.495,-2.637,0.0,-0.337,-0.253,-0.024,2.483,0.022,-0.334,12.647,0.0,0.0,0.0,-6.374,-0.11,-0.921,-4.15,-0.083,0.0,10.782,7.296,1.87 diff --git a/workflow/tests/base_results/results_simulations_misc.csv b/workflow/tests/base_results/results_simulations_misc.csv index 61b3d79dee..2ad5aec710 100644 --- a/workflow/tests/base_results/results_simulations_misc.csv +++ b/workflow/tests/base_results/results_simulations_misc.csv @@ -298,6 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,0.0,0.0,0.0,1286. base-hvac-ground-to-air-heat-pump-heating-only.xml,0.0,0.0,0.0,1286.4,890.5,11468.6,3942.3,4487.7,1890.2,4487.7,4487.7,1890.2,4487.7,30.981,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,10.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,4354.5,2470.6,4354.5,4354.5,2470.6,4354.5,27.899,25.563,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,4016.2,2628.3,4016.2,4016.2,2628.3,4016.2,31.346,24.084,0.0 +base-hvac-ground-to-water-heat-pump.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,2576.7,2355.2,2576.7,2576.7,2355.2,2576.7,17.113,13.107,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,10233.3,4592.1,10233.3,10233.3,4592.1,10233.3,33.093,26.404,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,9996.3,4294.6,9996.3,9996.3,4294.6,9996.3,33.089,26.109,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,9289.7,5573.8,9289.7,9289.7,5573.8,9289.7,33.092,25.461,0.0 diff --git a/workflow/tests/base_results/results_simulations_panel.csv b/workflow/tests/base_results/results_simulations_panel.csv index cdfb2cd58c..c44d9df2fd 100644 --- a/workflow/tests/base_results/results_simulations_panel.csv +++ b/workflow/tests/base_results/results_simulations_panel.csv @@ -298,6 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,0.0,0.0,0.0,0.0,0 base-hvac-ground-to-air-heat-pump-heating-only.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_sizing.csv b/workflow/tests/base_results/results_sizing.csv index 00deb0d2eb..4f46d0a1da 100644 --- a/workflow/tests/base_results/results_sizing.csv +++ b/workflow/tests/base_results/results_sizing.csv @@ -244,6 +244,9 @@ denver-hvac-autosize-ground-to-air-heat-pump-var-speed-experimental-sizing-metho denver-hvac-autosize-ground-to-air-heat-pump-var-speed-sizing-methodology-ACCA.xml,43930.0,43930.0,0.0,1318.0,1318.0 denver-hvac-autosize-ground-to-air-heat-pump-var-speed-sizing-methodology-HERS.xml,43930.0,43930.0,0.0,1318.0,1318.0 denver-hvac-autosize-ground-to-air-heat-pump-var-speed-sizing-methodology-MaxLoad.xml,58384.0,58384.0,0.0,1752.0,1752.0 +denver-hvac-autosize-ground-to-water-heat-pump-sizing-methodology-ACCA.xml,26650.0,26650.0,0.0,0.0,0.0 +denver-hvac-autosize-ground-to-water-heat-pump-sizing-methodology-HERS.xml,26650.0,26650.0,0.0,0.0,0.0 +denver-hvac-autosize-ground-to-water-heat-pump-sizing-methodology-MaxLoad.xml,31331.0,31331.0,0.0,0.0,0.0 denver-hvac-autosize-install-quality-air-to-air-heat-pump-1-speed-sizing-methodology-ACCA-backup-emergency.xml,39042.0,40904.0,39372.0,1171.0,1227.0 denver-hvac-autosize-install-quality-air-to-air-heat-pump-1-speed-sizing-methodology-ACCA-backup-supplemental.xml,39042.0,40904.0,23805.0,1171.0,1227.0 denver-hvac-autosize-install-quality-air-to-air-heat-pump-1-speed-sizing-methodology-HERS-backup-emergency.xml,44495.0,46618.0,39372.0,1334.0,1398.0 @@ -649,6 +652,9 @@ houston-hvac-autosize-ground-to-air-heat-pump-var-speed-experimental-sizing-meth houston-hvac-autosize-ground-to-air-heat-pump-var-speed-sizing-methodology-ACCA.xml,49352.0,49352.0,0.0,1481.0,1481.0 houston-hvac-autosize-ground-to-air-heat-pump-var-speed-sizing-methodology-HERS.xml,49352.0,49352.0,0.0,1481.0,1481.0 houston-hvac-autosize-ground-to-air-heat-pump-var-speed-sizing-methodology-MaxLoad.xml,49352.0,49352.0,0.0,1481.0,1481.0 +houston-hvac-autosize-ground-to-water-heat-pump-sizing-methodology-ACCA.xml,22707.0,22707.0,0.0,0.0,0.0 +houston-hvac-autosize-ground-to-water-heat-pump-sizing-methodology-HERS.xml,22707.0,22707.0,0.0,0.0,0.0 +houston-hvac-autosize-ground-to-water-heat-pump-sizing-methodology-MaxLoad.xml,22707.0,22707.0,0.0,0.0,0.0 houston-hvac-autosize-install-quality-air-to-air-heat-pump-1-speed-sizing-methodology-ACCA-backup-emergency.xml,50396.0,48528.0,24742.0,1511.0,1455.0 houston-hvac-autosize-install-quality-air-to-air-heat-pump-1-speed-sizing-methodology-ACCA-backup-supplemental.xml,50396.0,48528.0,0.0,1511.0,1455.0 houston-hvac-autosize-install-quality-air-to-air-heat-pump-1-speed-sizing-methodology-HERS-backup-emergency.xml,50396.0,48528.0,24742.0,1511.0,1455.0 From a2ee8f8c8b2c0b114dda00efc244084abb75e07e Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 2 Sep 2025 16:01:03 -0700 Subject: [PATCH 17/25] Update build measure to write compressor type for ground-to-water. --- BuildResidentialHPXML/measure.rb | 4 +++- BuildResidentialHPXML/measure.xml | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/BuildResidentialHPXML/measure.rb b/BuildResidentialHPXML/measure.rb index 719eae93dc..1815028293 100644 --- a/BuildResidentialHPXML/measure.rb +++ b/BuildResidentialHPXML/measure.rb @@ -6196,7 +6196,9 @@ def self.set_heat_pumps(hpxml_bldg, args) end end - if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit, HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump_type + if [HPXML::HVACTypeHeatPumpAirToAir, + HPXML::HVACTypeHeatPumpMiniSplit, + HPXML::HVACTypeHeatPumpGroundToAir].include?(heat_pump_type) || heat_pump_type.include?(HPXML::HVACTypeHeatPumpGroundToWater) compressor_type = args[:heat_pump_compressor_type] end diff --git a/BuildResidentialHPXML/measure.xml b/BuildResidentialHPXML/measure.xml index 344e4ea70f..d6657056d1 100644 --- a/BuildResidentialHPXML/measure.xml +++ b/BuildResidentialHPXML/measure.xml @@ -3,8 +3,8 @@ 3.1 build_residential_hpxml a13a8983-2b01-4930-8af2-42030b6e4233 - 52e24cb7-172f-4894-96c2-a46c2e02e526 - 2025-08-28T18:43:31Z + 8f4636c3-982c-47eb-a3d1-e69d82de664f + 2025-09-02T22:59:47Z 2C38F48B BuildResidentialHPXML HPXML Builder @@ -8417,7 +8417,7 @@ measure.rb rb script - 9F0AC5D1 + 2F23596A constants.rb From d3577aeca0b376d112f9e1364704a59f481774cc Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 2 Sep 2025 16:02:03 -0700 Subject: [PATCH 18/25] Update the new GroundSourceToWater schematron entries. --- .../hpxml_schematron/EPvalidator.sch | 51 +++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch index ee4fd94ef9..9a5a93606f 100644 --- a/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch +++ b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch @@ -1634,13 +1634,13 @@ Expected 0 or 1 element(s) for xpath: UnitLocation Expected UnitLocation to be 'conditioned space' or 'basement - unconditioned' or 'basement - conditioned' or 'attic - unvented' or 'attic - vented' or 'garage' or 'crawlspace - unvented' or 'crawlspace - vented' or 'crawlspace - conditioned' or 'other exterior' or 'other housing unit' or 'other heated space' or 'other multifamily buffer space' or 'other non-freezing space' or 'roof deck' or 'unconditioned space' or 'manufactured home belly' Expected 1 element(s) for xpath: DistributionSystem - Expected 0 or 1 element(s) for xpath: IsSharedSystem + Expected 0 or 1 element(s) for xpath: IsSharedSystem Expected 1 element(s) for xpath: HeatPumpFuel Expected HeatPumpFuel to be 'electricity' Expected 0 or 1 element(s) for xpath: HeatingCapacity Expected 0 or 1 element(s) for xpath: CoolingCapacity Expected 1 element(s) for xpath: CompressorType - Expected CompressorType to be 'single stage' or 'two stage' or 'variable speed' + Expected CompressorType to be 'single stage' or 'two stage' or 'variable speed' Expected 0 or 1 element(s) for xpath: BackupType Expected BackupType to be 'integrated' or 'separate' Expected 0 element(s) for xpath: BackupHeatingSwitchoverTemperature @@ -1676,18 +1676,59 @@ [HeatPumpType=GroundSourceToWater] - Expected 1 element(s) for xpath: ../../HVACDistribution/DistributionSystemType/AirDistribution/AirDistributionType[text()="fan coil"] + Expected 1 or more element(s) for xpath: ../../HVACDistribution/DistributionSystemType/AirDistribution/AirDistributionType[text()="fan coil"] | ../../HVACDistribution/DistributionSystemType/Other[text()="DSE"] + Expected 0 or 1 element(s) for xpath: UnitLocation + Expected UnitLocation to be 'conditioned space' or 'basement - unconditioned' or 'basement - conditioned' or 'attic - unvented' or 'attic - vented' or 'garage' or 'crawlspace - unvented' or 'crawlspace - vented' or 'crawlspace - conditioned' or 'other exterior' or 'other housing unit' or 'other heated space' or 'other multifamily buffer space' or 'other non-freezing space' or 'roof deck' or 'unconditioned space' or 'manufactured home belly' + Expected 1 element(s) for xpath: DistributionSystem + Expected 0 or 1 element(s) for xpath: IsSharedSystem + Expected 1 element(s) for xpath: HeatPumpFuel + Expected HeatPumpFuel to be 'electricity' + Expected 0 or 1 element(s) for xpath: HeatingCapacity + Expected 0 or 1 element(s) for xpath: CoolingCapacity + Expected 1 element(s) for xpath: CompressorType + Expected CompressorType to be 'single stage' + Expected 0 or 1 element(s) for xpath: BackupType + Expected BackupType to be 'integrated' or 'separate' + Expected 0 element(s) for xpath: BackupHeatingSwitchoverTemperature + Expected 1 element(s) for xpath: FractionHeatLoadServed + Expected 1 element(s) for xpath: FractionCoolLoadServed + Expected 1 element(s) for xpath: AnnualCoolingEfficiency[Units="EER"]/Value + Expected 1 element(s) for xpath: AnnualHeatingEfficiency[Units="COP"]/Value + Expected 0 or 1 element(s) for xpath: AttachedToGeothermalLoop + Expected 0 or 1 element(s) for xpath: extension/PumpPowerWattsPerTon + Expected extension/PumpPowerWattsPerTon to be greater than or equal to 0 + Expected 0 or 1 element(s) for xpath: extension/FanCoilWatts + Expected extension/FanCoilWatts to be greater than or equal to 0 + Expected 0 or 1 element(s) for xpath: extension/ChargeDefectRatio + Expected extension/ChargeDefectRatio to be greater than or equal to -0.9 + Expected extension/ChargeDefectRatio to be less than or equal to 9 + + EER should typically be greater than or equal to 6. + COP should typically be greater than or equal to 2. + Heating capacity should typically be greater than or equal to 1000 Btu/hr. + Cooling capacity should typically be greater than or equal to 1000 Btu/hr. - [HeatPumpType=GroundSourceWithSharedLoop] + [HeatPumpType=GroundSourceToAirWithSharedLoop] Expected 1 element(s) for xpath: ../../../../BuildingSummary/BuildingConstruction[ResidentialFacilityType[text()="single-family attached" or text()="apartment unit"]] Expected 1 element(s) for xpath: NumberofUnitsServed Expected NumberofUnitsServed to be greater than 1 Expected 1 element(s) for xpath: extension/SharedLoopWatts - Expected extension/SharedLoopWatts to be greater than or equal to 0 + Expected extension/SharedLoopWatts to be greater than or equal to 0 + + + + + [HeatPumpType=GroundSourceToWaterWithSharedLoop] + + Expected 1 element(s) for xpath: ../../../../BuildingSummary/BuildingConstruction[ResidentialFacilityType[text()="single-family attached" or text()="apartment unit"]] + Expected 1 element(s) for xpath: NumberofUnitsServed + Expected NumberofUnitsServed to be greater than 1 + Expected 1 element(s) for xpath: extension/SharedLoopWatts + Expected extension/SharedLoopWatts to be greater than or equal to 0 From 0b0c13a00c942ffe2a92fe2c2d17046c5f140255 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 2 Sep 2025 16:02:46 -0700 Subject: [PATCH 19/25] Update defaults, hpxml, and hvac resources for fan coil watts input. --- HPXMLtoOpenStudio/measure.xml | 12 +- HPXMLtoOpenStudio/resources/defaults.rb | 16 +++ HPXMLtoOpenStudio/resources/hpxml.rb | 3 + HPXMLtoOpenStudio/resources/hvac.rb | 121 +++++++++++------- .../base-hvac-ground-to-water-heat-pump.xml | 1 + 5 files changed, 99 insertions(+), 54 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 48896b5d7a..91b934470e 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 856de56b-3a93-4f55-9be6-a38fe1bf21ed - 2025-08-29T16:27:49Z + 51b02b03-ef03-47d4-bac7-be9b0d495017 + 2025-09-02T22:59:49Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -348,7 +348,7 @@ defaults.rb rb resource - 595F0928 + 8262FE71 electric_panel.rb @@ -384,7 +384,7 @@ hpxml.rb rb resource - 21EB950B + 2F8A1285 hpxml_schema/HPXML.xsd @@ -402,7 +402,7 @@ hpxml_schematron/EPvalidator.sch sch resource - A431C069 + 813783B0 hpxml_schematron/iso-schematron.xsd @@ -414,7 +414,7 @@ hvac.rb rb resource - 521B0611 + A1BFDB2B hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index f81c3d1dd0..9ade0865f6 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -2087,6 +2087,15 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu heat_pump.pump_watts_per_ton_isdefaulted = true end + # GSHP fan coil power + hpxml_bldg.heat_pumps.each do |heat_pump| + next unless [HPXML::HVACTypeHeatPumpGroundToWater].include?(heat_pump.heat_pump_type) + next unless heat_pump.fan_coil_watts.nil? + + heat_pump.fan_coil_watts = get_gshp_fan_coil_power() + heat_pump.fan_coil_watts_isdefaulted = true + end + # Charge defect ratio hpxml_bldg.cooling_systems.each do |cooling_system| next unless [HPXML::HVACTypeCentralAirConditioner, @@ -6559,6 +6568,13 @@ def self.get_gshp_pump_power() return 80.0 # Rough estimate based on a literature review of different studies/websites end + # Gets the default fan coil power for a closed loop ground-source heat pump. + # + # @return [Double] Fan coil power (W) + def self.get_gshp_fan_coil_power() + return 150.0 # FIXME: default this, or require this? + end + # Gets the default Electric Auxiliary Energy (EAE) for a boiler. # # @param heating_system [HPXML::HeatingSystem] The HPXML heating system of interest diff --git a/HPXMLtoOpenStudio/resources/hpxml.rb b/HPXMLtoOpenStudio/resources/hpxml.rb index d98dc66533..50d39d09a7 100644 --- a/HPXMLtoOpenStudio/resources/hpxml.rb +++ b/HPXMLtoOpenStudio/resources/hpxml.rb @@ -7046,6 +7046,7 @@ def initialize(hpxml_element, *args, **kwargs) :pump_watts_per_ton, # [Double] extension/PumpPowerWattsPerTon (W/ton) :shared_loop_watts, # [Double] extension/SharedLoopWatts (W) :shared_loop_motor_efficiency, # [Double] extension/SharedLoopMotorEfficiency (frac) + :fan_coil_watts, # [Double] extension/FanCoilWatts (W) :crankcase_heater_watts, # [Double] extension/CrankcaseHeaterPowerWatts (W) :pan_heater_watts, # [Double] extension/PanHeaterPowerWatts (W) :pan_heater_control_type, # [String] extension/PanHeaterControlType (HPXML::HVACPanHeaterControlTypeXXX) @@ -7307,6 +7308,7 @@ def to_doc(building) XMLHelper.add_extension(heat_pump, 'PumpPowerWattsPerTon', @pump_watts_per_ton, :float, @pump_watts_per_ton_isdefaulted) unless @pump_watts_per_ton.nil? XMLHelper.add_extension(heat_pump, 'SharedLoopWatts', @shared_loop_watts, :float) unless @shared_loop_watts.nil? XMLHelper.add_extension(heat_pump, 'SharedLoopMotorEfficiency', @shared_loop_motor_efficiency, :float) unless @shared_loop_motor_efficiency.nil? + XMLHelper.add_extension(heat_pump, 'FanCoilWatts', @fan_coil_watts, :float) unless @fan_coil_watts.nil? XMLHelper.add_extension(heat_pump, 'CrankcaseHeaterPowerWatts', @crankcase_heater_watts, :float, @crankcase_heater_watts_isdefaulted) unless @crankcase_heater_watts.nil? XMLHelper.add_extension(heat_pump, 'PanHeaterPowerWatts', @pan_heater_watts, :float, @pan_heater_watts_isdefaulted) unless @pan_heater_watts.nil? XMLHelper.add_extension(heat_pump, 'PanHeaterControlType', @pan_heater_control_type, :string, @pan_heater_control_type_isdefaulted) unless @pan_heater_control_type.nil? @@ -7383,6 +7385,7 @@ def from_doc(heat_pump) @pump_watts_per_ton = XMLHelper.get_value(heat_pump, 'extension/PumpPowerWattsPerTon', :float) @shared_loop_watts = XMLHelper.get_value(heat_pump, 'extension/SharedLoopWatts', :float) @shared_loop_motor_efficiency = XMLHelper.get_value(heat_pump, 'extension/SharedLoopMotorEfficiency', :float) + @fan_coil_watts = XMLHelper.get_value(heat_pump, 'extension/FanCoilWatts', :float) @crankcase_heater_watts = XMLHelper.get_value(heat_pump, 'extension/CrankcaseHeaterPowerWatts', :float) @pan_heater_watts = XMLHelper.get_value(heat_pump, 'extension/PanHeaterPowerWatts', :float) @pan_heater_control_type = XMLHelper.get_value(heat_pump, 'extension/PanHeaterControlType', :string) diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index ed953c2db4..c446a32068 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -914,7 +914,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml fan_cfms = [fan_cfm] end - fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) + fan = create_supply_fan(model, obj_name, fan_watts_per_cfm, fan_cfms, heat_pump) # fan coil energy included in above pump via Fan Coil Watts add_fan_pump_disaggregation_ems_program(model, fan, htg_coil, clg_coil, htg_supp_coil, heat_pump) if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir @@ -925,6 +925,8 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml add_ghp_pump_mass_flow_rate_ems_program(model, pump, control_zone, htg_coil, clg_coil) end elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater + add_pump_power_ems_program(model, pump, htg_coil, heat_pump) + max_water_flow = UnitConversions.convert([heat_pump.heating_capacity, heat_pump.cooling_capacity].max, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s plant_loop.addDemandBranchForComponent(htg_coil) @@ -1152,10 +1154,14 @@ def self.get_pump_power_watts(hvac_system) return hvac_system.electric_auxiliary_energy / 2.08 elsif hvac_system.is_a?(HPXML::HeatPump) && (not hvac_system.pump_watts_per_ton.nil?) if hvac_system.cooling_capacity > 1.0 - return hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.cooling_capacity, 'Btu/hr', 'ton') + pump_power_watts = hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.cooling_capacity, 'Btu/hr', 'ton') + hvac_system.fan_coil_watts else - return hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.heating_capacity, 'Btu/hr', 'ton') + pump_power_watts = hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.heating_capacity, 'Btu/hr', 'ton') + hvac_system.fan_coil_watts + end + if (not hvac_system.fan_coil_watts.nil?) + pump_power_watts += hvac_system.fan_coil_watts end + return pump_power_watts end return 0.0 @@ -2008,7 +2014,7 @@ def self.add_fan_power_ems_program(model, fan, hp_min_temp) # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param pump [OpenStudio::Model::PumpVariableSpeed] OpenStudio variable-speed pump object - # @param heating_object [OpenStudio::Model::AirLoopHVACUnitarySystem or OpenStudio::Model::BoilerHotWater] OpenStudio unitary system object or boiler object + # @param heating_object [OpenStudio::Model::AirLoopHVACUnitarySystem or OpenStudio::Model::BoilerHotWater or OpenStudio::Model::HeatPumpPlantLoopEIRHeating] OpenStudio unitary system object or boiler object or plant loop heat pump object # @param hvac_system [HPXML::HeatPump or HPXML::HeatingSystem] HPXML heat pump or heating system object # @return [nil] def self.add_pump_power_ems_program(model, pump, heating_object, hvac_system) @@ -2072,6 +2078,21 @@ def self.add_pump_power_ems_program(model, pump, heating_object, hvac_system) key_name: heating_object.name ) end + elsif heating_object.is_a? OpenStudio::Model::HeatPumpPlantLoopEIRHeating + htg_coil = heating_object + clg_coil = htg_coil.companionCoolingHeatPump.get + heating_plr_sensor = Model.add_ems_sensor( + model, + name: "#{htg_coil.name} plr s", + output_var_or_meter_name: 'Heat Pump Part Load Ratio', + key_name: htg_coil.name + ) + cooling_plr_sensor = Model.add_ems_sensor( + model, + name: "#{clg_coil.name} plr s", + output_var_or_meter_name: 'Heat Pump Part Load Ratio', + key_name: clg_coil.name + ) end pump_mfr_sensor = Model.add_ems_sensor( @@ -2105,50 +2126,54 @@ def self.add_pump_power_ems_program(model, pump, heating_object, hvac_system) if cooling_plr_sensor.nil? pump_program.addLine("Set hvac_plr = #{heating_plr_sensor.name}") else - hvac_ap = hvac_system.additional_properties - pump_program.addLine("Set heating_pump_vfr_max = #{htg_coil.speeds[-1].referenceUnitRatedWaterFlowRate}") - pump_program.addLine("Set cooling_pump_vfr_max = #{clg_coil.speeds[-1].referenceUnitRatedWaterFlowRate}") - pump_program.addLine('Set htg_flow_rate = 0.0') - pump_program.addLine('Set clg_flow_rate = 0.0') - (1..htg_coil.speeds.size).each do |i| - # Initialization - pump_program.addLine("Set heating_pump_vfr_#{i} = heating_pump_vfr_max * #{hvac_ap.heat_capacity_ratios[i - 1]}") - pump_program.addLine("Set heating_fraction_time_#{i} = 0.0") - end - pump_program.addLine("If #{heating_usl_sensor.name} == 1") - pump_program.addLine(" Set heating_fraction_time_1 = #{heating_plr_sensor.name}") - (1..(htg_coil.speeds.size - 1)).each do |i| - pump_program.addLine("ElseIf #{heating_usl_sensor.name} == #{i + 1}") - pump_program.addLine(" Set heating_fraction_time_#{i} = 1.0 - #{heating_nsl_sensor.name}") - pump_program.addLine(" Set heating_fraction_time_#{i + 1} = #{heating_nsl_sensor.name}") - end - pump_program.addLine('EndIf') - # sum up to get the actual flow rate - (1..htg_coil.speeds.size).each do |i| - pump_program.addLine("Set htg_flow_rate = htg_flow_rate + heating_fraction_time_#{i} * heating_pump_vfr_#{i}") - end - pump_program.addLine('Set heating_plr = htg_flow_rate / heating_pump_vfr_max') + if cooling_nsl_sensor.nil? + pump_program.addLine("Set hvac_plr = @Max #{heating_plr_sensor.name} #{cooling_plr_sensor.name}") + else + hvac_ap = hvac_system.additional_properties + pump_program.addLine("Set heating_pump_vfr_max = #{htg_coil.speeds[-1].referenceUnitRatedWaterFlowRate}") + pump_program.addLine("Set cooling_pump_vfr_max = #{clg_coil.speeds[-1].referenceUnitRatedWaterFlowRate}") + pump_program.addLine('Set htg_flow_rate = 0.0') + pump_program.addLine('Set clg_flow_rate = 0.0') + (1..htg_coil.speeds.size).each do |i| + # Initialization + pump_program.addLine("Set heating_pump_vfr_#{i} = heating_pump_vfr_max * #{hvac_ap.heat_capacity_ratios[i - 1]}") + pump_program.addLine("Set heating_fraction_time_#{i} = 0.0") + end + pump_program.addLine("If #{heating_usl_sensor.name} == 1") + pump_program.addLine(" Set heating_fraction_time_1 = #{heating_plr_sensor.name}") + (1..(htg_coil.speeds.size - 1)).each do |i| + pump_program.addLine("ElseIf #{heating_usl_sensor.name} == #{i + 1}") + pump_program.addLine(" Set heating_fraction_time_#{i} = 1.0 - #{heating_nsl_sensor.name}") + pump_program.addLine(" Set heating_fraction_time_#{i + 1} = #{heating_nsl_sensor.name}") + end + pump_program.addLine('EndIf') + # sum up to get the actual flow rate + (1..htg_coil.speeds.size).each do |i| + pump_program.addLine("Set htg_flow_rate = htg_flow_rate + heating_fraction_time_#{i} * heating_pump_vfr_#{i}") + end + pump_program.addLine('Set heating_plr = htg_flow_rate / heating_pump_vfr_max') - # Cooling - (1..clg_coil.speeds.size).each do |i| - # Initialization - pump_program.addLine("Set cooling_pump_vfr_#{i} = cooling_pump_vfr_max * #{hvac_ap.cool_capacity_ratios[i - 1]}") - pump_program.addLine("Set cooling_fraction_time_#{i} = 0.0") - end - pump_program.addLine("If #{cooling_usl_sensor.name} == 1") - pump_program.addLine(" Set cooling_fraction_time_1 = #{cooling_plr_sensor.name}") - (1..(clg_coil.speeds.size - 1)).each do |i| - pump_program.addLine("ElseIf (#{cooling_usl_sensor.name}) == #{i + 1}") - pump_program.addLine(" Set cooling_fraction_time_#{i} = 1.0 - #{cooling_nsl_sensor.name}") - pump_program.addLine(" Set cooling_fraction_time_#{i + 1} = #{cooling_nsl_sensor.name}") - end - pump_program.addLine('EndIf') - # sum up to get the actual flow rate - (1..clg_coil.speeds.size).each do |i| - pump_program.addLine("Set clg_flow_rate = clg_flow_rate + cooling_fraction_time_#{i} * heating_pump_vfr_#{i}") + # Cooling + (1..clg_coil.speeds.size).each do |i| + # Initialization + pump_program.addLine("Set cooling_pump_vfr_#{i} = cooling_pump_vfr_max * #{hvac_ap.cool_capacity_ratios[i - 1]}") + pump_program.addLine("Set cooling_fraction_time_#{i} = 0.0") + end + pump_program.addLine("If #{cooling_usl_sensor.name} == 1") + pump_program.addLine(" Set cooling_fraction_time_1 = #{cooling_plr_sensor.name}") + (1..(clg_coil.speeds.size - 1)).each do |i| + pump_program.addLine("ElseIf (#{cooling_usl_sensor.name}) == #{i + 1}") + pump_program.addLine(" Set cooling_fraction_time_#{i} = 1.0 - #{cooling_nsl_sensor.name}") + pump_program.addLine(" Set cooling_fraction_time_#{i + 1} = #{cooling_nsl_sensor.name}") + end + pump_program.addLine('EndIf') + # sum up to get the actual flow rate + (1..clg_coil.speeds.size).each do |i| + pump_program.addLine("Set clg_flow_rate = clg_flow_rate + cooling_fraction_time_#{i} * heating_pump_vfr_#{i}") + end + pump_program.addLine('Set cooling_plr = clg_flow_rate / cooling_pump_vfr_max') + pump_program.addLine('Set hvac_plr = @Max cooling_plr heating_plr') end - pump_program.addLine('Set cooling_plr = clg_flow_rate / cooling_pump_vfr_max') - pump_program.addLine('Set hvac_plr = @Max cooling_plr heating_plr') end pump_program.addLine("Set pump_total_eff = #{pump_rated_mfr_var.name} / 1000 * #{pump.ratedPumpHead} / #{pump.ratedPowerConsumption.get}") pump_program.addLine("Set pump_vfr = #{pump_mfr_sensor.name} / 1000") @@ -2269,7 +2294,7 @@ def self.add_fan_pump_disaggregation_ems_program(model, fan_or_pump, htg_object, else if clg_object.is_a? OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial var = 'Evaporative Cooler Water Volume' - elsif clg_object.is_a?(OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling) || clg_object.is_a?(OpenStudio::Model::HeatPumpPlantLoopEIRCooling) + elsif clg_object.is_a?(OpenStudio::Model::HeatPumpPlantLoopEIRCooling) var = 'Heat Pump Electricity Energy' else var = 'Cooling Coil Total Cooling Energy' @@ -2290,7 +2315,7 @@ def self.add_fan_pump_disaggregation_ems_program(model, fan_or_pump, htg_object, var = 'Baseboard Total Heating Energy' elsif htg_object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil var = 'Fan Coil Heating Energy' - elsif htg_object.is_a?(OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating) || htg_object.is_a?(OpenStudio::Model::HeatPumpPlantLoopEIRHeating) + elsif htg_object.is_a?(OpenStudio::Model::HeatPumpPlantLoopEIRHeating) var = 'Heat Pump Electricity Energy' else var = 'Heating Coil Heating Energy' diff --git a/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml b/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml index cae878178d..c2a1b48ee7 100644 --- a/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml +++ b/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml @@ -316,6 +316,7 @@ electricity 36000.0 36000.0 + single stage 1.0 1.0 From 34a3f2ac260cf19b4934629fb00d2b05c98d2551 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 2 Sep 2025 16:03:33 -0700 Subject: [PATCH 20/25] Start to build out docs for Ground-to-Water section. --- docs/source/workflow_inputs.rst | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index fee0971921..fc1edd11ce 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -3218,6 +3218,75 @@ Each ground-to-air heat pump is entered as a ``/HPXML/Building/BuildingDetails/S A non-zero charge defect should typically only be applied for systems that are charged on site, not for systems that have pre-charged line sets. See `ANSI/RESNET/ACCA 310-2020 `_ for more information. +.. _hvac_hp_ground_to_water: + +Ground-to-Water Heat Pump +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each ground-to-water heat pump is entered as a ``/HPXML/Building/BuildingDetails/Systems/HVAC/HVACPlant/HeatPump``. + + =============================================== ======== ====== =============== ======== ============== ============================================== + Element Type Units Constraints Required Default Notes + =============================================== ======== ====== =============== ======== ============== ============================================== + ``SystemIdentifier`` id Yes Unique identifier + ``AttachedToZone`` idref See [#]_ See [#]_ ID of attached zone + ``UnitLocation`` string See [#]_ No See [#]_ Location of heat pump + ``DistributionSystem`` idref See [#]_ Yes ID of attached distribution system + ``IsSharedSystem`` boolean No false Whether it has a shared hydronic circulation loop [#]_ + ``HeatPumpType`` string ground-to-water Yes Type of heat pump + ``HeatPumpFuel`` string electricity Yes Fuel type + ``HeatingCapacity`` double Btu/hr >= 0 No autosized [#]_ Heating output capacity + ``CoolingCapacity`` double Btu/hr >= 0 No autosized [#]_ Cooling output capacity + ``CompressorType`` string single stage Yes Type of compressor + ``BackupType`` string See [#]_ No Type of backup heating + ``FractionHeatLoadServed`` double frac >= 0, <= 1 [#]_ Yes Fraction of heating load served + ``FractionCoolLoadServed`` double frac >= 0, <= 1 [#]_ Yes Fraction of cooling load served + ``AnnualCoolingEfficiency[Units="EER"]/Value`` double Btu/Wh > 0 Yes Rated cooling efficiency + ``AnnualHeatingEfficiency[Units="COP"]/Value`` double W/W > 0 Yes Rated heating efficiency + ``NumberofUnitsServed`` integer > 0 See [#]_ Number of dwelling units served + ``AttachedToGeothermalLoop`` idref See [#]_ No [#]_ ID of attached geothermal loop + ``extension/PumpPowerWattsPerTon`` double W/ton >= 0 No See [#]_ Pump power [#]_ + ``extension/SharedLoopWatts`` double W >= 0 See [#]_ Shared pump power [#]_ + ``extension/FanCoilWatts`` double W >= 0 No 150.0 Fan coil power + ``extension/ChargeDefectRatio`` double frac >= -0.9, <= 9 No 0.0 Deviation between design/installed refrigerant charges [#]_ + ``extension/CoolingAutosizingFactor`` double frac > 0 No 1.0 Cooling autosizing capacity multiplier + ``extension/HeatingAutosizingFactor`` double frac > 0 No 1.0 Heating autosizing capacity multiplier + ``extension/CoolingAutosizingLimit`` double Btu/hr > 0 No Cooling autosizing capacity limit + ``extension/HeatingAutosizingLimit`` double Btu/hr > 0 No Heating autosizing capacity limit + =============================================== ======== ====== =============== ======== ============== ============================================== + + .. [#] If AttachedToZone provided, it must reference a conditioned ``Zone``. + .. [#] AttachedToZone only required if zone-level and space-level HVAC design load calculations are desired (see :ref:`zones_spaces`). + .. [#] UnitLocation choices are "conditioned space", "basement - unconditioned", "basement - conditioned", "attic - unvented", "attic - vented", "garage", "crawlspace - unvented", "crawlspace - vented", "crawlspace - conditioned", "other exterior", "other housing unit", "other heated space", "other multifamily buffer space", "other non-freezing space", "roof deck", "manufactured home belly", or "unconditioned space". + .. [#] If UnitLocation not provided, defaults based on the distribution system: + + \- **Air**: same default logic as :ref:`waterheatingsystems` + + \- **DSE**: "conditioned space" if ``FractionHeatLoadServed`` is 1, otherwise "unconditioned space" + + .. [#] HVACDistribution type must be :ref:`hvac_distribution_air` (type: "fan coil") or :ref:`hvac_distribution_dse`. + .. [#] IsSharedSystem should be true if the SFA/MF building has multiple ground source heat pumps connected to a shared hydronic circulation loop. + .. [#] Heating capacity autosized per ACCA Manual J/S based on heating design load. + .. [#] Cooling capacity autosized per ACCA Manual J/S based on cooling design load. + .. [#] BackupType choices are "integrated" or "separate". + Heat pump backup will only operate during colder temperatures when the heat pump runs out of heating capacity or is disabled due to a switchover/lockout temperature. + Use "integrated" if the heat pump's distribution system and blower fan power applies to the backup heating (e.g., built-in electric strip heat or an integrated backup furnace, i.e., a dual-fuel heat pump). + Use "separate" if the backup system has its own distribution system (e.g., electric baseboard or a boiler). + Additional backup inputs are described in :ref:`hvac_hp_backup`. + .. [#] The sum of all ``FractionHeatLoadServed`` (across all HVAC systems) must be less than or equal to 1. + .. [#] The sum of all ``FractionCoolLoadServed`` (across all HVAC systems) must be less than or equal to 1. + .. [#] NumberofUnitsServed only required if IsSharedSystem is true, in which case it must be > 1. + .. [#] AttachedToGeothermalLoop must reference a ``GeothermalLoop``. + .. [#] If AttachedToGeothermalLoop not provided, the ground-to-air heat pump will be automatically attached to a geothermal loop that is entirely defaulted. + .. [#] If PumpPowerWattsPerTon not provided, defaults to 80 W/ton for a closed loop system. + .. [#] Pump power is calculated using PumpPowerWattsPerTon and the cooling capacity in tons, unless the system only provides heating, in which case the heating capacity in tons is used instead. + Any pump power that is shared by multiple dwelling units should be included in SharedLoopWatts, *not* PumpPowerWattsPerTon, so that shared loop pump power attributed to the dwelling unit is calculated. + .. [#] SharedLoopWatts only required if IsSharedSystem is true. + .. [#] Shared loop pump power attributed to the dwelling unit is calculated as SharedLoopWatts / NumberofUnitsServed. + .. [#] ChargeDefectRatio is defined as (InstalledCharge - DesignCharge) / DesignCharge; a value of zero means no refrigerant charge defect. + A non-zero charge defect should typically only be applied for systems that are charged on site, not for systems that have pre-charged line sets. + See `ANSI/RESNET/ACCA 310-2020 `_ for more information. + .. _hvac_hp_water_loop: Water-Loop-to-Air Heat Pump From 1fff17528939206be6ab6f1ebeb71c9111ec3489 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Tue, 2 Sep 2025 16:32:42 -0700 Subject: [PATCH 21/25] Typo. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/resources/hvac.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 91b934470e..ae44b9f1dd 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 51b02b03-ef03-47d4-bac7-be9b0d495017 - 2025-09-02T22:59:49Z + 7c73d92b-da3c-46c9-954d-6f51850e667b + 2025-09-02T23:32:26Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -414,7 +414,7 @@ hvac.rb rb resource - A1BFDB2B + DAFF5395 hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index c446a32068..f7f4143612 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -1154,9 +1154,9 @@ def self.get_pump_power_watts(hvac_system) return hvac_system.electric_auxiliary_energy / 2.08 elsif hvac_system.is_a?(HPXML::HeatPump) && (not hvac_system.pump_watts_per_ton.nil?) if hvac_system.cooling_capacity > 1.0 - pump_power_watts = hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.cooling_capacity, 'Btu/hr', 'ton') + hvac_system.fan_coil_watts + pump_power_watts = hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.cooling_capacity, 'Btu/hr', 'ton') else - pump_power_watts = hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.heating_capacity, 'Btu/hr', 'ton') + hvac_system.fan_coil_watts + pump_power_watts = hvac_system.pump_watts_per_ton * UnitConversions.convert(hvac_system.heating_capacity, 'Btu/hr', 'ton') end if (not hvac_system.fan_coil_watts.nil?) pump_power_watts += hvac_system.fan_coil_watts From 33de98f8944a22765be915efc977228693199ae5 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 3 Sep 2025 00:29:17 +0000 Subject: [PATCH 22/25] Latest results. --- workflow/tests/base_results/results_simulations_bills.csv | 2 +- workflow/tests/base_results/results_simulations_energy.csv | 2 +- workflow/tests/base_results/results_simulations_misc.csv | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/workflow/tests/base_results/results_simulations_bills.csv b/workflow/tests/base_results/results_simulations_bills.csv index 5b6c7b5915..8247eb1fd8 100644 --- a/workflow/tests/base_results/results_simulations_bills.csv +++ b/workflow/tests/base_results/results_simulations_bills.csv @@ -298,7 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,1842.25,144.0,169 base-hvac-ground-to-air-heat-pump-heating-only.xml,1630.21,144.0,1486.21,0.0,1630.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,1779.47,144.0,1635.47,0.0,1779.47,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,1695.58,144.0,1551.58,0.0,1695.58,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-hvac-ground-to-water-heat-pump.xml,1482.41,144.0,1338.41,0.0,1482.41,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,1516.11,144.0,1372.11,0.0,1516.11,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,2391.78,144.0,2247.78,0.0,2391.78,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,2306.39,144.0,2162.39,0.0,2306.39,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,2429.04,144.0,2285.04,0.0,2429.04,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_energy.csv b/workflow/tests/base_results/results_simulations_energy.csv index c169f8fdb5..a26d4ac458 100644 --- a/workflow/tests/base_results/results_simulations_energy.csv +++ b/workflow/tests/base_results/results_simulations_energy.csv @@ -298,7 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,46.656,46.656,46. base-hvac-ground-to-air-heat-pump-heating-only.xml,40.831,40.831,40.831,40.831,0.0,0.0,0.0,0.0,0.0,0.0,7.046,1.958,0.0,0.0,0.0,0.0,10.735,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.156,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,44.931,44.931,44.931,44.931,0.0,0.0,0.0,0.0,0.0,0.0,8.555,2.413,0.0,0.0,1.164,1.019,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,42.626,42.626,42.626,42.626,0.0,0.0,0.0,0.0,0.0,0.0,5.977,1.855,0.0,0.0,1.505,1.509,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-hvac-ground-to-water-heat-pump.xml,36.77,36.77,36.77,36.77,0.0,0.0,0.0,0.0,0.0,0.0,2.412,0.123,0.0,0.0,1.775,0.103,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,37.696,37.696,37.696,37.696,0.0,0.0,0.0,0.0,0.0,0.0,2.412,0.668,0.0,0.0,1.775,0.483,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,61.753,61.753,61.753,61.753,0.0,0.0,0.0,0.0,0.0,0.0,16.67,1.592,5.304,0.182,5.46,0.765,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,59.407,59.407,59.407,59.407,0.0,0.0,0.0,0.0,0.0,0.0,15.431,1.294,5.123,0.17,5.111,0.498,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,62.777,62.777,62.777,62.777,0.0,0.0,0.0,0.0,0.0,0.0,18.165,1.473,3.998,0.107,6.761,0.493,10.77,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_misc.csv b/workflow/tests/base_results/results_simulations_misc.csv index 2ad5aec710..237cd0dba3 100644 --- a/workflow/tests/base_results/results_simulations_misc.csv +++ b/workflow/tests/base_results/results_simulations_misc.csv @@ -298,7 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,0.0,0.0,0.0,1286. base-hvac-ground-to-air-heat-pump-heating-only.xml,0.0,0.0,0.0,1286.4,890.5,11468.6,3942.3,4487.7,1890.2,4487.7,4487.7,1890.2,4487.7,30.981,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,10.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,4354.5,2470.6,4354.5,4354.5,2470.6,4354.5,27.899,25.563,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,4016.2,2628.3,4016.2,4016.2,2628.3,4016.2,31.346,24.084,0.0 -base-hvac-ground-to-water-heat-pump.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,2576.7,2355.2,2576.7,2576.7,2355.2,2576.7,17.113,13.107,0.0 +base-hvac-ground-to-water-heat-pump.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,2707.1,2432.5,2707.1,2707.1,2432.5,2707.1,17.113,13.107,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,10233.3,4592.1,10233.3,10233.3,4592.1,10233.3,33.093,26.404,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,9996.3,4294.6,9996.3,9996.3,4294.6,9996.3,33.089,26.109,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,9289.7,5573.8,9289.7,9289.7,5573.8,9289.7,33.092,25.461,0.0 From 9989811805f42abb48315f575ccf0819700fd240 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Wed, 3 Sep 2025 15:34:04 -0700 Subject: [PATCH 23/25] Set coil rated COPs and water temperatures, and secondary pump EMS programs. --- HPXMLtoOpenStudio/measure.xml | 6 +- HPXMLtoOpenStudio/resources/hvac.rb | 125 +++++++++++++++++----------- 2 files changed, 80 insertions(+), 51 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index ae44b9f1dd..3c3407a451 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 7c73d92b-da3c-46c9-954d-6f51850e667b - 2025-09-02T23:32:26Z + 546c4160-99ab-4636-b31e-61f0208579d8 + 2025-09-03T22:21:01Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -414,7 +414,7 @@ hvac.rb rb resource - DAFF5395 + 56D635C9 hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index f7f4143612..7e6a7dd985 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -534,7 +534,7 @@ def self.apply_evaporative_cooler(model, hpxml_bldg, cooling_system, hvac_sequen # @param hvac_sequential_load_fracs [Hash>] Map of htg/clg => Array of daily fractions of remaining heating/cooling load to be met by the HVAC system # @param control_zone [OpenStudio::Model::ThermalZone] Conditioned space thermal zone # @param hvac_unavailable_periods [Hash] Map of htg/clg => HPXML::UnavailablePeriods for heating/cooling - # @return [OpenStudio::Model::AirLoopHVAC] The newly created air loop hvac object + # @return [OpenStudio::Model::AirLoopHVAC or OpenStudio::Model::ZoneHVACFourPipeFanCoil] The newly created air loop or zone hvac object def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml_header, heat_pump, hvac_sequential_load_fracs, control_zone, hvac_unavailable_periods) @@ -777,22 +777,22 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml htg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRHeating.new(model) htg_coil.setName(obj_name + ' htg coil') htg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - # htg_coil.setSourceSideReferenceFlowRate() # ComStock autosizes + htg_coil.setSourceSideReferenceFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # ComStock autosizes # htg_coil.setLoadSideReferenceFlowRate() # ComStock autosizes # htg_coil.setCapacityModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_61WG_Glycol_90kW_htg.csv # htg_coil.setElectricInputtoOutputRatioModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_61WG_Glycol_90kW_htg.csv # htg_coil.setElectricInputtoOutputRatioModifierFunctionofPartLoadRatioCurve() # ComStock assumes a standard EIR vs. PLR line - # htg_coil.setReferenceCoefficientofPerformance() # ComStock uses 1 / rated_heating_eir + htg_coil.setReferenceCoefficientofPerformance(1 / 0.23419) # ComStock uses 1 / rated_heating_eir clg_coil = OpenStudio::Model::HeatPumpPlantLoopEIRCooling.new(model) clg_coil.setName(obj_name + ' clg coil') clg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) - # clg_coil.setSourceSideReferenceFlowRate() # ComStock autosizes + clg_coil.setSourceSideReferenceFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # ComStock autosizes # clg_coil.setLoadSideReferenceFlowRate() # ComStock autosizes # clg_coil.setCapacityModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_30WG_90kW_clg.csv # clg_coil.setElectricInputtoOutputRatioModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_30WG_90kW_clg.csv # clg_coil.setElectricInputtoOutputRatioModifierFunctionofPartLoadRatioCurve() # ComStock assumes a standard EIR vs. PLR line - # clg_coil.setReferenceCoefficientofPerformance() # ComStock uses 1 / rated_cooling_eir + clg_coil.setReferenceCoefficientofPerformance(1 / 0.21505) # ComStock uses 1 / rated_cooling_eir htg_coil.setCompanionCoolingHeatPump(clg_coil) clg_coil.setCompanionHeatingHeatPump(htg_coil) @@ -927,7 +927,14 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater add_pump_power_ems_program(model, pump, htg_coil, heat_pump) - max_water_flow = UnitConversions.convert([heat_pump.heating_capacity, heat_pump.cooling_capacity].max, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s + htg_design_temp = 140.0 # F; ComStock uses this value + clg_design_temp = 44.0 # F; ComStock uses this value + + htg_temp_diff = 20.0 # deltaF; ComStock uses this value + clg_temp_diff = 11.0 # deltaF; what does ComStock use? + + htg_max_water_flow = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(htg_temp_diff, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s + clg_max_water_flow = UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W') / UnitConversions.convert(clg_temp_diff, 'deltaF', 'deltaC') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s plant_loop.addDemandBranchForComponent(htg_coil) plant_loop.addDemandBranchForComponent(clg_coil) @@ -948,7 +955,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml supply_setpoint = Model.add_schedule_constant( model, name: "#{obj_name} hot water supply setpoint", - value: 60.000, + value: UnitConversions.convert(htg_design_temp, 'F', 'C'), limits: EPlus::ScheduleTypeLimitsTemperature ) @@ -959,18 +966,8 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml loop_sizing = hw_loop.sizingPlant loop_sizing.setLoopType('Heating') - loop_sizing.setDesignLoopExitTemperature(60.000) # ComStock uses this value (140F) - loop_sizing.setLoopDesignTemperatureDifference(11.111) - - htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) - htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) - htg_coil.setPerformanceInputMethod('NominalCapacity') - - bb_ua = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'deltaF', 'deltaC') * 3.0 # W/K - htg_coil.setUFactorTimesAreaValue(bb_ua) - htg_coil.setMaximumWaterFlowRate(max_water_flow) - htg_coil.setName(obj_name + ' htg coil') - hw_loop.addDemandBranchForComponent(htg_coil) + loop_sizing.setDesignLoopExitTemperature(UnitConversions.convert(htg_design_temp, 'F', 'C')) + loop_sizing.setLoopDesignTemperatureDifference(UnitConversions.convert(htg_temp_diff, 'deltaF', 'deltaC')) pump = Model.add_pump_variable_speed( model, @@ -978,11 +975,27 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml rated_power: pump_w ) pump.addToNode(hw_loop.supplyInletNode) + add_fan_pump_disaggregation_ems_program(model, pump, htg_coil, nil, nil, heat_pump) + add_pump_power_ems_program(model, pump, htg_coil, heat_pump) + + bb_ua = UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'deltaF', 'deltaC') * 3.0 # W/K + + htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule) + htg_coil.setName(obj_name + ' htg coil') + htg_coil.setRatedCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) + htg_coil.setPerformanceInputMethod('NominalCapacity') + htg_coil.setUFactorTimesAreaValue(bb_ua) + htg_coil.setMaximumWaterFlowRate(htg_max_water_flow) + htg_coil.setRatedInletWaterTemperature(UnitConversions.convert(htg_design_temp, 'F', 'C')) + htg_coil.setRatedOutletWaterTemperature(UnitConversions.convert(htg_design_temp - htg_temp_diff, 'F', 'C')) + # htg_coil.setRatedInletAirTemperature() + # htg_coil.setRatedOutletAirTemperature() + hw_loop.addDemandBranchForComponent(htg_coil) supply_setpoint = Model.add_schedule_constant( model, name: "#{obj_name} chilled water supply setpoint", - value: 6.666, + value: UnitConversions.convert(clg_design_temp, 'F', 'C'), limits: EPlus::ScheduleTypeLimitsTemperature ) @@ -993,20 +1006,8 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml loop_sizing = chw_loop.sizingPlant loop_sizing.setLoopType('Cooling') - loop_sizing.setDesignLoopExitTemperature(6.666) # ComStock uses this value (44F) - loop_sizing.setLoopDesignTemperatureDifference(5.611) - - clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) - clg_coil.setDesignWaterFlowRate(0.0022) - clg_coil.setDesignAirFlowRate(1.45) - clg_coil.setDesignInletWaterTemperature(6.1) - clg_coil.setDesignInletAirTemperature(25.0) - clg_coil.setDesignOutletAirTemperature(10.0) - clg_coil.setDesignInletAirHumidityRatio(0.012) - clg_coil.setDesignOutletAirHumidityRatio(0.008) - - clg_coil.setName(obj_name + ' clg coil') - chw_loop.addDemandBranchForComponent(clg_coil) + loop_sizing.setDesignLoopExitTemperature(UnitConversions.convert(clg_design_temp, 'F', 'C')) + loop_sizing.setLoopDesignTemperatureDifference(UnitConversions.convert(clg_temp_diff, 'deltaF', 'deltaC')) pump = Model.add_pump_variable_speed( model, @@ -1014,6 +1015,19 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml rated_power: pump_w ) pump.addToNode(chw_loop.supplyInletNode) + add_fan_pump_disaggregation_ems_program(model, pump, nil, clg_coil, nil, heat_pump) + add_pump_power_ems_program(model, pump, clg_coil, heat_pump) + + clg_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule) + clg_coil.setName(obj_name + ' clg coil') + clg_coil.setDesignWaterFlowRate(clg_max_water_flow) + clg_coil.setDesignAirFlowRate(UnitConversions.convert(fan_cfms[0], 'cfm', 'm^3/s')) + clg_coil.setDesignInletWaterTemperature(UnitConversions.convert(clg_design_temp, 'F', 'C')) + clg_coil.setDesignInletAirTemperature(25.0) + clg_coil.setDesignOutletAirTemperature(10.0) + clg_coil.setDesignInletAirHumidityRatio(0.012) + clg_coil.setDesignOutletAirHumidityRatio(0.008) + chw_loop.addDemandBranchForComponent(clg_coil) zone_hvac = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, model.alwaysOnDiscreteSchedule, fan, clg_coil, htg_coil) zone_hvac.setCapacityControlMethod('CyclingFan') @@ -1021,11 +1035,11 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml zone_hvac.setMaximumSupplyAirTemperatureInHeatingMode(UnitConversions.convert(120.0, 'F', 'C')) zone_hvac.setHeatingConvergenceTolerance(0.001) zone_hvac.setMinimumSupplyAirTemperatureInCoolingMode(UnitConversions.convert(55.0, 'F', 'C')) - zone_hvac.setMaximumColdWaterFlowRate(max_water_flow) + zone_hvac.setMaximumColdWaterFlowRate(clg_max_water_flow) zone_hvac.setCoolingConvergenceTolerance(0.001) zone_hvac.setMaximumOutdoorAirFlowRate(0.0) zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert(fan_cfms[0], 'cfm', 'm^3/s')) - zone_hvac.setMaximumHotWaterFlowRate(max_water_flow) + zone_hvac.setMaximumHotWaterFlowRate(htg_max_water_flow) zone_hvac.addToThermalZone(control_zone) end @@ -2008,7 +2022,7 @@ def self.add_fan_power_ems_program(model, fan, hp_min_temp) ) end - # Create EMS program to correctly account for pump power consumption based on heating object part load ratio + # Create EMS program to correctly account for pump power consumption based on heating (or cooling) object part load ratio # Without EMS, the pump power will vary according to the plant loop part load ratio # (based on flow rate) rather than the component part load ratio (based on load). # @@ -2017,18 +2031,18 @@ def self.add_fan_power_ems_program(model, fan, hp_min_temp) # @param heating_object [OpenStudio::Model::AirLoopHVACUnitarySystem or OpenStudio::Model::BoilerHotWater or OpenStudio::Model::HeatPumpPlantLoopEIRHeating] OpenStudio unitary system object or boiler object or plant loop heat pump object # @param hvac_system [HPXML::HeatPump or HPXML::HeatingSystem] HPXML heat pump or heating system object # @return [nil] - def self.add_pump_power_ems_program(model, pump, heating_object, hvac_system) + def self.add_pump_power_ems_program(model, pump, heating_or_cooling_object, hvac_system) # Sensors - if heating_object.is_a? OpenStudio::Model::BoilerHotWater + if heating_or_cooling_object.is_a? OpenStudio::Model::BoilerHotWater heating_plr_sensor = Model.add_ems_sensor( model, - name: "#{heating_object.name} plr s", + name: "#{heating_or_cooling_object.name} plr s", output_var_or_meter_name: 'Boiler Part Load Ratio', - key_name: heating_object.name + key_name: heating_or_cooling_object.name ) - elsif heating_object.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem - htg_coil = heating_object.heatingCoil.get - clg_coil = heating_object.coolingCoil.get + elsif heating_or_cooling_object.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem + htg_coil = heating_or_cooling_object.heatingCoil.get + clg_coil = heating_or_cooling_object.coolingCoil.get # GHP model, variable speed coils if htg_coil.to_CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized htg_coil = htg_coil.to_CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.get @@ -2073,13 +2087,13 @@ def self.add_pump_power_ems_program(model, pump, heating_object, hvac_system) else heating_plr_sensor = Model.add_ems_sensor( model, - name: "#{heating_object.name} plr s", + name: "#{heating_or_cooling_object.name} plr s", output_var_or_meter_name: 'Unitary System Part Load Ratio', - key_name: heating_object.name + key_name: heating_or_cooling_object.name ) end - elsif heating_object.is_a? OpenStudio::Model::HeatPumpPlantLoopEIRHeating - htg_coil = heating_object + elsif heating_or_cooling_object.is_a? OpenStudio::Model::HeatPumpPlantLoopEIRHeating + htg_coil = heating_or_cooling_object clg_coil = htg_coil.companionCoolingHeatPump.get heating_plr_sensor = Model.add_ems_sensor( model, @@ -2093,6 +2107,21 @@ def self.add_pump_power_ems_program(model, pump, heating_object, hvac_system) output_var_or_meter_name: 'Heat Pump Part Load Ratio', key_name: clg_coil.name ) + elsif heating_or_cooling_object.is_a? OpenStudio::Model::HeatPumpPlantLoopEIRCooling + clg_coil = heating_or_cooling_object + htg_coil = clg_coil.companionHeatingHeatPump.get + cooling_plr_sensor = Model.add_ems_sensor( + model, + name: "#{clg_coil.name} plr s", + output_var_or_meter_name: 'Heat Pump Part Load Ratio', + key_name: clg_coil.name + ) + heating_plr_sensor = Model.add_ems_sensor( + model, + name: "#{htg_coil.name} plr s", + output_var_or_meter_name: 'Heat Pump Part Load Ratio', + key_name: htg_coil.name + ) end pump_mfr_sensor = Model.add_ems_sensor( From 6f4c609e8a8d7afe895860bb5300a4516b5fc320 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 3 Sep 2025 23:30:17 +0000 Subject: [PATCH 24/25] Latest results. --- workflow/tests/base_results/results_simulations_bills.csv | 2 +- workflow/tests/base_results/results_simulations_energy.csv | 2 +- workflow/tests/base_results/results_simulations_misc.csv | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/workflow/tests/base_results/results_simulations_bills.csv b/workflow/tests/base_results/results_simulations_bills.csv index 8247eb1fd8..13cf4576bc 100644 --- a/workflow/tests/base_results/results_simulations_bills.csv +++ b/workflow/tests/base_results/results_simulations_bills.csv @@ -298,7 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,1842.25,144.0,169 base-hvac-ground-to-air-heat-pump-heating-only.xml,1630.21,144.0,1486.21,0.0,1630.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,1779.47,144.0,1635.47,0.0,1779.47,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,1695.58,144.0,1551.58,0.0,1695.58,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-hvac-ground-to-water-heat-pump.xml,1516.11,144.0,1372.11,0.0,1516.11,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,1640.02,144.0,1496.02,0.0,1640.02,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,2391.78,144.0,2247.78,0.0,2391.78,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,2306.39,144.0,2162.39,0.0,2306.39,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,2429.04,144.0,2285.04,0.0,2429.04,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_energy.csv b/workflow/tests/base_results/results_simulations_energy.csv index a26d4ac458..bc9acbede8 100644 --- a/workflow/tests/base_results/results_simulations_energy.csv +++ b/workflow/tests/base_results/results_simulations_energy.csv @@ -298,7 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,46.656,46.656,46. base-hvac-ground-to-air-heat-pump-heating-only.xml,40.831,40.831,40.831,40.831,0.0,0.0,0.0,0.0,0.0,0.0,7.046,1.958,0.0,0.0,0.0,0.0,10.735,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.156,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,44.931,44.931,44.931,44.931,0.0,0.0,0.0,0.0,0.0,0.0,8.555,2.413,0.0,0.0,1.164,1.019,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,42.626,42.626,42.626,42.626,0.0,0.0,0.0,0.0,0.0,0.0,5.977,1.855,0.0,0.0,1.505,1.509,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-hvac-ground-to-water-heat-pump.xml,37.696,37.696,37.696,37.696,0.0,0.0,0.0,0.0,0.0,0.0,2.412,0.668,0.0,0.0,1.775,0.483,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +base-hvac-ground-to-water-heat-pump.xml,41.1,41.1,41.1,41.1,0.0,0.0,0.0,0.0,0.0,0.0,4.133,1.312,0.0,0.0,2.898,0.977,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,61.753,61.753,61.753,61.753,0.0,0.0,0.0,0.0,0.0,0.0,16.67,1.592,5.304,0.182,5.46,0.765,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,59.407,59.407,59.407,59.407,0.0,0.0,0.0,0.0,0.0,0.0,15.431,1.294,5.123,0.17,5.111,0.498,10.771,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,62.777,62.777,62.777,62.777,0.0,0.0,0.0,0.0,0.0,0.0,18.165,1.473,3.998,0.107,6.761,0.493,10.77,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.073,0.0,0.0,0.284,0.347,1.436,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_misc.csv b/workflow/tests/base_results/results_simulations_misc.csv index 237cd0dba3..3e0366c78f 100644 --- a/workflow/tests/base_results/results_simulations_misc.csv +++ b/workflow/tests/base_results/results_simulations_misc.csv @@ -298,7 +298,7 @@ base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml,0.0,0.0,0.0,1286. base-hvac-ground-to-air-heat-pump-heating-only.xml,0.0,0.0,0.0,1286.4,890.5,11468.6,3942.3,4487.7,1890.2,4487.7,4487.7,1890.2,4487.7,30.981,0.0,0.0 base-hvac-ground-to-air-heat-pump-var-speed-experimental.xml,10.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,4354.5,2470.6,4354.5,4354.5,2470.6,4354.5,27.899,25.563,0.0 base-hvac-ground-to-air-heat-pump-var-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,4016.2,2628.3,4016.2,4016.2,2628.3,4016.2,31.346,24.084,0.0 -base-hvac-ground-to-water-heat-pump.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,2707.1,2432.5,2707.1,2707.1,2432.5,2707.1,17.113,13.107,0.0 +base-hvac-ground-to-water-heat-pump.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,3197.5,2760.2,3197.5,3197.5,2760.2,3197.5,17.113,13.107,0.0 base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,10233.3,4592.1,10233.3,10233.3,4592.1,10233.3,33.093,26.404,0.0 base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,9996.3,4294.6,9996.3,9996.3,4294.6,9996.3,33.089,26.109,0.0 base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml,0.0,0.0,0.0,1286.4,890.5,11468.5,3942.3,9289.7,5573.8,9289.7,9289.7,5573.8,9289.7,33.092,25.461,0.0 From 5af0e1695ac7ff7aa9e872a719fc19d34dd85191 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 8 Sep 2025 15:00:27 -0700 Subject: [PATCH 25/25] Move airflow lines under ground-to-air. --- HPXMLtoOpenStudio/measure.xml | 8 ++++---- HPXMLtoOpenStudio/resources/defaults.rb | 17 +++++++++++------ HPXMLtoOpenStudio/resources/hvac.rb | 14 +++++++------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 3c3407a451..4e24e20bd1 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 546c4160-99ab-4636-b31e-61f0208579d8 - 2025-09-03T22:21:01Z + 01ac3d88-9b68-4c6d-a84c-2941565a4191 + 2025-09-08T21:59:26Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -348,7 +348,7 @@ defaults.rb rb resource - 8262FE71 + B358A1CA electric_panel.rb @@ -414,7 +414,7 @@ hvac.rb rb resource - 56D635C9 + 0E49877A hvac_sizing.rb diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 9ade0865f6..ce79a7a3d3 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -7786,6 +7786,11 @@ def self.set_ground_to_air_heat_pump_cops(heat_pump, cop_ratios, mode) end # TODO + # + # @param heat_pump [HPXML::HeatPump] The HPXML heat pump of interest + # @param cop_ratios [Array] Heating or cooling COP ratios for each speed + # @param mode [Symbol] Heating or cooling + # @return [nil] def self.set_ground_to_water_heat_pump_cops(heat_pump, cop_ratios, mode) hp_ap = heat_pump.additional_properties # Fan/pump adjustments calculations @@ -7942,9 +7947,9 @@ def self.interpolate_seer2(seer2, eer2, seer2_array, seer2_eer2_ratio_array, cop # Based on RESNET HERS Addendum 82 clg_ap.cool_rated_shr_gross = 0.708 - clg_ap.cool_rated_cfm_per_ton = HVAC::RatedCFMPerTon + # clg_ap.cool_rated_cfm_per_ton = HVAC::RatedCFMPerTon - clg_ap.cool_capacity_ratios = [1.0] + # clg_ap.cool_capacity_ratios = [1.0] # E+ equation fit coil coefficients generated following approach in Tang's thesis: # See Appendix B of https://shareok.org/bitstream/handle/11244/10075/Tang_okstate_0664M_1318.pdf?sequence=1&isAllowed=y @@ -7954,7 +7959,7 @@ def self.interpolate_seer2(seer2, eer2, seer2_array, seer2_eer2_ratio_array, cop # Cooling Curves clg_ap.cool_cap_curve_spec = [[-5.45013866666657, 7.42301402824225, -1.43760846638838, 0.249103937703341, 0.0378875477019811]] - clg_ap.cool_power_curve_spec = [[-4.21572180554818, 0.322682268675807, 4.56870615863483, 0.154605773589744, -0.167531037948482]] + # clg_ap.cool_power_curve_spec = [[-4.21572180554818, 0.322682268675807, 4.56870615863483, 0.154605773589744, -0.167531037948482]] clg_ap.cool_sh_curve_spec = [[0.56143829895505, 18.7079597251858, -19.1482655264078, -0.138154731772664, 0.4823357726442, -0.00164644360129174]] cool_cop_ratios = [1.0] @@ -8165,9 +8170,9 @@ def self.interpolate_hspf2(hspf2, qm17full, hspf2_array, qm17full_array, cop47fu return elsif heating_system.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater # Based on RESNET HERS Addendum 82 - htg_ap.heat_rated_cfm_per_ton = HVAC::RatedCFMPerTon + # htg_ap.heat_rated_cfm_per_ton = HVAC::RatedCFMPerTon - htg_ap.heat_capacity_ratios = [1.0] + # htg_ap.heat_capacity_ratios = [1.0] # E+ equation fit coil coefficients following approach from Tang's thesis: # See Appendix B Figure B.3 of https://shareok.org/bitstream/handle/11244/10075/Tang_okstate_0664M_1318.pdf?sequence=1&isAllowed=y # Coefficients generated by catalog data: https://www.climatemaster.com/download/18.274be999165850ccd5b5b73/1535543867815/lc377-climatemaster-commercial-tranquility-20-single-stage-ts-series-water-source-heat-pump-submittal-set.pdf @@ -8176,7 +8181,7 @@ def self.interpolate_hspf2(hspf2, qm17full, hspf2_array, qm17full_array, cop47fu # Heating Curves htg_ap.heat_cap_curve_spec = [[-3.75031847962047, -2.18062040443483, 6.8363364819032, 0.188376814356582, 0.0869274802923634]] - htg_ap.heat_power_curve_spec = [[-8.4754723813072, 8.10952801956388, 1.38771494628738, -0.33766445915032, 0.0223085217874051]] + # htg_ap.heat_power_curve_spec = [[-8.4754723813072, 8.10952801956388, 1.38771494628738, -0.33766445915032, 0.0223085217874051]] heat_cop_ratios = [1.0] set_ground_to_water_heat_pump_cops(heating_system, heat_cop_ratios, :htg) diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 7e6a7dd985..3dade1169a 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -550,11 +550,6 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml geothermal_loop = heat_pump.geothermal_loop hp_ap = heat_pump.additional_properties - htg_cfm = hp_ap.heating_actual_airflow_cfm - clg_cfm = hp_ap.cooling_actual_airflow_cfm - htg_air_flow_rated = calc_rated_airflow(heat_pump.heating_capacity, hp_ap.heat_rated_cfm_per_ton, 'm^3/s') - clg_air_flow_rated = calc_rated_airflow(heat_pump.cooling_capacity, hp_ap.cool_rated_cfm_per_ton, 'm^3/s') - if hp_ap.frac_glycol == 0 hp_ap.fluid_type = EPlus::FluidWater runner.registerWarning("Specified #{hp_ap.fluid_type} fluid type and 0 fraction of glycol, so assuming #{EPlus::FluidWater} fluid type.") @@ -566,6 +561,11 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + htg_cfm = hp_ap.heating_actual_airflow_cfm + clg_cfm = hp_ap.cooling_actual_airflow_cfm + htg_air_flow_rated = calc_rated_airflow(heat_pump.heating_capacity, hp_ap.heat_rated_cfm_per_ton, 'm^3/s') + clg_air_flow_rated = calc_rated_airflow(heat_pump.cooling_capacity, hp_ap.cool_rated_cfm_per_ton, 'm^3/s') + if [HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard].include? hpxml_header.ground_to_air_heat_pump_model_type # Cooling Coil clg_total_cap_curve = Model.add_curve_quad_linear( @@ -778,7 +778,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml htg_coil.setName(obj_name + ' htg coil') htg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W')) htg_coil.setSourceSideReferenceFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # ComStock autosizes - # htg_coil.setLoadSideReferenceFlowRate() # ComStock autosizes + # htg_coil.setLoadSideReferenceFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # ComStock autosizes # htg_coil.setCapacityModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_61WG_Glycol_90kW_htg.csv # htg_coil.setElectricInputtoOutputRatioModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_61WG_Glycol_90kW_htg.csv # htg_coil.setElectricInputtoOutputRatioModifierFunctionofPartLoadRatioCurve() # ComStock assumes a standard EIR vs. PLR line @@ -788,7 +788,7 @@ def self.apply_ground_source_heat_pump(runner, model, weather, hpxml_bldg, hpxml clg_coil.setName(obj_name + ' clg coil') clg_coil.setReferenceCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W')) clg_coil.setSourceSideReferenceFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # ComStock autosizes - # clg_coil.setLoadSideReferenceFlowRate() # ComStock autosizes + # clg_coil.setLoadSideReferenceFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # ComStock autosizes # clg_coil.setCapacityModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_30WG_90kW_clg.csv # clg_coil.setElectricInputtoOutputRatioModifierFunctionofTemperatureCurve() # ComStock uses TableLookup for Carrier_30WG_90kW_clg.csv # clg_coil.setElectricInputtoOutputRatioModifierFunctionofPartLoadRatioCurve() # ComStock assumes a standard EIR vs. PLR line