Top Level Namespace

Defined Under Namespace

Modules: BTAP, CoilDX, CoolingTower, EnergyPlus, Fan, OpenstudioStandards, OsLib_Schedules, PrototypeBuilding, PrototypeFan, Pump Classes: FalseClass, Fixnum, Hash, NilClass, OSMArg, String, TrueClass, Utilities, Vintagizer

Instance Method Summary collapse

Instance Method Details

#adjust_infiltration_to_lower_pressure(initial_infiltration_rate_m3_per_s, intial_pressure_pa, final_pressure_pa, infiltration_coefficient = 0.65) ⇒ Object

Convert one infiltration rate at a given pressure to an infiltration rate at another pressure per method described here: www.taskair.net/knowledge/Infiltration%20Modeling%20Guidelines%20for%20Commercial%20Building%20Energy%20Analysis.pdf where the infiltration coefficient is 0.65

Parameters:

  • initial_infiltration_rate_m3_per_s (Double)

    initial infiltration rate in m^3/s

  • intial_pressure_pa (Double)

    pressure rise at which initial infiltration rate was determined in Pa

  • final_pressure_pa (Double)

    desired pressure rise to adjust infiltration rate to in Pa

  • infiltration_coefficient (Double) (defaults to: 0.65)

    infiltration coeffiecient



279
280
281
282
283
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 279

def adjust_infiltration_to_lower_pressure(initial_infiltration_rate_m3_per_s, intial_pressure_pa, final_pressure_pa, infiltration_coefficient = 0.65)
  adjusted_infiltration_rate_m3_per_s = initial_infiltration_rate_m3_per_s * (final_pressure_pa / intial_pressure_pa)**infiltration_coefficient

  return adjusted_infiltration_rate_m3_per_s
end

#adjust_infiltration_to_prototype_building_conditions(initial_infiltration_rate_m3_per_s) ⇒ Double

Convert the infiltration rate at a 75 Pa to an infiltration rate at the typical value for the prototype buildings per method described here: www.taskair.net/knowledge/Infiltration%20Modeling%20Guidelines%20for%20Commercial%20Building%20Energy%20Analysis.pdf

Parameters:

  • initial_infiltration_rate_m3_per_s (Double)

    initial infiltration rate in m^3/s

Returns:

  • (Double)


291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 291

def adjust_infiltration_to_prototype_building_conditions(initial_infiltration_rate_m3_per_s)
  # Details of these coefficients can be found in paper
  alpha = 0.22 # unitless - terrain adjustment factor
  intial_pressure_pa = 75.0 # 75 Pa
  uh = 4.47 # m/s - wind speed
  rho = 1.18 # kg/m^3 - air density
  cs = 0.1617 # unitless - positive surface pressure coefficient
  n = 0.65 # unitless - infiltration coefficient

  # Calculate the typical pressure - same for all building types
  final_pressure_pa = 0.5 * cs * rho * uh**2

  # OpenStudio::logFree(OpenStudio::Debug, "openstudio.Standards.Space", "Final pressure PA = #{final_pressure_pa.round(3)} Pa.")

  adjusted_infiltration_rate_m3_per_s = (1.0 + alpha) * initial_infiltration_rate_m3_per_s * (final_pressure_pa / intial_pressure_pa)**n

  return adjusted_infiltration_rate_m3_per_s
end

#afue_to_thermal_eff(afue) ⇒ Double

A helper method to convert from AFUE to thermal efficiency

Parameters:

  • afue (Double)

    Annual Fuel Utilization Efficiency

Returns:

  • (Double)

    Thermal efficiency (%)



242
243
244
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 242

def afue_to_thermal_eff(afue)
  return afue # Per PNNL doc, Boiler Addendum 90.1-04an
end

#combustion_eff_to_thermal_eff(combustion_eff) ⇒ Double

A helper method to convert from combustion efficiency to thermal efficiency

Parameters:

  • combustion_eff (Double)

    Combustion efficiency (%)

Returns:

  • (Double)

    Thermal efficiency (%)



258
259
260
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 258

def combustion_eff_to_thermal_eff(combustion_eff)
  return combustion_eff - 0.007 # Per PNNL doc, Boiler Addendum 90.1-04an
end

#cop_heating_to_cop_heating_no_fan(coph47, capacity_w) ⇒ Double

