openstudio-model-articulation 0.4.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -1
  3. data/CHANGELOG.md +24 -0
  4. data/Gemfile +2 -2
  5. data/README.md +22 -3
  6. data/lib/measures/AssignConstructionSetToBuilding/measure.xml +10 -10
  7. data/lib/measures/AssignSpaceTypeBySpaceName/measure.xml +27 -9
  8. data/lib/measures/AssignSpaceTypeToBuilding/measure.xml +10 -10
  9. data/lib/measures/AssignSpacesToStories/measure.rb +2 -4
  10. data/lib/measures/AssignSpacesToStories/measure.xml +10 -10
  11. data/lib/measures/BarAspectRatioStudy/measure.rb +2 -1
  12. data/lib/measures/BarAspectRatioStudy/measure.xml +4 -4
  13. data/lib/measures/CleanupSpaceOrigins/measure.rb +3 -0
  14. data/lib/measures/CleanupSpaceOrigins/measure.xml +10 -10
  15. data/lib/measures/FindAndReplaceObjectNames/measure.xml +8 -8
  16. data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/measure.rb +2 -2
  17. data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/measure.xml +22 -4
  18. data/lib/measures/RemoveHardAssignedConstructions/measure.xml +8 -8
  19. data/lib/measures/RenameSpaceSurfacesBasedonParentSpaceandOrientation/measure.xml +37 -7
  20. data/lib/measures/RotateBuilding/measure.xml +8 -8
  21. data/lib/measures/SetExtWallToGroundBoundaryConditionByStory/measure.xml +13 -7
  22. data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/measure.rb +1 -1
  23. data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/measure.xml +10 -10
  24. data/lib/measures/SetInteriorWallsToSelectedConstruction/measure.rb +1 -1
  25. data/lib/measures/SetInteriorWallsToSelectedConstruction/measure.xml +10 -10
  26. data/lib/measures/SetWindowToWallRatioByFacade/README.md +11 -0
  27. data/lib/measures/SetWindowToWallRatioByFacade/measure.rb +90 -142
  28. data/lib/measures/SetWindowToWallRatioByFacade/measure.xml +32 -11
  29. data/lib/measures/SetWindowToWallRatioByFacade/resources/functions.rb +176 -0
  30. data/lib/measures/SimplifyGeometryToSlicedBar/measure.rb +8 -4
  31. data/lib/measures/SimplifyGeometryToSlicedBar/measure.xml +31 -13
  32. data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_cofee.rb +6 -4
  33. data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_geometry.rb +13 -8
  34. data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_helper_methods.rb +2 -4
  35. data/lib/measures/SpaceTypeAndConstructionSetWizard/measure.rb +1 -1
  36. data/lib/measures/SpaceTypeAndConstructionSetWizard/measure.xml +4 -4
  37. data/lib/measures/SurfaceMatching/measure.rb +1 -0
  38. data/lib/measures/SurfaceMatching/measure.xml +10 -10
  39. data/lib/measures/add_empd_material_properties/LICENSE.md +27 -0
  40. data/lib/measures/add_empd_material_properties/README.md +116 -0
  41. data/lib/measures/add_empd_material_properties/README.md.erb +42 -0
  42. data/lib/measures/add_empd_material_properties/docs/.gitkeep +0 -0
  43. data/lib/measures/add_empd_material_properties/measure.rb +247 -0
  44. data/lib/measures/add_empd_material_properties/measure.xml +201 -0
  45. data/lib/measures/blended_space_type_from_floor_area_ratios/measure.rb +4 -3
  46. data/lib/measures/blended_space_type_from_floor_area_ratios/measure.xml +4 -4
  47. data/lib/measures/blended_space_type_from_model/{resources → docs}/replace_occupied_spaces_with_blended_space_type_design_doc.txt +0 -0
  48. data/lib/measures/blended_space_type_from_model/measure.rb +11 -3
  49. data/lib/measures/blended_space_type_from_model/measure.xml +15 -21
  50. data/lib/measures/clone_building_from_external_model/measure.xml +3 -3
  51. data/lib/measures/create_DOE_prototype_building/measure.rb +2 -2
  52. data/lib/measures/create_DOE_prototype_building/measure.xml +442 -438
  53. data/lib/measures/create_and_assign_thermal_zones_for_unassigned_spaces/measure.xml +3 -3
  54. data/lib/measures/create_bar_from_building_type_ratios/README.md +109 -35
  55. data/lib/measures/create_bar_from_building_type_ratios/README.md.erb +54 -35
  56. data/lib/measures/create_bar_from_building_type_ratios/measure.rb +8 -3
  57. data/lib/measures/create_bar_from_building_type_ratios/measure.xml +12 -12
  58. data/lib/measures/create_bar_from_deer_building_type_ratios/README.md +301 -79
  59. data/lib/measures/create_bar_from_deer_building_type_ratios/README.md.erb +62 -79
  60. data/lib/measures/create_bar_from_deer_building_type_ratios/measure.rb +9 -4
  61. data/lib/measures/create_bar_from_deer_building_type_ratios/measure.xml +15 -59
  62. data/lib/measures/create_bar_from_doe_building_type_ratios/README.md +298 -57
  63. data/lib/measures/create_bar_from_doe_building_type_ratios/README.md.erb +54 -57
  64. data/lib/measures/create_bar_from_doe_building_type_ratios/measure.rb +9 -4
  65. data/lib/measures/create_bar_from_doe_building_type_ratios/measure.xml +12 -16
  66. data/lib/measures/create_bar_from_model/measure.rb +10 -6
  67. data/lib/measures/create_bar_from_model/measure.xml +4 -4
  68. data/lib/measures/create_bar_from_space_type_ratios/README.md +94 -42
  69. data/lib/measures/create_bar_from_space_type_ratios/README.md.erb +60 -42
  70. data/lib/measures/create_bar_from_space_type_ratios/measure.rb +8 -3
  71. data/lib/measures/create_bar_from_space_type_ratios/measure.xml +15 -15
  72. data/lib/measures/create_baseline_building/measure.rb +3 -2
  73. data/lib/measures/create_baseline_building/measure.xml +4 -4
  74. data/lib/measures/create_deer_prototype_building/measure.xml +3 -3
  75. data/lib/measures/create_parametric_schedules/measure.rb +15 -10
  76. data/lib/measures/create_parametric_schedules/measure.xml +4 -4
  77. data/lib/measures/create_typical_building_from_model/README.md +81 -16
  78. data/lib/measures/create_typical_building_from_model/README.md.erb +36 -16
  79. data/lib/measures/create_typical_building_from_model/measure.rb +6 -1
  80. data/lib/measures/create_typical_building_from_model/measure.xml +19 -19
  81. data/lib/measures/create_typical_deer_building_from_model/README.md +173 -53
  82. data/lib/measures/create_typical_deer_building_from_model/README.md.erb +57 -53
  83. data/lib/measures/create_typical_deer_building_from_model/measure.rb +7 -2
  84. data/lib/measures/create_typical_deer_building_from_model/measure.xml +26 -26
  85. data/lib/measures/create_typical_doe_building_from_model/README.md +182 -44
  86. data/lib/measures/create_typical_doe_building_from_model/README.md.erb +58 -44
  87. data/lib/measures/create_typical_doe_building_from_model/measure.rb +7 -2
  88. data/lib/measures/create_typical_doe_building_from_model/measure.xml +26 -26
  89. data/lib/measures/deer_space_type_and_construction_set_wizard/measure.rb +1 -1
  90. data/lib/measures/deer_space_type_and_construction_set_wizard/measure.xml +4 -4
  91. data/lib/measures/find_and_replace_in_all_thermal_zone_names/measure.xml +3 -3
  92. data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/measure.rb +2 -0
  93. data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/measure.xml +4 -4
  94. data/lib/measures/merge_floorspace_js_with_model/measure.rb +4 -1
  95. data/lib/measures/merge_floorspace_js_with_model/measure.xml +4 -4
  96. data/lib/measures/merge_spaces_from_external_file/measure.xml +3 -3
  97. data/lib/measures/radiance_measure/measure.rb +62 -56
  98. data/lib/measures/radiance_measure/measure.xml +4 -4
  99. data/lib/measures/radiant_slab_with_doas/measure.rb +8 -1
  100. data/lib/measures/radiant_slab_with_doas/measure.xml +9 -9
  101. data/lib/measures/replace_geometry_by_story/measure.rb +4 -0
  102. data/lib/measures/replace_geometry_by_story/measure.xml +4 -4
  103. data/lib/measures/scale_geometry/measure.xml +3 -3
  104. data/lib/openstudio/model_articulation/version.rb +1 -1
  105. data/openstudio-model-articulation.gemspec +2 -2
  106. metadata +15 -9
  107. data/lib/measures/blended_space_type_from_model/resources/os_lib_model_simplification.rb +0 -1049
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.0</schema_version>
4
4
  <name>rotate_building</name>
