Skip to content

ChemistryTools/OptimaSolver.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OptimaSolver.jl

Stable Dev Build Status

A Julia-native primal-dual interior-point solver for Gibbs-energy minimisation in equilibrium chemistry.

What it does

OptimaSolver solves constrained optimisation problems of the form

minimize    f(n, p)              (e.g. Gibbs energy G(n) = Σ nᵢ(μᵢ⁰/RT + ln nᵢ))
subject to  A n = b              (mass conservation, m equations)
            n ≥ ε                (positivity bounds)

The algorithm is a log-barrier interior-point method with:

  • Schur-complement Newton step — reduces the KKT system from $(n_s+m)\times(n_s+m)$ to $m\times m$ by exploiting the diagonal Hessian structure. For typical chemistry problems $m$ is the number of elements ($\leq 15$), so this is a dramatic reduction.
  • Filter line search (Wächter & Biegler 2006) with Armijo sufficient decrease on the barrier objective.
  • Implicit-differentiation sensitivity — post-solve computation of $\partial n^{\ast}/\partial b$ and $\partial n^{\ast}/\partial(\mu^0/RT)$ at marginal cost.
  • Warm-start — consecutive solves reuse the previous solution as the starting point.
  • ForwardDiff/AD compatibility — no Float64 casts; the entire solver stack uses generic Julia arithmetic.
  • SciML drop-inOptimaOptimizer implements SciMLBase.AbstractOptimizationAlgorithm and is a drop-in replacement for IpoptOptimizer in ChemistryLab.jl.

Installation

julia> import Pkg; Pkg.add("OptimaSolver")

Requires Julia ≥ 1.10.

Quick example

using OptimaSolver

# Ideal three-species Gibbs problem: minimize Σ nᵢ(μᵢ⁰ + ln nᵢ) subject to Σ nᵢ = 1
μ⁰ = [0.0, 1.0, 2.0]

G(n, p)    = sum(n[i] * (p.μ⁰[i] + log(n[i])) for i in eachindex(n))
∇G!(g,n,p) = for i in eachindex(n); g[i] = p.μ⁰[i] + log(n[i]) + 1; end

A = ones(1, 3)
b = [1.0]
prob = OptimaProblem(A, b, G, ∇G!; lb=fill(1e-16, 3), p=(μ⁰=μ⁰,))
result = solve(prob, OptimaOptions(tol=1e-12))

println(result.n)          # ≈ [0.665241, 0.244728, 0.090031]  (exp(-μᵢ⁰)/Z)
println(result.converged)  # true
println(result.iterations) # typically 15–25

SciML / ChemistryLab interface

OptimaOptimizer is a drop-in replacement for IpoptOptimizer in ChemistryLab.jl:

using ChemistryLab, OptimaSolver
state_eq = equilibrate(state0; solver=OptimaOptimizer(tol=1e-10, verbose=false))

The SciML interface handles variable scaling (critical for multi-decade concentration ranges), cold-start lifting of absent species, and transparent warm-start caching between consecutive solves.

Documentation

Full documentation with theory, API reference, and worked examples:

https://ChemistryTools.github.io/OptimaSolver.jl

Credits and lineage

OptimaSolver.jl is a Julia port of the Optima C++ library developed by Allan Leal (ETH Zürich):

https://github.com/reaktoro/optima

The algorithmic design — Schur-complement Newton step, filter line search, variable stability classification, and implicit-differentiation sensitivity — originates from that library and from the following reference:

Leal, A.M.M., Blunt, M.J., LaForce, T.C. (2014). Efficient chemical equilibrium calculations for geochemical speciation and reactive transport modelling. Geochimica et Cosmochimica Acta, 131, 301–322. https://doi.org/10.1016/j.gca.2014.01.006

The Julia port was authored by Jean-François Barthélémy (CEREMA, France) with assistance from Claude Code (Anthropic).

License

OptimaSolver.jl is licensed under the GNU Lesser General Public License, version 2.1 or (at your option) any later version (LGPL-2.1-or-later), matching the licence of the upstream Optima C++ library from which it is derived.

  • Copyright © 2020–2024 Allan Leal (original C++ Optima).
  • Copyright © 2026 Jean-François Barthélémy (Julia port).

See LICENSE for the full notice and COPYING.LESSER for the full LGPL-2.1 text.

Licensing history. Version 0.1.0 of this package was inadvertently published under the MIT license. This was an error: a Julia port of an LGPL-licensed library is a derivative work under copyright law and cannot be legitimately relicensed under MIT without explicit authorisation from the upstream copyright holder. Version 0.2.0 corrects this oversight by adopting LGPL-2.1-or-later to match the upstream Optima license.

Practical note for downstream users. The LGPL permits using OptimaSolver from Julia code of any licence (including MIT, Apache-2.0, or proprietary code). The copyleft applies only to modifications of OptimaSolver.jl itself, which must remain LGPL.

About

Primal-dual interior-point solver for Gibbs-energy minimization

Resources

License

Unknown, LGPL-2.1 licenses found

Licenses found

Unknown
LICENSE
LGPL-2.1
COPYING.LESSER

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages