lib/measures/tbd/resources/psi.rb
def derate(model, id, surface, c)
  m = nil
  cl1 = OpenStudio::Model::Model
  cl2 = OpenStudio::Model::Construction

  unless model && id && surface && c
    TBD.log(TBD::DEBUG,
      "Can't derate insulation, invalid arguments - skipping")
    return m
  end
  unless id.is_a?(String)
    TBD.log(TBD::DEBUG,
      "Can't derate insulation, #{id.class}? expected an ID String - skipping")
    return m
  end
  unless model.is_a?(cl1)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', #{model.class}? expected #{cl1} - skipping")
    return m
  end
  unless surface.is_a?(Hash)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', #{surface.class}? expected a Hash - skipping")
    return m
  end
  unless c.is_a?(cl2)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', #{c.class}? expected #{cl2} - skipping")
    return m
  end
  unless surface.has_key?(:heatloss)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', no calculated heatloss - skipping")
    return m
  end
  unless surface[:heatloss].is_a?(Numeric)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-numeric heatloss - skipping")
    return m
  end
  if surface[:heatloss].abs < TOL
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', heatloss below #{TOL} - skipping")
    return m
  end
  unless surface.has_key?(:net)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing surface net area - skipping")
    return m
  end
  unless surface[:net].is_a?(Numeric)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-numeric surface net area - skipping")
    return m
  end
  if surface[:net] < TOL
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', surface net area below #{TOL} - skipping")
    return m
  end
  unless surface.has_key?(:ltype)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing material type - skipping")
    return m
  end
  unless surface[:ltype] == :massless || surface[:ltype] == :standard
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', must be Standard or Massless - skipping")
    return m
  end
  unless surface.has_key?(:construction)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing parent construction - skipping")
    return m
  end
  unless surface.has_key?(:index)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing material index - skipping")
    return m
  end
  unless surface[:index]
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', invalid material index - skipping")
    return m
  end
  unless surface[:index].is_a?(Integer)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-integer material index - skipping")
    return m
  end
  if surface[:index] < 0
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', material index < 0 - skipping")
    return m
  end
  unless surface.has_key?(:r)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', invalid material RSi value - skipping")
    return m
  end
  unless surface[:r].is_a?(Numeric)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-numeric material RSi value - skipping")
    return m
  end
  if surface[:r] < 0.001
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', material RSi value below MIN - skipping")
    return m
  end
  unless / tbd/i.match(c.nameString) == nil
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', material already derated - skipping")
    return m
  end

  index          = surface[:index]
  ltype          = surface[:ltype]
  r              = surface[:r]
  u              = surface[:heatloss] / surface[:net]
  loss           = 0.0
  de_u           = 1.0 / r + u                                       # derated U
  de_r           = 1.0 / de_u                                        # derated R

  if ltype == :massless
    m            = c.getLayer(index).to_MasslessOpaqueMaterial

    unless m.empty?
      m          = m.get
      m          = m.clone(model)
      m          = m.to_MasslessOpaqueMaterial.get
                   m.setName("'#{id}' m tbd")

      unless de_r > 0.001
        de_r     = 0.001
        loss     = (de_u - 1.0 / de_r) * surface[:net]
      end
      m.setThermalResistance(de_r)
    end

  else                                                      # ltype == :standard
    m            = c.getLayer(index).to_StandardOpaqueMaterial
    unless m.empty?
      m          = m.get
      m          = m.clone(model)
      m          = m.to_StandardOpaqueMaterial.get
                   m.setName("'#{id}' m tbd")
      k          = m.thermalConductivity
      if de_r > 0.001
        d        = de_r * k
        unless d > 0.003
          d      = 0.003
          k      = d / de_r
          unless k < 3.0
            k    = 3.0

            loss = (de_u - k / d) * surface[:net]
          end
        end
      else                                                 # de_r < 0.001 m2.K/W
        d        = 0.001 * k
        unless d > 0.003
          d      = 0.003
          k      = d / 0.001
        end
        loss     = (de_u - k / d) * surface[:net]
      end

      m.setThickness(d)
      m.setThermalConductivity(k)
    end
  end

  if m && loss > TOL
    surface[:r_heatloss] = loss
    h_loss  = format "%.3f", surface[:r_heatloss]
    TBD.log(TBD::WARN,
      "Won't assign #{h_loss} W/K to '#{id}', too conductive - skipping")
  end
  m
