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