Gyselalib++
 
Loading...
Searching...
No Matches
czarny_to_cartesian.hpp
1// SPDX-License-Identifier: MIT
2#pragma once
3
4#include <cmath>
5
6#include <ddc/ddc.hpp>
7
8#include <sll/view.hpp>
9
10#include "mapping_tools.hpp"
11
12// Pre-declaration of analytical inverse
13template <class X, class Y, class R, class Theta>
15
48template <class R, class Theta, class X, class Y>
50{
51public:
60
62 using CoordArg = ddc::Coordinate<R, Theta>;
64 using CoordResult = ddc::Coordinate<X, Y>;
65
66private:
67 double m_epsilon;
68 double m_e;
69
70public:
82 CzarnyToCartesian(double epsilon, double e) : m_epsilon(epsilon), m_e(e) {}
83
90 KOKKOS_FUNCTION CzarnyToCartesian(CzarnyToCartesian const& other)
91 : m_epsilon(other.epsilon())
92 , m_e(other.e())
93 {
94 }
95
103
104 ~CzarnyToCartesian() = default;
105
115
125
133 KOKKOS_FUNCTION double epsilon() const
134 {
135 return m_epsilon;
136 }
137
145 KOKKOS_FUNCTION double e() const
146 {
147 return m_e;
148 }
149
157 KOKKOS_FUNCTION ddc::Coordinate<X, Y> operator()(ddc::Coordinate<R, Theta> const& coord) const
158 {
159 const double r = ddc::get<R>(coord);
160 const double theta = ddc::get<Theta>(coord);
161 const double tmp1
162 = Kokkos::sqrt(m_epsilon * (m_epsilon + 2.0 * r * Kokkos::cos(theta)) + 1.0);
163
164 const double x = (1.0 - tmp1) / m_epsilon;
165 const double y = m_e * r * Kokkos::sin(theta)
166 / (Kokkos::sqrt(1.0 - 0.25 * m_epsilon * m_epsilon) * (2.0 - tmp1));
167
168 return ddc::Coordinate<X, Y>(x, y);
169 }
170
179 KOKKOS_FUNCTION double jacobian(ddc::Coordinate<R, Theta> const& coord) const
180 {
181 const double r = ddc::get<R>(coord);
182 const double theta = ddc::get<Theta>(coord);
183 const double xi = Kokkos::sqrt(1. / (1. - m_epsilon * m_epsilon * 0.25));
184 return -r / Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * Kokkos::cos(theta))) * m_e
185 * xi
186 / (2 - Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * Kokkos::cos(theta))));
187 }
188
208 KOKKOS_FUNCTION void jacobian_matrix(ddc::Coordinate<R, Theta> const& coord, Matrix_2x2& matrix)
209 const
210 {
211 const double r = ddc::get<R>(coord);
212 const double theta = ddc::get<Theta>(coord);
213
214 const double sin_theta = Kokkos::sin(theta);
215 const double cos_theta = Kokkos::cos(theta);
216 const double xi2 = 1. / (1. - m_epsilon * m_epsilon * 0.25);
217 const double xi = Kokkos::sqrt(xi2);
218 const double sqrt_eps = Kokkos::sqrt(m_epsilon * (m_epsilon + 2.0 * r * cos_theta) + 1.0);
219 const double sqrt_eps_2 = 2.0 - sqrt_eps;
220
221 matrix[0][0] = -cos_theta / sqrt_eps;
222 matrix[0][1] = r * sin_theta / sqrt_eps;
223 matrix[1][0] = m_e * m_epsilon * r * sin_theta * cos_theta * xi
224 / (sqrt_eps_2 * sqrt_eps_2 * sqrt_eps)
225 + m_e * sin_theta * xi / sqrt_eps_2;
226 matrix[1][1] = r
227 * (-m_e * m_epsilon * r * sin_theta * sin_theta * xi
228 / (sqrt_eps_2 * sqrt_eps_2 * sqrt_eps)
229 + m_e * cos_theta * xi / sqrt_eps_2);
230 }
231
243 KOKKOS_FUNCTION double jacobian_11(ddc::Coordinate<R, Theta> const& coord) const
244 {
245 const double r = ddc::get<R>(coord);
246 const double theta = ddc::get<Theta>(coord);
247 return -Kokkos::cos(theta)
248 / Kokkos::sqrt(m_epsilon * (m_epsilon + 2.0 * r * Kokkos::cos(theta)) + 1.0);
249 }
250
262 KOKKOS_FUNCTION double jacobian_12(ddc::Coordinate<R, Theta> const& coord) const
263 {
264 const double r = ddc::get<R>(coord);
265 const double theta = ddc::get<Theta>(coord);
266 return r * Kokkos::sin(theta)
267 / Kokkos::sqrt(m_epsilon * (m_epsilon + 2.0 * r * Kokkos::cos(theta)) + 1.0);
268 }
269
281 KOKKOS_FUNCTION double jacobian_21(ddc::Coordinate<R, Theta> const& coord) const
282 {
283 const double r = ddc::get<R>(coord);
284 const double theta = ddc::get<Theta>(coord);
285
286 const double sin_theta = Kokkos::sin(theta);
287 const double cos_theta = Kokkos::cos(theta);
288 const double xi2 = 1. / (1. - m_epsilon * m_epsilon * 0.25);
289 const double xi = Kokkos::sqrt(xi2);
290 const double tmp1 = Kokkos::sqrt(m_epsilon * (m_epsilon + 2.0 * r * cos_theta) + 1.0);
291 const double tmp2 = 2.0 - tmp1;
292 return m_e * m_epsilon * r * sin_theta * cos_theta * xi / (tmp2 * tmp2 * tmp1)
293 + m_e * sin_theta * xi / tmp2;
294 }
295
307 KOKKOS_FUNCTION double jacobian_22(ddc::Coordinate<R, Theta> const& coord) const
308 {
309 const double r = ddc::get<R>(coord);
310 const double theta = ddc::get<Theta>(coord);
311
312 const double sin_theta = Kokkos::sin(theta);
313 const double cos_theta = Kokkos::cos(theta);
314 const double xi2 = 1. / (1. - m_epsilon * m_epsilon * 0.25);
315 const double xi = Kokkos::sqrt(xi2);
316 const double tmp1 = Kokkos::sqrt(m_epsilon * (m_epsilon + 2.0 * r * cos_theta) + 1.0);
317 const double tmp2 = 2.0 - tmp1;
318 return r
319 * (-m_e * m_epsilon * r * sin_theta * sin_theta * xi / (tmp2 * tmp2 * tmp1)
320 + m_e * cos_theta * xi / tmp2);
321 }
322
342 KOKKOS_FUNCTION void inv_jacobian_matrix(
343 ddc::Coordinate<R, Theta> const& coord,
344 Matrix_2x2& matrix) const
345 {
346 const double r = ddc::get<R>(coord);
347 const double theta = ddc::get<Theta>(coord);
348
349 assert(r >= 1e-15);
350
351 const double sin_theta = Kokkos::sin(theta);
352 const double cos_theta = Kokkos::cos(theta);
353 const double xi = Kokkos::sqrt(1. / (1. - m_epsilon * m_epsilon * 0.25));
354 const double divisor = 2 - Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
355
356 const double fact_1 = 1 / Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
357 const double fact_2 = m_e * m_epsilon * xi * r * sin_theta * fact_1 / divisor / divisor;
358 const double fact_3 = m_e * xi / divisor;
359
360 matrix[0][0] = -1 / fact_1 * (-sin_theta * fact_2 + cos_theta * fact_3) / fact_3;
361 matrix[0][1] = sin_theta / fact_3;
362 matrix[1][0] = 1 / r / fact_1 * (cos_theta * fact_2 + sin_theta * fact_3) / fact_3;
363 matrix[1][1] = 1 / r * cos_theta / fact_3;
364 }
365
376 KOKKOS_FUNCTION double inv_jacobian_11(ddc::Coordinate<R, Theta> const& coord) const
377 {
378 const double r = ddc::get<R>(coord);
379 const double theta = ddc::get<Theta>(coord);
380
381 const double sin_theta = Kokkos::sin(theta);
382 const double cos_theta = Kokkos::cos(theta);
383 const double xi = Kokkos::sqrt(1. / (1. - m_epsilon * m_epsilon * 0.25));
384 const double divisor = 2 - Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
385
386 const double fact_1 = 1 / Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
387 const double fact_2 = m_e * m_epsilon * xi * r * sin_theta * fact_1 / divisor / divisor;
388 const double fact_3 = m_e * xi / divisor;
389
390 return -1 / fact_1 * (-sin_theta * fact_2 + cos_theta * fact_3) / fact_3;
391 }
392
403 KOKKOS_FUNCTION double inv_jacobian_12(ddc::Coordinate<R, Theta> const& coord) const
404 {
405 const double r = ddc::get<R>(coord);
406 const double theta = ddc::get<Theta>(coord);
407
408 const double sin_theta = Kokkos::sin(theta);
409 const double cos_theta = Kokkos::cos(theta);
410 const double xi = Kokkos::sqrt(1. / (1. - m_epsilon * m_epsilon * 0.25));
411 const double divisor = 2 - Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
412
413 const double fact_3 = m_e * xi / divisor;
414 return sin_theta / fact_3;
415 }
416
427 KOKKOS_FUNCTION double inv_jacobian_21(ddc::Coordinate<R, Theta> const& coord) const
428 {
429 const double r = ddc::get<R>(coord);
430 const double theta = ddc::get<Theta>(coord);
431
432 assert(r >= 1e-15);
433
434 const double sin_theta = Kokkos::sin(theta);
435 const double cos_theta = Kokkos::cos(theta);
436 const double xi = Kokkos::sqrt(1. / (1. - m_epsilon * m_epsilon * 0.25));
437 const double divisor = 2 - Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
438
439 const double fact_1 = 1 / Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
440 const double fact_2 = m_e * m_epsilon * xi * r * sin_theta * fact_1 / divisor / divisor;
441 const double fact_3 = m_e * xi / divisor;
442
443 return 1 / r / fact_1 * (cos_theta * fact_2 + sin_theta * fact_3) / fact_3;
444 }
445
456 KOKKOS_FUNCTION double inv_jacobian_22(ddc::Coordinate<R, Theta> const& coord) const
457 {
458 const double r = ddc::get<R>(coord);
459 const double theta = ddc::get<Theta>(coord);
460
461 assert(r >= 1e-15);
462
463 const double cos_theta = Kokkos::cos(theta);
464 const double xi = Kokkos::sqrt(1. / (1. - m_epsilon * m_epsilon * 0.25));
465 const double divisor = 2 - Kokkos::sqrt(1 + m_epsilon * (m_epsilon + 2.0 * r * cos_theta));
466
467 const double fact_3 = m_e * xi / divisor;
468 return 1 / r * cos_theta / fact_3;
469 }
470
480};
481
482namespace mapping_detail {
483template <class X, class Y, class R, class Theta, class ExecSpace>
484struct MappingAccessibility<ExecSpace, CzarnyToCartesian<R, Theta, X, Y>> : std::true_type
485{
486};
487
488template <class X, class Y, class R, class Theta>
489struct IsCurvilinear2DMapping<CzarnyToCartesian<X, Y, R, Theta>> : std::true_type
490{
491};
492
493template <class X, class Y, class R, class Theta>
494struct SingularOPointInvJacobian<CzarnyToCartesian<R, Theta, X, Y>> : std::true_type
495{
496};
497
498} // namespace mapping_detail
A class for describing the Czarny 2D mapping.
Definition cartesian_to_czarny.hpp:27
A class for describing the Czarny 2D mapping.
Definition czarny_to_cartesian.hpp:50
KOKKOS_FUNCTION double e() const
Return the parameter.
Definition czarny_to_cartesian.hpp:145
ddc::Coordinate< R, Theta > CoordArg
The type of the argument of the function described by this mapping.
Definition czarny_to_cartesian.hpp:62
KOKKOS_FUNCTION double inv_jacobian_22(ddc::Coordinate< R, Theta > const &coord) const
Compute the (2,2) coefficient of the inverse Jacobian matrix.
Definition czarny_to_cartesian.hpp:456
KOKKOS_FUNCTION double inv_jacobian_12(ddc::Coordinate< R, Theta > const &coord) const
Compute the (1,2) coefficient of the inverse Jacobian matrix.
Definition czarny_to_cartesian.hpp:403
ddc::Coordinate< X, Y > CoordResult
The type of the result of the function described by this mapping.
Definition czarny_to_cartesian.hpp:64
CartesianToCzarny< X, Y, R, Theta > get_inverse_mapping() const
Get the inverse mapping.
Definition czarny_to_cartesian.hpp:476
KOKKOS_FUNCTION double inv_jacobian_21(ddc::Coordinate< R, Theta > const &coord) const
Compute the (2,1) coefficient of the inverse Jacobian matrix.
Definition czarny_to_cartesian.hpp:427
KOKKOS_FUNCTION double epsilon() const
Return the parameter.
Definition czarny_to_cartesian.hpp:133
KOKKOS_FUNCTION double inv_jacobian_11(ddc::Coordinate< R, Theta > const &coord) const
Compute the (1,1) coefficient of the inverse Jacobian matrix.
Definition czarny_to_cartesian.hpp:376
KOKKOS_FUNCTION double jacobian_11(ddc::Coordinate< R, Theta > const &coord) const
Compute the (1,1) coefficient of the Jacobian matrix.
Definition czarny_to_cartesian.hpp:243
CzarnyToCartesian & operator=(CzarnyToCartesian const &x)=default
Assign a CzarnyToCartesian from another CzarnyToCartesian (lvalue).
KOKKOS_FUNCTION void jacobian_matrix(ddc::Coordinate< R, Theta > const &coord, Matrix_2x2 &matrix) const
Compute full Jacobian matrix.
Definition czarny_to_cartesian.hpp:208
KOKKOS_FUNCTION double jacobian_12(ddc::Coordinate< R, Theta > const &coord) const
Compute the (1,2) coefficient of the Jacobian matrix.
Definition czarny_to_cartesian.hpp:262
KOKKOS_FUNCTION ddc::Coordinate< X, Y > operator()(ddc::Coordinate< R, Theta > const &coord) const
Convert the coordinate to the equivalent (x,y) coordinate.
Definition czarny_to_cartesian.hpp:157
CzarnyToCartesian(double epsilon, double e)
Instantiate a CzarnyToCartesian from parameters.
Definition czarny_to_cartesian.hpp:82
KOKKOS_FUNCTION double jacobian_22(ddc::Coordinate< R, Theta > const &coord) const
Compute the (2,2) coefficient of the Jacobian matrix.
Definition czarny_to_cartesian.hpp:307
CzarnyToCartesian(CzarnyToCartesian &&x)=default
Instantiate a CzarnyToCartesian from another temporary CzarnyToCartesian (rvalue).
KOKKOS_FUNCTION CzarnyToCartesian(CzarnyToCartesian const &other)
Instantiate a CzarnyToCartesian from another CzarnyToCartesian (lvalue).
Definition czarny_to_cartesian.hpp:90
KOKKOS_FUNCTION void inv_jacobian_matrix(ddc::Coordinate< R, Theta > const &coord, Matrix_2x2 &matrix) const
Compute full inverse Jacobian matrix.
Definition czarny_to_cartesian.hpp:342
KOKKOS_FUNCTION double jacobian_21(ddc::Coordinate< R, Theta > const &coord) const
Compute the (2,1) coefficient of the Jacobian matrix.
Definition czarny_to_cartesian.hpp:281
CzarnyToCartesian & operator=(CzarnyToCartesian &&x)=default
Assign a CzarnyToCartesian from another temporary CzarnyToCartesian (rvalue).
KOKKOS_FUNCTION double jacobian(ddc::Coordinate< R, Theta > const &coord) const
Compute the Jacobian, the determinant of the Jacobian matrix of the mapping.
Definition czarny_to_cartesian.hpp:179
Define non periodic real R dimension.
Definition geometry.hpp:31
Define periodic real Theta dimension.
Definition geometry.hpp:42
Define non periodic real X dimension.
Definition geometry.hpp:278
Define non periodic real Y dimension.
Definition geometry.hpp:289