openstudio-standards 0.1.0 → 0.1.1

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/Geometry.hospital.osm +118 -109
  3. data/data/geometry/Geometry.hospital_original.osm +8947 -0
  4. data/data/geometry/Geometry.large_office_2010.osm +118 -102
  5. data/data/standards/OpenStudio_Standards.xlsx +0 -0
  6. data/data/standards/OpenStudio_Standards_construction_properties.json +1993 -1959
  7. data/data/standards/OpenStudio_Standards_construction_sets.json +18 -18
  8. data/data/standards/OpenStudio_Standards_constructions.json +28 -0
  9. data/data/standards/OpenStudio_Standards_ground_temperatures.json +561 -1071
  10. data/data/standards/OpenStudio_Standards_materials.json +2 -2
  11. data/data/standards/OpenStudio_Standards_prototype_inputs.json +32 -32
  12. data/data/standards/OpenStudio_Standards_schedules.json +435 -20
  13. data/data/standards/OpenStudio_Standards_space_types.json +2005 -614
  14. data/lib/openstudio-standards/hvac_sizing/HVACSizing.CoilCoolingWaterToAirHeatPumpEquationFit.rb +49 -7
  15. data/lib/openstudio-standards/hvac_sizing/HVACSizing.CoilHeatingWaterToAirHeatPumpEquationFit.rb +37 -7
  16. data/lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb +7 -0
  17. data/lib/openstudio-standards/hvac_sizing/HVACSizing.PumpVariableSpeed.rb +1 -1
  18. data/lib/openstudio-standards/prototypes/Prototype.AirTerminalSingleDuctVAVReheat.rb +14 -5
  19. data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +15 -5
  20. data/lib/openstudio-standards/prototypes/Prototype.Model.rb +59 -37
  21. data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +5 -3
  22. data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +86 -26
  23. data/lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb +97 -16
  24. data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +217 -6
  25. data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +48 -1
  26. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +126 -27
  27. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +1 -1
  28. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +14 -1
  29. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +40 -1
  30. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +4 -2
  31. data/lib/openstudio-standards/version.rb +1 -1
  32. metadata +3 -2
@@ -230,9 +230,10 @@ class OpenStudio::Model::Model
230
230
  if condenser_water_loop
231
231
  condenser_water_loop.addDemandBranchForComponent(chiller)
232
232
  chiller.setCondenserType('WaterCooled')
233
- end
233
+ end
234
+
234
235
 
235
- #chilled water loop pipes
236
+ #chilled water loop pipes
236
237
  chiller_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self)
237
238
  chilled_water_loop.addSupplyBranchForComponent(chiller_bypass_pipe)
238
239
  coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(self)
@@ -622,7 +623,6 @@ class OpenStudio::Model::Model
622
623
  oa_intake_controller.setEconomizerControlType("DifferentialEnthalpy")
623
624
  oa_intake_controller.setHeatRecoveryBypassControlType("BypassWhenOAFlowGreaterThanMinimum")
624
625
  oa_intake_controller.resetMaximumFractionofOutdoorAirSchedule
625
- oa_intake_controller.resetMaximumFractionofOutdoorAirSchedule
626
626
  oa_intake_controller.resetEconomizerMinimumLimitDryBulbTemperature
627
627
  end
628
628
 
@@ -650,9 +650,8 @@ class OpenStudio::Model::Model
650
650
  terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(self,self.alwaysOnDiscreteSchedule,rht_coil)
651
651
  terminal.setName("#{zone.name} VAV Term")
652
652
  terminal.setZoneMinimumAirFlowMethod('Constant')
653
-
654
- terminal.set_initial_prototype_damper_position(standard, zone.outdoor_airflow_rate_per_area)
655
-
653
+
654
+ terminal.set_initial_prototype_damper_position(building_type, standard, zone.outdoor_airflow_rate_per_area)
656
655
  terminal.setMaximumFlowPerZoneFloorAreaDuringReheat(0.0)
657
656
  terminal.setMaximumFlowFractionDuringReheat(0.5)
