diff --git a/lib/openstudio-standards/create_typical/create_typical.rb b/lib/openstudio-standards/create_typical/create_typical.rb index 0393c7c5d2..b69fc91be4 100644 --- a/lib/openstudio-standards/create_typical/create_typical.rb +++ b/lib/openstudio-standards/create_typical/create_typical.rb @@ -318,7 +318,7 @@ def self.create_typical_building_from_model(model, model.getBuilding.setDefaultConstructionSet(bldg_def_const_set) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CreateTypical', "Adding default construction set named #{bldg_def_const_set.name}") else - OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.CreateTypical', "Could not create default construction set for the building type #{lookup_building_type} in climate zone #{climate_zone}.") + OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.CreateTypical', "Could not create default construction set for the building type #{lookup_building_type} in climate zone #{climate_zone} with template #{template}.") return false end diff --git a/lib/openstudio-standards/create_typical/enumerations.rb b/lib/openstudio-standards/create_typical/enumerations.rb index cf299ffa80..431ddff4d4 100644 --- a/lib/openstudio-standards/create_typical/enumerations.rb +++ b/lib/openstudio-standards/create_typical/enumerations.rb @@ -297,6 +297,61 @@ def self.get_climate_zones(extended = false, extra = nil) return array end + # Map a DOE building type to the corresponding DEER building type. + # DEER to DEER mappings included for some use cases + # @param doe_building_type [String] DOE building type + # + # @return [String] DEER building type in short format + def self.doe_to_deer_building_type(doe_building_type) + dict = {} + dict['SecondarySchool'] = 'ESe', + dict['PrimarySchool'] = 'EPr', + dict['SmallOffice'] = 'OfS', + dict['MediumOffice'] = 'OfL', + dict['LargeOffice'] = 'OfL', + dict['SmallHotel'] = 'Mtl', + dict['LargeHotel'] = 'Htl', + dict['Warehouse'] = 'SUn', # Unconditioned Storage (SUn) is nearly identical to SCn + dict['RetailStandalone'] = 'RtL', + dict['RetailStripmall'] = 'RtS', + dict['QuickServiceRestaurant'] = 'RFF', + dict['FullServiceRestaurant'] = 'RSD', + dict['MidriseApartment'] = 'MFm', + dict['HighriseApartment'] = 'OfL', + dict['Hospital'] = 'Hsp', + dict['Outpatient'] = 'OfL', + dict['SuperMarket'] = 'Gro', + dict['Asm'] = 'Asm', + dict['DMo'] = 'DMo', + dict['ECC'] = 'ECC', + dict['EPr'] = 'EPr', + dict['ERC'] = 'ERC', + dict['ESe'] = 'ESe', + dict['EUn'] = 'EUn', + dict['GHs'] = 'GHs', + dict['Gro'] = 'Gro', + dict['Hsp'] = 'Hsp', + dict['Htl'] = 'Htl', + dict['MBT'] = 'MBT', + dict['MFm'] = 'MFm', + dict['MLI'] = 'MLI', + dict['Mtl'] = 'Mtl', + dict['Nrs'] = 'Nrs', + dict['OfL'] = 'OfL', + dict['OfS'] = 'OfS', + dict['RFF'] = 'RFF', + dict['RSD'] = 'RSD', + dict['Rt3'] = 'Rt3', + dict['RtL'] = 'RtL', + dict['RtS'] = 'RtS', + dict['SCn'] = 'SCn', + dict['SFm'] = 'SFm', + dict['SUn'] = 'SUn', + dict['WRf'] = 'WRf' + + return dict[doe_building_type] + end + # Building type abbreviation to long name map # # @param deer_building_type_short [String] DEER building type in short format diff --git a/lib/openstudio-standards/geometry/create_bar.rb b/lib/openstudio-standards/geometry/create_bar.rb index b8ccd9e433..f465ed603f 100644 --- a/lib/openstudio-standards/geometry/create_bar.rb +++ b/lib/openstudio-standards/geometry/create_bar.rb @@ -1994,6 +1994,8 @@ def self.create_bar_from_args_and_building_type_hash(model, args, building_type_ # @option args [String] :template ('90.1-2013') target standard # @return [Boolean] returns true if successful, false if not def self.create_bar_from_building_type_ratios(model, args) + # convert arguments to symbols + args = args.transform_keys(&:to_sym) bldg_type_a = args.fetch(:bldg_type_a, 'SmallOffice') bldg_type_b = args.fetch(:bldg_type_b, nil) bldg_type_c = args.fetch(:bldg_type_c, nil) @@ -2008,6 +2010,61 @@ def self.create_bar_from_building_type_ratios(model, args) bldg_type_d_fract_bldg_area = args.fetch(:bldg_type_d_fract_bldg_area, 0.0) template = args.fetch(:template, '90.1-2013') + # If DOE building type is supplied with a DEER template, map to the nearest DEER building type + if template.include?('DEER') + unless bldg_type_a.nil? + bldg_type_a_deer = OpenstudioStandards::CreateTypical.doe_to_deer_building_type(bldg_type_a) + if bldg_type_a_deer.nil? + OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Geometry.Create', "Could not find a DEER equivalent to #{bldg_type_a} to align with template #{template}.") + return false + elsif bldg_type_a == bldg_type_a_deer + # Already using a DEER building type with a DEER template, no need to change + else + OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Geometry.Create', "Mapped input of DOE building type #{bldg_type_a} to DEER building type #{bldg_type_a_deer} to match template #{template}") + bldg_type_a = bldg_type_a_deer + end + end + + unless bldg_type_b.nil? + bldg_type_b_deer = OpenstudioStandards::CreateTypical.doe_to_deer_building_type(bldg_type_b) + if bldg_type_b_deer.nil? + OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Geometry.Create', "Could not find a DEER equivalent to #{bldg_type_b} to align with template #{template}.") + return false + elsif bldg_type_b == bldg_type_b_deer + # Already using a DEER building type with a DEER template, no need to change + else + OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Geometry.Create', "Mapped input of DOE building type #{bldg_type_b} to DEER building type #{bldg_type_b_deer} to match template #{template}") + bldg_type_b = bldg_type_b_deer + end + end + + unless bldg_type_c.nil? + bldg_type_c_deer = OpenstudioStandards::CreateTypical.doe_to_deer_building_type(bldg_type_c) + if bldg_type_c_deer.nil? + OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Geometry.Create', "Could not find a DEER equivalent to #{bldg_type_c} to align with template #{template}.") + return false + elsif bldg_type_c == bldg_type_c_deer + # Already using a DEER building type with a DEER template, no need to change + else + OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Geometry.Create', "Mapped input of DOE building type #{bldg_type_c} to DEER building type #{bldg_type_c_deer} to match template #{template}") + bldg_type_c = bldg_type_c_deer + end + end + + unless bldg_type_d.nil? + bldg_type_d_deer = OpenstudioStandards::CreateTypical.doe_to_deer_building_type(bldg_type_d) + if bldg_type_d_deer.nil? + OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Geometry.Create', "Could not find a DEER equivalent to #{bldg_type_d} to align with template #{template}.") + return false + elsif bldg_type_d == bldg_type_d_deer + # Already using a DEER building type with a DEER template, no need to change + else + OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Geometry.Create', "Mapped input of DOE building type #{bldg_type_d} to DEER building type #{bldg_type_d_deer} to match template #{template}") + bldg_type_d = bldg_type_d_deer + end + end + end + # check that sum of fractions for b,c, and d is less than 1.0 (so something is left for primary building type) bldg_type_a_fract_bldg_area = 1.0 - bldg_type_b_fract_bldg_area - bldg_type_c_fract_bldg_area - bldg_type_d_fract_bldg_area if bldg_type_a_fract_bldg_area <= 0.0 diff --git a/test/modules/geometry/test_geometry_create_bar.rb b/test/modules/geometry/test_geometry_create_bar.rb index fcb0c5deb2..b260fcc880 100644 --- a/test/modules/geometry/test_geometry_create_bar.rb +++ b/test/modules/geometry/test_geometry_create_bar.rb @@ -52,6 +52,24 @@ def test_create_bar_from_building_type_ratios_ofs assert(result) end + def test_create_bar_from_building_type_ratios_doe_deer_mix + model = OpenStudio::Model::Model.new + + args = {} + args['total_bldg_floor_area'] = 2500.0 + args['bldg_type_a'] = 'PrimarySchool' + args['ns_to_ew_ratio'] = 1.0 + args['num_stories_above_grade'] = 3.0 + args['template'] = "DEER Pre-1975" + args['climate_zone'] = "CEC T24-CEC9" + args['floor_height'] = 9.0 + args['story_multiplier'] = "None" + args['wwr'] = 0.3 + result = @geo.create_bar_from_building_type_ratios(model, args) + assert(result) + assert('EPr', model.getSpaceTypes[0].standardsBuildingType.get) + end + def test_create_bar_from_building_type_ratios_division_methods model = OpenStudio::Model::Model.new