Skip to content

Commit 64f9732

Browse files
authored
Merge pull request #462 from NREL/max-ashp-output
Maximize ASHP output in dispatch
2 parents 9bdfe18 + d5983c4 commit 64f9732

File tree

5 files changed

+222
-45
lines changed

5 files changed

+222
-45
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ Classify the change according to the following categories:
2525
### Deprecated
2626
### Removed
2727

28+
## max-ashp-dispatch
29+
### Added
30+
- New parameter `force_dispatch` in the **ASHPSpaceHeater** and **ASHPWaterHeater** technologies (default = `false`). When set to `true`, the ASHP's thermal output will be the minimum of the site load(s) served and the system size (adjusted for timestep-specific capacity factor) in each period.
31+
2832
## load-year-align
2933
### Fixed
3034
- Align heating and cooling load profiles based on electric load year input, if using custom electric load profile with simulated (CRB or schedule-based flatloads) heating/cooling loads

src/constraints/thermal_tech_constraints.jl

+106-11
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,75 @@ end
107107

108108

109109
function add_ashp_force_in_constraints(m, p; _n="")
110-
if "ASHPSpaceHeater" in p.techs.ashp && p.s.ashp.force_into_system
111-
for t in setdiff(p.techs.can_serve_space_heating, ["ASHPSpaceHeater"])
112-
for ts in p.time_steps
113-
fix(m[Symbol("dvHeatingProduction"*_n)][t,"SpaceHeating",ts], 0.0, force=true)
114-
fix(m[Symbol("dvProductionToWaste"*_n)][t,"SpaceHeating",ts], 0.0, force=true)
110+
if "ASHPSpaceHeater" in p.techs.ashp
111+
if p.s.ashp.force_into_system
112+
for t in setdiff(p.techs.can_serve_space_heating, ["ASHPSpaceHeater"])
113+
for ts in p.time_steps
114+
fix(m[Symbol("dvHeatingProduction"*_n)][t,"SpaceHeating",ts], 0.0, force=true)
115+
fix(m[Symbol("dvProductionToWaste"*_n)][t,"SpaceHeating",ts], 0.0, force=true)
116+
end
117+
end
118+
elseif p.s.ashp.force_dispatch
119+
dv = "binASHPSHSizeExceedsThermalLoad"*_n
120+
m[Symbol(dv)] = @variable(m, [p.time_steps], binary=true, base_name=dv)
121+
dv = "dvASHPSHSizeTimesExcess"*_n
122+
m[Symbol(dv)] = @variable(m, [p.time_steps], lower_bound=0, base_name=dv)
123+
if p.s.ashp.can_serve_cooling
124+
max_sh_size_bigM = 2*max(p.max_sizes["ASHPSpaceHeater"], maximum(p.heating_loads_kw["SpaceHeating"] ./ p.heating_cf["ASHPSpaceHeater"])+maximum(p.s.cooling_load.loads_kw_thermal ./ p.cooling_cf["ASHPSpaceHeater"]))
125+
@constraint(m, [ts in p.time_steps],
126+
m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts] >= (
127+
m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"]
128+
- (p.heating_loads_kw["SpaceHeating"][ts] / p.heating_cf["ASHPSpaceHeater"][ts])
129+
- (p.s.cooling_load.loads_kw_thermal[ts] / p.cooling_cf["ASHPSpaceHeater"][ts])
130+
) / max_sh_size_bigM
131+
)
132+
@constraint(m, [ts in p.time_steps],
133+
m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts] <= 1 - (
134+
(p.heating_loads_kw["SpaceHeating"][ts] / p.heating_cf["ASHPSpaceHeater"][ts])
135+
+ (p.s.cooling_load.loads_kw_thermal[ts] / p.cooling_cf["ASHPSpaceHeater"][ts])
136+
- m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"]
137+
) / max_sh_size_bigM
138+
)
139+
# set dvASHPSHSizeTimesExcess = binASHPSHSizeExceedsThermalLoad * dvSize
140+
# big-M is min CF times heat load
141+
@constraint(m, [ts in p.time_steps],
142+
m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] >= m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"] - max_sh_size_bigM * (1-m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts])
143+
)
144+
@constraint(m, [ts in p.time_steps],
145+
m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] <= m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"]
146+
)
147+
@constraint(m, [ts in p.time_steps],
148+
m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] <= max_sh_size_bigM * m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts]
149+
)
150+
#Enforce dispatch: output = system size - (overage)
151+
@constraint(m, [ts in p.time_steps],
152+
m[Symbol("dvHeatingProduction"*_n)]["ASHPSpaceHeater","SpaceHeating",ts] / p.heating_cf["ASHPSpaceHeater"][ts] + m[Symbol("dvCoolingProduction"*_n)]["ASHPSpaceHeater",ts] / p.cooling_cf["ASHPSpaceHeater"][ts] >= m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"] - m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] + (p.heating_loads_kw["SpaceHeating"][ts] / p.heating_cf["ASHPSpaceHeater"][ts] + p.s.cooling_load.loads_kw_thermal[ts] / p.cooling_cf["ASHPSpaceHeater"][ts] ) * m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts]
153+
)
154+
else
155+
# binary variable enforcement for size >= load
156+
max_sh_size_bigM = 2*max(p.max_sizes["ASHPSpaceHeater"], maximum(p.heating_loads_kw["SpaceHeating"] ./ p.heating_cf["ASHPSpaceHeater"]))
157+
@constraint(m, [ts in p.time_steps],
158+
m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts] >= (m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"] - p.heating_loads_kw["SpaceHeating"][ts] / p.heating_cf["ASHPSpaceHeater"][ts]) / max_sh_size_bigM
159+
)
160+
@constraint(m, [ts in p.time_steps],
161+
m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts] <= 1 - (p.heating_loads_kw["SpaceHeating"][ts] / p.heating_cf["ASHPSpaceHeater"][ts] - m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"]) / max_sh_size_bigM
162+
)
163+
# set dvASHPSHSizeTimesExcess = binASHPSHSizeExceedsThermalLoad * dvSize
164+
# big-M is min CF times heat load
165+
166+
@constraint(m, [ts in p.time_steps],
167+
m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] >= p.heating_cf["ASHPSpaceHeater"][ts]*m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"] - max_sh_size_bigM * (1-m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts])
168+
)
169+
@constraint(m, [ts in p.time_steps],
170+
m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] <= p.heating_cf["ASHPSpaceHeater"][ts]*m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"]
171+
)
172+
@constraint(m, [ts in p.time_steps],
173+
m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] <= max_sh_size_bigM * m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts]
174+
)
175+
#Enforce dispatch: output = system size - (overage)
176+
@constraint(m, [ts in p.time_steps],
177+
m[Symbol("dvHeatingProduction"*_n)]["ASHPSpaceHeater","SpaceHeating",ts] >= p.heating_cf["ASHPSpaceHeater"][ts]*m[Symbol("dvSize"*_n)]["ASHPSpaceHeater"] - m[Symbol("dvASHPSHSizeTimesExcess"*_n)][ts] + p.heating_loads_kw["SpaceHeating"][ts] * m[Symbol("binASHPSHSizeExceedsThermalLoad"*_n)][ts]
178+
)
115179
end
116180
end
117181
end
@@ -124,13 +188,44 @@ function add_ashp_force_in_constraints(m, p; _n="")
124188
end
125189
end
126190

