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.
@@ -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
- # Finds the search criteria
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 Btu/hr
23
- #
24
- # @return [Double] capacity in Btu/hr to be used for find object
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
- if ratedTotalHeatingCapacity.is_initialized
29
- capacity_w = ratedTotalHeatingCapacity.get
30
- elsif autosizedRatedTotalHeatingCapacity.is_initialized
31
- capacity_w = autosizedRatedTotalHeatingCapacity.get
32
- else
33
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard.")
34
- return false
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
- # Convert capacity to Btu/hr
38
- capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
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
- return capacity_btu_per_hr
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, standards)
105
+ def standard_minimum_cop(template, rename=false)
49
106
  # find ac properties
50
107
  search_criteria = find_search_criteria(template)
51
- subcategory = search_criteria['subcategory']
52
- capacity_btu_per_hr = find_capacity
53
- capacity_kbtu_per_hr = OpenStudio.convert(capacity_btu_per_hr, 'Btu/hr', 'kBtu/hr').get
54
-
55
- # Determine supplemental heating type if unitary
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
- 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}")
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
- 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}")
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
- 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}")
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
- unitary_hps = $os_standards['heat_pumps']
106
- heat_pumps = $os_standards['heat_pumps_heating']
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
- # Convert capacity to Btu/hr
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 depending on whether it is a unitary HP or a heat pump
221
- ac_props = nil
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 successfully_set_all_properties
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
- # Get the minimum efficiency standards
281
- cop = nil
241
+ # Preserve the original name
242
+ orig_name = name.to_s
282
243
 
283
- # If PTHP, use equations
284
- if subcategory == 'PTHP'
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
- # If specified as HSPF
299
- unless ac_props['minimum_heating_seasonal_performance_factor'].nil?
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
- dom_fuel = fuel_to_area.sort_by { |k, v| v }.reverse[0][0]
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
- dom_fuel = fuel_to_area.sort_by { |k, v| v }.reverse[1][0]
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
- climate_zone = "ASHRAE 169-2006-#{cz.value}"
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