5
5
  <uid>b2742307-bce7-4747-8f94-977718217305</uid>
6
- <version_id>bdde9591-38c6-47ff-b43d-4e205864b64d</version_id>
7
- <version_modified>20210423T142510Z</version_modified>
6
+ <version_id>6d681308-f06a-49a4-b29c-85e02c940245</version_id>
7
+ <version_modified>20220505T182928Z</version_modified>
8
8
  <xml_checksum>49BEF039</xml_checksum>
9
9
  <class_name>RotateBuilding</class_name>
10
10
  <display_name>Rotate Building</display_name>
@@ -73,12 +73,6 @@
73
73
  <usage_type>readme</usage_type>
74
74
  <checksum>7E721F8C</checksum>
75
75
  </file>
76
- <file>
77
- <filename>RotateBuilding_Test.rb</filename>
78
- <filetype>rb</filetype>
79
- <usage_type>test</usage_type>
80
- <checksum>80D856EC</checksum>
81
- </file>
82
76
  <file>
83
77
  <filename>LICENSE.md</filename>
84
78
  <filetype>md</filetype>
@@ -96,5 +90,11 @@
96
90
  <usage_type>script</usage_type>
97
91
  <checksum>7A45B037</checksum>
98
92
  </file>
93
+ <file>
94
+ <filename>RotateBuilding_Test.rb</filename>
95
+ <filetype>rb</filetype>
96
+ <usage_type>test</usage_type>
97
+ <checksum>7844502E</checksum>
98
+ </file>
99
99
  </files>
100
100
  </measure>
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.0</schema_version>
4
4
  <name>set_ext_wall_to_ground_boundary_condition_by_story</name>
5
5
  <uid>a6da6f2b-2d07-4d25-b2b4-4b1dd62df237</uid>
6
- <version_id>561e388e-2470-4fe4-89dd-53da429a4faa</version_id>
7
- <version_modified>20210423T142510Z</version_modified>
6
+ <version_id>1aca0c67-bb5a-4d0d-ad64-42f3829fe1ba</version_id>
7
+ <version_modified>20220505T182931Z</version_modified>
8
8
  <xml_checksum>0F858D9E</xml_checksum>
9
9
  <class_name>SetExtWallToGroundBoundaryConditionByStory</class_name>
10
10
  <display_name>SetExtWallToGroundBoundaryConditionByStory</display_name>
@@ -76,17 +76,23 @@
76
76
  <usage_type>script</usage_type>
77
77
  <checksum>D74BDE59</checksum>
78
78
  </file>
79
+ <file>
80
+ <filename>LICENSE.md</filename>
81
+ <filetype>md</filetype>
82
+ <usage_type>license</usage_type>
83
+ <checksum>A21A3ED2</checksum>
84
+ </file>
79
85
  <file>
80
86
  <filename>SetExtWallToGroundByStory_Test.rb</filename>
81
87
  <filetype>rb</filetype>
82
88
  <usage_type>test</usage_type>
83
- <checksum>250AF3F7</checksum>
89
+ <checksum>43480F51</checksum>
84
90
  </file>
85
91
  <file>
86
- <filename>LICENSE.md</filename>
87
- <filetype>md</filetype>
88
- <usage_type>license</usage_type>
89
- <checksum>A21A3ED2</checksum>
92
+ <filename>3Story2Space/run.db</filename>
93
+ <filetype>db</filetype>
94
+ <usage_type>test</usage_type>
95
+ <checksum>761DC6F7</checksum>
90
96
  </file>
91
97
  </files>
92
98
  </measure>
@@ -69,7 +69,7 @@ class SetInteriorWallsAndFloorsToAdiabatic < OpenStudio::Measure::ModelMeasure
69
69
  end
70
70
 
71
71
  # looping through sorted hash of storys
72
- construction_args_hash.sort.map do |key, value| # todo - could filter this so only constructions that are valid on opaque surfaces will show up.
72
+ construction_args_hash.sort.map do |key, value| # TODO: - could filter this so only constructions that are valid on opaque surfaces will show up.
73
73
  construction_handles << value.handle.to_s
74
74
  construction_display_names << key
75
75
  end
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.0</schema_version>
4
4
  <name>set_interior_walls_and_floors_to_adiabatic</name>
5
5
  <uid>78cbde97-d7c4-425f-ab74-5053a681cc4b</uid>
6
- <version_id>f5114792-b53a-425c-911d-10fd356d8e79</version_id>
7
- <version_modified>20210423T142510Z</version_modified>
6
+ <version_id>4ceba5f6-8f6f-4969-848c-0e5ffbfdfe75</version_id>
7
+ <version_modified>20220505T182932Z</version_modified>
8
8
  <xml_checksum>1E963D9C</xml_checksum>
9
9
  <class_name>SetInteriorWallsAndFloorsToAdiabatic</class_name>
10
10
  <display_name>SetInteriorWallsAndFloorsToAdiabatic</display_name>
@@ -55,6 +55,12 @@
55
55
  <usage_type>readme</usage_type>
56
56
  <checksum>26905DFE</checksum>
57
57
  </file>
58
+ <file>
59
+ <filename>LICENSE.md</filename>
60
+ <filetype>md</filetype>
61
+ <usage_type>license</usage_type>
62
+ <checksum>A21A3ED2</checksum>
63
+ </file>
58
64
  <file>
59
65
  <version>
60
66
  <software_program>OpenStudio</software_program>
