Skip to content

Commit

Permalink
fix(room2d): Add clearer methods for getting Aperture/Door areas
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswmackey committed Dec 30, 2024
1 parent e7c3ab2 commit 1a18469
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 11 deletions.
64 changes: 57 additions & 7 deletions dragonfly/room2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,13 @@ class Room2D(_BaseGeometry):
* volume
* floor_area
* exterior_wall_area
* interior_wall_area
* exterior_window_area
* skylight_area
* exterior_aperture_area
* wall_sub_face_area
* roof_sub_face_area
* sub_face_area
* is_core
* is_perimeter
* min
Expand Down Expand Up @@ -715,7 +721,7 @@ def floor_area(self):

@property
def exterior_wall_area(self):
"""Get a the total wall area of the Room with an Outdoors boundary condition.
"""Get the total area of the Room walls with an Outdoors boundary condition.
"""
wall_areas = []
for seg, bc in zip(self.floor_segments, self._boundary_conditions):
Expand All @@ -725,7 +731,7 @@ def exterior_wall_area(self):

@property
def interior_wall_area(self):
"""Get a the total wall area of the Room without an Outdoors or Ground BC.
"""Get the total area of the Room walls without an Outdoors or Ground BC.
"""
wall_areas = []
for seg, bc in zip(self.floor_segments, self._boundary_conditions):
Expand All @@ -735,30 +741,74 @@ def interior_wall_area(self):

@property
def exterior_window_area(self):
"""Get a the total aperture area of the Room with an Outdoors boundary condition.
"""Get the total area of the Room Apertures in walls with an Outdoors BC.
This only refers to Apertures and excludes Doors.
"""
glz_areas = []
for seg, bc, glz in zip(self.floor_segments, self._boundary_conditions,
self._window_parameters):
if isinstance(bc, Outdoors) and glz is not None:
area = glz.area_from_segment(seg, self.floor_to_ceiling_height)
if isinstance(glz, _AsymmetricBase):
area = glz.aperture_area_from_segment(
seg, self.floor_to_ceiling_height)
else:
area = glz.area_from_segment(seg, self.floor_to_ceiling_height)
glz_areas.append(area)
return sum(glz_areas)

@property
def skylight_area(self):
"""Get a the total aperture area of the Room with an Outdoors boundary condition.
"""Get the total aperture area of Room's skylights.
This only refers to Apertures and excludes overhead Doors.
"""
if self.is_top_exposed and self.skylight_parameters is not None:
return self.skylight_parameters.area_from_face(self.floor_geometry)
sky_par = self.skylight_parameters
return sky_par.area_from_face(self.floor_geometry) \
if not isinstance(sky_par, DetailedSkylights) else \
sky_par.aperture_area_from_face(self.floor_geometry)
return 0

@property
def exterior_aperture_area(self):
"""Get a the total aperture area of the Room with an Outdoors boundary condition.
"""Get the total Aperture area of the Room with an Outdoors boundary condition.
"""
return self.exterior_window_area + self.skylight_area

@property
def wall_sub_face_area(self):
"""Get a the total sub-face area of the Room's walls.
This includes both Apertures and Doors in both interior and exterior walls.
"""
glz_areas = []
for seg, glz in zip(self.floor_segments, self._window_parameters):
if glz is not None:
area = glz.area_from_segment(seg, self.floor_to_ceiling_height)
glz_areas.append(area)
return sum(glz_areas)

@property
def roof_sub_face_area(self):
"""Get a the total sub-face area of the Room's roofs.
This includes both Apertures and overhead Doors.
"""
if self.is_top_exposed and self.skylight_parameters is not None:
sky_par = self.skylight_parameters
return sky_par.area_from_face(self.floor_geometry)
return 0

@property
def sub_face_area(self):
"""Get a the total sub-face area of the Room.
This includes both Apertures and Doors in both walls and roofs for all
accepted boundary conditions.
"""
return self.wall_sub_face_area + self.roof_sub_face_area

@property
def is_core(self):
"""Get a boolean for whether the Room2D is in the core of a story.
Expand Down
13 changes: 12 additions & 1 deletion dragonfly/skylightparameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,24 @@ def are_doors(self):
return self._are_doors

