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/ImexRungeKutta.hpp" 11 : #include "Utilities/Serialization/CharmPupable.hpp" 12 : #include "Utilities/TMPL.hpp" 13 : 14 : namespace TimeSteppers { 15 : /*! 16 : * \ingroup TimeSteppersGroup 17 : * \brief A third-order Runge-Kutta method with IMEX support. 18 : * 19 : * The method as published has four stages, but is implemented with 20 : * five as a way to convert it to an EDIRK method. 21 : * 22 : * The coefficients are given as IMEX-SSP3(4,3,3) in \cite Pareschi2005. 23 : * 24 : * While this method can be implemented so that the explicit part is 25 : * strong-stability-preserving, the presentation in \cite Pareschi2005 26 : * is not, and this implementation follows that presentation. See 27 : * \cite HesthavenWarburton section 5.7 for details. 28 : * 29 : * Using this time stepper in a non-IMEX simulation is not 30 : * recommended, as it performs two unused RHS evaluations. When using 31 : * IMEX it performs one extra evaluation because there are more 32 : * implicit steps than explicit. 33 : * 34 : * The implicit portion is L-stable. 35 : * 36 : * The CFL factor/stable step size is 1.25637. 37 : */ 38 1 : class Rk3Pareschi : public ImexRungeKutta { 39 : public: 40 0 : using options = tmpl::list<>; 41 0 : static constexpr Options::String help = { 42 : "A 3rd-order 4 stage Runge-Kutta scheme devised by Pareschi and Russo."}; 43 : 44 0 : Rk3Pareschi() = default; 45 0 : Rk3Pareschi(const Rk3Pareschi&) = default; 46 0 : Rk3Pareschi& operator=(const Rk3Pareschi&) = default; 47 0 : Rk3Pareschi(Rk3Pareschi&&) = default; 48 0 : Rk3Pareschi& operator=(Rk3Pareschi&&) = default; 49 0 : ~Rk3Pareschi() override = default; 50 : 51 1 : variants::TaggedVariant<Tags::FixedOrder, Tags::VariableOrder> order() 52 : const override; 53 : 54 1 : double stable_step() const override; 55 : 56 1 : size_t imex_order() const override; 57 : 58 1 : size_t implicit_stage_order() const override; 59 : 60 0 : WRAPPED_PUPable_decl_template(Rk3Pareschi); // NOLINT 61 : 62 0 : explicit Rk3Pareschi(CkMigrateMessage* /*unused*/) {} 63 : 64 0 : const ButcherTableau& butcher_tableau() const override; 65 : 66 0 : const ImplicitButcherTableau& implicit_butcher_tableau() const override; 67 : }; 68 : 69 0 : inline bool constexpr operator==(const Rk3Pareschi& /*lhs*/, 70 : const Rk3Pareschi& /*rhs*/) { 71 : return true; 72 : } 73 : 74 0 : inline bool constexpr operator!=(const Rk3Pareschi& lhs, 75 : const Rk3Pareschi& rhs) { 76 : return not(lhs == rhs); 77 : } 78 : } // namespace TimeSteppers