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 $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 : bool dense_output_uses_fsal() const override;
141 :
142 1 : TimeStepId next_time_id(const TimeStepId& current_id,
143 : const TimeDelta& time_step) const override;
144 :
145 1 : TimeStepId next_time_id_for_error(const TimeStepId& current_id,
146 : const TimeDelta& time_step) const override;
147 :
148 1 : bool neighbor_data_required(
149 : const TimeStepId& next_substep_id,
150 : const TimeStepId& neighbor_data_id) const override;
151 :
152 1 : bool neighbor_data_required(
153 : double dense_output_time,
154 : const TimeStepId& neighbor_data_id) const override;
155 :
156 0 : WRAPPED_PUPable_decl_template(AdamsMoultonPc); // NOLINT
157 :
158 0 : explicit AdamsMoultonPc(CkMigrateMessage* /*unused*/) {}
159 :
160 0 : void pup(PUP::er& p) override;
161 :
162 : private:
163 : template <bool DenseOutput, typename T>
164 0 : std::optional<StepperErrorEstimate> update_u_common(
165 : gsl::not_null<T*> u, const ConstUntypedHistory<T>& history,
166 : const tmpl::conditional_t<DenseOutput, ApproximateTime, Time>& time,
167 : bool corrector, const StepperErrorTolerances& tolerances) 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 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 : std::optional<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
|