Skip to content

Commit 438e5f6

Browse files
authored
Merge pull request #528 from NREL/slab-hvac-sizing
Updates HVAC sizing code for slab-on-grade foundation types
2 parents d2aa946 + 4a96ad1 commit 438e5f6

3 files changed

Lines changed: 134 additions & 10 deletions

File tree

HPXMLtoOpenStudio/measure.xml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<schema_version>3.0</schema_version>
44
<name>hpxm_lto_openstudio</name>
55
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
6-
<version_id>516faf23-4510-4e76-a9c0-5870d42526f9</version_id>
7-
<version_modified>20201028T181202Z</version_modified>
6+
<version_id>28973ccc-3461-4c07-b3a9-345fd52ee38b</version_id>
7+
<version_modified>20201028T181823Z</version_modified>
88
<xml_checksum>D8922A73</xml_checksum>
99
<class_name>HPXMLtoOpenStudio</class_name>
1010
<display_name>HPXML to OpenStudio Translator</display_name>
@@ -429,12 +429,6 @@
429429
<usage_type>test</usage_type>
430430
<checksum>97E9A445</checksum>
431431
</file>
432-
<file>
433-
<filename>hvac_sizing.rb</filename>
434-
<filetype>rb</filetype>
435-
<usage_type>resource</usage_type>
436-
<checksum>E50CBF7E</checksum>
437-
</file>
438432
<file>
439433
<filename>test_hvac.rb</filename>
440434
<filetype>rb</filetype>
@@ -500,5 +494,17 @@
500494
<usage_type>resource</usage_type>
501495
<checksum>721A9C7B</checksum>
502496
</file>
497+
<file>
498+
<filename>hvac_sizing.rb</filename>
499+
<filetype>rb</filetype>
500+
<usage_type>resource</usage_type>
501+
<checksum>51B1E37F</checksum>
502+
</file>
503+
<file>
504+
<filename>test_hvac_sizing.rb</filename>
505+
<filetype>rb</filetype>
506+
<usage_type>test</usage_type>
507+
<checksum>35C3F156</checksum>
508+
</file>
503509
</files>
504510
</measure>

HPXMLtoOpenStudio/resources/hvac_sizing.rb

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,8 +866,8 @@ def self.process_load_floors(zone_loads, weather)
866866
next unless slab.is_thermal_boundary
867867

868868
if slab.interior_adjacent_to == HPXML::LocationLivingSpace # Slab-on-grade
869-
floor_ufactor = 0.1 # FIXME: Hard-coded
870-
zone_loads.Heat_Floors += floor_ufactor * slab.area * (@heat_setpoint - weather.data.GroundMonthlyTemps[0])
869+
f_value = calc_slab_f_value(slab)
870+
zone_loads.Heat_Floors += f_value * slab.exposed_perimeter * @htd
871871
elsif slab.interior_adjacent_to == HPXML::LocationBasementConditioned
872872
# Based on MJ 8th Ed. A12-7 and ASHRAE HoF 2013 pg 18.31 Eq 40
873873
# FIXME: Assumes slab is uninsulated?
@@ -2980,6 +2980,70 @@ def self.get_foundation_wall_properties(foundation_wall)
29802980
return u_wall_with_soil, u_wall_without_soil
29812981
end
29822982

