lib/openstudio-standards/standards/Standards.SubSurface.rb in openstudio-standards-0.1.4 vs lib/openstudio-standards/standards/Standards.SubSurface.rb in openstudio-standards-0.1.5
- old
+ new
@@ -1,187 +1,187 @@
# open the class to add methods to apply HVAC efficiency standards
class OpenStudio::Model::SubSurface
-
# Determine the component infiltration rate for this surface
#
# @param type [String] choices are 'baseline' and 'advanced'
# @return [Double] infiltration rate
# @units cubic meters per second (m^3/s)
def component_infiltration_rate(type)
-
- comp_infil_rate_m3_per_s = 0.0
-
+ 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
+ '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
+ '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 = self.outsideBoundaryCondition
+
+ boundary_condition = outsideBoundaryCondition
# Skip non-outdoor surfaces
- return comp_infil_rate_m3_per_s unless self.outsideBoundaryCondition == 'Outdoors' || self.outsideBoundaryCondition == 'Ground'
-
+ return comp_infil_rate_m3_per_s unless outsideBoundaryCondition == 'Outdoors' || outsideBoundaryCondition == 'Ground'
+
# Per area infiltration rate for this surface
- surface_type = self.subSurfaceType
+ surface_type = 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 #{self.name}, assuming swinging_or_revolving_glass_door for infiltration calculation.")
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "For #{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'
+ when 'FixedWindow', 'OperableWindow'
infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['window']
- when 'Skylight','TubularDaylightDome','TubularDaylightDiffuser'
+ 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 #{self.name}, could not determine surface type for infiltration, will not be included in calculation.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "For #{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 = self.netArea
- area_ft2 = OpenStudio.convert(area_m2,'m^2','ft^2').get
-
+ area_m2 = 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
+ 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.")
-
+ # 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 percent_reduction [Double] the fractional amount
+ # to reduce the area.
+ def reduce_area_by_percent_by_shrinking_toward_centroid(percent_reduction)
+ mult = 1 - percent_reduction
+ scale_factor = mult**0.5
+
+ # Get the centroid (Point3d)
+ g = centroid
+
+ # Create an array to collect the new vertices
+ new_vertices = []
+
+ # Loop on vertices (Point3ds)
+ 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
+ setVertices(new_vertices)
+ end
+
# Reduce the area of the subsurface by raising the
# sill height.
#
# @param percent_reduction [Double] the fractional amount
# to reduce the area.
def reduce_area_by_percent_by_raising_sill(percent_reduction)
-
- mult = 1-percent_reduction
-
+
+ mult = 1 - percent_reduction
+
# Calculate the original area
- area_original = self.netArea
+ area_original = netArea
# Find the min and max z values
min_z_val = 99999
max_z_val = -99999
- self.vertices.each do |vertex|
+ 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 = []
- self.vertices.each do |vertex|
+ 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
- self.setVertices(new_vertices)
-
- # Compare the new area to the old for validation
- act_pct_red = 1.0 - (self.netArea / area_original)
-
+ setVertices(new_vertices)
+
return true
-
end
- # Reduce the area of the subsurface by shrinking it
- # in the x direction. Designed to work on skylights.
- #
- # @param percent_reduction [Double] the fractional amount
- # to reduce the area.
- def reduce_area_by_percent_by_shrinking_x(percent_reduction)
-
- mult = 1-percent_reduction
-
- # Calculate the original area
- area_original = self.netArea
+ # Determine if the sub surface is a vertical rectangle,
+ # meaning a rectangle where the bottom is parallel to the ground.
+ def vertical_rectangle?
+ # Get the vertices once
+ verts = vertices
- # Find the min and max x values
- min_x_val = 99999
- max_x_val = -99999
- self.vertices.each do |vertex|
- # Min x value
- if vertex.x < min_x_val
- min_x_val = vertex.x
- end
- # Max x value
- if vertex.x > max_x_val
- max_x_val = vertex.x
- end
+ # 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
-
- # Calculate the skylight width
- width = max_x_val - min_x_val
-
- # Calculate the new sill width
- new_width_x = max_x_val - (width * mult)
-
- # Reset the z value of the lowest points
- new_vertices = []
- self.vertices.each do |vertex|
- new_x = vertex.x
- if new_x == min_x_val
- new_x = new_width_x
- end
- new_y = vertex.y
- new_z = vertex.z
- new_vertices << OpenStudio::Point3d.new(new_x, new_y, new_z)
- end
-
- # Reset the vertices
- self.setVertices(new_vertices)
-
- # Compare the new area to the old for validation
- act_pct_red = 1.0 - (self.netArea / area_original)
-
+ 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
-
end