SpECTRE Documentation Coverage Report
Current view: top level - Time - VariableOrderAlgorithm.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 1 21 4.8 %
Date: 2025-12-05 05:03:31
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : // Tests for the VariableOrderAlgorithm class are performed in
       5             : // Test_ChangeTimeStepperOrder.cpp.  The class is split into this file
       6             : // to avoid include loops with the associated tags.
       7             : 
       8             : #pragma once
       9             : 
      10             : #include <array>
      11             : #include <cstddef>
      12             : #include <optional>
      13             : 
      14             : #include "Options/String.hpp"
      15             : #include "Time/History.hpp"
      16             : #include "Time/StepperErrorEstimate.hpp"
      17             : #include "Time/StepperErrorTolerances.hpp"
      18             : #include "Utilities/ErrorHandling/Assert.hpp"
      19             : #include "Utilities/TMPL.hpp"
      20             : 
      21             : /// \cond
      22             : namespace Options {
      23             : template <typename... AlternativeLists>
      24             : struct Alternatives;
      25             : }  // namespace Options
      26             : /// \endcond
      27             : 
      28             : /*!
      29             :  * \ingroup TimeGroup
      30             :  * \brief Class encapsulating the time-stepper order changing algorithms
      31             :  *
      32             :  * \details Supports two modes: driving the order to a specified constant, and
      33             :  * measuring the convergence of the error estimates.
      34             :  *
      35             :  * When driving to a constant, the order is changed by one towards the
      36             :  * goal if it is not at the goal.
      37             :  *
      38             :  * When measuring convergence, let the relative error estimate from
      39             :  * the time stepper for order-$k$ integration be $e_k$, and $\lambda
      40             :  * \le 1$ be the falloff this class was constructed with.  Then, we
      41             :  * decrease the order by one if, for any $k \ge 2$ and less than the
      42             :  * current integration order,
      43             :  *
      44             :  * \f{equation}
      45             :  *   \frac{e_k}{e_{k-1}} >
      46             :  *   \left(\min_{2 \le j < k} \frac{e_j}{e_{j-1}}\right)^\lambda,
      47             :  * \f}
      48             :  *
      49             :  * with the right-hand side taken to be $1$ for $k = 2$.  If the order
      50             :  * is not decreased, it is kept the same if the above condition holds
      51             :  * for $k$ equal to the current integration order, and is increased by
      52             :  * one otherwise.  If the current integration order is $1$ (not
      53             :  * possible for predictor-corrector methods), it is always increased.
      54             :  * This algorithm will almost never prefer an integration order less
      55             :  * than three.
      56             :  *
      57             :  * \note This is currently all implemented in one class for simplicity
      58             :  * with dealing with templates.  If we add more algorithms splitting
      59             :  * into a base class with implementations would be appropriate.
      60             :  */
      61           1 : class VariableOrderAlgorithm {
      62             :  public:
      63           0 :   struct GoalOrder {
      64           0 :     using type = size_t;
      65           0 :     static constexpr Options::String help = "Order to drive the integrator to.";
      66             :   };
      67             : 
      68           0 :   struct OrderFalloff {
      69           0 :     using type = double;
      70           0 :     static constexpr Options::String help =
      71             :         "Threshold for changing time-stepper order, as a logarithmic "
      72             :         "fraction of the best order-to-order improvement.";
      73             :   };
      74             : 
      75           0 :   using options = tmpl::list<
      76             :       Options::Alternatives<tmpl::list<GoalOrder>, tmpl::list<OrderFalloff>>>;
      77           0 :   static constexpr Options::String help =
      78             :       "Algorithm for choosing the time-stepper order in a variable-order "
      79             :       "evolution.";
      80             : 
      81           0 :   VariableOrderAlgorithm();
      82           0 :   explicit VariableOrderAlgorithm(size_t goal_order);
      83           0 :   explicit VariableOrderAlgorithm(double order_falloff);
      84             : 
      85           0 :   StepperErrorTolerances::Estimates required_estimates() const;
      86             : 
      87             :   template <typename... VariablesTags>
      88           0 :   size_t choose_order(
      89             :       const TimeSteppers::History<typename VariablesTags::type>&... histories,
      90             :       const typename tmpl::has_type<
      91             :           VariablesTags,
      92             :           std::array<std::optional<StepperErrorEstimate>, 2>>::type&... errors)
      93             :       const {
      94             :     const auto history_order =
      95             :         get_first_argument(histories...).integration_order();
      96             :     ASSERT((... and (history_order == histories.integration_order())),
      97             :            "Multiple histories with different integration orders.");
      98             : 
      99             :     if (goal_order_.has_value()) {
     100             :       ASSERT(not order_falloff_.has_value(),
     101             :              "Internal error: should not have multiple algorithms active");
     102             :       return choose_order_goal(history_order);
     103             :     } else {
     104             :       ASSERT(order_falloff_.has_value(),
     105             :              "VariableOrderAlgorithm not initialized");
     106             :       return choose_order_falloff(history_order, std::array{&errors[1]...});
     107             :     }
     108             :   }
     109             : 
     110           0 :   void pup(PUP::er& p);
     111             : 
     112             :  private:
     113           0 :   size_t choose_order_goal(size_t current_order) const;
     114             : 
     115             :   template <size_t NVars>
     116           0 :   size_t choose_order_falloff(
     117             :       size_t current_order,
     118             :       const std::array<const std::optional<StepperErrorEstimate>*, NVars>&
     119             :           errors) const;
     120             : 
     121           0 :   friend bool operator==(const VariableOrderAlgorithm& a,
     122             :                          const VariableOrderAlgorithm& b);
     123             : 
     124           0 :   std::optional<size_t> goal_order_{};
     125           0 :   std::optional<double> order_falloff_{};
     126             : };

Generated by: LCOV version 1.14