Chemical Equilibrium

ChemistryLab computes thermodynamic equilibrium by minimising 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.

using Optimization, OptimizationIpopt
using ChemistryLab
using DynamicQuantities

substances = build_species("../../../data/slop98-inorganic-thermofun.json")

# 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"])
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₃]
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)
ChemicalState{Species{Int64}, AbstractReaction, DynamicQuantities.Quantity{Float64, DynamicQuantities.SymbolicDimensions{DynamicQuantities.FRInt32}}}
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│           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.00015563│          0.00623736│         -0.00286963│         0.000155171│
│       HCO3-│         0.000134262│          0.00819215│          0.00325061│         0.000133866│
│         OH-│          3.41433e-5│         0.000580675│        -0.000160741│          3.40424e-5│
│       CO3-2│          2.12763e-5│          0.00127675│        -0.000128886│          2.12134e-5│
│        CO2@│          9.19514e-8│          4.04669e-6│          3.01662e-6│          9.16797e-8│
│          H+│          3.83001e-9│          3.86065e-9│                 0.0│          3.81869e-9│
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│   # solid #│             n [mol]│               m [g]│             V [cm³]│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│  tot. solid│          0.00084437│           0.0845096│           0.0311859│                    │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│         Cal│          0.00084437│           0.0845096│           0.0311859│                    │
╞════════════════════════════════════════════════════════════════════════════════════════════════╡
│   # 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 always takes priority for equilibrate(state).

Explicit solver (always works)

Pass the solver as the second positional argument:

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

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

Default shortcut

When only one extension is loaded:

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

using OptimaSolver
state_eq = equilibrate(state)   # → OptimaOptimizer

With both loaded, OptimaSolver always wins:

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

Inspecting the equilibrium state

The returned ChemicalState carries all derived thermodynamic quantities:

println("pH      = ", pH(state_eq))
println("pOH     = ", pOH(state_eq))
println("porosity   = ", porosity(state_eq))
println("saturation = ", saturation(state_eq))
pH      = 9.527415206123138
pOH     = 4.4679798329298395
porosity   = 0.9999689071703629
saturation = 1.0

Phase volumes and mole amounts are accessible via named tuples:

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.0010029635119444432 m³
V solid  = 3.1185943268259964e-8 m³
V total  = 0.0010029946978877115 m³
n liquid = 55.50960918339471 mol
n solid  = 0.0008443695256573842 mol

Individual species amounts (in mol):

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.50926377533243 mol
H+                  3.830008572261524e-9 mol
OH-                 3.414328479796852e-5 mol
CO2@                9.195137148453631e-8 mol
HCO3-               0.00013426225206497052 mol
CO3-2               2.127626686915876e-5 mol
Ca+2                0.00015563047716080978 mol
Cal                 0.0008443695256573842 mol

Scaling and normalisation

It is often useful to express a composition relative to a reference amount — per mole, per kilogram, or per cubic metre 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:

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.

# 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.00015561488655492893 mol  mol/kg
pH   = 9.527415206123138
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 optimisation variable space:

variable_spaceVariablesRecommended when
Val(:linear)mole amounts nᵢ ≥ 0most systems, default
Val(:log)log nᵢsystems spanning many orders of magnitude
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:

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:

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:

state_eq2 = solve(solver, state)
ChemicalState{Species{Int64}, AbstractReaction, DynamicQuantities.Quantity{Float64, DynamicQuantities.SymbolicDimensions{DynamicQuantities.FRInt32}}}
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│           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:

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)

s = ChemicalState(cs)
for θ in temperatures
    set_temperature!(s, (273.15 + θ) * u"K")
    s_eq = solve(solver, s)
    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
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4956935e-13 0.00e+00 3.32e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.2025432e-13 1.48e-31 1.50e+08  -1.0 3.54e-08    -  1.00e+00 1.37e-08f 12
   2 -1.2047221e-13 1.48e-31 1.53e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.2047226e-13 9.86e-32 3.85e-07 -11.0 6.87e-22    -  1.00e+00 1.00e+00   0
   4 -4.9364991e-13 9.37e-31 2.46e+00 -11.0 8.10e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0668167e-12 1.63e-30 1.95e+00 -11.0 1.67e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.2338793e-12 1.10e-29 9.77e-01 -11.0 7.72e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5455090e-12 8.83e-30 8.84e-02 -11.0 1.40e-14    -  1.00e+00 1.00e+00h  1
   8 -3.5476952e-12 9.66e-30 6.00e-04 -11.0 1.94e-15    -  1.00e+00 1.00e+00   0
   9 -3.5477255e-12 4.78e-30 6.40e-08 -11.0 1.49e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.5477255e-12 1.01e-29 1.78e-15 -11.0 1.57e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.4056197044188541e-13   -3.5477254668958915e-12
Dual infeasibility......:   1.7763568394002505e-15    8.5097893882865893e-15
Constraint violation....:   1.0107280348144214e-29    1.0107280348144214e-29
Variable bound violation:   1.0040723276967796e-13    1.0040723276967796e-13
Complementarity.........:   9.0909090909090936e-12    4.3550777634191928e-11
Overall NLP error.......:   9.0909090909090936e-12    4.3550777634191928e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4904656e-13 0.00e+00 3.33e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1975977e-13 4.93e-32 1.50e+08  -1.0 3.53e-08    -  1.00e+00 1.37e-08f 12
   2 -1.1997762e-13 4.93e-32 3.29e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1997767e-13 4.93e-32 5.60e-07 -11.0 6.88e-22    -  1.00e+00 1.00e+00   0
   4 -4.9231687e-13 7.40e-31 2.46e+00 -11.0 8.10e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0648554e-12 3.20e-30 1.95e+00 -11.0 1.67e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.2265479e-12 1.10e-29 9.99e-01 -11.0 7.72e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5392518e-12 3.99e-30 6.61e-02 -11.0 1.39e-14    -  1.00e+00 1.00e+00h  1
   8 -3.5412989e-12 9.66e-30 4.19e-04 -11.0 1.51e-15    -  1.00e+00 1.00e+00   0
   9 -3.5413213e-12 8.83e-30 3.12e-08 -11.0 1.04e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.5413213e-12 7.84e-30 1.24e-14 -11.0 7.67e-22    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.4177754309316537e-13   -3.5413213022949307e-12
Dual infeasibility......:   1.2434497875801753e-14    5.9363555315110397e-14
Constraint violation....:   7.8393052456338048e-30    7.8393052456338048e-30
Variable bound violation:   1.0049188974296617e-13    1.0049188974296617e-13
Complementarity.........:   9.0909090909090936e-12    4.3400922986447909e-11
Overall NLP error.......:   9.0909090909090936e-12    4.3400922986447909e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4852741e-13 0.00e+00 3.33e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1926831e-13 9.86e-32 1.50e+08  -1.0 3.52e-08    -  1.00e+00 1.38e-08f 12
   2 -1.1948613e-13 4.93e-32 2.53e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1948617e-13 4.93e-32 2.69e-07 -11.0 6.89e-22    -  1.00e+00 1.00e+00   0
   4 -4.9100649e-13 8.38e-31 2.46e+00 -11.0 8.11e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0629479e-12 2.96e-30 1.96e+00 -11.0 1.68e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.2194026e-12 1.19e-29 1.02e+00 -11.0 7.73e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5331753e-12 4.68e-30 4.41e-02 -11.0 1.38e-14    -  1.00e+00 1.00e+00h  1
   8 -3.5351184e-12 5.57e-30 2.74e-04 -11.0 1.08e-15    -  1.00e+00 1.00e+00   0
   9 -3.5351341e-12 4.63e-30 1.33e-08 -11.0 6.75e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 9

                                   (scaled)                 (unscaled)
Objective...............:  -7.4302889907565039e-13   -3.5351340795147369e-12
Dual infeasibility......:   1.3347269955943375e-08    6.3502764089576249e-08
Constraint violation....:   4.6345578181734444e-30    4.6345578181734444e-30
Variable bound violation:   1.0057899537809294e-13    1.0057899537809294e-13
Complementarity.........:   9.0909090909087608e-12    4.3252130006009164e-11
Overall NLP error.......:   1.3347269955943375e-08    6.3502764089576249e-08


Number of objective function evaluations             = 22
Number of objective gradient evaluations             = 10
Number of equality constraint evaluations            = 22
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 10
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Search Direction is becoming Too Small.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4801185e-13 0.00e+00 3.33e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1877992e-13 4.93e-32 1.50e+08  -1.0 3.51e-08    -  1.00e+00 1.38e-08f 12
   2 -1.1899770e-13 9.86e-32 1.24e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1899775e-13 9.86e-32 3.12e-07 -11.0 6.90e-22    -  1.00e+00 1.00e+00   0
   4 -4.8971827e-13 1.38e-30 2.46e+00 -11.0 8.11e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0610933e-12 1.77e-30 1.96e+00 -11.0 1.68e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.2124399e-12 5.08e-30 1.04e+00 -11.0 7.73e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5272760e-12 7.15e-30 2.25e-02 -11.0 1.37e-14    -  1.00e+00 1.00e+00f  1
   8 -3.5291493e-12 6.95e-30 1.63e-04 -11.0 7.22e-16    -  1.00e+00 1.00e+00   0
   9 -3.5291594e-12 2.96e-30 4.68e-09 -11.0 3.98e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 9

                                   (scaled)                 (unscaled)
Objective...............:  -7.4431558784044539e-13   -3.5291594320398967e-12
Dual infeasibility......:   4.6814605525469233e-09    2.2197063899574444e-08
Constraint violation....:   2.9582283945787943e-30    2.9582283945787943e-30
Variable bound violation:   1.0066849641161203e-13    1.0066849641161203e-13
Complementarity.........:   9.0909090909083569e-12    4.3104387558351086e-11
Overall NLP error.......:   4.6814605525469233e-09    2.2197063899574444e-08


Number of objective function evaluations             = 22
Number of objective gradient evaluations             = 10
Number of equality constraint evaluations            = 22
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 10
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Search Direction is becoming Too Small.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4749985e-13 0.00e+00 3.34e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1829458e-13 4.93e-32 1.50e+08  -1.0 3.49e-08    -  1.00e+00 1.39e-08f 12
   2 -1.1851233e-13 4.93e-32 2.15e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1851237e-13 4.93e-32 3.90e-07 -11.0 6.91e-22    -  1.00e+00 1.00e+00   0
   4 -4.8845173e-13 1.43e-30 2.47e+00 -11.0 8.12e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0592903e-12 1.63e-30 1.97e+00 -11.0 1.68e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.2056568e-12 1.64e-29 1.06e+00 -11.0 7.74e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5215504e-12 4.78e-30 2.20e-02 -11.0 1.36e-14    -  1.00e+00 1.00e+00h  1
   8 -3.5233876e-12 1.03e-29 8.21e-05 -11.0 5.15e-16    -  1.00e+00 1.00e+00   0
   9 -3.5233932e-12 8.83e-30 1.18e-09 -11.0 1.99e-18    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 9

                                   (scaled)                 (unscaled)
Objective...............:  -7.4563719284938099e-13   -3.5233932144404266e-12
Dual infeasibility......:   1.1758363172020836e-09    5.5562326303635941e-09
Constraint violation....:   8.8253813771600696e-30    8.8253813771600696e-30
Variable bound violation:   1.0076034198984540e-13    1.0076034198984540e-13
Complementarity.........:   9.0909090909086558e-12    4.2957684663769971e-11
Overall NLP error.......:   1.1758363172020836e-09    5.5562326303635941e-09


Number of objective function evaluations             = 22
Number of objective gradient evaluations             = 10
Number of equality constraint evaluations            = 22
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 10
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Search Direction is becoming Too Small.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4699138e-13 0.00e+00 3.34e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1781226e-13 4.93e-32 1.50e+08  -1.0 3.48e-08    -  1.00e+00 1.39e-08f 12
   2 -1.1802998e-13 4.93e-32 1.48e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1803003e-13 1.48e-31 6.34e-07 -11.0 6.92e-22    -  1.00e+00 1.00e+00   0
   4 -4.8720641e-13 1.38e-30 2.47e+00 -11.0 8.12e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0575380e-12 3.99e-30 1.97e+00 -11.0 1.68e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1990503e-12 4.63e-30 1.07e+00 -11.0 7.74e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5159957e-12 5.67e-30 2.34e-02 -11.0 1.35e-14    -  1.00e+00 1.00e+00f  1
   8 -3.5178297e-12 4.63e-30 3.00e-05 -11.0 4.05e-16    -  1.00e+00 1.00e+00   0
   9 -3.5178315e-12 4.63e-30 1.48e-10 -11.0 7.02e-19    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 9

                                   (scaled)                 (unscaled)
Objective...............:  -7.4699333051500644e-13   -3.5178314936023297e-12
Dual infeasibility......:   1.4754597543742420e-10    6.9484138337647392e-10
Constraint violation....:   4.6345578181734444e-30    4.6345578181734444e-30
Variable bound violation:   1.0085448390580427e-13    1.0085448390580427e-13
Complementarity.........:   9.0909090909091324e-12    4.2812010494695322e-11
Overall NLP error.......:   1.4754597543742420e-10    6.9484138337647392e-10


Number of objective function evaluations             = 22
Number of objective gradient evaluations             = 10
Number of equality constraint evaluations            = 22
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 10
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Search Direction is becoming Too Small.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4648640e-13 0.00e+00 3.34e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1733293e-13 9.86e-32 1.50e+08  -1.0 3.47e-08    -  1.00e+00 1.39e-08f 12
   2 -1.1755064e-13 9.86e-32 1.86e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1755068e-13 1.48e-31 7.54e-07 -11.0 6.92e-22    -  1.00e+00 1.00e+00   0
   4 -4.8598186e-13 1.63e-30 2.47e+00 -11.0 8.13e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0558352e-12 2.12e-30 1.98e+00 -11.0 1.69e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1926173e-12 3.35e-30 1.09e+00 -11.0 7.75e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5106090e-12 8.83e-30 3.99e-02 -11.0 1.36e-14    -  1.00e+00 1.00e+00f  1
   8 -3.5124719e-12 8.83e-30 3.95e-06 -11.0 6.81e-16    -  1.00e+00 1.00e+00   0
   9 -3.5124705e-12 9.66e-30 1.08e-12 -11.0 1.16e-19    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.5124705e-12 4.63e-30 8.88e-15 -11.0 4.34e-26    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.4838364751532561e-13   -3.5124705325103086e-12
Dual infeasibility......:   8.8817841970012523e-15    4.1685845717845905e-14
Constraint violation....:   4.6345578181734444e-30    4.6345578181734444e-30
Variable bound violation:   1.0095087629021677e-13    1.0095087629021677e-13
Complementarity.........:   9.0909090909090936e-12    4.2667354373071559e-11
Overall NLP error.......:   9.0909090909090936e-12    4.2667354373071559e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4598488e-13 0.00e+00 3.35e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1685659e-13 9.86e-32 1.50e+08  -1.0 3.46e-08    -  1.00e+00 1.40e-08f 12
   2 -1.1707427e-13 4.93e-32 2.05e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1707432e-13 4.93e-32 5.47e-07 -11.0 6.93e-22    -  1.00e+00 1.00e+00   0
   4 -4.8477766e-13 8.38e-31 2.47e+00 -11.0 8.13e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0541812e-12 1.63e-30 1.98e+00 -11.0 1.69e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1863551e-12 5.67e-30 1.11e+00 -11.0 7.75e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5053876e-12 9.27e-30 6.00e-02 -11.0 1.37e-14    -  1.00e+00 1.00e+00f  1
   8 -3.5073107e-12 3.35e-30 2.24e-06 -11.0 9.51e-16    -  1.00e+00 1.00e+00   0
   9 -3.5073068e-12 3.90e-30 1.38e-12 -11.0 2.61e-19    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.5073068e-12 5.47e-30 8.88e-15 -11.0 1.64e-25    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.4980781877477722e-13   -3.5073067774767852e-12
Dual infeasibility......:   8.8817841970012523e-15    4.1545501567496582e-14
Constraint violation....:   5.4727225299707694e-30    5.4727225299707694e-30
Variable bound violation:   1.0104947545874047e-13    1.0104947545874047e-13
Complementarity.........:   9.0909090909090936e-12    4.2523705767795002e-11
Overall NLP error.......:   9.0909090909090936e-12    4.2523705767795002e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4548678e-13 0.00e+00 3.35e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1638320e-13 9.86e-32 1.50e+08  -1.0 3.45e-08    -  1.00e+00 1.40e-08f 12
   2 -1.1660087e-13 4.93e-32 2.19e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1660091e-13 4.93e-32 2.80e-07 -11.0 6.94e-22    -  1.00e+00 1.00e+00   0
   4 -4.8359340e-13 1.38e-30 2.47e+00 -11.0 8.14e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0525750e-12 3.35e-30 1.99e+00 -11.0 1.69e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1802611e-12 1.01e-29 1.12e+00 -11.0 7.76e-14    -  1.00e+00 1.00e+00f  1
   7 -3.5003290e-12 8.83e-30 7.97e-02 -11.0 1.37e-14    -  1.00e+00 1.00e+00f  1
   8 -3.5023429e-12 1.01e-29 2.15e-05 -11.0 1.32e-15    -  1.00e+00 1.00e+00   0
   9 -3.5023368e-12 3.35e-30 7.46e-11 -11.0 5.12e-19    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.5023368e-12 3.99e-30 1.07e-14 -11.0 1.90e-24    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.5126554560901991e-13   -3.5023368463937066e-12
Dual infeasibility......:   1.0658141036401503e-14    4.9687357930928674e-14
Constraint violation....:   3.9936083326813723e-30    3.9936083326813723e-30
Variable bound violation:   1.0115023977162965e-13    1.0115023977162965e-13
Complementarity.........:   9.0909090909090920e-12    4.2381054292188414e-11
Overall NLP error.......:   9.0909090909090920e-12    4.2381054292188414e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4499207e-13 0.00e+00 3.35e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1591275e-13 4.93e-32 1.50e+08  -1.0 3.44e-08    -  1.00e+00 1.41e-08f 12
   2 -1.1613039e-13 9.86e-32 1.96e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1613044e-13 9.86e-32 4.03e-07 -11.0 6.95e-22    -  1.00e+00 1.00e+00   0
   4 -4.8242869e-13 1.63e-30 2.48e+00 -11.0 8.14e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0510157e-12 1.77e-30 2.00e+00 -11.0 1.70e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1743326e-12 5.67e-30 1.14e+00 -11.0 7.76e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4954307e-12 9.66e-30 9.90e-02 -11.0 1.38e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4975653e-12 4.78e-30 6.13e-05 -11.0 1.69e-15    -  1.00e+00 1.00e+00   0
   9 -3.4975575e-12 7.84e-30 6.70e-10 -11.0 1.50e-18    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4975575e-12 9.27e-30 1.07e-14 -11.0 1.65e-23    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.5275655403263730e-13   -3.4975575179789092e-12
