openstudio-model-articulation 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -2
- data/CHANGELOG.md +8 -0
- data/README.md +8 -3
- data/lib/measures/AssignConstructionSetToBuilding/measure.xml +10 -10
- data/lib/measures/AssignSpaceTypeBySpaceName/measure.xml +27 -9
- data/lib/measures/AssignSpaceTypeToBuilding/measure.xml +10 -10
- data/lib/measures/AssignSpacesToStories/measure.rb +2 -4
- data/lib/measures/AssignSpacesToStories/measure.xml +10 -10
- data/lib/measures/BarAspectRatioStudy/measure.rb +2 -1
- data/lib/measures/BarAspectRatioStudy/measure.xml +4 -4
- data/lib/measures/CleanupSpaceOrigins/measure.rb +3 -0
- data/lib/measures/CleanupSpaceOrigins/measure.xml +10 -10
- data/lib/measures/FindAndReplaceObjectNames/measure.xml +8 -8
- data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/measure.rb +2 -2
- data/lib/measures/InjectOsmGeometryIntoAnExternalIdf/measure.xml +22 -4
- data/lib/measures/RemoveHardAssignedConstructions/measure.xml +8 -8
- data/lib/measures/RenameSpaceSurfacesBasedonParentSpaceandOrientation/measure.xml +37 -7
- data/lib/measures/RotateBuilding/measure.xml +8 -8
- data/lib/measures/SetExtWallToGroundBoundaryConditionByStory/measure.xml +13 -7
- data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/measure.rb +1 -1
- data/lib/measures/SetInteriorWallsAndFloorsToAdiabatic/measure.xml +10 -10
- data/lib/measures/SetInteriorWallsToSelectedConstruction/measure.rb +1 -1
- data/lib/measures/SetInteriorWallsToSelectedConstruction/measure.xml +10 -10
- data/lib/measures/SetWindowToWallRatioByFacade/README.md +11 -0
- data/lib/measures/SetWindowToWallRatioByFacade/measure.rb +84 -143
- data/lib/measures/SetWindowToWallRatioByFacade/measure.xml +32 -17
- data/lib/measures/SetWindowToWallRatioByFacade/resources/functions.rb +176 -0
- data/lib/measures/SimplifyGeometryToSlicedBar/measure.rb +8 -4
- data/lib/measures/SimplifyGeometryToSlicedBar/measure.xml +31 -13
- data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_cofee.rb +6 -4
- data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_geometry.rb +13 -8
- data/lib/measures/SimplifyGeometryToSlicedBar/resources/os_lib_helper_methods.rb +2 -4
- data/lib/measures/SpaceTypeAndConstructionSetWizard/measure.rb +1 -1
- data/lib/measures/SpaceTypeAndConstructionSetWizard/measure.xml +4 -4
- data/lib/measures/SurfaceMatching/measure.rb +1 -0
- data/lib/measures/SurfaceMatching/measure.xml +10 -10
- data/lib/measures/blended_space_type_from_floor_area_ratios/measure.rb +4 -3
- data/lib/measures/blended_space_type_from_floor_area_ratios/measure.xml +4 -4
- data/lib/measures/blended_space_type_from_model/{resources → docs}/replace_occupied_spaces_with_blended_space_type_design_doc.txt +0 -0
- data/lib/measures/blended_space_type_from_model/measure.rb +15 -3
- data/lib/measures/blended_space_type_from_model/measure.xml +15 -21
- data/lib/measures/clone_building_from_external_model/measure.xml +3 -3
- data/lib/measures/create_DOE_prototype_building/measure.rb +2 -2
- data/lib/measures/create_DOE_prototype_building/measure.xml +442 -438
- data/lib/measures/create_and_assign_thermal_zones_for_unassigned_spaces/measure.xml +3 -3
- data/lib/measures/create_bar_from_building_type_ratios/measure.rb +3 -3
- data/lib/measures/create_bar_from_building_type_ratios/measure.xml +14 -14
- data/lib/measures/create_bar_from_deer_building_type_ratios/measure.rb +3 -3
- data/lib/measures/create_bar_from_deer_building_type_ratios/measure.xml +16 -16
- data/lib/measures/create_bar_from_doe_building_type_ratios/measure.rb +3 -3
- data/lib/measures/create_bar_from_doe_building_type_ratios/measure.xml +14 -14
- data/lib/measures/create_bar_from_model/measure.rb +10 -6
- data/lib/measures/create_bar_from_model/measure.xml +4 -4
- data/lib/measures/create_bar_from_space_type_ratios/measure.rb +3 -3
- data/lib/measures/create_bar_from_space_type_ratios/measure.xml +16 -16
- data/lib/measures/create_baseline_building/measure.rb +3 -2
- data/lib/measures/create_baseline_building/measure.xml +4 -4
- data/lib/measures/create_deer_prototype_building/measure.xml +3 -3
- data/lib/measures/create_parametric_schedules/measure.rb +15 -10
- data/lib/measures/create_parametric_schedules/measure.xml +4 -4
- data/lib/measures/create_typical_building_from_model/measure.rb +1 -1
- data/lib/measures/create_typical_building_from_model/measure.xml +21 -21
- data/lib/measures/create_typical_deer_building_from_model/measure.rb +1 -1
- data/lib/measures/create_typical_deer_building_from_model/measure.xml +21 -21
- data/lib/measures/create_typical_doe_building_from_model/measure.rb +1 -1
- data/lib/measures/create_typical_doe_building_from_model/measure.xml +21 -21
- data/lib/measures/deer_space_type_and_construction_set_wizard/measure.rb +1 -1
- data/lib/measures/deer_space_type_and_construction_set_wizard/measure.xml +4 -4
- data/lib/measures/find_and_replace_in_all_thermal_zone_names/measure.xml +3 -3
- data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/measure.rb +2 -0
- data/lib/measures/make_shading_surfaces_based_on_zone_multipliers/measure.xml +4 -4
- data/lib/measures/merge_floorspace_js_with_model/measure.rb +4 -1
- data/lib/measures/merge_floorspace_js_with_model/measure.xml +4 -4
- data/lib/measures/merge_spaces_from_external_file/measure.xml +3 -3
- data/lib/measures/radiance_measure/measure.rb +62 -56
- data/lib/measures/radiance_measure/measure.xml +4 -4
- data/lib/measures/radiant_slab_with_doas/measure.rb +4 -1
- data/lib/measures/radiant_slab_with_doas/measure.xml +4 -4
- data/lib/measures/replace_geometry_by_story/measure.rb +4 -0
- data/lib/measures/replace_geometry_by_story/measure.xml +4 -4
- data/lib/measures/scale_geometry/measure.xml +3 -3
- data/lib/openstudio/model_articulation/version.rb +1 -1
- data/openstudio-model-articulation.gemspec +1 -1
- metadata +7 -7
- 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>set_ext_wall_to_ground_boundary_condition_by_story</name>
|
5
5
|
<uid>a6da6f2b-2d07-4d25-b2b4-4b1dd62df237</uid>
|
6
|
-
<version_id>
|
7
|
-
<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>
|
89
|
+
<checksum>43480F51</checksum>
|
84
90
|
</file>
|
85
91
|
<file>
|
86
|
-
<filename>
|
87
|
-
<filetype>
|
88
|
-
<usage_type>
|
89
|
-
<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| #
|
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>
|
7
|
-
<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>
|
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>
|
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| #
|
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>
|
7
|
-
<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>
|
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>
|
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
|
-
|
205
|
-
|
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
|
-
|
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
|
@@ -320,7 +266,8 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
320
266
|
|
321
267
|
# remove windows before split at doors
|
322
268
|
s.subSurfaces.each do |sub_surface|
|
323
|
-
next if ['Door','OverheadDoor'].include? sub_surface.subSurfaceType
|
269
|
+
next if ['Door', 'OverheadDoor'].include? sub_surface.subSurfaceType
|
270
|
+
|
324
271
|
sub_surface.remove
|
325
272
|
end
|
326
273
|
|
@@ -339,22 +286,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
339
286
|
all_surfaces.sort.each do |ss|
|
340
287
|
# see if surface is rectangular (only checking non rotated on vertical wall)
|
341
288
|
# todo - add in more robust rectangle check that can look for rotate and tilted rectangles
|
342
|
-
rect_tri =
|
343
|
-
x_vals = []
|
344
|
-
y_vals = []
|
345
|
-
z_vals = []
|
346
|
-
vertices = ss.vertices
|
347
|
-
flag = false
|
348
|
-
vertices.each do |vertex|
|
349
|
-
# initialize new vertex to old vertex
|
350
|
-
# rounding values to address tolerance issue 10 digits digits in
|
351
|
-
x_vals << vertex.x.round(4)
|
352
|
-
y_vals << vertex.y.round(4)
|
353
|
-
z_vals << vertex.z.round(4)
|
354
|
-
end
|
355
|
-
if x_vals.uniq.size <= 2 && y_vals.uniq.size <= 2 && z_vals.uniq.size <= 2
|
356
|
-
rect_tri = true
|
357
|
-
end
|
289
|
+
rect_tri = Functions.rectangle?(ss)
|
358
290
|
|
359
291
|
has_doors = false
|
360
292
|
ss.subSurfaces.sort.each do |subSurface|
|
@@ -384,8 +316,14 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
384
316
|
subSurface.remove
|
385
317
|
end
|
386
318
|
|
319
|
+
# triangulate surface
|
387
320
|
ss.triangulation.each do |tri|
|
388
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
|
389
327
|
new_surface.setSpace(ss.space.get)
|
390
328
|
if ss.construction.is_initialized && !ss.isConstructionDefaulted
|
391
329
|
new_surface.setConstruction(ss.construction.get)
|
@@ -409,6 +347,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
409
347
|
orig_sub_surf_constructions = {}
|
410
348
|
ss.subSurfaces.sort.each do |sub_surf|
|
411
349
|
next if sub_surf.subSurfaceType == 'Door' || sub_surf.subSurfaceType == 'OverheadDoor'
|
350
|
+
|
412
351
|
if sub_surf.construction.is_initialized
|
413
352
|
if orig_sub_surf_constructions.key?(sub_surf.construction.get)
|
414
353
|
orig_sub_surf_constructions[sub_surf.construction.get] += 1
|
@@ -432,38 +371,35 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
432
371
|
if wwr > 0 && new_window.empty?
|
433
372
|
|
434
373
|
# if new window is empty then inset base surface to add window (check may need to skip on base surfaces with doors)
|
435
|
-
if
|
436
|
-
|
437
|
-
#
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
z = (vertex.z * scale + z_cent * (1.0 - scale))
|
453
|
-
new_vertices << OpenStudio::Point3d.new(x, y, z)
|
454
|
-
end
|
455
|
-
|
456
|
-
# create inset window
|
457
|
-
new_window = OpenStudio::Model::SubSurface.new(new_vertices, model)
|
458
|
-
new_window.setSurface(ss)
|
459
|
-
new_window.setSubSurfaceType('FixedWindow')
|
460
|
-
if non_rect_parent.key?(ss)
|
461
|
-
new_window.setConstruction(non_rect_parent[ss])
|
462
|
-
end
|
463
|
-
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)
|
464
391
|
end
|
465
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
|
466
401
|
end
|
402
|
+
|
467
403
|
else
|
468
404
|
if wwr > 0
|
469
405
|
new_window = new_window.get
|
@@ -472,7 +408,38 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
472
408
|
end
|
473
409
|
|
474
410
|
if !window_confirmed
|
475
|
-
|
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
|
476
443
|
end
|
477
444
|
|
478
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.
|
@@ -529,33 +496,7 @@ class SetWindowToWallRatioByFacade < OpenStudio::Measure::ModelMeasure
|
|
529
496
|
end
|
530
497
|
|
531
498
|
# data for final condition wwr
|
532
|
-
|
533
|
-
next if s.surfaceType != 'Wall'
|
534
|
-
next if s.outsideBoundaryCondition != 'Outdoors'
|
535
|
-
if s.space.empty?
|
536
|
-
runner.registerWarning("#{s.name} doesn't have a parent space and won't be included in the measure reporting or modifications.")
|
537
|
-
next
|
538
|
-
end
|
539
|
-
|
540
|
-
# get the absoluteAzimuth for the surface so we can categorize it
|
541
|
-
absoluteAzimuth = OpenStudio.convert(s.azimuth, 'rad', 'deg').get + s.space.get.directionofRelativeNorth + model.getBuilding.northAxis
|
542
|
-
absoluteAzimuth -= 360.0 until absoluteAzimuth < 360.0
|
543
|
-
|
544
|
-
if facade == 'North'
|
545
|
-
next if !((absoluteAzimuth >= 315.0) || (absoluteAzimuth < 45.0))
|
546
|
-
elsif facade == 'East'
|
547
|
-
next if !((absoluteAzimuth >= 45.0) && (absoluteAzimuth < 135.0))
|
548
|
-
elsif facade == 'South'
|
549
|
-
next if !((absoluteAzimuth >= 135.0) && (absoluteAzimuth < 225.0))
|
550
|
-
elsif facade == 'West'
|
551
|
-
next if !((absoluteAzimuth >= 225.0) && (absoluteAzimuth < 315.0))
|
552
|
-
elsif facade == 'All'
|
553
|
-
# no next needed
|
554
|
-
else
|
555
|
-
runner.registerError('Unexpected value of facade: ' + facade + '.')
|
556
|
-
return false
|
557
|
-
end
|
558
|
-
|
499
|
+
Functions.get_surfaces_or_subsurfaces_by_facade(model.getSurfaces, facade).sort.each do |s|
|
559
500
|
# get surface area adjusting for zone multiplier
|
560
501
|
space = s.space
|
561
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>
|
7
|
-
<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>
|
240
|
+
<checksum>7FCCDC8E</checksum>
|
220
241
|
</file>
|
221
242
|
<file>
|
222
|
-
<filename>
|
223
|
-
<filetype>
|
224
|
-
<usage_type>
|
225
|
-
<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,19 +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>
|
257
|
+
<checksum>E1F85411</checksum>
|
237
258
|
</file>
|
238
259
|
<file>
|
239
|
-
<filename>
|
260
|
+
<filename>functions.rb</filename>
|
240
261
|
<filetype>rb</filetype>
|
241
|
-
<usage_type>
|
242
|
-
<checksum>
|
243
|
-
</file>
|
244
|
-
<file>
|
245
|
-
<filename>prototype_sec_sch.osm</filename>
|
246
|
-
<filetype>osm</filetype>
|
247
|
-
<usage_type>test</usage_type>
|
248
|
-
<checksum>581DA01B</checksum>
|
262
|
+
<usage_type>resource</usage_type>
|
263
|
+
<checksum>8AFBC32D</checksum>
|
249
264
|
</file>
|
250
265
|
</files>
|
251
266
|
</measure>
|