Summary
Ripopt fails or runs very slowly on gas pipeline network NLP benchmark problems from Sakshi21299/gas_networks. These are Pyomo models built with the gas_net package on GasLib-11 and GasLib-40 test instances.
Two problem types arise from this package:
- Steady-state NLP: small, ~50–200 variables. Works fine.
- Dynamic NLP (24-hour horizon, finite-volume PDE discretization): n≈2500, m≈2500. Fails.
Benchmark Results (IPOPT vs RIPOPT)
Network Phase Solver Status Obj (kW·h) Time (s)
------------------------------------------------------------------------
GasLib-11 steady ipopt optimal 0.0329 0.021
GasLib-11 steady ripopt optimal 0.0329 0.048 ✓
GasLib-11 dynamic ipopt optimal 0.7885 0.092
GasLib-11 dynamic ripopt internalSolverError N/A 18.4 ✗
GasLib-40 steady ipopt optimal 1.2900 0.112
GasLib-40 steady ripopt internalSolverError N/A 1246.6 ✗
Ripopt matches IPOPT exactly on the steady-state GasLib-11 problem. It fails on both the dynamic GasLib-11 and the steady-state GasLib-40.
Diagnostic Output (GasLib-11 dynamic, print_level=5)
ripopt: Starting main loop (n=2542, m=2492)
0 1.7280000e0 8.64e2 0.00e0 -1.0 0.00e0 0.00e0 0
ripopt: Sparse condensed S has bandwidth 2541 for n=2542, switching to augmented KKT
1 1.7281070e0 8.64e2 2.38e2 -2.0 1.81e-4 5.94e-4 0
ripopt: L-BFGS Hessian fallback did not improve (NumericalError)
--- ripopt diagnostics ---
status: NumericalError
iterations: 63
wall_time: 18.407s
final_mu: 1.01e-7
final_primal_inf: 2.21e-9
final_dual_inf: 2.96e-1
final_compl: 1.01e-7
---
ripopt 0.5.0: NumericalError after 63 iterations
Objective: 7.885488421941358e-1 ← matches IPOPT's optimal value exactly
Note: the final objective value matches IPOPT's optimal (0.7885), and final_primal_inf: 2.21e-9 is essentially zero. The solver found the right answer but dual convergence stalled.
Root Cause Hypothesis
The key line is:
Sparse condensed S has bandwidth 2541 for n=2542, switching to augmented KKT
The dynamic gas network NLP arises from a finite-volume discretization of the Euler equations on a pipe network. The Jacobian/Hessian has a block-banded structure (space × time grid), but ripopt's bandwidth heuristic is detecting bandwidth ≈ n, treating it as essentially dense and switching to the augmented KKT system.
Once in augmented KKT mode, the L-BFGS Hessian fallback is triggered and fails (NumericalError), causing dual convergence to stall even though the primal solution is correct.
The GasLib-40 steady-state case (n+m probably around 300–400) presumably crosses the sparse_threshold and hits the same bandwidth detection issue.
Problem Structure
The model is a Pyomo ConcreteModel built by gas_net/model_nlp.py. It uses:
- Finite-volume discretization of mass/momentum PDEs (backward time differencing)
- Epsilon-regularized flow reversal (
|u| ≈ sqrt(u² + ε²))
- Scaled variables (pressure ÷ 1e5, power ÷ 1e5)
- Compressor performance maps as polynomial constraints
The .nl file produced by Pyomo likely has a variable ordering that makes the true banded structure non-obvious from the bandwidth of the condensed KKT matrix.
Options Tried
s.options['enable_lbfgs_hessian_fallback'] = 'no' # prevents the fallback
s.options['warm_start_init_point'] = 'yes'
s.options['mu_init'] = 1e-6
s.options['bound_push'] = 1e-6
Disabling the L-BFGS fallback doesn't resolve the underlying dual convergence issue.
Suggested Directions
-
Variable reordering: The .nl file variable ordering may be scrambling the natural banded structure. A bandwidth-reducing reordering (AMD, RCM) applied before bandwidth detection might reveal the true structure.
-
Augmented KKT linear solver robustness: On the augmented system, the linear algebra appears to fail for this problem. Better inertia correction or a more robust factorization might help.
-
Dual convergence with near-zero primal infeasibility: When primal_inf < 1e-8 but dual_inf > 0.1, the solver is essentially at the primal solution but can't close the dual gap. An option to accept this as locallyOptimal (rather than NumericalError) with a warning would be useful — the current behavior discards a correct primal solution.
Reproduction
git clone https://github.com/Sakshi21299/gas_networks
pip install -e gas_networks/
pip install pyomo-ripopt
import json, pyomo.environ as pyo, pyomo_ripopt
from pathlib import Path
from gas_net.util.import_data import import_data_from_excel
from gas_net.model_nlp import buildNonLinearModel
from gas_net.modelling_library.fix_and_init_vars import init_network_default
DATA = Path("gas_networks/gas_net/data")
opt = json.load(open(DATA / "Options.json"))
opt["dynamic"] = True
opt["T"] = 24
nd, id_ = import_data_from_excel(
str(DATA / "data_files/GasLib_11/networkData.xlsx"),
str(DATA / "data_files/GasLib_11/inputData.xlsx"),
)
m = buildNonLinearModel(nd, id_, opt)
m = init_network_default(m, p_default=55e5)
m.wSource["entry01", :].fix()
m.wSource["entry02", :].fix()
m.pSource["entry03", :].fix()
s = pyo.SolverFactory("ripopt")
s.options["print_level"] = 5
result = s.solve(m, tee=True)
Environment
- ripopt 0.5.0 / 0.6.1
- Pyomo 6.x
- pyomo-ripopt 0.1.0
- macOS Darwin 25.3.0
Summary
Ripopt fails or runs very slowly on gas pipeline network NLP benchmark problems from Sakshi21299/gas_networks. These are Pyomo models built with the
gas_netpackage on GasLib-11 and GasLib-40 test instances.Two problem types arise from this package:
Benchmark Results (IPOPT vs RIPOPT)
Ripopt matches IPOPT exactly on the steady-state GasLib-11 problem. It fails on both the dynamic GasLib-11 and the steady-state GasLib-40.
Diagnostic Output (GasLib-11 dynamic, print_level=5)
Note: the final objective value matches IPOPT's optimal (0.7885), and
final_primal_inf: 2.21e-9is essentially zero. The solver found the right answer but dual convergence stalled.Root Cause Hypothesis
The key line is:
The dynamic gas network NLP arises from a finite-volume discretization of the Euler equations on a pipe network. The Jacobian/Hessian has a block-banded structure (space × time grid), but ripopt's bandwidth heuristic is detecting bandwidth ≈ n, treating it as essentially dense and switching to the augmented KKT system.
Once in augmented KKT mode, the L-BFGS Hessian fallback is triggered and fails (
NumericalError), causing dual convergence to stall even though the primal solution is correct.The GasLib-40 steady-state case (n+m probably around 300–400) presumably crosses the
sparse_thresholdand hits the same bandwidth detection issue.Problem Structure
The model is a Pyomo
ConcreteModelbuilt by gas_net/model_nlp.py. It uses:|u| ≈ sqrt(u² + ε²))The
.nlfile produced by Pyomo likely has a variable ordering that makes the true banded structure non-obvious from the bandwidth of the condensed KKT matrix.Options Tried
Disabling the L-BFGS fallback doesn't resolve the underlying dual convergence issue.
Suggested Directions
Variable reordering: The
.nlfile variable ordering may be scrambling the natural banded structure. A bandwidth-reducing reordering (AMD, RCM) applied before bandwidth detection might reveal the true structure.Augmented KKT linear solver robustness: On the augmented system, the linear algebra appears to fail for this problem. Better inertia correction or a more robust factorization might help.
Dual convergence with near-zero primal infeasibility: When
primal_inf < 1e-8butdual_inf > 0.1, the solver is essentially at the primal solution but can't close the dual gap. An option to accept this aslocallyOptimal(rather thanNumericalError) with a warning would be useful — the current behavior discards a correct primal solution.Reproduction
Environment