Skip to content

Commit

Permalink
add multiple scenario problem
Browse files Browse the repository at this point in the history
  • Loading branch information
bluejuniper committed Dec 5, 2024
1 parent 0dfcd0c commit ade7c55
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 63 deletions.
3 changes: 2 additions & 1 deletion src/core/objective.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

"OBJECTIVE: minimize cost of installing GIC blocker"
function objective_blocker_placement_cost(pm::_PM.AbstractPowerModel)
# don't need to sum across all scenarios - objective will be somewhat confusing
return JuMP.@objective(pm.model, Min,
sum(
sum( blocker["multiplier"]*blocker["construction_cost"]*_PM.var(pm, n, :z_blocker, i) for (i,blocker) in nw_ref[:gmd_ne_blocker] )
sum( get(blocker, "multiplier", 1.0) * get(blocker, "construction_cost", 1.0) *_PM.var(pm, n, :z_blocker, i) for (i,blocker) in nw_ref[:gmd_ne_blocker] )
for (n, nw_ref) in _PM.nws(pm))
)

Expand Down
145 changes: 83 additions & 62 deletions src/prob/gmd_blocker_placement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,100 +113,121 @@ function build_blocker_placement(pm::_PM.AbstractPowerModel; kwargs...)
end


"FUNCTION: build the multi-time-series coupled quasi-dc-pf and ac-ots with ac-mls problem
as a generator dispatch minimization problem"
function build_blocker_placement_ts(pm::_PM.AbstractPowerModel; kwargs...)
# Reference:
# built minimum loadshedding problem specification corresponds to the "Model C4" of
# Mowen et al., "Optimal Transmission Line Switching under Geomagnetic Disturbances", 2018.
"FUNCTION: build the multi-scenario or time-series blocker placement problem.
This requires that PowerModelsGMD.get_connected_components() be run to generate the
connected components prior to running PowerModels.replicate()"
function solve_blocker_placement_ts(file, model_type::Type, optimizer; kwargs...)
return _PM.solve_model(
file,
model_type,
optimizer,
build_blocker_placement_ts;
ref_extensions = [
_PMG.ref_add_gmd!
_PMG.ref_add_ne_blocker!
],
solution_processors = [
_PMG.solution_gmd!,
_PMG.solution_gmd_qloss!,
],
kwargs...,
)
end


"FUNCTION: build the multi-scenario or time-series blocker placement problem"
function build_blocker_placement_multi_scenario(pm::_PM.AbstractPowerModel; kwargs...)
# Reference:
# built minimum loadshedding problem specification corresponds to the "Model C4" of
# Mowen et al., "Optimal Transmission Line Switching under Geomagnetic Disturbances", 2018.
network_ids = sort(collect(_PM.nw_ids(pm)))
n_1 = network_ids[1]

_PMG.variable_ne_blocker_indicator(pm, nw=n_1)

for n_2 in network_ids[2:end]
_PM.var(pm, n_2)[:z_blocker] = _PM.var(pm, n_1)[:z_blocker]
_PM.var(pm, n_2)[:zv_dc] = _PM.var(pm, n_1)[:zv_dc]
end

for (n, network) in _PM.nws(pm)
_PMR.variable_bus_voltage_on_off(pm, nw=n)
_PM.variable_gen_indicator(pm, nw=n)
_PMG.variable_bus_voltage(pm, nw=n)
_PM.variable_gen_power(pm, nw=n)
_PM.variable_branch_indicator(pm, nw=n)
_PM.variable_branch_power(pm, nw=n)
_PM.variable_dcline_power(pm, nw=n)

_PM.variable_load_power_factor(pm, relax=true)
_PM.variable_shunt_admittance_factor(pm, relax=true)

variable_dc_voltage_on_off(pm, nw=n)
variable_dc_line_flow(pm, nw=n, bounded=false)
variable_dc_current_mag(pm, nw=n)
variable_qloss(pm, nw=n)

variable_delta_oil_ss(pm, nw=n, bounded=true)
variable_delta_oil(pm, nw=n, bounded=true)
variable_delta_hotspot_ss(pm, nw=n, bounded=true)
variable_delta_hotspot(pm, nw=n, bounded=true)
variable_hotspot(pm, nw=n, bounded=true)

_PM.constraint_model_voltage_on_off(pm, nw=n)
# For MLD
_PM.variable_load_power_factor(pm, relax=true, nw=n)
_PM.variable_shunt_admittance_factor(pm, relax=true, nw=n)

_PMG.variable_dc_voltage(pm, nw=n)
_PMG.variable_gic_current(pm, nw=n)
_PMG.variable_dc_line_flow(pm, nw=n)
_PMG.variable_qloss(pm, nw=n)

if get(pm.setting, "ts", false)
_PMG.variable_delta_oil_ss(pm, nw=n, bounded=true)
_PMG.variable_delta_oil(pm, nw=n, bounded=true)
_PMG.variable_delta_hotspot_ss(pm, nw=n, bounded=true)
_PMG.variable_delta_hotspot(pm, nw=n, bounded=true)
_PMG.variable_hotspot(pm, nw=n, bounded=true)
end

# What's dis?
_PMG.constraint_model_voltage(pm, nw=n)

for i in _PM.ids(pm, :ref_buses, nw=n)
_PM.constraint_theta_ref(pm, i, nw=n)
end

for i in _PM.ids(pm, :bus, nw=n)
constraint_power_balance_gmd_shunt_ls(pm, i, nw=n)
end

for i in _PM.ids(pm, :bus, nw=n)
_PM.constraint_gen_power_on_off(pm, i, nw=n)
constraint_gen_ots_on_off(pm, i, nw=n)
constraint_gen_perspective(pm, i, nw=n)
_PMG.constraint_power_balance_gmd_shunt_ls(pm, i, nw=n)
end

for i in _PM.ids(pm, :branch, nw=n)
_PM.constraint_ohms_yt_from(pm, i, nw=n)
_PM.constraint_ohms_yt_to(pm, i, nw=n)

_PM.constraint_ohms_yt_from_on_off(pm, i, nw=n)
_PM.constraint_ohms_yt_to_on_off(pm, i, nw=n)
_PM.constraint_voltage_angle_difference(pm, i, nw=n)

_PM.constraint_voltage_angle_difference_on_off(pm, i, nw=n)

_PM.constraint_thermal_limit_from_on_off(pm, i, nw=n)
_PM.constraint_thermal_limit_to_on_off(pm, i, nw=n)

constraint_qloss_vnom(pm, i, nw=n)
constraint_dc_current_mag(pm, i, nw=n)
constraint_dc_current_mag_on_off(pm, i, nw=n)

constraint_temperature_state_ss(pm, i, nw=n)
constraint_hotspot_temperature_state_ss(pm, i, nw=n)
constraint_hotspot_temperature_state(pm, i, nw=n)
constraint_absolute_hotspot_temperature_state(pm, i, nw=n)
_PM.constraint_thermal_limit_from(pm, i, nw=n)
_PM.constraint_thermal_limit_to(pm, i, nw=n)

# consider using constraint_qloss_vnom
_PMG.constraint_qloss_pu(pm, i, nw=n)
_PMG.constraint_dc_current_mag(pm, i, nw=n)
end

for i in _PM.ids(pm, :dcline, nw=n)
_PM.constraint_dcline_power_losses(pm, i, nw=n)
end

for i in _PM.ids(pm, :gmd_bus, nw=n)
constraint_dc_kcl(pm, i, nw=n)
_PMG.constraint_dc_kcl_ne_blocker(pm, i, nw=n)
end

for i in _PM.ids(pm, :gmd_branch, nw=n)
constraint_dc_ohms_on_off(pm, i, nw=n)
_PMG.constraint_dc_ohms(pm, i, nw=n)
end

end
# If not using blocker status this can be a single constraint
# across all scenarios
for i in _PM.ids(pm, :gmd_connections, nw=n)
_PMG.constraint_gmd_connections(pm, i, nw=n)
end

network_ids = sort(collect(nw_ids(pm)))
n_1 = network_ids[1]
for i in _PM.ids(pm, :branch, nw=n_1)
constraint_temperature_state(pm, i, nw=n_1)
_PMG.constraint_load_served(pm, nw=n)
end
for n_2 in network_ids[2:end]
for i in _PM.ids(pm, :branch, nw=n_2)
constraint_temperature_state(pm, i, n_1, n_2)

if get(pm.setting, "ts", false)
for n_2 in network_ids[2:end]
for i in _PM.ids(pm, :branch, nw=n_2)
_PMG.constraint_temperature_state(pm, i, n_1, n_2)
end

n_1 = n_2
end
n_1 = n_2
end

_PM.objective_min_fuel_and_flow_cost(pm)
end



_PMG.objective_blocker_placement_cost(pm)
end

0 comments on commit ade7c55

Please sign in to comment.