lib/measures/SetWindowToWallRatioByFacade/measure.rb in openstudio-model-articulation-0.2.0 vs lib/measures/SetWindowToWallRatioByFacade/measure.rb in openstudio-model-articulation-0.2.1

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + # ******************************************************************************* # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -174,11 +176,11 @@ # flag for catchall glazing to be made only once catchall_glazing_const = nil # calculate initial envelope cost as negative value envelope_cost = 0 - constructions = model.getConstructions + constructions = model.getConstructions.sort constructions.each do |construction| const_llcs = construction.lifeCycleCosts const_llcs.each do |const_llc| if const_llc.category == 'Construction' envelope_cost += const_llc.totalCost * -1 @@ -188,26 +190,26 @@ # loop through surfaces finding exterior walls with proper orientation if exl_spaces_not_incl_fl_area # loop through spaces to gather surfaces. surfaces = [] - model.getSpaces.each do |space| + model.getSpaces.sort.each do |space| next if !space.partofTotalFloorArea - space.surfaces.each do |surface| + space.surfaces.sort.each do |surface| surfaces << surface end end else - surfaces = model.getSurfaces + surfaces = model.getSurfaces.sort end # used for new sub surfaces to find target construction orig_sub_surf_const_for_target_facade = {} orig_sub_surf_const_for_target_all_ext = {} # pre-loop through sub-surfaces to store constructions - model.getSubSurfaces.each do |sub_surf| + model.getSubSurfaces.sort.each do |sub_surf| # store constructions for entire building next if sub_surf.subSurfaceType == 'Door' || sub_surf.subSurfaceType == 'OverheadDoor' if sub_surf.construction.is_initialized if orig_sub_surf_const_for_target_all_ext.key?(sub_surf.construction.get) orig_sub_surf_const_for_target_all_ext[sub_surf.construction.get] += 1 @@ -246,11 +248,11 @@ end # hash for sub surfaces removed from non rectangular surfaces non_rect_parent = {} - surfaces.each do |s| + surfaces.sort.each do |s| next if s.surfaceType != 'Wall' next if s.outsideBoundaryCondition != 'Outdoors' if s.space.empty? runner.registerWarning("#{s.name} doesn't have a parent space and won't be included in the measure reporting or modifications.") next @@ -294,11 +296,11 @@ surface_gross_area = s.grossArea * zone_multiplier # loop through sub surfaces and add area including multiplier ext_window_area = 0 has_doors = false - s.subSurfaces.each do |subSurface| + s.subSurfaces.sort.each do |subSurface| # stop if non window or glass door if subSurface.subSurfaceType == 'Door' || subSurface.subSurfaceType == 'OverheadDoor' if split_at_doors == 'Remove Doors' subSurface.remove else @@ -319,19 +321,19 @@ if split_at_doors == 'Split Walls at Doors' && has_doors # split base surfaces at doors to create multiple base surfaces split_surfaces = s.splitSurfaceForSubSurfaces.to_a # frozen array # add original surface to new surfaces - split_surfaces.each do |ss| + split_surfaces.sort.each do |ss| all_surfaces << ss end end if wwr > 0 && triangulate all_surfaces2 = [] - all_surfaces.each do |ss| + all_surfaces.sort.each do |ss| # see if surface is rectangular (only checking non rotated on vertical wall) # todo - add in more robust rectangle check that can look for rotate and tilted rectangles rect_tri = false x_vals = [] y_vals = [] @@ -348,11 +350,11 @@ if x_vals.uniq.size <= 2 && y_vals.uniq.size <= 2 && z_vals.uniq.size <= 2 rect_tri = true end has_doors = false - ss.subSurfaces.each do |subSurface| + ss.subSurfaces.sort.each do |subSurface| if subSurface.subSurfaceType == 'Door' || subSurface.subSurfaceType == 'OverheadDoor' has_doors = true end end @@ -364,11 +366,11 @@ # add triangulated surfaces # todo - bring in more attributes # get construction from sub-surfaces and then delete them pre_tri_sub_const = {} - ss.subSurfaces.each do |subSurface| + ss.subSurfaces.sort.each do |subSurface| if subSurface.construction.is_initialized && !subSurface.isConstructionDefaulted if pre_tri_sub_const.key?(subSurface.construction.get) pre_tri_sub_const[subSurface.construction.get] = subSurface.grossArea else pre_tri_sub_const[subSurface.construction.get] = + subSurface.grossArea @@ -396,13 +398,13 @@ else all_surfaces2 = all_surfaces end # add windows - all_surfaces2.each do |ss| + all_surfaces2.sort.each do |ss| orig_sub_surf_constructions = {} - ss.subSurfaces.each do |sub_surf| + ss.subSurfaces.sort.each do |sub_surf| next if sub_surf.subSurfaceType == 'Door' || sub_surf.subSurfaceType == 'OverheadDoor' if sub_surf.construction.is_initialized if orig_sub_surf_constructions.key?(sub_surf.construction.get) orig_sub_surf_constructions[sub_surf.construction.get] += 1 else @@ -412,11 +414,11 @@ end # remove windows if ratio 0 or add in other cases if wwr == 0 # remove all sub surfaces - ss.subSurfaces.each(&:remove) + ss.subSurfaces.sort.each(&:remove) new_window = [] window_confirmed = true else new_window = ss.setWindowToWallRatio(wwr, sillHeight_si.value, true) window_confirmed = false @@ -520,11 +522,11 @@ runner.registerAsNotApplicable("The model has exterior #{facade.downcase} walls, but no windows could be added with the requested window to wall ratio") return true end # data for final condition wwr - surfaces.each do |s| + surfaces.sort.each do |s| next if s.surfaceType != 'Wall' next if s.outsideBoundaryCondition != 'Outdoors' if s.space.empty? runner.registerWarning("#{s.name} doesn't have a parent space and won't be included in the measure reporting or modifications.") next @@ -563,47 +565,35 @@ end surface_gross_area = s.grossArea * zone_multiplier # loop through sub surfaces and add area including multiplier ext_window_area = 0 - s.subSurfaces.each do |subSurface| # onlky one and should have multiplier of 1 + s.subSurfaces.sort.each do |subSurface| # onlky one and should have multiplier of 1 ext_window_area += subSurface.grossArea * subSurface.multiplier * zone_multiplier end final_gross_ext_wall_area += surface_gross_area final_ext_window_area += ext_window_area end - # short def to make numbers pretty (converts 4125001.25641 to 4,125,001.26 or 4,125,001). The definition be called through this measure - def neat_numbers(number, roundto = 2) # round to 0 or 2) - # round to zero or two decimals - if roundto == 2 - number = format '%.2f', number - else - number = number.round - end - # regex to add commas - number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse - end - # get delta in ft^2 for final - starting window area increase_window_area_si = OpenStudio::Quantity.new(final_ext_window_area - starting_ext_window_area, unit_area_si) increase_window_area_ip = OpenStudio.convert(increase_window_area_si, unit_area_ip).get # calculate final envelope cost as positive value - constructions = model.getConstructions + constructions = model.getConstructions.sort constructions.each do |construction| const_llcs = construction.lifeCycleCosts - const_llcs.each do |const_llc| + const_llcs.sort.each do |const_llc| if const_llc.category == 'Construction' envelope_cost += const_llc.totalCost end end end # report final condition final_wwr = format('%.02f', (final_ext_window_area / final_gross_ext_wall_area)) - runner.registerFinalCondition("The model's final window to wall ratio for #{facade} facing exterior walls is #{final_wwr}. Window area increased by #{neat_numbers(increase_window_area_ip.value, 0)} (ft^2). The material and construction costs increased by $#{neat_numbers(envelope_cost, 0)}.") + runner.registerFinalCondition("The model's final window to wall ratio for #{facade} facing exterior walls is #{final_wwr}. Window area increased by #{OpenStudio.toNeatString(increase_window_area_ip.value, 0)} (ft^2). The material and construction costs increased by $#{OpenStudio.toNeatString(envelope_cost, 0)}.") return true end end