Skip to content

Chemical Equilibrium

ChemistryLab computes thermodynamic equilibrium by minimizing the Gibbs free energy of the system subject to element-conservation constraints. The workflow always follows the same four steps:

  1. Build a ChemicalSystem (species + stoichiometric matrix).

  2. Create an initial ChemicalState (temperature, pressure, initial amounts).

  3. Call equilibrate (or use EquilibriumSolver explicitly).

  4. Inspect the resulting ChemicalState.


Minimal workflow

The convenience function equilibrate handles everything with sensible defaults. The example below computes the equilibrium state of calcite (CaCO₃) dissolving in mildly acidic water — a standard geochemical benchmark.

julia
using Optimization, OptimizationIpopt
using ChemistryLab
using DynamicQuantities

substances = build_species(datapath("slop98-inorganic-thermofun.json"); verbose = false)

# Select the carbonate-system species, calcite and its dissolution product Ca²⁺
dict = Dict(symbol(s) => s for s in substances)
species = [dict[sym] for sym in split("H2O@ H+ OH- CO2@ HCO3- CO3-2 Ca+2 Cal")]

cs = ChemicalSystem(species, ["H2O@", "H+", "Ca+2", "CO3-2", "Zz"])
┌──────────────────────────────────────────────────────────┐
│  Loading database: data/slop98-inorganic-thermofun.json  │
└──────────────────────────────────────────────────────────┘
┌────────────────────┐
│  Building species  │
└────────────────────┘

Progress:  23%|████████████████████████████████████▍                                                                                                                            |  ETA: 0:00:00
Progress:  45%|████████████████████████████████████████████████████████████████████████▏                                                                                        |  ETA: 0:00:00
Progress:  67%|████████████████████████████████████████████████████████████████████████████████████████████████████████████▍                                                    |  ETA: 0:00:00
Progress:  90%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▌                |  ETA: 0:00:00
Progress:  98%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▊   |  ETA: 0:00:00
Progress: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:00
The chemical system in full
julia
cs
8-element ChemicalSystem{Species{Int64}, AbstractReaction, StoichMatrix{Int64, Symbol, Vector{Symbol}, Matrix{Int64}, Species{Int64}}, StoichMatrix{Int64, Species{Int64}, Vector{Species{Int64}}, Matrix{Int64}, Species{Int64}}, Nothing}:
 H2O@ {Water HGK} [H2O@ ◆ H₂O@]
 H+ {H+} [H+ ◆ H⁺]
 OH- {OH- hydroXyl ion} [OH- ◆ OH⁻]
 CO2@ {CO2,aq (+ H2O = H2CO3,aq )} [CO2@ ◆ CO₂@]
 HCO3- {HCO3- bicarbonate ion} [HCO3- ◆ HCO₃⁻]
 CO3-2 {CO3-2 carbonate ion} [CO3-2 ◆ CO₃²⁻]
 Ca+2 {Ca+2 ion} [Ca+2 ◆ Ca²⁺]
 Cal {CALCITE} [CaCO3 ◆ CaCO₃]
julia
state = ChemicalState(cs)

# 1 mmol calcite dissolved in 1 L of acidic water (initial pH ≈ 4)
set_quantity!(state, "Cal",  1e-3u"mol")
set_quantity!(state, "H2O@", 1.0u"kg")

V = volume(state)
set_quantity!(state, "H+",  1e-4u"mol/L" * V.liquid)   # pH = 4
set_quantity!(state, "OH-", 1e-10u"mol/L" * V.liquid)  # charge seed

state_eq = equilibrate(state)
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
The solved state in full — every species, with its amount
julia
state_eq
ChemicalState{Species{Int64}, AbstractReaction, DynamicQuantities.Quantity{Float64, DynamicQuantities.SymbolicDimensions{DynamicQuantities.FRInt32}}, Float64}
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│           T : 298.15 K                                                                         │
│           P : 1.0 bar                                                                          │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│  # liquid #│             n [mol]│               m [g]│             V [cm³]│           c [mol/L]│
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│ tot. liquid│             55.5096│             1000.02│             1002.96│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│        H2O@│             55.5093│             999.999│             1002.96│             55.3452│
│        Ca+2│          0.00015562│          0.00623694│         -0.00286944│          0.00015516│
│       HCO3-│          0.00013426│          0.00819199│          0.00325055│         0.000133863│
│         OH-│          3.41397e-5│         0.000580613│        -0.000160724│          3.40388e-5│
│       CO3-2│          2.12724e-5│          0.00127651│        -0.000128862│          2.12095e-5│
│        CO2@│          8.79459e-8│          3.87041e-6│          2.88521e-6│           8.7686e-8│
│          H+│         2.96035e-10│         2.98403e-10│                 0.0│          2.9516e-10│
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│   # solid #│             n [mol]│               m [g]│             V [cm³]│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│  tot. solid│          0.00084438│           0.0845106│           0.0311863│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│         Cal│          0.00084438│           0.0845106│           0.0311863│                    │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│   # TOTAL #│             n [mol]│               m [g]│             V [cm³]│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│            │             55.5105│              1000.1│             1002.99│                    │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│          pH : 9.5274                                                                           │
│         pOH : 4.468                                                                            │
│    porosity : 0.999969                                                                         │
│  saturation : 1.0                                                                              │
└────────────────────────────────────────────────────────────────────────────────────────────────┘

Quick shortcut

Calling equilibrate(state) with no extra arguments uses sensible defaults and is usually sufficient for aqueous geochemical problems.


Choosing a solver

ChemistryLab provides two solver extensions. Load whichever fits your workflow:

Extension packagesDefault solverWhen to use
Optimization, OptimizationIpoptIpoptOptimizergeneral-purpose, robust
OptimaSolverOptimaOptimizerpreferred when available

When both are loaded, OptimaSolver provides the default single back end, and on a cement equilibrium it is the faster of the two: 0.10 s against 0.28 s for Ipopt on a CEM I paste at w/c = 0.45. An earlier version of this page quoted "3 to 26 times faster"; that range is not reproduced — the measured factor there is 2.8, and on a small calcite system Ipopt is both faster (0.015 s against 0.038 s) and far more accurate on the element balance (3e-12 relative against 3e-2). Which back end is quicker depends on the system, so neither ordering is worth stating as a rule.

What is worth stating is that neither of them returns a KKT point on a cement. Both satisfy the element balance to 10⁻¹⁴10⁻⁹ and agree on the pH to three decimals, while their stationarity residual sits at 133 and 136 in RT units. That does not matter for a pH, and it matters a great deal for a trace species or a saturation index — which is why equilibrate certifies by default, at a cost of about 1.4 s on the same paste.

equilibrate(state) does not pick one of them — it proves the answer

Neither back end is reliable on its own, so the one-argument equilibrate solves by every route available and keeps the answer optimality_certificate proves optimal. Measured, with the element balance judged row by row against each row's own budget:

caseinterior pointdual Newtoncertified route
calcite in water, 10–40 °C3.0e-23.0e-12certified
calcite + 1 mmol CO₂1.0e-36.3e-13certified
calcite + 50 mmol CO₂1.3e-168.5e-14certified
pure water1.3e-161.3e-16certified
CEM I paste, w/c 0.45 and 0.601.5e-142.0e-14certified
CEM I paste, w/c 0.307.2e-163.3e-10, not certifiedcertified

Ten of ten certified through both routes; seven through the interior point alone, nine through the dual Newton alone. The interior point's 3 % on the first row is not a tolerance: it is a charge balance wrong in the second digit, and the reason it cannot be improved is that the fraction-to-boundary rule caps its step at 15 % of a correction the next iteration re-poses — traced over twenty-three iterations with the residual frozen at 3.0e-6 and ‖dn‖ decaying at 1 − α.

julia
state_eq = equilibrate(state)                   # certified (the default)
state_eq = equilibrate(state; certify = false)  # one back end, as before
eq, cert = equilibrate_certified(state)         # when the proof itself is wanted

Pass a solver explicitly — equilibrate(state, OptimaOptimizer()) — to use that one back end and nothing else.

Certifying an answer

equilibrate takes the certifying route by default, and it returns a composition together with a proof that it is the Gibbs minimum rather than the point an iteration stopped at. Why such a proof exists — the problem is convex, so the KKT conditions are sufficient and not merely necessary — what the three conditions are, and how DualEquilibriumSolver aims at them directly, are in Proving that an answer is the answer.

Driving it explicitly, when the two stages are wanted separately:

julia
des  = DualEquilibriumSolver(cs, HKFActivityModel())
ipm  = equilibrate(state, OptimaOptimizer())      # into the neighborhood 
dual = solve(des, ipm; b = b)                     # to the KKT conditions
cert = optimality_certificate(des, dual; b = b)
cert.optimal    # true: a proof, for a convex problem

Constraints other than fixed T and P

A closed system at given temperature and pressure is one case among several. A vessel that exchanges no heat has its temperature determined by the reaction; a titration holds the pH and lets the amount of acid follow. Both are equilibrium problems, and both are stated by saying what is held and what is unknown.

Needs OptimaSolver 0.5

The blocks in this section are shown rather than executed: the documentation environment resolves OptimaSolver from the registry, and the parameter block these constraints ride on arrived in 0.5.0. The figures quoted below are the ones test/equilibrium_constraints.jl asserts.

julia
using ChemistryLab, DynamicQuantities, OptimaSolver

# The same calcite system, but adiabatic: no heat leaves, so T is an unknown
st = ChemicalState(cs)
set_quantity!(st, "Cal",  1e-2u"mol")
set_quantity!(st, "H2O@", 1.0u"kg")
set_quantity!(st, "H+",   1e-2u"mol")
set_quantity!(st, "OH-",  1e-10u"mol")

des   = DualEquilibriumSolver(cs, DiluteSolutionModel())
eq_ad = solve(des, st; constraint = Adiabatic())

temperature(eq_ad)      # 298.1996 K — the reaction warms it by 0.0496 K
pH(eq_ad)               # 6.4323, against 6.4329 at fixed temperature
constraintheldunknownvehicle
FixedTP (default)T, P
Adiabaticthe enthalpy of the initial stateTparameter
FixedEnthalpya prescribed HTparameter
FixedVolumea prescribed VPparameter
SealedVolumethe volume of the initial statePparameter
FixedpH−log₁₀ a(H⁺)the titrant amountcolumn
FixedActivitya of any speciesthe titrant amountcolumn

The two vehicles

They are not interchangeable, and the distinction is the same one Reaktoro draws.

A prescribed property — an enthalpy, a volume — adds one parameter and one equation to the solver's own square system. Nothing loops around the equilibrium solve: the temperature is an unknown beside the amounts and the element potentials, and the enthalpy balance is one more row of the same Newton system. So an adiabatic solve costs one equation, not a solve per trial temperature.

A prescribed chemical potential — a pH, an activity — adds one column to the conservation matrix instead: an unknown amount of a titrant the system may draw on. The linear rows become A n − A[:, titrant] q = b, so the system is open to that one substance and closed to everything else, and q comes back as part of the answer — it is the reagent consumed, which is what a titration measures.

julia
q = Ref(Float64[])
eq_ph = solve(des, st; constraint = FixedpH(7.0), parameters = q)
q[][1]      # 3.4673e-3 mol of H+ had to be added to hold pH 7

On 10 mmol of calcite in a kilogram of water, whose free pH is 9.90, holding the pH takes more acid the lower the target, and at pH 6 the calcite is gone entirely:

pH heldH⁺ added (mol)calcite left (mol)
61.689e-20
73.467e-37.063e-3
88.648e-49.149e-3
92.504e-49.728e-3

What is checked, and what is refused

The adiabatic answer is validated two ways. Against physics: H⁺ + OH⁻ → H₂O comes out at −55.85 kJ/mol at every amount tested, against the accepted −55.8, with nothing fitted to it — the enthalpies come from the database and the temperature is an unknown of the system. And against itself: solving at a fixed temperature equal to the one the adiabatic solve found returns the same composition to 1e-12.

A volume constraint on a condensed system is refused, with the lever it measured named in the error. The molar volumes of water and of the minerals in the shipped databases are exactly pressure-independent — V⁰(1 bar) = V⁰(100 bar) to the last bit for H2O@ and Cal — and only a few aqueous ions vary, OH⁻ by 8 % over 100 bar. The relative lever (∂V/∂P)·P/V is then about 1e-6, meaning some 9 600 bar to change the volume by one percent. That is the physics, not a solver limitation: the volume of an incompressible condensed system is fixed by its composition. Declare a gas phase to give the pressure something to do. To report the volume change of a sealed specimen at fixed pressure — what a hydrating binder actually needs — use porosity with a reference state instead.

Constraints need the certifying solver

The prescribed property or potential is an unknown of the dual Newton's own system, so a constraint other than FixedTP requires OptimaSolver and a system with an aqueous phase and H2O@. Asking for one otherwise raises, rather than being silently ignored. equilibrate(state; constraint = ...) routes through the certified path, so the answer still comes with its proof.

Differentiating an equilibrium

A ChemicalState carries whatever number type its amounts have, so a composition built from ForwardDiff.Dual values propagates through the speciation, and pH, pOH, porosity and saturation come back as duals too.

Crossing the solve works as well, and without asking any solver to iterate on dual numbers — Ipopt is a C library and never could. The equilibrium is solved once at the primal values, and the sensitivities come from the optimality conditions, the implicit-function-theorem route:

restricted to the species actually present. One factorization serves every partial derivative, and the result is exact — no step size to choose.

julia
using ChemistryLab, DynamicQuantities, ForwardDiff, OptimaSolver

f(x) = begin
    n = Any[fill(0.0u"mol", length(cs.species))...]
    n[i_h2o] = 55.5u"mol";  n[i_cal] = 0.05u"mol";  n[i_co2] = x * u"mol"
    eq = equilibrate(ChemicalState(cs, n), OptimaOptimizer())
    ustrip(us"mol", eq.n[i_ca])
end

ForwardDiff.derivative(f, 0.01)     # → 0.15193

Why the complementarity conditions cannot be skipped

The stationarity conditions are ∇G − Aᵀy − z = 0, A n = b, nᵢzᵢ = 0, with z ≥ 0 the stability multipliers. The last block partitions the species, and dropping it does not degrade the answer gently — it destroys it. On calcite + CO₂ in water with a gas phase declared, the unreduced system puts the whole response into the absent gas species (n = 5×10⁻¹¹ mol), returning a sensitivity that satisfies the element balance to 4×10⁻¹⁶ and means nothing.

No back-end returns z, so the active set is recovered internally: a species negligible on the scale of the system that nonetheless takes a leading share of the response is pinned, and the system re-solved.

Verified against Reaktoro

On calcite + CO₂ + water, ∂n/∂(CO₂) from this route agrees with the package's own finite differences to 9×10⁻⁵ — the finite-difference truncation error — and with Reaktoro 2.13 reading the same Cemdata18 file, over the same eleven species, under the same (ideal) activity model:

speciesChemistryLab (AD)Reaktoro (FD)rel. diff
H₂O−0.181336−0.1813973.4×10⁻⁴
Ca²⁺+0.151920+0.1519874.4×10⁻⁴
HCO₃⁻+0.333308+0.3334273.6×10⁻⁴
CO₂(aq)+0.818655+0.8186006.7×10⁻⁵
Ca(HCO₃)⁺+0.029333+0.0293381.6×10⁻⁴
calcite−0.181251−0.1813244.0×10⁻⁴

The equilibrium amounts agree to the same order (Ca²⁺ 3.5281×10⁻³ against 3.52902×10⁻³). Reaktoro's own spread across h ∈ {10⁻³, 10⁻⁴, 10⁻⁵} is 7.2×10⁻⁴, so the residual difference sits below the oracle's truncation error on every species.

The absent gas species gets exactly zero from the active-set treatment, against 2×10⁻⁹ by finite differences.

A cross-code comparison has three knobs, not one

Database, species list and activity model all have to match, and each is worth tens of percent here. Reading Cemdata18 in both codes but leaving Reaktoro on its HKF activity model against this package's default DiluteSolutionModel() moves ∂Ca²⁺/∂(CO₂) from +0.1520 to +0.2179 — a 35 % gap that says nothing about either code.

The species list matters just as much. Dropping the aqueous calcium complexes leaves free Ca²⁺ as the only aqueous home for calcium, so ∂Ca²⁺/∂(CO₂) and ∂calcite/∂(CO₂) mirror each other exactly. Restoring CaOH⁺, Ca(CO₃)@ and Ca(HCO₃)⁺ breaks that mirror — the difference is what Ca(HCO₃)⁺ takes up — and both codes break it the same way. The element balance closes to 2×10⁻¹⁶ either way.

Explicit solver (always works)

Pass the solver as the second positional argument:

julia
using Optimization, OptimizationIpopt
state_eq = equilibrate(state, IpoptOptimizer())

using OptimaSolver
state_eq = equilibrate(state, OptimaOptimizer())

Default shortcut

When only one extension is loaded:

julia
using Optimization, OptimizationIpopt
state_eq = equilibrate(state)   # → IpoptOptimizer

using OptimaSolver
state_eq = equilibrate(state)   # → OptimaOptimizer

With both loaded, OptimaSolver always wins:

julia
using Optimization, OptimizationIpopt
using OptimaSolver
state_eq = equilibrate(state)   # → OptimaOptimizer (priority)

