diff --git a/Manifest.toml b/Manifest.toml index ba92f2d..82cdd37 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0" manifest_format = "2.0" -project_hash = "2b196f4165a07d56342f51102f8b4a3a616731b5" +project_hash = "c0a6ee1697d0b2d35a20c1d7bcf24a2f1ae804be" [[deps.ADNLPModels]] deps = ["ColPack", "ForwardDiff", "LinearAlgebra", "NLPModels", "Requires", "ReverseDiff", "SparseArrays"] @@ -93,9 +93,9 @@ version = "7.7.0" [[deps.ArrayLayouts]] deps = ["FillArrays", "LinearAlgebra"] -git-tree-sha1 = "f5c3f5584f14322a0bd73362fd88b589dabd4019" +git-tree-sha1 = "64d582bcb9c93ac741234789eeb4f16812413efb" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.5.3" +version = "1.6.0" weakdeps = ["SparseArrays"] [deps.ArrayLayouts.extensions] @@ -660,9 +660,9 @@ weakdeps = ["Statistics"] [[deps.Ipopt]] deps = ["Ipopt_jll", "LinearAlgebra", "MathOptInterface", "OpenBLAS32_jll", "PrecompileTools"] -git-tree-sha1 = "3b646a77ae8818d72aa23e3e6924f481505e64fa" +git-tree-sha1 = "6600353576cee7e7388e57e94115f6aee034fb1c" uuid = "b6b21f68-93f8-5de0-b562-5493be1d77c9" -version = "1.6.0" +version = "1.6.1" [[deps.Ipopt_jll]] deps = ["ASL_jll", "Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "MUMPS_seq_jll", "OpenBLAS32_jll", "Pkg"] @@ -700,9 +700,9 @@ version = "0.21.4" [[deps.JuMP]] deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"] -git-tree-sha1 = "adef1dfbafeab635664fb3249b58be8d290ed49d" +git-tree-sha1 = "5036b4cf6d85b08d80de09ef65b4d951f6e68659" uuid = "4076af6c-e467-56ae-b986-b466b2749572" -version = "1.18.1" +version = "1.19.0" [deps.JuMP.extensions] JuMPDimensionalDataExt = "DimensionalData" @@ -1196,10 +1196,10 @@ uuid = "429524aa-4258-5aef-a3af-852621145aeb" version = "1.9.1" [[deps.Optimization]] -deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "Pkg", "Printf", "ProgressLogging", "Reexport", "SciMLBase", "SparseArrays", "SymbolicIndexingInterface", "TerminalLoggers"] -git-tree-sha1 = "e24a89f3f15fd4beff32a12bde4310768f47c5bc" +deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "Pkg", "Printf", "ProgressLogging", "Reexport", "SciMLBase", "SparseArrays", "TerminalLoggers"] +git-tree-sha1 = "145baedf71770d84bf590d307b4686a9ea619c4b" uuid = "7f7a1694-90dd-40f0-9382-eb1efda571ba" -version = "3.21.2" +version = "3.22.0" [deps.Optimization.extensions] OptimizationEnzymeExt = "Enzyme" @@ -1235,9 +1235,9 @@ version = "1.6.3" [[deps.OrdinaryDiffEq]] deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "MacroTools", "MuladdMacro", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "c971a69e5eea2eba435b55e962c283f15502a0c8" +git-tree-sha1 = "c99ec5e4da0dabe068e5f6af1e157e70f233996b" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.70.0" +version = "6.70.1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] @@ -1374,12 +1374,13 @@ version = "1.3.4" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "SparseArrays", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "5a904ad526cc9a2c5b464f6642ce9dd230fd69b6" +git-tree-sha1 = "2bd309f5171a628efdf5309361cd8a779b9e63a9" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.7.0" +version = "3.8.0" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" + RecursiveArrayToolsForwardDiffExt = "ForwardDiff" RecursiveArrayToolsMeasurementsExt = "Measurements" RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] @@ -1388,6 +1389,7 @@ version = "3.7.0" [deps.RecursiveArrayTools.weakdeps] FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" @@ -1751,9 +1753,9 @@ uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624" version = "0.5.28" [[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" +git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" +version = "0.10.3" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] diff --git a/Project.toml b/Project.toml index 8896bda..4becafa 100644 --- a/Project.toml +++ b/Project.toml @@ -1,5 +1,6 @@ [deps] ADNLPModels = "54578032-b7ea-4c30-94aa-7cbd1cce6c9a" +ConcreteStructs = "2569d6c7-a4a2-43d3-a901-331e8e4be471" ExaModels = "1037b233-b668-4ce9-9b63-f9f681f55dd2" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9" diff --git a/nlpmodels.jl b/nlpmodels.jl index fd12fd3..064ed44 100755 --- a/nlpmodels.jl +++ b/nlpmodels.jl @@ -4,73 +4,69 @@ # implementation reference: https://juliasmoothoptimizers.github.io/ADNLPModels.jl/stable/tutorial/ # other AD libraries can be considered: https://juliasmoothoptimizers.github.io/ADNLPModels.jl/stable/ # +# The original rosetta-opf implementation can be found here, +# https://github.com/lanl-ansi/rosetta-opf/blob/bdc924c23694d09f6393575f6d732176aef7605d/nlpmodels.jl +# +# This implementation is an adaption of the original rosetta-opf implementation +# that uses ConcreteStructs based on the SciMLBenchmarks from 01/16/2024, +# https://github.com/SciML/SciMLBenchmarks.jl/blob/master/benchmarks/OptimizationFrameworks/optimal_powerflow.jmd +# import PowerModels -import Symbolics import ADNLPModels +import ConcreteStructs import NLPModelsIpopt +import Symbolics -function solve_opf(file_name) - time_data_start = time() +ConcreteStructs.@concrete struct DataRepresentation + data + ref + var_lookup + var_init + var_lb + var_ub + ref_gen_idxs + lookup_pg + lookup_qg + lookup_va + lookup_vm + lookup_lij + lookup_p_lij + lookup_q_lij + cost_arrs + f_bus + t_bus + ref_bus_idxs + ref_buses_idxs + ref_bus_gens + ref_bus_arcs + ref_branch_idxs + ref_arcs_from + ref_arcs_to + p_idxmap + q_idxmap + bus_pd + bus_qd + bus_gs + bus_bs + br_g + br_b + br_tr + br_ti + br_ttm + br_g_fr + br_b_fr + br_g_to + br_b_to +end +function load_and_setup_data(file_name) data = PowerModels.parse_file(file_name) PowerModels.standardize_cost_terms!(data, order=2) PowerModels.calc_thermal_limits!(data) ref = PowerModels.build_ref(data)[:it][:pm][:nw][0] - data_load_time = time() - time_data_start - - - time_model_start = time() - - - bus_pd = Dict(i => 0.0 for (i,bus) in ref[:bus]) - bus_qd = Dict(i => 0.0 for (i,bus) in ref[:bus]) - - bus_gs = Dict(i => 0.0 for (i,bus) in ref[:bus]) - bus_bs = Dict(i => 0.0 for (i,bus) in ref[:bus]) - - for (i,bus) in ref[:bus] - if length(ref[:bus_loads][i]) > 0 - bus_pd[i] = sum(ref[:load][l]["pd"] for l in ref[:bus_loads][i]) - bus_qd[i] = sum(ref[:load][l]["qd"] for l in ref[:bus_loads][i]) - end - - if length(ref[:bus_shunts][i]) > 0 - bus_gs[i] = sum(ref[:shunt][s]["gs"] for s in ref[:bus_shunts][i]) - bus_bs[i] = sum(ref[:shunt][s]["bs"] for s in ref[:bus_shunts][i]) - end - end - - - br_g = Dict(i => 0.0 for (i,branch) in ref[:branch]) - br_b = Dict(i => 0.0 for (i,branch) in ref[:branch]) - - br_tr = Dict(i => 0.0 for (i,branch) in ref[:branch]) - br_ti = Dict(i => 0.0 for (i,branch) in ref[:branch]) - br_ttm = Dict(i => 0.0 for (i,branch) in ref[:branch]) - - br_g_fr = Dict(i => 0.0 for (i,branch) in ref[:branch]) - br_b_fr = Dict(i => 0.0 for (i,branch) in ref[:branch]) - br_g_to = Dict(i => 0.0 for (i,branch) in ref[:branch]) - br_b_to = Dict(i => 0.0 for (i,branch) in ref[:branch]) - - for (i,branch) in ref[:branch] - g, b = PowerModels.calc_branch_y(branch) - tr, ti = PowerModels.calc_branch_t(branch) - - br_g[i] = g - br_b[i] = b - - br_tr[i] = tr - br_ti[i] = ti - br_ttm[i] = tr^2 + ti^2 - - br_g_fr[i] = branch["g_fr"] - br_b_fr[i] = branch["b_fr"] - br_g_to[i] = branch["g_to"] - br_b_to[i] = branch["b_to"] - end + # Some data munging to type-stable forms var_lookup = Dict{String,Int}() @@ -124,123 +120,305 @@ function solve_opf(file_name) end @assert var_idx == length(var_init)+1 - #total_callback_time = 0.0 - function opf_objective(x) - #start = time() - cost = 0.0 - for (i,gen) in ref[:gen] - pg = x[var_lookup["pg_$(i)"]] - cost += gen["cost"][1]*pg^2 + gen["cost"][2]*pg + gen["cost"][3] + + ref_gen_idxs = [i for i in keys(ref[:gen])] + lookup_pg = Dict{Int,Int}() + lookup_qg = Dict{Int,Int}() + lookup_va = Dict{Int,Int}() + lookup_vm = Dict{Int,Int}() + lookup_lij = Tuple{Int,Int,Int}[] + lookup_p_lij = Int[] + lookup_q_lij = Int[] + cost_arrs = Dict{Int,Vector{Float64}}() + + for (i,gen) in ref[:gen] + lookup_pg[i] = var_lookup["pg_$(i)"] + lookup_qg[i] = var_lookup["qg_$(i)"] + cost_arrs[i] = gen["cost"] + end + + for (i,bus) in ref[:bus] + lookup_va[i] = var_lookup["va_$(i)"] + lookup_vm[i] = var_lookup["vm_$(i)"] + end + + for (l,i,j) in ref[:arcs] + push!(lookup_lij, (l,i,j)) + push!(lookup_p_lij,var_lookup["p_$(l)_$(i)_$(j)"]) + push!(lookup_q_lij,var_lookup["q_$(l)_$(i)_$(j)"]) + end + + f_bus = Dict{Int,Int}() + t_bus = Dict{Int,Int}() + + for (l,branch) in ref[:branch] + f_bus[l] = branch["f_bus"] + t_bus[l] = branch["t_bus"] + end + + ref_bus_idxs = [i for i in keys(ref[:bus])] + ref_buses_idxs = [i for i in keys(ref[:ref_buses])] + ref_bus_gens = ref[:bus_gens] + ref_bus_arcs = ref[:bus_arcs] + ref_branch_idxs = [i for i in keys(ref[:branch])] + ref_arcs_from = ref[:arcs_from] + ref_arcs_to = ref[:arcs_to] + + p_idxmap = Dict(lookup_lij[i] => lookup_p_lij[i] for i in 1:length(lookup_lij)) + q_idxmap = Dict(lookup_lij[i] => lookup_q_lij[i] for i in 1:length(lookup_lij)) + + bus_pd = Dict(i => 0.0 for (i,bus) in ref[:bus]) + bus_qd = Dict(i => 0.0 for (i,bus) in ref[:bus]) + + bus_gs = Dict(i => 0.0 for (i,bus) in ref[:bus]) + bus_bs = Dict(i => 0.0 for (i,bus) in ref[:bus]) + + for (i,bus) in ref[:bus] + if length(ref[:bus_loads][i]) > 0 + bus_pd[i] = sum(ref[:load][l]["pd"] for l in ref[:bus_loads][i]) + bus_qd[i] = sum(ref[:load][l]["qd"] for l in ref[:bus_loads][i]) + end + + if length(ref[:bus_shunts][i]) > 0 + bus_gs[i] = sum(ref[:shunt][s]["gs"] for s in ref[:bus_shunts][i]) + bus_bs[i] = sum(ref[:shunt][s]["bs"] for s in ref[:bus_shunts][i]) end - #total_callback_time += time() - start - return cost end - function opf_constraints!(cx, x) - #start = time() - va = Dict(i => x[var_lookup["va_$(i)"]] for (i,bus) in ref[:bus]) - vm = Dict(i => x[var_lookup["vm_$(i)"]] for (i,bus) in ref[:bus]) + br_g = Dict(i => 0.0 for (i,branch) in ref[:branch]) + br_b = Dict(i => 0.0 for (i,branch) in ref[:branch]) + + br_tr = Dict(i => 0.0 for (i,branch) in ref[:branch]) + br_ti = Dict(i => 0.0 for (i,branch) in ref[:branch]) + br_ttm = Dict(i => 0.0 for (i,branch) in ref[:branch]) + + br_g_fr = Dict(i => 0.0 for (i,branch) in ref[:branch]) + br_b_fr = Dict(i => 0.0 for (i,branch) in ref[:branch]) + br_g_to = Dict(i => 0.0 for (i,branch) in ref[:branch]) + br_b_to = Dict(i => 0.0 for (i,branch) in ref[:branch]) + + for (i,branch) in ref[:branch] + g, b = PowerModels.calc_branch_y(branch) + tr, ti = PowerModels.calc_branch_t(branch) + + br_g[i] = g + br_b[i] = b + + br_tr[i] = tr + br_ti[i] = ti + br_ttm[i] = tr^2 + ti^2 + + br_g_fr[i] = branch["g_fr"] + br_b_fr[i] = branch["b_fr"] + br_g_to[i] = branch["g_to"] + br_b_to[i] = branch["b_to"] + end - pg = Dict(i => x[var_lookup["pg_$(i)"]] for (i,gen) in ref[:gen]) - qg = Dict(i => x[var_lookup["qg_$(i)"]] for (i,gen) in ref[:gen]) + return DataRepresentation( + data, + ref, + var_lookup, + var_init, + var_lb, + var_ub, + ref_gen_idxs, + lookup_pg, + lookup_qg, + lookup_va, + lookup_vm, + lookup_lij, + lookup_p_lij, + lookup_q_lij, + cost_arrs, + f_bus, + t_bus, + ref_bus_idxs, + ref_buses_idxs, + ref_bus_gens, + ref_bus_arcs, + ref_branch_idxs, + ref_arcs_from, + ref_arcs_to, + p_idxmap, + q_idxmap, + bus_pd, + bus_qd, + bus_gs, + bus_bs, + br_g, + br_b, + br_tr, + br_ti, + br_ttm, + br_g_fr, + br_b_fr, + br_g_to, + br_b_to) +end - p = Dict((l,i,j) => x[var_lookup["p_$(l)_$(i)_$(j)"]] for (l,i,j) in ref[:arcs]) - q = Dict((l,i,j) => x[var_lookup["q_$(l)_$(i)_$(j)"]] for (l,i,j) in ref[:arcs]) +function build_opf_optimization_prob(dataset) + (;data, + ref, + var_lookup, + var_init, + var_lb, + var_ub, + ref_gen_idxs, + lookup_pg, + lookup_qg, + lookup_va, + lookup_vm, + lookup_lij, + lookup_p_lij, + lookup_q_lij, + cost_arrs, + f_bus, + t_bus, + ref_bus_idxs, + ref_buses_idxs, + ref_bus_gens, + ref_bus_arcs, + ref_branch_idxs, + ref_arcs_from, + ref_arcs_to, + p_idxmap, + q_idxmap, + bus_pd, + bus_qd, + bus_gs, + bus_bs, + br_g, + br_b, + br_tr, + br_ti, + br_ttm, + br_g_fr, + br_b_fr, + br_g_to, + br_b_to) = dataset - vm_fr = Dict(l => vm[branch["f_bus"]] for (l,branch) in ref[:branch]) - vm_to = Dict(l => vm[branch["t_bus"]] for (l,branch) in ref[:branch]) - va_fr = Dict(l => va[branch["f_bus"]] for (l,branch) in ref[:branch]) - va_to = Dict(l => va[branch["t_bus"]] for (l,branch) in ref[:branch]) + function opf_objective(x) + cost = 0.0 + for i in ref_gen_idxs + pg = x[lookup_pg[i]] + _cost_arr = cost_arrs[i] + cost += _cost_arr[1]*pg^2 + _cost_arr[2]*pg + _cost_arr[3] + end + return cost + end + function opf_constraints!(ret, x) + offsetidx = 0 - # va_con = [va[i] for (i,bus) in ref[:ref_buses]] - k = 0 - for (i,bus) in ref[:ref_buses] - k += 1 - cx[k] = va[i] + # va_con + for (reti,i) in enumerate(ref_buses_idxs) + ret[reti + offsetidx] = x[lookup_va[i]] end + offsetidx += length(ref_buses_idxs) + # @constraint(model, # sum(p[a] for a in ref[:bus_arcs][i]) == - # sum(pg[g] for g in ref[:bus_gens][i]) - + # sum(pg[g] for g in ref_bus_gens[i]) - # sum(load["pd"] for load in bus_loads) - - # sum(shunt["gs"] for shunt in bus_shunts)*vm[i]^2 + # sum(shunt["gs"] for shunt in bus_shunts)*x[lookup_vm[i]]^2 # ) - for (i, bus) in ref[:bus] - k += 1 - cx[k] = sum(pg[j] for j in ref[:bus_gens][i]; init=0.0) - bus_pd[i] - bus_gs[i]*vm[i]^2 - sum(p[a] for a in ref[:bus_arcs][i]) + for (reti,i) in enumerate(ref_bus_idxs) + ret[reti + offsetidx] = sum(x[lookup_pg[j]] for j in ref_bus_gens[i]; init=0.0) - + bus_pd[i] - + bus_gs[i]*x[lookup_vm[i]]^2 - + sum(x[p_idxmap[a]] for a in ref_bus_arcs[i]) end + offsetidx += length(ref_bus_idxs) + # @constraint(model, # sum(q[a] for a in ref[:bus_arcs][i]) == - # sum(qg[g] for g in ref[:bus_gens][i]) - + # sum(x[lookup_qg[g]] for g in ref_bus_gens[i]) - # sum(load["qd"] for load in bus_loads) + - # sum(shunt["bs"] for shunt in bus_shunts)*vm[i]^2 + # sum(shunt["bs"] for shunt in bus_shunts)*x[lookup_vm[i]]^2 # ) - for (i, bus) in ref[:bus] - k += 1 - cx[k] = sum(qg[j] for j in ref[:bus_gens][i]; init=0.0) - bus_qd[i] + bus_bs[i]*vm[i]^2 - sum(q[a] for a in ref[:bus_arcs][i]) + for (reti,i) in enumerate(ref_bus_idxs) + ret[reti + offsetidx] = sum(x[lookup_qg[j]] for j in ref_bus_gens[i]; init=0.0) - + bus_qd[i] + + bus_bs[i]*x[lookup_vm[i]]^2 - + sum(x[q_idxmap[a]] for a in ref_bus_arcs[i]) end + offsetidx += length(ref_bus_idxs) # @NLconstraint(model, p_fr == (g+g_fr)/ttm*vm_fr^2 + (-g*tr+b*ti)/ttm*(vm_fr*vm_to*cos(va_fr-va_to)) + (-b*tr-g*ti)/ttm*(vm_fr*vm_to*sin(va_fr-va_to)) ) - for (l,i,j) in ref[:arcs_from] - k += 1 - cx[k] = (br_g[l]+br_g_fr[l])/br_ttm[l]*vm_fr[l]^2 + - (-br_g[l]*br_tr[l]+br_b[l]*br_ti[l])/br_ttm[l]*(vm_fr[l]*vm_to[l]*cos(va_fr[l]-va_to[l])) + - (-br_b[l]*br_tr[l]-br_g[l]*br_ti[l])/br_ttm[l]*(vm_fr[l]*vm_to[l]*sin(va_fr[l]-va_to[l])) - - p[(l,i,j)] + # power_flow_p_from_con = + for (reti,(l,i,j)) in enumerate(ref_arcs_from) + ret[reti + offsetidx] = (br_g[l]+br_g_fr[l])/br_ttm[l]*x[lookup_vm[f_bus[l]]]^2 + + (-br_g[l]*br_tr[l]+br_b[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[f_bus[l]]]*x[lookup_vm[t_bus[l]]]*cos(x[lookup_va[f_bus[l]]]-x[lookup_va[t_bus[l]]])) + + (-br_b[l]*br_tr[l]-br_g[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[f_bus[l]]]*x[lookup_vm[t_bus[l]]]*sin(x[lookup_va[f_bus[l]]]-x[lookup_va[t_bus[l]]])) - + x[p_idxmap[(l,i,j)]] end + offsetidx += length(ref_arcs_from) + # @NLconstraint(model, p_to == (g+g_to)*vm_to^2 + (-g*tr-b*ti)/ttm*(vm_to*vm_fr*cos(va_to-va_fr)) + (-b*tr+g*ti)/ttm*(vm_to*vm_fr*sin(va_to-va_fr)) ) - for (l,i,j) in ref[:arcs_to] - k += 1 - cx[k] = (br_g[l]+br_g_to[l])*vm_to[l]^2 + - (-br_g[l]*br_tr[l]-br_b[l]*br_ti[l])/br_ttm[l]*(vm_to[l]*vm_fr[l]*cos(va_to[l]-va_fr[l])) + - (-br_b[l]*br_tr[l]+br_g[l]*br_ti[l])/br_ttm[l]*(vm_to[l]*vm_fr[l]*sin(va_to[l]-va_fr[l])) - - p[(l,i,j)] + # power_flow_p_to_con + for (reti,(l,i,j)) in enumerate(ref_arcs_to) + ret[reti + offsetidx] = (br_g[l]+br_g_to[l])*x[lookup_vm[t_bus[l]]]^2 + + (-br_g[l]*br_tr[l]-br_b[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[t_bus[l]]]*x[lookup_vm[f_bus[l]]]*cos(x[lookup_va[t_bus[l]]]-x[lookup_va[f_bus[l]]])) + + (-br_b[l]*br_tr[l]+br_g[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[t_bus[l]]]*x[lookup_vm[f_bus[l]]]*sin(x[lookup_va[t_bus[l]]]-x[lookup_va[f_bus[l]]])) - + x[p_idxmap[(l,i,j)]] end + offsetidx += length(ref_arcs_to) + # @NLconstraint(model, q_fr == -(b+b_fr)/ttm*vm_fr^2 - (-b*tr-g*ti)/ttm*(vm_fr*vm_to*cos(va_fr-va_to)) + (-g*tr+b*ti)/ttm*(vm_fr*vm_to*sin(va_fr-va_to)) ) - for (l,i,j) in ref[:arcs_from] - k += 1 - cx[k] = -(br_b[l]+br_b_fr[l])/br_ttm[l]*vm_fr[l]^2 - - (-br_b[l]*br_tr[l]-br_g[l]*br_ti[l])/br_ttm[l]*(vm_fr[l]*vm_to[l]*cos(va_fr[l]-va_to[l])) + - (-br_g[l]*br_tr[l]+br_b[l]*br_ti[l])/br_ttm[l]*(vm_fr[l]*vm_to[l]*sin(va_fr[l]-va_to[l])) - - q[(l,i,j)] + # power_flow_q_from_con + for (reti,(l,i,j)) in enumerate(ref_arcs_from) + ret[reti + offsetidx] = -(br_b[l]+br_b_fr[l])/br_ttm[l]*x[lookup_vm[f_bus[l]]]^2 - + (-br_b[l]*br_tr[l]-br_g[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[f_bus[l]]]*x[lookup_vm[t_bus[l]]]*cos(x[lookup_va[f_bus[l]]]-x[lookup_va[t_bus[l]]])) + + (-br_g[l]*br_tr[l]+br_b[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[f_bus[l]]]*x[lookup_vm[t_bus[l]]]*sin(x[lookup_va[f_bus[l]]]-x[lookup_va[t_bus[l]]])) - + x[q_idxmap[(l,i,j)]] end + offsetidx += length(ref_arcs_from) + # @NLconstraint(model, q_to == -(b+b_to)*vm_to^2 - (-b*tr+g*ti)/ttm*(vm_to*vm_fr*cos(va_to-va_fr)) + (-g*tr-b*ti)/ttm*(vm_to*vm_fr*sin(va_to-va_fr)) ) - for (l,i,j) in ref[:arcs_to] - k += 1 - cx[k] = -(br_b[l]+br_b_to[l])*vm_to[l]^2 - - (-br_b[l]*br_tr[l]+br_g[l]*br_ti[l])/br_ttm[l]*(vm_to[l]*vm_fr[l]*cos(va_to[l]-va_fr[l])) + - (-br_g[l]*br_tr[l]-br_b[l]*br_ti[l])/br_ttm[l]*(vm_to[l]*vm_fr[l]*sin(va_to[l]-va_fr[l])) - - q[(l,i,j)] + # power_flow_q_to_con + for (reti,(l,i,j)) in enumerate(ref_arcs_to) + ret[reti + offsetidx] = -(br_b[l]+br_b_to[l])*x[lookup_vm[t_bus[l]]]^2 - + (-br_b[l]*br_tr[l]+br_g[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[t_bus[l]]]*x[lookup_vm[f_bus[l]]]*cos(x[lookup_va[t_bus[l]]]-x[lookup_va[f_bus[l]]])) + + (-br_g[l]*br_tr[l]-br_b[l]*br_ti[l])/br_ttm[l]*(x[lookup_vm[t_bus[l]]]*x[lookup_vm[f_bus[l]]]*sin(x[lookup_va[t_bus[l]]]-x[lookup_va[f_bus[l]]])) - + x[q_idxmap[(l,i,j)]] end + offsetidx += length(ref_arcs_to) + # @constraint(model, va_fr - va_to <= branch["angmax"]) # @constraint(model, va_fr - va_to >= branch["angmin"]) - for (l,i,j) in ref[:arcs_from] - k += 1 - cx[k] = va_fr[l] - va_to[l] + # power_flow_vad_con + for (reti,(l,i,j)) in enumerate(ref_arcs_from) + ret[reti + offsetidx] = x[lookup_va[f_bus[l]]] - x[lookup_va[t_bus[l]]] end + offsetidx += length(ref_arcs_from) + # @constraint(model, p_fr^2 + q_fr^2 <= branch["rate_a"]^2) - for (l,i,j) in ref[:arcs_from] - k += 1 - cx[k] = p[(l,i,j)]^2 + q[(l,i,j)]^2 + # power_flow_mva_from_con + for (reti,(l,i,j)) in enumerate(ref_arcs_from) + ret[reti + offsetidx] = x[p_idxmap[(l,i,j)]]^2 + x[q_idxmap[(l,i,j)]]^2 end + offsetidx += length(ref_arcs_from) + # @constraint(model, p_to^2 + q_to^2 <= branch["rate_a"]^2) - for (l,i,j) in ref[:arcs_to] - k += 1 - cx[k] = p[(l,i,j)]^2 + q[(l,i,j)]^2 + # power_flow_mva_to_con + for (reti,(l,i,j)) in enumerate(ref_arcs_to) + ret[reti + offsetidx] = x[p_idxmap[(l,i,j)]]^2 + x[q_idxmap[(l,i,j)]]^2 end - #total_callback_time += time() - start - return cx + offsetidx += length(ref_arcs_to) + + @assert offsetidx == length(ret) + return ret end con_lbs = Float64[] @@ -309,26 +487,30 @@ function solve_opf(file_name) push!(con_ubs, branch["rate_a"]^2) end - model_variables = length(var_init) - model_constraints = length(opf_constraints!(similar(con_lbs), var_init)) - println("variables: $(model_variables), $(length(var_lb)), $(length(var_ub))") - println("constraints: $(model_constraints), $(length(con_lbs)), $(length(con_ubs))") - nlp = ADNLPModels.ADNLPModel!(opf_objective, var_init, var_lb, var_ub, opf_constraints!, con_lbs, con_ubs, backend = :optimized) + return ( + nlp = nlp, + con_lbs = con_lbs, + con_ubs = con_ubs, + ) +end - model_build_time = time() - time_model_start - - - time_solve_start = time() - +function solve_opf(file_name) + start = time() + dataset = load_and_setup_data(file_name); + data_load_time = time() - start + model = build_opf_optimization_prob(dataset) + nlp = model.nlp + model_build_time = time() - start - data_load_time output = NLPModelsIpopt.ipopt(nlp) cost = output.objective feasible = (output.primal_feas <= 1e-6) - - solve_time = time() - time_solve_start - total_time = time() - time_data_start - - + total_time = time() - start + solve_time = total_time - model_build_time - data_load_time + model_variables = length(dataset.var_init) + model_constraints = length(model.con_lbs) + println("variables: $(model_variables), $(length(dataset.var_lb)), $(length(dataset.var_ub))") + println("constraints: $(model_constraints), $(length(model.con_lbs)), $(length(model.con_ubs))") println("") println("\033[1mSummary\033[0m") println(" case........: $(file_name)") @@ -340,7 +522,6 @@ function solve_opf(file_name) println(" data time.: $(data_load_time)") println(" build time: $(model_build_time)") println(" solve time: $(solve_time)") - # println(" callbacks: $(total_callback_time)") println("") return Dict( @@ -353,10 +534,11 @@ function solve_opf(file_name) "time_data" => data_load_time, "time_build" => model_build_time, "time_solve" => solve_time, - "solution" => Dict(k => output.solution[v] for (k, v) in var_lookup), + "solution" => Dict(k => output.solution[v] for (k, v) in dataset.var_lookup), ) end if isinteractive() == false solve_opf("$(@__DIR__)/data/opf_warmup.m") end + diff --git a/variants/Manifest.toml b/variants/Manifest.toml index 740c67e..adbe5c3 100644 --- a/variants/Manifest.toml +++ b/variants/Manifest.toml @@ -70,9 +70,9 @@ version = "7.7.0" [[deps.ArrayLayouts]] deps = ["FillArrays", "LinearAlgebra"] -git-tree-sha1 = "a45ec4acc9d905f94b47243cff666820bb107789" +git-tree-sha1 = "64d582bcb9c93ac741234789eeb4f16812413efb" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.5.2" +version = "1.6.0" weakdeps = ["SparseArrays"] [deps.ArrayLayouts.extensions] @@ -115,9 +115,9 @@ version = "0.2.4" [[deps.CSTParser]] deps = ["Tokenize"] -git-tree-sha1 = "1dd0361befc505b9c6db4b5ab7eb874837de0569" +git-tree-sha1 = "b1d309487c04e92253b55c1f803b1d6f0e136920" uuid = "00ebfdb7-1f24-5e51-bd34-a7502290713f" -version = "3.4.0" +version = "3.4.1" [[deps.Calculus]] deps = ["LinearAlgebra"] @@ -127,9 +127,9 @@ version = "0.5.1" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "0d12ee16b3f62e4e33c3277773730a5b21a74152" +git-tree-sha1 = "1287e3872d646eed95198457873249bd9f0caed2" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.20.0" +version = "1.20.1" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -143,15 +143,15 @@ version = "0.1.12" [[deps.CodecBzip2]] deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"] -git-tree-sha1 = "c0ae2a86b162fb5d7acc65269b469ff5b8a73594" +git-tree-sha1 = "9b1ca1aa6ce3f71b3d1840c538a8210a043625eb" uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" -version = "0.8.1" +version = "0.8.2" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.3" +version = "0.7.4" [[deps.Combinatorics]] git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" @@ -404,9 +404,9 @@ version = "0.3.2" [[deps.FastLapackInterface]] deps = ["LinearAlgebra"] -git-tree-sha1 = "b12f05108e405dadcc2aff0008db7f831374e051" +git-tree-sha1 = "d576a29bf8bcabf4b1deb9abe88a3d7f78306ab5" uuid = "29a986be-02c6-4525-aec4-84b980013641" -version = "2.0.0" +version = "2.0.1" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" @@ -549,9 +549,9 @@ weakdeps = ["Statistics"] [[deps.Ipopt]] deps = ["Ipopt_jll", "LinearAlgebra", "MathOptInterface", "OpenBLAS32_jll", "PrecompileTools"] -git-tree-sha1 = "3b646a77ae8818d72aa23e3e6924f481505e64fa" +git-tree-sha1 = "6600353576cee7e7388e57e94115f6aee034fb1c" uuid = "b6b21f68-93f8-5de0-b562-5493be1d77c9" -version = "1.6.0" +version = "1.6.1" [[deps.Ipopt_jll]] deps = ["ASL_jll", "Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "MUMPS_seq_jll", "OpenBLAS32_jll", "Pkg"] @@ -595,9 +595,9 @@ version = "1.14.0" [[deps.JuMP]] deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"] -git-tree-sha1 = "adef1dfbafeab635664fb3249b58be8d290ed49d" +git-tree-sha1 = "5036b4cf6d85b08d80de09ef65b4d951f6e68659" uuid = "4076af6c-e467-56ae-b986-b466b2749572" -version = "1.18.1" +version = "1.19.0" [deps.JuMP.extensions] JuMPDimensionalDataExt = "DimensionalData" @@ -843,9 +843,9 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MathOptInterface]] deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] -git-tree-sha1 = "e2ae8cf5ac6daf5a3959f7f6ded9c2028b61d09d" +git-tree-sha1 = "8b40681684df46785a0012d352982e22ac3be59e" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.25.1" +version = "1.25.2" [[deps.MathOptSymbolicAD]] deps = ["MathOptInterface", "SparseArrays", "Symbolics"] @@ -950,9 +950,9 @@ version = "1.2.0" [[deps.NonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "LazyArrays", "LineSearches", "LinearAlgebra", "LinearSolve", "MaybeInplace", "PrecompileTools", "Preferences", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "TimerOutputs"] -git-tree-sha1 = "78bdd3a4a62865cf43c53d63783b0cbfddcdbbe6" +git-tree-sha1 = "323d2a61f4adc4dfe404bf332b59690253b4f4f2" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "3.5.0" +version = "3.5.3" [deps.NonlinearSolve.extensions] NonlinearSolveBandedMatricesExt = "BandedMatrices" @@ -1010,10 +1010,10 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" [[deps.Optimization]] -deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "Pkg", "Printf", "ProgressLogging", "Reexport", "SciMLBase", "SparseArrays", "SymbolicIndexingInterface", "TerminalLoggers"] -git-tree-sha1 = "e24a89f3f15fd4beff32a12bde4310768f47c5bc" +deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "Pkg", "Printf", "ProgressLogging", "Reexport", "SciMLBase", "SparseArrays", "TerminalLoggers"] +git-tree-sha1 = "145baedf71770d84bf590d307b4686a9ea619c4b" uuid = "7f7a1694-90dd-40f0-9382-eb1efda571ba" -version = "3.21.2" +version = "3.22.0" [deps.Optimization.extensions] OptimizationEnzymeExt = "Enzyme" @@ -1049,9 +1049,9 @@ version = "1.6.3" [[deps.OrdinaryDiffEq]] deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "MacroTools", "MuladdMacro", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "7c6738f21fba2ccd07b7eaa9d23b437a8a97f1a1" +git-tree-sha1 = "c99ec5e4da0dabe068e5f6af1e157e70f233996b" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.69.0" +version = "6.70.1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] @@ -1188,12 +1188,13 @@ version = "1.3.4" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "SparseArrays", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "16f1bb9de02b8bce31a7b2495345532901214cae" +git-tree-sha1 = "2bd309f5171a628efdf5309361cd8a779b9e63a9" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.6.2" +version = "3.8.0" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" + RecursiveArrayToolsForwardDiffExt = "ForwardDiff" RecursiveArrayToolsMeasurementsExt = "Measurements" RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] @@ -1202,6 +1203,7 @@ version = "3.6.2" [deps.RecursiveArrayTools.weakdeps] FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" @@ -1266,9 +1268,9 @@ version = "0.6.42" [[deps.SciMLBase]] deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces"] -git-tree-sha1 = "d91985cfda7d730a885d7dbc89889e8184b72802" +git-tree-sha1 = "535bb76be2c1090a09767b18b160f5729ad12aff" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.21.0" +version = "2.23.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1404,9 +1406,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" +git-tree-sha1 = "7b0e9c14c624e435076d19aea1e5cbdec2b9ca37" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.1" +version = "1.9.2" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1471,9 +1473,9 @@ uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" [[deps.SymbolicIndexingInterface]] -git-tree-sha1 = "34573fc920adfd457c5be704098d0168e4f20e54" +git-tree-sha1 = "b3103f4f50a3843e66297a2456921377c78f5e31" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.4" +version = "0.3.5" [[deps.SymbolicUtils]] deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TimerOutputs", "Unityper"] @@ -1549,9 +1551,9 @@ uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624" version = "0.5.28" [[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" +git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" +version = "0.10.3" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions]