diff --git a/Project.toml b/Project.toml index 5b1aa09..10a60b6 100644 --- a/Project.toml +++ b/Project.toml @@ -22,7 +22,7 @@ JSON = "0.21" JuMP = "0.21, 0.22" Juniper = "0.7, 0.8" Memento = "1" -PowerModels = "0.18, 0.19" +PowerModels = "0.19.2" julia = "1.1" [extras] diff --git a/docs/src/pptutorial.md b/docs/src/pptutorial.md index dd6f5ec..d4a996f 100644 --- a/docs/src/pptutorial.md +++ b/docs/src/pptutorial.md @@ -14,6 +14,7 @@ Functions from PowerModels: * [Storage Optimization](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_storage.ipynb) Functions from PandaModels: -* [Reactive Optimization - maintaining voltage setpoints](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) -* [Reactive Optimization - maintaining reactive power setpoints](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) -* [Reactive Optimization - active power loss reduction](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) +* [Reactive Power Optimization - maintaining voltage setpoints](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) +* [Reactive Power Optimization - maintaining reactive power setpoints](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) +* [Reactive Power Optimization - active power loss reduction](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) +* [Reactive Power Optimization - branch loading reduction](https://github.com/e2nIEE/pandapower/blob/develop/tutorials/pandamodels_reactive%20power%20optimization.ipynb) diff --git a/src/models/call_pandamodels.jl b/src/models/call_pandamodels.jl index 33fa440..cc03f53 100644 --- a/src/models/call_pandamodels.jl +++ b/src/models/call_pandamodels.jl @@ -101,3 +101,21 @@ function run_pandamodels_loading(json_path) ) return result end + + +function run_pandamodels_custom(json_path) + pm = load_pm_from_json(json_path) + active_powermodels_silence!(pm) + pm = check_powermodels_data!(pm) + model = get_model(pm["pm_model"]) + solver = get_solver(pm) + + result = _run_custom( + pm, + model, + solver, + setting = Dict("output" => Dict("branch_flows" => true)), + ext = extract_params!(pm), + ) + return result +end \ No newline at end of file diff --git a/src/models/create_custom_model.jl b/src/models/create_custom_model.jl new file mode 100644 index 0000000..ff49f25 --- /dev/null +++ b/src/models/create_custom_model.jl @@ -0,0 +1,197 @@ +function run_pandamodels_qflex_test(json_path) # before run_poweramodels + time_start = time() + ############################################################################### + # 0. Initialization + ############################################################################### + pm = load_pm_from_json(json_path) + solver = get_solver(pm["pm_solver"], pm["pm_nl_solver"], pm["pm_mip_solver"], + pm["pm_log_level"], pm["pm_time_limit"], pm["pm_nl_time_limit"], pm["pm_mip_time_limit"]) + if haskey(pm, "user_defined_params") + user_defined_params = pm["user_defined_params"] + data = delete!(pm, "user_defined_params") + else + data = pm + end + + # additional modification + for (i, branch) in pm["branch"] + pm["branch"][i]["angmin"] = -6.28 + pm["branch"][i]["angmax"] = 6.28 + end + + # use build_ref to filter out inactive components + ref = PowerModels.build_ref(data)[:it][:pm][:nw][0] + + ############################################################################### + # 1. Building the Optimal Power Flow Model + ############################################################################### + # Initialize a JuMP Optimization Model + #------------------------------------- + model = JuMP.Model(solver) + + # Add voltage angles va for each bus + JuMP.@variable(model, va[i in keys(ref[:bus])]) + # note: [i in keys(ref[:bus])] adds one `va` variable for each bus in the network + + # Add voltage angles vm for each bus + JuMP.@variable(model, ref[:bus][i]["vmin"] <= vm[i in keys(ref[:bus])] <= ref[:bus][i]["vmax"], start=1.0) + # note: this vairable also includes the voltage magnitude limits and a starting value + + # Add active power generation variable pg for each generator (including limits) + JuMP.@variable(model, ref[:gen][i]["pmin"] <= pg[i in keys(ref[:gen])] <= ref[:gen][i]["pmax"], start=ref[:gen][i]["pg"]) + # Add reactive power generation variable qg for each generator (including limits) + JuMP.@variable(model, ref[:gen][i]["qmin"] <= qg[i in keys(ref[:gen])] <= ref[:gen][i]["qmax"], start=ref[:gen][i]["qg"]) + + # Add power flow variables p to represent the active power flow for each branch + JuMP.@variable(model, -ref[:branch][l]["rate_a"] <= p[(l,i,j) in ref[:arcs]] <= ref[:branch][l]["rate_a"]) + # Add power flow variables q to represent the reactive power flow for each branch + JuMP.@variable(model, -ref[:branch][l]["rate_a"] <= q[(l,i,j) in ref[:arcs]] <= ref[:branch][l]["rate_a"]) + # note: ref[:arcs] includes both the from (i,j) and the to (j,i) sides of a branch + + # Add Objective Function + # ---------------------- + + JuMP.@objective(model, Min, sum((q[(content["element_index"], + content["f_bus"], + content["t_bus"])] - content["value"])^2 + for (i, content) in user_defined_params["setpoint_q"])) + + # Add Constraints + for (i,bus) in ref[:ref_buses] + JuMP.@constraint(model, va[i] == 0) + end + + # Nodal power balance constraints + for (i,bus) in ref[:bus] + # Build a list of the loads and shunt elements connected to the bus i + bus_loads = [ref[:load][l] for l in ref[:bus_loads][i]] + bus_shunts = [ref[:shunt][s] for s in ref[:bus_shunts][i]] + + # Active power balance at node i + JuMP.@constraint(model, + sum(p[a] for a in ref[:bus_arcs][i]) + # sum of active power flow on lines from bus i + + sum(p_dc[a_dc] for a_dc in ref[:bus_arcs_dc][i]) == # sum of active power flow on HVDC lines from bus i = + sum(pg[g] for g in ref[:bus_gens][i]) - # sum of active power generation at bus i - + sum(load["pd"] for load in bus_loads) - # sum of active load consumption at bus i - + sum(shunt["gs"] for shunt in bus_shunts)*vm[i]^2 # sum of active shunt element injections at bus i + ) + + # Reactive power balance at node i + JuMP.@constraint(model, + sum(q[a] for a in ref[:bus_arcs][i]) + # sum of reactive power flow on lines from bus i + + sum(q_dc[a_dc] for a_dc in ref[:bus_arcs_dc][i]) == # sum of reactive power flow on HVDC lines from bus i = + sum(qg[g] for g in ref[:bus_gens][i]) - # sum of reactive power generation at bus i - + sum(load["qd"] for load in bus_loads) + # sum of reactive load consumption at bus i - + sum(shunt["bs"] for shunt in bus_shunts)*vm[i]^2 # sum of reactive shunt element injections at bus i + ) + end + + # Branch power flow physics and limit constraints + for (i,branch) in ref[:branch] + # Build the from variable id of the i-th branch, which is a tuple given by (branch id, from bus, to bus) + f_idx = (i, branch["f_bus"], branch["t_bus"]) + # Build the to variable id of the i-th branch, which is a tuple given by (branch id, to bus, from bus) + t_idx = (i, branch["t_bus"], branch["f_bus"]) + # note: it is necessary to distinguish between the from and to sides of a branch due to power losses + + 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] + # note: adding constraints to p_fr is equivalent to adding constraints to p[f_idx], and so on + + 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 + + # Compute the branch parameters and transformer ratios from the data + g, b = PowerModels.calc_branch_y(branch) + tr, ti = PowerModels.calc_branch_t(branch) + g_fr = branch["g_fr"] + b_fr = branch["b_fr"] + g_to = branch["g_to"] + b_to = branch["b_to"] + tm = branch["tap"]^2 + # note: tap is assumed to be 1.0 on non-transformer branches + + + # AC Power Flow Constraints + + # From side of the branch flow + JuMP.@NLconstraint(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)) ) + JuMP.@NLconstraint(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 + JuMP.@NLconstraint(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)) ) + JuMP.@NLconstraint(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 + JuMP.@constraint(model, va_fr - va_to <= branch["angmax"]) + JuMP.@constraint(model, va_fr - va_to >= branch["angmin"]) + + # Apparent power limit, from side and to side + JuMP.@constraint(model, p_fr^2 + q_fr^2 <= branch["rate_a"]^2) + JuMP.@constraint(model, p_to^2 + q_to^2 <= branch["rate_a"]^2) + end + + + ############################################################################### + # 3. Solve the Optimal Power Flow Model and Review the Results + ############################################################################### + JuMP.optimize!(model) + + ############################################################################### + # 4. Create Result Dictionary such that the PowerModels Results can be used by pandapower + ############################################################################### + solution = Dict{String,Any}() + push!(solution, "baseMVA" => data["baseMVA"]) + push!(solution, "per_unit" => data["per_unit"]) + push!(solution, "gen" => data["gen"]) + push!(solution, "bus" => data["bus"]) + push!(solution, "branch" => data["branch"]) + push!(solution, "multinetwork" => false) + push!(solution, "multiinfrastructrue" => false) + + for (i, gen) in solution["gen"] + index = gen["index"] + gen["qg"] = value(model[:qg][index]) + gen["pg"] = value(model[:pg][index]) + end + + for (i, bus) in solution["bus"] + index = bus["index"] + bus["vm"] = value(model[:vm][index]) + bus["va"] = value(model[:va][index]) + end + + for (i, branch) in solution["branch"] + index = branch["index"] + push!(branch, "qf" => value(model[:q][(index, branch["f_bus"], branch["t_bus"])])) + push!(branch, "qt" => value(model[:q][(index, branch["t_bus"], branch["f_bus"])])) + push!(branch, "pf" => value(model[:p][(index, branch["f_bus"], branch["t_bus"])])) + push!(branch, "pt" => value(model[:p][(index, branch["t_bus"], branch["f_bus"])])) + end + println("The solver termination status is") + + result = Dict{String,Any}( + "optimizer" => JuMP.solver_name(model), + "termination_status" => JuMP.termination_status(model), # "LOCALLY_SOLVED", + "primal_status" => JuMP.primal_status(model), + "dual_status" => JuMP.dual_status(model), + "objective" => InfrastructureModels._guard_objective_value(model), + "objective_lb" => InfrastructureModels._guard_objective_bound(model), + "solve_time" => solve_time, + "solution" => solution) + + return result +end + + +# json_path = "C:/Users/fmeier/pandapower/pandapower/test/opf/case5_clm_matfile_va.json" +# # #@enter run_powermodels(json_path) +# # +# result = run_powermodels(json_path) +# println(result["termination_status"] == LOCALLY_SOLVED) +# println(isapprox(result["objective"], 17015.5; atol = 1e0)) +# mit eingeschränkter slack spannung: 17082.819507648066 diff --git a/src/models/custom.jl b/src/models/custom.jl new file mode 100644 index 0000000..684aed8 --- /dev/null +++ b/src/models/custom.jl @@ -0,0 +1,52 @@ +export _run_custom + +""" +run custom optimization +""" + +function _run_custom(file, model_type::_PM.Type, optimizer; kwargs...) + return _PM.solve_model(file, model_type, optimizer, _build_custom; kwargs...) +end + +""" +give a JuMP model with PowerModels network data structur and build opitmization model +""" + +function _build_custom(pm::_PM.AbstractPowerModel) + + _PM.variable_bus_voltage(pm) + _PM.variable_gen_power(pm) + _PM.variable_branch_power(pm) + _PM.variable_dcline_power(pm, bounded = false) # TODO: why false? + + objective_custom(pm) + + _PM.constraint_model_voltage(pm) + + for i in _PM.ids(pm, :ref_buses) + _PM.constraint_theta_ref(pm, i) + end + + for i in _PM.ids(pm, :bus) + _PM.constraint_power_balance(pm, i) + end + + for (i, branch) in _PM.ref(pm, :branch) + _PM.constraint_ohms_yt_from(pm, i) + _PM.constraint_ohms_yt_to(pm, i) + + _PM.constraint_thermal_limit_from(pm, i) + _PM.constraint_thermal_limit_to(pm, i) + end + + for i in _PM.ids(pm, :dcline) + _PM.constraint_dcline_power_losses(pm, i) + end +end + +function objective_custom(pm::_PM.AbstractPowerModel) + + return JuMP.@objective(pm.model, Min, sum((var(pm, :q, (content["element_index"], content["f_bus"], content["t_bus"])) - content["value"])^2 + for (i, content) in pm.ext[:setpoint_q])) +end + diff --git a/src/models/load_custom_pm.jl b/src/models/load_custom_pm.jl new file mode 100644 index 0000000..007face --- /dev/null +++ b/src/models/load_custom_pm.jl @@ -0,0 +1,7 @@ +using PandaModels; const _PdM = PandaModels +import PowerModels; const _PM = PowerModels + +json_path = "C:\\Users\\zliu\\.julia\\dev\\PandaModels\\test\\data\\test_custom.json" # path of the json file +pm = _PdM.load_pm_from_json(json_path) +user_defined_params = pm["user_defined_params"] +print(debug) \ No newline at end of file diff --git a/test/data/test_custom.json b/test/data/test_custom.json new file mode 100644 index 0000000..63b5274 --- /dev/null +++ b/test/data/test_custom.json @@ -0,0 +1 @@ +{"baseMVA": 1, "branch": {"1": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.026786049475940484, "b_to": 0.026786049475940484, "br_r": 0.00353205, "br_status": 1, "br_x": 0.005047799999999999, "f_bus": 2, "g_fr": -0.0, "g_to": -0.0, "index": 1, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 3, "tap": 1.0, "transformer": false}, "10": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.012348178836426464, "b_to": 0.012348178836426464, "br_r": 0.00162825, "br_status": 1, "br_x": 0.002327, "f_bus": 4, "g_fr": -0.0, "g_to": -0.0, "index": 10, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 9, "tap": 1.0, "transformer": false}, "11": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.003102216126048443, "b_to": 0.003102216126048443, "br_r": 0.00623475, "br_status": 1, "br_x": 0.004474349999999999, "f_bus": 13, "g_fr": -0.0, "g_to": -0.0, "index": 11, "rate_a": 20.26499444855586, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 14, "tap": 1.0, "transformer": false}, "12": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.0018968560770725657, "b_to": 0.0018968560770725657, "br_r": 0.0038122500000000005, "br_status": 1, "br_x": 0.00273585, "f_bus": 14, "g_fr": -0.0, "g_to": -0.0, "index": 12, "rate_a": 20.26499444855586, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 15, "tap": 1.0, "transformer": false}, "13": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.002279663785186424, "b_to": 0.002279663785186424, "br_r": 0.0003006, "br_status": 1, "br_x": 0.0004296, "f_bus": 7, "g_fr": -0.0, "g_to": -0.0, "index": 13, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 16, "tap": 1.0, "transformer": false}, "14": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.004654313561422283, "b_to": 0.004654313561422283, "br_r": 0.000613725, "br_status": 1, "br_x": 0.0008771, "f_bus": 12, "g_fr": -0.0, "g_to": -0.0, "index": 14, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 17, "tap": 1.0, "transformer": false}, "15": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.0012688000515535555, "b_to": 0.0012688000515535555, "br_r": 0.00255, "br_status": 1, "br_x": 0.00183, "f_bus": 15, "g_fr": -0.0, "g_to": -0.0, "index": 15, "rate_a": 20.26499444855586, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 18, "tap": 1.0, "transformer": false}, "16": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.0, "b_to": 0.0, "br_r": 6.4e-05, "br_status": 1, "br_x": 0.004800001352414809, "f_bus": 1, "g_fr": -0.0, "g_to": -0.0, "index": 16, "rate_a": 75.0, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.5235987755982988, "t_bus": 2, "tap": 1.0, "transformer": true}, "17": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.0, "b_to": 0.0, "br_r": 6.4e-05, "br_status": 1, "br_x": 0.004800001352414809, "f_bus": 1, "g_fr": -0.0, "g_to": -0.0, "index": 17, "rate_a": 75.0, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.5235987755982988, "t_bus": 13, "tap": 1.0, "transformer": true}, "2": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.04198380804384998, "b_to": 0.04198380804384998, "br_r": 0.00553605, "br_status": 1, "br_x": 0.0079118, "f_bus": 3, "g_fr": -0.0, "g_to": -0.0, "index": 2, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 4, "tap": 1.0, "transformer": false}, "3": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.005794145454015495, "b_to": 0.005794145454015495, "br_r": 0.000764025, "br_status": 1, "br_x": 0.0010919, "f_bus": 4, "g_fr": -0.0, "g_to": -0.0, "index": 3, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 5, "tap": 1.0, "transformer": false}, "4": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.005319215498768324, "b_to": 0.005319215498768324, "br_r": 0.0007014, "br_status": 1, "br_x": 0.0010024, "f_bus": 5, "g_fr": -0.0, "g_to": -0.0, "index": 4, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 6, "tap": 1.0, "transformer": false}, "5": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.014627842621612888, "b_to": 0.014627842621612888, "br_r": 0.00192885, "br_status": 1, "br_x": 0.0027566, "f_bus": 6, "g_fr": -0.0, "g_to": -0.0, "index": 5, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 7, "tap": 1.0, "transformer": false}, "6": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.015862660505255536, "b_to": 0.015862660505255536, "br_r": 0.002091675, "br_status": 1, "br_x": 0.0029893, "f_bus": 8, "g_fr": -0.0, "g_to": -0.0, "index": 6, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 9, "tap": 1.0, "transformer": false}, "7": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.003039551713581899, "b_to": 0.003039551713581899, "br_r": 0.0004008, "br_status": 1, "br_x": 0.0005727999999999999, "f_bus": 9, "g_fr": -0.0, "g_to": -0.0, "index": 7, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 10, "tap": 1.0, "transformer": false}, "8": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.007313921310806444, "b_to": 0.007313921310806444, "br_r": 0.000964425, "br_status": 1, "br_x": 0.0013783, "f_bus": 10, "g_fr": -0.0, "g_to": -0.0, "index": 8, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 11, "tap": 1.0, "transformer": false}, "9": {"angmax": 1.0471975511965976, "angmin": -1.0471975511965976, "b_fr": 0.0031345377046313335, "b_to": 0.0031345377046313335, "br_r": 0.00041332500000000003, "br_status": 1, "br_x": 0.0005907, "f_bus": 11, "g_fr": -0.0, "g_to": -0.0, "index": 9, "rate_a": 15.068842025849229, "rate_b": 250.0, "rate_c": 250.0, "shift": 0.0, "t_bus": 12, "tap": 1.0, "transformer": false}}, "bus": {"1": {"base_kv": 110.0, "bus_i": 1, "bus_type": 3, "index": 1, "va": 0.0, "vm": 1.03, "vmax": 1.03000001, "vmin": 1.02999999, "zone": 1}, "10": {"base_kv": 20.0, "bus_i": 10, "bus_type": 1, "index": 10, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "11": {"base_kv": 20.0, "bus_i": 11, "bus_type": 1, "index": 11, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "12": {"base_kv": 20.0, "bus_i": 12, "bus_type": 1, "index": 12, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "13": {"base_kv": 20.0, "bus_i": 13, "bus_type": 1, "index": 13, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "14": {"base_kv": 20.0, "bus_i": 14, "bus_type": 1, "index": 14, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "15": {"base_kv": 20.0, "bus_i": 15, "bus_type": 1, "index": 15, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "16": {"base_kv": 20.0, "bus_i": 16, "bus_type": 1, "index": 16, "va": 0.0, "vm": 1.0, "vmax": 1.1, "vmin": 0.9, "zone": 1}, "17": {"base_kv": 20.0, "bus_i": 17, "bus_type": 1, "index": 17, "va": 0.0, "vm": 1.0, "vmax": 1.1, "vmin": 0.9, "zone": 1}, "18": {"base_kv": 20.0, "bus_i": 18, "bus_type": 1, "index": 18, "va": 0.0, "vm": 1.0, "vmax": 1.1, "vmin": 0.9, "zone": 1}, "2": {"base_kv": 20.0, "bus_i": 2, "bus_type": 1, "index": 2, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "3": {"base_kv": 20.0, "bus_i": 3, "bus_type": 1, "index": 3, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "4": {"base_kv": 20.0, "bus_i": 4, "bus_type": 1, "index": 4, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "5": {"base_kv": 20.0, "bus_i": 5, "bus_type": 1, "index": 5, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "6": {"base_kv": 20.0, "bus_i": 6, "bus_type": 1, "index": 6, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "7": {"base_kv": 20.0, "bus_i": 7, "bus_type": 1, "index": 7, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "8": {"base_kv": 20.0, "bus_i": 8, "bus_type": 1, "index": 8, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}, "9": {"base_kv": 20.0, "bus_i": 9, "bus_type": 1, "index": 9, "va": 0.0, "vm": 1.0, "vmax": 1.2, "vmin": 0.8, "zone": 1}}, "correct_pm_network_data": true, "dcline": {}, "gen": {"1": {"cost": [0, 1.0, 0.0], "gen_bus": 1, "gen_status": 1, "index": 1, "model": 2, "ncost": 3, "pg": 0.0, "pmax": 10000.00000001, "pmin": -10000.00000001, "qg": 0.0, "qmax": 10000.00000001, "qmin": -10000.00000001, "shutdown": 0.0, "startup": 0.0, "vg": 1.03}, "10": {"cost": [0, 1.0, 0.0], "gen_bus": 8, "gen_status": 1, "index": 10, "model": 2, "ncost": 3, "pg": 10.350303552, "pmax": 10.35040706503552, "pmin": 10.350200038964479, "qg": 0.0, "qmax": 3.93600001, "qmin": -3.93600001, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "2": {"cost": [0, 1.0, 0.0], "gen_bus": 4, "gen_status": 1, "index": 2, "model": 2, "ncost": 3, "pg": 0.13800404736, "pmax": 0.13800543740047358, "pmin": 0.1380026573195264, "qg": 0.0, "qmax": 0.05248001000000001, "qmin": -0.05248001000000001, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "3": {"cost": [0, 1.0, 0.0], "gen_bus": 5, "gen_status": 1, "index": 3, "model": 2, "ncost": 3, "pg": 0.13800404736, "pmax": 0.13800543740047358, "pmin": 0.1380026573195264, "qg": 0.0, "qmax": 0.05248001000000001, "qmin": -0.05248001000000001, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "4": {"cost": [0, 1.0, 0.0], "gen_bus": 6, "gen_status": 1, "index": 4, "model": 2, "ncost": 3, "pg": 0.20700607104, "pmax": 0.20700815110071039, "pmin": 0.2070039909792896, "qg": 0.0, "qmax": 0.07872000999999999, "qmin": -0.07872000999999999, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "5": {"cost": [0, 1.0, 0.0], "gen_bus": 7, "gen_status": 1, "index": 5, "model": 2, "ncost": 3, "pg": 0.20700607104, "pmax": 0.20700815110071039, "pmin": 0.2070039909792896, "qg": 0.0, "qmax": 0.07872000999999999, "qmin": -0.07872000999999999, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "6": {"cost": [0, 1.0, 0.0], "gen_bus": 9, "gen_status": 1, "index": 6, "model": 2, "ncost": 3, "pg": 0.20700607104, "pmax": 0.20700815110071039, "pmin": 0.2070039909792896, "qg": 0.0, "qmax": 0.07872000999999999, "qmin": -0.07872000999999999, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "7": {"cost": [0, 1.0, 0.0], "gen_bus": 10, "gen_status": 1, "index": 7, "model": 2, "ncost": 3, "pg": 0.1598629404, "pmax": 0.15986454902940397, "pmin": 0.159861331770596, "qg": 0.0, "qmax": 0.07872000999999999, "qmin": -0.07872000999999999, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "8": {"cost": [0, 1.0, 0.0], "gen_bus": 11, "gen_status": 1, "index": 8, "model": 2, "ncost": 3, "pg": 0.2131505872, "pmax": 0.21315272870587199, "pmin": 0.213148445694128, "qg": 0.0, "qmax": 0.10496001, "qmin": -0.10496001, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}, "9": {"cost": [0, 1.0, 0.0], "gen_bus": 12, "gen_status": 1, "index": 9, "model": 2, "ncost": 3, "pg": 0.0532876468, "pmax": 0.053288189676468, "pmin": 0.053287103923531996, "qg": 0.0, "qmax": 0.026240010000000005, "qmin": -0.026240010000000005, "shutdown": 0.0, "startup": 0.0, "vg": 1.0}}, "load": {"1": {"index": 1, "load_bus": 2, "pd": 3.113519094, "qd": -0.443601099611376, "status": 1}, "10": {"index": 10, "load_bus": 15, "pd": 0.04330561605, "qd": -0.00761527849923, "status": 1}, "11": {"index": 11, "load_bus": 2, "pd": 1.006069095, "qd": -0.232020348184516, "status": 1}, "12": {"index": 12, "load_bus": 4, "pd": 0.04677338775, "qd": -0.020339063766402, "status": 1}, "13": {"index": 13, "load_bus": 8, "pd": 0.0158853015, "qd": -0.006907606562174, "status": 1}, "14": {"index": 14, "load_bus": 10, "pd": 0.11913976125, "qd": -0.051807049216306, "status": 1}, "15": {"index": 15, "load_bus": 11, "pd": 0.014120268, "qd": -0.006140094721933, "status": 1}, "16": {"index": 16, "load_bus": 13, "pd": 1.041577416, "qd": -0.240209301649852, "status": 1}, "17": {"index": 17, "load_bus": 14, "pd": 0.007060134, "qd": -0.003070047360966, "status": 1}, "18": {"index": 18, "load_bus": 15, "pd": 0.0688363065, "qd": -0.029932961769421, "status": 1}, "2": {"index": 2, "load_bus": 4, "pd": 0.05740511895, "qd": -0.01009467149898, "status": 1}, "3": {"index": 3, "load_bus": 5, "pd": 0.08963255415, "qd": -0.015761855498407, "status": 1}, "4": {"index": 4, "load_bus": 6, "pd": 0.1510661025, "qd": -0.026564924997315, "status": 1}, "5": {"index": 5, "load_bus": 7, "pd": 0.11380313055, "qd": -0.020012243497977, "status": 1}, "6": {"index": 6, "load_bus": 9, "pd": 0.12185998935, "qd": -0.021429039497834, "status": 1}, "7": {"index": 7, "load_bus": 11, "pd": 0.0986965203, "qd": -0.017355750998246, "status": 1}, "8": {"index": 8, "load_bus": 12, "pd": 0.0684832998, "qd": -0.012042765998783, "status": 1}, "9": {"index": 9, "load_bus": 13, "pd": 3.113519094, "qd": -0.443601099611376, "status": 1}}, "name": "", "ne_branch": {}, "per_unit": true, "pm_log_level": 0, "pm_mip_solver": "cbc", "pm_mip_time_limit": Infinity, "pm_model": "ACPPowerModel", "pm_nl_solver": "ipopt", "pm_nl_time_limit": Infinity, "pm_solver": "ipopt", "pm_time_limit": Infinity, "pm_tol": 1e-08, "shunt": {}, "silence": true, "source_version": "2.0.0", "sourcetype": "matpower", "storage": {}, "switch": {}, "user_defined_params": {"setpoint_q": {"1": {"element": "branch", "element_index": 1, "element_pp_index": 0, "f_bus": 2, "t_bus": 3, "value": 5.0}}, "side": {"1": {"element": "branch", "element_index": 1, "element_pp_index": 0, "value": "from"}}, "gen_and_controllable_sgen": {"2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10}}} \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 1a3c198..5ca8090 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -31,6 +31,7 @@ case_multi_vstab = joinpath(data_path, "cigre_with_timeseries.json") case_multi_qflex = joinpath(data_path, "test_mn_qflex.json") case_multi_storage = joinpath(data_path, "test_mn_storage.json") + @testset "PandaModels.jl" begin include("input.jl")