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 <optional>
8 : #include <tuple>
9 : #include <type_traits>
10 : #include <utility>
11 :
12 : #include "DataStructures/DataBox/DataBox.hpp"
13 : #include "DataStructures/TaggedTuple.hpp"
14 : #include "DataStructures/VariablesTag.hpp"
15 : #include "Evolution/Systems/Cce/AnalyticBoundaryDataManager.hpp"
16 : #include "Evolution/Systems/Cce/AnalyticSolutions/RobinsonTrautman.hpp"
17 : #include "Evolution/Systems/Cce/BoundaryData.hpp"
18 : #include "Evolution/Systems/Cce/InterfaceManagers/GhInterfaceManager.hpp"
19 : #include "Evolution/Systems/Cce/InterfaceManagers/GhLocalTimeStepping.hpp"
20 : #include "Evolution/Systems/Cce/InterfaceManagers/GhLockstep.hpp"
21 : #include "Evolution/Systems/Cce/OptionTags.hpp"
22 : #include "Evolution/Systems/Cce/Tags.hpp"
23 : #include "NumericalAlgorithms/Interpolation/SpanInterpolator.hpp"
24 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshCollocation.hpp"
25 : #include "Parallel/AlgorithmExecution.hpp"
26 : #include "Parallel/Invoke.hpp"
27 : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
28 : #include "Time/Tags/TimeStepper.hpp"
29 : #include "Time/TimeSteppers/LtsTimeStepper.hpp"
30 : #include "Time/TimeSteppers/TimeStepper.hpp"
31 : #include "Utilities/Gsl.hpp"
32 : #include "Utilities/MakeString.hpp"
33 : #include "Utilities/Requires.hpp"
34 : #include "Utilities/TMPL.hpp"
35 :
36 : namespace Cce {
37 : /// \cond
38 : template <typename Metavariables>
39 : struct H5WorldtubeBoundary;
40 : template <typename Metavariables>
41 : struct AnalyticWorldtubeBoundary;
42 : template <typename Metavariables>
43 : struct KleinGordonH5WorldtubeBoundary;
44 : template <typename Metavariables>
45 : struct GhWorldtubeBoundary;
46 : /// \endcond
47 : namespace Actions {
48 :
49 : namespace detail {
50 : template <typename Initializer, typename ManagerTags,
51 : typename... BoundaryCommunicationTagsList>
52 : struct InitializeWorldtubeBoundaryBase {
53 : using simple_tags_from_options = ManagerTags;
54 : using const_global_cache_tags = tmpl::list<Tags::LMax>;
55 :
56 : using simple_tags =
57 : tmpl::list<::Tags::Variables<BoundaryCommunicationTagsList>...>;
58 :
59 : template <typename DataBoxTagsList, typename... InboxTags,
60 : typename ArrayIndex, typename Metavariables, typename ActionList,
61 : typename ParallelComponent>
62 : static Parallel::iterable_action_return_t apply(
63 : db::DataBox<DataBoxTagsList>& box,
64 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
65 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
66 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
67 : const ParallelComponent* const /*meta*/) {
68 : if constexpr (std::is_same_v<Tags::AnalyticBoundaryDataManager,
69 : tmpl::front<ManagerTags>>) {
70 : if (dynamic_cast<const Solutions::RobinsonTrautman*>(
71 : &(db::get<Tags::AnalyticBoundaryDataManager>(box)
72 : .get_generator())) != nullptr) {
73 : if (db::get<Tags::CceEvolutionPrefix<
74 : ::Tags::ConcreteTimeStepper<LtsTimeStepper>>>(box)
75 : .number_of_substeps() != 1) {
76 : ERROR(
77 : "Do not use RobinsonTrautman analytic solution with a "
78 : "substep-based timestepper. This is to prevent severe slowdowns "
79 : "in the current RobinsonTrautman implementation. See the "
80 : "documentation for the RobinsonTrautman solution for details.");
81 : }
82 : }
83 : }
84 : // Pass the initial-data generator's interpolator to the worldtube data
85 : // manager, which computes the boundary value of Du<Dr<BondiJ>>.
86 : if constexpr (std::is_same_v<Tags::H5WorldtubeBoundaryDataManager,
87 : tmpl::front<ManagerTags>> and
88 : requires { Metavariables::evolve_ccm; }) {
89 : using generator_tag = Tags::InitializeJ<Metavariables::evolve_ccm>;
90 : if constexpr (db::tag_is_retrievable_v<generator_tag,
91 : db::DataBox<DataBoxTagsList>>) {
92 : auto du_dr_j_interpolator =
93 : db::get<generator_tag>(box).du_dr_j_interpolator();
94 : if (du_dr_j_interpolator != nullptr) {
95 : db::mutate<Tags::H5WorldtubeBoundaryDataManager>(
96 : [&du_dr_j_interpolator](const auto data_manager) {
97 : (*data_manager)
98 : ->set_du_dr_j_interpolator(std::move(du_dr_j_interpolator));
99 : },
100 : make_not_null(&box));
101 : }
102 : }
103 : } else if constexpr (std::is_same_v<Tags::AnalyticBoundaryDataManager,
104 : tmpl::front<ManagerTags>>) {
105 : // The analytic manager builds Du<Dr<BondiJ>> only when given an
106 : // interpolator, so pass it the generator's whenever the generator needs
107 : // that boundary value.
108 : if constexpr (db::tag_is_retrievable_v<Tags::InitializeJ<false>,
109 : db::DataBox<DataBoxTagsList>>) {
110 : const auto& generator = db::get<Tags::InitializeJ<false>>(box);
111 : if (generator.needs_du_dr_j()) {
112 : if (dynamic_cast<const Solutions::RobinsonTrautman*>(
113 : &(db::get<Tags::AnalyticBoundaryDataManager>(box)
114 : .get_generator())) != nullptr) {
115 : ERROR(
116 : "RobinsonTrautman does not support the centered time stencil "
117 : "for Du<Dr<BondiJ>>: past-time samples restart its internal "
118 : "evolution and can precede its initial time. Use an "
119 : "initial-data generator that does not require "
120 : "Du<Dr<BondiJ>>.");
121 : }
122 : auto du_dr_j_interpolator = generator.du_dr_j_interpolator();
123 : if (du_dr_j_interpolator == nullptr) {
124 : ERROR(
125 : "The initial-data generator needs the `Du<Dr<BondiJ>>` "
126 : "worldtube boundary value, but supplied no interpolator to "
127 : "build it with. Set the generator's `DuDrJInterpolator` "
128 : "option.");
129 : }
130 : db::mutate<Tags::AnalyticBoundaryDataManager>(
131 : [&du_dr_j_interpolator](const auto analytic_manager) {
132 : analytic_manager->set_du_dr_j_interpolator(
133 : std::move(du_dr_j_interpolator));
134 : },
135 : make_not_null(&box));
136 : }
137 : }
138 : } else {
139 : // No other manager produces `Du<Dr<BondiJ>>`.
140 : if constexpr (db::tag_is_retrievable_v<Tags::InitializeJ<false>,
141 : db::DataBox<DataBoxTagsList>>) {
142 : if (db::get<Tags::InitializeJ<false>>(box).needs_du_dr_j()) {
143 : ERROR(
144 : "The initial-data generator needs the `Du<Dr<BondiJ>>` worldtube "
145 : "boundary value, but this worldtube data manager does not "
146 : "produce it. Use a different generator, or add support for that "
147 : "boundary value to the manager.");
148 : }
149 : }
150 : }
151 :
152 : const size_t l_max = db::get<Tags::LMax>(box);
153 :
154 : Initialization::mutate_assign<simple_tags>(
155 : make_not_null(&box),
156 : Variables<BoundaryCommunicationTagsList>{
157 : Spectral::Swsh::number_of_swsh_collocation_points(l_max)}...);
158 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
159 : }
160 : };
161 : } // namespace detail
162 :
163 : /*!
164 : * \ingroup ActionsGroup
165 : * \brief Generic action for initializing various worldtube boundary components.
166 : *
167 : * \details See specializations of this class for initialization details for
168 : * individual worldtube components.
169 : */
170 : template <typename WorldtubeComponent>
171 1 : struct InitializeWorldtubeBoundary;
172 :
173 : /*!
174 : * \ingroup ActionsGroup
175 : * \brief Initializes a H5WorldtubeBoundary
176 : *
177 : * \details Uses:
178 : * - simple tags from options
179 : * `Cce::Tags::H5WorldtubeBoundaryDataManager`,
180 : * - const global cache tag `Cce::Tags::LMax`, `Tags::ExtractionRadiusFromH5`.
181 : *
182 : * Databox changes:
183 : * - Adds:
184 : * - `Cce::Tags::H5WorldtubeBoundaryDataManager`
185 : * - `Tags::Variables<typename
186 : * Metavariables::cce_boundary_communication_tags>`
187 : * - Removes: nothing
188 : * - Modifies: nothing
189 : */
190 : template <typename Metavariables>
191 1 : struct InitializeWorldtubeBoundary<H5WorldtubeBoundary<Metavariables>>
192 : : public detail::InitializeWorldtubeBoundaryBase<
193 : InitializeWorldtubeBoundary<H5WorldtubeBoundary<Metavariables>>,
194 : tmpl::list<Tags::H5WorldtubeBoundaryDataManager>,
195 : typename Metavariables::cce_boundary_communication_tags> {
196 0 : using base_type = detail::InitializeWorldtubeBoundaryBase<
197 : InitializeWorldtubeBoundary<H5WorldtubeBoundary<Metavariables>>,
198 : tmpl::list<Tags::H5WorldtubeBoundaryDataManager>,
199 : typename Metavariables::cce_boundary_communication_tags>;
200 : using base_type::apply;
201 : using typename base_type::simple_tags;
202 0 : using const_global_cache_tags =
203 : tmpl::list<Tags::LMax, Tags::ExtractionRadiusFromH5,
204 : Tags::EndTimeFromFile, Tags::StartTimeFromFile>;
205 : using typename base_type::simple_tags_from_options;
206 : };
207 :
208 : /*!
209 : * \ingroup ActionsGroup
210 : * \brief Initializes a KleinGordonH5WorldtubeBoundary
211 : *
212 : * \details Uses:
213 : * - simple tags from options
214 : * `Cce::Tags::H5WorldtubeBoundaryDataManager`,
215 : * `Cce::Tags::KleinGordonH5WorldtubeBoundaryDataManager`.
216 : * - const global cache tag `Cce::Tags::LMax`, `Tags::ExtractionRadiusFromH5`.
217 : *
218 : * Databox changes:
219 : * - Adds:
220 : * - `Cce::Tags::H5WorldtubeBoundaryDataManager`
221 : * - `Cce::Tags::KleinGordonH5WorldtubeBoundaryDataManager`
222 : * - `Tags::Variables<typename
223 : * Metavariables::cce_boundary_communication_tags>`
224 : * - `Tags::Variables<typename
225 : * Metavariables::klein_gordon_boundary_communication_tags>`
226 : * - Removes: nothing
227 : * - Modifies: nothing
228 : */
229 : template <typename Metavariables>
230 1 : struct InitializeWorldtubeBoundary<
231 : KleinGordonH5WorldtubeBoundary<Metavariables>>
232 : : public detail::InitializeWorldtubeBoundaryBase<
233 : InitializeWorldtubeBoundary<
234 : KleinGordonH5WorldtubeBoundary<Metavariables>>,
235 : tmpl::list<Tags::H5WorldtubeBoundaryDataManager,
236 : Tags::KleinGordonH5WorldtubeBoundaryDataManager>,
237 : typename Metavariables::cce_boundary_communication_tags,
238 : typename Metavariables::klein_gordon_boundary_communication_tags> {
239 0 : using base_type = detail::InitializeWorldtubeBoundaryBase<
240 : InitializeWorldtubeBoundary<
241 : KleinGordonH5WorldtubeBoundary<Metavariables>>,
242 : tmpl::list<Tags::H5WorldtubeBoundaryDataManager,
243 : Tags::KleinGordonH5WorldtubeBoundaryDataManager>,
244 : typename Metavariables::cce_boundary_communication_tags,
245 : typename Metavariables::klein_gordon_boundary_communication_tags>;
246 : using base_type::apply;
247 : using typename base_type::simple_tags;
248 0 : using const_global_cache_tags =
249 : tmpl::list<Tags::LMax, Tags::ExtractionRadiusFromH5,
250 : Tags::EndTimeFromFile, Tags::StartTimeFromFile>;
251 : using typename base_type::simple_tags_from_options;
252 : };
253 :
254 : /*!
255 : * \ingroup ActionsGroup
256 : * \brief Initializes a GhWorldtubeBoundary
257 : *
258 : * \details Uses:
259 : * - simple tags from options
260 : * `Cce::Tags::GhWorldtubeBoundaryDataManager`, `Tags::GhInterfaceManager`
261 : * - const global cache tags `Tags::LMax`, `Tags::ExtractionRadiusSimple`.
262 : *
263 : * Databox changes:
264 : * - Adds:
265 : * - `Tags::Variables<typename
266 : * Metavariables::cce_boundary_communication_tags>`
267 : * - Removes: nothing
268 : * - Modifies: nothing
269 : */
270 : template <typename Metavariables>
271 1 : struct InitializeWorldtubeBoundary<GhWorldtubeBoundary<Metavariables>>
272 : : public detail::InitializeWorldtubeBoundaryBase<
273 : InitializeWorldtubeBoundary<GhWorldtubeBoundary<Metavariables>>,
274 : tmpl::list<Tags::GhInterfaceManager,
275 : Tags::SelfStartGhInterfaceManager>,
276 : typename Metavariables::cce_boundary_communication_tags> {
277 0 : using base_type = detail::InitializeWorldtubeBoundaryBase<
278 : InitializeWorldtubeBoundary<GhWorldtubeBoundary<Metavariables>>,
279 : tmpl::list<Tags::GhInterfaceManager, Tags::SelfStartGhInterfaceManager>,
280 : typename Metavariables::cce_boundary_communication_tags>;
281 : using base_type::apply;
282 : using typename base_type::simple_tags;
283 :
284 0 : using const_global_cache_tags =
285 : tmpl::list<Tags::LMax, Tags::ExtractionRadiusSimple, Tags::NoEndTime,
286 : Tags::SpecifiedStartTime>;
287 : using typename base_type::simple_tags_from_options;
288 : };
289 :
290 : /*!
291 : * \ingroup ActionsGroup
292 : * \brief Initializes an AnalyticWorldtubeBoundary
293 : *
294 : * \details Uses:
295 : * - simple tags from options
296 : * `Cce::Tags::AnalyticBoundaryDataManager`,
297 : * - const global cache tags `Tags::LMax`,
298 : * `Tags::ExtractionRadiusSimple`.
299 : *
300 : * Databox changes:
301 : * - Adds:
302 : * - `Tags::Variables<typename
303 : * Metavariables::cce_boundary_communication_tags>`
304 : * - Removes: nothing
305 : * - Modifies: nothing
306 : */
307 : template <typename Metavariables>
308 1 : struct InitializeWorldtubeBoundary<AnalyticWorldtubeBoundary<Metavariables>>
309 : : public detail::InitializeWorldtubeBoundaryBase<
310 : InitializeWorldtubeBoundary<AnalyticWorldtubeBoundary<Metavariables>>,
311 : tmpl::list<Tags::AnalyticBoundaryDataManager>,
312 : typename Metavariables::cce_boundary_communication_tags> {
313 0 : using base_type = detail::InitializeWorldtubeBoundaryBase<
314 : InitializeWorldtubeBoundary<AnalyticWorldtubeBoundary<Metavariables>>,
315 : tmpl::list<Tags::AnalyticBoundaryDataManager>,
316 : typename Metavariables::cce_boundary_communication_tags>;
317 : using base_type::apply;
318 : using typename base_type::simple_tags;
319 0 : using compute_tags = tmpl::list<>;
320 0 : using const_global_cache_tags =
321 : tmpl::list<Tags::LMax, Tags::ExtractionRadiusSimple,
322 : Tags::SpecifiedEndTime, Tags::SpecifiedStartTime>;
323 : using typename base_type::simple_tags_from_options;
324 : };
325 : } // namespace Actions
326 : } // namespace Cce
|