lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb in openstudio-standards-0.1.6 vs lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb in openstudio-standards-0.1.7
- old
+ new
@@ -1,237 +1,198 @@
# open the class to add methods to return sizing values
class OpenStudio::Model::CoilHeatingDXSingleSpeed
- # Finds the search criteria
- #
- # @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'
- # @return [hash] has for search criteria to be used for find object
- def find_search_criteria(template)
- # Define the criteria to find the chiller properties
- # in the hvac standards data set.
- search_criteria = {}
- search_criteria['template'] = template
+ include CoilDX
- # TODO: Standards - add split system vs single package to model
- # For now, assume single package
- subcategory = 'Single Package'
- search_criteria['subcategory'] = subcategory
-
- return search_criteria
- end
-
- # Finds capacity in Btu/hr
- #
- # @return [Double] capacity in Btu/hr to be used for find object
+ # Finds capacity in W. This is the cooling capacity of the
+ # paired DX cooling coil.
+ #
+ # @return [Double] capacity in W to be used for find object
def find_capacity
- # Get the coil capacity
capacity_w = nil
- if ratedTotalHeatingCapacity.is_initialized
- capacity_w = ratedTotalHeatingCapacity.get
- elsif autosizedRatedTotalHeatingCapacity.is_initialized
- capacity_w = autosizedRatedTotalHeatingCapacity.get
- else
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard.")
- return false
+
+ # Get the paired cooling coil
+ clg_coil = nil
+
+ # Unitary and zone equipment
+ if airLoopHVAC.empty?
+ if containingHVACComponent.is_initialized
+ containing_comp = containingHVACComponent.get
+ if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
+ clg_coil = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get.coolingCoil
+ elsif containing_comp.to_AirLoopHVACUnitarySystem.is_initialized
+ unitary = containing_comp.to_AirLoopHVACUnitarySystem.get
+ if unitary.coolingCoil.is_initialized
+ clg_coil = unitary.coolingCoil.get
+ end
+ end # TODO: Add other unitary systems
+ elsif containingZoneHVACComponent.is_initialized
+ containing_comp = containingZoneHVACComponent.get
+ # PTHP
+ if containing_comp.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
+ pthp = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get
+ clg_coil = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get.coolingCoil
+ end
+ end
end
- # Convert capacity to Btu/hr
- capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
+ # On AirLoop directly
+ if airLoopHVAC.is_initialized
+ air_loop = airLoopHVAC.get
+ # Check for the presence of any other type of cooling coil
+ clg_types = ['OS:Coil:Cooling:DX:SingleSpeed',
+ 'OS:Coil:Cooling:DX:TwoSpeed',
+ 'OS:Coil:Cooling:DX:MultiSpeed']
+ clg_types.each do |ct|
+ coils = air_loop.supplyComponents(ct.to_IddObjectType)
+ next unless coils.size > 0
+ clg_coil = coils[0]
+ break # Stop on first DX cooling coil found
+ end
+ end
- return capacity_btu_per_hr
+ # If no paired cooling coil was found,
+ # throw an error and fall back to the heating capacity
+ # of the DX heating coil
+ if clg_coil.nil?
+ 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.")
+ if ratedTotalHeatingCapacity.is_initialized
+ capacity_w = ratedTotalHeatingCapacity.get
+ elsif autosizedRatedTotalHeatingCapacity.is_initialized
+ capacity_w = autosizedRatedTotalHeatingCapacity.get
+ else
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard to paired DX heating coil.")
+ return 0.0
+ end
+ return capacity_w
+ end
+
+ # If a coil was found, cast to the correct type
+ if clg_coil.to_CoilCoolingDXSingleSpeed.is_initialized
+ clg_coil = clg_coil.to_CoilCoolingDXSingleSpeed.get
+ elsif clg_coil.to_CoilCoolingDXTwoSpeed.is_initialized
+ clg_coil = clg_coil.to_CoilCoolingDXTwoSpeed.get
+ elsif clg_coil.to_CoilCoolingDXMultiSpeed.is_initialized
+ clg_coil = clg_coil.to_CoilCoolingDXMultiSpeed.get
+ end
+
+ # Get the capacity of the cooling coil
+ capacity_w = clg_coil.find_capacity
+
+ # If it's a PTAC or PTHP System, we need to divide the capacity by the potential zone multiplier
+ # because the COP is dependent on capacity, and the capacity should be the capacity of a single zone, not all the zones
+ if ['PTAC', 'PTHP'].include?(subcategory)
+ mult = 1
+ comp = containingZoneHVACComponent
+ if comp.is_initialized
+ if comp.get.thermalZone.is_initialized
+ mult = comp.get.thermalZone.get.multiplier
+ if mult > 1
+ total_cap = capacity_w
+ capacity_w /= mult
+ 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.")
+ end
+ end
+ end
+ end
+
+ return capacity_w
end
# Finds lookup object in standards and return efficiency
#
# @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'
- # @param standards [Hash] the OpenStudio_Standards spreadsheet in hash format
# @return [Double] full load efficiency (COP)
- def standard_minimum_cop(template, standards)
+ def standard_minimum_cop(template, rename=false)
# find ac properties
search_criteria = find_search_criteria(template)
- subcategory = search_criteria['subcategory']
- capacity_btu_per_hr = find_capacity
- capacity_kbtu_per_hr = OpenStudio.convert(capacity_btu_per_hr, 'Btu/hr', 'kBtu/hr').get
+ sub_category = search_criteria['subcategory']
+ suppl_heating_type = search_criteria['heating_type']
+ capacity_w = find_capacity
+ capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
+ capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
- # Determine supplemental heating type if unitary
- heat_pump = false
- if airLoopHVAC.empty?
- if containingHVACComponent.is_initialized
- containing_comp = containingHVACComponent.get
- if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
- heat_pump = true
- end
- end
- end
-
- # find object
- ac_props = model.find_object(standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
-
# Get the minimum efficiency standards
cop = nil
+ # find object
+ ac_props = model.find_object($os_standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
+
# Check to make sure properties were found
if ac_props.nil?
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, cannot find efficiency info, cannot apply efficiency standard.")
return cop # value of nil
end
+ # If PTHP, use equations
+ if sub_category == 'PTHP'
+ pthp_cop_coeff_1 = ac_props['pthp_cop_coefficient_1']
+ pthp_cop_coeff_2 = ac_props['pthp_cop_coefficient_2']
+ # TABLE 6.8.1D
+ # COP = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * Cap / 1000)
+ # Note c: Cap means the rated cooling capacity of the product in Btu/h.
+ # If the unit's capacity is less than 7000 Btu/h, use 7000 Btu/h in the calculation.
+ # If the unit's capacity is greater than 15,000 Btu/h, use 15,000 Btu/h in the calculation.
+ capacity_btu_per_hr = 7000 if capacity_btu_per_hr < 7000
+ capacity_btu_per_hr = 15_000 if capacity_btu_per_hr > 15_000
+ min_coph = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * capacity_btu_per_hr / 1000.0)
+ cop = cop_heating_to_cop_heating_no_fan(min_coph, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
+ new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_coph.round(1)}COPH"
+ 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)}")
+ end
+
# If specified as HSPF
unless ac_props['minimum_heating_seasonal_performance_factor'].nil?
min_hspf = ac_props['minimum_heating_seasonal_performance_factor']
cop = hspf_to_cop_heating_no_fan(min_hspf)
- 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}")
+ new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_hspf.round(1)}HSPF"
+ 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}")
end
# If specified as COPH
unless ac_props['minimum_coefficient_of_performance_heating'].nil?
min_coph = ac_props['minimum_coefficient_of_performance_heating']
cop = cop_heating_to_cop_heating_no_fan(min_coph, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
- 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}")
+ new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_coph.round(1)}COPH"
+ 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}")
end
# If specified as EER
unless ac_props['minimum_energy_efficiency_ratio'].nil?
min_eer = ac_props['minimum_energy_efficiency_ratio']
cop = eer_to_cop(min_eer, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
- 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}")
+ new_comp_name = "#{name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{min_eer.round(1)}EER"
+ 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}")
end
+ # Rename
+ if rename
+ setName(new_comp_name)
+ end
+
return cop
end
def apply_efficiency_and_curves(template, sql_db_vars_map)
successfully_set_all_properties = true
- unitary_hps = $os_standards['heat_pumps']
- heat_pumps = $os_standards['heat_pumps_heating']
+ # Get the search criteria
+ search_criteria = find_search_criteria(template)
- # Define the criteria to find the unitary properties
- # in the hvac standards data set.
- search_criteria = {}
- search_criteria['template'] = template
-
- # TODO: Standards - add split system vs single package to model
- # For now, assume single package
- subcategory = 'Single Package'
-
- # Assume they are all aircooled for now
- search_criteria['cooling_type'] = 'AirCooled'
-
- # Determine supplemental heating type if unitary
- unitary = false
- suppl_heating_type = nil
- if airLoopHVAC.empty?
- if containingHVACComponent.is_initialized
- containing_comp = containingHVACComponent.get
- if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
- unitary = true
- htg_coil = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get.supplementalHeatingCoil
- suppl_heating_type = if htg_coil.to_CoilHeatingElectric.is_initialized
- 'Electric Resistance or None'
- else
- 'All Other'
- end
- end # TODO: Add other unitary systems
- elsif containingZoneHVACComponent.is_initialized
- containing_comp = containingZoneHVACComponent.get
- # PTHP
- if containing_comp.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
- pthp = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get
- subcategory = 'PTHP'
- htg_coil = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get.supplementalHeatingCoil
- suppl_heating_type = if htg_coil.to_CoilHeatingElectric.is_initialized
- 'Electric Resistance or None'
- else
- 'All Other'
- end
- end
- end
- end
-
- # Add the subcategory to the search criteria
- search_criteria['subcategory'] = subcategory
-
- # Determine the supplemental heating type if on an airloop
- if airLoopHVAC.is_initialized
- air_loop = airLoopHVAC.get
- suppl_heating_type = if !air_loop.supplyComponents('OS:Coil:Heating:Electric'.to_IddObjectType).empty?
- 'Electric Resistance or None'
- elsif !air_loop.supplyComponents('OS:Coil:Heating:Gas'.to_IddObjectType).empty?
- 'All Other'
- elsif !air_loop.supplyComponents('OS:Coil:Heating:Water'.to_IddObjectType).empty?
- 'All Other'
- elsif !air_loop.supplyComponents('OS:Coil:Heating:DX:SingleSpeed'.to_IddObjectType).empty?
- 'All Other'
- elsif !air_loop.supplyComponents('OS:Coil:Heating:Gas:MultiStage'.to_IddObjectType).empty?
- 'All Other'
- elsif !air_loop.supplyComponents('OS:Coil:Heating:Desuperheater'.to_IddObjectType).empty?
- 'All Other'
- elsif !air_loop.supplyComponents('OS:Coil:Heating:WaterToAirHeatPump:EquationFit'.to_IddObjectType).empty?
- 'All Other'
- else
- 'Electric Resistance or None'
- end
- end
-
- # Add the heating type to the search criteria
- unless suppl_heating_type.nil?
- search_criteria['heating_type'] = suppl_heating_type
- end
-
- # Get the coil capacity
- capacity_w = nil
- if unitary
- containing_comp = containingHVACComponent.get
- heat_pump_comp = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get
- ccoil = heat_pump_comp.coolingCoil
- dxcoil = ccoil.to_CoilCoolingDXSingleSpeed.get
- dxcoil_name = dxcoil.name.to_s
- if sql_db_vars_map
- if sql_db_vars_map[dxcoil_name]
- dxcoil.setName(sql_db_vars_map[dxcoil_name])
- end
- end
- if dxcoil.ratedTotalCoolingCapacity.is_initialized
- capacity_w = dxcoil.ratedTotalCoolingCapacity.get
- elsif dxcoil.autosizedRatedTotalCoolingCapacity.is_initialized
- capacity_w = dxcoil.autosizedRatedTotalCoolingCapacity.get
- else
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard.")
- successfully_set_all_properties = false
- return successfully_set_all_properties
- end
- dxcoil.setName(dxcoil_name)
- else
- if ratedTotalHeatingCapacity.is_initialized
- capacity_w = ratedTotalHeatingCapacity.get
- elsif autosizedRatedTotalHeatingCapacity.is_initialized
- capacity_w = autosizedRatedTotalHeatingCapacity.get
- else
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name} capacity is not available, cannot apply efficiency standard.")
- successfully_set_all_properties = false
- return successfully_set_all_properties
- end
- end
-
- # Convert capacity to Btu/hr
+ # Get the capacity
+ capacity_w = find_capacity
capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
- # Lookup efficiencies depending on whether it is a unitary HP or a heat pump
- ac_props = nil
- ac_props = if unitary == true
- model.find_object(unitary_hps, search_criteria, capacity_btu_per_hr, Date.today)
- else
- model.find_object(heat_pumps, search_criteria, capacity_btu_per_hr, Date.today)
- end
+ # Lookup efficiencies
+ ac_props = model.find_object($os_standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
# Check to make sure properties were found
if ac_props.nil?
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, cannot find efficiency info, cannot apply efficiency standard.")
successfully_set_all_properties = false
- return successfully_set_all_properties
+ return sql_db_vars_map
end
# Make the HEAT-CAP-FT curve
heat_cap_ft = model.add_curve(ac_props['heat_cap_ft'])
if heat_cap_ft
@@ -275,47 +236,17 @@
else
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}, cannot find heat_plf_fplr curve, will not be set.")
successfully_set_all_properties = false
end
- # Get the minimum efficiency standards
- cop = nil
+ # Preserve the original name
+ orig_name = name.to_s
- # If PTHP, use equations
- if subcategory == 'PTHP'
- pthp_cop_coeff_1 = ac_props['pthp_cop_coefficient_1']
- pthp_cop_coeff_2 = ac_props['pthp_cop_coefficient_2']
- # TABLE 6.8.1D
- # COP = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * Cap / 1000)
- # Note c: Cap means the rated cooling capacity of the product in Btu/h.
- # If the unit's capacity is less than 7000 Btu/h, use 7000 Btu/h in the calculation.
- # If the unit's capacity is greater than 15,000 Btu/h, use 15,000 Btu/h in the calculation.
- capacity_btu_per_hr = 7000 if capacity_btu_per_hr < 7000
- capacity_btu_per_hr = 15_000 if capacity_btu_per_hr > 15_000
- cop = pthp_cop_coeff_1 - (pthp_cop_coeff_2 * capacity_btu_per_hr / 1000.0)
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingDXSingleSpeed', "For #{name}: #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; COPH = #{cop.round(2)}")
- end
+ # Find the minimum COP and rename with efficiency rating
+ cop = standard_minimum_cop(template, true)
- # If specified as HSPF
- unless ac_props['minimum_heating_seasonal_performance_factor'].nil?
- min_hspf = ac_props['minimum_heating_seasonal_performance_factor']
- cop = hspf_to_cop_heating_no_fan(min_hspf)
- 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}")
- end
-
- # If specified as COPH
- unless ac_props['minimum_coefficient_of_performance_heating'].nil?
- min_coph = ac_props['minimum_coefficient_of_performance_heating']
- cop = cop_heating_to_cop_heating_no_fan(min_coph, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
- 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}")
- end
-
- # If specified as EER
- unless ac_props['minimum_energy_efficiency_ratio'].nil?
- min_eer = ac_props['minimum_energy_efficiency_ratio']
- cop = eer_to_cop(min_eer, OpenStudio.convert(capacity_kbtu_per_hr, 'kBtu/hr', 'W').get)
- 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}")
- end
+ # Map the original name to the new name
+ sql_db_vars_map[name.to_s] = orig_name
# Set the efficiency values
unless cop.nil?
setRatedCOP(cop)
end