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