Skip to content

Commit

Permalink
Merge pull request #708 from NREL/ansi_301_2022_shared_boilers
Browse files Browse the repository at this point in the history
ANSI 301-2022: Boilers
  • Loading branch information
shorowit authored Jan 20, 2024
2 parents 544e53e + 50f4685 commit 906da5d
Show file tree
Hide file tree
Showing 67 changed files with 72 additions and 612 deletions.
3 changes: 2 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

__New Features__
- Implements ANSI/RESNET/ICC Standard 301-2022 and Addendum C.
- ERICalculation/Version and CO2IndexCalculation/Version can now be "2022C" or "2022".
- `ERICalculation/Version` and `CO2IndexCalculation/Version` can now be "2022C" or "2022".
- Allows modeling electric battery storage, including shared batteries ("2022C" or newer).
- The `ElectricAuxiliaryEnergy` input for boilers is no longer used.
- **Breaking change**: Each `VentilationFan` must have one (and only one) `UsedFor...` element set to true.
- Ground source heat pump model enhancements.
- Allows `Roof/RadiantBarrier` to be omitted; defaults to false.
Expand Down
6 changes: 0 additions & 6 deletions docs/source/workflow_inputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -774,18 +774,12 @@ Each in-unit boiler is entered as a ``/HPXML/Building/BuildingDetails/Systems/HV
``HeatingCapacity`` double Btu/hr >= 0 Yes Heating output capacity
``AnnualHeatingEfficiency[Units="AFUE"]/Value`` double frac > 0, <= 1 Yes Rated efficiency
``FractionHeatLoadServed`` double frac >= 0, <= 1 [#]_ Yes Fraction of heating load served
``ElectricAuxiliaryEnergy`` double kWh/yr >= 0 No See [#]_ Electric auxiliary energy
=============================================== ======== ====== =============== ======== ======== =========================================

.. [#] HVACDistribution type must be :ref:`hvac_distribution_hydronic` (type: "radiator", "baseboard", "radiant floor", or "radiant ceiling") or :ref:`hvac_distribution_dse`.
Note: The choice of hydronic distribution type does not currently affect simulation results.
.. [#] HeatingSystemFuel choices are "natural gas", "fuel oil", "propane", "electricity", "wood", or "wood pellets".
.. [#] The sum of all ``FractionHeatLoadServed`` (across all HVAC systems) must be less than or equal to 1.
.. [#] If ElectricAuxiliaryEnergy not provided, defaults as follows:
\- **Oil boiler**: 330 kWh/yr
\- **Gas boiler**: 170 kWh/yr
.. _hvac_heating_shared_boiler:

Expand Down
6 changes: 5 additions & 1 deletion hpxml-measures/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@

__New Features__
- Updates to HPXML v4.0-rc3.
- Updates per ANSI/RESNET/ICC 301-2022:
- **Breaking change**: Shared boilers require `SharedLoopWatts` (and `FanCoilWatts` if a fan coil system) inputs; removed EAE input/defaults.
- Allows shared batteries (batteries serving multiple dwelling units).
- Updated default CFIS fan power to 0.58 W/cfm.
- Removed natural ventilation availability RH constraint; HR constraint remains.
- Replaces `BuildingSummary/Site/extension/GroundConductivity` with `BuildingSummary/Site/Soil/Conductivity`.
- Allows radiant barriers for additional locations (attic gable walls and floor); reduced emissivity due to dust assumed for radiant barriers on attic floor.
- Ground source heat pump enhancements:
- Allows optional detailed inputs related to geothermal loop (`HVACPlant/GeothermalLoop`).
- Allows optional ground diffusivity input.
- Updates to using G-Functions from the [G-Function Library for Modeling Vertical Bore Ground Heat Exchanger](https://gdr.openei.org/submissions/1325).
- Updated heating/cooling performance curves to reflect newer equipment.
- Allows shared batteries (batteries serving multiple dwelling units).
- BuildResidentialHPXML measure:
- **Breaking change**: Replaces `roof_radiant_barrier`/`roof_radiant_barrier_grade` arguments with `radiant_barrier_attic_location`/`radiant_barrier_grade`.
- Adds detailed performance data inputs for variable-speed air source HVAC systems.
Expand Down
10 changes: 5 additions & 5 deletions hpxml-measures/HPXMLtoOpenStudio/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>hpxm_lto_openstudio</name>
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
<version_id>a8d2e00b-4fc0-446b-b656-4fca25f994d1</version_id>
<version_modified>2024-01-19T20:40:34Z</version_modified>
<version_id>16f4e535-89a0-492f-91a3-a4806a0e040d</version_id>
<version_modified>2024-01-20T00:24:23Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -310,7 +310,7 @@
<filename>hpxml_defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>A1BF056D</checksum>
<checksum>6EC7DAE7</checksum>
</file>
<file>
<filename>hpxml_schema/HPXML.xsd</filename>
Expand All @@ -328,7 +328,7 @@
<filename>hpxml_schematron/EPvalidator.xml</filename>
<filetype>xml</filetype>
<usage_type>resource</usage_type>
<checksum>8DDC715A</checksum>
<checksum>87643672</checksum>
</file>
<file>
<filename>hpxml_schematron/iso-schematron.xsd</filename>
Expand All @@ -340,7 +340,7 @@
<filename>hvac.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>55CA34C5</checksum>
<checksum>F2BFF85E</checksum>
</file>
<file>
<filename>hvac_sizing.rb</filename>
Expand Down
9 changes: 4 additions & 5 deletions hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1300,15 +1300,14 @@ def self.apply_hvac(runner, hpxml, hpxml_bldg, weather, convert_shared_systems)
heat_pump.backup_heating_lockout_temp_isdefaulted = true
end

# Default boiler EAE
# Default in-unit boiler EAE
hpxml_bldg.heating_systems.each do |heating_system|
next unless heating_system.electric_auxiliary_energy.nil?
next unless heating_system.heating_system_type == HPXML::HVACTypeBoiler
next if heating_system.is_shared_system

heating_system.electric_auxiliary_energy_isdefaulted = true
heating_system.electric_auxiliary_energy = HVAC.get_default_boiler_eae(heating_system)
heating_system.shared_loop_watts = nil
heating_system.shared_loop_motor_efficiency = nil
heating_system.fan_coil_watts = nil
heating_system.electric_auxiliary_energy = HVAC.get_default_in_unit_boiler_eae(heating_system.heating_system_fuel)
end

# Default AC/HP sensible heat ratio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@
<sch:assert role='ERROR' test='count(h:AnnualHeatingEfficiency[h:Units="AFUE"]/h:Value) = 1'>Expected 1 element(s) for xpath: AnnualHeatingEfficiency[Units="AFUE"]/Value</sch:assert>
<sch:assert role='ERROR' test='number(h:AnnualHeatingEfficiency[h:Units="AFUE"]/h:Value) &lt;= 1 or not(h:AnnualHeatingEfficiency[h:Units="AFUE"]/h:Value)'>Expected AnnualHeatingEfficiency[Units="AFUE"]/Value to be less than or equal to 1</sch:assert>
<sch:assert role='ERROR' test='count(h:FractionHeatLoadServed) = 1 or count(../h:HeatPump/h:BackupSystem) &gt;= 1'>Expected 1 element(s) for xpath: FractionHeatLoadServed</sch:assert> <!-- See [HeatingSystem=HeatPumpBackup] -->
<sch:assert role='ERROR' test='count(h:ElectricAuxiliaryEnergy) + count(h:extension/h:SharedLoopWatts) &lt;= 1'>Expected 0 or 1 element(s) for xpath: ElectricAuxiliaryEnergy | extension/SharedLoopWatts</sch:assert>
<sch:assert role='ERROR' test='count(h:extension/h:SharedLoopWatts) = 1'>Expected 1 element(s) for xpath: extension/SharedLoopWatts</sch:assert>
<sch:assert role='ERROR' test='number(h:extension/h:SharedLoopWatts) &gt;= 0 or not(h:extension/h:SharedLoopWatts)'>Expected extension/SharedLoopWatts to be greater than or equal to 0</sch:assert>
<!-- Warnings -->
<sch:report role='WARN' test='number(h:AnnualHeatingEfficiency[h:Units="AFUE"]/h:Value) &lt; 0.5'>AFUE should typically be greater than or equal to 0.5.</sch:report>
Expand All @@ -912,7 +912,7 @@
<sch:pattern>
<sch:title>[HeatingSystemType=SharedBoilerWthFanCoil]</sch:title>
<sch:rule context='/h:HPXML/h:Building/h:BuildingDetails/h:Systems/h:HVAC/h:HVACPlant/h:HeatingSystem[h:HeatingSystemType/h:Boiler and h:IsSharedSystem="true" and ../../h:HVACDistribution/h:DistributionSystemType/h:AirDistribution/h:AirDistributionType[text()="fan coil"]]'>
<sch:assert role='ERROR' test='count(h:ElectricAuxiliaryEnergy) + count(h:extension/h:FanCoilWatts) &lt;= 1'>Expected 0 or 1 element(s) for xpath: ElectricAuxiliaryEnergy | extension/FanCoilWatts</sch:assert>
<sch:assert role='ERROR' test='count(h:extension/h:FanCoilWatts) = 1'>Expected 1 element(s) for xpath: extension/FanCoilWatts</sch:assert>
<sch:assert role='ERROR' test='number(h:extension/h:FanCoilWatts) &gt;= 0 or not(h:extension/h:FanCoilWatts)'>Expected extension/FanCoilWatts to be greater than or equal to 0</sch:assert>
</sch:rule>
</sch:pattern>
Expand Down
81 changes: 21 additions & 60 deletions hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2001,66 +2001,16 @@ def self.apply_dehumidifier_ief_to_ef_inputs(dh_type, w_coeff, ef_coeff, ief, wa
return ef_input, water_removal_rate_input
end

def self.get_default_boiler_eae(heating_system)
if heating_system.heating_system_type != HPXML::HVACTypeBoiler
return
end
if not heating_system.electric_auxiliary_energy.nil?
return heating_system.electric_auxiliary_energy
end

# From ANSI/RESNET/ICC 301-2019 Standard
fuel = heating_system.heating_system_fuel

if heating_system.is_shared_system
distribution_system = heating_system.distribution_system
distribution_type = distribution_system.distribution_system_type

if not heating_system.shared_loop_watts.nil?
sp_kw = UnitConversions.convert(heating_system.shared_loop_watts, 'W', 'kW')
n_dweq = heating_system.number_of_units_served.to_f
if distribution_system.air_type == HPXML::AirTypeFanCoil
aux_in = UnitConversions.convert(heating_system.fan_coil_watts, 'W', 'kW')
else
aux_in = 0.0 # ANSI/RESNET/ICC 301-2019 Section 4.4.7.2
end
# ANSI/RESNET/ICC 301-2019 Equation 4.4-5
return (((sp_kw / n_dweq) + aux_in) * 2080.0).round(2) # kWh/yr
elsif distribution_type == HPXML::HVACDistributionTypeHydronic
# kWh/yr, per ANSI/RESNET/ICC 301-2019 Table 4.5.2(5)
if distribution_system.hydronic_type == HPXML::HydronicTypeWaterLoop # Shared boiler w/ WLHP
return 265.0
else # Shared boiler w/ baseboard/radiators/etc
return 220.0
end
elsif distribution_type == HPXML::HVACDistributionTypeAir
if distribution_system.air_type == HPXML::AirTypeFanCoil # Shared boiler w/ fan coil
return 438.0
end
end

else # In-unit boilers

if [HPXML::FuelTypeNaturalGas,
HPXML::FuelTypePropane,
HPXML::FuelTypeElectricity,
HPXML::FuelTypeWoodCord,
HPXML::FuelTypeWoodPellets].include? fuel
return 170.0 # kWh/yr
elsif [HPXML::FuelTypeOil,
HPXML::FuelTypeOil1,
HPXML::FuelTypeOil2,
HPXML::FuelTypeOil4,
HPXML::FuelTypeOil5or6,
HPXML::FuelTypeDiesel,
HPXML::FuelTypeKerosene,
HPXML::FuelTypeCoal,
HPXML::FuelTypeCoalAnthracite,
HPXML::FuelTypeCoalBituminous,
HPXML::FuelTypeCoke].include? fuel
return 330.0 # kWh/yr
end

def self.get_default_in_unit_boiler_eae(boiler_fuel)
# Electric auxiliary energy, from ANSI/RESNET/ICC 301-2022 Addendum C Standard
if [HPXML::FuelTypeNaturalGas,
HPXML::FuelTypePropane,
HPXML::FuelTypeElectricity,
HPXML::FuelTypeWoodCord,
HPXML::FuelTypeWoodPellets].include? boiler_fuel
return 170.0 # kWh/yr
else
return 330.0 # kWh/yr
end
end

Expand Down Expand Up @@ -3451,6 +3401,17 @@ def self.apply_shared_heating_systems(hpxml_bldg)
distribution_system = heating_system.distribution_system
hydronic_type = distribution_system.hydronic_type

if heating_system.heating_system_type == HPXML::HVACTypeBoiler
sp_kw = UnitConversions.convert(heating_system.shared_loop_watts, 'W', 'kW')
n_dweq = heating_system.number_of_units_served.to_f
if distribution_system.air_type == HPXML::AirTypeFanCoil
aux_in = UnitConversions.convert(heating_system.fan_coil_watts, 'W', 'kW')
else
aux_in = 0.0
end
heating_system.electric_auxiliary_energy = (((sp_kw / n_dweq) + aux_in) * 2080.0).round(2) # kWh/yr
end

if heating_system.heating_system_type == HPXML::HVACTypeBoiler && hydronic_type.to_s == HPXML::HydronicTypeWaterLoop

# Shared boiler w/ water loop heat pump
Expand Down
14 changes: 3 additions & 11 deletions hpxml-measures/docs/source/workflow_inputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1674,8 +1674,8 @@ Each shared boiler (serving multiple dwelling units) is entered as a ``/HPXML/Bu
``HeatingSystemFuel`` string See [#]_ Yes Fuel type
``AnnualHeatingEfficiency[Units="AFUE"]/Value`` double frac > 0, <= 1 Yes Rated efficiency
``FractionHeatLoadServed`` double frac >= 0, <= 1 [#]_ See [#]_ Fraction of heating load served
``ElectricAuxiliaryEnergy`` or ``extension/SharedLoopWatts`` double kWh/yr or W >= 0 No See [#]_ Electric auxiliary energy or shared loop power
``ElectricAuxiliaryEnergy`` or ``extension/FanCoilWatts`` double kWh/yr or W >= 0 No [#]_ Electric auxiliary energy or fan coil power
``extension/SharedLoopWatts`` double W >= 0 Yes Shared loop power
``extension/FanCoilWatts`` double W >= 0 See [#]_ Fan coil power
============================================================ ======= =========== =============== ======== ============== =========================================

.. [#] 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".
Expand All @@ -1692,15 +1692,7 @@ Each shared boiler (serving multiple dwelling units) is entered as a ``/HPXML/Bu
.. [#] The sum of all ``FractionHeatLoadServed`` (across all HVAC systems) must be less than or equal to 1.
.. [#] FractionHeatLoadServed is required unless the heating system is a heat pump backup system (i.e., referenced by a ``HeatPump[BackupType="separate"]/BackupSystem``; see :ref:`hvac_heatpump`), in which case FractionHeatLoadServed is not allowed.
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.
.. [#] If ElectricAuxiliaryEnergy nor SharedLoopWatts provided, defaults as follows:
\- **Shared boiler w/ baseboard**: 220 kWh/yr
\- **Shared boiler w/ water loop heat pump**: 265 kWh/yr
\- **Shared boiler w/ fan coil**: 438 kWh/yr
.. [#] FanCoilWatts only used if boiler connected to fan coil and SharedLoopWatts provided.
.. [#] FanCoilWatts only required if boiler connected to fan coil.
.. _hvac_heating_stove:

Expand Down
32 changes: 14 additions & 18 deletions hpxml-measures/tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1326,25 +1326,21 @@ def apply_hpxml_modification(hpxml_file, hpxml)
hpxml_bldg.heat_pumps[0].number_of_units_served = 6
hpxml_bldg.heat_pumps[0].pump_watts_per_ton = 0.0
end
if hpxml_file.include? 'eae'
hpxml_bldg.heating_systems[0].electric_auxiliary_energy = 500.0
else
if hpxml_file.include? 'shared-boiler'
hpxml_bldg.heating_systems[0].shared_loop_watts = 600
end
if hpxml_file.include?('chiller') || hpxml_file.include?('cooling-tower')
hpxml_bldg.cooling_systems[0].shared_loop_watts = 600
end
if hpxml_file.include? 'shared-ground-loop'
hpxml_bldg.heat_pumps[0].shared_loop_watts = 600
if hpxml_file.include? 'shared-boiler'
hpxml_bldg.heating_systems[0].shared_loop_watts = 600
end
if hpxml_file.include?('chiller') || hpxml_file.include?('cooling-tower')
hpxml_bldg.cooling_systems[0].shared_loop_watts = 600
end
if hpxml_file.include? 'shared-ground-loop'
hpxml_bldg.heat_pumps[0].shared_loop_watts = 600
end
if hpxml_file.include? 'fan-coil'
if hpxml_file.include? 'boiler'
hpxml_bldg.heating_systems[0].fan_coil_watts = 150
end
if hpxml_file.include? 'fan-coil'
if hpxml_file.include? 'boiler'
hpxml_bldg.heating_systems[0].fan_coil_watts = 150
end
if hpxml_file.include? 'chiller'
hpxml_bldg.cooling_systems[0].fan_coil_watts = 150
end
if hpxml_file.include? 'chiller'
hpxml_bldg.cooling_systems[0].fan_coil_watts = 150
end
end
if hpxml_file.include? 'install-quality'
Expand Down
3 changes: 0 additions & 3 deletions hpxml-measures/workflow/hpxml_inputs.json
Original file line number Diff line number Diff line change
Expand Up @@ -891,9 +891,6 @@
"sample_files/base-bldgtype-mf-unit-shared-boiler-only-fan-coil-ducted.xml": {
"parent_hpxml": "sample_files/base-bldgtype-mf-unit-shared-boiler-only-fan-coil.xml"
},
"sample_files/base-bldgtype-mf-unit-shared-boiler-only-fan-coil-eae.xml": {
"parent_hpxml": "sample_files/base-bldgtype-mf-unit-shared-boiler-only-fan-coil.xml"
},
"sample_files/base-bldgtype-mf-unit-shared-boiler-only-water-loop-heat-pump.xml": {
"parent_hpxml": "sample_files/base-bldgtype-mf-unit-shared-boiler-only-baseboard.xml"
},
Expand Down
Loading

0 comments on commit 906da5d

Please sign in to comment.