Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thermal Bridging and Derating #183

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
26a6ab9
add modified copy of the thermal bridging measure
mdahlhausen May 6, 2024
51bcd43
add thermal bridging measure to options lookup
mdahlhausen May 6, 2024
31e912b
add thermal bridging to sampling
mdahlhausen May 6, 2024
915f944
move sampling location for thermal_bridging
mdahlhausen May 8, 2024
92dbe01
reorganize tsv arrays for thermal bridging
amylebar May 9, 2024
829e27b
add no thermal bridging option
mdahlhausen May 13, 2024
f88b94e
change name to align with sampling
mdahlhausen May 13, 2024
efd6f9e
remove disallowed characters in options_lookup
mdahlhausen May 13, 2024
bb6b493
update tbd version
mdahlhausen May 15, 2024
ffe47a9
add thermal bridging documentation
mdahlhausen Jun 3, 2024
a33ffdf
add tbd tests to resources_measure_tests
mdahlhausen Jun 3, 2024
c5c0ca8
add tbd to upgrade env measures
mdahlhausen Jun 10, 2024
6f1e5c0
Merge branch 'main' into mdahlhausen/thermal_bridging
Jul 3, 2024
73c7fa0
Merge branch 'main' into mdahlhausen/thermal_bridging
Jul 3, 2024
f87c680
Merge branch 'main' into mdahlhausen/thermal_bridging
mdahlhausen Aug 8, 2024
6c2f60b
update measure tests
mdahlhausen Aug 8, 2024
a1d24d2
Merge branch 'main' into mdahlhausen/thermal_bridging
mdahlhausen Aug 13, 2024
92b41be
Set default construction templates
mdahlhausen Aug 13, 2024
7cc41d2
Merge branch 'main' into mdahlhausen/thermal_bridging
mdahlhausen Sep 9, 2024
08a0fde
update measure .xmls
mdahlhausen Sep 9, 2024
c8dfdf6
Update bibliography.bib
mdahlhausen Sep 10, 2024
51d53a8
Merge branch 'main' into mdahlhausen/thermal_bridging
mdahlhausen Sep 12, 2024
9bc8a79
add thermal_bridging to sampling
mdahlhausen Sep 12, 2024
b20067a
Update sampling README.md
mdahlhausen Sep 18, 2024
8143f9a
reset tsv resampling
mdahlhausen Sep 18, 2024
9986d96
add thermal bridging to tsv resampling
mdahlhausen Sep 18, 2024
b5d015d
Update tsvs-v99.zip
mdahlhausen Sep 18, 2024
820db34
Merge branch 'develop' into mdahlhausen/thermal_bridging
mdahlhausen Sep 25, 2024
b833758
Merge branch 'main' into mdahlhausen/thermal_bridging
mdahlhausen Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions documentation/reference_doc/4_5_envelope.tex

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions documentation/reference_doc/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ @techreport{ashrae_901_2010
year = 2010
}

@techreport{ashrae_901_2022,
title = {Standard 90.1-2022 (I-P Edition) Energy Standard for Buildings Except Low-Rise Residential Buildings},
author = {ASHRAE},
institution = {ASHRAE},
year = 2022
}