2983+
def self.calc_slab_f_value(slab)
2984+
# Calculation for the F-values in Table 4A for slab foundations.
2985+
# Important pages are the Table values (pg. 344-345) and the software protocols
2986+
# in Appendix 12 (pg. 517-518).
2987+
ins_rvalue = slab.under_slab_insulation_r_value + slab.perimeter_insulation_r_value
2988+
ins_rvalue_edge = slab.perimeter_insulation_r_value
2989+
edge_ins_rvalue =
2990+
if slab.under_slab_insulation_spans_entire_slab
2991+
ins_length = 1000.0
2992+
else
2993+
ins_length = 0
2994+
if slab.under_slab_insulation_r_value > 0
2995+
ins_length += slab.under_slab_insulation_width
2996+
end
2997+
if slab.perimeter_insulation_r_value > 0
2998+
ins_length += slab.perimeter_insulation_depth
2999+
end
3000+
end
3001+
3002+
soil_r_per_foot = Material.Soil(12.0).rvalue
3003+
slab_r_gravel_per_inch = 0.65 # Based on calibration by Tony Fontanini
3004+
3005+
# Because of uncertainty pertaining to the effective path radius, F-values are calculated
3006+
# for six radii (8, 9, 10, 11, 12, and 13 feet) and averaged.
3007+
f_values = []
3008+
for path_radius in 8..13
3009+
u_effective = []
3010+
for radius in 0..path_radius
3011+
spl = [Math::PI * radius - 1, 0].max # soil path length (SPL)
3012+
3013+
# Concrete, gravel, and insulation
3014+
if radius == 0
3015+
r_concrete = 0.0
3016+
r_gravel = 0.0 # No gravel on edge
3017+
r_ins = ins_rvalue_edge
3018+
else
3019+
r_concrete = Material.Concrete(slab.thickness).rvalue
3020+
r_gravel = [slab_r_gravel_per_inch * (12.0 - slab.thickness), 0].max
3021+
if radius <= ins_length
3022+
r_ins = ins_rvalue
3023+
else
3024+
r_ins = 0.0
3025+
end
3026+
end
3027+
3028+
# Air Films = Indoor Finish + Indoor Air Film + Exposed Air Film (Figure A12-6 pg. 517)
3029+
r_air_film = 0.05 + 0.92 + 0.17
3030+
3031+
# Soil
3032+
r_soil = soil_r_per_foot * spl # (h-F-ft2/BTU)
3033+
3034+
# Effective R-Value
3035+
r_air_to_air = r_concrete + r_gravel + r_ins + r_air_film + r_soil
3036+
3037+
# Effective U-Factor
3038+
u_effective << 1.0 / r_air_to_air
3039+
end
3040+
3041+
f_values << u_effective.inject(0, :+) # sum array
3042+
end
3043+
3044+
return f_values.sum() / f_values.size
3045+
end
3046+
29833047
def self.get_feature(obj, feature, datatype, fail_on_error = true)
29843048
val = nil
29853049
if datatype == 'string'
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../resources/minitest_helper'
4+
require 'openstudio'
5+
require 'openstudio/measure/ShowRunnerOutput'
6+
require 'minitest/autorun'
7+
require 'fileutils'
8+
require_relative '../measure.rb'
9+
require_relative '../resources/util.rb'
10+
11+
class HPXMLtoOpenStudioHVACSizingTest < MiniTest::Test
12+
def sample_files_dir
13+
return File.join(File.dirname(__FILE__), '..', '..', 'workflow', 'sample_files')
14+
end
15+
16+
def test_slab_f_factor
17+
def get_unins_slab()
18+
slab = HPXML::Slab.new(nil)
19+
slab.thickness = 4.0 # in
20+
slab.perimeter_insulation_depth = 0
21+
slab.perimeter_insulation_r_value = 0
22+
slab.under_slab_insulation_width = 0
23+
slab.under_slab_insulation_spans_entire_slab = false
24+
slab.under_slab_insulation_r_value = 0
25+
return slab
26+
end
27+
28+
# Uninsulated slab
29+
slab = get_unins_slab()
30+
f_factor = HVACSizing.calc_slab_f_value(slab)
31+
assert_in_epsilon(1.41, f_factor, 0.01)
32+
33+
# R-10, 4ft under slab insulation
34+
slab = get_unins_slab()
35+
slab.under_slab_insulation_width = 4
36+
slab.under_slab_insulation_r_value = 10
37+
f_factor = HVACSizing.calc_slab_f_value(slab)
38+
assert_in_epsilon(1.27, f_factor, 0.01)
39+
40+
# R-20, 4ft perimeter insulation
41+
slab = get_unins_slab()
42+
slab.perimeter_insulation_depth = 4
43+
slab.perimeter_insulation_r_value = 20
44+
f_factor = HVACSizing.calc_slab_f_value(slab)
45+
assert_in_epsilon(0.39, f_factor, 0.01)
46+
47+
# R-40, whole slab insulation
48+
slab = get_unins_slab()
49+
slab.under_slab_insulation_spans_entire_slab = true
50+
slab.under_slab_insulation_r_value = 40
51+
f_factor = HVACSizing.calc_slab_f_value(slab)
52+
assert_in_epsilon(1.04, f_factor, 0.01)
53+
end
54+
end

0 commit comments

Comments
 (0)