openstudio-standards 0.2.15 → 0.2.16.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/geometry/ASHRAEHighriseApartment.osm +0 -27
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx +0 -0
- data/data/standards/test_performance_expected_dd_results.csv +710 -710
- data/lib/openstudio-standards/btap/btap_result.rb +2 -2
- data/lib/openstudio-standards/btap/reporting.rb +2 -2
- data/lib/openstudio-standards/btap/simmanager.rb +2 -2
- data/lib/openstudio-standards/hvac_sizing/Siz.ControllerOutdoorAir.rb +0 -54
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +11 -1
- data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +26 -5
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +35 -16
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +23 -10
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +36 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +6 -6
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +0 -3
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +2 -2
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +9 -3
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +2 -0
- data/lib/openstudio-standards/standards/Standards.Construction.rb +12 -6
- data/lib/openstudio-standards/standards/Standards.Model.rb +38 -7
- data/lib/openstudio-standards/standards/Standards.Space.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +7 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +32 -11
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +22 -742
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +3 -3
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +19 -559
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_sets.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +3 -3
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +19 -559
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_sets.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +19 -559
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +370 -910
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.prototype_inputs.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_system.json +0 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +12 -12
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +19 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +2380 -1300
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.prototype_inputs.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_system.json +0 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +12 -12
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +140 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +1176 -312
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_properties.json +172 -1132
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_sets.json +14 -14
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.prototype_inputs.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_properties.json +180 -1140
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_sets.json +14 -14
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.prototype_inputs.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.construction_properties.json +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.construction_properties.json +9 -9
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +12 -6
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +12 -6
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +16 -8
- data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +10 -20
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +209 -37
- data/lib/openstudio-standards/standards/necb/ECMS/loads.rb +1 -0
- data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +8 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +16 -9
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartment.osm +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LowriseApartment.osm +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/MidriseApartment.osm +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +9 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +10 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +9 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +14 -8
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +14 -8
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +13 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +12 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +4 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +38 -19
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +15 -4
- data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +10 -651
- data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +8 -38
- data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +159 -0
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +41 -43
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +7 -4
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards.rb +1 -0
- metadata +4 -2
@@ -1,13 +1,13 @@
|
|
1
1
|
# This class holds methods that apply NECB2020 rules.
|
2
2
|
|
3
3
|
# Notes for adding new version of NECB:
|
4
|
-
# Essentially all you need to do is copy this file to a new folder and update the class name
|
5
|
-
# files if the content has changed. Do not forget to update the class name in the rb files
|
4
|
+
# Essentially all you need to do is copy this file to a new folder and update the class name (only the initialize and load_standards_database_new methods are required,
|
5
|
+
# everything else will be inherited. Only add methods, json files and other rb files if the content/functionality has changed. Do not forget to update the class name in the rb files!
|
6
6
|
# The spacetypes and led lighting json files are required (in the data folder) as they have the NECB version hardcoded (which requires updating).
|
7
7
|
# However there are a few other files to update:
|
8
8
|
# 1) NECB2011/necb_2011.rb:determine_spacetype_vintage method has an array of available versions of NECB hardcoded. Add the new one.
|
9
9
|
# 2) common/space_type_upgrade_map.json needs all the space types for the new version defined (386 in NECB 2020).
|
10
|
-
# 3) Add references to the
|
10
|
+
# 3) Add references to the rb files in this folder to openstudio_standards.rb
|
11
11
|
|
12
12
|
# @ref [References::NECB2020]
|
13
13
|
class NECB2020 < NECB2017
|
@@ -21,8 +21,8 @@ class NECB2020 < NECB2017
|
|
21
21
|
self.corrupt_standards_database()
|
22
22
|
end
|
23
23
|
|
24
|
-
def load_standards_database_new
|
25
|
-
#load
|
24
|
+
def load_standards_database_new
|
25
|
+
# load NECB2020 data.
|
26
26
|
super()
|
27
27
|
|
28
28
|
if __dir__[0] == ':' # Running from OpenStudio CLI
|
@@ -37,7 +37,7 @@ class NECB2020 < NECB2017
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
else
|
40
|
-
files = Dir.glob("#{File.dirname(__FILE__)}/data/*.json").select {|e| File.file? e}
|
40
|
+
files = Dir.glob("#{File.dirname(__FILE__)}/data/*.json").select { |e| File.file? e }
|
41
41
|
files.each do |file|
|
42
42
|
data = JSON.parse(File.read(file))
|
43
43
|
if !data['tables'].nil?
|
@@ -49,41 +49,11 @@ class NECB2020 < NECB2017
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
52
|
-
#Write test report file.
|
52
|
+
# Write test report file.
|
53
53
|
# Write database to file.
|
54
|
-
# File.open(File.join(File.dirname(__FILE__), '..', '
|
55
|
-
|
54
|
+
# File.open(File.join(File.dirname(__FILE__), '..', 'NECB2017.json'), 'w') {|f| f.write(JSON.pretty_generate(@standards_data))}
|
56
55
|
return @standards_data
|
57
56
|
end
|
58
|
-
|
59
|
-
def set_lighting_per_area_led_lighting(space_type:, definition:, lighting_per_area_led_lighting:, lights_scale:)
|
60
|
-
|
61
|
-
# puts "#{space_type.name.to_s} - 'space_height' - #{space_height.to_s}"
|
62
|
-
#TODO: Note that 'occ_sens_lpd_frac' in this function has been removed for NECB2015 and 2017.
|
63
|
-
# ##### Since Atrium's LPD for LED lighting depends on atrium's height, the height of the atrium (if applicable) should be found.
|
64
|
-
standards_space_type = space_type.standardsSpaceType.is_initialized ? space_type.standardsSpaceType.get : nil #Sara
|
65
|
-
if standards_space_type.include? 'Atrium' # TODO: Note that since none of the archetypes has Atrium, this was tested for 'Dining'. #Atrium
|
66
|
-
puts "#{standards_space_type} - has atrium" # space_type.name.to_s
|
67
|
-
# puts space_height
|
68
|
-
if get_max_space_height_for_space_type(space_type: space_type) < 12.0
|
69
|
-
# TODO: Regarding the below equations, identify which version of ASHRAE 90.1 was used in NECB2017.
|
70
|
-
atrium_lpd_eq_smaller_12_intercept = 0
|
71
|
-
atrium_lpd_eq_smaller_12_slope = 1.06
|
72
|
-
atrium_lpd_eq_larger_12_intercept = 4.3
|
73
|
-
atrium_lpd_eq_larger_12_slope = 0.71
|
74
|
-
lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_smaller_12_intercept + atrium_lpd_eq_smaller_12_slope * space_height) * 0.092903 # W/ft2
|
75
|
-
else # i.e. get_max_space_height_for_space_type >= 12.0
|
76
|
-
lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_larger_12_intercept + atrium_lpd_eq_larger_12_slope * space_height) * 0.092903 # W/ft2
|
77
|
-
end
|
78
|
-
puts "#{standards_space_type} - has lighting_per_area_led_lighting_atrium - #{lighting_per_area_led_lighting_atrium}"
|
79
|
-
lighting_per_area_led_lighting = lighting_per_area_led_lighting_atrium
|
80
|
-
end
|
81
|
-
lighting_per_area_led_lighting *= lights_scale
|
82
|
-
|
83
|
-
definition.setWattsperSpaceFloorArea(OpenStudio.convert(lighting_per_area_led_lighting.to_f, 'W/ft^2', 'W/m^2').get)
|
84
|
-
|
85
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} set LPD to #{lighting_per_area_led_lighting} W/ft^2.")
|
86
|
-
end
|
87
57
|
|
88
58
|
# Set the infiltration rate for this space to include
|
89
59
|
# the impact of air leakage requirements in the standard.
|
@@ -0,0 +1,159 @@
|
|
1
|
+
class NECB2020
|
2
|
+
|
3
|
+
# Applies the standard efficiency ratings and typical losses and paraisitic loads to this object.
|
4
|
+
# Efficiency and skin loss coefficient (UA)
|
5
|
+
# Per PNNL http://www.energycodes.gov/sites/default/files/documents/PrototypeModelEnhancements_2014_0.pdf
|
6
|
+
# Appendix A: Service Water Heating
|
7
|
+
#
|
8
|
+
# @return [Bool] true if successful, false if not
|
9
|
+
#
|
10
|
+
# This was modified in PCF 1630
|
11
|
+
#
|
12
|
+
def water_heater_mixed_apply_efficiency(water_heater_mixed)
|
13
|
+
# Get the capacity of the water heater
|
14
|
+
# TODO add capability to pull autosized water heater capacity
|
15
|
+
# if the Sizing:WaterHeater object is ever implemented in OpenStudio.
|
16
|
+
capacity_w = water_heater_mixed.heaterMaximumCapacity
|
17
|
+
if capacity_w.empty?
|
18
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, cannot find capacity, standard will not be applied.")
|
19
|
+
return false
|
20
|
+
else
|
21
|
+
capacity_w = capacity_w.get
|
22
|
+
end
|
23
|
+
capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
|
24
|
+
capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
|
25
|
+
|
26
|
+
# Get the volume of the water heater
|
27
|
+
# TODO add capability to pull autosized water heater volume
|
28
|
+
# if the Sizing:WaterHeater object is ever implemented in OpenStudio.
|
29
|
+
volume_m3 = water_heater_mixed.tankVolume
|
30
|
+
if volume_m3.empty?
|
31
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, cannot find volume, standard will not be applied.")
|
32
|
+
return false
|
33
|
+
else
|
34
|
+
volume_m3 = volume_m3.get
|
35
|
+
end
|
36
|
+
volume_gal = OpenStudio.convert(volume_m3, 'm^3', 'gal').get
|
37
|
+
|
38
|
+
# Get the heater fuel type
|
39
|
+
fuel_type = water_heater_mixed.heaterFuelType
|
40
|
+
unless fuel_type == 'NaturalGas' || fuel_type == 'Electricity' || fuel_type == 'FuelOilNo2'
|
41
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, fuel type of #{fuel_type} is not yet supported, standard will not be applied.")
|
42
|
+
end
|
43
|
+
|
44
|
+
# Calculate the water heater efficiency and
|
45
|
+
# skin loss coefficient (UA)
|
46
|
+
# Calculate the energy factor (EF)
|
47
|
+
# From PNNL http://www.energycodes.gov/sites/default/files/documents/PrototypeModelEnhancements_2014_0.pdf
|
48
|
+
# Appendix A: Service Water Heating
|
49
|
+
# and modified by PCF 1630 as noted below.
|
50
|
+
water_heater_eff = nil
|
51
|
+
ua_btu_per_hr_per_f = nil
|
52
|
+
sl_btu_per_hr = nil
|
53
|
+
case fuel_type
|
54
|
+
when 'Electricity'
|
55
|
+
volume_l_per_s = volume_m3 * 1000
|
56
|
+
if capacity_btu_per_hr <= OpenStudio.convert(12, 'kW', 'Btu/hr').get
|
57
|
+
# Fixed water heater efficiency per PNNL
|
58
|
+
water_heater_eff = 1
|
59
|
+
# Calculate the max allowable standby loss (SL)
|
60
|
+
sl_w = if volume_l_per_s < 270
|
61
|
+
40 + 0.2 * volume_l_per_s # assume bottom inlet
|
62
|
+
else
|
63
|
+
0.472 * volume_l_per_s - 33.5
|
64
|
+
# assume bottom inlet
|
65
|
+
end
|
66
|
+
sl_btu_per_hr = OpenStudio.convert(sl_w, 'W', 'Btu/hr').get
|
67
|
+
else
|
68
|
+
# Fixed water heater efficiency per PNNL
|
69
|
+
water_heater_eff = 1
|
70
|
+
# Calculate the max allowable standby loss (SL) # use this - NECB does not give SL calculation for cap > 12 kW
|
71
|
+
sl_btu_per_hr = 20 + (35 * Math.sqrt(volume_gal))
|
72
|
+
end
|
73
|
+
# Calculate the skin loss coefficient (UA)
|
74
|
+
ua_btu_per_hr_per_f = sl_btu_per_hr / 70
|
75
|
+
when 'NaturalGas'
|
76
|
+
volume_l = volume_m3 / 1000
|
77
|
+
if capacity_btu_per_hr <= 75_000
|
78
|
+
# Fixed water heater thermal efficiency per PNNL
|
79
|
+
water_heater_eff = 0.82
|
80
|
+
|
81
|
+
# Calculate the minimum Energy Factor (EF) (This was introduced in PCF 1630)
|
82
|
+
if volume_l < 68
|
83
|
+
uef = 0.5982 - 0.0005 * volume_l
|
84
|
+
ef = 1.0005 * uef + 0.0019
|
85
|
+
elsif volume_l >= 68 and volume_l < 193
|
86
|
+
uef = 0.6483 - 0.00045 * volume_l
|
87
|
+
ef = 1.0005 * uef + 0.0019
|
88
|
+
elsif volume_l >= 193 and volume_l < 284
|
89
|
+
uef = 0.692 - 0.00034 * volume_l
|
90
|
+
ef = 1.0005 * uef + 0.0019
|
91
|
+
end
|
92
|
+
|
93
|
+
# Calculate the Recovery Efficiency (RE)
|
94
|
+
# based on a fixed capacity of 75,000 Btu/hr
|
95
|
+
# and a fixed volume of 40 gallons by solving
|
96
|
+
# this system of equations:
|
97
|
+
# ua = (1/.95-1/re)/(67.5*(24/41094-1/(re*cap)))
|
98
|
+
# 0.82 = (ua*67.5+cap*re)/cap
|
99
|
+
cap = 75_000.0
|
100
|
+
re = (Math.sqrt(6724 * ef**2 * cap**2 + 40_409_100 * ef**2 * cap - 28_080_900 * ef * cap + 29_318_000_625 * ef**2 - 58_636_001_250 * ef + 29_318_000_625) + 82 * ef * cap + 171_225 * ef - 171_225) / (200 * ef * cap)
|
101
|
+
|
102
|
+
# Calculate the skin loss coefficient (UA)
|
103
|
+
# based on the actual capacity.
|
104
|
+
ua_btu_per_hr_per_f = (water_heater_eff - re) * capacity_btu_per_hr / 67.5
|
105
|
+
|
106
|
+
# This capacity band was introduced in PCF 1630
|
107
|
+
elsif capacity_btu_per_hr > 75_000 and capacity_btu_per_hr < 103977 and volume_l < 454
|
108
|
+
water_heater_eff = 0.82
|
109
|
+
uef = 0.8107 - 0.00021 * volume_l
|
110
|
+
ef = 1.0005 * uef + 0.0019
|
111
|
+
cap = 103977
|
112
|
+
re = (Math.sqrt(6724 * ef**2 * cap**2 + 40_409_100 * ef**2 * cap - 28_080_900 * ef * cap + 29_318_000_625 * ef**2 - 58_636_001_250 * ef + 29_318_000_625) + 82 * ef * cap + 171_225 * ef - 171_225) / (200 * ef * cap)
|
113
|
+
|
114
|
+
# Calculate the skin loss coefficient (UA)
|
115
|
+
# based on the actual capacity.
|
116
|
+
ua_btu_per_hr_per_f = (water_heater_eff - re) * capacity_btu_per_hr / 67.5
|
117
|
+
else
|
118
|
+
# Thermal efficiency (PCF 1630 update)
|
119
|
+
et = 0.9
|
120
|
+
sl_w = 0.84 * capacity_btu_per_hr / 3412.412 / 0.234 + 16.57 * (volume_l ** 0.5)
|
121
|
+
sl_btu_per_hr = sl_w * 3.412
|
122
|
+
# Calculate the skin loss coefficient (UA)
|
123
|
+
ua_btu_per_hr_per_f = (sl_btu_per_hr * et) / 70
|
124
|
+
# Calculate water heater efficiency
|
125
|
+
water_heater_eff = (ua_btu_per_hr_per_f * 70 + capacity_btu_per_hr * et) / capacity_btu_per_hr
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Convert to SI
|
130
|
+
ua_btu_per_hr_per_c = OpenStudio.convert(ua_btu_per_hr_per_f, 'Btu/hr*R', 'W/K').get
|
131
|
+
|
132
|
+
# Set the water heater properties
|
133
|
+
# Efficiency
|
134
|
+
water_heater_mixed.setHeaterThermalEfficiency(water_heater_eff)
|
135
|
+
# Skin loss
|
136
|
+
water_heater_mixed.setOffCycleLossCoefficienttoAmbientTemperature(ua_btu_per_hr_per_c)
|
137
|
+
water_heater_mixed.setOnCycleLossCoefficienttoAmbientTemperature(ua_btu_per_hr_per_c)
|
138
|
+
# TODO: Parasitic loss (pilot light)
|
139
|
+
# PNNL document says pilot lights were removed, but IDFs
|
140
|
+
# still have the on/off cycle parasitic fuel consumptions filled in
|
141
|
+
water_heater_mixed.setOnCycleParasiticFuelType(fuel_type)
|
142
|
+
# self.setOffCycleParasiticFuelConsumptionRate(??)
|
143
|
+
water_heater_mixed.setOnCycleParasiticHeatFractiontoTank(0)
|
144
|
+
water_heater_mixed.setOffCycleParasiticFuelType(fuel_type)
|
145
|
+
# self.setOffCycleParasiticFuelConsumptionRate(??)
|
146
|
+
water_heater_mixed.setOffCycleParasiticHeatFractiontoTank(0.8)
|
147
|
+
|
148
|
+
# set part-load performance curve
|
149
|
+
if (fuel_type == 'NaturalGas') || (fuel_type == 'FuelOilNo2')
|
150
|
+
plf_vs_plr_curve = model_add_curve(water_heater_mixed.model, 'SWH-EFFFPLR-NECB2011')
|
151
|
+
water_heater_mixed.setPartLoadFactorCurve(plf_vs_plr_curve)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Append the name with standards information
|
155
|
+
water_heater_mixed.setName("#{water_heater_mixed.name} #{water_heater_eff.round(3)} Therm Eff")
|
156
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.WaterHeaterMixed', "For #{template}: #{water_heater_mixed.name}; thermal efficiency = #{water_heater_eff.round(3)}, skin-loss UA = #{ua_btu_per_hr_per_f.round}Btu/hr")
|
157
|
+
return true
|
158
|
+
end
|
159
|
+
end
|
@@ -408,9 +408,19 @@ class BTAPData
|
|
408
408
|
'NU' => 'Nunavut' }
|
409
409
|
building_type = 'Commercial'
|
410
410
|
province = provinces_names_map[model.getWeatherFile.stateProvinceRegion]
|
411
|
-
neb_eplus_fuel_map = { '
|
412
|
-
|
413
|
-
|
411
|
+
neb_eplus_fuel_map = {'Natural Gas' => {eplus_fuel_name: 'NaturalGas',
|
412
|
+
eplus_table_name: 'Annual and Peak Values - Natural Gas',
|
413
|
+
eplus_row_name: 'NaturalGas:Facility',
|
414
|
+
eplus_column_name: 'Natural Gas Annual Value'},
|
415
|
+
'Electricity' => {eplus_fuel_name: 'Electricity',
|
416
|
+
eplus_table_name: 'Annual and Peak Values - Electricity',
|
417
|
+
eplus_row_name: 'Electricity:Facility',
|
418
|
+
eplus_column_name: 'Electricity Annual Value'},
|
419
|
+
'Oil' => {eplus_fuel_name: 'FuelOilNo2',
|
420
|
+
eplus_table_name: 'Annual and Peak Values - Other',
|
421
|
+
eplus_row_name: 'FuelOilNo2:Facility',
|
422
|
+
eplus_column_name: 'Annual Value'}
|
423
|
+
}
|
414
424
|
economics_data['cost_utility_neb_total_cost_per_m_sq'] = 0.0
|
415
425
|
economics_data['cost_utility_ghg_total_kg_per_m_sq'] = 0.0
|
416
426
|
# Create a hash of the neb data.
|
@@ -424,32 +434,20 @@ class BTAPData
|
|
424
434
|
end
|
425
435
|
neb_fuel_cost = row['2020']
|
426
436
|
fuel_consumption_gj = 0.0
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
fuel_consumption_gj = model.sqlFile.get.execAndReturnFirstDouble(sql_command).is_initialized ? model.sqlFile.get.execAndReturnFirstDouble(sql_command).get : 0.0
|
436
|
-
else
|
437
|
-
sql_command = " SELECT Value FROM tabulardatawithstrings
|
438
|
-
WHERE ReportName='EnergyMeters'
|
439
|
-
AND ReportForString='Entire Facility'
|
440
|
-
AND TableName='Annual and Peak Values - Other'
|
441
|
-
AND RowName='#{ep_fuel}:Facility'
|
442
|
-
AND ColumnName='Annual Value'
|
443
|
-
AND Units='GJ'"
|
444
|
-
|
445
|
-
fuel_consumption_gj = model.sqlFile.get.execAndReturnFirstDouble(sql_command).is_initialized ? model.sqlFile.get.execAndReturnFirstDouble(sql_command).get : 0.0
|
446
|
-
end
|
437
|
+
sql_command = "SELECT Value FROM tabulardatawithstrings
|
438
|
+
WHERE ReportName='EnergyMeters'
|
439
|
+
AND ReportForString='Entire Facility'
|
440
|
+
AND TableName='#{ep_fuel[:eplus_table_name]}'
|
441
|
+
AND RowName='#{ep_fuel[:eplus_row_name]}'
|
442
|
+
AND ColumnName='#{ep_fuel[:eplus_column_name]}'
|
443
|
+
AND Units='GJ'"
|
444
|
+
fuel_consumption_gj = model.sqlFile.get.execAndReturnFirstDouble(sql_command).is_initialized ? model.sqlFile.get.execAndReturnFirstDouble(sql_command).get : 0.0
|
447
445
|
|
448
446
|
# Determine costs in $$
|
449
447
|
economics_data["cost_utility_neb_#{neb_fuel.downcase}_cost_per_m_sq"] = fuel_consumption_gj * neb_fuel_cost.to_f / @conditioned_floor_area_m_sq
|
450
448
|
economics_data['cost_utility_neb_total_cost_per_m_sq'] += economics_data["cost_utility_neb_#{neb_fuel.downcase}_cost_per_m_sq"]
|
451
449
|
# Determine cost in GHG kg of CO2
|
452
|
-
economics_data["cost_utility_ghg_#{neb_fuel.downcase}_kg_per_m_sq"] = fuel_consumption_gj * get_utility_ghg_kg_per_gj(province: model.getWeatherFile.stateProvinceRegion, fuel_type: ep_fuel) / @conditioned_floor_area_m_sq
|
450
|
+
economics_data["cost_utility_ghg_#{neb_fuel.downcase}_kg_per_m_sq"] = fuel_consumption_gj * get_utility_ghg_kg_per_gj(province: model.getWeatherFile.stateProvinceRegion, fuel_type: ep_fuel[:eplus_fuel_name]) / @conditioned_floor_area_m_sq
|
453
451
|
economics_data['cost_utility_ghg_total_kg_per_m_sq'] += economics_data["cost_utility_ghg_#{neb_fuel.downcase}_kg_per_m_sq"]
|
454
452
|
end
|
455
453
|
# Commenting out block charge rates for now....
|
@@ -1242,8 +1240,8 @@ class BTAPData
|
|
1242
1240
|
" AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Electricity' AND RowName='Electricity:Facility'" \
|
1243
1241
|
" AND ColumnName='Electricity Maximum Value' AND Units='W'")
|
1244
1242
|
natural_gas_peak = @model.sqlFile.get.execAndReturnFirstDouble("SELECT Value FROM tabulardatawithstrings WHERE ReportName='EnergyMeters'" \
|
1245
|
-
" AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Gas' AND RowName='
|
1246
|
-
" AND ColumnName='Gas Maximum Value' AND Units='W'")
|
1243
|
+
" AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Natural Gas' AND RowName='NaturalGas:Facility'" \
|
1244
|
+
" AND ColumnName='Natural Gas Maximum Value' AND Units='W'")
|
1247
1245
|
data['energy_peak_electric_w_per_m_sq'] = electric_peak.empty? ? 0.0 : electric_peak.get / @conditioned_floor_area_m_sq
|
1248
1246
|
data['energy_peak_natural_gas_w_per_m_sq'] = natural_gas_peak.empty? ? 0.0 : natural_gas_peak.get / @conditioned_floor_area_m_sq
|
1249
1247
|
|
@@ -1261,9 +1259,9 @@ class BTAPData
|
|
1261
1259
|
FROM TabularDataWithStrings
|
1262
1260
|
WHERE ReportName='EnergyMeters'
|
1263
1261
|
AND ReportForString='Entire Facility'
|
1264
|
-
AND TableName='Annual and Peak Values - Gas'
|
1262
|
+
AND TableName='Annual and Peak Values - Natural Gas'
|
1265
1263
|
AND RowName='Heating:Gas'
|
1266
|
-
AND ColumnName='Gas Maximum Value'
|
1264
|
+
AND ColumnName='Natural Gas Maximum Value'
|
1267
1265
|
AND Units='W'"
|
1268
1266
|
heating_peak_w_gas = @sqlite_file.get.execAndReturnFirstDouble(command)
|
1269
1267
|
heating_peak_w = [heating_peak_w_electricity.to_f, heating_peak_w_gas.to_f].max
|
@@ -1283,7 +1281,7 @@ class BTAPData
|
|
1283
1281
|
FROM TabularDataWithStrings
|
1284
1282
|
WHERE ReportName='EnergyMeters'
|
1285
1283
|
AND ReportForString='Entire Facility'
|
1286
|
-
AND TableName='Annual and Peak Values - Gas'
|
1284
|
+
AND TableName='Annual and Peak Values - Natural Gas'
|
1287
1285
|
AND RowName='Cooling:Electricity'
|
1288
1286
|
AND ColumnName='Electricity Maximum Value'
|
1289
1287
|
AND Units='W'"
|
@@ -1406,7 +1404,7 @@ class BTAPData
|
|
1406
1404
|
# ["InputVerificationandResultsSummary", "Entire Facility", "Skylight-Roof Ratio"],
|
1407
1405
|
# ["DemandEndUseComponentsSummary", "Entire Facility", "End Uses"],
|
1408
1406
|
# ["ComponentSizingSummary", "Entire Facility", "AirLoopHVAC"],
|
1409
|
-
# ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Gas'],
|
1407
|
+
# ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Natural Gas'],
|
1410
1408
|
# ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Electricity'],
|
1411
1409
|
# ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - FuelOilNo2'],
|
1412
1410
|
# ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Other'],
|
@@ -1648,19 +1646,19 @@ class BTAPData
|
|
1648
1646
|
def get_utility_ghg_kg_per_gj(province:, fuel_type:)
|
1649
1647
|
ghg_data = [
|
1650
1648
|
# Obtained from Portfolio Manager https://portfoliomanager.energystar.gov/pdf/reference/Emissions.pdf 10/10/2020
|
1651
|
-
{ "province": 'AB', "fuel_type": '
|
1652
|
-
{ "province": 'BC', "fuel_type": '
|
1653
|
-
{ "province": 'MB', "fuel_type": '
|
1654
|
-
{ "province": 'NB', "fuel_type": '
|
1655
|
-
{ "province": 'NL', "fuel_type": '
|
1656
|
-
{ "province": 'NT', "fuel_type": '
|
1657
|
-
{ "province": 'NS', "fuel_type": '
|
1658
|
-
{ "province": 'NU', "fuel_type": '
|
1659
|
-
{ "province": 'ON', "fuel_type": '
|
1660
|
-
{ "province": 'PE', "fuel_type": '
|
1661
|
-
{ "province": 'QC', "fuel_type": '
|
1662
|
-
{ "province": 'SK', "fuel_type": '
|
1663
|
-
{ "province": 'YT', "fuel_type": '
|
1649
|
+
{ "province": 'AB', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 53.24, "CO2eq Emissions (g/m3)": 1939.0 },
|
1650
|
+
{ "province": 'BC', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 53.19, "CO2eq Emissions (g/m3)": 1937.0 },
|
1651
|
+
{ "province": 'MB', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.09, "CO2eq Emissions (g/m3)": 1897.0 },
|
1652
|
+
{ "province": 'NB', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1653
|
+
{ "province": 'NL', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1654
|
+
{ "province": 'NT', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1655
|
+
{ "province": 'NS', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1656
|
+
{ "province": 'NU', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1657
|
+
{ "province": 'ON', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.14, "CO2eq Emissions (g/m3)": 1912.0 },
|
1658
|
+
{ "province": 'PE', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1659
|
+
{ "province": 'QC', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.12, "CO2eq Emissions (g/m3)": 1898.0 },
|
1660
|
+
{ "province": 'SK', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 50.53, "CO2eq Emissions (g/m3)": 1840.0 },
|
1661
|
+
{ "province": 'YT', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
|
1664
1662
|
|
1665
1663
|
{ "province": 'AB', "fuel_type": 'FuelOilNo2', "CO2eq Emissions (kg/MBtu)": 75.13, "CO2eq Emissions (g/m3)": 2763.0 },
|
1666
1664
|
{ "province": 'BC', "fuel_type": 'FuelOilNo2', "CO2eq Emissions (kg/MBtu)": 75.13, "CO2eq Emissions (g/m3)": 2763.0 },
|
@@ -2,7 +2,7 @@ require 'openstudio'
|
|
2
2
|
require 'securerandom'
|
3
3
|
require 'optparse'
|
4
4
|
require 'yaml'
|
5
|
-
#
|
5
|
+
#require 'git-revision'
|
6
6
|
# resource_folder = File.join(__dir__, '..', '..', 'measures/btap_results/resources')
|
7
7
|
# OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
8
8
|
|
@@ -113,6 +113,7 @@ class BTAPDatapoint
|
|
113
113
|
lights_scale: @options[:lights_scale],
|
114
114
|
daylighting_type: @options[:daylighting_type], # Two options: @options[: (1) 'NECB_Default', (2) 'add_daylighting_controls'
|
115
115
|
ecm_system_name: @options[:ecm_system_name],
|
116
|
+
ecm_system_zones_map_option: @options[:ecm_system_zones_map_option], # (1) 'NECB_Default' (2) 'one_sys_per_floor' (3) 'one_sys_per_bldg'
|
116
117
|
erv_package: @options[:erv_package],
|
117
118
|
boiler_eff: @options[:boiler_eff],
|
118
119
|
# Inconsistent naming Todo Chris K.
|
@@ -155,7 +156,9 @@ class BTAPDatapoint
|
|
155
156
|
chiller_type: @options[:chiller_type],
|
156
157
|
output_variables: @options[:output_variables],
|
157
158
|
output_meters: @options[:output_meters],
|
158
|
-
airloop_economizer_type: @options[:airloop_economizer_type]
|
159
|
+
airloop_economizer_type: @options[:airloop_economizer_type],
|
160
|
+
shw_scale: @options[:shw_scale],
|
161
|
+
baseline_system_zones_map_option: @options[:baseline_system_zones_map_option])
|
159
162
|
end
|
160
163
|
|
161
164
|
# Save model to to disk.
|
@@ -267,8 +270,8 @@ class BTAPDatapoint
|
|
267
270
|
end
|
268
271
|
|
269
272
|
def s3_copy_file_to_s3(bucket_name:, source_file:, target_file:, n: 0)
|
270
|
-
require 'aws-sdk-core'
|
271
|
-
require 'aws-sdk-s3'
|
273
|
+
# require 'aws-sdk-core'
|
274
|
+
# require 'aws-sdk-s3'
|
272
275
|
Aws.use_bundled_cert!
|
273
276
|
s3_resource = Aws::S3::Resource.new(region: 'ca-central-1')
|
274
277
|
|
data/lib/openstudio-standards.rb
CHANGED
@@ -55,6 +55,7 @@ module OpenstudioStandards
|
|
55
55
|
# NECB2020 Code
|
56
56
|
require_relative "#{stds}/necb/NECB2020/necb_2020"
|
57
57
|
require_relative "#{stds}/necb/NECB2020/building_envelope"
|
58
|
+
require_relative "#{stds}/necb/NECB2020/service_water_heating"
|
58
59
|
|
59
60
|
# BTAPPRE1980
|
60
61
|
require_relative "#{stds}/necb/BTAPPRE1980/btap_pre1980"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstudio-standards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.16.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Parker
|
@@ -28,7 +28,7 @@ authors:
|
|
28
28
|
autorequire:
|
29
29
|
bindir: bin
|
30
30
|
cert_chain: []
|
31
|
-
date:
|
31
|
+
date: 2022-03-18 00:00:00.000000000 Z
|
32
32
|
dependencies:
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: minitest-reporters
|
@@ -640,6 +640,7 @@ files:
|
|
640
640
|
- data/geometry/DOERefWarehouse.json
|
641
641
|
- data/geometry/DOERefWarehouse.osm
|
642
642
|
- data/standards/OpenStudio_Standards-ashrae_90_1.xlsx
|
643
|
+
- data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx
|
643
644
|
- data/standards/exclude_list.csv
|
644
645
|
- data/standards/export_OpenStudio_libraries.rb
|
645
646
|
- data/standards/legacy_dd_results.csv
|
@@ -2879,6 +2880,7 @@ files:
|
|
2879
2880
|
- lib/openstudio-standards/standards/necb/NECB2020/data/surface_thermal_transmittance.json
|
2880
2881
|
- lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json
|
2881
2882
|
- lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb
|
2883
|
+
- lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb
|
2882
2884
|
- lib/openstudio-standards/standards/necb/common/bc_step_code_indicators.md
|
2883
2885
|
- lib/openstudio-standards/standards/necb/common/btap_data.rb
|
2884
2886
|
- lib/openstudio-standards/standards/necb/common/btap_datapoint.rb
|