Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove duplicate prm methods #1583

Merged
merged 18 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lib/openstudio-standards.rb
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,6 @@ module OpenstudioStandards
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface"
require_relative "#{stds}/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def boiler_hot_water_find_design_water_flow_rate(boiler_hot_water)
# Finds lookup object in standards and return minimum thermal efficiency
#
# @param boiler_hot_water [OpenStudio::Model::BoilerHotWater] hot water boiler object
# @param rename [Bool] if true, rename the boiler to include the new capacity and efficiency
# @return [Double] minimum thermal efficiency
def boiler_hot_water_standard_minimum_thermal_efficiency(boiler_hot_water, rename = false)
# Get the boiler properties
Expand Down
22 changes: 14 additions & 8 deletions lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,20 @@ def chiller_electric_eir_find_search_criteria(chiller_electric_eir)
condenser_type = 'WithCondenser' if absorption_type.nil?
end
elsif cooling_type == 'WaterCooled'
if name.include?('Reciprocating')
compressor_type = 'Reciprocating'
elsif name.include?('Rotary Screw')
compressor_type = 'Rotary Screw'
elsif name.include?('Scroll')
compressor_type = 'Scroll'
elsif name.include?('Centrifugal')
compressor_type = 'Centrifugal'
# use the chiller additional properties compressor type if defined
if chiller_electric_eir.additionalProperties.hasFeature('compressor_type')
compressor_type = chiller_electric_eir.additionalProperties.getFeatureAsString('compressor_type').get
else
# try to lookup by chiller name
if name.include?('Reciprocating')
compressor_type = 'Reciprocating'
elsif name.include?('Rotary Screw')
compressor_type = 'Rotary Screw'
elsif name.include?('Scroll')
compressor_type = 'Scroll'
elsif name.include?('Centrifugal')
compressor_type = 'Centrifugal'
end
end
end
unless condenser_type.nil?
Expand Down
10 changes: 5 additions & 5 deletions lib/openstudio-standards/standards/Standards.CoolingTower.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ def cooling_tower_apply_minimum_power_per_flow(cooling_tower)
fan_type = nil
if name.include?('Centrifugal')
fan_type = 'Centrifugal'
elsif name.include?('Propeller or Axial')
elsif name.include?('Propeller') || name.include?('Axial')
fan_type = 'Propeller or Axial'
end
unless fan_type.nil?
search_criteria['fan_type'] = fan_type
else
fan_type = 'Propeller or Axial'
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoolingTower', "#{cooling_tower.name} fan type is not discernible from the name. Defaulting to Propeller or Axial.")
end

# Limit on Centrifugal Fan
Expand All @@ -65,13 +65,13 @@ def cooling_tower_apply_minimum_power_per_flow(cooling_tower)
if gpm_limit
if design_water_flow_gpm >= gpm_limit
fan_type = 'Propeller or Axial'
search_criteria['fan_type'] = fan_type
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoolingTower', "For #{cooling_tower.name}, the design flow rate of #{design_water_flow_gpm.round} gpm is higher than the limit of #{gpm_limit.round} gpm for open centrifugal towers. This tower must meet the minimum performance of #{fan_type} instead.")
end
end
end

# Get the cooling tower properties
search_criteria['fan_type'] = fan_type
ct_props = model_find_object(heat_rejection, search_criteria)
unless ct_props
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoolingTower', "For #{cooling_tower.name}, cannot find heat rejection properties, cannot apply standard efficiencies or curves.")
Expand Down
37 changes: 18 additions & 19 deletions lib/openstudio-standards/standards/Standards.Model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,14 @@ def model_prm_baseline_system_groups(model, custom, bldg_type_hvac_zone_hash = n
# Define the minimum area for the
# exception that allows a different
# system type in part of the building.
exception_min_area_m2 = model_prm_baseline_system_group_minimum_area(model, custom)
exception_min_area_ft2 = OpenStudio.convert(exception_min_area_m2, 'm^2', 'ft^2').get
if custom == 'Xcel Energy CO EDA'
# Customization - Xcel EDA Program Manual 2014
# 3.2.1 Mechanical System Selection ii
exception_min_area_ft2 = 5000
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "Customization; per Xcel EDA Program Manual 2014 3.2.1 Mechanical System Selection ii, minimum area for non-predominant conditions reduced to #{exception_min_area_ft2} ft2.")
else
exception_min_area_ft2 = 20_000
end

