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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards.xlsx +0 -0
  3. data/data/standards/OpenStudio_Standards_boilers.json +62 -4
  4. data/data/standards/OpenStudio_Standards_chillers.json +778 -68
  5. data/data/standards/OpenStudio_Standards_construction_sets.json +52 -93
  6. data/data/standards/OpenStudio_Standards_curve_biquadratics.json +36 -36
  7. data/data/standards/OpenStudio_Standards_curve_quadratics.json +3 -3
  8. data/data/standards/OpenStudio_Standards_heat_pumps.json +840 -0
  9. data/data/standards/OpenStudio_Standards_heat_pumps_heating.json +352 -0
  10. data/data/standards/OpenStudio_Standards_heat_rejection.json +48 -0
  11. data/data/standards/OpenStudio_Standards_motors.json +270 -0
  12. data/data/standards/OpenStudio_Standards_space_types.json +10390 -2824
  13. data/data/standards/OpenStudio_Standards_unitary_acs.json +794 -18
  14. data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.ddy +538 -0
  15. data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.epw +8768 -0
  16. data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.stat +493 -0
  17. data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.ddy +536 -0
  18. data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.epw +8768 -0
  19. data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.stat +554 -0
  20. data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.ddy +536 -0
  21. data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.epw +8768 -0
  22. data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.stat +554 -0
  23. data/data/weather/envelope_info.csv +6 -0
  24. data/lib/openstudio-standards.rb +10 -11
  25. data/lib/openstudio-standards/btap/compliance.rb +251 -969
  26. data/lib/openstudio-standards/btap/envelope.rb +1 -1
  27. data/lib/openstudio-standards/btap/fileio.rb +37 -5
  28. data/lib/openstudio-standards/btap/geometry.rb +27 -17
  29. data/lib/openstudio-standards/btap/hvac.rb +80 -27
  30. data/lib/openstudio-standards/hvac_sizing/{HVACSizing.CoilHeatingDXMultiSpeed.rb → Siz.CoilHeatingDXMultiSpeed.rb} +0 -0
  31. data/lib/openstudio-standards/hvac_sizing/Siz.ControllerOutdoorAir.rb +30 -4
  32. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerTwoSpeed.rb +61 -5
  33. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerVariableSpeed.rb +37 -7
  34. data/lib/openstudio-standards/hvac_sizing/Siz.DistrictCooling.rb +27 -0
  35. data/lib/openstudio-standards/hvac_sizing/Siz.DistrictHeating.rb +27 -0
  36. data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsConstantSpeed.rb +55 -0
  37. data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsVariableSpeed.rb +55 -0
  38. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +51 -9
  39. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +99 -17
  40. data/lib/openstudio-standards/hvac_sizing/Siz.PumpConstantSpeed.rb +1 -1
  41. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +29 -6
  42. data/lib/openstudio-standards/hvac_sizing/Siz.WaterHeaterMixed.rb +16 -0
  43. data/lib/openstudio-standards/prototypes/Prototype.AirTerminalSingleDuctVAVReheat.rb +43 -48
  44. data/lib/openstudio-standards/prototypes/Prototype.ControllerWaterCoil.rb +5 -9
  45. data/lib/openstudio-standards/prototypes/Prototype.Fan.rb +68 -0
  46. data/lib/openstudio-standards/prototypes/Prototype.FanConstantVolume.rb +39 -43
  47. data/lib/openstudio-standards/prototypes/Prototype.FanOnOff.rb +49 -51
  48. data/lib/openstudio-standards/prototypes/Prototype.FanVariableVolume.rb +55 -61
  49. data/lib/openstudio-standards/prototypes/Prototype.FanZoneExhaust.rb +8 -10
  50. data/lib/openstudio-standards/prototypes/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +15 -20
  51. data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +330 -322
  52. data/lib/openstudio-standards/prototypes/Prototype.Model.rb +501 -446
  53. data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +221 -230
  54. data/lib/openstudio-standards/prototypes/Prototype.add_objects.rb +0 -2
  55. data/lib/openstudio-standards/prototypes/Prototype.full_service_restaurant.rb +130 -137
  56. data/lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb +374 -291
  57. data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +146 -193
  58. data/lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb +1315 -1113
  59. data/lib/openstudio-standards/prototypes/Prototype.large_hotel.rb +65 -88
  60. data/lib/openstudio-standards/prototypes/Prototype.large_office.rb +101 -156
  61. data/lib/openstudio-standards/prototypes/Prototype.medium_office.rb +46 -96
  62. data/lib/openstudio-standards/prototypes/Prototype.mid_rise_apartment.rb +113 -123
  63. data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +356 -345
  64. data/lib/openstudio-standards/prototypes/Prototype.primary_school.rb +48 -103
  65. data/lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb +115 -123
  66. data/lib/openstudio-standards/prototypes/Prototype.retail_standalone.rb +30 -39
  67. data/lib/openstudio-standards/prototypes/Prototype.retail_stripmall.rb +32 -45
  68. data/lib/openstudio-standards/prototypes/Prototype.secondary_school.rb +98 -258
  69. data/lib/openstudio-standards/prototypes/Prototype.small_hotel.rb +429 -474
  70. data/lib/openstudio-standards/prototypes/Prototype.small_office.rb +28 -36
  71. data/lib/openstudio-standards/prototypes/Prototype.strip_model.rb +7 -7
  72. data/lib/openstudio-standards/prototypes/Prototype.utilities.rb +172 -146
  73. data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +46 -53
  74. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +885 -707
  75. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +48 -57
  76. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +24 -31
  77. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +80 -93
  78. data/lib/openstudio-standards/standards/Standards.BuildingStory.rb +69 -0
  79. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +60 -72
  80. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +104 -108
  81. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +190 -198
  82. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +134 -146
  83. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +56 -60
  84. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +151 -161
  85. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +30 -34
  86. data/lib/openstudio-standards/standards/Standards.Construction.rb +116 -132
  87. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +138 -0
  88. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +11 -0
  89. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +11 -0
  90. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +16 -0
  91. data/lib/openstudio-standards/standards/Standards.Fan.rb +190 -236
  92. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -2
  93. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -2
  94. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +168 -14
  95. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -2
  96. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +33 -0
  97. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +83 -0
  98. data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +22 -0
  99. data/lib/openstudio-standards/standards/Standards.Model.rb +2385 -1622
  100. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +83 -35
  101. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +805 -395
  102. data/lib/openstudio-standards/standards/Standards.Pump.rb +139 -119
  103. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -2
  104. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +16 -15
  105. data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +35 -0
  106. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +7 -13
  107. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +144 -59
  108. data/lib/openstudio-standards/standards/Standards.Space.rb +1509 -1326
  109. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +254 -262
  110. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +105 -105
  111. data/lib/openstudio-standards/standards/Standards.Surface.rb +27 -31
  112. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +882 -157
  113. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +179 -69
  114. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +75 -0
  115. data/lib/openstudio-standards/utilities/logging.rb +31 -38
  116. data/lib/openstudio-standards/utilities/simulation.rb +118 -82
  117. data/lib/openstudio-standards/version.rb +1 -1
  118. data/lib/openstudio-standards/weather/Weather.Model.rb +382 -390
  119. data/lib/openstudio-standards/weather/Weather.stat_file.rb +159 -78
  120. metadata +59 -6