658
657
  terminal.setMaximumReheatAirTemperature(rht_sa_temp_c)
@@ -873,7 +872,8 @@ class OpenStudio::Model::Model
873
872
  hvac_op_sch,
874
873
  oa_damper_sch,
875
874
  hot_water_loop = nil,
876
- return_plenum = nil)
875
+ return_plenum = nil,
876
+ building_type = nil)
877
877
 
878
878
  OpenStudio::logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding Packaged VAV for #{thermal_zones.size} zones.")
879
879
  thermal_zones.each do |zone|
@@ -911,7 +911,11 @@ class OpenStudio::Model::Model
911
911
  zn_dsn_htg_sa_temp_f = 122 # Design VAV box to reheat to 122F
912
912
  rht_rated_air_in_temp_f = 62 # Reheat coils designed to receive 62F
913
913
  rht_rated_air_out_temp_f = 90 # Reheat coils designed to supply 90F...but zone expects 122F...?
914
- clg_sa_temp_f = 55 # Central deck clg temp operates at 55F
914
+ if sys_name == 'PVAV Outpatient F1'
915
+ clg_sa_temp_f = 52 # for AHU1 in Outpatient, SAT is 52F
916
+ else
917
+ clg_sa_temp_f = 55 # Central deck clg temp operates at 55F
918
+ end
915
919
 
916
920
  sys_dsn_prhtg_temp_c = OpenStudio.convert(sys_dsn_prhtg_temp_f,'F','C').get
917
921
  sys_dsn_clg_sa_temp_c = OpenStudio.convert(sys_dsn_clg_sa_temp_f,'F','C').get
@@ -985,6 +989,7 @@ class OpenStudio::Model::Model
985
989
  oa_intake.addToNode(air_loop.supplyInletNode)
986
990
  controller_mv = oa_intake_controller.controllerMechanicalVentilation
987
991
  controller_mv.setName("#{air_loop.name} Ventilation Controller")
992
+ controller_mv.setAvailabilitySchedule(oa_damper_sch)
988
993
 
989
994
  # Hook the VAV system to each zone
990
995
  thermal_zones.each do |zone|
@@ -1009,9 +1014,7 @@ class OpenStudio::Model::Model
1009
1014
  terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(self,self.alwaysOnDiscreteSchedule,rht_coil)
1010
1015
  terminal.setName("#{zone.name} VAV Term")
1011
1016
  terminal.setZoneMinimumAirFlowMethod('Constant')
1012
-
1013
- terminal.set_initial_prototype_damper_position(standard, zone.outdoor_airflow_rate_per_area)
1014
-
1017
+ terminal.set_initial_prototype_damper_position(building_type, standard, zone.outdoor_airflow_rate_per_area)
1015
1018
  air_loop.addBranchForZone(zone,terminal.to_StraightComponent)
1016
1019
 
1017
1020
  unless return_plenum.nil?
@@ -1188,7 +1191,7 @@ class OpenStudio::Model::Model
1188
1191
  terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(self,self.alwaysOnDiscreteSchedule,rht_coil)
1189
1192
  terminal.setName("#{zone.name} VAV Term")
1190
1193
  terminal.setZoneMinimumAirFlowMethod('Constant')
1191
- terminal.set_initial_prototype_damper_position(standard, zone.outdoor_airflow_rate_per_area)
1194
+ terminal.set_initial_prototype_damper_position(building_type, standard, zone.outdoor_airflow_rate_per_area)
1192
1195
  terminal.setMaximumFlowPerZoneFloorAreaDuringReheat(0.0)
1193
1196
  terminal.setMaximumFlowFractionDuringReheat(0.5)
1194
1197
  terminal.setMaximumReheatAirTemperature(rht_sa_temp_c)
@@ -1743,7 +1746,15 @@ class OpenStudio::Model::Model
1743
1746
  oa_controller.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum')
1744
1747
  oa_system = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(self,oa_controller)
1745
1748
  oa_system.setName("#{air_loop.name} OA Sys")
1746
-
1749
+ econ_eff_sch = self.add_schedule('RetailStandalone PSZ_Econ_MaxOAFrac_Sch')
1750
+
1751
+ case standard
1752
+ when '90.1-2004','90.1-2007','90.1-2010','90.1-2013'
1753
+ oa_controller.setMaximumFractionofOutdoorAirSchedule(econ_eff_sch) if building_type == "RetailStandalone" || building_type == "RetailStripmall"
1754
+ when 'DOE Ref Pre-1980','DOE Ref 1980-2004'
1755
+ OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'No maximum fraction outdoor air schedule in PSZ for building types except RetailStandalone')
1756
+ end
1757
+
1747
1758
  # Add the components to the air loop
1748
1759
  # in order from closest to zone to furthest from zone
1749
1760
  supply_inlet_node = air_loop.supplyInletNode
@@ -3686,7 +3697,7 @@ class OpenStudio::Model::Model
3686
3697
 
3687
3698
  end
3688
3699
 
3689
- def add_swh_end_uses_by_space(building_type, building_vintage, climate_zone, swh_loop, space_type_name, space_name, space_multiplier = nil)
3700
+ def add_swh_end_uses_by_space(building_type, building_vintage, climate_zone, swh_loop, space_type_name, space_name, space_multiplier = nil, is_flow_per_area = true)
3690
3701
 
3691
3702
  # find the specific space_type properties from standard.json
