WorldtubeData.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
9 #include "DataStructures/DataVector.hpp"
11 #include "Evolution/Systems/Cce/Initialize/InitializeJ.hpp"
12 #include "Evolution/Systems/Cce/Initialize/InverseCubic.hpp"
13 #include "Evolution/Systems/Cce/Tags.hpp"
14 #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
16 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
18 #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
19 #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
20 #include "Utilities/ContainerHelpers.hpp"
21 #include "Utilities/Gsl.hpp"
22 #include "Utilities/TMPL.hpp"
23 #include "Utilities/TaggedTuple.hpp"
24 
25 namespace Cce {
26 /// Analytic solutions for CCE worldtube data and corresponding waveform News
27 namespace Solutions {
28 
29 /// \cond
30 class BouncingBlackHole;
31 class GaugeWave;
32 class LinearizedBondiSachs;
33 class RobinsonTrautman;
34 class RotatingSchwarzschild;
35 class TeukolskyWave;
36 /// \endcond
37 
38 /*!
39  * \brief Abstract base class for analytic worldtube data for verifying the CCE
40  * system.
41  *
42  * \details All of the boundary data quantities are provided by the
43  * `WorldtubeData::variables()` function.
44  *
45  * This class provides caching and conversion between different
46  * representations of the metric data needed for the worldtube computation and
47  * evolution. The set of pure virtual functions (required to be overriden in the
48  * derived classes) is:
49  * - `WorldtubeData::get_clone()`: should return a
50  * `std::unique_ptr<WorldtubeData>` with cloned state
51  * - `WorldtubeData::variables_impl()` (a `protected` function): should compute
52  * and return by `not_null` pointer the spacetime metric quantity requested in
53  * the final (metavariable) tag argument. The function overloads that are
54  * required to be overriden in the derived class are
55  * `gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>`,
56  * `::Tags::dt<gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>`,
57  * `GeneralizedHarmonic::Tags::Phi<3, ::Frame::Inertial>`, and
58  * `Cce::Tags::News`.
59  * - `prepare_solution()`: Any initial precomputation needed to determine all of
60  * the solutions efficiently. This function is called by the base class prior to
61  * computing or retrieving from the internal cache the requested quantities.
62  *
63  * \warning This class is not intended to be threadsafe! Therefore, using
64  * instances of this class placed into the const global cache results in
65  * undefined behavior. The analytic data for CCE is not easily represented as a
66  * full closed-form solution for the entire Bondi-Sachs-like metric over the
67  * domain, so this class and its descendants perform numerical calculations such
68  * as spin-weighted derivatives over the sphere. Instead, it makes best sense to
69  * compute the global solution over the extraction sphere, and cache
70  * intermediate steps to avoid repeating potentially expensive tensor
71  * calculations.
72  */
73 struct WorldtubeData : public PUP::able {
74  using creatable_classes =
77 
78  /// The set of available tags provided by the analytic solution
79  using tags = tmpl::list<
93 
94  WRAPPED_PUPable_abstract(WorldtubeData); // NOLINT
95 
96  // clang doesn't manage to use = default correctly in this case
97  // NOLINTNEXTLINE(modernize-use-equals-default)
98  WorldtubeData() noexcept {};
99 
100  explicit WorldtubeData(const double extraction_radius) noexcept
101  : extraction_radius_{extraction_radius} {}
102 
103  explicit WorldtubeData(CkMigrateMessage* msg) noexcept : PUP::able(msg) {}
104 
105  virtual std::unique_ptr<WorldtubeData> get_clone() const noexcept = 0;
106 
107  /*!
108  * \brief Retrieve worldtube data represented by the analytic solution, at
109  * boundary angular resolution `l_max` and time `time`
110  *
111  * \details The set of requested tags are specified by the final argument,
112  * which must be a `tmpl::list` of tags to be retrieved. The set of available
113  * tags is found in `WorldtubeData::tags`, and includes coordinate and
114  * Jacobian quantities as well as metric quantities and derivatives thereof.
115  */
116  template <typename... Tags>
117  tuples::TaggedTuple<Tags...> variables(
118  // NOLINTNEXTLINE(readability-avoid-const-params-in-decls)
119  const size_t output_l_max, const double time,
120  tmpl::list<Tags...> /*meta*/) const noexcept {
121  prepare_solution(output_l_max, time);
122  return {cache_or_compute<Tags>(output_l_max, time)...};
123  }
124 
125  void pup(PUP::er& p) noexcept override;
126 
127  virtual std::unique_ptr<Cce::InitializeJ::InitializeJ> get_initialize_j(
128  const double /*start_time*/) const noexcept {
129  return std::make_unique<Cce::InitializeJ::InverseCubic>();
130  };
131 
132  virtual bool use_noninertial_news() const noexcept { return false; }
133 
134  protected:
135  template <typename Tag>
136  const auto& cache_or_compute(const size_t output_l_max,
137  const double time) const noexcept {
138  auto& item_cache = get<IntermediateCacheTag<Tag>>(intermediate_cache_);
139  if (item_cache.l_max == output_l_max and item_cache.time == time) {
140  return item_cache.data;
141  }
142  auto& item = item_cache.data;
144  make_not_null(&item),
146  variables_impl(make_not_null(&item), output_l_max, time,
147  tmpl::type_<Tag>{});
148  item_cache.l_max = output_l_max;
149  item_cache.time = time;
150  return item;
151  }
152  virtual void prepare_solution(size_t output_l_max, double time) const
153  noexcept = 0;
154 
155  // note that function template cannot be virtual, so we have to emulate
156  // template specializations through function overloads
157  virtual void variables_impl(
158  gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_coordinates,
159  size_t output_l_max, double time,
160  tmpl::type_<Tags::CauchyCartesianCoords> /*meta*/) const noexcept;
161 
162  virtual void variables_impl(
163  gsl::not_null<tnsr::i<DataVector, 3>*> dr_cartesian_coordinates,
164  size_t output_l_max, double time,
165  tmpl::type_<Tags::Dr<Tags::CauchyCartesianCoords>> /*meta*/) const
166  noexcept;
167 
168  virtual void variables_impl(
169  gsl::not_null<tnsr::aa<DataVector, 3>*> spacetime_metric,
170  size_t output_l_max, double time,
171  tmpl::type_<gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>
172  /*meta*/) const noexcept = 0;
173 
174  virtual void variables_impl(
175  gsl::not_null<tnsr::aa<DataVector, 3>*> dt_spacetime_metric,
176  size_t output_l_max, double time,
177  tmpl::type_<::Tags::dt<
178  gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>>
179  /*meta*/) const noexcept = 0;
180 
181  virtual void variables_impl(
182  gsl::not_null<tnsr::aa<DataVector, 3>*> pi, size_t output_l_max,
183  double time,
184  tmpl::type_<GeneralizedHarmonic::Tags::Pi<3, ::Frame::Inertial>>
185  /*meta*/) const noexcept;
186 
187  virtual void variables_impl(
188  gsl::not_null<tnsr::iaa<DataVector, 3>*> d_spacetime_metric,
189  size_t output_l_max, double time,
190  tmpl::type_<GeneralizedHarmonic::Tags::Phi<3, ::Frame::Inertial>>
191  /*meta*/) const noexcept = 0;
192 
193  virtual void variables_impl(
194  gsl::not_null<tnsr::ii<DataVector, 3>*> spatial_metric,
195  size_t output_l_max, double time,
196  tmpl::type_<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>
197  /*meta*/) const noexcept;
198 
199  virtual void variables_impl(
200  gsl::not_null<tnsr::ii<DataVector, 3>*> dt_spatial_metric,
201  size_t output_l_max, double time,
202  tmpl::type_<
203  ::Tags::dt<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>>
204  /*meta*/) const noexcept;
205 
206  virtual void variables_impl(
207  gsl::not_null<tnsr::ii<DataVector, 3>*> dr_spatial_metric,
208  size_t output_l_max, double time,
209  tmpl::type_<
210  Tags::Dr<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>>
211  /*meta*/) const noexcept;
212 
213  virtual void variables_impl(
214  gsl::not_null<tnsr::I<DataVector, 3>*> shift, size_t output_l_max,
215  double time,
216  tmpl::type_<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>
217  /*meta*/) const noexcept;
218 
219  virtual void variables_impl(
220  gsl::not_null<tnsr::I<DataVector, 3>*> dt_shift, size_t output_l_max,
221  double time,
222  tmpl::type_<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>
223  /*meta*/) const noexcept;
224 
225  virtual void variables_impl(
226  gsl::not_null<tnsr::I<DataVector, 3>*> dr_shift, size_t output_l_max,
227  double time,
228  tmpl::type_<Tags::Dr<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>
229  /*meta*/) const noexcept;
230 
231  virtual void variables_impl(gsl::not_null<Scalar<DataVector>*> lapse,
232  size_t output_l_max, double time,
233  tmpl::type_<gr::Tags::Lapse<DataVector>>
234  /*meta*/) const noexcept;
235 
236  virtual void variables_impl(
237  gsl::not_null<Scalar<DataVector>*> dt_lapse, size_t output_l_max,
238  double time, tmpl::type_<::Tags::dt<gr::Tags::Lapse<DataVector>>>
239  /*meta*/) const noexcept;
240 
241  virtual void variables_impl(gsl::not_null<Scalar<DataVector>*> dr_lapse,
242  size_t output_l_max, double time,
243  tmpl::type_<Tags::Dr<gr::Tags::Lapse<DataVector>>>
244  /*meta*/) const noexcept;
245 
246  virtual void variables_impl(
247  gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> news,
248  size_t output_l_max, double time, tmpl::type_<Tags::News> /*meta*/) const
249  noexcept = 0;
250 
251  template <typename Tag>
253  typename Tag::type data;
254  size_t l_max = 0;
255  double time = -std::numeric_limits<double>::infinity();
256  };
257 
258  template <typename Tag>
261  };
262 
263  using IntermediateCacheTuple =
264  tuples::tagged_tuple_from_typelist<tmpl::transform<
265  tmpl::list<
274  ::Tags::dt<
276  ::Tags::dt<
280  Tags::Dr<
284  tmpl::bind<IntermediateCacheTag, tmpl::_1>>>;
285 
286  mutable IntermediateCacheTuple intermediate_cache_;
287  double extraction_radius_ = std::numeric_limits<double>::quiet_NaN();
288 };
289 } // namespace Solutions
290 } // namespace Cce
Cce::Solutions::WorldtubeData::IntermediateCache
Definition: WorldtubeData.hpp:252
GeneralizedHarmonic::pi
void pi(gsl::not_null< tnsr::aa< DataType, SpatialDim, Frame > * > pi, const Scalar< DataType > &lapse, const Scalar< DataType > &dt_lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::I< DataType, SpatialDim, Frame > &dt_shift, const tnsr::ii< DataType, SpatialDim, Frame > &spatial_metric, const tnsr::ii< DataType, SpatialDim, Frame > &dt_spatial_metric, const tnsr::iaa< DataType, SpatialDim, Frame > &phi) noexcept
Computes the conjugate momentum of the spacetime metric .
CharmPupable.hpp
gr::Tags::SpatialMetric
Definition: Tags.hpp:26
std::numeric_limits::quiet_NaN
T quiet_NaN(T... args)
GeneralizedHarmonic
Items related to evolving the first-order generalized harmonic system.
Definition: Bjorhus.hpp:38
SpinWeighted
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition,...
Definition: SpinWeighted.hpp:24
gr::lapse
Scalar< DataType > lapse(const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric) noexcept
Compute lapse from shift and spacetime metric.
Cce::Solutions::BouncingBlackHole
Analytic solution representing a coordinate oscillation about a stationary Schwarzschild black hole.
Definition: BouncingBlackHole.hpp:36
DataBox.hpp
std::numeric_limits::infinity
T infinity(T... args)
cstddef
Cce::Solutions::LinearizedBondiSachs
Computes the analytic data for a Linearized solution to the Bondi-Sachs equations described in .
Definition: LinearizedBondiSachs.hpp:113
GeneralizedHarmonic::Tags::Pi
Conjugate momentum to the spacetime metric.
Definition: Tags.hpp:29
Cce::Solutions::WorldtubeData::tags
tmpl::list< Tags::CauchyCartesianCoords, Tags::Dr< Tags::CauchyCartesianCoords >, gr::Tags::SpacetimeMetric< 3, ::Frame::Inertial, DataVector >, ::Tags::dt< gr::Tags::SpacetimeMetric< 3, ::Frame::Inertial, DataVector > >, GeneralizedHarmonic::Tags::Pi< 3, ::Frame::Inertial >, GeneralizedHarmonic::Tags::Phi< 3, ::Frame::Inertial >, gr::Tags::SpatialMetric< 3, ::Frame::Inertial, DataVector >, ::Tags::dt< gr::Tags::SpatialMetric< 3, ::Frame::Inertial, DataVector > >, Tags::Dr< gr::Tags::SpatialMetric< 3, ::Frame::Inertial, DataVector > >, gr::Tags::Shift< 3, ::Frame::Inertial, DataVector >, ::Tags::dt< gr::Tags::Shift< 3, ::Frame::Inertial, DataVector > >, Tags::Dr< gr::Tags::Shift< 3, ::Frame::Inertial, DataVector > >, gr::Tags::Lapse< DataVector >, ::Tags::dt< gr::Tags::Lapse< DataVector > >, Tags::Dr< gr::Tags::Lapse< DataVector > >, Tags::News > tags
The set of available tags provided by the analytic solution.
Definition: WorldtubeData.hpp:92
Cce::Solutions::TeukolskyWave
Computes the analytic data for a Teukolsky wave solution described in .
Definition: TeukolskyWave.hpp:41
gr::Tags::SpacetimeMetric
Definition: Tags.hpp:17
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
gr::Tags::Shift
Definition: Tags.hpp:48
Cce::Tags::News
Definition: Tags.hpp:152
Cce::Solutions::WorldtubeData
Abstract base class for analytic worldtube data for verifying the CCE system.
Definition: WorldtubeData.hpp:73
tnsr
Type aliases to construct common Tensors.
Definition: TypeAliases.hpp:31
gr::shift
tnsr::I< DataType, SpatialDim, Frame > shift(const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric, const tnsr::II< DataType, SpatialDim, Frame > &inverse_spatial_metric) noexcept
Compute shift from spacetime metric and inverse spatial metric.
GeneralizedHarmonic::Tags::Phi
Auxiliary variable which is analytically the spatial derivative of the spacetime metric.
Definition: Tags.hpp:40
Tags::dt
Prefix indicating a time derivative.
Definition: Prefixes.hpp:29
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: CharacteristicExtractFwd.hpp:6
Cce::Solutions::WorldtubeData::IntermediateCacheTag
Definition: WorldtubeData.hpp:259
Gsl.hpp
Cce::Solutions::GaugeWave
Computes the analytic data for a gauge wave solution described in .
Definition: GaugeWave.hpp:47
Cce::Solutions::WorldtubeData::variables
tuples::TaggedTuple< Tags... > variables(const size_t output_l_max, const double time, tmpl::list< Tags... >) const noexcept
Retrieve worldtube data represented by the analytic solution, at boundary angular resolution l_max an...
Definition: WorldtubeData.hpp:117
Frame
Definition: IndexType.hpp:36
gr::spacetime_metric
void spacetime_metric(gsl::not_null< tnsr::aa< DataType, Dim, Frame > * > spacetime_metric, const Scalar< DataType > &lapse, const tnsr::I< DataType, Dim, Frame > &shift, const tnsr::ii< DataType, Dim, Frame > &spatial_metric) noexcept
Computes the spacetime metric from the spatial metric, lapse, and shift.
gr
Definition: GaugeWave.hpp:28
Tensor.hpp
gr::spatial_metric
tnsr::ii< DataType, SpatialDim, Frame > spatial_metric(const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric) noexcept
Compute spatial metric from spacetime metric.
std::time
T time(T... args)
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
PartialDerivatives.hpp
Cce::Solutions::RotatingSchwarzschild
Computes the analytic data for the rotating Schwarzschild solution described in , section VI....
Definition: RotatingSchwarzschild.hpp:37
ComplexDataVector
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:53
std::unique_ptr
gsl
Implementations from the Guideline Support Library.
Definition: ReadSpecPiecewisePolynomial.hpp:11
gr::Tags::Lapse
Definition: Tags.hpp:52
Cce::Solutions::RobinsonTrautman
An analytic solution representing a specialization of the radiative Robinson-Trautman solution descri...
Definition: RobinsonTrautman.hpp:59
TMPL.hpp
Cce::Tags::CauchyCartesianCoords
Definition: Tags.hpp:164
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13
destructive_resize_components
void destructive_resize_components(const gsl::not_null< Container * > container, const size_t new_size, DestructiveResizeFunction destructive_resize=ContainerDestructiveResize{}) noexcept
Checks the size of each component of the container, and resizes if necessary.
Definition: ContainerHelpers.hpp:177
Cce::Tags::Dr
The derivative with respect to Bondi .
Definition: Tags.hpp:125
Spectral::Swsh::number_of_swsh_collocation_points
constexpr size_t number_of_swsh_collocation_points(const size_t l_max) noexcept
Convenience function for determining the number of spin-weighted spherical harmonic collocation value...
Definition: SwshCollocation.hpp:24