@@ -64,19 +70,13 @@
64
70
  <filename>measure.rb</filename>
65
71
  <filetype>rb</filetype>
66
72
  <usage_type>script</usage_type>
67
- <checksum>CEFB1A45</checksum>
73
+ <checksum>3EC935EF</checksum>
68
74
  </file>
69
75
  <file>
70
76
  <filename>SetInteriorWallsAndFloorsToSelectedConstruction_Test.rb</filename>
71
77
  <filetype>rb</filetype>
72
78
  <usage_type>test</usage_type>
73
- <checksum>39534274</checksum>
74
- </file>
75
- <file>
76
- <filename>LICENSE.md</filename>
77
- <filetype>md</filetype>
78
- <usage_type>license</usage_type>
79
- <checksum>A21A3ED2</checksum>
79
+ <checksum>55AAC4F2</checksum>
80
80
  </file>
81
81
  </files>
82
82
  </measure>
@@ -66,7 +66,7 @@ class SetInteriorWallsToSelectedConstruction < OpenStudio::Measure::ModelMeasure
66
66
  end
67
67
 
68
68
  # looping through sorted hash of constructions
69
- construction_args_hash.sort.map do |key, value| # todo - could filter this so only constructions that are valid on opaque surfaces will show up.
69
+ construction_args_hash.sort.map do |key, value| # TODO: - could filter this so only constructions that are valid on opaque surfaces will show up.
70
70
  construction_handles << value.handle.to_s
71
71
  construction_display_names << key
72
72
  end
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.0</schema_version>
4
4
  <name>set_interior_walls_to_selected_construction</name>
5
5
  <uid>e3d59d0d-1ce8-4cb2-ae59-001f0fa2ac46</uid>
6
- <version_id>b3a51cf7-1156-4d3b-9c68-3f76f16ae570</version_id>
7
- <version_modified>20210423T142511Z</version_modified>
6
+ <version_id>bb0dd052-2f62-49ef-8e20-2e9c39786802</version_id>
7
+ <version_modified>20220505T182927Z</version_modified>
8
8
  <xml_checksum>1E963D9C</xml_checksum>
9
9
  <class_name>SetInteriorWallsToSelectedConstruction</class_name>
10
10
  <display_name>SetInteriorWallsToSelectedConstruction</display_name>
@@ -55,6 +55,12 @@
55
55
  <usage_type>readme</usage_type>
56
56
  <checksum>C8974F9D</checksum>
57
57
  </file>
58
+ <file>
59
+ <filename>LICENSE.md</filename>
60
+ <filetype>md</filetype>
61
+ <usage_type>license</usage_type>
62
+ <checksum>A21A3ED2</checksum>
63
+ </file>
58
64
  <file>
59
65
  <version>
60
66
  <software_program>OpenStudio</software_program>
@@ -64,19 +70,13 @@
64
70
  <filename>measure.rb</filename>
65
71
  <filetype>rb</filetype>
66
72
  <usage_type>script</usage_type>
67
- <checksum>0293AC5B</checksum>
73
+ <checksum>DC3C3C85</checksum>
68
74
  </file>
69
75
  <file>
70
76
  <filename>SetInteriorWallstoSelectedConstruction_Test.rb</filename>
71
77
  <filetype>rb</filetype>
72
78
  <usage_type>test</usage_type>
73
- <checksum>EE1A5054</checksum>
74
- </file>
75
- <file>
76
- <filename>LICENSE.md</filename>
77
- <filetype>md</filetype>
78
- <usage_type>license</usage_type>
79
- <checksum>A21A3ED2</checksum>
79
+ <checksum>17B7EFF1</checksum>
80
80
  </file>
81
81
  </files>
82
82
  </measure>
@@ -100,6 +100,17 @@ This will only impact exterior surfaces with specified orientation
100
100
 
101
101
 
102
102
 
103
+ ### Triangulation Minimum Area (m^2)
104
+ Triangulated surfaces less than this will not be created.
105
+ **Name:** triangulation_min_area,
106
+ **Type:** Double,
107
+ **Units:** ,
108
+ **Required:** true,
109
+ **Model Dependent:** false
110
+
111
+
112
+
113
+
103
114
 
104
115
 
105
116
 
@@ -33,6 +33,8 @@
33
33
  # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
34
  # *******************************************************************************
35
35
 
36
+ require_relative 'resources/functions'
37
+
36
38
  class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
37
39
  # override name to return the name of your script
38
40
  def name
@@ -97,6 +99,13 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
97
99
  triangulate.setDefaultValue(true)
98
100
  args << triangulate
99
101
 
