lib/openstudio-standards/standards/Standards.SubSurface.rb in openstudio-standards-0.5.0 vs lib/openstudio-standards/standards/Standards.SubSurface.rb in openstudio-standards-0.6.0.rc1
- old
+ new
@@ -1,206 +1,20 @@
class Standard
# @!group SubSurface
- # Determine the component infiltration rate for this surface
- #
- # @param sub_surface [OpenStudio::Model::SubSurface] sub surface object
- # @param type [String] choices are 'baseline' and 'advanced'
- # @return [Double] infiltration rate in m^3/s
- def sub_surface_component_infiltration_rate(sub_surface, type)
- comp_infil_rate_m3_per_s = 0.0
-
- # Define the envelope component infiltration rates
- component_infil_rates_cfm_per_ft2 = {
- 'baseline' => {
- 'opaque_door' => 0.40,
- 'loading_dock_door' => 0.40,
- 'swinging_or_revolving_glass_door' => 1.0,
- 'vestibule' => 1.0,
- 'sliding_glass_door' => 0.40,
- 'window' => 0.40,
- 'skylight' => 0.40
- },
- 'advanced' => {
- 'opaque_door' => 0.20,
- 'loading_dock_door' => 0.20,
- 'swinging_or_revolving_glass_door' => 1.0,
- 'vestibule' => 1.0,
- 'sliding_glass_door' => 0.20,
- 'window' => 0.20,
- 'skylight' => 0.20
- }
- }
-
- boundary_condition = sub_surface.outsideBoundaryCondition
- # Skip non-outdoor surfaces
- return comp_infil_rate_m3_per_s unless outsideBoundaryCondition == 'Outdoors' || sub_surface.outsideBoundaryCondition == 'Ground'
-
- # Per area infiltration rate for this surface
- surface_type = sub_surface.subSurfaceType
- infil_rate_cfm_per_ft2 = nil
- case boundary_condition
- when 'Outdoors'
- case surface_type
- when 'Door'
- infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['opaque_door']
- when 'OverheadDoor'
- infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['loading_dock_door']
- when 'GlassDoor'
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "For #{sub_surface.name}, assuming swinging_or_revolving_glass_door for infiltration calculation.")
- infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['swinging_or_revolving_glass_door']
- when 'FixedWindow', 'OperableWindow'
- infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['window']
- when 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser'
- infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['skylight']
- end
- end
- if infil_rate_cfm_per_ft2.nil?
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "For #{sub_surface.name}, could not determine surface type for infiltration, will not be included in calculation.")
- return comp_infil_rate_m3_per_s
- end
-
- # Area of the surface
- area_m2 = sub_surface.netArea
- area_ft2 = OpenStudio.convert(area_m2, 'm^2', 'ft^2').get
-
- # Rate for this surface
- comp_infil_rate_cfm = area_ft2 * infil_rate_cfm_per_ft2
-
- comp_infil_rate_m3_per_s = OpenStudio.convert(comp_infil_rate_cfm, 'cfm', 'm^3/s').get
-
- # OpenStudio::logFree(OpenStudio::Debug, "openstudio.Standards.Model", "......#{self.name}, infil = #{comp_infil_rate_cfm.round(2)} cfm @ rate = #{infil_rate_cfm_per_ft2} cfm/ft2, area = #{area_ft2.round} ft2.")
-
- return comp_infil_rate_m3_per_s
- end
-
- # Reduce the area of the subsurface by shrinking it toward the centroid.
- # @author Julien Marrec
- #
- # @param sub_surface [OpenStudio::Model::SubSurface] sub surface object
- # @param percent_reduction [Double] the fractional amount to reduce the area
- # @return [Boolean] returns true if successful, false if not
- def sub_surface_reduce_area_by_percent_by_shrinking_toward_centroid(sub_surface, percent_reduction)
- # if percent_reduction > 1=> percent increase instead of reduction
- mult = percent_reduction <= 1 ? 1 - percent_reduction : percent_reduction
- scale_factor = mult**0.5
-
- # Get the centroid (Point3d)
- g = sub_surface.centroid
-
- # Create an array to collect the new vertices
- new_vertices = []
-
- # Loop on vertices (Point3ds)
- sub_surface.vertices.each do |vertex|
- # Point3d - Point3d = Vector3d
- # Vector from centroid to vertex (GA, GB, GC, etc)
- centroid_vector = vertex - g
-
- # Resize the vector (done in place) according to scale_factor
- centroid_vector.setLength(centroid_vector.length * scale_factor)
-
- # Move the vertex toward the centroid
- vertex = g + centroid_vector
-
- new_vertices << vertex
- end
-
- # Assign the new vertices to the self
- sub_surface.setVertices(new_vertices)
- end
-
- # Reduce the area of the subsurface by raising the sill height.
- #
- # @param sub_surface [OpenStudio::Model::SubSurface] sub surface object
- # @param percent_reduction [Double] the fractional amount to reduce the area.
- # @return [Boolean] returns true if successful, false if not
- def sub_surface_reduce_area_by_percent_by_raising_sill(sub_surface, percent_reduction)
- mult = 1 - percent_reduction
-
- # Calculate the original area
- area_original = sub_surface.netArea
-
- # Find the min and max z values
- min_z_val = 99_999
- max_z_val = -99_999
- sub_surface.vertices.each do |vertex|
- # Min z value
- if vertex.z < min_z_val
- min_z_val = vertex.z
- end
- # Max z value
- if vertex.z > max_z_val
- max_z_val = vertex.z
- end
- end
-
- # Calculate the window height
- height = max_z_val - min_z_val
-
- # Calculate the new sill height
- new_sill_z = max_z_val - (height * mult)
-
- # Reset the z value of the lowest points
- new_vertices = []
- sub_surface.vertices.each do |vertex|
- new_x = vertex.x
- new_y = vertex.y
- new_z = vertex.z
- if new_z == min_z_val
- new_z = new_sill_z
- end
- new_vertices << OpenStudio::Point3d.new(new_x, new_y, new_z)
- end
-
- # Reset the vertices
- sub_surface.setVertices(new_vertices)
-
- return true
- end
-
- # Determine if the sub surface is a vertical rectangle,
- # meaning a rectangle where the bottom is parallel to the ground.
- #
- # @param sub_surface [OpenStudio::Model::SubSurface] sub surface object
- # @return [Boolean] returns true if the surface is a vertical rectangle, false if not
- def sub_surface_vertical_rectangle?(sub_surface)
- # Get the vertices once
- verts = sub_surface.vertices
-
- # Check for 4 vertices
- return false unless verts.size == 4
-
- # Check if the 2 lowest z-values
- # are the same
- z_vals = []
- verts.each do |vertex|
- z_vals << vertex.z
- end
- z_vals = z_vals.sort
- return false unless z_vals[0] == z_vals[1]
-
- # Check if the diagonals are equal length
- diag_a = verts[0] - verts[2]
- diag_b = verts[1] - verts[3]
- return false unless diag_a.length == diag_b.length
-
- # If here, we have a rectangle
- return true
- end
-
# This method adds a subsurface (a window or a skylight depending on the surface) to the centroid of a surface. The
# shape of the subsurface is the same as the surface but is scaled so the area of the subsurface is the defined
# fraction of the surface (set by area_fraction). Note that this only works for surfaces that do not fold into
# themselves (like an 'L' or a 'V').
#
# @param surface [OpenStudio::Model::Surface] surface object
# @param area_fraction [Double] fraction of area of the larger surface
# @return [Boolean] returns true if successful, false if not
def sub_surface_create_centered_subsurface_from_scaled_surface(surface, area_fraction)
# Get rid of all existing subsurfaces.
- remove_all_subsurfaces(surface: surface)
+ surface.subSurfaces.sort.each(&:remove)
+
# What is the centroid of the surface.
surf_cent = surface.centroid
scale_factor = Math.sqrt(area_fraction)
# Create an array to collect the new vertices
@@ -247,12 +61,14 @@
# @param construction [OpenStudio::Model::Construction] construction to use for the new surface
# @return [Boolean] returns true if successful, false if not
def sub_surface_create_scaled_subsurfaces_from_surface(surface:, area_fraction:, construction:)
# Set geometry tolerences:
geometry_tolerence = 12
- # Get rid of all existing subsurfaces.
- remove_all_subsurfaces(surface: surface)
+
+ # Get rid of all existing subsurfaces
+ surface.subSurfaces.sort.each(&:remove)
+
# Return vertices of smaller surfaces that fit inside this surface. This is done in case the surface is
# concave.
# Throw an error if the roof is not flat.
surface.vertices.each do |surf_vert|
@@ -323,36 +139,8 @@
new_sub_surface.setConstruction(construction)
new_sub_surface.setName(new_name)
# There is now only one surface on the subsurface. Enforce this
new_sub_surface.setMultiplier(1)
end
- return true
- end
-
- # This just uses applies 'setWindowToWallRatio' method from the OpenStudio SDK. The only addition is that it changes
- # the name of the window to be the surface name plus the subsurface type (always 'fixedwindow').
- #
- # @param surface [OpenStudio::Model::Surface] surface object
- # @param area_fraction [Double] fraction of area of the larger surface
- # @param construction [OpenStudio::Model::Construction] construction to use for the new surface
- # @return [Boolean] returns true if successful, false if not
- def set_window_to_wall_ratio_set_name(surface:, area_fraction:, construction:)
- surface.setWindowToWallRatio(area_fraction)
- surface.subSurfaces.sort.each do |sub_surf|
- sub_surf.setSubSurfaceType('FixedWindow')
- sub_surf.setConstruction(construction)
- new_name = surface.name.to_s + '_' + sub_surf.subSurfaceType.to_s
- sub_surf.setName(new_name)
- end
- return true
- end
-
- # This removes all of the subsurfaces from a surface.
- # Is a preparation for replaceing windows or clearing doors before adding windows.
- #
- # @param surface [OpenStudio::Model::Surface] surface object
- # @return [Boolean] returns true if successful, false if not
- def remove_all_subsurfaces(surface:)
- surface.subSurfaces.sort.each(&:remove)
return true
end
end