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/Tags.hpp"
12 #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
14 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
16 #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
17 #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
18 #include "Utilities/ContainerHelpers.hpp"
19 #include "Utilities/Gsl.hpp"
20 #include "Utilities/TMPL.hpp"
21 #include "Utilities/TaggedTuple.hpp"
22 
23 namespace Cce {
24 namespace Solutions {
25 
26 /// \cond
27 class BouncingBlackHole;
28 class LinearizedBondiSachs;
29 /// \endcond
30 
31 /*!
32  * \brief Abstract base class for analytic worldtube data for verifying the CCE
33  * system.
34  *
35  * \details All of the boundary data quantities are provided by the
36  * `WorldtubeData::variables()` function.
37  *
38  * This class provides caching and conversion between different
39  * representations of the metric data needed for the worldtube computation and
40  * evolution. The set of pure virtual functions (required to be overriden in the
41  * derived classes) is:
42  * - `WorldtubeData::get_clone()`: should return a
43  * `std::unique_ptr<WorldtubeData>` with cloned state
44  * - `WorldtubeData::variables_impl()` (a `protected` function): should compute
45  * and return by `not_null` pointer the spacetime metric quantity requested in
46  * the final (metavariable) tag argument. The function overloads that are
47  * required to be overriden in the derived class are
48  * `gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>`,
49  * `::Tags::dt<gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>`,
50  * `GeneralizedHarmonic::Tags::Phi<3, ::Frame::Inertial>`, and
51  * `Cce::Tags::News`.
52  * - `prepare_solution()`: Any initial precomputation needed to determine all of
53  * the solutions efficiently. This function is called by the base class prior to
54  * computing or retrieving from the internal cache the requested quantities.
55  *
56  * \warning This class is not intended to be threadsafe! Therefore, using
57  * instances of this class placed into the const global cache results in
58  * undefined behavior. The analytic data for CCE is not easily represented as a
59  * full closed-form solution for the entire Bondi-Sachs-like metric over the
60  * domain, so this class and its descendants perform numerical calculations such
61  * as spin-weighted derivatives over the sphere. Instead, it makes best sense to
62  * compute the global solution over the extraction sphere, and cache
63  * intermediate steps to avoid repeating potentially expensive tensor
64  * calculations.
65  */
66 struct WorldtubeData : public PUP::able {
67  using creatable_classes = tmpl::list<BouncingBlackHole, LinearizedBondiSachs>;
68 
69  /// The set of available tags provided by the analytic solution
70  using tags = tmpl::list<
84 
85  WRAPPED_PUPable_abstract(WorldtubeData); // NOLINT
86 
87  // clang doesn't manage to use = default correctly in this case
88  // NOLINTNEXTLINE(modernize-use-equals-default)
89  WorldtubeData() noexcept {};
90 
91  explicit WorldtubeData(const double extraction_radius) noexcept
92  : extraction_radius_{extraction_radius} {}
93 
94  virtual std::unique_ptr<WorldtubeData> get_clone() const noexcept = 0;
95 
96  /*!
97  * \brief Retrieve worldtube data represented by the analytic solution, at
98  * boundary angular resolution `l_max` and time `time`
99  *
100  * \details The set of requested tags are specified by the final argument,
101  * which must be a `tmpl::list` of tags to be retrieved. The set of available
102  * tags is found in `WorldtubeData::tags`, and includes coordinate and
103  * Jacobian quantities as well as metric quantities and derivatives thereof.
104  */
105  template <typename... Tags>
106  tuples::TaggedTuple<Tags...> variables(
107  // NOLINTNEXTLINE(readability-avoid-const-params-in-decls)
108  const size_t output_l_max, const double time,
109  tmpl::list<Tags...> /*meta*/) const noexcept {
110  prepare_solution(output_l_max, time);
111  return {cache_or_compute<Tags>(output_l_max, time)...};
112  }
113 
114  void pup(PUP::er& p) noexcept override;
115 
116  protected:
117  template <typename Tag>
118  const auto& cache_or_compute(const size_t output_l_max,
119  const double time) const noexcept {
120  auto& item_cache = get<IntermediateCacheTag<Tag>>(intermediate_cache_);
121  if (item_cache.l_max == output_l_max and item_cache.time == time) {
122  return item_cache.data;
123  }
124  auto& item = item_cache.data;
126  make_not_null(&item),
128  variables_impl(make_not_null(&item), output_l_max, time,
129  tmpl::type_<Tag>{});
130  item_cache.l_max = output_l_max;
131  item_cache.time = time;
132  return item;
133  }
134  virtual void prepare_solution(size_t output_l_max, double time) const
135  noexcept = 0;
136 
137  // note that function template cannot be virtual, so we have to emulate
138  // template specializations through function overloads
139  virtual void variables_impl(
140  gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_coordinates,
141  size_t output_l_max, double time,
142  tmpl::type_<Tags::CauchyCartesianCoords> /*meta*/) const noexcept;
143 
144  virtual void variables_impl(
145  gsl::not_null<tnsr::i<DataVector, 3>*> dr_cartesian_coordinates,
146  size_t output_l_max, double time,
147  tmpl::type_<Tags::Dr<Tags::CauchyCartesianCoords>> /*meta*/) const
148  noexcept;
149 
150  virtual void variables_impl(
151  gsl::not_null<tnsr::aa<DataVector, 3>*> spacetime_metric,
152  size_t output_l_max, double time,
153  tmpl::type_<gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>
154  /*meta*/) const noexcept = 0;
155 
156  virtual void variables_impl(
157  gsl::not_null<tnsr::aa<DataVector, 3>*> dt_spacetime_metric,
158  size_t output_l_max, double time,
159  tmpl::type_<::Tags::dt<
160  gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>>
161  /*meta*/) const noexcept = 0;
162 
163  virtual void variables_impl(
164  gsl::not_null<tnsr::aa<DataVector, 3>*> pi, size_t output_l_max,
165  double time,
166  tmpl::type_<GeneralizedHarmonic::Tags::Pi<3, ::Frame::Inertial>>
167  /*meta*/) const noexcept;
168 
169  virtual void variables_impl(
170  gsl::not_null<tnsr::iaa<DataVector, 3>*> d_spacetime_metric,
171  size_t output_l_max, double time,
172  tmpl::type_<GeneralizedHarmonic::Tags::Phi<3, ::Frame::Inertial>>
173  /*meta*/) const noexcept = 0;
174 
175  virtual void variables_impl(
176  gsl::not_null<tnsr::ii<DataVector, 3>*> spatial_metric,
177  size_t output_l_max, double time,
178  tmpl::type_<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>
179  /*meta*/) const noexcept;
180 
181  virtual void variables_impl(
182  gsl::not_null<tnsr::ii<DataVector, 3>*> dt_spatial_metric,
183  size_t output_l_max, double time,
184  tmpl::type_<
185  ::Tags::dt<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>>
186  /*meta*/) const noexcept;
187 
188  virtual void variables_impl(
189  gsl::not_null<tnsr::ii<DataVector, 3>*> dr_spatial_metric,
190  size_t output_l_max, double time,
191  tmpl::type_<
192  Tags::Dr<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>>
193  /*meta*/) const noexcept;
194 
195  virtual void variables_impl(
196  gsl::not_null<tnsr::I<DataVector, 3>*> shift, size_t output_l_max,
197  double time,
198  tmpl::type_<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>
199  /*meta*/) const noexcept;
200 
201  virtual void variables_impl(
202  gsl::not_null<tnsr::I<DataVector, 3>*> dt_shift, size_t output_l_max,
203  double time,
204  tmpl::type_<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>
205  /*meta*/) const noexcept;
206 
207  virtual void variables_impl(
208  gsl::not_null<tnsr::I<DataVector, 3>*> dr_shift, size_t output_l_max,
209  double time,
210  tmpl::type_<Tags::Dr<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>
211  /*meta*/) const noexcept;
212 
213  virtual void variables_impl(gsl::not_null<Scalar<DataVector>*> lapse,
214  size_t output_l_max, double time,
215  tmpl::type_<gr::Tags::Lapse<DataVector>>
216  /*meta*/) const noexcept;
217 
218  virtual void variables_impl(
219  gsl::not_null<Scalar<DataVector>*> dt_lapse, size_t output_l_max,
220  double time, tmpl::type_<::Tags::dt<gr::Tags::Lapse<DataVector>>>
221  /*meta*/) const noexcept;
222 
223  virtual void variables_impl(gsl::not_null<Scalar<DataVector>*> dr_lapse,
224  size_t output_l_max, double time,
225  tmpl::type_<Tags::Dr<gr::Tags::Lapse<DataVector>>>
226  /*meta*/) const noexcept;
227 
228  virtual void variables_impl(
229  gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> news,
230  size_t output_l_max, double time, tmpl::type_<Tags::News> /*meta*/) const
231  noexcept = 0;
232 
233  template <typename Tag>
235  typename Tag::type data;
236  size_t l_max = 0;
237  double time = -std::numeric_limits<double>::infinity();
238  };
239 
240  template <typename Tag>
243  };
244 
245  using IntermediateCacheTuple =
246  tuples::tagged_tuple_from_typelist<tmpl::transform<
247  tmpl::list<
256  ::Tags::dt<
258  ::Tags::dt<
262  Tags::Dr<
266  tmpl::bind<IntermediateCacheTag, tmpl::_1>>>;
267 
268  mutable IntermediateCacheTuple intermediate_cache_;
269  double extraction_radius_ = std::numeric_limits<double>::quiet_NaN();
270 };
271 } // namespace Solutions
272 } // namespace Cce
Cce::Solutions::WorldtubeData::IntermediateCache
Definition: WorldtubeData.hpp:234
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: Characteristics.cpp:21
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.
DataBox.hpp
std::numeric_limits::infinity
T infinity(T... args)
cstddef
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:83
gr::Tags::SpacetimeMetric
Definition: Tags.hpp:17
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:42
gr::Tags::Shift
Definition: Tags.hpp:48
Cce::Tags::News
Definition: Tags.hpp:151
Cce::Solutions::WorldtubeData
Abstract base class for analytic worldtube data for verifying the CCE system.
Definition: WorldtubeData.hpp:66
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: BoundaryComputeAndSendToEvolution.hpp:28
Cce::Solutions::WorldtubeData::IntermediateCacheTag
Definition: WorldtubeData.hpp:241
Gsl.hpp
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:106
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:27
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.
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
ComplexDataVector
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:47
std::unique_ptr
gsl
Implementations from the Guideline Support Library.
Definition: Gsl.hpp:80
gr::Tags::Lapse
Definition: Tags.hpp:52
TMPL.hpp
Cce::Tags::CauchyCartesianCoords
Definition: Tags.hpp:163
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
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:124
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:25