Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Sensible Capacity Curves with ADP/BF #1707

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
698aaf4
Committing pseudo_code_heat_pump_sizing.txt to branch OS_ACCA_Man_S_u…
Sashadf1 Apr 2, 2024
1ac11a2
adding comment on apply_equipment_adjustments
Sashadf1 Apr 8, 2024
82e23b6
Merge remote-tracking branch 'origin/master' into acca_manual_s
Sashadf1 Apr 8, 2024
af484e8
adding explanatory comments
Sashadf1 Apr 8, 2024
49e998d
hvac_sizing.rb
Sashadf1 Apr 9, 2024
2aca92f
Committing comments for ADP/BF
Sashadf1 May 8, 2024
6861e46
Merge branch 'master' into adp_bf_method_design_shr
Sashadf1 May 8, 2024
af58345
Translating E+ coil bypass factor method to recalculate cool_cap_design
Sashadf1 May 9, 2024
c1a7827
calculating A_o_rated with correct unit conversions and methods in ps…
Sashadf1 May 10, 2024
2cdde89
renamed A_o from A_o rated because A_o is not a function of design vs…
Sashadf1 May 10, 2024
1e3ef9a
refactor add_cooling_system function variable input order convention …
Sashadf1 May 13, 2024
7905315
fixed typo in comments of CoilAoFactor method in psychrometrics.rb
Sashadf1 May 14, 2024
f9ed1b8
fixed typo in descriptive comments of psychrometrics.rb
Sashadf1 May 14, 2024
74bb5fa
removing pesky return 1.0 that shouldn't be there, preventing it from…
Sashadf1 May 14, 2024
0391906
Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML int…
yzhou601 May 17, 2024
85b2e27
work on implementing ADP/BF. coil a_o factor already calculated in hv…
Sashadf1 May 21, 2024
d37f8c1
using pre-existing coil ao factor stored in cooling additional proper…
Sashadf1 May 30, 2024
26a55b3
fixed unit conversion on cool_cap_rated so that Psychrometrics.rb doe…
Sashadf1 May 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions HPXMLtoOpenStudio/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ def create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, epw_file, weat
@hvac_unavailable_periods = Schedule.get_unavailable_periods(runner, SchedulesFile::Columns[:HVAC].name, @hpxml_header.unavailable_periods)
airloop_map = {} # Map of HPXML System ID -> AirLoopHVAC (or ZoneHVACFourPipeFanCoil)
add_ideal_system(model, spaces, epw_path)
add_cooling_system(model, runner, weather, spaces, airloop_map)
add_cooling_system(runner, model, weather, spaces, airloop_map)
add_heating_system(runner, model, weather, spaces, airloop_map)
add_heat_pump(runner, model, weather, spaces, airloop_map)
add_dehumidifiers(runner, model, spaces)
Expand Down Expand Up @@ -1594,7 +1594,7 @@ def add_hot_water_and_appliances(runner, model, weather, spaces)
Waterheater.apply_combi_system_EMS(model, @hpxml_bldg.water_heating_systems, plantloop_map)
end

def add_cooling_system(model, runner, weather, spaces, airloop_map)
def add_cooling_system(runner, model, weather, spaces, airloop_map)
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get

HVAC.get_hpxml_hvac_systems(@hpxml_bldg).each do |hvac_system|
Expand Down
3 changes: 2 additions & 1 deletion HPXMLtoOpenStudio/resources/hvac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2993,7 +2993,8 @@ def self.set_cool_rated_shrs_gross(runner, cooling_system)
p_atm = UnitConversions.convert(1, 'atm', 'psi')

ao = Psychrometrics.CoilAoFactor(runner, dB_rated, p_atm, UnitConversions.convert(1, 'ton', 'kBtu/hr'), cool_nominal_cfm_per_ton, cooling_system.cooling_shr, win)


