openstudio-standards 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/geometry/ASHRAE90120042007LargeHotel.osm +55 -55
- data/data/geometry/ASHRAE9012010LargeHotel.osm +56 -56
- data/data/geometry/ASHRAE9012010SuperMarket.osm +153 -153
- data/data/geometry/ASHRAE9012013Hospital.osm +815 -874
- data/data/geometry/ASHRAE9012013LargeHotel.osm +56 -56
- data/data/geometry/ASHRAE9012013LargeOffice.osm +12 -3
- data/data/geometry/ASHRAE9012013MediumOffice.osm +8 -16
- data/data/geometry/ASHRAE9012013MidriseApartment.osm +792 -792
- data/data/geometry/ASHRAE9012013SuperMarket.osm +152 -152
- data/data/geometry/ASHRAEHospital.osm +815 -874
- data/data/geometry/ASHRAELargeOffice.osm +58 -49
- data/data/geometry/ASHRAEMediumOffice.osm +12 -3
- data/data/geometry/ASHRAEMidriseApartment.osm +792 -792
- data/data/geometry/ASHRAESmallOffice.osm +4 -4
- data/data/geometry/ASHRAESuperMarket.osm +152 -152
- data/data/geometry/DOERefLargeOffice.osm +38 -29
- data/data/geometry/DOERefMidriseApartment.osm +792 -792
- data/data/geometry/DOERefPre1980SmallOffice.osm +4 -4
- data/data/geometry/DOERefSmallHotel.osm +4 -4
- data/data/geometry/DOERefWarehouse.osm +80 -30
- data/data/standards/OpenStudio_Standards.xlsx +0 -0
- data/data/standards/OpenStudio_Standards_construction_sets.json +582 -238
- data/data/standards/OpenStudio_Standards_constructions.json +14 -14
- data/data/standards/OpenStudio_Standards_hvac_inference.json +741 -0
- data/data/standards/OpenStudio_Standards_prototype_inputs.json +12 -12
- data/data/standards/OpenStudio_Standards_schedules.json +1479 -622
- data/data/standards/OpenStudio_Standards_size_category.json +67 -0
- data/data/standards/OpenStudio_Standards_space_types.json +2640 -2032
- data/lib/openstudio-standards.rb +1 -0
- data/lib/openstudio-standards/btap/btap.rb +0 -1
- data/lib/openstudio-standards/btap/simmanager.rb +3 -10
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +24 -0
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +29 -4
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.elevators.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +68 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +36 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +743 -730
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +7 -2
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +95 -170
- data/lib/openstudio-standards/standards/Standards.Space.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +34 -1
- data/lib/openstudio-standards/standards/standard.rb +2 -0
- data/lib/openstudio-standards/version.rb +1 -1
- metadata +5 -2
data/lib/openstudio-standards.rb
CHANGED
@@ -253,6 +253,7 @@ module OpenstudioStandards
|
|
253
253
|
require_relative "#{proto}/common/objects/Prototype.Model.swh"
|
254
254
|
require_relative "#{proto}/common/objects/Prototype.refrigeration"
|
255
255
|
require_relative "#{proto}/common/objects/Prototype.ServiceWaterHeating"
|
256
|
+
require_relative "#{proto}/common/objects/Prototype.SizingSystem"
|
256
257
|
require_relative "#{proto}/common/objects/Prototype.utilities"
|
257
258
|
# 90.1-2004
|
258
259
|
require_relative "#{proto}/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirTerminalSingleDuctVAVReheat"
|
@@ -101,12 +101,10 @@ module BTAP
|
|
101
101
|
|
102
102
|
|
103
103
|
def getPaths
|
104
|
-
# Find EnergyPlus on this computer.
|
105
|
-
@ep_hash = OpenStudio::EnergyPlus::find_energyplus(BTAP::ENERGY_PLUS_MAJOR_VERSION,BTAP::ENERGY_PLUS_MINOR_VERSION)
|
106
104
|
#set the Energyplus.exe path variable
|
107
|
-
@ep_path = OpenStudio
|
105
|
+
@ep_path = OpenStudio.getEnergyPlusExecutable
|
108
106
|
#set the root folder for E+
|
109
|
-
@ep_parent_path =
|
107
|
+
@ep_parent_path = OpenStudio.getEnergyPlusDirectory
|
110
108
|
|
111
109
|
#find IDD path
|
112
110
|
idd_path = @ep_parent_path.to_s + "/Energy+.idd"
|
@@ -146,12 +144,7 @@ module BTAP
|
|
146
144
|
#@author Phylroy A. Lopez
|
147
145
|
#@return [String] a simple string of the epw file path, remember to escape the slashes..(i.e. // not / )
|
148
146
|
def self.find_energyplus_folder()
|
149
|
-
|
150
|
-
ep_hash = OpenStudio::EnergyPlus::find_energyplus(BTAP::ENERGY_PLUS_MAJOR_VERSION,BTAP::ENERGY_PLUS_MINOR_VERSION)
|
151
|
-
#set the Energyplus.exe path variable
|
152
|
-
ep_path = OpenStudio::Path.new( ep_hash[:energyplus_exe].to_s)
|
153
|
-
#set the root folder for E+
|
154
|
-
return ep_path.parent_path();
|
147
|
+
return OpenStudio.getEnergyPlusDirectory.to_s
|
155
148
|
end
|
156
149
|
|
157
150
|
#This method finds the eReadVarsESO.exe and returns the path string.
|
@@ -75,6 +75,30 @@ module LargeOffice
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
# set infiltration schedule for plenums
|
79
|
+
# @todo remove once infil_sch in Standards.Space pulls from default building infiltration schedule
|
80
|
+
model.getSpaces.each do |space|
|
81
|
+
next unless space.name.get.to_s.include? 'Plenum'
|
82
|
+
# add infiltration if DOE Ref vintage
|
83
|
+
if template == 'DOE Ref 1980-2004' || template == 'DOE Ref Pre-1980'
|
84
|
+
# Create an infiltration rate object for this space
|
85
|
+
infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(space.model)
|
86
|
+
infiltration.setName("#{space.name} Infiltration")
|
87
|
+
all_ext_infil_m3_per_s_per_m2 = OpenStudio.convert(0.2232, 'ft^3/min*ft^2', 'm^3/s*m^2').get
|
88
|
+
infiltration.setFlowperExteriorSurfaceArea(all_ext_infil_m3_per_s_per_m2)
|
89
|
+
infiltration.setSchedule(model_add_schedule(model, 'Large Office Infil Quarter On'))
|
90
|
+
infiltration.setConstantTermCoefficient(1.0)
|
91
|
+
infiltration.setTemperatureTermCoefficient(0.0)
|
92
|
+
infiltration.setVelocityTermCoefficient(0.0)
|
93
|
+
infiltration.setVelocitySquaredTermCoefficient(0.0)
|
94
|
+
infiltration.setSpace(space)
|
95
|
+
else
|
96
|
+
space.spaceInfiltrationDesignFlowRates.each do |infiltration_object|
|
97
|
+
infiltration_object.setSchedule(model_add_schedule(model, 'OfficeLarge INFIL_SCH_PNNL'))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
78
102
|
return true
|
79
103
|
end
|
80
104
|
|
@@ -25,6 +25,30 @@ module MediumOffice
|
|
25
25
|
add_door_infiltration(climate_zone, model)
|
26
26
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Added door infiltration')
|
27
27
|
|
28
|
+
# set infiltration schedule for plenums
|
29
|
+
# @todo remove once infil_sch in Standards.Space pulls from default building infiltration schedule
|
30
|
+
model.getSpaces.each do |space|
|
31
|
+
next unless space.name.get.to_s.include? 'Plenum'
|
32
|
+
# add infiltration if DOE Ref vintage
|
33
|
+
if template == 'DOE Ref 1980-2004' || template == 'DOE Ref Pre-1980'
|
34
|
+
# Create an infiltration rate object for this space
|
35
|
+
infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(space.model)
|
36
|
+
infiltration.setName("#{space.name} Infiltration")
|
37
|
+
all_ext_infil_m3_per_s_per_m2 = OpenStudio.convert(0.2232, 'ft^3/min*ft^2', 'm^3/s*m^2').get
|
38
|
+
infiltration.setFlowperExteriorSurfaceArea(all_ext_infil_m3_per_s_per_m2)
|
39
|
+
infiltration.setSchedule(model_add_schedule(model, 'Medium Office Infil Quarter On'))
|
40
|
+
infiltration.setConstantTermCoefficient(1.0)
|
41
|
+
infiltration.setTemperatureTermCoefficient(0.0)
|
42
|
+
infiltration.setVelocityTermCoefficient(0.0)
|
43
|
+
infiltration.setVelocitySquaredTermCoefficient(0.0)
|
44
|
+
infiltration.setSpace(space)
|
45
|
+
else
|
46
|
+
space.spaceInfiltrationDesignFlowRates.each do |infiltration_object|
|
47
|
+
infiltration_object.setSchedule(model_add_schedule(model, 'OfficeMedium INFIL_SCH_PNNL'))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
28
52
|
return true
|
29
53
|
end
|
30
54
|
|
@@ -59,10 +83,11 @@ module MediumOffice
|
|
59
83
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Adjusting daylight sensor positions and fractions')
|
60
84
|
|
61
85
|
adjustments = [
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
86
|
+
{
|
87
|
+
'stds_spc_type' => 'WholeBuilding - Md Office',
|
88
|
+
'sensor_1_frac' => 0.3835,
|
89
|
+
'sensor_2_frac' => 0.1395
|
90
|
+
}
|
66
91
|
]
|
67
92
|
|
68
93
|
# Adjust daylight sensors in each space
|
@@ -304,7 +304,7 @@ class Standard
|
|
304
304
|
'building_type' => building_type
|
305
305
|
}
|
306
306
|
|
307
|
-
prototype_input = model_find_object(standards_data['prototype_inputs'], search_criteria
|
307
|
+
prototype_input = model_find_object(standards_data['prototype_inputs'], search_criteria)
|
308
308
|
if prototype_input.nil?
|
309
309
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.prototype.elevators', "Could not find prototype inputs for #{search_criteria}, cannot add elevators.")
|
310
310
|
return nil
|
@@ -263,9 +263,9 @@ class Standard
|
|
263
263
|
fan_type: system['fan_type'])
|
264
264
|
|
265
265
|
when 'PTHP'
|
266
|
-
|
267
|
-
|
268
|
-
|
266
|
+
model_add_pthp(model,
|
267
|
+
thermal_zones,
|
268
|
+
fan_type: system['fan_type'])
|
269
269
|
|
270
270
|
when 'Exhaust Fan'
|
271
271
|
model_add_exhaust_fan(model,
|
@@ -365,6 +365,71 @@ class Standard
|
|
365
365
|
return true
|
366
366
|
end # add hvac
|
367
367
|
|
368
|
+
# Determine the typical system type given the inputs.
|
369
|
+
#
|
370
|
+
# @param area_type [String] Valid choices are residential and nonresidential
|
371
|
+
# @param delivery_type [String] Conditioning delivery type. Valid choices are air and hydronic
|
372
|
+
# @param heating_source [String] Valid choices are Electricity, NaturalGas, DistrictHeating, DistrictAmbient
|
373
|
+
# @param cooling_source [String] Valid choices are Electricity, DistrictCooling, DistrictAmbient
|
374
|
+
# @param area_m2 [Double] Area in m^2
|
375
|
+
# @param num_stories [Integer] Number of stories
|
376
|
+
# @return [Array] An array containing the system type, central heating fuel, zone heating fuel, and cooling fuel
|
377
|
+
def model_typical_hvac_system_type(model,
|
378
|
+
climate_zone,
|
379
|
+
area_type,
|
380
|
+
delivery_type,
|
381
|
+
heating_source,
|
382
|
+
cooling_source,
|
383
|
+
area_m2,
|
384
|
+
num_stories)
|
385
|
+
|
386
|
+
# Convert area to ft^2
|
387
|
+
area_ft2 = OpenStudio.convert(area_m2, 'm^2', 'ft^2').get
|
388
|
+
|
389
|
+
case area_type
|
390
|
+
when 'residential'
|
391
|
+
area_type = 'Residential'
|
392
|
+
when 'nonresidential', 'retail', 'publicassembly', 'heatedonly'
|
393
|
+
area_type = 'Nonresidential'
|
394
|
+
else
|
395
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', "area_type '#{area_type}' invalid or missing.")
|
396
|
+
return nil
|
397
|
+
end
|
398
|
+
|
399
|
+
# lookup size category
|
400
|
+
search_criteria = {}
|
401
|
+
search_criteria['template'] = template
|
402
|
+
search_criteria['building_category'] = area_type
|
403
|
+
size_data = model_find_object(standards_data['size_category'], search_criteria, nil, nil, area_ft2, num_stories)
|
404
|
+
if size_data.nil?
|
405
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', "Unable to find size category for #{search_criteria}.")
|
406
|
+
return nil
|
407
|
+
end
|
408
|
+
|
409
|
+
# lookup infered HVAC system type
|
410
|
+
search_criteria = {}
|
411
|
+
search_criteria['template'] = template
|
412
|
+
search_criteria['size_category'] = size_data['size_category']
|
413
|
+
search_criteria['heating_source'] = heating_source
|
414
|
+
search_criteria['cooling_source'] = cooling_source
|
415
|
+
search_criteria['delivery_type'] = delivery_type
|
416
|
+
hvac_data = model_find_object(standards_data['hvac_inference'], search_criteria)
|
417
|
+
|
418
|
+
# return system type inputs with format [type, central_heating_fuel, zone_heating_fuel, cooling_fuel]
|
419
|
+
if hvac_data.nil? || hvac_data.empty?
|
420
|
+
system_type_inputs = [nil, nil, nil, nil]
|
421
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Could not determine system type for #{area_type} building of size #{area_ft2.round} ft^2 and #{num_stories} stories, and lookups #{search_criteria}.")
|
422
|
+
else
|
423
|
+
system_type_inputs = [hvac_data['hvac_system_type'], hvac_data['central_heating_fuel'], hvac_data['zone_heating_fuel'], hvac_data['cooling_fuel']]
|
424
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "System type is #{system_type_inputs[0]} for #{area_type} building of size #{area_ft2.round} ft^2 and #{num_stories} stories, and lookups #{search_criteria}.")
|
425
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "--- #{system_type_inputs[1]} for main heating") unless system_type_inputs[1].nil?
|
426
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "--- #{system_type_inputs[2]} for zone heat/reheat") unless system_type_inputs[2].nil?
|
427
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "--- #{system_type_inputs[3]} for cooling") unless system_type_inputs[3].nil?
|
428
|
+
end
|
429
|
+
|
430
|
+
return system_type_inputs
|
431
|
+
end
|
432
|
+
|
368
433
|
private
|
369
434
|
|
370
435
|
def model_get_zones_from_spaces_on_system(model, system)
|
@@ -435,7 +435,7 @@ Standard.class_eval do
|
|
435
435
|
adj_space = adj_surface.space.get
|
436
436
|
if adj_space.spaceType.is_initialized && adj_space.spaceType.get.standardsSpaceType.is_initialized
|
437
437
|
adj_std_space_type = adj_space.spaceType.get.standardsSpaceType.get
|
438
|
-
if adj_std_space_type == '
|
438
|
+
if adj_std_space_type.downcase == 'plenum'
|
439
439
|
plenum_construction = adj_surface.construction
|
440
440
|
if plenum_construction.is_initialized
|
441
441
|
plenum_construction = plenum_construction.get
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Standard
|
2
|
+
# @!group Sizing System
|
3
|
+
|
4
|
+
# Prototype SizingSystem object
|
5
|
+
#
|
6
|
+
# @param air_loop_hvac [<OpenStudio::Model::AirLoopHVAC>] air loop to set sizing system properties
|
7
|
+
# @param dsgn_temps [Hash] a hash of design temperature lookups from standard_design_sizing_temperatures
|
8
|
+
def adjust_sizing_system(air_loop_hvac,
|
9
|
+
dsgn_temps,
|
10
|
+
type_of_load_sizing: 'Sensible',
|
11
|
+
min_sys_airflow_ratio: 0.3,
|
12
|
+
sizing_option: 'Coincident')
|
13
|
+
|
14
|
+
# adjust sizing system defaults
|
15
|
+
sizing_system = air_loop_hvac.sizingSystem
|
16
|
+
sizing_system.setTypeofLoadtoSizeOn(type_of_load_sizing)
|
17
|
+
sizing_system.autosizeDesignOutdoorAirFlowRate
|
18
|
+
sizing_system.setPreheatDesignTemperature(dsgn_temps['prehtg_dsgn_sup_air_temp_c'])
|
19
|
+
sizing_system.setPrecoolDesignTemperature(dsgn_temps['preclg_dsgn_sup_air_temp_c'])
|
20
|
+
sizing_system.setCentralCoolingDesignSupplyAirTemperature(dsgn_temps['clg_dsgn_sup_air_temp_c'])
|
21
|
+
sizing_system.setCentralHeatingDesignSupplyAirTemperature(dsgn_temps['htg_dsgn_sup_air_temp_c'])
|
22
|
+
sizing_system.setPreheatDesignHumidityRatio(0.008)
|
23
|
+
sizing_system.setPrecoolDesignHumidityRatio(0.008)
|
24
|
+
sizing_system.setCentralCoolingDesignSupplyAirHumidityRatio(0.0085)
|
25
|
+
sizing_system.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080)
|
26
|
+
sizing_system.setMinimumSystemAirFlowRatio(min_sys_airflow_ratio)
|
27
|
+
sizing_system.setSizingOption(sizing_option)
|
28
|
+
sizing_system.setAllOutdoorAirinCooling(false)
|
29
|
+
sizing_system.setAllOutdoorAirinHeating(false)
|
30
|
+
sizing_system.setSystemOutdoorAirMethod('ZoneSum')
|
31
|
+
sizing_system.setCoolingDesignAirFlowMethod('DesignDay')
|
32
|
+
sizing_system.setHeatingDesignAirFlowMethod('DesignDay')
|
33
|
+
|
34
|
+
return sizing_system
|
35
|
+
end
|
36
|
+
end
|
@@ -1,6 +1,26 @@
|
|
1
1
|
class Standard
|
2
2
|
# @!group hvac_systems
|
3
3
|
|
4
|
+
# Returns standard design sizing temperatures
|
5
|
+
|
6
|
+
# @return [Hash] Hash of design sizing temperature lookups
|
7
|
+
def standard_design_sizing_temperatures
|
8
|
+
dsgn_temps = {}
|
9
|
+
dsgn_temps['prehtg_dsgn_sup_air_temp_f'] = 45.0
|
10
|
+
dsgn_temps['preclg_dsgn_sup_air_temp_f'] = 55.0
|
11
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = 55.0
|
12
|
+
dsgn_temps['clg_dsgn_sup_air_temp_f'] = 55.0
|
13
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 104.0
|
14
|
+
dsgn_temps['zn_clg_dsgn_sup_air_temp_f'] = 55.0
|
15
|
+
dsgn_temps['prehtg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['prehtg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
16
|
+
dsgn_temps['preclg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['preclg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
17
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
18
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['clg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
19
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
20
|
+
dsgn_temps['zn_clg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_clg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
21
|
+
return dsgn_temps
|
22
|
+
end
|
23
|
+
|
4
24
|
# Creates a hot water loop with a boiler, district heating, or a
|
5
25
|
# water-to-water heat pump and adds it to the model.
|
6
26
|
#
|
@@ -113,7 +133,7 @@ class Standard
|
|
113
133
|
end
|
114
134
|
|
115
135
|
if boiler_out_temp_lmt.nil?
|
116
|
-
out_temp_lmt = OpenStudio.convert(203, 'F', 'C').get
|
136
|
+
out_temp_lmt = OpenStudio.convert(203.0, 'F', 'C').get
|
117
137
|
else
|
118
138
|
out_temp_lmt = boiler_out_temp_lmt
|
119
139
|
end
|
@@ -130,7 +150,7 @@ class Standard
|
|
130
150
|
sizing_factor: boiler_sizing_factor)
|
131
151
|
|
132
152
|
# TODO: Yixing. Adding temperature setpoint controller at boiler outlet causes simulation errors
|
133
|
-
# boiler_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self,hw_temp_sch)
|
153
|
+
# boiler_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(self, hw_temp_sch)
|
134
154
|
# boiler_stpt_manager.setName("Boiler outlet setpoint manager")
|
135
155
|
# boiler_stpt_manager.addToNode(boiler.outletModelObject.get.to_Node.get)
|
136
156
|
else
|
@@ -688,12 +708,15 @@ class Standard
|
|
688
708
|
loop_stpt_manager.addToNode(ground_hx_loop.supplyOutletNode)
|
689
709
|
|
690
710
|
# sensor to read supply inlet temperature
|
691
|
-
inlet_temp_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
711
|
+
inlet_temp_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
712
|
+
'System Node Temperature')
|
692
713
|
inlet_temp_sensor.setName("#{ground_hx.name.to_s.gsub(/[ +-.]/,'_')} Inlet Temp Sensor")
|
693
714
|
inlet_temp_sensor.setKeyName(ground_hx_loop.supplyInletNode.handle.to_s)
|
694
715
|
|
695
716
|
# actuator to set supply outlet temperature
|
696
|
-
outlet_temp_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(hx_temp_sch,
|
717
|
+
outlet_temp_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(hx_temp_sch,
|
718
|
+
'Schedule:Constant',
|
719
|
+
'Schedule Value')
|
697
720
|
outlet_temp_actuator.setName("#{ground_hx.name} Outlet Temp Actuator")
|
698
721
|
|
699
722
|
# program to control outlet temperature
|
@@ -747,17 +770,16 @@ class Standard
|
|
747
770
|
amb_temp_sizing_c = OpenStudio.convert(amb_temp_sizing_f, 'F', 'C').get
|
748
771
|
amb_delta_t_k = OpenStudio.convert(amb_delta_t_r, 'R', 'K').get
|
749
772
|
|
750
|
-
amb_high_temp_sch =
|
751
|
-
|
752
|
-
|
753
|
-
amb_high_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), amb_high_temp_c)
|
773
|
+
amb_high_temp_sch = model_add_constant_schedule_ruleset(model,
|
774
|
+
amb_high_temp_c,
|
775
|
+
name = "Ambient Loop High Temp - #{amb_high_temp_f}F")
|
754
776
|
|
755
|
-
amb_low_temp_sch =
|
756
|
-
|
757
|
-
|
758
|
-
amb_low_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), amb_low_temp_c)
|
777
|
+
amb_low_temp_sch = model_add_constant_schedule_ruleset(model,
|
778
|
+
amb_low_temp_c,
|
779
|
+
name = "Ambient Loop Low Temp - #{amb_low_temp_f}F")
|
759
780
|
|
760
781
|
amb_stpt_manager = OpenStudio::Model::SetpointManagerScheduledDualSetpoint.new(model)
|
782
|
+
amb_stpt_manager.setName("#{ambient_loop.name} Supply Water Setpoint Manager")
|
761
783
|
amb_stpt_manager.setHighSetpointSchedule(amb_high_temp_sch)
|
762
784
|
amb_stpt_manager.setLowSetpointSchedule(amb_low_temp_sch)
|
763
785
|
amb_stpt_manager.addToNode(ambient_loop.supplyOutletNode)
|
@@ -894,7 +916,10 @@ class Standard
|
|
894
916
|
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_dsgn_sup_air_temp_c)
|
895
917
|
|
896
918
|
# create supply fan
|
897
|
-
supply_fan = create_fan_by_name(model,
|
919
|
+
supply_fan = create_fan_by_name(model,
|
920
|
+
'Constant_DOAS_Fan',
|
921
|
+
fan_name: 'DOAS Supply Fan',
|
922
|
+
end_use_subcategory: 'DOAS Fans')
|
898
923
|
supply_fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
899
924
|
supply_fan.setMaximumFlowRate(OpenStudio.convert(fan_maximum_flow_rate, 'cfm', 'm^3/s').get) unless fan_maximum_flow_rate.nil?
|
900
925
|
supply_fan.addToNode(air_loop.supplyInletNode)
|
@@ -1019,11 +1044,11 @@ class Standard
|
|
1019
1044
|
air_loop.addBranchForZone(zone, air_terminal.to_StraightComponent)
|
1020
1045
|
|
1021
1046
|
# DOAS sizing
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1047
|
+
sizing_zone = zone.sizingZone
|
1048
|
+
sizing_zone.setAccountforDedicatedOutdoorAirSystem(true)
|
1049
|
+
sizing_zone.setDedicatedOutdoorAirSystemControlStrategy('ColdSupplyAir')
|
1050
|
+
sizing_zone.setDedicatedOutdoorAirLowSetpointTemperatureforDesign(clg_dsgn_sup_air_temp_c)
|
1051
|
+
sizing_zone.setDedicatedOutdoorAirHighSetpointTemperatureforDesign(htg_dsgn_sup_air_temp_c)
|
1027
1052
|
end
|
1028
1053
|
|
1029
1054
|
return air_loop
|
@@ -1120,9 +1145,15 @@ class Standard
|
|
1120
1145
|
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_dsgn_sup_air_temp_c)
|
1121
1146
|
|
1122
1147
|
if doas_type == 'DOASCV'
|
1123
|
-
supply_fan = create_fan_by_name(model,
|
1148
|
+
supply_fan = create_fan_by_name(model,
|
1149
|
+
'Constant_DOAS_Fan',
|
1150
|
+
fan_name: 'DOAS Supply Fan',
|
1151
|
+
end_use_subcategory: 'DOAS Fans')
|
1124
1152
|
else # 'DOASVAV'
|
1125
|
-
supply_fan = create_fan_by_name(model,
|
1153
|
+
supply_fan = create_fan_by_name(model,
|
1154
|
+
'Variable_DOAS_Fan',
|
1155
|
+
fan_name: 'DOAS Supply Fan',
|
1156
|
+
end_use_subcategory: 'DOAS Fans')
|
1126
1157
|
end
|
1127
1158
|
supply_fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
1128
1159
|
supply_fan.setMaximumFlowRate(OpenStudio.convert(fan_maximum_flow_rate, 'cfm', 'm^3/s').get) unless fan_maximum_flow_rate.nil?
|
@@ -1209,9 +1240,15 @@ class Standard
|
|
1209
1240
|
# create an exhaust fan
|
1210
1241
|
if include_exhaust_fan
|
1211
1242
|
if doas_type == 'DOASCV'
|
1212
|
-
exhaust_fan = create_fan_by_name(model,
|
1243
|
+
exhaust_fan = create_fan_by_name(model,
|
1244
|
+
'Constant_DOAS_Fan',
|
1245
|
+
fan_name: 'DOAS Exhaust Fan',
|
1246
|
+
end_use_subcategory: 'DOAS Fans')
|
1213
1247
|
else # 'DOASVAV'
|
1214
|
-
exhaust_fan = create_fan_by_name(model,
|
1248
|
+
exhaust_fan = create_fan_by_name(model,
|
1249
|
+
'Variable_DOAS_Fan',
|
1250
|
+
fan_name: 'DOAS Exhaust Fan',
|
1251
|
+
end_use_subcategory: 'DOAS Fans')
|
1215
1252
|
end
|
1216
1253
|
# set pressure rise 0.5 inH2O lower than supply fan, 0.5 inH2O minimum
|
1217
1254
|
exhaust_fan_pressure_rise = supply_fan.pressureRise - OpenStudio.convert(0.5, 'inH_{2}O', 'Pa').get
|
@@ -1293,11 +1330,11 @@ class Standard
|
|
1293
1330
|
air_loop.addBranchForZone(zone, air_terminal.to_StraightComponent)
|
1294
1331
|
|
1295
1332
|
# DOAS sizing
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1333
|
+
sizing_zone = zone.sizingZone
|
1334
|
+
sizing_zone.setAccountforDedicatedOutdoorAirSystem(true)
|
1335
|
+
sizing_zone.setDedicatedOutdoorAirSystemControlStrategy(doas_control_strategy)
|
1336
|
+
sizing_zone.setDedicatedOutdoorAirLowSetpointTemperatureforDesign(clg_dsgn_sup_air_temp_c)
|
1337
|
+
sizing_zone.setDedicatedOutdoorAirHighSetpointTemperatureforDesign(htg_dsgn_sup_air_temp_c)
|
1301
1338
|
end
|
1302
1339
|
|
1303
1340
|
return air_loop
|
@@ -1337,12 +1374,20 @@ class Standard
|
|
1337
1374
|
econo_ctrl_mthd: nil)
|
1338
1375
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding VAV system for #{thermal_zones.size} zones.")
|
1339
1376
|
|
1377
|
+
# create air handler
|
1378
|
+
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1379
|
+
if system_name.nil?
|
1380
|
+
air_loop.setName("#{thermal_zones.size} Zone VAV")
|
1381
|
+
else
|
1382
|
+
air_loop.setName(system_name)
|
1383
|
+
end
|
1384
|
+
|
1340
1385
|
# hvac operation schedule
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1386
|
+
if hvac_op_sch.nil?
|
1387
|
+
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
1388
|
+
else
|
1389
|
+
hvac_op_sch = model_add_schedule(model, hvac_op_sch)
|
1390
|
+
end
|
1346
1391
|
|
1347
1392
|
# oa damper schedule
|
1348
1393
|
if oa_damper_sch.nil?
|
@@ -1351,63 +1396,28 @@ class Standard
|
|
1351
1396
|
oa_damper_sch = model_add_schedule(model, oa_damper_sch)
|
1352
1397
|
end
|
1353
1398
|
|
1354
|
-
#
|
1399
|
+
# default design temperatures and settings used across all air loops
|
1400
|
+
dsgn_temps = standard_design_sizing_temperatures
|
1401
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps)
|
1402
|
+
sizing_system.setMinimumSystemAirFlowRatio(min_sys_airflow_ratio) unless min_sys_airflow_ratio.nil?
|
1403
|
+
sizing_system.setSizingOption(vav_sizing_option) unless vav_sizing_option.nil?
|
1355
1404
|
unless hot_water_loop.nil?
|
1356
1405
|
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
1357
1406
|
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
1358
1407
|
end
|
1359
|
-
clg_sa_temp_f = 55.04
|
1360
|
-
prehtg_sa_temp_f = 44.6
|
1361
|
-
preclg_sa_temp_f = 55.04
|
1362
|
-
htg_sa_temp_f = 55.04
|
1363
|
-
zone_htg_sa_temp_f = 104.0
|
1364
|
-
rht_sa_temp_f = 104.0
|
1365
|
-
clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f, 'F', 'C').get
|
1366
|
-
prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f, 'F', 'C').get
|
1367
|
-
preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f, 'F', 'C').get
|
1368
|
-
htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f, 'F', 'C').get
|
1369
|
-
rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f, 'F', 'C').get
|
1370
|
-
zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f, 'F', 'C').get
|
1371
|
-
sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(model)
|
1372
|
-
sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F")
|
1373
|
-
sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default")
|
1374
|
-
sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), clg_sa_temp_c)
|
1375
|
-
|
1376
|
-
# create air handler
|
1377
|
-
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1378
|
-
if system_name.nil?
|
1379
|
-
air_loop.setName("#{thermal_zones.size} Zone VAV")
|
1380
|
-
else
|
1381
|
-
air_loop.setName(system_name)
|
1382
|
-
end
|
1383
1408
|
|
1409
|
+
# air handler controls
|
1410
|
+
sa_temp_sch = model_add_constant_schedule_ruleset(model,
|
1411
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'],
|
1412
|
+
name = "Supply Air Temp - #{dsgn_temps['clg_dsgn_sup_air_temp_f']}F")
|
1384
1413
|
sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, sa_temp_sch)
|
1385
|
-
sa_stpt_manager.setName("#{
|
1414
|
+
sa_stpt_manager.setName("#{air_loop.name} Supply Air Setpoint Manager")
|
1386
1415
|
sa_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
1387
1416
|
|
1388
|
-
# air handler controls
|
1389
|
-
sizing_system = air_loop.sizingSystem
|
1390
|
-
if min_sys_airflow_ratio.nil?
|
1391
|
-
sizing_system.setMinimumSystemAirFlowRatio(0.3)
|
1392
|
-
else
|
1393
|
-
sizing_system.setMinimumSystemAirFlowRatio(min_sys_airflow_ratio)
|
1394
|
-
end
|
1395
|
-
# sizing_system.setPreheatDesignTemperature(htg_oa_tdb_c)
|
1396
|
-
sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c)
|
1397
|
-
sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c)
|
1398
|
-
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c)
|
1399
|
-
if vav_sizing_option.nil?
|
1400
|
-
sizing_system.setSizingOption('Coincident')
|
1401
|
-
else
|
1402
|
-
sizing_system.setSizingOption(vav_sizing_option) unless vav_sizing_option.nil?
|
1403
|
-
end
|
1404
|
-
sizing_system.setAllOutdoorAirinCooling(false)
|
1405
|
-
sizing_system.setAllOutdoorAirinHeating(false)
|
1406
|
-
sizing_system.setSystemOutdoorAirMethod('ZoneSum')
|
1407
|
-
|
1408
1417
|
# create fan
|
1409
1418
|
# @type [OpenStudio::Model::FanVariableVolume] fan
|
1410
|
-
fan = create_fan_by_name(model,
|
1419
|
+
fan = create_fan_by_name(model,
|
1420
|
+
'VAV_System_Fan',
|
1411
1421
|
fan_name: "#{air_loop.name} Fan",
|
1412
1422
|
fan_efficiency: fan_efficiency,
|
1413
1423
|
pressure_rise: fan_pressure_rise,
|
@@ -1428,8 +1438,8 @@ class Standard
|
|
1428
1438
|
name: "#{air_loop.name} Main Htg Coil",
|
1429
1439
|
rated_inlet_water_temperature: hw_temp_c,
|
1430
1440
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
1431
|
-
rated_inlet_air_temperature:
|
1432
|
-
rated_outlet_air_temperature:
|
1441
|
+
rated_inlet_air_temperature: dsgn_temps['prehtg_dsgn_sup_air_temp_c'],
|
1442
|
+
rated_outlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'])
|
1433
1443
|
end
|
1434
1444
|
|
1435
1445
|
# create cooling coil
|
@@ -1478,41 +1488,57 @@ class Standard
|
|
1478
1488
|
|
1479
1489
|
# create reheat coil
|
1480
1490
|
case reheat_type
|
1481
|
-
when 'NaturalGas'
|
1482
|
-
rht_coil = create_coil_heating_gas(model,
|
1491
|
+
when 'NaturalGas', 'Gas'
|
1492
|
+
rht_coil = create_coil_heating_gas(model,
|
1493
|
+
name: "#{zone.name} Gas Reheat Coil")
|
1483
1494
|
when 'Electricity'
|
1484
|
-
rht_coil = create_coil_heating_electric(model,
|
1495
|
+
rht_coil = create_coil_heating_electric(model,
|
1496
|
+
name: "#{zone.name} Electric Reheat Coil")
|
1485
1497
|
when 'Water'
|
1486
1498
|
rht_coil = create_coil_heating_water(model,
|
1487
1499
|
hot_water_loop,
|
1488
1500
|
name: "#{zone.name} Reheat Coil",
|
1489
1501
|
rated_inlet_water_temperature: hw_temp_c,
|
1490
1502
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
1491
|
-
rated_inlet_air_temperature:
|
1492
|
-
rated_outlet_air_temperature:
|
1503
|
+
rated_inlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'],
|
1504
|
+
rated_outlet_air_temperature: dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1493
1505
|
else
|
1494
|
-
#
|
1495
|
-
|
1496
|
-
name: "#{zone.name} No Reheat",
|
1497
|
-
schedule: model.alwaysOffDiscreteSchedule,
|
1498
|
-
nominal_capacity: 0.0)
|
1506
|
+
# no reheat
|
1507
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.Model.Model', "No reheat coil for terminal in #{zone.name}")
|
1499
1508
|
end
|
1500
1509
|
|
1501
|
-
#
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1510
|
+
# set zone reheat temperatures depending on reheat
|
1511
|
+
case reheat_type
|
1512
|
+
when 'NaturalGas', 'Gas', 'Electricity', 'Water'
|
1513
|
+
# create vav terminal
|
1514
|
+
terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(model, model.alwaysOnDiscreteSchedule, rht_coil)
|
1515
|
+
terminal.setName("#{zone.name} VAV Terminal")
|
1516
|
+
terminal.setZoneMinimumAirFlowMethod('Constant')
|
1517
|
+
air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(terminal, thermal_zone_outdoor_airflow_rate_per_area(zone))
|
1518
|
+
terminal.setMaximumFlowFractionDuringReheat(0.5)
|
1519
|
+
terminal.setMaximumReheatAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1520
|
+
air_loop.addBranchForZone(zone, terminal.to_StraightComponent)
|
1521
|
+
|
1522
|
+
# zone sizing
|
1523
|
+
sizing_zone = zone.sizingZone
|
1524
|
+
sizing_zone.setCoolingDesignAirFlowMethod('DesignDayWithLimit')
|
1525
|
+
sizing_zone.setHeatingDesignAirFlowMethod('DesignDay')
|
1526
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
1527
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1528
|
+
else
|
1529
|
+
# no reheat
|
1530
|
+
# create vav terminal
|
1531
|
+
terminal = OpenStudio::Model::AirTerminalSingleDuctVAVNoReheat.new(model, model.alwaysOnDiscreteSchedule)
|
1532
|
+
terminal.setName("#{zone.name} VAV Terminal")
|
1533
|
+
terminal.setZoneMinimumAirFlowInputMethod('Constant')
|
1534
|
+
air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(terminal, thermal_zone_outdoor_airflow_rate_per_area(zone))
|
1535
|
+
air_loop.addBranchForZone(zone, terminal.to_StraightComponent)
|
1536
|
+
|
1537
|
+
# zone sizing
|
1538
|
+
sizing_zone = zone.sizingZone
|
1539
|
+
sizing_zone.setCoolingDesignAirFlowMethod('DesignDayWithLimit')
|
1540
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
1541
|
+
end
|
1516
1542
|
|
1517
1543
|
unless return_plenum.nil?
|
1518
1544
|
zone.setReturnPlenum(return_plenum)
|
@@ -1547,6 +1573,14 @@ class Standard
|
|
1547
1573
|
fan_pressure_rise: 4.0)
|
1548
1574
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding VAV with PFP Boxes and Reheat system for #{thermal_zones.size} zones.")
|
1549
1575
|
|
1576
|
+
# create air handler
|
1577
|
+
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1578
|
+
if system_name.nil?
|
1579
|
+
air_loop.setName("#{thermal_zones.size} Zone VAV with PFP Boxes and Reheat")
|
1580
|
+
else
|
1581
|
+
air_loop.setName(system_name)
|
1582
|
+
end
|
1583
|
+
|
1550
1584
|
# hvac operation schedule
|
1551
1585
|
if hvac_op_sch.nil?
|
1552
1586
|
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
@@ -1561,50 +1595,22 @@ class Standard
|
|
1561
1595
|
oa_damper_sch = model_add_schedule(model, oa_damper_sch)
|
1562
1596
|
end
|
1563
1597
|
|
1564
|
-
#
|
1565
|
-
|
1566
|
-
|
1567
|
-
preclg_sa_temp_f = 55.04 # Precool to 55F
|
1568
|
-
htg_sa_temp_f = 55.04 # Central deck htg temp 55F
|
1569
|
-
rht_sa_temp_f = 104 # VAV box reheat to 104F
|
1570
|
-
zone_htg_sa_temp_f = 104 # Zone heating design supply air temperature to 104 F
|
1571
|
-
clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f, 'F', 'C').get
|
1572
|
-
prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f, 'F', 'C').get
|
1573
|
-
preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f, 'F', 'C').get
|
1574
|
-
htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f, 'F', 'C').get
|
1575
|
-
rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f, 'F', 'C').get
|
1576
|
-
zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f, 'F', 'C').get
|
1577
|
-
sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(model)
|
1578
|
-
sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F")
|
1579
|
-
sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default")
|
1580
|
-
sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), clg_sa_temp_c)
|
1581
|
-
|
1582
|
-
# create air handler
|
1583
|
-
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1584
|
-
if system_name.nil?
|
1585
|
-
air_loop.setName("#{thermal_zones.size} Zone VAV with PFP Boxes and Reheat")
|
1586
|
-
else
|
1587
|
-
air_loop.setName(system_name)
|
1588
|
-
end
|
1598
|
+
# default design temperatures and settings used across all air loops
|
1599
|
+
dsgn_temps = standard_design_sizing_temperatures
|
1600
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps)
|
1589
1601
|
|
1602
|
+
# air handler controls
|
1603
|
+
sa_temp_sch = model_add_constant_schedule_ruleset(model,
|
1604
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'],
|
1605
|
+
name = "Supply Air Temp - #{dsgn_temps['clg_dsgn_sup_air_temp_f']}F")
|
1590
1606
|
sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, sa_temp_sch)
|
1591
|
-
sa_stpt_manager.setName("#{
|
1607
|
+
sa_stpt_manager.setName("#{air_loop.name} Supply Air Setpoint Manager")
|
1592
1608
|
sa_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
1593
1609
|
|
1594
|
-
# air handler controls
|
1595
|
-
sizing_system = air_loop.sizingSystem
|
1596
|
-
sizing_system.setPreheatDesignTemperature(prehtg_sa_temp_c)
|
1597
|
-
sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c)
|
1598
|
-
sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c)
|
1599
|
-
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c)
|
1600
|
-
sizing_system.setSizingOption('Coincident')
|
1601
|
-
sizing_system.setAllOutdoorAirinCooling(false)
|
1602
|
-
sizing_system.setAllOutdoorAirinHeating(false)
|
1603
|
-
sizing_system.setSystemOutdoorAirMethod('ZoneSum')
|
1604
|
-
|
1605
1610
|
# create fan
|
1606
1611
|
# @type [OpenStudio::Model::FanVariableVolume] fan
|
1607
|
-
fan = create_fan_by_name(model,
|
1612
|
+
fan = create_fan_by_name(model,
|
1613
|
+
'VAV_System_Fan',
|
1608
1614
|
fan_name: "#{air_loop.name} Fan",
|
1609
1615
|
fan_efficiency: fan_efficiency,
|
1610
1616
|
pressure_rise: fan_pressure_rise,
|
@@ -1647,11 +1653,14 @@ class Standard
|
|
1647
1653
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding VAV with PFP Boxes and Reheat system terminal for #{zone.name}.")
|
1648
1654
|
|
1649
1655
|
# create reheat coil
|
1650
|
-
rht_coil = create_coil_heating_electric(model,
|
1656
|
+
rht_coil = create_coil_heating_electric(model,
|
1657
|
+
name: "#{zone.name} Electric Reheat Coil")
|
1651
1658
|
|
1652
1659
|
# create terminal fan
|
1653
1660
|
# @type [OpenStudio::Model::FanConstantVolume] pfp_fan
|
1654
|
-
pfp_fan = create_fan_by_name(model,
|
1661
|
+
pfp_fan = create_fan_by_name(model,
|
1662
|
+
'PFP_Fan',
|
1663
|
+
fan_name: "#{zone.name} PFP Term Fan")
|
1655
1664
|
pfp_fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
1656
1665
|
|
1657
1666
|
# create parallel fan powered terminal
|
@@ -1666,9 +1675,8 @@ class Standard
|
|
1666
1675
|
sizing_zone = zone.sizingZone
|
1667
1676
|
sizing_zone.setCoolingDesignAirFlowMethod('DesignDay')
|
1668
1677
|
sizing_zone.setHeatingDesignAirFlowMethod('DesignDay')
|
1669
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
1670
|
-
|
1671
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(zone_htg_sa_temp_c)
|
1678
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
1679
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1672
1680
|
end
|
1673
1681
|
|
1674
1682
|
return air_loop
|
@@ -1696,6 +1704,14 @@ class Standard
|
|
1696
1704
|
oa_damper_sch: nil)
|
1697
1705
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding Packaged VAV for #{thermal_zones.size} zones.")
|
1698
1706
|
|
1707
|
+
# create air handler
|
1708
|
+
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1709
|
+
if system_name.nil?
|
1710
|
+
air_loop.setName("#{thermal_zones.size} Zone PVAV")
|
1711
|
+
else
|
1712
|
+
air_loop.setName(system_name)
|
1713
|
+
end
|
1714
|
+
|
1699
1715
|
# hvac operation schedule
|
1700
1716
|
if hvac_op_sch.nil?
|
1701
1717
|
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
@@ -1710,62 +1726,32 @@ class Standard
|
|
1710
1726
|
oa_damper_sch = model_add_schedule(model, oa_damper_sch)
|
1711
1727
|
end
|
1712
1728
|
|
1713
|
-
#
|
1729
|
+
# default design temperatures used across all air loops
|
1730
|
+
dsgn_temps = standard_design_sizing_temperatures
|
1714
1731
|
unless hot_water_loop.nil?
|
1715
1732
|
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
1716
1733
|
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
1717
1734
|
end
|
1718
|
-
sys_dsn_prhtg_temp_f = 44.6 # Design central deck to preheat to 44.6F
|
1719
|
-
sys_dsn_clg_sa_temp_f = 55 # Design central deck to cool to 55F
|
1720
|
-
sys_dsn_htg_sa_temp_f = 55 # Central heat to 55F
|
1721
|
-
zn_dsn_clg_sa_temp_f = 55 # Design VAV box for 55F from central deck
|
1722
|
-
zn_dsn_htg_sa_temp_f = 122 # Design VAV box to reheat to 122F
|
1723
|
-
rht_rated_air_in_temp_f = 55 # Reheat coils designed to receive 55F
|
1724
|
-
rht_rated_air_out_temp_f = 122 # Reheat coils designed to supply 122F
|
1725
|
-
clg_sa_temp_f = 55 # Central deck clg temp operates at 55F
|
1726
|
-
sys_dsn_prhtg_temp_c = OpenStudio.convert(sys_dsn_prhtg_temp_f, 'F', 'C').get
|
1727
|
-
sys_dsn_clg_sa_temp_c = OpenStudio.convert(sys_dsn_clg_sa_temp_f, 'F', 'C').get
|
1728
|
-
sys_dsn_htg_sa_temp_c = OpenStudio.convert(sys_dsn_htg_sa_temp_f, 'F', 'C').get
|
1729
|
-
zn_dsn_clg_sa_temp_c = OpenStudio.convert(zn_dsn_clg_sa_temp_f, 'F', 'C').get
|
1730
|
-
zn_dsn_htg_sa_temp_c = OpenStudio.convert(zn_dsn_htg_sa_temp_f, 'F', 'C').get
|
1731
|
-
rht_rated_air_in_temp_c = OpenStudio.convert(rht_rated_air_in_temp_f, 'F', 'C').get
|
1732
|
-
rht_rated_air_out_temp_c = OpenStudio.convert(rht_rated_air_out_temp_f, 'F', 'C').get
|
1733
|
-
clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f, 'F', 'C').get
|
1734
|
-
sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(model)
|
1735
|
-
sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f.round(0)}F")
|
1736
|
-
sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f.round(0)}F Default")
|
1737
|
-
sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), clg_sa_temp_c)
|
1738
1735
|
|
1739
|
-
#
|
1740
|
-
|
1741
|
-
|
1742
|
-
air_loop.setName("#{thermal_zones.size} Zone PVAV")
|
1743
|
-
else
|
1744
|
-
air_loop.setName(system_name)
|
1745
|
-
end
|
1736
|
+
# adjusted zone design heating temperature for pvav
|
1737
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
1738
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
1746
1739
|
|
1747
|
-
#
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
air_loop.setNightCycleControlType('CycleOnAny')
|
1758
|
-
avail_mgr = air_loop.availabilityManager
|
1759
|
-
if avail_mgr.is_initialized
|
1760
|
-
avail_mgr = avail_mgr.get
|
1761
|
-
if avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
|
1762
|
-
avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
|
1763
|
-
avail_mgr.setCyclingRunTime(1800)
|
1764
|
-
end
|
1765
|
-
end
|
1740
|
+
# default design settings used across all air loops
|
1741
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps)
|
1742
|
+
|
1743
|
+
# air handler controls
|
1744
|
+
sa_temp_sch = model_add_constant_schedule_ruleset(model,
|
1745
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'],
|
1746
|
+
name = "Supply Air Temp - #{dsgn_temps['clg_dsgn_sup_air_temp_f']}F")
|
1747
|
+
sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, sa_temp_sch)
|
1748
|
+
sa_stpt_manager.setName("#{air_loop.name} Supply Air Setpoint Manager")
|
1749
|
+
sa_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
1766
1750
|
|
1767
1751
|
# create fan
|
1768
|
-
fan = create_fan_by_name(model,
|
1752
|
+
fan = create_fan_by_name(model,
|
1753
|
+
'VAV_default',
|
1754
|
+
fan_name: "#{air_loop.name} Fan")
|
1769
1755
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
1770
1756
|
fan.addToNode(air_loop.supplyInletNode)
|
1771
1757
|
|
@@ -1781,8 +1767,8 @@ class Standard
|
|
1781
1767
|
name: "#{air_loop.name} Main Htg Coil",
|
1782
1768
|
rated_inlet_water_temperature: hw_temp_c,
|
1783
1769
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
1784
|
-
rated_inlet_air_temperature:
|
1785
|
-
rated_outlet_air_temperature:
|
1770
|
+
rated_inlet_air_temperature: dsgn_temps['prehtg_dsgn_sup_air_temp_c'],
|
1771
|
+
rated_outlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'])
|
1786
1772
|
end
|
1787
1773
|
|
1788
1774
|
# create cooling coil
|
@@ -1814,6 +1800,14 @@ class Standard
|
|
1814
1800
|
# set air loop availability controls and night cycle manager, after oa system added
|
1815
1801
|
air_loop.setAvailabilitySchedule(hvac_op_sch)
|
1816
1802
|
air_loop.setNightCycleControlType('CycleOnAny')
|
1803
|
+
avail_mgr = air_loop.availabilityManager
|
1804
|
+
if avail_mgr.is_initialized
|
1805
|
+
avail_mgr = avail_mgr.get
|
1806
|
+
if avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
|
1807
|
+
avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
|
1808
|
+
avail_mgr.setCyclingRunTime(1800)
|
1809
|
+
end
|
1810
|
+
end
|
1817
1811
|
|
1818
1812
|
# attach the VAV system to each zone
|
1819
1813
|
thermal_zones.each do |zone|
|
@@ -1821,22 +1815,23 @@ class Standard
|
|
1821
1815
|
|
1822
1816
|
# create reheat coil
|
1823
1817
|
if electric_reheat || hot_water_loop.nil?
|
1824
|
-
rht_coil = create_coil_heating_electric(model,
|
1818
|
+
rht_coil = create_coil_heating_electric(model,
|
1819
|
+
name: "#{zone.name} Electric Reheat Coil")
|
1825
1820
|
else
|
1826
1821
|
rht_coil = create_coil_heating_water(model,
|
1827
1822
|
hot_water_loop,
|
1828
1823
|
name: "#{zone.name} Reheat Coil",
|
1829
1824
|
rated_inlet_water_temperature: hw_temp_c,
|
1830
1825
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
1831
|
-
rated_inlet_air_temperature:
|
1832
|
-
rated_outlet_air_temperature:
|
1826
|
+
rated_inlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'],
|
1827
|
+
rated_outlet_air_temperature: dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1833
1828
|
end
|
1834
1829
|
|
1835
1830
|
# create VAV terminal
|
1836
1831
|
terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(model, model.alwaysOnDiscreteSchedule, rht_coil)
|
1837
1832
|
terminal.setName("#{zone.name} VAV Terminal")
|
1838
1833
|
terminal.setZoneMinimumAirFlowMethod('Constant')
|
1839
|
-
terminal.setMaximumReheatAirTemperature(
|
1834
|
+
terminal.setMaximumReheatAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1840
1835
|
air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(terminal, thermal_zone_outdoor_airflow_rate_per_area(zone))
|
1841
1836
|
air_loop.addBranchForZone(zone, terminal.to_StraightComponent)
|
1842
1837
|
|
@@ -1846,8 +1841,8 @@ class Standard
|
|
1846
1841
|
|
1847
1842
|
# zone sizing
|
1848
1843
|
sizing_zone = zone.sizingZone
|
1849
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
1850
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
1844
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
1845
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
1851
1846
|
end
|
1852
1847
|
|
1853
1848
|
# set the damper action based on the template
|
@@ -1878,6 +1873,14 @@ class Standard
|
|
1878
1873
|
fan_pressure_rise: 4.0)
|
1879
1874
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding PVAV with PFP Boxes and Reheat system for #{thermal_zones.size} zones.")
|
1880
1875
|
|
1876
|
+
# create air handler
|
1877
|
+
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1878
|
+
if system_name.nil?
|
1879
|
+
air_loop.setName("#{thermal_zones.size} Zone VAV with PFP Boxes and Reheat")
|
1880
|
+
else
|
1881
|
+
air_loop.setName(system_name)
|
1882
|
+
end
|
1883
|
+
|
1881
1884
|
# hvac operation schedule
|
1882
1885
|
if hvac_op_sch.nil?
|
1883
1886
|
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
@@ -1892,47 +1895,18 @@ class Standard
|
|
1892
1895
|
oa_damper_sch = model_add_schedule(model, oa_damper_sch)
|
1893
1896
|
end
|
1894
1897
|
|
1895
|
-
#
|
1896
|
-
|
1897
|
-
|
1898
|
-
preclg_sa_temp_f = 55.04 # Precool to 55F
|
1899
|
-
htg_sa_temp_f = 55.04 # Central deck htg temp 55F
|
1900
|
-
rht_sa_temp_f = 104 # VAV box reheat to 104F
|
1901
|
-
zone_htg_sa_temp_f = 104 # Zone heating design supply air temperature to 104 F
|
1902
|
-
clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f, 'F', 'C').get
|
1903
|
-
prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f, 'F', 'C').get
|
1904
|
-
preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f, 'F', 'C').get
|
1905
|
-
htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f, 'F', 'C').get
|
1906
|
-
rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f, 'F', 'C').get
|
1907
|
-
zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f, 'F', 'C').get
|
1908
|
-
sa_temp_sch = OpenStudio::Model::ScheduleRuleset.new(model)
|
1909
|
-
sa_temp_sch.setName("Supply Air Temp #{clg_sa_temp_f}F")
|
1910
|
-
sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp #{clg_sa_temp_f}F Default")
|
1911
|
-
sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), clg_sa_temp_c)
|
1912
|
-
|
1913
|
-
# create air handler
|
1914
|
-
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
1915
|
-
if system_name.nil?
|
1916
|
-
air_loop.setName("#{thermal_zones.size} Zone VAV with PFP Boxes and Reheat")
|
1917
|
-
else
|
1918
|
-
air_loop.setName(system_name)
|
1919
|
-
end
|
1898
|
+
# default design temperatures and settings used across all air loops
|
1899
|
+
dsgn_temps = standard_design_sizing_temperatures
|
1900
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps)
|
1920
1901
|
|
1902
|
+
# air handler controls
|
1903
|
+
sa_temp_sch = model_add_constant_schedule_ruleset(model,
|
1904
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'],
|
1905
|
+
name = "Supply Air Temp - #{dsgn_temps['clg_dsgn_sup_air_temp_f']}F")
|
1921
1906
|
sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, sa_temp_sch)
|
1922
|
-
sa_stpt_manager.setName("#{
|
1907
|
+
sa_stpt_manager.setName("#{air_loop.name} Supply Air Setpoint Manager")
|
1923
1908
|
sa_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
1924
1909
|
|
1925
|
-
# set air handler controls
|
1926
|
-
sizing_system = air_loop.sizingSystem
|
1927
|
-
sizing_system.setPreheatDesignTemperature(prehtg_sa_temp_c)
|
1928
|
-
sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c)
|
1929
|
-
sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c)
|
1930
|
-
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c)
|
1931
|
-
sizing_system.setSizingOption('Coincident')
|
1932
|
-
sizing_system.setAllOutdoorAirinCooling(false)
|
1933
|
-
sizing_system.setAllOutdoorAirinHeating(false)
|
1934
|
-
sizing_system.setSystemOutdoorAirMethod('ZoneSum')
|
1935
|
-
|
1936
1910
|
# create fan
|
1937
1911
|
# @type [OpenStudio::Model::FanVariableVolume] fan
|
1938
1912
|
fan = create_fan_by_name(model,
|
@@ -1986,11 +1960,14 @@ class Standard
|
|
1986
1960
|
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.Model.Model', "Adding PVAV PFP Box to zone #{zone.name}")
|
1987
1961
|
|
1988
1962
|
# create electric reheat coil
|
1989
|
-
rht_coil = create_coil_heating_electric(model,
|
1963
|
+
rht_coil = create_coil_heating_electric(model,
|
1964
|
+
name: "#{zone.name} Electric Reheat Coil")
|
1990
1965
|
|
1991
1966
|
# create terminal fan
|
1992
1967
|
# @type [OpenStudio::Model::FanConstantVolume] pfp_fan
|
1993
|
-
pfp_fan = create_fan_by_name(model,
|
1968
|
+
pfp_fan = create_fan_by_name(model,
|
1969
|
+
'PFP_Fan',
|
1970
|
+
fan_name: "#{zone.name} PFP Term Fan")
|
1994
1971
|
pfp_fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
1995
1972
|
|
1996
1973
|
# parallel fan powered terminal
|
@@ -2005,8 +1982,8 @@ class Standard
|
|
2005
1982
|
sizing_zone = zone.sizingZone
|
2006
1983
|
sizing_zone.setCoolingDesignAirFlowMethod('DesignDay')
|
2007
1984
|
sizing_zone.setHeatingDesignAirFlowMethod('DesignDay')
|
2008
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
2009
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
1985
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
1986
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2010
1987
|
end
|
2011
1988
|
|
2012
1989
|
return air_loop
|
@@ -2036,6 +2013,14 @@ class Standard
|
|
2036
2013
|
fan_pressure_rise: 4.0)
|
2037
2014
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding CAV for #{thermal_zones.size} zones.")
|
2038
2015
|
|
2016
|
+
# create air handler
|
2017
|
+
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
2018
|
+
if system_name.nil?
|
2019
|
+
air_loop.setName("#{thermal_zones.size} Zone CAV")
|
2020
|
+
else
|
2021
|
+
air_loop.setName(system_name)
|
2022
|
+
end
|
2023
|
+
|
2039
2024
|
# hvac operation schedule
|
2040
2025
|
if hvac_op_sch.nil?
|
2041
2026
|
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
@@ -2050,54 +2035,30 @@ class Standard
|
|
2050
2035
|
oa_damper_sch = model_add_schedule(model, oa_damper_sch)
|
2051
2036
|
end
|
2052
2037
|
|
2053
|
-
#
|
2038
|
+
# default design temperatures used across all air loops
|
2039
|
+
dsgn_temps = standard_design_sizing_temperatures
|
2054
2040
|
unless hot_water_loop.nil?
|
2055
2041
|
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
2056
2042
|
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
2057
2043
|
end
|
2058
|
-
clg_sa_temp_f = 55.04
|
2059
|
-
prehtg_sa_temp_f = 44.6
|
2060
|
-
preclg_sa_temp_f = 55.04
|
2061
|
-
htg_sa_temp_f = 62.06
|
2062
|
-
rht_sa_temp_f = 122.0
|
2063
|
-
zone_htg_sa_temp_f = 122.0
|
2064
|
-
clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f, 'F', 'C').get
|
2065
|
-
prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f, 'F', 'C').get
|
2066
|
-
preclg_sa_temp_c = OpenStudio.convert(preclg_sa_temp_f, 'F', 'C').get
|
2067
|
-
htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f, 'F', 'C').get
|
2068
|
-
rht_sa_temp_c = OpenStudio.convert(rht_sa_temp_f, 'F', 'C').get
|
2069
|
-
zone_htg_sa_temp_c = OpenStudio.convert(zone_htg_sa_temp_f, 'F', 'C').get
|
2070
2044
|
|
2071
|
-
#
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
air_loop.setName(system_name)
|
2077
|
-
end
|
2045
|
+
# adjusted design heating temperature for cav
|
2046
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = 62.0
|
2047
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
2048
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
2049
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
2078
2050
|
|
2079
|
-
#
|
2080
|
-
|
2081
|
-
sa_temp_sch.setName("Supply Air Temp - #{clg_sa_temp_f}F")
|
2082
|
-
sa_temp_sch.defaultDaySchedule.setName("Supply Air Temp - #{clg_sa_temp_f}F Default")
|
2083
|
-
sa_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), clg_sa_temp_c)
|
2051
|
+
# default design settings used across all air loops
|
2052
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps, min_sys_airflow_ratio: 1.0)
|
2084
2053
|
|
2054
|
+
# air handler controls
|
2055
|
+
sa_temp_sch = model_add_constant_schedule_ruleset(model,
|
2056
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'],
|
2057
|
+
name = "Supply Air Temp - #{dsgn_temps['clg_dsgn_sup_air_temp_f']}F")
|
2085
2058
|
sa_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, sa_temp_sch)
|
2086
|
-
sa_stpt_manager.setName("#{air_loop.name}
|
2059
|
+
sa_stpt_manager.setName("#{air_loop.name} Supply Air Setpoint Manager")
|
2087
2060
|
sa_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
2088
2061
|
|
2089
|
-
# set air handler sizing
|
2090
|
-
sizing_system = air_loop.sizingSystem
|
2091
|
-
sizing_system.setMinimumSystemAirFlowRatio(1.0)
|
2092
|
-
sizing_system.setPreheatDesignTemperature(prehtg_sa_temp_c)
|
2093
|
-
sizing_system.setPrecoolDesignTemperature(preclg_sa_temp_c)
|
2094
|
-
sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c)
|
2095
|
-
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c)
|
2096
|
-
sizing_system.setSizingOption('Coincident')
|
2097
|
-
sizing_system.setAllOutdoorAirinCooling(false)
|
2098
|
-
sizing_system.setAllOutdoorAirinHeating(false)
|
2099
|
-
sizing_system.setSystemOutdoorAirMethod('ZoneSum')
|
2100
|
-
|
2101
2062
|
# create fan
|
2102
2063
|
fan = create_fan_by_name(model,
|
2103
2064
|
'Packaged_RTU_SZ_AC_CAV_Fan',
|
@@ -2116,8 +2077,8 @@ class Standard
|
|
2116
2077
|
name: "#{air_loop.name} Main Htg Coil",
|
2117
2078
|
rated_inlet_water_temperature: hw_temp_c,
|
2118
2079
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
2119
|
-
rated_inlet_air_temperature:
|
2120
|
-
rated_outlet_air_temperature:
|
2080
|
+
rated_inlet_air_temperature: dsgn_temps['prehtg_dsgn_sup_air_temp_c'],
|
2081
|
+
rated_outlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'])
|
2121
2082
|
|
2122
2083
|
# create cooling coil
|
2123
2084
|
if chilled_water_loop.nil?
|
@@ -2160,8 +2121,8 @@ class Standard
|
|
2160
2121
|
name: "#{zone.name} Reheat Coil",
|
2161
2122
|
rated_inlet_water_temperature: hw_temp_c,
|
2162
2123
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
2163
|
-
rated_inlet_air_temperature:
|
2164
|
-
rated_outlet_air_temperature:
|
2124
|
+
rated_inlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'],
|
2125
|
+
rated_outlet_air_temperature: dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2165
2126
|
# VAV terminal
|
2166
2127
|
terminal = OpenStudio::Model::AirTerminalSingleDuctVAVReheat.new(model, model.alwaysOnDiscreteSchedule, rht_coil)
|
2167
2128
|
terminal.setName("#{zone.name} VAV Terminal")
|
@@ -2169,16 +2130,15 @@ class Standard
|
|
2169
2130
|
air_terminal_single_duct_vav_reheat_apply_initial_prototype_damper_position(terminal, thermal_zone_outdoor_airflow_rate_per_area(zone))
|
2170
2131
|
terminal.setMaximumFlowPerZoneFloorAreaDuringReheat(0.0)
|
2171
2132
|
terminal.setMaximumFlowFractionDuringReheat(0.5)
|
2172
|
-
terminal.setMaximumReheatAirTemperature(
|
2133
|
+
terminal.setMaximumReheatAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2173
2134
|
air_loop.addBranchForZone(zone, terminal.to_StraightComponent)
|
2174
2135
|
|
2175
2136
|
# zone sizing
|
2176
2137
|
sizing_zone = zone.sizingZone
|
2177
2138
|
sizing_zone.setCoolingDesignAirFlowMethod('DesignDayWithLimit')
|
2178
2139
|
sizing_zone.setHeatingDesignAirFlowMethod('DesignDay')
|
2179
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
2180
|
-
|
2181
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(zone_htg_sa_temp_c)
|
2140
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2141
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2182
2142
|
end
|
2183
2143
|
|
2184
2144
|
# Set the damper action based on the template.
|
@@ -2240,42 +2200,49 @@ class Standard
|
|
2240
2200
|
air_loop.setName("#{zone.name} #{system_name}")
|
2241
2201
|
end
|
2242
2202
|
|
2243
|
-
#
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2203
|
+
# default design temperatures and settings used across all air loops
|
2204
|
+
dsgn_temps = standard_design_sizing_temperatures
|
2205
|
+
unless hot_water_loop.nil?
|
2206
|
+
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
2207
|
+
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
2208
|
+
end
|
2209
|
+
|
2210
|
+
# adjusted design heating temperature for psz_ac
|
2211
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
2212
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
2213
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_f']
|
2214
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_c']
|
2215
|
+
|
2216
|
+
# default design settings used across all air loops
|
2217
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps, min_sys_airflow_ratio: 1.0)
|
2218
|
+
|
2219
|
+
# air handler controls
|
2220
|
+
# add a setpoint manager single zone reheat to control the supply air temperature
|
2221
|
+
setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
|
2222
|
+
setpoint_mgr_single_zone_reheat.setName("#{zone.name} Setpoint Manager SZ Reheat")
|
2223
|
+
setpoint_mgr_single_zone_reheat.setControlZone(zone)
|
2224
|
+
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2225
|
+
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2226
|
+
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2264
2227
|
|
2265
2228
|
# zone sizing
|
2266
2229
|
sizing_zone = zone.sizingZone
|
2267
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
2268
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
2230
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2231
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2269
2232
|
|
2270
2233
|
# create fan
|
2271
2234
|
# ConstantVolume: Packaged Rooftop Single Zone Air conditioner
|
2272
2235
|
# Cycling: Unitary System
|
2273
2236
|
# CyclingHeatPump: Unitary Heat Pump system
|
2274
2237
|
if fan_type == 'ConstantVolume'
|
2275
|
-
fan = create_fan_by_name(model,
|
2238
|
+
fan = create_fan_by_name(model,
|
2239
|
+
'Packaged_RTU_SZ_AC_CAV_Fan',
|
2240
|
+
fan_name: "#{air_loop.name} Fan")
|
2276
2241
|
fan.setAvailabilitySchedule(hvac_op_sch)
|
2277
2242
|
elsif fan_type == 'Cycling'
|
2278
|
-
fan = create_fan_by_name(model,
|
2243
|
+
fan = create_fan_by_name(model,
|
2244
|
+
'Packaged_RTU_SZ_AC_Cycling_Fan',
|
2245
|
+
fan_name: "#{air_loop.name} Fan")
|
2279
2246
|
fan.setAvailabilitySchedule(hvac_op_sch)
|
2280
2247
|
else
|
2281
2248
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', "Fan type '#{fan_type}' not recognized, cannot add PSZ-AC.")
|
@@ -2285,31 +2252,34 @@ class Standard
|
|
2285
2252
|
# create heating coil
|
2286
2253
|
case heating_type
|
2287
2254
|
when 'NaturalGas', 'Gas'
|
2288
|
-
htg_coil = create_coil_heating_gas(model,
|
2255
|
+
htg_coil = create_coil_heating_gas(model,
|
2256
|
+
name: "#{air_loop.name} Gas Htg Coil")
|
2289
2257
|
when 'Water'
|
2290
2258
|
if hot_water_loop.nil?
|
2291
2259
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'No hot water plant loop supplied')
|
2292
2260
|
return false
|
2293
2261
|
end
|
2294
|
-
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
2295
|
-
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
2296
|
-
prehtg_sa_temp_c = OpenStudio.convert(44.6, 'F', 'C').get
|
2297
|
-
htg_sa_temp_c = OpenStudio.convert(55.0, 'F', 'C').get
|
2298
2262
|
htg_coil = create_coil_heating_water(model,
|
2299
2263
|
hot_water_loop,
|
2300
2264
|
name: "#{air_loop.name} Water Htg Coil",
|
2301
2265
|
rated_inlet_water_temperature: hw_temp_c,
|
2302
2266
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
2303
|
-
rated_inlet_air_temperature:
|
2304
|
-
rated_outlet_air_temperature:
|
2267
|
+
rated_inlet_air_temperature: dsgn_temps['prehtg_dsgn_sup_air_temp_c'],
|
2268
|
+
rated_outlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'])
|
2305
2269
|
when 'Single Speed Heat Pump'
|
2306
|
-
htg_coil = create_coil_heating_dx_single_speed(model,
|
2270
|
+
htg_coil = create_coil_heating_dx_single_speed(model,
|
2271
|
+
name: "#{zone.name} HP Htg Coil",
|
2272
|
+
type: 'PSZ-AC',
|
2273
|
+
cop: 3.3)
|
2307
2274
|
when 'Water To Air Heat Pump'
|
2308
|
-
htg_coil = create_coil_heating_water_to_air_heat_pump_equation_fit(model,
|
2275
|
+
htg_coil = create_coil_heating_water_to_air_heat_pump_equation_fit(model,
|
2276
|
+
hot_water_loop,
|
2277
|
+
name: "#{air_loop.name} Water-to-Air HP Htg Coil")
|
2309
2278
|
when 'Electricity', 'Electric'
|
2310
|
-
htg_coil = create_coil_heating_electric(model,
|
2279
|
+
htg_coil = create_coil_heating_electric(model,
|
2280
|
+
name: "#{air_loop.name} Electric Htg Coil")
|
2311
2281
|
else
|
2312
|
-
#
|
2282
|
+
# zero-capacity, always-off electric heating coil
|
2313
2283
|
htg_coil = create_coil_heating_electric(model,
|
2314
2284
|
name: "#{air_loop.name} No Heat",
|
2315
2285
|
schedule: model.alwaysOffDiscreteSchedule,
|
@@ -2319,9 +2289,11 @@ class Standard
|
|
2319
2289
|
# create supplemental heating coil
|
2320
2290
|
case supplemental_heating_type
|
2321
2291
|
when 'Electricity', 'Electric'
|
2322
|
-
supplemental_htg_coil = create_coil_heating_electric(model,
|
2292
|
+
supplemental_htg_coil = create_coil_heating_electric(model,
|
2293
|
+
name: "#{air_loop.name} Electric Backup Htg Coil")
|
2323
2294
|
when 'NaturalGas', 'Gas'
|
2324
|
-
supplemental_htg_coil = create_coil_heating_gas(model,
|
2295
|
+
supplemental_htg_coil = create_coil_heating_gas(model,
|
2296
|
+
name: "#{air_loop.name} Gas Backup Htg Coil")
|
2325
2297
|
else
|
2326
2298
|
# Zero-capacity, always-off electric heating coil
|
2327
2299
|
supplemental_htg_coil = create_coil_heating_electric(model,
|
@@ -2337,9 +2309,12 @@ class Standard
|
|
2337
2309
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'No chilled water plant loop supplied')
|
2338
2310
|
return false
|
2339
2311
|
end
|
2340
|
-
clg_coil = create_coil_cooling_water(model,
|
2312
|
+
clg_coil = create_coil_cooling_water(model,
|
2313
|
+
chilled_water_loop,
|
2314
|
+
name: "#{air_loop.name} Water Clg Coil")
|
2341
2315
|
when 'Two Speed DX AC'
|
2342
|
-
clg_coil = create_coil_cooling_dx_two_speed(model,
|
2316
|
+
clg_coil = create_coil_cooling_dx_two_speed(model,
|
2317
|
+
name: "#{air_loop.name} 2spd DX AC Clg Coil")
|
2343
2318
|
when 'Single Speed DX AC'
|
2344
2319
|
clg_coil = create_coil_cooling_dx_single_speed(model,
|
2345
2320
|
name: "#{air_loop.name} 1spd DX AC Clg Coil",
|
@@ -2357,16 +2332,13 @@ class Standard
|
|
2357
2332
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'No chilled water plant loop supplied')
|
2358
2333
|
return false
|
2359
2334
|
end
|
2360
|
-
clg_coil = create_coil_cooling_water_to_air_heat_pump_equation_fit(model,
|
2335
|
+
clg_coil = create_coil_cooling_water_to_air_heat_pump_equation_fit(model,
|
2336
|
+
chilled_water_loop,
|
2337
|
+
name: "#{air_loop.name} Water-to-Air HP Clg Coil")
|
2361
2338
|
else
|
2362
2339
|
clg_coil = nil
|
2363
2340
|
end
|
2364
2341
|
|
2365
|
-
# add a setpoint manager single zone reheat to control the supply air temperature
|
2366
|
-
setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
|
2367
|
-
setpoint_mgr_single_zone_reheat.setControlZone(zone)
|
2368
|
-
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2369
|
-
|
2370
2342
|
# wrap coils in a unitary system if cycling, or not if constant volume
|
2371
2343
|
if fan_type == 'Cycling'
|
2372
2344
|
if heating_type == 'Water To Air Heat Pump'
|
@@ -2378,14 +2350,13 @@ class Standard
|
|
2378
2350
|
unitary_system.setSupplementalHeatingCoil(supplemental_htg_coil) unless supplemental_htg_coil.nil?
|
2379
2351
|
unitary_system.setName("#{zone.name} Unitary HP")
|
2380
2352
|
unitary_system.setControllingZoneorThermostatLocation(zone)
|
2381
|
-
unitary_system.setMaximumSupplyAirTemperature(
|
2353
|
+
unitary_system.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2382
2354
|
unitary_system.setFanPlacement('BlowThrough')
|
2383
2355
|
unitary_system.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
|
2384
2356
|
unitary_system.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
|
2385
2357
|
unitary_system.setSupplyAirFlowRateMethodWhenNoCoolingorHeatingisRequired('SupplyAirFlowRate')
|
2386
2358
|
unitary_system.setSupplyAirFanOperatingModeSchedule(model.alwaysOnDiscreteSchedule)
|
2387
2359
|
unitary_system.addToNode(air_loop.supplyInletNode)
|
2388
|
-
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(50.0)
|
2389
2360
|
else
|
2390
2361
|
# CyclingHeatPump: Unitary Heat Pump system
|
2391
2362
|
unitary_system = OpenStudio::Model::AirLoopHVACUnitaryHeatPumpAirToAir.new(model,
|
@@ -2400,8 +2371,6 @@ class Standard
|
|
2400
2371
|
unitary_system.setFanPlacement(fan_location)
|
2401
2372
|
unitary_system.setSupplyAirFanOperatingModeSchedule(hvac_op_sch)
|
2402
2373
|
unitary_system.addToNode(air_loop.supplyInletNode)
|
2403
|
-
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(55.0, 'F', 'C').get)
|
2404
|
-
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(104.0, 'F', 'C').get)
|
2405
2374
|
end
|
2406
2375
|
else
|
2407
2376
|
# ConstantVolume: Packaged Rooftop Single Zone Air conditioner
|
@@ -2427,8 +2396,6 @@ class Standard
|
|
2427
2396
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Invalid fan location')
|
2428
2397
|
return false
|
2429
2398
|
end
|
2430
|
-
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(50.0, 'F', 'C').get)
|
2431
|
-
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(122.0, 'F', 'C').get)
|
2432
2399
|
end
|
2433
2400
|
|
2434
2401
|
# add the OA system
|
@@ -2508,36 +2475,29 @@ class Standard
|
|
2508
2475
|
air_loop.setName("#{zone.name} #{system_name}")
|
2509
2476
|
end
|
2510
2477
|
|
2511
|
-
#
|
2512
|
-
|
2513
|
-
air_loop_sizing.setTypeofLoadtoSizeOn('Sensible')
|
2514
|
-
air_loop_sizing.autosizeDesignOutdoorAirFlowRate
|
2515
|
-
air_loop_sizing.setMinimumSystemAirFlowRatio(0.0)
|
2516
|
-
air_loop_sizing.setPreheatDesignTemperature(7.0)
|
2517
|
-
air_loop_sizing.setPreheatDesignHumidityRatio(0.008)
|
2518
|
-
air_loop_sizing.setPrecoolDesignTemperature(12.8)
|
2519
|
-
air_loop_sizing.setPrecoolDesignHumidityRatio(0.008)
|
2520
|
-
air_loop_sizing.setCentralCoolingDesignSupplyAirTemperature(12.8)
|
2521
|
-
air_loop_sizing.setCentralHeatingDesignSupplyAirTemperature(40.0)
|
2522
|
-
air_loop_sizing.setSizingOption('Coincident')
|
2523
|
-
air_loop_sizing.setAllOutdoorAirinCooling(false)
|
2524
|
-
air_loop_sizing.setAllOutdoorAirinHeating(false)
|
2525
|
-
air_loop_sizing.setCentralCoolingDesignSupplyAirHumidityRatio(0.0085)
|
2526
|
-
air_loop_sizing.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080)
|
2527
|
-
air_loop_sizing.setCoolingDesignAirFlowMethod('DesignDay')
|
2528
|
-
air_loop_sizing.setCoolingDesignAirFlowRate(0.0)
|
2529
|
-
air_loop_sizing.setHeatingDesignAirFlowMethod('DesignDay')
|
2530
|
-
air_loop_sizing.setHeatingDesignAirFlowRate(0.0)
|
2531
|
-
air_loop_sizing.setSystemOutdoorAirMethod('ZoneSum')
|
2478
|
+
# default design temperatures used across all air loops
|
2479
|
+
dsgn_temps = standard_design_sizing_temperatures
|
2532
2480
|
|
2533
|
-
# zone
|
2534
|
-
|
2535
|
-
|
2536
|
-
|
2481
|
+
# adjusted zone design heating temperature for psz_vav
|
2482
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_f']
|
2483
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_c']
|
2484
|
+
|
2485
|
+
# default design settings used across all air loops
|
2486
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps)
|
2537
2487
|
|
2488
|
+
# air handler controls
|
2538
2489
|
# add a setpoint manager single zone reheat to control the supply air temperature
|
2539
2490
|
setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
|
2491
|
+
setpoint_mgr_single_zone_reheat.setName("#{zone.name} Setpoint Manager SZ Reheat")
|
2540
2492
|
setpoint_mgr_single_zone_reheat.setControlZone(zone)
|
2493
|
+
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2494
|
+
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2495
|
+
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2496
|
+
|
2497
|
+
# zone sizing
|
2498
|
+
sizing_zone = zone.sizingZone
|
2499
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2500
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2541
2501
|
|
2542
2502
|
# create fan
|
2543
2503
|
# @type [OpenStudio::Model::FanVariableVolume] fan
|
@@ -2550,9 +2510,11 @@ class Standard
|
|
2550
2510
|
# create heating coil
|
2551
2511
|
case heating_type
|
2552
2512
|
when 'NaturalGas', 'Gas'
|
2553
|
-
htg_coil = create_coil_heating_gas(model,
|
2513
|
+
htg_coil = create_coil_heating_gas(model,
|
2514
|
+
name: "#{air_loop.name} Gas Htg Coil")
|
2554
2515
|
when 'Electricity', 'Electric'
|
2555
|
-
htg_coil = create_coil_heating_electric(model,
|
2516
|
+
htg_coil = create_coil_heating_electric(model,
|
2517
|
+
name: "#{air_loop.name} Electric Htg Coil")
|
2556
2518
|
else
|
2557
2519
|
# Zero-capacity, always-off electric heating coil
|
2558
2520
|
htg_coil = create_coil_heating_electric(model,
|
@@ -2564,9 +2526,11 @@ class Standard
|
|
2564
2526
|
# create supplemental heating coil
|
2565
2527
|
case supplemental_heating_type
|
2566
2528
|
when 'Electricity', 'Electric'
|
2567
|
-
supplemental_htg_coil = create_coil_heating_electric(model,
|
2529
|
+
supplemental_htg_coil = create_coil_heating_electric(model,
|
2530
|
+
name: "#{air_loop.name} Electric Backup Htg Coil")
|
2568
2531
|
when 'NaturalGas', 'Gas'
|
2569
|
-
supplemental_htg_coil = create_coil_heating_gas(model,
|
2532
|
+
supplemental_htg_coil = create_coil_heating_gas(model,
|
2533
|
+
name: "#{air_loop.name} Gas Backup Htg Coil")
|
2570
2534
|
else
|
2571
2535
|
# zero-capacity, always-off electric heating coil
|
2572
2536
|
supplemental_htg_coil = create_coil_heating_electric(model,
|
@@ -2578,7 +2542,7 @@ class Standard
|
|
2578
2542
|
# create cooling coil
|
2579
2543
|
clg_coil = OpenStudio::Model::CoilCoolingDXVariableSpeed.new(model)
|
2580
2544
|
clg_coil.setName("#{air_loop.name} Var spd DX AC Clg Coil")
|
2581
|
-
clg_coil.setBasinHeaterCapacity(10)
|
2545
|
+
clg_coil.setBasinHeaterCapacity(10.0)
|
2582
2546
|
clg_coil.setBasinHeaterSetpointTemperature(2.0)
|
2583
2547
|
# first speed level
|
2584
2548
|
clg_spd_1 = OpenStudio::Model::CoilCoolingDXVariableSpeedSpeedData.new(model)
|
@@ -2597,7 +2561,7 @@ class Standard
|
|
2597
2561
|
unitary_system.setName("#{zone.name} Unitary PSZ-VAV")
|
2598
2562
|
unitary_system.setString(2, 'SingleZoneVAV') # TODO: add setControlType() method
|
2599
2563
|
unitary_system.setControllingZoneorThermostatLocation(zone)
|
2600
|
-
unitary_system.setMaximumSupplyAirTemperature(
|
2564
|
+
unitary_system.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2601
2565
|
unitary_system.setFanPlacement('BlowThrough')
|
2602
2566
|
unitary_system.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
|
2603
2567
|
unitary_system.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
|
@@ -2694,46 +2658,36 @@ class Standard
|
|
2694
2658
|
air_loop.setName("#{zone.name} #{system_name}")
|
2695
2659
|
end
|
2696
2660
|
|
2697
|
-
#
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2661
|
+
# default design temperatures across all air loops
|
2662
|
+
dsgn_temps = standard_design_sizing_temperatures
|
2663
|
+
unless hot_water_loop.nil?
|
2664
|
+
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
2665
|
+
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
2666
|
+
end
|
2667
|
+
|
2668
|
+
# adjusted zone design heating temperature for data center psz_ac
|
2669
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_f']
|
2670
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_c']
|
2671
|
+
|
2672
|
+
# default design settings used across all air loops
|
2673
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps, min_sys_airflow_ratio: 1.0)
|
2674
|
+
|
2675
|
+
# air handler controls
|
2676
|
+
# add a setpoint manager single zone reheat to control the supply air temperature
|
2677
|
+
setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
|
2678
|
+
setpoint_mgr_single_zone_reheat.setName("#{zone.name} Setpoint Manager SZ Reheat")
|
2679
|
+
setpoint_mgr_single_zone_reheat.setControlZone(zone)
|
2680
|
+
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2681
|
+
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2682
|
+
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2718
2683
|
|
2719
2684
|
# zone sizing
|
2720
2685
|
sizing_zone = zone.sizingZone
|
2721
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
2722
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
2686
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2687
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2723
2688
|
|
2724
2689
|
# add the components to the air loop in order from closest to zone to furthest from zone
|
2725
2690
|
if main_data_center
|
2726
|
-
|
2727
|
-
# control temps used across all air handlers
|
2728
|
-
unless hot_water_loop.nil?
|
2729
|
-
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
2730
|
-
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
2731
|
-
end
|
2732
|
-
prehtg_sa_temp_f = 44.6 # Preheat to 44.6F
|
2733
|
-
htg_sa_temp_f = 55.0 # Central deck htg temp 55F
|
2734
|
-
prehtg_sa_temp_c = OpenStudio.convert(prehtg_sa_temp_f, 'F', 'C').get
|
2735
|
-
htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f, 'F', 'C').get
|
2736
|
-
|
2737
2691
|
# extra water heating coil
|
2738
2692
|
create_coil_heating_water(model,
|
2739
2693
|
hot_water_loop,
|
@@ -2741,8 +2695,9 @@ class Standard
|
|
2741
2695
|
name: "#{air_loop.name} Water Htg Coil",
|
2742
2696
|
rated_inlet_water_temperature: hw_temp_c,
|
2743
2697
|
rated_outlet_water_temperature: (hw_temp_c - hw_delta_t_k),
|
2744
|
-
rated_inlet_air_temperature:
|
2745
|
-
rated_outlet_air_temperature:
|
2698
|
+
rated_inlet_air_temperature: dsgn_temps['prehtg_dsgn_sup_air_temp_c'],
|
2699
|
+
rated_outlet_air_temperature: dsgn_temps['htg_dsgn_sup_air_temp_c'])
|
2700
|
+
|
2746
2701
|
# extra electric heating coil
|
2747
2702
|
create_coil_heating_electric(model,
|
2748
2703
|
air_loop_node: air_loop.supplyInletNode,
|
@@ -2764,13 +2719,20 @@ class Standard
|
|
2764
2719
|
|
2765
2720
|
# create fan
|
2766
2721
|
# @type [OpenStudio::Model::FanConstantVolume]
|
2767
|
-
fan = create_fan_by_name(model,
|
2722
|
+
fan = create_fan_by_name(model,
|
2723
|
+
'Packaged_RTU_SZ_AC_Cycling_Fan',
|
2724
|
+
fan_name: "#{air_loop.name} Fan")
|
2768
2725
|
fan.setAvailabilitySchedule(hvac_op_sch)
|
2769
2726
|
|
2770
2727
|
# create heating and cooling coils
|
2771
|
-
htg_coil = create_coil_heating_water_to_air_heat_pump_equation_fit(model,
|
2772
|
-
|
2773
|
-
|
2728
|
+
htg_coil = create_coil_heating_water_to_air_heat_pump_equation_fit(model,
|
2729
|
+
heat_pump_loop,
|
2730
|
+
name: "#{air_loop.name} Water-to-Air HP Htg Coil")
|
2731
|
+
clg_coil = create_coil_cooling_water_to_air_heat_pump_equation_fit(model,
|
2732
|
+
heat_pump_loop,
|
2733
|
+
name: "#{air_loop.name} Water-to-Air HP Clg Coil")
|
2734
|
+
supplemental_htg_coil = create_coil_heating_electric(model,
|
2735
|
+
name: "#{air_loop.name} Electric Backup Htg Coil")
|
2774
2736
|
|
2775
2737
|
# wrap fan and coils in a unitary system object
|
2776
2738
|
unitary_system = OpenStudio::Model::AirLoopHVACUnitarySystem.new(model)
|
@@ -2796,13 +2758,6 @@ class Standard
|
|
2796
2758
|
oa_system.setName("#{air_loop.name} OA System")
|
2797
2759
|
oa_system.addToNode(air_loop.supplyInletNode)
|
2798
2760
|
|
2799
|
-
# add a setpoint manager single zone reheat to control the supply air temperature
|
2800
|
-
setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
|
2801
|
-
setpoint_mgr_single_zone_reheat.setControlZone(zone)
|
2802
|
-
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(55.0, 'F', 'C').get)
|
2803
|
-
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(104.0, 'F', 'C').get)
|
2804
|
-
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2805
|
-
|
2806
2761
|
# set air loop availability controls and night cycle manager, after oa system added
|
2807
2762
|
air_loop.setAvailabilitySchedule(hvac_op_sch)
|
2808
2763
|
air_loop.setNightCycleControlType('CycleOnAny')
|
@@ -2839,6 +2794,11 @@ class Standard
|
|
2839
2794
|
oa_damper_sch: nil,
|
2840
2795
|
econ_max_oa_frac_sch: nil)
|
2841
2796
|
|
2797
|
+
# create a split AC for each group of thermal zones
|
2798
|
+
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
2799
|
+
thermal_zones_name = (thermal_zones.map { |z| z.name }).join(' - ')
|
2800
|
+
air_loop.setName("#{thermal_zones_name} SAC")
|
2801
|
+
|
2842
2802
|
# hvac operation schedule
|
2843
2803
|
if hvac_op_sch.nil?
|
2844
2804
|
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
@@ -2853,33 +2813,26 @@ class Standard
|
|
2853
2813
|
oa_damper_sch = model_add_schedule(model, oa_damper_sch)
|
2854
2814
|
end
|
2855
2815
|
|
2856
|
-
#
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2816
|
+
# default design temperatures used across all air loops
|
2817
|
+
dsgn_temps = standard_design_sizing_temperatures
|
2818
|
+
|
2819
|
+
# adjusted zone design heating temperature for split_ac
|
2820
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
2821
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
2822
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_f']
|
2823
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_c']
|
2861
2824
|
|
2862
|
-
#
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
air_loop_sizing.setSizingOption('NonCoincident')
|
2874
|
-
air_loop_sizing.setAllOutdoorAirinCooling(false)
|
2875
|
-
air_loop_sizing.setAllOutdoorAirinHeating(false)
|
2876
|
-
air_loop_sizing.setCentralCoolingDesignSupplyAirHumidityRatio(0.008)
|
2877
|
-
air_loop_sizing.setCentralHeatingDesignSupplyAirHumidityRatio(0.0080)
|
2878
|
-
air_loop_sizing.setCoolingDesignAirFlowMethod('DesignDay')
|
2879
|
-
air_loop_sizing.setCoolingDesignAirFlowRate(0.0)
|
2880
|
-
air_loop_sizing.setHeatingDesignAirFlowMethod('DesignDay')
|
2881
|
-
air_loop_sizing.setHeatingDesignAirFlowRate(0.0)
|
2882
|
-
air_loop_sizing.setSystemOutdoorAirMethod('ZoneSum')
|
2825
|
+
# default design settings used across all air loops
|
2826
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps, min_sys_airflow_ratio: 1.0, sizing_option: 'NonCoincident')
|
2827
|
+
|
2828
|
+
# air handler controls
|
2829
|
+
# add a setpoint manager single zone reheat to control the supply air temperature
|
2830
|
+
setpoint_mgr_single_zone_reheat = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
|
2831
|
+
setpoint_mgr_single_zone_reheat.setName("#{air_loop.name} Setpoint Manager SZ Reheat")
|
2832
|
+
setpoint_mgr_single_zone_reheat.setControlZone(thermal_zones[0])
|
2833
|
+
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2834
|
+
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2835
|
+
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2883
2836
|
|
2884
2837
|
# add the components to the air loop in order from closest to zone to furthest from zone
|
2885
2838
|
# create fan
|
@@ -2957,14 +2910,8 @@ class Standard
|
|
2957
2910
|
oa_system.setName("#{air_loop.name} OA System")
|
2958
2911
|
oa_system.addToNode(air_loop.supplyInletNode)
|
2959
2912
|
|
2960
|
-
#
|
2961
|
-
|
2962
|
-
setpoint_mgr_single_zone_reheat.setName("#{air_loop.name} Setpoint Manager SZ Reheat")
|
2963
|
-
control_zone = thermal_zones[0]
|
2964
|
-
setpoint_mgr_single_zone_reheat.setControlZone(control_zone)
|
2965
|
-
setpoint_mgr_single_zone_reheat.setMinimumSupplyAirTemperature(OpenStudio.convert(55.4, 'F', 'C').get)
|
2966
|
-
setpoint_mgr_single_zone_reheat.setMaximumSupplyAirTemperature(OpenStudio.convert(113.0, 'F', 'C').get)
|
2967
|
-
setpoint_mgr_single_zone_reheat.addToNode(air_loop.supplyOutletNode)
|
2913
|
+
# set air loop availability controls after oa system added
|
2914
|
+
air_loop.setAvailabilitySchedule(hvac_op_sch)
|
2968
2915
|
|
2969
2916
|
# create a diffuser and attach the zone/diffuser pair to the air loop
|
2970
2917
|
thermal_zones.each do |zone|
|
@@ -2976,8 +2923,8 @@ class Standard
|
|
2976
2923
|
|
2977
2924
|
# zone sizing
|
2978
2925
|
sizing_zone = zone.sizingZone
|
2979
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
2980
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
2926
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2927
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
2981
2928
|
sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008)
|
2982
2929
|
sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008)
|
2983
2930
|
end
|
@@ -3000,6 +2947,19 @@ class Standard
|
|
3000
2947
|
hot_water_loop: nil,
|
3001
2948
|
fan_type: 'ConstantVolume')
|
3002
2949
|
|
2950
|
+
# default design temperatures used across all air loops
|
2951
|
+
dsgn_temps = standard_design_sizing_temperatures
|
2952
|
+
unless hot_water_loop.nil?
|
2953
|
+
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
2954
|
+
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
2955
|
+
end
|
2956
|
+
|
2957
|
+
# adjusted zone design temperatures for ptac
|
2958
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
2959
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
2960
|
+
dsgn_temps['zn_clg_dsgn_sup_air_temp_f'] = 57.0
|
2961
|
+
dsgn_temps['zn_clg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_clg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
2962
|
+
|
3003
2963
|
# make a PTAC for each zone
|
3004
2964
|
ptacs = []
|
3005
2965
|
thermal_zones.each do |zone|
|
@@ -3007,17 +2967,21 @@ class Standard
|
|
3007
2967
|
|
3008
2968
|
# zone sizing
|
3009
2969
|
sizing_zone = zone.sizingZone
|
3010
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
3011
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
2970
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
2971
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3012
2972
|
sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008)
|
3013
2973
|
sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008)
|
3014
2974
|
|
3015
2975
|
# add fan
|
3016
2976
|
if fan_type == 'ConstantVolume'
|
3017
|
-
fan = create_fan_by_name(model,
|
2977
|
+
fan = create_fan_by_name(model,
|
2978
|
+
'PTAC_CAV_Fan',
|
2979
|
+
fan_name: "#{zone.name} PTAC Fan")
|
3018
2980
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3019
2981
|
elsif fan_type == 'Cycling'
|
3020
|
-
fan = create_fan_by_name(model,
|
2982
|
+
fan = create_fan_by_name(model,
|
2983
|
+
'PTAC_Cycling_Fan',
|
2984
|
+
fan_name: "#{zone.name} PTAC Fan")
|
3021
2985
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3022
2986
|
else
|
3023
2987
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "ptac_fan_type of #{fan_type} is not recognized.")
|
@@ -3026,9 +2990,11 @@ class Standard
|
|
3026
2990
|
# add heating coil
|
3027
2991
|
case heating_type
|
3028
2992
|
when 'NaturalGas', 'Gas'
|
3029
|
-
htg_coil = create_coil_heating_gas(model,
|
2993
|
+
htg_coil = create_coil_heating_gas(model,
|
2994
|
+
name: "#{zone.name} PTAC Gas Htg Coil")
|
3030
2995
|
when 'Electricity', 'Electric'
|
3031
|
-
htg_coil = create_coil_heating_electric(model,
|
2996
|
+
htg_coil = create_coil_heating_electric(model,
|
2997
|
+
name: "#{zone.name} PTAC Electric Htg Coil")
|
3032
2998
|
when nil
|
3033
2999
|
htg_coil = create_coil_heating_electric(model,
|
3034
3000
|
name: "#{zone.name} PTAC No Heat",
|
@@ -3039,8 +3005,6 @@ class Standard
|
|
3039
3005
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'No hot water plant loop supplied')
|
3040
3006
|
return false
|
3041
3007
|
end
|
3042
|
-
hw_temp_c = hot_water_loop.sizingPlant.designLoopExitTemperature
|
3043
|
-
hw_delta_t_k = hot_water_loop.sizingPlant.loopDesignTemperatureDifference
|
3044
3008
|
htg_coil = create_coil_heating_water(model,
|
3045
3009
|
hot_water_loop,
|
3046
3010
|
name: "#{hot_water_loop.name} Water Htg Coil",
|
@@ -3052,9 +3016,12 @@ class Standard
|
|
3052
3016
|
|
3053
3017
|
# add cooling coil
|
3054
3018
|
if cooling_type == 'Two Speed DX AC'
|
3055
|
-
clg_coil = create_coil_cooling_dx_two_speed(model,
|
3019
|
+
clg_coil = create_coil_cooling_dx_two_speed(model,
|
3020
|
+
name: "#{zone.name} PTAC 2spd DX AC Clg Coil")
|
3056
3021
|
elsif cooling_type == 'Single Speed DX AC'
|
3057
|
-
clg_coil = create_coil_cooling_dx_single_speed(model,
|
3022
|
+
clg_coil = create_coil_cooling_dx_single_speed(model,
|
3023
|
+
name: "#{zone.name} PTAC 1spd DX AC Clg Coil",
|
3024
|
+
type: 'PTAC')
|
3058
3025
|
else
|
3059
3026
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "ptac_cooling_type of #{cooling_type} is not recognized.")
|
3060
3027
|
end
|
@@ -3087,6 +3054,16 @@ class Standard
|
|
3087
3054
|
def model_add_pthp(model,
|
3088
3055
|
thermal_zones,
|
3089
3056
|
fan_type: 'Cycling')
|
3057
|
+
|
3058
|
+
# default design temperatures used across all air loops
|
3059
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3060
|
+
|
3061
|
+
# adjusted zone design temperatures for pthp
|
3062
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
3063
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3064
|
+
dsgn_temps['zn_clg_dsgn_sup_air_temp_f'] = 57.0
|
3065
|
+
dsgn_temps['zn_clg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_clg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3066
|
+
|
3090
3067
|
# make a PTHP for each zone
|
3091
3068
|
pthps = []
|
3092
3069
|
thermal_zones.each do |zone|
|
@@ -3094,17 +3071,21 @@ class Standard
|
|
3094
3071
|
|
3095
3072
|
# zone sizing
|
3096
3073
|
sizing_zone = zone.sizingZone
|
3097
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
3098
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
3074
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
3075
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3099
3076
|
sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008)
|
3100
3077
|
sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008)
|
3101
3078
|
|
3102
3079
|
# add fan
|
3103
3080
|
if fan_type == 'ConstantVolume'
|
3104
|
-
fan = create_fan_by_name(model,
|
3081
|
+
fan = create_fan_by_name(model,
|
3082
|
+
'PTAC_CAV_Fan',
|
3083
|
+
fan_name: "#{zone.name} PTAC Fan")
|
3105
3084
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3106
3085
|
elsif fan_type == 'Cycling'
|
3107
|
-
fan = create_fan_by_name(model,
|
3086
|
+
fan = create_fan_by_name(model,
|
3087
|
+
'PTAC_Cycling_Fan',
|
3088
|
+
fan_name: "#{zone.name} PTAC Fan")
|
3108
3089
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3109
3090
|
else
|
3110
3091
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "PTHP fan_type of #{fan_type} is not recognized.")
|
@@ -3112,11 +3093,15 @@ class Standard
|
|
3112
3093
|
end
|
3113
3094
|
|
3114
3095
|
# add heating coil
|
3115
|
-
htg_coil = create_coil_heating_dx_single_speed(model,
|
3096
|
+
htg_coil = create_coil_heating_dx_single_speed(model,
|
3097
|
+
name: "#{zone.name} PTHP Htg Coil")
|
3116
3098
|
# add cooling coil
|
3117
|
-
clg_coil = create_coil_cooling_dx_single_speed(model,
|
3099
|
+
clg_coil = create_coil_cooling_dx_single_speed(model,
|
3100
|
+
name: "#{zone.name} PTHP Clg Coil",
|
3101
|
+
type: 'Heat Pump')
|
3118
3102
|
# supplemental heating coil
|
3119
|
-
supplemental_htg_coil = create_coil_heating_electric(model,
|
3103
|
+
supplemental_htg_coil = create_coil_heating_electric(model,
|
3104
|
+
name: "#{zone.name} PTHP Supplemental Htg Coil")
|
3120
3105
|
# wrap coils in a PTHP system
|
3121
3106
|
pthp_system = OpenStudio::Model::ZoneHVACPackagedTerminalHeatPump.new(model,
|
3122
3107
|
model.alwaysOnDiscreteSchedule,
|
@@ -3161,7 +3146,7 @@ class Standard
|
|
3161
3146
|
rated_inlet_water_temperature: 180.0,
|
3162
3147
|
rated_outlet_water_temperature: 160.0,
|
3163
3148
|
rated_inlet_air_temperature: 60.0,
|
3164
|
-
rated_outlet_air_temperature:
|
3149
|
+
rated_outlet_air_temperature: 104.0)
|
3165
3150
|
|
3166
3151
|
# hvac operation schedule
|
3167
3152
|
if hvac_op_sch.nil?
|
@@ -3174,6 +3159,13 @@ class Standard
|
|
3174
3159
|
fan_control_type = 'ConstantVolume' if fan_control_type.nil?
|
3175
3160
|
fan_pressure_rise = 0.2 if fan_pressure_rise.nil?
|
3176
3161
|
|
3162
|
+
# default design temperatures used across all air loops
|
3163
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3164
|
+
|
3165
|
+
# adjusted zone design heating temperature for unit heater
|
3166
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
3167
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3168
|
+
|
3177
3169
|
# make a unit heater for each zone
|
3178
3170
|
unit_heaters = []
|
3179
3171
|
thermal_zones.each do |zone|
|
@@ -3181,10 +3173,7 @@ class Standard
|
|
3181
3173
|
|
3182
3174
|
# zone sizing
|
3183
3175
|
sizing_zone = zone.sizingZone
|
3184
|
-
sizing_zone.
|
3185
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(50.0)
|
3186
|
-
sizing_zone.setZoneCoolingDesignSupplyAirHumidityRatio(0.008)
|
3187
|
-
sizing_zone.setZoneHeatingDesignSupplyAirHumidityRatio(0.008)
|
3176
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3188
3177
|
|
3189
3178
|
# add fan
|
3190
3179
|
fan = create_fan_by_name(model,
|
@@ -3195,9 +3184,13 @@ class Standard
|
|
3195
3184
|
|
3196
3185
|
# add heating coil
|
3197
3186
|
if heating_type == 'NaturalGas' || heating_type == 'Gas'
|
3198
|
-
htg_coil = create_coil_heating_gas(model,
|
3187
|
+
htg_coil = create_coil_heating_gas(model,
|
3188
|
+
name: "#{zone.name} UnitHeater Gas Htg Coil",
|
3189
|
+
schedule: hvac_op_sch)
|
3199
3190
|
elsif heating_type == 'Electricity' || heating_type == 'Electric'
|
3200
|
-
htg_coil = create_coil_heating_electric(model,
|
3191
|
+
htg_coil = create_coil_heating_electric(model,
|
3192
|
+
name: "#{zone.name} UnitHeater Electric Htg Coil",
|
3193
|
+
schedule: hvac_op_sch)
|
3201
3194
|
elsif heating_type == 'DistrictHeating' && !hot_water_loop.nil?
|
3202
3195
|
# control temperature for hot water loop
|
3203
3196
|
if rated_inlet_water_temperature.nil?
|
@@ -3216,7 +3209,7 @@ class Standard
|
|
3216
3209
|
rated_inlet_air_temperature_c = OpenStudio.convert(rated_inlet_air_temperature, 'F', 'C').get
|
3217
3210
|
end
|
3218
3211
|
if rated_outlet_air_temperature.nil?
|
3219
|
-
rated_outlet_air_temperature_c = OpenStudio.convert(
|
3212
|
+
rated_outlet_air_temperature_c = OpenStudio.convert(104.0, 'F', 'C').get
|
3220
3213
|
else
|
3221
3214
|
rated_outlet_air_temperature_c = OpenStudio.convert(rated_outlet_air_temperature, 'F', 'C').get
|
3222
3215
|
end
|
@@ -3233,8 +3226,11 @@ class Standard
|
|
3233
3226
|
end
|
3234
3227
|
|
3235
3228
|
# create unit heater
|
3236
|
-
unit_heater = OpenStudio::Model::ZoneHVACUnitHeater.new(model,
|
3237
|
-
|
3229
|
+
unit_heater = OpenStudio::Model::ZoneHVACUnitHeater.new(model,
|
3230
|
+
hvac_op_sch,
|
3231
|
+
fan,
|
3232
|
+
htg_coil)
|
3233
|
+
unit_heater.setName("#{zone.name} Unit Heater")
|
3238
3234
|
unit_heater.setFanControlType(fan_control_type)
|
3239
3235
|
unit_heater.addToThermalZone(zone)
|
3240
3236
|
unit_heaters << unit_heater
|
@@ -3300,19 +3296,16 @@ class Standard
|
|
3300
3296
|
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.Model.Model', "---#{zone.name}")
|
3301
3297
|
end
|
3302
3298
|
|
3303
|
-
#
|
3304
|
-
|
3305
|
-
clg_sa_temp_f = 70
|
3306
|
-
max_sa_temp_f = 78
|
3307
|
-
htg_sa_temp_f = 122 # Not used
|
3308
|
-
|
3309
|
-
min_sa_temp_c = OpenStudio.convert(min_sa_temp_f, 'F', 'C').get
|
3310
|
-
clg_sa_temp_c = OpenStudio.convert(clg_sa_temp_f, 'F', 'C').get
|
3311
|
-
max_sa_temp_c = OpenStudio.convert(max_sa_temp_f, 'F', 'C').get
|
3312
|
-
htg_sa_temp_c = OpenStudio.convert(htg_sa_temp_f, 'F', 'C').get
|
3299
|
+
# default design temperatures used across all air loops
|
3300
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3313
3301
|
|
3314
|
-
|
3315
|
-
|
3302
|
+
# adjusted design temperatures for evap cooler
|
3303
|
+
dsgn_temps['clg_dsgn_sup_air_temp_f'] = 70.0
|
3304
|
+
dsgn_temps['clg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['clg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3305
|
+
dsgn_temps['max_clg_dsgn_sup_air_temp_f'] = 78.0
|
3306
|
+
dsgn_temps['max_clg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['max_clg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3307
|
+
dsgn_temps['approach_r'] = 3.0 # wetbulb approach temperature
|
3308
|
+
dsgn_temps['approach_k'] = OpenStudio.convert(dsgn_temps['approach_r'], 'R', 'K').get
|
3316
3309
|
|
3317
3310
|
# EMS programs
|
3318
3311
|
programs = []
|
@@ -3326,6 +3319,19 @@ class Standard
|
|
3326
3319
|
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
3327
3320
|
air_loop.setName("#{zone_name_clean} Evaporative Cooler")
|
3328
3321
|
|
3322
|
+
# default design settings used across all air loops
|
3323
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps)
|
3324
|
+
|
3325
|
+
# air handler controls
|
3326
|
+
# setpoint follows OAT WetBulb
|
3327
|
+
evap_stpt_manager = OpenStudio::Model::SetpointManagerFollowOutdoorAirTemperature.new(model)
|
3328
|
+
evap_stpt_manager.setName("#{dsgn_temps['approach_r']} F above OATwb")
|
3329
|
+
evap_stpt_manager.setReferenceTemperatureType('OutdoorAirWetBulb')
|
3330
|
+
evap_stpt_manager.setMaximumSetpointTemperature(dsgn_temps['max_clg_dsgn_sup_air_temp_c'])
|
3331
|
+
evap_stpt_manager.setMinimumSetpointTemperature(dsgn_temps['clg_dsgn_sup_air_temp_c'])
|
3332
|
+
evap_stpt_manager.setOffsetTemperatureDifference(dsgn_temps['approach_k'])
|
3333
|
+
evap_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
3334
|
+
|
3329
3335
|
# Schedule to control the airloop availability
|
3330
3336
|
air_loop_avail_sch = OpenStudio::Model::ScheduleConstant.new(model)
|
3331
3337
|
air_loop_avail_sch.setName("#{air_loop.name} Availability Sch")
|
@@ -3336,12 +3342,15 @@ class Standard
|
|
3336
3342
|
# Without this EMS, the airloop runs 24/7-365 even when there is no load in the zone.
|
3337
3343
|
|
3338
3344
|
# Create a sensor to read the zone load
|
3339
|
-
zn_load_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
3345
|
+
zn_load_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
3346
|
+
'Zone Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate')
|
3340
3347
|
zn_load_sensor.setName("#{zone_name_clean.to_s.gsub(/[ +-.]/,'_')} Clg Load Sensor")
|
3341
3348
|
zn_load_sensor.setKeyName(zone.handle.to_s)
|
3342
3349
|
|
3343
3350
|
# Create an actuator to set the airloop availability
|
3344
|
-
air_loop_avail_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(air_loop_avail_sch,
|
3351
|
+
air_loop_avail_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(air_loop_avail_sch,
|
3352
|
+
'Schedule:Constant',
|
3353
|
+
'Schedule Value')
|
3345
3354
|
air_loop_avail_actuator.setName("#{air_loop.name.to_s.gsub(/[ +-.]/,'_')} Availability Actuator")
|
3346
3355
|
|
3347
3356
|
# Create a program to turn on Evap Cooler if
|
@@ -3360,23 +3369,6 @@ class Standard
|
|
3360
3369
|
|
3361
3370
|
programs << avail_program
|
3362
3371
|
|
3363
|
-
# Setpoint follows OAT WetBulb
|
3364
|
-
evap_stpt_manager = OpenStudio::Model::SetpointManagerFollowOutdoorAirTemperature.new(model)
|
3365
|
-
evap_stpt_manager.setName("#{approach_r} F above OATwb")
|
3366
|
-
evap_stpt_manager.setReferenceTemperatureType('OutdoorAirWetBulb')
|
3367
|
-
evap_stpt_manager.setMaximumSetpointTemperature(max_sa_temp_c)
|
3368
|
-
evap_stpt_manager.setMinimumSetpointTemperature(min_sa_temp_c)
|
3369
|
-
evap_stpt_manager.setOffsetTemperatureDifference(approach_k)
|
3370
|
-
evap_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
3371
|
-
|
3372
|
-
# Air handler sizing
|
3373
|
-
sizing_system = air_loop.sizingSystem
|
3374
|
-
sizing_system.setCentralCoolingDesignSupplyAirTemperature(clg_sa_temp_c)
|
3375
|
-
sizing_system.setCentralHeatingDesignSupplyAirTemperature(htg_sa_temp_c)
|
3376
|
-
sizing_system.setAllOutdoorAirinCooling(true)
|
3377
|
-
sizing_system.setAllOutdoorAirinHeating(true)
|
3378
|
-
sizing_system.setSystemOutdoorAirMethod('ZoneSum')
|
3379
|
-
|
3380
3372
|
# Direct Evap Cooler
|
3381
3373
|
# TODO: better assumptions for evap cooler performance and fan pressure rise
|
3382
3374
|
evap = OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial.new(model, model.alwaysOnDiscreteSchedule)
|
@@ -3385,7 +3377,9 @@ class Standard
|
|
3385
3377
|
evap.addToNode(air_loop.supplyInletNode)
|
3386
3378
|
|
3387
3379
|
# Fan (cycling), must be inside unitary system to cycle on airloop
|
3388
|
-
fan = create_fan_by_name(model,
|
3380
|
+
fan = create_fan_by_name(model,
|
3381
|
+
'Evap_Cooler_Supply_Fan',
|
3382
|
+
fan_name: "#{zone.name} Evap Cooler Supply Fan")
|
3389
3383
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3390
3384
|
|
3391
3385
|
# Dummy zero-capacity cooling coil
|
@@ -3397,7 +3391,7 @@ class Standard
|
|
3397
3391
|
unitary_system.setSupplyFan(fan)
|
3398
3392
|
unitary_system.setCoolingCoil(clg_coil)
|
3399
3393
|
unitary_system.setControllingZoneorThermostatLocation(zone)
|
3400
|
-
unitary_system.setMaximumSupplyAirTemperature(
|
3394
|
+
unitary_system.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3401
3395
|
unitary_system.setFanPlacement('BlowThrough')
|
3402
3396
|
unitary_system.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
|
3403
3397
|
unitary_system.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
|
@@ -3429,9 +3423,7 @@ class Standard
|
|
3429
3423
|
|
3430
3424
|
sizing_zone = zone.sizingZone
|
3431
3425
|
sizing_zone.setCoolingDesignAirFlowMethod('DesignDay')
|
3432
|
-
sizing_zone.
|
3433
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(clg_sa_temp_c)
|
3434
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(htg_sa_temp_c)
|
3426
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
3435
3427
|
|
3436
3428
|
evap_coolers << air_loop
|
3437
3429
|
end
|
@@ -3493,9 +3485,9 @@ class Standard
|
|
3493
3485
|
vrf_outdoor_unit = create_air_conditioner_variable_refrigerant_flow(model,
|
3494
3486
|
name: "#{thermal_zones.size} Zone VRF System",
|
3495
3487
|
master_zone: master_zone)
|
3496
|
-
|
3497
|
-
|
3498
|
-
|
3488
|
+
|
3489
|
+
# default design temperatures used across all air loops
|
3490
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3499
3491
|
|
3500
3492
|
vrfs = []
|
3501
3493
|
thermal_zones.each do |zone|
|
@@ -3503,8 +3495,8 @@ class Standard
|
|
3503
3495
|
|
3504
3496
|
# zone sizing
|
3505
3497
|
sizing_zone = zone.sizingZone
|
3506
|
-
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(
|
3507
|
-
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(
|
3498
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
3499
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3508
3500
|
|
3509
3501
|
# add vrf terminal unit
|
3510
3502
|
vrf_terminal_unit = OpenStudio::Model::ZoneHVACTerminalUnitVariableRefrigerantFlow.new(model)
|
@@ -3513,15 +3505,15 @@ class Standard
|
|
3513
3505
|
vrf_terminal_unit.setTerminalUnitAvailabilityschedule(model.alwaysOnDiscreteSchedule)
|
3514
3506
|
|
3515
3507
|
# no outdoor air assumed
|
3516
|
-
vrf_terminal_unit.setOutdoorAirFlowRateDuringCoolingOperation(0)
|
3517
|
-
vrf_terminal_unit.setOutdoorAirFlowRateDuringHeatingOperation(0)
|
3518
|
-
vrf_terminal_unit.setOutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded(0)
|
3508
|
+
vrf_terminal_unit.setOutdoorAirFlowRateDuringCoolingOperation(0.0)
|
3509
|
+
vrf_terminal_unit.setOutdoorAirFlowRateDuringHeatingOperation(0.0)
|
3510
|
+
vrf_terminal_unit.setOutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded(0.0)
|
3519
3511
|
|
3520
3512
|
# set fan variables
|
3521
3513
|
# always off denotes cycling fan
|
3522
3514
|
vrf_terminal_unit.setSupplyAirFanOperatingModeSchedule(model.alwaysOffDiscreteSchedule)
|
3523
3515
|
vrf_fan = vrf_terminal_unit.supplyAirFan.to_FanOnOff.get
|
3524
|
-
vrf_fan.setPressureRise(300)
|
3516
|
+
vrf_fan.setPressureRise(300.0)
|
3525
3517
|
vrf_fan.setMotorEfficiency(0.8)
|
3526
3518
|
vrf_fan.setFanEfficiency(0.6)
|
3527
3519
|
vrf_fan.setName("#{zone.name} VRF Unit Cycling Fan")
|
@@ -3548,17 +3540,16 @@ class Standard
|
|
3548
3540
|
hot_water_loop: nil,
|
3549
3541
|
ventilation: false)
|
3550
3542
|
|
3551
|
-
#
|
3552
|
-
|
3553
|
-
zn_dsn_htg_sa_temp_c = OpenStudio.convert(104.0, 'F', 'C').get
|
3543
|
+
# default design temperatures used across all air loops
|
3544
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3554
3545
|
|
3555
3546
|
# make a fan coil unit for each zone
|
3556
3547
|
fcus = []
|
3557
3548
|
thermal_zones.each do |zone|
|
3558
3549
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding fan coil for #{zone.name}.")
|
3559
|
-
|
3560
|
-
|
3561
|
-
|
3550
|
+
sizing_zone = zone.sizingZone
|
3551
|
+
sizing_zone.setZoneCoolingDesignSupplyAirTemperature(dsgn_temps['zn_clg_dsgn_sup_air_temp_c'])
|
3552
|
+
sizing_zone.setZoneHeatingDesignSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3562
3553
|
|
3563
3554
|
if chilled_water_loop
|
3564
3555
|
fcu_clg_coil = create_coil_cooling_water(model,
|
@@ -3573,7 +3564,7 @@ class Standard
|
|
3573
3564
|
fcu_htg_coil = create_coil_heating_water(model,
|
3574
3565
|
hot_water_loop,
|
3575
3566
|
name: "#{zone.name} FCU Heating Coil",
|
3576
|
-
rated_outlet_air_temperature:
|
3567
|
+
rated_outlet_air_temperature: dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3577
3568
|
else
|
3578
3569
|
# Zero-capacity, always-off electric heating coil
|
3579
3570
|
fcu_htg_coil = create_coil_heating_electric(model,
|
@@ -3645,7 +3636,11 @@ class Standard
|
|
3645
3636
|
name: "#{zone.name} Window AC Always Off Htg Coil",
|
3646
3637
|
schedule: model.alwaysOffDiscreteSchedule,
|
3647
3638
|
nominal_capacity: 0)
|
3648
|
-
ptac = OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner.new(model,
|
3639
|
+
ptac = OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner.new(model,
|
3640
|
+
model.alwaysOnDiscreteSchedule,
|
3641
|
+
fan,
|
3642
|
+
htg_coil,
|
3643
|
+
clg_coil)
|
3649
3644
|
ptac.setName("#{zone.name} Window AC")
|
3650
3645
|
ptac.setSupplyAirFanOperatingModeSchedule(model.alwaysOffDiscreteSchedule)
|
3651
3646
|
ptac.addToThermalZone(zone)
|
@@ -3697,6 +3692,21 @@ class Standard
|
|
3697
3692
|
air_loop.setName("#{zone.name} #{equip_name}")
|
3698
3693
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding furnace AC for #{zone.name}.")
|
3699
3694
|
|
3695
|
+
|
3696
|
+
# default design temperatures across all air loops
|
3697
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3698
|
+
|
3699
|
+
# adjusted temperatures for furnace_central_ac
|
3700
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
3701
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3702
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_f']
|
3703
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_c']
|
3704
|
+
|
3705
|
+
# default design settings used across all air loops
|
3706
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps, sizing_option: 'NonCoincident')
|
3707
|
+
sizing_system.setAllOutdoorAirinCooling(true)
|
3708
|
+
sizing_system.setAllOutdoorAirinHeating(true)
|
3709
|
+
|
3700
3710
|
# create heating coil
|
3701
3711
|
htg_coil = nil
|
3702
3712
|
if heating
|
@@ -3726,7 +3736,7 @@ class Standard
|
|
3726
3736
|
# create fan
|
3727
3737
|
fan = create_fan_by_name(model,
|
3728
3738
|
'Residential_HVAC_Fan',
|
3729
|
-
fan_name: "#{air_loop.name}
|
3739
|
+
fan_name: "#{air_loop.name} Supply Fan",
|
3730
3740
|
end_use_subcategory: 'Residential HVAC Fans')
|
3731
3741
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3732
3742
|
|
@@ -3743,9 +3753,9 @@ class Standard
|
|
3743
3753
|
|
3744
3754
|
# create unitary system (holds the coils and fan)
|
3745
3755
|
unitary = OpenStudio::Model::AirLoopHVACUnitarySystem.new(model)
|
3746
|
-
unitary.setName("#{air_loop.name}
|
3756
|
+
unitary.setName("#{air_loop.name} Unitary System")
|
3747
3757
|
unitary.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3748
|
-
unitary.setMaximumSupplyAirTemperature(
|
3758
|
+
unitary.setMaximumSupplyAirTemperature(dsgn_temps['zn_htg_dsgn_sup_air_temp_c'])
|
3749
3759
|
unitary.setControllingZoneorThermostatLocation(zone)
|
3750
3760
|
unitary.addToNode(air_loop.supplyInletNode)
|
3751
3761
|
|
@@ -3763,7 +3773,7 @@ class Standard
|
|
3763
3773
|
|
3764
3774
|
# create a diffuser
|
3765
3775
|
diffuser = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(model, model.alwaysOnDiscreteSchedule)
|
3766
|
-
diffuser.setName("#{zone.name}
|
3776
|
+
diffuser.setName("#{zone.name} Direct Air")
|
3767
3777
|
air_loop.addBranchForZone(zone, diffuser)
|
3768
3778
|
|
3769
3779
|
furnaces << air_loop
|
@@ -3804,6 +3814,20 @@ class Standard
|
|
3804
3814
|
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
3805
3815
|
air_loop.setName("#{zone.name} Central Air Source HP")
|
3806
3816
|
|
3817
|
+
# default design temperatures across all air loops
|
3818
|
+
dsgn_temps = standard_design_sizing_temperatures
|
3819
|
+
|
3820
|
+
# adjusted temperatures for furnace_central_ac
|
3821
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_f'] = 122.0
|
3822
|
+
dsgn_temps['zn_htg_dsgn_sup_air_temp_c'] = OpenStudio.convert(dsgn_temps['zn_htg_dsgn_sup_air_temp_f'], 'F', 'C').get
|
3823
|
+
dsgn_temps['htg_dsgn_sup_air_temp_f'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_f']
|
3824
|
+
dsgn_temps['htg_dsgn_sup_air_temp_c'] = dsgn_temps['zn_htg_dsgn_sup_air_temp_c']
|
3825
|
+
|
3826
|
+
# default design settings used across all air loops
|
3827
|
+
sizing_system = adjust_sizing_system(air_loop, dsgn_temps, sizing_option: 'NonCoincident')
|
3828
|
+
sizing_system.setAllOutdoorAirinCooling(true)
|
3829
|
+
sizing_system.setAllOutdoorAirinHeating(true)
|
3830
|
+
|
3807
3831
|
# create heating coil
|
3808
3832
|
htg_coil = nil
|
3809
3833
|
supplemental_htg_coil = nil
|
@@ -3824,14 +3848,15 @@ class Standard
|
|
3824
3848
|
# Supplemental Heating Coil
|
3825
3849
|
|
3826
3850
|
# create supplemental heating coil
|
3827
|
-
supplemental_htg_coil = create_coil_heating_electric(model,
|
3851
|
+
supplemental_htg_coil = create_coil_heating_electric(model,
|
3852
|
+
name: "#{air_loop.name} Supplemental Htg Coil")
|
3828
3853
|
end
|
3829
3854
|
|
3830
3855
|
# create cooling coil
|
3831
3856
|
clg_coil = nil
|
3832
3857
|
if cooling
|
3833
3858
|
clg_coil = create_coil_cooling_dx_single_speed(model,
|
3834
|
-
name: "#{air_loop.name}
|
3859
|
+
name: "#{air_loop.name} Cooling Coil",
|
3835
3860
|
type: 'Residential Central ASHP',
|
3836
3861
|
cop: cop)
|
3837
3862
|
clg_coil.setRatedSensibleHeatRatio(shr)
|
@@ -3848,7 +3873,7 @@ class Standard
|
|
3848
3873
|
# create fan
|
3849
3874
|
fan = create_fan_by_name(model,
|
3850
3875
|
'Residential_HVAC_Fan',
|
3851
|
-
fan_name: "#{air_loop.name}
|
3876
|
+
fan_name: "#{air_loop.name} Supply Fan",
|
3852
3877
|
end_use_subcategory: 'Residential HVAC Fans')
|
3853
3878
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3854
3879
|
|
@@ -3865,7 +3890,7 @@ class Standard
|
|
3865
3890
|
|
3866
3891
|
# create unitary system (holds the coils and fan)
|
3867
3892
|
unitary = OpenStudio::Model::AirLoopHVACUnitarySystem.new(model)
|
3868
|
-
unitary.setName("#{air_loop.name}
|
3893
|
+
unitary.setName("#{air_loop.name} Unitary System")
|
3869
3894
|
unitary.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3870
3895
|
unitary.setMaximumSupplyAirTemperature(OpenStudio.convert(170.0, 'F', 'C').get) # higher temp for supplemental heat as to not severely limit its use, resulting in unmet hours.
|
3871
3896
|
unitary.setMaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation(OpenStudio.convert(40.0, 'F', 'C').get)
|
@@ -3885,7 +3910,7 @@ class Standard
|
|
3885
3910
|
|
3886
3911
|
# create a diffuser
|
3887
3912
|
diffuser = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(model, model.alwaysOnDiscreteSchedule)
|
3888
|
-
diffuser.setName(" #{zone.name}
|
3913
|
+
diffuser.setName(" #{zone.name} Direct Air")
|
3889
3914
|
air_loop.addBranchForZone(zone, diffuser)
|
3890
3915
|
|
3891
3916
|
hps << air_loop
|
@@ -3910,15 +3935,27 @@ class Standard
|
|
3910
3935
|
|
3911
3936
|
water_to_air_hp_systems = []
|
3912
3937
|
thermal_zones.each do |zone|
|
3913
|
-
supplemental_htg_coil = create_coil_heating_electric(model,
|
3914
|
-
|
3915
|
-
|
3938
|
+
supplemental_htg_coil = create_coil_heating_electric(model,
|
3939
|
+
name: "#{zone.name} Supplemental Htg Coil")
|
3940
|
+
htg_coil = create_coil_heating_water_to_air_heat_pump_equation_fit(model,
|
3941
|
+
condenser_loop,
|
3942
|
+
name: "#{zone.name} Water-to-Air HP Htg Coil")
|
3943
|
+
clg_coil = create_coil_cooling_water_to_air_heat_pump_equation_fit(model,
|
3944
|
+
condenser_loop,
|
3945
|
+
name: "#{zone.name} Water-to-Air HP Clg Coil")
|
3916
3946
|
|
3917
3947
|
# add fan
|
3918
|
-
fan = create_fan_by_name(model,
|
3948
|
+
fan = create_fan_by_name(model,
|
3949
|
+
'WSHP_Fan',
|
3950
|
+
fan_name: "#{zone.name} WSHP Fan")
|
3919
3951
|
fan.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3920
3952
|
|
3921
|
-
water_to_air_hp_system = OpenStudio::Model::ZoneHVACWaterToAirHeatPump.new(model,
|
3953
|
+
water_to_air_hp_system = OpenStudio::Model::ZoneHVACWaterToAirHeatPump.new(model,
|
3954
|
+
model.alwaysOnDiscreteSchedule,
|
3955
|
+
fan,
|
3956
|
+
htg_coil,
|
3957
|
+
clg_coil,
|
3958
|
+
supplemental_htg_coil)
|
3922
3959
|
water_to_air_hp_system.setName("#{zone.name} WSHP")
|
3923
3960
|
unless ventilation
|
3924
3961
|
water_to_air_hp_system.setOutdoorAirFlowRateDuringHeatingOperation(OpenStudio::OptionalDouble.new(0.0))
|
@@ -3946,10 +3983,14 @@ class Standard
|
|
3946
3983
|
|
3947
3984
|
# Determine the OA requirement for this zone
|
3948
3985
|
min_oa_flow_m3_per_s_per_m2 = thermal_zone_outdoor_airflow_rate_per_area(zone)
|
3949
|
-
supply_fan = create_fan_by_name(model,
|
3986
|
+
supply_fan = create_fan_by_name(model,
|
3987
|
+
'ERV_Supply_Fan',
|
3988
|
+
fan_name: "#{zone.name} ERV Supply Fan")
|
3950
3989
|
impeller_eff = fan_baseline_impeller_efficiency(supply_fan)
|
3951
3990
|
fan_change_impeller_efficiency(supply_fan, impeller_eff)
|
3952
|
-
exhaust_fan = create_fan_by_name(model,
|
3991
|
+
exhaust_fan = create_fan_by_name(model,
|
3992
|
+
'ERV_Supply_Fan',
|
3993
|
+
fan_name: "#{zone.name} ERV Exhaust Fan")
|
3953
3994
|
fan_change_impeller_efficiency(exhaust_fan, impeller_eff)
|
3954
3995
|
|
3955
3996
|
erv_controller = OpenStudio::Model::ZoneHVACEnergyRecoveryVentilatorController.new(model)
|
@@ -4006,11 +4047,11 @@ class Standard
|
|
4006
4047
|
hottest_erv_supply_c = OpenStudio.convert(hottest_erv_supply_f, 'F', 'C').get
|
4007
4048
|
|
4008
4049
|
# Ensure that zone sizing accounts for OA from ERV
|
4009
|
-
|
4010
|
-
|
4011
|
-
|
4012
|
-
|
4013
|
-
|
4050
|
+
sizing_zone = zone.sizingZone
|
4051
|
+
sizing_zone.setAccountforDedicatedOutdoorAirSystem(true)
|
4052
|
+
sizing_zone.setDedicatedOutdoorAirSystemControlStrategy('NeutralSupplyAir')
|
4053
|
+
sizing_zone.setDedicatedOutdoorAirLowSetpointTemperatureforDesign(coldest_erv_supply_c)
|
4054
|
+
sizing_zone.setDedicatedOutdoorAirHighSetpointTemperatureforDesign(hottest_erv_supply_c)
|
4014
4055
|
|
4015
4056
|
ervs << zone_hvac
|
4016
4057
|
end
|
@@ -4020,19 +4061,158 @@ class Standard
|
|
4020
4061
|
|
4021
4062
|
# Adds ideal air loads systems for each zone.
|
4022
4063
|
#
|
4023
|
-
# @param thermal_zones [Array<OpenStudio::Model::ThermalZone>] array of zones to
|
4064
|
+
# @param thermal_zones [Array<OpenStudio::Model::ThermalZone>] array of zones to enable ideal air loads
|
4065
|
+
# @param hvac_op_sch [String] name of the HVAC operation schedule, default is always on
|
4066
|
+
# @param heat_avail_sch [String] name of the heating availability schedule, default is always on
|
4067
|
+
# @param cool_avail_sch [String] name of the cooling availability schedule, default is always on
|
4068
|
+
# @param heat_limit_type [String] heating limit type
|
4069
|
+
# options are 'NoLimit', 'LimitFlowRate', 'LimitCapacity', and 'LimitFlowRateAndCapacity'
|
4070
|
+
# @param cool_limit_type [String] cooling limit type
|
4071
|
+
# options are 'NoLimit', 'LimitFlowRate', 'LimitCapacity', and 'LimitFlowRateAndCapacity'
|
4072
|
+
# @param dehumid_limit_type [String] dehumidification limit type
|
4073
|
+
# options are 'None', 'ConstantSensibleHeatRatio', 'Humidistat', 'ConstantSupplyHumidityRatio'
|
4074
|
+
# @param cool_sensible_heat_ratio [Double] cooling sensible heat ratio if dehumidification limit type is 'ConstantSensibleHeatRatio'
|
4075
|
+
# @param humid_ctrl_type [String] humidification control type
|
4076
|
+
# options are 'None', 'Humidistat', 'ConstantSupplyHumidityRatio'
|
4077
|
+
# @param include_outdoor_air [Boolean] include design specification outdoor air ventilation
|
4078
|
+
# @param enable_dcv [Boolean] include demand control ventilation, uses occupancy schedule if true
|
4079
|
+
# @param econo_ctrl_mthd [String] economizer control method (require a cool_limit_type and include_outdoor_air set to true)
|
4080
|
+
# options are 'NoEconomizer', 'DifferentialDryBulb', 'DifferentialEnthalpy'
|
4081
|
+
# @param heat_recovery_type [String] heat recovery type
|
4082
|
+
# options are 'None', 'Sensible', 'Enthalpy'
|
4083
|
+
# @param heat_recovery_sensible_eff [Double] heat recovery sensible effectivness if heat recovery specified
|
4084
|
+
# @param heat_recovery_latent_eff [Double] heat recovery latent effectivness if heat recovery specified
|
4085
|
+
# @param add_output_meters [Boolean] include and output custom meter objects to sum all ideal air loads values
|
4024
4086
|
# @return [Array<OpenStudio::Model::ZoneHVACIdealLoadsAirSystem>] an array of ideal air loads systems
|
4025
|
-
# TODO: enable default ventilation settings, see https://github.com/UnmetHours/openstudio-measures/tree/master/ideal_loads_options
|
4026
4087
|
def model_add_ideal_air_loads(model,
|
4027
|
-
thermal_zones
|
4088
|
+
thermal_zones,
|
4089
|
+
hvac_op_sch: nil,
|
4090
|
+
heat_avail_sch: nil,
|
4091
|
+
cool_avail_sch: nil,
|
4092
|
+
heat_limit_type: 'NoLimit',
|
4093
|
+
cool_limit_type: 'NoLimit',
|
4094
|
+
dehumid_limit_type: 'ConstantSensibleHeatRatio',
|
4095
|
+
cool_sensible_heat_ratio: 0.7,
|
4096
|
+
humid_ctrl_type: 'None',
|
4097
|
+
include_outdoor_air: true,
|
4098
|
+
enable_dcv: false,
|
4099
|
+
econo_ctrl_mthd: 'NoEconomizer',
|
4100
|
+
heat_recovery_type: 'None',
|
4101
|
+
heat_recovery_sensible_eff: 0.7,
|
4102
|
+
heat_recovery_latent_eff: 0.65,
|
4103
|
+
add_output_meters: false)
|
4104
|
+
|
4105
|
+
# set availability schedules
|
4106
|
+
if hvac_op_sch.nil?
|
4107
|
+
hvac_op_sch = model.alwaysOnDiscreteSchedule
|
4108
|
+
else
|
4109
|
+
hvac_op_sch = model_add_schedule(model, hvac_op_sch)
|
4110
|
+
end
|
4111
|
+
|
4112
|
+
# set heating availability schedules
|
4113
|
+
if heat_avail_sch.nil?
|
4114
|
+
heat_avail_sch = model.alwaysOnDiscreteSchedule
|
4115
|
+
else
|
4116
|
+
heat_avail_sch = model_add_schedule(model, heat_avail_sch)
|
4117
|
+
end
|
4118
|
+
|
4119
|
+
# set cooling availability schedules
|
4120
|
+
if cool_avail_sch.nil?
|
4121
|
+
cool_avail_sch = model.alwaysOnDiscreteSchedule
|
4122
|
+
else
|
4123
|
+
cool_avail_sch = model_add_schedule(model, cool_avail_sch)
|
4124
|
+
end
|
4125
|
+
|
4028
4126
|
ideal_systems = []
|
4029
4127
|
thermal_zones.each do |zone|
|
4030
4128
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Adding ideal air loads for for #{zone.name}.")
|
4031
4129
|
ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
|
4130
|
+
ideal_loads.setName("#{zone.name} Ideal Loads Air System")
|
4131
|
+
ideal_loads.setAvailabilitySchedule(hvac_op_sch)
|
4132
|
+
ideal_loads.setHeatingAvailabilitySchedule(heat_avail_sch)
|
4133
|
+
ideal_loads.setCoolingAvailabilitySchedule(cool_avail_sch)
|
4134
|
+
ideal_loads.setHeatingLimit(heat_limit_type)
|
4135
|
+
ideal_loads.setCoolingLimit(cool_limit_type)
|
4136
|
+
ideal_loads.setDehumidificationControlType(dehumid_limit_type)
|
4137
|
+
ideal_loads.setCoolingSensibleHeatRatio(cool_sensible_heat_ratio)
|
4138
|
+
ideal_loads.setHumidificationControlType(humid_ctrl_type)
|
4139
|
+
if include_outdoor_air
|
4140
|
+
# get the design specification outdoor air of the largest space in the zone
|
4141
|
+
# TODO: create a new design specification outdoor air object that sums ventilation rates and schedules if multiple design specification outdoor air objects
|
4142
|
+
space_areas = zone.spaces.map { |s| s.floorArea }
|
4143
|
+
largest_space = zone.spaces.select { |s| s.floorArea == space_areas.max }
|
4144
|
+
largest_space = largest_space[0]
|
4145
|
+
design_spec_oa = largest_space.designSpecificationOutdoorAir
|
4146
|
+
if design_spec_oa.is_initialized
|
4147
|
+
design_spec_oa = design_spec_oa.get
|
4148
|
+
ideal_loads.setDesignSpecificationOutdoorAirObject(design_spec_oa)
|
4149
|
+
else
|
4150
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Model.Model', "Outdoor air requested for ideal loads object, but space #{largest_space.name} in thermal zone #{zone.name} does not have a design specification outdoor air object.")
|
4151
|
+
end
|
4152
|
+
end
|
4153
|
+
if enable_dcv
|
4154
|
+
ideal_loads.setDemandControlledVentilationType('OccupancySchedule')
|
4155
|
+
else
|
4156
|
+
ideal_loads.setDemandControlledVentilationType('None')
|
4157
|
+
end
|
4158
|
+
ideal_loads.setOutdoorAirEconomizerType(econo_ctrl_mthd)
|
4159
|
+
ideal_loads.setHeatRecoveryType(heat_recovery_type)
|
4160
|
+
ideal_loads.setSensibleHeatRecoveryEffectiveness(heat_recovery_sensible_eff)
|
4161
|
+
ideal_loads.setLatentHeatRecoveryEffectiveness(heat_recovery_latent_eff)
|
4032
4162
|
ideal_loads.addToThermalZone(zone)
|
4033
4163
|
ideal_systems << ideal_loads
|
4034
4164
|
end
|
4035
4165
|
|
4166
|
+
if add_output_meters
|
4167
|
+
# ideal air loads system variables to include
|
4168
|
+
ideal_air_loads_system_variables = [
|
4169
|
+
'Zone Ideal Loads Supply Air Sensible Heating Energy',
|
4170
|
+
'Zone Ideal Loads Supply Air Latent Heating Energy',
|
4171
|
+
'Zone Ideal Loads Supply Air Total Heating Energy',
|
4172
|
+
'Zone Ideal Loads Supply Air Sensible Cooling Energy',
|
4173
|
+
'Zone Ideal Loads Supply Air Latent Cooling Energy',
|
4174
|
+
'Zone Ideal Loads Supply Air Total Cooling Energy',
|
4175
|
+
'Zone Ideal Loads Zone Sensible Heating Energy',
|
4176
|
+
'Zone Ideal Loads Zone Latent Heating Energy',
|
4177
|
+
'Zone Ideal Loads Zone Total Heating Energy',
|
4178
|
+
'Zone Ideal Loads Zone Sensible Cooling Energy',
|
4179
|
+
'Zone Ideal Loads Zone Latent Cooling Energy',
|
4180
|
+
'Zone Ideal Loads Zone Total Cooling Energy',
|
4181
|
+
'Zone Ideal Loads Outdoor Air Sensible Heating Energy',
|
4182
|
+
'Zone Ideal Loads Outdoor Air Latent Heating Energy',
|
4183
|
+
'Zone Ideal Loads Outdoor Air Total Heating Energy',
|
4184
|
+
'Zone Ideal Loads Outdoor Air Sensible Cooling Energy',
|
4185
|
+
'Zone Ideal Loads Outdoor Air Latent Cooling Energy',
|
4186
|
+
'Zone Ideal Loads Outdoor Air Total Cooling Energy',
|
4187
|
+
'Zone Ideal Loads Heat Recovery Sensible Heating Energy',
|
4188
|
+
'Zone Ideal Loads Heat Recovery Latent Heating Energy',
|
4189
|
+
'Zone Ideal Loads Heat Recovery Total Heating Energy',
|
4190
|
+
'Zone Ideal Loads Heat Recovery Sensible Cooling Energy',
|
4191
|
+
'Zone Ideal Loads Heat Recovery Latent Cooling Energy',
|
4192
|
+
'Zone Ideal Loads Heat Recovery Total Cooling Energy'
|
4193
|
+
]
|
4194
|
+
|
4195
|
+
meters_added = 0
|
4196
|
+
outputs_added = 0
|
4197
|
+
ideal_air_loads_system_variables.each do |variable|
|
4198
|
+
# create meter definition for variable
|
4199
|
+
meter_definition = OpenStudio::Model::MeterCustom.new(model)
|
4200
|
+
meter_definition.setName("Sum #{variable}")
|
4201
|
+
meter_definition.setFuelType('Generic')
|
4202
|
+
model.getZoneHVACIdealLoadsAirSystems.each { |sys| meter_definition.addKeyVarGroup(sys.name.to_s, variable) }
|
4203
|
+
meters_added += 1
|
4204
|
+
|
4205
|
+
# add output meter
|
4206
|
+
output_meter_definition = OpenStudio::Model::OutputMeter.new(model)
|
4207
|
+
output_meter_definition.setName("Sum #{variable}")
|
4208
|
+
output_meter_definition.setReportingFrequency('Hourly')
|
4209
|
+
output_meter_definition.setMeterFileOnly(true)
|
4210
|
+
output_meter_definition.setCumulative(false)
|
4211
|
+
outputs_added += 1
|
4212
|
+
end
|
4213
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Added #{meters_added} custom meter objects and #{outputs_added} meter outputs for ideal loads air systems.")
|
4214
|
+
end
|
4215
|
+
|
4036
4216
|
return ideal_systems
|
4037
4217
|
end
|
4038
4218
|
|
@@ -4044,6 +4224,7 @@ class Standard
|
|
4044
4224
|
# @param flow_fraction_schedule_name [String] the name of the flow fraction schedule
|
4045
4225
|
# @param balanced_exhaust_fraction_schedule_name [String] the name of the balanced exhaust fraction schedule
|
4046
4226
|
# @return [Array<OpenStudio::Model::FanZoneExhaust>] an array of exhaust fans created
|
4227
|
+
# @todo: use the create_fan_zone_exhaust method, default to 1.25 inH2O pressure rise and fan efficiency of 0.6
|
4047
4228
|
def model_add_exhaust_fan(model,
|
4048
4229
|
thermal_zones,
|
4049
4230
|
flow_rate: nil,
|
@@ -4935,172 +5116,4 @@ class Standard
|
|
4935
5116
|
rename_air_loop_nodes(model)
|
4936
5117
|
rename_plant_loop_nodes(model)
|
4937
5118
|
end
|
4938
|
-
|
4939
|
-
# Determine the typical system type given the inputs.
|
4940
|
-
#
|
4941
|
-
# @param area_type [String] Valid choices are residential and nonresidential
|
4942
|
-
# @param delivery_type [String] Conditioning delivery type. Valid choices are air and hydronic
|
4943
|
-
# @param heating_source [String] Valid choices are Electricity, NaturalGas, DistrictHeating, DistrictAmbient
|
4944
|
-
# @param cooling_source [String] Valid choices are Electricity, DistrictCooling, DistrictAmbient
|
4945
|
-
# @param area_m2 [Double] Area in m^2
|
4946
|
-
# @param num_stories [Integer] Number of stories
|
4947
|
-
# @return [String] The system type. Possibilities are
|
4948
|
-
# PTHP, PTAC, PSZ_AC, PSZ_HP, PVAV_Reheat, PVAV_PFP_Boxes,
|
4949
|
-
# VAV_Reheat, VAV_PFP_Boxes, Gas_Furnace, Electric_Furnace
|
4950
|
-
def model_typical_hvac_system_type(model,
|
4951
|
-
climate_zone,
|
4952
|
-
area_type,
|
4953
|
-
delivery_type,
|
4954
|
-
heating_source,
|
4955
|
-
cooling_source,
|
4956
|
-
area_m2,
|
4957
|
-
num_stories)
|
4958
|
-
|
4959
|
-
# Convert area to ft^2
|
4960
|
-
area_ft2 = OpenStudio.convert(area_m2, 'm^2', 'ft^2').get
|
4961
|
-
|
4962
|
-
# categorize building by type & size
|
4963
|
-
size_category = nil
|
4964
|
-
case area_type
|
4965
|
-
when 'residential'
|
4966
|
-
# residential and less than 4 stories
|
4967
|
-
size_category = if num_stories <= 3
|
4968
|
-
'res_small'
|
4969
|
-
# residential and more than 4 stories
|
4970
|
-
else
|
4971
|
-
'res_med'
|
4972
|
-
end
|
4973
|
-
when 'nonresidential', 'retail', 'publicassembly', 'heatedonly'
|
4974
|
-
# nonresidential and 3 floors or less and < 75,000 ft2
|
4975
|
-
if num_stories <= 3 && area_ft2 < 75_000
|
4976
|
-
size_category = 'nonres_small'
|
4977
|
-
# nonresidential and 4 or 5 floors OR 5 floors or less and 75,000 ft2 to 150,000 ft2
|
4978
|
-
elsif ((num_stories == 4 || num_stories == 5) && area_ft2 < 75_000) || (num_stories <= 5 && (area_ft2 >= 75_000 && area_ft2 <= 150_000))
|
4979
|
-
size_category = 'nonres_med'
|
4980
|
-
# nonresidential and more than 5 floors or >150,000 ft2
|
4981
|
-
elsif num_stories >= 5 || area_ft2 > 150_000
|
4982
|
-
size_category = 'nonres_lg'
|
4983
|
-
end
|
4984
|
-
else
|
4985
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', 'No area_type specified.')
|
4986
|
-
end
|
4987
|
-
|
4988
|
-
# Define the lookup by row and by fuel type
|
4989
|
-
systems= Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
|
4990
|
-
# [heating_source][cooling_source][delivery_type][size_category] = [type, central_heating_fuel, zone_heating_fuel, cooling_fuel]
|
4991
|
-
|
4992
|
-
## Forced Air ##
|
4993
|
-
|
4994
|
-
# Gas, Electric, forced air
|
4995
|
-
systems['NaturalGas']['Electricity']['air']['res_small'] = ['PTAC', 'NaturalGas', nil, 'Electricity']
|
4996
|
-
systems['NaturalGas']['Electricity']['air']['res_med'] = ['PTAC', 'NaturalGas', nil, 'Electricity']
|
4997
|
-
systems['NaturalGas']['Electricity']['air']['nonres_small'] = ['PSZ-AC', 'NaturalGas', nil, 'Electricity']
|
4998
|
-
systems['NaturalGas']['Electricity']['air']['nonres_med'] = ['PVAV Reheat', 'NaturalGas', 'NaturalGas', 'Electricity']
|
4999
|
-
systems['NaturalGas']['Electricity']['air']['nonres_lg'] = ['VAV Reheat', 'NaturalGas', 'NaturalGas', 'Electricity']
|
5000
|
-
|
5001
|
-
# Electric, Electric, forced air
|
5002
|
-
systems['Electricity']['Electricity']['air']['res_small'] = ['PTHP', 'Electricity', nil, 'Electricity']
|
5003
|
-
systems['Electricity']['Electricity']['air']['res_med'] = ['PTHP', 'Electricity', nil, 'Electricity']
|
5004
|
-
systems['Electricity']['Electricity']['air']['nonres_small'] = ['PSZ-HP', 'Electricity', nil, 'Electricity']
|
5005
|
-
systems['Electricity']['Electricity']['air']['nonres_med'] = ['PVAV PFP Boxes', 'Electricity', 'Electricity', 'Electricity']
|
5006
|
-
systems['Electricity']['Electricity']['air']['nonres_lg'] = ['VAV PFP Boxes', 'Electricity', 'Electricity', 'Electricity']
|
5007
|
-
|
5008
|
-
# District Hot Water, Electric, forced air
|
5009
|
-
systems['DistrictHeating']['Electricity']['air']['res_small'] = ['PTAC', 'DistrictHeating', nil, 'Electricity']
|
5010
|
-
systems['DistrictHeating']['Electricity']['air']['res_med'] = ['PTAC', 'DistrictHeating', nil, 'Electricity']
|
5011
|
-
systems['DistrictHeating']['Electricity']['air']['nonres_small'] = ['PVAV Reheat', 'DistrictHeating', 'DistrictHeating', 'Electricity']
|
5012
|
-
systems['DistrictHeating']['Electricity']['air']['nonres_med'] = ['PVAV Reheat', 'DistrictHeating', 'DistrictHeating', 'Electricity']
|
5013
|
-
systems['DistrictHeating']['Electricity']['air']['nonres_lg'] = ['VAV Reheat', 'DistrictHeating', 'DistrictHeating', 'Electricity']
|
5014
|
-
|
5015
|
-
# Ambient Loop, Ambient Loop, forced air
|
5016
|
-
systems['DistrictAmbient']['DistrictAmbient']['air']['res_small'] = ['Water Source Heat Pumps with ERVs', 'HeatPump', nil, 'HeatPump']
|
5017
|
-
systems['DistrictAmbient']['DistrictAmbient']['air']['res_med'] = ['Water Source Heat Pumps with DOAS', 'HeatPump', nil, 'HeatPump']
|
5018
|
-
systems['DistrictAmbient']['DistrictAmbient']['air']['nonres_small'] = ['PVAV Reheat', 'HeatPump', 'HeatPump', 'HeatPump']
|
5019
|
-
systems['DistrictAmbient']['DistrictAmbient']['air']['nonres_med'] = ['PVAV Reheat', 'HeatPump', 'HeatPump', 'HeatPump']
|
5020
|
-
systems['DistrictAmbient']['DistrictAmbient']['air']['nonres_lg'] = ['VAV Reheat', 'HeatPump', 'HeatPump', 'HeatPump']
|
5021
|
-
|
5022
|
-
# Gas, District Chilled Water, forced air
|
5023
|
-
systems['NaturalGas']['DistrictCooling']['air']['res_small'] = ['PSZ-AC', 'NaturalGas', nil, 'DistrictCooling']
|
5024
|
-
systems['NaturalGas']['DistrictCooling']['air']['res_med'] = ['PSZ-AC', 'NaturalGas', nil, 'DistrictCooling']
|
5025
|
-
systems['NaturalGas']['DistrictCooling']['air']['nonres_small'] = ['PSZ-AC', 'NaturalGas', nil, 'DistrictCooling']
|
5026
|
-
systems['NaturalGas']['DistrictCooling']['air']['nonres_med'] = ['PVAV Reheat', 'NaturalGas', 'NaturalGas', 'DistrictCooling']
|
5027
|
-
systems['NaturalGas']['DistrictCooling']['air']['nonres_lg'] = ['VAV Reheat', 'NaturalGas', 'NaturalGas', 'DistrictCooling']
|
5028
|
-
|
5029
|
-
# Electric, District Chilled Water, forced air
|
5030
|
-
systems['Electricity']['DistrictCooling']['air']['res_small'] = ['PSZ-AC', 'Electricity', nil, 'DistrictCooling']
|
5031
|
-
systems['Electricity']['DistrictCooling']['air']['res_med'] = ['PSZ-AC', 'Electricity', nil, 'DistrictCooling']
|
5032
|
-
systems['Electricity']['DistrictCooling']['air']['nonres_small'] = ['PSZ-AC', 'Electricity', nil, 'DistrictCooling']
|
5033
|
-
systems['Electricity']['DistrictCooling']['air']['nonres_med'] = ['PVAV Reheat', 'Electricity', 'Electricity', 'DistrictCooling']
|
5034
|
-
systems['Electricity']['DistrictCooling']['air']['nonres_lg'] = ['VAV Reheat', 'Electricity', 'Electricity', 'DistrictCooling']
|
5035
|
-
|
5036
|
-
# District Hot Water, District Chilled Water, forced air
|
5037
|
-
systems['DistrictHeating']['DistrictCooling']['air']['res_small'] = ['PSZ-AC', 'DistrictHeating', nil, 'DistrictCooling']
|
5038
|
-
systems['DistrictHeating']['DistrictCooling']['air']['res_med'] = ['PSZ-AC', 'DistrictHeating', nil, 'DistrictCooling']
|
5039
|
-
systems['DistrictHeating']['DistrictCooling']['air']['nonres_small'] = ['PVAV Reheat', 'DistrictHeating', 'DistrictHeating', 'DistrictCooling']
|
5040
|
-
systems['DistrictHeating']['DistrictCooling']['air']['nonres_med'] = ['PVAV Reheat', 'DistrictHeating', 'DistrictHeating', 'DistrictCooling']
|
5041
|
-
systems['DistrictHeating']['DistrictCooling']['air']['nonres_lg'] = ['VAV Reheat', 'DistrictHeating', 'DistrictHeating', 'DistrictCooling']
|
5042
|
-
|
5043
|
-
## Hydronic ##
|
5044
|
-
|
5045
|
-
# Gas, Electric, hydronic
|
5046
|
-
systems['NaturalGas']['Electricity']['hydronic']['res_med'] = ['Fan Coil with DOAS', 'NaturalGas', nil, 'Electricity']
|
5047
|
-
systems['NaturalGas']['Electricity']['hydronic']['nonres_small'] = ['Water Source Heat Pumps with DOAS', 'NaturalGas', nil, 'Electricity']
|
5048
|
-
systems['NaturalGas']['Electricity']['hydronic']['nonres_med'] = ['Fan Coil with DOAS', 'NaturalGas', 'NaturalGas', 'Electricity']
|
5049
|
-
systems['NaturalGas']['Electricity']['hydronic']['nonres_lg'] = ['Fan Coil with DOAS', 'NaturalGas', 'NaturalGas', 'Electricity']
|
5050
|
-
|
5051
|
-
# Electric, Electric, hydronic
|
5052
|
-
systems['Electricity']['Electricity']['hydronic']['res_small'] = ['Ground Source Heat Pumps with ERVs', 'Electricity', nil, 'Electricity']
|
5053
|
-
systems['Electricity']['Electricity']['hydronic']['res_med'] = ['Ground Source Heat Pumps with DOAS', 'Electricity', nil, 'Electricity']
|
5054
|
-
systems['Electricity']['Electricity']['hydronic']['nonres_small'] = ['Ground Source Heat Pumps with DOAS', 'Electricity', nil, 'Electricity']
|
5055
|
-
systems['Electricity']['Electricity']['hydronic']['nonres_med'] = ['Ground Source Heat Pumps with DOAS', 'Electricity', 'Electricity', 'Electricity']
|
5056
|
-
systems['Electricity']['Electricity']['hydronic']['nonres_lg'] = ['Ground Source Heat Pumps with DOAS', 'Electricity', 'Electricity', 'Electricity']
|
5057
|
-
|
5058
|
-
# District Hot Water, Electric, hydronic
|
5059
|
-
systems['DistrictHeating']['Electricity']['hydronic']['res_small'] = [] # TODO decide if there is anything reasonable for this
|
5060
|
-
systems['DistrictHeating']['Electricity']['hydronic']['res_med'] = ['Fan Coil with DOAS', 'DistrictHeating', nil, 'Electricity']
|
5061
|
-
systems['DistrictHeating']['Electricity']['hydronic']['nonres_small'] = ['Water Source Heat Pumps with DOAS', 'DistrictHeating', 'DistrictHeating', 'Electricity']
|
5062
|
-
systems['DistrictHeating']['Electricity']['hydronic']['nonres_med'] = ['Fan Coil with DOAS', 'DistrictHeating', 'DistrictHeating', 'Electricity']
|
5063
|
-
systems['DistrictHeating']['Electricity']['hydronic']['nonres_lg'] = ['Fan Coil with DOAS', 'DistrictHeating', 'DistrictHeating', 'Electricity']
|
5064
|
-
|
5065
|
-
# Ambient Loop, Ambient Loop, hydronic
|
5066
|
-
systems['DistrictAmbient']['DistrictAmbient']['hydronic']['res_small'] = ['Water Source Heat Pumps with ERVs', 'HeatPump', nil, 'HeatPump']
|
5067
|
-
systems['DistrictAmbient']['DistrictAmbient']['hydronic']['res_med'] = ['Water Source Heat Pumps with DOAS', 'HeatPump', nil, 'HeatPump']
|
5068
|
-
systems['DistrictAmbient']['DistrictAmbient']['hydronic']['nonres_small'] = ['Water Source Heat Pumps with DOAS', 'HeatPump', 'HeatPump', 'HeatPump']
|
5069
|
-
systems['DistrictAmbient']['DistrictAmbient']['hydronic']['nonres_med'] = ['Water Source Heat Pumps with DOAS', 'HeatPump', 'HeatPump', 'HeatPump']
|
5070
|
-
systems['DistrictAmbient']['DistrictAmbient']['hydronic']['nonres_lg'] = ['Fan Coil with DOAS', 'DistrictHeating', nil, 'Electricity'] # TODO: is this reasonable?
|
5071
|
-
|
5072
|
-
# Gas, District Chilled Water, hydronic
|
5073
|
-
systems['NaturalGas']['DistrictCooling']['hydronic']['res_med'] = ['Fan Coil with DOAS', 'NaturalGas', nil, 'DistrictCooling']
|
5074
|
-
systems['NaturalGas']['DistrictCooling']['hydronic']['nonres_small'] = ['Fan Coil with DOAS', 'NaturalGas', nil, 'DistrictCooling']
|
5075
|
-
systems['NaturalGas']['DistrictCooling']['hydronic']['nonres_med'] = ['Fan Coil with DOAS', 'NaturalGas', 'NaturalGas', 'DistrictCooling']
|
5076
|
-
systems['NaturalGas']['DistrictCooling']['hydronic']['nonres_lg'] = ['Fan Coil with DOAS', 'NaturalGas', 'NaturalGas', 'DistrictCooling']
|
5077
|
-
|
5078
|
-
# Electric, District Chilled Water, hydronic
|
5079
|
-
systems['Electricity']['DistrictCooling']['hydronic']['res_med'] = ['Fan Coil with ERVs', 'Electricity', nil, 'DistrictCooling']
|
5080
|
-
systems['Electricity']['DistrictCooling']['hydronic']['nonres_small'] = ['Fan Coil with DOAS', 'Electricity', nil, 'DistrictCooling']
|
5081
|
-
systems['Electricity']['DistrictCooling']['hydronic']['nonres_med'] = ['Fan Coil with DOAS', 'Electricity', 'Electricity', 'DistrictCooling']
|
5082
|
-
systems['Electricity']['DistrictCooling']['hydronic']['nonres_lg'] = ['Fan Coil with DOAS', 'Electricity', 'Electricity', 'DistrictCooling']
|
5083
|
-
|
5084
|
-
# District Hot Water, District Chilled Water, hydronic
|
5085
|
-
systems['DistrictHeating']['DistrictCooling']['hydronic']['res_small'] = ['Fan Coil with ERVs', 'DistrictHeating', nil, 'DistrictCooling']
|
5086
|
-
systems['DistrictHeating']['DistrictCooling']['hydronic']['res_med'] = ['Fan Coil with DOAS', 'DistrictHeating', nil, 'DistrictCooling']
|
5087
|
-
systems['DistrictHeating']['DistrictCooling']['hydronic']['nonres_small'] = ['Fan Coil with DOAS', 'DistrictHeating', 'DistrictHeating', 'DistrictCooling']
|
5088
|
-
systems['DistrictHeating']['DistrictCooling']['hydronic']['nonres_med'] = ['Fan Coil with DOAS', 'DistrictHeating', 'DistrictHeating', 'DistrictCooling']
|
5089
|
-
systems['DistrictHeating']['DistrictCooling']['hydronic']['nonres_lg'] = ['Fan Coil with DOAS', 'DistrictHeating', 'DistrictHeating', 'DistrictCooling']
|
5090
|
-
|
5091
|
-
# Get the system type
|
5092
|
-
system_type = systems[heating_source][cooling_source][delivery_type][size_category]
|
5093
|
-
|
5094
|
-
if system_type.nil? || system_type.empty?
|
5095
|
-
system_type = [nil, nil, nil, nil]
|
5096
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Could not determine system type for #{template}, #{area_type}, #{heating_source} heating, #{cooling_source} cooling, #{delivery_type} delivery, #{area_ft2.round} ft^2, #{num_stories} stories.")
|
5097
|
-
else
|
5098
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "System type is #{system_type[0]} for #{template}, #{area_type}, #{heating_source} heating, #{cooling_source} cooling, #{delivery_type} delivery, #{area_ft2.round} ft^2, #{num_stories} stories.")
|
5099
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "--- #{system_type[1]} for main heating") unless system_type[1].nil?
|
5100
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "--- #{system_type[2]} for zone heat/reheat") unless system_type[2].nil?
|
5101
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "--- #{system_type[3]} for cooling") unless system_type[3].nil?
|
5102
|
-
end
|
5103
|
-
|
5104
|
-
return system_type
|
5105
|
-
end
|
5106
5119
|
end
|