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 : 9 : #include "Options/String.hpp" 10 : #include "Time/TimeSteppers/TimeStepper.hpp" 11 : #include "Utilities/Serialization/CharmPupable.hpp" 12 : #include "Utilities/TMPL.hpp" 13 : 14 : /// \cond 15 : class TimeDelta; 16 : class TimeStepId; 17 : namespace PUP { 18 : class er; 19 : } // namespace PUP 20 : namespace TimeSteppers { 21 : template <typename T> 22 : class ConstUntypedHistory; 23 : template <typename T> 24 : class MutableUntypedHistory; 25 : } // namespace TimeSteppers 26 : namespace gsl { 27 : template <class T> 28 : class not_null; 29 : } // namespace gsl 30 : /// \endcond 31 : 32 : namespace TimeSteppers { 33 : /*! 34 : * \ingroup TimeSteppersGroup 35 : * 36 : * An \f$N\$th order Adams-Moulton predictor-corrector method using an 37 : * \$(N - 1)\$th order Adams-Bashforth predictor. 38 : * 39 : * If \p Monotonic is true, dense output is performed using the 40 : * predictor stage, otherwise the corrector is used. The corrector 41 : * results are more accurate (but still formally the same order), but 42 : * require a RHS evaluation at the end of the step before dense output 43 : * can be performed. 44 : * 45 : * The stable step size factors for different orders are (to 46 : * approximately 4-5 digits): 47 : * 48 : * <table class="doxtable"> 49 : * <tr> 50 : * <th> %Order </th> 51 : * <th> CFL Factor </th> 52 : * </tr> 53 : * <tr> 54 : * <td> 2 </td> 55 : * <td> 1 </td> 56 : * </tr> 57 : * <tr> 58 : * <td> 3 </td> 59 : * <td> 0.981297 </td> 60 : * </tr> 61 : * <tr> 62 : * <td> 4 </td> 63 : * <td> 0.794227 </td> 64 : * </tr> 65 : * <tr> 66 : * <td> 5 </td> 67 : * <td> 0.612340 </td> 68 : * </tr> 69 : * <tr> 70 : * <td> 6 </td> 71 : * <td> 0.464542 </td> 72 : * </tr> 73 : * <tr> 74 : * <td> 7 </td> 75 : * <td> 0.350596 </td> 76 : * </tr> 77 : * <tr> 78 : * <td> 8 </td> 79 : * <td> 0.264373 </td> 80 : * </tr> 81 : * </table> 82 : */ 83 : template <bool Monotonic> 84 1 : class AdamsMoultonPc : public TimeStepper { 85 : public: 86 0 : static std::string name() { 87 : return Monotonic ? "AdamsMoultonPcMonotonic" : "AdamsMoultonPc"; 88 : } 89 : 90 0 : static constexpr size_t minimum_order = 2; 91 0 : static constexpr size_t maximum_order = 8; 92 : 93 0 : struct Order { 94 0 : using type = size_t; 95 0 : static constexpr Options::String help = {"Convergence order"}; 96 0 : static type lower_bound() { return minimum_order; } 97 0 : static type upper_bound() { return maximum_order; } 98 : }; 99 0 : using options = tmpl::list<Order>; 100 0 : static constexpr Options::String help = 101 : Monotonic 102 : ? "An Adams-Moulton predictor-corrector time-stepper with monotonic " 103 : "dense output." 104 : : "An Adams-Moulton predictor-corrector time-stepper."; 105 : 106 0 : AdamsMoultonPc() = default; 107 0 : explicit AdamsMoultonPc(size_t order); 108 0 : AdamsMoultonPc(const AdamsMoultonPc&) = default; 109 0 : AdamsMoultonPc& operator=(const AdamsMoultonPc&) = default; 110 0 : AdamsMoultonPc(AdamsMoultonPc&&) = default; 111 0 : AdamsMoultonPc& operator=(AdamsMoultonPc&&) = default; 112 0 : ~AdamsMoultonPc() override = default; 113 : 114 1 : size_t order() const override; 115 : 116 1 : size_t error_estimate_order() const override; 117 : 118 1 : uint64_t number_of_substeps() const override; 119 : 120 1 : uint64_t number_of_substeps_for_error() const override; 121 : 122 1 : size_t number_of_past_steps() const override; 123 : 124 1 : double stable_step() const override; 125 : 126 1 : bool monotonic() const override; 127 : 128 1 : TimeStepId next_time_id(const TimeStepId& current_id, 129 : const TimeDelta& time_step) const override; 130 : 131 1 : TimeStepId next_time_id_for_error(const TimeStepId& current_id, 132 : const TimeDelta& time_step) const override; 133 : 134 0 : WRAPPED_PUPable_decl_template(AdamsMoultonPc); // NOLINT 135 : 136 0 : explicit AdamsMoultonPc(CkMigrateMessage* /*unused*/) {} 137 : 138 0 : void pup(PUP::er& p) override; 139 : 140 : private: 141 : template <typename T> 142 0 : void update_u_impl(gsl::not_null<T*> u, 143 : const MutableUntypedHistory<T>& history, 144 : const TimeDelta& time_step) const; 145 : 146 : template <typename T> 147 0 : bool update_u_impl(gsl::not_null<T*> u, gsl::not_null<T*> u_error, 148 : const MutableUntypedHistory<T>& history, 149 : const TimeDelta& time_step) const; 150 : 151 : template <typename T> 152 0 : bool dense_update_u_impl(gsl::not_null<T*> u, 153 : const ConstUntypedHistory<T>& history, 154 : double time) const; 155 : 156 : template <typename T> 157 0 : bool can_change_step_size_impl(const TimeStepId& time_id, 158 : const ConstUntypedHistory<T>& history) const; 159 : 160 : TIME_STEPPER_DECLARE_OVERLOADS 161 : 162 0 : size_t order_{}; 163 : }; 164 : 165 : template <bool Monotonic> 166 0 : bool operator==(const AdamsMoultonPc<Monotonic>& lhs, 167 : const AdamsMoultonPc<Monotonic>& rhs); 168 : template <bool Monotonic> 169 0 : bool operator!=(const AdamsMoultonPc<Monotonic>& lhs, 170 : const AdamsMoultonPc<Monotonic>& rhs); 171 : } // namespace TimeSteppers