# Get occupancy type, fuel type, and area information for all zones,
# excluding unconditioned zones.
Expand Down Expand Up @@ -1125,18 +1131,6 @@ def get_8760_values_from_schedule(model, fan_schedule)
return fan_8760
end

# Determines the area of the building above which point
# the non-dominant area type gets it's own HVAC system type.
#
# @param model [OpenStudio::Model::Model] OpenStudio model object
# @param custom [String] custom fuel type
# @return [Double] the minimum area (m^2)
def model_prm_baseline_system_group_minimum_area(model, custom)
exception_min_area_ft2 = 20_000
exception_min_area_m2 = OpenStudio.convert(exception_min_area_ft2, 'ft^2', 'm^2').get
return exception_min_area_m2
end

# Determine the baseline system type given the inputs. Logic is different for different standards.
#
# 90.1-2007, 90.1-2010, 90.1-2013
Expand All @@ -1154,14 +1148,19 @@ def model_prm_baseline_system_type(model, climate_zone, sys_group, custom, hvac_
area_ft2 = sys_group['area_ft2']
num_stories = sys_group['stories']

# [type, central_heating_fuel, zone_heating_fuel, cooling_fuel]
# [type, central_heating_fuel, zone_heating_fuel, cooling_fuel]
system_type = [nil, nil, nil, nil]

# Get the row from TableG3.1.1A
sys_num = model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type, area_ft2, num_stories, custom)

# Modify the fuel type if called for by the standard
fuel_type = model_prm_baseline_system_change_fuel_type(model, fuel_type, climate_zone, custom)
if custom == 'Xcel Energy CO EDA'
# fuel type remains unchanged
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', 'Custom; per Xcel EDA Program Manual 2014 Table 3.2.2 Baseline HVAC System Types, the 90.1-2010 rules for heating fuel type (based on proposed model) rules apply.')
else
fuel_type = model_prm_baseline_system_change_fuel_type(model, fuel_type, climate_zone)
end

# Define the lookup by row and by fuel type
sys_lookup = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
Expand Down Expand Up @@ -1261,10 +1260,10 @@ def model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type,
# @param fuel_type [String] Valid choices are electric, fossil, fossilandelectric,
# purchasedheat, purchasedcooling, purchasedheatandcooling
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
# @param custom [String] custom fuel type
# @return [String] the revised fuel type
def model_prm_baseline_system_change_fuel_type(model, fuel_type, climate_zone, custom = nil)
return fuel_type # Don't change fuel type for most templates
def model_prm_baseline_system_change_fuel_type(model, fuel_type, climate_zone)
# Don't change fuel type for most templates
return fuel_type
end

# Determine whether heating type is fuel or electric
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
class ASHRAE9012013 < ASHRAE901
# @!group Model

# Determines the area of the building above which point
# the non-dominant area type gets it's own HVAC system type.
# @return [Double] the minimum area (m^2)
def model_prm_baseline_system_group_minimum_area(model, custom)
exception_min_area_ft2 = 20_000
# Customization - Xcel EDA Program Manual 2014
# 3.2.1 Mechanical System Selection ii
if custom == 'Xcel Energy CO EDA'
exception_min_area_ft2 = 5000
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Customization; per Xcel EDA Program Manual 2014 3.2.1 Mechanical System Selection ii, minimum area for non-predominant conditions reduced to #{exception_min_area_ft2} ft2.")
end
exception_min_area_m2 = OpenStudio.convert(exception_min_area_ft2, 'ft^2', 'm^2').get
return exception_min_area_m2
end

