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