openstudio-standards 0.2.10.rc2 → 0.2.10.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards-ashrae_90_1(space_types).xlsx +0 -0
  3. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  4. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  5. data/data/standards/OpenStudio_Standards-cbes.xlsx +0 -0
  6. data/data/standards/OpenStudio_Standards-deer.xlsx +0 -0
  7. data/data/standards/manage_OpenStudio_Standards.rb +4 -0
  8. data/data/standards/openstudio_standards_duplicates_log.csv +2 -0
  9. data/data/standards/test_performance_expected_dd_results.csv +152 -152
  10. data/lib/openstudio-standards.rb +3 -0
  11. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +19 -3
  12. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +20 -6
  13. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +1 -1
  14. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +130 -26
  15. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +1 -1
  16. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +109 -0
  17. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +10 -0
  18. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +176 -0
  19. data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +124 -0
  20. data/lib/openstudio-standards/standards/Standards.Model.rb +13 -1
  21. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +6 -6
  22. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps.json +31 -0
  23. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps_heating.json +13 -0
  24. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps.json +31 -0
  25. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps_heating.json +13 -0
  26. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps.json +31 -0
  27. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps_heating.json +13 -0
  28. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps.json +31 -0
  29. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +13 -0
  30. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +12 -0
  31. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.water_source_heat_pumps.json +31 -0
  32. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.water_source_heat_pumps_heating.json +13 -0
  33. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.water_source_heat_pumps.json +31 -0
  34. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.water_source_heat_pumps_heating.json +13 -0
  35. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.chillers.json +345 -3
  36. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_pumps.json +154 -0
  37. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_pumps_heating.json +104 -4
  38. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_rejection.json +40 -0
  39. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.unitary_acs.json +75 -6
  40. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.water_heaters.json +2 -2
  41. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.water_source_heat_pumps.json +31 -0
  42. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.water_source_heat_pumps_heating.json +13 -0
  43. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +0 -6
  44. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Model.rb +21 -2
  45. data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +12 -0
  46. data/lib/openstudio-standards/standards/deer/data/deer.fans.json +12 -0
  47. data/lib/openstudio-standards/version.rb +1 -1
  48. metadata +21 -11
  49. data/data/standards/OpenStudio_Standards-cbes(space_types).xlsx +0 -0
  50. data/data/standards/OpenStudio_Standards-deer(space_types).xlsx +0 -0
  51. data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
  52. data/data/standards/junk/legacy_dd_results - Copy.csv +0 -960
  53. data/data/standards/junk/legacy_dd_results.csv +0 -960
  54. data/data/standards/junk/legacy_dd_results_new - Copy.csv +0 -960
  55. data/data/standards/junk/legacy_dd_results_new.csv +0 -960
  56. data/data/standards/junk/legacy_dd_results_original.csv +0 -960
  57. data/lib/openstudio-standards/standards/necb/NECB2011/newway.json +0 -8102
@@ -18,6 +18,8 @@ module CoilDX
18
18
  sub_category = 'Single Package'
19
19
  elsif coil_dx.name.get.to_s.include?('Split System')
20
20
  sub_category = 'Split System'
21
+ elsif coil_dx.name.get.to_s.include?('Minisplit')
22
+ sub_category = 'Split System'
21
23
  elsif coil_dx.name.get.to_s.include?('CRAC')
22
24
  sub_category = 'CRAC'
23
25
  end
@@ -73,6 +75,10 @@ module CoilDX
73
75
  containing_comp = coil_dx.containingHVACComponent.get
74
76
  if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
75
77
  htg_type = 'Electric Resistance or None'
78
+ elsif containing_comp.to_AirLoopHVACUnitarySystem.is_initialized
79
+ if containing_comp.name.to_s.include? 'Minisplit'
80
+ htg_type = 'All Other'
81
+ end
76
82
  end # TODO: Add other unitary systems
77
83
  elsif coil_dx.containingZoneHVACComponent.is_initialized
78
84
  containing_comp = coil_dx.containingZoneHVACComponent.get
@@ -101,6 +107,10 @@ module CoilDX
101
107
  'All Other'
102
108
  elsif !air_loop.supplyComponents('OS:Coil:Heating:DX:SingleSpeed'.to_IddObjectType).empty?
103
109
  'All Other'
110
+ elsif !air_loop.supplyComponents('OS:Coil:Heating:DX:MultiSpeed'.to_IddObjectType).empty?
111
+ 'All Other'
112
+ elsif !air_loop.supplyComponents('OS:Coil:Heating:DX:VariableSpeed'.to_IddObjectType).empty?
113
+ 'All Other'
104
114
  elsif !air_loop.supplyComponents('OS:Coil:Heating:Gas:MultiStage'.to_IddObjectType).empty?
105
115
  'All Other'
106
116
  elsif !air_loop.supplyComponents('OS:Coil:Heating:Desuperheater'.to_IddObjectType).empty?
@@ -0,0 +1,176 @@
1
+ class Standard
2
+ # @!group CoilHeatingWaterToAirHeatPumpEquationFit
3
+
4
+ # Finds capacity in W.
5
+ # This is the cooling capacity of the paired cooling coil.
6
+ #
7
+ # @return [Double] capacity in W to be used for find object
8
+ def coil_heating_water_to_air_heat_pump_find_capacity(coil_heating_water_to_air_heat_pump)
9
+ capacity_w = nil
10
+
11
+ # Get the paired cooling coil
12
+ clg_coil = nil
13
+
14
+ # Unitary and zone equipment
15
+ if coil_heating_water_to_air_heat_pump.airLoopHVAC.empty?
16
+ if coil_heating_water_to_air_heat_pump.containingHVACComponent.is_initialized
17
+ containing_comp = coil_heating_water_to_air_heat_pump.containingHVACComponent.get
18
+ if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
19
+ clg_coil = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAir.get.coolingCoil
20
+ elsif containing_comp.to_AirLoopHVACUnitarySystem.is_initialized
21
+ unitary = containing_comp.to_AirLoopHVACUnitarySystem.get
22
+ if unitary.coolingCoil.is_initialized
23
+ clg_coil = unitary.coolingCoil.get
24
+ end
25
+ end
26
+ elsif coil_heating_water_to_air_heat_pump.containingZoneHVACComponent.is_initialized
27
+ containing_comp = coil_heating_water_to_air_heat_pump.containingZoneHVACComponent.get
28
+ # PTHP
29
+ if containing_comp.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
30
+ clg_coil = containing_comp.to_ZoneHVACPackagedTerminalHeatPump.get.coolingCoil
31
+ # WSHP
32
+ elsif containing_comp.to_ZoneHVACWaterToAirHeatPump.is_initialized
33
+ clg_coil = containing_comp.to_ZoneHVACWaterToAirHeatPump.get.coolingCoil
34
+ end
35
+ end
36
+ end
37
+
38
+ # On AirLoop directly
39
+ if coil_heating_water_to_air_heat_pump.airLoopHVAC.is_initialized
40
+ air_loop = coil_heating_water_to_air_heat_pump.airLoopHVAC.get
41
+ # Check for the presence of any other type of cooling coil
42
+ clg_types = ['OS:Coil:Cooling:DX:SingleSpeed',
43
+ 'OS:Coil:Cooling:DX:TwoSpeed',
44
+ 'OS:Coil:Cooling:DX:MultiSpeed']
45
+ clg_types.each do |ct|
46
+ coils = air_loop.supplyComponents(ct.to_IddObjectType)
47
+ next if coils.empty?
48
+
49
+ clg_coil = coils[0]
50
+ break # Stop on first cooling coil found
51
+ end
52
+ end
53
+
54
+ # If no paired cooling coil was found,
55
+ # throw an error and fall back to the heating capacity of the heating coil
56
+ if clg_coil.nil?
57
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingWaterToAirHeatPumpEquationFit', "For #{coil_heating_water_to_air_heat_pump.name}, the paired cooling coil could not be found to determine capacity. Efficiency will incorrectly be based on coil's heating capacity.")
58
+ if coil_heating_water_to_air_heat_pump.ratedTotalHeatingCapacity.is_initialized
59
+ capacity_w = coil_heating_water_to_air_heat_pump.ratedTotalHeatingCapacity.get
60
+ elsif coil_heating_water_to_air_heat_pump.autosizedRatedTotalHeatingCapacity.is_initialized
61
+ capacity_w = coil_heating_water_to_air_heat_pump.autosizedRatedTotalHeatingCapacity.get
62
+ else
63
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingWaterToAirHeatPumpEquationFit', "For #{coil_heating_water_to_air_heat_pump.name} capacity is not available, cannot apply efficiency standard to paired heating coil.")
64
+ return 0.0
65
+ end
66
+ return capacity_w
67
+ end
68
+
69
+ # If a coil was found, cast to the correct type
70
+ if clg_coil.to_CoilCoolingDXSingleSpeed.is_initialized
71
+ clg_coil = clg_coil.to_CoilCoolingDXSingleSpeed.get
72
+ capacity_w = coil_cooling_dx_single_speed_find_capacity(clg_coil)
73
+ elsif clg_coil.to_CoilCoolingDXTwoSpeed.is_initialized
74
+ clg_coil = clg_coil.to_CoilCoolingDXTwoSpeed.get
75
+ capacity_w = coil_cooling_dx_two_speed_find_capacity(clg_coil)
76
+ elsif clg_coil.to_CoilCoolingDXMultiSpeed.is_initialized
77
+ clg_coil = clg_coil.to_CoilCoolingDXMultiSpeed.get
78
+ capacity_w = coil_cooling_dx_multi_speed_find_capacity(clg_coil)
79
+ elsif clg_coil.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized
80
+ clg_coil = clg_coil.to_CoilCoolingWaterToAirHeatPumpEquationFit.get
81
+ capacity_w = coil_cooling_water_to_air_heat_pump_find_capacity(clg_coil)
82
+ end
83
+
84
+ return capacity_w
85
+ end
86
+
87
+ # Finds lookup object in standards and return efficiency
88
+ #
89
+ # @param rename [Bool] if true, object will be renamed to include capacity and efficiency level
90
+ # @return [Double] full load efficiency (COP)
91
+ def coil_heating_water_to_air_heat_pump_standard_minimum_cop(coil_heating_water_to_air_heat_pump, rename = false)
92
+ search_criteria = {}
93
+ search_criteria['template'] = template
94
+ capacity_w = coil_heating_water_to_air_heat_pump_find_capacity(coil_heating_water_to_air_heat_pump)
95
+ capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
96
+ capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
97
+
98
+ # Look up the efficiency characteristics
99
+ coil_props = model_find_object(standards_data['water_source_heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
100
+
101
+ # Check to make sure properties were found
102
+ if coil_props.nil?
103
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingWaterToAirHeatPumpEquationFit', "For #{coil_heating_water_to_air_heat_pump.name}, cannot find efficiency info using #{search_criteria}, cannot apply efficiency standard.")
104
+ successfully_set_all_properties = false
105
+ return successfully_set_all_properties
106
+ end
107
+
108
+ # Get the minimum efficiency standards
109
+ cop = nil
110
+
111
+ # If specified as EER
112
+ unless coil_props['minimum_coefficient_of_performance_heating'].nil?
113
+ cop = coil_props['minimum_coefficient_of_performance_heating']
114
+ new_comp_name = "#{coil_heating_water_to_air_heat_pump.name} #{capacity_kbtu_per_hr.round} Clg kBtu/hr #{cop.round(1)}COPH"
115
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingWaterToAirHeatPumpEquationFit', "For #{template}: #{coil_heating_water_to_air_heat_pump.name}: Cooling Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; COPH = #{cop}")
116
+ end
117
+
118
+ # Rename
119
+ if rename
120
+ coil_heating_water_to_air_heat_pump.setName(new_comp_name)
121
+ end
122
+
123
+ return cop
124
+ end
125
+
126
+ # Applies the standard efficiency ratings and typical performance curves to this object.
127
+ #
128
+ # @return [Bool] true if successful, false if not
129
+ def coil_heating_water_to_air_heat_pump_apply_efficiency_and_curves(coil_heating_water_to_air_heat_pump, sql_db_vars_map)
130
+ successfully_set_all_properties = true
131
+
132
+ # Get the search criteria
133
+ search_criteria = {}
134
+ search_criteria['template'] = template
135
+ capacity_w = coil_heating_water_to_air_heat_pump_find_capacity(coil_heating_water_to_air_heat_pump)
136
+ capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
137
+
138
+ # Look up the efficiency characteristics
139
+ coil_props = model_find_object(standards_data['water_source_heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
140
+
141
+ # Check to make sure properties were found
142
+ if coil_props.nil?
143
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingWaterToAirHeatPumpEquationFit', "For #{coil_heating_water_to_air_heat_pump.name}, cannot find efficiency info using #{search_criteria}, cannot apply efficiency standard.")
144
+ successfully_set_all_properties = false
145
+ return sql_db_vars_map
146
+ end
147
+
148
+ # TODO: Add methods to set coefficients, and add coefficients to data spreadsheet
149
+ # using OS defaults for now
150
+ # heat_cap_coeff1 = coil_props['heat_cap_coeff1']
151
+ # if heat_cap_coeff1
152
+ # coil_heating_water_to_air_heat_pump.setHeatingCapacityCoefficient1(heat_cap_coeff1)
153
+ # else
154
+ # OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingWaterToAirHeatPumpEquationFit', "For #{coil_heating_water_to_air_heat_pump.name}, cannot find heat_cap_coeff1, will not be set.")
155
+ # successfully_set_all_properties = false
156
+ # end
157
+
158
+ # Preserve the original name
159
+ orig_name = coil_heating_water_to_air_heat_pump.name.to_s
160
+
161
+ # Find the minimum COP and rename with efficiency rating
162
+ cop = coil_heating_water_to_air_heat_pump_standard_minimum_cop(coil_heating_water_to_air_heat_pump, true)
163
+
164
+ # Map the original name to the new name
165
+ sql_db_vars_map[coil_heating_water_to_air_heat_pump.name.to_s] = orig_name
166
+
167
+ # Set the efficiency values
168
+ unless cop.nil?
169
+ coil_heating_water_to_air_heat_pump.setRatedHeatingCoefficientofPerformance(cop)
170
+ end
171
+
172
+ return sql_db_vars_map
173
+ end
174
+
175
+
176
+ end
@@ -0,0 +1,124 @@
1
+ class Standard
2
+ # @!group FluidCooler
3
+
4
+ # Set the fluid cooler fan power such that the tower
5
+ # hits the minimum performance (gpm/hp) specified by the standard.
6
+ # Note that in this case hp is motor nameplate hp, per 90.1.
7
+ # This method assumes that the fan brake horsepower is 90%
8
+ # of the motor nameplate hp.
9
+ # This method determines the minimum motor efficiency
10
+ # for the nameplate motor hp and sets the actual
11
+ # fan power by multiplying the brake horsepower
12
+ # by the efficiency. Thus the fan power used as
13
+ # an input to the simulation divided by the design flow
14
+ # rate will not (and should not)
15
+ # exactly equal the minimum tower performance.
16
+ #
17
+ # @return [Bool] true if successful, false if not
18
+ def fluid_cooler_apply_minimum_power_per_flow(fluid_cooler)
19
+ # Get the design water flow rate
20
+ if fluid_cooler.designWaterFlowRate.is_initialized
21
+ design_water_flow_m3_per_s = fluid_cooler.designWaterFlowRate.get
22
+ elsif fluid_cooler.autosizedDesignWaterFlowRate.is_initialized
23
+ design_water_flow_m3_per_s = fluid_cooler.autosizedDesignWaterFlowRate.get
24
+ else
25
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.FluidCooler', "For #{fluid_cooler.name} design water flow rate is not available, cannot apply efficiency standard.")
26
+ return false
27
+ end
28
+ design_water_flow_gpm = OpenStudio.convert(design_water_flow_m3_per_s, 'm^3/s', 'gal/min').get
29
+
30
+ # Get the table of fluid cooler efficiencies
31
+ heat_rejection = standards_data['heat_rejection']
32
+
33
+ # Define the criteria to find the fluid cooler properties
34
+ # in the hvac standards data set.
35
+ search_criteria = {}
36
+ search_criteria['template'] = template
37
+
38
+ # Closed cooling towers are fluidcooler objects.
39
+ search_criteria['equipment_type'] = 'Closed Cooling Tower'
40
+
41
+ # TODO: Standards replace this with a mechanism to store this
42
+ # data in the fluid cooler object itself.
43
+ # For now, retrieve the fan type from the name
44
+ name = fluid_cooler.name.get
45
+ if name.include?('Centrifugal')
46
+ fan_type = 'Centrifugal'
47
+ elsif name.include?('Propeller or Axial')
48
+ fan_type = 'Propeller or Axial'
49
+ else
50
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.FluidCooler', "Cannot find fan type for #{fluid_cooler.name}. Assuming propeller or axial.")
51
+ fan_type = 'Propeller or Axial'
52
+ end
53
+ unless fan_type.nil?
54
+ search_criteria['fan_type'] = fan_type
55
+ end
56
+
57
+ # Get the fluid cooler properties
58
+ ct_props = model_find_object(heat_rejection, search_criteria)
59
+ unless ct_props
60
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.FluidCooler', "For #{fluid_cooler.name}, cannot find heat rejection properties, cannot apply standard efficiencies or curves.")
61
+ return false
62
+ end
63
+
64
+ # Get fluid cooler efficiency
65
+ min_gpm_per_hp = ct_props['minimum_performance']
66
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.FluidCooler', "For #{fluid_cooler.name}, design water flow = #{design_water_flow_gpm.round} gpm, minimum performance = #{min_gpm_per_hp} gpm/hp (nameplate).")
67
+
68
+ # Calculate the allowed fan brake horsepower
69
+ # per method used in PNNL prototype buildings.
70
+ # Assumes that the fan brake horsepower is 90%
71
+ # of the fan nameplate rated motor power.
72
+ fan_motor_nameplate_hp = design_water_flow_gpm / min_gpm_per_hp
73
+ fan_bhp = 0.9 * fan_motor_nameplate_hp
74
+
75
+ # Lookup the minimum motor efficiency
76
+ motors = standards_data['motors']
77
+
78
+ # Assuming all fan motors are 4-pole Enclosed
79
+ search_criteria = {
80
+ 'template' => template,
81
+ 'number_of_poles' => 4.0,
82
+ 'type' => 'Enclosed'
83
+ }
84
+
85
+ motor_properties = model_find_object(motors, search_criteria, fan_motor_nameplate_hp)
86
+ if motor_properties.nil?
87
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.FluidCooler', "For #{fluid_cooler.name}, could not find motor properties using search criteria: #{search_criteria}, motor_hp = #{motor_hp} hp.")
88
+ return false
89
+ end
90
+
91
+ fan_motor_eff = motor_properties['nominal_full_load_efficiency']
92
+ nominal_hp = motor_properties['maximum_capacity'].to_f.round(1)
93
+ # Round to nearest whole HP for niceness
94
+ if nominal_hp >= 2
95
+ nominal_hp = nominal_hp.round
96
+ end
97
+
98
+ # Calculate the fan motor power
99
+ fan_motor_actual_power_hp = fan_bhp / fan_motor_eff
100
+ # Convert to W
101
+ fan_motor_actual_power_w = fan_motor_actual_power_hp * 745.7 # 745.7 W/HP
102
+
103
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.FluidCooler', "For #{fluid_cooler.name}, allowed fan motor nameplate hp = #{fan_motor_nameplate_hp.round(1)} hp, fan brake horsepower = #{fan_bhp.round(1)}, and fan motor actual power = #{fan_motor_actual_power_hp.round(1)} hp (#{fan_motor_actual_power_w.round} W) at #{fan_motor_eff} motor efficiency.")
104
+
105
+ # Append the efficiency to the name
106
+ fluid_cooler.setName("#{fluid_cooler.name} #{min_gpm_per_hp.round(1)} gpm/hp")
107
+
108
+ # Hard size the design fan power.
109
+ # Leave the water flow and air flow autosized.
110
+ if fluid_cooler.to_FluidCoolerSingleSpeed.is_initialized
111
+ fluid_cooler.setDesignAirFlowRateFanPower(fan_motor_actual_power_w)
112
+ elsif fluid_cooler.to_FluidCoolerTwoSpeed.is_initialized
113
+ fluid_cooler.setHighFanSpeedFanPower(fan_motor_actual_power_w)
114
+ fluid_cooler.setLowFanSpeedFanPower(0.3 * fan_motor_actual_power_w)
115
+ elsif fluid_cooler.to_EvaporativeFluidCoolerSingleSpeed.is_initialized
116
+ fluid_cooler.setFanPoweratDesignAirFlowRate(fan_motor_actual_power_w)
117
+ elsif fluid_cooler.to_EvaporativeFluidCoolerTwoSpeed.is_initialized
118
+ fluid_cooler.setHighFanSpeedFanPower(fan_motor_actual_power_w)
119
+ fluid_cooler.setLowFanSpeedFanPower(0.3 * fan_motor_actual_power_w)
120
+ end
121
+
122
+ return true
123
+ end
124
+ end
@@ -1511,6 +1511,11 @@ class Standard
1511
1511
  model.getCoilCoolingDXTwoSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_two_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1512
1512
  model.getCoilCoolingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_single_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1513
1513
 
1514
+ # WSHPs
1515
+ # set WSHP heating coils before cooling coils to get cooling coil capacities before they are renamed
1516
+ model.getCoilHeatingWaterToAirHeatPumpEquationFits.sort.each { |obj| sql_db_vars_map = coil_heating_water_to_air_heat_pump_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1517
+ model.getCoilCoolingWaterToAirHeatPumpEquationFits.sort.each { |obj| sql_db_vars_map = coil_cooling_water_to_air_heat_pump_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1518
+
1514
1519
  # Chillers
1515
1520
  clg_tower_objs = model.getCoolingTowerSingleSpeeds
1516
1521
  model.getChillerElectricEIRs.sort.each { |obj| chiller_electric_eir_apply_efficiency_and_curves(obj, clg_tower_objs) }
@@ -1526,11 +1531,18 @@ class Standard
1526
1531
  model.getCoolingTowerTwoSpeeds.sort.each { |obj| cooling_tower_two_speed_apply_efficiency_and_curves(obj) }
1527
1532
  model.getCoolingTowerVariableSpeeds.sort.each { |obj| cooling_tower_variable_speed_apply_efficiency_and_curves(obj) }
1528
1533
 
1534
+ # Fluid Coolers
1535
+ # TODO: enable when evaportive fluid cooler methods and data are available
1536
+ # model.getFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1537
+ # model.getFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1538
+ # model.getEvaporativeFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1539
+ # model.getEvaporativeFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1540
+
1529
1541
  # ERVs
1530
1542
  model.getHeatExchangerAirToAirSensibleAndLatents.each { |obj| heat_exchanger_air_to_air_sensible_and_latent_apply_efficiency(obj) }
1531
1543
 
1532
1544
  # Gas Heaters
1533
- model.getCoilHeatingGass.sort.each {|obj| coil_heating_gas_apply_efficiency_and_curves(obj)}
1545
+ model.getCoilHeatingGass.sort.each { |obj| coil_heating_gas_apply_efficiency_and_curves(obj) }
1534
1546
 
1535
1547
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying HVAC efficiency standards.')
1536
1548
  end
@@ -37,7 +37,7 @@ class Standard
37
37
  OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, cannot find volume, standard will not be applied.")
38
38
  return false
39
39
  else
40
- volume_m3 = @instvarbuilding_type == 'MidriseApartment' ? volume_m3.get / 23 : volume_m3.get / water_heater_mixed.component_quantity
40
+ volume_m3 = @instvarbuilding_type == 'MidriseApartment' ? volume_m3.get / 23 : volume_m3.get / water_heater_mixed.component_quantity
41
41
  end
42
42
  volume_gal = OpenStudio.convert(volume_m3, 'm^3', 'gal').get
43
43
 
@@ -82,7 +82,7 @@ class Standard
82
82
  # differently depending on the fuel type
83
83
  if fuel_type == 'Electricity'
84
84
  # Fixed water heater efficiency per PNNL
85
- water_heater_eff = 1
85
+ water_heater_eff = 1.0
86
86
  ua_btu_per_hr_per_f = (41_094 * (1 / ef - 1)) / (24 * 67.5)
87
87
  elsif fuel_type == 'NaturalGas'
88
88
  # Fixed water heater thermal efficiency per PNNL
@@ -102,13 +102,13 @@ class Standard
102
102
  ua_btu_per_hr_per_f = (water_heater_eff - re) * capacity_btu_per_hr / 0.8 / 67.5
103
103
  end
104
104
  # Two booster water heaters
105
- ua_btu_per_hr_per_f = water_heater_mixed.name.to_s.include?('Booster') ? ua_btu_per_hr_per_f * 2 : ua_btu_per_hr_per_f
105
+ ua_btu_per_hr_per_f = water_heater_mixed.name.to_s.include?('Booster') ? ua_btu_per_hr_per_f * 2 : ua_btu_per_hr_per_f
106
106
  end
107
107
 
108
108
  # Typically specified this way for large electric water heaters
109
109
  if wh_props['standby_loss_base'] && wh_props['standby_loss_volume_allowance']
110
110
  # Fixed water heater efficiency per PNNL
111
- water_heater_eff = 1
111
+ water_heater_eff = 1.0
112
112
  # Calculate the max allowable standby loss (SL)
113
113
  sl_base = wh_props['standby_loss_base']
114
114
  sl_drt = wh_props['standby_loss_volume_allowance']
@@ -121,11 +121,11 @@ class Standard
121
121
  # Typically specified this way for newer large electric water heaters
122
122
  if wh_props['hourly_loss_base'] && wh_props['hourly_loss_volume_allowance']
123
123
  # Fixed water heater efficiency per PNNL
124
- water_heater_eff = 1
124
+ water_heater_eff = 1.0
125
125
  # Calculate the percent loss per hr
126
126
  hr_loss_base = wh_props['hourly_loss_base']
127
127
  hr_loss_allow = wh_props['hourly_loss_volume_allowance']
128
- hrly_loss_pct = hr_loss_base + (hr_loss_allow / volume_gal) / 100
128
+ hrly_loss_pct = hr_loss_base + (hr_loss_allow / volume_gal) / 100.0
129
129
  # Convert to Btu/hr, assuming:
130
130
  # Water at 120F, density = 8.25 lb/gal
131
131
  # 1 Btu to raise 1 lb of water 1 F
@@ -0,0 +1,31 @@
1
+ {
2
+ "water_source_heat_pumps": [
3
+ {
4
+ "template": "90.1-2004",
5
+ "minimum_capacity": 0.0,
6
+ "maximum_capacity": 16999.0,
7
+ "start_date": "1919-09-09T00:00:00+00:00",
8
+ "end_date": "2999-09-09T00:00:00+00:00",
9
+ "minimum_full_load_efficiency": 11.2,
10
+ "notes": "From 90.1-2004 Table 6.8.1B"
11
+ },
12
+ {
13
+ "template": "90.1-2004",
14
+ "minimum_capacity": 17000.0,
15
+ "maximum_capacity": 64999.0,
16
+ "start_date": "1919-09-09T00:00:00+00:00",
17
+ "end_date": "2999-09-09T00:00:00+00:00",
18
+ "minimum_full_load_efficiency": 12.0,
19
+ "notes": "From 90.1-2004 Table 6.8.1B"
20
+ },
21
+ {
22
+ "template": "90.1-2004",
23
+ "minimum_capacity": 65000.0,
24
+ "maximum_capacity": 134999.0,
25
+ "start_date": "1919-09-09T00:00:00+00:00",
26
+ "end_date": "2999-09-09T00:00:00+00:00",
27
+ "minimum_full_load_efficiency": 12.0,
28
+ "notes": "From 90.1-2004 Table 6.8.1B"
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "water_source_heat_pumps_heating": [
3
+ {
4
+ "template": "90.1-2004",
5
+ "minimum_capacity": 0.0,
6
+ "maximum_capacity": 9999999.0,
7
+ "start_date": "1919-09-09T00:00:00+00:00",
8
+ "end_date": "2999-09-09T00:00:00+00:00",
9
+ "minimum_coefficient_of_performance_heating": 4.2,
10
+ "notes": "From 90.1-2004 Table 6.8.1B"
11
+ }
12
+ ]
13
+ }