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 "Time/Tags.hpp"
23 : #include "Utilities/Gsl.hpp"
24 : #include "Utilities/TMPL.hpp"
25 :
26 : namespace domain {
27 : /// \ingroup ComputationalDomainGroup
28 : /// \brief %Tags for the domain.
29 : namespace Tags {
30 : /// The Inertial coordinates, the inverse Jacobian from the Grid to the Inertial
31 : /// frame, the Jacobian from the Grid to the Inertial frame, and the Inertial
32 : /// mesh velocity.
33 : ///
34 : /// The type is a `std::optional`, which, when is not valid, signals that the
35 : /// mesh is not moving. Thus,
36 : /// `coordinates_velocity_and_jacobian.has_value()` can be used to check
37 : /// if the mesh is moving.
38 : template <size_t Dim>
39 1 : struct CoordinatesMeshVelocityAndJacobians : db::SimpleTag {
40 0 : using type = std::optional<std::tuple<
41 : tnsr::I<DataVector, Dim, Frame::Inertial>,
42 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
43 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
44 : tnsr::I<DataVector, Dim, Frame::Inertial>>>;
45 : };
46 :
47 : /// Computes the Inertial coordinates, the inverse Jacobian from the Grid to the
48 : /// Inertial frame, the Jacobian from the Grid to the Inertial frame, and the
49 : /// Inertial mesh velocity.
50 : template <typename MapTagGridToInertial>
51 1 : struct CoordinatesMeshVelocityAndJacobiansCompute
52 : : CoordinatesMeshVelocityAndJacobians<MapTagGridToInertial::dim>,
53 : db::ComputeTag {
54 0 : static constexpr size_t dim = MapTagGridToInertial::dim;
55 0 : using base = CoordinatesMeshVelocityAndJacobians<dim>;
56 :
57 0 : using return_type = typename base::type;
58 :
59 0 : static void function(
60 : const gsl::not_null<return_type*> result,
61 : const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, dim>&
62 : grid_to_inertial_map,
63 : const tnsr::I<DataVector, dim, Frame::Grid>& source_coords,
64 : const double time,
65 : const std::unordered_map<
66 : std::string,
67 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
68 : functions_of_time) {
69 : // Use identity to signal time-independent
70 : if (not grid_to_inertial_map.is_identity()) {
71 : *result = grid_to_inertial_map.coords_frame_velocity_jacobians(
72 : source_coords, time, functions_of_time);
73 : } else {
74 : *result = std::nullopt;
75 : }
76 : }
77 :
78 0 : using argument_tags =
79 : tmpl::list<MapTagGridToInertial, Tags::Coordinates<dim, Frame::Grid>,
80 : ::Tags::Time, Tags::FunctionsOfTime>;
81 : };
82 :
83 : /// Computes the Inertial coordinates from
84 : /// `CoordinatesVelocityAndJacobians`
85 : template <size_t Dim>
86 1 : struct InertialFromGridCoordinatesCompute
87 : : Tags::Coordinates<Dim, Frame::Inertial>,
88 : db::ComputeTag {
89 0 : using base = Tags::Coordinates<Dim, Frame::Inertial>;
90 0 : using return_type = typename base::type;
91 :
92 0 : static void function(
93 : gsl::not_null<tnsr::I<DataVector, Dim, Frame::Inertial>*> target_coords,
94 : const tnsr::I<DataVector, Dim, Frame::Grid>& source_coords,
95 : const std::optional<std::tuple<
96 : tnsr::I<DataVector, Dim, Frame::Inertial>,
97 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
98 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
99 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
100 : grid_to_inertial_quantities);
101 :
102 0 : using argument_tags = tmpl::list<Tags::Coordinates<Dim, Frame::Grid>,
103 : CoordinatesMeshVelocityAndJacobians<Dim>>;
104 : };
105 :
106 : /// Computes the Grid to Inertial inverse Jacobian from
107 : /// `CoordinatesVelocityAndJacobians`. If the mesh is not moving, requesting
108 : /// this tag will throw an error because the Jacobian is just the identity.
109 : template <size_t Dim>
110 1 : struct GridToInertialInverseJacobian
111 : : Tags::InverseJacobian<Dim, Frame::Grid, Frame::Inertial>,
112 : db::ComputeTag {
113 0 : using base = Tags::InverseJacobian<Dim, Frame::Grid, Frame::Inertial>;
114 0 : using return_type = typename base::type;
115 :
116 0 : static void function(
117 : gsl::not_null<
118 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>*>
119 : inv_jac_grid_to_inertial,
120 : const std::optional<std::tuple<
121 : tnsr::I<DataVector, Dim, Frame::Inertial>,
122 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
123 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
124 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
125 : grid_to_inertial_quantities);
126 :
127 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>>;
128 : };
129 :
130 : /// Computes the Logical to Inertial inverse Jacobian from
131 : /// `CoordinatesVelocityAndJacobians`
132 : template <size_t Dim>
133 1 : struct ElementToInertialInverseJacobian
134 : : Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Inertial>,
135 : db::ComputeTag {
136 0 : using base =
137 : Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Inertial>;
138 0 : using return_type = typename base::type;
139 :
140 0 : static void function(
141 : gsl::not_null<::InverseJacobian<DataVector, Dim, Frame::ElementLogical,
142 : Frame::Inertial>*>
143 : inv_jac_logical_to_inertial,
144 : const ::InverseJacobian<DataVector, Dim, Frame::ElementLogical,
145 : Frame::Grid>& inv_jac_logical_to_grid,
146 : const std::optional<std::tuple<
147 : tnsr::I<DataVector, Dim, Frame::Inertial>,
148 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
149 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
150 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
151 : grid_to_inertial_quantities);
152 :
153 0 : using argument_tags =
154 : tmpl::list<Tags::InverseJacobian<Dim, Frame::ElementLogical, Frame::Grid>,
155 : CoordinatesMeshVelocityAndJacobians<Dim>>;
156 : };
157 :
158 : /// The mesh velocity
159 : ///
160 : /// The type is a `std::optional`, which when it is not set indicates that the
161 : /// mesh is not moving.
162 : template <size_t Dim, typename Frame = ::Frame::Inertial>
163 1 : struct MeshVelocity : db::SimpleTag {
164 0 : using type = std::optional<tnsr::I<DataVector, Dim, Frame>>;
165 : };
166 :
167 : /// Computes the Inertial mesh velocity from `CoordinatesVelocityAndJacobians`
168 : ///
169 : /// The type is a `std::optional`, which when it is not set indicates that the
170 : /// mesh is not moving.
171 : template <size_t Dim>
172 1 : struct InertialMeshVelocityCompute : MeshVelocity<Dim, Frame::Inertial>,
173 : db::ComputeTag {
174 0 : using base = MeshVelocity<Dim, Frame::Inertial>;
175 0 : using return_type = typename base::type;
176 :
177 0 : static void function(
178 : gsl::not_null<return_type*> mesh_velocity,
179 : const std::optional<std::tuple<
180 : tnsr::I<DataVector, Dim, Frame::Inertial>,
181 : ::InverseJacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
182 : ::Jacobian<DataVector, Dim, Frame::Grid, Frame::Inertial>,
183 : tnsr::I<DataVector, Dim, Frame::Inertial>>>&
184 : grid_to_inertial_quantities);
185 :
186 0 : using argument_tags = tmpl::list<CoordinatesMeshVelocityAndJacobians<Dim>>;
187 : };
188 :
189 : /// The divergence of the mesh velocity
190 1 : struct DivMeshVelocity : db::SimpleTag {
191 0 : using type = std::optional<Scalar<DataVector>>;
192 0 : static std::string name() { return "div(MeshVelocity)"; }
193 : };
194 : } // namespace Tags
195 : } // namespace domain
|