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