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/Tags.hpp"
22 : #include "Evolution/Systems/GrMhd/GhValenciaDivClean/BoundaryConditions/BoundaryCondition.hpp"
23 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/BoundaryConditions/HydroFreeOutflow.hpp"
24 : #include "Evolution/Systems/GrMhd/ValenciaDivClean/Tags.hpp"
25 : #include "Options/String.hpp"
26 : #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/ConstraintDampingTags.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 : std::optional<std::unique_ptr<::MathFunction<1, Frame::Inertial>>>
53 : incoming_wave_profile = std::nullopt);
54 :
55 0 : ConstraintPreservingFreeOutflow(ConstraintPreservingFreeOutflow&&) = default;
56 0 : ConstraintPreservingFreeOutflow& operator=(
57 : ConstraintPreservingFreeOutflow&&) = default;
58 0 : ConstraintPreservingFreeOutflow(const ConstraintPreservingFreeOutflow&) =
59 : default;
60 0 : ConstraintPreservingFreeOutflow& operator=(
61 : const ConstraintPreservingFreeOutflow&) = default;
62 0 : ~ConstraintPreservingFreeOutflow() override = default;
63 :
64 0 : explicit ConstraintPreservingFreeOutflow(CkMigrateMessage* msg);
65 :
66 0 : WRAPPED_PUPable_decl_base_template(
67 : domain::BoundaryConditions::BoundaryCondition,
68 : ConstraintPreservingFreeOutflow);
69 :
70 0 : auto get_clone() const -> std::unique_ptr<
71 : domain::BoundaryConditions::BoundaryCondition> override;
72 :
73 0 : static constexpr evolution::BoundaryConditions::Type bc_type =
74 : evolution::BoundaryConditions::Type::GhostAndTimeDerivative;
75 :
76 0 : void pup(PUP::er& p) override;
77 :
78 0 : using dg_interior_evolved_variables_tags =
79 : tmpl::list<gr::Tags::SpacetimeMetric<DataVector, 3>,
80 : gh::Tags::Pi<DataVector, 3>, gh::Tags::Phi<DataVector, 3>>;
81 0 : using dg_interior_temporary_tags =
82 : tmpl::list<domain::Tags::Coordinates<3, Frame::Inertial>,
83 : ::gh::Tags::ConstraintGamma1, ::gh::Tags::ConstraintGamma2,
84 : gr::Tags::Lapse<DataVector>, gr::Tags::Shift<DataVector, 3>,
85 : gr::Tags::InverseSpatialMetric<DataVector, 3>,
86 : gr::Tags::InverseSpacetimeMetric<DataVector, 3>,
87 : gr::Tags::SpacetimeNormalVector<DataVector, 3>,
88 : gh::Tags::ThreeIndexConstraint<DataVector, 3>,
89 : gh::Tags::GaugeH<DataVector, 3>,
90 : gh::Tags::SpacetimeDerivGaugeH<DataVector, 3>>;
91 0 : using dg_interior_primitive_variables_tags =
92 : tmpl::list<hydro::Tags::RestMassDensity<DataVector>,
93 : hydro::Tags::ElectronFraction<DataVector>,
94 : hydro::Tags::SpecificInternalEnergy<DataVector>,
95 : hydro::Tags::SpatialVelocity<DataVector, 3>,
96 : hydro::Tags::MagneticField<DataVector, 3>,
97 : hydro::Tags::LorentzFactor<DataVector>,
98 : hydro::Tags::Pressure<DataVector>,
99 : hydro::Tags::Temperature<DataVector>>;
100 0 : using dg_gridless_tags = tmpl::list<>;
101 :
102 0 : static std::optional<std::string> dg_ghost(
103 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> spacetime_metric,
104 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> pi,
105 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> phi,
106 : gsl::not_null<Scalar<DataVector>*> tilde_d,
107 : gsl::not_null<Scalar<DataVector>*> tilde_ye,
108 : gsl::not_null<Scalar<DataVector>*> tilde_tau,
109 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> tilde_s,
110 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_b,
111 : gsl::not_null<Scalar<DataVector>*> tilde_phi,
112 :
113 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_d_flux,
114 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> tilde_ye_flux,
115 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> 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>*> tilde_phi_flux,
119 :
120 : gsl::not_null<Scalar<DataVector>*> gamma1,
121 : gsl::not_null<Scalar<DataVector>*> gamma2,
122 : gsl::not_null<Scalar<DataVector>*> lapse,
123 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> shift,
124 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*>
125 : spatial_velocity_one_form,
126 : gsl::not_null<Scalar<DataVector>*> rest_mass_density,
127 : gsl::not_null<Scalar<DataVector>*> electron_fraction,
128 : gsl::not_null<Scalar<DataVector>*> temperature,
129 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> spatial_velocity,
130 : gsl::not_null<tnsr::II<DataVector, 3, Frame::Inertial>*>
131 : inv_spatial_metric,
132 :
133 : const std::optional<tnsr::I<DataVector, 3, Frame::Inertial>>&
134 : face_mesh_velocity,
135 : const tnsr::i<DataVector, 3, Frame::Inertial>& normal_covector,
136 : const tnsr::I<DataVector, 3, Frame::Inertial>& normal_vector,
137 :
138 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_spacetime_metric,
139 : const tnsr::aa<DataVector, 3, Frame::Inertial>& interior_pi,
140 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& interior_phi,
141 :
142 : const Scalar<DataVector>& interior_rest_mass_density,
143 : const Scalar<DataVector>& interior_electron_fraction,
144 : const Scalar<DataVector>& interior_specific_internal_energy,
145 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_spatial_velocity,
146 : const tnsr::I<DataVector, 3, Frame::Inertial>& interior_magnetic_field,
147 : const Scalar<DataVector>& interior_lorentz_factor,
148 : const Scalar<DataVector>& interior_pressure,
149 : const Scalar<DataVector>& interior_temperature,
150 :
151 : const tnsr::I<DataVector, 3, Frame::Inertial>& /*coords*/,
152 : const Scalar<DataVector>& interior_gamma1,
153 : const Scalar<DataVector>& interior_gamma2,
154 : const Scalar<DataVector>& interior_lapse,
155 : const tnsr::I<DataVector, 3>& interior_shift,
156 : const tnsr::II<DataVector, 3>& interior_inv_spatial_metric,
157 : const tnsr::AA<DataVector, 3,
158 : Frame::Inertial>& /*inverse_spacetime_metric*/,
159 : const tnsr::A<DataVector, 3, Frame::Inertial>&
160 : /*spacetime_unit_normal_vector*/,
161 : const tnsr::iaa<DataVector, 3,
162 : Frame::Inertial>& /*three_index_constraint*/,
163 : const tnsr::a<DataVector, 3, Frame::Inertial>& /*gauge_source*/,
164 : const tnsr::ab<DataVector, 3, Frame::Inertial>&
165 : /*spacetime_deriv_gauge_source*/,
166 :
167 : // c.f. dg_interior_dt_vars_tags
168 : const tnsr::aa<DataVector, 3, Frame::Inertial>&
169 : /*logical_dt_spacetime_metric*/,
170 : const tnsr::aa<DataVector, 3, Frame::Inertial>& /*logical_dt_pi*/,
171 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& /*logical_dt_phi*/,
172 : // c.f. dg_interior_deriv_vars_tags
173 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& /*d_spacetime_metric*/,
174 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& /*d_pi*/,
175 : const tnsr::ijaa<DataVector, 3, Frame::Inertial>& /*d_phi*/);
176 :
177 0 : using dg_interior_dt_vars_tags =
178 : tmpl::list<::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>,
179 : ::Tags::dt<gh::Tags::Pi<DataVector, 3>>,
180 : ::Tags::dt<gh::Tags::Phi<DataVector, 3>>>;
181 0 : using dg_interior_deriv_vars_tags =
182 : tmpl::list<::Tags::deriv<gr::Tags::SpacetimeMetric<DataVector, 3>,
183 : tmpl::size_t<3>, Frame::Inertial>,
184 : ::Tags::deriv<gh::Tags::Pi<DataVector, 3>, tmpl::size_t<3>,
185 : Frame::Inertial>,
186 : ::Tags::deriv<gh::Tags::Phi<DataVector, 3>, tmpl::size_t<3>,
187 : Frame::Inertial>>;
188 :
189 0 : std::optional<std::string> dg_time_derivative(
190 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*>
191 : dt_spacetime_metric_correction,
192 : gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> dt_pi_correction,
193 : gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*>
194 : dt_phi_correction,
195 : gsl::not_null<Scalar<DataVector>*> dt_tilde_d,
196 : gsl::not_null<Scalar<DataVector>*> dt_tilde_ye,
197 : gsl::not_null<Scalar<DataVector>*> dt_tilde_tau,
198 : gsl::not_null<tnsr::i<DataVector, 3, Frame::Inertial>*> dt_tilde_s,
199 : gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*> dt_tilde_b,
200 : gsl::not_null<Scalar<DataVector>*> dt_tilde_phi,
201 :
202 : const std::optional<tnsr::I<DataVector, 3, Frame::Inertial>>&
203 : face_mesh_velocity,
204 : const tnsr::i<DataVector, 3, Frame::Inertial>& normal_covector,
205 : const tnsr::I<DataVector, 3, Frame::Inertial>& normal_vector,
206 : // c.f. dg_interior_evolved_variables_tags
207 : const tnsr::aa<DataVector, 3, Frame::Inertial>& spacetime_metric,
208 : const tnsr::aa<DataVector, 3, Frame::Inertial>& pi,
209 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& phi,
210 : // c.f. dg_interior_primitive_variables_tags
211 : const Scalar<DataVector>& /*interior_rest_mass_density*/,
212 : const Scalar<DataVector>& /*interior_electron_fraction*/,
213 : const Scalar<DataVector>& /*interior_specific_internal_energy*/,
214 : const tnsr::I<DataVector, 3,
215 : Frame::Inertial>& /*interior_spatial_velocity*/,
216 : const tnsr::I<DataVector, 3,
217 : Frame::Inertial>& /*interior_magnetic_field*/,
218 : const Scalar<DataVector>& /*interior_lorentz_factor*/,
219 : const Scalar<DataVector>& /*interior_pressure*/,
220 : const Scalar<DataVector>& /*interior_temperature*/,
221 :
222 : // c.f. dg_interior_temporary_tags
223 : const tnsr::I<DataVector, 3, Frame::Inertial>& coords,
224 : const Scalar<DataVector>& gamma1, const Scalar<DataVector>& gamma2,
225 : const Scalar<DataVector>& lapse,
226 : const tnsr::I<DataVector, 3, Frame::Inertial>& shift,
227 : const tnsr::II<DataVector, 3>& /*interior_inv_spatial_metric*/,
228 : const tnsr::AA<DataVector, 3, Frame::Inertial>& inverse_spacetime_metric,
229 : const tnsr::A<DataVector, 3, Frame::Inertial>&
230 : spacetime_unit_normal_vector,
231 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& three_index_constraint,
232 : const tnsr::a<DataVector, 3, Frame::Inertial>& gauge_source,
233 : const tnsr::ab<DataVector, 3, Frame::Inertial>&
234 : spacetime_deriv_gauge_source,
235 : // c.f. dg_interior_dt_vars_tags
236 : const tnsr::aa<DataVector, 3, Frame::Inertial>&
237 : logical_dt_spacetime_metric,
238 : const tnsr::aa<DataVector, 3, Frame::Inertial>& logical_dt_pi,
239 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& logical_dt_phi,
240 : // c.f. dg_interior_deriv_vars_tags
241 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& d_spacetime_metric,
242 : const tnsr::iaa<DataVector, 3, Frame::Inertial>& d_pi,
243 : const tnsr::ijaa<DataVector, 3, Frame::Inertial>& d_phi) const;
244 :
245 0 : using fd_interior_evolved_variables_tags = tmpl::list<>;
246 0 : using fd_interior_temporary_tags = tmpl::list<>;
247 0 : using fd_interior_primitive_variables_tags = tmpl::list<>;
248 0 : using fd_gridless_tags = tmpl::list<>;
249 :
250 0 : [[noreturn]] static void fd_ghost(
251 : const gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*>
252 : /*spacetime_metric*/,
253 : const gsl::not_null<tnsr::aa<DataVector, 3, Frame::Inertial>*> /*pi*/,
254 : const gsl::not_null<tnsr::iaa<DataVector, 3, Frame::Inertial>*> /*phi*/,
255 : const gsl::not_null<Scalar<DataVector>*> /*rest_mass_density*/,
256 : const gsl::not_null<Scalar<DataVector>*> /*electron_fraction*/,
257 : const gsl::not_null<Scalar<DataVector>*> /*pressure*/,
258 : const gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
259 : /*lorentz_factor_times_spatial_velocity*/,
260 : const gsl::not_null<tnsr::I<DataVector, 3, Frame::Inertial>*>
261 : /*magnetic_field*/,
262 : const gsl::not_null<Scalar<DataVector>*> /*divergence_cleaning_field*/,
263 : const Direction<3>& /*direction*/) {
264 : ERROR(
265 : "Not implemented because it's not trivial to figure out what the right "
266 : "way of handling this case is.");
267 : }
268 :
269 : private:
270 : gh::BoundaryConditions::ConstraintPreservingBjorhus<3>
271 0 : constraint_preserving_{};
272 : };
273 : } // namespace grmhd::GhValenciaDivClean::BoundaryConditions
|