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