Gyselalib++
cartesian_to_pseudo_cartesian.hpp
1 // SPDX-License-Identifier: MIT
2 #pragma once
3 
4 #include <sll/view.hpp>
5 
6 #include "inverse_jacobian_matrix.hpp"
7 #include "mapping_tools.hpp"
8 
14 template <class MappingToCartesian, class MappingToPseudoCartesian>
16 {
17  static_assert(
18  std::is_same_v<
19  typename MappingToCartesian::curvilinear_tag_r,
20  typename MappingToPseudoCartesian::curvilinear_tag_r>,
21  "The Cartesian and pseudo-Cartesian mappings must share a logical space");
22  static_assert(
23  std::is_same_v<
24  typename MappingToCartesian::curvilinear_tag_theta,
25  typename MappingToPseudoCartesian::curvilinear_tag_theta>,
26  "The Cartesian and pseudo-Cartesian mappings must share a logical space");
27 
28 public:
30  using CartesianCoordinate = ddc::Coordinate<
31  typename MappingToCartesian::cartesian_tag_x,
32  typename MappingToCartesian::cartesian_tag_y>;
33 
35  using cartesian_tag_x = typename MappingToCartesian::cartesian_tag_x;
37  using cartesian_tag_y = typename MappingToCartesian::cartesian_tag_y;
38 
40  using pseudo_cartesian_tag_x = typename MappingToPseudoCartesian::cartesian_tag_x;
42  using pseudo_cartesian_tag_y = typename MappingToPseudoCartesian::cartesian_tag_y;
43 
45  using CoordArg = ddc::Coordinate<cartesian_tag_x, cartesian_tag_y>;
47  using CoordResult = ddc::Coordinate<pseudo_cartesian_tag_x, pseudo_cartesian_tag_y>;
48 
49 private:
50  using R = typename MappingToCartesian::curvilinear_tag_r;
51  using Theta = typename MappingToCartesian::curvilinear_tag_theta;
52  using CoordRTheta = ddc::Coordinate<R, Theta>;
53 
54  static_assert(is_2d_mapping_v<MappingToCartesian>);
55  static_assert(is_2d_mapping_v<MappingToPseudoCartesian>);
56  static_assert(has_2d_jacobian_v<MappingToCartesian, CoordRTheta>);
57  static_assert(has_2d_jacobian_v<MappingToPseudoCartesian, CoordRTheta>);
58 
59 private:
60  MappingToCartesian m_mapping_to_cartesian;
61  MappingToPseudoCartesian m_mapping_to_pseudo_cartesian;
62  double m_epsilon;
63 
64 public:
75  MappingToPseudoCartesian mapping_to_pseudo_cartesian,
76  MappingToCartesian mapping_to_cartesian,
77  double epsilon)
78  : m_mapping_to_cartesian(mapping_to_cartesian)
79  , m_mapping_to_pseudo_cartesian(mapping_to_pseudo_cartesian)
80  , m_epsilon(epsilon)
81  {
82  }
83 
96  KOKKOS_FUNCTION void jacobian_matrix(CoordRTheta const& coord_rtheta, Matrix_2x2& J) const
97  {
98  double r = ddc::get<R>(coord_rtheta);
99 
100  Matrix_2x2 inv_jacobian_from_cartesian;
101  Matrix_2x2 jacobian_from_pseudo_cartesian;
102  InverseJacobianMatrix inv_jacobian_cartesian(m_mapping_to_cartesian);
103  if (r < m_epsilon) {
104  Matrix_2x2 J_0;
105  m_mapping_to_cartesian.to_pseudo_cartesian_jacobian_center_matrix(J_0);
106 
107  CoordRTheta coord_eps(m_epsilon, ddc::get<Theta>(coord_rtheta));
108 
109  inv_jacobian_from_cartesian = inv_jacobian_cartesian(coord_eps);
110  m_mapping_to_pseudo_cartesian
111  .jacobian_matrix(coord_eps, jacobian_from_pseudo_cartesian);
112  Matrix_2x2 J_eps = mat_mul(jacobian_from_pseudo_cartesian, inv_jacobian_from_cartesian);
113 
114  J[0][0] = (1 - r / m_epsilon) * J_0[0][0] + r / m_epsilon * J_eps[0][0];
115  J[0][1] = (1 - r / m_epsilon) * J_0[0][1] + r / m_epsilon * J_eps[0][1];
116  J[1][0] = (1 - r / m_epsilon) * J_0[1][0] + r / m_epsilon * J_eps[1][0];
117  J[1][1] = (1 - r / m_epsilon) * J_0[1][1] + r / m_epsilon * J_eps[1][1];
118  } else {
119  inv_jacobian_from_cartesian = inv_jacobian_cartesian(coord_rtheta);
120  m_mapping_to_pseudo_cartesian
121  .jacobian_matrix(coord_rtheta, jacobian_from_pseudo_cartesian);
122  J = mat_mul(jacobian_from_pseudo_cartesian, inv_jacobian_from_cartesian);
123  }
124  }
125 
132  KOKKOS_FUNCTION double jacobian(CoordRTheta const& coord_rtheta) const
133  {
134  Matrix_2x2 J;
135  jacobian_matrix(coord_rtheta, J);
136  return determinant(J);
137  }
138 
145  KOKKOS_FUNCTION double jacobian_11(CoordRTheta const& coord_rtheta) const
146  {
147  Matrix_2x2 J;
148  jacobian_matrix(coord_rtheta, J);
149  return J[0][0];
150  }
151 
158  KOKKOS_FUNCTION double jacobian_12(CoordRTheta const& coord_rtheta) const
159  {
160  Matrix_2x2 J;
161  jacobian_matrix(coord_rtheta, J);
162  return J[0][1];
163  }
164 
171  KOKKOS_FUNCTION double jacobian_21(CoordRTheta const& coord_rtheta) const
172  {
173  Matrix_2x2 J;
174  jacobian_matrix(coord_rtheta, J);
175  return J[1][0];
176  }
177 
184  KOKKOS_FUNCTION double jacobian_22(CoordRTheta const& coord_rtheta) const
185  {
186  Matrix_2x2 J;
187  jacobian_matrix(coord_rtheta, J);
188  return J[1][1];
189  }
190 
204  KOKKOS_FUNCTION void inv_jacobian_matrix(CoordRTheta const& coord_rtheta, Matrix_2x2& J) const
205  {
206  double r = ddc::get<R>(coord_rtheta);
207 
208  Matrix_2x2 jacobian_from_cartesian;
209  Matrix_2x2 inv_jacobian_from_pseudo_cartesian;
210  InverseJacobianMatrix inv_jacobian_pseudo_cartesian(m_mapping_to_pseudo_cartesian);
211  if (r < m_epsilon) {
212  Matrix_2x2 J_0;
213  m_mapping_to_cartesian.to_pseudo_cartesian_jacobian_center_matrix(J_0);
214  Matrix_2x2 J_0_inv = inverse(J_0);
215 
216  CoordRTheta coord_eps(m_epsilon, ddc::get<Theta>(coord_rtheta));
217 
218  m_mapping_to_cartesian.jacobian_matrix(coord_eps, jacobian_from_cartesian);
219  inv_jacobian_from_pseudo_cartesian = inv_jacobian_pseudo_cartesian(coord_eps);
220  Matrix_2x2 J_eps = mat_mul(inv_jacobian_from_pseudo_cartesian, jacobian_from_cartesian);
221 
222  J[0][0] = (1 - r / m_epsilon) * J_0_inv[0][0] + r / m_epsilon * J_eps[0][0];
223  J[0][1] = (1 - r / m_epsilon) * J_0_inv[0][1] + r / m_epsilon * J_eps[0][1];
224  J[1][0] = (1 - r / m_epsilon) * J_0_inv[1][0] + r / m_epsilon * J_eps[1][0];
225  J[1][1] = (1 - r / m_epsilon) * J_0_inv[1][1] + r / m_epsilon * J_eps[1][1];
226  } else {
227  m_mapping_to_cartesian.jacobian_matrix(coord_rtheta, jacobian_from_cartesian);
228  inv_jacobian_from_pseudo_cartesian = inv_jacobian_pseudo_cartesian(coord_rtheta);
229  J = mat_mul(jacobian_from_cartesian, inv_jacobian_from_pseudo_cartesian);
230  }
231  }
232 
239  KOKKOS_FUNCTION double inv_jacobian_11(CoordRTheta const& coord_rtheta) const
240  {
241  Matrix_2x2 J;
242  inv_jacobian_matrix(coord_rtheta, J);
243  return J[0][0];
244  }
245 
252  KOKKOS_FUNCTION double inv_jacobian_12(CoordRTheta const& coord_rtheta) const
253  {
254  Matrix_2x2 J;
255  inv_jacobian_matrix(coord_rtheta, J);
256  return J[0][1];
257  }
258 
265  KOKKOS_FUNCTION double inv_jacobian_21(CoordRTheta const& coord_rtheta) const
266  {
267  Matrix_2x2 J;
268  inv_jacobian_matrix(coord_rtheta, J);
269  return J[1][0];
270  }
271 
278  KOKKOS_FUNCTION double inv_jacobian_22(CoordRTheta const& coord_rtheta) const
279  {
280  Matrix_2x2 J;
281  inv_jacobian_matrix(coord_rtheta, J);
282  return J[1][1];
283  }
284 };
285 
286 namespace mapping_detail {
287 template <class ExecSpace, class MappingToPseudoCartesian, class MappingToCartesian>
288 struct MappingAccessibility<
289  ExecSpace,
290  CartesianToPseudoCartesian<MappingToPseudoCartesian, MappingToCartesian>>
291 {
292  static bool constexpr value = MappingAccessibility<ExecSpace, MappingToPseudoCartesian>::value
293  && MappingAccessibility<ExecSpace, MappingToCartesian>::value;
294 };
295 
296 } // namespace mapping_detail
A class describing a mapping from a Cartesian domain to a pseudo-Cartesian.
Definition: cartesian_to_pseudo_cartesian.hpp:16
typename MappingToPseudoCartesian::cartesian_tag_x pseudo_cartesian_tag_x
The X dimension in the pseudo-Cartesian geometry.
Definition: cartesian_to_pseudo_cartesian.hpp:40
ddc::Coordinate< cartesian_tag_x, cartesian_tag_y > CoordArg
The type of the argument of the function described by this mapping.
Definition: cartesian_to_pseudo_cartesian.hpp:45
KOKKOS_FUNCTION double inv_jacobian_11(CoordRTheta const &coord_rtheta) const
Compute the (1,1) coefficient of the inverse of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:239
typename MappingToPseudoCartesian::cartesian_tag_y pseudo_cartesian_tag_y
The Y dimension in the pseudo-Cartesian geometry.
Definition: cartesian_to_pseudo_cartesian.hpp:42
KOKKOS_FUNCTION double jacobian_21(CoordRTheta const &coord_rtheta) const
Compute the (2,1) coefficient of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:171
KOKKOS_FUNCTION void inv_jacobian_matrix(CoordRTheta const &coord_rtheta, Matrix_2x2 &J) const
Compute the full inverse of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:204
KOKKOS_FUNCTION double jacobian_12(CoordRTheta const &coord_rtheta) const
Compute the (1,2) coefficient of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:158
KOKKOS_FUNCTION double inv_jacobian_12(CoordRTheta const &coord_rtheta) const
Compute the (1,2) coefficient of the inverse of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:252
typename MappingToCartesian::cartesian_tag_x cartesian_tag_x
The X dimension in the Cartesian geometry.
Definition: cartesian_to_pseudo_cartesian.hpp:35
KOKKOS_FUNCTION double jacobian(CoordRTheta const &coord_rtheta) const
Compute the determinant of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:132
typename MappingToCartesian::cartesian_tag_y cartesian_tag_y
The Y dimension in the Cartesian geometry.
Definition: cartesian_to_pseudo_cartesian.hpp:37
KOKKOS_FUNCTION double jacobian_22(CoordRTheta const &coord_rtheta) const
Compute the (2,2) coefficient of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:184
CartesianToPseudoCartesian(MappingToPseudoCartesian mapping_to_pseudo_cartesian, MappingToCartesian mapping_to_cartesian, double epsilon)
Construct an instance of the class.
Definition: cartesian_to_pseudo_cartesian.hpp:74
ddc::Coordinate< typename MappingToCartesian::cartesian_tag_x, typename MappingToCartesian::cartesian_tag_y > CartesianCoordinate
The type of a coordinate in the Cartesian geometry.
Definition: cartesian_to_pseudo_cartesian.hpp:32
KOKKOS_FUNCTION double inv_jacobian_21(CoordRTheta const &coord_rtheta) const
Compute the (2,1) coefficient of the inverse of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:265
KOKKOS_FUNCTION double jacobian_11(CoordRTheta const &coord_rtheta) const
Compute the (1,1) coefficient of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:145
KOKKOS_FUNCTION void jacobian_matrix(CoordRTheta const &coord_rtheta, Matrix_2x2 &J) const
Compute the full Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:96
KOKKOS_FUNCTION double inv_jacobian_22(CoordRTheta const &coord_rtheta) const
Compute the (2,2) coefficient of the inverse of the Jacobian matrix.
Definition: cartesian_to_pseudo_cartesian.hpp:278
ddc::Coordinate< pseudo_cartesian_tag_x, pseudo_cartesian_tag_y > CoordResult
The type of the result of the function described by this mapping.
Definition: cartesian_to_pseudo_cartesian.hpp:47
A class to calculate the inverse of the Jacobian matrix.
Definition: inverse_jacobian_matrix.hpp:18
Define non periodic real R dimension.
Definition: geometry.hpp:31
Define periodic real Theta dimension.
Definition: geometry.hpp:42