openstudio-model-articulation 0.3.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -1
  3. data/CHANGELOG.md +28 -0
  4. data/Gemfile +6 -0
  5. data/Jenkinsfile +1 -0
  6. data/LICENSE.md +1 -1
  7. data/README.md +22 -3
  8. data/doc_templates/LICENSE.md +1 -1
  9. data/doc_templates/copyright_erb.txt +1 -1
  10. data/doc_templates/copyright_js.txt +1 -1
  11. data/doc_templates/copyright_ruby.txt +1 -1
  12. data/lib/measures/AssignConstructionSetToBuilding/LICENSE.md +1 -1
  13. data/lib/measures/AssignConstructionSetToBuilding/measure.rb +1 -1
  14. data/lib/measures/AssignConstructionSetToBuilding/measure.xml +16 -15
  15. data/lib/measures/AssignSpaceTypeBySpaceName/LICENSE.md +1 -1
  16. data/lib/measures/AssignSpaceTypeBySpaceName/measure.rb +1 -1
  17. data/lib/measures/AssignSpaceTypeBySpaceName/measure.xml +32 -13
  18. data/lib/measures/AssignSpaceTypeToBuilding/LICENSE.md +1 -1
  19. data/lib/measures/AssignSpaceTypeToBuilding/measure.rb +1 -1
  20. data/lib/measures/AssignSpaceTypeToBuilding/measure.xml +16 -15
  21. data/lib/measures/AssignSpacesToStories/LICENSE.md +1 -1
  22. data/lib/measures/AssignSpacesToStories/measure.rb +3 -5
  23. data/lib/measures/AssignSpacesToStories/measure.xml +14 -13
  24. data/lib/measures/BarAspectRatioStudy/LICENSE.md +1 -1
  25. data/lib/measures/BarAspectRatioStudy/measure.rb +3 -2
  26. data/lib/measures/BarAspectRatioStudy/measure.xml +8 -7
  27. data/lib/measures/CleanupSpaceOrigins/LICENSE.md +1 -1
  28. data/lib/measures/CleanupSpaceOrigins/measure.rb +4 -1
  29. data/lib/measures/CleanupSpaceOrigins/measure.xml +14 -13
  30. data/lib/measures/FindAndReplaceObjectNames/LICENSE.md +1 -1
  31. data/lib/measures/FindAndReplaceObjectNames/measure.rb +1 -1
  32. data/lib/measures/FindAndReplaceObjectNames/measure.xml +13 -12
  33. data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/LICENSE.md +1 -1
  34. data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/measure.rb +3 -3
  35. data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/measure.xml +28 -10
  36. data/lib/measures/RemoveHardAssignedConstructions/LICENSE.md +1 -1
  37. data/lib/measures/RemoveHardAssignedConstructions/measure.rb +1 -1
  38. data/lib/measures/RemoveHardAssignedConstructions/measure.xml +13 -12
  39. data/lib/measures/RenameSpaceSurfacesBasedonParentSpaceandOrientation/LICENSE.md +1 -1
  40. data/lib/measures/RenameSpaceSurfacesBasedonParentSpaceandOrientation/measure.rb +1 -1
  41. data/lib/measures/RenameSpaceSurfacesBasedonParentSpaceandOrientation/measure.xml +42 -11
  42. data/lib/measures/RotateBuilding/LICENSE.md +1 -1
  43. data/lib/measures/RotateBuilding/measure.rb +1 -1
  44. data/lib/measures/RotateBuilding/measure.xml +13 -12
  45. data/lib/measures/SetExtWallToGroundBoundaryConditionByStory/LICENSE.md +1 -1
  46. data/lib/measures/SetExtWallToGroundBoundaryConditionByStory/measure.rb +1 -1
  47. data/lib/measures/SetExtWallToGroundBoundaryConditionByStory/measure.xml +17 -10
  48. data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/LICENSE.md +1 -1
  49. data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/measure.rb +2 -2
  50. data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/measure.xml +13 -12
  51. data/lib/measures/SetInteriorWallsToSelectedConstruction/LICENSE.md +1 -1
  52. data/lib/measures/SetInteriorWallsToSelectedConstruction/measure.rb +2 -2
  53. data/lib/measures/SetInteriorWallsToSelectedConstruction/measure.xml +13 -12
  54. data/lib/measures/SetWindowToWallRatioByFacade/LICENSE.md +1 -1
  55. data/lib/measures/SetWindowToWallRatioByFacade/README.md +11 -0
  56. data/lib/measures/SetWindowToWallRatioByFacade/measure.rb +91 -143
  57. data/lib/measures/SetWindowToWallRatioByFacade/measure.xml +32 -11
  58. data/lib/measures/SetWindowToWallRatioByFacade/resources/functions.rb +176 -0
  59. data/lib/measures/SimplifyGeometryToSlicedBar/LICENSE.md +1 -1
  60. data/lib/measures/SimplifyGeometryToSlicedBar/measure.rb +9 -5
  61. data/lib/measures/SimplifyGeometryToSlicedBar/measure.xml +31 -13
  62. data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_cofee.rb +7 -5
  63. data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_geometry.rb +14 -9
  64. data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_helper_methods.rb +3 -5
  65. data/lib/measures/SpaceTypeAndConstructionSetWizard/LICENSE.md +1 -1
  66. data/lib/measures/SpaceTypeAndConstructionSetWizard/measure.rb +2 -2
  67. data/lib/measures/SpaceTypeAndConstructionSetWizard/measure.xml +63 -11
  68. data/lib/measures/SurfaceMatching/LICENSE.md +1 -1
  69. data/lib/measures/SurfaceMatching/measure.rb +2 -1
  70. data/lib/measures/SurfaceMatching/measure.xml +13 -12
  71. data/lib/measures/{BarAspectRatioSlicedBySpaceType → add_empd_material_properties}/LICENSE.md +1 -1
  72. data/lib/measures/add_empd_material_properties/README.md +116 -0
  73. data/lib/measures/{BarAspectRatioSlicedBySpaceType → add_empd_material_properties}/README.md.erb +0 -0
  74. data/lib/measures/add_empd_material_properties/docs/.gitkeep +0 -0
  75. data/lib/measures/add_empd_material_properties/measure.rb +247 -0
  76. data/lib/measures/add_empd_material_properties/measure.xml +201 -0
  77. data/lib/measures/blended_space_type_from_floor_area_ratios/LICENSE.md +1 -1
  78. data/lib/measures/blended_space_type_from_floor_area_ratios/measure.rb +5 -4
  79. data/lib/measures/blended_space_type_from_floor_area_ratios/measure.xml +5 -5
  80. data/lib/measures/blended_space_type_from_model/LICENSE.md +1 -1
  81. data/lib/measures/blended_space_type_from_model/{resources → docs}/replace_occupied_spaces_with_blended_space_type_design_doc.txt +0 -0
  82. data/lib/measures/blended_space_type_from_model/measure.rb +16 -4
  83. data/lib/measures/blended_space_type_from_model/measure.xml +16 -22
  84. data/lib/measures/clone_building_from_external_model/LICENSE.md +1 -1
  85. data/lib/measures/clone_building_from_external_model/measure.rb +1 -1
  86. data/lib/measures/clone_building_from_external_model/measure.xml +5 -5
  87. data/lib/measures/create_DOE_prototype_building/LICENSE.md +1 -1
  88. data/lib/measures/create_DOE_prototype_building/measure.rb +4 -3
  89. data/lib/measures/create_DOE_prototype_building/measure.xml +163 -27
  90. data/lib/measures/create_and_assign_thermal_zones_for_unassigned_spaces/LICENSE.md +1 -1
  91. data/lib/measures/create_and_assign_thermal_zones_for_unassigned_spaces/measure.rb +1 -1
  92. data/lib/measures/create_and_assign_thermal_zones_for_unassigned_spaces/measure.xml +5 -5
  93. data/lib/measures/create_bar_from_building_type_ratios/LICENSE.md +1 -1
  94. data/lib/measures/create_bar_from_building_type_ratios/README.md +109 -35
  95. data/lib/measures/create_bar_from_building_type_ratios/README.md.erb +54 -35
  96. data/lib/measures/create_bar_from_building_type_ratios/measure.rb +9 -4
  97. data/lib/measures/create_bar_from_building_type_ratios/measure.xml +124 -12
  98. data/lib/measures/create_bar_from_deer_building_type_ratios/LICENSE.md +1 -1
  99. data/lib/measures/create_bar_from_deer_building_type_ratios/README.md +301 -79
  100. data/lib/measures/create_bar_from_deer_building_type_ratios/README.md.erb +62 -79
  101. data/lib/measures/create_bar_from_deer_building_type_ratios/measure.rb +10 -5
  102. data/lib/measures/create_bar_from_deer_building_type_ratios/measure.xml +15 -59
  103. data/lib/measures/create_bar_from_doe_building_type_ratios/LICENSE.md +1 -1
  104. data/lib/measures/create_bar_from_doe_building_type_ratios/README.md +298 -57
  105. data/lib/measures/create_bar_from_doe_building_type_ratios/README.md.erb +54 -57
  106. data/lib/measures/create_bar_from_doe_building_type_ratios/measure.rb +10 -5
  107. data/lib/measures/create_bar_from_doe_building_type_ratios/measure.xml +122 -14
  108. data/lib/measures/create_bar_from_model/LICENSE.md +1 -1
  109. data/lib/measures/create_bar_from_model/measure.rb +11 -7
  110. data/lib/measures/create_bar_from_model/measure.xml +5 -5
  111. data/lib/measures/create_bar_from_space_type_ratios/LICENSE.md +27 -0
  112. data/lib/measures/create_bar_from_space_type_ratios/README.md +556 -0
  113. data/lib/measures/create_bar_from_space_type_ratios/README.md.erb +324 -0
  114. data/lib/measures/create_bar_from_space_type_ratios/docs/ar_05.png +0 -0
  115. data/lib/measures/create_bar_from_space_type_ratios/docs/ar_1.png +0 -0
  116. data/lib/measures/create_bar_from_space_type_ratios/docs/ar_2.png +0 -0
  117. data/lib/measures/create_bar_from_space_type_ratios/docs/bar_double_loaded.png +0 -0
  118. data/lib/measures/create_bar_from_space_type_ratios/docs/bar_single_core_perim.png +0 -0
  119. data/lib/measures/create_bar_from_space_type_ratios/docs/bar_sliced_indiv.png +0 -0
  120. data/lib/measures/create_bar_from_space_type_ratios/docs/bar_sliced_simple.png +0 -0
  121. data/lib/measures/create_bar_from_space_type_ratios/docs/basement.png +0 -0
  122. data/lib/measures/create_bar_from_space_type_ratios/docs/custom_height_false.png +0 -0
  123. data/lib/measures/create_bar_from_space_type_ratios/docs/custom_height_true.png +0 -0
  124. data/lib/measures/create_bar_from_space_type_ratios/docs/no_party_mult.png +0 -0
  125. data/lib/measures/create_bar_from_space_type_ratios/docs/party.png +0 -0
  126. data/lib/measures/create_bar_from_space_type_ratios/docs/party_multi.png +0 -0
  127. data/lib/measures/create_bar_from_space_type_ratios/docs/perim_mult_2010.png +0 -0
  128. data/lib/measures/create_bar_from_space_type_ratios/docs/perim_mult_2012.png +0 -0
  129. data/lib/measures/create_bar_from_space_type_ratios/docs/perim_mult_2020.png +0 -0
  130. data/lib/measures/create_bar_from_space_type_ratios/docs/sep_05.png +0 -0
  131. data/lib/measures/create_bar_from_space_type_ratios/docs/sep_10.png +0 -0
  132. data/lib/measures/create_bar_from_space_type_ratios/docs/sep_3.png +0 -0
  133. data/lib/measures/create_bar_from_space_type_ratios/docs/story_sort.png +0 -0
  134. data/lib/measures/create_bar_from_space_type_ratios/docs/wwr_custom.png +0 -0
  135. data/lib/measures/create_bar_from_space_type_ratios/measure.rb +314 -0
  136. data/lib/measures/create_bar_from_space_type_ratios/measure.xml +687 -0
  137. data/lib/measures/create_baseline_building/LICENSE.md +1 -1
  138. data/lib/measures/create_baseline_building/measure.rb +4 -3
  139. data/lib/measures/create_baseline_building/measure.xml +5 -5
  140. data/lib/measures/create_deer_prototype_building/LICENSE.md +1 -1
  141. data/lib/measures/create_deer_prototype_building/measure.rb +1 -1
  142. data/lib/measures/create_deer_prototype_building/measure.xml +6 -6
  143. data/lib/measures/create_deer_prototype_building/resources/deer_building_types.rb +1 -1
  144. data/lib/measures/create_parametric_schedules/LICENSE.md +1 -1
  145. data/lib/measures/create_parametric_schedules/measure.rb +16 -11
  146. data/lib/measures/create_parametric_schedules/measure.xml +5 -5
  147. data/lib/measures/create_typical_building_from_model/LICENSE.md +1 -1
  148. data/lib/measures/create_typical_building_from_model/README.md +82 -17
  149. data/lib/measures/create_typical_building_from_model/README.md.erb +36 -16
  150. data/lib/measures/create_typical_building_from_model/measure.rb +8 -6
  151. data/lib/measures/create_typical_building_from_model/measure.xml +59 -27
  152. data/lib/measures/create_typical_building_from_model/resources/Model.hvac.rb +8 -5
  153. data/lib/measures/create_typical_deer_building_from_model/LICENSE.md +1 -1
  154. data/lib/measures/create_typical_deer_building_from_model/README.md +173 -53
  155. data/lib/measures/create_typical_deer_building_from_model/README.md.erb +57 -53
  156. data/lib/measures/create_typical_deer_building_from_model/measure.rb +8 -3
  157. data/lib/measures/create_typical_deer_building_from_model/measure.xml +26 -26
  158. data/lib/measures/create_typical_deer_building_from_model/resources/Model.hvac.rb +8 -5
  159. data/lib/measures/create_typical_doe_building_from_model/LICENSE.md +1 -1
  160. data/lib/measures/create_typical_doe_building_from_model/README.md +182 -44
  161. data/lib/measures/create_typical_doe_building_from_model/README.md.erb +58 -44
  162. data/lib/measures/create_typical_doe_building_from_model/measure.rb +8 -3
  163. data/lib/measures/create_typical_doe_building_from_model/measure.xml +60 -28
  164. data/lib/measures/create_typical_doe_building_from_model/resources/Model.hvac.rb +8 -5
  165. data/lib/measures/deer_space_type_and_construction_set_wizard/LICENSE.md +1 -1
  166. data/lib/measures/deer_space_type_and_construction_set_wizard/measure.rb +2 -2
  167. data/lib/measures/deer_space_type_and_construction_set_wizard/measure.xml +17 -17
  168. data/lib/measures/find_and_replace_in_all_thermal_zone_names/LICENSE.md +1 -1
  169. data/lib/measures/find_and_replace_in_all_thermal_zone_names/measure.rb +1 -1
  170. data/lib/measures/find_and_replace_in_all_thermal_zone_names/measure.xml +8 -7
  171. data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/LICENSE.md +1 -1
  172. data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/measure.rb +3 -1
  173. data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/measure.xml +5 -5
  174. data/lib/measures/merge_floorspace_js_with_model/LICENSE.md +1 -1
  175. data/lib/measures/merge_floorspace_js_with_model/measure.rb +5 -2
  176. data/lib/measures/merge_floorspace_js_with_model/measure.xml +5 -5
  177. data/lib/measures/merge_spaces_from_external_file/LICENSE.md +1 -1
  178. data/lib/measures/merge_spaces_from_external_file/measure.rb +1 -1
  179. data/lib/measures/merge_spaces_from_external_file/measure.xml +6 -6
  180. data/lib/measures/merge_spaces_from_external_file/resources/ScheduleTranslator.rb +1 -1
  181. data/lib/measures/radiance_measure/LICENSE.md +1 -1
  182. data/lib/measures/radiance_measure/measure.rb +63 -57
  183. data/lib/measures/radiance_measure/measure.xml +11 -11
  184. data/lib/measures/radiant_slab_with_doas/LICENSE.md +1 -1
  185. data/lib/measures/radiant_slab_with_doas/measure.rb +9 -2
  186. data/lib/measures/radiant_slab_with_doas/measure.xml +10 -10
  187. data/lib/measures/replace_geometry_by_story/LICENSE.md +1 -1
  188. data/lib/measures/replace_geometry_by_story/measure.rb +5 -1
  189. data/lib/measures/replace_geometry_by_story/measure.xml +5 -5
  190. data/lib/measures/scale_geometry/LICENSE.md +1 -1
  191. data/lib/measures/scale_geometry/measure.rb +1 -1
  192. data/lib/measures/scale_geometry/measure.xml +5 -5
  193. data/lib/openstudio/model_articulation/extension.rb +1 -1
  194. data/lib/openstudio/model_articulation/version.rb +2 -2
  195. data/lib/openstudio/model_articulation.rb +1 -1
  196. data/lib/openstudio-model-articulation.rb +1 -1
  197. data/openstudio-model-articulation.gemspec +3 -3
  198. metadata +42 -16
  199. data/lib/measures/BarAspectRatioSlicedBySpaceType/README.md +0 -64
  200. data/lib/measures/BarAspectRatioSlicedBySpaceType/measure.rb +0 -184
  201. data/lib/measures/BarAspectRatioSlicedBySpaceType/measure.xml +0 -130
  202. data/lib/measures/BarAspectRatioSlicedBySpaceType/resources/os_lib_cofee.rb +0 -252
  203. data/lib/measures/blended_space_type_from_model/resources/os_lib_model_simplification.rb +0 -1049
@@ -1,9 +1,10 @@
1
+ <?xml version="1.0"?>
1
2
  <measure>
2
3
  <schema_version>3.0</schema_version>
3
4
  <name>set_interior_walls_to_selected_construction</name>
4
5
  <uid>e3d59d0d-1ce8-4cb2-ae59-001f0fa2ac46</uid>
5
- <version_id>01d5fe6b-b17f-4cf5-8fb7-c510611e4257</version_id>
6
- <version_modified>20200229T024052Z</version_modified>
6
+ <version_id>bb0dd052-2f62-49ef-8e20-2e9c39786802</version_id>
7
+ <version_modified>20220505T182927Z</version_modified>
7
8
  <xml_checksum>1E963D9C</xml_checksum>
8
9
  <class_name>SetInteriorWallsToSelectedConstruction</class_name>
9
10
  <display_name>SetInteriorWallsToSelectedConstruction</display_name>
@@ -18,8 +19,8 @@
18
19
  <model_dependent>false</model_dependent>
19
20
  </argument>
20
21
  </arguments>
21
- <outputs/>
22
- <provenances/>
22
+ <outputs />
23
+ <provenances />
23
24
  <tags>
24
25
  <tag>Envelope.Opaque</tag>
25
26
  </tags>
@@ -54,6 +55,12 @@
54
55
  <usage_type>readme</usage_type>
