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