@@ -51,7 +51,7 @@ class OpenStudio::Model::PumpConstantSpeed
51
51
  col_name = 'Design Power Consumption'
52
52
  end
53
53
 
54
- return self.model.getAutosizedValue(self, col_name, 'm3/s')
54
+ return self.model.getAutosizedValue(self, col_name, 'W')
55
55
 
56
56
  end
57
57
 
@@ -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 per Area'
162
+ AND ColumnName='User Design Load'
163
163
  AND RowName='#{name}'
164
- AND Units='W/m2'"
164
+ AND Units='W'"
165
165
 
166
166
  val = sql.execAndReturnFirstDouble(query)
167
167
 
168
168
  if val.is_initialized
169
- result = OpenStudio::OptionalDouble.new(val.get)
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 per Area'
210
+ AND ColumnName='User Design Load'
208
211
  AND RowName='#{name}'
209
- AND Units='W/m2'"
212
+ AND Units='W'"
210
213
 
211
214
  val = sql.execAndReturnFirstDouble(query)
212
215
 
213
216
  if val.is_initialized
214
- result = OpenStudio::OptionalDouble.new(val.get)
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 building vintage.
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.set_minimum_vav_damper_positions
9
- # @param building_vintage [String] the building vintage
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 set_initial_prototype_damper_position(building_type, building_vintage, zone_oa_per_area)
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 = self.name.get
19
- case building_vintage
16
+ vav_name = name.get
17
+ case template
20
18
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
21
- if building_type == "Outpatient" and vav_name.include? "Floor 1"
22
- min_damper_position = 1
23
- elsif building_type == "Hospital" and vav_name.include? "PatRoom"
24
- min_damper_position = 1
25
- elsif building_type == "Hospital" and vav_name.include? "OR"
26
- min_damper_position = 1
27
- elsif building_type == "Hospital" and vav_name.include? "ICU"
28
- min_damper_position = 1
29
- elsif building_type == "Hospital" and vav_name.include? "Lab"
30
- min_damper_position = 1
31
- elsif building_type == "Hospital" and vav_name.include? "ER"
32
- min_damper_position = 1
33
- elsif building_type == "Hospital" and vav_name.include? "Kitchen"
34
- min_damper_position = 1
35
- elsif building_type == "Hospital" and vav_name.include? "NurseStn"
36
- min_damper_position = 0.3
37
- else
38
- min_damper_position = 0.3
39
- end
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 building_vintage
49
+ case template
52
50
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
53
- self.setConstantMinimumAirFlowFraction(min_damper_position)
51
+ setConstantMinimumAirFlowFraction(min_damper_position)
54
52
  else
