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, requesting
113 : /// this tag will throw an error because the Jacobian is just 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 :
132 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>>;
133 : };
134 :
135 : /// Computes the Logical to Inertial inverse Jacobian from
136 : /// `CoordinatesVelocityAndJacobians`
137 : template <size_t Dim>
138 1 : struct ElementToInertialInverseJacobian
139 : : Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Inertial>,
140 : db::ComputeTag {
141 0 : using base =
142 : Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Inertial>;
143 0 : using return_type = typename base::type;
144 :
145 0 : static void function(
146 : gsl::not_null<::InverseJacobian<DataVector, Dim, Frame::ElementLogical,
147 : Frame::Inertial>*>
148 : inv_jac_logical_to_inertial,
149 : const ::InverseJacobian<DataVector, Dim, Frame::ElementLogical,
150 : Frame::Grid>& inv_jac_logical_to_grid,
151 : const std::optional<std::tuple<
152 : tnsr::I<DataVector, Dim, Frame::Inertial>,
153 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
154 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
155 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
156 : grid_to_inertial_quantities);
157 :
158 0 : using argument_tags =
159 : tmpl::list<Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Grid>,
160 : CoordinatesMeshVelocityAndJacobians<Dim>>;
161 : };
162 :
163 : /// The mesh velocity
164 : ///
165 : /// The type is a `std::optional`, which when it is not set indicates that the
166 : /// mesh is not moving.
167 : template <size_t Dim, typename Frame = ::Frame::Inertial>
168 1 : struct MeshVelocity : db::SimpleTag {
169 0 : using type = std::optional<tnsr::I<DataVector, Dim, Frame>>;
170 : };
171 :
172 : /// Computes the Inertial mesh velocity from `CoordinatesVelocityAndJacobians`
173 : ///
174 : /// The type is a `std::optional`, which when it is not set indicates that the
175 : /// mesh is not moving.
176 : template <size_t Dim>
177 1 : struct InertialMeshVelocityCompute : MeshVelocity<Dim, Frame::Inertial>,
178 : db::ComputeTag {
179 0 : using base = MeshVelocity<Dim, Frame::Inertial>;
180 0 : using return_type = typename base::type;
181 :
182 0 : static void function(
183 : gsl::not_null<return_type*> mesh_velocity,
184 : const std::optional<std::tuple<
185 : tnsr::I<DataVector, Dim, Frame::Inertial>,
186 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
187 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
188 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
189 : grid_to_inertial_quantities);
190 :
191 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>>;
192 : };
193 :
194 : /// The divergence of the mesh velocity
195 1 : struct DivMeshVelocity : db::SimpleTag {
196 0 : using type = std::optional<Scalar<DataVector>>;
197 0 : static std::string name() { return "div(MeshVelocity)"; }
198 : };
199 : } // namespace Tags
200 : } // namespace domain
|