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 : 8 : #include "DataStructures/TaggedVariant.hpp" 9 : #include "Options/String.hpp" 10 : #include "Time/TimeSteppers/RungeKutta.hpp" 11 : #include "Utilities/Serialization/CharmPupable.hpp" 12 : #include "Utilities/TMPL.hpp" 13 : 14 : /// \cond 15 : namespace TimeSteppers { 16 : template <typename T> 17 : class UntypedHistory; 18 : } // namespace TimeSteppers 19 : /// \endcond 20 : 21 : namespace TimeSteppers { 22 : 23 : /*! 24 : * \ingroup TimeSteppersGroup 25 : * 26 : * The standard 4th-order Runge-Kutta method, given e.g. in 27 : * https://en.wikipedia.org/wiki/Runge-Kutta_methods 28 : * that solves equations of the form 29 : * 30 : * \f{eqnarray}{ 31 : * \frac{du}{dt} & = & \mathcal{L}(t,u). 32 : * \f} 33 : * Given a solution \f$u(t^n)=u^n\f$, this stepper computes 34 : * \f$u(t^{n+1})=u^{n+1}\f$ using the following equations: 35 : * 36 : * \f{eqnarray}{ 37 : * v^{(1)} & = & u^n + dt\cdot \mathcal{L}(t^n, u^n)/2,\\ 38 : * v^{(2)} & = & u^n + dt\cdot \mathcal{L}(t^n + dt/2, v^{(1)})/2,\\ 39 : * v^{(3)} & = & u^n + dt\cdot \mathcal{L}(t^n + dt/2, v^{(2)}),\\ 40 : * v^{(4)} & = & u^n + dt\cdot \mathcal{L}(t^n + dt, v^{(3)}),\\ 41 : * u^{n+1} & = & (2v^{(1)} + 4v^{(2)} + 2v^{(3)} + v^{(4)} - 3 u^n)/6. 42 : * \f} 43 : * 44 : * Note that in the implementation, the expression for \f$u^{n+1}\f$ is 45 : * computed simultaneously with \f$v^{(4)}\f$, so that there are 46 : * actually only four substeps per step. 47 : * 48 : * The CFL factor/stable step size is 1.3926467817026411. 49 : */ 50 1 : class ClassicalRungeKutta4 : public RungeKutta { 51 : public: 52 0 : using options = tmpl::list<>; 53 0 : static constexpr Options::String help = { 54 : "The standard fourth-order Runge-Kutta time-stepper."}; 55 : 56 0 : ClassicalRungeKutta4() = default; 57 0 : ClassicalRungeKutta4(const ClassicalRungeKutta4&) = default; 58 0 : ClassicalRungeKutta4& operator=(const ClassicalRungeKutta4&) = default; 59 0 : ClassicalRungeKutta4(ClassicalRungeKutta4&&) = default; 60 0 : ClassicalRungeKutta4& operator=(ClassicalRungeKutta4&&) = default; 61 0 : ~ClassicalRungeKutta4() override = default; 62 : 63 1 : variants::TaggedVariant<Tags::FixedOrder, Tags::VariableOrder> order() 64 : const override; 65 : 66 1 : double stable_step() const override; 67 : 68 0 : WRAPPED_PUPable_decl_template(ClassicalRungeKutta4); // NOLINT 69 : 70 0 : explicit ClassicalRungeKutta4(CkMigrateMessage* /*unused*/) {} 71 : 72 0 : const ButcherTableau& butcher_tableau() const override; 73 : }; 74 : 75 0 : inline bool constexpr operator==(const ClassicalRungeKutta4& /*lhs*/, 76 : const ClassicalRungeKutta4& /*rhs*/) { 77 : return true; 78 : } 79 : 80 0 : inline bool constexpr operator!=(const ClassicalRungeKutta4& /*lhs*/, 81 : const ClassicalRungeKutta4& /*rhs*/) { 82 : return false; 83 : } 84 : } // namespace TimeSteppers