WrappedGr.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <boost/preprocessor/list/for_each.hpp>
7 #include <boost/preprocessor/tuple/to_list.hpp>
8 #include <cstddef>
9 
12 #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
14 #include "Options/Options.hpp"
15 #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
16 #include "Utilities/GenerateInstantiations.hpp"
17 #include "Utilities/TMPL.hpp"
19 
20 // IWYU pragma: no_forward_declare Tags::deriv
21 
22 /// \cond
23 class DataVector;
24 namespace PUP {
25 class er;
26 } // namespace PUP
27 /// \endcond
28 
29 namespace GeneralizedHarmonic {
30 namespace Solutions {
31 
32 /*!
33  * \brief A wrapper for general-relativity analytic solutions that loads
34  * the analytic solution and then adds a function that returns
35  * any combination of the generalized-harmonic evolution variables,
36  * specifically `gr::Tags::SpacetimeMetric`, `GeneralizedHarmonic::Tags::Pi`,
37  * and `GeneralizedHarmonic::Tags::Phi`
38  */
39 template <typename SolutionType>
40 class WrappedGr : public SolutionType {
41  public:
42  using SolutionType::SolutionType;
43 
44  static constexpr size_t volume_dim = SolutionType::volume_dim;
45  using options = typename SolutionType::options;
46  static constexpr OptionString help = SolutionType::help;
47 
48  using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataVector>,
49  tmpl::size_t<volume_dim>, Frame::Inertial>;
50  using DerivShift =
51  ::Tags::deriv<gr::Tags::Shift<volume_dim, Frame::Inertial, DataVector>,
52  tmpl::size_t<volume_dim>, Frame::Inertial>;
53  using DerivSpatialMetric = ::Tags::deriv<
55  tmpl::size_t<volume_dim>, Frame::Inertial>;
57  using TimeDerivShift =
60  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataVector>>;
61 
62  using IntermediateVars = tuples::tagged_tuple_from_typelist<
63  typename SolutionType::template tags<DataVector>>;
64 
65  template <typename... Tags>
66  tuples::TaggedTuple<Tags...> variables(
67  const tnsr::I<DataVector, volume_dim>& x, double t,
68  tmpl::list<Tags...> /*meta*/) const noexcept {
69  // Get the underlying solution's variables using the solution's tags list,
70  // store in IntermediateVariables
71  const IntermediateVars& intermediate_vars = SolutionType::variables(
72  x, t, typename SolutionType::template tags<DataVector>{});
73 
74  return {
75  get<Tags>(variables(x, t, tmpl::list<Tags>{}, intermediate_vars))...};
76  }
77 
78  template <typename Tag>
79  tuples::TaggedTuple<Tag> variables(const tnsr::I<DataVector, volume_dim>& x,
80  double t, tmpl::list<Tag> /*meta*/) const
81  noexcept {
82  const IntermediateVars& intermediate_vars = SolutionType::variables(
83  x, t, typename SolutionType::template tags<DataVector>{});
84  return {get<Tag>(variables(x, t, tmpl::list<Tag>{}, intermediate_vars))};
85  }
86 
87  // clang-tidy: google-runtime-references
88  void pup(PUP::er& p) noexcept { SolutionType::pup(p); } // NOLINT
89 
90  private:
91  // Preprocessor logic to avoid declaring variables() functions for
92  // tags other than the three the wrapper adds (i.e., other than
93  // gr::Tags::SpacetimeMetric, GeneralizedHarmonic::Tags::Pi, and
94  // GeneralizedHarmonic:Tags::Phi)
96  using TagSpatialMetric =
97  gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataVector>;
100  using TagExCurvature =
102 
103 #define FUNC_DECL(r, data, elem) \
104  tuples::TaggedTuple<elem> variables( \
105  const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/, \
106  tmpl::list<elem> /*meta*/, const IntermediateVars& intermediate_vars) \
107  const noexcept;
108 
109 #define MY_LIST \
110  BOOST_PP_TUPLE_TO_LIST( \
111  (gr::Tags::Lapse<DataVector>, TimeDerivLapse, DerivLapse, TagShift, \
112  TimeDerivShift, DerivShift, TagSpatialMetric, TimeDerivSpatialMetric, \
113  DerivSpatialMetric, TagInverseSpatialMetric, TagExCurvature, \
114  gr::Tags::SqrtDetSpatialMetric<DataVector>))
115 
116  BOOST_PP_LIST_FOR_EACH(FUNC_DECL, _, MY_LIST)
117 #undef MY_LIST
118 #undef FUNC_DECL
119 
122  variables(const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
123  tmpl::list<gr::Tags::SpacetimeMetric<volume_dim, Frame::Inertial,
124  DataVector>> /*meta*/,
125  const IntermediateVars& intermediate_vars) const noexcept;
126 
129  variables(const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
130  tmpl::list<GeneralizedHarmonic::Tags::Pi<volume_dim,
131  Frame::Inertial>> /*meta*/,
132  const IntermediateVars& intermediate_vars) const noexcept;
133 
136  variables(
137  const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
138  tmpl::list<
140  const IntermediateVars& intermediate_vars) const noexcept;
141 };
142 
143 template <typename SolutionType>
144 inline constexpr bool operator==(const WrappedGr<SolutionType>& lhs,
145  const WrappedGr<SolutionType>& rhs) noexcept {
146  return dynamic_cast<const SolutionType&>(lhs) ==
147  dynamic_cast<const SolutionType&>(rhs);
148 }
149 
150 template <typename SolutionType>
151 inline constexpr bool operator!=(const WrappedGr<SolutionType>& lhs,
152  const WrappedGr<SolutionType>& rhs) noexcept {
153  return not(lhs == rhs);
154 }
155 } // namespace Solutions
156 } // namespace GeneralizedHarmonic
Auxiliary variable which is analytically the spatial derivative of the spacetime metric.
Definition: Tags.hpp:40
A wrapper for general-relativity analytic solutions that loads the analytic solution and then adds a ...
Definition: WrappedGr.hpp:40
Conjugate momentum to the spacetime metric.
Definition: Tags.hpp:28
Definition: Strahlkorper.hpp:14
Defines class tuples::TaggedTuple.
Definition: Tags.hpp:17
Defines classes and functions for making classes creatable from input files.
Define prefixes for DataBox tags.
Inverse of the spatial metric.
Definition: Tags.hpp:36
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:29
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Definition: Tags.hpp:28
Items related to evolving the first-order generalized harmonic system.
Definition: Characteristics.cpp:20
Defines functions computing partial derivatives.
Definition: Tags.hpp:54
Definition: DataBoxTag.hpp:29
Defines classes for Tensor.
Stores a collection of function values.
Definition: DataVector.hpp:42
Wraps the template metaprogramming library used (brigand)
Definition: IndexType.hpp:44
Definition: Tags.hpp:148