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

Generated by: LCOV version 1.14