102
+ # triangulation minimum area
103
+ triangulation_min_area = OpenStudio::Measure::OSArgument.makeDoubleArgument('triangulation_min_area', true)
104
+ triangulation_min_area.setDisplayName('Triangulation Minimum Area (m^2)')
105
+ triangulation_min_area.setDescription('Triangulated surfaces less than this will not be created.')
106
+ triangulation_min_area.setDefaultValue(0.001) # Two vertices < 0.01 meters apart are coincident in EnergyPlus (SurfaceGeometry.cc).
107
+ args << triangulation_min_area
108
+
100
109
  return args
101
110
  end
102
111
 
@@ -117,6 +126,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
117
126
  split_at_doors = runner.getStringArgumentValue('split_at_doors', user_arguments)
118
127
  inset_tri_sub = runner.getBoolArgumentValue('inset_tri_sub', user_arguments)
119
128
  triangulate = runner.getBoolArgumentValue('triangulate', user_arguments)
129
+ triangulation_min_area = runner.getDoubleArgumentValue('triangulation_min_area', user_arguments)
120
130
 
121
131
  # check reasonableness of fraction
122
132
  if wwr == 0
@@ -192,6 +202,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
192
202
  surfaces = []
193
203
  model.getSpaces.sort.each do |space|
194
204
  next if !space.partofTotalFloorArea
205
+
195
206
  space.surfaces.sort.each do |surface|
196
207
  surfaces << surface
197
208
  end
@@ -201,79 +212,14 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
201
212
  end
202
213
 
203
214
  # used for new sub surfaces to find target construction
204
- orig_sub_surf_const_for_target_facade = {}
205
- orig_sub_surf_const_for_target_all_ext = {}
206
-
207
- # pre-loop through sub-surfaces to store constructions
208
- model.getSubSurfaces.sort.each do |sub_surf|
209
- # store constructions for entire building
210
- next if sub_surf.subSurfaceType == 'Door' || sub_surf.subSurfaceType == 'OverheadDoor'
211
- if sub_surf.construction.is_initialized
212
- if orig_sub_surf_const_for_target_all_ext.key?(sub_surf.construction.get)
213
- orig_sub_surf_const_for_target_all_ext[sub_surf.construction.get] += 1
214
- else
215
- orig_sub_surf_const_for_target_all_ext[sub_surf.construction.get] = 1
216
- end
217
- end
218
-
219
- # get the absoluteAzimuth for the surface so we can categorize it
220
- absoluteAzimuth = OpenStudio.convert(sub_surf.azimuth, 'rad', 'deg').get + sub_surf.surface.get.space.get.directionofRelativeNorth + model.getBuilding.northAxis
221
- absoluteAzimuth -= 360.0 until absoluteAzimuth < 360.0
222
-
223
- if facade == 'North'
224
- next if !((absoluteAzimuth >= 315.0) || (absoluteAzimuth < 45.0))
225
- elsif facade == 'East'
226
- next if !((absoluteAzimuth >= 45.0) && (absoluteAzimuth < 135.0))
227
- elsif facade == 'South'
228
- next if !((absoluteAzimuth >= 135.0) && (absoluteAzimuth < 225.0))
229
- elsif facade == 'West'
230
- next if !((absoluteAzimuth >= 225.0) && (absoluteAzimuth < 315.0))
231
- elsif facade == 'All'
232
- # no next needed
233
- else
234
- runner.registerError('Unexpected value of facade: ' + facade + '.')
235
- return false
236
- end
237
-
238
- # store constructions for this facade
239
- if sub_surf.construction.is_initialized
240
- if orig_sub_surf_const_for_target_facade.key?(sub_surf.construction.get)
241
- orig_sub_surf_const_for_target_facade[sub_surf.construction.get] += 1
242
- else
243
- orig_sub_surf_const_for_target_facade[sub_surf.construction.get] = 1
244
- end
245
- end
246
- end
215
+ subsurfaces_by_facade = Functions.get_surfaces_or_subsurfaces_by_facade(model.getSubSurfaces, facade)
216
+ orig_sub_surf_const_for_target_facade = Functions.get_orig_sub_surf_const_for_target(subsurfaces_by_facade)
217
+ orig_sub_surf_const_for_target_all_ext = Functions.get_orig_sub_surf_const_for_target(model.getSubSurfaces)
247
218
 
248
219
  # hash for sub surfaces removed from non rectangular surfaces
249
220
  non_rect_parent = {}
250
221
 
