Line data Source code
1 0 : // 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 :
10 : #include "DataStructures/DataBox/Prefixes.hpp"
11 : #include "DataStructures/Tensor/Tensor.hpp"
12 : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
13 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp" // for tags
14 : #include "Options/Options.hpp"
15 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
16 : #include "Utilities/GenerateInstantiations.hpp"
17 : #include "Utilities/TMPL.hpp"
18 : #include "Utilities/TaggedTuple.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 0 : 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 1 : class WrappedGr : public SolutionType {
41 : public:
42 : using SolutionType::SolutionType;
43 :
44 0 : static constexpr size_t volume_dim = SolutionType::volume_dim;
45 0 : using options = typename SolutionType::options;
46 0 : static constexpr Options::String help = SolutionType::help;
47 0 : static std::string name() noexcept {
48 : return Options::name<SolutionType>();
49 : }
50 :
51 0 : using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataVector>,
52 : tmpl::size_t<volume_dim>, Frame::Inertial>;
53 0 : using DerivShift =
54 : ::Tags::deriv<gr::Tags::Shift<volume_dim, Frame::Inertial, DataVector>,
55 : tmpl::size_t<volume_dim>, Frame::Inertial>;
56 0 : using DerivSpatialMetric = ::Tags::deriv<
57 : gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataVector>,
58 : tmpl::size_t<volume_dim>, Frame::Inertial>;
59 0 : using TimeDerivLapse = ::Tags::dt<gr::Tags::Lapse<DataVector>>;
60 0 : using TimeDerivShift =
61 : ::Tags::dt<gr::Tags::Shift<volume_dim, Frame::Inertial, DataVector>>;
62 0 : using TimeDerivSpatialMetric = ::Tags::dt<
63 : gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataVector>>;
64 :
65 0 : using IntermediateVars = tuples::tagged_tuple_from_typelist<
66 : typename SolutionType::template tags<DataVector>>;
67 :
68 : template <typename DataType>
69 0 : using tags = tmpl::push_back<
70 : typename SolutionType::template tags<DataType>,
71 : gr::Tags::SpacetimeMetric<volume_dim, Frame::Inertial, DataType>,
72 : GeneralizedHarmonic::Tags::Pi<volume_dim, Frame::Inertial>,
73 : GeneralizedHarmonic::Tags::Phi<volume_dim, Frame::Inertial>>;
74 :
75 : template <typename... Tags>
76 0 : tuples::TaggedTuple<Tags...> variables(
77 : const tnsr::I<DataVector, volume_dim>& x, double t,
78 : tmpl::list<Tags...> /*meta*/) const noexcept {
79 : // Get the underlying solution's variables using the solution's tags list,
80 : // store in IntermediateVariables
81 : const IntermediateVars& intermediate_vars = SolutionType::variables(
82 : x, t, typename SolutionType::template tags<DataVector>{});
83 :
84 : return {
85 : get<Tags>(variables(x, t, tmpl::list<Tags>{}, intermediate_vars))...};
86 : }
87 :
88 : template <typename Tag>
89 0 : tuples::TaggedTuple<Tag> variables(const tnsr::I<DataVector, volume_dim>& x,
90 : double t, tmpl::list<Tag> /*meta*/) const
91 : noexcept {
92 : const IntermediateVars& intermediate_vars = SolutionType::variables(
93 : x, t, typename SolutionType::template tags<DataVector>{});
94 : return {get<Tag>(variables(x, t, tmpl::list<Tag>{}, intermediate_vars))};
95 : }
96 :
97 : // clang-tidy: google-runtime-references
98 0 : void pup(PUP::er& p) noexcept { SolutionType::pup(p); } // NOLINT
99 :
100 : private:
101 : // Preprocessor logic to avoid declaring variables() functions for
102 : // tags other than the three the wrapper adds (i.e., other than
103 : // gr::Tags::SpacetimeMetric, GeneralizedHarmonic::Tags::Pi, and
104 : // GeneralizedHarmonic:Tags::Phi)
105 0 : using TagShift = gr::Tags::Shift<volume_dim, Frame::Inertial, DataVector>;
106 0 : using TagSpatialMetric =
107 : gr::Tags::SpatialMetric<volume_dim, Frame::Inertial, DataVector>;
108 0 : using TagInverseSpatialMetric =
109 : gr::Tags::InverseSpatialMetric<volume_dim, Frame::Inertial, DataVector>;
110 0 : using TagExCurvature =
111 : gr::Tags::ExtrinsicCurvature<volume_dim, Frame::Inertial, DataVector>;
112 :
113 0 : #define FUNC_DECL(r, data, elem) \
114 : tuples::TaggedTuple<elem> variables( \
115 : const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/, \
116 : tmpl::list<elem> /*meta*/, const IntermediateVars& intermediate_vars) \
117 : const noexcept;
118 :
119 0 : #define MY_LIST \
120 : BOOST_PP_TUPLE_TO_LIST( \
121 : (gr::Tags::Lapse<DataVector>, TimeDerivLapse, DerivLapse, TagShift, \
122 : TimeDerivShift, DerivShift, TagSpatialMetric, TimeDerivSpatialMetric, \
123 : DerivSpatialMetric, TagInverseSpatialMetric, TagExCurvature, \
124 : gr::Tags::SqrtDetSpatialMetric<DataVector>))
125 :
126 : BOOST_PP_LIST_FOR_EACH(FUNC_DECL, _, MY_LIST)
127 : #undef MY_LIST
128 : #undef FUNC_DECL
129 :
130 : tuples::TaggedTuple<
131 : gr::Tags::SpacetimeMetric<volume_dim, Frame::Inertial, DataVector>>
132 0 : variables(const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
133 : tmpl::list<gr::Tags::SpacetimeMetric<volume_dim, Frame::Inertial,
134 : DataVector>> /*meta*/,
135 : const IntermediateVars& intermediate_vars) const noexcept;
136 :
137 : tuples::TaggedTuple<
138 : GeneralizedHarmonic::Tags::Pi<volume_dim, Frame::Inertial>>
139 0 : variables(const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
140 : tmpl::list<GeneralizedHarmonic::Tags::Pi<volume_dim,
141 : Frame::Inertial>> /*meta*/,
142 : const IntermediateVars& intermediate_vars) const noexcept;
143 :
144 : tuples::TaggedTuple<
145 : GeneralizedHarmonic::Tags::Phi<volume_dim, Frame::Inertial>>
146 0 : variables(
147 : const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
148 : tmpl::list<
149 : GeneralizedHarmonic::Tags::Phi<volume_dim, Frame::Inertial>> /*meta*/,
150 : const IntermediateVars& intermediate_vars) const noexcept;
151 : };
152 :
153 : template <typename SolutionType>
154 0 : inline constexpr bool operator==(const WrappedGr<SolutionType>& lhs,
155 : const WrappedGr<SolutionType>& rhs) noexcept {
156 : return dynamic_cast<const SolutionType&>(lhs) ==
157 : dynamic_cast<const SolutionType&>(rhs);
158 : }
159 :
160 : template <typename SolutionType>
161 0 : inline constexpr bool operator!=(const WrappedGr<SolutionType>& lhs,
162 : const WrappedGr<SolutionType>& rhs) noexcept {
163 : return not(lhs == rhs);
164 : }
165 : } // namespace Solutions
166 : } // namespace GeneralizedHarmonic
|