Convert from COP_H to COP (no fan) for heat pump heating coils per the method specified in 90.1-2013 Appendix G

Parameters:

  • coph47 (Double)

    coefficient of performance at 47F Tdb, 42F Twb

  • capacity_w (Double)

    the heating capacity at AHRI rating conditions, in W

Returns:

  • (Double)

    Coefficient of Performance (COP)



120
121
122
123
124
125
126
127
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 120

def cop_heating_to_cop_heating_no_fan(coph47, capacity_w)
  # Convert the capacity to Btu/hr
  capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get

  cop = 1.48E-7 * coph47 * capacity_btu_per_hr + 1.062 * coph47

  return cop
end

#cop_to_eer(cop, capacity_w = nil) ⇒ Double

Convert from COP to EER per the method specified in “Achieving the 30% Goal: Energy and cost savings analysis of ASHRAE Standard 90.1-2010 Thornton, et al 2011

Parameters:

  • COP (Double)

Returns:

  • (Double)

    Energy Efficiency Ratio (EER)



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 199

def cop_to_eer(cop, capacity_w = nil)
  eer = nil

  if capacity_w.nil?
    # The PNNL Method.
    # r is the ratio of supply fan power to total equipment power at the rating condition,
    # assumed to be 0.12 for the reference buildngs per PNNL.
    r = 0.12

    eer = 3.413 * (cop * (1 - r) - r)

  else

    # The 90.1-2013 method

    # Convert the capacity to Btu/hr
    capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
    eer = cop / (7.84E-8 * capacity_btu_per_hr + 0.338)
  end

  return eer
end

#cop_to_kw_per_ton(cop) ⇒ Double

Convert from COP to kW/ton

Parameters:

  • cop (Double)

    Coefficient of Performance (COP)

Returns:

  • (Double)

    kW of input power per ton of cooling



226
227
228
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 226

def cop_to_kw_per_ton(cop)
  return 3.517 / cop
end

#cop_to_seer(cop) ⇒ Double

Convert from COP to SEER per the method specified in “Achieving the 30% Goal: Energy and cost savings analysis of ASHRAE Standard 90.1-2010 Thornton, et al 2011

Parameters:

  • COP (Double)

Returns:

  • (Double)

    Seasonal Energy Efficiency Ratio



147
148
149
150
151
152
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 147

def cop_to_seer(cop)
  delta = 0.3796**2 - 4.0 * 0.0076 * cop
  seer = (-delta**0.5 + 0.3796) / (2.0 * 0.0076)

  return seer
end

#eer_to_cop(eer, capacity_w = nil) ⇒ Double

Convert from EER to COP If capacity is not supplied, use the method specified in “Achieving the 30% Goal: Energy and cost savings analysis of ASHRAE Standard 90.1-2010 Thornton, et al 2011. If capacity is supplied, use the method specified in 90.1-2013.

Parameters:

  • eer (Double)

    Energy Efficiency Ratio (EER)

  • capacity_w (Double) (defaults to: nil)

    the heating capacity at AHRI rating conditions, in W

Returns:

  • (Double)

    Coefficient of Performance (COP)



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 165

def eer_to_cop(eer, capacity_w = nil)
  cop = nil

  if capacity_w.nil?

    # The PNNL Method.

    # r is the ratio of supply fan power to total equipment power at the rating condition,
    # assumed to be 0.12 for the reference buildngs per PNNL.
    r = 0.12

    cop = (eer / 3.413 + r) / (1 - r)

  else

    # The 90.1-2013 method

    # Convert the capacity to Btu/hr
    capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get

    cop = 7.84E-8 * eer * capacity_btu_per_hr + 0.338 * eer

  end

  return cop
end

#get_logs(log_type = OpenStudio::Error) ⇒ Object

Get an array of all messages of a given type in the log



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/openstudio-standards/utilities/logging.rb', line 83

