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.
- checksums.yaml +4 -4
- data/data/geometry/Geometry.hospital.osm +118 -109
- data/data/geometry/Geometry.hospital_original.osm +8947 -0
- data/data/geometry/Geometry.large_office_2010.osm +118 -102
- data/data/standards/OpenStudio_Standards.xlsx +0 -0
- data/data/standards/OpenStudio_Standards_construction_properties.json +1993 -1959
- data/data/standards/OpenStudio_Standards_construction_sets.json +18 -18
- data/data/standards/OpenStudio_Standards_constructions.json +28 -0
- data/data/standards/OpenStudio_Standards_ground_temperatures.json +561 -1071
- data/data/standards/OpenStudio_Standards_materials.json +2 -2
- data/data/standards/OpenStudio_Standards_prototype_inputs.json +32 -32
- data/data/standards/OpenStudio_Standards_schedules.json +435 -20
- data/data/standards/OpenStudio_Standards_space_types.json +2005 -614
- data/lib/openstudio-standards/hvac_sizing/HVACSizing.CoilCoolingWaterToAirHeatPumpEquationFit.rb +49 -7
- data/lib/openstudio-standards/hvac_sizing/HVACSizing.CoilHeatingWaterToAirHeatPumpEquationFit.rb +37 -7
- data/lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb +7 -0
- data/lib/openstudio-standards/hvac_sizing/HVACSizing.PumpVariableSpeed.rb +1 -1
- data/lib/openstudio-standards/prototypes/Prototype.AirTerminalSingleDuctVAVReheat.rb +14 -5
- data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +15 -5
- data/lib/openstudio-standards/prototypes/Prototype.Model.rb +59 -37
- data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +5 -3
- data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +86 -26
- data/lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb +97 -16
- data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +217 -6
- data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +48 -1
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +126 -27
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +14 -1
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +40 -1
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +4 -2
- data/lib/openstudio-standards/version.rb +1 -1
- 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
|
-
|
233
|
+
end
|
234
|
+
|
234
235
|
|
235
|
-
|
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
|
-
|
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
|
-
|
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'
|
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
|
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
|
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
|
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
|