Inspecting the equilibrium state

The returned ChemicalState carries all derived thermodynamic quantities:

julia
println("pH      = ", pH(state_eq))
println("pOH     = ", pOH(state_eq))
println("porosity   = ", porosity(state_eq))
println("saturation = ", saturation(state_eq))
pH      = 9.527368995318179
pOH     = 4.468026043734797
porosity   = 0.999968906788299
saturation = 1.0

Phase volumes and mole amounts are accessible via named tuples:

julia
v = volume(state_eq)
println("V liquid = ", v.liquid)
println("V solid  = ", v.solid)
println("V total  = ", v.total)

m = moles(state_eq)
println("n liquid = ", m.liquid)
println("n solid  = ", m.solid)
V liquid = 0.00100296351197813 m³
V solid  = 3.118632648932848e-8 m³
V total  = 0.0010029946983046193 m³
n liquid = 55.509609155105174 mol
n solid  = 0.0008443799014920693 mol

Individual species amounts (in mol):

julia
cs_eq = state_eq.system
for (i, sp) in enumerate(cs_eq.species)
    n_i = state_eq.n[i]
    println(rpad(symbol(sp), 20), ustrip(n_i), " mol")
end
H2O@                55.50926377496003 mol
H+                  2.96034710758174e-10 mol
OH-                 3.413965199970977e-5 mol
CO2@                8.794585905438738e-8 mol
HCO3-               0.0001342597672172696 mol
CO3-2               2.12723854802627e-5 mol
Ca+2                0.00015562009855239967 mol
Cal                 0.0008443799014920693 mol

Scaling and normalization

It is often useful to express a composition relative to a reference amount — per mole, per kilogram, or per cubic meter of system. Two mechanisms are provided.

Scalar multiplication

A ChemicalState can be multiplied or divided by a real number. All molar amounts are scaled proportionally; temperature, pressure, and the chemical system are unchanged. The operation is non-mutating — a new state is returned:

julia
state2  = state_eq * 2.0    # double all amounts
state_m = state_eq / 1000   # millimolar scale

rescale! — rescale to a target total

rescale! scales all molar amounts in-place so that the total of the matching physical quantity equals target:

target dimensionQuantity brought to target
molmoles(state).total
kg (mass)mass(state).total
m³ (volume)volume(state).total

All derived quantities (pH, porosity, volume, …) are recomputed automatically after scaling.

julia
# Express the equilibrium composition per kilogram of total system
state_pkg = copy(state_eq)
rescale!(state_pkg, 1.0u"kg")

println("Ca²⁺ = ", moles(state_pkg, "Ca+2"), "  mol/kg")
println("pH   = ", pH(state_pkg))   # intensive quantities are invariant
Ca²⁺ = 0.0001556045089878263 mol  mol/kg
pH   = 9.527368995318179

Intensive quantities

pH, porosity, and saturation are intensive — they are invariant under homothety and remain unchanged after rescale! or scalar multiplication.


Controlling the solver

Variable space: :linear vs :log

equilibrate accepts a variable_space keyword that selects the optimization variable space:

variable_spaceVariablesRecommended when
Val(:linear)mole amounts nᵢ ≥ 0most systems, default
Val(:log)log nᵢsystems spanning many orders of magnitude
julia
state_eq_log = equilibrate(state; variable_space=Val(:log))

Convergence

Solving a system of equations in chemistry can be a difficult undertaking. The orders of magnitude can vary greatly, and convergence is not guaranteed.


Tolerances

Tighter tolerances are passed directly as keyword arguments and forwarded to the underlying Ipopt solver:

julia
state_eq_tight = equilibrate(state; abstol=1e-12, reltol=1e-12)

Using EquilibriumSolver explicitly

For batch calculations where many different initial states share the same system and activity model, construct an EquilibriumSolver once and reuse it:

julia
using Optimization, OptimizationIpopt

opt = IpoptOptimizer(
    acceptable_tol        = 1e-12,
    dual_inf_tol          = 1e-12,
    acceptable_iter       = 1000,
    constr_viol_tol       = 1e-12,
    warm_start_init_point = "no",
)

solver = EquilibriumSolver(
    cs,
    DiluteSolutionModel(),
    opt;
    variable_space = Val(:linear),
    abstol  = 1e-10,
    reltol  = 1e-10,
)

Once built, solver is called with any compatible ChemicalState:

julia
state_eq2 = solve(solver, state)
ChemicalState{Species{Int64}, AbstractReaction, DynamicQuantities.Quantity{Float64, DynamicQuantities.SymbolicDimensions{DynamicQuantities.FRInt32}}, Float64}
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│           T : 298.15 K                                                                         │
│           P : 1.0 bar                                                                          │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│  # liquid #│             n [mol]│               m [g]│             V [cm³]│           c [mol/L]│
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│ tot. liquid│             55.5096│             1000.02│             1002.96│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│        H2O@│             55.5093│             999.999│             1002.96│             55.3452│
│        Ca+2│          0.00015562│          0.00623692│         -0.00286943│          0.00015516│
│       HCO3-│         0.000134259│          0.00819197│          0.00325053│         0.000133863│
│         OH-│          3.41393e-5│         0.000580607│        -0.000160722│          3.40384e-5│
│       CO3-2│          2.12722e-5│           0.0012765│        -0.000128861│          2.12094e-5│
│        CO2@│          8.79874e-8│          3.87224e-6│          2.88657e-6│          8.77274e-8│
│          H+│         3.34877e-10│         3.37556e-10│                 0.0│         3.33888e-10│
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│   # solid #│             n [mol]│               m [g]│             V [cm³]│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│  tot. solid│          0.00084438│           0.0845107│           0.0311863│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│         Cal│          0.00084438│           0.0845107│           0.0311863│                    │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│   # TOTAL #│             n [mol]│               m [g]│             V [cm³]│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│            │             55.5105│              1000.1│             1002.99│                    │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│          pH : 9.5274                                                                           │
│         pOH : 4.468                                                                            │
│    porosity : 0.999969                                                                         │
│  saturation : 1.0                                                                              │
└────────────────────────────────────────────────────────────────────────────────────────────────┘

Performance

The potential function μ(n, p) is compiled once during EquilibriumSolver construction. Repeated calls to solve(solver, ...) with different states reuse it, avoiding redundant compilation overhead.


Temperature dependence (10–30 °C)

Calcite solubility varies with temperature. Using the solver built above, we sweep from 10 to 30 °C and track pH, dissolved calcium and remaining solid calcite:

julia
using Plots


temperatures = 10:30   # °C

pH_vals   = Float64[]
nCa_vals  = Float64[]  # mmol
nCal_vals = Float64[]  # mmol

i_Ca  = findfirst(sp -> symbol(sp) == "Ca+2", cs.species)
i_Cal = findfirst(sp -> symbol(sp) == "Cal",  cs.species)

# Start from the charged state built above, not from `ChemicalState(cs)`:
# a fresh state holds no matter at all, so every element balance would be zero
# and the sweep would return the same trivial solution at all 21 temperatures.
for θ in temperatures
    s_T = deepcopy(state)
    set_temperature!(s_T, (273.15 + θ) * u"K")
    s_eq = solve(solver, s_T)
    push!(pH_vals,   pH(s_eq))
    push!(nCa_vals,  ustrip(s_eq.n[i_Ca]) * 1e3)
    push!(nCal_vals, ustrip(s_eq.n[i_Cal]) * 1e3)
end
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.5828675e+03 3.90e-02 2.01e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.5792157e+03 3.01e-02 1.13e+01  -1.0 8.01e-02    -  9.90e-01 2.28e-01h  1
   2 -5.5714334e+03 9.01e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.5695959e+03 4.29e-03 3.05e+01  -1.0 1.05e-02    -  1.00e+00 5.24e-01h  1
   4 -5.5682518e+03 7.77e-04 2.31e+01  -1.0 3.29e-03    -  1.00e+00 8.19e-01h  1
   5 -5.5680292e+03 2.01e-04 5.35e+01  -1.0 1.22e-03    -  1.00e+00 7.41e-01h  1
   6 -5.5679523e+03 3.17e-18 1.86e+00  -1.0 4.30e-04    -  1.00e+00 1.00e+00f  1
   7 -5.5679522e+03 5.56e-18 1.63e-02  -1.0 8.50e-05    -  1.00e+00 1.00e+00f  1
   8 -5.5687692e+03 3.52e-19 3.18e-01  -2.5 3.23e-02    -  1.00e+00 1.00e+00f  1
   9 -5.5688076e+03 2.17e-19 5.96e-02  -2.5 1.79e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.5688124e+03 2.17e-19 3.70e-03  -2.5 2.45e-04    -  1.00e+00 1.00e+00f  1
  11 -5.5688329e+03 2.17e-19 1.63e+00  -3.8 1.11e-03    -  1.00e+00 9.87e-01f  1
  12 -5.5688357e+03 7.11e-15 6.38e+01  -3.8 3.51e-04    -  1.00e+00 1.00e+00f  1
  13 -5.5688353e+03 2.17e-19 3.57e-02  -3.8 5.29e-05    -  1.00e+00 1.00e+00f  1
  14 -5.5688352e+03 7.11e-15 3.20e-04  -3.8 1.54e-05    -  1.00e+00 1.00e+00f  1
  15 -5.5688371e+03 7.11e-15 3.93e-01  -5.7 2.28e-04    -  7.04e-01 1.00e+00f  1
  16 -5.5688375e+03 7.11e-15 7.09e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.5688375e+03 7.11e-15 5.24e-02  -5.7 3.32e-05    -  1.00e+00 1.00e+00f  1
  18 -5.5688375e+03 1.36e-20 7.51e-03  -5.7 7.89e-06    -  1.00e+00 1.00e+00f  1
  19 -5.5688375e+03 1.36e-20 7.14e-05  -5.7 7.93e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.5688375e+03 0.00e+00 7.83e-09  -5.7 1.01e-08    -  1.00e+00 1.00e+00h  1
  21 -5.5688376e+03 7.11e-15 2.86e-01  -8.6 1.08e-05    -  9.89e-01 1.00e+00f  1
  22 -5.5688376e+03 0.00e+00 1.17e-01  -8.6 9.70e-07    -  1.00e+00 1.00e+00f  1
  23 -5.5688376e+03 0.00e+00 1.11e-01  -8.6 1.71e-07    -  1.00e+00 1.00e+00f  1
  24 -5.5688376e+03 0.00e+00 3.42e-02  -8.6 5.96e-08    -  1.00e+00 1.00e+00f  1
  25 -5.5688376e+03 7.11e-15 2.89e-03  -8.6 1.61e-08    -  1.00e+00 1.00e+00f  1
  26 -5.5688376e+03 0.00e+00 2.81e-05  -8.6 1.74e-09    -  1.00e+00 1.00e+00h  1
  27 -5.5688376e+03 0.00e+00 6.14e-09  -8.6 2.51e-11    -  1.00e+00 1.00e+00f  1
  28 -5.5688376e+03 7.11e-15 1.40e-01 -11.0 1.48e-08    -  1.00e+00 1.00e+00f  1
  29 -5.5688376e+03 1.36e-20 4.12e-02 -11.0 1.71e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.5688376e+03 0.00e+00 2.83e-02 -11.0 1.92e-10    -  1.00e+00 1.00e+00h  1
  31 -5.5688376e+03 7.11e-15 5.40e-03 -11.0 5.26e-11    -  1.00e+00 1.00e+00f  1
  32 -5.5688376e+03 0.00e+00 2.74e-04 -11.0 9.93e-12    -  1.00e+00 1.00e+00h  1
  33 -5.5688376e+03 1.36e-20 5.03e-07 -11.0 4.11e-13    -  1.00e+00 1.00e+00f  1
  34 -5.5688376e+03 0.00e+00 1.91e-12 -11.0 7.98e-16    -  1.00e+00 1.00e+00   0
  35 -5.5688376e+03 2.17e-19 1.24e-14 -11.0 2.56e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1624544665369197e+03   -5.5688375580224829e+03
Dual infeasibility......:   1.2406798029746332e-14    5.9435827236039411e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090936e-12    4.3550777634191928e-11
Overall NLP error.......:   9.0909090909090936e-12    4.3550777634191928e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.5647766e+03 3.90e-02 2.01e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.5611352e+03 3.01e-02 1.13e+01  -1.0 8.01e-02    -  9.90e-01 2.28e-01h  1
   2 -5.5533799e+03 9.01e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.5515495e+03 4.28e-03 3.05e+01  -1.0 1.05e-02    -  1.00e+00 5.24e-01h  1
   4 -5.5502113e+03 7.79e-04 2.32e+01  -1.0 3.29e-03    -  1.00e+00 8.18e-01h  1
   5 -5.5499886e+03 2.01e-04 5.33e+01  -1.0 1.22e-03    -  1.00e+00 7.42e-01h  1
   6 -5.5499120e+03 7.11e-15 1.82e+00  -1.0 4.31e-04    -  1.00e+00 1.00e+00f  1
   7 -5.5499119e+03 7.11e-15 1.66e-02  -1.0 8.52e-05    -  1.00e+00 1.00e+00f  1
   8 -5.5507258e+03 5.72e-18 3.19e-01  -2.5 3.23e-02    -  1.00e+00 1.00e+00f  1
   9 -5.5507641e+03 8.13e-20 5.98e-02  -2.5 1.79e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.5507689e+03 7.11e-15 3.75e-03  -2.5 2.46e-04    -  1.00e+00 1.00e+00f  1
  11 -5.5507894e+03 1.90e-19 1.64e+00  -3.8 1.11e-03    -  1.00e+00 9.87e-01f  1
  12 -5.5507921e+03 2.71e-20 6.40e+01  -3.8 3.49e-04    -  1.00e+00 1.00e+00f  1
  13 -5.5507917e+03 0.00e+00 3.70e-02  -3.8 5.21e-05    -  1.00e+00 1.00e+00f  1
  14 -5.5507917e+03 2.71e-20 3.05e-04  -3.8 1.49e-05    -  1.00e+00 1.00e+00f  1
  15 -5.5507935e+03 1.36e-20 3.94e-01  -5.7 2.28e-04    -  7.04e-01 1.00e+00f  1
  16 -5.5507939e+03 7.11e-15 7.13e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.5507939e+03 0.00e+00 5.27e-02  -5.7 3.33e-05    -  1.00e+00 1.00e+00f  1
  18 -5.5507939e+03 0.00e+00 7.51e-03  -5.7 7.90e-06    -  1.00e+00 1.00e+00f  1
  19 -5.5507939e+03 1.36e-20 7.20e-05  -5.7 7.90e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.5507939e+03 0.00e+00 8.15e-09  -5.7 1.01e-08    -  1.00e+00 1.00e+00h  1
  21 -5.5507940e+03 1.36e-20 2.86e-01  -8.6 1.08e-05    -  9.89e-01 1.00e+00f  1
  22 -5.5507940e+03 0.00e+00 1.17e-01  -8.6 9.58e-07    -  1.00e+00 1.00e+00f  1
  23 -5.5507940e+03 7.11e-15 1.11e-01  -8.6 1.74e-07    -  1.00e+00 1.00e+00f  1
  24 -5.5507940e+03 0.00e+00 3.43e-02  -8.6 5.97e-08    -  1.00e+00 1.00e+00h  1
  25 -5.5507940e+03 0.00e+00 2.95e-03  -8.6 1.61e-08    -  1.00e+00 1.00e+00f  1
  26 -5.5507940e+03 2.17e-19 2.63e-05  -8.6 1.71e-09    -  1.00e+00 1.00e+00f  1
  27 -5.5507940e+03 0.00e+00 5.38e-09  -8.6 2.39e-11    -  1.00e+00 1.00e+00h  1
  28 -5.5507940e+03 7.11e-15 1.39e-01 -11.0 1.49e-08    -  1.00e+00 1.00e+00f  1
  29 -5.5507940e+03 2.17e-19 4.08e-02 -11.0 1.68e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.5507940e+03 1.36e-20 2.78e-02 -11.0 1.95e-10    -  1.00e+00 1.00e+00h  1
  31 -5.5507940e+03 0.00e+00 5.21e-03 -11.0 5.32e-11    -  1.00e+00 1.00e+00h  1
  32 -5.5507940e+03 0.00e+00 2.56e-04 -11.0 9.93e-12    -  1.00e+00 1.00e+00f  1
  33 -5.5507940e+03 2.17e-19 4.43e-07 -11.0 3.99e-13    -  1.00e+00 1.00e+00f  1
  34 -5.5507940e+03 0.00e+00 1.48e-12 -11.0 7.29e-16    -  1.00e+00 1.00e+00   0
  35 -5.5507940e+03 2.17e-19 7.19e-15 -11.0 6.76e-19    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1626887139031803e+03   -5.5507939662256485e+03
Dual infeasibility......:   7.1935233014127414e-15    3.4342610588641607e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090936e-12    4.3400922986447909e-11
Overall NLP error.......:   9.0909090909090936e-12    4.3400922986447909e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.5468187e+03 3.90e-02 2.01e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.5431877e+03 3.01e-02 1.13e+01  -1.0 8.00e-02    -  9.90e-01 2.29e-01h  1
   2 -5.5354592e+03 9.00e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.5336359e+03 4.28e-03 3.05e+01  -1.0 1.05e-02    -  1.00e+00 5.24e-01h  1
   4 -5.5323036e+03 7.81e-04 2.33e+01  -1.0 3.29e-03    -  1.00e+00 8.18e-01h  1
   5 -5.5320807e+03 2.01e-04 5.30e+01  -1.0 1.23e-03    -  1.00e+00 7.43e-01h  1
   6 -5.5320044e+03 7.11e-15 1.79e+00  -1.0 4.32e-04    -  1.00e+00 1.00e+00f  1
   7 -5.5320043e+03 7.32e-19 1.69e-02  -1.0 8.55e-05    -  1.00e+00 1.00e+00f  1
   8 -5.5328151e+03 1.49e-18 3.19e-01  -2.5 3.23e-02    -  1.00e+00 1.00e+00f  1
   9 -5.5328534e+03 7.11e-15 6.01e-02  -2.5 1.80e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.5328582e+03 7.11e-15 3.79e-03  -2.5 2.47e-04    -  1.00e+00 1.00e+00f  1
  11 -5.5328786e+03 8.13e-20 1.64e+00  -3.8 1.11e-03    -  1.00e+00 9.87e-01f  1
  12 -5.5328813e+03 7.11e-15 6.43e+01  -3.8 3.48e-04    -  1.00e+00 1.00e+00f  1
  13 -5.5328809e+03 7.11e-15 3.83e-02  -3.8 5.13e-05    -  1.00e+00 1.00e+00f  1
  14 -5.5328809e+03 7.11e-15 2.94e-04  -3.8 1.45e-05    -  1.00e+00 1.00e+00f  1
  15 -5.5328827e+03 7.11e-15 3.95e-01  -5.7 2.28e-04    -  7.04e-01 1.00e+00f  1
  16 -5.5328831e+03 1.36e-20 7.17e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.5328831e+03 1.36e-20 5.29e-02  -5.7 3.33e-05    -  1.00e+00 1.00e+00f  1
  18 -5.5328831e+03 0.00e+00 7.51e-03  -5.7 7.90e-06    -  1.00e+00 1.00e+00f  1
  19 -5.5328831e+03 0.00e+00 7.25e-05  -5.7 7.87e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.5328831e+03 1.36e-20 8.49e-09  -5.7 1.01e-08    -  1.00e+00 1.00e+00f  1
  21 -5.5328831e+03 7.11e-15 2.86e-01  -8.6 1.08e-05    -  9.89e-01 1.00e+00f  1
  22 -5.5328831e+03 7.11e-15 1.17e-01  -8.6 9.46e-07    -  1.00e+00 1.00e+00f  1
  23 -5.5328831e+03 7.11e-15 1.11e-01  -8.6 1.77e-07    -  1.00e+00 1.00e+00h  1
  24 -5.5328831e+03 0.00e+00 3.45e-02  -8.6 5.99e-08    -  1.00e+00 1.00e+00h  1
  25 -5.5328831e+03 0.00e+00 3.01e-03  -8.6 1.61e-08    -  1.00e+00 1.00e+00f  1
  26 -5.5328831e+03 0.00e+00 2.45e-05  -8.6 1.68e-09    -  1.00e+00 1.00e+00f  1
  27 -5.5328831e+03 7.11e-15 4.68e-09  -8.6 2.27e-11    -  1.00e+00 1.00e+00f  1
  28 -5.5328831e+03 2.17e-19 1.38e-01 -11.0 1.49e-08    -  1.00e+00 1.00e+00h  1
  29 -5.5328831e+03 7.11e-15 4.03e-02 -11.0 1.64e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.5328831e+03 2.17e-19 2.72e-02 -11.0 1.97e-10    -  1.00e+00 1.00e+00h  1
  31 -5.5328831e+03 0.00e+00 5.02e-03 -11.0 5.38e-11    -  1.00e+00 1.00e+00h  1
  32 -5.5328831e+03 1.36e-20 2.39e-04 -11.0 9.92e-12    -  1.00e+00 1.00e+00f  1
  33 -5.5328831e+03 7.11e-15 3.87e-07 -11.0 3.86e-13    -  1.00e+00 1.00e+00h  1
  34 -5.5328831e+03 0.00e+00 1.14e-12 -11.0 6.95e-15    -  1.00e+00 1.00e+00   0
  35 -5.5328831e+03 0.00e+00 8.02e-15 -11.0 1.30e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1629239443521717e+03   -5.5328831391045214e+03
Dual infeasibility......:   8.0179994784688658e-15    3.8147511141394785e-14
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090920e-12    4.3252130006010741e-11
Overall NLP error.......:   9.0909090909090920e-12    4.3252130006010741e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.5289925e+03 3.90e-02 2.02e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.5253717e+03 3.01e-02 1.13e+01  -1.0 8.00e-02    -  9.90e-01 2.29e-01h  1
   2 -5.5176699e+03 9.00e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.5158536e+03 4.28e-03 3.05e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.5145272e+03 7.83e-04 2.33e+01  -1.0 3.29e-03    -  1.00e+00 8.17e-01h  1
   5 -5.5143041e+03 2.01e-04 5.28e+01  -1.0 1.23e-03    -  1.00e+00 7.44e-01h  1
   6 -5.5142282e+03 4.31e-18 1.76e+00  -1.0 4.33e-04    -  1.00e+00 1.00e+00f  1
   7 -5.5142281e+03 7.11e-15 1.72e-02  -1.0 8.57e-05    -  1.00e+00 1.00e+00f  1
   8 -5.5150358e+03 7.11e-15 3.20e-01  -2.5 3.23e-02    -  1.00e+00 1.00e+00f  1
   9 -5.5150740e+03 2.71e-20 6.03e-02  -2.5 1.80e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.5150788e+03 7.11e-15 3.84e-03  -2.5 2.49e-04    -  1.00e+00 1.00e+00f  1
  11 -5.5150992e+03 2.17e-19 1.65e+00  -3.8 1.12e-03    -  1.00e+00 9.88e-01f  1
  12 -5.5151018e+03 2.17e-19 6.45e+01  -3.8 3.46e-04    -  1.00e+00 1.00e+00f  1
  13 -5.5151014e+03 7.11e-15 3.95e-02  -3.8 5.06e-05    -  1.00e+00 1.00e+00f  1
  14 -5.5151014e+03 5.42e-20 3.01e-04  -3.8 1.41e-05    -  1.00e+00 1.00e+00f  1
  15 -5.5151032e+03 1.36e-20 3.96e-01  -5.7 2.28e-04    -  7.04e-01 1.00e+00f  1
  16 -5.5151036e+03 1.36e-20 7.21e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.5151036e+03 0.00e+00 5.32e-02  -5.7 3.34e-05    -  1.00e+00 1.00e+00f  1
  18 -5.5151036e+03 1.36e-20 7.52e-03  -5.7 7.90e-06    -  1.00e+00 1.00e+00f  1
  19 -5.5151036e+03 7.11e-15 7.32e-05  -5.7 7.84e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.5151036e+03 0.00e+00 8.88e-09  -5.7 1.00e-08    -  1.00e+00 1.00e+00h  1
  21 -5.5151037e+03 7.11e-15 2.86e-01  -8.6 1.08e-05    -  9.89e-01 1.00e+00f  1
  22 -5.5151037e+03 7.11e-15 1.17e-01  -8.6 9.34e-07    -  1.00e+00 1.00e+00f  1
  23 -5.5151037e+03 0.00e+00 1.11e-01  -8.6 1.80e-07    -  1.00e+00 1.00e+00h  1
  24 -5.5151037e+03 0.00e+00 3.47e-02  -8.6 6.01e-08    -  1.00e+00 1.00e+00f  1
  25 -5.5151037e+03 7.11e-15 3.07e-03  -8.6 1.61e-08    -  1.00e+00 1.00e+00f  1
  26 -5.5151037e+03 7.11e-15 2.27e-05  -8.6 1.65e-09    -  1.00e+00 1.00e+00h  1
  27 -5.5151037e+03 7.11e-15 4.04e-09  -8.6 2.16e-11    -  1.00e+00 1.00e+00h  1
  28 -5.5151037e+03 1.36e-20 1.37e-01 -11.0 1.50e-08    -  1.00e+00 1.00e+00h  1
  29 -5.5151037e+03 7.11e-15 3.98e-02 -11.0 1.60e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.5151037e+03 1.36e-20 2.66e-02 -11.0 2.00e-10    -  1.00e+00 1.00e+00h  1
  31 -5.5151037e+03 0.00e+00 4.83e-03 -11.0 5.45e-11    -  1.00e+00 1.00e+00h  1
  32 -5.5151037e+03 7.11e-15 2.22e-04 -11.0 9.90e-12    -  1.00e+00 1.00e+00f  1
  33 -5.5151037e+03 0.00e+00 3.36e-07 -11.0 3.73e-13    -  1.00e+00 1.00e+00h  1
  34 -5.5151037e+03 0.00e+00 8.68e-13 -11.0 5.99e-16    -  1.00e+00 1.00e+00   0
  35 -5.5151037e+03 2.17e-19 7.38e-15 -11.0 1.38e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1631601530096141e+03   -5.5151036630537546e+03
Dual infeasibility......:   7.3760335397376377e-15    3.4973334917430037e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090936e-12    4.3104387558354582e-11
Overall NLP error.......:   9.0909090909090936e-12    4.3104387558354582e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.5112966e+03 3.90e-02 2.02e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.5076859e+03 3.01e-02 1.13e+01  -1.0 8.00e-02    -  9.90e-01 2.29e-01h  1
   2 -5.5000106e+03 9.00e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.4982013e+03 4.28e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.4968808e+03 7.85e-04 2.34e+01  -1.0 3.29e-03    -  1.00e+00 8.17e-01h  1
   5 -5.4966574e+03 2.00e-04 5.25e+01  -1.0 1.23e-03    -  1.00e+00 7.45e-01h  1
   6 -5.4965819e+03 7.11e-15 1.73e+00  -1.0 4.34e-04    -  1.00e+00 1.00e+00f  1
   7 -5.4965818e+03 7.11e-15 1.75e-02  -1.0 8.60e-05    -  1.00e+00 1.00e+00f  1
   8 -5.4973864e+03 2.17e-19 3.21e-01  -2.5 3.23e-02    -  1.00e+00 1.00e+00f  1
   9 -5.4974246e+03 7.11e-15 6.06e-02  -2.5 1.81e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.4974294e+03 7.11e-15 3.89e-03  -2.5 2.50e-04    -  1.00e+00 1.00e+00f  1
  11 -5.4974497e+03 7.11e-15 1.65e+00  -3.8 1.12e-03    -  1.00e+00 9.88e-01f  1
  12 -5.4974523e+03 7.11e-15 6.47e+01  -3.8 3.44e-04    -  1.00e+00 1.00e+00f  1
  13 -5.4974519e+03 7.11e-15 4.08e-02  -3.8 4.99e-05    -  1.00e+00 1.00e+00f  1
  14 -5.4974519e+03 2.71e-20 3.07e-04  -3.8 1.37e-05    -  1.00e+00 1.00e+00f  1
  15 -5.4974537e+03 1.36e-20 3.97e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.4974541e+03 0.00e+00 7.24e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.4974541e+03 0.00e+00 5.35e-02  -5.7 3.34e-05    -  1.00e+00 1.00e+00f  1
  18 -5.4974541e+03 7.11e-15 7.52e-03  -5.7 7.90e-06    -  1.00e+00 1.00e+00f  1
  19 -5.4974541e+03 1.36e-20 7.39e-05  -5.7 7.81e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.4974541e+03 7.11e-15 9.31e-09  -5.7 1.00e-08    -  1.00e+00 1.00e+00h  1
  21 -5.4974541e+03 1.36e-20 2.87e-01  -8.6 1.08e-05    -  9.89e-01 1.00e+00f  1
  22 -5.4974541e+03 0.00e+00 1.16e-01  -8.6 9.23e-07    -  1.00e+00 1.00e+00f  1
  23 -5.4974541e+03 0.00e+00 1.11e-01  -8.6 1.83e-07    -  1.00e+00 1.00e+00f  1
  24 -5.4974541e+03 2.17e-19 3.49e-02  -8.6 6.03e-08    -  1.00e+00 1.00e+00f  1
  25 -5.4974541e+03 2.17e-19 3.13e-03  -8.6 1.60e-08    -  1.00e+00 1.00e+00h  1
  26 -5.4974541e+03 2.17e-19 2.10e-05  -8.6 1.62e-09    -  1.00e+00 1.00e+00h  1
  27 -5.4974541e+03 1.36e-20 3.47e-09  -8.6 2.04e-11    -  1.00e+00 1.00e+00h  1
  28 -5.4974541e+03 2.17e-19 1.36e-01 -11.0 1.50e-08    -  1.00e+00 1.00e+00f  1
  29 -5.4974541e+03 2.17e-19 3.93e-02 -11.0 1.56e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.4974541e+03 7.11e-15 2.61e-02 -11.0 2.03e-10    -  1.00e+00 1.00e+00h  1
  31 -5.4974541e+03 2.17e-19 4.65e-03 -11.0 5.51e-11    -  1.00e+00 1.00e+00h  1
  32 -5.4974541e+03 7.11e-15 2.06e-04 -11.0 9.87e-12    -  1.00e+00 1.00e+00h  1
  33 -5.4974541e+03 7.11e-15 2.91e-07 -11.0 3.60e-13    -  1.00e+00 1.00e+00h  1
  34 -5.4974541e+03 0.00e+00 6.53e-13 -11.0 7.24e-15    -  1.00e+00 1.00e+00   0
  35 -5.4974541e+03 0.00e+00 9.13e-15 -11.0 3.48e-19    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1633973350411104e+03   -5.4974541443105627e+03
Dual infeasibility......:   9.1328121079013979e-15    4.3155690888717811e-14
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090936e-12    4.2957684663772039e-11
Overall NLP error.......:   9.0909090909090936e-12    4.2957684663772039e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.4937295e+03 3.90e-02 2.02e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.4901289e+03 3.01e-02 1.13e+01  -1.0 7.99e-02    -  9.90e-01 2.29e-01h  1
   2 -5.4824799e+03 8.99e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.4806776e+03 4.28e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.4793629e+03 7.87e-04 2.35e+01  -1.0 3.29e-03    -  1.00e+00 8.16e-01h  1
   5 -5.4791393e+03 2.00e-04 5.23e+01  -1.0 1.23e-03    -  1.00e+00 7.46e-01h  1
   6 -5.4790642e+03 7.11e-15 1.71e+00  -1.0 4.35e-04    -  1.00e+00 1.00e+00f  1
   7 -5.4790641e+03 7.11e-15 1.78e-02  -1.0 8.62e-05    -  1.00e+00 1.00e+00f  1
   8 -5.4798656e+03 3.01e-18 3.21e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.4799037e+03 7.11e-15 6.08e-02  -2.5 1.81e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.4799086e+03 7.11e-15 3.93e-03  -2.5 2.52e-04    -  1.00e+00 1.00e+00f  1
  11 -5.4799288e+03 7.11e-15 1.66e+00  -3.8 1.12e-03    -  1.00e+00 9.88e-01f  1
  12 -5.4799314e+03 7.11e-15 6.49e+01  -3.8 3.43e-04    -  1.00e+00 1.00e+00f  1
  13 -5.4799310e+03 5.42e-20 4.21e-02  -3.8 4.96e-05    -  1.00e+00 1.00e+00f  1
  14 -5.4799310e+03 0.00e+00 3.13e-04  -3.8 1.33e-05    -  1.00e+00 1.00e+00f  1
  15 -5.4799328e+03 2.17e-19 3.98e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.4799331e+03 2.71e-20 7.27e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.4799332e+03 7.11e-15 5.37e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.4799332e+03 7.11e-15 7.53e-03  -5.7 7.90e-06    -  1.00e+00 1.00e+00f  1
  19 -5.4799332e+03 7.11e-15 7.46e-05  -5.7 7.77e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.4799332e+03 1.36e-20 9.78e-09  -5.7 9.99e-09    -  1.00e+00 1.00e+00h  1
  21 -5.4799332e+03 1.36e-20 2.87e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.4799332e+03 7.11e-15 1.16e-01  -8.6 9.12e-07    -  1.00e+00 1.00e+00f  1
  23 -5.4799332e+03 2.17e-19 1.11e-01  -8.6 1.86e-07    -  1.00e+00 1.00e+00h  1
  24 -5.4799332e+03 7.11e-15 3.51e-02  -8.6 6.05e-08    -  1.00e+00 1.00e+00f  1
  25 -5.4799332e+03 0.00e+00 3.19e-03  -8.6 1.60e-08    -  1.00e+00 1.00e+00h  1
  26 -5.4799332e+03 1.36e-20 1.94e-05  -8.6 1.59e-09    -  1.00e+00 1.00e+00f  1
  27 -5.4799332e+03 1.36e-20 2.95e-09  -8.6 1.92e-11    -  1.00e+00 1.00e+00h  1
  28 -5.4799332e+03 0.00e+00 1.35e-01 -11.0 1.50e-08    -  1.00e+00 1.00e+00f  1
  29 -5.4799332e+03 0.00e+00 3.88e-02 -11.0 1.53e-09    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.4799332e+03 1.36e-20 2.55e-02 -11.0 2.05e-10    -  1.00e+00 1.00e+00f  1
  31 -5.4799332e+03 1.36e-20 4.46e-03 -11.0 5.57e-11    -  1.00e+00 1.00e+00h  1
  32 -5.4799332e+03 7.11e-15 1.90e-04 -11.0 9.83e-12    -  1.00e+00 1.00e+00h  1
  33 -5.4799332e+03 0.00e+00 2.50e-07 -11.0 3.46e-13    -  1.00e+00 1.00e+00h  1
  34 -5.4799332e+03 0.00e+00 4.83e-13 -11.0 4.81e-16    -  1.00e+00 1.00e+00   0
  35 -5.4799332e+03 1.36e-20 1.07e-14 -11.0 1.99e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1636354856516193e+03   -5.4799332086088471e+03
Dual infeasibility......:   1.0713066327808564e-14    5.0451269886215581e-14
Constraint violation....:   1.3552527156068805e-20    1.3552527156068805e-20
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090920e-12    4.2812010494695135e-11
Overall NLP error.......:   9.0909090909090920e-12    4.2812010494695135e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.4762901e+03 3.90e-02 2.02e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.4726993e+03 3.01e-02 1.13e+01  -1.0 7.99e-02    -  9.90e-01 2.29e-01h  1
   2 -5.4650765e+03 8.99e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.4632811e+03 4.28e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.4619722e+03 7.90e-04 2.36e+01  -1.0 3.28e-03    -  1.00e+00 8.15e-01h  1
   5 -5.4617484e+03 2.00e-04 5.21e+01  -1.0 1.24e-03    -  1.00e+00 7.47e-01h  1
   6 -5.4616736e+03 3.77e-18 1.68e+00  -1.0 4.36e-04    -  1.00e+00 1.00e+00f  1
   7 -5.4616735e+03 8.94e-19 1.81e-02  -1.0 8.65e-05    -  1.00e+00 1.00e+00f  1
   8 -5.4624721e+03 7.11e-15 3.22e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.4625101e+03 1.90e-19 6.11e-02  -2.5 1.82e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.4625150e+03 2.71e-20 3.98e-03  -2.5 2.53e-04    -  1.00e+00 1.00e+00f  1
  11 -5.4625351e+03 7.11e-15 1.66e+00  -3.8 1.12e-03    -  1.00e+00 9.88e-01f  1
  12 -5.4625377e+03 7.11e-15 6.51e+01  -3.8 3.41e-04    -  1.00e+00 1.00e+00f  1
  13 -5.4625373e+03 2.71e-20 4.34e-02  -3.8 5.09e-05    -  1.00e+00 1.00e+00f  1
  14 -5.4625373e+03 2.17e-19 3.19e-04  -3.8 1.29e-05    -  1.00e+00 1.00e+00f  1
  15 -5.4625391e+03 2.17e-19 3.99e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.4625394e+03 7.11e-15 7.30e-02  -5.7 1.21e-04    -  1.00e+00 1.00e+00f  1
  17 -5.4625395e+03 7.11e-15 5.40e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.4625395e+03 0.00e+00 7.54e-03  -5.7 7.89e-06    -  1.00e+00 1.00e+00f  1
  19 -5.4625395e+03 1.42e-14 7.54e-05  -5.7 7.73e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.4625395e+03 1.36e-20 1.03e-08  -5.7 9.98e-09    -  1.00e+00 1.00e+00h  1
  21 -5.4625395e+03 7.11e-15 2.87e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.4625395e+03 1.36e-20 1.16e-01  -8.6 9.02e-07    -  1.00e+00 1.00e+00f  1
  23 -5.4625395e+03 1.36e-20 1.11e-01  -8.6 1.88e-07    -  1.00e+00 1.00e+00f  1
  24 -5.4625395e+03 7.11e-15 3.53e-02  -8.6 6.07e-08    -  1.00e+00 1.00e+00f  1
  25 -5.4625395e+03 7.11e-15 3.26e-03  -8.6 1.60e-08    -  1.00e+00 1.00e+00h  1
  26 -5.4625395e+03 7.11e-15 1.78e-05  -8.6 1.56e-09    -  1.00e+00 1.00e+00h  1
  27 -5.4625395e+03 7.11e-15 2.49e-09  -8.6 1.81e-11    -  1.00e+00 1.00e+00h  1
  28 -5.4625395e+03 7.11e-15 1.34e-01 -11.0 1.51e-08    -  1.00e+00 1.00e+00h  1
  29 -5.4625395e+03 7.11e-15 3.83e-02 -11.0 1.49e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.4625395e+03 0.00e+00 2.49e-02 -11.0 2.08e-10    -  1.00e+00 1.00e+00h  1
  31 -5.4625395e+03 7.11e-15 4.28e-03 -11.0 5.63e-11    -  1.00e+00 1.00e+00f  1
  32 -5.4625395e+03 7.11e-15 1.75e-04 -11.0 9.78e-12    -  1.00e+00 1.00e+00h  1
  33 -5.4625395e+03 0.00e+00 2.13e-07 -11.0 3.32e-13    -  1.00e+00 1.00e+00h  1
  34 -5.4625395e+03 0.00e+00 3.55e-13 -11.0 4.27e-16    -  1.00e+00 1.00e+00   0
  35 -5.4625395e+03 1.36e-20 1.24e-14 -11.0 3.12e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1638746000849387e+03   -5.4625395008405103e+03
Dual infeasibility......:   1.2367958451865715e-14    5.8047887275089781e-14
Constraint violation....:   1.3552527156068805e-20    1.3552527156068805e-20
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090936e-12    4.2667354373071559e-11
Overall NLP error.......:   9.0909090909090936e-12    4.2667354373071559e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.4589768e+03 3.90e-02 2.03e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.4553959e+03 3.01e-02 1.13e+01  -1.0 7.99e-02    -  9.90e-01 2.29e-01h  1
   2 -5.4477991e+03 8.98e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.4460106e+03 4.27e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.4447074e+03 7.92e-04 2.37e+01  -1.0 3.28e-03    -  1.00e+00 8.15e-01h  1
   5 -5.4444834e+03 2.00e-04 5.18e+01  -1.0 1.24e-03    -  1.00e+00 7.48e-01h  1
   6 -5.4444090e+03 7.11e-15 1.66e+00  -1.0 4.38e-04    -  1.00e+00 1.00e+00f  1
   7 -5.4444089e+03 7.11e-15 1.84e-02  -1.0 8.68e-05    -  1.00e+00 1.00e+00f  1
   8 -5.4452044e+03 7.32e-19 3.23e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.4452424e+03 7.11e-15 6.13e-02  -2.5 1.82e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.4452473e+03 7.11e-15 4.03e-03  -2.5 2.54e-04    -  1.00e+00 1.00e+00f  1
  11 -5.4452673e+03 2.17e-19 1.67e+00  -3.8 1.12e-03    -  1.00e+00 9.89e-01f  1
  12 -5.4452699e+03 7.11e-15 6.54e+01  -3.8 3.40e-04    -  1.00e+00 1.00e+00f  1
  13 -5.4452695e+03 0.00e+00 4.47e-02  -3.8 5.21e-05    -  1.00e+00 1.00e+00f  1
  14 -5.4452695e+03 7.11e-15 3.24e-04  -3.8 1.26e-05    -  1.00e+00 1.00e+00f  1
  15 -5.4452713e+03 7.11e-15 4.00e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.4452716e+03 1.36e-20 7.33e-02  -5.7 1.20e-04    -  1.00e+00 1.00e+00f  1
  17 -5.4452717e+03 7.11e-15 5.42e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.4452717e+03 0.00e+00 7.56e-03  -5.7 7.88e-06    -  1.00e+00 1.00e+00f  1
  19 -5.4452717e+03 0.00e+00 7.63e-05  -5.7 7.69e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.4452717e+03 0.00e+00 1.08e-08  -5.7 9.96e-09    -  1.00e+00 1.00e+00f  1
  21 -5.4452717e+03 7.11e-15 2.87e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.4452717e+03 7.11e-15 1.16e-01  -8.6 8.91e-07    -  1.00e+00 1.00e+00f  1
  23 -5.4452717e+03 1.36e-20 1.11e-01  -8.6 1.91e-07    -  1.00e+00 1.00e+00h  1
  24 -5.4452717e+03 0.00e+00 3.54e-02  -8.6 6.10e-08    -  1.00e+00 1.00e+00f  1
  25 -5.4452717e+03 2.17e-19 3.32e-03  -8.6 1.59e-08    -  1.00e+00 1.00e+00f  1
  26 -5.4452717e+03 2.17e-19 1.73e-05  -8.6 1.53e-09    -  1.00e+00 1.00e+00h  1
  27 -5.4452717e+03 7.11e-15 2.09e-09  -8.6 1.69e-11    -  1.00e+00 1.00e+00h  1
  28 -5.4452717e+03 0.00e+00 1.33e-01 -11.0 1.51e-08    -  1.00e+00 1.00e+00h  1
  29 -5.4452717e+03 1.36e-20 3.78e-02 -11.0 1.45e-09    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.4452717e+03 7.11e-15 2.44e-02 -11.0 2.11e-10    -  1.00e+00 1.00e+00h  1
  31 -5.4452717e+03 7.11e-15 4.10e-03 -11.0 5.69e-11    -  1.00e+00 1.00e+00h  1
  32 -5.4452717e+03 1.36e-20 1.61e-04 -11.0 9.72e-12    -  1.00e+00 1.00e+00h  1
  33 -5.4452717e+03 1.36e-20 1.81e-07 -11.0 3.17e-13    -  1.00e+00 1.00e+00h  1
  34 -5.4452717e+03 0.00e+00 2.58e-13 -11.0 3.77e-16    -  1.00e+00 1.00e+00   0
  35 -5.4452717e+03 2.17e-19 7.54e-15 -11.0 1.37e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 35

                                   (scaled)                 (unscaled)
Objective...............:  -1.1641146736231954e+03   -5.4452716847237998e+03
Dual infeasibility......:   7.5441035547929104e-15    3.5288356383036903e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909090920e-12    4.2523705767794995e-11
Overall NLP error.......:   9.0909090909090920e-12    4.2523705767794995e-11


Number of objective function evaluations             = 36
Number of objective gradient evaluations             = 36
Number of equality constraint evaluations            = 36
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 36
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 35
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.4417884e+03 3.90e-02 2.03e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.4382172e+03 3.01e-02 1.13e+01  -1.0 7.98e-02    -  9.90e-01 2.29e-01h  1
   2 -5.4306462e+03 8.98e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.4288646e+03 4.27e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.4275671e+03 7.94e-04 2.38e+01  -1.0 3.28e-03    -  1.00e+00 8.14e-01h  1
   5 -5.4273429e+03 1.99e-04 5.16e+01  -1.0 1.24e-03    -  1.00e+00 7.49e-01h  1
   6 -5.4272689e+03 7.11e-15 1.64e+00  -1.0 4.39e-04    -  1.00e+00 1.00e+00f  1
   7 -5.4272687e+03 7.11e-15 1.87e-02  -1.0 8.73e-05    -  1.00e+00 1.00e+00f  1
   8 -5.4280613e+03 3.17e-18 3.23e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.4280992e+03 7.11e-15 6.16e-02  -2.5 1.83e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.4281041e+03 7.11e-15 4.07e-03  -2.5 2.56e-04    -  1.00e+00 1.00e+00f  1
  11 -5.4281241e+03 7.11e-15 1.68e+00  -3.8 1.12e-03    -  1.00e+00 9.89e-01f  1
  12 -5.4281266e+03 7.11e-15 6.56e+01  -3.8 3.38e-04    -  1.00e+00 1.00e+00f  1
  13 -5.4281263e+03 7.11e-15 4.60e-02  -3.8 5.33e-05    -  1.00e+00 1.00e+00f  1
  14 -5.4281262e+03 7.11e-15 3.29e-04  -3.8 1.23e-05    -  1.00e+00 1.00e+00f  1
  15 -5.4281280e+03 7.11e-15 4.01e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.4281284e+03 7.11e-15 7.36e-02  -5.7 1.20e-04    -  1.00e+00 1.00e+00f  1
  17 -5.4281284e+03 7.11e-15 5.44e-02  -5.7 3.36e-05    -  1.00e+00 1.00e+00f  1
  18 -5.4281284e+03 7.11e-15 7.57e-03  -5.7 7.86e-06    -  1.00e+00 1.00e+00f  1
  19 -5.4281284e+03 7.11e-15 7.72e-05  -5.7 7.64e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.4281284e+03 0.00e+00 1.15e-08  -5.7 1.01e-08    -  1.00e+00 1.00e+00h  1
  21 -5.4281284e+03 2.17e-19 2.88e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.4281284e+03 1.36e-20 1.16e-01  -8.6 8.81e-07    -  1.00e+00 1.00e+00f  1
  23 -5.4281284e+03 2.17e-19 1.11e-01  -8.6 1.93e-07    -  1.00e+00 1.00e+00f  1
  24 -5.4281284e+03 2.17e-19 3.56e-02  -8.6 6.12e-08    -  1.00e+00 1.00e+00f  1
  25 -5.4281284e+03 2.17e-19 3.39e-03  -8.6 1.59e-08    -  1.00e+00 1.00e+00h  1
  26 -5.4281284e+03 0.00e+00 1.82e-05  -8.6 1.49e-09    -  1.00e+00 1.00e+00h  1
  27 -5.4281284e+03 0.00e+00 1.73e-09  -8.6 1.58e-11    -  1.00e+00 1.00e+00f  1
  28 -5.4281284e+03 1.36e-20 1.32e-01 -11.0 1.52e-08    -  1.00e+00 1.00e+00f  1
  29 -5.4281284e+03 7.11e-15 3.73e-02 -11.0 1.42e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.4281284e+03 1.36e-20 2.38e-02 -11.0 2.14e-10    -  1.00e+00 1.00e+00h  1
  31 -5.4281284e+03 7.11e-15 3.92e-03 -11.0 5.74e-11    -  1.00e+00 1.00e+00h  1
  32 -5.4281284e+03 7.11e-15 1.48e-04 -11.0 9.64e-12    -  1.00e+00 1.00e+00h  1
  33 -5.4281284e+03 7.11e-15 1.53e-07 -11.0 3.02e-13    -  1.00e+00 1.00e+00h  1
  34 -5.4281284e+03 2.71e-20 1.83e-13 -11.0 7.19e-15    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1643557015863453e+03   -5.4281284424785035e+03
Dual infeasibility......:   1.8302835096146658e-13    8.5326279270183942e-13
Constraint violation....:   2.7105054312137611e-20    2.7105054312137611e-20
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090910525060e-12    4.2381054292857002e-11
Overall NLP error.......:   9.0909090910525060e-12    4.2381054292857002e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.4247236e+03 3.90e-02 2.03e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.4211620e+03 3.00e-02 1.13e+01  -1.0 7.98e-02    -  9.90e-01 2.30e-01h  1
   2 -5.4136167e+03 8.97e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.01e-01h  1
   3 -5.4118419e+03 4.27e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.4105501e+03 7.96e-04 2.39e+01  -1.0 3.28e-03    -  1.00e+00 8.14e-01h  1
   5 -5.4103257e+03 1.99e-04 5.13e+01  -1.0 1.24e-03    -  1.00e+00 7.50e-01h  1
   6 -5.4102520e+03 4.04e-18 1.62e+00  -1.0 4.40e-04    -  1.00e+00 1.00e+00f  1
   7 -5.4102519e+03 7.11e-15 1.90e-02  -1.0 8.78e-05    -  1.00e+00 1.00e+00f  1
   8 -5.4110415e+03 7.11e-15 3.24e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.4110794e+03 7.11e-15 6.18e-02  -2.5 1.83e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.4110843e+03 7.11e-15 4.12e-03  -2.5 2.57e-04    -  1.00e+00 1.00e+00f  1
  11 -5.4111041e+03 7.11e-15 1.68e+00  -3.8 1.12e-03    -  1.00e+00 9.89e-01f  1
  12 -5.4111067e+03 7.11e-15 6.58e+01  -3.8 3.37e-04    -  1.00e+00 1.00e+00f  1
  13 -5.4111063e+03 0.00e+00 4.73e-02  -3.8 5.44e-05    -  1.00e+00 1.00e+00f  1
  14 -5.4111063e+03 5.42e-20 3.34e-04  -3.8 1.19e-05    -  1.00e+00 1.00e+00f  1
  15 -5.4111081e+03 4.07e-20 4.01e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.4111084e+03 0.00e+00 7.39e-02  -5.7 1.20e-04    -  1.00e+00 1.00e+00f  1
  17 -5.4111085e+03 2.17e-19 5.46e-02  -5.7 3.36e-05    -  1.00e+00 1.00e+00f  1
  18 -5.4111085e+03 7.11e-15 7.59e-03  -5.7 7.85e-06    -  1.00e+00 1.00e+00f  1
  19 -5.4111085e+03 7.11e-15 7.81e-05  -5.7 7.60e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.4111085e+03 0.00e+00 1.21e-08  -5.7 1.02e-08    -  1.00e+00 1.00e+00h  1
  21 -5.4111085e+03 2.17e-19 2.88e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.4111085e+03 1.36e-20 1.16e-01  -8.6 8.72e-07    -  1.00e+00 1.00e+00f  1
  23 -5.4111085e+03 1.36e-20 1.11e-01  -8.6 1.96e-07    -  1.00e+00 1.00e+00f  1
  24 -5.4111085e+03 7.11e-15 3.58e-02  -8.6 6.15e-08    -  1.00e+00 1.00e+00f  1
  25 -5.4111085e+03 7.11e-15 3.45e-03  -8.6 1.58e-08    -  1.00e+00 1.00e+00h  1
  26 -5.4111085e+03 0.00e+00 1.90e-05  -8.6 1.46e-09    -  1.00e+00 1.00e+00h  1
  27 -5.4111085e+03 0.00e+00 1.43e-09  -8.6 1.47e-11    -  1.00e+00 1.00e+00f  1
  28 -5.4111085e+03 7.11e-15 1.31e-01 -11.0 1.52e-08    -  1.00e+00 1.00e+00f  1
  29 -5.4111085e+03 0.00e+00 3.68e-02 -11.0 1.38e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.4111085e+03 1.36e-20 2.32e-02 -11.0 2.17e-10    -  1.00e+00 1.00e+00f  1
  31 -5.4111085e+03 7.11e-15 3.74e-03 -11.0 5.80e-11    -  1.00e+00 1.00e+00h  1
  32 -5.4111085e+03 1.36e-20 1.35e-04 -11.0 9.56e-12    -  1.00e+00 1.00e+00h  1
  33 -5.4111085e+03 0.00e+00 1.28e-07 -11.0 2.87e-13    -  1.00e+00 1.00e+00h  1
  34 -5.4111085e+03 1.36e-20 1.30e-13 -11.0 2.89e-16    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1645976793316854e+03   -5.4111084745078460e+03