def get_logs(log_type = OpenStudio::Error)
  errors = []

  $OPENSTUDIO_LOG.logMessages.each do |msg|
    if /openstudio.*/ =~ msg.logChannel
      # Skip certain messages that are irrelevant/misleading
      next if msg.logMessage.include?('Skipping layer') || # Annoying/bogus "Skipping layer" warnings
              msg.logChannel.include?('runmanager') || # RunManager messages
              msg.logChannel.include?('setFileExtension') || # .ddy extension unexpected
              msg.logChannel.include?('Translator') || # Forward translator and geometry translator
              msg.logMessage.include?('UseWeatherFile') || # 'UseWeatherFile' is not yet a supported option for YearDescription
              msg.logMessage.include?('Successive data points') || # Successive data points (2004-Jan-31 to 2001-Feb-01, ending on line 753) are greater than 1 day apart in EPW file
              msg.logMessage.include?('has multiple parents') # Bogus errors about curves having multiple parents
      # Only fail on the errors
      if msg.logLevel == log_type
        errors << "[#{msg.logChannel}] #{msg.logMessage}"
      end
    end
  end

  return errors
end

#hspf_to_cop_heating_no_fan(hspf) ⇒ Double

Convert from HSPF to COP (no fan) for heat pump heating coils per the method specified in 90.1-2013 Appendix G

Parameters:

  • hspf (Double)

    heating seasonal performance factor (HSPF)

Returns:

  • (Double)

    Coefficient of Performance (COP)



134
135
136
137
138
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 134

def hspf_to_cop_heating_no_fan(hspf)
  cop = -0.0296 * hspf * hspf + 0.7134 * hspf

  return cop
end

#kw_per_ton_to_cop(kw_per_ton) ⇒ Double

A helper method to convert from kW/ton to COP

Parameters:

  • kw_per_ton (Double)

    kW of input power per ton of cooling

Returns:

  • (Double)

    Coefficient of Performance (COP)



234
235
236
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 234

def kw_per_ton_to_cop(kw_per_ton)
  return 3.517 / kw_per_ton
end

#load_openstudio_standards_jsonHash

Loads the openstudio standards dataset.

Returns:

  • (Hash)

    a hash of standards data



5
6
7
8
9
10
11
12
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
# File 'lib/openstudio-standards/standards/Standards.Model.rb', line 5

def load_openstudio_standards_json
  standards_files = []
  standards_files << 'OpenStudio_Standards_boilers.json'
  standards_files << 'OpenStudio_Standards_chillers.json'
  standards_files << 'OpenStudio_Standards_climate_zone_sets.json'
  standards_files << 'OpenStudio_Standards_climate_zones.json'
  standards_files << 'OpenStudio_Standards_construction_properties.json'
  standards_files << 'OpenStudio_Standards_construction_sets.json'
  standards_files << 'OpenStudio_Standards_constructions.json'
  standards_files << 'OpenStudio_Standards_curve_bicubics.json'
  standards_files << 'OpenStudio_Standards_curve_biquadratics.json'
  standards_files << 'OpenStudio_Standards_curve_cubics.json'
  standards_files << 'OpenStudio_Standards_curve_quadratics.json'
  standards_files << 'OpenStudio_Standards_ground_temperatures.json'
  standards_files << 'OpenStudio_Standards_heat_pumps_heating.json'
  standards_files << 'OpenStudio_Standards_heat_pumps.json'
  standards_files << 'OpenStudio_Standards_materials.json'
  standards_files << 'OpenStudio_Standards_motors.json'
  standards_files << 'OpenStudio_Standards_prototype_inputs.json'
  standards_files << 'OpenStudio_Standards_schedules.json'
  standards_files << 'OpenStudio_Standards_space_types.json'
  standards_files << 'OpenStudio_Standards_templates.json'
  standards_files << 'OpenStudio_Standards_unitary_acs.json'
  standards_files << 'OpenStudio_Standards_heat_rejection.json'
  #    standards_files << 'OpenStudio_Standards_unitary_hps.json'

  # Combine the data from the JSON files into a single hash
  top_dir = File.expand_path('../../..', File.dirname(__FILE__))
  standards_data_dir = "#{top_dir}/data/standards"
  standards_data = {}
  standards_files.sort.each do |standards_file|
    temp = ""
    begin
      temp = load_resource_relative("../../../data/standards/#{standards_file}", 'r:UTF-8')
    rescue NoMethodError 
      File.open("#{standards_data_dir}/#{standards_file}", 'r:UTF-8') do |f|
        temp = f.read
      end
    end
    file_hash = JSON.load(temp)
    standards_data = standards_data.merge(file_hash)
  end

  # Check that standards data was loaded
  if standards_data.keys.size.zero?
    OpenStudio.logFree(OpenStudio::Error, 'OpenStudio Standards JSON data was not loaded correctly.')
  end

  return standards_data