3692
3703
  search_criteria = {
@@ -3708,7 +3719,11 @@ class OpenStudio::Model::Model
3708
3719
  # Water fixture definition
3709
3720
  water_fixture_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(self)
3710
3721
  rated_flow_rate_per_area = data['service_water_heating_peak_flow_per_area'].to_f # gal/h.ft2
3711
- rated_flow_rate_gal_per_hour = rated_flow_rate_per_area * space_area * space_multiplier # gal/h
3722
+ if is_flow_per_area
3723
+ rated_flow_rate_gal_per_hour = rated_flow_rate_per_area * space_area * space_multiplier # gal/h
3724
+ else
3725
+ rated_flow_rate_gal_per_hour = data['service_water_heating_peak_flow_rate'].to_f
3726
+ end
3712
3727
  rated_flow_rate_gal_per_min = rated_flow_rate_gal_per_hour/60 # gal/h to gal/min
3713
3728
  rated_flow_rate_m3_per_s = OpenStudio.convert(rated_flow_rate_gal_per_min,'gal/min','m^3/s').get
3714
3729
  # water_use_sensible_frac_sch = OpenStudio::Model::ScheduleConstant.new(self)
@@ -3875,7 +3890,7 @@ class OpenStudio::Model::Model
3875
3890
  fan.setFanEfficiency(0.58175)
3876
3891
  fan.setPressureRise(622.5) #Pa
3877
3892
  if fan_max_flow_rate != nil
3878
- fan.setMaximumFlowRate(fan_max_flow_rate)
3893
+ fan.setMaximumFlowRate(OpenStudio.convert(fan_max_flow_rate, 'cfm', 'm^3/s').get) # unit of fan_max_flow_rate is cfm
3879
3894
  else
3880
3895
  fan.autosizeMaximumFlowRate
3881
3896
  end
@@ -4143,6 +4158,72 @@ class OpenStudio::Model::Model
4143
4158
 
4144
4159
  end
4145
4160
 
4161
+ # Adds a zone ventilation design flow rate to each zone.
4162
+ #
4163
+ # @param availability_sch_name [String] the name of the fan availability schedule
4164
+ # @param flow_rate [Double] the ventilation design flow rate in m^3/s for Exhaust/Natural or
4165
+ # Flow Rate per Zone Floor Area in m^3/s-m^2 for Intake
4166
+ # @param ventilation_type [String] the zone ventilation type either Exhaust, Natural, or Intake
4167
+ # @param thermal_zones [Array<OpenStudio::Model::ThermalZone>] an array of thermal zones
4168
+ # @return [Array<OpenStudio::Model::ZoneVentilationDesignFlowRate>] an array of zone ventilation objects created
4169
+ def add_zone_ventilation(availability_sch_name,
4170
+ flow_rate,
4171
+ ventilation_type,
4172
+ thermal_zones)
4173
+
4174
+ # Make an exhaust fan for each zone
4175
+ zone_ventilations = []
4176
+ thermal_zones.each do |zone|
4177
+ ventilation = OpenStudio::Model::ZoneVentilationDesignFlowRate.new(self)
4178
+ ventilation.setName("#{zone.name} Ventilation")
4179
+ ventilation.setSchedule(self.add_schedule(availability_sch_name))
4180
+ ventilation.setVentilationType(ventilation_type)
4181
+
4182
+ ventilation.setAirChangesperHour(0)
4183
+ ventilation.setTemperatureTermCoefficient(0)
4184
+
4185
+ if ventilation_type == 'Exhaust'
4186
+ ventilation.setDesignFlowRateCalculationMethod("Flow/Zone")
4187
+ ventilation.setDesignFlowRate(flow_rate)
4188
+ ventilation.setFanPressureRise(31.1361206455786)
4189
+ ventilation.setFanTotalEfficiency(0.51)
4190
+ ventilation.setConstantTermCoefficient(1)
4191
+ ventilation.setVelocityTermCoefficient(0)
4192
+ ventilation.setMinimumIndoorTemperature(29.4444452244559)
4193
+ ventilation.setMaximumIndoorTemperature(100)
4194
+ ventilation.setDeltaTemperature(-100)
4195
+ elsif ventilation_type == 'Natural'
4196
+ ventilation.setDesignFlowRateCalculationMethod("Flow/Zone")
4197
+ ventilation.setDesignFlowRate(flow_rate)
4198
+ ventilation.setFanPressureRise(0)
4199
+ ventilation.setFanTotalEfficiency(1)
4200
+ ventilation.setConstantTermCoefficient(0)
4201
+ ventilation.setVelocityTermCoefficient(0.224)
4202
+ ventilation.setMinimumIndoorTemperature(-73.3333352760033)
4203
+ ventilation.setMaximumIndoorTemperature(29.4444452244559)
4204
+ ventilation.setDeltaTemperature(-100)
4205
+ elsif ventilation_type == 'Intake'
4206
+ ventilation.setDesignFlowRateCalculationMethod("Flow/Area")
4207
+ ventilation.setFlowRateperZoneFloorArea(flow_rate)
4208
+ ventilation.setFanPressureRise(49.8)
4209
+ ventilation.setFanTotalEfficiency(0.53625)
4210
+ ventilation.setConstantTermCoefficient(1)
4211
+ ventilation.setVelocityTermCoefficient(0)
4212
+ ventilation.setMinimumIndoorTemperature(7.5)
4213
+ ventilation.setMaximumIndoorTemperature(35)
4214
+ ventilation.setDeltaTemperature(-27.5)
4215
+ ventilation.setMinimumOutdoorTemperature(-30.0)
4216
+ ventilation.setMaximumOutdoorTemperature(50.0)
4217
+ ventilation.setMaximumWindSpeed(6.0)
4218
+ end
4219
+ ventilation.addToThermalZone(zone)
4220
+ zone_ventilations << ventilation
4221
+ end
4222
+
4223
+ return zone_ventilations
4224
+
4225
+ end
4226
+
4146
4227
  # Adds a single refrigerated case connected to a rack composed
4147
4228
  # of a single compressor and a single air-cooled condenser.
4148
4229
  #
@@ -15,16 +15,17 @@ class OpenStudio::Model::Model
15
15
  'CleanWork' => ['Floor 1 Clean', 'Floor 1 Clean Work', ],
16
16
  'Conference' => ['Floor 2 Conference'],
17
17
  'DressingRoom' => ['Floor 1 Dressing Room', 'Floor 3 Dressing Room'],
18
- 'Elec/MechRoom' => ['Floor 1 Electrical Room', 'Floor 3 Mechanical', 'NW Elevator'],
18
+ 'Elec/MechRoom' => ['Floor 1 Electrical Room', 'Floor 3 Mechanical'],
19
19
  'ElevatorPumpRoom' => ['Floor 1 Elevator Pump Room'],
20
20
  # 'Floor 3 Treatment' same as 'Exam'
21
21
  'Exam' => ['Floor 2 Exam 1', 'Floor 2 Exam 2', 'Floor 2 Exam 3', 'Floor 2 Exam 4', 'Floor 2 Exam 5', 'Floor 2 Exam 6', 'Floor 2 Exam 7',
22
22
  'Floor 2 Exam 8', 'Floor 2 Exam 9', 'Floor 3 Treatment'],
23
23
  # 'Floor 1 Scrub', 'Floor 1 Sub-Sterile', 'Floor 1 Vestibule' same as 'Hall'
24
24
  'Hall' => ['Floor 1 IT Hall', 'Floor 1 Lobby Hall', 'Floor 1 Locker Room Hall', 'Floor 1 MRI Hall', 'Floor 1 Nurse Hall', 'Floor 1 Pre-Op Hall',
25
- 'Floor 1 Reception Hall', 'Floor 1 Sterile Hall', 'Floor 1 Utility Hall', 'Floor 2 Exam Hall 1', 'Floor 2 Exam Hall 2', 'Floor 2 Exam Hall 3',
25
+ 'Floor 1 Reception Hall', 'Floor 1 Sterile Hall', 'Floor 2 Exam Hall 1', 'Floor 2 Exam Hall 2', 'Floor 2 Exam Hall 3',
26
26
  'Floor 2 Exam Hall 4', 'Floor 2 Exam Hall 5', 'Floor 2 Exam Hall 6', 'Floor 2 Office Hall', 'Floor 2 Reception Hall', 'Floor 2 Work Hall',
27
- 'Floor 3 Elevator Hall', 'Floor 3 Mechanical Hall', 'Floor 3 Office Hall', 'Floor 1 Scrub', 'Floor 1 Sub-Sterile', 'Floor 1 Vestibule'],
27
+ 'Floor 3 Mechanical Hall', 'Floor 1 Scrub'],
28
+ 'Hall_infil' => ['Floor 1 Utility Hall', 'Floor 1 Sub-Sterile', 'Floor 1 Vestibule', 'Floor 3 Elevator Hall', 'Floor 3 Office Hall'],
28
29
  'IT_Room' => ['Floor 1 IT Room'],
