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
|