127-
if "ASHPWaterHeater" in p.techs.ashp && p.s.ashp_wh.force_into_system
128-
for t in setdiff(p.techs.can_serve_dhw, ["ASHPWaterHeater"])
129-
for ts in p.time_steps
130-
fix(m[Symbol("dvHeatingProduction"*_n)][t,"DomesticHotWater",ts], 0.0, force=true)
131-
fix(m[Symbol("dvProductionToWaste"*_n)][t,"DomesticHotWater",ts], 0.0, force=true)
191+
if "ASHPWaterHeater" in p.techs.ashp
192+
if p.s.ashp_wh.force_into_system
193+
for t in setdiff(p.techs.can_serve_dhw, ["ASHPWaterHeater"])
194+
for ts in p.time_steps
195+
fix(m[Symbol("dvHeatingProduction"*_n)][t,"DomesticHotWater",ts], 0.0, force=true)
196+
fix(m[Symbol("dvProductionToWaste"*_n)][t,"DomesticHotWater",ts], 0.0, force=true)
197+
end
132198
end
133-
end
199+
elseif p.s.ashp_wh.force_dispatch
200+
dv = "binASHPWHSizeExceedsThermalLoad"*_n
201+
m[Symbol(dv)] = @variable(m, [p.time_steps], binary=true, base_name=dv)
202+
dv = "dvASHPWHSizeTimesExcess"*_n
203+
m[Symbol(dv)] = @variable(m, [p.time_steps], lower_bound=0, base_name=dv)
204+
# binary variable enforcement for size >= load
205+
max_wh_size_bigM = 2*max(p.max_sizes["ASHPWaterHeater"], maximum(p.heating_loads_kw["DomesticHotWater"] ./ p.heating_cf["ASHPWaterHeater"]))
206+
@constraint(m, [ts in p.time_steps],
207+
m[Symbol("binASHPWHSizeExceedsThermalLoad"*_n)][ts] >= (m[Symbol("dvSize"*_n)]["ASHPWaterHeater"] - p.heating_loads_kw["DomesticHotWater"][ts] / p.heating_cf["ASHPWaterHeater"][ts]) / max_wh_size_bigM
208+
)
209+
@constraint(m, [ts in p.time_steps],
210+
m[Symbol("binASHPWHSizeExceedsThermalLoad"*_n)][ts] <= 1 - (p.heating_loads_kw["DomesticHotWater"][ts] / p.heating_cf["ASHPWaterHeater"][ts] - m[Symbol("dvSize"*_n)]["ASHPWaterHeater"]) / max_wh_size_bigM
211+
)
212+
# set dvASHPWHSizeTimesExcess = binASHPWHSizeExceedsThermalLoad * dvSize
213+
# big-M is min CF times heat load
214+
215+
@constraint(m, [ts in p.time_steps],
216+
m[Symbol("dvASHPWHSizeTimesExcess"*_n)][ts] >= p.heating_cf["ASHPWaterHeater"][ts]*m[Symbol("dvSize"*_n)]["ASHPWaterHeater"] - max_wh_size_bigM * (1-m[Symbol("binASHPWHSizeExceedsThermalLoad"*_n)][ts])
217+
)
218+
@constraint(m, [ts in p.time_steps],
219+
m[Symbol("dvASHPWHSizeTimesExcess"*_n)][ts] <= p.heating_cf["ASHPWaterHeater"][ts]*m[Symbol("dvSize"*_n)]["ASHPWaterHeater"]
220+
)
221+
@constraint(m, [ts in p.time_steps],
222+
m[Symbol("dvASHPWHSizeTimesExcess"*_n)][ts] <= max_wh_size_bigM * m[Symbol("binASHPWHSizeExceedsThermalLoad"*_n)][ts]
223+
)
224+
#Enforce dispatch: output = system size - (overage)
225+
@constraint(m, [ts in p.time_steps],
226+
m[Symbol("dvHeatingProduction"*_n)]["ASHPWaterHeater","DomesticHotWater",ts] >= p.heating_cf["ASHPWaterHeater"][ts]*m[Symbol("dvSize"*_n)]["ASHPWaterHeater"] - m[Symbol("dvASHPWHSizeTimesExcess"*_n)][ts] + p.heating_loads_kw["DomesticHotWater"][ts] * m[Symbol("binASHPWHSizeExceedsThermalLoad"*_n)][ts]
227+
)
228+
end
134229
end
135230
end
136231

