Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <memory>
8 : #include <optional>
9 : #include <string>
10 : #include <tuple>
11 : #include <unordered_map>
12 :
13 : #include "DataStructures/DataBox/Tag.hpp"
14 : #include "DataStructures/DataVector.hpp"
15 : #include "DataStructures/Tensor/EagerMath/Magnitude.hpp" // For Tags::Normalized
16 : #include "DataStructures/Tensor/Tensor.hpp"
17 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
18 : #include "Domain/FaceNormal.hpp"
19 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
20 : #include "Domain/FunctionsOfTime/Tags.hpp"
21 : #include "Domain/Tags.hpp"
22 : #include "Utilities/Gsl.hpp"
23 : #include "Utilities/TMPL.hpp"
24 :
25 : /// \cond
26 : namespace Tags {
27 : struct Time;
28 : } // namespace Tags
29 : /// \endcond
30 :
31 : namespace domain {
32 : /// \ingroup ComputationalDomainGroup
33 : /// \brief %Tags for the domain.
34 : namespace Tags {
35 : /// The Inertial coordinates, the inverse Jacobian from the Grid to the Inertial
36 : /// frame, the Jacobian from the Grid to the Inertial frame, and the Inertial
37 : /// mesh velocity.
38 : ///
39 : /// The type is a `std::optional`, which, when is not valid, signals that the
40 : /// mesh is not moving. Thus,
41 : /// `coordinates_velocity_and_jacobian.has_value()` can be used to check
42 : /// if the mesh is moving.
43 : template <size_t Dim>
44 1 : struct CoordinatesMeshVelocityAndJacobians : db::SimpleTag {
45 0 : using type = std::optional<std::tuple<
46 : tnsr::I<DataVector, Dim, Frame::Inertial>,
47 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
48 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
49 : tnsr::I<DataVector, Dim, Frame::Inertial>>>;
50 : };
51 :
52 : /// Computes the Inertial coordinates, the inverse Jacobian from the Grid to the
53 : /// Inertial frame, the Jacobian from the Grid to the Inertial frame, and the
54 : /// Inertial mesh velocity.
55 : template <typename MapTagGridToInertial>
56 1 : struct CoordinatesMeshVelocityAndJacobiansCompute
57 : : CoordinatesMeshVelocityAndJacobians<MapTagGridToInertial::dim>,
58 : db::ComputeTag {
59 0 : static constexpr size_t dim = MapTagGridToInertial::dim;
60 0 : using base = CoordinatesMeshVelocityAndJacobians<dim>;
61 :
62 0 : using return_type = typename base::type;
63 :
64 0 : static void function(
65 : const gsl::not_null<return_type*> result,
66 : const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, dim>&
67 : grid_to_inertial_map,
68 : const tnsr::I<DataVector, dim, Frame::Grid>& source_coords,
69 : const double time,
70 : const std::unordered_map<
71 : std::string,
72 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
73 : functions_of_time) {
74 : // Use identity to signal time-independent
75 : if (not grid_to_inertial_map.is_identity()) {
76 : *result = grid_to_inertial_map.coords_frame_velocity_jacobians(
77 : source_coords, time, functions_of_time);
78 : } else {
79 : *result = std::nullopt;
80 : }
81 : }
82 :
83 0 : using argument_tags =
84 : tmpl::list<MapTagGridToInertial, Tags::Coordinates<dim, Frame::Grid>,
85 : ::Tags::Time, Tags::FunctionsOfTime>;
86 : };
87 :
88 : /// Computes the Inertial coordinates from
89 : /// `CoordinatesVelocityAndJacobians`
90 : template <size_t Dim>
91 1 : struct InertialFromGridCoordinatesCompute
92 : : Tags::Coordinates<Dim, Frame::Inertial>,
93 : db::ComputeTag {
94 0 : using base = Tags::Coordinates<Dim, Frame::Inertial>;
95 0 : using return_type = typename base::type;
96 :
97 0 : static void function(
98 : gsl::not_null<tnsr::I<DataVector, Dim, Frame::Inertial>*> target_coords,
99 : const tnsr::I<DataVector, Dim, Frame::Grid>& source_coords,
100 : const std::optional<std::tuple<
101 : tnsr::I<DataVector, Dim, Frame::Inertial>,
102 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
103 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
104 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
105 : grid_to_inertial_quantities);
106 :
107 0 : using argument_tags = tmpl::list<Tags::Coordinates<Dim, Frame::Grid>,
108 : CoordinatesMeshVelocityAndJacobians<Dim>>;
109 : };
110 :
111 : /// Computes the Grid to Inertial inverse Jacobian from
112 : /// `CoordinatesVelocityAndJacobians`. If the mesh is not moving, sets the
113 : /// Jacobian to the identity.
114 : template <size_t Dim>
115 1 : struct GridToInertialInverseJacobian
116 : : Tags::InverseJacobian<Dim, Frame::Grid, Frame::Inertial>,
117 : db::ComputeTag {
118 0 : using base = Tags::InverseJacobian<Dim, Frame::Grid, Frame::Inertial>;
119 0 : using return_type = typename base::type;
120 :
121 0 : static void function(
122 : gsl::not_null<
123 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>*>
124 : inv_jac_grid_to_inertial,
125 : const std::optional<std::tuple<
126 : tnsr::I<DataVector, Dim, Frame::Inertial>,
127 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
128 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
129 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
130 : grid_to_inertial_quantities,
131 : const tnsr::I<DataVector, Dim, Frame::Grid>&);
132 :
133 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>,
134 : Tags::Coordinates<Dim, Frame::Grid>>;
135 : };
136 :
137 : /// Computes the Grid to Inertial Jacobian from
138 : /// `CoordinatesVelocityAndJacobians`. If the mesh is not moving, sets the
139 : /// Jacobian to the identity.
140 : template <size_t Dim>
141 1 : struct GridToInertialJacobian
142 : : Tags::Jacobian<Dim, Frame::Grid, Frame::Inertial>,
143 : db::ComputeTag {
144 0 : using base = Tags::Jacobian<Dim, Frame::Grid, Frame::Inertial>;
145 0 : using return_type = typename base::type;
146 :
147 0 : static void function(
148 : gsl::not_null<::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>*>
149 : jac_grid_to_inertial,
150 : const std::optional<std::tuple<
151 : tnsr::I<DataVector, Dim, Frame::Inertial>,
152 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
153 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
154 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
155 : grid_to_inertial_quantities,
156 : const tnsr::I<DataVector, Dim, Frame::Grid>&);
157 :
158 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>,
159 : Tags::Coordinates<Dim, Frame::Grid>>;
160 : };
161 :
162 : /// Computes the Logical to Inertial inverse Jacobian from
163 : /// `CoordinatesVelocityAndJacobians`
164 : template <size_t Dim>
165 1 : struct ElementToInertialInverseJacobian
166 : : Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Inertial>,
167 : db::ComputeTag {
168 0 : using base =
169 : Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Inertial>;
170 0 : using return_type = typename base::type;
171 :
172 0 : static void function(
173 : gsl::not_null<::InverseJacobian<DataVector, Dim, Frame::ElementLogical,
174 : Frame::Inertial>*>
175 : inv_jac_logical_to_inertial,
176 : const ::InverseJacobian<DataVector, Dim, Frame::ElementLogical,
177 : Frame::Grid>& inv_jac_logical_to_grid,
178 : const std::optional<std::tuple<
179 : tnsr::I<DataVector, Dim, Frame::Inertial>,
180 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
181 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
182 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
183 : grid_to_inertial_quantities);
184 :
185 0 : using argument_tags =
186 : tmpl::list<Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Grid>,
187 : CoordinatesMeshVelocityAndJacobians<Dim>>;
188 : };
189 :
190 : /// The mesh velocity
191 : ///
192 : /// The type is a `std::optional`, which when it is not set indicates that the
193 : /// mesh is not moving.
194 : template <size_t Dim, typename Frame = ::Frame::Inertial>
195 1 : struct MeshVelocity : db::SimpleTag {
196 0 : using type = std::optional<tnsr::I<DataVector, Dim, Frame>>;
197 : };
198 :
199 : /// Computes the Inertial mesh velocity from `CoordinatesVelocityAndJacobians`
200 : ///
201 : /// The type is a `std::optional`, which when it is not set indicates that the
202 : /// mesh is not moving.
203 : template <size_t Dim>
204 1 : struct InertialMeshVelocityCompute : MeshVelocity<Dim, Frame::Inertial>,
205 : db::ComputeTag {
206 0 : using base = MeshVelocity<Dim, Frame::Inertial>;
207 0 : using return_type = typename base::type;
208 :
209 0 : static void function(
210 : gsl::not_null<return_type*> mesh_velocity,
211 : const std::optional<std::tuple<
212 : tnsr::I<DataVector, Dim, Frame::Inertial>,
213 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
214 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
215 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
216 : grid_to_inertial_quantities);
217 :
218 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>>;
219 : };
220 :
221 : /// The divergence of the mesh velocity
222 1 : struct DivMeshVelocity : db::SimpleTag {
223 0 : using type = std::optional<Scalar<DataVector>>;
224 0 : static std::string name() { return "div(MeshVelocity)"; }
225 : };
226 : } // namespace Tags
227 : } // namespace domain
|