Summary
EqSolver.solve() fails to converge (last_error: 8, CEA_NOT_CONVERGED) for a
simple ternary Ar/N2/H2 gas mixture at 1 atm, for essentially every temperature
at or above ~6600 K, up through at least 20,000 K. Below ~6600 K it converges
cleanly. This has been reproduced across multiple independent variations
(see below), all of which fail identically, which suggests the issue is in
the core solver rather than in how it's being called.
import numpy as np
import cea
cea.init()
cea.set_log_level(cea.LOG_ERROR)
reactants = cea.Mixture(["Ar", "N2", "H2"], ions=True)
products = cea.Mixture(["Ar", "N2", "H2"], products_from_reactants=True, ions=True)
solver = cea.EqSolver(products, reactants=reactants)
solution = cea.EqSolution(solver)
reactant_moles = np.zeros(reactants.num_species)
reactant_moles[reactants.species_names.index("Ar")] = 0.75
reactant_moles[reactants.species_names.index("N2")] = 0.10
reactant_moles[reactants.species_names.index("H2")] = 0.15
reactant_weights = reactants.moles_to_weights(reactant_moles)
pressure_bar = cea.units.atm_to_bar(1.0)
solver.solve(solution, cea.TP, 6600.0, pressure_bar, reactant_weights)
print(solution.converged, solution.last_error) # True, 0
solver.solve(solution, cea.TP, 6610.0, pressure_bar, reactant_weights)
print(solution.converged, solution.last_error) # False, 8
A 10 K step (6600 K -> 6610 K) is the difference between clean convergence
and total failure. Every point from ~6610 K through 20,000 K fails with the
same last_error: 8.
Variations tested (all fail identically)
Fresh state per call: rebuilding Mixture (both reactant and product),
EqSolver, and EqSolution completely from scratch at every single
temperature point (no shared/warm-start state at all) -- same failure at
the same temperature.
Product species list: tested with (a) the full auto-generated list
(products_from_reactants=True, 24 species including NH/NH2/NH3/N2H4/etc),
(b) a manually trimmed list excluding NH-family molecules, and (c) a
minimal list of only atoms/diatomics/ions/electron
(Ar, Ar+, N2, N, N+, H2, H, H+, e-) -- all three fail at the same T.
Composition: tested both Ar 75%/N2 10%/H2 15% and Ar 45%/N2 45%/H2 10%
(mole basis) -- identical failure point and identical convergence count
(51/140 on a shared test grid) for both.
Interface: tested both the EqSolver/EqSolution object API and the
cea.matlab.eq_solve() wrapper function -- both fail identically (the
wrapper appears to call the same underlying EqSolver.solve() internally).
Package version: tested on both 3.2.1 (current at time of testing) and
3.1.2 (released Mar 23, 2026) -- identical failure point, identical error
code, identical convergence count on both versions.
Input scale: tested reactant mole amounts as both fractions summing to
1 (0.75/0.10/0.15) and as percentages summing to 100 (75/10/15) -- no
difference, as expected since equilibrium composition should only depend
on ratios.
Environment
cea version: 3.2.1 and 3.1.2 (both tested)
OS: Windows
Python: 3.11
Install method: pip install cea
Additional context
This appears right around the onset of significant ionization for this
mixture (Ar's first ionization energy is ~15.76 eV; the electron mole
fraction is going from numerically negligible to nonzero in this
temperature range), which may be relevant to whatever is happening
internally in the solver at that transition.
We separately verified using a from-scratch Saha-equation-based equilibrium
model that ionization at this composition/pressure should be physically
significant well before 20,000 K (Ar+ mole fraction approaching ~0.30 by
20,000 K at 1 atm), so this isn't a case where the "correct" answer is
trivially near-zero ionization -- there's a real physical solution the
solver should be finding but isn't.
Happy to provide the full test scripts if useful.
Summary
EqSolver.solve() fails to converge (last_error: 8, CEA_NOT_CONVERGED) for a
simple ternary Ar/N2/H2 gas mixture at 1 atm, for essentially every temperature
at or above ~6600 K, up through at least 20,000 K. Below ~6600 K it converges
cleanly. This has been reproduced across multiple independent variations
(see below), all of which fail identically, which suggests the issue is in
the core solver rather than in how it's being called.
import numpy as np
import cea
cea.init()
cea.set_log_level(cea.LOG_ERROR)
reactants = cea.Mixture(["Ar", "N2", "H2"], ions=True)
products = cea.Mixture(["Ar", "N2", "H2"], products_from_reactants=True, ions=True)
solver = cea.EqSolver(products, reactants=reactants)
solution = cea.EqSolution(solver)
reactant_moles = np.zeros(reactants.num_species)
reactant_moles[reactants.species_names.index("Ar")] = 0.75
reactant_moles[reactants.species_names.index("N2")] = 0.10
reactant_moles[reactants.species_names.index("H2")] = 0.15
reactant_weights = reactants.moles_to_weights(reactant_moles)
pressure_bar = cea.units.atm_to_bar(1.0)
solver.solve(solution, cea.TP, 6600.0, pressure_bar, reactant_weights)
print(solution.converged, solution.last_error) # True, 0
solver.solve(solution, cea.TP, 6610.0, pressure_bar, reactant_weights)
print(solution.converged, solution.last_error) # False, 8
A 10 K step (6600 K -> 6610 K) is the difference between clean convergence
and total failure. Every point from ~6610 K through 20,000 K fails with the
same last_error: 8.
Variations tested (all fail identically)
Fresh state per call: rebuilding Mixture (both reactant and product),
EqSolver, and EqSolution completely from scratch at every single
temperature point (no shared/warm-start state at all) -- same failure at
the same temperature.
Product species list: tested with (a) the full auto-generated list
(products_from_reactants=True, 24 species including NH/NH2/NH3/N2H4/etc),
(b) a manually trimmed list excluding NH-family molecules, and (c) a
minimal list of only atoms/diatomics/ions/electron
(Ar, Ar+, N2, N, N+, H2, H, H+, e-) -- all three fail at the same T.
Composition: tested both Ar 75%/N2 10%/H2 15% and Ar 45%/N2 45%/H2 10%
(mole basis) -- identical failure point and identical convergence count
(51/140 on a shared test grid) for both.
Interface: tested both the EqSolver/EqSolution object API and the
cea.matlab.eq_solve() wrapper function -- both fail identically (the
wrapper appears to call the same underlying EqSolver.solve() internally).
Package version: tested on both 3.2.1 (current at time of testing) and
3.1.2 (released Mar 23, 2026) -- identical failure point, identical error
code, identical convergence count on both versions.
Input scale: tested reactant mole amounts as both fractions summing to
1 (0.75/0.10/0.15) and as percentages summing to 100 (75/10/15) -- no
difference, as expected since equilibrium composition should only depend
on ratios.
Environment
cea version: 3.2.1 and 3.1.2 (both tested)
OS: Windows
Python: 3.11
Install method: pip install cea
Additional context
This appears right around the onset of significant ionization for this
mixture (Ar's first ionization energy is ~15.76 eV; the electron mole
fraction is going from numerically negligible to nonzero in this
temperature range), which may be relevant to whatever is happening
internally in the solver at that transition.
We separately verified using a from-scratch Saha-equation-based equilibrium
model that ionization at this composition/pressure should be physically
significant well before 20,000 K (Ar+ mole fraction approaching ~0.30 by
20,000 K at 1 atm), so this isn't a case where the "correct" answer is
trivially near-zero ionization -- there's a real physical solution the
solver should be finding but isn't.
Happy to provide the full test scripts if useful.