Module: OpenstudioStandards::Constructions
- Defined in:
- lib/openstudio-standards/constructions/create.rb,
lib/openstudio-standards/constructions/modify.rb,
lib/openstudio-standards/constructions/information.rb,
lib/openstudio-standards/constructions/materials/modify.rb,
lib/openstudio-standards/constructions/materials/information.rb
Overview
The Constructions module provides methods create, modify, and get information about model Constructions
Defined Under Namespace
Modules: Materials
Create collapse
-
.construction_deep_copy(construction) ⇒ OpenStudio::Model::Construction
This will create a deep copy of the construction, meaning it will clone and create new material objects as well.
-
.model_get_adiabatic_floor_construction(model) ⇒ OpenStudio::Model::Construction
Return the existing adiabatic floor construction, or create one if absent.
-
.model_get_adiabatic_wall_construction(model) ⇒ OpenStudio::Model::Construction
Return the existing adiabatic wall construction, or create one if absent.
Modify collapse
-
.construction_add_new_opaque_material(construction, layer_index: 0, name: nil, roughness: nil, thickness: nil, conductivity: nil, density: nil, specific_heat: nil, thermal_absorptance: nil, solar_absorptance: nil, visible_absorptance: nil) ⇒ OpenStudio::Model::StandardOpaqueMaterial
add new material layer to a construction.
-
.construction_find_and_set_insulation_layer(construction) ⇒ OpenStudio::Model::OpaqueMaterial
Find and set the insulation layer for a layered construction.
-
.construction_set_glazing_u_value(construction, target_u_value_ip, target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) ⇒ Boolean
Sets the U-value of a simple glazing construction to a specified value by modifying the SimpleGlazing material.
-
.construction_set_slab_f_factor(construction, target_f_factor_ip, insulation_layer_name: nil) ⇒ Boolean
Set the F-Factor of a slab to a specified value.
-
.construction_set_surface_properties(construction, roughness: nil, thermal_absorptance: nil, solar_absorptance: nil, visible_absorptance: nil) ⇒ OpenStudio::Model::OpaqueMaterial
set construction surface properties.
-
.construction_set_surface_slab_f_factor(construction, target_f_factor_ip, surface) ⇒ Boolean
Set the surface specific F-factor parameters of a construction.
-
.construction_set_surface_underground_wall_c_factor(construction, target_c_factor_ip, surface) ⇒ Boolean
Set the surface specific C-factor parameters of a construction.
-
.construction_set_u_value(construction, target_u_value_ip, insulation_layer_name: nil, intended_surface_type: 'ExteriorWall', target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) ⇒ Boolean
Sets the heat transfer coefficient (U-value) of a construction to a specified value by modifying the thickness of the insulation layer.
-
.construction_set_underground_wall_c_factor(construction, target_c_factor_ip, insulation_layer_name: nil) ⇒ Boolean
Set the C-Factor of an underground wall to a specified value.
Information collapse
-
.film_coefficients_r_value(intended_surface_type, int_film, ext_film) ⇒ Double
Gives the total R-value of the interior and exterior (if applicable) film coefficients for a particular type of surface.
Information:Construction collapse
-
.construction_get_conductance(construction, temperature: 0.0) ⇒ Double
Return the thermal conductance for an OpenStudio Construction object.
-
.construction_get_solar_reflectance_index(construction) ⇒ Double
Returns the solar reflectance index of an exposed surface.
-
.construction_get_solar_transmittance(construction) ⇒ Double
Get the total solar transmittance for a fenestration construction (SHGC).
-
.construction_get_visible_transmittance(construction) ⇒ Double
Get the total visible transmittance for a fenestration construction.
-
.construction_simple_glazing?(construction) ⇒ Boolean
Determines if the construction is a simple glazing construction, as indicated by having a single layer of type SimpleGlazing.
Information:Surfaces collapse
-
.surfaces_get_conductance(surfaces) ⇒ Double
Determine the weighted average conductance for a set of planar surfaces (surfaces or sub surfaces).
-
.surfaces_get_solar_transmittance(surfaces) ⇒ Double
Determine the weighted average solar transmittance for a set of planar surfaces (surfaces or sub surfaces).
-
.surfaces_get_visible_transmittance(surfaces) ⇒ Double
Determine the weighted average visible transmittance for a set of planar surfaces (surfaces or sub surfaces).
Information:DefaultConstructionSet collapse
-
.construction_set_get_constructions(default_construction_set) ⇒ Array<OpenStudio::Model::Construction>
report names of constructions in a construction set.
Information:Model collapse
-
.model_get_constructions(model, boundary_condition, surface_type) ⇒ Object
Get a unique list of constructions with a given boundary condition and surface type.
Class Method Details
.construction_add_new_opaque_material(construction, layer_index: 0, name: nil, roughness: nil, thickness: nil, conductivity: nil, density: nil, specific_heat: nil, thermal_absorptance: nil, solar_absorptance: nil, visible_absorptance: nil) ⇒ OpenStudio::Model::StandardOpaqueMaterial
add new material layer to a construction
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 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 22 def self.construction_add_new_opaque_material(construction, layer_index: 0, name: nil, roughness: nil, thickness: nil, conductivity: nil, density: nil, specific_heat: nil, thermal_absorptance: nil, solar_absorptance: nil, visible_absorptance: nil) # make new material new_material = OpenStudio::Model::StandardOpaqueMaterial.new(construction.model) if name.nil? new_material.setName("#{construction.name} New Material") else new_material.setName(name) end # set requested material properties new_material.setRoughness(roughness) unless roughness.nil? new_material.setThickness(thickness) unless thickness.nil? new_material.setConductivity(conductivity) unless conductivity.nil? new_material.setDensity(density) unless density.nil? new_material.setSpecificHeat(specific_heat) unless specific_heat.nil? new_material.setThermalAbsorptance(thermal_absorptance) unless thermal_absorptance.nil? new_material.setSolarAbsorptance(solar_absorptance) unless solar_absorptance.nil? new_material.setVisibleAbsorptance(visible_absorptance) unless visible_absorptance.nil? # add material to construction construction.insertLayer(layer_index, new_material) return new_material end |
.construction_deep_copy(construction) ⇒ OpenStudio::Model::Construction
This will create a deep copy of the construction, meaning it will clone and create new material objects as well
11 12 13 14 15 16 17 18 |
# File 'lib/openstudio-standards/constructions/create.rb', line 11 def self.construction_deep_copy(construction) new_construction = construction.clone.to_Construction.get (0..new_construction.layers.length - 1).each do |layer_number| cloned_layer = new_construction.getLayer(layer_number).clone.to_Material.get new_construction.setLayer(layer_number, cloned_layer) end return new_construction end |
.construction_find_and_set_insulation_layer(construction) ⇒ OpenStudio::Model::OpaqueMaterial
Find and set the insulation layer for a layered construction
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 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 62 def self.construction_find_and_set_insulation_layer(construction) # skip and return the insulation layer if already set return construction.insulation.get if construction.insulation.is_initialized # loop through construction layers to find insulation layer min_conductance = 100.0 insulation_material = nil construction.layers.each do |layer| # skip layers that aren't an OpaqueMaterial next unless layer.to_OpaqueMaterial.is_initialized material = layer.to_OpaqueMaterial.get material_conductance = OpenstudioStandards::Constructions::Materials.material_get_conductance(material) if material_conductance < min_conductance min_conductance = material_conductance insulation_material = material end end construction.setInsulation(insulation_material) unless insulation_material.nil? if construction.isOpaque && !construction.insulation.is_initialized OpenStudio.logFree(OpenStudio::Error, 'OpenstudioStandards::Constructions', "Unable to determine the insulation layer for construction #{construction.name.get}.") return nil end return construction.insulation.get end |
.construction_get_conductance(construction, temperature: 0.0) ⇒ Double
Return the thermal conductance for an OpenStudio Construction object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/openstudio-standards/constructions/information.rb', line 102 def self.construction_get_conductance(construction, temperature: 0.0) # check to see if it can be cast as a layered construction, otherwise error unless construction.to_LayeredConstruction.is_initialized OpenStudio.logFree(OpenStudio::Error, 'OpenstudioStandards::Constructions', "Unable to determine conductance for construction #{construction.name} because it is not a LayeredConstruction.") return nil end construction = construction.to_LayeredConstruction.get total = 0.0 construction.layers.each do |material| total += 1.0 / OpenstudioStandards::Constructions::Materials.material_get_conductance(material, temperature: temperature) end return 1.0 / total end |
.construction_get_solar_reflectance_index(construction) ⇒ Double
Returns the solar reflectance index of an exposed surface. On a scale of 0 to 100, standard black is 0, and standard white is 100. The calculation derived from ASTM E1980 assuming medium wind speed.
178 179 180 181 182 183 184 185 186 |
# File 'lib/openstudio-standards/constructions/information.rb', line 178 def self.construction_get_solar_reflectance_index(construction) exposed_material = construction.to_LayeredConstruction.get.getLayer(0) solar_absorptance = exposed_material.to_OpaqueMaterial.get.solarAbsorptance thermal_emissivity = exposed_material.to_OpaqueMaterial.get.thermalAbsorptance x = ((20.797 * solar_absorptance) - (0.603 * thermal_emissivity)) / ((9.5205 * thermal_emissivity) + 12.0) sri = 123.97 - (141.35 * x) + (9.6555 * x * x) return sri end |
.construction_get_solar_transmittance(construction) ⇒ Double
Get the total solar transmittance for a fenestration construction (SHGC)
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/openstudio-standards/constructions/information.rb', line 122 def self.construction_get_solar_transmittance(construction) tsol = nil if construction.isFenestration tsol = 1.0 construction.layers.each do |layer| # Use shgc for simple glazing tsol *= layer.to_SimpleGlazing.get.solarHeatGainCoefficient unless layer.to_SimpleGlazing.empty? # Use solar transmittance for standard glazing tsol *= layer.to_StandardGlazing.get.solarTransmittance unless layer.to_StandardGlazing.empty? end end if tsol.nil? OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Constructions', "Unable to determine total solar transmittance for construction #{construction.name} because it is not considered Fenestration in the model. Returning a total solar transmittance of 0.0.") tsol = 0.0 end return tsol end |
.construction_get_visible_transmittance(construction) ⇒ Double
Get the total visible transmittance for a fenestration construction
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/openstudio-standards/constructions/information.rb', line 146 def self.construction_get_visible_transmittance(construction) tvis = nil if construction.isFenestration tvis = 1.0 construction.layers.each do |layer| # Use visible transmittance for simple glazing if specified unless layer.to_SimpleGlazing.empty? val = layer.to_SimpleGlazing.get.visibleTransmittance tvis *= val.get unless val.empty? end # Use visible transmittance for standard glazing if specified unless layer.to_StandardGlazing.empty? val = layer.to_StandardGlazing.get.visibleTransmittanceatNormalIncidence tvis *= val.get unless val.empty? end end end if tvis.nil? OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Constructions', "Unable to determine total visible transmittance for construction #{construction.name} because it is not considered Fenestration in the model. Returning a total visible transmittance of 0.0.") tvis = 0.0 end return tvis end |
.construction_set_get_constructions(default_construction_set) ⇒ Array<OpenStudio::Model::Construction>
report names of constructions in a construction set
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/openstudio-standards/constructions/information.rb', line 261 def self.construction_set_get_constructions(default_construction_set) construction_array = [] # populate exterior surfaces if default_construction_set.defaultExteriorSurfaceConstructions.is_initialized default_surface_constructions = default_construction_set.defaultExteriorSurfaceConstructions.get construction_array << default_surface_constructions.floorConstruction.get if default_surface_constructions.floorConstruction.is_initialized construction_array << default_surface_constructions.wallConstruction.get if default_surface_constructions.wallConstruction.is_initialized construction_array << default_surface_constructions.roofCeilingConstruction.get if default_surface_constructions.roofCeilingConstruction.is_initialized end # populate interior surfaces if default_construction_set.defaultInteriorSurfaceConstructions.is_initialized default_surface_constructions = default_construction_set.defaultInteriorSurfaceConstructions.get construction_array << default_surface_constructions.floorConstruction.get if default_surface_constructions.floorConstruction.is_initialized construction_array << default_surface_constructions.wallConstruction.get if default_surface_constructions.wallConstruction.is_initialized construction_array << default_surface_constructions.roofCeilingConstruction.get if default_surface_constructions.roofCeilingConstruction.is_initialized end # populate ground surfaces if default_construction_set.defaultGroundContactSurfaceConstructions.is_initialized default_surface_constructions = default_construction_set.defaultGroundContactSurfaceConstructions.get construction_array << default_surface_constructions.floorConstruction.get if default_surface_constructions.floorConstruction.is_initialized construction_array << default_surface_constructions.wallConstruction.get if default_surface_constructions.wallConstruction.is_initialized construction_array << default_surface_constructions.roofCeilingConstruction.get if default_surface_constructions.roofCeilingConstruction.is_initialized end # populate exterior sub-surfaces if default_construction_set.defaultExteriorSubSurfaceConstructions.is_initialized default_subsurface_constructions = default_construction_set.defaultExteriorSubSurfaceConstructions.get construction_array << default_subsurface_constructions.fixedWindowConstruction.get if default_subsurface_constructions.fixedWindowConstruction.is_initialized construction_array << default_subsurface_constructions.operableWindowConstruction.get if default_subsurface_constructions.operableWindowConstruction.is_initialized construction_array << default_subsurface_constructions.doorConstruction.get if default_subsurface_constructions.doorConstruction.is_initialized construction_array << default_subsurface_constructions.glassDoorConstruction.get if default_subsurface_constructions.glassDoorConstruction.is_initialized construction_array << default_subsurface_constructions.overheadDoorConstruction.get if default_subsurface_constructions.overheadDoorConstruction.is_initialized construction_array << default_subsurface_constructions.skylightConstruction.get if default_subsurface_constructions.skylightConstruction.is_initialized construction_array << default_subsurface_constructions.tubularDaylightDomeConstruction.get if default_subsurface_constructions.tubularDaylightDomeConstruction.is_initialized construction_array << default_subsurface_constructions.tubularDaylightDiffuserConstruction.get if default_subsurface_constructions.tubularDaylightDiffuserConstruction.is_initialized end # populate interior sub-surfaces if default_construction_set.defaultInteriorSubSurfaceConstructions.is_initialized default_subsurface_constructions = default_construction_set.defaultInteriorSubSurfaceConstructions.get construction_array << default_subsurface_constructions.fixedWindowConstruction.get if default_subsurface_constructions.fixedWindowConstruction.is_initialized construction_array << default_subsurface_constructions.operableWindowConstruction.get if default_subsurface_constructions.operableWindowConstruction.is_initialized construction_array << default_subsurface_constructions.doorConstruction.get if default_subsurface_constructions.doorConstruction.is_initialized construction_array << default_subsurface_constructions.glassDoorConstruction.get if default_subsurface_constructions.glassDoorConstruction.is_initialized construction_array << default_subsurface_constructions.overheadDoorConstruction.get if default_subsurface_constructions.overheadDoorConstruction.is_initialized construction_array << default_subsurface_constructions.skylightConstruction.get if default_subsurface_constructions.skylightConstruction.is_initialized construction_array << default_subsurface_constructions.tubularDaylightDomeConstruction.get if default_subsurface_constructions.tubularDaylightDomeConstruction.is_initialized construction_array << default_subsurface_constructions.tubularDaylightDiffuserConstruction.get if default_subsurface_constructions.tubularDaylightDiffuserConstruction.is_initialized end # populate misc surfaces construction_array << default_construction_set.interiorPartitionConstruction.get if default_construction_set.interiorPartitionConstruction.is_initialized construction_array << default_construction_set.spaceShadingConstruction.get if default_construction_set.spaceShadingConstruction.is_initialized construction_array << default_construction_set.buildingShadingConstruction.get if default_construction_set.buildingShadingConstruction.is_initialized construction_array << default_construction_set.siteShadingConstruction.get if default_construction_set.siteShadingConstruction.is_initialized return construction_array end |
.construction_set_glazing_u_value(construction, target_u_value_ip, target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) ⇒ Boolean
Sets the U-value of a simple glazing construction to a specified value by modifying the SimpleGlazing material.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 217 def self.construction_set_glazing_u_value(construction, target_u_value_ip, target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) # Skip layer-by-layer fenestration constructions unless OpenstudioStandards::Constructions.construction_simple_glazing?(construction) OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Construction', "The construction_set_glazing_u_value method can only set the u-value of simple glazing. #{construction.name} does not containg simple glazing.") return false end # Convert the target U-value to SI target_r_value_ip = 1.0 / target_u_value_ip.to_f 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 # Determine the R-value of the air films, if requested # In EnergyPlus, the U-factor input of the WindowMaterial:SimpleGlazingSystem # object includes the film coefficients (see IDD description, and I/O reference # guide) so the target_includes_interior_film_coefficients and target_includes_exterior_film_coefficients # variable values are changed to their opposite so if the target value includes a film # the target value is unchanged film_coeff_r_value_si = 0.0 film_coeff_r_value_si += OpenstudioStandards::Constructions.film_coefficients_r_value('ExteriorWindow', !target_includes_interior_film_coefficients, !target_includes_exterior_film_coefficients) film_coeff_u_value_si = 1.0 / film_coeff_r_value_si film_coeff_u_value_ip = OpenStudio.convert(film_coeff_u_value_si, 'W/m^2*K', 'Btu/ft^2*hr*R').get film_coeff_r_value_ip = 1.0 / film_coeff_u_value_ip # Determine the difference between the desired R-value # and the R-value of the and air films. # This is the desired R-value of the insulation. ins_r_value_si = target_r_value_si - film_coeff_r_value_si if ins_r_value_si <= 0.0 ins_r_value_si = 0.001 OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Construction', "Requested U-value of #{target_u_value_ip} Btu/ft^2*hr*R for #{construction.name} is too high given the film coefficients of U-#{film_coeff_u_value_ip.round(2)} Btu/ft^2*hr*R.") end ins_u_value_si = 1.0 / ins_r_value_si if ins_u_value_si > 7.0 OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Construction', "Requested U-value of #{target_u_value_ip} for #{construction.name} is too high given the film coefficients of U-#{film_coeff_u_value_ip.round(2)}; setting U-value to EnergyPlus limit of 7.0 W/m^2*K (1.23 Btu/ft^2*hr*R).") ins_u_value_si = 7.0 end ins_u_value_ip = OpenStudio.convert(ins_u_value_si, 'W/m^2*K', 'Btu/ft^2*hr*R').get # Set the U-value of the insulation layer glazing = construction.layers.first.to_SimpleGlazing.get starting_u_value_si = glazing.uFactor.round(2) staring_u_value_ip = OpenStudio.convert(starting_u_value_si, 'W/m^2*K', 'Btu/ft^2*hr*R').get OpenStudio.logFree(OpenStudio::Debug, 'OpenstudioStandards::Construction', "Construction #{construction.name} contains SimpleGlazing '#{glazing.name}' with starting u_factor #{starting_u_value_si.round(2)} 'W/m^2*K' = #{staring_u_value_ip.round(2)} 'Btu/ft^2*hr*R'. Changing to u_factor #{ins_u_value_si.round(2)} 'W/m^2*K' = #{ins_u_value_ip.round(2)} 'Btu/ft^2*hr*R'.") glazing.setUFactor(ins_u_value_si) return true end |
.construction_set_slab_f_factor(construction, target_f_factor_ip, insulation_layer_name: nil) ⇒ Boolean
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 Table A6.3 Assembly F-Factors for Slab-on-Grade Floors.
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 301 def self.construction_set_slab_f_factor(construction, 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 # Set the insulation U-value OpenstudioStandards::Constructions.construction_set_u_value(construction, u_value_ip, insulation_layer_name: insulation_layer_name, intended_surface_type: 'GroundContactFloor', target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) # Modify the construction name construction.setName("#{construction.name} F-#{target_f_factor_ip.round(3)}") return true end |
.construction_set_surface_properties(construction, roughness: nil, thermal_absorptance: nil, solar_absorptance: nil, visible_absorptance: nil) ⇒ OpenStudio::Model::OpaqueMaterial
set construction surface properties
277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 277 def self.construction_set_surface_properties(construction, roughness: nil, thermal_absorptance: nil, solar_absorptance: nil, visible_absorptance: nil) surface_material = construction.to_LayeredConstruction.get.getLayer(0) new_material = OpenstudioStandards::Constructions::Materials.opaque_material_set_surface_properties(surface_material, roughness: roughness, thermal_absorptance: thermal_absorptance, solar_absorptance: solar_absorptance, visible_absorptance: visible_absorptance) return new_material end |
.construction_set_surface_slab_f_factor(construction, target_f_factor_ip, surface) ⇒ Boolean
Set the surface specific F-factor parameters of a construction. This method only assumes one floor per space when calculating perimeter and area
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 326 def self.construction_set_surface_slab_f_factor(construction, target_f_factor_ip, surface) # Get space associated with surface space = surface.space.get # Find this space's exposed floor area and perimeter. perimeter = OpenstudioStandards::Geometry.space_get_f_floor_perimeter(space) area = OpenstudioStandards::Geometry.space_get_f_floor_area(space) if area.zero? OpenStudio.logFree(OpenStudio::Error, 'OpenstudioStandards::Construction', "Area for #{surface.name} was calculated to be 0 m2, slab f-factor cannot be set.") return false end # Change construction name construction.setName("#{construction.name}_#{surface.name}_#{target_f_factor_ip}") # Set properties f_factor_si = target_f_factor_ip * OpenStudio.convert(1.0, 'Btu/ft*h*R', 'W/m*K').get construction.setFFactor(f_factor_si) construction.setArea(area) construction.setPerimeterExposed(perimeter) # Set surface outside boundary condition surface.setOutsideBoundaryCondition('GroundFCfactorMethod') return true end |
.construction_set_surface_underground_wall_c_factor(construction, target_c_factor_ip, surface) ⇒ Boolean
Set the surface specific C-factor parameters of a construction
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 387 def self.construction_set_surface_underground_wall_c_factor(construction, target_c_factor_ip, surface) # Get space associated with surface space = surface.space.get # Get height of the first below grade wall in this space. below_grade_wall_height = OpenstudioStandards::Geometry.space_get_below_grade_wall_height(space) if below_grade_wall_height.zero? OpenStudio.logFree(OpenStudio::Error, 'OpenstudioStandards::Construction', "Below grade wall height for #{surface.name} was calculated to be 0 m2, below grade wall c-factor cannot be set.") return false end # Change construction name construction.setName("#{construction.name}_#{surface.name}_#{target_c_factor_ip}") # Set properties c_factor_si = target_c_factor_ip * OpenStudio.convert(1.0, 'Btu/ft^2*h*R', 'W/m^2*K').get construction.setCFactor(c_factor_si) construction.setHeight(below_grade_wall_height) # Set surface outside boundary condition surface.setOutsideBoundaryCondition('GroundFCfactorMethod') end |
.construction_set_u_value(construction, target_u_value_ip, insulation_layer_name: nil, intended_surface_type: 'ExteriorWall', target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) ⇒ Boolean
Sets the heat transfer coefficient (U-value) of a construction to a specified value by modifying the thickness of the insulation layer.
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 163 164 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 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 106 def self.construction_set_u_value(construction, target_u_value_ip, insulation_layer_name: nil, intended_surface_type: 'ExteriorWall', target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) # Skip layer-by-layer fenestration constructions if construction.isFenestration OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Constructions', "Can only set the u-value of opaque constructions or simple glazing. #{construction.name} is not opaque or simple glazing.") return false end # Make sure an insulation layer was specified if insulation_layer_name.nil? && (target_u_value_ip.abs < 0.01) # Do nothing if the construction already doesn't have an insulation layer elsif insulation_layer_name.nil? insulation_layer_name = OpenstudioStandards::Constructions.construction_find_and_set_insulation_layer(construction).name.get end # Remove the insulation layer if the specified U-value is zero. if target_u_value_ip.abs < 0.01 layer_index = 0 construction.layers.each do |layer| break if layer.name.get == insulation_layer_name layer_index += 1 end construction.eraseLayer(layer_index) return true end min_r_value_si = OpenstudioStandards::Constructions.film_coefficients_r_value(intended_surface_type, target_includes_interior_film_coefficients, target_includes_exterior_film_coefficients) max_u_value_si = 1.0 / min_r_value_si max_u_value_ip = OpenStudio.convert(max_u_value_si, 'W/m^2*K', 'Btu/ft^2*hr*R').get if target_u_value_ip >= max_u_value_ip target_u_value_ip = 1.0 / OpenStudio.convert(min_r_value_si + 0.001, 'm^2*K/W', 'ft^2*hr*R/Btu').get OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Constructions', "Requested U-value of #{target_u_value_ip} for #{construction.name} is greater than the sum of the inside and outside resistance, and the max U-value (6.636 SI) is used instead.") end # Convert the target U-value to SI target_r_value_ip = 1.0 / target_u_value_ip.to_f 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, 'OpenstudioStandards::Constructions', "Setting U-Value for #{construction.name} to #{target_u_value_si.round(3)} W/m^2*K or #{target_u_value_ip.round(3)} 'Btu/ft^2*hr*R', which is an R-value of #{target_r_value_si.round(3)} m^2*K/W or #{target_r_value_ip.round(3)} 'ft^2*hr*R/Btu'.") # Determine the R-value of the non-insulation layers other_layer_r_value_si = 0.0 construction.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 # Determine the R-value of the air films, if requested other_layer_r_value_si += OpenstudioStandards::Constructions.film_coefficients_r_value(intended_surface_type, target_includes_interior_film_coefficients, target_includes_exterior_film_coefficients) # 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 # Set the R-value of the insulation layer construction.layers.each_with_index do |layer, l| next unless layer.name.get == insulation_layer_name # Remove insulation layer if requested R-value is lower than sum of non-insulation materials if ins_r_value_si <= 0.0 OpenStudio.logFree(OpenStudio::Warn, 'OpenstudioStandards::Construction', "Requested U-value of #{target_u_value_ip} for #{construction.name} is too low given the other materials in the construction; insulation layer will be removed.") construction.eraseLayer(l) # Set the target R-value to the sum of other layers to make name match properties target_r_value_ip = OpenStudio.convert(other_layer_r_value_si, 'm^2*K/W', 'ft^2*hr*R/Btu').get break # Don't modify the insulation layer since it has been removed end # Modify the insulation layer ins_r_value_ip = OpenStudio.convert(ins_r_value_si, 'm^2*K/W', 'ft^2*h*R/Btu').get if layer.to_StandardOpaqueMaterial.is_initialized layer = layer.to_StandardOpaqueMaterial.get layer.setThickness(ins_r_value_si * layer.conductivity) layer.setName("#{layer.name} R-#{ins_r_value_ip.round(2)}") break # Stop looking for the insulation layer once found elsif layer.to_MasslessOpaqueMaterial.is_initialized layer = layer.to_MasslessOpaqueMaterial.get layer.setThermalResistance(ins_r_value_si) layer.setName("#{layer.name} R-#{ins_r_value_ip.round(2)}") break # Stop looking for the insulation layer once found elsif layer.to_AirGap.is_initialized layer = layer.to_AirGap.get target_thickness = ins_r_value_si * layer.thermalConductivity 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 construction.setName("#{construction.name} R-#{target_r_value_ip.round(2)}") return true end |
.construction_set_underground_wall_c_factor(construction, target_c_factor_ip, insulation_layer_name: nil) ⇒ Boolean
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 Table A4.2 Assembly C-Factors for Below-Grade walls.
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/openstudio-standards/constructions/modify.rb', line 363 def self.construction_set_underground_wall_c_factor(construction, 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 # Set the insulation U-value OpenstudioStandards::Constructions.construction_set_u_value(construction, u_value_ip, insulation_layer_name: insulation_layer_name, intended_surface_type: 'GroundContactWall', target_includes_interior_film_coefficients: true, target_includes_exterior_film_coefficients: true) # Modify the construction name construction.setName("#{construction.name} C-#{target_c_factor_ip.round(3)}") return true end |
.construction_simple_glazing?(construction) ⇒ Boolean
Determines if the construction is a simple glazing construction, as indicated by having a single layer of type SimpleGlazing.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/openstudio-standards/constructions/information.rb', line 81 def self.construction_simple_glazing?(construction) # Not simple if more than 1 layer if construction.layers.length > 1 return false end # Not simple unless the layer is a SimpleGlazing material # if construction.layers.first.to_SimpleGlazing.empty? if construction.layers.first.to_SimpleGlazing.empty? return false end # If here, must be simple glazing return true end |
.film_coefficients_r_value(intended_surface_type, int_film, ext_film) ⇒ Double
Gives the total R-value of the interior and exterior (if applicable) film coefficients for a particular type of surface.
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 |
# File 'lib/openstudio-standards/constructions/information.rb', line 19 def self.film_coefficients_r_value(intended_surface_type, int_film, ext_film) # Return zero if both interior and exterior are false return 0.0 if !int_film && !ext_film # Film values from 90.1-2010 A9.4.1 Air Films film_ext_surf_r_ip = 0.17 film_semi_ext_surf_r_ip = 0.46 film_int_surf_ht_flow_up_r_ip = 0.61 film_int_surf_ht_flow_dwn_r_ip = 0.92 fil_int_surf_vertical_r_ip = 0.68 film_ext_surf_r_si = OpenStudio.convert(film_ext_surf_r_ip, 'ft^2*hr*R/Btu', 'm^2*K/W').get film_semi_ext_surf_r_si = OpenStudio.convert(film_semi_ext_surf_r_ip, 'ft^2*hr*R/Btu', 'm^2*K/W').get 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 film_r_si = 0.0 case intended_surface_type when 'AtticFloor' film_r_si += film_int_surf_ht_flow_up_r_si if ext_film # Outside film_r_si += film_semi_ext_surf_r_si if int_film # Inside @todo: this is only true if the attic is ventilated, interior film should be used otheriwse when 'AtticWall', 'AtticRoof' film_r_si += film_ext_surf_r_si if ext_film # Outside film_r_si += film_semi_ext_surf_r_si if int_film # Inside @todo: this is only true if the attic is ventilated, interior film should be used otherwise when 'DemisingFloor', 'InteriorFloor' film_r_si += film_int_surf_ht_flow_up_r_si if ext_film # Outside film_r_si += film_int_surf_ht_flow_dwn_r_si if int_film # Inside when 'InteriorCeiling' film_r_si += film_int_surf_ht_flow_dwn_r_si if ext_film # Outside film_r_si += film_int_surf_ht_flow_up_r_si if int_film # Inside when 'DemisingWall', 'InteriorWall', 'InteriorPartition', 'InteriorWindow', 'InteriorDoor' film_r_si += fil_int_surf_vertical_r_si if ext_film # Outside film_r_si += fil_int_surf_vertical_r_si if int_film # Inside when 'DemisingRoof', 'ExteriorRoof', 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser' film_r_si += film_ext_surf_r_si if ext_film # Outside film_r_si += film_int_surf_ht_flow_up_r_si if int_film # Inside when 'ExteriorFloor' film_r_si += film_ext_surf_r_si if ext_film # Outside film_r_si += film_int_surf_ht_flow_dwn_r_si if int_film # Inside when 'ExteriorWall', 'ExteriorWindow', 'ExteriorDoor', 'GlassDoor', 'OverheadDoor' film_r_si += film_ext_surf_r_si if ext_film # Outside film_r_si += fil_int_surf_vertical_r_si if int_film # Inside when 'GroundContactFloor' film_r_si += film_int_surf_ht_flow_dwn_r_si if int_film # Inside when 'GroundContactWall' film_r_si += fil_int_surf_vertical_r_si if int_film # Inside when 'GroundContactRoof' film_r_si += film_int_surf_ht_flow_up_r_si if int_film # Inside end return film_r_si end |
.model_get_adiabatic_floor_construction(model) ⇒ OpenStudio::Model::Construction
Return the existing adiabatic floor construction, or create one if absent.
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 |
# File 'lib/openstudio-standards/constructions/create.rb', line 24 def self.model_get_adiabatic_floor_construction(model) adiabatic_construction_name = 'Adiabatic floor construction' # Check if adiabatic floor construction already exists in the model adiabatic_construct_exists = model.getConstructionByName(adiabatic_construction_name).is_initialized # Check to see if adiabatic construction has been constructed. If so, return it. Else, construct it. return model.getConstructionByName(adiabatic_construction_name).get if adiabatic_construct_exists # Assign construction to adiabatic construction cp02_carpet_pad = OpenStudio::Model::MasslessOpaqueMaterial.new(model) cp02_carpet_pad.setName('CP02 CARPET PAD') cp02_carpet_pad.setRoughness('VeryRough') cp02_carpet_pad.setThermalResistance(0.21648) cp02_carpet_pad.setThermalAbsorptance(0.9) cp02_carpet_pad.setSolarAbsorptance(0.7) cp02_carpet_pad.setVisibleAbsorptance(0.8) normalweight_concrete_floor = OpenStudio::Model::StandardOpaqueMaterial.new(model) normalweight_concrete_floor.setName('100mm Normalweight concrete floor') normalweight_concrete_floor.setRoughness('MediumSmooth') normalweight_concrete_floor.setThickness(0.1016) normalweight_concrete_floor.setThermalConductivity(2.31) normalweight_concrete_floor.setDensity(2322) normalweight_concrete_floor.setSpecificHeat(832) nonres_floor_insulation = OpenStudio::Model::MasslessOpaqueMaterial.new(model) nonres_floor_insulation.setName('Nonres_Floor_Insulation') nonres_floor_insulation.setRoughness('MediumSmooth') nonres_floor_insulation.setThermalResistance(2.88291975297193) nonres_floor_insulation.setThermalAbsorptance(0.9) nonres_floor_insulation.setSolarAbsorptance(0.7) nonres_floor_insulation.setVisibleAbsorptance(0.7) floor_adiabatic_construction = OpenStudio::Model::Construction.new(model) floor_adiabatic_construction.setName(adiabatic_construction_name) floor_layers = OpenStudio::Model::MaterialVector.new floor_layers << cp02_carpet_pad floor_layers << normalweight_concrete_floor floor_layers << nonres_floor_insulation floor_adiabatic_construction.setLayers(floor_layers) return floor_adiabatic_construction end |
.model_get_adiabatic_wall_construction(model) ⇒ OpenStudio::Model::Construction
Return the existing adiabatic wall construction, or create one if absent.
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/constructions/create.rb', line 73 def self.model_get_adiabatic_wall_construction(model) adiabatic_construction_name = 'Adiabatic wall construction' # Check if adiabatic wall construction already exists in the model adiabatic_construct_exists = model.getConstructionByName(adiabatic_construction_name).is_initialized # Check to see if adiabatic construction has been constructed. If so, return it. Else, construct it. return model.getConstructionByName(adiabatic_construction_name).get if adiabatic_construct_exists g01_13mm_gypsum_board = OpenStudio::Model::StandardOpaqueMaterial.new(model) g01_13mm_gypsum_board.setName('G01 13mm gypsum board') g01_13mm_gypsum_board.setRoughness('Smooth') g01_13mm_gypsum_board.setThickness(0.0127) g01_13mm_gypsum_board.setThermalConductivity(0.1600) g01_13mm_gypsum_board.setDensity(800) g01_13mm_gypsum_board.setSpecificHeat(1090) g01_13mm_gypsum_board.setThermalAbsorptance(0.9) g01_13mm_gypsum_board.setSolarAbsorptance(0.7) g01_13mm_gypsum_board.setVisibleAbsorptance(0.5) wall_adiabatic_construction = OpenStudio::Model::Construction.new(model) wall_adiabatic_construction.setName(adiabatic_construction_name) wall_layers = OpenStudio::Model::MaterialVector.new wall_layers << g01_13mm_gypsum_board wall_layers << g01_13mm_gypsum_board wall_adiabatic_construction.setLayers(wall_layers) return wall_adiabatic_construction end |
.model_get_constructions(model, boundary_condition, surface_type) ⇒ Object
Get a unique list of constructions with a given boundary condition and surface type. Pulls from both default construction sets and hard-assigned constructions.
return [Array<OpenStudio::Model::ConstructionBase>] An array of all constructions matching the given boundary condition and surface type
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/openstudio-standards/constructions/information.rb', line 358 def self.model_get_constructions(model, boundary_condition, surface_type) constructions = [] # From default construction sets model.getDefaultConstructionSets.sort.each do |const_set| ext_surfs = const_set.defaultExteriorSurfaceConstructions int_surfs = const_set.defaultInteriorSurfaceConstructions gnd_surfs = const_set.defaultGroundContactSurfaceConstructions ext_subsurfs = const_set.defaultExteriorSubSurfaceConstructions int_subsurfs = const_set.defaultInteriorSubSurfaceConstructions # Can't handle incomplete construction sets if ext_surfs.empty? || int_surfs.empty? || gnd_surfs.empty? || ext_subsurfs.empty? || int_subsurfs.empty? OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Space', "Default construction set #{const_set.name} is incomplete; constructions from this set will not be reported.") next end ext_surfs = ext_surfs.get int_surfs = int_surfs.get gnd_surfs = gnd_surfs.get ext_subsurfs = ext_subsurfs.get int_subsurfs = int_subsurfs.get case surface_type # Exterior Surfaces when 'ExteriorWall', 'AtticWall' constructions << ext_surfs.wallConstruction when 'ExteriorFloor' constructions << ext_surfs.floorConstruction when 'ExteriorRoof', 'AtticRoof' constructions << ext_surfs.roofCeilingConstruction # Interior Surfaces when 'InteriorWall', 'DemisingWall', 'InteriorPartition' constructions << int_surfs.wallConstruction when 'InteriorFloor', 'AtticFloor', 'DemisingFloor' constructions << int_surfs.floorConstruction when 'InteriorCeiling', 'DemisingRoof' constructions << int_surfs.roofCeilingConstruction # Ground Contact Surfaces when 'GroundContactWall' constructions << gnd_surfs.wallConstruction when 'GroundContactFloor' constructions << gnd_surfs.floorConstruction when 'GroundContactRoof' constructions << gnd_surfs.roofCeilingConstruction # Exterior SubSurfaces when 'ExteriorWindow' constructions << ext_subsurfs.fixedWindowConstruction constructions << ext_subsurfs.operableWindowConstruction when 'ExteriorDoor' constructions << ext_subsurfs.doorConstruction when 'GlassDoor' constructions << ext_subsurfs.glassDoorConstruction when 'OverheadDoor' constructions << ext_subsurfs.overheadDoorConstruction when 'Skylight' constructions << ext_subsurfs.skylightConstruction when 'TubularDaylightDome' constructions << ext_subsurfs.tubularDaylightDomeConstruction when 'TubularDaylightDiffuser' constructions << ext_subsurfs.tubularDaylightDiffuserConstruction # Interior SubSurfaces when 'InteriorWindow' constructions << int_subsurfs.fixedWindowConstruction constructions << int_subsurfs.operableWindowConstruction when 'InteriorDoor' constructions << int_subsurfs.doorConstruction end end # Hard-assigned surfaces model.getSurfaces.sort.each do |surface| next unless surface.outsideBoundaryCondition == boundary_condition if surface.surfaceType == 'Floor' || surface.surfaceType == 'Wall' next unless surface_type.include?(surface.surfaceType) elsif surface.surfaceType == 'RoofCeiling' next unless surface_type.include?('Roof') || surface_type.include?('Ceiling') end constructions << surface.construction end # Hard-assigned subsurfaces model.getSubSurfaces.sort.each do |surface| next unless surface.outsideBoundaryCondition == boundary_condition case surface.subSurfaceType when 'FixedWindow', 'OperableWindow' next unless surface_type == 'ExteriorWindow' when 'Door' next unless surface_type.include?('Door') else next unless surface.subSurfaceType == surface_type end constructions << surface.construction end # Throw out the empty constructions all_constructions = [] constructions.uniq.each do |construction| next if construction.empty? all_constructions << construction.get end # return unique sorted ConstructionBases all_constructions = all_constructions.uniq.sort return all_constructions end |
.surfaces_get_conductance(surfaces) ⇒ Double
Determine the weighted average conductance for a set of planar surfaces (surfaces or sub surfaces)
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/openstudio-standards/constructions/information.rb', line 196 def self.surfaces_get_conductance(surfaces) return nil if surfaces.empty? total_area = 0.0 temp = 0.0 surfaces.each do |surface| next unless surface.construction.is_initialized surface_construction = surface.model.getConstructionByName(surface.construction.get.name.to_s).get surface_conductance = OpenstudioStandards::Constructions.construction_get_conductance(surface_construction) temp += surface.netArea * surface_conductance total_area += surface.netArea end return nil if temp.zero? average_conductance = total_area.zero? ? 0.0 : temp / total_area return average_conductance end |
.surfaces_get_solar_transmittance(surfaces) ⇒ Double
Determine the weighted average solar transmittance for a set of planar surfaces (surfaces or sub surfaces)
219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/openstudio-standards/constructions/information.rb', line 219 def self.surfaces_get_solar_transmittance(surfaces) total_area = 0.0 temp = 0.0 surfaces.each do |surface| next unless surface.construction.is_initialized surface_construction = surface.model.getConstructionByName(surface.construction.get.name.to_s).get surface_shgc = OpenstudioStandards::Constructions.construction_get_solar_transmittance(surface_construction) temp += surface.netArea * surface_shgc total_area += surface.netArea end ave_shgc = total_area.zero? ? 1.0 : temp / total_area return ave_shgc end |
.surfaces_get_visible_transmittance(surfaces) ⇒ Double
Determine the weighted average visible transmittance for a set of planar surfaces (surfaces or sub surfaces)
238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/openstudio-standards/constructions/information.rb', line 238 def self.surfaces_get_visible_transmittance(surfaces) total_area = 0.0 temp = 0.0 surfaces.each do |surface| next unless surface.construction.is_initialized surface_construction = surface.model.getConstructionByName(surface.construction.get.name.to_s).get surface_tvis = OpenstudioStandards::Constructions.construction_get_visible_transmittance(surface_construction) temp += surface.netArea * surface_tvis total_area += surface.netArea end ave_tvis = total_area.zero? ? 1.0 : temp / total_area return ave_tvis end |