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