Dual infeasibility......:   1.3019561277710945e-13    6.0493215480752450e-13
Constraint violation....:   1.3552527156068805e-20    1.3552527156068805e-20
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090910141407e-12    4.2239389702026742e-11
Overall NLP error.......:   9.0909090910141407e-12    4.2239389702026742e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.4077811e+03 3.90e-02 2.04e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.4042289e+03 3.00e-02 1.13e+01  -1.0 7.98e-02    -  9.90e-01 2.30e-01h  1
   2 -5.3967092e+03 8.97e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.3949412e+03 4.27e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.3936550e+03 7.98e-04 2.39e+01  -1.0 3.28e-03    -  1.00e+00 8.13e-01h  1
   5 -5.3934305e+03 1.99e-04 5.11e+01  -1.0 1.25e-03    -  1.00e+00 7.51e-01h  1
   6 -5.3933571e+03 2.03e-18 1.60e+00  -1.0 4.41e-04    -  1.00e+00 1.00e+00f  1
   7 -5.3933570e+03 2.36e-18 1.94e-02  -1.0 8.82e-05    -  1.00e+00 1.00e+00f  1
   8 -5.3941437e+03 2.52e-18 3.25e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.3941815e+03 2.71e-20 6.21e-02  -2.5 1.83e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.3941864e+03 7.11e-15 4.17e-03  -2.5 2.58e-04    -  1.00e+00 1.00e+00f  1
  11 -5.3942062e+03 7.11e-15 1.69e+00  -3.8 1.12e-03    -  1.00e+00 9.90e-01f  1
  12 -5.3942087e+03 2.71e-20 6.60e+01  -3.8 3.35e-04    -  1.00e+00 1.00e+00f  1
  13 -5.3942083e+03 7.11e-15 4.86e-02  -3.8 5.55e-05    -  1.00e+00 1.00e+00f  1
  14 -5.3942083e+03 7.11e-15 3.38e-04  -3.8 1.16e-05    -  1.00e+00 1.00e+00f  1
  15 -5.3942101e+03 2.17e-19 4.02e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.3942104e+03 2.17e-19 7.41e-02  -5.7 1.20e-04    -  1.00e+00 1.00e+00f  1
  17 -5.3942105e+03 7.11e-15 5.48e-02  -5.7 3.36e-05    -  1.00e+00 1.00e+00f  1
  18 -5.3942105e+03 7.11e-15 7.61e-03  -5.7 7.83e-06    -  1.00e+00 1.00e+00f  1
  19 -5.3942105e+03 7.11e-15 7.91e-05  -5.7 7.55e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.3942105e+03 7.11e-15 1.28e-08  -5.7 1.03e-08    -  1.00e+00 1.00e+00h  1
  21 -5.3942105e+03 7.11e-15 2.88e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.3942105e+03 7.11e-15 1.16e-01  -8.6 8.62e-07    -  1.00e+00 1.00e+00f  1
  23 -5.3942105e+03 2.71e-20 1.11e-01  -8.6 1.98e-07    -  1.00e+00 1.00e+00h  1
  24 -5.3942105e+03 7.11e-15 3.60e-02  -8.6 6.18e-08    -  1.00e+00 1.00e+00f  1
  25 -5.3942105e+03 7.11e-15 3.52e-03  -8.6 1.58e-08    -  1.00e+00 1.00e+00h  1
  26 -5.3942105e+03 2.17e-19 2.00e-05  -8.6 1.42e-09    -  1.00e+00 1.00e+00h  1
  27 -5.3942105e+03 2.17e-19 1.17e-09  -8.6 1.37e-11    -  1.00e+00 1.00e+00h  1
  28 -5.3942105e+03 2.17e-19 1.30e-01 -11.0 1.53e-08    -  1.00e+00 1.00e+00f  1
  29 -5.3942105e+03 7.11e-15 3.63e-02 -11.0 1.35e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.3942105e+03 7.11e-15 2.26e-02 -11.0 2.20e-10    -  1.00e+00 1.00e+00h  1
  31 -5.3942105e+03 7.11e-15 3.57e-03 -11.0 5.85e-11    -  1.00e+00 1.00e+00h  1
  32 -5.3942105e+03 7.11e-15 1.23e-04 -11.0 9.46e-12    -  1.00e+00 1.00e+00h  1
  33 -5.3942105e+03 0.00e+00 1.06e-07 -11.0 2.72e-13    -  1.00e+00 1.00e+00h  1
  34 -5.3942105e+03 0.00e+00 9.03e-14 -11.0 2.50e-16    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1648406022533695e+03   -5.3942104990869102e+03
Dual infeasibility......:   9.0338606193058493e-14    4.1834518564753632e-13
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909850456e-12    4.2098701891033193e-11
Overall NLP error.......:   9.0909090909850456e-12    4.2098701891033193e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.3909596e+03 3.90e-02 2.04e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.3874168e+03 3.00e-02 1.13e+01  -1.0 7.97e-02    -  9.90e-01 2.30e-01h  1
   2 -5.3799225e+03 8.96e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.3781612e+03 4.27e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.3768807e+03 8.00e-04 2.40e+01  -1.0 3.28e-03    -  1.00e+00 8.12e-01h  1
   5 -5.3766559e+03 1.98e-04 5.09e+01  -1.0 1.25e-03    -  1.00e+00 7.52e-01h  1
   6 -5.3765829e+03 3.17e-18 1.58e+00  -1.0 4.42e-04    -  1.00e+00 1.00e+00f  1
   7 -5.3765828e+03 6.42e-18 1.97e-02  -1.0 8.87e-05    -  1.00e+00 1.00e+00f  1
   8 -5.3773666e+03 2.79e-18 3.25e-01  -2.5 3.22e-02    -  1.00e+00 1.00e+00f  1
   9 -5.3774043e+03 2.44e-19 6.23e-02  -2.5 1.84e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.3774092e+03 8.13e-20 4.22e-03  -2.5 2.60e-04    -  1.00e+00 1.00e+00f  1
  11 -5.3774290e+03 7.11e-15 1.69e+00  -3.8 1.12e-03    -  1.00e+00 9.90e-01f  1
  12 -5.3774315e+03 7.11e-15 6.62e+01  -3.8 3.34e-04    -  1.00e+00 1.00e+00f  1
  13 -5.3774311e+03 2.17e-19 4.99e-02  -3.8 5.66e-05    -  1.00e+00 1.00e+00f  1
  14 -5.3774311e+03 5.42e-20 3.42e-04  -3.8 1.14e-05    -  1.00e+00 1.00e+00f  1
  15 -5.3774328e+03 7.11e-15 4.03e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.3774332e+03 2.17e-19 7.44e-02  -5.7 1.20e-04    -  1.00e+00 1.00e+00f  1
  17 -5.3774332e+03 7.11e-15 5.50e-02  -5.7 3.36e-05    -  1.00e+00 1.00e+00f  1
  18 -5.3774332e+03 7.11e-15 7.63e-03  -5.7 7.81e-06    -  1.00e+00 1.00e+00f  1
  19 -5.3774332e+03 2.17e-19 8.02e-05  -5.7 7.50e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.3774332e+03 7.11e-15 1.36e-08  -5.7 1.05e-08    -  1.00e+00 1.00e+00h  1
  21 -5.3774333e+03 2.17e-19 2.88e-01  -8.6 1.07e-05    -  9.89e-01 1.00e+00f  1
  22 -5.3774333e+03 2.17e-19 1.16e-01  -8.6 8.53e-07    -  1.00e+00 1.00e+00f  1
  23 -5.3774333e+03 2.17e-19 1.11e-01  -8.6 2.01e-07    -  1.00e+00 1.00e+00f  1
  24 -5.3774333e+03 7.11e-15 3.61e-02  -8.6 6.21e-08    -  1.00e+00 1.00e+00f  1
  25 -5.3774333e+03 1.36e-20 3.59e-03  -8.6 1.57e-08    -  1.00e+00 1.00e+00h  1
  26 -5.3774333e+03 1.36e-20 2.09e-05  -8.6 1.38e-09    -  1.00e+00 1.00e+00h  1
  27 -5.3774333e+03 7.11e-15 9.45e-10  -8.6 1.27e-11    -  1.00e+00 1.00e+00h  1
  28 -5.3774333e+03 0.00e+00 1.29e-01 -11.0 1.53e-08    -  1.00e+00 1.00e+00h  1
  29 -5.3774333e+03 7.11e-15 3.58e-02 -11.0 1.31e-09    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.3774333e+03 0.00e+00 2.21e-02 -11.0 2.22e-10    -  1.00e+00 1.00e+00h  1
  31 -5.3774333e+03 7.11e-15 3.40e-03 -11.0 5.90e-11    -  1.00e+00 1.00e+00f  1
  32 -5.3774333e+03 7.11e-15 1.11e-04 -11.0 9.35e-12    -  1.00e+00 1.00e+00h  1
  33 -5.3774333e+03 1.36e-20 8.80e-08 -11.0 2.57e-13    -  1.00e+00 1.00e+00h  1
  34 -5.3774333e+03 0.00e+00 6.20e-14 -11.0 2.15e-16    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1650844657819339e+03   -5.3774332520574226e+03
Dual infeasibility......:   6.2041796852916611e-14    2.8635316254976937e-13
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909632868e-12    4.1958980891885758e-11
Overall NLP error.......:   9.0909090909632868e-12    4.1958980891885758e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.3742579e+03 3.90e-02 2.04e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.3707244e+03 3.00e-02 1.13e+01  -1.0 7.97e-02    -  9.90e-01 2.30e-01h  1
   2 -5.3632553e+03 8.96e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.3615007e+03 4.27e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.3602258e+03 8.02e-04 2.41e+01  -1.0 3.28e-03    -  1.00e+00 8.12e-01h  1
   5 -5.3600008e+03 1.98e-04 5.06e+01  -1.0 1.25e-03    -  1.00e+00 7.53e-01h  1
   6 -5.3599282e+03 8.94e-19 1.56e+00  -1.0 4.43e-04    -  1.00e+00 1.00e+00f  1
   7 -5.3599281e+03 7.11e-15 2.01e-02  -1.0 8.92e-05    -  1.00e+00 1.00e+00f  1
   8 -5.3607090e+03 4.61e-19 3.26e-01  -2.5 3.21e-02    -  1.00e+00 1.00e+00f  1
   9 -5.3607467e+03 7.11e-15 6.26e-02  -2.5 1.84e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.3607516e+03 7.11e-15 4.26e-03  -2.5 2.61e-04    -  1.00e+00 1.00e+00f  1
  11 -5.3607712e+03 2.17e-19 1.70e+00  -3.8 1.12e-03    -  1.00e+00 9.90e-01f  1
  12 -5.3607737e+03 2.17e-19 6.64e+01  -3.8 3.33e-04    -  1.00e+00 1.00e+00f  1
  13 -5.3607734e+03 2.17e-19 5.12e-02  -3.8 5.76e-05    -  1.00e+00 1.00e+00f  1
  14 -5.3607733e+03 2.17e-19 3.46e-04  -3.8 1.11e-05    -  1.00e+00 1.00e+00f  1
  15 -5.3607751e+03 7.11e-15 4.04e-01  -5.7 2.29e-04    -  7.04e-01 1.00e+00f  1
  16 -5.3607754e+03 7.11e-15 7.46e-02  -5.7 1.20e-04    -  1.00e+00 1.00e+00f  1
  17 -5.3607755e+03 1.36e-20 5.52e-02  -5.7 3.36e-05    -  1.00e+00 1.00e+00f  1
  18 -5.3607755e+03 0.00e+00 7.65e-03  -5.7 7.78e-06    -  1.00e+00 1.00e+00f  1
  19 -5.3607755e+03 0.00e+00 8.13e-05  -5.7 7.45e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.3607755e+03 0.00e+00 1.44e-08  -5.7 1.06e-08    -  1.00e+00 1.00e+00f  1
  21 -5.3607755e+03 1.36e-20 2.88e-01  -8.6 1.06e-05    -  9.89e-01 1.00e+00f  1
  22 -5.3607755e+03 7.11e-15 1.16e-01  -8.6 8.45e-07    -  1.00e+00 1.00e+00f  1
  23 -5.3607755e+03 2.17e-19 1.11e-01  -8.6 2.03e-07    -  1.00e+00 1.00e+00h  1
  24 -5.3607755e+03 0.00e+00 3.63e-02  -8.6 6.24e-08    -  1.00e+00 1.00e+00f  1
  25 -5.3607755e+03 0.00e+00 3.66e-03  -8.6 1.57e-08    -  1.00e+00 1.00e+00f  1
  26 -5.3607755e+03 7.11e-15 2.20e-05  -8.6 1.34e-09    -  1.00e+00 1.00e+00f  1
  27 -5.3607755e+03 0.00e+00 8.98e-10  -8.6 1.17e-11    -  1.00e+00 1.00e+00h  1
  28 -5.3607755e+03 7.11e-15 1.28e-01 -11.0 1.53e-08    -  1.00e+00 1.00e+00f  1
  29 -5.3607755e+03 0.00e+00 3.52e-02 -11.0 1.28e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.3607755e+03 7.11e-15 2.15e-02 -11.0 2.25e-10    -  1.00e+00 1.00e+00f  1
  31 -5.3607755e+03 1.36e-20 3.23e-03 -11.0 5.94e-11    -  1.00e+00 1.00e+00h  1
  32 -5.3607755e+03 1.36e-20 1.01e-04 -11.0 9.23e-12    -  1.00e+00 1.00e+00h  1
  33 -5.3607755e+03 2.17e-19 7.23e-08 -11.0 2.42e-13    -  1.00e+00 1.00e+00h  1
  34 -5.3607755e+03 2.17e-19 4.20e-14 -11.0 1.84e-16    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1653292653838334e+03   -5.3607754865287843e+03
Dual infeasibility......:   4.2026557387087628e-14    1.9333157187096597e-13
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909472457e-12    4.1820216871460501e-11
Overall NLP error.......:   9.0909090909472457e-12    4.1820216871460501e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.076

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.3576747e+03 3.90e-02 2.04e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.3541505e+03 3.00e-02 1.13e+01  -1.0 7.97e-02    -  9.90e-01 2.30e-01h  1
   2 -5.3467064e+03 8.95e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.3449585e+03 4.26e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.3436891e+03 8.05e-04 2.42e+01  -1.0 3.28e-03    -  1.00e+00 8.11e-01h  1
   5 -5.3434640e+03 1.98e-04 5.04e+01  -1.0 1.25e-03    -  1.00e+00 7.54e-01h  1
   6 -5.3433917e+03 2.17e-19 1.54e+00  -1.0 4.44e-04    -  1.00e+00 1.00e+00f  1
   7 -5.3433916e+03 7.11e-15 2.04e-02  -1.0 8.97e-05    -  1.00e+00 1.00e+00f  1
   8 -5.3441696e+03 3.28e-18 3.27e-01  -2.5 3.21e-02    -  1.00e+00 1.00e+00f  1
   9 -5.3442072e+03 7.11e-15 6.29e-02  -2.5 1.85e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.3442122e+03 8.13e-20 4.31e-03  -2.5 2.62e-04    -  1.00e+00 1.00e+00f  1
  11 -5.3442317e+03 1.36e-19 1.70e+00  -3.8 1.12e-03    -  1.00e+00 9.90e-01f  1
  12 -5.3442342e+03 7.11e-15 6.67e+01  -3.8 3.31e-04    -  1.00e+00 1.00e+00f  1
  13 -5.3442338e+03 7.11e-15 5.25e-02  -3.8 5.86e-05    -  1.00e+00 1.00e+00f  1
  14 -5.3442338e+03 7.11e-15 3.50e-04  -3.8 1.08e-05    -  1.00e+00 1.00e+00f  1
  15 -5.3442356e+03 1.36e-20 4.05e-01  -5.7 2.29e-04    -  7.05e-01 1.00e+00f  1
  16 -5.3442359e+03 2.17e-19 7.48e-02  -5.7 1.19e-04    -  1.00e+00 1.00e+00f  1
  17 -5.3442359e+03 2.17e-19 5.54e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.3442360e+03 2.17e-19 7.67e-03  -5.7 7.76e-06    -  1.00e+00 1.00e+00f  1
  19 -5.3442360e+03 0.00e+00 8.25e-05  -5.7 7.39e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.3442360e+03 0.00e+00 1.53e-08  -5.7 1.08e-08    -  1.00e+00 1.00e+00f  1
  21 -5.3442360e+03 7.11e-15 2.88e-01  -8.6 1.06e-05    -  9.89e-01 1.00e+00f  1
  22 -5.3442360e+03 2.71e-20 1.15e-01  -8.6 8.36e-07    -  1.00e+00 1.00e+00f  1
  23 -5.3442360e+03 0.00e+00 1.11e-01  -8.6 2.05e-07    -  1.00e+00 1.00e+00f  1
  24 -5.3442360e+03 0.00e+00 3.65e-02  -8.6 6.27e-08    -  1.00e+00 1.00e+00f  1
  25 -5.3442360e+03 7.11e-15 3.73e-03  -8.6 1.56e-08    -  1.00e+00 1.00e+00f  1
  26 -5.3442360e+03 2.17e-19 2.30e-05  -8.6 1.31e-09    -  1.00e+00 1.00e+00h  1
  27 -5.3442360e+03 7.11e-15 9.93e-10  -8.6 1.07e-11    -  1.00e+00 1.00e+00h  1
  28 -5.3442360e+03 7.11e-15 1.26e-01 -11.0 1.54e-08    -  1.00e+00 1.00e+00h  1
  29 -5.3442360e+03 2.17e-19 3.47e-02 -11.0 1.25e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.3442360e+03 7.11e-15 2.09e-02 -11.0 2.28e-10    -  1.00e+00 1.00e+00h  1
  31 -5.3442360e+03 2.17e-19 3.07e-03 -11.0 5.99e-11    -  1.00e+00 1.00e+00h  1
  32 -5.3442360e+03 0.00e+00 9.09e-05 -11.0 9.10e-12    -  1.00e+00 1.00e+00h  1
  33 -5.3442360e+03 7.11e-15 5.90e-08 -11.0 2.27e-13    -  1.00e+00 1.00e+00f  1
  34 -5.3442360e+03 0.00e+00 2.74e-14 -11.0 7.06e-15    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1655749965609825e+03   -5.3442359725851584e+03
Dual infeasibility......:   2.7437532954113706e-14    1.2580284498638301e-13
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909355892e-12    4.1682400129228858e-11
Overall NLP error.......:   9.0909090909355892e-12    4.1682400129228858e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.3412089e+03 3.90e-02 2.05e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.3376937e+03 3.00e-02 1.13e+01  -1.0 7.96e-02    -  9.90e-01 2.30e-01h  1
   2 -5.3302745e+03 8.95e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.3285333e+03 4.26e-03 3.06e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.3272695e+03 8.07e-04 2.43e+01  -1.0 3.27e-03    -  1.00e+00 8.11e-01h  1
   5 -5.3270441e+03 1.97e-04 5.01e+01  -1.0 1.26e-03    -  1.00e+00 7.55e-01h  1
   6 -5.3269722e+03 7.11e-15 1.53e+00  -1.0 4.45e-04    -  1.00e+00 1.00e+00f  1
   7 -5.3269721e+03 1.44e-18 2.08e-02  -1.0 9.02e-05    -  1.00e+00 1.00e+00f  1
   8 -5.3277473e+03 4.63e-18 3.27e-01  -2.5 3.21e-02    -  1.00e+00 1.00e+00f  1
   9 -5.3277849e+03 2.44e-19 6.31e-02  -2.5 1.85e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.3277898e+03 7.11e-15 4.36e-03  -2.5 2.63e-04    -  1.00e+00 1.00e+00f  1
  11 -5.3278093e+03 8.13e-20 1.71e+00  -3.8 1.12e-03    -  1.00e+00 9.91e-01f  1
  12 -5.3278117e+03 2.17e-19 6.69e+01  -3.8 3.30e-04    -  1.00e+00 1.00e+00f  1
  13 -5.3278114e+03 2.17e-19 5.38e-02  -3.8 5.96e-05    -  1.00e+00 1.00e+00f  1
  14 -5.3278113e+03 2.17e-19 3.53e-04  -3.8 1.05e-05    -  1.00e+00 1.00e+00f  1
  15 -5.3278131e+03 2.17e-19 4.06e-01  -5.7 2.29e-04    -  7.05e-01 1.00e+00f  1
  16 -5.3278134e+03 1.36e-20 7.50e-02  -5.7 1.19e-04    -  1.00e+00 1.00e+00f  1
  17 -5.3278135e+03 0.00e+00 5.56e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.3278135e+03 7.11e-15 7.69e-03  -5.7 7.73e-06    -  1.00e+00 1.00e+00f  1
  19 -5.3278135e+03 7.11e-15 8.38e-05  -5.7 7.34e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.3278135e+03 2.17e-19 1.63e-08  -5.7 1.09e-08    -  1.00e+00 1.00e+00h  1
  21 -5.3278135e+03 2.17e-19 2.88e-01  -8.6 1.06e-05    -  9.89e-01 1.00e+00f  1
  22 -5.3278135e+03 7.11e-15 1.15e-01  -8.6 8.28e-07    -  1.00e+00 1.00e+00f  1
  23 -5.3278135e+03 7.11e-15 1.11e-01  -8.6 2.07e-07    -  1.00e+00 1.00e+00h  1
  24 -5.3278135e+03 7.11e-15 3.66e-02  -8.6 6.31e-08    -  1.00e+00 1.00e+00h  1
  25 -5.3278135e+03 1.36e-20 3.80e-03  -8.6 1.56e-08    -  1.00e+00 1.00e+00h  1
  26 -5.3278135e+03 7.11e-15 2.41e-05  -8.6 1.27e-09    -  1.00e+00 1.00e+00h  1
  27 -5.3278135e+03 7.11e-15 1.10e-09  -8.6 9.84e-12    -  1.00e+00 1.00e+00h  1
  28 -5.3278135e+03 7.11e-15 1.25e-01 -11.0 1.54e-08    -  1.00e+00 1.00e+00h  1
  29 -5.3278135e+03 7.11e-15 3.42e-02 -11.0 1.22e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.3278135e+03 7.11e-15 2.04e-02 -11.0 2.31e-10    -  1.00e+00 1.00e+00h  1
  31 -5.3278135e+03 1.36e-20 2.90e-03 -11.0 6.03e-11    -  1.00e+00 1.00e+00h  1
  32 -5.3278135e+03 0.00e+00 8.17e-05 -11.0 8.95e-12    -  1.00e+00 1.00e+00h  1
  33 -5.3278135e+03 0.00e+00 4.78e-08 -11.0 2.13e-13    -  1.00e+00 1.00e+00f  1
  34 -5.3278135e+03 2.17e-19 1.82e-14 -11.0 1.32e-16    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1658216548503071e+03   -5.3278134969985113e+03
Dual infeasibility......:   1.8167170698484246e-14    8.3024103083836056e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909272382e-12    4.1545521095032048e-11
Overall NLP error.......:   9.0909090909272382e-12    4.1545521095032048e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.3248592e+03 3.90e-02 2.05e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.3213530e+03 3.00e-02 1.13e+01  -1.0 7.96e-02    -  9.90e-01 2.31e-01h  1
   2 -5.3139586e+03 8.94e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.3122239e+03 4.26e-03 3.07e+01  -1.0 1.06e-02    -  1.00e+00 5.24e-01h  1
   4 -5.3109657e+03 8.09e-04 2.44e+01  -1.0 3.27e-03    -  1.00e+00 8.10e-01h  1
   5 -5.3107401e+03 1.97e-04 4.99e+01  -1.0 1.26e-03    -  1.00e+00 7.57e-01h  1
   6 -5.3106686e+03 5.01e-18 1.51e+00  -1.0 4.46e-04    -  1.00e+00 1.00e+00f  1
   7 -5.3106684e+03 7.11e-15 2.11e-02  -1.0 9.07e-05    -  1.00e+00 1.00e+00f  1
   8 -5.3114408e+03 1.82e-18 3.28e-01  -2.5 3.21e-02    -  1.00e+00 1.00e+00f  1
   9 -5.3114783e+03 7.11e-15 6.34e-02  -2.5 1.85e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.3114832e+03 2.71e-20 4.41e-03  -2.5 2.65e-04    -  1.00e+00 1.00e+00f  1
  11 -5.3115027e+03 7.11e-15 1.71e+00  -3.8 1.12e-03    -  1.00e+00 9.91e-01f  1
  12 -5.3115051e+03 2.17e-19 6.71e+01  -3.8 3.29e-04    -  1.00e+00 1.00e+00f  1
  13 -5.3115048e+03 7.11e-15 5.51e-02  -3.8 6.05e-05    -  1.00e+00 1.00e+00f  1
  14 -5.3115047e+03 7.11e-15 3.61e-04  -3.8 1.03e-05    -  1.00e+00 1.00e+00f  1
  15 -5.3115065e+03 7.11e-15 4.07e-01  -5.7 2.30e-04    -  7.05e-01 1.00e+00f  1
  16 -5.3115068e+03 0.00e+00 7.52e-02  -5.7 1.19e-04    -  1.00e+00 1.00e+00f  1
  17 -5.3115068e+03 7.11e-15 5.58e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.3115068e+03 2.17e-19 7.72e-03  -5.7 7.70e-06    -  1.00e+00 1.00e+00f  1
  19 -5.3115068e+03 7.11e-15 8.51e-05  -5.7 7.28e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.3115068e+03 7.11e-15 1.73e-08  -5.7 1.11e-08    -  1.00e+00 1.00e+00h  1
  21 -5.3115069e+03 7.11e-15 2.88e-01  -8.6 1.06e-05    -  9.89e-01 1.00e+00f  1
  22 -5.3115069e+03 1.36e-20 1.15e-01  -8.6 8.21e-07    -  1.00e+00 1.00e+00f  1
  23 -5.3115069e+03 0.00e+00 1.11e-01  -8.6 2.10e-07    -  1.00e+00 1.00e+00f  1
  24 -5.3115069e+03 0.00e+00 3.68e-02  -8.6 6.34e-08    -  1.00e+00 1.00e+00f  1
  25 -5.3115069e+03 7.11e-15 3.87e-03  -8.6 1.55e-08    -  1.00e+00 1.00e+00f  1
  26 -5.3115069e+03 7.11e-15 2.53e-05  -8.6 1.23e-09    -  1.00e+00 1.00e+00h  1
  27 -5.3115069e+03 1.36e-20 1.22e-09  -8.6 8.99e-12    -  1.00e+00 1.00e+00h  1
  28 -5.3115069e+03 1.36e-20 1.24e-01 -11.0 1.55e-08    -  1.00e+00 1.00e+00f  1
  29 -5.3115069e+03 7.11e-15 3.37e-02 -11.0 1.18e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.3115069e+03 7.11e-15 1.98e-02 -11.0 2.34e-10    -  1.00e+00 1.00e+00h  1
  31 -5.3115069e+03 7.11e-15 2.75e-03 -11.0 6.07e-11    -  1.00e+00 1.00e+00h  1
  32 -5.3115069e+03 7.11e-15 7.31e-05 -11.0 8.80e-12    -  1.00e+00 1.00e+00h  1
  33 -5.3115069e+03 7.11e-15 3.84e-08 -11.0 1.98e-13    -  1.00e+00 1.00e+00h  1
  34 -5.3115069e+03 2.17e-19 1.11e-14 -11.0 7.07e-15    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1660692358233002e+03   -5.3115068629474181e+03
Dual infeasibility......:   1.1096437810392961e-14    5.0544859407561535e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909213478e-12    4.1409570326900272e-11
Overall NLP error.......:   9.0909090909213478e-12    4.1409570326900272e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.3086244e+03 3.90e-02 2.05e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.3051272e+03 3.00e-02 1.13e+01  -1.0 7.96e-02    -  9.90e-01 2.31e-01h  1
   2 -5.2977573e+03 8.94e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.2960293e+03 4.26e-03 3.07e+01  -1.0 1.06e-02    -  1.00e+00 5.23e-01h  1
   4 -5.2947765e+03 8.11e-04 2.45e+01  -1.0 3.27e-03    -  1.00e+00 8.10e-01h  1
   5 -5.2945507e+03 1.96e-04 4.97e+01  -1.0 1.26e-03    -  1.00e+00 7.58e-01h  1
   6 -5.2944795e+03 2.52e-18 1.50e+00  -1.0 4.47e-04    -  1.00e+00 1.00e+00f  1
   7 -5.2944794e+03 5.15e-19 2.15e-02  -1.0 9.11e-05    -  1.00e+00 1.00e+00f  1
   8 -5.2952490e+03 2.98e-19 3.28e-01  -2.5 3.21e-02    -  1.00e+00 1.00e+00f  1
   9 -5.2952864e+03 2.17e-19 6.36e-02  -2.5 1.86e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.2952914e+03 7.11e-15 4.46e-03  -2.5 2.66e-04    -  1.00e+00 1.00e+00f  1
  11 -5.2953107e+03 7.11e-15 1.72e+00  -3.8 1.12e-03    -  1.00e+00 9.91e-01f  1
  12 -5.2953131e+03 2.71e-20 6.73e+01  -3.8 3.28e-04    -  1.00e+00 1.00e+00f  1
  13 -5.2953128e+03 2.71e-20 5.63e-02  -3.8 6.14e-05    -  1.00e+00 1.00e+00f  1
  14 -5.2953128e+03 7.11e-15 3.68e-04  -3.8 1.01e-05    -  1.00e+00 1.00e+00f  1
  15 -5.2953145e+03 2.17e-19 4.07e-01  -5.7 2.30e-04    -  7.05e-01 1.00e+00f  1
  16 -5.2953148e+03 2.17e-19 7.53e-02  -5.7 1.19e-04    -  1.00e+00 1.00e+00f  1
  17 -5.2953149e+03 0.00e+00 5.60e-02  -5.7 3.35e-05    -  1.00e+00 1.00e+00f  1
  18 -5.2953149e+03 2.17e-19 7.75e-03  -5.7 7.66e-06    -  1.00e+00 1.00e+00f  1
  19 -5.2953149e+03 2.17e-19 8.64e-05  -5.7 7.23e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.2953149e+03 7.11e-15 1.84e-08  -5.7 1.12e-08    -  1.00e+00 1.00e+00h  1
  21 -5.2953149e+03 7.11e-15 2.88e-01  -8.6 1.05e-05    -  9.89e-01 1.00e+00f  1
  22 -5.2953149e+03 7.11e-15 1.15e-01  -8.6 8.13e-07    -  1.00e+00 1.00e+00f  1
  23 -5.2953149e+03 7.11e-15 1.11e-01  -8.6 2.12e-07    -  1.00e+00 1.00e+00h  1
  24 -5.2953149e+03 7.11e-15 3.69e-02  -8.6 6.37e-08    -  1.00e+00 1.00e+00h  1
  25 -5.2953149e+03 2.17e-19 3.94e-03  -8.6 1.54e-08    -  1.00e+00 1.00e+00h  1
  26 -5.2953149e+03 7.11e-15 2.64e-05  -8.6 1.18e-09    -  1.00e+00 1.00e+00h  1
  27 -5.2953149e+03 7.11e-15 1.34e-09  -8.6 8.17e-12    -  1.00e+00 1.00e+00h  1
  28 -5.2953149e+03 7.11e-15 1.23e-01 -11.0 1.55e-08    -  1.00e+00 1.00e+00h  1
  29 -5.2953149e+03 7.11e-15 3.31e-02 -11.0 1.15e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.2953149e+03 7.11e-15 1.92e-02 -11.0 2.37e-10    -  1.00e+00 1.00e+00h  1
  31 -5.2953149e+03 2.17e-19 2.60e-03 -11.0 6.10e-11    -  1.00e+00 1.00e+00h  1
  32 -5.2953149e+03 7.11e-15 6.53e-05 -11.0 8.64e-12    -  1.00e+00 1.00e+00h  1
  33 -5.2953149e+03 7.11e-15 3.07e-08 -11.0 1.84e-13    -  1.00e+00 1.00e+00h  1
  34 -5.2953149e+03 0.00e+00 1.20e-14 -11.0 7.14e-15    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1663177350855913e+03   -5.2953148897415495e+03
