From 863c2941c8b93e670674aabfbde7166e65f2d0bf Mon Sep 17 00:00:00 2001 From: Carleton Coffrin Date: Sat, 27 Jan 2024 06:45:20 -0700 Subject: [PATCH] Add Optim via JuMP to Debugging Models (#61) * add jump model with optim solver for debugging * update variants manifest --- debug/optim-jump.jl | 131 +++++++++++++++++++++++++++++++++++++++++ variants/Manifest.toml | 47 ++++++++------- 2 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 debug/optim-jump.jl diff --git a/debug/optim-jump.jl b/debug/optim-jump.jl new file mode 100644 index 0000000..a458eb0 --- /dev/null +++ b/debug/optim-jump.jl @@ -0,0 +1,131 @@ +time_start = time() + +using PowerModels +using JuMP +using Optim + +pkg_load_time = time() - time_start + + +time_start = time() + +file_name = "../data/pglib_opf_case5_pjm.m" +#file_name = "../data/pglib_opf_case118_ieee.m" + +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_start + + +time_start = time() + +model = JuMP.Model() + +@variable(model, va[i in keys(ref[:bus])]) +@variable(model, ref[:bus][i]["vmin"] <= vm[i in keys(ref[:bus])] <= ref[:bus][i]["vmax"], start=1.0) + +@variable(model, ref[:gen][i]["pmin"] <= pg[i in keys(ref[:gen])] <= ref[:gen][i]["pmax"], start=(ref[:gen][i]["pmin"] + ref[:gen][i]["pmax"])/2) +@variable(model, ref[:gen][i]["qmin"] <= qg[i in keys(ref[:gen])] <= ref[:gen][i]["qmax"], start=(ref[:gen][i]["qmin"] + ref[:gen][i]["qmax"])/2) + +@variable(model, -ref[:branch][l]["rate_a"] <= p[(l,i,j) in ref[:arcs]] <= ref[:branch][l]["rate_a"]) +@variable(model, -ref[:branch][l]["rate_a"] <= q[(l,i,j) in ref[:arcs]] <= ref[:branch][l]["rate_a"]) + + +@objective(model, Min, sum(gen["cost"][1]*pg[i]^2 + gen["cost"][2]*pg[i] + gen["cost"][3] for (i,gen) in ref[:gen])) + + +for (i,bus) in ref[:ref_buses] + @constraint(model, va[i] == 0) +end + +for (i,bus) in ref[:bus] + bus_loads = [ref[:load][l] for l in ref[:bus_loads][i]] + bus_shunts = [ref[:shunt][s] for s in ref[:bus_shunts][i]] + + @constraint(model, + sum(p[a] for a in ref[:bus_arcs][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 + ) + + @constraint(model, + sum(q[a] for a in ref[:bus_arcs][i]) == + sum(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 + ) +end + +# Branch power flow physics and limit constraints +for (i,branch) in ref[:branch] + f_idx = (i, branch["f_bus"], branch["t_bus"]) + t_idx = (i, branch["t_bus"], branch["f_bus"]) + + p_fr = p[f_idx] # p_fr is a reference to the optimization variable p[f_idx] + q_fr = q[f_idx] # q_fr is a reference to the optimization variable q[f_idx] + p_to = p[t_idx] # p_to is a reference to the optimization variable p[t_idx] + q_to = q[t_idx] # q_to is a reference to the optimization variable q[t_idx] + + vm_fr = vm[branch["f_bus"]] # vm_fr is a reference to the optimization variable vm on the from side of the branch + vm_to = vm[branch["t_bus"]] # vm_to is a reference to the optimization variable vm on the to side of the branch + va_fr = va[branch["f_bus"]] # va_fr is a reference to the optimization variable va on the from side of the branch + va_to = va[branch["t_bus"]] # va_fr is a reference to the optimization variable va on the to side of the branch + + g, b = PowerModels.calc_branch_y(branch) + tr, ti = PowerModels.calc_branch_t(branch) + tm = tr^2 + ti^2 + g_fr = branch["g_fr"] + b_fr = branch["b_fr"] + g_to = branch["g_to"] + b_to = branch["b_to"] + + # From side of the branch flow + @constraint(model, p_fr == (g+g_fr)/tm*vm_fr^2 + (-g*tr+b*ti)/tm*(vm_fr*vm_to*cos(va_fr-va_to)) + (-b*tr-g*ti)/tm*(vm_fr*vm_to*sin(va_fr-va_to)) ) + @constraint(model, q_fr == -(b+b_fr)/tm*vm_fr^2 - (-b*tr-g*ti)/tm*(vm_fr*vm_to*cos(va_fr-va_to)) + (-g*tr+b*ti)/tm*(vm_fr*vm_to*sin(va_fr-va_to)) ) + + # To side of the branch flow + @constraint(model, p_to == (g+g_to)*vm_to^2 + (-g*tr-b*ti)/tm*(vm_to*vm_fr*cos(va_to-va_fr)) + (-b*tr+g*ti)/tm*(vm_to*vm_fr*sin(va_to-va_fr)) ) + @constraint(model, q_to == -(b+b_to)*vm_to^2 - (-b*tr+g*ti)/tm*(vm_to*vm_fr*cos(va_fr-va_to)) + (-g*tr-b*ti)/tm*(vm_to*vm_fr*sin(va_to-va_fr)) ) + + # Voltage angle difference limit + @constraint(model, branch["angmin"] <= va_fr - va_to <= branch["angmax"]) + + # Apparent power limit, from side and to side + @constraint(model, p_fr^2 + q_fr^2 <= branch["rate_a"]^2) + @constraint(model, p_to^2 + q_to^2 <= branch["rate_a"]^2) +end + + +set_optimizer(model, Optim.Optimizer) +set_optimizer_attribute(model, "method", IPNewton()) +set_optimizer_attribute(model, "show_trace", true) + +model_build_time = time() - time_start + + +time_start = time() + +JuMP.optimize!(model) +cost = JuMP.objective_value(model) +feasible = JuMP.termination_status(model) + +solve_time = time() - time_start + + +println("") +println("\033[1mSummary\033[0m") +println(" case..........: $(file_name)") +println(" cost..........: $(round(Int, cost))") +println(" feasible......: $(feasible)") +println(" primal status.: $(JuMP.primal_status(model))") +println(" dual status...: $(JuMP.dual_status(model))") +println(" pkg time......: $(pkg_load_time)") +println(" data time.....: $(data_load_time)") +println(" build time....: $(model_build_time)") +println(" solve time....: $(solve_time)") +println("") + diff --git a/variants/Manifest.toml b/variants/Manifest.toml index 07f2b4a..740c67e 100644 --- a/variants/Manifest.toml +++ b/variants/Manifest.toml @@ -127,9 +127,9 @@ version = "0.5.1" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" +git-tree-sha1 = "0d12ee16b3f62e4e33c3277773730a5b21a74152" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.19.1" +version = "1.20.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -235,9 +235,9 @@ uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" version = "4.1.1" [[deps.DataAPI]] -git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.15.0" +version = "1.16.0" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] @@ -949,10 +949,10 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.NonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "LazyArrays", "LineSearches", "LinearAlgebra", "LinearSolve", "MaybeInplace", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArrays", "UnPack"] -git-tree-sha1 = "72b036b728461272ae1b1c3f7096cb4c319d8793" +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" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "3.4.0" +version = "3.5.0" [deps.NonlinearSolve.extensions] NonlinearSolveBandedMatricesExt = "BandedMatrices" @@ -1011,9 +1011,9 @@ 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 = "31fe8abda56b2168d262b515ecabdb44d7c36b4d" +git-tree-sha1 = "e24a89f3f15fd4beff32a12bde4310768f47c5bc" uuid = "7f7a1694-90dd-40f0-9382-eb1efda571ba" -version = "3.21.1" +version = "3.21.2" [deps.Optimization.extensions] OptimizationEnzymeExt = "Enzyme" @@ -1108,9 +1108,9 @@ version = "0.2.1" [[deps.PowerModels]] deps = ["InfrastructureModels", "JSON", "JuMP", "LinearAlgebra", "Memento", "NLsolve", "SparseArrays"] -git-tree-sha1 = "ebb09c118540aa4f15a0f5a157969ef4a578b6f0" +git-tree-sha1 = "82dc2524b633fdc459052f4ce28d67d62ffbb0db" uuid = "c36e90e8-916a-50a6-bd94-075b64ef4655" -version = "0.20.1" +version = "0.21.0" [[deps.PreallocationTools]] deps = ["Adapt", "ArrayInterface", "ForwardDiff"] @@ -1188,14 +1188,15 @@ version = "1.3.4" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "SparseArrays", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "720e17f568661f7c1d9ce8df20c75b544b22e249" +git-tree-sha1 = "16f1bb9de02b8bce31a7b2495345532901214cae" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.5.3" +version = "3.6.2" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" RecursiveArrayToolsMeasurementsExt = "Measurements" RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" + RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] RecursiveArrayToolsTrackerExt = "Tracker" RecursiveArrayToolsZygoteExt = "Zygote" @@ -1203,6 +1204,7 @@ version = "3.5.3" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" @@ -1264,9 +1266,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 = "ad711463cb386572f33f6209464d8dca5a081247" +git-tree-sha1 = "d91985cfda7d730a885d7dbc89889e8184b72802" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.19.0" +version = "2.21.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1351,17 +1353,19 @@ version = "1.10.0" [[deps.SparseDiffTools]] deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] -git-tree-sha1 = "c281e11db4eacb36a292a054bac83c5a0aca2a26" +git-tree-sha1 = "3b38ae7a1cbe9b8b1344359599753957644b03d4" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "2.15.0" +version = "2.16.0" [deps.SparseDiffTools.extensions] SparseDiffToolsEnzymeExt = "Enzyme" + SparseDiffToolsPolyesterForwardDiffExt = "PolyesterForwardDiff" SparseDiffToolsSymbolicsExt = "Symbolics" SparseDiffToolsZygoteExt = "Zygote" [deps.SparseDiffTools.weakdeps] Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" @@ -1467,9 +1471,9 @@ uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" [[deps.SymbolicIndexingInterface]] -git-tree-sha1 = "74502f408d99fc217a9d7cd901d9ffe45af892b1" +git-tree-sha1 = "34573fc920adfd457c5be704098d0168e4f20e54" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.3" +version = "0.3.4" [[deps.SymbolicUtils]] deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TimerOutputs", "Unityper"] @@ -1479,11 +1483,12 @@ version = "1.5.0" [[deps.Symbolics]] deps = ["ArrayInterface", "Bijections", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "RecipesBase", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "SymbolicUtils"] -git-tree-sha1 = "8960d2f32a99e52bb323de7c6c564f04427cfe63" +git-tree-sha1 = "ab1785cd8cbfa6cc26af3efa491fd241aa69855e" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "5.16.0" +version = "5.16.1" [deps.Symbolics.extensions] + SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" SymbolicsPreallocationToolsExt = ["ForwardDiff", "PreallocationTools"] SymbolicsSymPyExt = "SymPy"