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