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/DataVector.hpp"
12 : #include "DataStructures/Tensor/Tensor.hpp"
13 : #include "DataStructures/Variables.hpp"
14 : #include "Evolution/BoundaryConditions/Type.hpp"
15 : #include "Evolution/Systems/CurvedScalarWave/BoundaryConditions/BoundaryCondition.hpp"
16 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp"
17 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Tags.hpp"
18 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
19 : #include "Utilities/Gsl.hpp"
20 : #include "Utilities/Serialization/CharmPupable.hpp"
21 : #include "Utilities/TMPL.hpp"
22 :
23 : namespace CurvedScalarWave::BoundaryConditions {
24 :
25 : /*!
26 : * \brief Sets boundary conditions for the elements abutting the worldtube using
27 : * a combination of constraint-preserving boundary conditions and the local
28 : * solution evolved inside the worldtube.
29 : *
30 : * \details After extensive experimentation we found this set of boundary
31 : * conditions to be optimal. They are formulated in terms of characteristic
32 : * fields.
33 : *
34 : * Boundary conditions for \f$w^0_\psi\f$ \f$w^0_i\f$ are formulated
35 : * by demanding that there are no constraint violations flowing into the
36 : * numerical domain and are formulated as corrections to the time derivative of
37 : * the evolved variables directly. The derivation is described in
38 : * \ref ConstraintPreservingSphericalRadiation .
39 : *
40 : * Boundary conditions for \f$\w^-\f$ are formulated by evaluating the
41 : * analytical solution of the worldtube at the grid points of each element
42 : * abutting the worldtube. The data is updated and saved to
43 : * \ref CurvedScalarWave::Worldtube::Tags::WorldtubeSolution each time step.
44 : * It is then treated like a ghost field and applied with the chosen numerical
45 : * flux. So far only the upwind flux has been tried.
46 : *
47 : * We tried several other combinations such as setting all fields from the
48 : * worldtube solution but found that this caused major constraint violations to
49 : * flow out of the worldtube.
50 : *
51 : * \note We found that, depending on the worldtube size, a fairly high value for
52 : * \f$\gamma_2\f$ of ca. 10 is required near the worldtube to ensure a stable
53 : * evolution when using these boundary conditions.
54 : */
55 : template <size_t Dim>
56 1 : class Worldtube final : public BoundaryConditions::BoundaryCondition<Dim> {
57 : public:
58 0 : using options = tmpl::list<>;
59 0 : static constexpr Options::String help{
60 : "Boundary conditions set by the worldtube. w^- will be set by the "
61 : "internal worldtube solution, w^psi and w^0_i are fixed by constraint "
62 : "preserving boundary conditions on the time derivative."};
63 :
64 0 : Worldtube() = default;
65 0 : explicit Worldtube(CkMigrateMessage* msg);
66 :
67 0 : WRAPPED_PUPable_decl_base_template(
68 : domain::BoundaryConditions::BoundaryCondition, Worldtube);
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_temporary_tags =
79 : tmpl::list<gr::Tags::Lapse<DataVector>, gr::Tags::Shift<DataVector, Dim>,
80 : gr::Tags::InverseSpatialMetric<DataVector, Dim>,
81 : Tags::ConstraintGamma1, Tags::ConstraintGamma2>;
82 :
83 0 : using dg_gridless_tags =
84 : tmpl::list<CurvedScalarWave::Worldtube::Tags::WorldtubeSolution<Dim>>;
85 :
86 0 : using dg_interior_evolved_variables_tags =
87 : tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>>;
88 0 : using dg_interior_dt_vars_tags = tmpl::list<::Tags::dt<Tags::Psi>>;
89 0 : using dg_interior_deriv_vars_tags = tmpl::list<
90 : ::Tags::deriv<Tags::Psi, tmpl::size_t<Dim>, Frame::Inertial>,
91 : ::Tags::deriv<Tags::Phi<Dim>, tmpl::size_t<Dim>, Frame::Inertial>>;
92 :
93 0 : std::optional<std::string> dg_time_derivative(
94 : gsl::not_null<Scalar<DataVector>*> dt_psi_correction,
95 : gsl::not_null<Scalar<DataVector>*> dt_pi_correction,
96 : gsl::not_null<tnsr::i<DataVector, Dim, Frame::Inertial>*>
97 : dt_phi_correction,
98 : const std::optional<tnsr::I<DataVector, Dim>>& face_mesh_velocity,
99 : const tnsr::i<DataVector, Dim>& normal_covector,
100 : const tnsr::I<DataVector, Dim>& normal_vector,
101 : const Scalar<DataVector>& /*psi*/, const Scalar<DataVector>& /*pi*/,
102 : const tnsr::i<DataVector, Dim>& phi, const Scalar<DataVector>& lapse,
103 : const tnsr::I<DataVector, Dim>& shift,
104 : const tnsr::II<DataVector, Dim,
105 : Frame::Inertial>& /*inverse_spatial_metric*/,
106 : const Scalar<DataVector>& gamma1, const Scalar<DataVector>& gamma2,
107 : const Scalar<DataVector>& /*dt_psi*/,
108 : const tnsr::i<DataVector, Dim>& d_psi,
109 : const tnsr::ij<DataVector, Dim>& d_phi,
110 : const Variables<tmpl::list<Tags::Psi, Tags::Pi,
111 : Tags::Phi<Dim>>>& /*worldtube_vars*/) const;
112 :
113 0 : std::optional<std::string> dg_ghost(
114 : const gsl::not_null<Scalar<DataVector>*> psi,
115 : const gsl::not_null<Scalar<DataVector>*> pi,
116 : const gsl::not_null<tnsr::i<DataVector, Dim, Frame::Inertial>*> phi,
117 : const gsl::not_null<Scalar<DataVector>*> lapse,
118 : const gsl::not_null<tnsr::I<DataVector, Dim, Frame::Inertial>*> shift,
119 : const gsl::not_null<Scalar<DataVector>*> gamma1,
120 : const gsl::not_null<Scalar<DataVector>*> gamma2,
121 : const gsl::not_null<tnsr::II<DataVector, Dim, Frame::Inertial>*>
122 : inverse_spatial_metric,
123 :
124 : const std::optional<tnsr::I<DataVector, Dim, Frame::Inertial>>&
125 : /*face_mesh_velocity*/,
126 : const tnsr::i<DataVector, Dim, Frame::Inertial>& normal_covector,
127 : const tnsr::I<DataVector, Dim, Frame::Inertial>& normal_vector,
128 : const Scalar<DataVector>& psi_interior,
129 : const Scalar<DataVector>& pi_interior,
130 : const tnsr::i<DataVector, Dim>& phi_interior,
131 : const Scalar<DataVector>& lapse_interior,
132 : const tnsr::I<DataVector, Dim, Frame::Inertial>& shift_interior,
133 : const tnsr::II<DataVector, Dim, Frame::Inertial>&
134 : inverse_spatial_metric_interior,
135 : const Scalar<DataVector>& gamma1_interior,
136 : const Scalar<DataVector>& gamma2_interior,
137 : const Scalar<DataVector>& /*dt_psi*/,
138 : const tnsr::i<DataVector, Dim>& d_psi,
139 : const tnsr::ij<DataVector, Dim>& /*d_phi*/,
140 : const Variables<tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>>>&
141 : worldtube_vars) const;
142 : };
143 : } // namespace CurvedScalarWave::BoundaryConditions
|