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/DataVector.hpp"
13 : #include "DataStructures/Tensor/Tensor.hpp"
14 : #include "DataStructures/Variables.hpp"
15 : #include "Domain/CoordinateMaps/Tags.hpp"
16 : #include "Domain/ElementMap.hpp"
17 : #include "Domain/Structure/Direction.hpp"
18 : #include "Domain/Tags.hpp"
19 : #include "Evolution/BoundaryConditions/Type.hpp"
20 : #include "Evolution/Systems/GeneralizedHarmonic/BoundaryConditions/Bjorhus.hpp"
21 : #include "Evolution/Systems/GeneralizedHarmonic/ConstraintDamping/Tags.hpp"
22 : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
23 : #include "Evolution/Systems/GrMhd/GhValenciaDivClean/BoundaryConditions/BoundaryCondition.hpp"
24 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/BoundaryConditions/HydroFreeOutflow.hpp"
25 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/Tags.hpp"
26 : #include "Options/String.hpp"
27 : #include "PointwiseFunctions/Hydro/Tags.hpp"
28 : #include "Utilities/Gsl.hpp"
29 : #include "Utilities/Serialization/CharmPupable.hpp"
30 : #include "Utilities/TMPL.hpp"
31 :
32 : namespace grmhd::GhValenciaDivClean::BoundaryConditions {
33 : /*!
34 : * \brief Sets constraint-preserving boundary conditions on the spacetime
35 : * variables and hydro free outflow on the GRMHD variables.
36 : *
37 : * \warning This is only implemented for DG, on FD you get an error. The
38 : * reason is that some care and experimentation is necessary to impose the
39 : * boundary condition correctly on FD.
40 : */
41 1 : class ConstraintPreservingFreeOutflow final : public BoundaryCondition {
42 : public:
43 0 : using options =
44 : typename gh::BoundaryConditions::ConstraintPreservingBjorhus<3>::options;
45 0 : static constexpr Options::String help{
46 : "ConstraintPreservingAnalytic boundary conditions for GH variables and "
47 : "hydro free outflow for GRMHD."};
48 :
49 0 : ConstraintPreservingFreeOutflow() = default;
50 0 : explicit ConstraintPreservingFreeOutflow(
51 : gh::BoundaryConditions::detail::ConstraintPreservingBjorhusType type);
52 :
53 0 : ConstraintPreservingFreeOutflow(ConstraintPreservingFreeOutflow&&) = default;
54 0 : ConstraintPreservingFreeOutflow& operator=(
55 : ConstraintPreservingFreeOutflow&&) = default;
56 0 : ConstraintPreservingFreeOutflow(const ConstraintPreservingFreeOutflow&) =
57 : default;
58 0 : ConstraintPreservingFreeOutflow& operator=(
59 : const ConstraintPreservingFreeOutflow&) = default;
60 0 : ~ConstraintPreservingFreeOutflow() override = default;
61 :
62 0 : explicit ConstraintPreservingFreeOutflow(CkMigrateMessage* msg);
63 :
64 0 : WRAPPED_PUPable_decl_base_template(
65 : domain::BoundaryConditions::BoundaryCondition,
66 : ConstraintPreservingFreeOutflow);
67 :
68 0 : auto get_clone() const -> std::unique_ptr<
69 : domain::BoundaryConditions::BoundaryCondition> override;
70 :
71 0 : static constexpr evolution::BoundaryConditions::Type bc_type =
72 : evolution::BoundaryConditions::Type::GhostAndTimeDerivative;
73 :
74 0 : void pup(PUP::er& p) override;
75 :
76 0 : using dg_interior_evolved_variables_tags =
77 : tmpl::list<gr::Tags::SpacetimeMetric<DataVector, 3>,
78 : gh::Tags::Pi<DataVector, 3>, gh::Tags::Phi<DataVector, 3>>;
79 0 : using dg_interior_temporary_tags =
80 : tmpl::list<domain::Tags::Coordinates<3, Frame::Inertial>,
81 : ::gh::ConstraintDamping::Tags::ConstraintGamma1,
82 : ::gh::ConstraintDamping::Tags::ConstraintGamma2,
83 : gr::Tags::Lapse<DataVector>, gr::Tags::Shift<DataVector, 3>,
84 : gr::Tags::InverseSpatialMetric<DataVector, 3>,
85 : gr::Tags::InverseSpacetimeMetric<DataVector, 3>,
86 : gr::Tags::SpacetimeNormalVector<DataVector, 3>,
87 : gh::Tags::ThreeIndexConstraint<DataVector, 3>,
88 : gh::Tags::GaugeH<DataVector, 3>,
89 : gh::Tags::SpacetimeDerivGaugeH<DataVector, 3>>;
90 0 : using dg_interior_primitive_variables_tags =
91 : tmpl::list<hydro::Tags::RestMassDensity<DataVector>,
92 : hydro::Tags::ElectronFraction<DataVector>,
93 : hydro::Tags::SpecificInternalEnergy<DataVector>,
94 : hydro::Tags::SpatialVelocity<DataVector, 3>,
95 : hydro::Tags::MagneticField<DataVector, 3>,
96 : hydro::Tags::LorentzFactor<DataVector>,
97 : hydro::Tags::Pressure<DataVector>>;
98 0 : using dg_gridless_tags = tmpl::list<>;
99 :
100 0 : static std::optional<std::string> dg_ghost(
101 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> spacetime_metric,
102 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> pi,
103 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> phi,
104 : gsl::not_null<Scalar<DataVector>*> tilde_d,
105 : gsl::not_null<Scalar<DataVector>*> tilde_ye,
106 : gsl::not_null<Scalar<DataVector>*> tilde_tau,
107 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> tilde_s,
108 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_b,
109 : gsl::not_null<Scalar<DataVector>*> tilde_phi,
110 :
111 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_d_flux,
112 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_ye_flux,
113 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_tau_flux,
114 : gsl::not_null<tnsr::Ij<DataVector, 3, Frame::Inertial>*> tilde_s_flux,
115 : gsl::not_null<tnsr::IJ<DataVector, 3, Frame::Inertial>*> tilde_b_flux,
116 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_phi_flux,
117 :
118 : gsl::not_null<Scalar<DataVector>*> gamma1,
119 : gsl::not_null<Scalar<DataVector>*> gamma2,
120 : gsl::not_null<Scalar<DataVector>*> lapse,
121 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> shift,
122 : gsl::not_null<tnsr::II<DataVector, 3, Frame::Inertial>*>
123 : inv_spatial_metric,
124 :
125 : const std::optional<tnsr::I<DataVector, 3, Frame::Inertial>>&
126 : face_mesh_velocity,
127 : const tnsr::i<DataVector, 3, Frame::Inertial>& normal_covector,
128 : const tnsr::I<DataVector, 3, Frame::Inertial>& normal_vector,
129 :
130 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_spacetime_metric,
131 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_pi,
132 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& interior_phi,
133 :
134 : const Scalar<DataVector>& interior_rest_mass_density,
135 : const Scalar<DataVector>& interior_electron_fraction,
136 : const Scalar<DataVector>& interior_specific_internal_energy,
137 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_spatial_velocity,
138 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_magnetic_field,
139 : const Scalar<DataVector>& interior_lorentz_factor,
140 : const Scalar<DataVector>& interior_pressure,
141 :
142 : const tnsr::I<DataVector, 3, Frame::Inertial>& /*coords*/,
143 : const Scalar<DataVector>& interior_gamma1,
144 : const Scalar<DataVector>& interior_gamma2,
145 : const Scalar<DataVector>& interior_lapse,
146 : const tnsr::I<DataVector, 3>& interior_shift,
147 : const tnsr::II<DataVector, 3>& interior_inv_spatial_metric,
148 : const tnsr::AA<DataVector, 3,
149 : Frame::Inertial>& /*inverse_spacetime_metric*/,
150 : const tnsr::A<DataVector, 3, Frame::Inertial>&
151 : /*spacetime_unit_normal_vector*/,
152 : const tnsr::iaa<DataVector, 3,
153 : Frame::Inertial>& /*three_index_constraint*/,
154 : const tnsr::a<DataVector, 3, Frame::Inertial>& /*gauge_source*/,
155 : const tnsr::ab<DataVector, 3, Frame::Inertial>&
156 : /*spacetime_deriv_gauge_source*/,
157 :
158 : // c.f. dg_interior_dt_vars_tags
159 : const tnsr::aa<DataVector, 3, Frame::Inertial>&
160 : /*logical_dt_spacetime_metric*/,
161 : const tnsr::aa<DataVector, 3, Frame::Inertial>& /*logical_dt_pi*/,
162 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& /*logical_dt_phi*/,
163 : // c.f. dg_interior_deriv_vars_tags
164 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& /*d_spacetime_metric*/,
165 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& /*d_pi*/,
166 : const tnsr::ijaa<DataVector, 3, Frame::Inertial>& /*d_phi*/);
167 :
168 0 : using dg_interior_dt_vars_tags =
169 : tmpl::list<::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>,
170 : ::Tags::dt<gh::Tags::Pi<DataVector, 3>>,
171 : ::Tags::dt<gh::Tags::Phi<DataVector, 3>>>;
172 0 : using dg_interior_deriv_vars_tags =
173 : tmpl::list<::Tags::deriv<gr::Tags::SpacetimeMetric<DataVector, 3>,
174 : tmpl::size_t<3>, Frame::Inertial>,
175 : ::Tags::deriv<gh::Tags::Pi<DataVector, 3>, tmpl::size_t<3>,
176 : Frame::Inertial>,
177 : ::Tags::deriv<gh::Tags::Phi<DataVector, 3>, tmpl::size_t<3>,
178 : Frame::Inertial>>;
179 :
180 0 : std::optional<std::string> dg_time_derivative(
181 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*>
182 : dt_spacetime_metric_correction,
183 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> dt_pi_correction,
184 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*>
185 : dt_phi_correction,
186 : gsl::not_null<Scalar<DataVector>*> dt_tilde_d,
187 : gsl::not_null<Scalar<DataVector>*> dt_tilde_ye,
188 : gsl::not_null<Scalar<DataVector>*> dt_tilde_tau,
189 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> dt_tilde_s,
190 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> dt_tilde_b,
191 : gsl::not_null<Scalar<DataVector>*> dt_tilde_phi,
192 :
193 : const std::optional<tnsr::I<DataVector, 3, Frame::Inertial>>&
194 : face_mesh_velocity,
195 : const tnsr::i<DataVector, 3, Frame::Inertial>& normal_covector,
196 : const tnsr::I<DataVector, 3, Frame::Inertial>& normal_vector,
197 : // c.f. dg_interior_evolved_variables_tags
198 : const tnsr::aa<DataVector, 3, Frame::Inertial>& spacetime_metric,
199 : const tnsr::aa<DataVector, 3, Frame::Inertial>& pi,
200 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& phi,
201 : // c.f. dg_interior_primitive_variables_tags
202 : const Scalar<DataVector>& /*interior_rest_mass_density*/,
203 : const Scalar<DataVector>& /*interior_electron_fraction*/,
204 : const Scalar<DataVector>& /*interior_specific_internal_energy*/,
205 : const tnsr::I<DataVector, 3,
206 : Frame::Inertial>& /*interior_spatial_velocity*/,
207 : const tnsr::I<DataVector, 3,
208 : Frame::Inertial>& /*interior_magnetic_field*/,
209 : const Scalar<DataVector>& /*interior_lorentz_factor*/,
210 : const Scalar<DataVector>& /*interior_pressure*/,
211 :
212 : // c.f. dg_interior_temporary_tags
213 : const tnsr::I<DataVector, 3, Frame::Inertial>& coords,
214 : const Scalar<DataVector>& gamma1, const Scalar<DataVector>& gamma2,
215 : const Scalar<DataVector>& lapse,
216 : const tnsr::I<DataVector, 3, Frame::Inertial>& shift,
217 : const tnsr::II<DataVector, 3>& /*interior_inv_spatial_metric*/,
218 : const tnsr::AA<DataVector, 3, Frame::Inertial>& inverse_spacetime_metric,
219 : const tnsr::A<DataVector, 3, Frame::Inertial>&
220 : spacetime_unit_normal_vector,
221 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& three_index_constraint,
222 : const tnsr::a<DataVector, 3, Frame::Inertial>& gauge_source,
223 : const tnsr::ab<DataVector, 3, Frame::Inertial>&
224 : spacetime_deriv_gauge_source,
225 : // c.f. dg_interior_dt_vars_tags
226 : const tnsr::aa<DataVector, 3, Frame::Inertial>&
227 : logical_dt_spacetime_metric,
228 : const tnsr::aa<DataVector, 3, Frame::Inertial>& logical_dt_pi,
229 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& logical_dt_phi,
230 : // c.f. dg_interior_deriv_vars_tags
231 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& d_spacetime_metric,
232 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& d_pi,
233 : const tnsr::ijaa<DataVector, 3, Frame::Inertial>& d_phi) const;
234 :
235 0 : using fd_interior_evolved_variables_tags = tmpl::list<>;
236 0 : using fd_interior_temporary_tags = tmpl::list<>;
237 0 : using fd_interior_primitive_variables_tags = tmpl::list<>;
238 0 : using fd_gridless_tags = tmpl::list<>;
239 :
240 0 : [[noreturn]] static void fd_ghost(
241 : const gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*>
242 : /*spacetime_metric*/,
243 : const gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> /*pi*/,
244 : const gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> /*phi*/,
245 : const gsl::not_null<Scalar<DataVector>*> /*rest_mass_density*/,
246 : const gsl::not_null<Scalar<DataVector>*> /*electron_fraction*/,
247 : const gsl::not_null<Scalar<DataVector>*> /*pressure*/,
248 : const gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
249 : /*lorentz_factor_times_spatial_velocity*/,
250 : const gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
251 : /*magnetic_field*/,
252 : const gsl::not_null<Scalar<DataVector>*> /*divergence_cleaning_field*/,
253 : const Direction<3>& /*direction*/) {
254 : ERROR(
255 : "Not implemented because it's not trivial to figure out what the right "
256 : "way of handling this case is.");
257 : }
258 :
259 : private:
260 : gh::BoundaryConditions::ConstraintPreservingBjorhus<3>
261 0 : constraint_preserving_{};
262 : };
263 : } // namespace grmhd::GhValenciaDivClean::BoundaryConditions
|