end
##
# Thermally derate insulating material within construction.
#
# @param [OpenStudio::Model::Model] model An OS model
# @param [String] id Surface identifier
# @param [Hash] surface A TBD surface
# @param [OpenStudio::Model::Construction] c An OS construction
#
# @return [OpenStudio::Model::Material] Returns derated (cloned) material
Thermally derate insulating material within construction.
Thermally derate insulating material within construction .
def derate(model, id, surface, c)
  m = nil
  cl1 = OpenStudio::Model::Model
  cl2 = OpenStudio::Model::Construction
  unless model && id && surface && c
    TBD.log(TBD::DEBUG,
      "Can't derate insulation, invalid arguments - skipping")
    return m
  end
  unless id.is_a?(String)
    TBD.log(TBD::DEBUG,
      "Can't derate insulation, #{id.class}? expected an ID String - skipping")
    return m
  end
  unless model.is_a?(cl1)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', #{model.class}? expected #{cl1} - skipping")
    return m
  end
  unless surface.is_a?(Hash)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', #{surface.class}? expected a Hash - skipping")
    return m
  end
  unless c.is_a?(cl2)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', #{c.class}? expected #{cl2} - skipping")
    return m
  end
  unless surface.has_key?(:heatloss)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', no calculated heatloss - skipping")
    return m
  end
  unless surface[:heatloss].is_a?(Numeric)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-numeric heatloss - skipping")
    return m
  end
  if surface[:heatloss].abs < TOL
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', heatloss below #{TOL} - skipping")
    return m
  end
  unless surface.has_key?(:net)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing surface net area - skipping")
    return m
  end
  unless surface[:net].is_a?(Numeric)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-numeric surface net area - skipping")
    return m
  end
  if surface[:net] < TOL
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', surface net area below #{TOL} - skipping")
    return m
  end
  unless surface.has_key?(:ltype)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing material type - skipping")
    return m
  end
  unless surface[:ltype] == :massless || surface[:ltype] == :standard
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', must be Standard or Massless - skipping")
    return m
  end
  unless surface.has_key?(:construction)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing parent construction - skipping")
    return m
  end
  unless surface.has_key?(:index)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', missing material index - skipping")
    return m
  end
  unless surface[:index]
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', invalid material index - skipping")
    return m
  end
  unless surface[:index].is_a?(Integer)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-integer material index - skipping")
    return m
  end
  if surface[:index] < 0
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', material index < 0 - skipping")
    return m
  end
  unless surface.has_key?(:r)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', invalid material RSi value - skipping")
    return m
  end
  unless surface[:r].is_a?(Numeric)
    TBD.log(TBD::DEBUG,
      "Can't derate '#{id}', non-numeric material RSi value - skipping")
    return m
  end
  if surface[:r] < 0.001
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', material RSi value below MIN - skipping")
    return m
  end
  unless / tbd/i.match(c.nameString) == nil
    TBD.log(TBD::WARN,
      "Won't derate '#{id}', material already derated - skipping")
    return m
  end
  index          = surface[:index]
  ltype          = surface[:ltype]
  r              = surface[:r]
  u              = surface[:heatloss] / surface[:net]
  loss           = 0.0
  de_u           = 1.0 / r + u                                       
  de_r           = 1.0 / de_u                                        
  if ltype == :massless
    m            = c.getLayer(index).to_MasslessOpaqueMaterial
    unless m.empty?
      m          = m.get
      m          = m.clone(model)
      m          = m.to_MasslessOpaqueMaterial.get
                   m.setName("'#{id}' m tbd")
      unless de_r > 0.001
        de_r     = 0.001
        loss     = (de_u - 1.0 / de_r) * surface[:net]
      end
      m.setThermalResistance(de_r)
    end
  else                                                      
    m            = c.getLayer(index).to_StandardOpaqueMaterial
    unless m.empty?
      m          = m.get
      m          = m.clone(model)
      m          = m.to_StandardOpaqueMaterial.get
                   m.setName("'#{id}' m tbd")
      k          = m.thermalConductivity
      if de_r > 0.001
        d        = de_r * k
        unless d > 0.003
          d      = 0.003
          k      = d / de_r
          unless k < 3.0
            k    = 3.0
            loss = (de_u - k / d) * surface[:net]
          end
        end
      else                                                 
        d        = 0.001 * k
        unless d > 0.003
          d      = 0.003
          k      = d / 0.001
        end
        loss     = (de_u - k / d) * surface[:net]
      end
      m.setThickness(d)
      m.setThermalConductivity(k)
    end
  end
  if m && loss > TOL
    surface[:r_heatloss] = loss
    h_loss  = format "%.3f", surface[:r_heatloss]
    TBD.log(TBD::WARN,
      "Won't assign #{h_loss} W/K to '#{id}', too conductive - skipping")
  end
  m