55
53
  # High OA zones
56
- if building_type == "Outpatient"
57
- self.setConstantMinimumAirFlowFraction(1)
58
- elsif building_type == "Hospital"
59
- case building_vintage
60
- when '90.1-2010', '90.1-2013'
61
- if vav_name.include? "PatRoom"
62
- self.setConstantMinimumAirFlowFraction(0.5)
63
- else
64
- self.setConstantMinimumAirFlowFraction(1)
65
- end
66
- when '90.1-2004', '90.1-2007'
67
- self.setConstantMinimumAirFlowFraction(1)
68
- end
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
- self.setConstantMinimumAirFlowFraction(0.7)
68
+ setConstantMinimumAirFlowFraction(0.7)
72
69
  end
73
70
  end
74
71
  else
75
72
  # Low OA zones
76
- self.setConstantMinimumAirFlowFraction(min_damper_position)
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
- self.setControllerConvergenceTolerance(0.0001)
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 setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)
9
-
9
+ def apply_prototype_fan_pressure_rise(building_type, template, climate_zone)
10
10
  # NECB
11
- if building_vintage == 'NECB 2011' then
11
+ if template == 'NECB 2011'
12
12
  pressure_rise_pa = 640.0
13
- self.setPressureRise(pressure_rise_pa)
13
+ setPressureRise(pressure_rise_pa)
14
14
  return true
15
15
  end
16
-
17
- return true if self.name.to_s.include?("UnitHeater Fan")
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 self.maximumFlowRate.is_initialized
22
- maximum_flow_rate_m3_per_s = self.maximumFlowRate.get
23
- elsif self.autosizedMaximumFlowRate.is_initialized
24
- maximum_flow_rate_m3_per_s = self.autosizedMaximumFlowRate.get
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::logFree(OpenStudio::Warn, "openstudio.prototype.FanConstantVolume", "For #{self.name} max flow rate is not available, cannot apply prototype assumptions.")
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 self.containingZoneHVACComponent.is_initialized
39
- zone_hvac = self.containingZoneHVACComponent.get
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
- if self.airLoopHVAC.is_initialized
53
- case building_vintage
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
- pressure_rise_in_h2o = 2.5
57
- elsif maximum_flow_rate_cfm >= 7437 && maximum_flow_rate_cfm < 20000
58
- pressure_rise_in_h2o = 4.46
59
- else # Over 20,000 cfm
60
- pressure_rise_in_h2o = 4.09
61
- end
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
- pressure_rise_in_h2o = 2.5
65
- else # Over 7,437 cfm
66
- pressure_rise_in_h2o = 4.09
67
- end
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
- self.setPressureRise(pressure_rise_pa)
74
-
75
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.FanConstantVolume', "For Prototype: #{self.name}: #{maximum_flow_rate_cfm.round}cfm; Pressure Rise = #{pressure_rise_in_h2o}in w.c.")
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 setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)
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 self.maximumFlowRate.is_initialized
13
- maximum_flow_rate_m3_per_s = self.maximumFlowRate.get
14
- elsif self.autosizedMaximumFlowRate.is_initialized
15
- maximum_flow_rate_m3_per_s = self.autosizedMaximumFlowRate.get
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::logFree(OpenStudio::Warn, "openstudio.prototype.FanOnOff", "For #{self.name} max flow rate is not available, cannot apply prototype assumptions.")
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, "m^3/s", "cfm").get
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 self.containingZoneHVACComponent.is_initialized
30
- zone_hvac = self.containingZoneHVACComponent.get
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 self.airLoopHVAC.is_initialized
44
- case building_vintage
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
- pressure_rise_in_h2o = 2.5
48
- elsif maximum_flow_rate_cfm >= 7437 && maximum_flow_rate_cfm < 20000
49
- pressure_rise_in_h2o = 4.46
50
- else # Over 20,000 cfm
51
- pressure_rise_in_h2o = 4.09
52
- end
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
- pressure_rise_in_h2o = 2.5
56
- else # Over 7,437 cfm
57
- pressure_rise_in_h2o = 4.09
58
- end
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 self.airLoopHVAC.empty? && self.containingZoneHVACComponent.empty?
64
- case building_vintage
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
- pressure_rise_in_h2o = 2.5
68
- elsif maximum_flow_rate_cfm >= 7437 && maximum_flow_rate_cfm < 20000
69
- pressure_rise_in_h2o = 4.46
70
- else # Over 20,000 cfm
71
- pressure_rise_in_h2o = 4.09
72
- end
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
- pressure_rise_in_h2o = 2.5
76
- else # Over 7,437 cfm
77
- pressure_rise_in_h2o = 4.09
78
- end
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, "inH_{2}O","Pa").get
84
- self.setPressureRise(pressure_rise_pa)
85
-
86
- OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.FanOnOff", "For Prototype: #{self.name}: #{maximum_flow_rate_cfm.round}cfm; Pressure Rise = #{pressure_rise_in_h2o}in w.c.")
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