Skip to content
Snippets Groups Projects
Commit d36fbdde authored by Julian Stürmer's avatar Julian Stürmer
Browse files

Fix type bugs and add saving to calc_total_impact!

parent ee07fabe
No related branches found
No related tags found
No related merge requests found
......@@ -144,22 +144,33 @@ end
#*------------------------------------------------------------------------------
#=
Calculates the total impact of a hurricane given a time series of damaged transmission lines. Each time a transmission line is destroyed, the AC power flow equations are solved and failure cascades may unfold. The output of the solver is saved in a .txt file.
Calculates the total impact of a hurricane given a time series of damaged transmission lines. Each time a transmission line is destroyed, the AC power flow equations are solved and failure cascades may unfold. The terminal output of the solver is saved in a .txt file, if an "outputpath" is defined. Additionally the final network data dictionary is saved in a .jld2 file, if a "savepath" is defined.
=#
function calc_total_impact!(
network_data::Dict{String,<:Any},
tl_damage::Array{Tuple{String,Int64},1}, # time series of tl damage
savepath::String;
tl_damage::Array{Tuple{String,Int64},1}; # time series of tl damage
method = :JuMP, # solver to use
print_level = 5 # Ipopt output details
print_level = 5, # Ipopt output details
outputpath = "", # path for saving solver terminal output
savepath = "", # path for saving final network data dictionary
)
output = @capture_out _calc_total_impact!(
network_data, tl_damage, method=method, print_level=print_level
)
### Write terminal output of solver into file
open(savepath, "w") do io
write(io, output)
if isempty(outputpath) == true # calculate cascade without saving output
_calc_total_impact!(
network_data, tl_damage, method=method, print_level=print_level
)
else # calculate cascade and save output
output = @capture_out _calc_total_impact!(
network_data, tl_damage, method=method, print_level=print_level
)
### Write terminal output of solver into file
open(outputpath, "w") do io
write(io, output)
end
end
if isempty(savepath) == false # save final network data
save(savepath, "network_data", network_data)
end
return nothing
......@@ -252,12 +263,12 @@ end
Restores active power balance in a connected component identified by the set of buses cc. Depending on whether an overproduction or underproduction exists, generator dispatches may be increased or reduced. If necessary, load can be shed by reducing the demands uniformly until the total demand matches generation. For more details see flow chart.
=#
function _restore_p_balance!(network_data::Dict{String,<:Any}, cc::Set{Int64})
active_cc_gens = [
active_cc_gens = Int64[
gen["index"] for gen in values(network_data["gen"]) if
gen["gen_bus"] cc && gen["gen_status"] != 0
] # indices of active generators that are connected to buses in cc
active_cc_loads = [
active_cc_loads = Int64[
load["index"] for load in values(network_data["load"]) if
load["load_bus"] cc && load["status"] != 0
] # indices of active loads that are connected to buses in cc
......@@ -279,7 +290,7 @@ function _restore_p_balance!(network_data::Dict{String,<:Any}, cc::Set{Int64})
elseif cc_Δp_lim < 0 # sufficient dispatch reduction possible
### Reduce all dispatches uniformly
_reduce_p_dispatch!(
network_data, active_cc_gens, active_cc_loads, cc_Δp
network_data, active_cc_gens, active_cc_loads, cc, cc_Δp
)
else # overproduction is unavoidable
### Fail complete component
......@@ -300,12 +311,12 @@ function _restore_p_balance!(network_data::Dict{String,<:Any}, cc::Set{Int64})
end
### Shed the minimum amount of load
_shed_minimum_load!(
network_data, active_cc_gens, active_cc_loads, cc_Δp_lim
network_data, active_cc_gens, active_cc_loads, cc, cc_Δp_lim
)
else # sufficient dispatch increase possible
### Increase all dispatches uniformly
_increase_p_dispatch!(
network_data, active_cc_gens, active_cc_loads, cc_Δp
network_data, active_cc_gens, active_cc_loads, cc, cc_Δp
)
end
end
......@@ -324,16 +335,20 @@ function calc_Δp(
)
### Calculate active power demand in connected component
cc_pd = sum([network_data["load"]["$l"]["pd"] for l in active_cc_loads])
cc_pd = sum(
Float64[network_data["load"]["$l"]["pd"] for l in active_cc_loads]
)
### Calculate total active power loss in branches in connected component
cc_ploss = sum(
[br["pt"] + br["pf"] for br in values(network_data["branch"])
Float64[br["pt"] + br["pf"] for br in values(network_data["branch"])
if br["f_bus"] cc && br["t_bus"] in cc && br["br_status"] == 1]
)
### Calculate active power generation in connected component
cc_pg = sum([network_data["gen"]["$g"]["pg"] for g in active_c_gens])
cc_pg = sum(
Float64[network_data["gen"]["$g"]["pg"] for g in active_cc_gens]
)
### Calculate relevant mismatches
cc_Δp = cc_pg - cc_pd - cc_ploss
......@@ -342,12 +357,12 @@ function calc_Δp(
cc_Δp_lim = NaN # limiting mismatch not needed
elseif cc_Δp > 0 # overproduction
cc_pmin = sum(
[network_data["gen"]["$g"]["pmin"] for g in active_cc_gens]
Float64[network_data["gen"]["$g"]["pmin"] for g in active_cc_gens]
) # minimum possible active power dispatch
cc_Δp_lim = cc_pmin - cc_pd - cc_ploss # limiting mismatch
elseif cc_Δp < 0 # underproduction
cc_pmax = sum(
[network_data["gen"]["$g"]["pmax"] for g in active_cc_gens]
Float64[network_data["gen"]["$g"]["pmax"] for g in active_cc_gens]
) # maximum possible active power dispatch
cc_Δp_lim = cc_pmax - cc_pd - cc_ploss # limiting mismatch
end
......@@ -362,11 +377,12 @@ function _reduce_p_dispatch!(
network_data::Dict{String,<:Any},
active_cc_gens::Array{Int64,1},
active_cc_loads::Array{Int64,1},
cc::Set{Int64},
cc_Δp::Float64 # positive mismatch
)
### Find active generators that are able to reduce their dispatch
capable_cc_gens = [
capable_cc_gens = Int64[
g for g in active_cc_gens if
network_data["gen"]["$g"]["pg"] > network_data["gen"]["$g"]["pmin"]
]
......@@ -388,7 +404,7 @@ function _reduce_p_dispatch!(
)
if !isapprox(cc_Δp, 0, atol=1e-10) # power balance still not restored
_reduce_p_dispatch!(
network_data, active_cc_gens, active_cc_loads, cc_Δp
network_data, active_cc_gens, active_cc_loads, cc, cc_Δp
) # repeat
end
......@@ -402,11 +418,12 @@ function _increase_p_dispatch!(
network_data::Dict{String,<:Any},
active_cc_gens::Array{Int64,1},
active_cc_loads::Array{Int64,1},
cc::Set{Int64},
cc_Δp::Float64 # negative mismatch
)
### Find active generators that are able to increase their dispatch
capable_cc_gens = [
capable_cc_gens = Int64[
g for g in active_cc_gens if
network_data["gen"]["$g"]["pg"] < network_data["gen"]["$g"]["pmax"]
]
......@@ -422,13 +439,13 @@ function _increase_p_dispatch!(
end
end
### Recalculate active power mismatch and repeat increase, if necessary
### Recalculate active power mismatch and repeat increase, if necessary
cc_Δp, cc_Δp_lim = calc_Δp(
network_data, active_cc_gens, active_cc_loads, cc
)
if !isapprox(cc_Δp, 0, atol=1e-10) # power balance still not restored
_increase_p_dispatch!(
network_data, active_cc_gens, active_cc_loads, cc_Δp
network_data, active_cc_gens, active_cc_loads, cc, cc_Δp
) # repeat
end
......@@ -442,11 +459,12 @@ function _shed_minimum_load!(
network_data::Dict{String,<:Any},
active_cc_gens::Array{Int64,1},
active_cc_loads::Array{Int64,1},
cc::Set{Int64},
cc_Δp_lim::Float64 # negative limiting mismatch
)
### Find active loads that are able to reduce their demand
capable_cc_loads = [
capable_cc_loads = Int64[
l for l in active_cc_loads if network_data["load"]["$l"]["pd"] > 0
]
l_Δp = abs(cc_Δp_lim) / length(capable_cc_loads) # demand reduction per load
......@@ -467,7 +485,7 @@ function _shed_minimum_load!(
)
if !isapprox(cc_Δp, 0, atol=1e-10) # power balance still not restored
_shed_minimum_load!(
network_data, active_cc_gens, active_cc_loads, cc_Δp_lim
network_data, active_cc_gens, active_cc_loads, cc, cc_Δp_lim
) # repeat
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment