Skip to content

Commit

Permalink
Merge branch 'develop' into yml-resilience-args
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-robertson committed Aug 21, 2023
2 parents 6f95609 + e346c36 commit d4045c0
Show file tree
Hide file tree
Showing 31 changed files with 732 additions and 179 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ jobs:
- name: Process results
run: |
pip install plotly
python test/process_bsb_analysis.py
- name: Run tests
Expand All @@ -175,8 +177,8 @@ jobs:
path: |
project_national/national_baseline/results_csvs/results_up00.csv
project_testing/testing_baseline/results_csvs/results_up00.csv
project_national/national_upgrades/results_csvs/results_up15.csv
project_testing/testing_upgrades/results_csvs/results_up15.csv
project_national/national_upgrades/results_csvs/results_up16.csv
project_testing/testing_upgrades/results_csvs/results_up16.csv
name: buildstockbatch_results_csvs

compare-tools:
Expand Down Expand Up @@ -262,9 +264,9 @@ jobs:
python test/compare.py -a results -af sum -ac build_existing_model.geometry_building_type_recs -x results_output_building_type_sum.csv -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
python test/compare.py -a visualize -dc build_existing_model.geometry_building_type_recs -x results_output_building_type.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
python test/compare.py -a visualize -dc build_existing_model.geometry_foundation_type -x results_output_foundation_type.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
python test/compare.py -a visualize -dc build_existing_model.census_region -x results_output_cr.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
python test/compare.py -a visualize -dc build_existing_model.geometry_building_type_recs -ac build_existing_model.census_region -af sum -x results_output_cr_sum.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
# python test/compare.py -a visualize -dc build_existing_model.geometry_foundation_type -x results_output_foundation_type.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
# python test/compare.py -a visualize -dc build_existing_model.census_region -x results_output_cr.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
# python test/compare.py -a visualize -dc build_existing_model.geometry_building_type_recs -ac build_existing_model.census_region -af sum -x results_output_cr_sum.html -b base_results/baseline/annual -f results/baseline/annual -e test/base_results/comparisons/baseline/annual
mkdir test/base_results/comparisons/baseline/timeseries
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Features
- Add 2022 Cambium emissions data ([#1038](https://github.com/NREL/resstock/pull/1038))
- Update characteristics to use EIA 2020 RECS ([#1031](https://github.com/NREL/resstock/pull/1031))
- Include HVAC secondary heating capabilities for project_testing ([#1090](https://github.com/NREL/resstock/pull/1090))
- For heat pump upgrades, adds the ability to set the existing primary (non-shared) heating system as the backup system using only a single option from the lookup ([#1074](https://github.com/NREL/resstock/pull/1074))

Fixes
- Set standard format for options_lookup ([#962](https://github.com/NREL/resstock/pull/962))
Expand Down
109 changes: 109 additions & 0 deletions docs/read_the_docs/source/advanced_tutorial/heat_pump_upgrades.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
Heat Pump Upgrades
==================

The following information is relevant for when a heat pump -related upgrade is defined in a project definition file.

Types of Backup
---------------

The ResStock workflow allows modeling heat pumps with either "integrated" or "separate" backup heating.
Definitions for each are given below.
See `HPXML Heat Pumps <https://openstudio-hpxml.readthedocs.io/en/latest/workflow_inputs.html#hpxml-heat-pumps>`_ for more information.

- *integrated*: 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).
- *separate*: the backup system has its own distribution system (e.g., electric baseboard or a boiler).

Lockout Temperatures
--------------------

The ResStock workflow allows for controlling the compressor and/or backup heating lockout temperatures.
Definitions for each are given below.
See the `Backup <https://openstudio-hpxml.readthedocs.io/en/latest/workflow_inputs.html#backup>`_ section of the OpenStudio-HPXML documentation for more information.

- *compressor*: minimum outdoor temperature for compressor operation.
- *backup heating*: maximum outdoor temperature for backup operation.

For example, a heat pump upgrade option could be defined with a compressor lockout temperature of 5F and a backup heating lockout temperature of 40F.
See below the argument assignments that would need to be added to the ``options_lookup.tsv`` file.
These values would override the OpenStudio-HPXML defaults.

.. code::
heat_pump_compressor_lockout_temp=5
heat_pump_backup_heating_lockout_temp=40
Replacement Scenarios
---------------------

When defining a heat pump upgrade, the new heat pump can either (a) replace the primary (existing) system, or (b) retain the primary (existing) system as its backup heating system.
In the latter case, all properties (e.g., capacity) of the primary (existing) system are retained as properties of the heat pump backup heating system.

Replace Primary System with New Heat Pump
*****************************************

For example:

.. code-block:: yaml
- upgrade_name: ASHP
options:
- option: HVAC Heating Efficiency|ASHP, SEER 22, 10 HSPF
apply_logic:
- HVAC Has Ducts|Yes
costs:
- value: 50.0
multiplier: Size, Heating System Primary (kBtu/h)
lifetime: 30
- option: HVAC Cooling Efficiency|Ducted Heat Pump
Primary System becomes Backup to New Heat Pump
**********************************************

Use the ``Heat Pump Backup|Use Existing System`` option from the lookup.
The following properties are retained:

- fuel type
- efficiency
- capacity

For example:

.. code-block:: yaml
- upgrade_name: ASHP
options:
- option: HVAC Heating Efficiency|ASHP, SEER 22, 10 HSPF
apply_logic:
- HVAC Has Ducts|Yes
costs:
- value: 50.0
multiplier: Size, Heating System Primary (kBtu/h)
lifetime: 30
- option: HVAC Cooling Efficiency|Ducted Heat Pump
- option: Heat Pump Backup|Use Existing System
For this scenario, the type of the backup is (automatically) determined based on information in the table below:

============= ============= =========== =============================
New Heat Pump Backup System Backup Type Example
============= ============= =========== =============================
ducted ducted integrated ASHP w/Furnace [#]_
ducted ductless separate ASHP w/Boiler
ductless ducted separate Ductless MSHP w/Furnace
ductless ductless separate Ductless MSHP w/Boiler
============= ============= =========== =============================

.. [#] When furnace is fuel-fired (i.e., non-electric).
When furnace is electric, it likely wouldn't be used as integrated backup.
Other situations and considerations:

- The primary (existing) system does not become backup to the heat pump when:

- the primary system is a heat pump
- the primary system is a shared system

- When a secondary (existing) system exists:

- it remains secondary if the heat pump upgrade is integrated backup
- it is removed if the heat pump upgrade is separate backup
3 changes: 2 additions & 1 deletion docs/read_the_docs/source/advanced_tutorial/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ If your changes are intended to be merged into the ``develop`` branch of the `Re
tasks
options_lookup
increasing_upgrade_options
upgrade_scenario_config
upgrade_scenario_config
heat_pump_upgrades
2 changes: 1 addition & 1 deletion docs/read_the_docs/source/advanced_tutorial/tasks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Run ``openstudio tasks.rb download_weather`` to download available EPW weather f

.. code:: bash
$ /c/openstudio-3.4.0/bin/openstudio.exe tasks.rb download_weather
$ openstudio tasks.rb download_weather
Downloading /files/156/BuildStock_TMY3_FIPS.zip ( 1%)
Downloading /files/156/BuildStock_TMY3_FIPS.zip ( 2%)
Downloading /files/156/BuildStock_TMY3_FIPS.zip ( 3%)
Expand Down
12 changes: 8 additions & 4 deletions docs/read_the_docs/source/basic_tutorial/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ See :doc:`run_project` for more information about running ResStock analyses.
Sampling
--------

To run the sampling script yourself, from the command line execute, e.g. ``openstudio resources/run_sampling.rb -p project_national -n 10000 -o buildstock.csv``, and a file ``buildstock.csv`` will be created in the ``resources`` directory.

If a custom ``buildstock.csv`` file is located in a project's ``housing_characteristics`` directory when you run the project, it will automatically be used to generate simulations. If it’s not found, the sampling will be run automatically to create one. For each datapoint, the measure will then look up its building description from the sampled csv.
To run the sampling script yourself, from the command line execute, e.g. ``openstudio resources/run_sampling.rb -p project_national -n 10000 -o buildstock.csv``, and a ``buildstock.csv`` file will be created in the ``resources`` directory.

If a custom ``buildstock.csv`` file is referenced using the `precomputed sampler <https://buildstockbatch.readthedocs.io/en/stable/samplers/precomputed.html>`_ when you run the project, it will be used as the basis for generating simulation datapoints.
Alternatively by using other (non-precomputed) quota-based samplers, the sampling will be run automatically to create a ``buildstock.csv`` file.
For each simulation datapoint, the workflow will then look up its building description from the sampled ``buildstock.csv`` file.

You can use this manual sampling process to downselect which simulations you want to run. For example, you can use the command above to generate a ``buildstock.csv`` for the entire U.S. and then open up this file in Excel and delete all of the rows that you don't want to simulate (e.g., all rows that aren't in New York). Keep in mind that if you do this, you will need to re-enumerate the "Building" column as "1" through the number of rows.
You can use this manual sampling process to downselect which simulations you want to run.
For example, you can use the command above to generate a ``buildstock.csv`` for the entire U.S. and then open up this file in Excel and delete all of the rows that you don't want to simulate (e.g., all rows that aren't in New York).
Keep in mind that if you do this, you will need to re-enumerate the "Building" column as "1" through the number of rows.

Measures
--------
Expand Down
129 changes: 105 additions & 24 deletions measures/ApplyUpgrade/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ def run(model, runner, user_arguments)
new_runner.result.stepValues.each do |step_value|
value = get_value_from_workflow_step_value(step_value)
next if value == ''
next if step_value.name == 'heat_pump_backup_use_existing_system'

measures['BuildResidentialHPXML'][0][step_value.name] = value
end
Expand All @@ -339,31 +340,66 @@ def run(model, runner, user_arguments)
measures['BuildResidentialHPXML'][0]['additional_properties'] = additional_properties.join('|') unless additional_properties.empty?

# Retain HVAC capacities

capacities = get_system_capacities(hpxml, system_upgrades)
measures['BuildResidentialHPXML'][0]['heating_system_heating_capacity'] = capacities['heating_system_heating_capacity']
measures['BuildResidentialHPXML'][0]['heating_system_2_heating_capacity'] = capacities['heating_system_2_heating_capacity']
measures['BuildResidentialHPXML'][0]['cooling_system_cooling_capacity'] = capacities['cooling_system_cooling_capacity']
measures['BuildResidentialHPXML'][0]['heat_pump_heating_capacity'] = capacities['heat_pump_heating_capacity']
measures['BuildResidentialHPXML'][0]['heat_pump_cooling_capacity'] = capacities['heat_pump_cooling_capacity']
measures['BuildResidentialHPXML'][0]['heat_pump_backup_heating_capacity'] = capacities['heat_pump_backup_heating_capacity']

# Retain Existing Heating System as Heat Pump Backup
heat_pump_backup_use_existing_system = measures['ResStockArguments'][0]['heat_pump_backup_use_existing_system']
if heat_pump_backup_use_existing_system == 'true'
heating_system = get_heating_system(hpxml)
heat_pump_type = measures['BuildResidentialHPXML'][0]['heat_pump_type']
heat_pump_is_ducted = measures['BuildResidentialHPXML'][0]['heat_pump_is_ducted']

# Only set the backup if the heat pump is applied and there is an existing heating system
if (heat_pump_type != 'none') && (not heating_system.nil?)
heat_pump_backup_type = get_heat_pump_backup_type(heating_system, heat_pump_type, heat_pump_is_ducted)
heat_pump_backup_values = get_heat_pump_backup_values(heating_system)

heating_system_type = heat_pump_backup_values['heating_system_type']
heat_pump_backup_fuel = heat_pump_backup_values['heat_pump_backup_fuel']
heat_pump_backup_heating_efficiency = heat_pump_backup_values['heat_pump_backup_heating_efficiency']
heat_pump_backup_heating_capacity = heat_pump_backup_values['heat_pump_backup_heating_capacity']

# Integrated; heat pump's distribution system and blower fan power applies to the backup heating
# e.g., ducted heat pump (e.g., ashp, gshp, ducted minisplit) with ducted (e.g., furnace) backup
if heat_pump_backup_type == HPXML::HeatPumpBackupTypeIntegrated

# Likely only fuel-fired furnace as integrated backup
if heat_pump_backup_fuel != HPXML::FuelTypeElectricity
measures['BuildResidentialHPXML'][0]['heat_pump_backup_type'] = heat_pump_backup_type
measures['BuildResidentialHPXML'][0]['heat_pump_backup_fuel'] = heat_pump_backup_fuel
measures['BuildResidentialHPXML'][0]['heat_pump_backup_heating_efficiency'] = heat_pump_backup_heating_efficiency
measures['BuildResidentialHPXML'][0]['heat_pump_backup_heating_capacity'] = heat_pump_backup_heating_capacity

runner.registerInfo("Found '#{heating_system_type}' heating system type; setting it as 'heat_pump_backup_type=#{measures['BuildResidentialHPXML'][0]['heat_pump_backup_type']}'.")
else # Likely would not have electric furnace as integrated backup
runner.registerInfo("Found '#{heating_system_type}' heating system type with '#{heat_pump_backup_fuel}' fuel type; not setting it as integrated backup.")
end

unless capacities['heating_system_heating_capacity'].nil?
measures['BuildResidentialHPXML'][0]['heating_system_heating_capacity'] = capacities['heating_system_heating_capacity']
end

unless capacities['heating_system_2_heating_capacity'].nil?
measures['BuildResidentialHPXML'][0]['heating_system_2_heating_capacity'] = capacities['heating_system_2_heating_capacity']
end

unless capacities['cooling_system_cooling_capacity'].nil?
measures['BuildResidentialHPXML'][0]['cooling_system_cooling_capacity'] = capacities['cooling_system_cooling_capacity']
end

unless capacities['heat_pump_heating_capacity'].nil?
measures['BuildResidentialHPXML'][0]['heat_pump_heating_capacity'] = capacities['heat_pump_heating_capacity']
end

unless capacities['heat_pump_cooling_capacity'].nil?
measures['BuildResidentialHPXML'][0]['heat_pump_cooling_capacity'] = capacities['heat_pump_cooling_capacity']
end

unless capacities['heat_pump_backup_heating_capacity'].nil?
measures['BuildResidentialHPXML'][0]['heat_pump_backup_heating_capacity'] = capacities['heat_pump_backup_heating_capacity']
# Separate; backup system has its own distribution system
# e.g., ductless heat pump (e.g., ductless minisplit) with ducted (e.g., furnace) or ductless (e.g., boiler) backup
# e.g., ducted heat pump (e.g., ashp, gshp) with ductless (e.g., boiler) backup
elsif heat_pump_backup_type == HPXML::HeatPumpBackupTypeSeparate
# It's possible this was < 1.0 due to adjustment for secondary heating system
measures['BuildResidentialHPXML'][0]['heat_pump_fraction_heat_load_served'] = 1.0

measures['BuildResidentialHPXML'][0]['heat_pump_backup_type'] = heat_pump_backup_type
measures['BuildResidentialHPXML'][0]['heating_system_2_type'] = heating_system_type
measures['BuildResidentialHPXML'][0]['heating_system_2_fuel'] = heat_pump_backup_fuel
measures['BuildResidentialHPXML'][0]['heating_system_2_heating_efficiency'] = heat_pump_backup_heating_efficiency
measures['BuildResidentialHPXML'][0]['heating_system_2_heating_capacity'] = heat_pump_backup_heating_capacity

runner.registerInfo("Found '#{heating_system_type}' heating system type; setting it as 'heat_pump_backup_type=#{measures['BuildResidentialHPXML'][0]['heat_pump_backup_type']}'.")
else
runner.registerError("Unknown heat pump backup type '#{heat_pump_backup_type}'.")
return false
end
end
end

# Get software program used and version
Expand Down Expand Up @@ -458,6 +494,44 @@ def halt_workflow(runner, measures)
return false
end

def get_heating_system(hpxml)
hpxml.heating_systems.each do |heating_system|
next unless heating_system.primary_system
next if heating_system.is_shared_system

return heating_system
end
return
end

def get_heat_pump_backup_type(heating_system, heat_pump_type, heat_pump_is_ducted)
ducted_backup = [HPXML::HVACTypeFurnace].include?(heating_system.heating_system_type)
if (ducted_backup && (heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit) && (heat_pump_is_ducted == 'true')) ||
(ducted_backup && [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpGroundToAir].include?(heat_pump_type))
return HPXML::HeatPumpBackupTypeIntegrated
end

return HPXML::HeatPumpBackupTypeSeparate
end

def get_heat_pump_backup_values(heating_system)
heating_system_type = heating_system.heating_system_type
heat_pump_backup_fuel = heating_system.heating_system_fuel
if not heating_system.heating_efficiency_afue.nil?
heat_pump_backup_heating_efficiency = heating_system.heating_efficiency_afue
elsif not heating_system.heating_efficiency_percent.nil?
heat_pump_backup_heating_efficiency = heating_system.heating_efficiency_percent
end
heat_pump_backup_heating_capacity = heating_system.heating_capacity
values = {
'heating_system_type' => heating_system_type,
'heat_pump_backup_fuel' => heat_pump_backup_fuel,
'heat_pump_backup_heating_efficiency' => heat_pump_backup_heating_efficiency,
'heat_pump_backup_heating_capacity' => heat_pump_backup_heating_capacity
}
return values
end

def get_system_upgrades(hpxml, system_upgrades, args_hash)
args_hash.keys.each do |arg|
# Detect whether we are upgrading the heating system
Expand Down Expand Up @@ -497,7 +571,14 @@ def get_system_upgrades(hpxml, system_upgrades, args_hash)
end

def get_system_capacities(hpxml, system_upgrades)
capacities = {}
capacities = {
'heating_system_heating_capacity' => nil,
'heating_system_2_heating_capacity' => nil,
'cooling_system_cooling_capacity' => nil,
'heat_pump_heating_capacity' => nil,
'heat_pump_cooling_capacity' => nil,
'heat_pump_backup_heating_capacity' => nil
}

hpxml.heating_systems.each do |heating_system|
next unless heating_system.primary_system
Expand Down
Loading

0 comments on commit d4045c0

Please sign in to comment.