Skip to content

Commit

Permalink
Added logic for adiabatic surfaces. Added adiabatic HPXML test file a…
Browse files Browse the repository at this point in the history
…nd windows test. Some code simplification.
  • Loading branch information
shorowit committed May 30, 2019
1 parent 6b61ad1 commit 7a5ebfc
Show file tree
Hide file tree
Showing 4 changed files with 480 additions and 45 deletions.
31 changes: 30 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def create_hpxmls
'base-dhw-uef.xml' => 'base.xml',
'base-enclosure-2stories.xml' => 'base.xml',
'base-enclosure-2stories-garage.xml' => 'base-enclosure-2stories.xml',
'base-enclosure-adiabatic-surfaces.xml' => 'base.xml',
'base-enclosure-garage.xml' => 'base.xml',
'base-enclosure-infil-cfm50.xml' => 'base.xml',
'base-enclosure-no-natural-ventilation.xml' => 'base.xml',
Expand Down Expand Up @@ -732,6 +733,8 @@ def get_hpxml_file_roofs_values(hpxml_file, roofs_values)
:pitch => 6,
:radiant_barrier => false,
:insulation_assembly_r_value => 2.3 }
elsif ['base-enclosure-adiabatic-surfaces.xml'].include? hpxml_file
roofs_values = []
end
return roofs_values
end
Expand Down Expand Up @@ -784,6 +787,12 @@ def get_hpxml_file_rim_joists_values(hpxml_file, rim_joists_values)
:solar_absorptance => 0.75,
:emittance => 0.9,
:insulation_assembly_r_value => 23.0 }
elsif ['base-enclosure-adiabatic-surfaces.xml'].include? hpxml_file
rim_joists_values << rim_joists_values[0].dup
rim_joists_values[0][:area] *= 0.25
rim_joists_values[-1][:area] *= 0.75
rim_joists_values[-1][:id] += "Adiabatic"
rim_joists_values[-1][:exterior_adjacent_to] = "other housing unit"
end
return rim_joists_values
end
Expand Down Expand Up @@ -930,6 +939,13 @@ def get_hpxml_file_walls_values(hpxml_file, walls_values)
:solar_absorptance => 0.75,
:emittance => 0.9,
:insulation_assembly_r_value => 4 }]
elsif ['base-enclosure-adiabatic-surfaces.xml'].include? hpxml_file
walls_values.delete_at(1)
walls_values << walls_values[0].dup
walls_values[0][:area] *= 0.25
walls_values[-1][:area] *= 0.75
walls_values[-1][:id] += "Adiabatic"
walls_values[-1][:exterior_adjacent_to] = "other housing unit"
end
return walls_values
end
Expand Down Expand Up @@ -993,6 +1009,12 @@ def get_hpxml_file_foundation_walls_values(hpxml_file, foundation_walls_values)
hpxml_file.include? 'hvac_dse' or
hpxml_file.include? 'hvac_load_fracs'
foundation_walls_values = []
elsif ['base-enclosure-adiabatic-surfaces.xml'].include? hpxml_file
foundation_walls_values << foundation_walls_values[0].dup
foundation_walls_values[0][:area] *= 0.25
foundation_walls_values[-1][:area] *= 0.75
foundation_walls_values[-1][:id] += "Adiabatic"
foundation_walls_values[-1][:exterior_adjacent_to] = "other housing unit"
end
return foundation_walls_values
end
Expand Down Expand Up @@ -1054,6 +1076,12 @@ def get_hpxml_file_floors_values(hpxml_file, floors_values)
:interior_adjacent_to => "living space",
:area => 400,
:insulation_assembly_r_value => 18.7 }
elsif ['base-enclosure-adiabatic-surfaces.xml'].include? hpxml_file
floors_values = [{ :id => "FloorAboveAdiabatic",
:exterior_adjacent_to => "other housing unit",
:interior_adjacent_to => "living space",
:area => 1350,
:insulation_assembly_r_value => 39.3 }]
end
return floors_values
end
Expand Down Expand Up @@ -1842,7 +1870,8 @@ def get_hpxml_file_ducts_values(hpxml_file, ducts_values)
elsif ['base-atticroof-vented.xml'].include? hpxml_file
ducts_values[0][0][:duct_location] = "attic - vented"
ducts_values[0][1][:duct_location] = "attic - vented"
elsif ['base-atticroof-conditioned.xml'].include? hpxml_file
elsif ['base-atticroof-conditioned.xml',
'base-enclosure-adiabatic-surfaces.xml'].include? hpxml_file
ducts_values[0][0][:duct_location] = "living space"
ducts_values[0][1][:duct_location] = "living space"
elsif ['base-enclosure-garage.xml',
Expand Down
63 changes: 20 additions & 43 deletions measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -642,32 +642,25 @@ def self.check_for_errors(runner, model)
# 2. At least one roofceiling surface
# 3. At least one surface adjacent to outside/ground
model.getThermalZones.each do |zone|
n_floors = 0
n_roofsceilings = 0
n_floorsroofsceilings = 0
n_exteriors = 0
zone.spaces.each do |space|
space.surfaces.each do |surface|
if ["outdoors", "foundation"].include? surface.outsideBoundaryCondition.downcase
n_exteriors += 1
end
if surface.surfaceType.downcase == "floor"
n_floors += 1
elsif surface.surfaceType.downcase == "roofceiling"
n_roofsceilings += 1
if ["floor", "roofceiling"].include? surface.surfaceType.downcase
n_floorsroofsceilings += 1
end
end
end

if n_floors == 0
runner.registerError("Thermal zone '#{zone.name}' must have at least one floor surface.")
end
if n_roofsceilings == 0
runner.registerError("Thermal zone '#{zone.name}' must have at least one roof/ceiling surface.")
if n_floorsroofsceilings < 1
runner.registerError("Thermal zone '#{zone.name}' must have at least two floor/roof/ceiling surfaces.")
return false
end
if n_exteriors == 0
runner.registerError("Thermal zone '#{zone.name}' must have at least one surface adjacent to outside/ground.")
end
if n_floors == 0 or n_roofsceilings == 0 or n_exteriors == 0
return false
end
end
Expand Down Expand Up @@ -903,7 +896,7 @@ def self.add_roofs(runner, model, building, spaces)
set_surface_interior(model, spaces, surface, roof_values[:id], roof_values[:interior_adjacent_to])

# Apply construction
if is_external_thermal_boundary(roof_values[:interior_adjacent_to], roof_values[:exterior_adjacent_to])
if is_thermal_boundary(roof_values)
drywall_thick_in = 0.5
else
drywall_thick_in = 0.0
Expand Down Expand Up @@ -974,7 +967,7 @@ def self.add_walls(runner, model, building, spaces)
# The code below constructs a reasonable wall construction based on the
# wall type while ensuring the correct assembly R-value.

if is_external_thermal_boundary(wall_values[:interior_adjacent_to], wall_values[:exterior_adjacent_to])
if is_thermal_boundary(wall_values)
drywall_thick_in = 0.5
else
drywall_thick_in = 0.0
Expand Down Expand Up @@ -1022,7 +1015,7 @@ def self.add_rim_joists(runner, model, building, spaces)

# Apply construction

if is_external_thermal_boundary(rim_joist_values[:interior_adjacent_to], rim_joist_values[:exterior_adjacent_to])
if is_thermal_boundary(rim_joist_values)
drywall_thick_in = 0.5
else
drywall_thick_in = 0.0
Expand Down Expand Up @@ -1088,7 +1081,7 @@ def self.add_floors(runner, model, building, spaces)

# Apply construction

if is_external_thermal_boundary(floor_values[:interior_adjacent_to], floor_values[:exterior_adjacent_to])
if is_thermal_boundary(floor_values)
drywall_thick_in = 0.5
else
drywall_thick_in = 0.0
Expand Down Expand Up @@ -1195,7 +1188,7 @@ def self.add_foundation_walls_slabs(runner, model, building, spaces)
set_surface_interior(model, spaces, surface, fnd_wall_values[:id], fnd_wall_values[:interior_adjacent_to])
set_surface_exterior(model, spaces, surface, fnd_wall_values[:id], fnd_wall_values[:exterior_adjacent_to])

if is_external_thermal_boundary(fnd_wall_values[:interior_adjacent_to], fnd_wall_values[:exterior_adjacent_to])
if is_thermal_boundary(fnd_wall_values)
drywall_thick_in = 0.5
else
drywall_thick_in = 0.0
Expand Down Expand Up @@ -3627,38 +3620,22 @@ def to_beopt_wh_type(type)
'heat pump water heater' => Constants.WaterHeaterTypeHeatPump }[type]
end