251
- surfaces.sort.each do |s|
252
- next if s.surfaceType != 'Wall'
253
- next if s.outsideBoundaryCondition != 'Outdoors'
254
- if s.space.empty?
255
- runner.registerWarning("#{s.name} doesn't have a parent space and won't be included in the measure reporting or modifications.")
256
- next
257
- end
258
-
259
- # get the absoluteAzimuth for the surface so we can categorize it
260
- absoluteAzimuth = OpenStudio.convert(s.azimuth, 'rad', 'deg').get + s.space.get.directionofRelativeNorth + model.getBuilding.northAxis
261
- absoluteAzimuth -= 360.0 until absoluteAzimuth < 360.0
262
-
263
- if facade == 'North'
264
- next if !((absoluteAzimuth >= 315.0) || (absoluteAzimuth < 45.0))
265
- elsif facade == 'East'
266
- next if !((absoluteAzimuth >= 45.0) && (absoluteAzimuth < 135.0))
267
- elsif facade == 'South'
268
- next if !((absoluteAzimuth >= 135.0) && (absoluteAzimuth < 225.0))
269
- elsif facade == 'West'
270
- next if !((absoluteAzimuth >= 225.0) && (absoluteAzimuth < 315.0))
271
- elsif facade == 'All'
272
- # no next needed
273
- else
274
- runner.registerError('Unexpected value of facade: ' + facade + '.')
275
- return false
276
- end
222
+ Functions.get_surfaces_or_subsurfaces_by_facade(model.getSurfaces, facade).sort.each do |s|
277
223
  exterior_walls = true
278
224
 
279
225
  # get surface area adjusting for zone multiplier
@@ -317,6 +263,14 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
317
263
 
318
264
  all_surfaces = [s]
319
265
  if split_at_doors == 'Split Walls at Doors' && has_doors
266
+
267
+ # remove windows before split at doors
268
+ s.subSurfaces.each do |sub_surface|
269
+ next if ['Door', 'OverheadDoor'].include? sub_surface.subSurfaceType
270
+
271
+ sub_surface.remove
272
+ end
273
+
320
274
  # split base surfaces at doors to create multiple base surfaces
321
275
  split_surfaces = s.splitSurfaceForSubSurfaces.to_a # frozen array
322
276
 
@@ -332,22 +286,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
332
286
  all_surfaces.sort.each do |ss|
333
287
  # see if surface is rectangular (only checking non rotated on vertical wall)
334
288
  # todo - add in more robust rectangle check that can look for rotate and tilted rectangles
335
- rect_tri = false
336
- x_vals = []
337
- y_vals = []
338
- z_vals = []
339
- vertices = ss.vertices
340
- flag = false
341
- vertices.each do |vertex|
342
- # initialize new vertex to old vertex
343
- # rounding values to address tolerance issue 10 digits digits in
344
- x_vals << vertex.x.round(8)
345
- y_vals << vertex.y.round(8)
346
- z_vals << vertex.z.round(8)
347
- end
348
- if x_vals.uniq.size <= 2 && y_vals.uniq.size <= 2 && z_vals.uniq.size <= 2
349
- rect_tri = true
350
- end
289
+ rect_tri = Functions.rectangle?(ss)
351
290
 
352
291
  has_doors = false
353
292
  ss.subSurfaces.sort.each do |subSurface|
@@ -377,8 +316,14 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
377
316
  subSurface.remove
378
317
  end
379
318
 
319
+ # triangulate surface
380
320
  ss.triangulation.each do |tri|
381
321
  new_surface = OpenStudio::Model::Surface.new(tri, model)
322
+ if new_surface.grossArea < triangulation_min_area
323
+ runner.registerWarning("triangulation produced a surface with area less than minimum for surface = #{ss.name}")
324
+ new_surface.remove
325
+ next
326
+ end
382
327
  new_surface.setSpace(ss.space.get)
383
328
  if ss.construction.is_initialized && !ss.isConstructionDefaulted
384
329
  new_surface.setConstruction(ss.construction.get)
@@ -402,6 +347,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
402
347
  orig_sub_surf_constructions = {}
403
348
  ss.subSurfaces.sort.each do |sub_surf|
404
349
  next if sub_surf.subSurfaceType == 'Door' || sub_surf.subSurfaceType == 'OverheadDoor'
350
+
405
351
  if sub_surf.construction.is_initialized
406
352
  if orig_sub_surf_constructions.key?(sub_surf.construction.get)
407
353
  orig_sub_surf_constructions[sub_surf.construction.get] += 1
@@ -425,38 +371,35 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
425
371
  if wwr > 0 && new_window.empty?
426
372
 
427
373
  # if new window is empty then inset base surface to add window (check may need to skip on base surfaces with doors)
