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