Dual infeasibility......:   1.2046764302214012e-14    5.4694710080902125e-14
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909172507e-12    4.1274538508915142e-11
Overall NLP error.......:   9.0909090909172507e-12    4.1274538508915142e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.2925034e+03 3.90e-02 2.06e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.2890150e+03 3.00e-02 1.13e+01  -1.0 7.95e-02    -  9.90e-01 2.31e-01h  1
   2 -5.2816696e+03 8.93e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.2799481e+03 4.26e-03 3.07e+01  -1.0 1.06e-02    -  1.00e+00 5.23e-01h  1
   4 -5.2787008e+03 8.13e-04 2.46e+01  -1.0 3.27e-03    -  1.00e+00 8.09e-01h  1
   5 -5.2784748e+03 1.96e-04 4.94e+01  -1.0 1.26e-03    -  1.00e+00 7.59e-01h  1
   6 -5.2784040e+03 1.36e-19 1.49e+00  -1.0 4.48e-04    -  1.00e+00 1.00e+00f  1
   7 -5.2784039e+03 2.71e-20 2.19e-02  -1.0 9.16e-05    -  1.00e+00 1.00e+00f  1
   8 -5.2791706e+03 2.90e-18 3.29e-01  -2.5 3.21e-02    -  1.00e+00 1.00e+00f  1
   9 -5.2792080e+03 2.17e-19 6.39e-02  -2.5 1.86e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.2792130e+03 2.17e-19 4.51e-03  -2.5 2.67e-04    -  1.00e+00 1.00e+00f  1
  11 -5.2792323e+03 1.36e-19 1.73e+00  -3.8 1.12e-03    -  1.00e+00 9.92e-01f  1
  12 -5.2792347e+03 7.11e-15 6.75e+01  -3.8 3.27e-04    -  1.00e+00 1.00e+00f  1
  13 -5.2792343e+03 7.11e-15 5.76e-02  -3.8 6.23e-05    -  1.00e+00 1.00e+00f  1
  14 -5.2792343e+03 7.11e-15 3.76e-04  -3.8 9.83e-06    -  1.00e+00 1.00e+00f  1
  15 -5.2792360e+03 1.36e-20 4.08e-01  -5.7 2.30e-04    -  7.05e-01 1.00e+00f  1
  16 -5.2792363e+03 7.11e-15 7.55e-02  -5.7 1.18e-04    -  1.00e+00 1.00e+00f  1
  17 -5.2792364e+03 7.11e-15 5.61e-02  -5.7 3.34e-05    -  1.00e+00 1.00e+00f  1
  18 -5.2792364e+03 7.11e-15 7.77e-03  -5.7 7.63e-06    -  1.00e+00 1.00e+00f  1
  19 -5.2792364e+03 1.36e-20 8.79e-05  -5.7 7.17e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.2792364e+03 7.11e-15 1.96e-08  -5.7 1.14e-08    -  1.00e+00 1.00e+00h  1
  21 -5.2792364e+03 7.11e-15 2.88e-01  -8.6 1.05e-05    -  9.89e-01 1.00e+00f  1
  22 -5.2792364e+03 0.00e+00 1.15e-01  -8.6 8.06e-07    -  1.00e+00 1.00e+00f  1
  23 -5.2792364e+03 7.11e-15 1.11e-01  -8.6 2.14e-07    -  1.00e+00 1.00e+00f  1
  24 -5.2792364e+03 2.17e-19 3.71e-02  -8.6 6.41e-08    -  1.00e+00 1.00e+00h  1
  25 -5.2792364e+03 2.17e-19 4.01e-03  -8.6 1.53e-08    -  1.00e+00 1.00e+00h  1
  26 -5.2792364e+03 1.36e-20 2.77e-05  -8.6 1.14e-09    -  1.00e+00 1.00e+00h  1
  27 -5.2792364e+03 2.71e-20 1.48e-09  -8.6 7.41e-12    -  1.00e+00 1.00e+00h  1
  28 -5.2792364e+03 7.11e-15 1.22e-01 -11.0 1.55e-08    -  1.00e+00 1.00e+00f  1
  29 -5.2792364e+03 7.11e-15 3.26e-02 -11.0 1.12e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.2792364e+03 0.00e+00 1.86e-02 -11.0 2.40e-10    -  1.00e+00 1.00e+00h  1
  31 -5.2792364e+03 7.11e-15 2.45e-03 -11.0 6.14e-11    -  1.00e+00 1.00e+00f  1
  32 -5.2792364e+03 7.11e-15 5.80e-05 -11.0 8.46e-12    -  1.00e+00 1.00e+00h  1
  33 -5.2792364e+03 2.71e-20 2.43e-08 -11.0 1.71e-13    -  1.00e+00 1.00e+00h  1
  34 -5.2792364e+03 1.36e-20 6.12e-15 -11.0 7.59e-17    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1665671482765144e+03   -5.2792364125516769e+03
Dual infeasibility......:   6.1212508812704751e-15    2.7701389148931616e-14
Constraint violation....:   1.3552527156068805e-20    1.3552527156068805e-20
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909144460e-12    4.1140416449115271e-11
Overall NLP error.......:   9.0909090909144460e-12    4.1140416449115271e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.2764951e+03 3.90e-02 2.06e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.2730154e+03 3.00e-02 1.13e+01  -1.0 7.95e-02    -  9.90e-01 2.31e-01h  1
   2 -5.2656943e+03 8.93e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.2639793e+03 4.25e-03 3.07e+01  -1.0 1.06e-02    -  1.00e+00 5.23e-01h  1
   4 -5.2627374e+03 8.15e-04 2.47e+01  -1.0 3.27e-03    -  1.00e+00 8.08e-01h  1
   5 -5.2625112e+03 1.96e-04 4.92e+01  -1.0 1.27e-03    -  1.00e+00 7.60e-01h  1
   6 -5.2624408e+03 1.42e-14 1.48e+00  -1.0 4.49e-04    -  1.00e+00 1.00e+00f  1
   7 -5.2624406e+03 7.11e-15 2.23e-02  -1.0 9.21e-05    -  1.00e+00 1.00e+00f  1
   8 -5.2632046e+03 7.32e-19 3.30e-01  -2.5 3.20e-02    -  1.00e+00 1.00e+00f  1
   9 -5.2632420e+03 8.13e-20 6.41e-02  -2.5 1.87e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.2632469e+03 7.11e-15 4.55e-03  -2.5 2.68e-04    -  1.00e+00 1.00e+00f  1
  11 -5.2632662e+03 8.13e-20 1.73e+00  -3.8 1.12e-03    -  1.00e+00 9.92e-01f  1
  12 -5.2632685e+03 2.71e-20 6.77e+01  -3.8 3.25e-04    -  1.00e+00 1.00e+00f  1
  13 -5.2632682e+03 0.00e+00 5.89e-02  -3.8 6.32e-05    -  1.00e+00 1.00e+00f  1
  14 -5.2632682e+03 2.71e-20 3.84e-04  -3.8 9.61e-06    -  1.00e+00 1.00e+00f  1
  15 -5.2632699e+03 2.71e-20 4.09e-01  -5.7 2.30e-04    -  7.05e-01 1.00e+00f  1
  16 -5.2632702e+03 1.36e-20 7.56e-02  -5.7 1.18e-04    -  1.00e+00 1.00e+00f  1
  17 -5.2632703e+03 7.11e-15 5.63e-02  -5.7 3.34e-05    -  1.00e+00 1.00e+00f  1
  18 -5.2632703e+03 7.11e-15 7.80e-03  -5.7 7.59e-06    -  1.00e+00 1.00e+00f  1
  19 -5.2632703e+03 1.36e-20 8.94e-05  -5.7 7.11e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.2632703e+03 0.00e+00 2.09e-08  -5.7 1.16e-08    -  1.00e+00 1.00e+00h  1
  21 -5.2632703e+03 7.11e-15 2.88e-01  -8.6 1.05e-05    -  9.89e-01 1.00e+00f  1
  22 -5.2632703e+03 7.11e-15 1.15e-01  -8.6 7.99e-07    -  1.00e+00 1.00e+00f  1
  23 -5.2632703e+03 0.00e+00 1.11e-01  -8.6 2.17e-07    -  1.00e+00 1.00e+00h  1
  24 -5.2632703e+03 2.17e-19 3.72e-02  -8.6 6.44e-08    -  1.00e+00 1.00e+00f  1
  25 -5.2632703e+03 2.17e-19 4.08e-03  -8.6 1.52e-08    -  1.00e+00 1.00e+00h  1
  26 -5.2632703e+03 0.00e+00 2.90e-05  -8.6 1.10e-09    -  1.00e+00 1.00e+00h  1
  27 -5.2632703e+03 0.00e+00 1.64e-09  -8.6 6.70e-12    -  1.00e+00 1.00e+00f  1
  28 -5.2632703e+03 7.11e-15 1.21e-01 -11.0 1.56e-08    -  1.00e+00 1.00e+00f  1
  29 -5.2632703e+03 0.00e+00 3.20e-02 -11.0 1.10e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.2632703e+03 1.36e-20 1.81e-02 -11.0 2.43e-10    -  1.00e+00 1.00e+00f  1
  31 -5.2632703e+03 7.11e-15 2.31e-03 -11.0 6.16e-11    -  1.00e+00 1.00e+00h  1
  32 -5.2632703e+03 0.00e+00 5.14e-05 -11.0 8.28e-12    -  1.00e+00 1.00e+00h  1
  33 -5.2632703e+03 7.11e-15 1.92e-08 -11.0 1.57e-13    -  1.00e+00 1.00e+00f  1
  34 -5.2632703e+03 2.17e-19 4.54e-15 -11.0 7.13e-15    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1668174710686937e+03   -5.2632702821450785e+03
Dual infeasibility......:   4.5394639155843549e-15    2.0476575056664074e-14
Constraint violation....:   2.1684043449710089e-19    2.1684043449710089e-19
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909125526e-12    4.1007195077442948e-11
Overall NLP error.......:   9.0909090909125526e-12    4.1007195077442948e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.2605982e+03 3.90e-02 2.06e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.2571272e+03 3.00e-02 1.13e+01  -1.0 7.95e-02    -  9.90e-01 2.31e-01h  1
   2 -5.2498302e+03 8.92e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.02e-01h  1
   3 -5.2481217e+03 4.25e-03 3.07e+01  -1.0 1.06e-02    -  1.00e+00 5.23e-01h  1
   4 -5.2468852e+03 8.17e-04 2.47e+01  -1.0 3.26e-03    -  1.00e+00 8.08e-01h  1
   5 -5.2466588e+03 1.95e-04 4.89e+01  -1.0 1.27e-03    -  1.00e+00 7.61e-01h  1
   6 -5.2465887e+03 6.78e-19 1.46e+00  -1.0 4.50e-04    -  1.00e+00 1.00e+00f  1
   7 -5.2465886e+03 1.11e-18 2.26e-02  -1.0 9.26e-05    -  1.00e+00 1.00e+00f  1
   8 -5.2473499e+03 7.11e-15 3.30e-01  -2.5 3.20e-02    -  1.00e+00 1.00e+00f  1
   9 -5.2473872e+03 2.44e-19 6.44e-02  -2.5 1.87e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.2473921e+03 7.11e-15 4.60e-03  -2.5 2.70e-04    -  1.00e+00 1.00e+00f  1
  11 -5.2474113e+03 1.36e-19 1.74e+00  -3.8 1.12e-03    -  1.00e+00 9.92e-01f  1
  12 -5.2474136e+03 7.11e-15 6.80e+01  -3.8 3.24e-04    -  1.00e+00 1.00e+00f  1
  13 -5.2474133e+03 8.13e-20 6.02e-02  -3.8 6.40e-05    -  1.00e+00 1.00e+00f  1
  14 -5.2474133e+03 0.00e+00 3.92e-04  -3.8 9.40e-06    -  1.00e+00 1.00e+00f  1
  15 -5.2474150e+03 4.07e-20 4.10e-01  -5.7 2.30e-04    -  7.05e-01 1.00e+00f  1
  16 -5.2474153e+03 1.36e-20 7.58e-02  -5.7 1.18e-04    -  1.00e+00 1.00e+00f  1
  17 -5.2474153e+03 2.17e-19 5.64e-02  -5.7 3.33e-05    -  1.00e+00 1.00e+00f  1
  18 -5.2474153e+03 7.11e-15 7.83e-03  -5.7 7.55e-06    -  1.00e+00 1.00e+00f  1
  19 -5.2474153e+03 7.11e-15 9.09e-05  -5.7 7.05e-07    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.2474153e+03 7.11e-15 2.22e-08  -5.7 1.17e-08    -  1.00e+00 1.00e+00h  1
  21 -5.2474154e+03 7.11e-15 2.89e-01  -8.6 1.04e-05    -  9.89e-01 1.00e+00f  1
  22 -5.2474154e+03 7.11e-15 1.15e-01  -8.6 7.92e-07    -  1.00e+00 1.00e+00f  1
  23 -5.2474154e+03 7.11e-15 1.11e-01  -8.6 2.19e-07    -  1.00e+00 1.00e+00h  1
  24 -5.2474154e+03 7.11e-15 3.74e-02  -8.6 6.48e-08    -  1.00e+00 1.00e+00h  1
  25 -5.2474154e+03 7.11e-15 4.16e-03  -8.6 1.51e-08    -  1.00e+00 1.00e+00h  1
  26 -5.2474154e+03 2.17e-19 3.03e-05  -8.6 1.06e-09    -  1.00e+00 1.00e+00h  1
  27 -5.2474154e+03 2.17e-19 1.81e-09  -8.6 6.03e-12    -  1.00e+00 1.00e+00h  1
  28 -5.2474154e+03 2.17e-19 1.20e-01 -11.0 1.56e-08    -  1.00e+00 1.00e+00f  1
  29 -5.2474154e+03 2.17e-19 3.15e-02 -11.0 1.07e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.2474154e+03 0.00e+00 1.75e-02 -11.0 2.46e-10    -  1.00e+00 1.00e+00h  1
  31 -5.2474154e+03 7.11e-15 2.17e-03 -11.0 6.19e-11    -  1.00e+00 1.00e+00f  1
  32 -5.2474154e+03 2.71e-20 4.54e-05 -11.0 8.08e-12    -  1.00e+00 1.00e+00h  1
  33 -5.2474154e+03 0.00e+00 1.50e-08 -11.0 1.45e-13    -  1.00e+00 1.00e+00h  1
  34 -5.2474154e+03 1.36e-20 7.02e-15 -11.0 5.07e-17    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1670686991676259e+03   -5.2474153646261902e+03
Dual infeasibility......:   7.0214774213193986e-15    3.1570213929381813e-14
Constraint violation....:   1.3552527156068805e-20    1.3552527156068805e-20
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909112956e-12    4.0874865443731825e-11
Overall NLP error.......:   9.0909090909112956e-12    4.0874865443731825e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.
┌ Warning: Verbosity toggle: missing_second_order_ad
│  The selected optimization algorithm requires second order derivatives, but `SecondOrder` ADtype was not provided. So a `SecondOrder` with AutoForwardDiff() for both inner and outer will be created, this can be suboptimal and not work in some cases so an explicit `SecondOrder` ADtype is recommended.
└ @ OptimizationBase ~/.julia/packages/OptimizationBase/TvAnm/src/cache.jl:116
┌ Info: Verbosity toggle: unsupported_kwargs
└  common abstol is currently not used by IpoptOptimizer(1.0e-12, 1000, 1.0e-12, 1.0e-12, 0.0001, "no", "no", "mumps", "none", "", "", "yes", "gradient-based", 100.0, "no", "no", "monotone", "quality-function", 0.1, "obj-constr-filter", "no", "exact", 6, "bfgs", "no", "filter", "no", Dict{String, Any}())
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

Number of nonzeros in equality constraint Jacobian...:       32
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       36

Total number of variables............................:        8
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        8
                     variables with only upper bounds:        0