@misc{egrid2020,
title = {Emissions and Generation Resource Integrated Database (eGRID), 2020},
author = {{U.S. Environmental Protection Agency (EPA)}},
Expand Down Expand Up @@ -583,6 +590,13 @@ @misc{trane_foundation
year = 2023,
}

@misc{tbd_gem,
title = {Thermal Bridging and Derating, Version 3.4.2},
author = {Denis Bourgeois and Dan Macumber},
url = {https://github.com/rd2/tbd},
year = 2024,
}

@misc{carrier_economiser,
title = {Carrier Economi$er},
author = {{Carrier}},
Expand Down
9 changes: 9 additions & 0 deletions national/housing_characteristics/options_lookup.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -4638,6 +4638,15 @@ baseline_window_type Single - No LowE - Tinted/Reflective - Aluminum replace_bas
baseline_window_type Single - No LowE - Tinted/Reflective - Wood replace_baseline_windows window_pane_type=Single - No LowE - Tinted/Reflective - Wood u_value_ip=0.91 shgc=0.525 vlt=0.436
baseline_window_type Triple - LowE - Clear - Thermally Broken Aluminum replace_baseline_windows window_pane_type=Triple - LowE - Clear - Thermally Broken Aluminum u_value_ip=0.3 shgc=0.328 vlt=0.527
baseline_window_type Triple - LowE - Tinted/Reflective - Thermally Broken Aluminum replace_baseline_windows window_pane_type=Triple - LowE - Tinted/Reflective - Thermally Broken Aluminum u_value_ip=0.299 shgc=0.224 vlt=0.32
thermal_bridging steel-framed and metal default thermal_bridging_derating option=90.1.22|steel.m|default
thermal_bridging steel-framed and metal unmitigated thermal_bridging_derating option=90.1.22|steel.m|unmitigated
thermal_bridging mass default thermal_bridging_derating option=90.1.22|mass.ex|default
thermal_bridging mass unmitigated thermal_bridging_derating option=90.1.22|mass.ex|unmitigated
thermal_bridging interior mass default thermal_bridging_derating option=90.1.22|mass.in|default
thermal_bridging interior mass unmitigated thermal_bridging_derating option=90.1.22|mass.in|unmitigated
thermal_bridging wood-framed default thermal_bridging_derating option=90.1.22|wood.fr|default
thermal_bridging wood-framed unmitigated thermal_bridging_derating option=90.1.22|wood.fr|unmitigated
thermal_bridging no thermal bridging thermal_bridging_derating option=(non thermal bridging)
baseline_hvac_sizing autosize hardsize_model apply_hardsize=false
baseline_hvac_sizing hardsize hardsize_model apply_hardsize=true
occupancy_schedule_adjust adjust_schedule adjust_occupancy_schedule peak_occ_frac=0.231
Expand Down
2 changes: 1 addition & 1 deletion resources/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ gem 'openstudio-workflow', '= 2.4.0'
gem 'openstudio-standards', '= 0.6.3'
#gem 'openstudio-standards', git: 'https://github.com/NREL/openstudio-standards.git', ref: 'e61d7d41a0e285cc99c7c6ea4aff1fcdc0be3599'
# gem 'openstudio-standards', path: "C:/GitRepos/openstudio-standards" # Use this format when testing openstudio-standards changes locally
gem 'tbd', '= 3.4.1'
gem 'tbd', '= 3.4.2'
gem 'openstudio-geb', '= 0.4.0',:github => 'LBNL-ETA/Openstudio-GEB-gem', :ref => 'a18e023936dd5c92be7dbf354f6331f60a965828'

group :test do
Expand Down
1 change: 1 addition & 0 deletions resources/measures/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Measures are added to the workflow in order they first appear in the [`options_l
| add_thermostat_setpoint_variability | Modifies the heating and cooling setpoints and setbacks/setups. |
| set_primary_kitchen_equipment | Replaces kitchen equiment with discrete equipment assumptions |
| replace_baseline_windows | Replaces windows in model (originally based on code) with windows of a specific technology type (single-pane, double-pane, etc.) |
| thermal_bridging_derating | Derates opaque constructions thermal resistance to account for thermal bridging |
| adjust_occupancy_schedule | Reduced the values of all occupancy schedules in the model by a specified percentage |
| hardsize_model | Do a sizing run, which populates the SQL file with the EnergyPlus-calculated capacities and flows |
| | Hard-size HVAC and SWH equipment in the model based on EnergyPlus-calculated capacities and flows. No model changes from here forward will be reflected in the sizing of HVAC equipment unless done intentionally as part of an upgrade. |
Expand Down
79 changes: 44 additions & 35 deletions resources/measures/set_roof_template/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,49 +198,58 @@ def run(model, runner, user_arguments)
reset_log
standard = Standard.build("#{template}")

# Apply standard constructions to this model at the surface-by-surface level,
# which will override default contruction sets for the surface types being updated,
# which is not all surface types.
types_to_modify = []
types_to_modify << ['Outdoors', 'RoofCeiling']

# Find just those surfaces
surfaces_to_modify = []
types_to_modify.each do |boundary_condition, surface_type|
# Surfaces
model.getSurfaces.sort.each do |surf|
next unless surf.outsideBoundaryCondition == boundary_condition
next unless surf.surfaceType == surface_type

surfaces_to_modify << surf
end

# SubSurfaces
model.getSubSurfaces.sort.each do |surf|
next unless surf.outsideBoundaryCondition == boundary_condition
next unless surf.subSurfaceType == surface_type

surfaces_to_modify << surf
end
# Check that a default construction set is defined
bldg_def_const_set = model.getBuilding.defaultConstructionSet
unless bldg_def_const_set.is_initialized
runner.registerError('Model does not have a default construction set.')
return false
end
bldg_def_const_set = bldg_def_const_set.get

# Modify these surfaces
prev_created_consts = {}
surfaces_to_modify.sort.each do |surf|
prev_created_consts = standard.planar_surface_apply_standard_construction(surf, climate_zone, prev_created_consts)
# Check that a default exterior construction set is defined
ext_surf_consts = bldg_def_const_set.defaultExteriorSurfaceConstructions
unless ext_surf_consts.is_initialized
runner.registerError("Default construction set '#{bldg_def_const_set.name}' has no default exterior surface constructions.")
return false
end
ext_surf_consts = ext_surf_consts.get

# List the unique array of constructions
prev_created_consts.each do |surf_type, construction|
runner.registerInfo("For #{surf_type.join(' ')}, applied #{construction.name}.")
# Check that a default exterior roof is defined
unless ext_surf_consts.roofCeilingConstruction.is_initialized
runner.registerError("Default surface construction set #{ext_surf_consts.name} has no default exterior roof construction.")
return false
end
old_construction = ext_surf_consts.roofCeilingConstruction.get
standards_info = old_construction.standardsInformation

log_messages_to_runner(runner, debug = false)
reset_log
# Get the old roof construction type
if standards_info.standardsConstructionType.empty?
old_roof_construction_type = 'Not defined'
else
old_roof_construction_type = standards_info.standardsConstructionType.get
end

if prev_created_consts.size.zero?
runner.registerAsNotApplicable("Found no #{surf_type.join(' ')} surfaces in the model to update")
# Get the building occupancy type
if model.getBuilding.standardsBuildingType.is_initialized
model_building_type = model.getBuilding.standardsBuildingType.get
else
model_building_type = ''
end
if ['SmallHotel', 'LargeHotel', 'MidriseApartment', 'HighriseApartment'].include?(model_building_type)
occ_type = 'Residential'
else
occ_type = 'Nonresidential'
end
climate_zone_set = standard.model_find_climate_zone_set(model, climate_zone)
new_construction = standard.model_find_and_add_construction(model,
climate_zone_set,
'ExteriorRoof',
old_roof_construction_type,
occ_type)
ext_surf_consts.setRoofCeilingConstruction(new_construction)

log_messages_to_runner(runner, debug = false)
reset_log

return true
end
Expand Down
8 changes: 4 additions & 4 deletions resources/measures/set_roof_template/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>set_roof_template</name>
<uid>0b13c46d-123f-4d6c-b5d8-65a23acf1141</uid>
<version_id>3f9d5a8d-5986-4beb-bfbe-b87310d67228</version_id>
<version_modified>2024-06-20T18:58:40Z</version_modified>
<version_id>50a0d7cb-0683-4f02-aaea-8d24b379101a</version_id>
<version_modified>2024-09-09T21:44:53Z</version_modified>
<xml_checksum>66CE07BA</xml_checksum>
<class_name>SetRoofTemplate</class_name>
<display_name>Set Roof Template</display_name>
Expand Down Expand Up @@ -530,7 +530,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>ADEF285E</checksum>
<checksum>F5D033A6</checksum>
</file>
<file>
<filename>Rt3-DEER Pre-1975-DXEH-CEC T24-CEC1.osm</filename>
Expand All @@ -542,7 +542,7 @@
<filename>measure_test.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>B6C88F42</checksum>
<checksum>E7647EF2</checksum>
</file>
</files>
</measure>
1 change: 0 additions & 1 deletion resources/measures/set_roof_template/tests/measure_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ def test_envelope_changes
# and the energy code being applied have the same envelope requirements.
expected_const_name = 'DEER Mass Roof R-17.48'
modified_surf = model.getSurfaceByName(modified_surf_name).get
assert(modified_surf.isConstructionDefaulted == false, "Expected construction for #{modified_surf_name} to be hard-assigned.")
modified_surf_const_name = modified_surf.construction.get.name.to_s
assert_equal(expected_const_name, modified_surf_const_name)

Expand Down
79 changes: 44 additions & 35 deletions resources/measures/set_wall_template/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,49 +198,58 @@ def run(model, runner, user_arguments)
reset_log
standard = Standard.build("#{template}")

# Apply standard constructions to this model at the surface-by-surface level,
# which will override default contruction sets for the surface types being updated,
# which is not all surface types.
types_to_modify = []
types_to_modify << ['Outdoors', 'Wall']

# Find just those surfaces
surfaces_to_modify = []
types_to_modify.each do |boundary_condition, surface_type|
# Surfaces
model.getSurfaces.sort.each do |surf|
next unless surf.outsideBoundaryCondition == boundary_condition
next unless surf.surfaceType == surface_type

surfaces_to_modify << surf
end

# SubSurfaces
model.getSubSurfaces.sort.each do |surf|
next unless surf.outsideBoundaryCondition == boundary_condition
next unless surf.subSurfaceType == surface_type

surfaces_to_modify << surf
end
# Check that a default construction set is defined
bldg_def_const_set = model.getBuilding.defaultConstructionSet
unless bldg_def_const_set.is_initialized
runner.registerError('Model does not have a default construction set.')
return false
end
bldg_def_const_set = bldg_def_const_set.get

# Modify these surfaces
prev_created_consts = {}
surfaces_to_modify.sort.each do |surf|
prev_created_consts = standard.planar_surface_apply_standard_construction(surf, climate_zone, prev_created_consts)
# Check that a default exterior construction set is defined
ext_surf_consts = bldg_def_const_set.defaultExteriorSurfaceConstructions
unless ext_surf_consts.is_initialized
runner.registerError("Default construction set '#{bldg_def_const_set.name}' has no default exterior surface constructions.")
return false
end
ext_surf_consts = ext_surf_consts.get

# List the unique array of constructions
prev_created_consts.each do |surf_type, construction|
runner.registerInfo("For #{surf_type.join(' ')}, applied #{construction.name}.")
# Check that a default exterior wall is defined
unless ext_surf_consts.wallConstruction.is_initialized
runner.registerError("Default surface construction set #{ext_surf_consts.name} has no default exterior wall construction.")
return false
end
old_construction = ext_surf_consts.wallConstruction.get
standards_info = old_construction.standardsInformation

log_messages_to_runner(runner, debug = false)
reset_log
# Get the old wall construction type
if standards_info.standardsConstructionType.empty?
old_wall_construction_type = 'Not defined'
else
old_wall_construction_type = standards_info.standardsConstructionType.get
end

if prev_created_consts.size.zero?
runner.registerAsNotApplicable("Found no #{surf_type.join(' ')} surfaces in the model to update")
# Get the building occupancy type
if model.getBuilding.standardsBuildingType.is_initialized
model_building_type = model.getBuilding.standardsBuildingType.get
else
model_building_type = ''
end
if ['SmallHotel', 'LargeHotel', 'MidriseApartment', 'HighriseApartment'].include?(model_building_type)
occ_type = 'Residential'
else
occ_type = 'Nonresidential'
end
climate_zone_set = standard.model_find_climate_zone_set(model, climate_zone)
new_construction = standard.model_find_and_add_construction(model,
climate_zone_set,
'ExteriorWall',
old_wall_construction_type,
occ_type)
ext_surf_consts.setWallConstruction(new_construction)

log_messages_to_runner(runner, debug = false)
reset_log

return true
end
Expand Down
8 changes: 4 additions & 4 deletions resources/measures/set_wall_template/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>set_wall_template</name>
<uid>3d02e4de-a6ad-4d83-8331-078f9fd5bb6f</uid>
<version_id>1cfe28de-1c49-4751-b51d-55c42a4594b0</version_id>
<version_modified>2024-06-20T18:58:41Z</version_modified>
<version_id>01564a56-0147-4bdc-a8d1-a4e43f2b46ef</version_id>
<version_modified>2024-09-09T21:45:03Z</version_modified>
<xml_checksum>66CE07BA</xml_checksum>
<class_name>SetWallTemplate</class_name>
<display_name>Set Wall Template</display_name>
Expand Down Expand Up @@ -530,7 +530,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>924C20FA</checksum>
<checksum>82CC940E</checksum>
</file>
<file>
<filename>Rt3-DEER Pre-1975-DXEH-CEC T24-CEC1.osm</filename>
Expand All @@ -542,7 +542,7 @@
<filename>measure_test.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>7A9D265F</checksum>
<checksum>5EEB08DD</checksum>
</file>
</files>
</measure>
1 change: 0 additions & 1 deletion resources/measures/set_wall_template/tests/measure_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ def test_envelope_changes
# and the energy code being applied have the same envelope requirements.
expected_const_name = 'DEER Insulated Exterior Mass Wall R-3.51 1'
modified_surf = model.getSurfaceByName(modified_surf_name).get
assert(modified_surf.isConstructionDefaulted == false, "Expected construction for #{modified_surf_name} to be hard-assigned.")
modified_surf_const_name = modified_surf.construction.get.name.to_s
assert_equal(expected_const_name, modified_surf_const_name)

Expand Down
21 changes: 21 additions & 0 deletions resources/measures/thermal_bridging_derating/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020-2024 Denis Bourgeois & Dan Macumber

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
32 changes: 32 additions & 0 deletions resources/measures/thermal_bridging_derating/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@


###### (Automatically generated documentation)

# Thermal Bridging Derating

## Description
Derates opaque construction thermal resistance for major thermal bridges.

## Modeler Description
This measure is adapted from the Thermal Bridging and Derating measure. Details, including default psi value sets, are avialble at rd2.github.io/tbd

## Measure Type
ModelMeasure

## Taxonomy


## Arguments


### Default thermal bridge set
e.g. '90.1.22|steel.m|unmitigated'
**Name:** option,
**Type:** Choice,
**Units:** ,
**Required:** false,
**Model Dependent:** false




Loading