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"
14 : #include "Options/String.hpp"
15 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
16 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
17 : #include "Utilities/GenerateInstantiations.hpp"
18 : #include "Utilities/Serialization/CharmPupable.hpp"
19 : #include "Utilities/TMPL.hpp"
20 : #include "Utilities/TaggedTuple.hpp"
21 :
22 : /// \cond
23 : class DataVector;
24 : namespace PUP {
25 : class er;
26 : } // namespace PUP
27 : /// \endcond
28 :
29 : namespace gh {
30 : namespace Solutions {
31 : /*!
32 : * \brief A wrapper for general-relativity analytic solutions that loads
33 : * the analytic solution and then adds a function that returns
34 : * any combination of the generalized-harmonic evolution variables,
35 : * specifically `gr::Tags::SpacetimeMetric`, `gh::Tags::Pi`,
36 : * and `gh::Tags::Phi`
37 : */
38 : template <typename SolutionType>
39 1 : class WrappedGr : public virtual evolution::initial_data::InitialData,
40 : public SolutionType {
41 : public:
42 : using SolutionType::SolutionType;
43 :
44 0 : WrappedGr() = default;
45 0 : WrappedGr(const WrappedGr& /*rhs*/) = default;
46 0 : WrappedGr& operator=(const WrappedGr& /*rhs*/) = default;
47 0 : WrappedGr(WrappedGr&& /*rhs*/) = default;
48 0 : WrappedGr& operator=(WrappedGr&& /*rhs*/) = default;
49 0 : ~WrappedGr() override = default;
50 :
51 0 : explicit WrappedGr(const SolutionType& wrapped_solution)
52 : : SolutionType(wrapped_solution) {}
53 :
54 0 : auto get_clone() const
55 : -> std::unique_ptr<evolution::initial_data::InitialData> override;
56 :
57 : /// \cond
58 : explicit WrappedGr(CkMigrateMessage* msg);
59 : using PUP::able::register_constructor;
60 : WRAPPED_PUPable_decl_template(WrappedGr);
61 : /// \endcond
62 :
63 0 : static constexpr size_t volume_dim = SolutionType::volume_dim;
64 0 : using options = typename SolutionType::options;
65 0 : static constexpr Options::String help = SolutionType::help;
66 0 : static std::string name() {
67 : return "GeneralizedHarmonic(" + pretty_type::name<SolutionType>() + ")";
68 : }
69 :
70 0 : using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataVector>,
71 : tmpl::size_t<volume_dim>, Frame::Inertial>;
72 0 : using DerivShift = ::Tags::deriv<gr::Tags::Shift<DataVector, volume_dim>,
73 : tmpl::size_t<volume_dim>, Frame::Inertial>;
74 0 : using DerivSpatialMetric =
75 : ::Tags::deriv<gr::Tags::SpatialMetric<DataVector, volume_dim>,
76 : tmpl::size_t<volume_dim>, Frame::Inertial>;
77 0 : using TimeDerivLapse = ::Tags::dt<gr::Tags::Lapse<DataVector>>;
78 0 : using TimeDerivShift = ::Tags::dt<gr::Tags::Shift<DataVector, volume_dim>>;
79 0 : using TimeDerivSpatialMetric =
80 : ::Tags::dt<gr::Tags::SpatialMetric<DataVector, volume_dim>>;
81 :
82 0 : using IntermediateVars = tuples::tagged_tuple_from_typelist<
83 : typename SolutionType::template tags<DataVector>>;
84 :
85 : template <typename DataType>
86 0 : using tags = tmpl::push_back<typename SolutionType::template tags<DataType>,
87 : gr::Tags::SpacetimeMetric<DataType, volume_dim>,
88 : gh::Tags::Pi<DataVector, volume_dim>,
89 : gh::Tags::Phi<DataVector, volume_dim>>;
90 :
91 : template <typename... Tags>
92 0 : tuples::TaggedTuple<Tags...> variables(
93 : const tnsr::I<DataVector, volume_dim>& x, double t,
94 : tmpl::list<Tags...> /*meta*/) const {
95 : // Get the underlying solution's variables using the solution's tags list,
96 : // store in IntermediateVariables
97 : const IntermediateVars& intermediate_vars = SolutionType::variables(
98 : x, t, typename SolutionType::template tags<DataVector>{});
99 :
100 : return {
101 : get<Tags>(variables(x, t, tmpl::list<Tags>{}, intermediate_vars))...};
102 : }
103 :
104 : template <typename Tag>
105 0 : tuples::TaggedTuple<Tag> variables(const tnsr::I<DataVector, volume_dim>& x,
106 : double t, tmpl::list<Tag> /*meta*/) const {
107 : const IntermediateVars& intermediate_vars = SolutionType::variables(
108 : x, t, typename SolutionType::template tags<DataVector>{});
109 : return {get<Tag>(variables(x, t, tmpl::list<Tag>{}, intermediate_vars))};
110 : }
111 :
112 : // overloads for wrapping analytic data
113 :
114 : template <typename... Tags>
115 0 : tuples::TaggedTuple<Tags...> variables(
116 : const tnsr::I<DataVector, volume_dim>& x,
117 : tmpl::list<Tags...> /*meta*/) const {
118 : // Get the underlying solution's variables using the solution's tags list,
119 : // store in IntermediateVariables
120 : const IntermediateVars intermediate_vars = SolutionType::variables(
121 : x, typename SolutionType::template tags<DataVector>{});
122 :
123 : return {get<Tags>(variables(x, tmpl::list<Tags>{}, intermediate_vars))...};
124 : }
125 :
126 : template <typename Tag>
127 0 : tuples::TaggedTuple<Tag> variables(const tnsr::I<DataVector, volume_dim>& x,
128 : tmpl::list<Tag> /*meta*/) const {
129 : const IntermediateVars intermediate_vars = SolutionType::variables(
130 : x, typename SolutionType::template tags<DataVector>{});
131 : return {get<Tag>(variables(x, tmpl::list<Tag>{}, intermediate_vars))};
132 : }
133 :
134 : // NOLINTNEXTLINE(google-runtime-references)
135 0 : void pup(PUP::er& p) override;
136 :
137 : private:
138 : // Preprocessor logic to avoid declaring variables() functions for
139 : // tags other than the three the wrapper adds (i.e., other than
140 : // gr::Tags::SpacetimeMetric, gh::Tags::Pi, and
141 : // GeneralizedHarmonic:Tags::Phi)
142 0 : using TagShift = gr::Tags::Shift<DataVector, volume_dim>;
143 0 : using TagSpatialMetric = gr::Tags::SpatialMetric<DataVector, volume_dim>;
144 0 : using TagInverseSpatialMetric =
145 : gr::Tags::InverseSpatialMetric<DataVector, volume_dim>;
146 0 : using TagExCurvature = gr::Tags::ExtrinsicCurvature<DataVector, volume_dim>;
147 :
148 : template <typename Tag>
149 0 : tuples::TaggedTuple<Tag> variables(
150 : const tnsr::I<DataVector, volume_dim>& /*x*/, double /*t*/,
151 : tmpl::list<Tag> /*meta*/,
152 : const IntermediateVars& intermediate_vars) const {
153 : static_assert(
154 : tmpl::list_contains_v<typename SolutionType::template tags<DataVector>,
155 : Tag>);
156 : return {get<Tag>(intermediate_vars)};
157 : }
158 :
159 : template <typename Tag>
160 0 : tuples::TaggedTuple<Tag> variables(
161 : const tnsr::I<DataVector, volume_dim>& /*x*/, tmpl::list<Tag> /*meta*/,
162 : const IntermediateVars& intermediate_vars) const {
163 : static_assert(
164 : tmpl::list_contains_v<typename SolutionType::template tags<DataVector>,
165 : Tag>);
166 : return {get<Tag>(intermediate_vars)};
167 : }
168 :
169 : tuples::TaggedTuple<gr::Tags::SpacetimeMetric<DataVector, volume_dim>>
170 0 : variables(
171 : const tnsr::I<DataVector, volume_dim>& /*x*/,
172 : tmpl::list<gr::Tags::SpacetimeMetric<DataVector, volume_dim>> /*meta*/,
173 : const IntermediateVars& intermediate_vars) const;
174 0 : tuples::TaggedTuple<gh::Tags::Pi<DataVector, volume_dim>> variables(
175 : const tnsr::I<DataVector, volume_dim>& /*x*/,
176 : tmpl::list<gh::Tags::Pi<DataVector, volume_dim>> /*meta*/,
177 : const IntermediateVars& intermediate_vars) const;
178 0 : tuples::TaggedTuple<gh::Tags::Phi<DataVector, volume_dim>> variables(
179 : const tnsr::I<DataVector, volume_dim>& /*x*/,
180 : tmpl::list<gh::Tags::Phi<DataVector, volume_dim>> /*meta*/,
181 : const IntermediateVars& intermediate_vars) const;
182 :
183 : tuples::TaggedTuple<gr::Tags::SpacetimeMetric<DataVector, volume_dim>>
184 0 : variables(const tnsr::I<DataVector, volume_dim>& x, const double /*t*/,
185 : tmpl::list<gr::Tags::SpacetimeMetric<DataVector, volume_dim>> meta,
186 : const IntermediateVars& intermediate_vars) const {
187 : return variables(x, meta, intermediate_vars);
188 : }
189 0 : tuples::TaggedTuple<gh::Tags::Pi<DataVector, volume_dim>> variables(
190 : const tnsr::I<DataVector, volume_dim>& x, double /*t*/,
191 : tmpl::list<gh::Tags::Pi<DataVector, volume_dim>> meta,
192 : const IntermediateVars& intermediate_vars) const {
193 : return variables(x, meta, intermediate_vars);
194 : }
195 0 : tuples::TaggedTuple<gh::Tags::Phi<DataVector, volume_dim>> variables(
196 : const tnsr::I<DataVector, volume_dim>& x, double /*t*/,
197 : tmpl::list<gh::Tags::Phi<DataVector, volume_dim>> meta,
198 : const IntermediateVars& intermediate_vars) const {
199 : return variables(x, meta, intermediate_vars);
200 : }
201 : };
202 :
203 : template <typename SolutionType>
204 0 : bool operator==(const WrappedGr<SolutionType>& lhs,
205 : const WrappedGr<SolutionType>& rhs);
206 :
207 : template <typename SolutionType>
208 0 : bool operator!=(const WrappedGr<SolutionType>& lhs,
209 : const WrappedGr<SolutionType>& rhs);
210 :
211 : template <typename SolutionType>
212 0 : WrappedGr(SolutionType solution) -> WrappedGr<SolutionType>;
213 : } // namespace Solutions
214 : } // namespace gh
|