# Determines which system number is used
# for the baseline system.
# @return [String] the system number: 1_or_2, 3_or_4,
Expand Down Expand Up @@ -84,13 +69,12 @@ def model_prm_baseline_system_number(model, climate_zone, area_type, fuel_type,

# Change the fuel type based on climate zone, depending on the standard.
# For 90.1-2013, fuel type is based on climate zone, not the proposed model.
# @param model [OpenStudio::Model::Model] OpenStudio model object
# @param fuel_type [String] Valid choices are electric, fossil, fossilandelectric,
# purchasedheat, purchasedcooling, purchasedheatandcooling
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
# @return [String] the revised fuel type
def model_prm_baseline_system_change_fuel_type(model, fuel_type, climate_zone, custom = nil)
if custom == 'Xcel Energy CO EDA'
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', 'Custom; per Xcel EDA Program Manual 2014 Table 3.2.2 Baseline HVAC System Types, the 90.1-2010 rules for heating fuel type (based on proposed model) rules apply.')
return fuel_type
end

def model_prm_baseline_system_change_fuel_type(model, fuel_type, climate_zone)
# For 90.1-2013 the fuel type is determined based on climate zone.
# Don't change the fuel if it purchased heating or cooling.
if fuel_type == 'electric' || fuel_type == 'fossil'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,6 @@ def air_loop_hvac_multizone_vav_system?(air_loop_hvac)
return false
end

# Determine if multizone vav optimization is required.
# Not required for stable baseline.
#
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
# @return [Bool] returns true if required, false if not
def air_loop_hvac_multizone_vav_optimization_required?(air_loop_hvac, climate_zone)
multizone_opt_required = false
return multizone_opt_required
end

# Determine whether the VAV damper control is single maximum or dual maximum control.
# Defaults to Single Maximum for stable baseline.
#
Expand Down
Original file line number Diff line number Diff line change
@@ -1,79 +1,6 @@
class ASHRAE901PRM < Standard
# @!group BoilerHotWater

# find search criteria
#
# @param boiler_hot_water [OpenStudio::Model::BoilerHotWater] hot water boiler object
# @return [Hash] used for standards_lookup_table(model)
def boiler_hot_water_find_search_criteria(boiler_hot_water)
# Define the criteria to find the boiler properties
# in the hvac standards data set.
search_criteria = {}
search_criteria['template'] = template

# Get fuel type
search_criteria['fuel_type'] = 'Gas'

# Get the fluid type
search_criteria['fluid_type'] = 'Hot Water'

return search_criteria
end

# Finds lookup object in standards and return minimum thermal efficiency
#
# @param boiler_hot_water [OpenStudio::Model::BoilerHotWater] hot water boiler object
# @param rename [Bool] returns true if successful, false if not
# @return [Double] minimum thermal efficiency
def boiler_hot_water_standard_minimum_thermal_efficiency(boiler_hot_water, rename = false)
# Get the boiler properties
search_criteria = boiler_hot_water_find_search_criteria(boiler_hot_water)
capacity_w = boiler_hot_water_find_capacity(boiler_hot_water)
capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get

# Get the minimum efficiency standards
thermal_eff = nil

# Get the boiler properties
blr_props = model_find_object(standards_data['boilers'], search_criteria, capacity_btu_per_hr)
unless blr_props
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.BoilerHotWater', "For #{boiler_hot_water.name}, cannot find boiler properties, cannot apply efficiency standard.")
successfully_set_all_properties = false
return successfully_set_all_properties
end

# If specified as AFUE
unless blr_props['minimum_annual_fuel_utilization_efficiency'].nil?
min_afue = blr_props['minimum_annual_fuel_utilization_efficiency']
thermal_eff = afue_to_thermal_eff(min_afue)
new_comp_name = "#{boiler_hot_water.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_afue} AFUE"
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.BoilerHotWater', "For #{template}: #{boiler_hot_water.name}: Gas Hot Water Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; AFUE = #{min_afue}")
end

# If specified as thermal efficiency
unless blr_props['minimum_thermal_efficiency'].nil?
thermal_eff = blr_props['minimum_thermal_efficiency']
new_comp_name = "#{boiler_hot_water.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{thermal_eff} Thermal Eff"
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.BoilerHotWater', "For #{template}: #{boiler_hot_water.name}: Gas Hot Water Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; Thermal Efficiency = #{thermal_eff}")
end

# If specified as combustion efficiency
unless blr_props['minimum_combustion_efficiency'].nil?
min_comb_eff = blr_props['minimum_combustion_efficiency']
thermal_eff = combustion_eff_to_thermal_eff(min_comb_eff)
new_comp_name = "#{boiler_hot_water.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_comb_eff} Combustion Eff"
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.BoilerHotWater', "For #{template}: #{boiler_hot_water.name}: Gas Hot Water Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; Combustion Efficiency = #{min_comb_eff}")
end

# Rename
if rename
boiler_hot_water.setName(new_comp_name)
end

return thermal_eff
end

# Applies the standard efficiency ratings to this object.
#
# @param boiler_hot_water [OpenStudio::Model::BoilerHotWater] hot water boiler object
Expand Down
Original file line number Diff line number Diff line change
@@ -1,72 +1,20 @@
class ASHRAE901PRM < Standard
# @!group ChillerElectricEIR

# Finds the search criteria
#
# @param chiller_electric_eir [OpenStudio::Model::ChillerElectricEIR] chiller object
# @return [hash] has for search criteria to be used for find object
def chiller_electric_eir_find_search_criteria(chiller_electric_eir)
search_criteria = {}
search_criteria['template'] = template

# In AppG prm models, all scenarios are WaterCooled for cooling type.
cooling_type = 'WaterCooled'

search_criteria['cooling_type'] = cooling_type

# TODO: Standards replace this with a mechanism to store this
# data in the chiller object itself.
# For now, retrieve the condenser type from the name
name = chiller_electric_eir.name.get
condenser_type = nil
compressor_type = nil
if chiller_electric_eir.additionalProperties.hasFeature('compressor_type')
compressor_type = chiller_electric_eir.additionalProperties.getFeatureAsString('compressor_type').get
end
unless condenser_type.nil?
search_criteria['condenser_type'] = condenser_type
end
unless compressor_type.nil?
search_criteria['compressor_type'] = compressor_type
end

return search_criteria
end

# Finds lookup object in standards and return full load efficiency
#
# @param chiller_electric_eir [OpenStudio::Model::ChillerElectricEIR] chiller object
# @return [Double] full load efficiency (COP), [Double] capacity in tons, [Double] kw/ton
def chiller_electric_eir_standard_minimum_full_load_efficiency(chiller_electric_eir)
# Get the chiller properties
search_criteria = chiller_electric_eir_find_search_criteria(chiller_electric_eir)
capacity_w = chiller_electric_eir_find_capacity(chiller_electric_eir)
unless capacity_w
return nil
end

capacity_tons = OpenStudio.convert(capacity_w, 'W', 'ton').get
chlr_props = model_find_object(standards_data['chillers'], search_criteria, capacity_tons, Date.today)

if chlr_props.nil? || !chlr_props['minimum_full_load_efficiency']
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.ChillerElectricEIR', "For #{chiller_electric_eir.name}, cannot find minimum full load efficiency.")
return nil
else
# lookup the efficiency value
kw_per_ton = chlr_props['minimum_full_load_efficiency']
cop = kw_per_ton_to_cop(kw_per_ton)
end

return cop, capacity_tons, kw_per_ton
end

# Applies the standard efficiency ratings to this object.
#
# @param chiller_electric_eir [OpenStudio::Model::ChillerElectricEIR] chiller object
# @return [Bool] true if successful, false if not
def chiller_electric_eir_apply_efficiency_and_curves(chiller_electric_eir)
# Get the chiller capacity
capacity_w = chiller_electric_eir_find_capacity(chiller_electric_eir)

# Convert capacity to tons
capacity_tons = OpenStudio.convert(capacity_w, 'W', 'ton').get

# Set the efficiency value
cop, capacity_tons, kw_per_ton = chiller_electric_eir_standard_minimum_full_load_efficiency(chiller_electric_eir)
cop = chiller_electric_eir_standard_minimum_full_load_efficiency(chiller_electric_eir)
kw_per_ton = cop_to_kw_per_ton(cop)
if cop.nil?
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.ChillerElectricEIR', "For #{chiller_electric_eir.name}, cannot find minimum full load efficiency, will not be set.")
successfully_set_all_properties = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,6 @@ def coil_heating_gas_find_search_criteria(coil_heating_gas, sys_type)
return search_criteria
end

# find furnace capacity
#
# @param coil_heating_gas [OpenStudio::Model::CoilHeatingGas] coil heating gas object
# @return [Double] capacity in W to be used for find object
def coil_heating_gas_find_capacity(coil_heating_gas)
# Get the coil capacity
capacity_w = nil
if coil_heating_gas.nominalCapacity.is_initialized
capacity_w = coil_heating_gas.nominalCapacity.get
elsif coil_heating_gas.autosizedNominalCapacity.is_initialized
capacity_w = coil_heating_gas.autosizedNominalCapacity.get
else
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingGas', "For #{coil_heating_gas.name} capacity is not available, cannot apply efficiency standard.")
successfully_set_all_properties = false
return successfully_set_all_properties
end

return capacity_w
end

# Finds lookup object in standards and return minimum thermal efficiency
#
# @param coil_heating_gas [OpenStudio::Model::CoilHeatingGas] coil heating gas object
Expand Down
Loading