end

#log_messages_to_file(file_path, debug = false) ⇒ Array<String>

Log the info, warning, and error messages to a file. runner @param [file_path] The path to the log file debug @param [Boolean] If true, include the debug messages in the log

Returns:

  • (Array<String>)

    The array of messages, which can be used elsewhere.



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
# File 'lib/openstudio-standards/utilities/logging.rb', line 41

def log_messages_to_file(file_path, debug = false)
  messages = []

  File.open(file_path, 'w') do |file|
    $OPENSTUDIO_LOG.logMessages.each do |msg|
      # DLM: you can filter on log channel here for now
      if /openstudio.*/ =~ msg.logChannel # /openstudio\.model\..*/
        # Skip certain messages that are irrelevant/misleading
        next if msg.logMessage.include?('Skipping layer') || # Annoying/bogus "Skipping layer" warnings
                msg.logChannel.include?('runmanager') || # RunManager messages
                msg.logChannel.include?('setFileExtension') || # .ddy extension unexpected
                msg.logChannel.include?('Translator') || # Forward translator and geometry translator
                msg.logMessage.include?('UseWeatherFile') || # 'UseWeatherFile' is not yet a supported option for YearDescription
                msg.logMessage.include?('Successive data points') || # Successive data points (2004-Jan-31 to 2001-Feb-01, ending on line 753) are greater than 1 day apart in EPW file
                msg.logMessage.include?('has multiple parents') # Bogus errors about curves having multiple parents

        # Report the message in the correct way
        if msg.logLevel == OpenStudio::Info
          s = "INFO  #{msg.logMessage}"
          file.puts(s)
          messages << s
        elsif msg.logLevel == OpenStudio::Warn
          s = "WARN  #{msg.logMessage}"
          file.puts(s)
          messages << s
        elsif msg.logLevel == OpenStudio::Error
          s = "ERROR #{msg.logMessage}"
          file.puts(s)
          messages << s
        elsif msg.logLevel == OpenStudio::Debug && debug
          s = "DEBUG #{msg.logMessage}"
          file.puts(s)
          messages << s
        end
      end
    end
  end

  return messages
end

#log_messages_to_runner(runner, debug = false) ⇒ Runner

Log the info, warning, and error messages to a runner. runner @param [Runner] The Measure runner to add the messages to debug @param [Boolean] If true, include the debug messages in the log

Returns:

  • (Runner)

    The same Measure runner, with messages from the openstudio-standards library added



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/openstudio-standards/utilities/logging.rb', line 10

def log_messages_to_runner(runner, debug = false)
  $OPENSTUDIO_LOG.logMessages.each do |msg|
    # DLM: you can filter on log channel here for now
    if /openstudio.*/ =~ msg.logChannel # /openstudio\.model\..*/
      # Skip certain messages that are irrelevant/misleading
      next if msg.logMessage.include?('Skipping layer') || # Annoying/bogus "Skipping layer" warnings
              msg.logChannel.include?('runmanager') || # RunManager messages
              msg.logChannel.include?('setFileExtension') || # .ddy extension unexpected
              msg.logChannel.include?('Translator') || # Forward translator and geometry translator
              msg.logMessage.include?('UseWeatherFile') || # 'UseWeatherFile' is not yet a supported option for YearDescription
              msg.logMessage.include?('Successive data points') || # Successive data points (2004-Jan-31 to 2001-Feb-01, ending on line 753) are greater than 1 day apart in EPW file
              msg.logMessage.include?('has multiple parents') # Bogus errors about curves having multiple parents

      # Report the message in the correct way
      if msg.logLevel == OpenStudio::Info
        runner.registerInfo(msg.logMessage)
      elsif msg.logLevel == OpenStudio::Warn
        runner.registerWarning("[#{msg.logChannel}] #{msg.logMessage}")
      elsif msg.logLevel == OpenStudio::Error
        runner.registerError("[#{msg.logChannel}] #{msg.logMessage}")
      elsif msg.logLevel == OpenStudio::Debug && debug
        runner.registerInfo("DEBUG - #{msg.logMessage}")
      end
    end
  end
end

#reset_logObject



106
107
108
# File 'lib/openstudio-standards/utilities/logging.rb', line 106

def reset_log
  $OPENSTUDIO_LOG.resetStringStream
end

#safe_load_model(model_path_string) ⇒ Object

