Skip to content

Commit 3af2fc0

Browse files
committed
Debugging and minor improvements
1 parent 71959c4 commit 3af2fc0

5 files changed

Lines changed: 32 additions & 12 deletions

File tree

src/constraints/storage_constraints.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ function add_elec_storage_dispatch_constraints(m, p, b; _n="")
8383
#+ (p.s.storage.attr[b].charge_efficiency * m[Symbol("dvHydroToStorage")][ts])
8484
- ((m[Symbol("dvDischargeFromStorage"*_n)][b,ts]+m[Symbol("dvStorageToGrid")][ts]) / p.s.storage.attr[b].discharge_efficiency)
8585
)
86-
- (p.s.storage.attr[b].per_timestep_self_discharge_fraction * m[Symbol("dvStoredEnergy"*_n)][b, ts])
86+
#- (p.s.storage.attr[b].per_timestep_self_discharge_fraction * m[Symbol("dvStoredEnergy"*_n)][b, ts])
8787
)
8888

8989
# Note: Hydro to storage not added for off-grid scenarios

src/constraints/water_power_constraints.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,16 @@ function add_water_power_constraints(m,p)
308308
dvs = ["binTurbineActive"]
309309
end
310310

311+
solvers_incompatible_with_indicator_constraints = ["HiGHS", "Cbc"]
311312

312313
# Define the minimum operating time (in time steps) for the water_power turbine
313314
if p.s.water_power.minimum_operating_time_steps_individual_turbine > 1
315+
@warn "Setting minimum_operating_time_steps_individual_turbine to greater than 1 requires an optimization solver that can handle indicator constraints."
316+
317+
if p.s.settings.solver_name in solvers_incompatible_with_indicator_constraints
318+
throw(@error("A solver that can handle indicator constraints must be used if minimum_turbine_off_time_steps is set to greater than 1"))
319+
end
320+
314321
print("\n Adding minimum operating time constraint \n")
315322
@variable(m, indicator_min_operating_time[t in p.techs.water_power, ts in p.time_steps, dv in dvs], Bin)
316323
for dv in dvs
@@ -332,6 +339,12 @@ function add_water_power_constraints(m,p)
332339

333340
# Define the minimum operating time for the maximum water flow (in time steps) for a water_power turbine
334341
if p.s.water_power.minimum_operating_time_steps_at_local_maximum_turbine_output > 1
342+
@warn "Setting minimum_operating_time_steps_at_local_maximum_turbine_output to greater than 1 requires an optimization solver that can handle indicator constraints."
343+
344+
if p.s.settings.solver_name in solvers_incompatible_with_indicator_constraints
345+
throw(@error("A solver that can handle indicator constraints must be used if minimum_turbine_off_time_steps is set to greater than 1"))
346+
end
347+
335348
print("\n Adding a constraint for the minimum operating time at a local maximum water flow \n")
336349
@variable(m, indicator_turn_down[t in p.techs.water_power_turbines, ts in p.time_steps, dv in dvs], Bin)
337350
for dv in dvs
@@ -354,6 +367,12 @@ function add_water_power_constraints(m,p)
354367
end
355368

356369
if p.s.water_power.minimum_turbine_off_time_steps > 1
370+
@warn "Setting minimum_turbine_off_time_steps to greater than 1 requires an optimization solver that can handle indicator constraints."
371+
372+
if p.s.settings.solver_name in solvers_incompatible_with_indicator_constraints
373+
throw(@error("A solver that can handle indicator constraints must be used if minimum_turbine_off_time_steps is set to greater than 1"))
374+
end
375+
357376
print("\n Adding minimum off duration for the turbines \n")
358377
@variable(m, indicator_turbine_turn_off[t in p.techs.water_power_turbines, ts in p.time_steps], Bin)
359378
for t in p.techs.water_power_turbines, ts in 1:Int(length(p.time_steps)- p.s.water_power.minimum_turbine_off_time_steps - 1 )

src/mpc/structs.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ Base.@kwdef struct MPCElectricStorage <: AbstractElectricStorage
242242
max_kw::Float64 = size_kw
243243
max_kwh::Float64 = size_kwh
244244
minimum_avg_soc_fraction::Float64 = 0.0
245-
per_timestep_self_discharge_fraction::Float64 = 0.0
245+
#per_timestep_self_discharge_fraction::Float64 = 0.0
246246
end
247247

248248