Total number of equality constraints.................:        4
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0 -5.2448117e+03 3.90e-02 2.06e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -5.2413493e+03 3.00e-02 1.13e+01  -1.0 7.94e-02    -  9.90e-01 2.31e-01h  1
   2 -5.2340763e+03 8.91e-03 1.03e+01  -1.0 2.14e-02    -  1.00e+00 7.03e-01h  1
   3 -5.2323742e+03 4.25e-03 3.07e+01  -1.0 1.06e-02    -  1.00e+00 5.23e-01h  1
   4 -5.2311431e+03 8.19e-04 2.48e+01  -1.0 3.26e-03    -  1.00e+00 8.07e-01h  1
   5 -5.2309165e+03 1.95e-04 4.87e+01  -1.0 1.27e-03    -  1.00e+00 7.62e-01h  1
   6 -5.2308468e+03 4.15e-18 1.45e+00  -1.0 4.51e-04    -  1.00e+00 1.00e+00f  1
   7 -5.2308467e+03 5.07e-18 2.30e-02  -1.0 9.31e-05    -  1.00e+00 1.00e+00f  1
   8 -5.2316052e+03 1.82e-18 3.31e-01  -2.5 3.20e-02    -  1.00e+00 1.00e+00f  1
   9 -5.2316424e+03 2.44e-19 6.46e-02  -2.5 1.87e-03    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -5.2316474e+03 7.11e-15 4.65e-03  -2.5 2.71e-04    -  1.00e+00 1.00e+00f  1
  11 -5.2316665e+03 7.11e-15 1.74e+00  -3.8 1.12e-03    -  1.00e+00 9.92e-01f  1
  12 -5.2316688e+03 2.17e-19 6.82e+01  -3.8 3.23e-04    -  1.00e+00 1.00e+00f  1
  13 -5.2316685e+03 7.11e-15 6.14e-02  -3.8 6.48e-05    -  1.00e+00 1.00e+00f  1
  14 -5.2316684e+03 7.11e-15 4.01e-04  -3.8 9.19e-06    -  1.00e+00 1.00e+00f  1
  15 -5.2316702e+03 7.11e-15 4.11e-01  -5.7 2.30e-04    -  7.05e-01 1.00e+00f  1
  16 -5.2316705e+03 7.11e-15 7.59e-02  -5.7 1.18e-04    -  1.00e+00 1.00e+00f  1
  17 -5.2316705e+03 7.11e-15 5.65e-02  -5.7 3.33e-05    -  1.00e+00 1.00e+00f  1
  18 -5.2316705e+03 2.17e-19 7.86e-03  -5.7 7.51e-06    -  1.00e+00 1.00e+00f  1
  19 -5.2316705e+03 1.36e-20 9.25e-05  -5.7 6.99e-07    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20 -5.2316705e+03 2.17e-19 2.37e-08  -5.7 1.19e-08    -  1.00e+00 1.00e+00h  1
  21 -5.2316705e+03 7.11e-15 2.89e-01  -8.6 1.04e-05    -  9.89e-01 1.00e+00f  1
  22 -5.2316705e+03 7.11e-15 1.15e-01  -8.6 7.86e-07    -  1.00e+00 1.00e+00f  1
  23 -5.2316705e+03 7.11e-15 1.11e-01  -8.6 2.21e-07    -  1.00e+00 1.00e+00h  1
  24 -5.2316705e+03 7.11e-15 3.75e-02  -8.6 6.52e-08    -  1.00e+00 1.00e+00h  1
  25 -5.2316705e+03 2.17e-19 4.23e-03  -8.6 1.50e-08    -  1.00e+00 1.00e+00h  1
  26 -5.2316705e+03 0.00e+00 3.17e-05  -8.6 1.02e-09    -  1.00e+00 1.00e+00h  1
  27 -5.2316705e+03 7.11e-15 1.99e-09  -8.6 5.42e-12    -  1.00e+00 1.00e+00f  1
  28 -5.2316705e+03 7.11e-15 1.18e-01 -11.0 1.56e-08    -  1.00e+00 1.00e+00h  1
  29 -5.2316705e+03 7.11e-15 3.10e-02 -11.0 1.04e-09    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30 -5.2316705e+03 7.11e-15 1.70e-02 -11.0 2.49e-10    -  1.00e+00 1.00e+00h  1
  31 -5.2316705e+03 2.17e-19 2.03e-03 -11.0 6.21e-11    -  1.00e+00 1.00e+00h  1
  32 -5.2316705e+03 2.17e-19 3.99e-05 -11.0 7.88e-12    -  1.00e+00 1.00e+00h  1
  33 -5.2316705e+03 7.11e-15 1.16e-08 -11.0 1.33e-13    -  1.00e+00 1.00e+00h  1
  34 -5.2316705e+03 0.00e+00 7.78e-15 -11.0 7.12e-15    -  1.00e+00 1.00e+00   0

Number of Iterations....: 34

                                   (scaled)                 (unscaled)
Objective...............:  -1.1673208283112774e+03   -5.2316705411824496e+03
Dual infeasibility......:   7.7761193144053897e-15    3.4850825373130641e-14
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.0909090909104765e-12    4.0743418715734215e-11
Overall NLP error.......:   9.0909090909104765e-12    4.0743418715734215e-11


Number of objective function evaluations             = 35
Number of objective gradient evaluations             = 35
Number of equality constraint evaluations            = 35
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 35
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 34
Total seconds in IPOPT                               = 0.004

EXIT: Optimal Solution Found.

The figures can then be drawn.

julia
p1 = plot(collect(temperatures), pH_vals,
    xlabel = "T (°C)", ylabel = "pH", label = "pH",
    marker = :circle, linewidth = 2, title = "pH")
p2 = plot(collect(temperatures), nCa_vals,
    xlabel = "T (°C)", ylabel = "n (mmol)", label = "Ca²⁺",
    marker = :circle, linewidth = 2, title = "Dissolved species")
plot!(p2, collect(temperatures), nCal_vals,
    label = "Cal", marker = :square, linewidth = 2)
plot(p1, p2, layout = (1, 2), left_margin = 8Plots.mm, bottom_margin = 8Plots.mm, size = (900, 400))

Retrograde Kₛₚ, and yet more dissolved calcium

Calcite is retrograde soluble: its solubility product falls as temperature rises. The sweep above reproduces that — the ionic product it settles on goes from at 10 °C to at 30 °C, matching the the database itself gives to within 0.003 log units, and at 25 °C is the accepted value for calcite.

The dissolved calcium nevertheless increases, from 0.146 to 0.158 mmol/L. That is not a contradiction: this system is closed, with 1 mmol of total carbonate and no CO₂ reservoir. As temperature rises the pH drops from 9.83 to 9.43, which shifts carbonate to bicarbonate and takes free CO₃²⁻ from 26.5 down to 19.2 µmol/L — more than enough to offset the smaller . The familiar statement that retrograde solubility means less dissolved calcium holds for a system buffered at a fixed CO₂ partial pressure, not for a sealed one. Fix the partial pressure instead (add a gas phase) and the sign flips.


Activity models

All activity models inherit from AbstractActivityModel. Three built-in models are provided, covering ideal behavior through to the extended Debye-Hückel level used by standard geochemical codes.

Choosing a model

ModelFormulaValid rangeParameters needed
DiluteSolutionModelRaoult / HenryI ≪ 1 mol/kgnone
HKFActivityModelB-dot extended Debye-HückelI ≲ 1 mol/kgA, B, (defaults at 25 °C)
DaviesActivityModelDavies equationI ≲ 0.5 mol/kgA, b (defaults at 25 °C)

DiluteSolutionModel (ideal dilute solution)

PhaseLawExpression
Solvent (H₂O)Raoultln a = ln xₛ
Aqueous solutesHenryln a = ln(cᵢ / c°), c° = 1 mol/L
CrystalsPure solidln a = 0
GasIdeal mixtureln a = ln xᵢ
julia
state_eq = equilibrate(state)   # DiluteSolutionModel is the default

HKFActivityModel (extended Debye-Hückel B-dot)

Implements the extended Debye-Hückel model of Helgeson (Helgeson, 1969) and Helgeson, Kirkham & Flowers (Helgeson et al., 1981), identical to the model used by PHREEQC (Parkhurst and Appelo, 2013) and EQ3/6.

Ion activity coefficient:

log₁₀ γᵢ = −A zᵢ² √I / (1 + B åᵢ √I)  +  Ḃ I

Neutral aqueous species (salting-out):

log₁₀ γᵢ = Kₙ I

Water activity is computed from the osmotic coefficient via Gibbs-Duhem (not Raoult), which is accurate up to I ≈ 1 mol/kg.

Ionic radius lookup (priority order):

  1. model.å — one common radius for every ion, when given. Short-circuits the rest of the chain.

  2. sp[:å] — explicit value set in species properties.

  3. REJ_HKF — Helgeson et al. (1981) Table 3 (27 common ions) (Helgeson et al., 1981).

  4. REJ_CHARGE_DEFAULT — fallback by formal charge (Xu et al., 2011).

  5. model.å_default (default: 3.72 Å).

å_default does not impose a common ionic radius

It is the last resort of the chain above, reached only for a charge that neither table covers — in practice |z| ≥ 5. Setting it changes essentially nothing for a real solution. Pass å to impose one common radius, which is what GEM-Selektor, PHREEQC's -gamma and most published cement models actually use.

Usage:

julia
# Fixed A, B at 25 °C / 1 bar (fast — suitable for isothermal calculations)
state_eq = equilibrate(state; model=HKFActivityModel())

# Temperature-dependent A and B (recomputed from T, P at each equilibrium solve)
state_eq = equilibrate(state; model=HKFActivityModel(temperature_dependent=true))

# Custom parameters
model = HKFActivityModel(A=0.52, B=0.33, Ḃ=0.04)

# One common ion size of 3.72 Å, overriding the per-species tables
model = HKFActivityModel= 3.72)

# å = 0 collapses the denominator to 1: the Debye-Hückel limiting law plus Ḃ I
model = HKFActivityModel= 0.0)

Reproducing a GEM-Selektor CEMDATA18 run

CEMDATA18 (Lothenbach et al., 2019) carries no ion-size parameter, so a GEM-Selektor run of a Portland cement starts from å = 0 and carries the whole non-ideality in the B-dot term, with no salting-out on the neutral species. For a KOH-dominated pore solution that is

julia
model = HKFActivityModel= 0.0, Ḃ = 0.097637, Kₙ = 0.0)

which reproduces the activity coefficients such a run reports to 0.25 % on the monovalent ions and 1.2 % on the divalent ones. The package defaults are a different and more defensible model — the limiting law has no validity at I ≈ 0.2 mol/kg — and give divalent coefficients about twice as large, so the two must not be mixed in one comparison.

The A and B parameters depend on the water dielectric constant and density and can be computed explicitly via hkf_debye_huckel_params:

julia
ab = hkf_debye_huckel_params(298.15, 1e5)   # → (A=0.5114, B=0.3288)

Valid range

The B-dot model is reliable for I ≲ 1 mol/kg. For higher ionic strengths (brines, evaporites), use the Pitzer model (planned future extension).


DaviesActivityModel (Davies equation)

Simpler alternative with no species-specific ionic radii (Davies, 1962). Suitable when ionic radii data are unavailable or for rapid screening calculations.

Ion activity coefficient:

log₁₀ γᵢ = −A zᵢ² (√I / (1 + √I)  −  b I)

Water activity uses the Raoult (mole fraction) approximation.

julia
state_eq = equilibrate(state; model=DaviesActivityModel())

# Temperature-dependent A
state_eq = equilibrate(state; model=DaviesActivityModel(temperature_dependent=true))

Custom activity models

To implement a custom activity model, define a new subtype and extend activity_model:

julia
struct MyModel <: AbstractActivityModel
    # model parameters
end

function ChemistryLab.activity_model(cs::ChemicalSystem, ::MyModel)
    # Precompute species indices and constants here (called once)
    idx_solvent = only(cs.idx_solvent)
    # ...

    # Return a closure lna(n, p) -> Vector compatible with ForwardDiff
    function lna(n::AbstractVector, p)
        # p contains at minimum: p.ΔₐG⁰overRT, p.T, p.P, p.ϵ
        # n is dimensionless mole vector, same indexing as cs.species
        out = zeros(eltype(n), length(n))
        # ... fill log-activities ...
        return out
    end
    return lna
end

Pass your model to equilibrate or EquilibriumSolver:

julia
state_eq = equilibrate(state; model=MyModel(...))

A custom model should also declare its solute concentration scale, so that activity_coefficients divides by the right thing:

julia
ChemistryLab.concentration_scale(::MyModel) = :molality

Reading the aqueous properties back

The activity closures compute the molalities, the ionic strength and the activity coefficients on their way to the log-activities. All of it is readable off a state:

callreturns
molalities(state)mᵢ of every solute, mol/kg of solvent
ionic_strength(state)I = ½ Σ mⱼ zⱼ², mol/kg
activity_coefficients(state, model)γᵢ of every aqueous species
log_activities(state, model)ln aᵢ of every species
activities(state, model)aᵢ of every species
pH(state, model)−log₁₀ a(H⁺)
pOH(state, model)−log₁₀ a(OH⁻)
julia
eq = equilibrate(state; model = HKFActivityModel())

ionic_strength(eq)                      # 0.212 mol/kg
molalities(eq)["K+"]                    # 0.146 mol/kg
activity_coefficients(eq, model)["Ca+2"]
activities(eq, model)["H2O@"]           # water activity
pH(eq, model)                           # activity convention

molalities and ionic_strength need no model: they are properties of the composition, and every model in the package computes the ionic strength this way. When comparing against another code, compare the ionic strength first — if it disagrees, the two are not describing the same solution, whatever their volumes happen to agree on.

Two conventions of pH, 0.2 units apart

The one-argument pH(state) and the two-argument pH(state, model) are different quantities:

  • pH(state) is −log₁₀ c(H⁺), a concentration in mol/L over the computed liquid volume, and in an alkaline solution it is reconstructed from OH⁻ through pKw. It is stored on the state and needs no activity model.

  • pH(state, model) is −log₁₀ a(H⁺), the activity on the molality scale. This is what GEM-Selektor, PHREEQC and Reaktoro report.

On a Portland cement pore solution at I ≈ 0.2 mol/kg, with γ(H⁺) ≈ 0.61, the two differ by about 0.21 units (13.31 against 13.10). Comparing the wrong one against another code means chasing a discrepancy that is a convention, not a result.

γ comes from the formula, not from a ratio

activity_coefficients evaluates the model's own expression, rather than dividing an activity by a concentration. The ratio agrees for an abundant solute — the test suite checks that it does — but a species parked at the solver's 1e-16 mol lower bound has its log-activity dominated by the closures' + ϵ regularization, and the ratio then returns values of order 1e300 for a charge class whose only members are trace. The formula depends on the ionic strength and the charge alone, so it is exact at any amount.

Relatedly, an activity is a number on a scale, and nothing in the number says which. DiluteSolutionModel puts its solutes on the molarity scale and takes ρ = 1 kg/L, so its activities coincide numerically with molalities even though the scale differs; the other two models are on the molality scale. concentration_scale is the only way to tell them apart.


Solid solutions

Pure crystalline species have activity ln a = 0. Solid solutions are mineral phases with variable composition (e.g. C-S-H, AFm, hydrogarnet), where the activity of each end-member depends on its mole fraction within the phase.

Defining end-members and phases

End-member species must carry aggregate_state = AS_CRYSTAL. SolidSolutionPhase automatically requalifies any end-member whose class is not already SC_SSENDMEMBER, so database species with SC_COMPONENT can be passed directly.

Workflow A — pass database species directly:

julia
using ChemistryLab

substances = build_species(datapath("cemdata18-thermofun.json"); verbose = false)
dict = Dict(symbol(s) => s for s in substances)

# SolidSolutionPhase requalifies SC_COMPONENT → SC_SSENDMEMBER automatically
ss_afm = SolidSolutionPhase("AFm",
    [dict["monosulphate12"], dict["monocarbonate"]])

Workflow B — automated via build_solid_solutions and a TOML file:

julia
# Load all phases defined in the TOML
ss_phases = build_solid_solutions(datapath("solid_solutions.toml"), dict)

See the Databases tutorial for the TOML format and the pre-built data/solid_solutions.toml file shipped with ChemistryLab.

What the shipped file is, and is not

Two of its entries reproduce CEMDATA18 (Lothenbach et al., 2019) phases of the same name. CSHQ is the six-end-member C-S-H of Kulik's downscaled solid solution model (Kulik, 2011); its KSiOH and NaSiOH members carry the uptake of potassium and sodium, whose records name Robie & Hemingway (Robie and Hemingway, 1995) among their sources, and they are what fixes the pore-solution pH of a Portland cement — leaving them out strands the alkalis in solution. C3(AF)S0.84H is the Fe-siliceous hydrogarnet.

AFm, Hydrogarnet and Hydrotalcite are deliberate alternatives to the CEMDATA18 phase model, not reproductions of it: GEM-Selektor treats monocarbonate, C3AH6, C3FH6 and hydrotalcite as pure phases, its AFm solid solution is C4AH13 + monosulphate12, and its hydrotalcite solid solution is Mg3AlC0.5OH + Mg3FeC0.5OH at Mg:Al = 3. Reproducing a published GEM-Selektor result means declaring the phases in the script, as above, rather than taking this file wholesale.

Then pass solid_solutions as a keyword to ChemicalSystem:

julia
cs = ChemicalSystem(
    [H2O_sp, dict["monosulphate12"], dict["monocarbonate"], ...],
    ["H2O@", "Al+3", ...];           # primaries
    solid_solutions = [ss_afm],      # or solid_solutions = ss_phases
)

Activity models for solid solutions

ModelFormulaNotes
IdealSolidSolutionModelln aᵢ = ln xᵢDefault, any number of end-members
RedlichKisterModelln aᵢ = ln xᵢ + ln γᵢ (Margules)Binary only (2 end-members), parameters in J/mol

The solid-solution activity is computed inside the aqueous activity closure — no separate activity model is needed. The existing equilibrate(state) call handles solid solutions automatically.

Ideal solid solution

julia
ss = SolidSolutionPhase("AFm", [em_ms, em_mc])   # IdealSolidSolutionModel() by default
cs = ChemicalSystem([...]; solid_solutions=[ss])
state_eq = equilibrate(state)

Non-ideal binary: Redlich-Kister

julia
# Interaction parameters for monosulfoaluminate-monocarboaluminate (example values)
rk = RedlichKisterModel(a0 = 3000.0, a1 = 500.0)          # a2 defaults to 0.0
# or 3-parameter:  RedlichKisterModel(a0 = 3000.0, a1 = 500.0, a2 = 50.0)
ss = SolidSolutionPhase("AFm", [em_ms, em_mc]; model=rk)

Activity coefficients (Guggenheim / ThermoCalc convention):

Valid range

RedlichKisterModel requires exactly 2 end-members. For ternary or higher-order solid solutions, use the ideal model (IdealSolidSolutionModel).

Integration with aqueous models

Solid-solution activities are computed independently of the aqueous activity model. You can combine HKFActivityModel() for the aqueous phase with any solid-solution model — the same equilibrate call handles both.