SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - ImexTimeStepper.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 60.0 % 10 6
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            0 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : #pragma once
       5              : 
       6              : #include "DataStructures/DataBox/PrefixHelpers.hpp"
       7              : #include "DataStructures/DataBox/Prefixes.hpp"
       8              : #include "DataStructures/MathWrapper.hpp"
       9              : #include "Time/History.hpp"
      10              : #include "Time/Time.hpp"
      11              : #include "Time/TimeSteppers/TimeStepper.hpp"
      12              : #include "Utilities/GenerateInstantiations.hpp"
      13              : #include "Utilities/Gsl.hpp"
      14              : #include "Utilities/Serialization/CharmPupable.hpp"
      15              : 
      16              : /// \cond
      17              : #define IMEX_TIME_STEPPER_WRAPPED_TYPE(data) BOOST_PP_TUPLE_ELEM(0, data)
      18              : #define IMEX_TIME_STEPPER_DERIVED_CLASS(data) BOOST_PP_TUPLE_ELEM(1, data)
      19              : /// \endcond
      20              : 
      21              : /*!
      22              :  * \ingroup TimeSteppersGroup
      23              :  *
      24              :  * Base class for TimeSteppers with IMEX support, derived from
      25              :  * TimeStepper.
      26              :  *
      27              :  * All supported time-stepping algorithms (both implicit and
      28              :  * explicit) consist of substeps that add linear combinations of
      29              :  * derivative values.  For implicit substeps, it is convenient to
      30              :  * split out the contribution of the final implicit term from
      31              :  * contributions from the history.  We therefore write an implicit
      32              :  * substep as
      33              :  *
      34              :  * \f{equation}{
      35              :  *   Y_{n+1} =
      36              :  *   Y_{n,\text{explicit}} + Y_{n,\text{inhomogeneous}} + w_n S(Y_{n+1})
      37              :  * \f}
      38              :  *
      39              :  * Here \f$Y_{n,\text{explicit}}\f$ is the value of the evolved
      40              :  * variables before the implicit substep is applied,
      41              :  * \f$Y_{n,\text{inhomogeneous}}\f$ is the contribution of the past
      42              :  * values from the implicit derivative history, and \f$S(\cdot)\f$ is
      43              :  * the implicit portion of the right-hand-side (generally source
      44              :  * terms for PDEs).  We call \f$w_n\f$ the *implicit weight*.
      45              :  * This split form is convenient for most consumers of this class, so
      46              :  * we present methods for calculating
      47              :  * \f$Y_{n,\text{inhomogeneous}}\f$ and \f$w_n\f$ individually
      48              :  * instead of a method to perform a full step update.
      49              :  *
      50              :  * History cleanup is the same for the explicit and implicit parts,
      51              :  * and should be done together.
      52              :  *
      53              :  * Dense output formulae are the same for the explicit and implicit
      54              :  * parts of any conservative IMEX stepper.  To evaluate dense output,
      55              :  * call `dense_update_u` with the implicit history after a successful
      56              :  * call to `dense_update_u` with the explicit history.
      57              :  *
      58              :  * Several of the member functions of this class are templated and
      59              :  * perform type erasure before forwarding their arguments to the
      60              :  * derived classes.  This is implemented using the macros \ref
      61              :  * IMEX_TIME_STEPPER_DECLARE_OVERLOADS, which must be placed in a
      62              :  * private section of the class body, and
      63              :  * IMEX_TIME_STEPPER_DEFINE_OVERLOADS(derived_class), which must be
      64              :  * placed in the cpp file.
      65              :  */
      66            1 : class ImexTimeStepper : public virtual TimeStepper {
      67              :  public:
      68            0 :   static constexpr bool imex = true;
      69            0 :   using provided_time_stepper_interfaces =
      70              :       tmpl::list<ImexTimeStepper, TimeStepper>;
      71              : 
      72            0 :   WRAPPED_PUPable_abstract(ImexTimeStepper);  // NOLINT
      73              : 
      74              : /// \cond
      75              : #define IMEX_TIME_STEPPER_DECLARE_VIRTUALS_IMPL(_, data)                      \
      76              :   virtual void add_inhomogeneous_implicit_terms_forward(                      \
      77              :       gsl::not_null<IMEX_TIME_STEPPER_WRAPPED_TYPE(data)*> u,                 \
      78              :       const TimeSteppers::ConstUntypedHistory<IMEX_TIME_STEPPER_WRAPPED_TYPE( \
      79              :           data)>& implicit_history,                                           \
      80              :       const TimeDelta& time_step) const = 0;                                  \
      81              :   virtual double implicit_weight_forward(                                     \
      82              :       const TimeSteppers::ConstUntypedHistory<IMEX_TIME_STEPPER_WRAPPED_TYPE( \
      83              :           data)>& implicit_history,                                           \
      84              :       const TimeDelta& time_step) const = 0;
      85              : 
      86              :   GENERATE_INSTANTIATIONS(IMEX_TIME_STEPPER_DECLARE_VIRTUALS_IMPL,
      87              :                           (MATH_WRAPPER_TYPES))
      88              : #undef IMEX_TIME_STEPPER_DECLARE_VIRTUALS_IMPL
      89              :   /// \endcond
      90              : 
      91              :   /// Convergence order of the integrator when used in IMEX mode.
      92            1 :   virtual size_t imex_order() const = 0;
      93              : 
      94              :   /// Add the change for the current implicit substep,
      95              :   /// \f$Y_{n,\text{inhomogeneous}}\f$, to u, given a past history of
      96              :   /// the implicit derivatives.
      97              :   ///
      98              :   /// Derived classes must implement this as a function with signature
      99              :   ///
     100              :   /// ```
     101              :   /// template <typename T>
     102              :   /// void add_inhomogeneous_implicit_terms_impl(
     103              :   ///     gsl::not_null<T*> u,
     104              :   ///     const ConstUntypedHistory<T>& implicit_history,
     105              :   ///     const TimeDelta& time_step) const;
     106              :   /// ```
     107              :   ///
     108              :   /// \note
     109              :   /// Unlike the `update_u` methods, which overwrite their result
     110              :   /// arguments, this function adds the result to the existing value.
     111              :   template <typename Vars>
     112            1 :   void add_inhomogeneous_implicit_terms(
     113              :       const gsl::not_null<Vars*> u,
     114              :       const TimeSteppers::History<Vars>& implicit_history,
     115              :       const TimeDelta& time_step) const {
     116              :     return add_inhomogeneous_implicit_terms_forward(
     117              :         &*make_math_wrapper(u), implicit_history.untyped(), time_step);
     118              :   }
     119              : 
     120              :   /// The coefficient \f$w_n\f$ of the implicit derivative for the
     121              :   /// current substep.  For a Runge-Kutta method, this is the
     122              :   /// coefficient on the diagonal of the Butcher tableau.
     123              :   ///
     124              :   /// Derived classes must implement this as a function with signature
     125              :   ///
     126              :   /// ```
     127              :   /// template <typename T>
     128              :   /// double implicit_weight_impl(
     129              :   ///     const ConstUntypedHistory<T>& implicit_history,
     130              :   ///     const TimeDelta& time_step) const;
     131              :   /// ```
     132              :   template <typename Vars>
     133            1 :   double implicit_weight(const TimeSteppers::History<Vars>& implicit_history,
     134              :                          const TimeDelta& time_step) const {
     135              :     return implicit_weight_forward(implicit_history.untyped(), time_step);
     136              :   }
     137              : };
     138              : 
     139              : /// \cond
     140              : #define IMEX_TIME_STEPPER_DECLARE_OVERLOADS_IMPL(_, data)                     \
     141              :   void add_inhomogeneous_implicit_terms_forward(                              \
     142              :       gsl::not_null<IMEX_TIME_STEPPER_WRAPPED_TYPE(data)*> u,                 \
     143              :       const TimeSteppers::ConstUntypedHistory<IMEX_TIME_STEPPER_WRAPPED_TYPE( \
     144              :           data)>& implicit_history,                                           \
     145              :       const TimeDelta& time_step) const override;                             \
     146              :   double implicit_weight_forward(                                             \
     147              :       const TimeSteppers::ConstUntypedHistory<IMEX_TIME_STEPPER_WRAPPED_TYPE( \
     148              :           data)>& implicit_history,                                           \
     149              :       const TimeDelta& time_step) const override;
     150              : 
     151              : #define IMEX_TIME_STEPPER_DEFINE_OVERLOADS_IMPL(_, data)                      \
     152              :   void IMEX_TIME_STEPPER_DERIVED_CLASS(data)::                                \
     153              :       add_inhomogeneous_implicit_terms_forward(                               \
     154              :           const gsl::not_null<IMEX_TIME_STEPPER_WRAPPED_TYPE(data)*> u,       \
     155              :           const TimeSteppers::ConstUntypedHistory<                            \
     156              :               IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history,        \
     157              :           const TimeDelta& time_step) const {                                 \
     158              :     return add_inhomogeneous_implicit_terms_impl(u, implicit_history,         \
     159              :                                                  time_step);                  \
     160              :   }                                                                           \
     161              :   double IMEX_TIME_STEPPER_DERIVED_CLASS(data)::implicit_weight_forward(      \
     162              :       const TimeSteppers::ConstUntypedHistory<IMEX_TIME_STEPPER_WRAPPED_TYPE( \
     163              :           data)>& implicit_history,                                           \
     164              :       const TimeDelta& time_step) const {                                     \
     165              :     return implicit_weight_impl(implicit_history, time_step);                 \
     166              :   }
     167              : /// \endcond
     168              : 
     169              : /// \ingroup TimeSteppersGroup
     170              : /// Macro declaring overloaded detail methods in classes derived from
     171              : /// ImexTimeStepper.  Must be placed in a private section of the class
     172              : /// body.
     173            1 : #define IMEX_TIME_STEPPER_DECLARE_OVERLOADS                         \
     174              :   GENERATE_INSTANTIATIONS(IMEX_TIME_STEPPER_DECLARE_OVERLOADS_IMPL, \
     175              :                           (MATH_WRAPPER_TYPES))
     176              : 
     177              : /// \ingroup TimeSteppersGroup
     178              : /// Macro defining overloaded detail methods in classes derived from
     179              : /// ImexTimeStepper.  Must be placed in the cpp file for the derived
     180              : /// class.
     181            1 : #define IMEX_TIME_STEPPER_DEFINE_OVERLOADS(derived_class)          \
     182              :   GENERATE_INSTANTIATIONS(IMEX_TIME_STEPPER_DEFINE_OVERLOADS_IMPL, \
     183              :                           (MATH_WRAPPER_TYPES), (derived_class))
        

Generated by: LCOV version 2.0-1