lib/openstudio-standards/standards/Standards.SubSurface.rb in openstudio-standards-0.2.9 vs lib/openstudio-standards/standards/Standards.SubSurface.rb in openstudio-standards-0.2.10.rc1
- old
+ new
@@ -181,6 +181,141 @@
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').
+ def sub_surface_create_centered_subsurface_from_scaled_surface(surface, area_fraction, model)
+ # Get rid of all existing subsurfaces.
+ remove_All_Subsurfaces(surface: surface)
+ # 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
+ new_vertices = []
+
+ # Loop on vertices (Point3ds)
+ surface.vertices.each do |vertex|
+ # Point3d - Point3d = Vector3d
+ # Vector from centroid to vertex (GA, GB, GC, etc)
+ centroid_vector = vertex - surf_cent
+
+ # Resize the vector (done in place) according to scale_factor
+ centroid_vector.setLength(centroid_vector.length * scale_factor)
+
+ # Move the vertex toward the centroid
+ new_vertex = surf_cent + centroid_vector
+
+ # Add the new vertices to an array of vertices.
+ new_vertices << new_vertex
+ end
+ # Create a new subsurface with the vertices determined above.
+ new_sub_surface = OpenStudio::Model::SubSurface.new(new_vertices, model)
+ # Put this sub-surface on the surface.
+ new_sub_surface.setSurface(surface)
+ # Set the name of the subsurface to be the surface name plus the subsurface type (likely either 'fixedwindow' or
+ # 'skylight').
+ new_name = surface.name.to_s + '_' + new_sub_surface.subSurfaceType.to_s
+ new_sub_surface.setName(new_name)
+ # There is now only one surface on the subsurface. Enforce this
+ new_sub_surface.setMultiplier(1)
+ 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). This method is different than the
+ # 'sub_surface_create_centered_subsurface_from_scaled_surface' method because it can handle concave surfaces.
+ # However, it takes longer because it uses BTAP::Geometry::Surfaces.make_convex_surfaces which includes many nested
+ # loops that cycle through the verticies in a surface.
+ def sub_surface_create_scaled_subsurfaces_from_surface (surface, area_fraction, model)
+ # Get rid of all existing subsurfaces.
+ remove_All_Subsurfaces(surface: surface)
+ # 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|
+ surface.vertices.each do |surf_vert_2|
+ unless surf_vert_2.z.to_f == surf_vert.z.to_f
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Currently skylights can only be added to buildings with non-plenum flat roofs.")
+ end
+ end
+ end
+ new_surfaces = BTAP::Geometry::Surfaces.make_convex_surfaces(surface: surface, tol: 12)
+
+ # What is the centroid of the surface.
+ new_surf_cents = []
+ for i in 0..(new_surfaces.length - 1)
+ new_surf_cents << BTAP::Geometry::Surfaces.surf_centroid(surf: new_surfaces[i])
+ end
+
+ # Turn everything back into OpenStudio stuff
+ os_surf_points = []
+ os_surf_cents =[]
+ for i in 0..(new_surfaces.length - 1)
+ os_surf_point = []
+ for j in 0..(new_surfaces[i].length - 1)
+ os_surf_point << OpenStudio::Point3d.new(new_surfaces[i][j][:x].to_f, new_surfaces[i][j][:y].to_f, new_surfaces[i][j][:z].to_f)
+ end
+ os_surf_cents << OpenStudio::Point3d.new(new_surf_cents[i][:x].to_f, new_surf_cents[i][:y].to_f, new_surf_cents[i][:z].to_f)
+ os_surf_points << os_surf_point
+ end
+ scale_factor = Math.sqrt(area_fraction)
+
+ new_sub_vertices = []
+ os_surf_points.each_with_index do |new_surf, index|
+ # Create an array to collect the new vertices
+ new_vertices = []
+ # Loop on vertices
+ new_surf.each do |vertex|
+ # Point3d - Point3d = Vector3d
+ # Vector from centroid to vertex (GA, GB, GC, etc)
+ centroid_vector = vertex - os_surf_cents[index]
+
+ # Resize the vector (done in place) according to scale_factor
+ centroid_vector.setLength(centroid_vector.length * scale_factor)
+
+ # Move the vertex toward the centroid
+ new_vertex = os_surf_cents[index] + centroid_vector
+
+ # Add the new vertices to an array of vertices.
+ new_vertices << new_vertex
+ end
+ # Create a new subsurface with the vertices determined above.
+ new_sub_surface = OpenStudio::Model::SubSurface.new(new_vertices, model)
+ # Put this sub-surface on the surface.
+ new_sub_surface.setSurface(surface)
+ # Set the name of the subsurface to be the surface name plus the subsurface type (likely either 'fixedwindow' or
+ # 'skylight'). If there will be more than one subsurface then add a counter at the end.
+ new_name = surface.name.to_s + '_' + new_sub_surface.subSurfaceType.to_s
+ if new_surfaces.length > 1
+ new_name = surface.name.to_s + '_' + new_sub_surface.subSurfaceType.to_s + '_' + "#{index}"
+ end
+ new_sub_surface.setName(new_name)
+ # There is now only one surface on the subsurface. Enforce this
+ new_sub_surface.setMultiplier(1)
+ end
+ 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').
+ def set_Window_To_Wall_Ratio_set_name(surface, area_fraction)
+ surface.setWindowToWallRatio(area_fraction)
+ surface.subSurfaces.sort.each do |sub_surf|
+ new_name = surface.name.to_s + '_' + sub_surf.subSurfaceType.to_s
+ sub_surf.setName(new_name)
+ end
+ end
+
+ # This removes all of the subsurfaces from a surface. Is a preparation for replaceing windows or clearing doors
+ # before adding windows.
+ def remove_All_Subsurfaces(surface:)
+ surface.subSurfaces.sort.each do |sub_surface|
+ sub_surface.remove
+ end
+ end
end