src/results/electric_storage.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ function add_electric_storage_results(m::JuMP.AbstractModel, p::REoptInputs, d::
3737
r["size_kw"] * p.s.storage.attr[b].installed_cost_per_kw +
3838
p.s.storage.attr[b].installed_cost_constant
3939

40-
StoragePerUnitOMCosts = p.third_party_factor * p.pwf_om * (p.s.storage.attr[b].om_cost_per_kw * m[Symbol("dvStoragePower"*_n)][b] +
41-
p.s.storage.attr[b].om_cost_per_kwh * m[Symbol("dvStorageEnergy"*_n)][b])
40+
# TODO: correct the StoragePerUnitOMCosts
41+
StoragePerUnitOMCosts = -9999999 #p.third_party_factor * p.pwf_om * (p.s.storage.attr[b].om_cost_per_kw * m[Symbol("dvStoragePower"*_n)][b] +
42+
# p.s.storage.attr[b].om_cost_per_kwh * m[Symbol("dvStorageEnergy"*_n)][b])
4243

4344
r["lifecycle_om_cost_after_tax"] = round(value(StoragePerUnitOMCosts) * (1 - p.s.financial.owner_tax_rate_fraction), digits=0)
4445
r["year_one_om_cost_before_tax"] = round(value(StoragePerUnitOMCosts) / (p.pwf_om * p.third_party_factor), digits=0)
@@ -71,7 +72,7 @@ function add_electric_storage_results(m::JuMP.AbstractModel, p::REoptInputs, d::
7172

7273
BattExport = (m[Symbol("dvStorageToGrid")][ts] for ts in p.time_steps)
7374
r["storage_to_grid_series_kw"] = round.(value.(BattExport), digits = 3)
74-
r["residual_value"] = value(m[:residual_value])
75+
# r["residual_value"] = value(m[:residual_value])
7576

7677
else
7778
r["soc_series_fraction"] = []

src/results/water_power.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function add_water_power_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict;
7373
# Upstream reservoir volume
7474
upstream_reservoir_volume = @expression(m, [ts in p.time_steps], m[:dvWaterVolume][ts])
7575
r["upstream_reservoir_water_volume_cubic_meters"] = round.(value.(upstream_reservoir_volume).data, digits=3)
76-
r["upstream_reservoir_water_capacity_cubic_meters"] = round.(value.(m[:dvUpperReservoirCapacity]).data, digits=3)
76+
r["upstream_reservoir_water_capacity_cubic_meters"] = round.(value.(m[:dvUpperReservoirCapacity]), digits=3)
7777

7878

7979
# Water flow into upstream reservoir (input into the model)
@@ -100,14 +100,12 @@ function add_water_power_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict;
100100
for t in p.techs.water_power, ts in p.time_steps)
101101
)
102102
r["annual_energy_produced_kwh"] = round(value(AnnualWaterPowerProd), digits=0) # includes curtailment
103-
104-
103+
105104
if p.s.water_power.model_downstream_reservoir
106105
# Downstream reservoir volume
107106
downstream_reservoir_volume = @expression(m, [ts in p.time_steps], m[:dvDownstreamReservoirWaterVolume][ts])
108107
r["downstream_reservoir_water_volume_cubic_meters"] = round.(value.(downstream_reservoir_volume).data, digits=3)
109-
110-
r["downstream_reservoir_water_capacity_cubic_meters"] = round.(value.(m[:dvDownstreamReservoirCapacity]).data, digits=3)
108+
r["downstream_reservoir_water_capacity_cubic_meters"] = round.(value.(m[:dvDownstreamReservoirCapacity]), digits=3)
111109

112110
end
113111
# Compile results for the pumps
@@ -130,11 +128,13 @@ function add_water_power_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict;
130128
r["individual_pump_results"] = Dict([])
131129

132130
print("\n **** p.techs.water_power_pumps are: $(p.techs.water_power_pumps)")
131+
print("\n **** p.techs.water_power_turbines are: $(p.techs.water_power_turbines)")
132+
print("\n ")
133133

134134
for i in p.techs.water_power_pumps
135135
r["individual_pump_results"][string(i)*"_results"] = Dict([])
136136

137-
r["individual_pump_results"][string(i)*"_results"]["pump_power_rating"] = value.(m[:pump_power_rating][i])
137+
r["individual_pump_results"][string(i)*"_results"]["pump_power_rating"] = round(value.(m[:pump_power_rating][i]), digits=3)
138138

139139
IndividualPumpedWaterFlow = @expression(m, [ts in p.time_steps], m[:dvPumpedWaterFlow][i, ts])
140140
r["individual_pump_results"][string(i)*"_results"]["pump_water_flow"] = round.(value.(IndividualPumpedWaterFlow).data, digits=3)
@@ -152,7 +152,7 @@ function add_water_power_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict;
152152

153153
r["individual_turbine_results"][string(i)*"_results"] = Dict([])
154154

155-
r["individual_turbine_results"][string(i)*"_results"]["turbine_power_rating"] = value.(m[:turbine_power_rating][i])
155+
r["individual_turbine_results"][string(i)*"_results"]["turbine_power_rating"] = round(value.(m[:turbine_power_rating][i]), digits=3)
156156

157157
water_outflow_individual = @expression(m, [ts in p.time_steps], m[:dvWaterOutFlow][i, ts])
158158
r["individual_turbine_results"][string(i)*"_results"]["water_outflow"] = round.(value.(water_outflow_individual).data, digits=3)

0 commit comments

Comments
 (0)