openstudio-extension 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +36 -1
- data/Gemfile +0 -2
- data/README.md +10 -5
- data/Rakefile +1 -3
- data/bin/console +0 -1
- data/lib/change_log.rb +138 -129
- data/lib/measures/openstudio_extension_test_measure/measure.rb +0 -2
- data/lib/measures/openstudio_extension_test_measure/measure.xml +20 -19
- data/lib/openstudio-extension.rb +0 -2
- data/lib/openstudio/extension.rb +24 -4
- data/lib/openstudio/extension/core/os_lib_geometry.rb +3 -3
- data/lib/openstudio/extension/core/os_lib_hvac.rb +17 -17
- data/lib/openstudio/extension/core/os_lib_model_generation.rb +85 -48
- data/lib/openstudio/extension/core/os_lib_model_simplification.rb +9 -9
- data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +2 -2
- data/lib/openstudio/extension/rake_task.rb +232 -20
- data/lib/openstudio/extension/runner.rb +25 -15
- data/lib/openstudio/extension/runner_config.rb +4 -4
- data/lib/openstudio/extension/version.rb +1 -3
- data/openstudio-extension.gemspec +5 -6
- metadata +30 -18
- data/lib/measures/openstudio_extension_test_measure/tests/openstudio_extension_test_measure_test.rb +0 -76
- data/lib/openstudio/extension/core/os_lib_reporting.rb +0 -4755
data/lib/openstudio-extension.rb
CHANGED
data/lib/openstudio/extension.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# *******************************************************************************
|
4
2
|
# OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
|
5
3
|
# All rights reserved.
|
@@ -93,6 +91,7 @@ module OpenStudio
|
|
93
91
|
|
94
92
|
result << obj
|
95
93
|
end
|
94
|
+
|
96
95
|
return result.uniq
|
97
96
|
end
|
98
97
|
|
@@ -107,7 +106,7 @@ module OpenStudio
|
|
107
106
|
result << dir if dir
|
108
107
|
rescue StandardError
|
109
108
|
end
|
110
|
-
return result.uniq
|
109
|
+
return result.uniq.sort
|
111
110
|
end
|
112
111
|
|
113
112
|
##
|
@@ -121,7 +120,7 @@ module OpenStudio
|
|
121
120
|
result << dir if dir
|
122
121
|
rescue StandardError
|
123
122
|
end
|
124
|
-
return result.uniq
|
123
|
+
return result.uniq.sort
|
125
124
|
end
|
126
125
|
|
127
126
|
##
|
@@ -228,5 +227,26 @@ module OpenStudio
|
|
228
227
|
|
229
228
|
return osw
|
230
229
|
end
|
230
|
+
|
231
|
+
##
|
232
|
+
# Module method used to check whether a measure is present in an OSW file
|
233
|
+
##
|
234
|
+
# @param [Hash] in_osw Initial OSW object as a Hash, keys should be symbolized
|
235
|
+
# @param [String] measure_dir_name Directory name of measure to set argument on
|
236
|
+
# @param [String] step_name Optional argument, if present used to further identify the measure
|
237
|
+
#
|
238
|
+
# @return [Boolean] true or false
|
239
|
+
def self.measure_in_osw(osw, measure_dir_name, step_name = nil)
|
240
|
+
result = false
|
241
|
+
osw[:steps].each do |step|
|
242
|
+
if step[:measure_dir_name] == measure_dir_name
|
243
|
+
if step_name.nil? || step[:name] == step_name
|
244
|
+
result = true
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
return result
|
250
|
+
end
|
231
251
|
end
|
232
252
|
end
|
@@ -765,7 +765,7 @@ module OsLib_Geometry
|
|
765
765
|
story_hash.each_with_index do |(story_name, story_data), index|
|
766
766
|
# make new story unless story at requested height already exists.
|
767
767
|
story = nil
|
768
|
-
model.getBuildingStorys.each do |ext_story|
|
768
|
+
model.getBuildingStorys.sort.each do |ext_story|
|
769
769
|
if (ext_story.nominalZCoordinate.to_f - story_data[:space_origin_z].to_f).abs < 0.01
|
770
770
|
story = ext_story
|
771
771
|
end
|
@@ -1133,11 +1133,11 @@ module OsLib_Geometry
|
|
1133
1133
|
# todo - also odd with multi-height spaces
|
1134
1134
|
def self.calculate_perimeter(model)
|
1135
1135
|
perimeter = 0
|
1136
|
-
model.getSpaces.each do |space|
|
1136
|
+
model.getSpaces.sort.each do |space|
|
1137
1137
|
# counter to use later
|
1138
1138
|
edge_hash = {}
|
1139
1139
|
edge_counter = 0
|
1140
|
-
space.surfaces.each do |surface|
|
1140
|
+
space.surfaces.sort.each do |surface|
|
1141
1141
|
# get vertices
|
1142
1142
|
vertex_hash = {}
|
1143
1143
|
vertex_counter = 0
|
@@ -117,7 +117,7 @@ module OsLib_HVAC
|
|
117
117
|
zonesUnconditioned = []
|
118
118
|
|
119
119
|
# get thermal zones
|
120
|
-
zones = model.getThermalZones
|
120
|
+
zones = model.getThermalZones.sort
|
121
121
|
zones.each do |zone|
|
122
122
|
# assign appropriate zones to zonesPlenum or zonesUnconditioned (those that don't have thermostats or zone HVAC equipment)
|
123
123
|
# if not conditioned then add to zonesPlenum or zonesUnconditioned
|
@@ -177,9 +177,9 @@ module OsLib_HVAC
|
|
177
177
|
|
178
178
|
def self.reportConditions(model, runner, condition,extra_string = '')
|
179
179
|
|
180
|
-
airloops = model.getAirLoopHVACs
|
181
|
-
plantLoops = model.getPlantLoops
|
182
|
-
zones = model.getThermalZones
|
180
|
+
airloops = model.getAirLoopHVACs.sort
|
181
|
+
plantLoops = model.getPlantLoops.sort
|
182
|
+
zones = model.getThermalZones.sort
|
183
183
|
|
184
184
|
# count up zone equipment (not counting zone exhaust fans)
|
185
185
|
zoneHasEquip = false
|
@@ -205,9 +205,9 @@ module OsLib_HVAC
|
|
205
205
|
end
|
206
206
|
|
207
207
|
def self.removeEquipment(model, runner)
|
208
|
-
airloops = model.getAirLoopHVACs
|
209
|
-
plantLoops = model.getPlantLoops
|
210
|
-
zones = model.getThermalZones
|
208
|
+
airloops = model.getAirLoopHVACs.sort
|
209
|
+
plantLoops = model.getPlantLoops.sort
|
210
|
+
zones = model.getThermalZones.sort
|
211
211
|
|
212
212
|
# remove all airloops
|
213
213
|
airloops.each(&:remove)
|
@@ -244,7 +244,7 @@ module OsLib_HVAC
|
|
244
244
|
require "#{File.dirname(__FILE__)}/os_lib_schedules"
|
245
245
|
|
246
246
|
schedulesHVAC = {}
|
247
|
-
airloops = model.getAirLoopHVACs
|
247
|
+
airloops = model.getAirLoopHVACs.sort
|
248
248
|
|
249
249
|
# find airloop with most primary spaces
|
250
250
|
max_primary_spaces = 0
|
@@ -628,7 +628,7 @@ module OsLib_HVAC
|
|
628
628
|
|
629
629
|
# check for water-cooled chillers
|
630
630
|
waterCooledChiller = false
|
631
|
-
model.getChillerElectricEIRs.each do |chiller|
|
631
|
+
model.getChillerElectricEIRs.sort.each do |chiller|
|
632
632
|
next if waterCooledChiller == true
|
633
633
|
if chiller.condenserType == 'WaterCooled'
|
634
634
|
waterCooledChiller = true
|
@@ -678,7 +678,7 @@ module OsLib_HVAC
|
|
678
678
|
pipe_supply_outlet.addToNode(condenser_loop.supplyOutletNode)
|
679
679
|
setpoint_manager_follow_oa.addToNode(condenser_loop.supplyOutletNode)
|
680
680
|
# demand side components
|
681
|
-
model.getChillerElectricEIRs.each do |chiller|
|
681
|
+
model.getChillerElectricEIRs.sort.each do |chiller|
|
682
682
|
if chiller.condenserType == 'WaterCooled' # works only if chillers not already connected to condenser loop(s)
|
683
683
|
condenser_loop.addDemandBranchForComponent(chiller)
|
684
684
|
end
|
@@ -771,7 +771,7 @@ module OsLib_HVAC
|
|
771
771
|
primary_airloops = []
|
772
772
|
# create primary airloop for each story
|
773
773
|
assignedThermalZones = []
|
774
|
-
model.getBuildingStorys.each do |building_story|
|
774
|
+
model.getBuildingStorys.sort.each do |building_story|
|
775
775
|
# ML stories need to be reordered from the ground up
|
776
776
|
thermalZonesToAdd = []
|
777
777
|
building_story.spaces.each do |space|
|
@@ -1069,7 +1069,7 @@ module OsLib_HVAC
|
|
1069
1069
|
def self.createSecondaryAirLoops(model, runner, options)
|
1070
1070
|
secondary_airloops = []
|
1071
1071
|
# create secondary airloop for each secondary zone
|
1072
|
-
model.getThermalZones.each do |zone|
|
1072
|
+
model.getThermalZones.sort.each do |zone|
|
1073
1073
|
if options['zonesSecondary'].include? zone
|
1074
1074
|
# create secondary airloop
|
1075
1075
|
airloop_secondary = OpenStudio::Model::AirLoopHVAC.new(model)
|
@@ -1314,7 +1314,7 @@ module OsLib_HVAC
|
|
1314
1314
|
end
|
1315
1315
|
|
1316
1316
|
def self.createPrimaryZoneEquipment(model, runner, options)
|
1317
|
-
model.getThermalZones.each do |zone|
|
1317
|
+
model.getThermalZones.sort.each do |zone|
|
1318
1318
|
if options['zonesPrimary'].include? zone
|
1319
1319
|
if options['zoneHVAC'] == 'FanCoil'
|
1320
1320
|
# create fan coil
|
@@ -1521,7 +1521,7 @@ module OsLib_HVAC
|
|
1521
1521
|
def self.get_or_add_hot_water_loop(model)
|
1522
1522
|
# How water loop
|
1523
1523
|
hw_loop = nil
|
1524
|
-
model.getLoops.each do |loop|
|
1524
|
+
model.getLoops.sort.each do |loop|
|
1525
1525
|
if loop.name.to_s == 'Hot Water Loop' # sizingPlant has loopType method to do this better
|
1526
1526
|
hw_loop = loop.to_PlantLoop.get
|
1527
1527
|
end
|
@@ -1580,7 +1580,7 @@ module OsLib_HVAC
|
|
1580
1580
|
# Chilled Water Plant
|
1581
1581
|
# todo - add in logic here that if existing chw_loop is air cooled, replace it with this one.
|
1582
1582
|
chw_loop = nil
|
1583
|
-
model.getLoops.each do |loop|
|
1583
|
+
model.getLoops.sort.each do |loop|
|
1584
1584
|
if loop.name.to_s == 'Chilled Water Loop'
|
1585
1585
|
chw_loop = loop.to_PlantLoop.get
|
1586
1586
|
end
|
@@ -1658,7 +1658,7 @@ module OsLib_HVAC
|
|
1658
1658
|
|
1659
1659
|
# Condenser System
|
1660
1660
|
cw_loop = nil
|
1661
|
-
model.getLoops.each do |loop|
|
1661
|
+
model.getLoops.sort.each do |loop|
|
1662
1662
|
if loop.name.to_s == 'Condenser Water Loop'
|
1663
1663
|
cw_loop = loop.to_PlantLoop.get
|
1664
1664
|
end
|
@@ -1702,7 +1702,7 @@ module OsLib_HVAC
|
|
1702
1702
|
def self.get_or_add_air_cooled_chiller_loop(model)
|
1703
1703
|
# Chilled Water Plant
|
1704
1704
|
chw_loop = nil
|
1705
|
-
model.getLoops.each do |loop|
|
1705
|
+
model.getLoops.sort.each do |loop|
|
1706
1706
|
if loop.name.to_s == 'Chilled Water Loop'
|
1707
1707
|
chw_loop = loop.to_PlantLoop.get
|
1708
1708
|
end
|
@@ -79,6 +79,11 @@ module OsLib_ModelGeneration
|
|
79
79
|
array << 'Hospital'
|
80
80
|
array << 'Outpatient'
|
81
81
|
array << 'SuperMarket'
|
82
|
+
array << 'Laboratory'
|
83
|
+
array << 'LargeDataCenterLowITE'
|
84
|
+
array << 'LargeDataCenterHighITE'
|
85
|
+
array << 'SmallDataCenterLowITE'
|
86
|
+
array << 'SmallDataCenterHighITE'
|
82
87
|
|
83
88
|
return array
|
84
89
|
end
|
@@ -328,7 +333,7 @@ module OsLib_ModelGeneration
|
|
328
333
|
supermarket_a = 45001.0
|
329
334
|
supermarket_p = 866.0
|
330
335
|
supermarket_wwr = 1880.0 / (supermarket_p * 20.0)
|
331
|
-
|
336
|
+
supermarket_aspect_ratio = calc_aspect_ratio(supermarket_a, supermarket_p)
|
332
337
|
|
333
338
|
hash['SmallOffice'] = { aspect_ratio: 1.5, wwr: 0.15, typical_story: 10.0, perim_mult: 1.0 }
|
334
339
|
hash['MediumOffice'] = { aspect_ratio: 1.5, wwr: 0.33, typical_story: 13.0, perim_mult: 1.0 }
|
@@ -351,7 +356,14 @@ module OsLib_ModelGeneration
|
|
351
356
|
hash['MidriseApartment'] = { aspect_ratio: 2.75, wwr: 0.15, typical_story: 10.0, perim_mult: 1.0 }
|
352
357
|
hash['HighriseApartment'] = { aspect_ratio: 2.75, wwr: 0.15, typical_story: 10.0, perim_mult: 1.0 }
|
353
358
|
# SuperMarket inputs come from prototype model
|
354
|
-
hash['SuperMarket'] = { aspect_ratio:
|
359
|
+
hash['SuperMarket'] = { aspect_ratio: supermarket_aspect_ratio.round(1), wwr: supermarket_wwr.round(2), typical_story: 20.0, perim_mult: 1.0 }
|
360
|
+
|
361
|
+
# Add Laboratory and Data Centers
|
362
|
+
hash['Laboratory'] = { aspect_ratio: 1.33, wwr: 0.12, typical_story: 10.0, perim_mult: 1.0 }
|
363
|
+
hash['LargeDataCenterLowITE'] = { aspect_ratio: 1.67, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
|
364
|
+
hash['LargeDataCenterHighITE'] = { aspect_ratio: 1.67, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
|
365
|
+
hash['SmallDataCenterLowITE'] = { aspect_ratio: 1.5, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
|
366
|
+
hash['SmallDataCenterHighITE'] = { aspect_ratio: 1.5, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
|
355
367
|
|
356
368
|
# DEER Prototypes
|
357
369
|
hash['Asm'] = { aspect_ratio: 1.0, wwr: 0.19, typical_story: 15.0 }
|
@@ -664,6 +676,19 @@ module OsLib_ModelGeneration
|
|
664
676
|
hash['Meeting'] = { ratio: 0.99, space_type_gen: true, default: true }
|
665
677
|
hash['Restroom'] = { ratio: 0.99, space_type_gen: true, default: true }
|
666
678
|
hash['Vestibule'] = { ratio: 0.99, space_type_gen: true, default: true }
|
679
|
+
elsif building_type == 'Laboratory'
|
680
|
+
hash['Office'] = { ratio: 0.50, space_type_gen: true, default: true }
|
681
|
+
hash['Open lab'] = { ratio: 0.35, space_type_gen: true, default: true }
|
682
|
+
hash['Equipment corridor'] = { ratio: 0.05, space_type_gen: true, default: true }
|
683
|
+
hash['Lab with fume hood'] = { ratio: 0.10, space_type_gen: true, default: true }
|
684
|
+
elsif building_type == 'LargeDataCenterHighITE'
|
685
|
+
hash['StandaloneDataCenter'] = { ratio: 1.0, space_type_gen: true, default: true }
|
686
|
+
elsif building_type == 'LargeDataCenterLowITE'
|
687
|
+
hash['StandaloneDataCenter'] = { ratio: 1.0, space_type_gen: true, default: true }
|
688
|
+
elsif building_type == 'SmallDataCenterHighITE'
|
689
|
+
hash['ComputerRoom'] = { ratio: 1.0, space_type_gen: true, default: true }
|
690
|
+
elsif building_type == 'SmallDataCenterLowITE'
|
691
|
+
hash['ComputerRoom'] = { ratio: 1.0, space_type_gen: true, default: true }
|
667
692
|
# DEER Prototypes
|
668
693
|
elsif building_type == 'Asm'
|
669
694
|
hash['Auditorium'] = { ratio: 0.7658, space_type_gen: true, default: true }
|
@@ -884,6 +909,7 @@ module OsLib_ModelGeneration
|
|
884
909
|
stories_flat = []
|
885
910
|
stories_flat_counter = 0
|
886
911
|
bar_hash[:stories].each_with_index do |(k, v), i|
|
912
|
+
#runner.registerInfo("STORY: k: #{k}, v: #{v}, index: #{i}")
|
887
913
|
# k is invalid in some cases, old story object that has been removed, should be from low to high including basement
|
888
914
|
# skip if source story insn't included in building area
|
889
915
|
if v[:story_included_in_building_area].nil? || (v[:story_included_in_building_area] == true)
|
@@ -1024,7 +1050,7 @@ module OsLib_ModelGeneration
|
|
1024
1050
|
# only intersect if make_mid_story_surfaces_adiabatic false
|
1025
1051
|
if diagnostic_intersect
|
1026
1052
|
|
1027
|
-
model.getPlanarSurfaces.each do |surface|
|
1053
|
+
model.getPlanarSurfaces.sort.each do |surface|
|
1028
1054
|
array = []
|
1029
1055
|
vertices = surface.vertices
|
1030
1056
|
fixed = false
|
@@ -1050,7 +1076,7 @@ module OsLib_ModelGeneration
|
|
1050
1076
|
end
|
1051
1077
|
|
1052
1078
|
# remove collinear points in a surface
|
1053
|
-
model.getPlanarSurfaces.each do |surface|
|
1079
|
+
model.getPlanarSurfaces.sort.each do |surface|
|
1054
1080
|
new_vertices = OpenStudio.removeCollinear(surface.vertices)
|
1055
1081
|
starting_count = surface.vertices.size
|
1056
1082
|
final_count = new_vertices.size
|
@@ -1061,7 +1087,7 @@ module OsLib_ModelGeneration
|
|
1061
1087
|
end
|
1062
1088
|
|
1063
1089
|
# remove duplicate surfaces in a space (should be done after remove duplicate and collinear points)
|
1064
|
-
model.getSpaces.each do |space|
|
1090
|
+
model.getSpaces.sort.each do |space|
|
1065
1091
|
|
1066
1092
|
# secondary array to compare against
|
1067
1093
|
surfaces_b = space.surfaces.sort
|
@@ -1105,7 +1131,7 @@ module OsLib_ModelGeneration
|
|
1105
1131
|
end
|
1106
1132
|
runner.registerInfo('Intersecting and matching surfaces in model, this will create additional geometry.')
|
1107
1133
|
else #elsif bar_hash[:double_loaded_corridor] # only intersect spaces in each story, not between wtory
|
1108
|
-
model.getBuilding.buildingStories.each do |story|
|
1134
|
+
model.getBuilding.buildingStories.sort.each do |story|
|
1109
1135
|
# intersect and surface match two pair by pair
|
1110
1136
|
spaces_b = story.spaces.sort
|
1111
1137
|
# looping through vector of each space
|
@@ -1136,7 +1162,7 @@ module OsLib_ModelGeneration
|
|
1136
1162
|
runner.registerInfo('Intersecting and matching surfaces in model, this will create additional geometry.')
|
1137
1163
|
end
|
1138
1164
|
else #elsif bar_hash[:double_loaded_corridor] # only intersect spaces in each story, not between wtory
|
1139
|
-
model.getBuilding.buildingStories.each do |story|
|
1165
|
+
model.getBuilding.buildingStories.sort.each do |story|
|
1140
1166
|
story_spaces = OpenStudio::Model::SpaceVector.new
|
1141
1167
|
story.spaces.sort.each do |space|
|
1142
1168
|
story_spaces << space
|
@@ -1152,11 +1178,11 @@ module OsLib_ModelGeneration
|
|
1152
1178
|
# set boundary conditions if not already set when geometry was created
|
1153
1179
|
# todo - update this to use space original z value vs. story name
|
1154
1180
|
if bar_hash[:num_stories_below_grade] > 0
|
1155
|
-
model.getBuildingStorys.each do |story|
|
1181
|
+
model.getBuildingStorys.sort.each do |story|
|
1156
1182
|
next if !story.name.to_s.include?('Story B')
|
1157
|
-
story.spaces.each do |space|
|
1183
|
+
story.spaces.sort.each do |space|
|
1158
1184
|
next if not new_spaces.include?(space)
|
1159
|
-
space.surfaces.each do |surface|
|
1185
|
+
space.surfaces.sort.each do |surface|
|
1160
1186
|
next if surface.surfaceType != 'Wall'
|
1161
1187
|
next if surface.outsideBoundaryCondition != 'Outdoors'
|
1162
1188
|
surface.setOutsideBoundaryCondition('Ground')
|
@@ -1621,10 +1647,7 @@ module OsLib_ModelGeneration
|
|
1621
1647
|
end
|
1622
1648
|
end
|
1623
1649
|
end
|
1624
|
-
|
1625
1650
|
end
|
1626
|
-
|
1627
|
-
|
1628
1651
|
end
|
1629
1652
|
|
1630
1653
|
# bar_from_building_type_ratios
|
@@ -2354,7 +2377,7 @@ module OsLib_ModelGeneration
|
|
2354
2377
|
if args['party_wall_fraction'] > 0
|
2355
2378
|
actual_ext_wall_area = model.getBuilding.exteriorWallArea
|
2356
2379
|
actual_party_wall_area = 0.0
|
2357
|
-
model.getSurfaces.each do |surface|
|
2380
|
+
model.getSurfaces.sort.each do |surface|
|
2358
2381
|
next if surface.outsideBoundaryCondition != 'Adiabatic'
|
2359
2382
|
next if surface.surfaceType != 'Wall'
|
2360
2383
|
actual_party_wall_area += surface.grossArea * surface.space.get.multiplier
|
@@ -2365,7 +2388,7 @@ module OsLib_ModelGeneration
|
|
2365
2388
|
end
|
2366
2389
|
|
2367
2390
|
# check ns/ew aspect ratio (harder to check when party walls are added)
|
2368
|
-
wall_and_window_by_orientation = OsLib_Geometry.getExteriorWindowAndWllAreaByOrientation(model,model.getSpaces)
|
2391
|
+
wall_and_window_by_orientation = OsLib_Geometry.getExteriorWindowAndWllAreaByOrientation(model,model.getSpaces.sort)
|
2369
2392
|
wall_ns = (wall_and_window_by_orientation['northWall'] + wall_and_window_by_orientation['southWall'])
|
2370
2393
|
wall_ew = wall_and_window_by_orientation['eastWall'] + wall_and_window_by_orientation['westWall']
|
2371
2394
|
wall_ns_ip = OpenStudio.convert(wall_ns,'m^2','ft^2').get
|
@@ -2560,6 +2583,19 @@ module OsLib_ModelGeneration
|
|
2560
2583
|
# Make the standard applier
|
2561
2584
|
standard = Standard.build((args['template']).to_s)
|
2562
2585
|
|
2586
|
+
# validate climate zone
|
2587
|
+
if !args.has_key?('climate_zone') || args['climate_zone'] == 'Lookup From Model'
|
2588
|
+
climate_zone = standard.model_get_building_climate_zone_and_building_type(model)['climate_zone']
|
2589
|
+
runner.registerInfo("Using climate zone #{climate_zone} from model")
|
2590
|
+
else
|
2591
|
+
climate_zone = args['climate_zone']
|
2592
|
+
runner.registerInfo("Using climate zone #{climate_zone} from user arguments")
|
2593
|
+
end
|
2594
|
+
if climate_zone == ''
|
2595
|
+
runner.registerError("Could not determine climate zone from measure arguments or model.")
|
2596
|
+
return false
|
2597
|
+
end
|
2598
|
+
|
2563
2599
|
# make sure daylight savings is turned on up prior to any sizing runs being done.
|
2564
2600
|
if args['enable_dst']
|
2565
2601
|
start_date = '2nd Sunday in March'
|
@@ -2575,7 +2611,7 @@ module OsLib_ModelGeneration
|
|
2575
2611
|
|
2576
2612
|
# remove internal loads
|
2577
2613
|
if args['remove_objects']
|
2578
|
-
model.getSpaceLoads.each do |instance|
|
2614
|
+
model.getSpaceLoads.sort.each do |instance|
|
2579
2615
|
next if instance.name.to_s.include?('Elevator') # most prototype building types model exterior elevators with name Elevator
|
2580
2616
|
next if instance.to_InternalMass.is_initialized
|
2581
2617
|
next if instance.to_WaterUseEquipment.is_initialized
|
@@ -2585,7 +2621,7 @@ module OsLib_ModelGeneration
|
|
2585
2621
|
model.getDefaultScheduleSets.each(&:remove)
|
2586
2622
|
end
|
2587
2623
|
|
2588
|
-
model.getSpaceTypes.each do |space_type|
|
2624
|
+
model.getSpaceTypes.sort.each do |space_type|
|
2589
2625
|
# Don't add infiltration here; will be added later in the script
|
2590
2626
|
test = standard.space_type_apply_internal_loads(space_type, true, true, true, true, true, false)
|
2591
2627
|
if test == false
|
@@ -2604,7 +2640,7 @@ module OsLib_ModelGeneration
|
|
2604
2640
|
|
2605
2641
|
# warn if spaces in model without space type
|
2606
2642
|
spaces_without_space_types = []
|
2607
|
-
model.getSpaces.each do |space|
|
2643
|
+
model.getSpaces.sort.each do |space|
|
2608
2644
|
next if space.spaceType.is_initialized
|
2609
2645
|
spaces_without_space_types << space
|
2610
2646
|
end
|
@@ -2615,7 +2651,7 @@ module OsLib_ModelGeneration
|
|
2615
2651
|
|
2616
2652
|
# identify primary building type (used for construction, and ideally HVAC as well)
|
2617
2653
|
building_types = {}
|
2618
|
-
model.getSpaceTypes.each do |space_type|
|
2654
|
+
model.getSpaceTypes.sort.each do |space_type|
|
2619
2655
|
# populate hash of building types
|
2620
2656
|
if space_type.standardsBuildingType.is_initialized
|
2621
2657
|
bldg_type = space_type.standardsBuildingType.get
|
@@ -2646,13 +2682,6 @@ module OsLib_ModelGeneration
|
|
2646
2682
|
else
|
2647
2683
|
is_residential = 'No'
|
2648
2684
|
end
|
2649
|
-
if !args.has_key?('climate_zone') || args['climate_zone'] == 'Lookup From Model'
|
2650
|
-
climate_zone = standard.model_get_building_climate_zone_and_building_type(model)['climate_zone']
|
2651
|
-
runner.registerInfo("Using climate zone #{climate_zone} from model")
|
2652
|
-
else
|
2653
|
-
climate_zone = args['climate_zone']
|
2654
|
-
runner.registerInfo("Using climate zone #{climate_zone} from user arguments")
|
2655
|
-
end
|
2656
2685
|
bldg_def_const_set = standard.model_add_construction_set(model, climate_zone, lookup_building_type, nil, is_residential)
|
2657
2686
|
if bldg_def_const_set.is_initialized
|
2658
2687
|
bldg_def_const_set = bldg_def_const_set.get
|
@@ -2666,7 +2695,7 @@ module OsLib_ModelGeneration
|
|
2666
2695
|
end
|
2667
2696
|
|
2668
2697
|
# address any adiabatic surfaces that don't have hard assigned constructions
|
2669
|
-
model.getSurfaces.each do |surface|
|
2698
|
+
model.getSurfaces.sort.each do |surface|
|
2670
2699
|
next if surface.outsideBoundaryCondition != 'Adiabatic'
|
2671
2700
|
next if surface.construction.is_initialized
|
2672
2701
|
surface.setAdjacentSurface(surface)
|
@@ -2690,11 +2719,11 @@ module OsLib_ModelGeneration
|
|
2690
2719
|
if args['add_elevators']
|
2691
2720
|
|
2692
2721
|
# remove elevators as spaceLoads or exteriorLights
|
2693
|
-
model.getSpaceLoads.each do |instance|
|
2722
|
+
model.getSpaceLoads.sort.each do |instance|
|
2694
2723
|
next if !instance.name.to_s.include?('Elevator') # most prototype building types model exterior elevators with name Elevator
|
2695
2724
|
instance.remove
|
2696
2725
|
end
|
2697
|
-
model.getExteriorLightss.each do |ext_light|
|
2726
|
+
model.getExteriorLightss.sort.each do |ext_light|
|
2698
2727
|
next if !ext_light.name.to_s.include?('Fuel equipment') # some prototype building types model exterior elevators by this name
|
2699
2728
|
ext_light.remove
|
2700
2729
|
end
|
@@ -2715,7 +2744,7 @@ module OsLib_ModelGeneration
|
|
2715
2744
|
if args['add_exterior_lights']
|
2716
2745
|
|
2717
2746
|
if args['remove_objects']
|
2718
|
-
model.getExteriorLightss.each do |ext_light|
|
2747
|
+
model.getExteriorLightss.sort.each do |ext_light|
|
2719
2748
|
next if ext_light.name.to_s.include?('Fuel equipment') # some prototype building types model exterior elevators by this name
|
2720
2749
|
ext_light.remove
|
2721
2750
|
end
|
@@ -2797,16 +2826,25 @@ module OsLib_ModelGeneration
|
|
2797
2826
|
end
|
2798
2827
|
end
|
2799
2828
|
|
2800
|
-
#
|
2829
|
+
# add_daylighting_controls (since outdated measure don't have this default to true if arg not found)
|
2830
|
+
if !args.has_key?('add_daylighting_controls')
|
2831
|
+
args['add_daylighting_controls'] = true
|
2832
|
+
end
|
2833
|
+
if args['add_daylighting_controls']
|
2834
|
+
# remove add_daylighting_controls objects
|
2835
|
+
if args['remove_objects']
|
2836
|
+
model.getDaylightingControls.each(&:remove)
|
2837
|
+
end
|
2801
2838
|
|
2802
|
-
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
|
2839
|
+
# add daylight controls, need to perform a sizing run for 2010
|
2840
|
+
if args['template'] == '90.1-2010'
|
2841
|
+
if standard.model_run_sizing_run(model, "#{Dir.pwd}/SRvt") == false
|
2842
|
+
log_messages_to_runner(runner, debug = true)
|
2843
|
+
return false
|
2844
|
+
end
|
2807
2845
|
end
|
2808
|
-
end
|
2809
2846
|
standard.model_add_daylighting_controls(model)
|
2847
|
+
end
|
2810
2848
|
|
2811
2849
|
# add refrigeration
|
2812
2850
|
if args['add_refrigeration']
|
@@ -2824,7 +2862,7 @@ module OsLib_ModelGeneration
|
|
2824
2862
|
if args['add_internal_mass']
|
2825
2863
|
|
2826
2864
|
if args['remove_objects']
|
2827
|
-
model.getSpaceLoads.each do |instance|
|
2865
|
+
model.getSpaceLoads.sort.each do |instance|
|
2828
2866
|
next unless instance.to_InternalMass.is_initialized
|
2829
2867
|
instance.remove
|
2830
2868
|
end
|
@@ -2847,7 +2885,7 @@ module OsLib_ModelGeneration
|
|
2847
2885
|
model.getThermostatSetpointDualSetpoints.each(&:remove)
|
2848
2886
|
end
|
2849
2887
|
|
2850
|
-
model.getSpaceTypes.each do |space_type|
|
2888
|
+
model.getSpaceTypes.sort.each do |space_type|
|
2851
2889
|
# create thermostat schedules
|
2852
2890
|
# skip un-recognized space types
|
2853
2891
|
next if standard.space_type_get_standards_data(space_type).empty?
|
@@ -2855,12 +2893,12 @@ module OsLib_ModelGeneration
|
|
2855
2893
|
standard.space_type_apply_internal_load_schedules(space_type, false, false, false, false, false, false, true)
|
2856
2894
|
|
2857
2895
|
# identify thermal thermostat and apply to zones (apply_internal_load_schedules names )
|
2858
|
-
model.getThermostatSetpointDualSetpoints.each do |thermostat|
|
2896
|
+
model.getThermostatSetpointDualSetpoints.sort.each do |thermostat|
|
2859
2897
|
next if thermostat.name.to_s != "#{space_type.name} Thermostat"
|
2860
2898
|
next if !thermostat.coolingSetpointTemperatureSchedule.is_initialized
|
2861
2899
|
next if !thermostat.heatingSetpointTemperatureSchedule.is_initialized
|
2862
2900
|
runner.registerInfo("Assigning #{thermostat.name} to thermal zones with #{space_type.name} assigned.")
|
2863
|
-
space_type.spaces.each do |space|
|
2901
|
+
space_type.spaces.sort.each do |space|
|
2864
2902
|
next if !space.thermalZone.is_initialized
|
2865
2903
|
space.thermalZone.get.setThermostatSetpointDualSetpoint(thermostat)
|
2866
2904
|
end
|
@@ -3038,7 +3076,7 @@ module OsLib_ModelGeneration
|
|
3038
3076
|
if args['add_internal_mass']
|
3039
3077
|
|
3040
3078
|
if args['remove_objects']
|
3041
|
-
model.getSpaceLoads.each do |instance|
|
3079
|
+
model.getSpaceLoads.sort.each do |instance|
|
3042
3080
|
next unless instance.to_InternalMass.is_initialized
|
3043
3081
|
instance.remove
|
3044
3082
|
end
|
@@ -3091,8 +3129,8 @@ module OsLib_ModelGeneration
|
|
3091
3129
|
set_building_defaults = runner.getBoolArgumentValue('set_building_defaults', user_arguments)
|
3092
3130
|
|
3093
3131
|
# reporting initial condition of model
|
3094
|
-
starting_spaceTypes = model.getSpaceTypes
|
3095
|
-
starting_constructionSets = model.getDefaultConstructionSets
|
3132
|
+
starting_spaceTypes = model.getSpaceTypes.sort
|
3133
|
+
starting_constructionSets = model.getDefaultConstructionSets.sort
|
3096
3134
|
runner.registerInitialCondition("The building started with #{starting_spaceTypes.size} space types and #{starting_constructionSets.size} construction sets.")
|
3097
3135
|
|
3098
3136
|
# lookup space types for specified building type (false indicates not to use whole building type only)
|
@@ -3129,7 +3167,7 @@ module OsLib_ModelGeneration
|
|
3129
3167
|
if create_space_types
|
3130
3168
|
|
3131
3169
|
# array of starting space types
|
3132
|
-
space_types_starting = model.getSpaceTypes
|
3170
|
+
space_types_starting = model.getSpaceTypes.sort
|
3133
3171
|
|
3134
3172
|
# create stub space types
|
3135
3173
|
space_type_hash.each do |space_type_name, hash|
|
@@ -3242,11 +3280,10 @@ module OsLib_ModelGeneration
|
|
3242
3280
|
end
|
3243
3281
|
|
3244
3282
|
# reporting final condition of model
|
3245
|
-
finishing_spaceTypes = model.getSpaceTypes
|
3246
|
-
finishing_constructionSets = model.getDefaultConstructionSets
|
3283
|
+
finishing_spaceTypes = model.getSpaceTypes.sort
|
3284
|
+
finishing_constructionSets = model.getDefaultConstructionSets.sort
|
3247
3285
|
runner.registerFinalCondition("The building finished with #{finishing_spaceTypes.size} space types and #{finishing_constructionSets.size} construction sets.")
|
3248
3286
|
|
3249
3287
|
return true
|
3250
3288
|
end
|
3251
|
-
|
3252
3289
|
end
|