openstudio-standards 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards.xlsx +0 -0
- data/data/standards/OpenStudio_Standards_boilers.json +62 -4
- data/data/standards/OpenStudio_Standards_chillers.json +778 -68
- data/data/standards/OpenStudio_Standards_construction_sets.json +52 -93
- data/data/standards/OpenStudio_Standards_curve_biquadratics.json +36 -36
- data/data/standards/OpenStudio_Standards_curve_quadratics.json +3 -3
- data/data/standards/OpenStudio_Standards_heat_pumps.json +840 -0
- data/data/standards/OpenStudio_Standards_heat_pumps_heating.json +352 -0
- data/data/standards/OpenStudio_Standards_heat_rejection.json +48 -0
- data/data/standards/OpenStudio_Standards_motors.json +270 -0
- data/data/standards/OpenStudio_Standards_space_types.json +10390 -2824
- data/data/standards/OpenStudio_Standards_unitary_acs.json +794 -18
- data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.ddy +538 -0
- data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.epw +8768 -0
- data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.stat +493 -0
- data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.ddy +536 -0
- data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.epw +8768 -0
- data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.stat +554 -0
- data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.ddy +536 -0
- data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.epw +8768 -0
- data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.stat +554 -0
- data/data/weather/envelope_info.csv +6 -0
- data/lib/openstudio-standards.rb +10 -11
- data/lib/openstudio-standards/btap/compliance.rb +251 -969
- data/lib/openstudio-standards/btap/envelope.rb +1 -1
- data/lib/openstudio-standards/btap/fileio.rb +37 -5
- data/lib/openstudio-standards/btap/geometry.rb +27 -17
- data/lib/openstudio-standards/btap/hvac.rb +80 -27
- data/lib/openstudio-standards/hvac_sizing/{HVACSizing.CoilHeatingDXMultiSpeed.rb → Siz.CoilHeatingDXMultiSpeed.rb} +0 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.ControllerOutdoorAir.rb +30 -4
- data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerTwoSpeed.rb +61 -5
- data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerVariableSpeed.rb +37 -7
- data/lib/openstudio-standards/hvac_sizing/Siz.DistrictCooling.rb +27 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.DistrictHeating.rb +27 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsConstantSpeed.rb +55 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsVariableSpeed.rb +55 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +51 -9
- data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +99 -17
- data/lib/openstudio-standards/hvac_sizing/Siz.PumpConstantSpeed.rb +1 -1
- data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +29 -6
- data/lib/openstudio-standards/hvac_sizing/Siz.WaterHeaterMixed.rb +16 -0
- data/lib/openstudio-standards/prototypes/Prototype.AirTerminalSingleDuctVAVReheat.rb +43 -48
- data/lib/openstudio-standards/prototypes/Prototype.ControllerWaterCoil.rb +5 -9
- data/lib/openstudio-standards/prototypes/Prototype.Fan.rb +68 -0
- data/lib/openstudio-standards/prototypes/Prototype.FanConstantVolume.rb +39 -43
- data/lib/openstudio-standards/prototypes/Prototype.FanOnOff.rb +49 -51
- data/lib/openstudio-standards/prototypes/Prototype.FanVariableVolume.rb +55 -61
- data/lib/openstudio-standards/prototypes/Prototype.FanZoneExhaust.rb +8 -10
- data/lib/openstudio-standards/prototypes/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +15 -20
- data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +330 -322
- data/lib/openstudio-standards/prototypes/Prototype.Model.rb +501 -446
- data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +221 -230
- data/lib/openstudio-standards/prototypes/Prototype.add_objects.rb +0 -2
- data/lib/openstudio-standards/prototypes/Prototype.full_service_restaurant.rb +130 -137
- data/lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb +374 -291
- data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +146 -193
- data/lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb +1315 -1113
- data/lib/openstudio-standards/prototypes/Prototype.large_hotel.rb +65 -88
- data/lib/openstudio-standards/prototypes/Prototype.large_office.rb +101 -156
- data/lib/openstudio-standards/prototypes/Prototype.medium_office.rb +46 -96
- data/lib/openstudio-standards/prototypes/Prototype.mid_rise_apartment.rb +113 -123
- data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +356 -345
- data/lib/openstudio-standards/prototypes/Prototype.primary_school.rb +48 -103
- data/lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb +115 -123
- data/lib/openstudio-standards/prototypes/Prototype.retail_standalone.rb +30 -39
- data/lib/openstudio-standards/prototypes/Prototype.retail_stripmall.rb +32 -45
- data/lib/openstudio-standards/prototypes/Prototype.secondary_school.rb +98 -258
- data/lib/openstudio-standards/prototypes/Prototype.small_hotel.rb +429 -474
- data/lib/openstudio-standards/prototypes/Prototype.small_office.rb +28 -36
- data/lib/openstudio-standards/prototypes/Prototype.strip_model.rb +7 -7
- data/lib/openstudio-standards/prototypes/Prototype.utilities.rb +172 -146
- data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +46 -53
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +885 -707
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +48 -57
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +24 -31
- data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +80 -93
- data/lib/openstudio-standards/standards/Standards.BuildingStory.rb +69 -0
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +60 -72
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +104 -108
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +190 -198
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +134 -146
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +56 -60
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +151 -161
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +30 -34
- data/lib/openstudio-standards/standards/Standards.Construction.rb +116 -132
- data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +138 -0
- data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +11 -0
- data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +11 -0
- data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +16 -0
- data/lib/openstudio-standards/standards/Standards.Fan.rb +190 -236
- data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -2
- data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -2
- data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +168 -14
- data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -2
- data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +33 -0
- data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +83 -0
- data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +22 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +2385 -1622
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +83 -35
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +805 -395
- data/lib/openstudio-standards/standards/Standards.Pump.rb +139 -119
- data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -2
- data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +16 -15
- data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +35 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +7 -13
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +144 -59
- data/lib/openstudio-standards/standards/Standards.Space.rb +1509 -1326
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +254 -262
- data/lib/openstudio-standards/standards/Standards.SubSurface.rb +105 -105
- data/lib/openstudio-standards/standards/Standards.Surface.rb +27 -31
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +882 -157
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +179 -69
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +75 -0
- data/lib/openstudio-standards/utilities/logging.rb +31 -38
- data/lib/openstudio-standards/utilities/simulation.rb +118 -82
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +382 -390
- data/lib/openstudio-standards/weather/Weather.stat_file.rb +159 -78
- metadata +59 -6
@@ -159,14 +159,17 @@ class OpenStudio::Model::ThermalZone
|
|
159
159
|
WHERE ReportName='HVACSizingSummary'
|
160
160
|
AND ReportForString='Entire Facility'
|
161
161
|
AND TableName='#{table_name}'
|
162
|
-
AND ColumnName='User Design Load
|
162
|
+
AND ColumnName='User Design Load'
|
163
163
|
AND RowName='#{name}'
|
164
|
-
AND Units='W
|
164
|
+
AND Units='W'"
|
165
165
|
|
166
166
|
val = sql.execAndReturnFirstDouble(query)
|
167
167
|
|
168
168
|
if val.is_initialized
|
169
|
-
|
169
|
+
floor_area_no_multiplier_m2 = self.floorArea
|
170
|
+
floor_area_m2 = floor_area_no_multiplier_m2 * self.multiplier
|
171
|
+
w_per_m2 = val.get/floor_area_m2
|
172
|
+
result = OpenStudio::OptionalDouble.new(w_per_m2)
|
170
173
|
else
|
171
174
|
#OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "Data not found for query: #{query}")
|
172
175
|
end
|
@@ -204,14 +207,17 @@ class OpenStudio::Model::ThermalZone
|
|
204
207
|
WHERE ReportName='HVACSizingSummary'
|
205
208
|
AND ReportForString='Entire Facility'
|
206
209
|
AND TableName='#{table_name}'
|
207
|
-
AND ColumnName='User Design Load
|
210
|
+
AND ColumnName='User Design Load'
|
208
211
|
AND RowName='#{name}'
|
209
|
-
AND Units='W
|
212
|
+
AND Units='W'"
|
210
213
|
|
211
214
|
val = sql.execAndReturnFirstDouble(query)
|
212
215
|
|
213
216
|
if val.is_initialized
|
214
|
-
|
217
|
+
floor_area_no_multiplier_m2 = self.floorArea
|
218
|
+
floor_area_m2 = floor_area_no_multiplier_m2 * self.multiplier
|
219
|
+
w_per_m2 = val.get/floor_area_m2
|
220
|
+
result = OpenStudio::OptionalDouble.new(w_per_m2)
|
215
221
|
else
|
216
222
|
#OpenStudio::logFree(OpenStudio::Warn, "openstudio.model.Model", "Data not found for query: #{query}")
|
217
223
|
end
|
@@ -237,6 +243,23 @@ class OpenStudio::Model::ThermalZone
|
|
237
243
|
|
238
244
|
fuels = []
|
239
245
|
|
246
|
+
# Special logic for models imported from Sefaira.
|
247
|
+
# In this case, the fuels are listed as a comment
|
248
|
+
# above the Zone object.
|
249
|
+
if !self.comment == ''
|
250
|
+
m = self.comment.match /! *(.*)/
|
251
|
+
if m
|
252
|
+
all_fuels = m[1].split(',')
|
253
|
+
all_fuels.each do |fuel|
|
254
|
+
fuels += fuel.strip
|
255
|
+
end
|
256
|
+
end
|
257
|
+
if fuels.size > 0
|
258
|
+
OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "For #{self.name}, fuel type #{fuels.join(', ')} pulled from Zone comment.")
|
259
|
+
fuels.uniq.sort
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
240
263
|
# Check the zone hvac heating fuels
|
241
264
|
fuels += self.model.zone_equipment_heating_fuels(self)
|
242
265
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
# open the class to add methods to return sizing values
|
3
|
+
# @Todo: currently OpenStudio is missing the WaterHeater:Sizing object, so unlikely to need it right now...
|
4
|
+
class OpenStudio::Model::WaterHeaterMixed
|
5
|
+
|
6
|
+
|
7
|
+
# returns the autosized Heater Maximum Capacity as an optional double
|
8
|
+
def autosizedHeaterMaximumCapacity
|
9
|
+
|
10
|
+
# @Todo: check the correct syntax here
|
11
|
+
return self.model.getAutosizedValue(self, 'Design Size Nominal Capacity', 'W')
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
end # close the class
|
@@ -1,83 +1,78 @@
|
|
1
1
|
|
2
2
|
class OpenStudio::Model::AirTerminalSingleDuctVAVReheat
|
3
|
-
|
4
3
|
# Set the initial minimum damper position based on OA
|
5
|
-
# rate of the space and the
|
4
|
+
# rate of the space and the template.
|
6
5
|
# Zones with low OA per area get lower initial guesses.
|
7
6
|
# Final position will be adjusted upward
|
8
|
-
# as necessary by Standards.AirLoopHVAC.
|
9
|
-
# @param
|
7
|
+
# as necessary by Standards.AirLoopHVAC.apply_minimum_vav_damper_positions
|
8
|
+
# @param template [String] the template
|
10
9
|
# @param zone_oa_per_area [Double] the zone outdoor air per area, m^3/s
|
11
10
|
# @return [Bool] returns true if successful, false if not
|
12
11
|
# @todo remove exception where older vintages don't have minimum positions adjusted.
|
13
|
-
def
|
14
|
-
|
12
|
+
def apply_initial_prototype_damper_position(building_type, template, zone_oa_per_area)
|
15
13
|
# Minimum damper position is based on prototype
|
16
14
|
# assumptions, which are not clearly documented.
|
17
15
|
min_damper_position = nil
|
18
|
-
vav_name =
|
19
|
-
case
|
16
|
+
vav_name = name.get
|
17
|
+
case template
|
20
18
|
when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
|
21
|
-
if building_type ==
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
19
|
+
min_damper_position = if building_type == 'Outpatient' && vav_name.include?('Floor 1')
|
20
|
+
1
|
21
|
+
elsif building_type == 'Hospital' && vav_name.include?('PatRoom')
|
22
|
+
1
|
23
|
+
elsif building_type == 'Hospital' && vav_name.include?('OR')
|
24
|
+
1
|
25
|
+
elsif building_type == 'Hospital' && vav_name.include?('ICU')
|
26
|
+
1
|
27
|
+
elsif building_type == 'Hospital' && vav_name.include?('Lab')
|
28
|
+
1
|
29
|
+
elsif building_type == 'Hospital' && vav_name.include?('ER')
|
30
|
+
1
|
31
|
+
elsif building_type == 'Hospital' && vav_name.include?('Kitchen')
|
32
|
+
1
|
33
|
+
elsif building_type == 'Hospital' && vav_name.include?('NurseStn')
|
34
|
+
0.3
|
35
|
+
else
|
36
|
+
0.3
|
37
|
+
end
|
40
38
|
when '90.1-2004', '90.1-2007'
|
41
39
|
min_damper_position = 0.3
|
42
40
|
when '90.1-2010', '90.1-2013'
|
43
41
|
min_damper_position = 0.2
|
44
42
|
end
|
45
43
|
|
46
|
-
# TODO remove the template conditional; doesn't make sense
|
44
|
+
# TODO: remove the template conditional; doesn't make sense
|
47
45
|
# Determine whether or not to use the high minimum guess.
|
48
46
|
# Cutoff was determined by correlating apparent minimum guesses
|
49
47
|
# to OA rates in prototypes since not well documented in papers.
|
50
48
|
if zone_oa_per_area > 0.001 # 0.001 m^3/s*m^2 = .196 cfm/ft2
|
51
|
-
case
|
49
|
+
case template
|
52
50
|
when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
|
53
|
-
|
51
|
+
setConstantMinimumAirFlowFraction(min_damper_position)
|
54
52
|
else
|
55
53
|
# High OA zones
|
56
|
-
if building_type ==
|
57
|
-
|
58
|
-
elsif building_type ==
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
54
|
+
if building_type == 'Outpatient'
|
55
|
+
setConstantMinimumAirFlowFraction(1)
|
56
|
+
elsif building_type == 'Hospital'
|
57
|
+
case template
|
58
|
+
when '90.1-2010', '90.1-2013'
|
59
|
+
if vav_name.include? 'PatRoom'
|
60
|
+
setConstantMinimumAirFlowFraction(0.5)
|
61
|
+
else
|
62
|
+
setConstantMinimumAirFlowFraction(1)
|
63
|
+
end
|
64
|
+
when '90.1-2004', '90.1-2007'
|
65
|
+
setConstantMinimumAirFlowFraction(1)
|
66
|
+
end
|
70
67
|
else
|
71
|
-
|
68
|
+
setConstantMinimumAirFlowFraction(0.7)
|
72
69
|
end
|
73
70
|
end
|
74
71
|
else
|
75
72
|
# Low OA zones
|
76
|
-
|
73
|
+
setConstantMinimumAirFlowFraction(min_damper_position)
|
77
74
|
end
|
78
75
|
|
79
76
|
return true
|
80
|
-
|
81
77
|
end
|
82
|
-
|
83
78
|
end
|
@@ -1,25 +1,21 @@
|
|
1
1
|
|
2
2
|
# Reopen the OpenStudio class to add methods to apply standards to this object
|
3
3
|
class OpenStudio::Model::ControllerWaterCoil
|
4
|
-
|
5
4
|
# Sets the convergence tolerance to 0.0001 deltaC
|
6
5
|
# for all hot water coils.
|
7
|
-
#
|
6
|
+
#
|
8
7
|
# @return [Bool] returns true if successful, false if not
|
9
8
|
# @todo Figure out what the reason for this is,
|
10
9
|
# because it seems like a workaround for an E+ bug
|
11
10
|
# that was probably addressed long ago.
|
12
|
-
def set_convergence_limits
|
13
|
-
|
14
|
-
controller_action = self.action
|
11
|
+
def set_convergence_limits
|
12
|
+
controller_action = action
|
15
13
|
if controller_action.is_initialized
|
16
14
|
if controller_action.get == 'Normal'
|
17
|
-
|
15
|
+
setControllerConvergenceTolerance(0.0001)
|
18
16
|
end
|
19
17
|
end
|
20
|
-
|
18
|
+
|
21
19
|
return true
|
22
|
-
|
23
20
|
end
|
24
|
-
|
25
21
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
# Prototype fan calculation methods that are the same regardless of fan type.
|
3
|
+
# These methods are available to FanConstantVolume, FanOnOff, FanVariableVolume, and FanZoneExhaust
|
4
|
+
module PrototypeFan
|
5
|
+
# Sets the fan motor efficiency using the Prototype
|
6
|
+
# model assumptions for fan impeller efficiency,
|
7
|
+
# motor type, and a 10% safety factor on brake horsepower.
|
8
|
+
#
|
9
|
+
# @return [Bool] true if successful, false if not
|
10
|
+
def apply_prototype_fan_efficiency(template)
|
11
|
+
# Get the max flow rate from the fan.
|
12
|
+
maximum_flow_rate_m3_per_s = nil
|
13
|
+
if maximumFlowRate.is_initialized
|
14
|
+
maximum_flow_rate_m3_per_s = maximumFlowRate.get
|
15
|
+
elsif autosizedMaximumFlowRate.is_initialized
|
16
|
+
maximum_flow_rate_m3_per_s = autosizedMaximumFlowRate.get
|
17
|
+
else
|
18
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Fan', "For #{name} max flow rate is not hard sized, cannot apply efficiency standard.")
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
|
22
|
+
# Convert max flow rate to cfm
|
23
|
+
maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s, 'm^3/s', 'cfm').get
|
24
|
+
|
25
|
+
# Get the pressure rise from the fan
|
26
|
+
pressure_rise_pa = pressureRise
|
27
|
+
pressure_rise_in_h2o = OpenStudio.convert(pressure_rise_pa, 'Pa', 'inH_{2}O').get
|
28
|
+
|
29
|
+
# Get the default impeller efficiency
|
30
|
+
fan_impeller_eff = baseline_impeller_efficiency(template)
|
31
|
+
|
32
|
+
# Calculate the Brake Horsepower
|
33
|
+
brake_hp = (pressure_rise_in_h2o * maximum_flow_rate_cfm) / (fan_impeller_eff * 6356)
|
34
|
+
allowed_hp = brake_hp * 1.1 # Per PNNL document #TODO add reference
|
35
|
+
if allowed_hp > 0.1
|
36
|
+
allowed_hp = allowed_hp.round(2) + 0.0001
|
37
|
+
elsif allowed_hp < 0.01
|
38
|
+
allowed_hp = 0.01
|
39
|
+
end
|
40
|
+
|
41
|
+
# Minimum motor size for efficiency lookup
|
42
|
+
# is 1 HP unless the motor serves an exhaust fan,
|
43
|
+
# a powered VAV terminal, or a fan coil unit.
|
44
|
+
unless small_fan?
|
45
|
+
if allowed_hp < 1.0
|
46
|
+
allowed_hp = 1.01
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Find the motor efficiency
|
51
|
+
motor_eff, nominal_hp = standard_minimum_motor_efficiency_and_size(template, allowed_hp)
|
52
|
+
|
53
|
+
# Calculate the total fan efficiency
|
54
|
+
total_fan_eff = fan_impeller_eff * motor_eff
|
55
|
+
|
56
|
+
# Set the total fan efficiency and the motor efficiency
|
57
|
+
if to_FanZoneExhaust.is_initialized
|
58
|
+
setFanEfficiency(total_fan_eff)
|
59
|
+
else
|
60
|
+
setFanEfficiency(total_fan_eff)
|
61
|
+
setMotorEfficiency(motor_eff)
|
62
|
+
end
|
63
|
+
|
64
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Fan', "For #{name}: allowed_hp = #{allowed_hp.round(2)}HP; motor eff = #{(motor_eff * 100).round(2)}%; total fan eff = #{(total_fan_eff * 100).round}% based on #{maximum_flow_rate_cfm.round} cfm.")
|
65
|
+
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
end
|
@@ -1,42 +1,42 @@
|
|
1
1
|
|
2
2
|
# Reopen the OpenStudio class to add methods to apply standards to this object
|
3
3
|
class OpenStudio::Model::FanConstantVolume
|
4
|
+
include PrototypeFan
|
4
5
|
|
5
6
|
# Sets the fan pressure rise based on the Prototype buildings inputs
|
6
7
|
# which are governed by the flow rate coming through the fan
|
7
8
|
# and whether the fan lives inside a unit heater, PTAC, etc.
|
8
|
-
def
|
9
|
-
|
9
|
+
def apply_prototype_fan_pressure_rise(building_type, template, climate_zone)
|
10
10
|
# NECB
|
11
|
-
if
|
11
|
+
if template == 'NECB 2011'
|
12
12
|
pressure_rise_pa = 640.0
|
13
|
-
|
13
|
+
setPressureRise(pressure_rise_pa)
|
14
14
|
return true
|
15
15
|
end
|
16
|
-
|
17
|
-
return true if
|
18
|
-
|
16
|
+
|
17
|
+
return true if name.to_s.include?('UnitHeater Fan')
|
18
|
+
|
19
19
|
# Get the max flow rate from the fan.
|
20
20
|
maximum_flow_rate_m3_per_s = nil
|
21
|
-
if
|
22
|
-
maximum_flow_rate_m3_per_s =
|
23
|
-
elsif
|
24
|
-
maximum_flow_rate_m3_per_s =
|
21
|
+
if maximumFlowRate.is_initialized
|
22
|
+
maximum_flow_rate_m3_per_s = maximumFlowRate.get
|
23
|
+
elsif autosizedMaximumFlowRate.is_initialized
|
24
|
+
maximum_flow_rate_m3_per_s = autosizedMaximumFlowRate.get
|
25
25
|
else
|
26
|
-
OpenStudio
|
26
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.FanConstantVolume', "For #{name} max flow rate is not available, cannot apply prototype assumptions.")
|
27
27
|
return false
|
28
|
-
end
|
29
|
-
|
28
|
+
end
|
29
|
+
|
30
30
|
# Convert max flow rate to cfm
|
31
31
|
maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s, 'm^3/s', 'cfm').get
|
32
|
-
|
33
|
-
# Pressure rise will be determined based on the
|
32
|
+
|
33
|
+
# Pressure rise will be determined based on the
|
34
34
|
# following logic.
|
35
35
|
pressure_rise_in_h2o = 0.0
|
36
|
-
|
36
|
+
|
37
37
|
# If the fan lives inside of a zone hvac equipment
|
38
|
-
if
|
39
|
-
zone_hvac =
|
38
|
+
if containingZoneHVACComponent.is_initialized
|
39
|
+
zone_hvac = containingZoneHVACComponent.get
|
40
40
|
if zone_hvac.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized
|
41
41
|
pressure_rise_in_h2o = 1.33
|
42
42
|
elsif zone_hvac.to_ZoneHVACFourPipeFanCoil.is_initialized
|
@@ -46,36 +46,32 @@ class OpenStudio::Model::FanConstantVolume
|
|
46
46
|
else # This type of fan should not exist in the prototype models
|
47
47
|
return false
|
48
48
|
end
|
49
|
-
end
|
50
|
-
|
51
49
|
# If the fan lives on an airloop
|
52
|
-
|
53
|
-
case
|
50
|
+
elsif airLoopHVAC.is_initialized
|
51
|
+
case template
|
54
52
|
when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004'
|
55
|
-
if maximum_flow_rate_cfm < 7437
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
|
54
|
+
2.5
|
55
|
+
elsif maximum_flow_rate_cfm >= 7437 && maximum_flow_rate_cfm < 20_000
|
56
|
+
4.46
|
57
|
+
else # Over 20,000 cfm
|
58
|
+
4.09
|
59
|
+
end
|
62
60
|
when '90.1-2007', '90.1-2010', '90.1-2013'
|
63
|
-
if maximum_flow_rate_cfm < 7437
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
|
62
|
+
2.5
|
63
|
+
else # Over 7,437 cfm
|
64
|
+
4.09
|
65
|
+
end
|
68
66
|
end
|
69
67
|
end
|
70
|
-
|
68
|
+
|
71
69
|
# Set the fan pressure rise
|
72
|
-
pressure_rise_pa = OpenStudio.convert(pressure_rise_in_h2o, 'inH_{2}O','Pa').get
|
73
|
-
|
74
|
-
|
75
|
-
OpenStudio
|
76
|
-
|
70
|
+
pressure_rise_pa = OpenStudio.convert(pressure_rise_in_h2o, 'inH_{2}O', 'Pa').get
|
71
|
+
setPressureRise(pressure_rise_pa)
|
72
|
+
|
73
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.FanConstantVolume', "For Prototype: #{name}: #{maximum_flow_rate_cfm.round}cfm; Pressure Rise = #{pressure_rise_in_h2o}in w.c.")
|
74
|
+
|
77
75
|
return true
|
78
|
-
|
79
76
|
end
|
80
|
-
|
81
77
|
end
|
@@ -1,33 +1,33 @@
|
|
1
1
|
|
2
2
|
# open the class to add methods to return sizing values
|
3
3
|
class OpenStudio::Model::FanOnOff
|
4
|
+
include PrototypeFan
|
4
5
|
|
5
6
|
# Sets the fan pressure rise based on the Prototype buildings inputs
|
6
7
|
# which are governed by the flow rate coming through the fan
|
7
8
|
# and whether the fan lives inside a unit heater, PTAC, etc.
|
8
|
-
def
|
9
|
-
|
9
|
+
def apply_prototype_fan_pressure_rise(building_type, template, climate_zone)
|
10
10
|
# Get the max flow rate from the fan.
|
11
11
|
maximum_flow_rate_m3_per_s = nil
|
12
|
-
if
|
13
|
-
maximum_flow_rate_m3_per_s =
|
14
|
-
elsif
|
15
|
-
maximum_flow_rate_m3_per_s =
|
12
|
+
if maximumFlowRate.is_initialized
|
13
|
+
maximum_flow_rate_m3_per_s = maximumFlowRate.get
|
14
|
+
elsif autosizedMaximumFlowRate.is_initialized
|
15
|
+
maximum_flow_rate_m3_per_s = autosizedMaximumFlowRate.get
|
16
16
|
else
|
17
|
-
OpenStudio
|
17
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.FanOnOff', "For #{name} max flow rate is not available, cannot apply prototype assumptions.")
|
18
18
|
return false
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Convert max flow rate to cfm
|
22
|
-
maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s,
|
23
|
-
|
24
|
-
# Pressure rise will be determined based on the
|
22
|
+
maximum_flow_rate_cfm = OpenStudio.convert(maximum_flow_rate_m3_per_s, 'm^3/s', 'cfm').get
|
23
|
+
|
24
|
+
# Pressure rise will be determined based on the
|
25
25
|
# following logic.
|
26
26
|
pressure_rise_in_h2o = 0.0
|
27
|
-
|
27
|
+
|
28
28
|
# If the fan lives inside of a zone hvac equipment
|
29
|
-
if
|
30
|
-
zone_hvac =
|
29
|
+
if containingZoneHVACComponent.is_initialized
|
30
|
+
zone_hvac = containingZoneHVACComponent.get
|
31
31
|
if zone_hvac.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized
|
32
32
|
pressure_rise_in_h2o = 1.33
|
33
33
|
elsif zone_hvac.to_ZoneHVACFourPipeFanCoil.is_initialized
|
@@ -38,55 +38,53 @@ class OpenStudio::Model::FanOnOff
|
|
38
38
|
return false
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# If the fan lives on an airloop
|
43
|
-
if
|
44
|
-
case
|
43
|
+
if airLoopHVAC.is_initialized
|
44
|
+
case template
|
45
45
|
when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004'
|
46
|
-
if maximum_flow_rate_cfm < 7437
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
|
47
|
+
2.5
|
48
|
+
elsif maximum_flow_rate_cfm >= 7437 && maximum_flow_rate_cfm < 20_000
|
49
|
+
4.46
|
50
|
+
else # Over 20,000 cfm
|
51
|
+
4.09
|
52
|
+
end
|
53
53
|
when '90.1-2007', '90.1-2010', '90.1-2013'
|
54
|
-
if maximum_flow_rate_cfm < 7437
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
|
55
|
+
2.5
|
56
|
+
else # Over 7,437 cfm
|
57
|
+
4.09
|
58
|
+
end
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
# If the fan lives inside a unitary system
|
63
|
-
if
|
64
|
-
case
|
63
|
+
if airLoopHVAC.empty? && containingZoneHVACComponent.empty?
|
64
|
+
case template
|
65
65
|
when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004'
|
66
|
-
if maximum_flow_rate_cfm < 7437
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
|
67
|
+
2.5
|
68
|
+
elsif maximum_flow_rate_cfm >= 7437 && maximum_flow_rate_cfm < 20_000
|
69
|
+
4.46
|
70
|
+
else # Over 20,000 cfm
|
71
|
+
4.09
|
72
|
+
end
|
73
73
|
when '90.1-2007', '90.1-2010', '90.1-2013'
|
74
|
-
if maximum_flow_rate_cfm < 7437
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
pressure_rise_in_h2o = if maximum_flow_rate_cfm < 7437
|
75
|
+
2.5
|
76
|
+
else # Over 7,437 cfm
|
77
|
+
4.09
|
78
|
+
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
# Set the fan pressure rise
|
83
|
-
pressure_rise_pa = OpenStudio.convert(pressure_rise_in_h2o,
|
84
|
-
|
85
|
-
|
86
|
-
OpenStudio
|
87
|
-
|
83
|
+
pressure_rise_pa = OpenStudio.convert(pressure_rise_in_h2o, 'inH_{2}O', 'Pa').get
|
84
|
+
setPressureRise(pressure_rise_pa)
|
85
|
+
|
86
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.prototype.FanOnOff', "For Prototype: #{name}: #{maximum_flow_rate_cfm.round}cfm; Pressure Rise = #{pressure_rise_in_h2o}in w.c.")
|
87
|
+
|
88
88
|
return true
|
89
|
-
|
90
89
|
end
|
91
|
-
|
92
90
|
end
|