openstudio-standards 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openstudio-standards/exterior_lighting/create.rb +2 -2
- data/lib/openstudio-standards/exterior_lighting/data/convert_entryway_data.rb +94 -0
- data/lib/openstudio-standards/exterior_lighting/data/convert_parking_data.rb +82 -0
- data/lib/openstudio-standards/exterior_lighting/data/entryways.json +565 -0
- data/lib/openstudio-standards/exterior_lighting/data/parking.json +428 -0
- data/lib/openstudio-standards/exterior_lighting/information.rb +14 -14
- data/lib/openstudio-standards/hvac/components/create.rb +4 -4
- data/lib/openstudio-standards/hvac/components/modify.rb +2 -2
- data/lib/openstudio-standards/hvac/exhaust/create_exhaust_fan.rb +2 -2
- data/lib/openstudio-standards/hvac/exhaust/data/convert_typical_exhaust_data.rb +67 -0
- data/lib/openstudio-standards/infiltration/data/NISTInfiltrationCorrelations.json +3172 -0
- data/lib/openstudio-standards/infiltration/data/convert_infiltration_data.rb +87 -0
- data/lib/openstudio-standards/infiltration/infiltration.rb +3 -3
- data/lib/openstudio-standards/infiltration/nist_infiltration.rb +42 -42
- data/lib/openstudio-standards/refrigeration/create_case.rb +2 -2
- data/lib/openstudio-standards/refrigeration/create_typical_refrigeration.rb +22 -21
- data/lib/openstudio-standards/service_water_heating/create_typical.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Space.rb +3 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +10 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +131 -107
- data/lib/openstudio-standards/standards/deer/data/deer.schedules.json +24 -24
- data/lib/openstudio-standards/utilities/ruleset_check.rb +1 -2
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/stat_file.rb +13 -4
- metadata +9 -3
- data/lib/openstudio-standards/hvac/exhaust/data/convert_data.rb +0 -86
@@ -0,0 +1,87 @@
|
|
1
|
+
# These methods convert infiltration data to and from .csv for editing.
|
2
|
+
private
|
3
|
+
|
4
|
+
require 'csv'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
def infiltration_csv_to_json(input_csv = 'NISTInfiltrationCorrelations.csv',
|
8
|
+
output_json = 'NISTInfiltrationCorrelations.json')
|
9
|
+
# Initialize the structure
|
10
|
+
result = {
|
11
|
+
infiltration: []
|
12
|
+
}
|
13
|
+
|
14
|
+
# Read the CSV file
|
15
|
+
CSV.foreach(input_csv, headers: true, header_converters: :symbol) do |row|
|
16
|
+
building_type = row[:building_type]
|
17
|
+
climate_zone = row[:climate_zone]
|
18
|
+
air_barrier = row[:air_barrier]
|
19
|
+
hvac_status = row[:hvac_status]
|
20
|
+
a = row[:a]&.to_f
|
21
|
+
b = row[:b]&.to_f
|
22
|
+
d = row[:d]&.to_f
|
23
|
+
|
24
|
+
infiltration_hash = {
|
25
|
+
building_type: building_type,
|
26
|
+
climate_zone: climate_zone,
|
27
|
+
air_barrier: air_barrier,
|
28
|
+
hvac_status: hvac_status,
|
29
|
+
a: a,
|
30
|
+
b: b,
|
31
|
+
d: d
|
32
|
+
}
|
33
|
+
|
34
|
+
# Add the space_type_hash to the result array
|
35
|
+
result[:infiltration] << infiltration_hash
|
36
|
+
end
|
37
|
+
|
38
|
+
# Write to the output JSON file
|
39
|
+
File.write(output_json, JSON.pretty_generate(result))
|
40
|
+
|
41
|
+
puts "Data has been converted to JSON and saved to #{output_json}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# convert to json
|
45
|
+
infiltration_csv_to_json
|
46
|
+
|
47
|
+
def infiltration_json_to_csv(input_json = 'NISTInfiltrationCorrelations.json',
|
48
|
+
output_csv = 'NISTInfiltrationCorrelations.csv')
|
49
|
+
# Read the JSON file
|
50
|
+
data = JSON.parse(File.read(input_json), symbolize_names: true)
|
51
|
+
|
52
|
+
# Prepare the CSV headers
|
53
|
+
headers = [
|
54
|
+
:building_type,
|
55
|
+
:climate_zone,
|
56
|
+
:air_barrier,
|
57
|
+
:hvac_status,
|
58
|
+
:a,
|
59
|
+
:b,
|
60
|
+
:d
|
61
|
+
]
|
62
|
+
|
63
|
+
# Write the CSV file
|
64
|
+
CSV.open(output_csv, 'w', write_headers: true, headers: headers) do |csv|
|
65
|
+
data[:infiltration].each do |infiltration_entry|
|
66
|
+
building_type = infiltration_entry[:building_type]
|
67
|
+
climate_zone = infiltration_entry[:climate_zone]
|
68
|
+
air_barrier = infiltration_entry[:air_barrier]
|
69
|
+
hvac_status = infiltration_entry[:hvac_status]
|
70
|
+
a = infiltration_entry[:a]
|
71
|
+
b = infiltration_entry[:b]
|
72
|
+
d = infiltration_entry[:d]
|
73
|
+
|
74
|
+
csv << [
|
75
|
+
building_type,
|
76
|
+
climate_zone,
|
77
|
+
air_barrier,
|
78
|
+
hvac_status,
|
79
|
+
a,
|
80
|
+
b,
|
81
|
+
d
|
82
|
+
]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
puts "Data has been converted to CSV and saved to #{output_csv}"
|
87
|
+
end
|
@@ -96,7 +96,7 @@ module OpenstudioStandards
|
|
96
96
|
infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['slab_on_grade']
|
97
97
|
end
|
98
98
|
else
|
99
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "Could not determine infiltration surface type for #{surface.name}, defaulting to 0 component infiltration rate.")
|
99
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.infiltration', "Could not determine infiltration surface type for #{surface.name}, defaulting to 0 component infiltration rate.")
|
100
100
|
return 0.0
|
101
101
|
end
|
102
102
|
|
@@ -156,14 +156,14 @@ module OpenstudioStandards
|
|
156
156
|
when 'OverheadDoor'
|
157
157
|
infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['loading_dock_door']
|
158
158
|
when 'GlassDoor'
|
159
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Assuming swinging_or_revolving_glass_door for #{sub_surface.name} for component infiltration rate.")
|
159
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.infiltration', "Assuming swinging_or_revolving_glass_door for #{sub_surface.name} for component infiltration rate.")
|
160
160
|
infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['swinging_or_revolving_glass_door']
|
161
161
|
when 'FixedWindow', 'OperableWindow'
|
162
162
|
infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['window']
|
163
163
|
when 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser'
|
164
164
|
infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['skylight']
|
165
165
|
else
|
166
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "Could not determine infiltration sub surface type for #{sub_surface.name}, defaulting to 0 component infiltration rate.")
|
166
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.infiltration', "Could not determine infiltration sub surface type for #{sub_surface.name}, defaulting to 0 component infiltration rate.")
|
167
167
|
return 0.0
|
168
168
|
end
|
169
169
|
|
@@ -51,11 +51,11 @@ module OpenstudioStandards
|
|
51
51
|
else
|
52
52
|
nist_building_type = 'RetailStripmall'
|
53
53
|
end
|
54
|
-
when 'RetailStripmall', 'StripMall', 'Warehouse', 'QuickServiceRestaurant', 'FullServiceRestaurant', 'RtS', 'RSD', 'RFF', 'SCn', 'SUn', 'WRf'
|
54
|
+
when 'RetailStripmall', 'StripMall', 'Warehouse', 'QuickServiceRestaurant', 'FullServiceRestaurant', 'RtS', 'RSD', 'RFF', 'SCn', 'SUn', 'WRf', 'Asm', 'MLI'
|
55
55
|
nist_building_type = 'RetailStripmall'
|
56
|
-
when 'RetailStandalone', 'SuperMarket', 'RtL', 'Gro'
|
56
|
+
when 'RetailStandalone', 'SuperMarket', 'RtL', 'Rt3', 'Gro'
|
57
57
|
nist_building_type = 'RetailStandalone'
|
58
|
-
when 'PrimarySchool', 'EPr'
|
58
|
+
when 'PrimarySchool', 'EPr', 'ERC'
|
59
59
|
nist_building_type = 'PrimarySchool'
|
60
60
|
when 'SecondarySchool', 'ESe'
|
61
61
|
nist_building_type = 'SecondarySchool'
|
@@ -63,26 +63,26 @@ module OpenstudioStandards
|
|
63
63
|
nist_building_type = 'SmallHotel'
|
64
64
|
when 'LargeHotel', 'Htl'
|
65
65
|
nist_building_type = 'LargeHotel'
|
66
|
-
when 'Hospital', 'Hsp'
|
66
|
+
when 'Hospital', 'Hsp', 'Nrs'
|
67
67
|
nist_building_type = 'Hospital'
|
68
|
-
when 'MidriseApartment'
|
68
|
+
when 'MidriseApartment', 'MFm'
|
69
69
|
nist_building_type = 'MidriseApartment'
|
70
70
|
when 'HighriseApartment'
|
71
71
|
nist_building_type = 'HighriseApartment'
|
72
72
|
when 'TallBuilding', 'SuperTallBuilding'
|
73
73
|
nist_building_type = 'LargeHotel'
|
74
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "NIST coefficients aren't available for model building type #{model_building_type}. Since the building type is for a tall building, using nist building type #{nist_building_type} to best represent infiltration coefficients.")
|
75
|
-
when 'College', 'Laboratory'
|
74
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.nist_infiltration', "NIST coefficients aren't available for model building type #{model_building_type}. Since the building type is for a tall building, using nist building type #{nist_building_type} to best represent infiltration coefficients.")
|
75
|
+
when 'College', 'Laboratory', 'EUn', 'ECC', 'MBT'
|
76
76
|
nist_building_type = 'SecondarySchool'
|
77
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "NIST coefficients aren't available for model building type #{model_building_type}. Since the building may involve complex geometry, using nist building type #{nist_building_type} to best represent infiltration coefficients.")
|
77
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.nist_infiltration', "NIST coefficients aren't available for model building type #{model_building_type}. Since the building may involve complex geometry, using nist building type #{nist_building_type} to best represent infiltration coefficients.")
|
78
78
|
when 'Courthouse'
|
79
79
|
nist_building_type = 'MediumOffice'
|
80
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "NIST coefficients aren't available for model building type #{model_building_type}. Using nist building type #{nist_building_type} to best represent infiltration coefficients.")
|
80
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.nist_infiltration', "NIST coefficients aren't available for model building type #{model_building_type}. Using nist building type #{nist_building_type} to best represent infiltration coefficients.")
|
81
81
|
else
|
82
82
|
nist_building_type = model_building_type
|
83
83
|
end
|
84
84
|
|
85
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Using building type #{nist_building_type} for model building type #{model_building_type}.")
|
85
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "Using building type #{nist_building_type} for model building type #{model_building_type}.")
|
86
86
|
|
87
87
|
return nist_building_type
|
88
88
|
end
|
@@ -112,18 +112,18 @@ module OpenstudioStandards
|
|
112
112
|
nist_building_type: nil)
|
113
113
|
# validate airtightness value and pressure
|
114
114
|
if airtightness_value < 0.0
|
115
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', 'Airtightness value must be postive.')
|
115
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', 'Airtightness value must be postive.')
|
116
116
|
return false
|
117
117
|
end
|
118
118
|
|
119
119
|
if airtightness_pressure < 0.0
|
120
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', 'Airtightness pressure must be postive.')
|
120
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', 'Airtightness pressure must be postive.')
|
121
121
|
return false
|
122
122
|
end
|
123
123
|
|
124
124
|
# calculate infiltration design value at 4 Pa
|
125
125
|
airtightness_value_4pa_per_hr = airtightness_value * ((4.0 / airtightness_pressure)**0.65)
|
126
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "User-inputed airtightness design value #{airtightness_value} (m^3/h-m^2) at #{airtightness_pressure} Pa converts to #{airtightness_value_4pa_per_hr.round(7)} (m^3/h-m^2) at 4 Pa")
|
126
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "User-inputed airtightness design value #{airtightness_value} (m^3/h-m^2) at #{airtightness_pressure} Pa converts to #{airtightness_value_4pa_per_hr.round(7)} (m^3/h-m^2) at 4 Pa")
|
127
127
|
|
128
128
|
# convert to m^3/s-m^2
|
129
129
|
airtightness_value_4pa_per_s = airtightness_value_4pa_per_hr / 3600.0
|
@@ -150,19 +150,19 @@ module OpenstudioStandards
|
|
150
150
|
five_sided_area = exterior_wall_area + ground_wall_area + exterior_roof_area + ground_roof_area
|
151
151
|
six_sided_area = exterior_wall_area + ground_wall_area + exterior_roof_area + ground_roof_area + exterior_floor_area + ground_floor_area
|
152
152
|
energy_plus_area = exterior_wall_area + exterior_roof_area
|
153
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "4-sided area = #{four_sided_area.round(2)} m^2, 5-sided area = #{five_sided_area.round(2)} m^2, 6-sided area = #{six_sided_area.round(2)} m^2.")
|
153
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "4-sided area = #{four_sided_area.round(2)} m^2, 5-sided area = #{five_sided_area.round(2)} m^2, 6-sided area = #{six_sided_area.round(2)} m^2.")
|
154
154
|
|
155
155
|
# The SpaceInfiltrationDesignFlowRate object FlowperExteriorSurfaceArea method only counts surfaces with the 'Outdoors' boundary conditions towards exterior surface area, not surfaces with the 'Ground' boundary conditions. That means all values need to be normalized to exterior wall and roof area.
|
156
156
|
case airtightness_area_covered
|
157
157
|
when '4-sided'
|
158
158
|
design_infiltration_4pa = airtightness_value_4pa_per_s * (four_sided_area / energy_plus_area)
|
159
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 4-sided area #{four_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.")
|
159
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 4-sided area #{four_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.")
|
160
160
|
when '5-sided'
|
161
161
|
design_infiltration_4pa = airtightness_value_4pa_per_s * (five_sided_area / energy_plus_area)
|
162
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 5-sided area #{five_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.")
|
162
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 5-sided area #{five_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.")
|
163
163
|
when '6-sided'
|
164
164
|
design_infiltration_4pa = airtightness_value_4pa_per_s * (six_sided_area / energy_plus_area)
|
165
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 6-sided area #{six_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.")
|
165
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 6-sided area #{six_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.")
|
166
166
|
end
|
167
167
|
|
168
168
|
# validate hvac schedule
|
@@ -171,7 +171,7 @@ module OpenstudioStandards
|
|
171
171
|
else
|
172
172
|
hvac_schedule = model.getScheduleByName(hvac_schedule_name)
|
173
173
|
unless hvac_schedule.is_initialized
|
174
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} not found in the model. It may have been removed by another measure.")
|
174
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', "HVAC schedule argument #{hvac_schedule} not found in the model. It may have been removed by another measure.")
|
175
175
|
return false
|
176
176
|
end
|
177
177
|
hvac_schedule = hvac_schedule.get
|
@@ -180,16 +180,16 @@ module OpenstudioStandards
|
|
180
180
|
elsif hvac_schedule.to_ScheduleConstant.is_initialized
|
181
181
|
hvac_schedule = hvac_schedule.to_ScheduleConstant.get
|
182
182
|
else
|
183
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} is not a Schedule Constant or Schedule Ruleset object.")
|
183
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', "HVAC schedule argument #{hvac_schedule} is not a Schedule Constant or Schedule Ruleset object.")
|
184
184
|
return false
|
185
185
|
end
|
186
186
|
|
187
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Using HVAC schedule #{hvac_schedule.name} from user arguments to determine infiltration on/off schedule.")
|
187
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "Using HVAC schedule #{hvac_schedule.name} from user arguments to determine infiltration on/off schedule.")
|
188
188
|
end
|
189
189
|
|
190
190
|
# creating infiltration schedules based on hvac schedule
|
191
191
|
if hvac_schedule.nil?
|
192
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', 'Unable to determine the building HVAC schedule. Treating the building as if there is no HVAC system with outdoor air. This may be appropriate for design sizing, particularly heating design sizing. If this is not the case, input a schedule argument, or assign one to an air loop in the model.')
|
192
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.nist_infiltration', 'Unable to determine the building HVAC schedule. Treating the building as if there is no HVAC system with outdoor air. This may be appropriate for design sizing, particularly heating design sizing. If this is not the case, input a schedule argument, or assign one to an air loop in the model.')
|
193
193
|
on_schedule = OpenStudio::Model::ScheduleConstant.new(model)
|
194
194
|
on_schedule.setName('Infiltration HVAC On Schedule')
|
195
195
|
on_schedule.setValue(0.0)
|
@@ -228,26 +228,26 @@ module OpenstudioStandards
|
|
228
228
|
|
229
229
|
# check that model building type is supported
|
230
230
|
unless nist_building_types.include? nist_building_type
|
231
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "NIST coefficients are not available for model building type #{nist_building_type}.")
|
231
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', "NIST coefficients are not available for model building type #{nist_building_type}.")
|
232
232
|
return false
|
233
233
|
end
|
234
234
|
|
235
235
|
# remove existing infiltration objects
|
236
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "The modeled started with #{model.getSpaceInfiltrationDesignFlowRates.size} infiltration objects and #{model.getSpaceInfiltrationEffectiveLeakageAreas.size} effective leakage area objects.")
|
236
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "The modeled started with #{model.getSpaceInfiltrationDesignFlowRates.size} infiltration objects and #{model.getSpaceInfiltrationEffectiveLeakageAreas.size} effective leakage area objects.")
|
237
237
|
model.getSpaceInfiltrationDesignFlowRates.each(&:remove)
|
238
238
|
model.getSpaceInfiltrationEffectiveLeakageAreas.each(&:remove)
|
239
239
|
|
240
240
|
# load NIST infiltration correlations file and convert to hash table
|
241
|
-
|
242
|
-
unless File.exist?(
|
243
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "Unable to find file: #{
|
241
|
+
nist_infiltration_correlations_json = "#{File.dirname(__FILE__)}/data/NISTInfiltrationCorrelations.json"
|
242
|
+
unless File.exist?(nist_infiltration_correlations_json)
|
243
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', "Unable to find file: #{nist_infiltration_correlations_json}")
|
244
244
|
return false
|
245
245
|
end
|
246
|
-
|
247
|
-
coefficients_hsh =
|
246
|
+
coefficients_hsh = JSON.parse(File.read("#{File.dirname(__FILE__)}/data/NISTInfiltrationCorrelations.json"), symbolize_names: true)
|
247
|
+
coefficients_hsh = coefficients_hsh[:infiltration]
|
248
248
|
|
249
249
|
# select down to building type and climate zone
|
250
|
-
coefficients = coefficients_hsh.select { |r| (r[:building_type] == nist_building_type) && (r[:climate_zone] == climate_zone_number) }
|
250
|
+
coefficients = coefficients_hsh.select { |r| (r[:building_type] == nist_building_type) && (r[:climate_zone].to_i == climate_zone_number) }
|
251
251
|
|
252
252
|
# filter by air barrier
|
253
253
|
if air_barrier
|
@@ -258,14 +258,14 @@ module OpenstudioStandards
|
|
258
258
|
|
259
259
|
# determine coefficients
|
260
260
|
# if no off coefficients are defined, use 0 for a and the on coefficients for b and d
|
261
|
-
on_coefficients = coefficients.select { |r| r[:hvac_status] == 'on' }
|
262
|
-
off_coefficients = coefficients.select { |r| r[:hvac_status] == 'off' }
|
263
|
-
a_on = on_coefficients[
|
264
|
-
b_on = on_coefficients[
|
265
|
-
d_on = on_coefficients[
|
266
|
-
a_off = off_coefficients[
|
267
|
-
b_off = off_coefficients[
|
268
|
-
d_off = off_coefficients[
|
261
|
+
on_coefficients = coefficients.select { |r| r[:hvac_status] == 'on' }[0]
|
262
|
+
off_coefficients = coefficients.select { |r| r[:hvac_status] == 'off' }[0]
|
263
|
+
a_on = on_coefficients[:a]
|
264
|
+
b_on = on_coefficients[:b]
|
265
|
+
d_on = on_coefficients[:d]
|
266
|
+
a_off = off_coefficients[:a].nil? ? on_coefficients[:a] : off_coefficients[:a]
|
267
|
+
b_off = off_coefficients[:b].nil? ? on_coefficients[:b] : off_coefficients[:b]
|
268
|
+
d_off = off_coefficients[:d].nil? ? on_coefficients[:d] : off_coefficients[:d]
|
269
269
|
|
270
270
|
# add new infiltration objects
|
271
271
|
# define infiltration as flow per exterior area
|
@@ -293,7 +293,7 @@ module OpenstudioStandards
|
|
293
293
|
hvac_off_infiltration.setSchedule(off_schedule)
|
294
294
|
end
|
295
295
|
|
296
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "The modeled finished with #{model.getSpaceInfiltrationDesignFlowRates.size} infiltration objects.")
|
296
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "The modeled finished with #{model.getSpaceInfiltrationDesignFlowRates.size} infiltration objects.")
|
297
297
|
|
298
298
|
return true
|
299
299
|
end
|
@@ -315,7 +315,7 @@ module OpenstudioStandards
|
|
315
315
|
hvac_schedule = OpenstudioStandards::Schedules.model_get_hvac_schedule(model)
|
316
316
|
else
|
317
317
|
unless hvac_schedule.to_Schedule.is_initialized
|
318
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} not found in the model or is not a Schedule object. It may have been removed by another measure.")
|
318
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', "HVAC schedule argument #{hvac_schedule} not found in the model or is not a Schedule object. It may have been removed by another measure.")
|
319
319
|
return false
|
320
320
|
end
|
321
321
|
hvac_schedule = hvac_schedule.to_Schedule.get
|
@@ -324,16 +324,16 @@ module OpenstudioStandards
|
|
324
324
|
elsif hvac_schedule.to_ScheduleConstant.is_initialized
|
325
325
|
hvac_schedule = hvac_schedule.to_ScheduleConstant.get
|
326
326
|
else
|
327
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} is not a Schedule Constant or Schedule Ruleset object.")
|
327
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration.nist_infiltration', "HVAC schedule argument #{hvac_schedule} is not a Schedule Constant or Schedule Ruleset object.")
|
328
328
|
return false
|
329
329
|
end
|
330
330
|
|
331
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Using HVAC schedule #{hvac_schedule.name} from user arguments to determine infiltration on/off schedule.")
|
331
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration.nist_infiltration', "Using HVAC schedule #{hvac_schedule.name} from user arguments to determine infiltration on/off schedule.")
|
332
332
|
end
|
333
333
|
|
334
334
|
# creating infiltration schedules based on hvac schedule
|
335
335
|
if hvac_schedule.nil?
|
336
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', 'Unable to determine the HVAC schedule. Treating the building as if there is no HVAC system with outdoor air. If this is not the case, input a schedule argument, or assign one to an air loop in the model.')
|
336
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration.nist_infiltration', 'Unable to determine the HVAC schedule. Treating the building as if there is no HVAC system with outdoor air. If this is not the case, input a schedule argument, or assign one to an air loop in the model.')
|
337
337
|
on_schedule = OpenStudio::Model::ScheduleConstant.new(model)
|
338
338
|
on_schedule.setName('Infiltration HVAC On Schedule')
|
339
339
|
on_schedule.setValue(0.0)
|
@@ -96,8 +96,8 @@ module OpenstudioStandards
|
|
96
96
|
|
97
97
|
# Dripdown schedule
|
98
98
|
dripdown_sch = OpenStudio::Model::ScheduleRuleset.new(model)
|
99
|
-
dripdown_sch.setName("#{ref_case.name}
|
100
|
-
dripdown_sch.defaultDaySchedule.setName("#{ref_case.name}
|
99
|
+
dripdown_sch.setName("#{ref_case.name} Dripdown")
|
100
|
+
dripdown_sch.defaultDaySchedule.setName("#{ref_case.name} Dripdown Default")
|
101
101
|
dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, i, 0, 0), 0)
|
102
102
|
dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, i, 59, 0), 1)
|
103
103
|
dripdown_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0)
|
@@ -8,11 +8,11 @@ module OpenstudioStandards
|
|
8
8
|
#
|
9
9
|
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
10
10
|
# @param template [String] Technology or standards level, either 'old', 'new', or 'advanced'
|
11
|
-
# @param separate_system_size_limit [Float] The area in square feet above which a refrigeration system will be split into multiple systems
|
11
|
+
# @param separate_system_size_limit [Float] The area in square feet above which a refrigeration system will be split into multiple systems. Currently not used.
|
12
12
|
# @return [Boolean] returns true if successful, false if not
|
13
13
|
def self.create_typical_refrigeration(model,
|
14
14
|
template: 'new',
|
15
|
-
separate_system_size_limit:
|
15
|
+
separate_system_size_limit: 0.0)
|
16
16
|
# get refrigeration equipment list based on space types and area
|
17
17
|
ref_equip_list = OpenstudioStandards::Refrigeration.typical_refrigeration_equipment_list(model)
|
18
18
|
|
@@ -71,25 +71,26 @@ module OpenstudioStandards
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
74
|
+
# @todo Disable self-contained refrigeration units until we have efficiency data and cases and walkins can connect to those systems and simulate correctly.
|
75
|
+
# refrigeration_space_type_area = OpenStudio.convert(model.getBuilding.floorArea, 'm^2', 'ft^2').get
|
76
|
+
# if refrigeration_space_type_area < separate_system_size_limit
|
77
|
+
# # each case is self-contained
|
78
|
+
# medium_temperature_cases.each { |ref_equip| OpenstudioStandards::Refrigeration.create_compressor_rack(model, ref_equip, template: template) }
|
79
|
+
# low_temperature_cases.each { |ref_equip| OpenstudioStandards::Refrigeration.create_compressor_rack(model, ref_equip, template: template) }
|
80
|
+
|
81
|
+
# # each walkin gets its own refrigeration system
|
82
|
+
# medium_temperature_walkins.each { |ref_equip| OpenstudioStandards::Refrigeration.create_refrigeration_system(model, [ref_equip], template: template, operation_type: 'MT') }
|
83
|
+
# low_temperature_walkins.each { |ref_equip| OpenstudioStandards::Refrigeration.create_refrigeration_system(model, [ref_equip], template: template, operation_type: 'LT') }
|
84
|
+
# else
|
85
|
+
medium_temperature_equip = medium_temperature_cases + medium_temperature_walkins
|
86
|
+
OpenstudioStandards::Refrigeration.create_refrigeration_system(model, medium_temperature_equip,
|
87
|
+
template: template,
|
88
|
+
operation_type: 'MT')
|
89
|
+
low_temperature_equip = low_temperature_cases + low_temperature_walkins
|
90
|
+
OpenstudioStandards::Refrigeration.create_refrigeration_system(model, low_temperature_equip,
|
91
|
+
template: template,
|
92
|
+
operation_type: 'LT')
|
93
|
+
# end
|
93
94
|
|
94
95
|
return true
|
95
96
|
end
|
@@ -41,7 +41,7 @@ module OpenstudioStandards
|
|
41
41
|
standards_building_type = space_type.standardsBuildingType.get
|
42
42
|
|
43
43
|
# load typical water use equipment data
|
44
|
-
data = JSON.parse(File.read("#{
|
44
|
+
data = JSON.parse(File.read("#{File.dirname(__FILE__)}/data/typical_water_use_equipment.json"), symbolize_names: true)
|
45
45
|
space_type_properties = data[:space_types].select { |hash| (hash[:space_type] == standards_space_type) && (hash[:building_type] == standards_building_type) }
|
46
46
|
|
47
47
|
# skip spaces with no equipment defined
|
@@ -1254,6 +1254,9 @@ class Standard
|
|
1254
1254
|
|
1255
1255
|
# Get climate zone
|
1256
1256
|
climate_zone = OpenstudioStandards::Weather.model_get_climate_zone(space.model)
|
1257
|
+
if climate_zone.empty?
|
1258
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Space', 'Model has no climate zone assigned, cannot determine space conditioning category.')
|
1259
|
+
end
|
1257
1260
|
|
1258
1261
|
# Get the zone this space is inside
|
1259
1262
|
zone = space.thermalZone
|
data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb
CHANGED
@@ -29,7 +29,7 @@ class ASHRAE9012013 < ASHRAE901
|
|
29
29
|
# Moisture regime is not needed for climate zone 8
|
30
30
|
climate_zone = climate_zone.split('-')[-1]
|
31
31
|
climate_zone = '8' if climate_zone.include?('8')
|
32
|
-
|
32
|
+
|
33
33
|
search_criteria = {
|
34
34
|
'template' => template,
|
35
35
|
'climate_zone' => climate_zone
|
@@ -455,6 +455,13 @@ class ASHRAE9012013 < ASHRAE901
|
|
455
455
|
# Moisture regime is not needed for climate zone 8
|
456
456
|
climate_zone = climate_zone.split('-')[-1]
|
457
457
|
climate_zone = '8' if climate_zone.include?('8')
|
458
|
+
# Default to use values for cooling for climate zones 0, 1, 2, and 3 and heating for all others.
|
459
|
+
case climate_zone
|
460
|
+
when '0A', '0B', '1A', '1A', '1B', '2A', '2B', '3A', '3B', '3C'
|
461
|
+
design_conditions = 'Cooling'
|
462
|
+
else
|
463
|
+
design_conditions = 'Heating'
|
464
|
+
end
|
458
465
|
|
459
466
|
# Check annual operating hours
|
460
467
|
if ann_op_hrs < 8000.0
|
@@ -469,7 +476,8 @@ class ASHRAE9012013 < ASHRAE901
|
|
469
476
|
search_criteria = {
|
470
477
|
'template' => template,
|
471
478
|
'climate_zone' => climate_zone,
|
472
|
-
'under_8000_hours' => under_8000_hours
|
479
|
+
'under_8000_hours' => under_8000_hours,
|
480
|
+
'design_conditions' => design_conditions
|
473
481
|
}
|
474
482
|
energy_recovery_limits = model_find_object(standards_data['energy_recovery'], search_criteria)
|
475
483
|
if energy_recovery_limits.nil?
|