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 <limits>
8 : #include <optional>
9 : #include <stdexcept>
10 :
11 : #include "DataStructures/ComplexDataVector.hpp"
12 : #include "DataStructures/ComplexModalVector.hpp"
13 : #include "DataStructures/DataBox/Tag.hpp"
14 : #include "DataStructures/DataBox/TagName.hpp"
15 : #include "DataStructures/DataBox/TagTraits.hpp"
16 : #include "Evolution/Systems/Cce/AnalyticBoundaryDataManager.hpp"
17 : #include "Evolution/Systems/Cce/AnalyticSolutions/WorldtubeData.hpp"
18 : #include "Evolution/Systems/Cce/ExtractionRadius.hpp"
19 : #include "Evolution/Systems/Cce/Initialize/InitializeJ.hpp"
20 : #include "Evolution/Systems/Cce/InterfaceManagers/GhInterfaceManager.hpp"
21 : #include "Evolution/Systems/Cce/InterfaceManagers/GhLocalTimeStepping.hpp"
22 : #include "Evolution/Systems/Cce/InterfaceManagers/GhLockstep.hpp"
23 : #include "Evolution/Systems/Cce/WorldtubeDataManager.hpp"
24 : #include "NumericalAlgorithms/Interpolation/SpanInterpolator.hpp"
25 : #include "Options/Auto.hpp"
26 : #include "Options/String.hpp"
27 : #include "Parallel/InitializationTag.hpp"
28 : #include "Parallel/Printf/Printf.hpp"
29 : #include "Utilities/PrettyType.hpp"
30 : #include "Utilities/TMPL.hpp"
31 :
32 : namespace Cce {
33 : /// \brief %Option tags for CCE
34 1 : namespace OptionTags {
35 :
36 : /// %Option group
37 1 : struct Cce {
38 0 : static constexpr Options::String help = {
39 : "Options for the Cce evolution system"};
40 : };
41 :
42 : /// %Option group
43 1 : struct Filtering {
44 0 : static constexpr Options::String help = {"Options for the filtering in Cce"};
45 0 : using group = Cce;
46 : };
47 :
48 : /// %Option group for evolution-related quantities in the CCE system
49 1 : struct Evolution {
50 0 : static constexpr Options::String help = {"Options for the CCE evolution"};
51 0 : using group = Cce;
52 : };
53 :
54 : /// A prefix for common tags (e.g. from Time/Tags.hpp) that are specific to CCE,
55 : /// so should be in the Cce::Evolution group.
56 : template <typename OptionTag>
57 1 : struct CceEvolutionPrefix {
58 0 : using type = typename OptionTag::type;
59 0 : static std::string name() { return pretty_type::name<OptionTag>(); }
60 0 : static constexpr Options::String help = OptionTag::help;
61 0 : using group = Evolution;
62 : };
63 :
64 0 : struct BondiSachsOutputFilePrefix {
65 0 : using type = std::string;
66 0 : static constexpr Options::String help{
67 : "Filename prefix for dumping Bondi-Sachs data on worltube radii. Files "
68 : "will have this prefix prepended to 'CceRXXXX.h5' where XXXX will be the "
69 : "zero-padded extraction radius to the nearest integer."};
70 0 : using group = Cce;
71 : };
72 :
73 0 : struct FilterLMax {
74 0 : using type = size_t;
75 0 : static constexpr Options::String help{"l mode cutoff for angular filtering"};
76 0 : using group = Filtering;
77 : };
78 :
79 0 : struct RadialFilterAlpha {
80 0 : using type = double;
81 0 : static constexpr Options::String help{
82 : "alpha parameter in exponential radial filter"};
83 0 : using group = Filtering;
84 : };
85 :
86 0 : struct RadialFilterHalfPower {
87 0 : using type = size_t;
88 0 : static constexpr Options::String help{
89 : "Half-power of the exponential radial filter argument"};
90 0 : using group = Filtering;
91 : };
92 :
93 0 : struct ObservationLMax {
94 0 : using type = size_t;
95 0 : static constexpr Options::String help{"Maximum l value for swsh output"};
96 0 : using group = Cce;
97 : };
98 :
99 0 : struct ExtractionRadius {
100 0 : using type = double;
101 0 : static constexpr Options::String help{"Extraction radius of the CCE system."};
102 0 : using group = Cce;
103 : };
104 :
105 0 : struct StandaloneExtractionRadius {
106 0 : static std::string name() { return "ExtractionRadius"; }
107 0 : using type = Options::Auto<double>;
108 :
109 0 : static constexpr Options::String help{
110 : "Extraction radius of the CCE system for a standalone run. This may be "
111 : "set to \"Auto\" to infer the radius from the filename (often used for "
112 : "SpEC worldtube data)."};
113 0 : using group = Cce;
114 : };
115 :
116 0 : struct EndTime {
117 0 : using type = Options::Auto<double>;
118 0 : static constexpr Options::String help{"End time for the Cce Evolution."};
119 0 : static type suggested_value() { return {}; }
120 0 : using group = Cce;
121 : };
122 :
123 0 : struct StartTime {
124 0 : using type = Options::Auto<double>;
125 0 : static constexpr Options::String help{
126 : "Cce Start time (default to earliest possible time)."};
127 0 : static type suggested_value() { return {}; }
128 0 : using group = Cce;
129 : };
130 :
131 0 : struct BoundaryDataFilename {
132 0 : using type = std::string;
133 0 : static constexpr Options::String help{
134 : "H5 file to read the wordltube data from."};
135 0 : using group = Cce;
136 : };
137 :
138 0 : struct KleinGordonBoundaryDataFilename {
139 0 : using type = std::string;
140 0 : static constexpr Options::String help{
141 : "H5 file to read the Klein-Gordon wordltube data from. It could be the "
142 : "same as/different from `BoundaryDataFilename`."};
143 0 : using group = Cce;
144 : };
145 :
146 0 : struct H5LookaheadTimes {
147 0 : using type = size_t;
148 0 : static constexpr Options::String help{
149 : "Number of times steps from the h5 to cache each read."};
150 0 : static size_t suggested_value() { return 200; }
151 0 : using group = Cce;
152 : };
153 :
154 0 : struct H5Interpolator {
155 0 : using type = std::unique_ptr<intrp::SpanInterpolator>;
156 0 : static constexpr Options::String help{
157 : "The interpolator for imported h5 worldtube data."};
158 0 : using group = Cce;
159 : };
160 :
161 0 : struct AnalyticSolution {
162 0 : using type = std::unique_ptr<Solutions::WorldtubeData>;
163 0 : static constexpr Options::String help{
164 : "Analytic worldtube data for tests of CCE."};
165 0 : using group = Cce;
166 : };
167 :
168 0 : struct GhInterfaceManager {
169 0 : using type = InterfaceManagers::GhLocalTimeStepping;
170 0 : static constexpr Options::String help{
171 : "Class to manage worldtube data from a GH system."};
172 0 : using group = Cce;
173 : };
174 :
175 0 : struct ScriInterpolationOrder {
176 0 : static std::string name() { return "ScriInterpOrder"; }
177 0 : using type = size_t;
178 0 : static constexpr Options::String help{
179 : "Order of time interpolation at scri+."};
180 0 : static size_t suggested_value() { return 5; }
181 0 : using group = Cce;
182 : };
183 :
184 0 : struct ScriOutputDensity {
185 0 : using type = size_t;
186 0 : static constexpr Options::String help{
187 : "Number of scri output points per timestep."};
188 0 : static size_t suggested_value() { return 1; }
189 0 : using group = Cce;
190 : };
191 :
192 : template <bool evolve_ccm>
193 0 : struct InitializeJ {
194 0 : using type = std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>;
195 0 : static constexpr Options::String help{
196 : "The initialization for the first hypersurface for J"};
197 0 : using group = Cce;
198 : };
199 : } // namespace OptionTags
200 :
201 : /// \brief Initialization tags for CCE
202 1 : namespace InitializationTags {
203 0 : struct ScriInterpolationOrder : db::SimpleTag {
204 0 : using type = size_t;
205 0 : using option_tags = tmpl::list<OptionTags::ScriInterpolationOrder>;
206 :
207 0 : static constexpr bool pass_metavariables = false;
208 0 : static size_t create_from_options(
209 : const size_t scri_plus_interpolation_order) {
210 : return scri_plus_interpolation_order;
211 : }
212 : };
213 :
214 0 : struct ScriOutputDensity : db::SimpleTag {
215 0 : using type = size_t;
216 0 : using option_tags = tmpl::list<OptionTags::ScriOutputDensity>;
217 :
218 0 : static constexpr bool pass_metavariables = false;
219 0 : static size_t create_from_options(const size_t scri_output_density) {
220 : return scri_output_density;
221 : }
222 : };
223 : } // namespace InitializationTags
224 :
225 : namespace Tags {
226 0 : struct ExtractionRadius : db::SimpleTag {
227 0 : using type = double;
228 : };
229 :
230 0 : struct ExtractionRadiusSimple : ExtractionRadius {
231 0 : using base = ExtractionRadius;
232 0 : using option_tags = tmpl::list<OptionTags::ExtractionRadius>;
233 :
234 0 : static constexpr bool pass_metavariables = false;
235 0 : static double create_from_options(const double extraction_radius) {
236 : return extraction_radius;
237 : }
238 : };
239 :
240 0 : struct ExtractionRadiusFromH5 : ExtractionRadius {
241 0 : using base = ExtractionRadius;
242 0 : using option_tags = tmpl::list<OptionTags::BoundaryDataFilename,
243 : OptionTags::StandaloneExtractionRadius>;
244 :
245 0 : static constexpr bool pass_metavariables = false;
246 0 : static double create_from_options(
247 : const std::string& filename,
248 : const std::optional<double>& extraction_radius) {
249 : const std::optional<double> radius =
250 : Cce::get_extraction_radius(filename, extraction_radius);
251 : return radius.value();
252 : }
253 : };
254 :
255 0 : struct FilePrefix : db::SimpleTag {
256 0 : using type = std::string;
257 0 : using option_tags = tmpl::list<OptionTags::BondiSachsOutputFilePrefix>;
258 0 : static constexpr bool pass_metavariables = false;
259 0 : static type create_from_options(const type& option) { return option; }
260 : };
261 :
262 : /// Tag for duplicating functionality of another tag, but allows creation from
263 : /// options in the Cce::Evolution option group.
264 : /// @{
265 : template <typename Tag>
266 1 : struct CceEvolutionPrefix;
267 :
268 : namespace CceEvolutionPrefix_detail {
269 : template <typename Tag>
270 : struct CopyBase : db::SimpleTag {};
271 :
272 : template <typename Tag>
273 : requires requires { typename Tag::base; }
274 : struct CopyBase<Tag> : CceEvolutionPrefix<typename Tag::base> {
275 : using base = CceEvolutionPrefix<typename Tag::base>;
276 : };
277 : } // namespace CceEvolutionPrefix_detail
278 :
279 : template <db::simple_tag Tag>
280 0 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix_detail::CopyBase<Tag> {
281 0 : using type = typename Tag::type;
282 0 : static std::string name() { return db::tag_name<Tag>(); }
283 : };
284 :
285 : template <Parallel::untemplated_initialization_tag Tag>
286 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix_detail::CopyBase<Tag> {
287 0 : using type = typename Tag::type;
288 0 : using option_tags = db::wrap_tags_in<OptionTags::CceEvolutionPrefix,
289 : typename Tag::option_tags>;
290 0 : static std::string name() { return db::tag_name<Tag>(); }
291 :
292 0 : static constexpr bool pass_metavariables = Tag::pass_metavariables;
293 : template <typename... Args>
294 0 : static type create_from_options(const Args&... args) {
295 : return Tag::create_from_options(args...);
296 : }
297 : };
298 :
299 : template <Parallel::templated_initialization_tag Tag>
300 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix_detail::CopyBase<Tag> {
301 0 : using type = typename Tag::type;
302 : template <typename Metavariables>
303 0 : using option_tags =
304 : db::wrap_tags_in<OptionTags::CceEvolutionPrefix,
305 : typename Tag::template option_tags<Metavariables>>;
306 0 : static std::string name() { return db::tag_name<Tag>(); }
307 :
308 : static constexpr bool pass_metavariables = Tag::pass_metavariables;
309 : template <typename Metavariables, typename... Args>
310 0 : static type create_from_options(const Args&... args) {
311 : return Tag::template create_from_options<Metavariables>(args...);
312 : }
313 : };
314 :
315 : template <db::reference_tag Tag>
316 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix<typename Tag::base>,
317 : db::ReferenceTag {
318 0 : using base = CceEvolutionPrefix<typename Tag::base>;
319 0 : using argument_tags =
320 : tmpl::transform<typename Tag::argument_tags,
321 : tmpl::bind<CceEvolutionPrefix, tmpl::_1>>;
322 : template <typename... Args>
323 0 : static const auto& get(const Args&... args) {
324 : return Tag::get(args...);
325 : }
326 : };
327 : /// @}
328 :
329 : /// A tag that constructs a `MetricWorldtubeDataManager` or
330 : /// `BondiWorldtubeDataManager` from options
331 1 : struct H5WorldtubeBoundaryDataManager : db::SimpleTag {
332 0 : using type = std::unique_ptr<WorldtubeDataManager<
333 : Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>>>;
334 0 : using option_tags =
335 : tmpl::list<Spectral::Swsh::OptionTags::LMax,
336 : OptionTags::BoundaryDataFilename, OptionTags::H5LookaheadTimes,
337 : OptionTags::H5Interpolator,
338 : OptionTags::StandaloneExtractionRadius>;
339 :
340 0 : static constexpr bool pass_metavariables = false;
341 0 : static type create_from_options(
342 : const size_t l_max, const std::string& filename,
343 : const size_t number_of_lookahead_times,
344 : const std::unique_ptr<intrp::SpanInterpolator>& interpolator,
345 : const std::optional<double> extraction_radius) {
346 : const std::string text_radius_str = Cce::get_text_radius(filename);
347 : try {
348 : // If this doesn't throw an exception, then an extraction radius was
349 : // supplied in the filename. We don't actually need the value.
350 : const double text_radius = std::stod(text_radius_str);
351 : (void)text_radius;
352 : if (extraction_radius.has_value()) {
353 : Parallel::printf(
354 : "Warning: Option ExtractionRadius is set to a specific value and "
355 : "there is an extraction radius in the H5 filename. The value in "
356 : "the file name will be ignored.It is recommended to set "
357 : "`ExtractionRadius` to `\"Auto\"` if the H5 filename has the "
358 : "extraction radius in it to make the input file clearer.\n");
359 : }
360 : } catch (const std::invalid_argument&) {
361 : }
362 :
363 : return std::make_unique<BondiWorldtubeDataManager>(
364 : std::make_unique<BondiWorldtubeH5BufferUpdater<ComplexModalVector>>(
365 : filename, extraction_radius),
366 : l_max, number_of_lookahead_times, interpolator->get_clone());
367 : }
368 : };
369 :
370 : /// A tag that constructs a `KleinGordonWorldtubeDataManager` from options
371 1 : struct KleinGordonH5WorldtubeBoundaryDataManager : db::SimpleTag {
372 0 : using type = std::unique_ptr<
373 : WorldtubeDataManager<Tags::klein_gordon_worldtube_boundary_tags>>;
374 0 : using option_tags =
375 : tmpl::list<Spectral::Swsh::OptionTags::LMax,
376 : OptionTags::KleinGordonBoundaryDataFilename,
377 : OptionTags::H5LookaheadTimes, OptionTags::H5Interpolator,
378 : OptionTags::StandaloneExtractionRadius>;
379 :
380 0 : static constexpr bool pass_metavariables = false;
381 0 : static type create_from_options(
382 : const size_t l_max, const std::string& filename,
383 : const size_t number_of_lookahead_times,
384 : const std::unique_ptr<intrp::SpanInterpolator>& interpolator,
385 : const std::optional<double> extraction_radius) {
386 : return std::make_unique<KleinGordonWorldtubeDataManager>(
387 : std::make_unique<KleinGordonWorldtubeH5BufferUpdater>(
388 : filename, extraction_radius),
389 : l_max, number_of_lookahead_times, interpolator->get_clone());
390 : }
391 : };
392 :
393 0 : struct ObservationLMax : db::SimpleTag {
394 0 : using type = size_t;
395 0 : using option_tags = tmpl::list<OptionTags::ObservationLMax>;
396 :
397 0 : static constexpr bool pass_metavariables = false;
398 0 : static size_t create_from_options(const size_t observation_l_max) {
399 : return observation_l_max;
400 : }
401 : };
402 :
403 0 : struct FilterLMax : db::SimpleTag {
404 0 : using type = size_t;
405 0 : using option_tags = tmpl::list<OptionTags::FilterLMax>;
406 :
407 0 : static constexpr bool pass_metavariables = false;
408 0 : static size_t create_from_options(const size_t filter_l_max) {
409 : return filter_l_max;
410 : }
411 : };
412 :
413 0 : struct RadialFilterAlpha : db::SimpleTag {
414 0 : using type = double;
415 0 : using option_tags = tmpl::list<OptionTags::RadialFilterAlpha>;
416 :
417 0 : static constexpr bool pass_metavariables = false;
418 0 : static double create_from_options(const double radial_filter_alpha) {
419 : return radial_filter_alpha;
420 : }
421 : };
422 :
423 0 : struct RadialFilterHalfPower : db::SimpleTag {
424 0 : using type = size_t;
425 0 : using option_tags = tmpl::list<OptionTags::RadialFilterHalfPower>;
426 :
427 0 : static constexpr bool pass_metavariables = false;
428 0 : static size_t create_from_options(const size_t radial_filter_half_power) {
429 : return radial_filter_half_power;
430 : }
431 : };
432 :
433 : /// \brief Represents the start time of a bounded CCE evolution, determined
434 : /// either from option specification or from the file
435 : ///
436 : /// \details If no start time is specified in the input file (so the option
437 : /// `OptionTags::StartTime` is set to "Auto"), this will find the start time
438 : /// from the provided H5 file. If `OptionTags::StartTime` takes any other value,
439 : /// it will be used directly as the start time for the CCE evolution instead.
440 1 : struct StartTimeFromFile : Tags::StartTime {
441 0 : using base = Tags::StartTime;
442 0 : using option_tags =
443 : tmpl::list<OptionTags::StartTime, OptionTags::BoundaryDataFilename,
444 : OptionTags::StandaloneExtractionRadius>;
445 :
446 0 : static constexpr bool pass_metavariables = false;
447 0 : static double create_from_options(
448 : const std::optional<double> start_time, const std::string& filename,
449 : const std::optional<double>& extraction_radius) {
450 : if (start_time.has_value()) {
451 : return *start_time;
452 : }
453 :
454 : BondiWorldtubeH5BufferUpdater<ComplexModalVector> h5_boundary_updater{
455 : filename, extraction_radius};
456 : const auto& time_buffer = h5_boundary_updater.get_time_buffer();
457 : return time_buffer[0];
458 : }
459 : };
460 :
461 : /// \brief Represents the start time of a bounded CCE evolution that must be
462 : /// supplied in the input file (for e.g. analytic tests).
463 1 : struct SpecifiedStartTime : Tags::StartTime {
464 0 : using base = Tags::StartTime;
465 0 : using option_tags = tmpl::list<OptionTags::StartTime>;
466 :
467 0 : static constexpr bool pass_metavariables = false;
468 0 : static double create_from_options(const std::optional<double> start_time) {
469 : if (not start_time.has_value()) {
470 : ERROR(
471 : "The start time must be explicitly specified for the tag "
472 : "`SpecifiedStartTime`");
473 : }
474 : return *start_time;
475 : }
476 : };
477 :
478 : /// \brief Represents the final time of a bounded CCE evolution, determined
479 : /// either from option specification or from the file
480 : ///
481 : /// \details If no end time is specified in the input file (so the option
482 : /// `OptionTags::EndTime` is set to "Auto"), this will find the end time
483 : /// from the provided H5 file. If `OptionTags::EndTime` takes any other value,
484 : /// it will be used directly as the final time for the CCE evolution instead.
485 1 : struct EndTimeFromFile : Tags::EndTime {
486 0 : using base = Tags::EndTime;
487 0 : using option_tags =
488 : tmpl::list<OptionTags::EndTime, OptionTags::BoundaryDataFilename,
489 : OptionTags::StandaloneExtractionRadius>;
490 :
491 0 : static constexpr bool pass_metavariables = false;
492 0 : static double create_from_options(
493 : const std::optional<double> end_time, const std::string& filename,
494 : const std::optional<double>& extraction_radius) {
495 : if (end_time) {
496 : return *end_time;
497 : }
498 : BondiWorldtubeH5BufferUpdater<ComplexModalVector> h5_boundary_updater{
499 : filename, extraction_radius};
500 : const auto& time_buffer = h5_boundary_updater.get_time_buffer();
501 : return time_buffer[time_buffer.size() - 1];
502 : }
503 : };
504 :
505 : /// \brief Represents the final time of a CCE evolution that should just proceed
506 : /// until it receives no more boundary data and becomes quiescent.
507 1 : struct NoEndTime : Tags::EndTime {
508 0 : using base = Tags::EndTime;
509 0 : using option_tags = tmpl::list<>;
510 :
511 0 : static constexpr bool pass_metavariables = false;
512 0 : static double create_from_options() {
513 : return std::numeric_limits<double>::infinity();
514 : }
515 : };
516 :
517 : /// \brief Represents the final time of a bounded CCE evolution that must be
518 : /// supplied in the input file (for e.g. analytic tests).
519 1 : struct SpecifiedEndTime : Tags::EndTime {
520 0 : using base = Tags::EndTime;
521 0 : using option_tags = tmpl::list<OptionTags::EndTime>;
522 :
523 0 : static constexpr bool pass_metavariables = false;
524 0 : static double create_from_options(const std::optional<double> end_time) {
525 : if (not end_time.has_value()) {
526 : ERROR(
527 : "The end time must be explicitly specified for the tag "
528 : "`SpecifiedEndTime`");
529 : }
530 : return *end_time;
531 : }
532 : };
533 :
534 0 : struct GhInterfaceManager : db::SimpleTag {
535 0 : using type = InterfaceManagers::GhLocalTimeStepping;
536 0 : using option_tags = tmpl::list<OptionTags::GhInterfaceManager>;
537 :
538 0 : static constexpr bool pass_metavariables = false;
539 0 : static InterfaceManagers::GhLocalTimeStepping create_from_options(
540 : const InterfaceManagers::GhLocalTimeStepping& interface_manager) {
541 : return interface_manager;
542 : }
543 : };
544 :
545 : /// Tag for first-hypersurface initialization procedure specified by input
546 : /// options.
547 : template <bool evolve_ccm>
548 1 : struct InitializeJ : db::SimpleTag {
549 0 : using type = std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>;
550 0 : using option_tags = tmpl::list<OptionTags::InitializeJ<evolve_ccm>>;
551 :
552 0 : static constexpr bool pass_metavariables = false;
553 : static std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>
554 0 : create_from_options(
555 : const std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>&
556 : initialize_j) {
557 : return initialize_j->get_clone();
558 : }
559 : };
560 :
561 : // Tags that generates an `Cce::InitializeJ::InitializeJ` derived class from an
562 : // analytic solution.
563 0 : struct AnalyticInitializeJ : InitializeJ<false> {
564 0 : using base = InitializeJ<false>;
565 0 : using option_tags =
566 : tmpl::list<OptionTags::AnalyticSolution, OptionTags::StartTime>;
567 0 : static constexpr bool pass_metavariables = false;
568 : static std::unique_ptr<::Cce::InitializeJ::InitializeJ<false>>
569 0 : create_from_options(
570 : const std::unique_ptr<Cce::Solutions::WorldtubeData>& worldtube_data,
571 : const std::optional<double> start_time) {
572 : return worldtube_data->get_initialize_j(*start_time);
573 : }
574 : };
575 :
576 : /// A tag that constructs a `AnalyticBoundaryDataManager` from options
577 1 : struct AnalyticBoundaryDataManager : db::SimpleTag {
578 0 : using type = ::Cce::AnalyticBoundaryDataManager;
579 0 : using option_tags =
580 : tmpl::list<OptionTags::ExtractionRadius, Spectral::Swsh::OptionTags::LMax,
581 : OptionTags::AnalyticSolution>;
582 :
583 0 : static constexpr bool pass_metavariables = false;
584 0 : static Cce::AnalyticBoundaryDataManager create_from_options(
585 : const double extraction_radius, const size_t l_max,
586 : const std::unique_ptr<Cce::Solutions::WorldtubeData>& worldtube_data) {
587 : return ::Cce::AnalyticBoundaryDataManager(l_max, extraction_radius,
588 : worldtube_data->get_clone());
589 : }
590 : };
591 :
592 : /// Represents whether the news should be provided at noninertial times.
593 : ///
594 : /// \details Currently, this is only useful for analytic solutions for which the
595 : /// inertial-time news is difficult to compute.
596 1 : struct OutputNoninertialNews : db::SimpleTag {
597 0 : using type = bool;
598 0 : using option_tags = tmpl::list<OptionTags::AnalyticSolution>;
599 0 : static constexpr bool pass_metavariables = false;
600 0 : static bool create_from_options(
601 : const std::unique_ptr<Cce::Solutions::WorldtubeData>& worldtube_data) {
602 : return worldtube_data->use_noninertial_news();
603 : }
604 : };
605 : } // namespace Tags
606 : } // namespace Cce
|