Dual infeasibility......:   1.0658141036401503e-14    4.9521271000357649e-14
Constraint violation....:   9.2691156363468887e-30    9.2691156363468887e-30
Variable bound violation:   1.0125312950575730e-13    1.0125312950575730e-13
Complementarity.........:   9.0909090909090936e-12    4.2239389701538660e-11
Overall NLP error.......:   9.0909090909090936e-12    4.2239389701538660e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4450072e-13 0.00e+00 3.35e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1544520e-13 1.48e-31 1.50e+08  -1.0 3.42e-08    -  1.00e+00 1.41e-08f 12
   2 -1.1566284e-13 4.93e-32 2.15e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1566288e-13 4.93e-32 4.20e-07 -11.0 6.96e-22    -  1.00e+00 1.00e+00   0
   4 -4.8128315e-13 1.77e-30 2.48e+00 -11.0 8.15e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0495024e-12 1.63e-30 2.00e+00 -11.0 1.70e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1685672e-12 3.11e-30 1.15e+00 -11.0 7.77e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4906907e-12 9.66e-30 1.18e-01 -11.0 1.39e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4929749e-12 7.94e-30 1.19e-04 -11.0 2.06e-15    -  1.00e+00 1.00e+00   0
   9 -3.4929657e-12 1.02e-29 2.62e-09 -11.0 2.94e-18    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4929657e-12 1.01e-29 1.07e-14 -11.0 6.38e-23    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.5428059319056088e-13   -3.4929657218121374e-12
Dual infeasibility......:   1.0658141036401503e-14    4.9356329242033616e-14
Constraint violation....:   1.0107280348144214e-29    1.0107280348144214e-29
Variable bound violation:   1.0135810673510399e-13    1.0135810673510399e-13
Complementarity.........:   9.0909090909090936e-12    4.2098701890681467e-11
Overall NLP error.......:   9.0909090909090936e-12    4.2098701890681467e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4401269e-13 0.00e+00 3.36e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1498054e-13 1.48e-31 1.50e+08  -1.0 3.41e-08    -  1.00e+00 1.42e-08f 12
   2 -1.1519816e-13 9.86e-32 2.10e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1519821e-13 4.93e-32 3.90e-07 -11.0 6.97e-22    -  1.00e+00 1.00e+00   0
   4 -4.8015643e-13 1.38e-30 2.48e+00 -11.0 8.16e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0480345e-12 1.68e-30 2.01e+00 -11.0 1.70e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1629626e-12 5.67e-30 1.17e+00 -11.0 7.77e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4861066e-12 2.96e-30 1.37e-01 -11.0 1.40e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4885690e-12 5.57e-30 1.94e-04 -11.0 2.42e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4885585e-12 3.90e-30 7.02e-09 -11.0 4.79e-18    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4885585e-12 3.35e-30 8.88e-15 -11.0 1.71e-22    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.5583743392296687e-13   -3.4885585291872333e-12
Dual infeasibility......:   8.8817841970012523e-15    4.0993767474616745e-14
Constraint violation....:   3.3526588471893002e-30    3.3526588471893002e-30
Variable bound violation:   1.0146513522023081e-13    1.0146513522023081e-13
Complementarity.........:   9.0909090909090936e-12    4.1958980891635633e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1958980891635633e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4352795e-13 0.00e+00 3.36e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1451874e-13 4.93e-32 1.50e+08  -1.0 3.40e-08    -  1.00e+00 1.42e-08f 12
   2 -1.1473636e-13 9.86e-32 1.96e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1473640e-13 4.93e-32 5.08e-07 -11.0 6.98e-22    -  1.00e+00 1.00e+00   0
   4 -4.7904817e-13 1.73e-30 2.48e+00 -11.0 8.16e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0466111e-12 1.48e-30 2.01e+00 -11.0 1.71e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1575165e-12 1.62e-29 1.18e+00 -11.0 7.78e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4816766e-12 1.01e-29 1.55e-01 -11.0 1.41e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4843446e-12 3.90e-30 2.85e-04 -11.0 2.77e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4843331e-12 5.67e-30 1.52e-08 -11.0 7.01e-18    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4843331e-12 1.01e-29 5.33e-15 -11.0 3.69e-22    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.5742686743267756e-13   -3.4843331446189855e-12