def is_external_thermal_boundary(interior_adjacent_to, exterior_adjacent_to)
interior_conditioned = is_adjacent_to_conditioned(interior_adjacent_to)
exterior_conditioned = is_adjacent_to_conditioned(exterior_adjacent_to)
def is_thermal_boundary(surface_values)
if surface_values[:exterior_adjacent_to] == "other housing unit"
return false # adiabatic
end

interior_conditioned = is_adjacent_to_conditioned(surface_values[:interior_adjacent_to])
exterior_conditioned = is_adjacent_to_conditioned(surface_values[:exterior_adjacent_to])
return (interior_conditioned != exterior_conditioned)
end

def is_adjacent_to_conditioned(adjacent_to)
if adjacent_to == "living space"
return true
elsif adjacent_to == "garage"
return false
elsif adjacent_to == "attic - vented"
return false
elsif adjacent_to == "attic - unvented"
return false
elsif adjacent_to == "basement - unconditioned"
return false
elsif adjacent_to == "basement - conditioned"
return true
elsif adjacent_to == "crawlspace - vented"
return false
elsif adjacent_to == "crawlspace - unvented"
return false
elsif adjacent_to == "outside"
return false
elsif adjacent_to == "ground"
return false
elsif adjacent_to == "other housing unit"
if ["living space", "basement - conditioned"].include? adjacent_to
return true
end

