Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <memory>
7 : #include <optional>
8 : #include <pup.h>
9 : #include <string>
10 :
11 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
12 : #include "DataStructures/DataBox/Prefixes.hpp"
13 : #include "DataStructures/Tensor/TypeAliases.hpp"
14 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
15 : #include "Domain/BoundaryConditions/Cartoon.hpp"
16 : #include "Evolution/BoundaryConditions/Type.hpp"
17 : #include "Evolution/DgSubcell/Tags/Mesh.hpp"
18 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/BoundaryConditions/BoundaryCondition.hpp"
19 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/FiniteDifference/Tag.hpp"
20 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/System.hpp"
21 : #include "Options/String.hpp"
22 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
23 : #include "PointwiseFunctions/Hydro/Tags.hpp"
24 : #include "Utilities/Serialization/CharmPupable.hpp"
25 : #include "Utilities/TMPL.hpp"
26 :
27 : /// \cond
28 : class DataVector;
29 : template <size_t VolumeDim>
30 : class Direction;
31 : namespace gsl {
32 : template <typename T>
33 : class not_null;
34 : } // namespace gsl
35 : /// \endcond
36 :
37 : namespace grmhd::ValenciaDivClean::BoundaryConditions {
38 : /*!
39 : * \brief Apply parity-respecting FD ghost values for internal boundaries in a
40 : * Cartoon evolution.
41 : *
42 : * Domains using the cartoon method have boundaries at $x = 0$, which require
43 : * ghost data for FD evolution. We fill this FD ghost data by reflecting the
44 : * data appropriately: due to the symmetry of cartoon simulations, we can
45 : * determine the parity of each component of an arbitrary tensor, allowing us
46 : * to either reflect the data or reflect and negate the data.
47 : *
48 : * This only has `fd_ghost()` implemented because this boundary uses ZernikeB1
49 : * bases in DG elements which do not require a boundary condition.
50 : */
51 1 : class CartoonGhost final : public BoundaryCondition,
52 : public domain::BoundaryConditions::MarkAsCartoon {
53 : private:
54 0 : using RestMassDensity = hydro::Tags::RestMassDensity<DataVector>;
55 0 : using ElectronFraction = hydro::Tags::ElectronFraction<DataVector>;
56 0 : using Temperature = hydro::Tags::Temperature<DataVector>;
57 0 : using Pressure = hydro::Tags::Pressure<DataVector>;
58 0 : using LorentzFactorTimesSpatialVelocity =
59 : hydro::Tags::LorentzFactorTimesSpatialVelocity<DataVector, 3>;
60 0 : using MagneticField = hydro::Tags::MagneticField<DataVector, 3>;
61 0 : using DivergenceCleaningField =
62 : hydro::Tags::DivergenceCleaningField<DataVector>;
63 0 : using SpecificInternalEnergy =
64 : hydro::Tags::SpecificInternalEnergy<DataVector>;
65 0 : using SpatialVelocity = hydro::Tags::SpatialVelocity<DataVector, 3>;
66 0 : using LorentzFactor = hydro::Tags::LorentzFactor<DataVector>;
67 0 : using SqrtDetSpatialMetric = gr::Tags::SqrtDetSpatialMetric<DataVector>;
68 0 : using SpatialMetric = gr::Tags::SpatialMetric<DataVector, 3>;
69 0 : using InvSpatialMetric = gr::Tags::InverseSpatialMetric<DataVector, 3>;
70 0 : using Lapse = gr::Tags::Lapse<DataVector>;
71 0 : using Shift = gr::Tags::Shift<DataVector, 3>;
72 :
73 : template <typename T>
74 0 : using Flux = ::Tags::Flux<T, tmpl::size_t<3>, Frame::Inertial>;
75 :
76 : public:
77 0 : static constexpr bool factory_creatable = false;
78 :
79 0 : CartoonGhost() = default;
80 0 : CartoonGhost(CartoonGhost&&) = default;
81 0 : CartoonGhost& operator=(CartoonGhost&&) = default;
82 0 : CartoonGhost(const CartoonGhost&) = default;
83 0 : CartoonGhost& operator=(const CartoonGhost&) = default;
84 0 : ~CartoonGhost() override = default;
85 :
86 0 : explicit CartoonGhost(CkMigrateMessage* msg);
87 :
88 0 : WRAPPED_PUPable_decl_base_template(
89 : domain::BoundaryConditions::BoundaryCondition, CartoonGhost);
90 :
91 0 : auto get_clone() const -> std::unique_ptr<
92 : domain::BoundaryConditions::BoundaryCondition> override;
93 :
94 0 : static constexpr evolution::BoundaryConditions::Type bc_type =
95 : evolution::BoundaryConditions::Type::Ghost;
96 :
97 0 : void pup(PUP::er& p) override;
98 :
99 0 : using dg_interior_evolved_variables_tags = tmpl::list<>;
100 0 : using dg_interior_primitive_variables_tags = tmpl::list<>;
101 0 : using dg_interior_temporary_tags = tmpl::list<>;
102 0 : using dg_gridless_tags = tmpl::list<>;
103 :
104 0 : [[noreturn]] static std::optional<std::string> dg_ghost(
105 : gsl::not_null<Scalar<DataVector>*> /*tilde_d*/,
106 : gsl::not_null<Scalar<DataVector>*> /*tilde_ye*/,
107 : gsl::not_null<Scalar<DataVector>*> /*tilde_tau*/,
108 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> /*tilde_s*/,
109 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> /*tilde_b*/,
110 : gsl::not_null<Scalar<DataVector>*> /*tilde_phi*/,
111 :
112 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> /*tilde_d_flux*/,
113 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> /*tilde_ye_flux*/,
114 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
115 : /*tilde_tau_flux*/,
116 : gsl::not_null<tnsr::Ij<DataVector, 3, Frame::Inertial>*> /*tilde_s_flux*/,
117 : gsl::not_null<tnsr::IJ<DataVector, 3, Frame::Inertial>*> /*tilde_b_flux*/,
118 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
119 : /*tilde_phi_flux*/,
120 :
121 : gsl::not_null<Scalar<DataVector>*> /*lapse*/,
122 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> /*shift*/,
123 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*>
124 : /*spatial_velocity_one_form*/,
125 : gsl::not_null<Scalar<DataVector>*> /*rest_mass_density*/,
126 : gsl::not_null<Scalar<DataVector>*> /*electron_fraction*/,
127 : gsl::not_null<Scalar<DataVector>*> /*temperature*/,
128 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
129 : /*spatial_velocity*/,
130 :
131 : gsl::not_null<tnsr::II<DataVector, 3, Frame::Inertial>*>
132 : /*inv_spatial_metric*/,
133 :
134 : const std::optional<
135 : tnsr::I<DataVector, 3, Frame::Inertial>>& /*face_mesh_velocity*/,
136 : const tnsr::i<DataVector, 3, Frame::Inertial>& /*normal_covector*/,
137 : const tnsr::I<DataVector, 3, Frame::Inertial>& /*normal_vector*/) {
138 : ERROR(
139 : "dg_ghost() should never be called: the boundary it would apply to "
140 : "uses ZernikeB1 bases in DG evolution which do not need a boundary "
141 : "condition. When applying DG boundary conditions this class should be "
142 : "skipped as it is marked as Cartoon");
143 : }
144 :
145 0 : using fd_interior_evolved_variables_tags = tmpl::list<>;
146 0 : using fd_interior_temporary_tags =
147 : tmpl::list<evolution::dg::subcell::Tags::Mesh<3>, Shift, Lapse,
148 : SpatialMetric>;
149 0 : using fd_interior_primitive_variables_tags =
150 : tmpl::list<RestMassDensity, ElectronFraction, Temperature,
151 : hydro::Tags::Pressure<DataVector>,
152 : hydro::Tags::SpecificInternalEnergy<DataVector>,
153 : hydro::Tags::LorentzFactor<DataVector>,
154 : hydro::Tags::DivergenceCleaningField<DataVector>,
155 : hydro::Tags::SpatialVelocity<DataVector, 3>, MagneticField>;
156 0 : using fd_gridless_tags = tmpl::list<fd::Tags::Reconstructor>;
157 :
158 0 : static void fd_ghost(
159 : gsl::not_null<Scalar<DataVector>*> rest_mass_density,
160 : gsl::not_null<Scalar<DataVector>*> electron_fraction,
161 : gsl::not_null<Scalar<DataVector>*> temperature,
162 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
163 : lorentz_factor_times_spatial_velocity,
164 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> magnetic_field,
165 : gsl::not_null<Scalar<DataVector>*> divergence_cleaning_field,
166 :
167 : gsl::not_null<std::optional<Variables<db::wrap_tags_in<
168 : Flux, typename grmhd::ValenciaDivClean::System::flux_variables>>>*>
169 : cell_centered_ghost_fluxes,
170 :
171 : const Direction<3>& direction,
172 :
173 : // interior temporary tags
174 : const Mesh<3>& subcell_mesh,
175 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_shift,
176 : const Scalar<DataVector>& interior_lapse,
177 : const tnsr::ii<DataVector, 3, Frame::Inertial>& interior_spatial_metric,
178 :
179 : // interior prim vars tags
180 : const Scalar<DataVector>& interior_rest_mass_density,
181 : const Scalar<DataVector>& interior_electron_fraction,
182 : const Scalar<DataVector>& interior_temperature,
183 : const Scalar<DataVector>& interior_pressure,
184 : const Scalar<DataVector>& interior_specific_internal_energy,
185 : const Scalar<DataVector>& interior_lorentz_factor,
186 : const Scalar<DataVector>& interior_divergence_cleaning_field,
187 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_spatial_velocity,
188 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_magnetic_field,
189 :
190 : // fd_gridless_tags
191 : const fd::Reconstructor& reconstructor);
192 :
193 : // have an impl to make sharing code with GH+GRMHD easy
194 0 : static void fd_ghost_impl(
195 : gsl::not_null<Scalar<DataVector>*> rest_mass_density,
196 : gsl::not_null<Scalar<DataVector>*> electron_fraction,
197 : gsl::not_null<Scalar<DataVector>*> temperature,
198 : gsl::not_null<Scalar<DataVector>*> pressure,
199 : gsl::not_null<Scalar<DataVector>*> specific_internal_energy,
200 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
201 : lorentz_factor_times_spatial_velocity,
202 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> spatial_velocity,
203 : gsl::not_null<Scalar<DataVector>*> lorentz_factor,
204 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> magnetic_field,
205 : gsl::not_null<Scalar<DataVector>*> divergence_cleaning_field,
206 : gsl::not_null<tnsr::ii<DataVector, 3, Frame::Inertial>*> spatial_metric,
207 : gsl::not_null<tnsr::II<DataVector, 3, Frame::Inertial>*>
208 : inv_spatial_metric,
209 : gsl::not_null<Scalar<DataVector>*> sqrt_det_spatial_metric,
210 : gsl::not_null<Scalar<DataVector>*> lapse,
211 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> shift,
212 :
213 : const Direction<3>& direction,
214 :
215 : // fd_interior_temporary_tags
216 : const Mesh<3>& subcell_mesh,
217 :
218 : // fd_interior_primitive_variables_tags
219 : const Scalar<DataVector>& interior_rest_mass_density,
220 : const Scalar<DataVector>& interior_electron_fraction,
221 : const Scalar<DataVector>& interior_temperature,
222 : const Scalar<DataVector>& interior_pressure,
223 : const Scalar<DataVector>& interior_specific_internal_energy,
224 : const Scalar<DataVector>& interior_lorentz_factor,
225 : const Scalar<DataVector>& interior_divergence_cleaning_field,
226 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_spatial_velocity,
227 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_magnetic_field,
228 : const tnsr::ii<DataVector, 3, Frame::Inertial>& interior_spatial_metric,
229 : const Scalar<DataVector>& interior_lapse,
230 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_shift,
231 :
232 : size_t ghost_zone_size, bool need_tags_for_fluxes);
233 : };
234 : } // namespace grmhd::ValenciaDivClean::BoundaryConditions
|