Newton solution from PowerModels.jl


I’m using PowerModels.jl to run some power flow studies and I’m interested in comparing the results obtained from the JuMP solution to the Newton solution. In most cases, those results are the same; however, when I make modifications on the power system (e.g. deleting a transmission line) and run Newton’s method, the flow on one branch of my system results in a much higher value when compared to JuMP’s solution. I’m using version 0.18.1 of PowerModels and my system has 10 buses.

This is the code I’m using to run this power flow study:

using PowerModels
using Ipopt

network_data = parse_file("/teste_novo.raw")

# ========================= Changes in the system =========================

# Open line 8-9 (branch 6):
delete!(network_data["branch"], "6")

# ========================= Newton solution =========================

result = compute_ac_pf(network_data)

# Check that the solver converged:
update_data!(network_data, result["solution"])

flows = calc_branch_flow_ac(network_data)
update_data!(network_data, flows)

Am I doing something wrong in this code for Newton’s method?

1 Like

Hi @Mariana, the work flow you are showing here looks reasonable. So I it is not clear what might be the problem to me. One question that does come to mind, when you speak of the “JuMP solution”, I presume you are referring to the output of a call to run_ac_pf?

Yes! In fact, I’m using the run_pf function as:

run_pf(network_data, ACPPowerModel, Ipopt.Optimizer)

Ok. It is not obvious to me why you would see different results in these two cases. It is possible the two approaches have converged to different feasible flow solutions, but this is very rare in my experience. This kind of workflow can be used to test the feasibility of a given power flow solution,

If you find there are very large power imbalances this might be a bug in PowerModels, but I would need a detailed example to confirm and fix it, if that is the case.

1 Like

@ccoffrin sorry for the late response! I followed the workflow you posted and, in order to eliminate branch 6 of my system, I ran the following code:

@testset "test 3" begin
    data = PowerModels.parse_file("/teste_novo.raw")
    data["branch"]["6"]["br_status"] = 0
    result = compute_ac_pf(data)
    #result = run_pf(data, ACPPowerModel, Ipopt.Optimizer)
    PowerModels.update_data!(data, result["solution"])

    flows = PowerModels.calc_branch_flow_ac(data)
    PowerModels.update_data!(data, flows)

    balance = PowerModels.calc_power_balance(data)

    for (i,bus) in balance["bus"]
        @test isapprox(bus["p_delta"], 0.0; atol=1e-6)
        @test isapprox(bus["q_delta"], 0.0; atol=1e-6)

All the 20 tests pass when I use the run_pf function; however, when I use the compute_ac_pf function, 16 tests pass and 4 fail.

Am I doing something wrong?

I would start by checking the status value in result to see if compute_ac_pf belives it has converged or not. You can also pass NLsolve keyword arguments to compute_ac_pf to control the options of that solver.

I will also point you to this documentation about the different power flow models that are available in PowerModels,

compute_ac_pf is not expected to be as reliable as run_ac_pf using a solver like Ipopt.

1 Like

@ccoffrin thank you very much for your answers! I tried the workflow you suggested to check the feasibility of the solution with different power systems and all tests passed, so I guess I was using an ill-conditioned system. Just to confirm: the PowerModels.calc_power_balance function works by checking if Kirchhoff’s Law is satisfied in all the buses of the system, right?

1 Like

Another question: could you explain, or point to some documentation, how PowerModels.jl solve power flows with multiple reference buses? My system has 9 buses, and 2 reference buses. When I run run_ac_pf and compute_ac_pf I get the same results, but they are different than the ones I obtained from another power flow software.

Yes that is correct. By default it does not calculate the branch flow values so before calling calc_power_balance you should make sure the branch flows have been computed using the latest version of the voltage profile.

I am not aware of how other software treats multiple reference buses, so I am not surprised there may be some differences here.

In the case of compute_ac_pf I think this should produce an error or warning message. If not, please post an issue.

For run_ac_pf PowerModels will build one JuMP model that has two PowerFlow models inside of it. As long as they are mathematically well formed it should converge. Typically “mathematically well formed” AC Power Flow requires that there is exactly one reference bus per connected component in the network. The function correct_bus_types! can be used to check and prepare a given network data for Power Flow solving.

1 Like

Hi @ccoffrin!

I think since 0.3.4 the code is generic for any number of reference buses when running AC Power Flow. If more than one reference is given, the angle of the multiple references buses are set to zero. I also don’t know how other softwares treat this feature.

Currently, correct_bus_types! only checks if there is an active generator in each given reference bus, but it does not limit the number of ref buses to one.

1 Like

This is correct, thanks for that clarification @iagoschavarry!

In the case of run_ac_pf you are correct. compute_ac_pf is a relatively new feature that solves an AC power flow without building a JuMP model, so its functionalities are more limited. You can see in this test script that multiple slack buses are currently not supported.

Right, @ccoffrin! Thanks for the response.

I tried to follow the begin-to-end code of compute_ac_pf.

In 0.18.2 it seems that this function is also generic to any numbers of reference buses. Although, this appers to be a recent feature, added in the 0.18.0 update.

Before that, 0.17.4 for example, compute_ac_pf calls calc_admittance_matrix which calls reference_bus. The last function checks if there is more than one reference bus in the network data.
Since 0.18.0, reference_bus is no longer called in calc_admittance_matrix, therefore no warnings or errors are given when multiple references buses are used in compute_ac_pf.

I guess this wasn’t a intended feature then? In our studies, calling compute_ac_pf and run_ac_pf with mutiple reference buses in a small network data (10 buses) resulted approximately in the same outcome.