lib/openstudio-standards/standards/Standards.Construction.rb in openstudio-standards-0.1.4 vs lib/openstudio-standards/standards/Standards.Construction.rb in openstudio-standards-0.1.5
- old
+ new
@@ -1,77 +1,73 @@
# Reopen the OpenStudio class to add methods to apply standards to this object
class OpenStudio::Model::Construction
-
# Sets the U-value of a construction to a specified value
# by modifying the thickness of the insulation layer.
#
# @param target_u_value_ip [Double] U-Value (Btu/ft^2*hr*R)
# @param insulation_layer_name [String] The name of the insulation layer in this construction
- # @param intended_surface_type [String]
- # Valid choices: 'AtticFloor', 'AtticWall', 'AtticRoof', 'DemisingFloor', 'InteriorFloor', 'InteriorCeiling',
+ # @param intended_surface_type [String]
+ # Valid choices: 'AtticFloor', 'AtticWall', 'AtticRoof', 'DemisingFloor', 'InteriorFloor', 'InteriorCeiling',
# 'DemisingWall', 'InteriorWall', 'InteriorPartition', 'InteriorWindow', 'InteriorDoor', 'DemisingRoof',
- # 'ExteriorRoof', 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser', 'ExteriorFloor',
+ # 'ExteriorRoof', 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser', 'ExteriorFloor',
# 'ExteriorWall', 'ExteriorWindow', 'ExteriorDoor', 'GlassDoor', 'OverheadDoor', 'GroundContactFloor',
# 'GroundContactWall', 'GroundContactRoof'
# @param target_includes_film_coefficients [Bool] if true, subtracts off standard film coefficients from your
- # target_u_value before modifying insulation thickness. Film values from 90.1-2010 A9.4.1 Air Films
+ # target_u_value before modifying insulation thickness. Film values from 90.1-2010 A9.4.1 Air Films
# @return [Bool] returns true if successful, false if not
# @todo Put in Phlyroy's logic for inferring the insulation layer of a construction
- def set_u_value(target_u_value_ip, insulation_layer_name = nil, intended_surface_type = 'ExteriorWall', target_includes_film_coefficients = true)
-
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "Setting U-Value for #{self.name}.")
-
+ def set_u_value(target_u_value_ip, insulation_layer_name = nil, intended_surface_type = 'ExteriorWall', target_includes_film_coefficients = true)
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "Setting U-Value for #{name}.")
+
# Skip fenestration constructions
- if self.isFenestration
- OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.ConstructionBase', "Can only set the u-value of opaque constructions. #{self.name} is not opaque.")
+ if isFenestration
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.ConstructionBase', "Can only set the u-value of opaque constructions. #{name} is not opaque.")
return false
end
-
+
# Make sure an insulation layer was specified
if insulation_layer_name.nil? && target_u_value_ip == 0.0
# Do nothing if the construction already doesn't have an insulation layer
elsif insulation_layer_name.nil?
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.ConstructionBase', "Requested U-value of #{target_u_value_ip} for #{self.name}, but this construction has no insulation layer specified. Requested U-value will not be set.")
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.ConstructionBase', "Requested U-value of #{target_u_value_ip} for #{name}, but this construction has no insulation layer specified. Requested U-value will not be set.")
return false
- else
- # TODO put in Phlyroy's logic for inferring the insulation layer of a construction
- end
-
- # Remove the insulation layer if the specified U-value is zero.
+ end
+
+ # Remove the insulation layer if the specified U-value is zero.
if target_u_value_ip == 0.0
layer_index = 0
- self.layers.each do |layer|
+ layers.each do |layer|
break if layer.name.get == insulation_layer_name
layer_index += 1
end
- self.eraseLayer(layer_index)
+ eraseLayer(layer_index)
return true
end
-
+
# Convert the target U-value to SI
target_u_value_ip = target_u_value_ip.to_f
- target_r_value_ip = 1.0/target_u_value_ip
-
+ target_r_value_ip = 1.0 / target_u_value_ip
+
target_u_value_si = OpenStudio.convert(target_u_value_ip, 'Btu/ft^2*hr*R', 'W/m^2*K').get
- target_r_value_si = 1.0/target_u_value_si
-
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "#{self.name}.")
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_u_value_ip = #{target_u_value_ip.round(3)} for #{self.name}.")
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_r_value_ip = #{target_r_value_ip.round(2)} for #{self.name}.")
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_u_value_si = #{target_u_value_si.round(3)} for #{self.name}.")
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_r_value_si = #{target_r_value_si.round(2)} for #{self.name}.")
-
+ target_r_value_si = 1.0 / target_u_value_si
+
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "#{name}.")
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_u_value_ip = #{target_u_value_ip.round(3)} for #{name}.")
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_r_value_ip = #{target_r_value_ip.round(2)} for #{name}.")
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_u_value_si = #{target_u_value_si.round(3)} for #{name}.")
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.ConstructionBase', "---target_r_value_si = #{target_r_value_si.round(2)} for #{name}.")
+
# Determine the R-value of the non-insulation layers
other_layer_r_value_si = 0.0
- self.layers.each do |layer|
+ layers.each do |layer|
next if layer.to_OpaqueMaterial.empty?
next if layer.name.get == insulation_layer_name
other_layer_r_value_si += layer.to_OpaqueMaterial.get.thermalResistance
end
- # todo - remove code below and use film_coefficients_u_value method instead
+ # TODO: - remove code below and use film_coefficients_u_value method instead
# Determine the R-value of the air films, if requested
# Film values from 90.1-2010 A9.4.1 Air Films
if target_includes_film_coefficients
film_ext_surf_r_ip = 0.17
film_semi_ext_surf_r_ip = 0.46
@@ -122,17 +118,17 @@
# Determine the difference between the desired R-value
# and the R-value of the non-insulation layers and air films.
# This is the desired R-value of the insulation.
ins_r_value_si = target_r_value_si - other_layer_r_value_si
if ins_r_value_si <= 0.0
- OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.ConstructionBase', "Requested U-value of #{target_u_value_ip} for #{self.name} is too low given the other materials in the construction; insulation layer will not be modified.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.ConstructionBase', "Requested U-value of #{target_u_value_ip} for #{name} is too low given the other materials in the construction; insulation layer will not be modified.")
return false
end
ins_r_value_ip = OpenStudio.convert(ins_r_value_si, 'm^2*K/W', 'ft^2*h*R/Btu').get
-
+
# Set the R-value of the insulation layer
- self.layers.each do |layer|
+ layers.each do |layer|
next unless layer.name.get == insulation_layer_name
if layer.to_StandardOpaqueMaterial.is_initialized
layer = layer.to_StandardOpaqueMaterial.get
layer.setThickness(ins_r_value_si * layer.getConductivity)
layer.setName("#{layer.name} R-#{ins_r_value_ip.round(2)}")
@@ -148,73 +144,70 @@
layer.setThickness(target_thickness)
layer.setName("#{layer.name} R-#{ins_r_value_ip.round(2)}")
break # Stop looking for the insulation layer once found
end
end
-
+
# Modify the construction name
- self.setName("#{self.name} R-#{target_r_value_ip.round(2)}")
-
+ setName("#{name} R-#{target_r_value_ip.round(2)}")
+
return true
-
end
# Set the F-Factor of a slab to a specified value.
# Assumes an unheated, fully insulated slab, and modifies
- # the insulation layer according to the values from 90.1-2004
+ # the insulation layer according to the values from 90.1-2004
# Table A6.3 Assembly F-Factors for Slab-on-Grade Floors.
#
# @param target_f_factor_ip [Double] F-Factor
# @param insulation_layer_name [String] The name of the insulation layer in this construction
# @return [Bool] returns true if successful, false if not
def set_slab_f_factor(target_f_factor_ip, insulation_layer_name = nil)
-
# Regression from table A6.3 unheated, fully insulated slab
r_value_ip = 1.0248 * target_f_factor_ip**-2.186
- u_value_ip = 1.0/r_value_ip
-
+ u_value_ip = 1.0 / r_value_ip
+
# Set the insulation U-value
set_u_value(u_value_ip, insulation_layer_name, 'GroundContactFloor', true)
-
+
# Modify the construction name
- self.setName("#{self.name} F-#{target_f_factor_ip.round(3)}")
-
+ setName("#{name} F-#{target_f_factor_ip.round(3)}")
+
return true
-
end
# Set the C-Factor of an underground wall to a specified value.
# Assumes continuous exterior insulation and modifies
- # the insulation layer according to the values from 90.1-2004
+ # the insulation layer according to the values from 90.1-2004
# Table A4.2 Assembly C-Factors for Below-Grade walls.
#
# @param target_c_factor_ip [Double] C-Factor
# @param insulation_layer_name [String] The name of the insulation layer in this construction
# @return [Bool] returns true if successful, false if not
def set_underground_wall_c_factor(target_c_factor_ip, insulation_layer_name = nil)
-
# Regression from table A4.2 continuous exterior insulation
r_value_ip = 0.775 * target_c_factor_ip**-1.067
- u_value_ip = 1.0/r_value_ip
-
+ u_value_ip = 1.0 / r_value_ip
+
# Set the insulation U-value
set_u_value(u_value_ip, insulation_layer_name, 'GroundContactWall', true)
-
+
# Modify the construction name
- self.setName("#{self.name} C-#{target_c_factor_ip.round(3)}")
-
+ setName("#{name} C-#{target_c_factor_ip.round(3)}")
+
return true
-
end
+ # Get the SHGC as calculated by EnergyPlus.
+ # Only applies to fenestration constructions.
+ # @return [Double] the SHGC as a decimal.
def calculated_solar_heat_gain_coefficient
+ construction_name = name.get.to_s
- construction_name = self.name.get.to_s
-
shgc = nil
- sql = self.model.sqlFile
+ sql = model.sqlFile
if sql.is_initialized
sql = sql.get
row_query = "SELECT RowName
@@ -227,11 +220,11 @@
row_id = sql.execAndReturnFirstString(row_query)
if row_id.is_initialized
row_id = row_id.get
else
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "SHGC row ID not found for construction: #{construction_name}.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "SHGC row ID not found for construction: #{construction_name}.")
row_id = 9999
end
shgc_query = "SELECT Value
FROM tabulardatawithstrings
@@ -239,36 +232,32 @@
AND ReportForString='Entire Facility'
AND TableName='Exterior Fenestration'
AND ColumnName='Glass SHGC'
AND RowName='#{row_id}'"
-
shgc = sql.execAndReturnFirstDouble(shgc_query)
- if shgc.is_initialized
- shgc = shgc.get
- else
- shgc = nil
- end
+ shgc = if shgc.is_initialized
+ shgc.get
+ end
else
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Construction', 'Model has no sql file containing results, cannot lookup data.')
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Construction', 'Model has no sql file containing results, cannot lookup data.')
end
return shgc
-
end
- # Get the VT as calculated by EnergyPlus
- #
+ # Get the VT as calculated by EnergyPlus.
+ # Only applies to fenestration constructions.
+ # @return [Double] the visible transmittance as a decimal.
def calculated_visible_transmittance
+ construction_name = name.get.to_s
- construction_name = self.name.get.to_s
-
vt = nil
- sql = self.model.sqlFile
+ sql = model.sqlFile
if sql.is_initialized
sql = sql.get
row_query = "SELECT RowName
@@ -281,11 +270,11 @@
row_id = sql.execAndReturnFirstString(row_query)
if row_id.is_initialized
row_id = row_id.get
else
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "VT row ID not found for construction: #{construction_name}.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "VT row ID not found for construction: #{construction_name}.")
row_id = 9999
end
vt_query = "SELECT Value
FROM tabulardatawithstrings
@@ -293,36 +282,32 @@
AND ReportForString='Entire Facility'
AND TableName='Exterior Fenestration'
AND ColumnName='Glass Visible Transmittance'
AND RowName='#{row_id}'"
-
vt = sql.execAndReturnFirstDouble(vt_query)
- if vt.is_initialized
- vt = vt.get
- else
- vt = nil
- end
+ vt = if vt.is_initialized
+ vt.get
+ end
else
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Space', 'Model has no sql file containing results, cannot lookup data.')
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Space', 'Model has no sql file containing results, cannot lookup data.')
end
return vt
-
end
- # Get the U-Factor as calculated by EnergyPlus
- # in W/m^2*K
+ # Get the U-Factor as calculated by EnergyPlus.
+ # Only applies to fenestration constructions.
+ # @return [Double] the U-Factor in W/m^2*K.
def calculated_u_factor
+ construction_name = name.get.to_s
- construction_name = self.name.get.to_s
-
u_factor_w_per_m2_k = nil
- sql = self.model.sqlFile
+ sql = model.sqlFile
if sql.is_initialized
sql = sql.get
row_query = "SELECT RowName
@@ -335,11 +320,11 @@
row_id = sql.execAndReturnFirstString(row_query)
if row_id.is_initialized
row_id = row_id.get
else
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "U-Factor row ID not found for construction: #{construction_name}.")
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "U-Factor row ID not found for construction: #{construction_name}.")
row_id = 9999
end
u_factor_query = "SELECT Value
FROM tabulardatawithstrings
@@ -347,31 +332,33 @@
AND ReportForString='Entire Facility'
AND TableName='Exterior Fenestration'
AND ColumnName='Glass U-Factor'
AND RowName='#{row_id}'"
-
u_factor_w_per_m2_k = sql.execAndReturnFirstDouble(u_factor_query)
- if u_factor_w_per_m2_k.is_initialized
- u_factor_w_per_m2_k = u_factor_w_per_m2_k.get
- else
- u_factor_w_per_m2_k = nil
- end
+ u_factor_w_per_m2_k = if u_factor_w_per_m2_k.is_initialized
+ u_factor_w_per_m2_k.get
+ end
else
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Space', 'Model has no sql file containing results, cannot lookup data.')
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Space', 'Model has no sql file containing results, cannot lookup data.')
end
return u_factor_w_per_m2_k
-
end
- # @param intended_surface_type [string]
- # @return u value [double]
+ # Returns the R-value of the combined inside and outside
+ # air film values from 90.1-2010 A9.4.1 Air Films
+ # @param intended_surface_type [String]
+ # Valid choices: 'AtticFloor', 'AtticWall', 'AtticRoof', 'DemisingFloor', 'InteriorFloor', 'InteriorCeiling',
+ # 'DemisingWall', 'InteriorWall', 'InteriorPartition', 'InteriorWindow', 'InteriorDoor', 'DemisingRoof',
+ # 'ExteriorRoof', 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser', 'ExteriorFloor',
+ # 'ExteriorWall', 'ExteriorWindow', 'ExteriorDoor', 'GlassDoor', 'OverheadDoor', 'GroundContactFloor',
+ # 'GroundContactWall', 'GroundContactRoof'
+ # @return [double] r-value in m^2*K/W.
def film_coefficients_r_value(intended_surface_type)
-
other_layer_r_value_si = 0.0
# Determine the R-value of the air films, if requested
# Film values from 90.1-2010 A9.4.1 Air Films
film_ext_surf_r_ip = 0.17
@@ -385,43 +372,40 @@
film_int_surf_ht_flow_up_r_si = OpenStudio.convert(film_int_surf_ht_flow_up_r_ip, 'ft^2*hr*R/Btu', 'm^2*K/W').get
film_int_surf_ht_flow_dwn_r_si = OpenStudio.convert(film_int_surf_ht_flow_dwn_r_ip, 'ft^2*hr*R/Btu', 'm^2*K/W').get
fil_int_surf_vertical_r_si = OpenStudio.convert(fil_int_surf_vertical_r_ip, 'ft^2*hr*R/Btu', 'm^2*K/W').get
case intended_surface_type
- when 'AtticFloor'
- other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Outside
- other_layer_r_value_si += film_semi_ext_surf_r_si # Inside
- when 'AtticWall', 'AtticRoof'
- other_layer_r_value_si += film_ext_surf_r_si # Outside
- other_layer_r_value_si += film_semi_ext_surf_r_si # Inside
- when 'DemisingFloor', 'InteriorFloor'
- other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Outside
- other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Inside
- when 'InteriorCeiling'
- other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Outside
- other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Inside
- when 'DemisingWall', 'InteriorWall', 'InteriorPartition', 'InteriorWindow', 'InteriorDoor'
- other_layer_r_value_si += fil_int_surf_vertical_r_si # Outside
- other_layer_r_value_si += fil_int_surf_vertical_r_si # Inside
- when 'DemisingRoof', 'ExteriorRoof', 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser'
- other_layer_r_value_si += film_ext_surf_r_si # Outside
- other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Inside
- when 'ExteriorFloor'
- other_layer_r_value_si += film_ext_surf_r_si # Outside
- other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Inside
- when 'ExteriorWall', 'ExteriorWindow', 'ExteriorDoor', 'GlassDoor', 'OverheadDoor'
- other_layer_r_value_si += film_ext_surf_r_si # Outside
- other_layer_r_value_si += fil_int_surf_vertical_r_si # Inside
- when 'GroundContactFloor'
- other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Inside
- when 'GroundContactWall'
- other_layer_r_value_si += fil_int_surf_vertical_r_si # Inside
- when 'GroundContactRoof'
- other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Inside
+ when 'AtticFloor'
+ other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Outside
+ other_layer_r_value_si += film_semi_ext_surf_r_si # Inside
+ when 'AtticWall', 'AtticRoof'
+ other_layer_r_value_si += film_ext_surf_r_si # Outside
+ other_layer_r_value_si += film_semi_ext_surf_r_si # Inside
+ when 'DemisingFloor', 'InteriorFloor'
+ other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Outside
+ other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Inside
+ when 'InteriorCeiling'
+ other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Outside
+ other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Inside
+ when 'DemisingWall', 'InteriorWall', 'InteriorPartition', 'InteriorWindow', 'InteriorDoor'
+ other_layer_r_value_si += fil_int_surf_vertical_r_si # Outside
+ other_layer_r_value_si += fil_int_surf_vertical_r_si # Inside
+ when 'DemisingRoof', 'ExteriorRoof', 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser'
+ other_layer_r_value_si += film_ext_surf_r_si # Outside
+ other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Inside
+ when 'ExteriorFloor'
+ other_layer_r_value_si += film_ext_surf_r_si # Outside
+ other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Inside
+ when 'ExteriorWall', 'ExteriorWindow', 'ExteriorDoor', 'GlassDoor', 'OverheadDoor'
+ other_layer_r_value_si += film_ext_surf_r_si # Outside
+ other_layer_r_value_si += fil_int_surf_vertical_r_si # Inside
+ when 'GroundContactFloor'
+ other_layer_r_value_si += film_int_surf_ht_flow_dwn_r_si # Inside
+ when 'GroundContactWall'
+ other_layer_r_value_si += fil_int_surf_vertical_r_si # Inside
+ when 'GroundContactRoof'
+ other_layer_r_value_si += film_int_surf_ht_flow_up_r_si # Inside
end
-
return other_layer_r_value_si
-
end
-
end