clg_ap.a_o = ao
clg_ap.cool_rated_shrs_gross = []
clg_ap.cool_capacity_ratios.each_with_index do |capacity_ratio, i|
# Calculate the SHR for each speed. Use minimum value of 0.98 to prevent E+ bypass factor calculation errors
Expand Down
49 changes: 37 additions & 12 deletions HPXMLtoOpenStudio/resources/hvac_sizing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def self.calculate(runner, weather, hpxml_bldg, hvac_systems, update_hpxml: true
end

# Assign initial loads for each HVAC system (before duct loads)
all_hvac_loads = {}
hvac_systems.each do |hvac_system|
all_hvac_loads = {} #assign hvac_sizing_values to empty hash
hvac_systems.each do |hvac_system| #loop thru each hvac_system object
hvac_heating, hvac_cooling = hvac_system[:heating], hvac_system[:cooling]
zone = hvac_heating.nil? ? hvac_cooling.zone : hvac_heating.zone
next if is_system_to_skip(hvac_heating, hvac_cooling, zone)
Expand Down Expand Up @@ -1689,6 +1689,7 @@ def self.apply_hvac_duct_loads_cooling(mj, zone, hvac_loads, zone_loads, all_spa
def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hvac_heating, hvac_cooling, hvac_system, hpxml_bldg)
'''
Equipment Adjustments
This is where the bulk of ACCA Man. S is applied
'''

# Cooling
Expand Down Expand Up @@ -1716,8 +1717,16 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva
# such as different indoor/outdoor coil combinations and different blower settings.
# Ductless systems don't offer this flexibility.

#per E+ docs, capacity and SHR inputs should be “gross” values

entering_temp = hpxml_bldg.header.manualj_cooling_design_temp
hvac_cooling_speed = get_sizing_speed(hvac_cooling_ap, true)
#ADP/BF specified for Coil:Cooling:DX:SingleSpeed, but should be implemented for all coils
#rated total capacity and rated SHR are used to calculate coil bypass factor constant A_o at rated conditions
#this is already done in hvac.rb and stored in the hvac_cooling_ap object
#once A_o is determined, the BF at design conditions can be calculated and used to determine the design SHR
#last step is to calculate sensible capacity at design conditions using design_shr

if hvac_cooling.compressor_type == HPXML::HVACCompressorTypeVariableSpeed
idb_adj = adjust_indoor_condition_var_speed(entering_temp, mj.cool_indoor_wetbulb, :clg)
odb_adj = adjust_outdoor_condition_var_speed(hvac_cooling.cooling_detailed_performance_data, entering_temp, hvac_cooling, :clg)
Expand All @@ -1729,21 +1738,35 @@ def self.apply_hvac_equipment_adjustments(mj, runner, hvac_sizings, weather, hva

cool_cap_rated = hvac_sizings.Cool_Load_Tot / total_cap_curve_value

hvac_cooling_shr = hvac_cooling_ap.cool_rated_shrs_gross[hvac_cooling_speed]
hvac_cooling_shr = hvac_cooling_ap.cool_rated_shrs_gross[hvac_cooling_speed] #same as net shr per comments in hvac.rb, see set_cool_rated_shrs_gross for details
sens_cap_rated = cool_cap_rated * hvac_cooling_shr

# Calculate the air flow rate required for design conditions
hvac_sizings.Cool_Airflow = calc_airflow_rate_manual_s(mj, hvac_sizings.Cool_Load_Sens, (mj.cool_setpoint - leaving_air_temp), cool_cap_rated)
#units of Cool_Airflow are cfm
#calculate rated coil bypass factor HERE, then use rated BF --> design BF --> design SHR --> design sensible capacity

cool_airflow_rated = UnitConversions.convert(cool_cap_rated, 'Btu/hr', 'ton')*hvac_cooling.additional_properties.cool_rated_cfm_per_ton[-1] #rated cfm, check whether cfm/ton is net or gross?
#following Calculate max rated cfm section in hvac.rb, which sets rated airflow to the product of detailed performance capacity and the last (highest speed?) element of cool_rated_cfm_per_ton array
#for base.xml, cool_airflow_rated = 705.6 cfm and hvac_sizings.Cool_Airflow = 715.96 cfm
#assuming hvac_sizings.Cool_Airflow is the design airflow rate, inferred from comments in calc_airflow_rate_manual_s
#note: using MJ cooling setpoint as EDB in Psychrometrics.calculateSHR() ignores return duct losses

sensible_cap_curve_value = process_curve_fit(hvac_sizings.Cool_Airflow, hvac_sizings.Cool_Load_Tot, entering_temp)
sens_cap_design = sens_cap_rated * sensible_cap_curve_value
lat_cap_design = [hvac_sizings.Cool_Load_Tot - sens_cap_design, 1.0].max
hr_indoor_cooling_local = calculate_indoor_hr(hpxml_bldg.header.manualj_humidity_setpoint, mj.cool_setpoint, mj.p_atm)
#hr_indoor_cooling is calculated above in the script, but is calculated after the method call of apply_hvac_equipment_adjustments. Therefore, it needs to calculated from MJ objects locally in apply_hvac_equipment_adjustments for use in CalculateSHR().

hvac_cooling_ap.rated_shr = Psychrometrics.CalculateSHR(runner, mj.cool_setpoint, UnitConversions.convert(mj.p_atm, 'atm', 'psi'), UnitConversions.convert(cool_cap_rated, 'btu/hr', 'kbtu/hr'), hvac_sizings.Cool_Airflow, hvac_cooling_ap.a_o, hr_indoor_cooling_local)
#Calculate the coil SHR at the given incoming air state, CFM, total capacity, and coil Ao factor
#coil Ao needs to be in SI units, currently 0.38 for base.xml --> check if unit conversion is necessary?
puts(hvac_cooling_shr)
puts(hvac_cooling_ap.rated_shr)

sens_cap_design = cool_cap_design*hvac_cooling_shr_design

lat_cap_design = [hvac_sizing_values.Cool_Load_Tot - sens_cap_design, 1.0].max



shr_biquadratic = get_shr_biquadratic
a_sens = shr_biquadratic[0]
b_sens = shr_biquadratic[1]
c_sens = shr_biquadratic[3]
d_sens = shr_biquadratic[5]

# Adjust Sizing
if hvac_cooling.is_a?(HPXML::HeatPump) && (hpxml_bldg.header.heat_pump_sizing_methodology == HPXML::HeatPumpSizingHERS)
Expand Down Expand Up @@ -2876,10 +2899,12 @@ def self.process_curve_fit(airflow_rate, capacity, temp)

def self.get_shr_biquadratic
# Based on EnergyPlus's model for calculating SHR at off-rated conditions. This curve fit
# avoids the iterations in the actual model. It does not account for altitude or variations
# avoids the iterations in the actual model. The ADP/BF method incorporates these iterations. It does not account for altitude or variations
# in the SHRRated. It is a function of ODB (MJ design temp) and CFM/Ton (from MJ)
return [1.08464364, 0.002096954, 0, -0.005766327, 0, -0.000011147]
end
#get_shr_biquadratic will be replaced with ADP/BF method for calculating SHR at off-rated conditions


def self.get_sizing_speed(hvac_ap, is_cooling)
if is_cooling && hvac_ap.respond_to?(:cool_capacity_ratios)
Expand Down
14 changes: 14 additions & 0 deletions HPXMLtoOpenStudio/resources/pseudo_code_heat_pump_sizing.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#Pseudo-Code for Heat Pump Sizing Condition
def assign_hvac_sizing_condition(mj, system_design_loads, hvac_heating, hvac_cooling)
Assign HVAC sizing condition "String Classification" that takes in system design loads from MJ
Step 1: produce MJ load calc (already done)
Step 2: follow equipment selection and sizing procedure flowchart
- if system is heat pump, determine HP sizing condition
- else, either clg only, furnace, or boiler yes/no checks
Step 3: procure OEM performance data
- is forced air system?
- water-air system?
- ACF required? (altitude above 2,500 ft)
- extract capacity from OEM performance data, interpolate if necessary
- determine blower CFM
Step 4: apply sizing requirements (normative section N2)
6 changes: 3 additions & 3 deletions HPXMLtoOpenStudio/resources/psychrometrics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def self.CoilAoFactor(runner, dBin, p, qdot, cfm, shr, win)
'''
Description:
------------
Find the coil Ao factor at the given incoming air state (entering drybubl and wetbulb) and CFM,
Find the coil Ao factor at the given incoming air state (entering drybulb and wetbulb) and CFM,
total capacity and SHR


Expand Down Expand Up @@ -428,7 +428,7 @@ def self.CoilBypassFactor(runner, dBin, p, qdot, cfm, shr, win)
'''
Description:
------------
Find the coil bypass factor at the given incoming air state (entering drybubl and wetbulb) and CFM,
Find the coil bypass factor at the given incoming air state (entering drybulb and wetbulb) and CFM,
total capacity and SHR


Expand Down Expand Up @@ -514,7 +514,7 @@ def self.CalculateMassflowRate(dBin, p, cfm, win)
'''
Description:
------------
Calculate the mass flow rate at the given incoming air state (entering drybubl and wetbulb) and CFM
Calculate the mass flow rate at the given incoming air state (entering drybul and wetbulb) and CFM

Source:
-------
Expand Down