428
- if inset_tri_sub
429
-
430
- # skip of surface already has sub-surfaces or if not triangle
431
- if ss.subSurfaces.empty? && ss.vertices.size <= 3
432
- # get centroid
433
- vertices = ss.vertices
434
- centroid = OpenStudio.getCentroid(vertices).get
435
- x_cent = centroid.x
436
- y_cent = centroid.y
437
- z_cent = centroid.z
438
-
439
- # reduce vertices towards centroid
440
- scale = Math.sqrt(wwr)
441
- new_vertices = OpenStudio::Point3dVector.new
442
- vertices.each do |vertex|
443
- x = (vertex.x * scale + x_cent * (1.0 - scale))
444
- y = (vertex.y * scale + y_cent * (1.0 - scale))
445
- z = (vertex.z * scale + z_cent * (1.0 - scale))
446
- new_vertices << OpenStudio::Point3d.new(x, y, z)
447
- end
448
-
449
- # create inset window
450
- new_window = OpenStudio::Model::SubSurface.new(new_vertices, model)
451
- new_window.setSurface(ss)
452
- new_window.setSubSurfaceType('FixedWindow')
453
- if non_rect_parent.key?(ss)
454
- new_window.setConstruction(non_rect_parent[ss])
455
- end
456
- window_confirmed = true
374
+ # skip of surface already has sub-surfaces or if not triangle
375
+ if inset_tri_sub && (ss.subSurfaces.empty? && ss.vertices.size <= 3)
376
+ # get centroid
377
+ vertices = ss.vertices
378
+ centroid = OpenStudio.getCentroid(vertices).get
379
+ x_cent = centroid.x
380
+ y_cent = centroid.y
381
+ z_cent = centroid.z
382
+
383
+ # reduce vertices towards centroid
384
+ scale = Math.sqrt(wwr)
385
+ new_vertices = OpenStudio::Point3dVector.new
386
+ vertices.each do |vertex|
387
+ x = (vertex.x * scale + x_cent * (1.0 - scale))
388
+ y = (vertex.y * scale + y_cent * (1.0 - scale))
389
+ z = (vertex.z * scale + z_cent * (1.0 - scale))
390
+ new_vertices << OpenStudio::Point3d.new(x, y, z)
457
391
  end
458
392
 
393
+ # create inset window
394
+ new_window = OpenStudio::Model::SubSurface.new(new_vertices, model)
395
+ new_window.setSurface(ss)
396
+ new_window.setSubSurfaceType('FixedWindow')
397
+ if non_rect_parent.key?(ss)
398
+ new_window.setConstruction(non_rect_parent[ss])
399
+ end
400
+ window_confirmed = true
459
401
  end
402
+
460
403
  else
461
404
  if wwr > 0
462
405
  new_window = new_window.get
@@ -465,7 +408,38 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
465
408
  end
466
409
 
467
410
  if !window_confirmed
468
- runner.registerWarning("Fenestration could not be added for #{ss.name}. Surface may not be rectangular or triangular, may have a door, or the requested WWR may be too large.")
411
+ case ss.vertices.size
412
+ when 3
413
+ if !inset_tri_sub
414
+ runner.registerWarning("window could not be added because the surface has 3 sides, but the inset_tri_sub argument is false = #{ss.name}")
415
+ end
416
+ when 4
417
+ case Functions.rectangle?(ss)
418
+ when true
419
+ # if Functions.requested_window_area_greater_than_max?(ss, wwr)
420
+ # runner.registerWarning("window could not be added because the surface has 4 sides and is rectangular, but the WWR exceeds the maximum = #{ss.name}")
421
+ # end
422
+ # HACK until requested_window_area_greater_than_max? works. reduce by 0.01 to find the "maximum".
423
+ (1..(wwr / 0.1).floor).each do |i|
424
+ wwr_adj = wwr - (i / 100.0)
425
+ new_window = ss.setWindowToWallRatio(wwr_adj, sillHeight_si.value, true)
426
+ unless new_window.empty?
427
+ new_window = new_window.get
428
+ window_confirmed = true
429
+ runner.registerWarning("window-to-wall ratio exceeds maximum and was reduced to #{wwr_adj.round(3)} for surface = #{ss.name}")
430
+ break
431
+ end
432
+ end
433
+ when false
434
+ if !triangulate
435
+ runner.registerWarning("window could not be added because the surface has 4 sides, but is not rectangular and the triangulate argument is false = #{ss.name}")
436
+ end
437
+ end
438
+ else
439
+ if !triangulate
440
+ runner.registerWarning("window could not be added because the surface has more than 4 sides and the triangulate argument is false = #{ss.name}")
441
+ end
442
+ end
469
443
  end
470
444
 
471
445
  # warn user if resulting window doesn't have a construction, as it will result in failed simulation. In the future may use logic from starting windows to apply construction to new window.
@@ -522,33 +496,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
522
496
  end
523
497
 
524
498
  # data for final condition wwr