end
def derate ( model , id , surface , c ) m = nil cl1 = OpenStudio :: Model :: Model cl2 = OpenStudio :: Model :: Construction unless model && id && surface && c TBD . log ( TBD :: DEBUG , "Can't derate insulation, invalid arguments - skipping" ) return m end unless id . is_a? ( String ) TBD . log ( TBD :: DEBUG , "Can't derate insulation, #{id.class}? expected an ID String - skipping" ) return m end unless model . is_a? ( cl1 ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', #{model.class}? expected #{cl1} - skipping" ) return m end unless surface . is_a? ( Hash ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', #{surface.class}? expected a Hash - skipping" ) return m end unless c . is_a? ( cl2 ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', #{c.class}? expected #{cl2} - skipping" ) return m end unless surface . has_key? ( :heatloss ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', no calculated heatloss - skipping" ) return m end unless surface [ :heatloss ] . is_a? ( Numeric ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', non-numeric heatloss - skipping" ) return m end if surface [ :heatloss ] . abs < TOL TBD . log ( TBD :: WARN , "Won't derate '#{id}', heatloss below #{TOL} - skipping" ) return m end unless surface . has_key? ( :net ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', missing surface net area - skipping" ) return m end unless surface [ :net ] . is_a? ( Numeric ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', non-numeric surface net area - skipping" ) return m end if surface [ :net ] < TOL TBD . log ( TBD :: WARN , "Won't derate '#{id}', surface net area below #{TOL} - skipping" ) return m end unless surface . has_key? ( :ltype ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', missing material type - skipping" ) return m end unless surface [ :ltype ] == :massless || surface [ :ltype ] == :standard TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', must be Standard or Massless - skipping" ) return m end unless surface . has_key? ( :construction ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', missing parent construction - skipping" ) return m end unless surface . has_key? ( :index ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', missing material index - skipping" ) return m end unless surface [ :index ] TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', invalid material index - skipping" ) return m end unless surface [ :index ] . is_a? ( Integer ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', non-integer material index - skipping" ) return m end if surface [ :index ] < 0 TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', material index < 0 - skipping" ) return m end unless surface . has_key? ( :r ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', invalid material RSi value - skipping" ) return m end unless surface [ :r ] . is_a? ( Numeric ) TBD . log ( TBD :: DEBUG , "Can't derate '#{id}', non-numeric material RSi value - skipping" ) return m end if surface [ :r ] < 0.001 TBD . log ( TBD :: WARN , "Won't derate '#{id}', material RSi value below MIN - skipping" ) return m end unless /  tbd /i . match ( c . nameString ) == nil TBD . log ( TBD :: WARN , "Won't derate '#{id}', material already derated - skipping" ) return m end index = surface [ :index ] ltype = surface [ :ltype ] r = surface [ :r ] u = surface [ :heatloss ] / surface [ :net ] loss = 0.0 de_u = 1.0 / r + u de_r = 1.0 / de_u if ltype == :massless m = c . getLayer ( index ) . to_MasslessOpaqueMaterial unless m . empty? m = m . get m = m . clone ( model ) m = m . to_MasslessOpaqueMaterial . get m . setName ( "'#{id}' m tbd" ) unless de_r > 0.001 de_r = 0.001 loss = ( de_u - 1.0 / de_r ) * surface [ :net ] end m . setThermalResistance ( de_r ) end else m = c . getLayer ( index ) . to_StandardOpaqueMaterial unless m . empty? m = m . get m = m . clone ( model ) m = m . to_StandardOpaqueMaterial . get m . setName ( "'#{id}' m tbd" ) k = m . thermalConductivity if de_r > 0.001 d = de_r * k unless d > 0.003 d = 0.003 k = d / de_r unless k < 3.0 k = 3.0 loss = ( de_u - k / d ) * surface [ :net ] end end else d = 0.001 * k unless d > 0.003 d = 0.003 k = d / 0.001 end loss = ( de_u - k / d ) * surface [ :net ] end m . setThickness ( d ) m . setThermalConductivity ( k ) end end if m && loss > TOL surface [ :r_heatloss ] = loss h_loss = format "%.3f" , surface [ :r_heatloss ] TBD . log ( TBD :: WARN , "Won't assign #{h_loss} W/K to '#{id}', too conductive - skipping" ) end m end
Thermally derate insulating material within construction.
Thermally derate insulating material within construction .
# derated U # derated R # ltype == :standard # de_r < 0.001 m2.K/W
Returns derated (cloned) material
Returns derated ( cloned ) material
OpenStudio::Model::Material
model
id
surface
c
c An OS construction
c An OS construction