SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - AdamsBashforth.hpp Hit Total Coverage
Commit: e1f22ede76131d2a431eabbd2dd32008f3162edb Lines: 11 43 25.6 %
Date: 2025-04-16 15:32:12
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 <cstddef>
       7             : #include <cstdint>
       8             : #include <optional>
       9             : 
      10             : #include "Options/String.hpp"
      11             : #include "Time/StepperErrorEstimate.hpp"
      12             : #include "Time/TimeStepId.hpp"
      13             : #include "Time/TimeSteppers/LtsTimeStepper.hpp"
      14             : #include "Utilities/Serialization/CharmPupable.hpp"
      15             : #include "Utilities/TMPL.hpp"
      16             : 
      17             : /// \cond
      18             : struct ApproximateTime;
      19             : struct StepperErrorTolerances;
      20             : class TimeDelta;
      21             : namespace PUP {
      22             : class er;
      23             : }  // namespace PUP
      24             : namespace TimeSteppers {
      25             : template <typename T>
      26             : class BoundaryHistoryEvaluator;
      27             : class ConstBoundaryHistoryTimes;
      28             : template <typename T>
      29             : class ConstUntypedHistory;
      30             : class MutableBoundaryHistoryTimes;
      31             : template <typename T>
      32             : class MutableUntypedHistory;
      33             : }  // namespace TimeSteppers
      34             : namespace gsl {
      35             : template <class T>
      36             : class not_null;
      37             : }  // namespace gsl
      38             : /// \endcond
      39             : 
      40             : namespace TimeSteppers {
      41             : 
      42             : /*!
      43             :  * \ingroup TimeSteppersGroup
      44             :  *
      45             :  * An Nth order Adams-Bashforth time stepper.
      46             :  *
      47             :  * The stable step size factors for different orders are given by:
      48             :  *
      49             :  * <table class="doxtable">
      50             :  *  <tr>
      51             :  *    <th> %Order </th>
      52             :  *    <th> CFL Factor </th>
      53             :  *  </tr>
      54             :  *  <tr>
      55             :  *    <td> 1 </td>
      56             :  *    <td> 1 </td>
      57             :  *  </tr>
      58             :  *  <tr>
      59             :  *    <td> 2 </td>
      60             :  *    <td> 1 / 2 </td>
      61             :  *  </tr>
      62             :  *  <tr>
      63             :  *    <td> 3 </td>
      64             :  *    <td> 3 / 11 </td>
      65             :  *  </tr>
      66             :  *  <tr>
      67             :  *    <td> 4 </td>
      68             :  *    <td> 3 / 20 </td>
      69             :  *  </tr>
      70             :  *  <tr>
      71             :  *    <td> 5 </td>
      72             :  *    <td> 45 / 551 </td>
      73             :  *  </tr>
      74             :  *  <tr>
      75             :  *    <td> 6 </td>
      76             :  *    <td> 5 / 114 </td>
      77             :  *  </tr>
      78             :  *  <tr>
      79             :  *    <td> 7 </td>
      80             :  *    <td> 945 / 40663 </td>
      81             :  *  </tr>
      82             :  *  <tr>
      83             :  *    <td> 8 </td>
      84             :  *    <td> 945 / 77432 </td>
      85             :  *  </tr>
      86             :  * </table>
      87             :  *
      88             :  * \section lts Local time stepping calculation
      89             :  *
      90             :  * \f$\newcommand\tL{t^L}\newcommand\tR{t^R}\newcommand\tU{\tilde{t}\!}
      91             :  * \newcommand\mat{\mathbf}\f$
      92             :  *
      93             :  * Suppose the local and remote sides of the interface are evaluated
      94             :  * at times \f$\ldots, \tL_{-1}, \tL_0, \tL_1, \ldots\f$ and
      95             :  * \f$\ldots, \tR_{-1}, \tR_0, \tR_1, \ldots\f$, respectively, with
      96             :  * the starting location of the numbering arbitrary in each case.
      97             :  * Let the step we wish to calculate the effect of be the step from
      98             :  * \f$\tL_{m_S}\f$ to \f$\tL_{m_S+1}\f$.  We call the sequence
      99             :  * produced from the union of the local and remote time sequences
     100             :  * \f$\ldots, \tU_{-1}, \tU_0, \tU_1, \ldots\f$.  For example, one
     101             :  * possible sequence of times is:
     102             :  * \f{equation}
     103             :  *   \begin{aligned}
     104             :  *     \text{Local side:} \\ \text{Union times:} \\ \text{Remote side:}
     105             :  *   \end{aligned}
     106             :  *   \cdots
     107             :  *   \begin{gathered}
     108             :  *     \, \\ \tU_1 \\ \tR_5
     109             :  *   \end{gathered}
     110             :  *   \leftarrow \Delta \tU_1 \rightarrow
     111             :  *   \begin{gathered}
     112             :  *     \tL_4 \\ \tU_2 \\ \,
     113             :  *   \end{gathered}
     114             :  *   \leftarrow \Delta \tU_2 \rightarrow
     115             :  *   \begin{gathered}
     116             :  *     \, \\ \tU_3 \\ \tR_6
     117             :  *   \end{gathered}
     118             :  *   \leftarrow \Delta \tU_3 \rightarrow
     119             :  *   \begin{gathered}
     120             :  *    \, \\ \tU_4 \\ \tR_7
     121             :  *   \end{gathered}
     122             :  *   \leftarrow \Delta \tU_4 \rightarrow
     123             :  *   \begin{gathered}
     124             :  *     \tL_5 \\ \tU_5 \\ \,
     125             :  *   \end{gathered}
     126             :  *   \cdots
     127             :  * \f}
     128             :  * We call the indices of the step's start and end times in the
     129             :  * union time sequence \f$n_S\f$ and \f$n_E\f$, respectively.  We
     130             :  * define \f$n^L_m\f$ to be the union-time index corresponding to
     131             :  * \f$\tL_m\f$ and \f$m^L_n\f$ to be the index of the last local
     132             :  * time not later than \f$\tU_n\f$ and similarly for the remote
     133             :  * side.  So for the above example, \f$n^L_4 = 2\f$ and \f$m^R_2 =
     134             :  * 5\f$, and if we wish to compute the step from \f$\tL_4\f$ to
     135             :  * \f$\tL_5\f$ we would have \f$m_S = 4\f$, \f$n_S = 2\f$, and
     136             :  * \f$n_E = 5\f$.
     137             :  *
     138             :  * If we wish to evaluate the change over this step to \f$k\f$th
     139             :  * order, we can write the change in the value as a linear
     140             :  * combination of the values of the coupling between the elements at
     141             :  * unequal times:
     142             :  * \f{equation}
     143             :  *   \mat{F}_{m_S} =
     144             :  *   \mspace{-10mu}
     145             :  *   \sum_{q^L = m_S-(k-1)}^{m_S}
     146             :  *   \,
     147             :  *   \sum_{q^R = m^R_{n_S}-(k-1)}^{m^R_{n_E-1}}
     148             :  *   \mspace{-10mu}
     149             :  *   \mat{D}_{q^Lq^R}
     150             :  *   I_{q^Lq^R},
     151             :  * \f}
     152             :  * where \f$\mat{D}_{q^Lq^R}\f$ is the coupling function evaluated
     153             :  * between data from \f$\tL_{q^L}\f$ and \f$\tR_{q^R}\f$.  The
     154             :  * coefficients can be written as the sum of three terms,
     155             :  * \f{equation}
     156             :  *   I_{q^Lq^R} = I^E_{q^Lq^R} + I^R_{q^Lq^R} + I^L_{q^Lq^R},
     157             :  * \f}
     158             :  * which can be interpreted as a contribution from equal-time
     159             :  * evaluations and contributions related to the remote and local
     160             :  * evaluation times.  These are given by
     161             :  * \f{align}
     162             :  *   I^E_{q^Lq^R} &=
     163             :  *   \mspace{-10mu}
     164             :  *   \sum_{n=n_S}^{\min\left\{n_E, n^L+k\right\}-1}
     165             :  *   \mspace{-10mu}
     166             :  *   \tilde{\alpha}_{n,n-n^L} \Delta \tU_n
     167             :  *   &&\text{if $\tL_{q^L} = \tR_{q^R}$, otherwise 0}
     168             :  *   \\
     169             :  *   I^R_{q^Lq^R} &=
     170             :  *   \ell_{q^L - m_S + k}\!\left(
     171             :  *     \tU_{n^R}; \tL_{m_S - (k-1)}, \ldots, \tL_{m_S}\right)
     172             :  *   \mspace{-10mu}
     173             :  *   \sum_{n=\max\left\{n_S, n^R\right\}}
     174             :  *       ^{\min\left\{n_E, n^R+k\right\}-1}
     175             :  *   \mspace{-10mu}
     176             :  *   \tilde{\alpha}_{n,n-n^R} \Delta \tU_n
     177             :  *   &&\text{if $\tR_{q^R}$ is not in $\{\tL_{\vphantom{|}\cdots}\}$,
     178             :  *     otherwise 0}
     179             :  *   \\
     180             :  *   I^L_{q^Lq^R} &=
     181             :  *   \mspace{-10mu}
     182             :  *   \sum_{n=\max\left\{n_S, n^R\right\}}
     183             :  *       ^{\min\left\{n_E, n^L+k, n^R_{q^R+k}\right\}-1}
     184             :  *   \mspace{-10mu}
     185             :  *   \ell_{q^R - m^R_n + k}\!\left(\tU_{n^L};
     186             :  *     \tR_{m^R_n - (k-1)}, \ldots, \tR_{m^R_n}\right)
     187             :  *   \tilde{\alpha}_{n,n-n^L} \Delta \tU_n
     188             :  *   &&\text{if $\tL_{q^L}$ is not in $\{\tR_{\vphantom{|}\cdots}\}$,
     189             :  *     otherwise 0,}
     190             :  * \f}
     191             :  * where for brevity we write \f$n^L = n^L_{q^L}\f$ and \f$n^R =
     192             :  * n^R_{q^R}\f$, and where \f$\ell_a(t; x_1, \ldots, x_k)\f$ a
     193             :  * Lagrange interpolating polynomial and \f$\tilde{\alpha}_{nj}\f$
     194             :  * is the \f$j\f$th coefficient for an Adams-Bashforth step over the
     195             :  * union times from step \f$n\f$ to step \f$n+1\f$.
     196             :  */
     197           1 : class AdamsBashforth : public LtsTimeStepper {
     198             :  public:
     199           0 :   static constexpr const size_t minimum_order = 1;
     200           0 :   static constexpr const size_t maximum_order = 8;
     201             : 
     202           0 :   struct Order {
     203           0 :     using type = size_t;
     204           0 :     static constexpr Options::String help = {"Convergence order"};
     205           0 :     static type lower_bound() { return 1; }
     206           0 :     static type upper_bound() { return maximum_order; }
     207             :   };
     208           0 :   using options = tmpl::list<Order>;
     209           0 :   static constexpr Options::String help = {
     210             :       "An Adams-Bashforth Nth order time-stepper."};
     211             : 
     212           0 :   AdamsBashforth() = default;
     213           0 :   explicit AdamsBashforth(size_t order);
     214           0 :   AdamsBashforth(const AdamsBashforth&) = default;
     215           0 :   AdamsBashforth& operator=(const AdamsBashforth&) = default;
     216           0 :   AdamsBashforth(AdamsBashforth&&) = default;
     217           0 :   AdamsBashforth& operator=(AdamsBashforth&&) = default;
     218           0 :   ~AdamsBashforth() override = default;
     219             : 
     220           1 :   size_t order() const override;
     221             : 
     222           1 :   uint64_t number_of_substeps() const override;
     223             : 
     224           1 :   uint64_t number_of_substeps_for_error() const override;
     225             : 
     226           1 :   size_t number_of_past_steps() const override;
     227             : 
     228           1 :   double stable_step() const override;
     229             : 
     230           1 :   bool monotonic() const override;
     231             : 
     232           1 :   TimeStepId next_time_id(const TimeStepId& current_id,
     233             :                           const TimeDelta& time_step) const override;
     234             : 
     235           1 :   TimeStepId next_time_id_for_error(const TimeStepId& current_id,
     236             :                                     const TimeDelta& time_step) const override;
     237             : 
     238           1 :   bool neighbor_data_required(
     239             :       const TimeStepId& next_substep_id,
     240             :       const TimeStepId& neighbor_data_id) const override;
     241             : 
     242           1 :   bool neighbor_data_required(
     243             :       double dense_output_time,
     244             :       const TimeStepId& neighbor_data_id) const override;
     245             : 
     246           0 :   WRAPPED_PUPable_decl_template(AdamsBashforth);  // NOLINT
     247             : 
     248           0 :   explicit AdamsBashforth(CkMigrateMessage* /*unused*/) {}
     249             : 
     250             :   // clang-tidy: do not pass by non-const reference
     251           0 :   void pup(PUP::er& p) override;  // NOLINT
     252             : 
     253             :  private:
     254           0 :   friend bool operator==(const AdamsBashforth& lhs, const AdamsBashforth& rhs);
     255             : 
     256             :   template <bool DenseOutput, typename T>
     257           0 :   std::optional<StepperErrorEstimate> update_u_common(
     258             :       gsl::not_null<T*> u, const ConstUntypedHistory<T>& history,
     259             :       const tmpl::conditional_t<DenseOutput, ApproximateTime, Time>& time,
     260             :       const std::optional<StepperErrorTolerances>& tolerances) const;
     261             : 
     262             :   template <typename T>
     263           0 :   void update_u_impl(gsl::not_null<T*> u, const ConstUntypedHistory<T>& history,
     264             :                      const TimeDelta& time_step) const;
     265             : 
     266             :   template <typename T>
     267           0 :   std::optional<StepperErrorEstimate> update_u_impl(
     268             :       gsl::not_null<T*> u, const ConstUntypedHistory<T>& history,
     269             :       const TimeDelta& time_step,
     270             :       const std::optional<StepperErrorTolerances>& tolerances) const;
     271             : 
     272             :   template <typename T>
     273           0 :   void clean_history_impl(const MutableUntypedHistory<T>& history) const;
     274             : 
     275             :   template <typename T>
     276           0 :   bool dense_update_u_impl(gsl::not_null<T*> u,
     277             :                            const ConstUntypedHistory<T>& history,
     278             :                            double time) const;
     279             : 
     280             :   template <typename T>
     281           0 :   bool can_change_step_size_impl(const TimeStepId& time_id,
     282             :                                  const ConstUntypedHistory<T>& history) const;
     283             : 
     284             :   template <typename T>
     285           0 :   void add_boundary_delta_impl(
     286             :       gsl::not_null<T*> result,
     287             :       const TimeSteppers::ConstBoundaryHistoryTimes& local_times,
     288             :       const TimeSteppers::ConstBoundaryHistoryTimes& remote_times,
     289             :       const TimeSteppers::BoundaryHistoryEvaluator<T>& coupling,
     290             :       const TimeDelta& time_step) const;
     291             : 
     292           0 :   void clean_boundary_history_impl(
     293             :       const TimeSteppers::MutableBoundaryHistoryTimes& local_times,
     294             :       const TimeSteppers::MutableBoundaryHistoryTimes& remote_times)
     295             :       const override;
     296             : 
     297             :   template <typename T>
     298           0 :   void boundary_dense_output_impl(
     299             :       gsl::not_null<T*> result,
     300             :       const TimeSteppers::ConstBoundaryHistoryTimes& local_times,
     301             :       const TimeSteppers::ConstBoundaryHistoryTimes& remote_times,
     302             :       const TimeSteppers::BoundaryHistoryEvaluator<T>& coupling,
     303             :       const double time) const;
     304             : 
     305             :   TIME_STEPPER_DECLARE_OVERLOADS
     306             :   LTS_TIME_STEPPER_DECLARE_OVERLOADS
     307             : 
     308           0 :   size_t order_ = 3;
     309             : };
     310             : 
     311           0 : bool operator!=(const AdamsBashforth& lhs, const AdamsBashforth& rhs);
     312             : }  // namespace TimeSteppers

Generated by: LCOV version 1.14