openstudio-standards 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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