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