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..1815028293 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 @@ -6195,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 @@ -6232,6 +6235,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 +6518,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..d6657056d1 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 + 8f4636c3-982c-47eb-a3d1-e69d82de664f + 2025-09-02T22:59:47Z 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 + 2F23596A constants.rb diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 10a4ab12cf..4e24e20bd1 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - c17fea11-5360-49b1-928e-22fe6122fd51 - 2025-08-28T03:34:02Z + 01ac3d88-9b68-4c6d-a84c-2941565a4191 + 2025-09-08T21:59:26Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -348,7 +348,7 @@ defaults.rb rb resource - CCE4785C + B358A1CA electric_panel.rb @@ -384,7 +384,7 @@ hpxml.rb rb resource - 0F94A077 + 2F8A1285 hpxml_schema/HPXML.xsd @@ -402,7 +402,7 @@ hpxml_schematron/EPvalidator.sch sch resource - 4BBE1448 + 813783B0 hpxml_schematron/iso-schematron.xsd @@ -414,13 +414,13 @@ hvac.rb rb resource - 1275B557 + 0E49877A hvac_sizing.rb rb resource - 30537BFF + EEF8EC23 internal_gains.rb @@ -438,7 +438,7 @@ location.rb rb resource - 7DB56BD8 + 815CA656 materials.rb diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 8360166c55..ce79a7a3d3 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,13 +2080,22 @@ 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() 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, @@ -2099,7 +2108,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 +2353,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) @@ -6558,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 @@ -7768,6 +7785,36 @@ def self.set_ground_to_air_heat_pump_cops(heat_pump, cop_ratios, mode) end 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 + # 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 @@ -7804,14 +7851,105 @@ 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 - case hpxml_header.ground_to_air_heat_pump_model_type - when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard - clg_ap.cool_capacity_ratios = [1.0] + set_ground_to_air_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + return + 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 + + # 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 @@ -7821,79 +7959,14 @@ 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] - 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) - return + set_ground_to_water_heat_pump_cops(cooling_system, cool_cop_ratios, :clg) + return + end end # Based on RESNET HERS Addendum 82 @@ -8011,13 +8084,95 @@ 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 - case hpxml_header.ground_to_air_heat_pump_model_type - when HPXML::AdvancedResearchGroundToAirHeatPumpModelTypeStandard - htg_ap.heat_capacity_ratios = [1.0] + 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 + + # 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 @@ -8026,74 +8181,12 @@ 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] - 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) - return + + set_ground_to_water_heat_pump_cops(heating_system, heat_cop_ratios, :htg) + return + end end htg_ap.heat_cap_fflow_spec = htg_ap.heat_cap_fflow_spec_iq diff --git a/HPXMLtoOpenStudio/resources/hpxml.rb b/HPXMLtoOpenStudio/resources/hpxml.rb index 6be98943da..50d39d09a7 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' @@ -7045,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) @@ -7306,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? @@ -7382,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/hpxml_schematron/EPvalidator.sch b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.sch index 127cea9d40..9a5a93606f 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,19 +1628,19 @@ - [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 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 @@ -1674,13 +1674,61 @@ - [HeatPumpType=GroundSourceWithSharedLoop] + [HeatPumpType=GroundSourceToWater] + + 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=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 diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index a5a4611044..3dade1169a 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 @@ -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) @@ -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.") @@ -564,212 +559,245 @@ 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 - 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')) - 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( + 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( 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 + name: "#{obj_name} clg total cap curve", + coeff: hp_ap.cool_cap_curve_spec[0] ) - eir_fwf_curve = Model.add_curve_quadratic( + clg_sens_cap_curve = Model.add_curve_quint_linear( 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 + name: "#{obj_name} clg sens cap curve", + coeff: hp_ap.cool_sh_curve_spec[0] ) - # Recoverable heat modifier as a function of indoor wet-bulb and water entering temperatures. - waste_heat_ft = Model.add_curve_biquadratic( + clg_power_curve = Model.add_curve_quad_linear( model, - name: "WasteHeat-FT#{i + 1}", - coeff: [1, 0, 0, 0, 0, 0] + name: "#{obj_name} clg power curve", + coeff: hp_ap.cool_power_curve_spec[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::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 - 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( + 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: "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 + name: "#{obj_name} htg cap curve", + coeff: hp_ap.heat_cap_curve_spec[0] ) - # Recoverable heat modifier as a function of indoor wet-bulb and water entering temperatures. - waste_heat_ft = Model.add_curve_biquadratic( + htg_power_curve = Model.add_curve_quad_linear( model, - name: "WasteHeat-FT#{i + 1}", - coeff: [1, 0, 0, 0, 0, 0] + name: "#{obj_name} htg power curve", + coeff: hp_ap.heat_power_curve_spec[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) + 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')) + 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 - 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) + 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 + 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(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # 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 + 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(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) # 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 + clg_coil.setReferenceCoefficientofPerformance(1 / 0.21505) # 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 @@ -867,21 +895,152 @@ 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 heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + 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 + 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 + 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) # 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) - # 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 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 + elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToWater + add_pump_power_ems_program(model, pump, htg_coil, heat_pump) + + 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) + + 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) + chw_loop.addSupplyBranchForComponent(clg_coil) + + supply_setpoint = Model.add_schedule_constant( + model, + name: "#{obj_name} hot water supply setpoint", + value: UnitConversions.convert(htg_design_temp, 'F', 'C'), + 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(UnitConversions.convert(htg_design_temp, 'F', 'C')) + loop_sizing.setLoopDesignTemperatureDifference(UnitConversions.convert(htg_temp_diff, 'deltaF', 'deltaC')) + + pump = Model.add_pump_variable_speed( + model, + name: "#{obj_name} hot water pump", + 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: UnitConversions.convert(clg_design_temp, 'F', 'C'), + 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(UnitConversions.convert(clg_design_temp, 'F', 'C')) + loop_sizing.setLoopDesignTemperatureDifference(UnitConversions.convert(clg_temp_diff, 'deltaF', 'deltaC')) + + pump = Model.add_pump_variable_speed( + model, + name: "#{obj_name} chilled water pump", + 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') + 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(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(htg_max_water_flow) + zone_hvac.addToThermalZone(control_zone) end if heat_pump.is_shared_system @@ -902,13 +1061,19 @@ 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 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) - # 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 + 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 # Adds the HPXML water-loop heat pump system to the OpenStudio model. @@ -1003,10 +1168,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') 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') 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 @@ -1853,27 +2022,27 @@ 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). # # @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) + 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 @@ -1918,11 +2087,41 @@ 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_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, + 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 + ) + 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( @@ -1956,50 +2155,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") @@ -2120,6 +2323,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::HeatPumpPlantLoopEIRCooling) + var = 'Heat Pump Electricity Energy' else var = 'Cooling Coil Total Cooling Energy' end @@ -2139,6 +2344,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::HeatPumpPlantLoopEIRHeating) + var = 'Heat Pump Electricity Energy' else var = 'Heating Coil Heating Energy' end @@ -5027,11 +5234,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? @@ -5243,6 +5450,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..ac44f083f5 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 = 0.0 + 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 = 0.0 + hvac_sizings.Heat_Capacity = hvac_sizings.Cool_Capacity + end + hvac_sizings.Heat_Airflow = 0.0 + 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 @@ -5222,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 @@ -5298,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 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 diff --git a/ReportSimulationOutput/measure.rb b/ReportSimulationOutput/measure.rb index e9ddc68bce..070386b0c7 100644 --- a/ReportSimulationOutput/measure.rb +++ b/ReportSimulationOutput/measure.rb @@ -2977,6 +2977,9 @@ def get_object_outputs_by_key(model, object, class_type) elsif object.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized return { [FT::Elec, EUT::Heating] => ['Heating Coil Electricity Energy'] } + 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 if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get return { [FT::Elec, EUT::HeatingHeatPumpBackup] => ['Baseboard Electricity Energy'] } @@ -3026,6 +3029,9 @@ def get_object_outputs_by_key(model, object, class_type) elsif object.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized return { [FT::Elec, EUT::Cooling] => ['Cooling Coil Electricity Energy'] } + 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 return { [FT::Elec, EUT::Cooling] => ['Evaporative Cooler Electricity Energy'] } diff --git a/ReportSimulationOutput/measure.xml b/ReportSimulationOutput/measure.xml index 798416f271..a589a90579 100644 --- a/ReportSimulationOutput/measure.xml +++ b/ReportSimulationOutput/measure.xml @@ -3,8 +3,8 @@ 3.1 report_simulation_output df9d170c-c21a-4130-866d-0d46b06073fd - d2815bb5-3851-437a-84ad-0747dfd93113 - 2025-08-25T16:51:58Z + d77169e3-539a-4920-88f3-b5d228f9c811 + 2025-08-27T20:55:30Z 9BF1E6AC ReportSimulationOutput HPXML Simulation Output Report @@ -1991,7 +1991,7 @@ measure.rb rb script - 0B89F7D1 + 4D36A836 test_report_sim_output.rb diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index 79261e5136..d4968b1256 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 diff --git a/workflow/hpxml_inputs.json b/workflow/hpxml_inputs.json index 89d4cd715b..d8324a5426 100644 --- a/workflow/hpxml_inputs.json +++ b/workflow/hpxml_inputs.json @@ -2718,6 +2718,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..c2a1b48ee7 --- /dev/null +++ b/workflow/sample_files/base-hvac-ground-to-water-heat-pump.xml @@ -0,0 +1,478 @@ + + + + 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 + single stage + 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 diff --git a/workflow/tests/base_results/results_simulations_bills.csv b/workflow/tests/base_results/results_simulations_bills.csv index 6485a33864..13cf4576bc 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,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 e3f61e2882..bc9acbede8 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,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_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..3e0366c78f 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,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 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 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