Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AC ROP fails if there is no ref-bus, but AC OPF works fine. #67

Open
noahrhodes opened this issue Nov 21, 2023 · 2 comments
Open

AC ROP fails if there is no ref-bus, but AC OPF works fine. #67

noahrhodes opened this issue Nov 21, 2023 · 2 comments

Comments

@noahrhodes
Copy link
Collaborator

When solving AC-ROP if there is no ref-bus (bustype==3) juniper will fail to solve the problem.

using PGLib, PowerModels, PowerModelsRestoration, Juniper, Ipopt
case = pglib("pglib_opf_case3_lmbd")
case["bus"]["1"]["bus_type"] = 2 # no ref bus
case["bus"]["2"]["bus_type"] = 2
case["bus"]["3"]["bus_type"] = 2
case["bus"]["1"]["damaged"] = 0 
case["bus"]["2"]["damaged"] = 1
case["bus"]["3"]["damaged"] = 1

case_mn = replicate_restoration_network(case, count_damaged_components(case))
julia> PowerModelsRestoration.run_rop(case_mn, ACPPowerModel, minlp_solver)
....
106r 7.4549345e+00 2.35e-04 1.72e+02  -7.0 7.34e-01    -  8.01e-01 6.62e-01h  1
 107r 9.7990705e+00 1.01e-04 2.19e+01  -7.0 5.53e-01    -  1.00e+00 9.38e-01h  1
 108r 1.1170669e+01 3.02e-05 2.67e-03  -7.0 3.22e-01    -  1.00e+00 1.00e+00h  1
Restoration phase converged to a feasible point that is
unacceptable to the filter for the original problem.
Restoration phase in the restoration phase failed.

Number of Iterations....: 108

                                   (scaled)                 (unscaled)
Objective...............:  -1.1328883119944665e+01    1.1328883119944665e+01
Dual infeasibility......:   3.9999993103033539e+01    3.9999993103033539e+01
Constraint violation....:   4.5380391761051797e-07    4.5380391761051797e-07
Variable bound violation:   5.6941909194847506e-09    5.6941909194847506e-09
Complementarity.........:   9.1147285638831260e-08    9.1147285638831260e-08
Overall NLP error.......:   3.9999993103033539e+01    3.9999993103033539e+01


Number of objective function evaluations             = 197
Number of objective gradient evaluations             = 92
Number of equality constraint evaluations            = 197
Number of inequality constraint evaluations          = 197
Number of equality constraint Jacobian evaluations   = 127
Number of inequality constraint Jacobian evaluations = 127
Number of Lagrangian Hessian evaluations             = 109
Total seconds in IPOPT                               = 0.339

EXIT: Restoration Failed!
    0       2                 -                          17.0               -     3.4       0         -

#branches: 1
Obj: NaN

This is not an issue for OPF

case = pglib("pglib_opf_case3_lmbd") # fails when there is not ref-bus
case["bus"]["1"]["bus_type"] = 2 # no ref-bus
case["bus"]["2"]["bus_type"] = 2 
case["bus"]["3"]["bus_type"] = 2

julia> run_opf(case, ACPPowerModel, minlp_solver)
...
EXIT: Optimal Solution Found.
Status of relaxation: LOCALLY_SOLVED
Time for relaxation: 0.1510000228881836
Relaxation Obj: 5812.64297227752
Obj: 5812.64297227752

Is there a particular reason for this issue related to NLP vs. MINLP problems?

This comes up as an issue when running cleanup of an rop solution for a followup optimization problem, where the bus_type might be overwritten, causing the subsequent optimization problem to fail.

PowerModelsRestoration.clean_status!(result_rop_ac["solution"]) # can overwrite the ref bus type
PowerModelsRestoration.update_status!(case, result_rop_ac["solution"]) # case now has no ref bus
@Robbybp
Copy link

Robbybp commented Nov 22, 2024

The lack of a reference bus is likely contributing to rank deficiency in the KKT matrix. For OPF, IPOPT's Hessian regularization is sufficient to converge. I don't know exactly what the ROP problem is, but along with the integer relaxation it is likely introducing additional rank deficiency (or otherwise incorrect inertia) into the KKT system, which throws off the interior point algorithm.

It's worth noting that returning the "Restoration Failed" status when the solver is at a feasible or almost-feasible point is borderline a bug in IPOPT. IMO IPOPT should have a "converged to feasible point" status that gets returned in situations like this.

@Robbybp
Copy link

Robbybp commented Nov 23, 2024

IMO IPOPT should have a "converged to feasible point" status that gets returned in situations like this.

I hacked this into the Ipopt MOI interface here. With this branch, the following code works for me (with lots of warnings):

using PGLib, PowerModels, PowerModelsRestoration, Juniper, Ipopt, JuMP
case = pglib("pglib_opf_case3_lmbd")
case["bus"]["1"]["bus_type"] = 2 # no ref bus
case["bus"]["2"]["bus_type"] = 2
case["bus"]["3"]["bus_type"] = 2
case["bus"]["1"]["damaged"] = 0 
case["bus"]["2"]["damaged"] = 1
case["bus"]["3"]["damaged"] = 1

case_mn = replicate_restoration_network(case, count_damaged_components(case))

nlp_solver = JuMP.optimizer_with_attributes(
    Ipopt.Optimizer,
    "linear_solver" => "ma27",
    "acceptable_tol" => 1e-3,
    "print_level" => 0,
)
minlp_solver = JuMP.optimizer_with_attributes(Juniper.Optimizer, "nl_solver" => nlp_solver)
PowerModelsRestoration.run_rop(case_mn, ACPPowerModel, minlp_solver)

Note that I had to turn down the tolerance to get this to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants