SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - LtsTimeStepper.hpp Hit Total Coverage
Commit: 9b01d30df5d2e946e7e38cc43c008be18ae9b1d2 Lines: 8 13 61.5 %
Date: 2024-04-23 04:54:49
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 <pup.h>
       7             : #include <type_traits>
       8             : 
       9             : #include "DataStructures/DataBox/PrefixHelpers.hpp"
      10             : #include "DataStructures/MathWrapper.hpp"
      11             : #include "Time/BoundaryHistory.hpp"
      12             : #include "Time/TimeSteppers/TimeStepper.hpp"
      13             : #include "Utilities/GenerateInstantiations.hpp"
      14             : #include "Utilities/Gsl.hpp"
      15             : #include "Utilities/Serialization/CharmPupable.hpp"
      16             : 
      17             : /// \cond
      18             : class TimeDelta;
      19             : class TimeStepId;
      20             : /// \endcond
      21             : 
      22             : /// \cond
      23             : #define LTS_TIME_STEPPER_WRAPPED_TYPE(data) BOOST_PP_TUPLE_ELEM(0, data)
      24             : #define LTS_TIME_STEPPER_DERIVED_CLASS(data) BOOST_PP_TUPLE_ELEM(1, data)
      25             : /// \endcond
      26             : 
      27             : /// \ingroup TimeSteppersGroup
      28             : ///
      29             : /// Base class for TimeSteppers with local time-stepping support,
      30             : /// derived from TimeStepper.
      31             : ///
      32             : /// Several of the member functions of this class are templated and
      33             : /// perform type erasure before forwarding their arguments to the
      34             : /// derived classes.  This is implemented using the macros \ref
      35             : /// LTS_TIME_STEPPER_DECLARE_OVERLOADS, which must be placed in a
      36             : /// private section of the class body, and
      37             : /// LTS_TIME_STEPPER_DEFINE_OVERLOADS(derived_class), which must be
      38             : /// placed in the cpp file.
      39           1 : class LtsTimeStepper : public virtual TimeStepper {
      40             :  public:
      41           0 :   static constexpr bool local_time_stepping = true;
      42           0 :   using provided_time_stepper_interfaces =
      43             :       tmpl::list<LtsTimeStepper, TimeStepper>;
      44             : 
      45           0 :   WRAPPED_PUPable_abstract(LtsTimeStepper);  // NOLINT
      46             : 
      47             :   // These two are defined as separate type aliases to keep the
      48             :   // doxygen page width somewhat under control.
      49             :   template <typename LocalVars, typename RemoteVars, typename Coupling>
      50           0 :   using BoundaryHistoryType = TimeSteppers::BoundaryHistory<
      51             :       LocalVars, RemoteVars,
      52             :       std::invoke_result_t<const Coupling&, LocalVars, RemoteVars>>;
      53             : 
      54             :   /// Return type of boundary-related functions.  The coupling returns
      55             :   /// the derivative of the variables, but this is multiplied by the
      56             :   /// time step so the return type should not have `dt` prefixes.
      57             :   template <typename LocalVars, typename RemoteVars, typename Coupling>
      58           1 :   using BoundaryReturn = db::unprefix_variables<
      59             :       std::invoke_result_t<const Coupling&, LocalVars, RemoteVars>>;
      60             : 
      61             : /// \cond
      62             : #define LTS_TIME_STEPPER_DECLARE_VIRTUALS_IMPL(_, data)              \
      63             :   virtual void add_boundary_delta_forward(                           \
      64             :       gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result,    \
      65             :       const TimeSteppers::MutableBoundaryHistoryTimes& local_times,  \
      66             :       const TimeSteppers::MutableBoundaryHistoryTimes& remote_times, \
      67             :       const TimeSteppers::BoundaryHistoryEvaluator<                  \
      68             :           LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling,            \
      69             :       const TimeDelta& time_step) const = 0;                         \
      70             :   virtual void boundary_dense_output_forward(                        \
      71             :       gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result,    \
      72             :       const TimeSteppers::ConstBoundaryHistoryTimes& local_times,    \
      73             :       const TimeSteppers::ConstBoundaryHistoryTimes& remote_times,   \
      74             :       const TimeSteppers::BoundaryHistoryEvaluator<                  \
      75             :           LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling,            \
      76             :       const double time) const = 0;
      77             : 
      78             :   GENERATE_INSTANTIATIONS(LTS_TIME_STEPPER_DECLARE_VIRTUALS_IMPL,
      79             :                           (MATH_WRAPPER_TYPES))
      80             : #undef LTS_TIME_STEPPER_DECLARE_VIRTUALS_IMPL
      81             :   /// \endcond
      82             : 
      83             :   /// \brief Check whether a neighbor record is needed for boundary
      84             :   /// output.
      85             :   ///
      86             :   /// In order to perform boundary output, all records from the
      87             :   /// neighbor with `TimeStepId`s for which this method returns true
      88             :   /// should have been added to the history.  Versions are provided
      89             :   /// for a substep and for dense output.
      90             :   /// @{
      91           1 :   virtual bool neighbor_data_required(
      92             :       const TimeStepId& next_substep_id,
      93             :       const TimeStepId& neighbor_data_id) const = 0;
      94             : 
      95           1 :   virtual bool neighbor_data_required(
      96             :       double dense_output_time, const TimeStepId& neighbor_data_id) const = 0;
      97             :   /// @}
      98             : 
      99             :   /// \brief Compute the change in a boundary quantity due to the
     100             :   /// coupling on the interface.
     101             :   ///
     102             :   /// The coupling function `coupling` should take the local and
     103             :   /// remote flux data and compute the derivative of the boundary
     104             :   /// quantity.  These values may be used to form a linear combination
     105             :   /// internally, so the result should have appropriate mathematical
     106             :   /// operators defined to allow that.
     107             :   ///
     108             :   /// Derived classes must implement this as a function with signature
     109             :   ///
     110             :   /// ```
     111             :   /// template <typename T>
     112             :   /// void add_boundary_delta_impl(
     113             :   ///     gsl::not_null<T*> result,
     114             :   ///     const TimeSteppers::MutableBoundaryHistoryTimes& local_times,
     115             :   ///     const TimeSteppers::MutableBoundaryHistoryTimes& remote_times,
     116             :   ///     const TimeSteppers::BoundaryHistoryEvaluator<T>& coupling,
     117             :   ///     const TimeDelta& time_step) const;
     118             :   /// ```
     119             :   ///
     120             :   /// \note
     121             :   /// Unlike the `update_u` methods, which overwrite the `result`
     122             :   /// argument, this function adds the result to the existing value.
     123             :   template <typename LocalVars, typename RemoteVars, typename Coupling>
     124           1 :   void add_boundary_delta(
     125             :       const gsl::not_null<BoundaryReturn<LocalVars, RemoteVars, Coupling>*>
     126             :           result,
     127             :       const gsl::not_null<BoundaryHistoryType<LocalVars, RemoteVars, Coupling>*>
     128             :           history,
     129             :       const TimeDelta& time_step, const Coupling& coupling) const {
     130             :     return add_boundary_delta_forward(&*make_math_wrapper(result),
     131             :                                       history->local(), history->remote(),
     132             :                                       history->evaluator(coupling), time_step);
     133             :   }
     134             : 
     135             :   /// Derived classes must implement this as a function with signature
     136             :   ///
     137             :   /// ```
     138             :   /// template <typename T>
     139             :   /// void boundary_dense_output_impl(
     140             :   ///     gsl::not_null<T*> result,
     141             :   ///     const TimeSteppers::ConstBoundaryHistoryTimes& local_times,
     142             :   ///     const TimeSteppers::ConstBoundaryHistoryTimes& remote_times,
     143             :   ///     const TimeSteppers::BoundaryHistoryEvaluator<T>& coupling,
     144             :   ///     const double time) const;
     145             :   /// ```
     146             :   template <typename LocalVars, typename RemoteVars, typename Coupling>
     147           1 :   void boundary_dense_output(
     148             :       const gsl::not_null<BoundaryReturn<LocalVars, RemoteVars, Coupling>*>
     149             :           result,
     150             :       const BoundaryHistoryType<LocalVars, RemoteVars, Coupling>& history,
     151             :       const double time, const Coupling& coupling) const {
     152             :     return boundary_dense_output_forward(&*make_math_wrapper(result),
     153             :                                          history.local(), history.remote(),
     154             :                                          history.evaluator(coupling), time);
     155             :   }
     156             : };
     157             : 
     158             : /// \cond
     159             : #define LTS_TIME_STEPPER_DECLARE_OVERLOADS_IMPL(_, data)             \
     160             :   void add_boundary_delta_forward(                                   \
     161             :       gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result,    \
     162             :       const TimeSteppers::MutableBoundaryHistoryTimes& local_times,  \
     163             :       const TimeSteppers::MutableBoundaryHistoryTimes& remote_times, \
     164             :       const TimeSteppers::BoundaryHistoryEvaluator<                  \
     165             :           LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling,            \
     166             :       const TimeDelta& time_step) const override;                    \
     167             :   void boundary_dense_output_forward(                                \
     168             :       gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result,    \
     169             :       const TimeSteppers::ConstBoundaryHistoryTimes& local_times,    \
     170             :       const TimeSteppers::ConstBoundaryHistoryTimes& remote_times,   \
     171             :       const TimeSteppers::BoundaryHistoryEvaluator<                  \
     172             :           LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling,            \
     173             :       const double time) const override;
     174             : 
     175             : #define LTS_TIME_STEPPER_DEFINE_OVERLOADS_IMPL(_, data)                     \
     176             :   void LTS_TIME_STEPPER_DERIVED_CLASS(data)::add_boundary_delta_forward(    \
     177             :       const gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result,     \
     178             :       const TimeSteppers::MutableBoundaryHistoryTimes& local_times,         \
     179             :       const TimeSteppers::MutableBoundaryHistoryTimes& remote_times,        \
     180             :       const TimeSteppers::BoundaryHistoryEvaluator<                         \
     181             :           LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling,                   \
     182             :       const TimeDelta& time_step) const {                                   \
     183             :     return add_boundary_delta_impl(result, local_times, remote_times,       \
     184             :                                    coupling, time_step);                    \
     185             :   }                                                                         \
     186             :   void LTS_TIME_STEPPER_DERIVED_CLASS(data)::boundary_dense_output_forward( \
     187             :       const gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result,     \
     188             :       const TimeSteppers::ConstBoundaryHistoryTimes& local_times,           \
     189             :       const TimeSteppers::ConstBoundaryHistoryTimes& remote_times,          \
     190             :       const TimeSteppers::BoundaryHistoryEvaluator<                         \
     191             :           LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling,                   \
     192             :       const double time) const {                                            \
     193             :     return boundary_dense_output_impl(result, local_times, remote_times,    \
     194             :                                       coupling, time);                      \
     195             :   }
     196             : /// \endcond
     197             : 
     198             : /// \ingroup TimeSteppersGroup
     199             : /// Macro declaring overloaded detail methods in classes derived from
     200             : /// TimeStepper.  Must be placed in a private section of the class
     201             : /// body.
     202           1 : #define LTS_TIME_STEPPER_DECLARE_OVERLOADS                         \
     203             :   GENERATE_INSTANTIATIONS(LTS_TIME_STEPPER_DECLARE_OVERLOADS_IMPL, \
     204             :                           (MATH_WRAPPER_TYPES))
     205             : 
     206             : /// \ingroup TimeSteppersGroup
     207             : /// Macro defining overloaded detail methods in classes derived from
     208             : /// TimeStepper.  Must be placed in the cpp file for the derived
     209             : /// class.
     210           1 : #define LTS_TIME_STEPPER_DEFINE_OVERLOADS(derived_class)          \
     211             :   GENERATE_INSTANTIATIONS(LTS_TIME_STEPPER_DEFINE_OVERLOADS_IMPL, \
     212             :                           (MATH_WRAPPER_TYPES), (derived_class))

Generated by: LCOV version 1.14