Skip to main content
Log in

A Detailed Error Quantification Analysis of Extrapolation-Based Stiff ODE Solvers for Combustion CFD

  • Published:
Flow, Turbulence and Combustion Aims and scope Submit manuscript

    We’re sorry, something doesn't seem to be working properly.

    Please try refreshing the page. If that doesn't work, please contact support so we can address the problem.

Abstract

In this paper, high-order single-point extrapolation-based stiff ordinary differential equation (ODE) solvers are studied for computational fluid dynamics modeling of combustion where operator splitting is applicable. Performances of these extrapolation-based solvers and a state-of-the-art solver using multipoint backward differentiation formula method are investigated in terms of speed and solution accuracy. For a constant-pressure adiabatic system, three ODE systems based on molar concentrations, mass fractions, and mole fractions are considered. Semianalytic Jacobian formulations are derived for all these systems. Compared to the previous study, error quantification analyses are performed in a more detailed way that all physical quantities in the ODE system are taken into account with the purpose that root mean square of normalized errors can be computed (rather than evaluating only temperature and some key radical species). These calculations are repeated for a range of user-specified error tolerance values of each ODE solver considered. Accuracy, computational efficiency, and robustness are demonstrated using chemical mechanisms for real or surrogate engine-relevant fuels that range in size from 48 to 7171 species, and for two configurations: a constant-pressure homogeneous reactor and a high-pressure transient spray flame at an engine-relevant condition.

This is a preview of subscription content, log in via an institution to check access.

Access this article

Price excludes VAT (USA)
Tax calculation will be finalised during checkout.

Instant access to the full article PDF.

Institutional subscriptions

Fig. 1
Fig. 2
Fig. 3
Fig. 4
Fig. 5
Fig. 6
Fig. 7
Fig. 8
Fig. 9
Fig. 10
Fig. 11
Fig. 12
Fig. 13
Fig. 14
Fig. 15
Fig. 16
Fig. 17

Similar content being viewed by others

References

Download references

Acknowledgements

The author is grateful for technical support from Dr. Daniel C. Haworth of the Pennsylvania State University.

Author information

Authors and Affiliations

Authors

Corresponding author

Correspondence to Abdurrahman Imren.

Ethics declarations

Conflict of interest

The author declares no conflict of interest.

Ethical approval

Not applicable.

Appendices

Appendix

Appendix A describes the SIBS algorithm including modifications that have been made from the original formulation in the literature. Computer files can be provided by the author on request.

Appendix A SIBS algorithm

The original SIBS (semi-implicit Bulirsch-Stoer) method is presented in Bader and Deuflhard (1983). Further discussion can be found in Press et al. (2007), and a C++ implementation has been provided with recent versions of Cantera (see Goodwin et al. (2022)) and OpenFOAM (see OpenFOAM (2022)). Several changes have been made in the current implementation. These include: reformulating the ODEs as described in the main text, including approximations in computing the Jacobian that are described in detail in Section 3; modifying the algorithm used to estimate the solver internal time step and the target order of accuracy, following what was done with SEULEX in Imren and Haworth (2016); adding a Jacobian stability algorithm (see Deuflhard (1985), and Hairer and Wanner (1996)) and other robustness checks appropriate for combustion problems, following what was done with SEULEX in Imren and Haworth (2016); and modifying the data structures for computational efficiency and to use the KLU sparse linear algebra libraries.

The ODE solver is called for each computational element to solve the initial value problem of Eqs. 14 of the paper, given the initial composition (either mass fractions, mole fractions, or molar concentrations) and temperature (initial condition vector \({\varvec{\phi }} _ 0 = {\varvec{\phi }} ( t_0 )\)), the right-hand side vector \(\mathbf{S} = \mathbf{S} ( {\varvec{\phi }} )\), and the computational time step \(\Delta t _ \mathrm{CFD}\). The solver requires the user-specified tolerances RTOL and ATOL, an initial estimate of the solver internal time step \(\Delta t _ \mathrm{ODE}\), and an initial target order of accuracy for the time integration. The latter is expressed in terms of the target number of rows to be computed in the extrapolation table \(k_\mathrm{targ} + 1\), and the order of accuracy is a factor of two times the number of rows that is computed. Here \(\Delta t _ \mathrm{ODE}\) is taken to be the solver’s internal time step estimate from the end of the previous CFD time step for the computational element (\(\Delta t _ \mathrm{ODE}\) is saved for each computational element). Discussion of the extent to which the saved value of \(\Delta t _ \mathrm{ODE}\) from the end of the previous time step provides a reasonable estimate for the start of a new time step in an operator-splitting strategy can be found in Imren and Haworth (2016). For the cases reported in this paper, the CPU time and accuracy results are essentially the same if \(\Delta t _ \mathrm{ODE}\) is set to \(\Delta t _ \mathrm{CFD}\) at the beginning of each CFD time step. The value of \(k_\mathrm{targ}\) can be specified directly, or can be computed based on the values of the user-specified error tolerances RTOL and ATOL, and on the maximum number of rows that can be computed \(k_\mathrm{max}\). Here \(k_\mathrm{max} = 12\), corresponding to 24th-order time accuracy. The general idea on each internal solver time step \(\Delta t _ \mathrm{ODE}\) is to construct a sequence of progressively more accurate approximations to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\), until a solution is found that is accurate to within the user-specified tolerances RTOL and ATOL. Then \(\Delta t _ \mathrm{ODE}\) and \(k_\mathrm{targ}\) are updated, and integration continues over the next solver internal time step, until eventually the end of the current CFD time step \(\Delta t _ \mathrm{CFD}\) is reached.

For each \(\Delta t _ \mathrm{ODE}\), the approximate solutions for \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\) can be organized into a divided difference table (Fig. A1). The table is constructed row by row, starting with the top row (\(i = 0\)), and continuing as needed to the bottom row (\(i = k _ \mathrm{targ} + 1\)). The first two rows are always computed; rows \(3 \rightarrow k _\mathrm{targ} +1\) are computed only if needed to satisfy the specified level of accuracy, as described in the following. Each row i of the table corresponds to a uniform partition of \(\Delta t _ \mathrm{ODE}\) into substeps \(h_i = \Delta t _ \mathrm{ODE} / n_i\), where the sequence of partitions for \(k_\mathrm{targ} = 12\) is:

$$\begin{aligned} n _ i = 2 , 6, 10, 14, 22, 34, 50, 70, 102, 142, 206, 286, 414 \ \ (i = 0, 2, \ldots , 12) \ . \end{aligned}$$
(A1)

Entries in the first column of the table are generated using a modified midpoint-rule method; that requires the solution of a linear system. Then an algebraic formula is used to construct columns \(1 \rightarrow i\) to yield successively higher-order approximations to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\). The Jacobian matrix is computed only once, at the beginning of the procedure for the current \(\Delta t _ \mathrm{ODE}\).

Fig. 18
figure 18

SIBS extrapolation table structure for \(k_\mathrm{targ} = 5\). A minimum of two rows and a maximum of \(k_\mathrm{targ} + 1\) rows are computed. The first column is a succession of approximations to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\) obtained using a modified midpoint-rule method with progressively finer (on successive rows i) uniform partitions of \(\Delta t _ \mathrm{ODE}\) (Eq. A1). The remaining columns are higher-order approximations to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\) obtained algebraically using Eq. A5, where the order of accuracy increases by two in each successive column. In general, \({\varvec{\phi }} _ {i,j}\) is a \(\bigl (2 \cdot (j+1) \bigr )\)th-order-accurate estimate of \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\) based on partitions \(i , i - 1 , \ldots , i-j\)

At the start of each \(\Delta t _ \mathrm{ODE}\), some initial operations are performed. The Jacobian \(\mathbf{J} = \mathbf{J} _ 0 = \mathbf{J} ( {\varvec{\phi }} _ 0 )\) is computed. Then a semi-implicit Euler step is taken to compute \({\varvec{\Delta }} _ 0 = {\varvec{\phi }} _ 1 - {\varvec{\phi }} _ 0\) for a time step \(h = h_0\):

$$\begin{aligned} ( \mathbf{I}/h - \mathbf{J} ) {\varvec{\Delta }}_0 = \mathbf{S}_0 \ . \end{aligned}$$
(A2)

This form (divided through by the time step) is computationally expedient, as it reduces the number of operations required to update the solution when h changes (for fixed \(\mathbf{J}\)). A “Jacobian stability” algorithm is applied to ensure that the time step is sufficiently small for the method to eventually converge. The approach was suggested by Deuflhard (see Deuflhard (1985), and Hairer and Wanner (1996)), based on convergence of Newton iterations. Eq. A2 is solved again with the right-hand side vector updated based on \({\varvec{\phi }} _ {1}\) (without updating the Jacobian), to obtain \({\varvec{\Delta }}_1\):

$$\begin{aligned} ( \mathbf{I}/h - \mathbf{J} ) {\varvec{\Delta }}_1 = \mathbf{S} _ 1 - {\varvec{\Delta }_0} / h \ . \end{aligned}$$
(A3)

The computational cost is that of a single right-hand side evaluation, since the factored matrix is available from the first solution of the linear system. A monotonicity check is then performed to ensure that \(\theta \equiv |\mathbf{\Delta }_1 / \mathbf{\Delta } _ 0 |< 1\). If \(\theta \ge 1\), \(\Delta t _ \mathrm{ODE}\) is reduced by a specified factor f (here \(f = 2\)), and the solver internal time step is restarted. When \(\Delta t _ \mathrm{ODE}\) is sufficiently small that \(\theta < 1\), the algorithm proceeds.

First-column entries for rows \(i = 0 , \ldots , k _ \mathrm{targ} + 1\) are computed (only if needed for \(i > 1\)) using a modified semi-implicit midpoint rule. For row i, \(m = n_i\) (Eq. A1) steps are required to integrate from \({\varvec{\phi }} _ 0\) to \({\varvec{\phi }} ( t _ 0 + \Delta t _ \mathrm{ODE} )\). A semi-implicit Euler method is used for the first step; that is followed by \(m - 1\) steps using a semi-implicit midpoint rule; then a final “smoothing step” is taken. With \(h = h _ i\) and \(\mathbf{J} = \mathbf{J} _ 0\), the algorithm (written in terms of the solution update on each step, \({\varvec{\Delta }} _ k \equiv {\varvec{\phi }} _ {k+1} - {\varvec{\phi }} _ k\)) can be written as:

$$\begin{aligned} {\varvec{\Delta }}_0= & {} [\mathbf{I} / h - \mathbf{J} ]^ {-1} \mathbf{S}_0 \ , \ {\varvec{\phi }}_1 = {\varvec{\phi }}_0 + {\varvec{\Delta }}_0 \ ; \nonumber \\ \mathrm{for} \ k= & {} 1 , \ldots , m-1 : \nonumber \\ {\varvec{\Delta }}_k= & {} \mathbf{\Delta }_{k - 1} + 2 [\mathbf{I} / h - \mathbf{J} ]^ {-1} ( \mathbf{S}_{k} - {\varvec{\Delta }}_{k-1} / h ) \ , \ {\varvec{\phi }}_{k+1} = {\varvec{\phi }}_k + {\varvec{\Delta }}_k \ ; \nonumber \\ {\varvec{\Delta }}_{m}= & {} [\mathbf{I} / h - \mathbf{J} ]^ {-1} ( \mathbf{S}_{m} - {\varvec{\Delta }}_{m-1} / h ) \ , \ \overline{{\varvec{\phi }}}_{m} = {\varvec{\phi }}_m + {\varvec{\Delta }}_m \ . \end{aligned}$$
(A4)

Then \(\overline{{\varvec{\phi }}} _ {m}\) is the first-column table entry for row i. The computational cost for each step is that of a single right-hand side evaluation.

As noted earlier, the table of successive approximations to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\) is constructed row by row, and only as needed for \(i \ge 2\). The first-column entry for row i is computed using the modified midpoint-rule method described above. Then the Aitken-Neville algorithm (or Richardson extrapolation) is used to calculate columns \(1 \rightarrow i\) of row i to yield higher-order approximations to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\), where the order of accuracy increases by two in each successive column:

$$\begin{aligned} {\varvec{\phi }} _ {i,j} = {\varvec{\phi }} _ {i,j-1} + \frac{ {\varvec{\phi }} _ {i,j-1} - {\varvec{\phi }} _ {i-1,j-1} }{ \Bigl ( \frac{n_i}{n_{i-j+1}} \Bigr ) - 1 } \ \ ( i = 1 , \ldots , k _ \mathrm{targ} + 1 ; j = 1, \ldots , i ) \ . \end{aligned}$$
(A5)

This formula is used to compute \({\varvec{\phi }} _ {i,j}\) for \(1 \le j \le i\), where \({\varvec{\phi }} _ {i,j}\) is a \(\bigl ( 2 \cdot (j+1) \bigr )\)th-order approximation to \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\). As each row of the table is computed, an estimate of the work required for that row (denoted as \(cpu_i\), proportional to the CPU time used to form the row) is computed and stored, based on the number of linear system solves and right-hand side updates. After each row is computed, convergence is checked using criteria that are essentially the same as those used in CVODE. Here the difference between \({\varvec{\phi }} _ {i,i}\) and \({\varvec{\phi }} _ {i,i-1}\) is used to determine whether or not \({\varvec{\phi }} _ {i,i}\) is a sufficiently accurate estimate of \({\varvec{\phi }} ( t_0 + \Delta t _ \mathrm{ODE} )\). For each dependent variable \(\alpha\) in table row i, \({\Delta } _ {\alpha , i} = \vert \phi _ {\alpha , i,i} - \phi _ {\alpha , i,i-1} \vert\) (\(\alpha = 1 , \ldots , N _ {\phi }\)) is calculated, and a scaled error is computed as:

$$\begin{aligned} err_{i} \equiv \sqrt{ \frac{1}{N_{\phi }} \sum _ {\alpha =1} ^ {N_{\phi }} \Bigl ( \frac{\Delta _ {\alpha , i}}{scale _ {\alpha }} \Bigr ) ^ 2 } \end{aligned}$$
(A6)

where \(scale _ {\alpha } \equiv \mathrm{ATOL} + \vert \phi _ {\alpha , i , i} \vert \cdot \mathrm{RTOL}\).

A provisional value of \(\Delta t _ \mathrm{ODE}\) for each row, \(\Delta t ' _{\mathrm{ODE},i}\), is computed and stored based on the expected relationship between the scaled error and the time step size:

$$\begin{aligned} \Bigl ( \frac{\Delta t ' _ {\mathrm{ODE},i}}{\Delta t _ \mathrm{ODE}} \Bigr ) ^{2i+1} = \frac{1}{err_{i}} \ , \end{aligned}$$
(A7)

from which a provisional value for the next internal time step is:

$$\begin{aligned} \Delta t ' _ {\mathrm{ODE},i} = S_1 \Delta t _ \mathrm{ODE} \Bigl ( \frac{S_2}{err_{i}} \Bigr ) ^{\frac{1}{2i+1}} \ , \end{aligned}$$
(A8)

where \(S_1\) and \(S_2\) are heuristic “safety factors” whose values are close to, but less than, one. Convergence corresponds to \(err _ {i} < 1\). If \(err _ {i} \ge 1\) and \(i < k _ \mathrm{targ}\), the algorithm continues to the next value of i (to compute the next row of the table). If \(err _ {i} \ge 1\) and \(i = k _ \mathrm{targ}\), \(\Delta t _ \mathrm{ODE}\) is reduced by a specified factor f (here \(f = 2\)), and the time step starts over using the smaller value of \(\Delta t _ \mathrm{ODE}\). If \(err _ {i} < 1\), then \(i _\mathrm{conv}\) (the row at which a converged solution was found) is set to i, \(\Delta t _ \mathrm{ODE}\) and \(k _ \mathrm{targ}\) are updated as described below, and integration proceeds to the next solver internal time step.

At the conclusion of a successful (converged) internal time step, the values of \(\Delta t _ \mathrm{ODE}\) and \(k _ \mathrm{targ}\) for the next internal time step are set in a manner that is expected to yield a converged solution for the least CPU time, based on the values of \(\Delta t ' _ {\mathrm{ODE},i}\) and \(cpu_i\) that were computed and stored for each row for the current time step. Specifically, \(\Delta t _ \mathrm{ODE} = \Delta t ' _ {\mathrm{ODE},i_\mathrm{conv}} \cdot cpu_{i_\mathrm{conv}} / cpu_{i_\mathrm{conv}-1}\), and \(k_\mathrm{targ}\) can decrease by two if \(cpu_{i_\mathrm{conv}-1} / h_{i_\mathrm{conv}-1} < 0.7 cpu_{i_\mathrm{conv}} / h_{i_\mathrm{conv}}\) and can increase by two if \(cpu_{i_\mathrm{conv}-1} / h_{i_\mathrm{conv}-1} > 0.9 cpu_{i_\mathrm{conv}} / h_{i_\mathrm{conv}}\).

Additional tests have been implemented for robustness in combustion applications. The temperature is checked to ensure that it remains between the lower and upper limits specified in the thermodynamic property data, and the magnitude of the scaled change in the solution vector over an iteration is checked to make sure that it is not too large. A failure of either of these checks also results in a reduction in \(\Delta t_\mathrm{ODE}\).

Rights and permissions

Springer Nature or its licensor holds exclusive rights to this article under a publishing agreement with the author(s) or other rightsholder(s); author self-archiving of the accepted manuscript version of this article is solely governed by the terms of such publishing agreement and applicable law.

Reprints and permissions

About this article

Check for updates. Verify currency and authenticity via CrossMark

Cite this article

Imren, A. A Detailed Error Quantification Analysis of Extrapolation-Based Stiff ODE Solvers for Combustion CFD. Flow Turbulence Combust 110, 457–488 (2023). https://doi.org/10.1007/s10494-022-00369-z

Download citation

  • Received:

  • Accepted:

  • Published:

  • Issue Date:

  • DOI: https://doi.org/10.1007/s10494-022-00369-z

Keywords

Navigation