55
56
  <checksum>C8974F9D</checksum>
56
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>
57
64
  <file>
58
65
  <version>
59
66
  <software_program>OpenStudio</software_program>
@@ -63,19 +70,13 @@
63
70
  <filename>measure.rb</filename>
64
71
  <filetype>rb</filetype>
65
72
  <usage_type>script</usage_type>
66
- <checksum>934DE430</checksum>
73
+ <checksum>DC3C3C85</checksum>
67
74
  </file>
68
75
  <file>
69
76
  <filename>SetInteriorWallstoSelectedConstruction_Test.rb</filename>
70
77
  <filetype>rb</filetype>
71
78
  <usage_type>test</usage_type>
72
- <checksum>AAF34E3E</checksum>
73
- </file>
74
- <file>
75
- <filename>LICENSE.md</filename>
76
- <filetype>md</filetype>
77
- <usage_type>license</usage_type>
78
- <checksum>E0468DD6</checksum>
79
+ <checksum>17B7EFF1</checksum>
79
80
  </file>
80
81
  </files>
81
82
  </measure>
@@ -1,4 +1,4 @@
1
- OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. All rights reserved.
1
+ OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC. All rights reserved.
2
2
 
3
3
  Redistribution and use in source and binary forms, with or without modification, are permitted
4
4
  provided that the following conditions are met:
@@ -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
 
@@ -1,5 +1,5 @@
1
1
  # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
2
+ # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
3
3
  # All rights reserved.
4
4
  # Redistribution and use in source and binary forms, with or without
5
5
  # modification, are permitted provided that the following conditions are met:
@@ -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>ba8a1d2e-0d49-4e86-9aba-f4d55097f358</version_id>
7
- <version_modified>20200928T200703Z</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>E0468DD6</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>CB9895D2</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>268FC2B7</checksum>
262
+ <usage_type>resource</usage_type>
263
+ <checksum>8AFBC32D</checksum>
243
264
  </file>
244
265
  </files>
245
266
  </measure>
@@ -0,0 +1,176 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ require 'openstudio'
37
+
38
+ module Functions
39
+ # return an array of surfaces or subsurfaces from a specific facade.
40
+ def self.get_surfaces_or_subsurfaces_by_facade(surfaces_or_subsurfaces, facade)
41
+ surfaces_or_subsurfaces_by_facade = []
42
+
43
+ surfaces_or_subsurfaces.each do |surface_or_subsurface|
44
+ case surface_or_subsurface.class.to_s.gsub('OpenStudio::Model::', '')
45
+ when 'Surface'
46
+ next if surface_or_subsurface.surfaceType != 'Wall'
47
+ next if surface_or_subsurface.outsideBoundaryCondition != 'Outdoors'
48
+
49
+ if surface_or_subsurface.space.empty?
50
+ runner.registerWarning("#{surface_or_subsurface.name} doesn't have a parent space and won't be included in the measure reporting or modifications.")
51
+ next
52
+ end
53
+ direction_of_relative_north = surface_or_subsurface.space.get.directionofRelativeNorth
54
+ when 'SubSurface'
55
+ next if surface_or_subsurface.subSurfaceType == 'Door' || surface_or_subsurface.subSurfaceType == 'OverheadDoor'
56
+
57
+ direction_of_relative_north = surface_or_subsurface.surface.get.space.get.directionofRelativeNorth
58
+ end
59
+
60
+ # get the absoluteAzimuth for the surface so we can categorize it
61
+ absoluteAzimuth = OpenStudio.convert(surface_or_subsurface.azimuth, 'rad', 'deg').get + direction_of_relative_north + surface_or_subsurface.model.getBuilding.northAxis
62
+ absoluteAzimuth -= 360.0 until absoluteAzimuth < 360.0
63
+
64
+ case facade
65
+ when 'North'
66
+ next if !((absoluteAzimuth >= 315.0) || (absoluteAzimuth < 45.0))
67
+ when 'East'
68
+ next if !((absoluteAzimuth >= 45.0) && (absoluteAzimuth < 135.0))
69
+ when 'South'
70
+ next if !((absoluteAzimuth >= 135.0) && (absoluteAzimuth < 225.0))
71
+ when 'West'
72
+ next if !((absoluteAzimuth >= 225.0) && (absoluteAzimuth < 315.0))
73
+ when 'All'
74
+ # no next needed
75
+ else
76
+ runner.registerError("Unexpected value of facade: #{facade}.")
77
+ return false
78
+ end
79
+
80
+ surfaces_or_subsurfaces_by_facade << surface_or_subsurface
81
+ end
82
+
83
+ return surfaces_or_subsurfaces_by_facade
84
+ end
85
+
86
+ # return a hash of subsurface constructions.
87
+ def self.get_orig_sub_surf_const_for_target(subsurfaces)
88
+ orig_sub_surf_const_for_target = {}
89
+
90
+ subsurfaces.each do |subsurface|
91
+ next if subsurface.subSurfaceType == 'Door' || subsurface.subSurfaceType == 'OverheadDoor'
92
+
93
+ if subsurface.construction.is_initialized
94
+ if orig_sub_surf_const_for_target.key?(subsurface.construction.get)
95
+ orig_sub_surf_const_for_target[subsurface.construction.get] += 1
96
+ else
97
+ orig_sub_surf_const_for_target[subsurface.construction.get] = 1
98
+ end
99
+ end
100
+ end
101
+
102
+ return orig_sub_surf_const_for_target
103
+ end
104
+
105
+ # see if surface is rectangular (only checking non rotated on vertical wall)
106
+ # todo - add in more robust rectangle check that can look for rotate and tilted rectangles
107
+ def self.rectangle?(surface)
108
+ x_vals = []
109
+ y_vals = []
110
+ z_vals = []
111
+ vertices = surface.vertices
112
+ vertices.each do |vertex|
113
+ # initialize new vertex to old vertex
114
+ # rounding values to address tolerance issue 10 digits digits in
115
+ x_vals << vertex.x.round(4)
116
+ y_vals << vertex.y.round(4)
117
+ z_vals << vertex.z.round(4)
118
+ end
119
+ if x_vals.uniq.size <= 2 && y_vals.uniq.size <= 2 && z_vals.uniq.size <= 2
120
+ return true
121
+ else
122
+ return false
123
+ end
124
+ end
125
+
126
+ # return true if the requested window-to-wall area exceeds the maximum allowed area, false if not.
127
+ # implements the following part of the applyViewAndDaylightingGlassRatios method, which is what setWindowToWallRatio uses.
128
+ # https://github.com/NREL/OpenStudio/blob/760613c7ac9c2093f7dbd65f947a6853356c558d/src/utilities/geometry/Geometry.cpp#L605-L695
129
+ def self.requested_window_area_greater_than_max?(surface, viewGlassToWallRatio)
130
+ daylightingGlassToWallRatio = 0
131
+ totalWWR = viewGlassToWallRatio + daylightingGlassToWallRatio
132
+
133
+ vertices = surface.vertices
134
+ transformation = OpenStudio::Transformation.alignFace(vertices)
135
+ faceVertices = transformation.inverse * vertices
136
+
137
+ # // new coordinate system has z' in direction of outward normal, y' is up
138
+ xmin = 0
139
+ xmax = 0
140
+ ymin = 0
141
+ ymax = 0
142
+ faceVertices.each do |faceVertex|
143
+ xmin = [xmin, faceVertex.x].min
144
+ xmax = [xmax, faceVertex.x].max
145
+ ymin = [ymin, faceVertex.y].min
146
+ ymax = [ymax, faceVertex.y].max
147
+ end
148
+
149
+ oneInch = 0.0254 # meters
150
+
151
+ # // DLM: preserve a 1" gap between window and edge to keep SketchUp happy
152
+ minGlassToEdgeDistance = oneInch
153
+ minViewToDaylightDistance = 0
154
+
155
+ # // wall parameters
156
+ wallWidth = xmax - xmin
157
+ wallHeight = ymax - ymin
158
+ wallArea = wallWidth * wallHeight
159
+
160
+ # return false if wallWidth < 2 * minGlassToEdgeDistance
161
+
162
+ # return false if wallHeight < 2 * minGlassToEdgeDistance + minViewToDaylightDistance
163
+
164
+ maxWindowArea = wallArea - 2 * wallHeight * minGlassToEdgeDistance
165
+ - (wallWidth - 2 * minGlassToEdgeDistance) * (2 * minGlassToEdgeDistance + minViewToDaylightDistance)
166
+ requestedViewArea = viewGlassToWallRatio * wallArea
167
+ requestedDaylightingArea = daylightingGlassToWallRatio * wallArea
168
+ requestedTotalWindowArea = totalWWR * wallArea
169
+
170
+ if requestedTotalWindowArea > maxWindowArea
171
+ return true
172
+ else
173
+ return false
174
+ end
175
+ end
176
+ end
@@ -1,4 +1,4 @@
1
- OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. All rights reserved.
1
+ OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC. All rights reserved.
2
2
 
3
3
  Redistribution and use in source and binary forms, with or without modification, are permitted
4
4
  provided that the following conditions are met: