rkstiff.etd5

Constant-Step Fifth-Order Exponential Time-Differencing Integrator

Implements a fifth-order exponential time-differencing (ETD5) solver for stiff partial differential equations (PDEs) of the form

\[\frac{\partial \mathbf{U}}{\partial t} = \mathcal{L}\mathbf{U} + \mathcal{N}(\mathbf{U}),\]

where \(\mathcal{L}\) is a linear spatial differential operator (e.g. Laplacian, biharmonic, etc.), and \(\mathcal{N}(\mathbf{U})\) is a nonlinear term in physical or spectral space.

The solver advances the field \(\mathbf{U}(x, t)\) in time using a six-stage exponential Runge–Kutta (ETD5) method with precomputed matrix functions derived from \(\psi_r\) integrals.

This constant-step version corresponds to the fixed-step form of the adaptive ETD(3,5) scheme described in Whalen et al. (2015).

References

Whalen, P., Brio, M., & Moloney, J.V. (2015). Exponential time-differencing with embedded Runge–Kutta adaptive step control. Journal of Computational Physics, 280, 579–601.

Classes

ETD5(lin_op, nl_func[, etd_config, loglevel])

Fifth-order Exponential Time-Differencing solver for PDEs.

_Etd5Diagonal(lin_op, nl_func[, etd_config])

ETD5 solver for diagonalized PDE systems.

_Etd5NonDiagonal(lin_op, nl_func, etd_config)

ETD5 solver for non-diagonal PDE operators.

class rkstiff.etd5.ETD5(lin_op, nl_func, etd_config=ETDConfig(), loglevel='WARNING')[source]

Bases: ETDCS

Fifth-order Exponential Time-Differencing solver for PDEs.

Integrates stiff PDEs of the form

\[\frac{\partial \mathbf{U}}{\partial t} = \mathcal{L}\mathbf{U} + \mathcal{N}(\mathbf{U}),\]

where - \(\mathcal{L}\) is a linear spatial operator (e.g. diffusion or advection), - \(\mathcal{N}\) represents nonlinear stiff terms.

The solution is advanced in time using a six-stage exponential Runge–Kutta scheme, with coefficients derived from the \(\psi_r\) functions.

Parameters:
  • lin_op (np.ndarray) – Discretized linear operator \(\mathcal{L}\) in matrix or diagonal form.

  • nl_func (Callable[[np.ndarray], np.ndarray]) – Nonlinear functional \(\mathcal{N}[\mathbf{U}]\).

  • etd_config (ETDConfig, optional) – Configuration for contour integration and cutoff parameters.

Notes

  • Automatically detects whether the linear operator is diagonal and selects optimized routines.

  • Coefficients are cached and recomputed only when the step size \(h\) changes.

  • Uses the First Same As Last (FSAL) property to reuse the last nonlinear evaluation efficiently.

  • Designed for PDEs discretized in space via spectral or finite-difference methods.

References

Cox, S.M. & Matthews, P.C. (2002). Exponential time differencing for stiff systems. Journal of Computational Physics, 176(2), 430–455.

Krogstad, S. (2005). Generalized integrating factor methods for stiff PDEs. Journal of Computational Physics, 203(1), 72–88.

__init__(lin_op, nl_func, etd_config=ETDConfig(), loglevel='WARNING')[source]

Initialize the ETD5 solver.

Sets up the fifth-order exponential time-differencing solver by configuring the linear and nonlinear components, and selecting the appropriate internal method (diagonal or non-diagonal) based on the structure of the linear operator.

Parameters:
  • lin_op (np.ndarray) – Linear operator (L) in the system dU/dt = L*U + NL(U). If 1D array: treated as a diagonal operator (more efficient). If 2D array: treated as a full matrix operator. Supports both real and complex values.

  • nl_func (Callable[[np.ndarray], np.ndarray]) – Nonlinear function that maps the solution vector to its nonlinear contribution.

  • etd_config (ETDConfig, default=ETDConfig()) – Configuration object containing modecutoff, contour_points, contour_radius.

  • loglevel (Union[str, int], default="WARNING") – Logging level.

Notes

  • The solver automatically detects if lin_op is 1D (diagonal) and selects the optimized _Etd5Diagonal method; otherwise uses _Etd5NonDiagonal.

  • Internal state variables are initialized but coefficients are not computed until the first time step is taken.

  • The parent class ETDCS handles common setup and validation.

evolve(u, t0, tf, h, store_data=True, store_freq=1)

Integrate the system from \(t_0\) to \(t_f\) using fixed step size.

Repeatedly applies step() with constant \(h\) until the final time is reached.

Parameters:
  • u (np.ndarray) – Initial solution vector at \(t_0\).

  • t0 (float) – Initial time.

  • tf (float) – Final time (integration stops when t tf).

  • h (float) – Constant step size \(\Delta t\).

  • store_data (bool, default=True) – Whether to store intermediate results in t and u.

  • store_freq (int, default=1) – Frequency of storing data; every store_freq steps.

Returns:

Final solution vector at \(t_f\).

Return type:

np.ndarray

Raises:

ValueError – If h exceeds the total time span tf - t0.

Notes

  • The time grid is uniformly spaced with spacing \(h\).

  • Stored data can be accessed through t and u.

Example

>>> solver = ETD4(lin_op, nl_func)
>>> u_final = solver.evolve(u0, t0=0.0, tf=10.0, h=0.05)
>>> len(solver.t)
200
reset()

Reset solver state and clear stored time/solution data.

Return type:

None

set_loglevel(loglevel)

Adjust the solver’s logging verbosity at runtime.

Parameters:

loglevel (str or int) – New logging level. Accepts standard string levels or numeric constants from logging.

Return type:

None

Examples

>>> solver.set_loglevel("INFO")
>>> solver.set_loglevel(logging.DEBUG)
property solver_type: SolverType

Return the solver type for constant-step solvers.

Returns:

Always returns SolverType.CONSTANT_STEP.

Return type:

SolverType

Examples

>>> from rkstiff.if4 import IF4
>>> solver = IF4(lin_op, nl_func)
>>> solver.solver_type == SolverType.CONSTANT_STEP
True
step(u, h)

Perform a single constant-step propagation.

Parameters:
  • u (np.ndarray) – Current solution vector.

  • h (float) – Constant step size (must be non-negative).

Returns:

Updated solution after one full time step.

Return type:

np.ndarray

Notes

This method simply wraps _update_stages() and performs minimal validation and logging.