fail "Unexpected AdjacentTo (#{adjacent_to})."
return false
end

def hpxml_floor_is_ceiling(floor_interior_adjacent_to, floor_exterior_adjacent_to)
Expand Down
2 changes: 1 addition & 1 deletion resources/EPvalidator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def self.run_validator(hpxml_doc)
"/HPXML/Building/BuildingDetails/Enclosure/AirInfiltration[AirInfiltrationMeasurement[HousePressure=50]/BuildingAirLeakage[UnitofMeasure='ACH' or UnitofMeasure='CFM']/AirLeakage | AirInfiltrationMeasurement/extension/ConstantACHnatural]" => one, # ACH50, CFM50, or constant nACH; see [AirInfiltration]
"/HPXML/Building/BuildingDetails/Enclosure/AirInfiltration/AirInfiltrationMeasurement/InfiltrationVolume" => zero_or_one, # Assumes InfiltrationVolume = ConditionedVolume if not provided

"/HPXML/Building/BuildingDetails/Enclosure/Roofs/Roof" => one_or_more, # See [Roof]
"/HPXML/Building/BuildingDetails/Enclosure/Roofs/Roof" => zero_or_more, # See [Roof]
"/HPXML/Building/BuildingDetails/Enclosure/Walls/Wall" => one_or_more, # See [Wall]
"/HPXML/Building/BuildingDetails/Enclosure/RimJoists/RimJoist" => zero_or_more, # See [RimJoist]
"/HPXML/Building/BuildingDetails/Enclosure/FoundationWalls/FoundationWall" => zero_or_more, # See [FoundationWall]
Expand Down
Loading

0 comments on commit 7a5ebfc

Please sign in to comment.