openstudio-standards 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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