SpECTRE Documentation Coverage Report
Current view: top level - Time - VariableOrderAlgorithm.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 4.8 % 21 1
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              : // 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 2.0-1