# Ipopt solves large-scale nonlinear problems

**URL:** https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831
**Category:** Optimization (Mathematical)
**Tags:** nlp
**Created:** [May 14, 2023, 11:17am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831 "2023-05-14T11:17:28Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 14, 2023, 11:17am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/1 "2023-05-14T11:17:29Z")

</div>

I’m new to Julia, I’m working on optimal power flow problems in the direction of power systems, and when solving large-scale problems with Julia (there are thousands of variables and constraints, of course, most of them are the same), I run out of memory and don’t know how to solve it

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [May 14, 2023, 1:08pm UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/2 "2023-05-14T13:08:03Z")

</div>

Is the problem sparse? If so, are you making use of sparse arrays to define the problem? The Hessian of the lagrangian and the constraint Jacobian are often sparse for such large problems, and using sparse matrices is then important for performance.

---

<div class="post-metadata">

### Author: ![ccoffrin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ccoffrin/32/400_2.png) [@ccoffrin](https://discourse.julialang.org/u/ccoffrin)
#### Post date: [May 14, 2023, 2:15pm UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/3 "2023-05-14T14:15:38Z")

</div>

I think you will find this post interesting,

> [@AC Optimal Power Flow in Various Nonlinear Optimization Frameworks](https://discourse.julialang.org/t/ac-optimal-power-flow-in-various-nonlinear-optimization-frameworks/78486/2):
>
> You forgot to add constraints slight_smile I will look into the Zygote issue. Nonconvex uses l-BFGS Ipopt by default which explains the Hessian.

And this talk,

[![](https://global.discourse-cdn.com/julialang/original/3X/d/5/d5a2c72743cbbed33e3cf52df9e543495bab8d0c.jpeg "Benchmarking Nonlinear Optimization with AC Optimal Power Flow | Carleton Coffrin | JuliaCon 2022") ](https://www.youtube.com/watch?v=tvBNQcuU-hY)

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 15, 2023, 12:14am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/4 "2023-05-15T00:14:15Z")

</div>

The problem is sparse, but I don’t know how to modify and invoke it in Ipopt, and I always thought that in Julia, ipopt would be able to create and process sparse matrices on its own based on the model I provided

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [May 15, 2023, 12:46am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/5 "2023-05-15T00:46:34Z")

</div>

If you use JuMP or PowerModels, we do create sparse Jacobians and Hessians. See the benchmarks mentioned by Carleton. You can scale Ipopt to 10^5 and 10^6 variables and constraints on a laptop for optimal power flow.

If you still have trouble, it would be useful if you provided a reproducible example of exactly how you’re setting up and solving your models.

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 15, 2023, 1:43am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/6 "2023-05-15T01:43:18Z")

</div>

I’m not quite sure where benchmarks should look. I’m researching the most basic ACOPF model, and below is my code, which would be very grateful if you could provide me with some valuable input

```julia
using DataFrames
using CSV
using JuMP, Ipopt,Pardiso

mpc = CSV.read("E:\\RTS\\CSV_data\\case118.csv", header=false,DataFrame) # return DataFrame
bus_data_row = findfirst(x -> x == "bus data", mpc[:, 1])[1]
gen_data_row = findfirst(x -> x == "gen data", mpc[:, 1])[1]
branch_data_row = findfirst(x -> x == "branch data", mpc[:, 1])[1]
gencost_data_row = findfirst(x -> x == "gencost data", mpc[:, 1])[1]
baseMVA_row = findfirst(x -> x == "baseMVA", mpc[:, 1])[1]
baseMVA = parse(Int, mpc[baseMVA_row+1,1])
bus_num = gen_data_row -bus_data_row-2
gen_num = branch_data_row -gen_data_row -2
branch_num = gencost_data_row-branch_data_row -2

bus_i = parse.(Int,mpc[3:bus_num+2,1])   
bus_type = parse.(Int,mpc[3:bus_num+2,2])
bus_Pd =parse.(Float64,mpc[3:bus_num+2,3] )/baseMVA
bus_Qd =parse.(Float64,mpc[3:bus_num+2,4] )/baseMVA
bus_Gs =parse.(ComplexF64,mpc[3:bus_num+2,5])/baseMVA
bus_Bs =parse.(ComplexF64,mpc[3:bus_num+2,6])/baseMVA
bus_Vmax =parse.(Float64,mpc[3:bus_num+2,12])
bus_Vmin =parse.(Float64,mpc[3:bus_num+2,13])
balance_bus = findall(bus_type .== 3)[1]
bus_Omax = fill(2*pi, bus_num)
bus_Omax[balance_bus] = 0
bus_Omin = fill(-2*pi, bus_num)
bus_Omin[balance_bus] = 0

gen_bus = parse.(Int,mpc[gen_data_row+2:gen_data_row+gen_num+1,1])
gen_PG = parse.(Float64,mpc[gen_data_row+2:gen_data_row+gen_num+1,2])
gen_QG = parse.(Float64,mpc[gen_data_row+2:gen_data_row+gen_num+1,3])
gen_Qmax = parse.(Float64,mpc[gen_data_row+2:gen_data_row+gen_num+1,4])
gen_Qmin = parse.(Float64,mpc[gen_data_row+2:gen_data_row+gen_num+1,5])
g_status = parse.(Int,mpc[gen_data_row+2:gen_data_row+gen_num+1,8])
gen_Pmax = parse.(Float64,mpc[gen_data_row+2:gen_data_row+gen_num+1,9])
gen_Pmin= parse.(Float64,mpc[gen_data_row+2:gen_data_row+gen_num+1,10])
gencost_cs = parse.(Float64,mpc[gencost_data_row+2:gencost_data_row+gen_num+1,7])
gencost_yc = parse.(Float64,mpc[gencost_data_row+2:gencost_data_row+gen_num+1,6])
gencost_ec = parse.(Float64,mpc[gencost_data_row+2:gencost_data_row+gen_num+1,5])
##############################################################################
gstart_num = count(x -> x == 1, g_status)
gen_on_bus = [gen_bus[i] for i in eachindex(g_status) if g_status[i] != 0]
gon_PG = [gen_PG[i] for i in eachindex(g_status) if g_status[i] != 0]/baseMVA
gon_QG = [gen_QG[i] for i in eachindex(g_status) if g_status[i] != 0]/baseMVA
gon_Qmax = [gen_Qmax[i] for i in eachindex(g_status) if g_status[i] != 0]/baseMVA
gon_Qmin = [gen_Qmin[i] for i in eachindex(g_status) if g_status[i] != 0]/baseMVA
gon_Pmax = [gen_Pmax[i] for i in eachindex(g_status) if g_status[i] != 0]/baseMVA
gon_Pmin = [gen_Pmin[i] for i in eachindex(g_status) if g_status[i] != 0]/baseMVA
goncost_cs = [gencost_cs[i] for i in eachindex(g_status) if g_status[i] != 0]
goncost_yc = [gencost_yc[i] for i in eachindex(g_status) if g_status[i] != 0]*baseMVA
goncost_ec = [gencost_ec[i] for i in eachindex(g_status) if g_status[i] != 0]*baseMVA^2
##############################################################################
ybranch_fbus = parse.(Int,mpc[branch_data_row+2:branch_data_row+branch_num+1,1])
ybranch_tbus = parse.(Int,mpc[branch_data_row+2:branch_data_row+branch_num+1,2])
branch_fbus =zeros(Int,length(ybranch_fbus))
branch_tbus =zeros(Int,length(ybranch_tbus))
for i in 1:branch_num
    branch_fbus[i] = findall(bus_i .== ybranch_fbus[i])[1] 
    branch_tbus[i] = findall(bus_i .== ybranch_tbus[i])[1] 
end  
branch_r = parse.(ComplexF64,mpc[branch_data_row+2:branch_data_row+branch_num+1,3])
branch_x = parse.(ComplexF64,mpc[branch_data_row+2:branch_data_row+branch_num+1,4])
branch_b = parse.(ComplexF64,mpc[branch_data_row+2:branch_data_row+branch_num+1,5])
branch_rate = parse.(Float64,mpc[branch_data_row+2:branch_data_row+branch_num+1,6])/baseMVA
branch_ratio = parse.(Float64,mpc[branch_data_row+2:branch_data_row+branch_num+1,9])
branch_ratio =[if x == 0 1 else x end for x in branch_ratio]   
branch_status =mpc[branch_data_row+2:branch_data_row+branch_num+1,11]

#Node admittance matrix
Y = zeros(ComplexF64,bus_num, bus_num)
for k in 1:branch_num
    k1 = branch_fbus[k]
    k2 = branch_tbus[k]
    Y[k1, k2] -= 1 / ((branch_r[k] + im*branch_x[k])* branch_ratio[k])
    Y[k2, k1] = Y[k1, k2]
    Y[k1, k1] += 1 / ((branch_r[k] + im*branch_x[k]) * branch_ratio[k] ^ 2) + im*branch_b[k]/2
    Y[k2, k2] += 1 / (branch_r[k] + im*branch_x[k]) + im*branch_b[k]/2
end

for u in 1:bus_num
    if bus_Gs[u] != 0 || bus_Bs[u] != 0
        Y[u, u] += bus_Gs[u] + bus_Bs[u] * im
    end
end
G = real(Y)
B = imag(Y)

################Branch admittance matrix#################
y = zeros(ComplexF64, branch_num, 2)
for i in 1:branch_num
    y[i, 1] = 1 / ((branch_r[i] + im*branch_x[i]) * branch_ratio[i])
    y[i, 2] = y[i, 1]
end
g = real(y) 
b = imag(y)

#################Yijo = Yi0+Yij############
Yijo = zeros(ComplexF64, branch_num, 2)
for l in 1:branch_num
    if branch_ratio[l] == 1
        Yijo[l, 1] = im*branch_b[l]/2 + 1/((branch_r[l] + im*branch_x[l])* branch_ratio[l])  
        Yijo[l, 2] = Yijo[l, 1]
    else
        Yijo[l, 1] = 1 /((branch_r[l] + im*branch_x[l]) * branch_ratio[l] ^ 2 ) 
        Yijo[l, 2] = 1 /(branch_r[l] + im*branch_x[l])
    end
end

for u in 1:branch_num
    k1 = branch_fbus[u]
    k2 = branch_tbus[u]
    if bus_Gs[k1] != 0 || bus_Bs[k1] != 0 || bus_Gs[k2] != 0 || bus_Bs[k2] != 0
        Yijo[u, 1] += bus_Gs[k1] + bus_Bs[k1]*im
        Yijo[u, 2] += bus_Gs[k2] + bus_Bs[k2]*im
    end
end
Gijo = real(Yijo)
Bijo = imag(Yijo)

######################################################################
# Create model objects
model = Model(
    optimizer_with_attributes(
        Ipopt.Optimizer,
        "print_level" => 4

        )
        )

# Define decision variables
@variable(model, V[1:bus_num])
@variable(model, O[1:bus_num])
@variable(model, PG[1:gstart_num])
@variable(model, QG[1:gstart_num])

# Define the objective function
OPF_Object =sum(goncost_ec[i]*PG[i]^2+goncost_yc[i]*PG[i]+goncost_cs[i] for i in 1:gstart_num)
@objective(model, Min, OPF_Object)

# Define constraints
# local t = 0
for i in 1:bus_num
    if bus_i[i] in gen_on_bus #Generator node
        local q = findall(gen_on_bus .== bus_i[i]) 
        @NLconstraint(model, sum(PG[j] for j in q)-bus_Pd[i]-V[i]^2*G[i,i]-V[i]*sum(V[j]*(G[i,j]*cos(O[i]-O[j])+B[i,j]*sin(O[i]-O[j])) for j in 1:bus_num if j!=i) == 0)
        @NLconstraint(model, sum(QG[j] for j in q)-bus_Qd[i]+V[i]^2*B[i,i]-V[i]*sum(V[j]*(G[i,j]*sin(O[i]-O[j])-B[i,j]*cos(O[i]-O[j])) for j in 1:bus_num if j!=i) == 0)
    else #Non-generator nodes
        @NLconstraint(model, -bus_Pd[i]-V[i]^2*G[i,i]-V[i]*sum(V[j]*(G[i,j]*cos(O[i]-O[j])+B[i,j]*sin(O[i]-O[j])) for j in 1:bus_num if j!=i) == 0)
        @NLconstraint(model, -bus_Qd[i]+V[i]^2*B[i,i]-V[i]*sum(V[j]*(G[i,j]*sin(O[i]-O[j])-B[i,j]*cos(O[i]-O[j])) for j in 1:bus_num if j!=i) == 0)
    end
end

#Line constraints
for i in 1:branch_num
    if branch_rate[i] !=0
        local p = branch_fbus[i]
        local q = branch_tbus[i]
        @NLconstraint(model, -branch_rate[i]<=Gijo[i,1]*V[p]^2-V[p]*V[q]*(g[i,1]*cos(O[p]-O[q])+b[i,1]*sin(O[p]-O[q]))<=branch_rate[i])
        @NLconstraint(model, -branch_rate[i]<=Gijo[i,2]*V[q]^2-V[p]*V[q]*(g[i,2]*cos(O[q]-O[p])+b[i,2]*sin(O[q]-O[p]))<=branch_rate[i])
    end
end   

#Variable constraints
for i in 1:bus_num
    @NLconstraint(model,bus_Vmin[i]<=V[i]<=bus_Vmax[i])
    @NLconstraint(model,bus_Omin[i]<=O[i]<=bus_Omax[i])
end
for i in 1:gstart_num
    @NLconstraint(model,gon_Pmin[i]<=PG[i]<=gon_Pmax[i])
    @NLconstraint(model,gon_Qmin[i]<=QG[i]<=gon_Qmax[i])
end

# Set the initial value
for i in 1:bus_num
    set_start_value(V[i], 1)
    set_start_value(O[i], 0)
end 
for i in 1:gstart_num
    set_start_value(PG[i], gon_PG[i])
    set_start_value(QG[i], gon_QG[i])
end 

# Solve optimization problems
optimize!(model)

println("Optimal objective value: ", JuMP.objective_value(model))

```

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [May 15, 2023, 1:59am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/7 "2023-05-15T01:59:17Z")

</div>

I can’t run your code because I don’t have the `.csv`. The main thing I’d change with your code would be:

```plaintext
# Define decision variables
@variable(model, bus_Vmin[i] <= V[i=1:bus_num] <= bus_Vmax[i])
@variable(model, bus_Omin[i] <= O[i=1:bus_num] <= bus_Omax[i])
@variable(model, gon_Pmin[i] <= PG[i=1:gstart_num] <= gon_Pmax[i])
@variable(model, gon_Qmin[i] <= QG[i=1:gstart_num] <= gon_Qmax[i])

```

and delete the `#Variable constraints` blocks. My way adds variable bounds. Your way adds new rows to the constraint matrix.

Have you considered using PowerModels.jl? [GitHub - lanl-ansi/PowerModels.jl: A Julia/JuMP Package for Power Network Optimization](https://github.com/lanl-ansi/PowerModels.jl)

You should also take a look at @ccoffrin’s `rosetta-opf` project: [rosetta-opf/jump.jl at main · lanl-ansi/rosetta-opf · GitHub](https://github.com/lanl-ansi/rosetta-opf/blob/main/jump.jl)

If you’re just wanting to solve problems, there are plenty of examples in the PowerModels documentation: [Getting Started · PowerModels](https://lanl-ansi.github.io/PowerModels.jl/stable/quickguide/).

If you want to build a JuMP model of the formulation and then do stuff to it, you can use:

```julia
using JuMP, PowerModels, Ipopt
download(
    "https://raw.githubusercontent.com/power-grid-lib/pglib-opf/master/pglib_opf_case118_ieee.m",
    "pglib_opf_case118_ieee.m",
)
model = Model(Ipopt.Optimizer)
power_model = PowerModels.instantiate_model(
    PowerModels.parse_file("pglib_opf_case118_ieee.m"),
    PowerModels.ACPPowerModel,
    PowerModels.build_opf;
    jump_model = model,
)
optimize!(model)

```

On my laptop, this solves in 0.4 seconds:

```plaintext
julia> optimize!(model)
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...: 4552
Number of nonzeros in inequality constraint Jacobian.: 1460
Number of nonzeros in Lagrangian Hessian.............: 8198

Total number of variables............................: 1053
                     variables with only lower bounds: 0
                variables with lower and upper bounds: 935
                     variables with only upper bounds: 0
Total number of equality constraints.................: 981
Total number of inequality constraints...............: 730
        inequality constraints with only lower bounds: 179
   inequality constraints with lower and upper bounds: 0
        inequality constraints with only upper bounds: 551

iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
   0 4.7812282e+02 2.76e+00 2.19e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
   1 3.4413674e+04 2.00e+00 7.98e+01 -1.0 2.86e+00 - 3.58e-03 2.74e-01h 1
   2 3.5528977e+04 1.90e+00 7.55e+01 -1.0 6.95e+00 - 8.37e-02 5.16e-02h 1
   3 3.6121278e+04 1.78e+00 6.94e+01 -1.0 9.60e+00 - 2.78e-01 6.39e-02h 1
   4 4.3035932e+04 1.56e+00 6.06e+01 -1.0 5.99e+00 - 3.79e-01 1.25e-01h 1
   5 6.1165471e+04 9.99e-01 3.88e+01 -1.0 6.58e+00 - 5.19e-01 3.58e-01h 1
   6 7.0545871e+04 7.30e-01 3.17e+01 -1.0 8.66e+00 - 5.33e-01 2.69e-01h 1
   7 8.3787955e+04 3.59e-01 2.24e+01 -1.0 1.00e+01 - 9.37e-01 5.08e-01h 1
   8 9.0768955e+04 1.66e-01 8.62e+00 -1.0 1.30e+01 - 2.12e-01 5.38e-01h 1
   9 9.2115541e+04 1.22e-01 9.08e+00 -1.0 1.78e+01 - 8.00e-01 2.67e-01h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
  10 9.4118086e+04 7.71e-02 5.72e+00 -1.0 8.50e+00 - 2.88e-01 3.66e-01h 1
  11 9.7131618e+04 1.91e-02 1.64e+00 -1.0 3.65e+00 - 1.00e+00 8.42e-01h 1
  12 9.7745336e+04 1.85e-03 6.29e+01 -1.0 4.66e+00 - 2.24e-01 1.00e+00H 1
  13 9.7687599e+04 7.47e-03 7.32e+00 -1.0 2.01e+00 - 1.00e+00 1.00e+00f 1
  14 9.7695486e+04 4.71e-04 1.96e-01 -1.0 7.26e-01 - 1.00e+00 1.00e+00h 1
  15 9.7487469e+04 4.57e-03 1.23e+00 -2.5 5.77e+00 - 7.89e-01 5.54e-01f 1
  16 9.7309870e+04 2.44e-03 2.29e-01 -2.5 1.86e+00 - 7.38e-01 7.83e-01f 1
  17 9.7248611e+04 2.04e-03 1.10e+00 -2.5 2.50e+00 - 9.51e-01 7.64e-01h 1
  18 9.7231319e+04 1.11e-03 1.34e-02 -2.5 9.23e-01 - 1.00e+00 1.00e+00h 1
  19 9.7233035e+04 2.49e-06 8.98e-05 -2.5 5.66e-02 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
  20 9.7219104e+04 2.56e-04 1.84e-01 -3.8 6.46e-01 - 8.60e-01 7.15e-01f 1
  21 9.7214346e+04 6.81e-05 1.40e-01 -3.8 1.78e-01 - 8.75e-01 1.00e+00h 1
  22 9.7214571e+04 4.67e-06 1.27e-04 -3.8 2.43e-02 - 1.00e+00 1.00e+00h 1
  23 9.7213705e+04 6.33e-06 3.71e-03 -5.7 3.15e-02 - 9.22e-01 9.07e-01h 1
  24 9.7213619e+04 7.25e-07 2.59e-05 -5.7 7.28e-03 - 1.00e+00 1.00e+00h 1
  25 9.7213619e+04 1.13e-07 5.09e-06 -5.7 3.18e-03 - 1.00e+00 1.00e+00h 1
  26 9.7213607e+04 4.76e-08 3.72e-05 -8.6 2.04e-03 - 9.88e-01 1.00e+00h 1
  27 9.7213607e+04 1.05e-08 4.75e-07 -8.6 9.70e-04 - 1.00e+00 1.00e+00h 1
  28 9.7213607e+04 1.93e-09 8.74e-08 -8.6 4.15e-04 - 1.00e+00 1.00e+00h 1
  29 9.7213607e+04 1.51e-10 6.86e-09 -8.6 1.16e-04 - 1.00e+00 1.00e+00h 1

Number of Iterations....: 29

                                   (scaled) (unscaled)
Objective...............: 7.8032097059689613e+02 9.7213606938959332e+04
Dual infeasibility......: 6.8594320180172386e-09 8.5455876895626375e-07
Constraint violation....: 1.5122502902698010e-10 1.5122502902698010e-10
Variable bound violation: 6.5043916031015669e-08 6.5043916031015669e-08
Complementarity.........: 6.1117630289071873e-09 7.6141299693863464e-07
Overall NLP error.......: 6.8594320180172386e-09 8.5455876895626375e-07

Number of objective function evaluations = 31
Number of objective gradient evaluations = 30
Number of equality constraint evaluations = 31
Number of inequality constraint evaluations = 31
Number of equality constraint Jacobian evaluations = 30
Number of inequality constraint Jacobian evaluations = 30
Number of Lagrangian Hessian evaluations = 29
Total seconds in IPOPT = 0.370

EXIT: Optimal Solution Found.

```

You can find other cases at [GitHub - power-grid-lib/pglib-opf: Benchmarks for the Optimal Power Flow Problem](https://github.com/power-grid-lib/pglib-opf)

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 15, 2023, 2:51am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/8 "2023-05-15T02:51:05Z")

</div>

Thank you very much for your help, my code does have shortcomings, I also tried to run the PowerModels you mentioned and it worked

```julia
using JuMP, PowerModels, Ipopt
download(
    "https://raw.githubusercontent.com/power-grid-lib/pglib-opf/master/pglib_opf_case2736sp_k.m",
    "pglib_opf_case2736sp_k__api.m",
)
model = Model(Ipopt.Optimizer)
power_model = PowerModels.instantiate_model(
    PowerModels.parse_file("pglib_opf_case2736sp_k__api.m"),
    PowerModels.ACPPowerModel,
    PowerModels.build_opf;
    jump_model = model,
)
optimize!(model)
println("Optimal objective value: ", JuMP.objective_value(model))

```

Here is the result of my output

```julia
This is Ipopt version 3.13.4, running with linear solver mumps.
NOTE: Other linear solvers might be more efficient (see Ipopt documentation).

Number of nonzeros in equality constraint Jacobian...: 78762
Number of nonzeros in inequality constraint Jacobian.: 26128
Number of nonzeros in Lagrangian Hessian.............: 143837

Total number of variables............................: 18852
                     variables with only lower bounds: 0
                variables with lower and upper bounds: 16116
                     variables with only upper bounds: 0
Total number of equality constraints.................: 18549
Total number of inequality constraints...............: 13064
        inequality constraints with only lower bounds: 3263
   inequality constraints with lower and upper bounds: 0
        inequality constraints with only upper bounds: 9801

iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
   0 9.5127271e+05 7.87e+00 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
   1 9.5469096e+05 7.79e+00 9.89e+01 -1.0 5.30e+00 - 6.92e-03 1.00e-02h 1
   2 9.5073275e+05 7.68e+00 9.81e+01 -1.0 1.65e+01 - 2.31e-03 1.42e-02f 1
   3 9.4740076e+05 7.56e+00 9.48e+01 -1.0 1.48e+01 - 3.95e-02 1.63e-02f 1
   4 9.4701858e+05 6.93e+00 8.21e+01 -1.0 9.56e+00 - 1.50e-01 8.32e-02f 1
   5 9.4725378e+05 6.41e+00 7.33e+01 -1.0 3.00e+01 - 1.37e-01 7.44e-02f 1
   6 9.4770877e+05 6.30e+00 7.66e+01 -1.0 4.81e+01 - 4.01e-02 1.82e-02h 1
   7 9.6460459e+05 5.94e+00 6.06e+01 -1.0 1.71e+01 - 4.50e-04 5.65e-02h 1
   8 9.8599397e+05 5.48e+00 5.58e+01 -1.0 1.97e+01 - 4.35e-02 7.80e-02h 1
   9 1.0047233e+06 5.08e+00 5.15e+01 -1.0 2.22e+01 - 3.91e-02 7.21e-02h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
  10 1.0184715e+06 4.81e+00 4.88e+01 -1.0 2.21e+01 - 6.14e-02 5.45e-02h 1
  11 1.0354602e+06 4.50e+00 4.48e+01 -1.0 2.11e+01 - 2.40e-02 6.27e-02h 1
  12 1.1000420e+06 3.36e+00 3.30e+01 -1.0 2.59e+01 - 3.03e-02 2.55e-01h 1
  13 1.1207195e+06 3.00e+00 2.94e+01 -1.0 2.19e+01 - 1.37e-01 1.06e-01h 1
  14 1.1473702e+06 2.56e+00 2.51e+01 -1.0 1.74e+01 - 1.30e-01 1.49e-01h 1
  15 1.1718054e+06 2.16e+00 2.11e+01 -1.0 1.22e+01 - 2.24e-01 1.56e-01h 1
  16 1.2179292e+06 1.42e+00 1.40e+01 -1.0 1.17e+01 - 2.55e-01 3.44e-01h 1
  17 1.2462822e+06 9.74e-01 9.86e+00 -1.0 9.13e+00 - 5.15e-01 3.12e-01h 1
  18 1.2628349e+06 7.23e-01 9.08e+00 -1.0 6.47e+00 - 4.00e-01 2.58e-01h 1
  19 1.2968734e+06 2.15e-01 1.12e+01 -1.0 7.15e+00 - 9.91e-01 7.02e-01h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
  20 1.3105249e+06 1.73e-02 3.45e+00 -1.0 2.23e+00 - 1.00e+00 9.20e-01h 1
  21 1.3117980e+06 8.26e-05 3.24e-02 -1.0 3.58e-01 - 1.00e+00 1.00e+00h 1
  22 1.3109731e+06 6.05e-04 1.18e+01 -2.5 9.02e-01 - 6.56e-01 5.72e-01f 1
  23 1.3099179e+06 2.55e-03 3.75e+00 -2.5 7.06e-01 - 2.45e-01 7.33e-01f 1
  24 1.3089933e+06 2.59e-03 1.62e+00 -2.5 3.43e-01 - 6.00e-01 8.98e-01f 1
  25 1.3085161e+06 1.71e-03 4.04e+00 -2.5 1.84e-01 - 2.80e-01 5.64e-01f 1
  26 1.3083348e+06 1.14e-03 7.77e+00 -2.5 3.12e-01 - 9.47e-01 3.89e-01f 1
  27 1.3082912e+06 9.33e-04 2.59e+01 -2.5 3.16e-01 - 1.00e+00 1.78e-01h 1
  28 1.3081319e+06 5.77e-04 3.64e+01 -2.5 2.42e-01 - 1.62e-01 9.66e-01f 1
  29 1.3081541e+06 3.35e-05 1.30e-02 -2.5 9.10e-02 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
  30 1.3081003e+06 6.51e-05 2.75e+01 -3.8 1.80e-01 - 6.77e-01 3.07e-01f 1
  31 1.3080502e+06 1.95e-04 2.29e+01 -3.8 1.97e-01 - 7.50e-01 5.09e-01f 1
  32 1.3080315e+06 1.65e-04 1.62e+01 -3.8 1.74e-01 - 9.40e-01 5.14e-01h 1
  33 1.3080210e+06 9.02e-05 6.38e+00 -3.8 1.26e-01 - 1.00e+00 7.83e-01h 1
  34 1.3080197e+06 5.43e-06 2.19e-04 -3.8 3.17e-02 - 1.00e+00 1.00e+00h 1
  35 1.3080166e+06 7.57e-06 2.29e+00 -5.7 1.09e-01 - 8.60e-01 6.40e-01h 1
  36 1.3080154e+06 5.62e-06 1.72e+00 -5.7 1.01e-01 - 9.22e-01 7.20e-01h 1
  37 1.3080150e+06 1.70e-06 1.91e-02 -5.7 5.09e-02 - 1.00e+00 9.91e-01h 1
  38 1.3080150e+06 2.89e-08 8.45e-07 -5.7 3.68e-03 - 1.00e+00 1.00e+00h 1
  39 1.3080150e+06 1.85e-08 3.48e-02 -8.6 4.85e-03 - 8.25e-01 9.73e-01h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
  40 1.3080150e+06 1.16e-09 5.34e-04 -8.6 1.05e-03 - 9.88e-01 1.00e+00h 1
  41 1.3080150e+06 2.67e-11 5.68e-09 -8.6 4.31e-05 - 1.00e+00 1.00e+00h 1

Number of Iterations....: 41

                                   (scaled) (unscaled)
Objective...............: 1.1275019335795156e+04 1.3080149931455960e+06
Dual infeasibility......: 5.6835424466209047e-09 6.5934775923249118e-07
Constraint violation....: 2.6710969373844318e-11 2.6710969373844318e-11
Complementarity.........: 5.5561117961707670e-09 6.4456452947377074e-07
Overall NLP error.......: 5.6835424466209047e-09 6.5934775923249118e-07

Number of objective function evaluations = 42
Number of objective gradient evaluations = 42
Number of equality constraint evaluations = 42
Number of inequality constraint evaluations = 42
Number of equality constraint Jacobian evaluations = 42
Number of inequality constraint Jacobian evaluations = 42
Number of Lagrangian Hessian evaluations = 41
Total CPU secs in IPOPT (w/o function evaluations) = 4.523
Total CPU secs in NLP function evaluations = 1.397

EXIT: Optimal Solution Found.
Optimal objective value: 1.308014993145596e6

```

This result is consistent with the MATPOWER result，but what I wanted to do was how to add some new constraints and variables to the original OPF model, which has been bothering me for a long time, but I see hope in PowerModels。

---

<div class="post-metadata">

### Author: ![ccoffrin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ccoffrin/32/400_2.png) [@ccoffrin](https://discourse.julialang.org/u/ccoffrin)
#### Post date: [May 15, 2023, 3:34am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/9 "2023-05-15T03:34:34Z")

</div>

`download(...)` is a tool that I did not know about until this post. Thanks for the tip @odow. If you want an even more Julia friendly version of PGLib data there is this package,

> **[GitHub - noahrhodes/PGLib.jl](https://github.com/noahrhodes/PGLib.jl)**
>
> Contribute to noahrhodes/PGLib.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [May 15, 2023, 6:40am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/10 "2023-05-15T06:40:38Z")

</div>

See [PowerModelsAnnex.jl/ac-opf.jl at master · lanl-ansi/PowerModelsAnnex.jl · GitHub](https://github.com/lanl-ansi/PowerModelsAnnex.jl/blob/master/src/model/ac-opf.jl) for a selection of models that you could use as the base to make modifications

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 16, 2023, 12:00pm UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/11 "2023-05-16T12:00:53Z")

</div>

How to call a class function you wrote in another file, something like this  
`mutable struct PyClass  
a::Float64  
b::Float64  
n::Int  
end

PyClass() = PyClass(0.0, 0.0, 0)  
function **init** (self::PyClass)  
self.a = 1.0  
self.b = 2.0  
self.n = 10  
end

function method1(self::PyClass)  
self.n += 1  
nothing  
end

function method2(self::PyClass)  
return self.a + self.b  
end

mim = **init** (PyClass())  
method1(mim)  
method2(mim)`

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [May 16, 2023, 9:26pm UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/13 "2023-05-16T21:26:58Z")

</div>

You can use `include("path/to/file.jl")` to load another file.

Note that unlike Python, Julia doesn’t have classes, and it doesn’t have file-level namespaces.

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 18, 2023, 6:21am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/14 "2023-05-18T06:21:59Z")

</div>

Can I ask you again how to use the ‘OPFLearn’ package, if there are examples of running it, I think I can grasp it a little faster

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [May 18, 2023, 7:16am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/15 "2023-05-18T07:16:05Z")

</div>

> [@lzq-zbc](#):
>
> OPFLearn

I don’t know what this is. If you have specific questions and can provide more information, please start a new thread.

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [May 18, 2023, 7:20am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/16 "2023-05-18T07:20:53Z")

</div>

ok

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [July 6, 2023, 1:39am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/17 "2023-07-06T01:39:39Z")

</div>

```julia
using JuMP, PowerModels, Ipopt,SCS

file_name = "E:/Vscode——data/data/case300.m"

model = Model(Ipopt.Optimizer)
power_model = PowerModels.instantiate_model(
    PowerModels.parse_file(file_name),
    # println(PowerModels.parse_file(file_name)),
    PowerModels.DCPLLPowerModel,
    PowerModels.build_opf;
    jump_model = model,
)
optimize!(model)
println("Optimal objective value: ", JuMP.objective_value(model))

```

Can I replace the .m file here with a csv file and import it directly into this model to run. Or is there a way to modify the data directly in the .m file and import it into a later model

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [July 6, 2023, 2:15am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/18 "2023-07-06T02:15:00Z")

</div>

What is the format of the CSV file you want to use?

You could just edit the file manually?

Otherwise you can modify the elements of the dictionary returned by `parse_file`.

See [Network Data Format · PowerModels](https://lanl-ansi.github.io/PowerModels.jl/stable/network-data/#Working-with-Matpower-Data-Files)

---

<div class="post-metadata">

### Author: ![lzq-zbc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lzq-zbc/32/49776_2.png) [@lzq-zbc](https://discourse.julialang.org/u/lzq-zbc)
#### Post date: [July 6, 2023, 2:49am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/19 "2023-07-06T02:49:45Z")

</div>

Manual editing is very difficult, my intention is to modify the load in the case300 study, I need to modify it thousands of times, and then output their final result

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [July 7, 2023, 2:06am UTC](https://discourse.julialang.org/t/ipopt-solves-large-scale-nonlinear-problems/98831/20 "2023-07-07T02:06:52Z")

</div>

Then you may want to call `parse_file` once, and programmatically edit the elements inside it for each solve.
