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/Prefixes.hpp"
12 : #include "DataStructures/Tensor/TypeAliases.hpp"
13 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
14 : #include "Domain/BoundaryConditions/Cartoon.hpp"
15 : #include "Evolution/BoundaryConditions/Type.hpp"
16 : #include "Evolution/DgSubcell/Tags/Mesh.hpp"
17 : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
18 : #include "Evolution/Systems/GrMhd/GhValenciaDivClean/BoundaryConditions/BoundaryCondition.hpp"
19 : #include "Evolution/Systems/GrMhd/GhValenciaDivClean/FiniteDifference/Reconstructor.hpp"
20 : #include "Evolution/Systems/GrMhd/GhValenciaDivClean/FiniteDifference/Tag.hpp"
21 : #include "Options/String.hpp"
22 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
23 : #include "PointwiseFunctions/Hydro/Tags.hpp"
24 : #include "Utilities/TMPL.hpp"
25 :
26 : /// \cond
27 : class DataVector;
28 : template <size_t VolumeDim>
29 : class Direction;
30 : namespace gsl {
31 : template <typename T>
32 : class not_null;
33 : } // namespace gsl
34 : /// \endcond
35 :
36 : namespace grmhd::GhValenciaDivClean::BoundaryConditions {
37 : /*!
38 : * \brief Apply parity-respecting FD ghost values for internal boundaries in a
39 : * Cartoon evolution.
40 : *
41 : * Domains using the cartoon method have boundaries at $x = 0$, which require
42 : * ghost data for FD evolution. We fill this FD ghost data by reflecting the
43 : * data appropriately: due to the symmetry of cartoon simulations, we can
44 : * determine the parity of each component of an arbitrary tensor, allowing us
45 : * to either reflect the data or reflect and negate the data.
46 : *
47 : * This only has `fd_ghost()` implemented because this boundary uses ZernikeB1
48 : * bases in DG elements which do not require a boundary condition.
49 : *
50 : * Sets GH variables based on their parity, and calls the
51 : * `ValenciaDivClean::BoundaryConditions::CartoonGhost` implementation to set
52 : * the hydro variables.
53 : */
54 : template <typename System>
55 1 : class CartoonGhost final : public BoundaryCondition,
56 : public domain::BoundaryConditions::MarkAsCartoon {
57 : private:
58 0 : using SpacetimeMetric = gr::Tags::SpacetimeMetric<DataVector, 3>;
59 0 : using Pi = gh::Tags::Pi<DataVector, 3>;
60 0 : using Phi = gh::Tags::Phi<DataVector, 3>;
61 :
62 : public:
63 0 : static constexpr bool factory_creatable = false;
64 :
65 0 : CartoonGhost() = default;
66 0 : CartoonGhost(CartoonGhost&&) = default;
67 0 : CartoonGhost& operator=(CartoonGhost&&) = default;
68 0 : CartoonGhost(const CartoonGhost&) = default;
69 0 : CartoonGhost& operator=(const CartoonGhost&) = default;
70 0 : ~CartoonGhost() override = default;
71 :
72 0 : explicit CartoonGhost(CkMigrateMessage* msg);
73 :
74 0 : WRAPPED_PUPable_decl_base_template(
75 : domain::BoundaryConditions::BoundaryCondition, CartoonGhost);
76 :
77 0 : auto get_clone() const -> std::unique_ptr<
78 : domain::BoundaryConditions::BoundaryCondition> override;
79 :
80 0 : static constexpr evolution::BoundaryConditions::Type bc_type =
81 : evolution::BoundaryConditions::Type::Ghost;
82 :
83 0 : void pup(PUP::er& p) override;
84 :
85 0 : using dg_interior_evolved_variables_tags = tmpl::list<>;
86 0 : using dg_interior_primitive_variables_tags = tmpl::list<>;
87 0 : using dg_interior_temporary_tags = tmpl::list<>;
88 0 : using dg_gridless_tags = tmpl::list<>;
89 :
90 0 : [[noreturn]] static std::optional<std::string> dg_ghost(
91 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*>
92 : /*spacetime_metric*/,
93 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> /*pi*/,
94 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> /*phi*/,
95 : gsl::not_null<Scalar<DataVector>*> /*tilde_d*/,
96 : gsl::not_null<Scalar<DataVector>*> /*tilde_ye*/,
97 : gsl::not_null<Scalar<DataVector>*> /*tilde_tau*/,
98 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> /*tilde_s*/,
99 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> /*tilde_b*/,
100 : gsl::not_null<Scalar<DataVector>*> /*tilde_phi*/,
101 :
102 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
103 : /*tilde_d_flux*/,
104 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
105 : /*tilde_ye_flux*/,
106 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
107 : /*tilde_tau_flux*/,
108 : gsl::not_null<tnsr::Ij<DataVector, 3, Frame::Inertial>*>
109 : /*tilde_s_flux*/,
110 : gsl::not_null<tnsr::IJ<DataVector, 3, Frame::Inertial>*>
111 : /*tilde_b_flux*/,
112 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
113 : /*tilde_phi_flux*/,
114 :
115 : gsl::not_null<Scalar<DataVector>*> /*gamma1*/,
116 : gsl::not_null<Scalar<DataVector>*> /*gamma2*/,
117 : gsl::not_null<Scalar<DataVector>*> /*lapse*/,
118 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> /*shift*/,
119 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*>
120 : /*spatial_velocity_one_form*/,
121 : gsl::not_null<Scalar<DataVector>*> /*rest_mass_density*/,
122 : gsl::not_null<Scalar<DataVector>*> /*electron_fraction*/,
123 : gsl::not_null<Scalar<DataVector>*> /*temperature*/,
124 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
125 : /*spatial_velocity*/,
126 : gsl::not_null<tnsr::II<DataVector, 3, Frame::Inertial>*>
127 : /*inv_spatial_metric*/,
128 :
129 : const std::optional<
130 : tnsr::I<DataVector, 3, Frame::Inertial>>& /*face_mesh_velocity*/,
131 : const tnsr::i<DataVector, 3, Frame::Inertial>& /*normal_covector*/,
132 : const tnsr::I<DataVector, 3, Frame::Inertial>& /*normal_vector*/) {
133 : ERROR(
134 : "dg_ghost() should never be called: the boundary it would apply to "
135 : "uses ZernikeB1 bases in DG evolution which do not need a boundary "
136 : "condition. When applying DG boundary conditions this class should be "
137 : "skipped as it is marked as Cartoon");
138 : }
139 :
140 0 : using fd_interior_evolved_variables_tags =
141 : tmpl::list<gr::Tags::SpacetimeMetric<DataVector, 3>,
142 : gh::Tags::Pi<DataVector, 3>, gh::Tags::Phi<DataVector, 3>>;
143 0 : using fd_interior_temporary_tags =
144 : tmpl::list<evolution::dg::subcell::Tags::Mesh<3>>;
145 0 : using fd_interior_primitive_variables_tags =
146 : tmpl::list<hydro::Tags::RestMassDensity<DataVector>,
147 : hydro::Tags::ElectronFraction<DataVector>,
148 : hydro::Tags::Temperature<DataVector>,
149 : hydro::Tags::Pressure<DataVector>,
150 : hydro::Tags::SpecificInternalEnergy<DataVector>,
151 : hydro::Tags::LorentzFactor<DataVector>,
152 : hydro::Tags::DivergenceCleaningField<DataVector>,
153 : hydro::Tags::SpatialVelocity<DataVector, 3>,
154 : hydro::Tags::MagneticField<DataVector, 3>>;
155 0 : using fd_gridless_tags = tmpl::list<fd::Tags::Reconstructor<System>>;
156 :
157 0 : static void fd_ghost(
158 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> spacetime_metric,
159 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> pi,
160 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> phi,
161 : gsl::not_null<Scalar<DataVector>*> rest_mass_density,
162 : gsl::not_null<Scalar<DataVector>*> electron_fraction,
163 : gsl::not_null<Scalar<DataVector>*> temperature,
164 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
165 : lorentz_factor_times_spatial_velocity,
166 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> magnetic_field,
167 : gsl::not_null<Scalar<DataVector>*> divergence_cleaning_field,
168 : const Direction<3>& direction,
169 :
170 : // fd_interior_evolved_variables_tags
171 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_spacetime_metric,
172 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_pi,
173 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& interior_phi,
174 :
175 : // fd_interior_temporary_tags
176 : const Mesh<3>& subcell_mesh,
177 :
178 : // fd_interior_primitive_variables_tags
179 : const Scalar<DataVector>& interior_rest_mass_density,
180 : const Scalar<DataVector>& interior_electron_fraction,
181 : const Scalar<DataVector>& interior_temperature,
182 : const Scalar<DataVector>& interior_pressure,
183 : const Scalar<DataVector>& interior_specific_internal_energy,
184 : const Scalar<DataVector>& interior_lorentz_factor,
185 : const Scalar<DataVector>& interior_divergence_cleaning_field,
186 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_spatial_velocity,
187 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_magnetic_field,
188 :
189 : // fd_gridless_tags
190 : const fd::Reconstructor<System>& reconstructor);
191 :
192 : private:
193 0 : static void fd_ghost_gh_impl(
194 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> spacetime_metric,
195 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> pi,
196 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> phi,
197 : const Direction<3>& direction,
198 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_spacetime_metric,
199 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_pi,
200 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& interior_phi,
201 : const Mesh<3>& subcell_mesh, size_t ghost_zone_size);
202 : };
203 : } // namespace grmhd::GhValenciaDivClean::BoundaryConditions
|