525
- surfaces.sort.each do |s|
526
- next if s.surfaceType != 'Wall'
527
- next if s.outsideBoundaryCondition != 'Outdoors'
528
- if s.space.empty?
529
- runner.registerWarning("#{s.name} doesn't have a parent space and won't be included in the measure reporting or modifications.")
530
- next
531
- end
532
-
533
- # get the absoluteAzimuth for the surface so we can categorize it
534
- absoluteAzimuth = OpenStudio.convert(s.azimuth, 'rad', 'deg').get + s.space.get.directionofRelativeNorth + model.getBuilding.northAxis
535
- absoluteAzimuth -= 360.0 until absoluteAzimuth < 360.0
536
-
537
- if facade == 'North'
538
- next if !((absoluteAzimuth >= 315.0) || (absoluteAzimuth < 45.0))
539
- elsif facade == 'East'
540
- next if !((absoluteAzimuth >= 45.0) && (absoluteAzimuth < 135.0))
541
- elsif facade == 'South'
542
- next if !((absoluteAzimuth >= 135.0) && (absoluteAzimuth < 225.0))
543
- elsif facade == 'West'
544
- next if !((absoluteAzimuth >= 225.0) && (absoluteAzimuth < 315.0))
545
- elsif facade == 'All'
546
- # no next needed
547
- else
548
- runner.registerError('Unexpected value of facade: ' + facade + '.')
549
- return false
550
- end
551
-
499
+ Functions.get_surfaces_or_subsurfaces_by_facade(model.getSurfaces, facade).sort.each do |s|
552
500
  # get surface area adjusting for zone multiplier
553
501
  space = s.space
554
502
  if !space.empty?
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.0</schema_version>
4
4
  <name>set_window_to_wall_ratio_by_facade</name>
5
5
  <uid>c567a0bf-a7d9-4a06-afe9-bf7df79e6bf8</uid>
6
- <version_id>aff8deeb-a011-4ad8-8c0d-22e736faa347</version_id>
7
- <version_modified>20210423T142511Z</version_modified>
6
+ <version_id>d0d69032-509b-4257-a4c5-74e0e4615cc4</version_id>
7
+ <version_modified>20220505T182928Z</version_modified>
8
8
  <xml_checksum>6DE831F7</xml_checksum>
9
9
  <class_name>SetWindowToWallRatioByFacade</class_name>
10
10
  <display_name>Set Window to Wall Ratio by Facade</display_name>
@@ -153,6 +153,15 @@ The measure doesn?t have any cost or lifecycle arguments, however If lifecycle o
153
153
  </choice>
154
154
  </choices>
155
155
  </argument>
156
+ <argument>
157
+ <name>triangulation_min_area</name>
158
+ <display_name>Triangulation Minimum Area (m^2)</display_name>
159
+ <description>Triangulated surfaces less than this will not be created.</description>
160
+ <type>Double</type>
161
+ <required>true</required>
162
+ <model_dependent>false</model_dependent>
163
+ <default_value>0.001</default_value>
164
+ </argument>
156
165
  </arguments>
157
166
  <outputs />
158
167
  <provenances />
@@ -212,17 +221,29 @@ The measure doesn?t have any cost or lifecycle arguments, however If lifecycle o
212
221
  <usage_type>readmeerb</usage_type>
213
222
  <checksum>232D0477</checksum>
214
223
  </file>
224
+ <file>
225
+ <filename>LICENSE.md</filename>
226
+ <filetype>md</filetype>
227
+ <usage_type>license</usage_type>
228
+ <checksum>A21A3ED2</checksum>
229
+ </file>
230
+ <file>
231
+ <filename>prototype_sec_sch.osm</filename>
232
+ <filetype>osm</filetype>
233
+ <usage_type>test</usage_type>
234
+ <checksum>581DA01B</checksum>
235
+ </file>
215
236
  <file>
216
237
  <filename>README.md</filename>
217
238
  <filetype>md</filetype>
218
239
  <usage_type>readme</usage_type>
219
- <checksum>C85B9D94</checksum>
240
+ <checksum>7FCCDC8E</checksum>
220
241
  </file>
221
242
  <file>
222
- <filename>LICENSE.md</filename>
223
- <filetype>md</filetype>
224
- <usage_type>license</usage_type>
225
- <checksum>A21A3ED2</checksum>
243
+ <filename>SetWindowToWallRatioByFacade_Test.rb</filename>
244
+ <filetype>rb</filetype>
245
+ <usage_type>test</usage_type>
246
+ <checksum>2FAF08A3</checksum>
226
247
  </file>
227
248
  <file>
228
249
  <version>
@@ -233,13 +254,13 @@ The measure doesn?t have any cost or lifecycle arguments, however If lifecycle o
233
254
  <filename>measure.rb</filename>
234
255
  <filetype>rb</filetype>
235
256
  <usage_type>script</usage_type>
236
- <checksum>DC3FE3CF</checksum>
257
+ <checksum>E1F85411</checksum>
237
258
  </file>
238
259
  <file>
239
- <filename>SetWindowToWallRatioByFacade_Test.rb</filename>
260
+ <filename>functions.rb</filename>
240
261
  <filetype>rb</filetype>
241
- <usage_type>test</usage_type>
242
- <checksum>23972ACF</checksum>
262
+ <usage_type>resource</usage_type>
263
+ <checksum>8AFBC32D</checksum>
243
264
  </file>
244
265
  </files>
245
266
  </measure>