src/core/ashp.jl

+42-17
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ASHPSpaceHeater has the following attributes:
2323
cooling_cf::Array{<:Real,1} # ASHP's cooling capacity factor curves
2424
can_serve_cooling::Bool # If ASHP can supply heat to the cooling load
2525
force_into_system::Bool # force into system to serve all space heating loads if true
26+
force_dispatch::Bool # force ASHP to meet load or maximize output if true
2627
back_up_temp_threshold_degF::Real # Degree in F that system switches from ASHP to resistive heater
2728
avoided_capex_by_ashp_present_value::Real # avoided capital expenditure due to presence of ASHP system vs. defaults heating and cooling techs
2829
max_ton::Real # maximum allowable thermal power (tons)
@@ -48,6 +49,7 @@ struct ASHP <: AbstractThermalTech
4849
can_serve_process_heat::Bool
4950
can_serve_cooling::Bool
5051
force_into_system::Bool
52+
force_dispatch::Bool
5153
back_up_temp_threshold_degF::Real
5254
avoided_capex_by_ashp_present_value::Real
5355
max_ton::Real
@@ -81,6 +83,7 @@ function ASHPSpaceHeater(;
8183
macrs_bonus_fraction::Real = 0.0, # Fraction of upfront project costs to depreciate under MACRS
8284
can_serve_cooling::Union{Bool, Nothing} = nothing # If ASHP can supply heat to the cooling load
8385
force_into_system::Bool = false # force into system to serve all space heating loads if true
86+
force_dispatch::Bool = false # force ASHP to meet load or maximize output if true
8487
avoided_capex_by_ashp_present_value::Real = 0.0 # avoided capital expenditure due to presence of ASHP system vs. defaults heating and cooling techs
8588
8689
#The following inputs are used to create the attributes heating_cop and heating cf:
@@ -103,7 +106,7 @@ function ASHPSpaceHeater(;
103106
"""
104107
function ASHPSpaceHeater(;
105108
min_ton::Real = 0.0,
106-
max_ton::Real = BIG_NUMBER,
109+
max_ton::Union{Real, Nothing} = nothing,
107110
min_allowable_ton::Union{Real, Nothing} = nothing,
108111
min_allowable_peak_capacity_fraction::Union{Real, Nothing} = nothing,
109112
sizing_factor::Union{Real, Nothing} = nothing,
@@ -114,6 +117,7 @@ function ASHPSpaceHeater(;
114117
avoided_capex_by_ashp_present_value::Real = 0.0,
115118
can_serve_cooling::Union{Bool, Nothing} = nothing,
116119
force_into_system::Bool = false,
120+
force_dispatch::Bool = false,
117121
heating_cop_reference::Array{<:Real,1} = Real[],
118122
heating_cf_reference::Array{<:Real,1} = Real[],
119123
heating_reference_temps_degF::Array{<:Real,1} = Real[],
@@ -144,9 +148,6 @@ function ASHPSpaceHeater(;
144148
if isnothing(back_up_temp_threshold_degF)
145149
back_up_temp_threshold_degF = defaults["back_up_temp_threshold_degF"]
146150
end
147-
if isnothing(max_ton)
148-
max_ton = defaults["max_ton"]
149-
end
150151
if isnothing(sizing_factor)
151152
sizing_factor = defaults["sizing_factor"]
152153
end
@@ -177,11 +178,6 @@ function ASHPSpaceHeater(;
177178
can_serve_process_heat = defaults["can_serve_process_heat"]
178179

179180

180-
# Convert max sizes, cost factors from mmbtu_per_hour to kw
181-
min_kw = min_ton * KWH_THERMAL_PER_TONHOUR
182-
max_kw = max_ton * KWH_THERMAL_PER_TONHOUR
183-
184-
185181
installed_cost_per_kw = installed_cost_per_ton / KWH_THERMAL_PER_TONHOUR
186182
om_cost_per_kw = om_cost_per_ton / KWH_THERMAL_PER_TONHOUR
187183

@@ -206,6 +202,26 @@ function ASHPSpaceHeater(;
206202
cooling_cf = Float64[]
207203
end
208204

205+
if isnothing(max_ton)
206+
if can_serve_cooling
207+
#these are in kW rathern than tons so will be larger as a measure of conservatism
208+
max_ton = min(defaults["max_ton"], 10*(maximum(heating_load ./ heating_cf)+maximum(cooling_load ./ cooling_cf)))
209+
else
210+
max_ton = min(defaults["max_ton"], 10*maximum(heating_load ./ heating_cf))
211+
end
212+
else
213+
if can_serve_cooling
214+
max_ton = min(max_ton, 10*(maximum(heating_load ./ heating_cf)+maximum(cooling_load ./ cooling_cf)))
215+
else
216+
max_ton = min(max_ton, 10*maximum(heating_load ./ heating_cf))
217+
end
218+
max_ton = max(max_ton, min_ton)
219+
end
220+
221+
# Convert max sizes, cost factors from mmbtu_per_hour to kw
222+
min_kw = min_ton * KWH_THERMAL_PER_TONHOUR
223+
max_kw = max_ton * KWH_THERMAL_PER_TONHOUR
224+
209225
if !isnothing(min_allowable_ton) && !isnothing(min_allowable_peak_capacity_fraction)
210226
throw(@error("at most one of min_allowable_ton and min_allowable_peak_capacity_fraction may be input."))
211227
elseif !isnothing(min_allowable_ton)
@@ -244,6 +260,7 @@ function ASHPSpaceHeater(;
244260
can_serve_process_heat,
245261
can_serve_cooling,
246262
force_into_system,
263+
force_dispatch,
247264
back_up_temp_threshold_degF,
248265
avoided_capex_by_ashp_present_value,
249266
max_ton,
@@ -278,6 +295,7 @@ function ASHPWaterHeater(;
278295
can_supply_steam_turbine::Union{Bool, nothing} = nothing # If the boiler can supply steam to the steam turbine for electric production
279296
avoided_capex_by_ashp_present_value::Real = 0.0 # avoided capital expenditure due to presence of ASHP system vs. defaults heating and cooling techs
280297
force_into_system::Bool = false # force into system to serve all hot water loads if true
298+
force_dispatch::Bool = false # force ASHP to meet load or maximize output if true
281299
282300
#The following inputs are used to create the attributes heating_cop and heating cf:
283301
heating_cop_reference::Array{<:Real,1}, # COP of the heating (i.e., thermal produced / electricity consumed)
@@ -293,7 +311,7 @@ function ASHPWaterHeater(;
293311
"""
294312
function ASHPWaterHeater(;
295313
min_ton::Real = 0.0,
296-
max_ton::Real = BIG_NUMBER,
314+
max_ton::Union{Real, Nothing} = nothing,
297315
min_allowable_ton::Union{Real, Nothing} = nothing,
298316
min_allowable_peak_capacity_fraction::Union{Real, Nothing} = nothing,
299317
sizing_factor::Union{Real, Nothing} = nothing,
@@ -303,6 +321,7 @@ function ASHPWaterHeater(;
303321
macrs_bonus_fraction::Real = 0.0,
304322
avoided_capex_by_ashp_present_value::Real = 0.0,
305323
force_into_system::Bool = false,
324+
force_dispatch::Bool = false,
306325
heating_cop_reference::Array{<:Real,1} = Real[],
307326
heating_cf_reference::Array{<:Real,1} = Real[],
308327
heating_reference_temps_degF::Array{<:Real,1} = Real[],
@@ -323,9 +342,6 @@ function ASHPWaterHeater(;
323342
if isnothing(back_up_temp_threshold_degF)
324343
back_up_temp_threshold_degF = defaults["back_up_temp_threshold_degF"]
325344
end
326-
if isnothing(max_ton)
327-
max_ton = defaults["max_ton"]
328-
end
329345
if isnothing(sizing_factor)
330346
sizing_factor = defaults["sizing_factor"]
331347
end
@@ -347,10 +363,6 @@ function ASHPWaterHeater(;
347363
can_serve_process_heat = defaults["can_serve_process_heat"]
348364
can_serve_cooling = defaults["can_serve_cooling"]
349365

350-
# Convert max sizes, cost factors from mmbtu_per_hour to kw
351-
min_kw = min_ton * KWH_THERMAL_PER_TONHOUR
352-
max_kw = max_ton * KWH_THERMAL_PER_TONHOUR
353-
354366
installed_cost_per_kw = installed_cost_per_ton / KWH_THERMAL_PER_TONHOUR
355367
om_cost_per_kw = om_cost_per_ton / KWH_THERMAL_PER_TONHOUR
356368

@@ -363,6 +375,18 @@ function ASHPWaterHeater(;
363375

364376
heating_cf[heating_cop .== 1] .= 1
365377

378+
if isnothing(max_ton)
379+
#these are in kW rathern than tons so will be larger as a measure of conservatism
380+
max_ton = min(defaults["max_ton"], 10*maximum(heating_load ./ heating_cf))
381+
else
382+
max_ton = min(max_ton, 10*maximum(heating_load ./ heating_cf))
383+
end
384+
max_ton = max(max_ton, min_ton)
385+
386+
# Convert max sizes, cost factors from mmbtu_per_hour to kw
387+
min_kw = min_ton * KWH_THERMAL_PER_TONHOUR
388+
max_kw = max_ton * KWH_THERMAL_PER_TONHOUR
389+
366390
if !isnothing(min_allowable_ton) && !isnothing(min_allowable_peak_capacity_fraction)
367391
throw(@error("at most one of min_allowable_ton and min_allowable_peak_capacity_fraction may be input."))
368392
elseif !isnothing(min_allowable_ton)
@@ -398,6 +422,7 @@ function ASHPWaterHeater(;
398422
can_serve_process_heat,
399423
can_serve_cooling,
400424
force_into_system,
425+
force_dispatch,
401426
back_up_temp_threshold_degF,
402427
avoided_capex_by_ashp_present_value,
403428
max_ton,

src/core/reopt_inputs.jl

+2-16
Original file line numberDiff line numberDiff line change
@@ -953,14 +953,7 @@ function setup_ASHPSpaceHeater_inputs(s, max_sizes, min_sizes, cap_cost_slope, o
953953
if s.ashp.min_allowable_kw > 0.0
954954
cap_cost_slope["ASHPSpaceHeater"] = s.ashp.installed_cost_per_kw
955955
push!(segmented_techs, "ASHPSpaceHeater")
956-
#as a reasonable big-M, assume 10 times the size to serve 100% of peak load.
957-
ashp_sh_max_size = get_ashp_default_min_allowable_size(s.space_heating_load.loads_kw,
958-
s.ashp.heating_cf,
959-
s.cooling_load.loads_kw_thermal,
960-
s.ashp.cooling_cf,
961-
10.0
962-
)
963-
seg_max_size["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => min(s.ashp.max_kw, ashp_sh_max_size))
956+
seg_max_size["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => min(s.ashp.max_kw))
964957
seg_min_size["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => s.ashp.min_allowable_kw)
965958
n_segs_by_tech["ASHPSpaceHeater"] = 1
966959
seg_yint["ASHPSpaceHeater"] = Dict{Int,Float64}(1 => 0.0)
@@ -997,14 +990,7 @@ function setup_ASHPWaterHeater_inputs(s, max_sizes, min_sizes, cap_cost_slope, o
997990
if s.ashp_wh.min_allowable_kw > 0.0
998991
cap_cost_slope["ASHPWaterHeater"] = s.ashp_wh.installed_cost_per_kw
999992
push!(segmented_techs, "ASHPWaterHeater")
1000-
#as a reasonable big-M, assume 10 times the size to serve 100% of peak load.
1001-
ashp_wh_max_size = get_ashp_default_min_allowable_size(s.dhw_load.loads_kw,
1002-
s.ashp_wh.heating_cf,
1003-
Real[],
1004-
Real[],
1005-
10.0
1006-
)
1007-
seg_max_size["ASHPWaterHeater"] = Dict{Int,Float64}(1 => min(s.ashp_wh.max_kw, ashp_wh_max_size))
993+
seg_max_size["ASHPWaterHeater"] = Dict{Int,Float64}(1 => s.ashp_wh.max_kw)
1008994
seg_min_size["ASHPWaterHeater"] = Dict{Int,Float64}(1 => s.ashp_wh.min_allowable_kw)
1009995
n_segs_by_tech["ASHPWaterHeater"] = 1
1010996
seg_yint["ASHPWaterHeater"] = Dict{Int,Float64}(1 => 0.0)

0 commit comments

Comments
 (0)