openstudio-standards 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards.xlsx +0 -0
  3. data/lib/openstudio-standards/btap/compliance.rb +17 -7
  4. data/lib/openstudio-standards/btap/hvac.rb +6 -5
  5. data/lib/openstudio-standards/btap/measures.rb +137 -102
  6. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +2 -2
  7. data/lib/openstudio-standards/prototypes/Prototype.FanVariableVolume.rb +1 -1
  8. data/lib/openstudio-standards/prototypes/Prototype.Model.rb +96 -31
  9. data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +1 -1
  10. data/lib/openstudio-standards/prototypes/Prototype.building_specific_methods.rb +163 -0
  11. data/lib/openstudio-standards/prototypes/Prototype.full_service_restaurant.rb +54 -52
  12. data/lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb +28 -26
  13. data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +41 -39
  14. data/lib/openstudio-standards/prototypes/Prototype.large_hotel.rb +19 -17
  15. data/lib/openstudio-standards/prototypes/Prototype.large_office.rb +16 -13
  16. data/lib/openstudio-standards/prototypes/Prototype.medium_office.rb +13 -11
  17. data/lib/openstudio-standards/prototypes/Prototype.mid_rise_apartment.rb +33 -31
  18. data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +66 -64
  19. data/lib/openstudio-standards/prototypes/Prototype.primary_school.rb +8 -88
  20. data/lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb +54 -52
  21. data/lib/openstudio-standards/prototypes/Prototype.retail_standalone.rb +13 -11
  22. data/lib/openstudio-standards/prototypes/Prototype.retail_stripmall.rb +15 -13
  23. data/lib/openstudio-standards/prototypes/Prototype.secondary_school.rb +11 -9
  24. data/lib/openstudio-standards/prototypes/Prototype.small_hotel.rb +13 -11
  25. data/lib/openstudio-standards/prototypes/Prototype.small_office.rb +7 -5
  26. data/lib/openstudio-standards/prototypes/Prototype.utilities.rb +18 -13
  27. data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +11 -9
  28. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +23 -12
  29. data/lib/openstudio-standards/standards/Standards.Fan.rb +7 -4
  30. data/lib/openstudio-standards/standards/Standards.Model.rb +4 -4
  31. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +9 -4
  32. data/lib/openstudio-standards/utilities/simulation.rb +6 -1
  33. data/lib/openstudio-standards/version.rb +1 -1
  34. data/lib/openstudio-standards/weather/Weather.Model.rb +1 -1
  35. metadata +3 -2
@@ -1,7 +1,8 @@
1
1
 
2
- # Extend the class to add Large Hotel specific stuff
3
- class OpenStudio::Model::Model
4
- def define_space_type_map(building_type, template, climate_zone)
2
+ # Modules for building-type specific methods
3
+ module PrototypeBuilding
4
+ module LargeHotel
5
+ def self.define_space_type_map(building_type, template, climate_zone)
5
6
  space_type_map = nil
6
7
  case template
7
8
  when 'NECB 2011'
@@ -43,7 +44,7 @@ class OpenStudio::Model::Model
43
44
  return space_type_map
44
45
  end
45
46
 