29
30
  # ['Floor 1 Sterile Storage', 'Floor 1 Storage', 'Floor 1 Utility Room', 'Floor 2 Storage 1', 'Floor 2 Storage 2', 'Floor 2 Storage 3', ...
30
31
  # 'Floor 2 Utility', 'Floor 3 Storage 1', 'Floor 3 Storage 2', 'Floor 3 Utility'] same as 'Janitor'
@@ -51,7 +52,7 @@ class OpenStudio::Model::Model
51
52
  'PreOp' => ['Floor 1 Pre-Op Room 1', 'Floor 1 Pre-Op Room 2'],
52
53
  'ProcedureRoom' => ['Floor 1 Procedure Room'],
53
54
  'Soil Work' => ['Floor 1 Soil', 'Floor 1 Soil Hold', 'Floor 1 Soil Work'],
54
- 'Stair' => ['NE Stair', 'NW Stair', 'SW Stair'],
55
+ 'Stair' => ['NE Stair', 'NW Stair', 'SW Stair', 'NW Elevator'],
55
56
  'Toilet' => ['Floor 1 Nurse Toilet', 'Floor 1 Pre-Op Toilet', 'Floor 1 Lobby Toilet', 'Floor 1 MRI Toilet', 'Floor 2 Conference Toilet',
56
57
  'Floor 2 Reception Toilet', 'Floor 2 Work Toilet', 'Floor 3 Lounge Toilet', 'Floor 3 Office Toilet', 'Floor 3 Physical Therapy Toilet'],
57
58
  'Xray' => ['Floor 2 X-Ray'],
