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.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards-ashrae_90_1(space_types).xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-cbes.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-deer.xlsx +0 -0
- data/data/standards/manage_OpenStudio_Standards.rb +4 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +2 -0
- data/data/standards/test_performance_expected_dd_results.csv +152 -152
- data/lib/openstudio-standards.rb +3 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +19 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +20 -6
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +130 -26
- data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +109 -0
- data/lib/openstudio-standards/standards/Standards.CoilDX.rb +10 -0
- data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +176 -0
- data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +124 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +13 -1
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +12 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.chillers.json +345 -3
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_pumps.json +154 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_pumps_heating.json +104 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_rejection.json +40 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.unitary_acs.json +75 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.water_heaters.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.water_source_heat_pumps.json +31 -0
- 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
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +0 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Model.rb +21 -2
- data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +12 -0
- data/lib/openstudio-standards/standards/deer/data/deer.fans.json +12 -0
- data/lib/openstudio-standards/version.rb +1 -1
- metadata +21 -11
- data/data/standards/OpenStudio_Standards-cbes(space_types).xlsx +0 -0
- data/data/standards/OpenStudio_Standards-deer(space_types).xlsx +0 -0
- data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
- data/data/standards/junk/legacy_dd_results - Copy.csv +0 -960
- data/data/standards/junk/legacy_dd_results.csv +0 -960
- data/data/standards/junk/legacy_dd_results_new - Copy.csv +0 -960
- data/data/standards/junk/legacy_dd_results_new.csv +0 -960
- data/data/standards/junk/legacy_dd_results_original.csv +0 -960
- 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
|
-
|
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
|
-
|
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
|
+
}
|