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