@@ -140,6 +141,9 @@ class OpenStudio::Model::Model
140
141
  'Floor 3 Treatment', 'Floor 3 Work'
141
142
  ]
142
143
  }
144
+ # {
145
+ # TODO exhaust fans
146
+ # }
143
147
  ]
144
148
  end
145
149
 
@@ -155,6 +159,28 @@ class OpenStudio::Model::Model
155
159
 
156
160
  # add elevator for the elevator pump room (the fan&lights are already added via standard spreadsheet)
157
161
  self.add_extra_equip_elevator_pump_room(building_vintage)
162
+ # adjust cooling setpoint at vintages 1B,2B,3B
163
+ self.adjust_clg_setpoint(building_vintage,climate_zone)
164
+ # Get the hot water loop
165
+ hot_water_loop = nil
166
+ self.getPlantLoops.each do |loop|
167
+ # If it has a boiler:hotwater, it is the correct loop
168
+ if loop.supplyComponents('Boiler:HotWater'.to_IddObjectType).size > 0
169
+ hot_water_loop = loop
170
+ end
171
+ end
172
+ # add humidifier to AHU1 (contains operating room 1)
173
+ if hot_water_loop
174
+ self.add_humidifier(building_vintage, hot_water_loop)
175
+ else
176
+ OpenStudio::logFree(OpenStudio::Warn, 'openstudio.model.Model', 'Could not find hot water loop to attach humidifier to.')
177
+ end
178
+ # adjust infiltration for vintages 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
179
+ self.adjust_infiltration(building_vintage)
180
+ # add door infiltration for vertibule
181
+ self.add_door_infiltration(building_vintage,climate_zone)
182
+ # reset boiler sizing factor to 0.3 (default 1)
183
+ self.reset_boiler_sizing_factor
158
184
 
159
185
  OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding HVAC')
160
186
 
@@ -179,12 +205,197 @@ class OpenStudio::Model::Model
179
205
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
180
206
  elec_equip.setSchedule(add_schedule("OutPatientHealthCare BLDG_ELEVATORS_Pre2004"))
181
207
  end
208
+ return true
182
209
  end
183
210
 
184
- def custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input)
211
+ def adjust_clg_setpoint(building_vintage,climate_zone)
212
+ self.getSpaceTypes.sort.each do |space_type|
213
+ space_type_name = space_type.name.get
214
+ thermostat_name = space_type_name + ' Thermostat'
215
+ thermostat = self.getThermostatSetpointDualSetpointByName(thermostat_name).get
216
+ case building_vintage
217
+ when '90.1-2004', '90.1-2007', '90.1-2010'
218
+ case climate_zone
219
+ when 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-3B'
220
+ thermostat.setCoolingSetpointTemperatureSchedule(add_schedule("OutPatientHealthCare CLGSETP_SCH_YES_OPTIMUM"))
221
+ end
222
+ end
223
+ end
224
+ return true
225
+ end
226
+
227
+ def adjust_infiltration(building_vintage)
228
+ case building_vintage
229
+ when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
230
+ self.getSpaces.sort.each do |space|
231
+ space_type = space.spaceType.get
232
+ if space.exterior_wall_and_window_area <= 0
233
+ next
234
+ elsif space_type.spaceInfiltrationDesignFlowRates.size <= 0
235
+ next
236
+ else
237
+ # get the infiltration information from the space type infiltration
238
+ infiltration_space_type = space_type.spaceInfiltrationDesignFlowRates[0]
239
+ infil_sch = infiltration_space_type.schedule.get
240
+ infil_rate = nil
241
+ infil_ach = nil
242
+ if infiltration_space_type.flowperExteriorWallArea.is_initialized
243
+ infil_rate = infiltration_space_type.flowperExteriorWallArea.get
244
+ elsif infiltration_space_type.airChangesperHour.is_initialized
245
+ infil_ach = infiltration_space_type.airChangesperHour.get
246
+ end
247
+ # Create an infiltration rate object for this space
248
+ infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
249
+ infiltration.setName("#{space.name} Infiltration")
250
+ infiltration.setFlowperExteriorSurfaceArea(infil_rate) unless infil_rate.nil? || infil_rate.to_f == 0
251
+ infiltration.setAirChangesperHour(infil_ach) unless infil_ach.nil? || infil_ach.to_f == 0
252
+ infiltration.setSchedule(infil_sch)
253
+ infiltration.setSpace(space)
254
+ end
255
+ end
256
+ self.getSpaceTypes.each do |space_type|
257
+ space_type.spaceInfiltrationDesignFlowRates.each do |infil|
258
+ infil.remove
259
+ end
260
+ end
261
+ else
262
+ return true
263
+ end
264
+ end
185
265
 
