SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - LtsTimeStepper.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 66.7 % 15 10
Test Date: 2026-10-22 17:29:42
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 :   using provided_time_stepper_interfaces =
      44              :       tmpl::list<LtsTimeStepper, TimeStepper>;
      45              : 
      46            0 :   WRAPPED_PUPable_abstract(LtsTimeStepper);  // NOLINT
      47              : 
      48              :   // These two are defined as separate type aliases to keep the
      49              :   // doxygen page width somewhat under control.
      50              :   template <typename LocalVars, typename RemoteVars, typename Coupling>
      51            0 :   using BoundaryHistoryType = TimeSteppers::BoundaryHistory<
      52              :       LocalVars, RemoteVars,
      53              :       math_wrapper_type<
      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 2.0-1