openstudio-standards 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +24 -8
- data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +4 -0
- data/lib/openstudio-standards/prototypes/Prototype.Model.rb +10 -0
- data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +38 -56
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +22 -61
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +3 -7
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +103 -271
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +62 -187
- data/lib/openstudio-standards/standards/Standards.CoilDX.rb +150 -0
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +6 -4
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +139 -208
- data/lib/openstudio-standards/standards/Standards.Model.rb +37 -12
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +3 -3
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +110 -0
- data/lib/openstudio-standards/version.rb +1 -1
- metadata +3 -2
@@ -1,99 +1,172 @@
|
|
1
1
|
|
2
2
|
# open the class to add methods to return sizing values
|
3
3
|
class OpenStudio::Model::CoilHeatingDXSingleSpeed
|
4
|
-
|
5
|
-
#
|
6
|
-
# @param template [String] valid choices: 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
|
7
|
-
# @return [hash] has for search criteria to be used for find object
|
8
|
-
def find_search_criteria(template)
|
9
|
-
# Define the criteria to find the chiller properties
|
10
|
-
# in the hvac standards data set.
|
11
|
-
search_criteria = {}
|
12
|
-
search_criteria['template'] = template
|
13
|
-
|
14
|
-
# TODO: Standards - add split system vs single package to model
|
15
|
-
# For now, assume single package
|
16
|
-
subcategory = 'Single Package'
|
17
|
-
search_criteria['subcategory'] = subcategory
|
18
|
-
|
19
|
-
return search_criteria
|
20
|
-
end
|
4
|
+
include CoilDX
|
21
5
|
|
22
|
-
# Finds capacity in
|
23
|
-
#
|
24
|
-
#
|
6
|
+
# Finds capacity in W. This is the cooling capacity of the
|
7
|
+
# paired DX cooling coil.
|
8
|
+
#
|
9
|
+
# @return [Double] capacity in W to be used for find object
|
25
10
|
def find_capacity
|
26
|
-
# Get the coil capacity
|
27
11
|
capacity_w = nil
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
12
|
+
|
13
|
+
# Get the paired cooling coil
|
14
|
+
clg_coil = nil
|
15
|
+
|
16
|
+
# Unitary and zone equipment
|
17
|
+
if airLoopHVAC.empty?
|
18
|
+
if containingHVACComponent.is_initialized
|
19
|
+
containing_comp = containingHVACComponent.get
|
20
|
+
if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
|
21
|
+
clg_coil = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get.coolingCoil
|
22
|
+
elsif containing_comp.to_AirLoopHVACUnitarySystem.is_initialized
|
23
|
+
unitary = containing_comp.to_AirLoopHVACUnitarySystem.get
|
24
|
+
if unitary.coolingCoil.is_initialized
|
25
|
+
clg_coil = unitary.coolingCoil.get
|
26
|
+
end
|
27
|
+
end # TODO: Add other unitary systems
|
28
|
+
elsif containingZoneHVACComponent.is_initialized
|
29
|
+
containing_comp = containingZoneHVACComponent.get
|
30
|
+
# PTHP
|
31
|
+
if containing_comp.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
|
32
|
+
pthp = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get
|
33
|
+
clg_coil = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get.coolingCoil
|
34
|
+
end
|
35
|
+
end
|
35
36
|
end
|
36
37
|
|
37
|
-
#
|
38
|
-
|
38
|
+
# On AirLoop directly
|
39
|
+
if airLoopHVAC.is_initialized
|
40
|
+
air_loop = airLoopHVAC.get
|
41
|
+
# Check for the presence of any other type of cooling coil
|
42
|
+
clg_types = ['OS:Coil:Cooling:DX:SingleSpeed',
|
43
|
+
'OS:Coil:Cooling:DX:TwoSpeed',
|
44
|
+
'OS:Coil:Cooling:DX:MultiSpeed']
|
45
|
+
clg_types.each do |ct|
|
46
|
+
coils = air_loop.supplyComponents(ct.to_IddObjectType)
|
47
|
+
next unless coils.size > 0
|
48
|
+
clg_coil = coils[0]
|
49
|
+
break # Stop on first DX cooling coil found
|
50
|
+
end
|
51
|
+
end
|
39
52
|
|
40
|
-
|
53
|
+
# If no paired cooling coil was found,
|
54
|
+
# throw an error and fall back to the heating capacity
|
55
|
+
# of the DX heating coil
|
56
|
+
if clg_coil.nil?
|
57
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, the paired DX cooling coil could not be found to determine capacity. Efficiency will incorrectly be based on DX coil's heating capacity.")
|
58
|
+
if ratedTotalHeatingCapacity.is_initialized
|
59
|
+
capacity_w = ratedTotalHeatingCapacity.get
|
60
|
+
elsif autosizedRatedTotalHeatingCapacity.is_initialized
|
61
|
+
capacity_w = autosizedRatedTotalHeatingCapacity.get
|
62
|
+
else
|
63
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard to paired DX heating coil.")
|
64
|
+
return 0.0
|
65
|
+
end
|
66
|
+
return capacity_w
|
67
|
+
end
|
68
|
+
|
69
|
+
# If a coil was found, cast to the correct type
|
70
|
+
if clg_coil.to_CoilCoolingDXSingleSpeed.is_initialized
|
71
|
+
clg_coil = clg_coil.to_CoilCoolingDXSingleSpeed.get
|
72
|
+
elsif clg_coil.to_CoilCoolingDXTwoSpeed.is_initialized
|
73
|
+
clg_coil = clg_coil.to_CoilCoolingDXTwoSpeed.get
|
74
|
+
elsif clg_coil.to_CoilCoolingDXMultiSpeed.is_initialized
|
75
|
+
clg_coil = clg_coil.to_CoilCoolingDXMultiSpeed.get
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get the capacity of the cooling coil
|
79
|
+
capacity_w = clg_coil.find_capacity
|
80
|
+
|
81
|
+
# If it's a PTAC or PTHP System, we need to divide the capacity by the potential zone multiplier
|
82
|
+
# because the COP is dependent on capacity, and the capacity should be the capacity of a single zone, not all the zones
|
83
|
+
if ['PTAC', 'PTHP'].include?(subcategory)
|
84
|
+
mult = 1
|
85
|
+
comp = containingZoneHVACComponent
|
86
|
+
if comp.is_initialized
|
87
|
+
if comp.get.thermalZone.is_initialized
|
88
|
+
mult = comp.get.thermalZone.get.multiplier
|
89
|
+
if mult > 1
|
90
|
+
total_cap = capacity_w
|
91
|
+
capacity_w /= mult
|
92
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, total capacity of #{OpenStudio.convert(total_cap, 'W', 'kBtu/hr').get.round(2)}kBTU/hr was divided by the zone multiplier of #{mult} to give #{capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get.round(2)}kBTU/hr.")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
return capacity_w
|
41
99
|
end
|
42
100
|
|
43
101
|
# Finds lookup object in standards and return efficiency
|
44
102
|
#
|
45
103
|
# @param template [String] valid choices: 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
|
46
|
-
# @param standards [Hash] the OpenStudio_Standards spreadsheet in hash format
|
47
104
|
# @return [Double] full load efficiency (COP)
|
48
|
-
def standard_minimum_cop(template,
|
105
|
+
def standard_minimum_cop(template, rename=false)
|
49
106
|
# find ac properties
|
50
107
|
search_criteria = find_search_criteria(template)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
heat_pump = false
|
57
|
-
if airLoopHVAC.empty?
|
58
|
-
if containingHVACComponent.is_initialized
|
59
|
-
containing_comp = containingHVACComponent.get
|
60
|
-
if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
|
61
|
-
heat_pump = true
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
# find object
|
67
|
-
ac_props = model.find_object(standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
|
108
|
+
sub_category = search_criteria['subcategory']
|
109
|
+
suppl_heating_type = search_criteria['heating_type']
|
110
|
+
capacity_w = find_capacity
|
111
|
+
capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
|
112
|
+
capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
|
68
113
|
|
69
114
|
# Get the minimum efficiency standards
|
70
115
|
cop = nil
|
71
116
|
|
117
|
+
# find object
|
118
|
+
ac_props = model.find_object($os_standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
|
119
|
+
|
72
120
|
# Check to make sure properties were found
|
73
121
|
if ac_props.nil?
|
74
122
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, cannot find efficiency info, cannot apply efficiency standard.")
|
75
123
|
return cop # value of nil
|
76
124
|
end
|
77
125
|
|
126
|
+
# If PTHP, use equations
|
127
|
+
if sub_category == 'PTHP'
|
128
|
+
pthp_cop_coeff_1 = ac_props['pthp_cop_coefficient_1']
|
129
|
+
pthp_cop_coeff_2 = ac_props['pthp_cop_coefficient_2']
|
130
|
+
# TABLE 6.8.1D
|
131
|
+
# COP = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * Cap / 1000)
|
132
|
+
# Note c: Cap means the rated cooling capacity of the product in Btu/h.
|
133
|
+
# If the unit's capacity is less than 7000 Btu/h, use 7000 Btu/h in the calculation.
|
134
|
+
# If the unit's capacity is greater than 15,000 Btu/h, use 15,000 Btu/h in the calculation.
|
135
|
+
capacity_btu_per_hr = 7000 if capacity_btu_per_hr < 7000
|
136
|
+
capacity_btu_per_hr = 15_000 if capacity_btu_per_hr > 15_000
|
137
|
+
min_coph = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * capacity_btu_per_hr / 1000.0)
|
138
|
+
cop = cop_heating_to_cop_heating_no_fan(min_coph, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
|
139
|
+
new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_coph.round(1)}COPH"
|
140
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}: #{sub_category} Cooling Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; COPH = #{min_coph.round(2)}")
|
141
|
+
end
|
142
|
+
|
78
143
|
# If specified as HSPF
|
79
144
|
unless ac_props['minimum_heating_seasonal_performance_factor'].nil?
|
80
145
|
min_hspf = ac_props['minimum_heating_seasonal_performance_factor']
|
81
146
|
cop = hspf_to_cop_heating_no_fan(min_hspf)
|
82
|
-
|
147
|
+
new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_hspf.round(1)}HSPF"
|
148
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{template}: #{name}: #{suppl_heating_type} #{sub_category} Cooling Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; HSPF = #{min_hspf}")
|
83
149
|
end
|
84
150
|
|
85
151
|
# If specified as COPH
|
86
152
|
unless ac_props['minimum_coefficient_of_performance_heating'].nil?
|
87
153
|
min_coph = ac_props['minimum_coefficient_of_performance_heating']
|
88
154
|
cop = cop_heating_to_cop_heating_no_fan(min_coph, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
|
89
|
-
|
155
|
+
new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_coph.round(1)}COPH"
|
156
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{template}: #{name}: #{suppl_heating_type} #{sub_category} Cooling Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; COPH = #{min_coph}")
|
90
157
|
end
|
91
158
|
|
92
159
|
# If specified as EER
|
93
160
|
unless ac_props['minimum_energy_efficiency_ratio'].nil?
|
94
161
|
min_eer = ac_props['minimum_energy_efficiency_ratio']
|
95
162
|
cop = eer_to_cop(min_eer, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
|
96
|
-
|
163
|
+
new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_eer.round(1)}EER"
|
164
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{template}: #{name}: #{suppl_heating_type} #{sub_category} Cooling Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; EER = #{min_eer}")
|
165
|
+
end
|
166
|
+
|
167
|
+
# Rename
|
168
|
+
if rename
|
169
|
+
setName(new_comp_name)
|
97
170
|
end
|
98
171
|
|
99
172
|
return cop
|
@@ -102,134 +175,22 @@ class OpenStudio::Model::CoilHeatingDXSingleSpeed
|
|
102
175
|
def apply_efficiency_and_curves(template, sql_db_vars_map)
|
103
176
|
successfully_set_all_properties = true
|
104
177
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
# Define the criteria to find the unitary properties
|
109
|
-
# in the hvac standards data set.
|
110
|
-
search_criteria = {}
|
111
|
-
search_criteria['template'] = template
|
112
|
-
|
113
|
-
# TODO: Standards - add split system vs single package to model
|
114
|
-
# For now, assume single package
|
115
|
-
subcategory = 'Single Package'
|
116
|
-
|
117
|
-
# Assume they are all aircooled for now
|
118
|
-
search_criteria['cooling_type'] = 'AirCooled'
|
119
|
-
|
120
|
-
# Determine supplemental heating type if unitary
|
121
|
-
unitary = false
|
122
|
-
suppl_heating_type = nil
|
123
|
-
if airLoopHVAC.empty?
|
124
|
-
if containingHVACComponent.is_initialized
|
125
|
-
containing_comp = containingHVACComponent.get
|
126
|
-
if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
|
127
|
-
unitary = true
|
128
|
-
htg_coil = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get.supplementalHeatingCoil
|
129
|
-
suppl_heating_type = if htg_coil.to_CoilHeatingElectric.is_initialized
|
130
|
-
'Electric Resistance or None'
|
131
|
-
else
|
132
|
-
'All Other'
|
133
|
-
end
|
134
|
-
end # TODO: Add other unitary systems
|
135
|
-
elsif containingZoneHVACComponent.is_initialized
|
136
|
-
containing_comp = containingZoneHVACComponent.get
|
137
|
-
# PTHP
|
138
|
-
if containing_comp.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
|
139
|
-
pthp = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get
|
140
|
-
subcategory = 'PTHP'
|
141
|
-
htg_coil = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get.supplementalHeatingCoil
|
142
|
-
suppl_heating_type = if htg_coil.to_CoilHeatingElectric.is_initialized
|
143
|
-
'Electric Resistance or None'
|
144
|
-
else
|
145
|
-
'All Other'
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# Add the subcategory to the search criteria
|
152
|
-
search_criteria['subcategory'] = subcategory
|
153
|
-
|
154
|
-
# Determine the supplemental heating type if on an airloop
|
155
|
-
if airLoopHVAC.is_initialized
|
156
|
-
air_loop = airLoopHVAC.get
|
157
|
-
suppl_heating_type = if !air_loop.supplyComponents('OS:Coil:Heating:Electric'.to_IddObjectType).empty?
|
158
|
-
'Electric Resistance or None'
|
159
|
-
elsif !air_loop.supplyComponents('OS:Coil:Heating:Gas'.to_IddObjectType).empty?
|
160
|
-
'All Other'
|
161
|
-
elsif !air_loop.supplyComponents('OS:Coil:Heating:Water'.to_IddObjectType).empty?
|
162
|
-
'All Other'
|
163
|
-
elsif !air_loop.supplyComponents('OS:Coil:Heating:DX:SingleSpeed'.to_IddObjectType).empty?
|
164
|
-
'All Other'
|
165
|
-
elsif !air_loop.supplyComponents('OS:Coil:Heating:Gas:MultiStage'.to_IddObjectType).empty?
|
166
|
-
'All Other'
|
167
|
-
elsif !air_loop.supplyComponents('OS:Coil:Heating:Desuperheater'.to_IddObjectType).empty?
|
168
|
-
'All Other'
|
169
|
-
elsif !air_loop.supplyComponents('OS:Coil:Heating:WaterToAirHeatPump:EquationFit'.to_IddObjectType).empty?
|
170
|
-
'All Other'
|
171
|
-
else
|
172
|
-
'Electric Resistance or None'
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# Add the heating type to the search criteria
|
177
|
-
unless suppl_heating_type.nil?
|
178
|
-
search_criteria['heating_type'] = suppl_heating_type
|
179
|
-
end
|
180
|
-
|
181
|
-
# Get the coil capacity
|
182
|
-
capacity_w = nil
|
183
|
-
if unitary
|
184
|
-
containing_comp = containingHVACComponent.get
|
185
|
-
heat_pump_comp = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get
|
186
|
-
ccoil = heat_pump_comp.coolingCoil
|
187
|
-
dxcoil = ccoil.to_CoilCoolingDXSingleSpeed.get
|
188
|
-
dxcoil_name = dxcoil.name.to_s
|
189
|
-
if sql_db_vars_map
|
190
|
-
if sql_db_vars_map[dxcoil_name]
|
191
|
-
dxcoil.setName(sql_db_vars_map[dxcoil_name])
|
192
|
-
end
|
193
|
-
end
|
194
|
-
if dxcoil.ratedTotalCoolingCapacity.is_initialized
|
195
|
-
capacity_w = dxcoil.ratedTotalCoolingCapacity.get
|
196
|
-
elsif dxcoil.autosizedRatedTotalCoolingCapacity.is_initialized
|
197
|
-
capacity_w = dxcoil.autosizedRatedTotalCoolingCapacity.get
|
198
|
-
else
|
199
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard.")
|
200
|
-
successfully_set_all_properties = false
|
201
|
-
return successfully_set_all_properties
|
202
|
-
end
|
203
|
-
dxcoil.setName(dxcoil_name)
|
204
|
-
else
|
205
|
-
if ratedTotalHeatingCapacity.is_initialized
|
206
|
-
capacity_w = ratedTotalHeatingCapacity.get
|
207
|
-
elsif autosizedRatedTotalHeatingCapacity.is_initialized
|
208
|
-
capacity_w = autosizedRatedTotalHeatingCapacity.get
|
209
|
-
else
|
210
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard.")
|
211
|
-
successfully_set_all_properties = false
|
212
|
-
return successfully_set_all_properties
|
213
|
-
end
|
214
|
-
end
|
178
|
+
# Get the search criteria
|
179
|
+
search_criteria = find_search_criteria(template)
|
215
180
|
|
216
|
-
#
|
181
|
+
# Get the capacity
|
182
|
+
capacity_w = find_capacity
|
217
183
|
capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
|
218
184
|
capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
|
219
185
|
|
220
|
-
# Lookup efficiencies
|
221
|
-
ac_props =
|
222
|
-
ac_props = if unitary == true
|
223
|
-
model.find_object(unitary_hps, search_criteria, capacity_btu_per_hr, Date.today)
|
224
|
-
else
|
225
|
-
model.find_object(heat_pumps, search_criteria, capacity_btu_per_hr, Date.today)
|
226
|
-
end
|
186
|
+
# Lookup efficiencies
|
187
|
+
ac_props = model.find_object($os_standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
|
227
188
|
|
228
189
|
# Check to make sure properties were found
|
229
190
|
if ac_props.nil?
|
230
191
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, cannot find efficiency info, cannot apply efficiency standard.")
|
231
192
|
successfully_set_all_properties = false
|
232
|
-
return
|
193
|
+
return sql_db_vars_map
|
233
194
|
end
|
234
195
|
|
235
196
|
# Make the HEAT-CAP-FT curve
|
@@ -277,44 +238,14 @@ class OpenStudio::Model::CoilHeatingDXSingleSpeed
|
|
277
238
|
successfully_set_all_properties = false
|
278
239
|
end
|
279
240
|
|
280
|
-
#
|
281
|
-
|
241
|
+
# Preserve the original name
|
242
|
+
orig_name = name.to_s
|
282
243
|
|
283
|
-
#
|
284
|
-
|
285
|
-
pthp_cop_coeff_1 = ac_props['pthp_cop_coefficient_1']
|
286
|
-
pthp_cop_coeff_2 = ac_props['pthp_cop_coefficient_2']
|
287
|
-
# TABLE 6.8.1D
|
288
|
-
# COP = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * Cap / 1000)
|
289
|
-
# Note c: Cap means the rated cooling capacity of the product in Btu/h.
|
290
|
-
# If the unit's capacity is less than 7000 Btu/h, use 7000 Btu/h in the calculation.
|
291
|
-
# If the unit's capacity is greater than 15,000 Btu/h, use 15,000 Btu/h in the calculation.
|
292
|
-
capacity_btu_per_hr = 7000 if capacity_btu_per_hr < 7000
|
293
|
-
capacity_btu_per_hr = 15_000 if capacity_btu_per_hr > 15_000
|
294
|
-
cop = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * capacity_btu_per_hr / 1000.0)
|
295
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}: #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; COPH = #{cop.round(2)}")
|
296
|
-
end
|
244
|
+
# Find the minimum COP and rename with efficiency rating
|
245
|
+
cop = standard_minimum_cop(template, true)
|
297
246
|
|
298
|
-
#
|
299
|
-
|
300
|
-
min_hspf = ac_props['minimum_heating_seasonal_performance_factor']
|
301
|
-
cop = hspf_to_cop_heating_no_fan(min_hspf)
|
302
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{template}: #{name}: #{suppl_heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; HSPF = #{min_hspf}")
|
303
|
-
end
|
304
|
-
|
305
|
-
# If specified as COPH
|
306
|
-
unless ac_props['minimum_coefficient_of_performance_heating'].nil?
|
307
|
-
min_coph = ac_props['minimum_coefficient_of_performance_heating']
|
308
|
-
cop = cop_heating_to_cop_heating_no_fan(min_coph, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
|
309
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{template}: #{name}: #{suppl_heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; COPH = #{min_coph}")
|
310
|
-
end
|
311
|
-
|
312
|
-
# If specified as EER
|
313
|
-
unless ac_props['minimum_energy_efficiency_ratio'].nil?
|
314
|
-
min_eer = ac_props['minimum_energy_efficiency_ratio']
|
315
|
-
cop = eer_to_cop(min_eer, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
|
316
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{template}: #{name}: #{suppl_heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; EER = #{min_eer}")
|
317
|
-
end
|
247
|
+
# Map the original name to the new name
|
248
|
+
sql_db_vars_map[name.to_s] = orig_name
|
318
249
|
|
319
250
|
# Set the efficiency values
|
320
251
|
unless cop.nil?
|
@@ -65,6 +65,7 @@ class OpenStudio::Model::Model
|
|
65
65
|
require_relative 'Standards.FanOnOff'
|
66
66
|
require_relative 'Standards.FanZoneExhaust'
|
67
67
|
require_relative 'Standards.ChillerElectricEIR'
|
68
|
+
require_relative 'Standards.CoilDX'
|
68
69
|
require_relative 'Standards.CoilCoolingDXTwoSpeed'
|
69
70
|
require_relative 'Standards.CoilCoolingDXSingleSpeed'
|
70
71
|
require_relative 'Standards.CoilHeatingDXSingleSpeed'
|
@@ -152,6 +153,14 @@ class OpenStudio::Model::Model
|
|
152
153
|
|
153
154
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', '*** Adding Daylighting Controls ***')
|
154
155
|
|
156
|
+
# Run a sizing run to calculate VLT for layer-by-layer windows.
|
157
|
+
# Only necessary for 90.1-2010 daylighting control determination.
|
158
|
+
if template == '90.1-2010'
|
159
|
+
if runSizingRun("#{sizing_run_dir}/SizingRunVLT") == false
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
155
164
|
# Add daylighting controls to each space
|
156
165
|
getSpaces.sort.each do |space|
|
157
166
|
added = space.add_daylighting_controls(template, false, false)
|
@@ -454,6 +463,12 @@ class OpenStudio::Model::Model
|
|
454
463
|
# fossilandelectric
|
455
464
|
zones = zones_with_occ_and_fuel_type(template, custom)
|
456
465
|
|
466
|
+
# Ensure that there is at least one conditioned zone
|
467
|
+
if zones.size.zero?
|
468
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Model', "The building does not appear to have any conditioned zones. Make sure zones have thermostat with appropriate heating and cooling setpoint schedules.")
|
469
|
+
return []
|
470
|
+
end
|
471
|
+
|
457
472
|
# Group the zones by occupancy type
|
458
473
|
type_to_area = Hash.new { 0.0 }
|
459
474
|
zones_grouped_by_occ = zones.group_by { |z| z['occ'] }
|
@@ -525,12 +540,19 @@ class OpenStudio::Model::Model
|
|
525
540
|
fuel_to_area[fuel] += zn['area']
|
526
541
|
end
|
527
542
|
end
|
528
|
-
|
543
|
+
|
544
|
+
sorted_by_area = fuel_to_area.sort_by { |k, v| v }.reverse
|
545
|
+
dom_fuel = sorted_by_area[0][0]
|
529
546
|
|
530
547
|
# Don't allow unconditioned to be the dominant fuel,
|
531
548
|
# go to the next biggest
|
532
549
|
if dom_fuel == 'unconditioned'
|
533
|
-
|
550
|
+
if sorted_by_area.size > 1
|
551
|
+
dom_fuel = sorted_by_area[1][0]
|
552
|
+
else
|
553
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "The fuel type was not able to be determined for any zones in this model. Run with debug messages enabled to see possible reasons.")
|
554
|
+
return []
|
555
|
+
end
|
534
556
|
end
|
535
557
|
|
536
558
|
# Get the dominant fuel type group
|
@@ -1419,9 +1441,6 @@ class OpenStudio::Model::Model
|
|
1419
1441
|
# because it requires knowledge of proposed HVAC fuels.
|
1420
1442
|
sys_groups = prm_baseline_system_groups(template, custom)
|
1421
1443
|
|
1422
|
-
# Remove all HVAC from model
|
1423
|
-
BTAP::Resources::HVAC.clear_all_hvac_from_model(self)
|
1424
|
-
|
1425
1444
|
# Assign building stories to spaces in the building
|
1426
1445
|
# where stories are not yet assigned.
|
1427
1446
|
assign_spaces_to_stories
|
@@ -1436,7 +1455,7 @@ class OpenStudio::Model::Model
|
|
1436
1455
|
sys_group['fuel'],
|
1437
1456
|
sys_group['area_ft2'],
|
1438
1457
|
sys_group['stories'],
|
1439
|
-
custom)
|
1458
|
+
custom)[0]
|
1440
1459
|
|
1441
1460
|
# Record the zone-by-zone system type assignments
|
1442
1461
|
case template
|
@@ -1989,14 +2008,16 @@ class OpenStudio::Model::Model
|
|
1989
2008
|
getHeaderedPumpsConstantSpeeds.sort.each { |obj| obj.apply_standard_minimum_motor_efficiency(template) }
|
1990
2009
|
getHeaderedPumpsVariableSpeeds.sort.each { |obj| obj.apply_standard_minimum_motor_efficiency(template) }
|
1991
2010
|
|
1992
|
-
# Unitary ACs
|
1993
|
-
|
1994
|
-
getCoilCoolingDXTwoSpeeds.sort.each { |obj| obj.apply_efficiency_and_curves(template) }
|
1995
|
-
getCoilCoolingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = obj.apply_efficiency_and_curves(template, sql_db_vars_map) }
|
1996
|
-
|
1997
2011
|
# Unitary HPs
|
2012
|
+
# set DX HP coils before DX clg coils because when DX HP coils need to first
|
2013
|
+
# pull the capacities of their paried DX clg coils, and this does not work
|
2014
|
+
# correctly if the DX clg coil efficiencies have been set because they are renamed.
|
1998
2015
|
getCoilHeatingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = obj.apply_efficiency_and_curves(template, sql_db_vars_map) }
|
1999
2016
|
|
2017
|
+
# Unitary ACs
|
2018
|
+
getCoilCoolingDXTwoSpeeds.sort.each { |obj| sql_db_vars_map = obj.apply_efficiency_and_curves(template, sql_db_vars_map) }
|
2019
|
+
getCoilCoolingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = obj.apply_efficiency_and_curves(template, sql_db_vars_map) }
|
2020
|
+
|
2000
2021
|
# Chillers
|
2001
2022
|
clg_tower_objs = getCoolingTowerSingleSpeeds
|
2002
2023
|
getChillerElectricEIRs.sort.each { |obj| obj.apply_efficiency_and_curves(template, clg_tower_objs) }
|
@@ -3101,7 +3122,11 @@ class OpenStudio::Model::Model
|
|
3101
3122
|
climate_zone = ''
|
3102
3123
|
getClimateZones.climateZones.each do |cz|
|
3103
3124
|
if cz.institution == 'ASHRAE'
|
3104
|
-
|
3125
|
+
if cz.value == '7'||cz.value == '8'
|
3126
|
+
climate_zone = "ASHRAE 169-2006-#{cz.value}A"
|
3127
|
+
else
|
3128
|
+
climate_zone = "ASHRAE 169-2006-#{cz.value}"
|
3129
|
+
end
|
3105
3130
|
next
|
3106
3131
|
end
|
3107
3132
|
end
|
@@ -1286,7 +1286,7 @@ class OpenStudio::Model::PlantLoop
|
|
1286
1286
|
# Check the plant loop connection on the source side
|
1287
1287
|
if component.secondaryPlantLoop.is_initialized
|
1288
1288
|
source_plant_loop = component.secondaryPlantLoop.get
|
1289
|
-
secondary_fuels += plant_loop_heating_fuels(source_plant_loop)
|
1289
|
+
secondary_fuels += model.plant_loop_heating_fuels(source_plant_loop)
|
1290
1290
|
secondary_heating_capacity += source_plant_loop.total_heating_capacity
|
1291
1291
|
end
|
1292
1292
|
|
@@ -1308,7 +1308,7 @@ class OpenStudio::Model::PlantLoop
|
|
1308
1308
|
# Check the plant loop connection on the source side
|
1309
1309
|
if component.secondaryPlantLoop.is_initialized
|
1310
1310
|
source_plant_loop = component.secondaryPlantLoop.get
|
1311
|
-
secondary_fuels += plant_loop_heating_fuels(source_plant_loop)
|
1311
|
+
secondary_fuels += model.plant_loop_heating_fuels(source_plant_loop)
|
1312
1312
|
secondary_heating_capacity += source_plant_loop.total_heating_capacity
|
1313
1313
|
end
|
1314
1314
|
|
@@ -1323,7 +1323,7 @@ class OpenStudio::Model::PlantLoop
|
|
1323
1323
|
cooling_hx_control_types.each {|x| x.downcase!}
|
1324
1324
|
if !cooling_hx_control_types.include?(hx.controlType.downcase) && hx.secondaryPlantLoop.is_initialized
|
1325
1325
|
source_plant_loop = hx.secondaryPlantLoop.get
|
1326
|
-
secondary_fuels += plant_loop_heating_fuels(source_plant_loop)
|
1326
|
+
secondary_fuels += model.plant_loop_heating_fuels(source_plant_loop)
|
1327
1327
|
secondary_heating_capacity += source_plant_loop.total_heating_capacity
|
1328
1328
|
end
|
1329
1329
|
|