SpECTRE Documentation Coverage Report
Current view: top level - Time/TimeSteppers - TimeStepper.hpp Hit Total Coverage
Commit: b1342d46f40e2d46bbd11d0cef68fd973031a24b Lines: 11 19 57.9 %
Date: 2020-09-24 20:24: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 <cstddef>
       7             : #include <cstdint>
       8             : #include <pup.h>
       9             : #include <type_traits>
      10             : 
      11             : #include "Parallel/CharmPupable.hpp"
      12             : #include "Time/TimeStepId.hpp"
      13             : #include "Utilities/FakeVirtual.hpp"
      14             : #include "Utilities/Gsl.hpp"
      15             : #include "Utilities/TMPL.hpp"
      16             : 
      17             : /// \cond
      18             : class TimeDelta;
      19             : namespace TimeSteppers {
      20             : class AdamsBashforthN;  // IWYU pragma: keep
      21             : template <typename LocalVars, typename RemoteVars, typename CouplingResult>
      22             : class BoundaryHistory;
      23             : template <typename Vars, typename DerivVars>
      24             : class History;
      25             : }  // namespace TimeSteppers
      26             : /// \endcond
      27             : 
      28             : /// \ingroup TimeSteppersGroup
      29             : ///
      30             : /// Holds classes that take time steps.
      31             : namespace TimeSteppers {
      32             : class AdamsBashforthN;  // IWYU pragma: keep
      33             : class DormandPrince5;
      34             : class RungeKutta3;  // IWYU pragma: keep
      35             : class RungeKutta4;
      36             : }  // namespace TimeSteppers
      37             : 
      38             : namespace TimeStepper_detail {
      39             : DEFINE_FAKE_VIRTUAL(can_change_step_size)
      40             : DEFINE_FAKE_VIRTUAL(dense_update_u)
      41             : DEFINE_FAKE_VIRTUAL(update_u)
      42             : }  // namespace TimeStepper_detail
      43             : 
      44             : /// \ingroup TimeSteppersGroup
      45             : ///
      46             : /// Abstract base class for TimeSteppers.
      47           1 : class TimeStepper : public PUP::able {
      48             :  public:
      49           0 :   using Inherit = TimeStepper_detail::FakeVirtualInherit_can_change_step_size<
      50             :       TimeStepper_detail::FakeVirtualInherit_dense_update_u<
      51             :           TimeStepper_detail::FakeVirtualInherit_update_u<TimeStepper>>>;
      52           0 :   using creatable_classes =
      53             :       tmpl::list<TimeSteppers::AdamsBashforthN, TimeSteppers::DormandPrince5,
      54             :                  TimeSteppers::RungeKutta3, TimeSteppers::RungeKutta4>;
      55             : 
      56           0 :   WRAPPED_PUPable_abstract(TimeStepper);  // NOLINT
      57             : 
      58             :   /// Add the change for the current substep to u.
      59             :   template <typename Vars, typename DerivVars>
      60           1 :   void update_u(
      61             :       const gsl::not_null<Vars*> u,
      62             :       const gsl::not_null<TimeSteppers::History<Vars, DerivVars>*> history,
      63             :       const TimeDelta& time_step) const noexcept {
      64             :     return TimeStepper_detail::fake_virtual_update_u<creatable_classes>(
      65             :         this, u, history, time_step);
      66             :   }
      67             : 
      68             :   /// Compute the solution value at a time between steps.  To evaluate
      69             :   /// at a time within a given step, this must be called before the
      70             :   /// step is completed but after any intermediate substeps have been
      71             :   /// taken.  The value of `*u` before this function is called should
      72             :   /// be the value at the last substep.
      73             :   template <typename Vars, typename DerivVars>
      74           1 :   void dense_update_u(const gsl::not_null<Vars*> u,
      75             :                       const TimeSteppers::History<Vars, DerivVars>& history,
      76             :                       const double time) const noexcept {
      77             :     return TimeStepper_detail::fake_virtual_dense_update_u<creatable_classes>(
      78             :         this, u, history, time);
      79             :   }
      80             : 
      81             :   /// Number of substeps in this TimeStepper
      82           1 :   virtual uint64_t number_of_substeps() const noexcept = 0;
      83             : 
      84             :   /// Number of past time steps needed for multi-step method
      85           1 :   virtual size_t number_of_past_steps() const noexcept = 0;
      86             : 
      87             :   /// Rough estimate of the maximum step size this method can take
      88             :   /// stably as a multiple of the step for Euler's method.
      89           1 :   virtual double stable_step() const noexcept = 0;
      90             : 
      91             :   /// The TimeStepId after the current substep
      92           1 :   virtual TimeStepId next_time_id(
      93             :       const TimeStepId& current_id,
      94             :       const TimeDelta& time_step) const noexcept = 0;
      95             : 
      96             :   /// Whether a change in the step size is allowed before taking
      97             :   /// a step.
      98             :   template <typename Vars, typename DerivVars>
      99           1 :   bool can_change_step_size(
     100             :       const TimeStepId& time_id,
     101             :       const TimeSteppers::History<Vars, DerivVars>& history) const noexcept {
     102             :     return TimeStepper_detail::fake_virtual_can_change_step_size<
     103             :         creatable_classes>(this, time_id, history);
     104             :   }
     105             : };
     106             : 
     107             : // LtsTimeStepper cannot be split out into its own file because the
     108             : // LtsTimeStepper -> TimeStepper -> AdamsBashforthN -> LtsTimeStepper
     109             : // include loop causes AdamsBashforthN to be defined before its base
     110             : // class if LtsTimeStepper is included first.
     111             : namespace LtsTimeStepper_detail {
     112             : DEFINE_FAKE_VIRTUAL(boundary_dense_output)
     113             : DEFINE_FAKE_VIRTUAL(compute_boundary_delta)
     114             : }  // namespace LtsTimeStepper_detail
     115             : 
     116             : /// \ingroup TimeSteppersGroup
     117             : ///
     118             : /// Base class for TimeSteppers with local time-stepping support,
     119             : /// derived from TimeStepper.
     120           1 : class LtsTimeStepper : public TimeStepper::Inherit {
     121             :  public:
     122           0 :   using Inherit =
     123             :       LtsTimeStepper_detail::FakeVirtualInherit_boundary_dense_output<
     124             :           LtsTimeStepper_detail::FakeVirtualInherit_compute_boundary_delta<
     125             :               LtsTimeStepper>>;
     126             :   // When you add a class here, remember to add it to TimeStepper as well.
     127           0 :   using creatable_classes = tmpl::list<TimeSteppers::AdamsBashforthN>;
     128             : 
     129           0 :   WRAPPED_PUPable_abstract(LtsTimeStepper);  // NOLINT
     130             : 
     131             :   /// \brief Compute the change in a boundary quantity due to the
     132             :   /// coupling on the interface.
     133             :   ///
     134             :   /// The coupling function `coupling` should take the local and
     135             :   /// remote flux data and compute the derivative of the boundary
     136             :   /// quantity.  These values may be used to form a linear combination
     137             :   /// internally, so the result should have appropriate mathematical
     138             :   /// operators defined to allow that.
     139             :   template <typename LocalVars, typename RemoteVars, typename Coupling>
     140             :   std::result_of_t<const Coupling&(LocalVars, RemoteVars)>
     141           1 :   compute_boundary_delta(
     142             :       const Coupling& coupling,
     143             :       const gsl::not_null<TimeSteppers::BoundaryHistory<
     144             :           LocalVars, RemoteVars,
     145             :           std::result_of_t<const Coupling&(LocalVars, RemoteVars)>>*>
     146             :           history,
     147             :       const TimeDelta& time_step) const noexcept {
     148             :     return LtsTimeStepper_detail::fake_virtual_compute_boundary_delta<
     149             :         creatable_classes>(this, coupling, history, time_step);
     150             :   }
     151             : 
     152             :   template <typename LocalVars, typename RemoteVars, typename Coupling>
     153             :   std::result_of_t<const Coupling&(LocalVars, RemoteVars)>
     154           0 :   boundary_dense_output(
     155             :       const Coupling& coupling,
     156             :       const TimeSteppers::BoundaryHistory<
     157             :           LocalVars, RemoteVars,
     158             :           std::result_of_t<const Coupling&(LocalVars, RemoteVars)>>& history,
     159             :       const double time) const noexcept {
     160             :     return LtsTimeStepper_detail::fake_virtual_boundary_dense_output<
     161             :         creatable_classes>(this, coupling, history, time);
     162             :   }
     163             : 
     164             :   /// Substep LTS integrators are not supported, so this is always 1.
     165           1 :   uint64_t number_of_substeps() const noexcept final { return 1; }
     166             : 
     167             :   /// \cond
     168             :   // FakeVirtual forces derived classes to override the fake virtual
     169             :   // methods.  Here the base class method is actually what we want
     170             :   // because we are not a most-derived class, so we forward to the
     171             :   // TimeStepper version.
     172             :   template <typename Vars, typename DerivVars>
     173             :   void update_u(
     174             :       const gsl::not_null<Vars*> u,
     175             :       const gsl::not_null<TimeSteppers::History<Vars, DerivVars>*> history,
     176             :       const TimeDelta& time_step) const noexcept {
     177             :     return TimeStepper::update_u(u, history, time_step);
     178             :   }
     179             : 
     180             :   template <typename Vars, typename DerivVars>
     181             :   bool can_change_step_size(
     182             :       const TimeStepId& time_id,
     183             :       const TimeSteppers::History<Vars, DerivVars>& history) const noexcept {
     184             :     return TimeStepper::can_change_step_size(time_id, history);
     185             :   }
     186             :   /// \endcond
     187             : };
     188             : 
     189             : 
     190             : #include "Time/TimeSteppers/AdamsBashforthN.hpp"  // IWYU pragma: keep
     191             : #include "Time/TimeSteppers/DormandPrince5.hpp"
     192             : #include "Time/TimeSteppers/RungeKutta3.hpp"  // IWYU pragma: keep
     193             : #include "Time/TimeSteppers/RungeKutta4.hpp"  // IWYU pragma: keep

Generated by: LCOV version 1.14