load a model into OS & version translates, exiting and erroring if a problem is found



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 3

def safe_load_model(model_path_string)
  model_path = OpenStudio::Path.new(model_path_string)
  if OpenStudio.exists(model_path)
    version_translator = OpenStudio::OSVersion::VersionTranslator.new
    model = version_translator.loadModel(model_path)
    if model.empty?
      OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Version translation failed for #{model_path_string}")
      return false
    else
      model = model.get
    end
  else
    OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "#{model_path_string} couldn't be found")
    return false
  end
  return model
end

#safe_load_sql(sql_path_string) ⇒ Object

load a sql file, exiting and erroring if a problem is found



22
23
24
25
26
27
28
29
30
31
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 22

def safe_load_sql(sql_path_string)
  sql_path = OpenStudio::Path.new(sql_path_string)
  if OpenStudio.exists(sql_path)
    sql = OpenStudio::SqlFile.new(sql_path)
  else
    OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "#{sql_path} couldn't be found")
    return false
  end
  return sql
end

#seer_to_cop_cooling_no_fan(seer) ⇒ Double

Convert from SEER to COP (no fan) for cooling coils per the method specified in 90.1-2013 Appendix G

Parameters:

  • seer (Double)

    seasonal energy efficiency ratio (SEER)

Returns:

  • (Double)

    Coefficient of Performance (COP)



108
109
110
111
112
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 108

def seer_to_cop_cooling_no_fan(seer)
  cop = -0.0076 * seer * seer + 0.3796 * seer

  return cop
end

#strip_model(model) ⇒ Object



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
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 33

def strip_model(model)
  # remove all materials
  model.getMaterials.each(&:remove)

  # remove all constructions
  model.getConstructions.each(&:remove)

  # remove performance curves
  model.getCurves.each(&:remove)

  # remove all zone equipment
  model.getThermalZones.each do |zone|
    zone.equipment.each(&:remove)
  end

  # remove all thermostats
  model.getThermostatSetpointDualSetpoints.each(&:remove)

  # remove all people
  model.getPeoples.each(&:remove)
  model.getPeopleDefinitions.each(&:remove)

  # remove all lights
  model.getLightss.each(&:remove)
  model.getLightsDefinitions.each(&:remove)

  # remove all electric equipment
  model.getElectricEquipments.each(&:remove)
  model.getElectricEquipmentDefinitions.each(&:remove)

  # remove all gas equipment
  model.getGasEquipments.each(&:remove)
  model.getGasEquipmentDefinitions.each(&:remove)

  # remove all outdoor air
  model.getDesignSpecificationOutdoorAirs.each(&:remove)

  # remove all infiltration
  model.getSpaceInfiltrationDesignFlowRates.each(&:remove)

  # Remove all internal mass
  model.getInternalMasss.each(&:remove)

  # Remove all internal mass defs
  model.getInternalMassDefinitions.each(&:remove)

  # Remove all thermal zones
  model.getThermalZones.each(&:remove)

  # Remove all schedules
  model.getSchedules.each(&:remove)

  # Remove all schedule type limits
  model.getScheduleTypeLimitss.each(&:remove)

  # Remove the sizing parameters
  model.getSizingParameters.remove

  # Remove the design days
  model.getDesignDays.each(&:remove)

  # Remove the rendering colors
  model.getRenderingColors.each(&:remove)

  # Remove the daylight controls
  model.getDaylightingControls.each(&:remove)

  return model
end

#thermal_eff_to_afue(teff) ⇒ Double

A helper method to convert from thermal efficiency to AFUE

Parameters:

  • teff (Double)

    Thermal Efficiency

Returns:

  • (Double)

    AFUE



250
251
252
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 250

def thermal_eff_to_afue(teff)
  return teff # Per PNNL doc, Boiler Addendum 90.1-04an
end

#thermal_eff_to_comb_eff(teff) ⇒ Double

A helper method to convert from thermal efficiency to combustion efficiency

Parameters:

  • combustion_eff (Double)

    Thermal efficiency

Returns:

  • (Double)

    Thermal efficiency



266
267
268
# File 'lib/openstudio-standards/prototypes/Prototype.utilities.rb', line 266

def thermal_eff_to_comb_eff(teff)
  return teff + 0.007 # Per PNNL doc, Boiler Addendum 90.1-04an
end