Skip to content

Whole building MF Common Spaces #1850

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

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
57e268c
same as adjacency first cut
yzhou601 Oct 4, 2024
8edc860
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Oct 4, 2024
37aac01
update measures
yzhou601 Oct 4, 2024
db9794d
simplify implementation with additional properties
yzhou601 Oct 4, 2024
4ea65c6
oops
yzhou601 Oct 4, 2024
e0979da
skipped creating duplicate surfaces, addressed default and hvac sizing
yzhou601 Oct 11, 2024
5ee2c83
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Oct 11, 2024
c96242e
bugfix, name change
yzhou601 Oct 12, 2024
edd9aee
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Oct 21, 2024
ad4c8a0
change to only use sameas in one element instead of both elements
yzhou601 Oct 22, 2024
c31f15d
bugfix and some cleanups
yzhou601 Oct 22, 2024
bb5e641
simplify EPvalidator.xml
yzhou601 Oct 22, 2024
c1f0dd3
update measures
yzhou601 Oct 22, 2024
11f013f
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Oct 22, 2024
a1126ef
simplified the approach further more: store adjacent surface id in sp…
yzhou601 Oct 23, 2024
6c065d6
Add test file to include unconditioned common spaces and shared surfaces
yzhou601 Oct 24, 2024
6cad724
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Oct 24, 2024
4f0e0dd
Oops, forgot to add the generated test file
yzhou601 Oct 24, 2024
774b737
more fix
yzhou601 Oct 24, 2024
a8a6c50
test validations
yzhou601 Oct 24, 2024
388025e
fixed util.rb, relax the unused schedule check for common spaces(may …
yzhou601 Oct 24, 2024
60feccc
Latest results.
Oct 24, 2024
45a9415
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Nov 15, 2024
0e2fe3d
fix foundation wall attachment, reconfigure test files to include attics
yzhou601 Nov 19, 2024
cf686cc
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 Nov 19, 2024
c250a6a
Merge branch 'whole_building_common_spaces' of https://github.com/NRE…
yzhou601 Nov 19, 2024
5d6080a
fix ci
yzhou601 Nov 19, 2024
0872523
change the approach to create surfaces at unit models to avoid compon…
yzhou601 Nov 21, 2024
136c569
Latest results.
Nov 21, 2024
faf101c
fix typos
yzhou601 Nov 21, 2024
97682d9
Merge branch 'whole_building_common_spaces' of https://github.com/NRE…
yzhou601 Nov 21, 2024
19ecece
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
shorowit Nov 27, 2024
944bd45
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
shorowit Dec 16, 2024
3f6a380
Merge branch 'whole-mf-bldg-zero-occupants' of https://github.com/NRE…
shorowit Dec 17, 2024
c995c2e
Latest results.
Dec 17, 2024
57e65fe
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
shorowit Dec 27, 2024
9373f61
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
shorowit Jan 17, 2025
98d4b67
add reverse surface description test file
yzhou601 Jan 23, 2025
fc65762
Latest results.
Jan 23, 2025
6a0e79c
add EPvalidator check for wholebuildingsimulation
yzhou601 Jan 23, 2025
8b631ae
Merge branch 'whole_building_common_spaces' of https://github.com/NRE…
yzhou601 Jan 23, 2025
2517ffb
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
shorowit Feb 18, 2025
c466bf0
Update new code merged in.
shorowit Feb 18, 2025
2dc8a4b
Latest results.
Feb 18, 2025
0b4c0fe
Merge branch 'fix_default_solar_screens_films' of https://github.com/…
shorowit Mar 13, 2025
ebf8f18
Latest results.
Mar 13, 2025
71e0e0d
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
shorowit Mar 18, 2025
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
18 changes: 9 additions & 9 deletions 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>f28eadf0-9073-42d8-b644-d6e6562270c0</version_id>
<version_modified>2025-03-18T19:22:35Z</version_modified>
<version_id>326163fe-6402-4072-a925-2ff55bc798d1</version_id>
<version_modified>2025-03-18T21:39:29Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -333,7 +333,7 @@
<filename>defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>CFE01CCD</checksum>
<checksum>2E4CD1B7</checksum>
</file>
<file>
<filename>energyplus.rb</filename>
Expand All @@ -351,7 +351,7 @@
<filename>geometry.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>B6CCA5A7</checksum>
<checksum>0566822E</checksum>
</file>
<file>
<filename>hotwater_appliances.rb</filename>
Expand All @@ -363,7 +363,7 @@
<filename>hpxml.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>38DA3B96</checksum>
<checksum>DEC801AD</checksum>
</file>
<file>
<filename>hpxml_schema/HPXML.xsd</filename>
Expand All @@ -381,7 +381,7 @@
<filename>hpxml_schematron/EPvalidator.xml</filename>
<filetype>xml</filetype>
<usage_type>resource</usage_type>
<checksum>1132E1D6</checksum>
<checksum>8F8D8923</checksum>
</file>
<file>
<filename>hpxml_schematron/iso-schematron.xsd</filename>
Expand All @@ -399,7 +399,7 @@
<filename>hvac_sizing.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>A079BB8E</checksum>
<checksum>B3CA4DE5</checksum>
</file>
<file>
<filename>internal_gains.rb</filename>
Expand Down Expand Up @@ -453,7 +453,7 @@
<filename>model.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>F0F4648E</checksum>
<checksum>F4C2E38F</checksum>
</file>
<file>
<filename>output.rb</filename>
Expand Down Expand Up @@ -783,7 +783,7 @@
<filename>test_validation.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>F55AEAC1</checksum>
<checksum>CCE7A1E7</checksum>
</file>
<file>
<filename>test_vehicle.rb</filename>
Expand Down
8 changes: 8 additions & 0 deletions HPXMLtoOpenStudio/resources/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,8 @@ def self.apply_roofs(hpxml_bldg)
# @return [nil]
def self.apply_rim_joists(hpxml_bldg)
hpxml_bldg.rim_joists.each do |rim_joist|
next if rim_joist.sameas_id

if rim_joist.azimuth.nil?
rim_joist.azimuth = get_azimuth_from_orientation(rim_joist.orientation)
rim_joist.azimuth_isdefaulted = true
Expand Down Expand Up @@ -1277,6 +1279,8 @@ def self.apply_rim_joists(hpxml_bldg)
# @return [nil]
def self.apply_walls(hpxml_bldg)
hpxml_bldg.walls.each do |wall|
next if wall.sameas_id

if wall.azimuth.nil?
wall.azimuth = get_azimuth_from_orientation(wall.orientation)
wall.azimuth_isdefaulted = true
Expand Down Expand Up @@ -1340,6 +1344,8 @@ def self.apply_walls(hpxml_bldg)
# @return [nil]
def self.apply_foundation_walls(hpxml_bldg)
hpxml_bldg.foundation_walls.each do |foundation_wall|
next if foundation_wall.sameas_id

if foundation_wall.type.nil?
foundation_wall.type = HPXML::FoundationWallTypeSolidConcrete
foundation_wall.type_isdefaulted = true
Expand Down Expand Up @@ -1400,6 +1406,8 @@ def self.apply_foundation_walls(hpxml_bldg)
# @return [nil]
def self.apply_floors(runner, hpxml_bldg)
hpxml_bldg.floors.each do |floor|
next if floor.sameas_id

if floor.floor_or_ceiling.nil?
if floor.is_ceiling
floor.floor_or_ceiling = HPXML::FloorOrCeilingCeiling
Expand Down
79 changes: 70 additions & 9 deletions HPXMLtoOpenStudio/resources/geometry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ def self.apply_walls(runner, model, spaces, hpxml_bldg, hpxml_header)
_walls_top, foundation_top = get_foundation_and_walls_top(hpxml_bldg)

hpxml_bldg.walls.each do |wall|
hpxml_id = wall.id
if wall.sameas_id
hpxml_sameas_id = wall.sameas_id
wall = wall.sameas
end
next if wall.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area

if wall.azimuth.nil?
Expand All @@ -149,6 +154,9 @@ def self.apply_walls(runner, model, spaces, hpxml_bldg, hpxml_header)
else
azimuths = [wall.azimuth]
end
if hpxml_sameas_id
azimuths = azimuths.map { |a| (a + 180) % 360 }
end

surfaces = []

Expand All @@ -171,14 +179,17 @@ def self.apply_walls(runner, model, spaces, hpxml_bldg, hpxml_header)
end
surface.setSurfaceType(EPlus::SurfaceTypeWall)
set_surface_interior(model, spaces, surface, wall, hpxml_bldg)
set_surface_exterior(model, spaces, surface, wall, hpxml_bldg)
set_surface_exterior(model, spaces, surface, wall, hpxml_bldg) if hpxml_sameas_id.nil?
if wall.is_interior
surface.setSunExposure(EPlus::SurfaceSunExposureNo)
surface.setWindExposure(EPlus::SurfaceWindExposureNo)
end
surface.additionalProperties.setFeature('hpxmlID', hpxml_id)
surface.additionalProperties.setFeature('hpxmlSameasID', hpxml_sameas_id) unless hpxml_sameas_id.nil?
end

next if surfaces.empty?
next unless hpxml_sameas_id.nil?

# Apply construction
# The code below constructs a reasonable wall construction based on the
Expand Down Expand Up @@ -220,6 +231,12 @@ def self.apply_rim_joists(runner, model, spaces, hpxml_bldg)
_walls_top, foundation_top = get_foundation_and_walls_top(hpxml_bldg)

hpxml_bldg.rim_joists.each do |rim_joist|
hpxml_id = rim_joist.id
if rim_joist.sameas_id
hpxml_sameas_id = rim_joist.sameas_id
rim_joist = rim_joist.sameas
end

if rim_joist.azimuth.nil?
if rim_joist.is_exterior
azimuths = default_azimuths # Model as four directions for average exterior incident solar
Expand All @@ -229,6 +246,9 @@ def self.apply_rim_joists(runner, model, spaces, hpxml_bldg)
else
azimuths = [rim_joist.azimuth]
end
if hpxml_sameas_id
azimuths = azimuths.map { |a| (a + 180) % 360 }
end

surfaces = []

Expand All @@ -251,13 +271,17 @@ def self.apply_rim_joists(runner, model, spaces, hpxml_bldg)
end
surface.setSurfaceType(EPlus::SurfaceTypeWall)
set_surface_interior(model, spaces, surface, rim_joist, hpxml_bldg)
set_surface_exterior(model, spaces, surface, rim_joist, hpxml_bldg)
set_surface_exterior(model, spaces, surface, rim_joist, hpxml_bldg) if hpxml_sameas_id.nil?
if rim_joist.is_interior
surface.setSunExposure(EPlus::SurfaceSunExposureNo)
surface.setWindExposure(EPlus::SurfaceWindExposureNo)
end
surface.additionalProperties.setFeature('hpxmlID', hpxml_id)
surface.additionalProperties.setFeature('hpxmlSameasID', hpxml_sameas_id) unless hpxml_sameas_id.nil?
end

next unless hpxml_sameas_id.nil?

# Apply construction

inside_film = Material.AirFilmVertical
Expand Down Expand Up @@ -303,6 +327,14 @@ def self.apply_floors(runner, model, spaces, hpxml_bldg, hpxml_header)
walls_top, foundation_top = get_foundation_and_walls_top(hpxml_bldg)

hpxml_bldg.floors.each do |floor|
hpxml_id = floor.id
if floor.sameas_id
is_ceiling = !floor.sameas.is_ceiling
hpxml_sameas_id = floor.sameas_id
floor = floor.sameas
else
is_ceiling = floor.is_ceiling
end
next if floor.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area

area = floor.net_area
Expand All @@ -314,7 +346,7 @@ def self.apply_floors(runner, model, spaces, hpxml_bldg, hpxml_header)
z_origin = foundation_top
end

if floor.is_ceiling
if is_ceiling
vertices = create_ceiling_vertices(length, width, z_origin, default_azimuths)
surface = OpenStudio::Model::Surface.new(vertices, model)
surface.additionalProperties.setFeature('SurfaceType', 'Ceiling')
Expand All @@ -325,7 +357,7 @@ def self.apply_floors(runner, model, spaces, hpxml_bldg, hpxml_header)
end
surface.additionalProperties.setFeature('Tilt', 0.0)
set_surface_interior(model, spaces, surface, floor, hpxml_bldg)
set_surface_exterior(model, spaces, surface, floor, hpxml_bldg)
set_surface_exterior(model, spaces, surface, floor, hpxml_bldg) if hpxml_sameas_id.nil?
surface.setName(floor.id)
if floor.is_interior
surface.setSunExposure(EPlus::SurfaceSunExposureNo)
Expand All @@ -339,6 +371,9 @@ def self.apply_floors(runner, model, spaces, hpxml_bldg, hpxml_header)
end
end
end
surface.additionalProperties.setFeature('hpxmlID', hpxml_id)
surface.additionalProperties.setFeature('hpxmlSameasID', hpxml_sameas_id) unless hpxml_sameas_id.nil?
next unless hpxml_sameas_id.nil?

# Apply construction

Expand Down Expand Up @@ -445,8 +480,14 @@ def self.apply_foundation_walls_slabs(runner, model, spaces, weather, hpxml_bldg
# The above-grade portion of these walls are modeled as EnergyPlus surfaces with standard adjacency.
# The below-grade portion of these walls (in contact with ground) are not modeled, as Kiva does not
# calculate heat flow between two zones through the ground.
int_fnd_walls = hpxml_bldg.foundation_walls.select { |fw| fw.is_interior && fw.interior_adjacent_to == foundation_type }
int_fnd_walls = hpxml_bldg.foundation_walls.select { |fw| (fw.is_interior && fw.interior_adjacent_to == foundation_type) || fw.sameas_id }
int_fnd_walls.each do |fnd_wall|
hpxml_id = fnd_wall.id
if fnd_wall.sameas_id
hpxml_sameas_id = fnd_wall.sameas_id
fnd_wall = fnd_wall.sameas
end

next unless fnd_wall.is_interior

ag_height = fnd_wall.height - fnd_wall.depth_below_grade
Expand All @@ -460,6 +501,9 @@ def self.apply_foundation_walls_slabs(runner, model, spaces, weather, hpxml_bldg
else
azimuth = fnd_wall.azimuth
end
if hpxml_sameas_id
azimuth = (azimuth + 180) % 360
end

vertices = create_wall_vertices(length, ag_height, z_origin, azimuth)
surface = OpenStudio::Model::Surface.new(vertices, model)
Expand All @@ -470,9 +514,13 @@ def self.apply_foundation_walls_slabs(runner, model, spaces, weather, hpxml_bldg
surface.setName(fnd_wall.id)
surface.setSurfaceType(EPlus::SurfaceTypeWall)
set_surface_interior(model, spaces, surface, fnd_wall, hpxml_bldg)
set_surface_exterior(model, spaces, surface, fnd_wall, hpxml_bldg)
set_surface_exterior(model, spaces, surface, fnd_wall, hpxml_bldg) if hpxml_sameas_id.nil?
surface.setSunExposure(EPlus::SurfaceSunExposureNo)
surface.setWindExposure(EPlus::SurfaceWindExposureNo)
surface.additionalProperties.setFeature('hpxmlID', hpxml_id)
surface.additionalProperties.setFeature('hpxmlSameasID', hpxml_sameas_id) unless hpxml_sameas_id.nil?

next unless hpxml_sameas_id.nil?

# Apply construction

Expand Down Expand Up @@ -1051,6 +1099,7 @@ def self.apply_thermal_mass(model, spaces, hpxml_bldg, hpxml_header)
def self.get_foundation_and_walls_top(hpxml_bldg)
foundation_top = [hpxml_bldg.building_construction.unit_height_above_grade, 0].max
hpxml_bldg.foundation_walls.each do |foundation_wall|
foundation_wall = foundation_wall.sameas if foundation_wall.sameas_id
top = -1 * foundation_wall.depth_below_grade + foundation_wall.height
foundation_top = top if top > foundation_top
end
Expand Down Expand Up @@ -1701,13 +1750,24 @@ def self.get_temperature_scheduled_space_values(location)
# @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects
# @param surface [OpenStudio::Model::Surface] an OpenStudio::Model::Surface object
# @param hpxml_surface [HPXML::Wall or HPXML::Roof or HPXML::RimJoist or HPXML::FoundationWall or HPXML::Slab] any HPXML surface
# @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit
# @return [nil]
def self.set_surface_interior(model, spaces, surface, hpxml_surface, hpxml_bldg)
interior_adjacent_to = hpxml_surface.interior_adjacent_to
surface.setSpace(get_interior_space(model, spaces, hpxml_surface.interior_adjacent_to, hpxml_bldg))
end

# Return the OpenStudio Space based on the adjacent interior location of an HPXML Surface.
#
# @param model [OpenStudio::Model::Model] OpenStudio Model object
# @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects
# @param interior_adjacent_to [String] HPXML interior location
# @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit
# @return [OpenStudio::Model::Space] the OpenStudio::Model::Space object based on the interior location
def self.get_interior_space(model, spaces, interior_adjacent_to, hpxml_bldg)
if HPXML::conditioned_below_grade_locations.include? interior_adjacent_to
surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationConditionedSpace, hpxml_bldg))
return create_or_get_space(model, spaces, HPXML::LocationConditionedSpace, hpxml_bldg)
else
surface.setSpace(create_or_get_space(model, spaces, interior_adjacent_to, hpxml_bldg))
return create_or_get_space(model, spaces, interior_adjacent_to, hpxml_bldg)
end
end

Expand All @@ -1717,6 +1777,7 @@ def self.set_surface_interior(model, spaces, surface, hpxml_surface, hpxml_bldg)
# @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects
# @param surface [OpenStudio::Model::Surface] an OpenStudio::Model::Surface object
# @param hpxml_surface [HPXML::Wall or HPXML::Roof or HPXML::RimJoist or HPXML::FoundationWall or HPXML::Slab] any HPXML surface
# @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit
# @return [nil]
def self.set_surface_exterior(model, spaces, surface, hpxml_surface, hpxml_bldg)
exterior_adjacent_to = hpxml_surface.exterior_adjacent_to
Expand Down
Loading