Dual infeasibility......:   5.3290705182007514e-15    2.4514917327287913e-14
Constraint violation....:   1.0107280348144214e-29    1.0107280348144214e-29
Variable bound violation:   1.0157418030581493e-13    1.0157418030581493e-13
Complementarity.........:   9.0909090909090936e-12    4.1820216871284997e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1820216871284997e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4304647e-13 0.00e+00 3.36e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1405977e-13 4.93e-32 1.50e+08  -1.0 3.39e-08    -  1.00e+00 1.43e-08f 12
   2 -1.1427739e-13 4.93e-32 7.63e-06  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1427743e-13 4.93e-32 4.76e-07 -11.0 6.98e-22    -  1.00e+00 1.00e+00   0
   4 -4.7795804e-13 1.63e-30 2.49e+00 -11.0 8.17e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0452315e-12 1.68e-30 2.02e+00 -11.0 1.71e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1522267e-12 1.35e-29 1.19e+00 -11.0 7.78e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4773986e-12 5.47e-30 1.73e-01 -11.0 1.42e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4802993e-12 3.35e-30 3.89e-04 -11.0 3.11e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4802869e-12 8.83e-30 2.86e-08 -11.0 9.57e-18    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4802869e-12 6.95e-30 7.11e-15 -11.0 6.93e-22    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.5904870406757780e-13   -3.4802868980467698e-12
Dual infeasibility......:   7.1054273576010019e-15    3.2578839282861406e-14
Constraint violation....:   6.9518367272601665e-30    6.9518367272601665e-30
Variable bound violation:   1.0168520882625093e-13    1.0168520882625093e-13
Complementarity.........:   9.0909090909090936e-12    4.1682400129107372e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1682400129107372e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4256822e-13 0.00e+00 3.37e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1360363e-13 1.48e-31 1.50e+08  -1.0 3.38e-08    -  1.00e+00 1.43e-08f 12
   2 -1.1382124e-13 4.93e-32 2.24e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1382129e-13 4.93e-32 2.15e-07 -11.0 6.99e-22    -  1.00e+00 1.00e+00   0
   4 -4.7688572e-13 1.77e-30 2.49e+00 -11.0 8.17e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0438950e-12 2.61e-30 2.02e+00 -11.0 1.71e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1470912e-12 1.36e-29 1.21e+00 -11.0 7.79e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4732708e-12 3.80e-30 1.91e-01 -11.0 1.43e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4764306e-12 3.80e-30 5.07e-04 -11.0 3.45e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4764172e-12 3.80e-30 4.88e-08 -11.0 1.24e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4764172e-12 6.95e-30 7.11e-15 -11.0 1.18e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.6070277218596222e-13   -3.4764172375721984e-12
Dual infeasibility......:   7.1054273576010019e-15    3.2471855039122509e-14
Constraint violation....:   6.9518367272601665e-30    6.9518367272601665e-30
Variable bound violation:   1.0179818901789385e-13    1.0179818901789385e-13
Complementarity.........:   9.0909090909090936e-12    4.1545521094949129e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1545521094949129e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4209316e-13 0.00e+00 3.37e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1315027e-13 4.93e-32 1.50e+08  -1.0 3.37e-08    -  1.00e+00 1.44e-08f 12
   2 -1.1336789e-13 9.86e-32 1.67e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1336793e-13 9.86e-32 3.89e-07 -11.0 7.00e-22    -  1.00e+00 1.00e+00   0
   4 -4.7583090e-13 1.38e-30 2.49e+00 -11.0 8.18e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0426010e-12 2.51e-30 2.03e+00 -11.0 1.72e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1421081e-12 9.27e-30 1.22e+00 -11.0 7.80e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4692915e-12 3.35e-30 2.08e-01 -11.0 1.44e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4727359e-12 3.90e-30 6.36e-04 -11.0 3.79e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4727217e-12 1.01e-29 7.72e-08 -11.0 1.56e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4727217e-12 5.18e-30 8.88e-15 -11.0 1.86e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.6238891711407427e-13   -3.4727217227606241e-12