46
- def define_hvac_system_map(building_type, template, climate_zone)
47
+ def self.define_hvac_system_map(building_type, template, climate_zone)
47
48
  system_to_space_map = [
48
49
  {
49
50
  'type' => 'VAV',
@@ -98,7 +99,7 @@ class OpenStudio::Model::Model
98
99
  return system_to_space_map
99
100
  end
100
101
 
101
- def define_space_multiplier
102
+ def self.define_space_multiplier
102
103
  # This map define the multipliers for spaces with multipliers not equals to 1
103
104
  space_multiplier_map = {
104
105
  'Room_1_Flr_3' => 4,
@@ -113,7 +114,7 @@ class OpenStudio::Model::Model
113
114
  return space_multiplier_map
114
115
  end
115
116
 
116
- def custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
117
+ def self.custom_hvac_tweaks(building_type, template, climate_zone, prototype_input, model)
117
118
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started building type specific adjustments')
118
119
 
119
120
  # Add Exhaust Fan
@@ -127,26 +128,26 @@ class OpenStudio::Model::Model
127
128
  end
128
129
 
129
130
  exhaust_fan_space_types.each do |space_type_name|
130
- space_type_data = find_object($os_standards['space_types'], 'template' => template, 'building_type' => building_type, 'space_type' => space_type_name)
131
+ space_type_data = model.find_object($os_standards['space_types'], 'template' => template, 'building_type' => building_type, 'space_type' => space_type_name)
131
132
  if space_type_data.nil?
132
133
  OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Unable to find space type #{template}-#{building_type}-#{space_type_name}")
133
134
  return false
134
135
  end
135
136
 
136
- exhaust_schedule = add_schedule(space_type_data['exhaust_schedule'])
137
+ exhaust_schedule = model.add_schedule(space_type_data['exhaust_schedule'])
137
138
  if exhaust_schedule.class.to_s == 'NilClass'
138
139
  OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Unable to find Exhaust Schedule for space type #{template}-#{building_type}-#{space_type_name}")
139
140
  return false
140
141
  end
141
142
 
142
- balanced_exhaust_schedule = add_schedule(space_type_data['balanced_exhaust_fraction_schedule'])
143
+ balanced_exhaust_schedule = model.add_schedule(space_type_data['balanced_exhaust_fraction_schedule'])
143
144
 
144
145
  space_names = space_type_map[space_type_name]
145
146
  space_names.each do |space_name|
146
- space = getSpaceByName(space_name).get
147
+ space = model.getSpaceByName(space_name).get
147
148
  thermal_zone = space.thermalZone.get
148
149
 
149
- zone_exhaust_fan = OpenStudio::Model::FanZoneExhaust.new(self)
150
+ zone_exhaust_fan = OpenStudio::Model::FanZoneExhaust.new(model)
150
151
  zone_exhaust_fan.setName(space.name.to_s + ' Exhaust Fan')
151
152
  zone_exhaust_fan.setAvailabilitySchedule(exhaust_schedule)
152
153
  zone_exhaust_fan.setFanEfficiency(space_type_data['exhaust_fan_efficiency'])
@@ -162,7 +163,7 @@ class OpenStudio::Model::Model
162
163
 
163
164
  if !space_type_data['exhaust_fan_power'].nil? && space_type_data['exhaust_fan_power'].to_f.nonzero?
164
165
  # Create the electric equipment definition
165
- exhaust_fan_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(self)
166
+ exhaust_fan_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
166
167
  exhaust_fan_equip_def.setName("#{space_name} Electric Equipment Definition")
167
168
  exhaust_fan_equip_def.setDesignLevel(space_type_data['exhaust_fan_power'].to_f)
168
169
  exhaust_fan_equip_def.setFractionLatent(0)
@@ -179,10 +180,10 @@ class OpenStudio::Model::Model
179
180
  end
180
181
 
181
182
  # Update Sizing Zone
182
- zone_sizing = getSpaceByName('Kitchen_Flr_6').get.thermalZone.get.sizingZone
183
+ zone_sizing = model.getSpaceByName('Kitchen_Flr_6').get.thermalZone.get.sizingZone
183
184
  zone_sizing.setCoolingMinimumAirFlowFraction(0.7)
184
185
 
185
- zone_sizing = getSpaceByName('Laundry_Flr_1').get.thermalZone.get.sizingZone
186
+ zone_sizing = model.getSpaceByName('Laundry_Flr_1').get.thermalZone.get.sizingZone
186
187
  zone_sizing.setCoolingMinimumAirFlow(0.23567919336)
187
188
 
188
189
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished building type specific adjustments')
@@ -191,15 +192,16 @@ class OpenStudio::Model::Model
191
192
  end # add hvac
192
193
 
193
194
  # Add the daylighting controls for lobby, cafe, dinning and banquet
194
- def large_hotel_add_daylighting_controls(template)
195
+ def self.large_hotel_add_daylighting_controls(template, model)
195
196
  space_names = ['Banquet_Flr_6', 'Dining_Flr_6', 'Cafe_Flr_1', 'Lobby_Flr_1']
196
197
  space_names.each do |space_name|
197
- space = getSpaceByName(space_name).get
198
+ space = model.getSpaceByName(space_name).get
198
199
  space.add_daylighting_controls(template, false, false)
199
200
  end
200
201
  end
201
202
 
202
- def custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
203
+ def self.custom_swh_tweaks(building_type, template, climate_zone, prototype_input, model)
203
204
  return true
204
205
  end
205
206
  end
207
+ end
@@ -1,6 +1,8 @@
1
- # Extend the class to add Medium Office specific stuff
2
- class OpenStudio::Model::Model
3
- def define_space_type_map(building_type, template, climate_zone)
1
+
2
+ # Modules for building-type specific methods
3
+ module PrototypeBuilding
4
+ module LargeOffice
5
+ def self.define_space_type_map(building_type, template, climate_zone)
4
6
  case template
5
7
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
6
8
  space_type_map = {
@@ -27,7 +29,7 @@ class OpenStudio::Model::Model
27
29
  when 'NECB 2011'
28
30
  # Dom is A
29
31
  space_type_map = {
30
- 'Electrical/Mechanical' => ['Basement'],
32
+ 'Electrical/Mechanical-sch-A' => ['Basement'],
31
33
 
32
34
  'Office - open plan' => ['Core_bottom', 'Core_mid', 'Core_top', 'Perimeter_bot_ZN_1', 'Perimeter_bot_ZN_2', 'Perimeter_bot_ZN_3', 'Perimeter_bot_ZN_4', 'Perimeter_mid_ZN_1', 'Perimeter_mid_ZN_2', 'Perimeter_mid_ZN_3', 'Perimeter_mid_ZN_4', 'Perimeter_top_ZN_1', 'Perimeter_top_ZN_2', 'Perimeter_top_ZN_3', 'Perimeter_top_ZN_4', 'DataCenter_basement_ZN_6', 'DataCenter_bot_ZN_6', 'DataCenter_mid_ZN_6', 'DataCenter_top_ZN_6'],
33
35
  '- undefined -' => ['GroundFloor_Plenum', 'TopFloor_Plenum', 'MidFloor_Plenum']
@@ -36,7 +38,7 @@ class OpenStudio::Model::Model
36
38
  return space_type_map
37
39
  end
38
40
 
39
- def define_hvac_system_map(building_type, template, climate_zone)
41
+ def self.define_hvac_system_map(building_type, template, climate_zone)
40
42
  case template
41
43
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
42
44
  system_to_space_map = [
@@ -145,7 +147,7 @@ class OpenStudio::Model::Model
145
147
  return system_to_space_map
146
148
  end
147
149
 
148
- def define_space_multiplier
150
+ def self.define_space_multiplier
149
151
  # This map define the multipliers for spaces with multipliers not equals to 1
150
152
  space_multiplier_map = {
151
153
  'DataCenter_mid_ZN_6' => 10,
@@ -159,14 +161,14 @@ class OpenStudio::Model::Model
159
161
  return space_multiplier_map
160
162
  end
161
163
 
162
- def custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
164
+ def self.custom_hvac_tweaks(building_type, template, climate_zone, prototype_input, model)
163
165
  system_to_space_map = define_hvac_system_map(building_type, template, climate_zone)
164
166
 
165
167
  system_to_space_map.each do |system|
166
168
  # find all zones associated with these spaces
167
169
  thermal_zones = []
168
170
  system['space_names'].each do |space_name|
169
- space = getSpaceByName(space_name)
171
+ space = model.getSpaceByName(space_name)
170
172
  if space.empty?
171
173
  OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "No space called #{space_name} was found in the model")
172
174
  return false
@@ -182,7 +184,7 @@ class OpenStudio::Model::Model
182
184
 
183
185
  return_plenum = nil
184
186
  unless system['return_plenum'].nil?
185
- return_plenum_space = getSpaceByName(system['return_plenum'])
187
+ return_plenum_space = model.getSpaceByName(system['return_plenum'])
186
188
  if return_plenum_space.empty?
187
189
  OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "No space called #{system['return_plenum']} was found in the model")
188
190
  return false
@@ -200,18 +202,19 @@ class OpenStudio::Model::Model
200
202
  return true
201
203
  end
202
204
 
203
- def update_waterheater_loss_coefficient(template)
205
+ def self.update_waterheater_loss_coefficient(template, model)
204
206
  case template
205
207
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', 'NECB 2011'
206
- getWaterHeaterMixeds.sort.each do |water_heater|
208
+ model.getWaterHeaterMixeds.sort.each do |water_heater|
207
209
  water_heater.setOffCycleLossCoefficienttoAmbientTemperature(11.25413987)
208
210
  water_heater.setOnCycleLossCoefficienttoAmbientTemperature(11.25413987)
209
211
  end
210
212
  end
211
213
  end
212
214
 
213
- def custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
214
- update_waterheater_loss_coefficient(template)
215
+ def self.custom_swh_tweaks(building_type, template, climate_zone, prototype_input, model)
216
+ PrototypeBuilding::LargeOffice.update_waterheater_loss_coefficient(template, model)
215
217
  return true
216
218
  end
217
219
  end
220
+ end
@@ -1,7 +1,8 @@
1
1
 
2
- # Extend the class to add Medium Office specific stuff
3
- class OpenStudio::Model::Model
4
- def define_space_type_map(building_type, template, climate_zone)
2
+ # Modules for building-type specific methods
3
+ module PrototypeBuilding
4
+ module MediumOffice
5
+ def self.define_space_type_map(building_type, template, climate_zone)
5
6
  space_type_map = nil
6
7
  space_type_map = case template
7
8
  when 'NECB 2011'
@@ -18,7 +19,7 @@ class OpenStudio::Model::Model
18
19
  return space_type_map
19
20
  end
20
21
 
21
- def define_hvac_system_map(building_type, template, climate_zone)
22
+ def self.define_hvac_system_map(building_type, template, climate_zone)
22
23
  system_to_space_map = case template
23
24
  when 'DOE Ref Pre-1980'
24
25
  [
@@ -54,12 +55,12 @@ class OpenStudio::Model::Model
54
55
  return system_to_space_map
55
56
  end
56
57
 
57
- def custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
58
+ def self.custom_hvac_tweaks(building_type, template, climate_zone, prototype_input, model)
58
59
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started building type specific adjustments')
59
60
 
60
- getSpaces.each do |space|
61
+ model.getSpaces.each do |space|
61
62
  if space.name.get.to_s == 'Core_bottom'
62
- add_elevator(template,
63
+ model.add_elevator(template,
63
64
  space,
64
65
  prototype_input['number_of_elevators'],
65
66
  prototype_input['elevator_type'],
@@ -75,19 +76,20 @@ class OpenStudio::Model::Model
75
76
  return true
76
77
  end # add hvac
77
78
 
78
- def update_waterheater_loss_coefficient(template)
79
+ def self.update_waterheater_loss_coefficient(template, model)
79
80
  case template
80
81
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', 'NECB 2011'
81
- getWaterHeaterMixeds.sort.each do |water_heater|
82
+ model.getWaterHeaterMixeds.sort.each do |water_heater|
82
83
  water_heater.setOffCycleLossCoefficienttoAmbientTemperature(7.561562668)
83
84
  water_heater.setOnCycleLossCoefficienttoAmbientTemperature(7.561562668)
84
85
  end
85
86
  end
86
87
  end
87
88
 
88
- def custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
89
- update_waterheater_loss_coefficient(template)
89
+ def self.custom_swh_tweaks(building_type, template, climate_zone, prototype_input, model)
90
+ PrototypeBuilding::MediumOffice.update_waterheater_loss_coefficient(template, model)
90
91
 
91
92
  return true
92
93
  end
93
94
  end
95
+ end
@@ -1,7 +1,8 @@
1
1
 
2
-
3
- class OpenStudio::Model::Model
4
- def define_space_type_map(building_type, template, climate_zone)
2
+ # Modules for building-type specific methods
3
+ module PrototypeBuilding
4
+ module MidriseApartment
5
+ def self.define_space_type_map(building_type, template, climate_zone)
5
6
  space_type_map = nil
6
7
 
7
8
  case template
@@ -91,7 +92,7 @@ class OpenStudio::Model::Model
91
92
  return space_type_map
92
93
  end
93
94
 
94
- def define_hvac_system_map(building_type, template, climate_zone)
95
+ def self.define_hvac_system_map(building_type, template, climate_zone)
95
96
  system_to_space_map = [
96
97
  { 'type' => 'SAC',
97
98
  'space_names' => ['G SW Apartment'] },
@@ -153,7 +154,7 @@ class OpenStudio::Model::Model
153
154
  return system_to_space_map
154
155
  end
155
156
 
156
- def define_space_multiplier
157
+ def self.define_space_multiplier
157
158
  # This map define the multipliers for spaces with multipliers not equals to 1
158
159
  space_multiplier_map = {
159
160
  'M SW Apartment' => 2,
@@ -169,40 +170,40 @@ class OpenStudio::Model::Model
169
170
  return space_multiplier_map
170
171
  end
171
172
 
172
- def custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
173
+ def self.custom_hvac_tweaks(building_type, template, climate_zone, prototype_input, model)
173
174
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started building type specific adjustments')
174
175
 
175
176
  # adjust the cooling setpoint
176
- adjust_clg_setpoint(template, climate_zone)
177
+ PrototypeBuilding::MidriseApartment.adjust_clg_setpoint(template, climate_zone, model)
177
178
  # add elevator and lights&fans for the ground floor corridor
178
- add_extra_equip_corridor(template)
179
+ PrototypeBuilding::MidriseApartment.add_extra_equip_corridor(template, model)
179
180
  # add extra infiltration for ground floor corridor
180
- add_door_infiltration(template, climate_zone)
181
+ PrototypeBuilding::MidriseApartment.add_door_infiltration(template, climate_zone, model)
181
182
 
182
183
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished building type specific adjustments')
183
184
 
184
185
  return true
185
186
  end
186
187
 
187
- def adjust_clg_setpoint(template, climate_zone)
188
+ def self.adjust_clg_setpoint(template, climate_zone, model)
188
189
  space_name = 'Office'
189
- space_type_name = getSpaceByName(space_name).get.spaceType.get.name.get
190
+ space_type_name = model.getSpaceByName(space_name).get.spaceType.get.name.get
190
191
  thermostat_name = space_type_name + ' Thermostat'
191
- thermostat = getThermostatSetpointDualSetpointByName(thermostat_name).get
192
+ thermostat = model.getThermostatSetpointDualSetpointByName(thermostat_name).get
192
193
  case template
193
194
  when '90.1-2004', '90.1-2007', '90.1-2010'
194
195
  case climate_zone
195
196
  when 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-3B'
196
- thermostat.setCoolingSetpointTemperatureSchedule(add_schedule('ApartmentMidRise CLGSETP_OFF_SCH_NO_OPTIMUM'))
197
+ thermostat.setCoolingSetpointTemperatureSchedule(model.add_schedule('ApartmentMidRise CLGSETP_OFF_SCH_NO_OPTIMUM'))
197
198
  end
198
199
  end
199
200
  end
200
201
 
201
202
  # add elevator and lights&fans for the ground floor corridor
202
- def add_extra_equip_corridor(template)
203
- corridor_ground_space = getSpaceByName('G Corridor').get
204
- elec_equip_def1 = OpenStudio::Model::ElectricEquipmentDefinition.new(self)
205
- elec_equip_def2 = OpenStudio::Model::ElectricEquipmentDefinition.new(self)
203
+ def self.add_extra_equip_corridor(template, model)
204
+ corridor_ground_space = model.getSpaceByName('G Corridor').get
205
+ elec_equip_def1 = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
206
+ elec_equip_def2 = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
206
207
  elec_equip_def1.setName('Ground Corridor Electric Equipment Definition1')
207
208
  elec_equip_def2.setName('Ground Corridor Electric Equipment Definition2')
208
209
  case template
@@ -228,12 +229,12 @@ class OpenStudio::Model::Model
228
229
  elec_equip2.setName('Elevators_Lights_Fan')
229
230
  elec_equip1.setSpace(corridor_ground_space)
230
231
  elec_equip2.setSpace(corridor_ground_space)
231
- elec_equip1.setSchedule(add_schedule('ApartmentMidRise BLDG_ELEVATORS'))
232
+ elec_equip1.setSchedule(model.add_schedule('ApartmentMidRise BLDG_ELEVATORS'))
232
233
  case template
233
234
  when '90.1-2004', '90.1-2007'
234
- elec_equip2.setSchedule(add_schedule('ApartmentMidRise ELEV_LIGHT_FAN_SCH_24_7'))
235
+ elec_equip2.setSchedule(model.add_schedule('ApartmentMidRise ELEV_LIGHT_FAN_SCH_24_7'))
235
236
  when '90.1-2010', '90.1-2013'
236
- elec_equip2.setSchedule(add_schedule('ApartmentMidRise ELEV_LIGHT_FAN_SCH_ADD_DF'))
237
+ elec_equip2.setSchedule(model.add_schedule('ApartmentMidRise ELEV_LIGHT_FAN_SCH_ADD_DF'))
237
238
  end
238
239
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
239
240
  elec_equip_def1.setDesignLevel(16_055)
@@ -244,14 +245,14 @@ class OpenStudio::Model::Model
244
245
  elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1)
245
246
  elec_equip1.setName('G Corridor_Elevators_Equip')
246
247
  elec_equip1.setSpace(corridor_ground_space)
247
- elec_equip1.setSchedule(add_schedule('ApartmentMidRise BLDG_ELEVATORS Pre2004'))
248
+ elec_equip1.setSchedule(model.add_schedule('ApartmentMidRise BLDG_ELEVATORS Pre2004'))
248
249
  end
249
250
  end
250
251
 
251
- def update_waterheater_loss_coefficient(template)
252
+ def self.update_waterheater_loss_coefficient(template, model)
252
253
  case template
253
254
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', 'NECB 2011'
254
- getWaterHeaterMixeds.sort.each do |water_heater|
255
+ model.getWaterHeaterMixeds.sort.each do |water_heater|
255
256
  water_heater.setOffCycleLossCoefficienttoAmbientTemperature(46.288874618)
256
257
  water_heater.setOnCycleLossCoefficienttoAmbientTemperature(46.288874618)
257
258
  end
@@ -259,19 +260,19 @@ class OpenStudio::Model::Model
259
260
  end
260
261
 
261
262
  # add extra infiltration for ground floor corridor
262
- def add_door_infiltration(template, climate_zone)
263
+ def self.add_door_infiltration(template, climate_zone, model)
263
264
  case template
264
265
  when 'DOE Ref 1980-2004', 'DOE Ref Pre-1980'
265
266
  # no door infiltration in these two vintages
266
267
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
267
- g_corridor = getSpaceByName('G Corridor').get
268
- infiltration_g_corridor_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
268
+ g_corridor = model.getSpaceByName('G Corridor').get
269
+ infiltration_g_corridor_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model)
269
270
  infiltration_g_corridor_door.setName('G Corridor door Infiltration')
270
271
  infiltration_g_corridor_door.setSpace(g_corridor)
271
272
  case template
272
273
  when '90.1-2004'
273
274
  infiltration_g_corridor_door.setDesignFlowRate(0.520557541)
274
- infiltration_g_corridor_door.setSchedule(add_schedule('ApartmentMidRise INFIL_Door_Opening_SCH_2004_2007'))
275
+ infiltration_g_corridor_door.setSchedule(model.add_schedule('ApartmentMidRise INFIL_Door_Opening_SCH_2004_2007'))
275
276
  when '90.1-2007'
276
277
  case climate_zone
277
278
  when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B'
@@ -279,7 +280,7 @@ class OpenStudio::Model::Model
279
280
  else
280
281
  infiltration_g_corridor_door.setDesignFlowRate(0.327531218)
281
282
  end
282
- infiltration_g_corridor_door.setSchedule(add_schedule('ApartmentMidRise INFIL_Door_Opening_SCH_2004_2007'))
283
+ infiltration_g_corridor_door.setSchedule(model.add_schedule('ApartmentMidRise INFIL_Door_Opening_SCH_2004_2007'))
283
284
  when '90.1-2010', '90.1-2013'
284
285
  case climate_zone
285
286
  when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B'
@@ -287,14 +288,15 @@ class OpenStudio::Model::Model
287
288
  else
288
289
  infiltration_g_corridor_door.setDesignFlowRate(0.327531218)
289
290
  end
290
- infiltration_g_corridor_door.setSchedule(add_schedule('ApartmentMidRise INFIL_Door_Opening_SCH_2010_2013'))
291
+ infiltration_g_corridor_door.setSchedule(model.add_schedule('ApartmentMidRise INFIL_Door_Opening_SCH_2010_2013'))
291
292
  end
292
293
  end
293
294
  end
294
295
 
295
- def custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
296
- update_waterheater_loss_coefficient(template)
296
+ def self.custom_swh_tweaks(building_type, template, climate_zone, prototype_input, model)
297
+ PrototypeBuilding::MidriseApartment.update_waterheater_loss_coefficient(template, model)
297
298
 
298
299
  return true
299
300
  end
300
301
  end
302
+ end
@@ -1,7 +1,8 @@
1
1
 
2
- # Extend the class to add Medium Office specific stuff
3
- class OpenStudio::Model::Model
4
- def define_space_type_map(building_type, template, climate_zone)
2
+ # Modules for building-type specific methods
3
+ module PrototypeBuilding
4
+ module Outpatient
5
+ def self.define_space_type_map(building_type, template, climate_zone)
5
6
  space_type_map = nil
6
7
  case template
7
8
  when 'NECB 2011'
@@ -133,7 +134,7 @@ class OpenStudio::Model::Model
133
134
  return space_type_map
134
135
  end
135
136
 
136
- def define_hvac_system_map(building_type, template, climate_zone)
137
+ def self.define_hvac_system_map(building_type, template, climate_zone)
137
138
  case template
138
139
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
139
140
  system_to_space_map = [
@@ -302,18 +303,18 @@ class OpenStudio::Model::Model
302
303
  return system_to_space_map
303
304
  end
304
305
 
305
- def custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
306
+ def self.custom_hvac_tweaks(building_type, template, climate_zone, prototype_input, model)
306
307
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding HVAC')
307
308
 
308
- system_to_space_map = define_hvac_system_map(building_type, template, climate_zone)
309
+ system_to_space_map = PrototypeBuilding::Outpatient.define_hvac_system_map(building_type, template, climate_zone)
309
310
 
310
311
  # add elevator for the elevator pump room (the fan&lights are already added via standard spreadsheet)
311
- add_extra_equip_elevator_pump_room(template)
312
+ PrototypeBuilding::Outpatient.add_extra_equip_elevator_pump_room(template, model)
312
313
  # adjust cooling setpoint at vintages 1B,2B,3B
313
- adjust_clg_setpoint(template, climate_zone)
314
+ PrototypeBuilding::Outpatient.adjust_clg_setpoint(template, climate_zone, model)
314
315
  # Get the hot water loop
315
316
  hot_water_loop = nil
316
- getPlantLoops.each do |loop|
317
+ model.getPlantLoops.each do |loop|
317
318
  # If it has a boiler:hotwater, it is the correct loop
318
319
  unless loop.supplyComponents('OS:Boiler:HotWater'.to_IddObjectType).empty?
319
320
  hot_water_loop = loop
@@ -321,27 +322,27 @@ class OpenStudio::Model::Model
321
322
  end
322
323
  # add humidifier to AHU1 (contains operating room 1)
323
324
  if hot_water_loop
324
- add_humidifier(template, hot_water_loop)
325
+ PrototypeBuilding::Outpatient.add_humidifier(template, hot_water_loop, model)
325
326
  else
326
327
  OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', 'Could not find hot water loop to attach humidifier to.')
327
328
  end
328
329
  # adjust infiltration for vintages 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
329
- adjust_infiltration(template)
330
+ PrototypeBuilding::Outpatient.adjust_infiltration(template, model)
330
331
  # add door infiltration for vertibule
331
- add_door_infiltration(template, climate_zone)
332
+ PrototypeBuilding::Outpatient.add_door_infiltration(template, climate_zone, model)
332
333
  # reset boiler sizing factor to 0.3 (default 1)
333
- reset_boiler_sizing_factor
334
+ PrototypeBuilding::Outpatient.reset_boiler_sizing_factor(model)
334
335
  # assign the minimum total air changes to the cooling minimum air flow in Sizing:Zone
335
- apply_minimum_total_ach(building_type, template)
336
+ PrototypeBuilding::Outpatient.apply_minimum_total_ach(building_type, template, model)
336
337
 
337
338
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding HVAC')
338
339
 
339
340
  return true
340
341
  end
341
342
 
342
- def add_extra_equip_elevator_pump_room(template)
343
- elevator_pump_room = getSpaceByName('Floor 1 Elevator Pump Room').get
344
- elec_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(self)
343
+ def self.add_extra_equip_elevator_pump_room(template, model)
344
+ elevator_pump_room = model.getSpaceByName('Floor 1 Elevator Pump Room').get
345
+ elec_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
345
346
  elec_equip_def.setName('Elevator Pump Room Electric Equipment Definition')
346
347
  elec_equip_def.setFractionLatent(0)
347
348
  elec_equip_def.setFractionRadiant(0.1)
@@ -352,33 +353,33 @@ class OpenStudio::Model::Model
352
353
  elec_equip.setSpace(elevator_pump_room)
353
354
  case template
354
355
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
355
- elec_equip.setSchedule(add_schedule('OutPatientHealthCare BLDG_ELEVATORS'))
356
+ elec_equip.setSchedule(model.add_schedule('OutPatientHealthCare BLDG_ELEVATORS'))
356
357
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
357
- elec_equip.setSchedule(add_schedule('OutPatientHealthCare BLDG_ELEVATORS_Pre2004'))
358
+ elec_equip.setSchedule(model.add_schedule('OutPatientHealthCare BLDG_ELEVATORS_Pre2004'))
358
359
  end
359
360
  return true
360
361
  end
361
362
 
362
- def adjust_clg_setpoint(template, climate_zone)
363
- getSpaceTypes.sort.each do |space_type|
363
+ def self.adjust_clg_setpoint(template, climate_zone, model)
364
+ model.getSpaceTypes.sort.each do |space_type|
364
365
  space_type_name = space_type.name.get
365
366
  thermostat_name = space_type_name + ' Thermostat'
366
- thermostat = getThermostatSetpointDualSetpointByName(thermostat_name).get
367
+ thermostat = model.getThermostatSetpointDualSetpointByName(thermostat_name).get
367
368
  case template
368
369
  when '90.1-2004', '90.1-2007', '90.1-2010'
369
370
  case climate_zone
370
371
  when 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-3B'
371
- thermostat.setCoolingSetpointTemperatureSchedule(add_schedule('OutPatientHealthCare CLGSETP_SCH_YES_OPTIMUM'))
372
+ thermostat.setCoolingSetpointTemperatureSchedule(model.add_schedule('OutPatientHealthCare CLGSETP_SCH_YES_OPTIMUM'))
372
373
  end
373
374
  end
374
375
  end
375
376
  return true
376
377
  end
377
378
 
378
- def adjust_infiltration(template)
379
+ def self.adjust_infiltration(template, model)
379
380
  case template
380
381
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
381
- getSpaces.sort.each do |space|
382
+ model.getSpaces.sort.each do |space|
382
383
  space_type = space.spaceType.get
383
384
  # Skip interior spaces
384
385
  next if space.exterior_wall_and_window_area <= 0
@@ -396,14 +397,14 @@ class OpenStudio::Model::Model
396
397
  infil_ach = infiltration_space_type.airChangesperHour.get
397
398
  end
398
399
  # Create an infiltration rate object for this space
399
- infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
400
+ infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model)
400
401
  infiltration.setName("#{space.name} Infiltration")
401
402
  infiltration.setFlowperExteriorSurfaceArea(infil_rate) unless infil_rate.nil? || infil_rate.to_f.zero?
402
403
  infiltration.setAirChangesperHour(infil_ach) unless infil_ach.nil? || infil_ach.to_f.zero?
403
404
  infiltration.setSchedule(infil_sch)
404
405
  infiltration.setSpace(space)
405
406
  end
406
- getSpaceTypes.each do |space_type|
407
+ model.getSpaceTypes.each do |space_type|
407
408
  space_type.spaceInfiltrationDesignFlowRates.each(&:remove)
408
409
  end
409
410
  else
@@ -411,28 +412,28 @@ class OpenStudio::Model::Model
411
412
  end
412
413
  end
413
414
 
414
- def add_door_infiltration(template, climate_zone)
415
+ def self.add_door_infiltration(template, climate_zone, model)
415
416
  # add extra infiltration for vestibule door
416
417
  case template
417
418
  when 'DOE Ref 1980-2004', 'DOE Ref Pre-1980'
418
419
  return true
419
420
  else
420
- vestibule_space = getSpaceByName('Floor 1 Vestibule').get
421
- infiltration_vestibule_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
421
+ vestibule_space = model.getSpaceByName('Floor 1 Vestibule').get
422
+ infiltration_vestibule_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model)
422
423
  infiltration_vestibule_door.setName('Vestibule door Infiltration')
423
424
  infiltration_rate_vestibule_door = 0
424
425
  case template
425
426
  when '90.1-2004'
426
427
  infiltration_rate_vestibule_door = 1.186002811
427
- infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
428
+ infiltration_vestibule_door.setSchedule(model.add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
428
429
  when '90.1-2007', '90.1-2010', '90.1-2013'
429
430
  case climate_zone
430
431
  when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B'
431
432
  infiltration_rate_vestibule_door = 1.186002811
432
- infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
433
+ infiltration_vestibule_door.setSchedule(model.add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
433
434
  else
434
435
  infiltration_rate_vestibule_door = 0.776824762
435
- infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.131'))
436
+ infiltration_vestibule_door.setSchedule(model.add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.131'))
436
437
  end
437
438
  end
438
439
  infiltration_vestibule_door.setDesignFlowRate(infiltration_rate_vestibule_door)
@@ -440,10 +441,10 @@ class OpenStudio::Model::Model
440
441
  end
441
442
  end
442
443
 
443
- def update_waterheater_loss_coefficient(template)
444
+ def self.update_waterheater_loss_coefficient(template, model)
444
445
  case template
445
446
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', 'NECB 2011'
446
- getWaterHeaterMixeds.sort.each do |water_heater|
447
+ model.getWaterHeaterMixeds.sort.each do |water_heater|
447
448
  if water_heater.name.to_s.include?('Booster')
448
449
  water_heater.setOffCycleLossCoefficienttoAmbientTemperature(1.053159296)
449
450
  water_heater.setOnCycleLossCoefficienttoAmbientTemperature(1.053159296)
@@ -456,16 +457,16 @@ class OpenStudio::Model::Model
456
457
  end
457
458
 
458
459
  # add humidifier to AHU1 (contains operating room1)
459
- def add_humidifier(template, hot_water_loop)
460
- operatingroom1_space = getSpaceByName('Floor 1 Operating Room 1').get
460
+ def self.add_humidifier(template, hot_water_loop, model)
461
+ operatingroom1_space = model.getSpaceByName('Floor 1 Operating Room 1').get
461
462
  operatingroom1_zone = operatingroom1_space.thermalZone.get
462
- humidistat = OpenStudio::Model::ZoneControlHumidistat.new(self)
463
- humidistat.setHumidifyingRelativeHumiditySetpointSchedule(add_schedule('OutPatientHealthCare MinRelHumSetSch'))
464
- humidistat.setDehumidifyingRelativeHumiditySetpointSchedule(add_schedule('OutPatientHealthCare MaxRelHumSetSch'))
463
+ humidistat = OpenStudio::Model::ZoneControlHumidistat.new(model)
464
+ humidistat.setHumidifyingRelativeHumiditySetpointSchedule(model.add_schedule('OutPatientHealthCare MinRelHumSetSch'))
465
+ humidistat.setDehumidifyingRelativeHumiditySetpointSchedule(model.add_schedule('OutPatientHealthCare MaxRelHumSetSch'))
465
466
  operatingroom1_zone.setZoneControlHumidistat(humidistat)
466
- getAirLoopHVACs.each do |air_loop|
467
+ model.getAirLoopHVACs.each do |air_loop|
467
468
  if air_loop.thermalZones.include? operatingroom1_zone
468
- humidifier = OpenStudio::Model::HumidifierSteamElectric.new(self)
469
+ humidifier = OpenStudio::Model::HumidifierSteamElectric.new(model)
469
470
  humidifier.setRatedCapacity(3.72E-5)
470
471
  humidifier.setRatedPower(100_000)
471
472
  humidifier.setName("#{air_loop.name.get} Electric Steam Humidifier")
@@ -479,12 +480,12 @@ class OpenStudio::Model::Model
479
480
  heating_coil_outlet_node = htg_coil.airOutletModelObject.get.to_Node.get
480
481
  supply_outlet_node = air_loop.supplyOutletNode
481
482
  humidifier.addToNode(heating_coil_outlet_node)
482
- humidity_spm = OpenStudio::Model::SetpointManagerSingleZoneHumidityMinimum.new(self)
483
+ humidity_spm = OpenStudio::Model::SetpointManagerSingleZoneHumidityMinimum.new(model)
483
484
  case template
484
485
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
485
- extra_elec_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self, alwaysOnDiscreteSchedule)
486
+ extra_elec_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model, model.alwaysOnDiscreteSchedule)
486
487
  extra_elec_htg_coil.setName('AHU1 extra Electric Htg Coil')
487
- extra_water_htg_coil = OpenStudio::Model::CoilHeatingWater.new(self, alwaysOnDiscreteSchedule)
488
+ extra_water_htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule)
488
489
  extra_water_htg_coil.setName('AHU1 extra Water Htg Coil')
489
490
  hot_water_loop.addDemandBranchForComponent(extra_water_htg_coil)
490
491
  extra_elec_htg_coil.addToNode(supply_outlet_node)
@@ -499,52 +500,52 @@ class OpenStudio::Model::Model
499
500
 
500
501
  # for 90.1-2010 Outpatient, AHU2 set minimum outdoor air flow rate as 0
501
502
  # AHU1 doesn't have economizer
502
- def modify_oa_controller(template)
503
- getAirLoopHVACs.each do |air_loop|
503
+ def self.modify_oa_controller(template, model)
504
+ model.getAirLoopHVACs.each do |air_loop|
504
505
  oa_system = air_loop.airLoopHVACOutdoorAirSystem.get
505
506
  controller_oa = oa_system.getControllerOutdoorAir
506
507
  controller_mv = controller_oa.controllerMechanicalVentilation
507
508
  # AHU1 OA doesn't have controller:mechanicalventilation
508
509
  if air_loop.name.to_s.include? 'Outpatient F1'
509
- controller_mv.setAvailabilitySchedule(alwaysOffDiscreteSchedule)
510
+ controller_mv.setAvailabilitySchedule(model.alwaysOffDiscreteSchedule)
510
511
  # add minimum fraction of outdoor air schedule to AHU1
511
- controller_oa.setMinimumFractionofOutdoorAirSchedule(add_schedule('OutPatientHealthCare AHU-1_OAminOAFracSchedule'))
512
+ controller_oa.setMinimumFractionofOutdoorAirSchedule(model.add_schedule('OutPatientHealthCare AHU-1_OAminOAFracSchedule'))
512
513
  # for AHU2, at vintages '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013', the minimum OA schedule is not the same as
513
514
  # airloop availability schedule, but separately assigned.
514
515
  elsif template == '90.1-2004' || template == '90.1-2007' || template == '90.1-2010' || template == '90.1-2013'
515
- controller_oa.setMinimumOutdoorAirSchedule(add_schedule('OutPatientHealthCare BLDG_OA_SCH'))
516
+ controller_oa.setMinimumOutdoorAirSchedule(model.add_schedule('OutPatientHealthCare BLDG_OA_SCH'))
516
517
  # add minimum fraction of outdoor air schedule to AHU2
517
- controller_oa.setMinimumFractionofOutdoorAirSchedule(add_schedule('OutPatientHealthCare BLDG_OA_FRAC_SCH'))
518
+ controller_oa.setMinimumFractionofOutdoorAirSchedule(model.add_schedule('OutPatientHealthCare BLDG_OA_FRAC_SCH'))
518
519
  end
519
520
  end
520
521
  end
521
522
 
522
523
  # For operating room 1&2 in 2010 and 2013, VAV minimum air flow is set by schedule
523
- def reset_or_room_vav_minimum_damper(prototype_input, template)
524
+ def self.reset_or_room_vav_minimum_damper(prototype_input, template, model)
524
525
  case template
525
526
  when '90.1-2004', '90.1-2007'
526
527
  return true
527
528
  when '90.1-2010', '90.1-2013'
528
- getAirTerminalSingleDuctVAVReheats.sort.each do |airterminal|
529
+ model.getAirTerminalSingleDuctVAVReheats.sort.each do |airterminal|
529
530
  airterminal_name = airterminal.name.get
530
531
  if airterminal_name.include?('Floor 1 Operating Room 1') || airterminal_name.include?('Floor 1 Operating Room 2')
531
532
  airterminal.setZoneMinimumAirFlowMethod('Scheduled')
532
- airterminal.setMinimumAirFlowFractionSchedule(add_schedule('OutPatientHealthCare OR_MinSA_Sched'))
533
+ airterminal.setMinimumAirFlowFractionSchedule(model.add_schedule('OutPatientHealthCare OR_MinSA_Sched'))
533
534
  end
534
535
  end
535
536
  end
536
537
  end
537
538
 
538
- def reset_boiler_sizing_factor
539
- getBoilerHotWaters.sort.each do |boiler|
539
+ def self.reset_boiler_sizing_factor(model)
540
+ model.getBoilerHotWaters.sort.each do |boiler|
540
541
  boiler.setSizingFactor(0.3)
541
542
  end
542
543
  end
543
544
 
544
- def update_exhaust_fan_efficiency(template)
545
+ def self.update_exhaust_fan_efficiency(template, model)
545
546
  case template
546
547
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
547
- getFanZoneExhausts.sort.each do |exhaust_fan|
548
+ model.getFanZoneExhausts.sort.each do |exhaust_fan|
548
549
  fan_name = exhaust_fan.name.to_s
549
550
  if (fan_name.include? 'X-Ray') || (fan_name.include? 'MRI Room')
550
551
  exhaust_fan.setFanEfficiency(0.16)
@@ -555,7 +556,7 @@ class OpenStudio::Model::Model
555
556
  end
556
557
  end
557
558
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
558
- getFanZoneExhausts.sort.each do |exhaust_fan|
559
+ model.getFanZoneExhausts.sort.each do |exhaust_fan|
559
560
  exhaust_fan.setFanEfficiency(0.338)
560
561
  exhaust_fan.setPressureRise(125)
561
562
  end
@@ -563,15 +564,15 @@ class OpenStudio::Model::Model
563
564
  end
564
565
 
565
566
  # assign the minimum total air changes to the cooling minimum air flow in Sizing:Zone
566
- def apply_minimum_total_ach(building_type, template)
567
- getSpaces.each do |space|
567
+ def self.apply_minimum_total_ach(building_type, template, model)
568
+ model.getSpaces.each do |space|
568
569
  space_type_name = space.spaceType.get.standardsSpaceType.get
569
570
  search_criteria = {
570
571
  'template' => template,
571
572
  'building_type' => building_type,
572
573
  'space_type' => space_type_name
573
574
  }
574
- data = find_object($os_standards['space_types'], search_criteria)
575
+ data = model.find_object($os_standards['space_types'], search_criteria)
575
576
 
576
577
  # skip space type without minimum total air changes
577
578
  next if data['minimum_total_air_changes'].nil?
@@ -595,9 +596,10 @@ class OpenStudio::Model::Model
595
596
  end
596
597
  end
597
598
 
598
- def custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
599
- update_waterheater_loss_coefficient(template)
599
+ def self.custom_swh_tweaks(building_type, template, climate_zone, prototype_input, model)
600
+ PrototypeBuilding::Outpatient.update_waterheater_loss_coefficient(template, model)
600
601
 
601
602
  return true
602
603
  end
603
604
  end
605
+ end