Cantera 4.0.0#
Under development
Breaking Changes#
As a new major version, Cantera 4.0 includes a number of backwards-incompatible changes which may require updates to user code. These changes are summarized here, along with some guidance on how to migrate existing code.
C++: Transition to std::span for array arguments#
Methods operating on arrays have been modified to take std::span arguments instead of
pointers to unsized arrays or references to std::vector. This approach provides the
opportunity to ensure array sizes are correct while providing compatibility with
different data containers. For example, Phase::getMoleFractions(double* x) has been
replaced with Phase::getMoleFractions(span<double> x).
The following code demonstrates how to use different container types with Cantera’s
methods that take span arguments:
using namespace Cantera;
auto soln = newSolution("mech.yaml");
auto phase = soln->thermo();
vector<double> x1(phase->nSpecies());
Eigen::ArrayXd x2 = Eigen::ArrayXd::Zero(phase->nSpecies());
// custom user container for multiple states
MyVector x3(4 * phase->nSpecies());
size_t offset = 2 * phase->nSpecies();
// Old call signatures (Cantera 3.2 and older)
phase->getMoleFractions(x1.data());
phase->getMoleFractions(x2.data());
phase->getMoleFractions(&x3[offset]);
// New call signatures (Cantera 4.0 and newer)
phase->getMoleFractions(x1);
phase->getMoleFractions(asSpan(x2)); // Eigen 3.4.0
phase->getMoleFractions(x2); // Eigen 5.0
phase->getMoleFractions(span<const double>(&x3[offset], phase->nSpecies()));
For methods that had an extra argument specifying array sizes, this argument has
been removed. For example,
PlasmaPhase::setElectronEnergyLevels(const double* levels, size_t length) is now just
PlasmaPhase::setElectronEnergyLevels(span<const double> levels).
Additionally, a number of methods which previously returned references to std::vector
have been updated to return std::span instead. For example,
const std::vector<double> Phase::molecularWeights() has been replaced with
span<const double> Phase::molecularWeights().
CLib#
The generated CLib function
reactornet_sensitivity, which wrappedReactorNet::sensitivity(const string& component, size_t p, int reactor), has been renamed toreactornet_sensitivityByName. The namereactornet_sensitivitynow wraps the index-based overloadReactorNet::sensitivity(size_t k, size_t p), wherekis an index into the global state vector of the network.
New features#
Map between reactor state-vector indices and component names from the CLib and MATLAB interfaces. The generated CLib gains
reactor_neq,reactor_componentNameandreactor_componentIndex, wrappingReactorBase::neq(),ReactorBase::componentName(size_t)andReactorBase::componentIndex(const string&), plusreactornet_globalComponentIndex, wrappingReactorNet::globalComponentIndex(const string&, size_t); these join the existingreactornet_neqandreactornet_componentName. The MATLAB toolbox gains the correspondingReactorBase.nVars,ReactorBase.componentIndex,ReactorBase.componentName,ReactorNet.nVars,ReactorNet.componentNameandReactorNet.globalComponentIndex, all using 1-based indices. Note thatReactorNet.componentNamereturns a name prefixed with that of the reactor it belongs to, for examplereactor1: temperature, whileReactorNet.globalComponentIndextakes an unprefixed name resolved within a given reactor.Make an analytic Jacobian the default for 1D flame simulations. The species mass-fraction Jacobian columns at interior grid points are evaluated analytically from kinetics concentration-derivative functions instead of by finite differences, which substantially reduces Jacobian construction time, particularly for large reaction mechanisms. The speedup grows with mechanism size as kinetic sparsity increases; measured ~2.4–3× for mechanisms with 53–173 species. For very large mechanisms the O(K³) factorization cost eventually exceeds the evaluation savings (crossover roughly at 400 species with the analytic Jacobian). The
jacobian_modeproperty selects"auto"(the default; analytic where supported, silent fallback to finite differences otherwise),"analytic"(which raises if analytic evaluation was requested but is unavailable because the kinetics lacks composition derivatives or multicomponent transport is active), or"finite-difference". The analytic mode makes the same frozen-transport approximation as the finite-difference Jacobian. See Nonlinear Solver for One-dimensional Flows for details. Also addsSim1D.eval_jacobian()andDomain1D.global_component_index(). [C++] Adds a pattern-reusingKinetics::netProductionRates_ddCioverload that refills a caller-owned sparse matrix in place, avoiding repeated sparse assembly.Add
Sim1D.solver_stats, which reports per-grid 1D solver statistics (residual evaluation, Jacobian construction, Jacobian factorization, linear solves, and total) as a dictionary of parallel arrays. Timing now uses wall-clock time. The previous per-metric properties (grid_size_stats,jacobian_time_stats,jacobian_count_stats,eval_time_stats,eval_count_stats,time_step_stats) are deprecated in favor ofsolver_stats.