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 :
200 : /// Option for choosing the first-hypersurface initialization of J in an
201 : /// analytic-solution CCE run.
202 : ///
203 : /// \details Set to `FromAnalyticSolution` to use the J initialization provided
204 : /// by the analytic solution itself (via
205 : /// `Cce::Solutions::WorldtubeData::get_initialize_j`). Otherwise, any
206 : /// option-creatable `Cce::InitializeJ::InitializeJ<false>` may be specified to
207 : /// override the solution-provided initialization, exactly as in a standard CCE
208 : /// run.
209 1 : struct AnalyticInitializeJ {
210 0 : static std::string name() { return "InitializeJ"; }
211 0 : struct FromAnalyticSolution {};
212 0 : using type =
213 : Options::Auto<std::unique_ptr<::Cce::InitializeJ::InitializeJ<false>>,
214 : FromAnalyticSolution>;
215 0 : static constexpr Options::String help{
216 : "The initialization for the first hypersurface for J. Set to "
217 : "'FromAnalyticSolution' to use the initialization provided by the "
218 : "analytic solution."};
219 0 : using group = Cce;
220 : };
221 : } // namespace OptionTags
222 :
223 : /// \brief Initialization tags for CCE
224 1 : namespace InitializationTags {
225 0 : struct ScriInterpolationOrder : db::SimpleTag {
226 0 : using type = size_t;
227 0 : using option_tags = tmpl::list<OptionTags::ScriInterpolationOrder>;
228 :
229 0 : static constexpr bool pass_metavariables = false;
230 0 : static size_t create_from_options(
231 : const size_t scri_plus_interpolation_order) {
232 : return scri_plus_interpolation_order;
233 : }
234 : };
235 :
236 0 : struct ScriOutputDensity : db::SimpleTag {
237 0 : using type = size_t;
238 0 : using option_tags = tmpl::list<OptionTags::ScriOutputDensity>;
239 :
240 0 : static constexpr bool pass_metavariables = false;
241 0 : static size_t create_from_options(const size_t scri_output_density) {
242 : return scri_output_density;
243 : }
244 : };
245 : } // namespace InitializationTags
246 :
247 : namespace Tags {
248 0 : struct ExtractionRadius : db::SimpleTag {
249 0 : using type = double;
250 : };
251 :
252 0 : struct ExtractionRadiusSimple : ExtractionRadius {
253 0 : using base = ExtractionRadius;
254 0 : using option_tags = tmpl::list<OptionTags::ExtractionRadius>;
255 :
256 0 : static constexpr bool pass_metavariables = false;
257 0 : static double create_from_options(const double extraction_radius) {
258 : return extraction_radius;
259 : }
260 : };
261 :
262 0 : struct ExtractionRadiusFromH5 : ExtractionRadius {
263 0 : using base = ExtractionRadius;
264 0 : using option_tags = tmpl::list<OptionTags::BoundaryDataFilename,
265 : OptionTags::StandaloneExtractionRadius>;
266 :
267 0 : static constexpr bool pass_metavariables = false;
268 0 : static double create_from_options(
269 : const std::string& filename,
270 : const std::optional<double>& extraction_radius) {
271 : const std::optional<double> radius =
272 : Cce::get_extraction_radius(filename, extraction_radius);
273 : return radius.value();
274 : }
275 : };
276 :
277 0 : struct FilePrefix : db::SimpleTag {
278 0 : using type = std::string;
279 0 : using option_tags = tmpl::list<OptionTags::BondiSachsOutputFilePrefix>;
280 0 : static constexpr bool pass_metavariables = false;
281 0 : static type create_from_options(const type& option) { return option; }
282 : };
283 :
284 : /// Tag for duplicating functionality of another tag, but allows creation from
285 : /// options in the Cce::Evolution option group.
286 : /// @{
287 : template <typename Tag>
288 1 : struct CceEvolutionPrefix;
289 :
290 : namespace CceEvolutionPrefix_detail {
291 : template <typename Tag>
292 : struct CopyBase : db::SimpleTag {};
293 :
294 : template <typename Tag>
295 : requires requires { typename Tag::base; }
296 : struct CopyBase<Tag> : CceEvolutionPrefix<typename Tag::base> {
297 : using base = CceEvolutionPrefix<typename Tag::base>;
298 : };
299 : } // namespace CceEvolutionPrefix_detail
300 :
301 : template <db::simple_tag Tag>
302 0 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix_detail::CopyBase<Tag> {
303 0 : using type = typename Tag::type;
304 0 : static std::string name() { return db::tag_name<Tag>(); }
305 : };
306 :
307 : template <Parallel::untemplated_initialization_tag Tag>
308 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix_detail::CopyBase<Tag> {
309 0 : using type = typename Tag::type;
310 0 : using option_tags = db::wrap_tags_in<OptionTags::CceEvolutionPrefix,
311 : typename Tag::option_tags>;
312 0 : static std::string name() { return db::tag_name<Tag>(); }
313 :
314 0 : static constexpr bool pass_metavariables = Tag::pass_metavariables;
315 : template <typename... Args>
316 0 : static type create_from_options(const Args&... args) {
317 : return Tag::create_from_options(args...);
318 : }
319 : };
320 :
321 : template <Parallel::templated_initialization_tag Tag>
322 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix_detail::CopyBase<Tag> {
323 0 : using type = typename Tag::type;
324 : template <typename Metavariables>
325 0 : using option_tags =
326 : db::wrap_tags_in<OptionTags::CceEvolutionPrefix,
327 : typename Tag::template option_tags<Metavariables>>;
328 0 : static std::string name() { return db::tag_name<Tag>(); }
329 :
330 : static constexpr bool pass_metavariables = Tag::pass_metavariables;
331 : template <typename Metavariables, typename... Args>
332 0 : static type create_from_options(const Args&... args) {
333 : return Tag::template create_from_options<Metavariables>(args...);
334 : }
335 : };
336 :
337 : template <db::reference_tag Tag>
338 : struct CceEvolutionPrefix<Tag> : CceEvolutionPrefix<typename Tag::base>,
339 : db::ReferenceTag {
340 0 : using base = CceEvolutionPrefix<typename Tag::base>;
341 0 : using argument_tags =
342 : tmpl::transform<typename Tag::argument_tags,
343 : tmpl::bind<CceEvolutionPrefix, tmpl::_1>>;
344 : template <typename... Args>
345 0 : static const auto& get(const Args&... args) {
346 : return Tag::get(args...);
347 : }
348 : };
349 : /// @}
350 :
351 : /// A tag that constructs a `MetricWorldtubeDataManager` or
352 : /// `BondiWorldtubeDataManager` from options
353 1 : struct H5WorldtubeBoundaryDataManager : db::SimpleTag {
354 0 : using type = std::unique_ptr<WorldtubeDataManager<
355 : Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>>>;
356 0 : using option_tags =
357 : tmpl::list<Spectral::Swsh::OptionTags::LMax,
358 : OptionTags::BoundaryDataFilename, OptionTags::H5LookaheadTimes,
359 : OptionTags::H5Interpolator,
360 : OptionTags::StandaloneExtractionRadius>;
361 :
362 0 : static constexpr bool pass_metavariables = false;
363 0 : static type create_from_options(
364 : const size_t l_max, const std::string& filename,
365 : const size_t number_of_lookahead_times,
366 : const std::unique_ptr<intrp::SpanInterpolator>& interpolator,
367 : const std::optional<double> extraction_radius) {
368 : const std::string text_radius_str = Cce::get_text_radius(filename);
369 : try {
370 : // If this doesn't throw an exception, then an extraction radius was
371 : // supplied in the filename. We don't actually need the value.
372 : const double text_radius = std::stod(text_radius_str);
373 : (void)text_radius;
374 : if (extraction_radius.has_value()) {
375 : Parallel::printf(
376 : "Warning: Option ExtractionRadius is set to a specific value and "
377 : "there is an extraction radius in the H5 filename. The value in "
378 : "the file name will be ignored.It is recommended to set "
379 : "`ExtractionRadius` to `\"Auto\"` if the H5 filename has the "
380 : "extraction radius in it to make the input file clearer.\n");
381 : }
382 : } catch (const std::invalid_argument&) {
383 : }
384 :
385 : return std::make_unique<BondiWorldtubeDataManager>(
386 : std::make_unique<BondiWorldtubeH5BufferUpdater<ComplexModalVector>>(
387 : filename, extraction_radius),
388 : l_max, number_of_lookahead_times, interpolator->get_clone());
389 : }
390 : };
391 :
392 : /// A tag that constructs a `KleinGordonWorldtubeDataManager` from options
393 1 : struct KleinGordonH5WorldtubeBoundaryDataManager : db::SimpleTag {
394 0 : using type = std::unique_ptr<
395 : WorldtubeDataManager<Tags::klein_gordon_worldtube_boundary_tags>>;
396 0 : using option_tags =
397 : tmpl::list<Spectral::Swsh::OptionTags::LMax,
398 : OptionTags::KleinGordonBoundaryDataFilename,
399 : OptionTags::H5LookaheadTimes, OptionTags::H5Interpolator,
400 : OptionTags::StandaloneExtractionRadius>;
401 :
402 0 : static constexpr bool pass_metavariables = false;
403 0 : static type create_from_options(
404 : const size_t l_max, const std::string& filename,
405 : const size_t number_of_lookahead_times,
406 : const std::unique_ptr<intrp::SpanInterpolator>& interpolator,
407 : const std::optional<double> extraction_radius) {
408 : return std::make_unique<KleinGordonWorldtubeDataManager>(
409 : std::make_unique<KleinGordonWorldtubeH5BufferUpdater>(
410 : filename, extraction_radius),
411 : l_max, number_of_lookahead_times, interpolator->get_clone());
412 : }
413 : };
414 :
415 0 : struct ObservationLMax : db::SimpleTag {
416 0 : using type = size_t;
417 0 : using option_tags = tmpl::list<OptionTags::ObservationLMax>;
418 :
419 0 : static constexpr bool pass_metavariables = false;
420 0 : static size_t create_from_options(const size_t observation_l_max) {
421 : return observation_l_max;
422 : }
423 : };
424 :
425 0 : struct FilterLMax : db::SimpleTag {
426 0 : using type = size_t;
427 0 : using option_tags = tmpl::list<OptionTags::FilterLMax>;
428 :
429 0 : static constexpr bool pass_metavariables = false;
430 0 : static size_t create_from_options(const size_t filter_l_max) {
431 : return filter_l_max;
432 : }
433 : };
434 :
435 0 : struct RadialFilterAlpha : db::SimpleTag {
436 0 : using type = double;
437 0 : using option_tags = tmpl::list<OptionTags::RadialFilterAlpha>;
438 :
439 0 : static constexpr bool pass_metavariables = false;
440 0 : static double create_from_options(const double radial_filter_alpha) {
441 : return radial_filter_alpha;
442 : }
443 : };
444 :
445 0 : struct RadialFilterHalfPower : db::SimpleTag {
446 0 : using type = size_t;
447 0 : using option_tags = tmpl::list<OptionTags::RadialFilterHalfPower>;
448 :
449 0 : static constexpr bool pass_metavariables = false;
450 0 : static size_t create_from_options(const size_t radial_filter_half_power) {
451 : return radial_filter_half_power;
452 : }
453 : };
454 :
455 : /// \brief Represents the start time of a bounded CCE evolution, determined
456 : /// either from option specification or from the file
457 : ///
458 : /// \details If no start time is specified in the input file (so the option
459 : /// `OptionTags::StartTime` is set to "Auto"), this will find the start time
460 : /// from the provided H5 file. If `OptionTags::StartTime` takes any other value,
461 : /// it will be used directly as the start time for the CCE evolution instead.
462 1 : struct StartTimeFromFile : Tags::StartTime {
463 0 : using base = Tags::StartTime;
464 0 : using option_tags =
465 : tmpl::list<OptionTags::StartTime, OptionTags::BoundaryDataFilename,
466 : OptionTags::StandaloneExtractionRadius>;
467 :
468 0 : static constexpr bool pass_metavariables = false;
469 0 : static double create_from_options(
470 : const std::optional<double> start_time, const std::string& filename,
471 : const std::optional<double>& extraction_radius) {
472 : if (start_time.has_value()) {
473 : return *start_time;
474 : }
475 :
476 : BondiWorldtubeH5BufferUpdater<ComplexModalVector> h5_boundary_updater{
477 : filename, extraction_radius};
478 : const auto& time_buffer = h5_boundary_updater.get_time_buffer();
479 : return time_buffer[0];
480 : }
481 : };
482 :
483 : /// \brief Represents the start time of a bounded CCE evolution that must be
484 : /// supplied in the input file (for e.g. analytic tests).
485 1 : struct SpecifiedStartTime : Tags::StartTime {
486 0 : using base = Tags::StartTime;
487 0 : using option_tags = tmpl::list<OptionTags::StartTime>;
488 :
489 0 : static constexpr bool pass_metavariables = false;
490 0 : static double create_from_options(const std::optional<double> start_time) {
491 : if (not start_time.has_value()) {
492 : ERROR(
493 : "The start time must be explicitly specified for the tag "
494 : "`SpecifiedStartTime`");
495 : }
496 : return *start_time;
497 : }
498 : };
499 :
500 : /// \brief Represents the final time of a bounded CCE evolution, determined
501 : /// either from option specification or from the file
502 : ///
503 : /// \details If no end time is specified in the input file (so the option
504 : /// `OptionTags::EndTime` is set to "Auto"), this will find the end time
505 : /// from the provided H5 file. If `OptionTags::EndTime` takes any other value,
506 : /// it will be used directly as the final time for the CCE evolution instead.
507 1 : struct EndTimeFromFile : Tags::EndTime {
508 0 : using base = Tags::EndTime;
509 0 : using option_tags =
510 : tmpl::list<OptionTags::EndTime, OptionTags::BoundaryDataFilename,
511 : OptionTags::StandaloneExtractionRadius>;
512 :
513 0 : static constexpr bool pass_metavariables = false;
514 0 : static double create_from_options(
515 : const std::optional<double> end_time, const std::string& filename,
516 : const std::optional<double>& extraction_radius) {
517 : if (end_time) {
518 : return *end_time;
519 : }
520 : BondiWorldtubeH5BufferUpdater<ComplexModalVector> h5_boundary_updater{
521 : filename, extraction_radius};
522 : const auto& time_buffer = h5_boundary_updater.get_time_buffer();
523 : return time_buffer[time_buffer.size() - 1];
524 : }
525 : };
526 :
527 : /// \brief Represents the final time of a CCE evolution that should just proceed
528 : /// until it receives no more boundary data and becomes quiescent.
529 1 : struct NoEndTime : Tags::EndTime {
530 0 : using base = Tags::EndTime;
531 0 : using option_tags = tmpl::list<>;
532 :
533 0 : static constexpr bool pass_metavariables = false;
534 0 : static double create_from_options() {
535 : return std::numeric_limits<double>::infinity();
536 : }
537 : };
538 :
539 : /// \brief Represents the final time of a bounded CCE evolution that must be
540 : /// supplied in the input file (for e.g. analytic tests).
541 1 : struct SpecifiedEndTime : Tags::EndTime {
542 0 : using base = Tags::EndTime;
543 0 : using option_tags = tmpl::list<OptionTags::EndTime>;
544 :
545 0 : static constexpr bool pass_metavariables = false;
546 0 : static double create_from_options(const std::optional<double> end_time) {
547 : if (not end_time.has_value()) {
548 : ERROR(
549 : "The end time must be explicitly specified for the tag "
550 : "`SpecifiedEndTime`");
551 : }
552 : return *end_time;
553 : }
554 : };
555 :
556 0 : struct GhInterfaceManager : db::SimpleTag {
557 0 : using type = InterfaceManagers::GhLocalTimeStepping;
558 0 : using option_tags = tmpl::list<OptionTags::GhInterfaceManager>;
559 :
560 0 : static constexpr bool pass_metavariables = false;
561 0 : static InterfaceManagers::GhLocalTimeStepping create_from_options(
562 : const InterfaceManagers::GhLocalTimeStepping& interface_manager) {
563 : return interface_manager;
564 : }
565 : };
566 :
567 : /// Tag for first-hypersurface initialization procedure specified by input
568 : /// options.
569 : template <bool evolve_ccm>
570 1 : struct InitializeJ : db::SimpleTag {
571 0 : using type = std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>;
572 0 : using option_tags = tmpl::list<OptionTags::InitializeJ<evolve_ccm>>;
573 :
574 0 : static constexpr bool pass_metavariables = false;
575 : static std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>
576 0 : create_from_options(
577 : const std::unique_ptr<::Cce::InitializeJ::InitializeJ<evolve_ccm>>&
578 : initialize_j) {
579 : return initialize_j->get_clone();
580 : }
581 : };
582 :
583 : // Tag that generates an `Cce::InitializeJ::InitializeJ` derived class for an
584 : // analytic-solution run. By default the initialization is provided by the
585 : // analytic solution itself, but it may be overridden from the input file via
586 : // `OptionTags::AnalyticInitializeJ`.
587 0 : struct AnalyticInitializeJ : InitializeJ<false> {
588 0 : using base = InitializeJ<false>;
589 0 : using option_tags =
590 : tmpl::list<OptionTags::AnalyticInitializeJ, OptionTags::AnalyticSolution,
591 : OptionTags::StartTime>;
592 0 : static constexpr bool pass_metavariables = false;
593 : static std::unique_ptr<::Cce::InitializeJ::InitializeJ<false>>
594 0 : create_from_options(
595 : const std::optional<std::unique_ptr<
596 : ::Cce::InitializeJ::InitializeJ<false>>>& initialize_j,
597 : const std::unique_ptr<Cce::Solutions::WorldtubeData>& worldtube_data,
598 : const std::optional<double> start_time) {
599 : if (initialize_j.has_value()) {
600 : return initialize_j.value()->get_clone();
601 : }
602 : return worldtube_data->get_initialize_j(*start_time);
603 : }
604 : };
605 :
606 : /// A tag that constructs a `AnalyticBoundaryDataManager` from options
607 1 : struct AnalyticBoundaryDataManager : db::SimpleTag {
608 0 : using type = ::Cce::AnalyticBoundaryDataManager;
609 0 : using option_tags =
610 : tmpl::list<OptionTags::ExtractionRadius, Spectral::Swsh::OptionTags::LMax,
611 : OptionTags::AnalyticSolution>;
612 :
613 0 : static constexpr bool pass_metavariables = false;
614 0 : static Cce::AnalyticBoundaryDataManager create_from_options(
615 : const double extraction_radius, const size_t l_max,
616 : const std::unique_ptr<Cce::Solutions::WorldtubeData>& worldtube_data) {
617 : return ::Cce::AnalyticBoundaryDataManager(l_max, extraction_radius,
618 : worldtube_data->get_clone());
619 : }
620 : };
621 :
622 : /// Represents whether the news should be provided at noninertial times.
623 : ///
624 : /// \details Currently, this is only useful for analytic solutions for which the
625 : /// inertial-time news is difficult to compute.
626 1 : struct OutputNoninertialNews : db::SimpleTag {
627 0 : using type = bool;
628 0 : using option_tags = tmpl::list<OptionTags::AnalyticSolution>;
629 0 : static constexpr bool pass_metavariables = false;
630 0 : static bool create_from_options(
631 : const std::unique_ptr<Cce::Solutions::WorldtubeData>& worldtube_data) {
632 : return worldtube_data->use_noninertial_news();
633 : }
634 : };
635 : } // namespace Tags
636 : } // namespace Cce
|