Module: OpenstudioStandards::Refrigeration
- Defined in:
- lib/openstudio-standards/refrigeration/create_case.rb,
lib/openstudio-standards/refrigeration/information.rb,
lib/openstudio-standards/refrigeration/create_walkin.rb,
lib/openstudio-standards/refrigeration/create_compressor.rb,
lib/openstudio-standards/refrigeration/create_compressor_rack.rb,
lib/openstudio-standards/refrigeration/create_refrigeration_system.rb,
lib/openstudio-standards/refrigeration/create_typical_refrigeration.rb
Overview
The Refrigeration module provides methods to create, modify, and get information about refrigeration
Create Case collapse
-
.create_case(model, template: 'new', case_type: 'Vertical Open - All', case_length: nil, defrost_schedule: nil, defrost_start_hour: 0, dripdown_schedule: nil, thermal_zone: nil) ⇒ OpenStudio::Model::RefrigerationCase
Adds a refrigerated case to the model.
Information collapse
-
.refrigeration_case_zone(model) ⇒ OpenStudio::Model::ThermalZone
Find the thermal zone that is best for adding refrigerated display cases into.
-
.refrigeration_walkin_zone(model) ⇒ OpenStudio::Model::ThermalZone
Find the thermal zone that is best for adding refrigerated walkins into.
Create Walkin collapse
-
.create_walkin(model, name: nil, template: 'new', walkin_type: 'Walk-in Cooler - 120SF with no glass door', defrost_schedule: nil, defrost_start_hour: 0, dripdown_schedule: nil, thermal_zone: nil) ⇒ OpenStudio::Model::RefrigerationWalkIn
Adds a refrigerated walkin to the model.
Create Refrigeration Compressor collapse
-
.create_compressor(model, template: 'new', operation_type: 'MT') ⇒ OpenStudio::Model::RefrigerationCompressor
Adds a refrigeration system compressor to the model.
Create Refrigeration Compressor Rack collapse
-
.create_compressor_rack(model, refrigeration_equipment, template: 'new') ⇒ OpenStudio::Model::RefrigerationCase
Adds a self contained refrigeration compressor rack for a case or walkin to the model.
Create Refrigeration System collapse
-
.create_refrigeration_system(model, refrigeration_equipment, template: 'new', operation_type: 'MT', refrigerant: 'R404a') ⇒ OpenStudio::Model::RefrigerationCase
Adds a refrigerated system to the model.
Create Typical Refrigeration collapse
-
.create_typical_refrigeration(model, template: 'new', separate_system_size_limit: 0.0) ⇒ Boolean
Adds typical refrigeration to a model.
-
.typical_refrigeration_equipment_list(model) ⇒ Hash
Returns the typical refrigeration equipment in a model based on space types.
Class Method Details
.create_case(model, template: 'new', case_type: 'Vertical Open - All', case_length: nil, defrost_schedule: nil, defrost_start_hour: 0, dripdown_schedule: nil, thermal_zone: nil) ⇒ OpenStudio::Model::RefrigerationCase
Adds a refrigerated case to the model.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/openstudio-standards/refrigeration/create_case.rb', line 18 def self.create_case(model, template: 'new', case_type: 'Vertical Open - All', case_length: nil, defrost_schedule: nil, defrost_start_hour: 0, dripdown_schedule: nil, thermal_zone: nil) # get thermal zone if not provided if thermal_zone.nil? # Find the thermal zones most suited for holding the display cases thermal_zone = OpenstudioStandards::Refrigeration.refrigeration_case_zone(model) if thermal_zone.nil? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', 'Attempted to add display cases to the model, but could find no thermal zone to put them into.') return nil end end # load refrigeration cases data cases_csv = "#{File.dirname(__FILE__)}/data/refrigerated_cases.csv" unless File.file?(cases_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{cases_csv}") return nil end cases_tbl = CSV.table(cases_csv, encoding: 'ISO8859-1:utf-8') cases_hsh = cases_tbl.map(&:to_hash) # get case properties case_properties = cases_hsh.select { |r| (r[:template] == template) && (r[:case_name] == case_type) }[0] if case_properties.nil? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find case data for template #{template} case type #{case_type}.") return nil end # add case ref_case = OpenStudio::Model::RefrigerationCase.new(model, model.alwaysOnDiscreteSchedule) ref_case.setName(case_type) case_length_m = case_length.nil? ? case_properties[:unit_length] : case_length ref_case.setCaseLength(case_length_m) ref_case.setRatedTotalCoolingCapacityperUnitLength(case_properties[:rated_capacity]) ref_case.(case_properties[:case_operating_temperature]) ref_case.setDesignEvaporatorTemperatureorBrineInletTemperature(case_properties[:evaporator_temperature]) ref_case.setRatedLatentHeatRatio(case_properties[:rated_latent_heat_ratio]) ref_case.setRatedRuntimeFraction(case_properties[:rated_runtime_fraction]) ref_case.setLatentCaseCreditCurveType(case_properties[:latent_case_credit_curve_type]) # TODO: replace once curves are standardized std = Standard.build('90.1-2013') latent_case_credit_curve = std.model_add_curve(model, case_properties[:latent_case_credit_curve_name]) ref_case.setLatentCaseCreditCurve(latent_case_credit_curve) ref_case.setStandardCaseFanPowerperUnitLength(case_properties[:fan_power]) ref_case.(case_properties[:fan_power]) ref_case.setStandardCaseLightingPowerperUnitLength(case_properties[:lighting_power]) ref_case.setInstalledCaseLightingPowerperUnitLength(case_properties[:lighting_power]) ref_case.setCaseLightingSchedule(model.alwaysOnDiscreteSchedule) ref_case.setFractionofLightingEnergytoCase(case_properties[:fraction_of_lighting_energy_to_case]) unless case_properties[:fraction_of_lighting_energy_to_case].nil? ref_case.setCaseAntiSweatHeaterPowerperUnitLength(case_properties[:anti_sweat_power]) unless case_properties[:anti_sweat_power].nil? ref_case.setMinimumAntiSweatHeaterPowerperUnitLength(0.0) ref_case.setHumidityatZeroAntiSweatHeaterEnergy(0.0) ref_case.setAntiSweatHeaterControlType(case_properties[:anti_sweat_heater_control_type]) ref_case.setFractionofAntiSweatHeaterEnergytoCase(case_properties[:fraction_of_anti_sweat_heater_energy_to_cases]) unless case_properties[:fraction_of_anti_sweat_heater_energy_to_cases].nil? ref_case.setCaseDefrostPowerperUnitLength(case_properties[:defrost_power]) unless case_properties[:defrost_power].nil? ref_case.setCaseDefrostType(case_properties[:defrost_type]) ref_case.setDefrostEnergyCorrectionCurveType(case_properties[:defrost_energy_correction_curve_type]) unless case_properties[:defrost_energy_correction_curve_type].nil? unless case_properties[:defrost_energy_correction_curve_name].nil? # TODO: replace once curves are standardized defrost_correction_curve_name = std.model_add_curve(model, case_properties[:defrost_energy_correction_curve_name]) ref_case.setDefrostEnergyCorrectionCurve(defrost_correction_curve_name) end ref_case.setUnderCaseHVACReturnAirFraction(0.0) ref_case.resetRefrigeratedCaseRestockingSchedule ref_case.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule) ref_case.setThermalZone(thermal_zone) ref_case.setRatedAmbientTemperature(OpenStudio.convert(75.0, 'F', 'C').get) # only add defrost schedules if not OffCycle unless case_properties[:defrost_type] == 'OffCycle' # defrost properties, default to one 45 minute defrost cycle per day followed by a 5 minute dripdown duration defrost_duration = case_properties[:defrost_duration].nil? ? 45 : case_properties[:defrost_duration] defrosts_per_day = case_properties[:defrosts_per_day].nil? ? 1 : case_properties[:defrosts_per_day] dripdown_duration = case_properties[:dripdown_duration].nil? ? 5 : case_properties[:dripdown_duration] # defrost hours are calculated from the start hour and number of defrosts per day defrost_interval = (24 / defrosts_per_day).floor defrost_hours = (1..defrosts_per_day).map { |i| defrost_start_hour + ((i - 1) * defrost_interval) } defrost_hours.map! { |hr| hr > 23 ? hr - 24 : hr } defrost_hours.sort! # Defrost schedule if defrost_schedule.nil? defrost_schedule = OpenStudio::Model::ScheduleRuleset.new(model) defrost_schedule.setName("#{ref_case.name} Defrost") defrost_schedule.defaultDaySchedule.setName("#{ref_case.name} Defrost Default") defrost_hours.each do |defrost_hour| defrost_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, defrost_hour, 0, 0), 0) defrost_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, defrost_hour, defrost_duration, 0), 1) end defrost_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0) else unless defrost_schedule.to_Schedule.is_initialized OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Input for defrost_schedule #{defrost_schedule} is not a valid OpenStudio::Model::Schedule object") return nil end end ref_case.setCaseDefrostSchedule(defrost_schedule) # Dripdown schedule, synced to occur after the defrost schedule if dripdown_schedule.nil? dripdown_schedule = OpenStudio::Model::ScheduleRuleset.new(model) dripdown_schedule.setName("#{ref_case.name} Dripdown") dripdown_schedule.defaultDaySchedule.setName("#{ref_case.name} Dripdown Default") defrost_hours.each do |defrost_hour| dripdown_hour = (defrost_duration + dripdown_duration) > 59 ? defrost_hour + 1 : defrost_hour dripdown_hour = dripdown_hour > 23 ? dripdown_hour - 24 : dripdown_hour dripdown_end_min = (defrost_duration + dripdown_duration) > 59 ? defrost_duration + dripdown_duration - 60 : defrost_duration + dripdown_duration dripdown_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, defrost_hour, defrost_duration, 0), 0) dripdown_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, dripdown_hour, dripdown_end_min, 0), 1) end dripdown_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0) else unless dripdown_schedule.to_Schedule.is_initialized OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Input for dripdown_schedule #{dripdown_schedule} is not a valid OpenStudio::Model::Schedule object") return nil end end ref_case.setCaseDefrostDripDownSchedule(dripdown_schedule) end # Case Credit Schedule case_credit_sch = OpenStudio::Model::ScheduleRuleset.new(model) case_credit_sch.setName("#{ref_case.name} Case Credit") case_credit_sch.defaultDaySchedule.setName("#{ref_case.name} Case Credit Default") case_credit_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 1.0) ref_case.setCaseCreditFractionSchedule(case_credit_sch) # reporting length_ft = OpenStudio.convert(ref_case.caseLength, 'm', 'ft').get cooling_capacity_w = ref_case.caseLength * ref_case.ratedTotalCoolingCapacityperUnitLength cooling_capacity_btu_per_hr = OpenStudio.convert(cooling_capacity_w, 'W', 'Btu/hr').get OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Added #{length_ft.round} ft display case called #{case_type} with a cooling capacity of #{cooling_capacity_btu_per_hr.round} Btu/hr to #{thermal_zone&.name}.") return ref_case end |
.create_compressor(model, template: 'new', operation_type: 'MT') ⇒ OpenStudio::Model::RefrigerationCompressor
Adds a refrigeration system compressor to the model.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/openstudio-standards/refrigeration/create_compressor.rb', line 13 def self.create_compressor(model, template: 'new', operation_type: 'MT') # load refrigeration compressor data compressors_csv = "#{File.dirname(__FILE__)}/data/refrigeration_compressors.csv" unless File.file?(compressors_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{compressors_csv}") return nil end compressors_tbl = CSV.table(compressors_csv, encoding: 'ISO8859-1:utf-8') compressors_hsh = compressors_tbl.map(&:to_hash) # get case properties compressor_properties = compressors_hsh.select { |r| (r[:template] == template) && (r[:operation_type] == operation_type) } if compressor_properties.nil? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find compressor for template #{template} operation type #{operation_type}.") return nil end pc = compressor_properties.select { |r| r[:curve_type] == 'Power' }[0] cc = compressor_properties.select { |r| r[:curve_type] == 'Capacity' }[0] # TODO: replace with curve data once curves are refactored std = Standard.build('90.1-2013') # create power curve power_coeffs = [] power_coeffs << pc[:coefficient1] power_coeffs << pc[:coefficient2] power_coeffs << pc[:coefficient3] power_coeffs << pc[:coefficient4] power_coeffs << pc[:coefficient5] power_coeffs << pc[:coefficient6] power_coeffs << pc[:coefficient7] power_coeffs << pc[:coefficient8] power_coeffs << pc[:coefficient9] power_coeffs << pc[:coefficient10] power_curve = std.create_curve_bicubic(model, power_coeffs, pc[:curve_name], pc[:min_val_x], pc[:max_val_x], pc[:min_val_y], pc[:max_val_y], nil, nil) # create capacity curve capacity_coeffs = [] capacity_coeffs << cc[:coefficient1] capacity_coeffs << cc[:coefficient2] capacity_coeffs << cc[:coefficient3] capacity_coeffs << cc[:coefficient4] capacity_coeffs << cc[:coefficient5] capacity_coeffs << cc[:coefficient6] capacity_coeffs << cc[:coefficient7] capacity_coeffs << cc[:coefficient8] capacity_coeffs << cc[:coefficient9] capacity_coeffs << cc[:coefficient10] capacity_curve = std.create_curve_bicubic(model, capacity_coeffs, cc[:curve_name], cc[:min_val_x], cc[:max_val_x], cc[:min_val_y], cc[:max_val_y], nil, nil) # Make the compressor compressor = OpenStudio::Model::RefrigerationCompressor.new(model) compressor.setName("#{template} #{operation_type} Refrigeration Compressor") compressor.setRefrigerationCompressorPowerCurve(power_curve) compressor.setRefrigerationCompressorCapacityCurve(capacity_curve) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Added refrigeration compressor #{compressor.name}.") return compressor end |
.create_compressor_rack(model, refrigeration_equipment, template: 'new') ⇒ OpenStudio::Model::RefrigerationCase
Adds a self contained refrigeration compressor rack for a case or walkin to the model.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/openstudio-standards/refrigeration/create_compressor_rack.rb', line 13 def self.create_compressor_rack(model, refrigeration_equipment, template: 'new') # Add refrigeration system ref_rack = OpenStudio::Model::RefrigerationCompressorRack.new(model) ref_rack.setName('Self-Contained Refrigeration System') # Add refrigeration case or walkin to the rack if refrigeration_equipment.to_RefrigerationCase.is_initialized ref_case = refrigeration_equipment.to_RefrigerationCase.get rated_capacity_w = ref_case.ratedTotalCoolingCapacityperUnitLength * ref_case.caseLength ref_rack.addCase(ref_case) thermal_zone = ref_case.thermalZone.get elsif refrigeration_equipment.to_RefrigerationWalkIn.is_initialized ref_walkin = refrigeration_equipment.to_RefrigerationWalkIn.get rated_capacity_w = ref_walkin.ratedCoilCoolingCapacity ref_rack.addWalkin(ref_walkin) thermal_zone = ref_walkin.zoneBoundaryThermalZone.get end # set zone based on equipment zone ref_rack.setHeatRejectionLocation('Zone') ref_rack.setHeatRejectionZone(thermal_zone) ref_rack.setCondenserType('AirCooled') # @todo add cop and curves for compressor racks # ref_rack.setDesignCompressorRackCOP(Double) # ref_rack.setCompressorRackCOPFunctionofTemperatureCurve(&Curve) # ref_rack.setDesignCondenserFanPower(Double) # ref_rack.setCondenserFanPowerFunctionofTemperatureCurve(&Curve) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Added compressor rack with capacity #{OpenStudio.convert(rated_capacity_w, 'W', 'Btu/hr').get.round} Btu/hr of load serving #{refrigeration_equipment.name}.") return ref_rack end |
.create_refrigeration_system(model, refrigeration_equipment, template: 'new', operation_type: 'MT', refrigerant: 'R404a') ⇒ OpenStudio::Model::RefrigerationCase
Adds a refrigerated system to the model.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/openstudio-standards/refrigeration/create_refrigeration_system.rb', line 15 def self.create_refrigeration_system(model, refrigeration_equipment, template: 'new', operation_type: 'MT', refrigerant: 'R404a') # Add refrigeration system ref_system = OpenStudio::Model::RefrigerationSystem.new(model) ref_system.setName("#{operation_type} Refrigeration System") ref_system.setRefrigerationSystemWorkingFluidType(refrigerant) ref_system.setSuctionTemperatureControlType('ConstantSuctionTemperature') # Add equipment to the system and sum capacity. # Allowable equipment are refrigeration cases and walkins. rated_capacity_w = 0 refrigeration_equipment.each do |ref_equip| if ref_equip.to_RefrigerationCase.is_initialized ref_case = ref_equip.to_RefrigerationCase.get rated_capacity_w += ref_case.ratedTotalCoolingCapacityperUnitLength * ref_case.caseLength ref_system.addCase(ref_case) elsif ref_equip.to_RefrigerationWalkIn.is_initialized ref_walkin = ref_equip.to_RefrigerationWalkIn.get rated_capacity_w += ref_walkin.ratedCoilCoolingCapacity ref_system.addWalkin(ref_walkin) end end # Calculate number of compressors rated_compressor_capacity_btu_per_hr = 60_000.0 number_of_compressors = (rated_capacity_w / OpenStudio.convert(rated_compressor_capacity_btu_per_hr, 'Btu/h', 'W').get).ceil # add compressors (1..number_of_compressors).each do |compressor_number| compressor = OpenstudioStandards::Refrigeration.create_compressor(model, template: template, operation_type: operation_type) compressor.setName("#{ref_system.name} Compressor #{compressor_number}") ref_system.addCompressor(compressor) end OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Added #{number_of_compressors} compressors, each with a capacity of #{rated_compressor_capacity_btu_per_hr.round} Btu/hr to serve #{OpenStudio.convert(rated_capacity_w, 'W', 'Btu/hr').get.round} Btu/hr of case and walkin load.") # Heat rejection as a function of temperature heat_rejection_curve = OpenStudio::Model::CurveLinear.new(model) heat_rejection_curve.setName('Condenser Heat Rejection Function of Temperature') heat_rejection_curve.setCoefficient1Constant(0.0) heat_rejection_curve.setCoefficient2x(22000.0) heat_rejection_curve.setMinimumValueofx(-50.0) heat_rejection_curve.setMaximumValueofx(50.0) # Add condenser condenser = OpenStudio::Model::RefrigerationCondenserAirCooled.new(model) condenser.setRatedEffectiveTotalHeatRejectionRateCurve(heat_rejection_curve) condenser.setRatedSubcoolingTemperatureDifference(OpenStudio.convert(2.0, 'F', 'C').get) condenser.setMinimumFanAirFlowRatio(0.0) condenser.setRatedFanPower(0.04 * rated_capacity_w) condenser.setCondenserFanSpeedControlType('VariableSpeed') ref_system.setRefrigerationCondenser(condenser) return ref_system end |
.create_typical_refrigeration(model, template: 'new', separate_system_size_limit: 0.0) ⇒ Boolean
Adds typical refrigeration to a model
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/openstudio-standards/refrigeration/create_typical_refrigeration.rb', line 13 def self.create_typical_refrigeration(model, template: 'new', separate_system_size_limit: 0.0) # get refrigeration equipment list based on space types and area ref_equip_list = OpenstudioStandards::Refrigeration.typical_refrigeration_equipment_list(model) if ref_equip_list[:cases].empty? && ref_equip_list[:walkins].empty? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', 'The model space types do not typical have refrigeration cases or walkins. No refrigeration system will be added.') return true end # Find the thermal zones most suited for holding the display cases unless ref_equip_list[:cases].empty? thermal_zone_case = OpenstudioStandards::Refrigeration.refrigeration_case_zone(model) if thermal_zone_case.nil? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', 'Attempted to add display cases to the model, but could find no thermal zone to put them into.') return false end end # create cases medium_temperature_cases = [] low_temperature_cases = [] ref_equip_list[:cases].each_with_index do |ref_case, index| case_ = OpenstudioStandards::Refrigeration.create_case(model, template: template, case_type: ref_case[:case_type], case_length: ref_case[:length], defrost_start_hour: index, thermal_zone: thermal_zone_case) if case_. > -3.0 medium_temperature_cases << case_ else low_temperature_cases << case_ end end # Find the thermal zones most suited for holding the walkins unless ref_equip_list[:walkins].empty? thermal_zone_walkin = OpenstudioStandards::Refrigeration.refrigeration_walkin_zone(model) if thermal_zone_walkin.nil? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', 'Attempted to add walkins to the model, but could find no thermal zone to put them into.') return false end end # create walkins medium_temperature_walkins = [] low_temperature_walkins = [] ref_equip_list[:walkins].each_with_index do |walkin, index| ref_walkin = OpenstudioStandards::Refrigeration.create_walkin(model, name: walkin[:walkin_name], template: template, walkin_type: walkin[:walkin_type], defrost_start_hour: index, thermal_zone: thermal_zone_walkin) if ref_walkin. > -3.0 medium_temperature_walkins << ref_walkin else low_temperature_walkins << ref_walkin end end # @todo Disable self-contained refrigeration units until we have efficiency data and cases and walkins can connect to those systems and simulate correctly. # refrigeration_space_type_area = OpenStudio.convert(model.getBuilding.floorArea, 'm^2', 'ft^2').get # if refrigeration_space_type_area < separate_system_size_limit # # each case is self-contained # medium_temperature_cases.each { |ref_equip| OpenstudioStandards::Refrigeration.create_compressor_rack(model, ref_equip, template: template) } # low_temperature_cases.each { |ref_equip| OpenstudioStandards::Refrigeration.create_compressor_rack(model, ref_equip, template: template) } # # each walkin gets its own refrigeration system # medium_temperature_walkins.each { |ref_equip| OpenstudioStandards::Refrigeration.create_refrigeration_system(model, [ref_equip], template: template, operation_type: 'MT') } # low_temperature_walkins.each { |ref_equip| OpenstudioStandards::Refrigeration.create_refrigeration_system(model, [ref_equip], template: template, operation_type: 'LT') } # else medium_temperature_equip = medium_temperature_cases + medium_temperature_walkins OpenstudioStandards::Refrigeration.create_refrigeration_system(model, medium_temperature_equip, template: template, operation_type: 'MT') low_temperature_equip = low_temperature_cases + low_temperature_walkins OpenstudioStandards::Refrigeration.create_refrigeration_system(model, low_temperature_equip, template: template, operation_type: 'LT') # end return true end |
.create_walkin(model, name: nil, template: 'new', walkin_type: 'Walk-in Cooler - 120SF with no glass door', defrost_schedule: nil, defrost_start_hour: 0, dripdown_schedule: nil, thermal_zone: nil) ⇒ OpenStudio::Model::RefrigerationWalkIn
Adds a refrigerated walkin to the model.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/openstudio-standards/refrigeration/create_walkin.rb', line 18 def self.create_walkin(model, name: nil, template: 'new', walkin_type: 'Walk-in Cooler - 120SF with no glass door', defrost_schedule: nil, defrost_start_hour: 0, dripdown_schedule: nil, thermal_zone: nil) # get thermal zone if not provided if thermal_zone.nil? # Find the thermal zones most suited for holding the walkin thermal_zone = OpenstudioStandards::Refrigeration.refrigeration_walkin_zone(model) if thermal_zone.nil? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', 'Attempted to add walkins to the model, but could find no thermal zone to put them into.') return nil end end # load refrigeration walkin data walkins_csv = "#{File.dirname(__FILE__)}/data/refrigerated_walkins.csv" unless File.file?(walkins_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{walkins_csv}") return nil end walkins_tbl = CSV.table(walkins_csv, encoding: 'ISO8859-1:utf-8') walkins_hsh = walkins_tbl.map(&:to_hash) # get walkin properties walkins_properties = walkins_hsh.select { |r| (r[:template] == template) && (r[:walkin_name] == walkin_type) } if walkins_properties.empty? OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find walkin properties for walkin #{template} #{walkin_type}.") return nil end walkins_properties = walkins_properties[0] if name.nil? name = "#{walkin_type} #{template}" end # add walkin ref_walkin = OpenStudio::Model::RefrigerationWalkIn.new(model, model.alwaysOnDiscreteSchedule) ref_walkin.setName(name) ref_walkin.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule) ref_walkin.setRatedCoilCoolingCapacity(walkins_properties[:rated_capacity]) ref_walkin.(walkins_properties[:operating_temperature]) ref_walkin.setRatedCoolingSourceTemperature(walkins_properties[:rated_cooling_source_temperature]) ref_walkin.setRatedTotalHeatingPower(walkins_properties[:rated_total_heating_power]) ref_walkin.setRatedCirculationFanPower(0.0) ref_walkin.setRatedCoolingCoilFanPower(walkins_properties[:rated_cooling_fan_power]) ref_walkin.setRatedTotalLightingPower(walkins_properties[:lighting_power]) ref_walkin.setLightingSchedule(model.alwaysOnDiscreteSchedule) ref_walkin.setDefrostType(walkins_properties[:defrost_type]) ref_walkin.setDefrostControlType(walkins_properties[:defrost_control_type]) ref_walkin.setDefrostPower(walkins_properties[:defrost_power]) ref_walkin.setTemperatureTerminationDefrostFractiontoIce(walkins_properties[:temperature_termination_defrost_fraction_to_ice]) ref_walkin.setInsulatedFloorSurfaceArea(walkins_properties[:insulated_floor_area]) ref_walkin.setInsulatedFloorUValue(walkins_properties[:insulated_floor_uvalue]) ref_walkin.setZoneBoundaryTotalInsulatedSurfaceAreaFacingZone(walkins_properties[:total_insulatedsurface_area_facing_zone]) ref_walkin.setZoneBoundaryInsulatedSurfaceUValueFacingZone(walkins_properties[:insulated_surface_uvalue_facing_zone]) ref_walkin.setZoneBoundaryAreaofGlassReachInDoorsFacingZone(walkins_properties[:area_of_glass_reachin_doors_facing_zone]) ref_walkin.setZoneBoundaryGlassReachInDoorUValueFacingZone(walkins_properties[:reachin_door_uvalue]) unless walkins_properties[:reachin_door_uvalue].nil? ref_walkin.setZoneBoundaryAreaofStockingDoorsFacingZone(walkins_properties[:area_of_stocking_doors_facing_zone]) ref_walkin.setZoneBoundaryHeightofStockingDoorsFacingZone(walkins_properties[:height_of_stocking_doors_facing_zone]) # replace with glass height property when added ref_walkin.setZoneBoundaryHeightofGlassReachInDoorsFacingZone(walkins_properties[:height_of_stocking_doors_facing_zone]) ref_walkin.setZoneBoundaryStockingDoorUValueFacingZone(walkins_properties[:stocking_door_u]) ref_walkin.zoneBoundaries.each { |zb| zb.setStockingDoorOpeningProtectionTypeFacingZone(walkins_properties[:stocking_door_opening_protection]) } ref_walkin.setZoneBoundaryThermalZone(thermal_zone) # only add defrost schedules if not OffCycle unless walkins_properties[:defrost_type] == 'OffCycle' # defrost properties, default to two 45 minute defrost cycles per day followed by a 5 minute dripdown duration defrost_duration = walkins_properties[:defrost_duration].nil? ? 45 : walkins_properties[:defrost_duration] defrosts_per_day = walkins_properties[:defrosts_per_day].nil? ? 2 : walkins_properties[:defrosts_per_day] dripdown_duration = walkins_properties[:dripdown_duration].nil? ? 5 : walkins_properties[:dripdown_duration] # defrost hours are calculated from the start hour and number of defrosts per day defrost_interval = (24 / defrosts_per_day).floor defrost_hours = (1..defrosts_per_day).map { |i| defrost_start_hour + ((i - 1) * defrost_interval) } defrost_hours.map! { |hr| hr > 23 ? hr - 24 : hr } defrost_hours.sort! # Defrost schedule if defrost_schedule.nil? defrost_schedule = OpenStudio::Model::ScheduleRuleset.new(model) defrost_schedule.setName("#{ref_walkin.name} Defrost") defrost_schedule.defaultDaySchedule.setName("#{ref_walkin.name} Defrost Default") defrost_hours.each do |defrost_hour| defrost_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, defrost_hour, 0, 0), 0) defrost_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, defrost_hour, defrost_duration, 0), 1) end defrost_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0) else unless defrost_schedule.to_Schedule.is_initialized OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Input for defrost_schedule #{defrost_schedule} is not a valid OpenStudio::Model::Schedule object") return nil end end ref_walkin.setDefrostSchedule(defrost_schedule) # Dripdown schedule, synced with defrost schedule if dripdown_schedule.nil? dripdown_schedule = OpenStudio::Model::ScheduleRuleset.new(model) dripdown_schedule.setName("#{ref_walkin.name} Dripdown") dripdown_schedule.defaultDaySchedule.setName("#{ref_walkin.name} Dripdown Default") defrost_hours.each do |defrost_hour| dripdown_hour = (defrost_duration + dripdown_duration) > 59 ? defrost_hour + 1 : defrost_hour dripdown_hour = dripdown_hour > 23 ? dripdown_hour - 24 : dripdown_hour dripdown_end_min = (defrost_duration + dripdown_duration) > 59 ? defrost_duration + dripdown_duration - 60 : defrost_duration + dripdown_duration dripdown_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, defrost_hour, defrost_duration, 0), 0) dripdown_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, dripdown_hour, dripdown_end_min, 0), 1) end dripdown_schedule.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0) else unless dripdown_schedule.to_Schedule.is_initialized OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Input for dripdown_schedule #{dripdown_schedule} is not a valid OpenStudio::Model::Schedule object") return nil end end ref_walkin.setDefrostDripDownSchedule(dripdown_schedule) end # stocking schedule # ref_walkin.setRestockingSchedule(model.alwaysOffDiscreteSchedule) ref_walkin.setZoneBoundaryStockingDoorOpeningScheduleFacingZone(model.alwaysOffDiscreteSchedule) insulated_floor_area_ft2 = OpenStudio.convert(walkins_properties[:insulated_floor_area], 'm^2', 'ft^2').get rated_cooling_capacity_btu_per_hr = OpenStudio.convert(walkins_properties[:rated_capacity], 'W', 'Btu/hr').get OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Added #{insulated_floor_area_ft2.round} ft2 walkin called #{walkin_type} with a capacity of #{rated_cooling_capacity_btu_per_hr.round} Btu/hr to #{thermal_zone&.name}.") return ref_walkin end |
.refrigeration_case_zone(model) ⇒ OpenStudio::Model::ThermalZone
Find the thermal zone that is best for adding refrigerated display cases into. First, check for space types that typically have refrigeration. Fall back to largest zone in the model if no typical space types are found.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/openstudio-standards/refrigeration/information.rb', line 13 def self.refrigeration_case_zone(model) # load refrigeration cases data cases_csv = "#{File.dirname(__FILE__)}/data/typical_refrigerated_cases.csv" unless File.file?(cases_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{cases_csv}") return nil end cases_tbl = CSV.table(cases_csv, encoding: 'ISO8859-1:utf-8') cases_hsh = cases_tbl.map(&:to_hash) # Look for one of the space types that would typically have refrigeration display_case_zone = nil display_case_zone_area_m2 = 0.0 model.getThermalZones.each do |zone| space_type = OpenstudioStandards::ThermalZone.thermal_zone_get_space_type(zone) next if space_type.empty? space_type = space_type.get next if space_type.standardsSpaceType.empty? next if space_type.standardsBuildingType.empty? stds_spc_type = space_type.standardsSpaceType.get stds_bldg_type = space_type.standardsBuildingType.get cases = cases_hsh.select { |r| (r[:building_type] == stds_bldg_type) && (r[:space_type] == stds_spc_type) } unless cases.empty? if zone.floorArea > display_case_zone_area_m2 display_case_zone = zone display_case_zone_area_m2 = zone.floorArea end end end unless display_case_zone.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Display case zone is #{display_case_zone.name}, the largest zone with a space type typical for display cases.") return display_case_zone end # If no typical space type was found, choose the largest zone in the model. display_case_zone = nil display_case_zone_area_m2 = 0 model.getThermalZones.each do |zone| if zone.floorArea > display_case_zone_area_m2 display_case_zone = zone display_case_zone_area_m2 = zone.floorArea end end unless display_case_zone.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "No space types typical for display cases were found, so the display cases will be placed in #{display_case_zone.name}, the largest zone.") return display_case_zone end return display_case_zone end |
.refrigeration_walkin_zone(model) ⇒ OpenStudio::Model::ThermalZone
Find the thermal zone that is best for adding refrigerated walkins into. First, check for space types that typically have refrigeration. Fall back to largest zone in the model if no typical space types are found.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/openstudio-standards/refrigeration/information.rb', line 74 def self.refrigeration_walkin_zone(model) # load refrigeration walkin data walkins_csv = "#{File.dirname(__FILE__)}/data/typical_refrigerated_walkins.csv" unless File.file?(walkins_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{walkins_csv}") return nil end walkins_tbl = CSV.table(walkins_csv, encoding: 'ISO8859-1:utf-8') walkins_hsh = walkins_tbl.map(&:to_hash) # Look for one of the space types that would typically have walkins walkin_zone = nil walkin_zone_area_m2 = 0.0 model.getThermalZones.each do |zone| space_type = OpenstudioStandards::ThermalZone.thermal_zone_get_space_type(zone) next if space_type.empty? space_type = space_type.get next if space_type.standardsSpaceType.empty? next if space_type.standardsBuildingType.empty? stds_spc_type = space_type.standardsSpaceType.get stds_bldg_type = space_type.standardsBuildingType.get walkins = walkins_hsh.select { |r| (r[:building_type] == stds_bldg_type) && (r[:space_type] == stds_spc_type) } unless walkins.empty? if zone.floorArea > walkin_zone_area_m2 walkin_zone = zone walkin_zone_area_m2 = zone.floorArea end end end unless walkin_zone.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "Walkin zone is #{walkin_zone.name}, the largest zone with a space type typical for walkins.") return walkin_zone end # If no typical space type was found, # choose the largest zone in the model. walkin_zone = nil walkin_zone_area_m2 = 0 model.getThermalZones.each do |zone| if zone.floorArea > walkin_zone_area_m2 walkin_zone = zone walkin_zone_area_m2 = zone.floorArea end end unless walkin_zone.nil? OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Refrigeration', "No space types typical for walkins were found, so the walkins will be placed in #{walkin_zone.name}, the largest zone.") return walkin_zone end return walkin_zone end |
.typical_refrigeration_equipment_list(model) ⇒ Hash
Returns the typical refrigeration equipment in a model based on space types
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/openstudio-standards/refrigeration/create_typical_refrigeration.rb', line 104 def self.typical_refrigeration_equipment_list(model) # load refrigeration cases data cases_csv = "#{File.dirname(__FILE__)}/data/typical_refrigerated_cases.csv" unless File.file?(cases_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{cases_csv}") return false end cases_tbl = CSV.table(cases_csv, encoding: 'ISO8859-1:utf-8') cases_hsh = cases_tbl.map(&:to_hash) # load refrigeration walkin data walkins_csv = "#{File.dirname(__FILE__)}/data/typical_refrigerated_walkins.csv" unless File.file?(walkins_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Refrigeration', "Unable to find file: #{walkins_csv}") return false end walkins_tbl = CSV.table(walkins_csv, encoding: 'ISO8859-1:utf-8') walkins_hsh = walkins_tbl.map(&:to_hash) # loop through space types to get collection of cases and walkins cases_list = [] walkins_list = [] model.getSpaceTypes.sort.each do |space_type| total_space_floor_area_m2 = space_type.floorArea total_space_floor_area_ft2 = OpenStudio.convert(total_space_floor_area_m2, 'm^2', 'ft^2').get next unless space_type.standardsSpaceType.is_initialized next unless space_type.standardsBuildingType.is_initialized standards_space_type = space_type.standardsSpaceType.get standards_building_type = space_type.standardsBuildingType.get # create list of cases ref_cases = cases_hsh.select { |hash| (hash[:space_type] == standards_space_type) && (hash[:building_type] == standards_building_type) } ref_cases.each do |ref_case| length_modifier = total_space_floor_area_ft2 / ref_case[:reference_space_type_area_ft2] case_length = OpenStudio.convert(ref_case[:length_ft] * length_modifier, 'ft', 'm').get cases_list << { case_type: ref_case[:case_type], length: case_length } end # create list of walkins ref_walkins = walkins_hsh.select { |hash| (hash[:space_type] == standards_space_type) && (hash[:building_type] == standards_building_type) } ref_walkins.each do |ref_walkin| area_modifier = total_space_floor_area_ft2 / ref_walkin[:reference_space_type_area_ft2] # round to the nearest 120 ft2, with a minimum size of 80 ft2 and maximum size of 480 ft2 walkin_size_ft2 = (120.0 * ((ref_walkin[:size_ft2] * area_modifier) / 120.0).round).clamp(80.0, 480.0).to_int walkin_lookup_name = "#{ref_walkin[:walkin_type]} - #{walkin_size_ft2}SF" walkin_lookup_name = "#{walkin_lookup_name} with no glass door" if walkin_lookup_name.include? 'Cooler' walkins_list << { walkin_name: ref_walkin[:walkin_name], walkin_type: walkin_lookup_name } end end equipment_list = { cases: cases_list, walkins: walkins_list } return equipment_list end |