Dual infeasibility......:   8.8817841970012523e-15    4.0456995406693684e-14
Constraint violation....:   5.1768996905128900e-30    5.1768996905128900e-30
Variable bound violation:   1.0191309043790804e-13    1.0191309043790804e-13
Complementarity.........:   9.0909090909090936e-12    4.1409570326844450e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1409570326844450e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4162126e-13 0.00e+00 3.37e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1269968e-13 9.86e-32 1.50e+08  -1.0 3.36e-08    -  1.00e+00 1.44e-08f 12
   2 -1.1291730e-13 9.86e-32 1.72e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1291735e-13 1.48e-31 5.06e-07 -11.0 7.01e-22    -  1.00e+00 1.00e+00   0
   4 -4.7479327e-13 1.38e-30 2.49e+00 -11.0 8.19e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0413487e-12 2.12e-30 2.04e+00 -11.0 1.72e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1372754e-12 3.80e-30 1.23e+00 -11.0 7.80e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4654589e-12 2.96e-30 2.25e-01 -11.0 1.45e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4692131e-12 9.27e-30 7.76e-04 -11.0 4.11e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4691980e-12 9.66e-30 1.16e-07 -11.0 1.90e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4691980e-12 6.95e-30 1.24e-14 -11.0 2.79e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.6410700017651567e-13   -3.4691980184057811e-12
Dual infeasibility......:   1.2434497875801753e-14    5.6455097755467659e-14
Constraint violation....:   6.9518367272601665e-30    6.9518367272601665e-30
Variable bound violation:   1.0202988388879412e-13    1.0202988388879412e-13
Complementarity.........:   9.0909090909090936e-12    4.1274538508878113e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1274538508878113e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4115250e-13 0.00e+00 3.38e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1225184e-13 4.93e-32 1.50e+08  -1.0 3.35e-08    -  1.00e+00 1.45e-08f 12
   2 -1.1246947e-13 1.48e-31 2.10e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1246951e-13 9.86e-32 4.03e-07 -11.0 7.02e-22    -  1.00e+00 1.00e+00   0
   4 -4.7377255e-13 1.43e-30 2.50e+00 -11.0 8.19e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0401376e-12 3.35e-30 2.04e+00 -11.0 1.73e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1325913e-12 3.11e-30 1.25e+00 -11.0 7.81e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4617715e-12 3.80e-30 2.42e-01 -11.0 1.45e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4658599e-12 9.27e-30 9.26e-04 -11.0 4.44e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4658439e-12 3.35e-30 1.66e-07 -11.0 2.27e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4658439e-12 9.27e-30 1.07e-14 -11.0 3.98e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.6585689780042876e-13   -3.4658438887510452e-12
Dual infeasibility......:   1.0658141036401503e-14    4.8232839689177500e-14
Constraint violation....:   9.2691156363468887e-30    9.2691156363468887e-30
Variable bound violation:   1.0214854134833648e-13    1.0214854134833648e-13
Complementarity.........:   9.0909090909090936e-12    4.1140416449091051e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1140416449091051e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4068684e-13 0.00e+00 3.38e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1180672e-13 4.93e-32 1.50e+08  -1.0 3.34e-08    -  1.00e+00 1.45e-08f 12
   2 -1.1202436e-13 4.93e-32 2.10e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1202440e-13 4.93e-32 5.12e-07 -11.0 7.03e-22    -  1.00e+00 1.00e+00   0
   4 -4.7276845e-13 1.38e-30 2.50e+00 -11.0 8.20e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0389671e-12 1.48e-30 2.05e+00 -11.0 1.73e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1280541e-12 6.95e-30 1.26e+00 -11.0 7.81e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4582278e-12 3.90e-30 2.58e-01 -11.0 1.46e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4626743e-12 3.90e-30 1.09e-03 -11.0 4.75e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4626572e-12 9.66e-30 2.28e-07 -11.0 2.65e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4626572e-12 3.35e-30 1.60e-14 -11.0 5.49e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.6763850068398657e-13   -3.4626571921141279e-12
Dual infeasibility......:   1.5987211554602254e-14    7.2114977326004243e-14
Constraint violation....:   3.3526588471893002e-30    3.3526588471893002e-30
Variable bound violation:   1.0226903590442867e-13    1.0226903590442867e-13
Complementarity.........:   9.0909090909090936e-12    4.1007195077427342e-11
Overall NLP error.......:   9.0909090909090936e-12    4.1007195077427342e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.4022426e-13 0.00e+00 3.38e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1136430e-13 4.93e-32 1.50e+08  -1.0 3.32e-08    -  1.00e+00 1.46e-08f 12
   2 -1.1158195e-13 4.93e-32 2.34e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1158199e-13 4.93e-32 7.24e-07 -11.0 7.04e-22    -  1.00e+00 1.00e+00   0
   4 -4.7178070e-13 1.77e-30 2.50e+00 -11.0 8.21e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0378366e-12 2.96e-30 2.05e+00 -11.0 1.73e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1236621e-12 3.35e-30 1.27e+00 -11.0 7.82e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4548262e-12 2.96e-30 2.75e-01 -11.0 1.47e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4596541e-12 1.27e-29 1.25e-03 -11.0 5.06e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4596359e-12 6.95e-30 3.06e-07 -11.0 3.06e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4596359e-12 1.06e-29 2.31e-14 -11.0 7.34e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.6945171302302977e-13   -3.4596358758783439e-12
Dual infeasibility......:   2.3092638912203256e-14    1.0382993591044413e-13
Constraint violation....:   1.0600318413907346e-29    1.0600318413907346e-29
Variable bound violation:   1.0239134169434724e-13    1.0239134169434724e-13
Complementarity.........:   9.0909090909090936e-12    4.0874865443721925e-11
Overall NLP error.......:   9.0909090909090936e-12    4.0874865443721925e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

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 -1.3976471e-13 0.00e+00 3.38e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1 -1.1092455e-13 1.48e-31 1.50e+08  -1.0 3.31e-08    -  1.00e+00 1.46e-08f 12
   2 -1.1114222e-13 4.93e-32 3.29e-05  -2.5 6.25e-18    -  1.00e+00 1.00e+00   0
   3 -1.1114226e-13 9.86e-32 3.23e-07 -11.0 7.04e-22    -  1.00e+00 1.00e+00   0
   4 -4.7080904e-13 1.48e-30 2.50e+00 -11.0 8.21e-15    -  1.00e+00 1.00e+00f  1
   5 -1.0367456e-12 4.39e-30 2.06e+00 -11.0 1.74e-14  14.0 1.00e+00 1.00e+00f  1
   6 -3.1194137e-12 1.33e-29 1.28e+00 -11.0 7.83e-14    -  1.00e+00 1.00e+00f  1
   7 -3.4515653e-12 9.66e-30 2.91e-01 -11.0 1.48e-14    -  1.00e+00 1.00e+00f  1
   8 -3.4567975e-12 4.68e-30 1.43e-03 -11.0 5.36e-15    -  1.00e+00 1.00e+00h  1
   9 -3.4567779e-12 3.35e-30 3.99e-07 -11.0 3.48e-17    -  1.00e+00 1.00e+00   0
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10 -3.4567780e-12 3.35e-30 2.49e-14 -11.0 9.57e-21    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 10

                                   (scaled)                 (unscaled)
Objective...............:  -7.7129645179475436e-13   -3.4567779718371899e-12
Dual infeasibility......:   2.4868995751603507e-14    1.1145726976419668e-13
Constraint violation....:   3.3526588471893002e-30    3.3526588471893002e-30
Variable bound violation:   1.0251543384822464e-13    1.0251543384822464e-13
Complementarity.........:   9.0909090909090936e-12    4.0743418715728018e-11
Overall NLP error.......:   9.0909090909090936e-12    4.0743418715728018e-11


Number of objective function evaluations             = 23
Number of objective gradient evaluations             = 11
Number of equality constraint evaluations            = 23
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 11
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 10
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.

The figures can then be drawn.

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), size = (700, 350))
Example block output
Calcite solubility

Calcite is a retrograde soluble mineral: its solubility decreases with increasing temperature, so less Ca²⁺ is released and pH rises slightly as temperature increases.


Activity models

All activity models inherit from AbstractActivityModel. Three built-in models are provided, covering ideal behaviour 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ᵢ
state_eq = equilibrate(state)   # DiluteSolutionModel is the default

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

Implements the extended Debye-Hückel model of Helgeson (1969) and Helgeson, Kirkham & Flowers (1981), identical to the model used by PHREEQC 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. sp[:å] — explicit value set in species properties.
  2. REJ_HKF — Helgeson et al. (1981) Table 3 (27 common ions).
  3. REJ_CHARGE_DEFAULT — fallback by formal charge.
  4. model.å_default (default: 3.72 Å).

Usage:

# 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)

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

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. 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.

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:

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⁰overT, 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:

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

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:

using ChemistryLab

substances = build_species("data/cemdata18-thermofun.json")
dict = Dict(symbol(s) => s for s in substances)

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

Workflow B — automated via build_solid_solutions and a TOML file:

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

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

Then pass solid_solutions as a keyword to ChemicalSystem:

cs = ChemicalSystem(
    [H2O_sp, dict["Ms"], dict["Mc"], ...],
    ["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

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

Non-ideal binary: Redlich-Kister

# 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):

\[\begin{aligned} \ln \gamma_1 &= \frac{x_2^2}{RT}\bigl[a_0 + a_1(3x_1 - x_2) + a_2(x_1 - x_2)(5x_1 - x_2)\bigr] \\[4pt] \ln \gamma_2 &= \frac{x_1^2}{RT}\bigl[a_0 - a_1(3x_2 - x_1) + a_2(x_2 - x_1)(5x_2 - x_1)\bigr] \end{aligned}\]

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.