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