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