Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstdint>
7 : #include <pup.h>
8 : #include <type_traits>
9 :
10 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
11 : #include "DataStructures/MathWrapper.hpp"
12 : #include "Time/BoundaryHistory.hpp"
13 : #include "Time/TimeSteppers/TimeStepper.hpp"
14 : #include "Utilities/GenerateInstantiations.hpp"
15 : #include "Utilities/Gsl.hpp"
16 : #include "Utilities/Serialization/CharmPupable.hpp"
17 :
18 : /// \cond
19 : class TimeDelta;
20 : class TimeStepId;
21 : /// \endcond
22 :
23 : /// \cond
24 : #define LTS_TIME_STEPPER_WRAPPED_TYPE(data) BOOST_PP_TUPLE_ELEM(0, data)
25 : #define LTS_TIME_STEPPER_DERIVED_CLASS(data) BOOST_PP_TUPLE_ELEM(1, data)
26 : /// \endcond
27 :
28 : /// \ingroup TimeSteppersGroup
29 : ///
30 : /// Base class for TimeSteppers with local time-stepping support,
31 : /// derived from TimeStepper.
32 : ///
33 : /// Several of the member functions of this class are templated and
34 : /// perform type erasure before forwarding their arguments to the
35 : /// derived classes. This is implemented using the macros \ref
36 : /// LTS_TIME_STEPPER_DECLARE_OVERLOADS, which must be placed in a
37 : /// private section of the class body, and
38 : /// LTS_TIME_STEPPER_DEFINE_OVERLOADS(derived_class), which must be
39 : /// placed in the cpp file.
40 1 : class LtsTimeStepper : public TimeStepper {
41 : public:
42 0 : WRAPPED_PUPable_abstract(LtsTimeStepper); // NOLINT
43 :
44 : // These two are defined as separate type aliases to keep the
45 : // doxygen page width somewhat under control.
46 : template <typename LocalVars, typename RemoteVars, typename Coupling>
47 0 : using BoundaryHistoryType = TimeSteppers::BoundaryHistory<
48 : LocalVars, RemoteVars,
49 : std::result_of_t<const Coupling&(LocalVars, RemoteVars)>>;
50 :
51 : /// Return type of boundary-related functions. The coupling returns
52 : /// the derivative of the variables, but this is multiplied by the
53 : /// time step so the return type should not have `dt` prefixes.
54 : template <typename LocalVars, typename RemoteVars, typename Coupling>
55 1 : using BoundaryReturn = db::unprefix_variables<
56 : std::result_of_t<const Coupling&(LocalVars, RemoteVars)>>;
57 :
58 : /// \cond
59 : #define LTS_TIME_STEPPER_DECLARE_VIRTUALS_IMPL(_, data) \
60 : virtual void add_boundary_delta_forward( \
61 : gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result, \
62 : const TimeSteppers::BoundaryHistoryEvaluator< \
63 : LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling, \
64 : const TimeSteppers::BoundaryHistoryCleaner& cleaner, \
65 : const TimeDelta& time_step) const = 0; \
66 : virtual void boundary_dense_output_forward( \
67 : gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result, \
68 : const TimeSteppers::BoundaryHistoryEvaluator< \
69 : LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling, \
70 : const double time) const = 0;
71 :
72 : GENERATE_INSTANTIATIONS(LTS_TIME_STEPPER_DECLARE_VIRTUALS_IMPL,
73 : (MATH_WRAPPER_TYPES))
74 : #undef LTS_TIME_STEPPER_DECLARE_VIRTUALS_IMPL
75 : /// \endcond
76 :
77 : /// \brief Compute the change in a boundary quantity due to the
78 : /// coupling on the interface.
79 : ///
80 : /// The coupling function `coupling` should take the local and
81 : /// remote flux data and compute the derivative of the boundary
82 : /// quantity. These values may be used to form a linear combination
83 : /// internally, so the result should have appropriate mathematical
84 : /// operators defined to allow that.
85 : ///
86 : /// Derived classes must implement this as a function with signature
87 : ///
88 : /// ```
89 : /// template <typename T>
90 : /// void add_boundary_delta_impl(
91 : /// gsl::not_null<T*> result,
92 : /// const TimeSteppers::BoundaryHistoryEvaluator<T>& coupling,
93 : /// const TimeSteppers::BoundaryHistoryCleaner& cleaner,
94 : /// const TimeDelta& time_step) const;
95 : /// ```
96 : ///
97 : /// \note
98 : /// Unlike the `update_u` methods, which overwrite the `result`
99 : /// argument, this function adds the result to the existing value.
100 : template <typename LocalVars, typename RemoteVars, typename Coupling>
101 1 : void add_boundary_delta(
102 : const gsl::not_null<BoundaryReturn<LocalVars, RemoteVars, Coupling>*>
103 : result,
104 : const gsl::not_null<BoundaryHistoryType<LocalVars, RemoteVars, Coupling>*>
105 : history,
106 : const TimeDelta& time_step, const Coupling& coupling) const {
107 : return add_boundary_delta_forward(&*make_math_wrapper(result),
108 : history->evaluator(coupling),
109 : history->cleaner(), time_step);
110 : }
111 :
112 : /// Derived classes must implement this as a function with signature
113 : ///
114 : /// ```
115 : /// template <typename T>
116 : /// void boundary_dense_output_impl(
117 : /// gsl::not_null<T*> result,
118 : /// const TimeSteppers::BoundaryHistoryEvaluator<T>& coupling,
119 : /// const double time) const;
120 : /// ```
121 : template <typename LocalVars, typename RemoteVars, typename Coupling>
122 1 : void boundary_dense_output(
123 : const gsl::not_null<BoundaryReturn<LocalVars, RemoteVars, Coupling>*>
124 : result,
125 : const BoundaryHistoryType<LocalVars, RemoteVars, Coupling>& history,
126 : const double time, const Coupling& coupling) const {
127 : return boundary_dense_output_forward(&*make_math_wrapper(result),
128 : history.evaluator(coupling), time);
129 : }
130 :
131 : /// Substep LTS integrators are not supported, so this is always 1.
132 1 : uint64_t number_of_substeps() const final { return 1; }
133 :
134 : /// Substep LTS integrators are not supported, so this is always 1.
135 1 : uint64_t number_of_substeps_for_error() const final { return 1; }
136 :
137 1 : TimeStepId next_time_id_for_error(const TimeStepId& current_id,
138 : const TimeDelta& time_step) const final {
139 : return next_time_id(current_id, time_step);
140 : }
141 : };
142 :
143 : /// \cond
144 : #define LTS_TIME_STEPPER_DECLARE_OVERLOADS_IMPL(_, data) \
145 : void add_boundary_delta_forward( \
146 : gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result, \
147 : const TimeSteppers::BoundaryHistoryEvaluator< \
148 : LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling, \
149 : const TimeSteppers::BoundaryHistoryCleaner& cleaner, \
150 : const TimeDelta& time_step) const override; \
151 : void boundary_dense_output_forward( \
152 : gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result, \
153 : const TimeSteppers::BoundaryHistoryEvaluator< \
154 : LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling, \
155 : const double time) const override;
156 :
157 : #define LTS_TIME_STEPPER_DEFINE_OVERLOADS_IMPL(_, data) \
158 : void LTS_TIME_STEPPER_DERIVED_CLASS(data)::add_boundary_delta_forward( \
159 : const gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result, \
160 : const TimeSteppers::BoundaryHistoryEvaluator< \
161 : LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling, \
162 : const TimeSteppers::BoundaryHistoryCleaner& cleaner, \
163 : const TimeDelta& time_step) const { \
164 : return add_boundary_delta_impl(result, coupling, cleaner, time_step); \
165 : } \
166 : void LTS_TIME_STEPPER_DERIVED_CLASS(data)::boundary_dense_output_forward( \
167 : const gsl::not_null<LTS_TIME_STEPPER_WRAPPED_TYPE(data)*> result, \
168 : const TimeSteppers::BoundaryHistoryEvaluator< \
169 : LTS_TIME_STEPPER_WRAPPED_TYPE(data)>& coupling, \
170 : const double time) const { \
171 : return boundary_dense_output_impl(result, coupling, time); \
172 : }
173 : /// \endcond
174 :
175 : /// \ingroup TimeSteppersGroup
176 : /// Macro declaring overloaded detail methods in classes derived from
177 : /// TimeStepper. Must be placed in a private section of the class
178 : /// body.
179 1 : #define LTS_TIME_STEPPER_DECLARE_OVERLOADS \
180 : GENERATE_INSTANTIATIONS(LTS_TIME_STEPPER_DECLARE_OVERLOADS_IMPL, \
181 : (MATH_WRAPPER_TYPES))
182 :
183 : /// \ingroup TimeSteppersGroup
184 : /// Macro defining overloaded detail methods in classes derived from
185 : /// TimeStepper. Must be placed in the cpp file for the derived
186 : /// class.
187 1 : #define LTS_TIME_STEPPER_DEFINE_OVERLOADS(derived_class) \
188 : GENERATE_INSTANTIATIONS(LTS_TIME_STEPPER_DEFINE_OVERLOADS_IMPL, \
189 : (MATH_WRAPPER_TYPES), (derived_class))
|