Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <memory>
8 : #include <pup.h>
9 :
10 : #include "Evolution/BoundaryCorrection.hpp"
11 : #include "Evolution/Systems/GeneralizedHarmonic/System.hpp"
12 : #include "Evolution/Systems/GrMhd/GhValenciaDivClean/Tags.hpp"
13 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/System.hpp"
14 : #include "NumericalAlgorithms/DiscontinuousGalerkin/Formulation.hpp"
15 : #include "Options/String.hpp"
16 : #include "Utilities/Gsl.hpp"
17 : #include "Utilities/PrettyType.hpp"
18 : #include "Utilities/Serialization/CharmPupable.hpp"
19 : #include "Utilities/StdHelpers/RetrieveUniquePtr.hpp"
20 : #include "Utilities/TMPL.hpp"
21 :
22 : namespace grmhd::GhValenciaDivClean::BoundaryCorrections {
23 : namespace detail {
24 : template <typename DerivedGhCorrection, typename DerivedValenciaCorrection,
25 : typename GhPackageFieldTagList, typename ValenciaPackageFieldTagList,
26 : typename GhEvolvedTagList, typename ValenciaEvolvedTags,
27 : typename GhFluxTagList, typename ValenciaFluxTagList,
28 : typename GhTempTagList, typename ValenciaTempTagList,
29 : typename DeduplicatedTempTags, typename GhPrimTagList,
30 : typename ValenicaPrimTagList, typename GhVolumeTagList,
31 : typename ValenciaVolumeTagList>
32 : struct ProductOfCorrectionsImpl;
33 :
34 : template <typename DerivedGhCorrection, typename DerivedValenciaCorrection,
35 : typename... GhPackageFieldTags, typename... ValenciaPackageFieldTags,
36 : typename... GhEvolvedTags, typename... ValenciaEvolvedTags,
37 : typename... GhFluxTags, typename... ValenciaFluxTags,
38 : typename... GhTempTags, typename... ValenciaTempTags,
39 : typename... DeduplicatedTempTags, typename... GhPrimTags,
40 : typename... ValenciaPrimTags, typename... GhVolumeTags,
41 : typename... ValenciaVolumeTags>
42 : struct ProductOfCorrectionsImpl<
43 : DerivedGhCorrection, DerivedValenciaCorrection,
44 : tmpl::list<GhPackageFieldTags...>, tmpl::list<ValenciaPackageFieldTags...>,
45 : tmpl::list<GhEvolvedTags...>, tmpl::list<ValenciaEvolvedTags...>,
46 : tmpl::list<GhFluxTags...>, tmpl::list<ValenciaFluxTags...>,
47 : tmpl::list<GhTempTags...>, tmpl::list<ValenciaTempTags...>,
48 : tmpl::list<DeduplicatedTempTags...>, tmpl::list<GhPrimTags...>,
49 : tmpl::list<ValenciaPrimTags...>, tmpl::list<GhVolumeTags...>,
50 : tmpl::list<ValenciaVolumeTags...>> {
51 : static double dg_package_data(
52 : const gsl::not_null<
53 : typename GhPackageFieldTags::type*>... gh_packaged_fields,
54 : const gsl::not_null<
55 : typename ValenciaPackageFieldTags::type*>... valencia_packaged_fields,
56 :
57 : const typename GhEvolvedTags::type&... gh_variables,
58 : const typename ValenciaEvolvedTags::type&... valencia_variables,
59 :
60 : const typename GhFluxTags::type&... gh_fluxes,
61 : const typename ValenciaFluxTags::type&... valencia_fluxes,
62 :
63 : const typename DeduplicatedTempTags::type&... temporaries,
64 :
65 : const typename GhPrimTags::type&... gh_primitives,
66 : const typename ValenciaPrimTags::type&... valencia_primitives,
67 :
68 : const tnsr::i<DataVector, 3, Frame::Inertial>& normal_covector,
69 : const tnsr::I<DataVector, 3, Frame::Inertial>& normal_vector,
70 : const std::optional<tnsr::I<DataVector, 3, Frame::Inertial>>&
71 : mesh_velocity,
72 : const std::optional<Scalar<DataVector>>& normal_dot_mesh_velocity,
73 :
74 : const typename GhVolumeTags::type&... gh_volume_quantities,
75 : decltype(StdHelpers::retrieve(
76 : std::declval<typename ValenciaVolumeTags::
77 : type>()))... valencia_volume_quantities,
78 :
79 : const DerivedGhCorrection& gh_correction,
80 : const DerivedValenciaCorrection& valencia_correction) {
81 : tuples::TaggedTuple<
82 : Tags::detail::TemporaryReference<DeduplicatedTempTags>...>
83 : shuffle_refs{temporaries...};
84 : return std::max(
85 : gh_correction.dg_package_data(
86 : gh_packaged_fields..., gh_variables..., gh_fluxes...,
87 : tuples::get<Tags::detail::TemporaryReference<GhTempTags>>(
88 : shuffle_refs)...,
89 : gh_primitives..., normal_covector, normal_vector, mesh_velocity,
90 : normal_dot_mesh_velocity, gh_volume_quantities...),
91 : valencia_correction.dg_package_data(
92 : valencia_packaged_fields..., valencia_variables...,
93 : valencia_fluxes...,
94 : tuples::get<Tags::detail::TemporaryReference<ValenciaTempTags>>(
95 : shuffle_refs)...,
96 : valencia_primitives..., normal_covector, normal_vector,
97 : mesh_velocity, normal_dot_mesh_velocity,
98 : StdHelpers::retrieve(valencia_volume_quantities)...));
99 : }
100 :
101 : static void dg_boundary_terms(
102 : const gsl::not_null<
103 : typename GhEvolvedTags::type*>... gh_boundary_corrections,
104 : const gsl::not_null<
105 : typename ValenciaEvolvedTags::type*>... valencia_boundary_corrections,
106 :
107 : const typename GhPackageFieldTags::type&... gh_internal_packaged_fields,
108 : const typename ValenciaPackageFieldTags::
109 : type&... valencia_internal_packaged_fields,
110 :
111 : const typename GhPackageFieldTags::type&... gh_external_packaged_fields,
112 : const typename ValenciaPackageFieldTags::
113 : type&... valencia_external_packaged_fields,
114 : const dg::Formulation dg_formulation,
115 :
116 : const DerivedGhCorrection& gh_correction,
117 : const DerivedValenciaCorrection& valencia_correction) {
118 : gh_correction.dg_boundary_terms(
119 : gh_boundary_corrections..., gh_internal_packaged_fields...,
120 : gh_external_packaged_fields..., dg_formulation);
121 : valencia_correction.dg_boundary_terms(
122 : valencia_boundary_corrections..., valencia_internal_packaged_fields...,
123 : valencia_external_packaged_fields..., dg_formulation);
124 : }
125 : };
126 : } // namespace detail
127 :
128 : /*!
129 : * \brief Apply a boundary condition to the combined Generalized Harmonic (GH)
130 : * and Valencia GRMHD system using boundary corrections defined separately for
131 : * the GH and Valencia systems.
132 : *
133 : * \details The implementation of this boundary correction applies the
134 : * `DerivedGhCorrection` followed by the `DerivedValenciaCorrection`. It is
135 : * anticipated that the systems are sufficiently independent that the order of
136 : * application is inconsequential.
137 : */
138 : template <typename DerivedGhCorrection, typename DerivedValenciaCorrection>
139 1 : class ProductOfCorrections final : public evolution::BoundaryCorrection {
140 : public:
141 0 : using dg_package_field_tags =
142 : tmpl::append<typename DerivedGhCorrection::dg_package_field_tags,
143 : typename DerivedValenciaCorrection::dg_package_field_tags>;
144 :
145 0 : using dg_package_data_temporary_tags = tmpl::remove_duplicates<tmpl::append<
146 : typename DerivedGhCorrection::dg_package_data_temporary_tags,
147 : typename DerivedValenciaCorrection::dg_package_data_temporary_tags>>;
148 :
149 0 : using dg_package_data_primitive_tags =
150 : typename DerivedValenciaCorrection::dg_package_data_primitive_tags;
151 :
152 0 : using dg_package_data_volume_tags = tmpl::append<
153 : typename DerivedGhCorrection::dg_package_data_volume_tags,
154 : typename DerivedValenciaCorrection::dg_package_data_volume_tags>;
155 :
156 0 : using dg_boundary_terms_volume_tags = tmpl::append<
157 : typename DerivedGhCorrection::dg_boundary_terms_volume_tags,
158 : typename DerivedValenciaCorrection::dg_boundary_terms_volume_tags>;
159 :
160 0 : using derived_product_correction_impl = detail::ProductOfCorrectionsImpl<
161 : DerivedGhCorrection, DerivedValenciaCorrection,
162 : typename DerivedGhCorrection::dg_package_field_tags,
163 : typename DerivedValenciaCorrection::dg_package_field_tags,
164 : typename gh::System<3_st>::variables_tag::tags_list,
165 : typename grmhd::ValenciaDivClean::System::variables_tag::tags_list,
166 : db::wrap_tags_in<::Tags::Flux, typename gh::System<3_st>::flux_variables,
167 : tmpl::size_t<3_st>, Frame::Inertial>,
168 : db::wrap_tags_in<::Tags::Flux,
169 : typename grmhd::ValenciaDivClean::System::flux_variables,
170 : tmpl::size_t<3_st>, Frame::Inertial>,
171 : typename DerivedGhCorrection::dg_package_data_temporary_tags,
172 : typename DerivedValenciaCorrection::dg_package_data_temporary_tags,
173 : dg_package_data_temporary_tags, tmpl::list<>,
174 : typename DerivedValenciaCorrection::dg_package_data_primitive_tags,
175 : typename DerivedGhCorrection::dg_package_data_volume_tags,
176 : typename DerivedValenciaCorrection::dg_package_data_volume_tags>;
177 :
178 0 : static std::string name() {
179 : return "Product" + pretty_type::name<DerivedGhCorrection>() + "And" +
180 : pretty_type::name<DerivedValenciaCorrection>();
181 : }
182 :
183 0 : struct GhCorrection {
184 0 : using type = DerivedGhCorrection;
185 0 : static std::string name() {
186 : return pretty_type::name<DerivedGhCorrection>();
187 : }
188 0 : static constexpr Options::String help{
189 : "The Generalized Harmonic part of the product boundary condition"};
190 : };
191 0 : struct ValenciaCorrection {
192 0 : using type = DerivedValenciaCorrection;
193 0 : static std::string name() {
194 : return pretty_type::name<DerivedValenciaCorrection>();
195 : }
196 0 : static constexpr Options::String help{
197 : "The Valencia part of the product boundary condition"};
198 : };
199 :
200 0 : using options = tmpl::list<GhCorrection, ValenciaCorrection>;
201 :
202 0 : static constexpr Options::String help = {
203 : "Direct product of a GH and ValenciaDivClean GRMHD boundary correction. "
204 : "See the documentation for the two individual boundary corrections for "
205 : "further details."};
206 :
207 0 : ProductOfCorrections() = default;
208 0 : ProductOfCorrections(DerivedGhCorrection gh_correction,
209 : DerivedValenciaCorrection valencia_correction)
210 : : derived_gh_correction_{gh_correction},
211 : derived_valencia_correction_{valencia_correction} {}
212 0 : ProductOfCorrections(const ProductOfCorrections&) = default;
213 0 : ProductOfCorrections& operator=(const ProductOfCorrections&) = default;
214 0 : ProductOfCorrections(ProductOfCorrections&&) = default;
215 0 : ProductOfCorrections& operator=(ProductOfCorrections&&) = default;
216 0 : ~ProductOfCorrections() override = default;
217 :
218 : /// \cond
219 : explicit ProductOfCorrections(CkMigrateMessage* msg)
220 : : BoundaryCorrection(msg) {}
221 : using PUP::able::register_constructor;
222 : WRAPPED_PUPable_decl_template(ProductOfCorrections); // NOLINT
223 : /// \endcond
224 0 : void pup(PUP::er& p) override {
225 : BoundaryCorrection::pup(p);
226 : p | derived_gh_correction_;
227 : p | derived_valencia_correction_;
228 : }
229 :
230 0 : std::unique_ptr<BoundaryCorrection> get_clone() const override {
231 : return std::make_unique<ProductOfCorrections>(*this);
232 : }
233 :
234 : template <typename... Args>
235 0 : double dg_package_data(Args&&... args) const {
236 : return derived_product_correction_impl::dg_package_data(
237 : std::forward<Args>(args)..., derived_gh_correction_,
238 : derived_valencia_correction_);
239 : }
240 :
241 : template <typename... Args>
242 0 : void dg_boundary_terms(Args&&... args) const {
243 : derived_product_correction_impl::dg_boundary_terms(
244 : std::forward<Args>(args)..., derived_gh_correction_,
245 : derived_valencia_correction_);
246 : }
247 :
248 0 : const DerivedGhCorrection& gh_correction() const {
249 : return derived_gh_correction_;
250 : }
251 :
252 0 : const DerivedValenciaCorrection& valencia_correction() const {
253 : return derived_valencia_correction_;
254 : }
255 :
256 : private:
257 0 : DerivedGhCorrection derived_gh_correction_;
258 0 : DerivedValenciaCorrection derived_valencia_correction_;
259 : };
260 :
261 : /// \cond
262 : template <typename DerivedGhCorrection, typename DerivedValenciaCorrection>
263 : PUP::able::PUP_ID ProductOfCorrections<DerivedGhCorrection,
264 : DerivedValenciaCorrection>::my_PUP_ID =
265 : 0; // NOLINT
266 : /// \endcond
267 : } // namespace grmhd::GhValenciaDivClean::BoundaryCorrections
|