SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - ImexTimeStepper.hpp Hit Total Coverage
Commit: a9ee6aa7c65ba703dbdc6dfb79436bb5378d4465 Lines: 6 10 60.0 %
Date: 2024-05-05 02:31:09
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             :  * Dense output formulae are the same for the explicit and implicit
      51             :  * parts of any conservative IMEX stepper.  To evaluate dense output,
      52             :  * call `dense_update_u` with the implicit history after a successful
      53             :  * call to `dense_update_u` with the explicit history.
      54             :  *
      55             :  * Several of the member functions of this class are templated and
      56             :  * perform type erasure before forwarding their arguments to the
      57             :  * derived classes.  This is implemented using the macros \ref
      58             :  * IMEX_TIME_STEPPER_DECLARE_OVERLOADS, which must be placed in a
      59             :  * private section of the class body, and
      60             :  * IMEX_TIME_STEPPER_DEFINE_OVERLOADS(derived_class), which must be
      61             :  * placed in the cpp file.
      62             :  */
      63           1 : class ImexTimeStepper : public virtual TimeStepper {
      64             :  public:
      65           0 :   static constexpr bool imex = true;
      66           0 :   using provided_time_stepper_interfaces =
      67             :       tmpl::list<ImexTimeStepper, TimeStepper>;
      68             : 
      69           0 :   WRAPPED_PUPable_abstract(ImexTimeStepper);  // NOLINT
      70             : 
      71             : /// \cond
      72             : #define IMEX_TIME_STEPPER_DECLARE_VIRTUALS_IMPL(_, data)           \
      73             :   virtual void add_inhomogeneous_implicit_terms_forward(           \
      74             :       gsl::not_null<IMEX_TIME_STEPPER_WRAPPED_TYPE(data)*> u,      \
      75             :       const TimeSteppers::MutableUntypedHistory<                   \
      76             :           IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history, \
      77             :       const TimeDelta& time_step) const = 0;                       \
      78             :   virtual double implicit_weight_forward(                          \
      79             :       const TimeSteppers::MutableUntypedHistory<                   \
      80             :           IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history, \
      81             :       const TimeDelta& time_step) const = 0;
      82             : 
      83             :   GENERATE_INSTANTIATIONS(IMEX_TIME_STEPPER_DECLARE_VIRTUALS_IMPL,
      84             :                           (MATH_WRAPPER_TYPES))
      85             : #undef IMEX_TIME_STEPPER_DECLARE_VIRTUALS_IMPL
      86             :   /// \endcond
      87             : 
      88             :   /// Convergence order of the integrator when used in IMEX mode.
      89           1 :   virtual size_t imex_order() const = 0;
      90             : 
      91             :   /// Add the change for the current implicit substep,
      92             :   /// \f$Y_{n,\text{inhomogeneous}}\f$, to u, given a past history of
      93             :   /// the implicit derivatives.
      94             :   ///
      95             :   /// Derived classes must implement this as a function with signature
      96             :   ///
      97             :   /// ```
      98             :   /// template <typename T>
      99             :   /// void add_inhomogeneous_implicit_terms_impl(
     100             :   ///     gsl::not_null<T*> u,
     101             :   ///     const MutableUntypedHistory<T>& implicit_history,
     102             :   ///     const TimeDelta& time_step) const;
     103             :   /// ```
     104             :   ///
     105             :   /// \note
     106             :   /// Unlike the `update_u` methods, which overwrite their result
     107             :   /// arguments, this function adds the result to the existing value.
     108             :   template <typename Vars>
     109           1 :   void add_inhomogeneous_implicit_terms(
     110             :       const gsl::not_null<Vars*> u,
     111             :       const gsl::not_null<TimeSteppers::History<Vars>*> implicit_history,
     112             :       const TimeDelta& time_step) const {
     113             :     return add_inhomogeneous_implicit_terms_forward(
     114             :         &*make_math_wrapper(u), implicit_history->untyped(), time_step);
     115             :   }
     116             : 
     117             :   /// The coefficient \f$w_n\f$ of the implicit derivative for the
     118             :   /// current substep.  For a Runge-Kutta method, this is the
     119             :   /// coefficient on the diagonal of the Butcher tableau.
     120             :   ///
     121             :   /// Derived classes must implement this as a function with signature
     122             :   ///
     123             :   /// ```
     124             :   /// template <typename T>
     125             :   /// double implicit_weight_impl(
     126             :   ///     const MutableUntypedHistory<T>& implicit_history,
     127             :   ///     const TimeDelta& time_step) const;
     128             :   /// ```
     129             :   template <typename Vars>
     130           1 :   double implicit_weight(
     131             :       const gsl::not_null<TimeSteppers::History<Vars>*> implicit_history,
     132             :       const TimeDelta& time_step) const {
     133             :     return implicit_weight_forward(implicit_history->untyped(), time_step);
     134             :   }
     135             : };
     136             : 
     137             : /// \cond
     138             : #define IMEX_TIME_STEPPER_DECLARE_OVERLOADS_IMPL(_, data)          \
     139             :   void add_inhomogeneous_implicit_terms_forward(                   \
     140             :       gsl::not_null<IMEX_TIME_STEPPER_WRAPPED_TYPE(data)*> u,      \
     141             :       const TimeSteppers::MutableUntypedHistory<                   \
     142             :           IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history, \
     143             :       const TimeDelta& time_step) const override;                  \
     144             :   double implicit_weight_forward(                                  \
     145             :       const TimeSteppers::MutableUntypedHistory<                   \
     146             :           IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history, \
     147             :       const TimeDelta& time_step) const override;
     148             : 
     149             : #define IMEX_TIME_STEPPER_DEFINE_OVERLOADS_IMPL(_, data)                 \
     150             :   void IMEX_TIME_STEPPER_DERIVED_CLASS(data)::                           \
     151             :       add_inhomogeneous_implicit_terms_forward(                          \
     152             :           const gsl::not_null<IMEX_TIME_STEPPER_WRAPPED_TYPE(data)*> u,  \
     153             :           const TimeSteppers::MutableUntypedHistory<                     \
     154             :               IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history,   \
     155             :           const TimeDelta& time_step) const {                            \
     156             :     return add_inhomogeneous_implicit_terms_impl(u, implicit_history,    \
     157             :                                                  time_step);             \
     158             :   }                                                                      \
     159             :   double IMEX_TIME_STEPPER_DERIVED_CLASS(data)::implicit_weight_forward( \
     160             :       const TimeSteppers::MutableUntypedHistory<                         \
     161             :           IMEX_TIME_STEPPER_WRAPPED_TYPE(data)>& implicit_history,       \
     162             :       const TimeDelta& time_step) const {                                \
     163             :     return implicit_weight_impl(implicit_history, time_step);            \
     164             :   }
     165             : /// \endcond
     166             : 
     167             : /// \ingroup TimeSteppersGroup
     168             : /// Macro declaring overloaded detail methods in classes derived from
     169             : /// ImexTimeStepper.  Must be placed in a private section of the class
     170             : /// body.
     171           1 : #define IMEX_TIME_STEPPER_DECLARE_OVERLOADS                         \
     172             :   GENERATE_INSTANTIATIONS(IMEX_TIME_STEPPER_DECLARE_OVERLOADS_IMPL, \
     173             :                           (MATH_WRAPPER_TYPES))
     174             : 
     175             : /// \ingroup TimeSteppersGroup
     176             : /// Macro defining overloaded detail methods in classes derived from
     177             : /// ImexTimeStepper.  Must be placed in the cpp file for the derived
     178             : /// class.
     179           1 : #define IMEX_TIME_STEPPER_DEFINE_OVERLOADS(derived_class)          \
     180             :   GENERATE_INSTANTIATIONS(IMEX_TIME_STEPPER_DEFINE_OVERLOADS_IMPL, \
     181             :                           (MATH_WRAPPER_TYPES), (derived_class))

Generated by: LCOV version 1.14