SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - ImexTimeStepper.hpp Hit Total Coverage
Commit: 6e1258ccd353220e12442198913007fb6c170b6b Lines: 6 10 60.0 %
Date: 2024-10-23 19:54:13
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 1.14