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

Generated by: LCOV version 1.14