diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ed84a14..f34e35fbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ Classify the change according to the following categories: - Change type of **value_of_lost_load** in **FinancialInputs** struct to fix convert error when user provides an _Int_ - Change international location in "Solar Dataset" test set from Cameroon to Oulu because the locations in the NSRDB have been expanded significantly so there is now an NSRDB point at Cameroon - Handle edge case where the values of **outage_start_time_steps** and **outage_durations** makes an outage extend beyond the end of the year. The outage will now wrap around to the beginning of the year. +- Enforce minimum allowable sizes for ASHP technologies by introducing improved big-M values for segmented size constraints. +- Removed default values from ASHP functions that calculate minimum allowable size and performance. ## v0.48.0 ### Added diff --git a/src/core/ashp.jl b/src/core/ashp.jl index f2f2bfcc0..b29a4fe7f 100644 --- a/src/core/ashp.jl +++ b/src/core/ashp.jl @@ -444,14 +444,14 @@ function get_ashp_performance(cop_reference, cf_reference, reference_temps, ambient_temp_degF, - back_up_temp_threshold_degF = 10.0 + back_up_temp_threshold_degF ) """ function get_ashp_performance(cop_reference, cf_reference, reference_temps, ambient_temp_degF, - back_up_temp_threshold_degF = 10.0 + back_up_temp_threshold_degF ) num_timesteps = length(ambient_temp_degF) cop = zeros(num_timesteps) @@ -493,9 +493,9 @@ Obtains the default minimum allowable size for ASHP system. This is calculated """ function get_ashp_default_min_allowable_size(heating_load::Array{<:Real,1}, heating_cf::Array{<:Real,1}, - cooling_load::Array{<:Real,1} = Real[], - cooling_cf::Array{<:Real,1} = Real[], - peak_load_thermal_factor::Real = 0.5 + cooling_load::Array{<:Real,1}, + cooling_cf::Array{<:Real,1}, + peak_load_thermal_factor::Real ) if isempty(cooling_cf) diff --git a/src/core/reopt_inputs.jl b/src/core/reopt_inputs.jl index 409458e6c..bb1d1bf94 100644 --- a/src/core/reopt_inputs.jl +++ b/src/core/reopt_inputs.jl @@ -953,7 +953,14 @@ function setup_ASHPSpaceHeater_inputs(s, max_sizes, min_sizes, cap_cost_slope, o if s.ashp.min_allowable_kw > 0.0 cap_cost_slope["ASHPSpaceHeater"] = s.ashp.installed_cost_per_kw push!(segmented_techs, "ASHPSpaceHeater") - seg_max_size["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => s.ashp.max_kw) + #as a reasonable big-M, assume 10 times the size to serve 100% of peak load. + ashp_sh_max_size = get_ashp_default_min_allowable_size(s.space_heating_load.loads_kw, + s.ashp.heating_cf, + s.cooling_load.loads_kw_thermal, + s.ashp.cooling_cf, + 10.0 + ) + seg_max_size["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => min(s.ashp.max_kw, ashp_sh_max_size)) seg_min_size["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => s.ashp.min_allowable_kw) n_segs_by_tech["ASHPSpaceHeater"] = 1 seg_yint["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => 0.0) @@ -990,7 +997,14 @@ function setup_ASHPWaterHeater_inputs(s, max_sizes, min_sizes, cap_cost_slope, o if s.ashp_wh.min_allowable_kw > 0.0 cap_cost_slope["ASHPWaterHeater"] = s.ashp_wh.installed_cost_per_kw push!(segmented_techs, "ASHPWaterHeater") - seg_max_size["ASHPWaterHeater"] = Dict{Int,Float64}(1 => s.ashp_wh.max_kw) + #as a reasonable big-M, assume 10 times the size to serve 100% of peak load. + ashp_wh_max_size = get_ashp_default_min_allowable_size(s.dhw_load.loads_kw, + s.ashp_wh.heating_cf, + Real[], + Real[], + 10.0 + ) + seg_max_size["ASHPWaterHeater"] = Dict{Int,Float64}(1 => min(s.ashp_wh.max_kw, ashp_wh_max_size)) seg_min_size["ASHPWaterHeater"] = Dict{Int,Float64}(1 => s.ashp_wh.min_allowable_kw) n_segs_by_tech["ASHPWaterHeater"] = 1 seg_yint["ASHPWaterHeater"] = Dict{Int,Float64}(1 => 0.0) diff --git a/test/runtests.jl b/test/runtests.jl index e7edf12db..bf4e4e89d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -118,8 +118,8 @@ else # run HiGHS tests # min allowable size heating_load = Array{Real}([10.0,10.0,10.0,10.0]) cooling_load = Array{Real}([10.0,10.0,10.0,10.0]) - space_heating_min_allowable_size = REopt.get_ashp_default_min_allowable_size(heating_load, heating_cf, cooling_load, cooling_cf) - wh_min_allowable_size = REopt.get_ashp_default_min_allowable_size(heating_load, heating_cf) + space_heating_min_allowable_size = REopt.get_ashp_default_min_allowable_size(heating_load, heating_cf, cooling_load, cooling_cf, 0.5) + wh_min_allowable_size = REopt.get_ashp_default_min_allowable_size(heating_load, heating_cf, Real[], Real[], 0.5) @test space_heating_min_allowable_size ≈ 9.166666666666666 atol=1e-8 @test wh_min_allowable_size ≈ 5.0 atol=1e-8 end