def area_from_face(self, face):
"""Get the skylight area generated by these parameters from a Room2D Face3D.
"""Get the sub-face area generated by these parameters from a Room2D Face3D.
This includes both skylights and overhead doors.
Args:
face: A Roof Face3D to which these parameters are applied.
"""
return sum(polygon.area for polygon in self._polygons)

def aperture_area_from_face(self, face):
"""Get the Aperture area generated by these parameters from a Room2D Face3D.
Args:
face: A Roof Face3D to which these parameters are applied.
"""
return sum(poly.area for poly, isd in zip(self.polygons, self.are_doors)
if not isd)

def check_overlaps(self, tolerance=0.01):
"""Check whether any polygons overlap with one another.
Expand Down
40 changes: 37 additions & 3 deletions dragonfly/windowparameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,9 @@ def are_doors(self):
return self._are_doors

def area_from_segment(self, segment, floor_to_ceiling_height):
"""Get the window area generated by these parameters from a LineSegment3D.
"""Get the sub-face area generated by these parameters from a LineSegment3D.
Note that this includes both the areas of Apertures and Doors.
Args:
segment: A LineSegment3D to which these parameters are applied.
Expand All @@ -1526,14 +1528,33 @@ def area_from_segment(self, segment, floor_to_ceiling_height):
"""
max_width = segment.length
max_height = floor_to_ceiling_height

areas = []
for o, width, height in zip(self.origins, self.widths, self.heights):
final_width = max_width - o.x if width + o.x > max_width else width
final_height = max_height - o.y if height + o.y > max_height else height
if final_height > 0 and final_height > 0: # inside wall boundary
areas.append(final_width * final_height)
return sum(areas)

def aperture_area_from_segment(self, segment, floor_to_ceiling_height):
"""Get the Aperture area generated by these parameters from a LineSegment3D.
Note that this excludes the area of Doors.
Args:
segment: A LineSegment3D to which these parameters are applied.
floor_to_ceiling_height: The floor-to-ceiling height of the Room2D
to which the segment belongs.
"""
max_width = segment.length
max_height = floor_to_ceiling_height
areas = []
for o, w, h, isd in zip(self.origins, self.widths, self.heights, self.are_doors):
if not isd:
final_width = max_width - o.x if w + o.x > max_width else w
final_height = max_height - o.y if h + o.y > max_height else h
if final_height > 0 and final_height > 0: # inside wall boundary
areas.append(final_width * final_height)
return sum(areas)

def check_window_overlaps(self, tolerance=0.01):
Expand Down Expand Up @@ -2121,7 +2142,9 @@ def is_flipped_equivalent(self, other, segment, tolerance=0.01):
return False

def area_from_segment(self, segment, floor_to_ceiling_height):
"""Get the window area generated by these parameters from a LineSegment3D.
"""Get the sub-face area generated by these parameters from a LineSegment3D.
This includes both Apertures and Doors.
Args:
segment: A LineSegment3D to which these parameters are applied.
Expand All @@ -2130,6 +2153,17 @@ def area_from_segment(self, segment, floor_to_ceiling_height):
"""
return sum(polygon.area for polygon in self._polygons)

def aperture_area_from_segment(self, segment, floor_to_ceiling_height):
"""Get the Aperture area generated by these parameters from a LineSegment3D.
Args:
segment: A LineSegment3D to which these parameters are applied.
floor_to_ceiling_height: The floor-to-ceiling height of the Room2D
to which the segment belongs.
"""
return sum(poly.area for poly, isd in zip(self.polygons, self.are_doors)
if not isd)

def check_window_overlaps(self, tolerance=0.01):
"""Check whether any polygons overlap with one another.
Expand Down

0 comments on commit 1a18469

Please sign in to comment.