266
+ def add_door_infiltration(building_vintage,climate_zone)
267
+ # add extra infiltration for vestibule door
268
+ case building_vintage
269
+ when 'DOE Ref 1980-2004', 'DOE Ref Pre-1980'
270
+ return true
271
+ else
272
+ vestibule_space = self.getSpaceByName('Floor 1 Vestibule').get
273
+ infiltration_vestibule_door = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(self)
274
+ infiltration_vestibule_door.setName("Vestibule door Infiltration")
275
+ infiltration_rate_vestibule_door = 0
276
+ case building_vintage
277
+ when '90.1-2004'
278
+ infiltration_rate_vestibule_door = 1.186002811
279
+ infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
280
+ when '90.1-2007', '90.1-2010', '90.1-2013'
281
+ case climate_zone
282
+ when 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B'
283
+ infiltration_rate_vestibule_door = 1.186002811
284
+ infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.144'))
285
+ else
286
+ infiltration_rate_vestibule_door = 0.776824762
287
+ infiltration_vestibule_door.setSchedule(add_schedule('OutPatientHealthCare INFIL_Door_Opening_SCH_0.131'))
288
+ end
289
+ end
290
+ infiltration_vestibule_door.setDesignFlowRate(infiltration_rate_vestibule_door)
291
+ infiltration_vestibule_door.setSpace(vestibule_space)
292
+ end
293
+ end
294
+
295
+ def update_waterheater_loss_coefficient(building_vintage)
296
+ case building_vintage
297
+ when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
298
+ self.getWaterHeaterMixeds.sort.each do |water_heater|
299
+ if water_heater.name.to_s.include?("Booster")
300
+ water_heater.setOffCycleLossCoefficienttoAmbientTemperature(1.053159296)
301
+ water_heater.setOnCycleLossCoefficienttoAmbientTemperature(1.053159296)
302
+ else
303
+ water_heater.setOffCycleLossCoefficienttoAmbientTemperature(9.643286505)
304
+ water_heater.setOnCycleLossCoefficienttoAmbientTemperature(9.643286505)
305
+ end
306
+ end
307
+ end
308
+ end
309
+
310
+ def custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input)
311
+
312
+ self.update_waterheater_loss_coefficient(building_vintage)
313
+
186
314
  return true
187
315
 
188
- end
316
+ end
317
+
318
+ # add humidifier to AHU1 (contains operating room1)
319
+ def add_humidifier(building_vintage, hot_water_loop)
320
+ operatingroom1_space = self.getSpaceByName('Floor 1 Operating Room 1').get
321
+ operatingroom1_zone = operatingroom1_space.thermalZone.get
322
+ humidistat = OpenStudio::Model::ZoneControlHumidistat.new(self)
323
+ humidistat.setHumidifyingRelativeHumiditySetpointSchedule(self.add_schedule('OutPatientHealthCare MinRelHumSetSch'))
324
+ humidistat.setDehumidifyingRelativeHumiditySetpointSchedule(self.add_schedule('OutPatientHealthCare MaxRelHumSetSch'))
325
+ operatingroom1_zone.setZoneControlHumidistat(humidistat)
326
+ self.getAirLoopHVACs.each do |air_loop|
327
+ if air_loop.thermalZones.include? operatingroom1_zone
328
+ humidifier = OpenStudio::Model::HumidifierSteamElectric.new(self)
329
+ humidifier.setRatedCapacity(3.72E-5)
330
+ humidifier.setRatedPower(100000)
331
+ humidifier.setName("#{air_loop.name.get} Electric Steam Humidifier")
332
+ # get the water heating coil and add humidifier to the outlet of heating coil (right before fan)
333
+ htg_coil = nil
334
+ air_loop.supplyComponents.each do |equip|
335
+ if equip.to_CoilHeatingWater.is_initialized
336
+ htg_coil = equip.to_CoilHeatingWater.get
337
+ end
338
+ end
339
+ heating_coil_outlet_node = htg_coil.airOutletModelObject().get.to_Node.get
340
+ supply_outlet_node = air_loop.supplyOutletNode
341
+ humidifier.addToNode(heating_coil_outlet_node)
342
+ humidity_spm = OpenStudio::Model::SetpointManagerSingleZoneHumidityMinimum.new(self)
343
+ case building_vintage
344
+ when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
345
+ extra_elec_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(self,self.alwaysOnDiscreteSchedule)
346
+ extra_elec_htg_coil.setName("AHU1 extra Electric Htg Coil")
347
+ extra_water_htg_coil = OpenStudio::Model::CoilHeatingWater.new(self,self.alwaysOnDiscreteSchedule)
348
+ extra_water_htg_coil.setName("AHU1 extra Water Htg Coil")
349
+ hot_water_loop.addDemandBranchForComponent(extra_water_htg_coil)
350
+ extra_elec_htg_coil.addToNode(supply_outlet_node)
351
+ extra_water_htg_coil.addToNode(supply_outlet_node)
352
+ end
353
+ # humidity_spm.addToNode(supply_outlet_node)
354
+ humidity_spm.addToNode(humidifier.outletModelObject().get.to_Node.get)
355
+ humidity_spm.setControlZone(operatingroom1_zone)
356
+ end
357
+ end
358
+ end
359
+
360
+ # for 90.1-2010 Outpatient, AHU2 set minimum outdoor air flow rate as 0
361
+ # AHU1 doesn't have economizer
362
+ def modify_OAcontroller(building_vintage)
363
+ self.getAirLoopHVACs.each do |air_loop|
364
+ oa_sys = air_loop.airLoopHVACOutdoorAirSystem.get
365
+ oa_control = oa_sys.getControllerOutdoorAir
366
+ if air_loop.name.get == 'PVAV Outpatient F1'
367
+ oa_control.setEconomizerControlType('NoEconomizer')
368
+ elsif air_loop.name.get == 'PVAV Outpatient F2 F3'
369
+ case building_vintage
370
+ when '90.1-2010'
371
+ oa_control.setMinimumOutdoorAirFlowRate(0)
372
+ else
373
+ next
374
+ end
375
+ end
376
+ end
377
+ end
378
+
379
+ # For operating room 1&2 in 2010 and 2013, VAV minimum air flow is set by schedule
380
+ def reset_or_room_vav_minimum_damper(prototype_input, building_vintage)
381
+ case building_vintage
382
+ when '90.1-2004', '90.1-2007'
383
+ return true
384
+ when '90.1-2010', '90.1-2013'
385
+ self.getAirTerminalSingleDuctVAVReheats.sort.each do |airterminal|
386
+ airterminal_name = airterminal.name.get
387
+ if airterminal_name.include? "Floor 1 Operating Room 1" or airterminal_name.include? "Floor 1 Operating Room 2"
388
+ airterminal.setZoneMinimumAirFlowMethod('Scheduled')
389
+ airterminal.setMinimumAirFlowFractionSchedule(add_schedule("OutPatientHealthCare OR_MinSA_Sched"))
390
+ end
391
+ end
392
+ end
393
+ end
394
+
395
+ def reset_boiler_sizing_factor
396
+ self.getBoilerHotWaters.sort.each do |boiler|
397
+ boiler.setSizingFactor(0.3)
398
+ end
399
+ end
189
400
 
190
401
  end