Gyselalib++
discrete_to_cartesian.hpp
1 // SPDX-License-Identifier: MIT
2 #pragma once
3 #include <iostream>
4 
5 #include <ddc/ddc.hpp>
6 
7 #include <sll/view.hpp>
8 
9 #include "coordinate_converter.hpp"
10 #include "curvilinear2d_to_cartesian.hpp"
11 #include "jacobian.hpp"
12 #include "mapping_tools.hpp"
13 #include "pseudo_cartesian_compatible_mapping.hpp"
14 
29 template <
30  class X,
31  class Y,
32  class SplineEvaluator,
33  class R = typename SplineEvaluator::continuous_dimension_type1,
34  class Theta = typename SplineEvaluator::continuous_dimension_type2,
35  class MemorySpace = typename SplineEvaluator::memory_space>
37  : public CoordinateConverter<ddc::Coordinate<R, Theta>, ddc::Coordinate<X, Y>>
38  , public NonAnalyticalJacobian<ddc::Coordinate<R, Theta>>
40  , public Curvilinear2DToCartesian<X, Y, R, Theta>
41 {
42  static_assert(std::is_same_v<MemorySpace, typename SplineEvaluator::memory_space>);
43 
44 public:
48  using BSplineR = typename SplineEvaluator::bsplines_type1;
52  using BSplineTheta = typename SplineEvaluator::bsplines_type2;
53 
63 
65  using CoordArg = ddc::Coordinate<R, Theta>;
67  using CoordResult = ddc::Coordinate<X, Y>;
68 
69 private:
70  using spline_idx_range = ddc::DiscreteDomain<BSplineR, BSplineTheta>;
71 
72  using SplineType = ddc::
73  ChunkView<double, spline_idx_range, std::experimental::layout_right, MemorySpace>;
74 
75  using IdxRangeTheta = typename SplineEvaluator::evaluation_domain_type2;
76  using IdxTheta = typename IdxRangeTheta::discrete_element_type;
77 
78 private:
79  SplineType m_x_spline_representation;
80  SplineType m_y_spline_representation;
81  SplineEvaluator m_spline_evaluator;
82  IdxRangeTheta m_idx_range_theta;
83 
84 public:
116  KOKKOS_FUNCTION DiscreteToCartesian(
117  SplineType curvilinear_to_x,
118  SplineType curvilinear_to_y,
119  SplineEvaluator const& evaluator,
120  IdxRangeTheta idx_range_theta)
121  : m_x_spline_representation(curvilinear_to_x)
122  , m_y_spline_representation(curvilinear_to_y)
123  , m_spline_evaluator(evaluator)
124  , m_idx_range_theta(idx_range_theta)
125  {
126  }
127 
141  KOKKOS_FUNCTION ddc::Coordinate<X, Y> operator()(
142  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const& coord) const final
143  {
144  const double x = m_spline_evaluator(coord, m_x_spline_representation.span_cview());
145  const double y = m_spline_evaluator(coord, m_y_spline_representation.span_cview());
146  return ddc::Coordinate<X, Y>(x, y);
147  }
148 
167  KOKKOS_FUNCTION void jacobian_matrix(
168  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const& coord,
169  Matrix_2x2& matrix) const final
170  {
171  matrix[0][0]
172  = m_spline_evaluator.deriv_dim_1(coord, m_x_spline_representation.span_cview());
173  matrix[0][1]
174  = m_spline_evaluator.deriv_dim_2(coord, m_x_spline_representation.span_cview());
175  matrix[1][0]
176  = m_spline_evaluator.deriv_dim_1(coord, m_y_spline_representation.span_cview());
177  matrix[1][1]
178  = m_spline_evaluator.deriv_dim_2(coord, m_y_spline_representation.span_cview());
179  }
180 
197  KOKKOS_FUNCTION double jacobian_11(
198  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const& coord) const final
199  {
200  return m_spline_evaluator.deriv_dim_1(coord, m_x_spline_representation.span_cview());
201  }
202 
219  KOKKOS_FUNCTION double jacobian_12(
220  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const& coord) const final
221  {
222  return m_spline_evaluator.deriv_dim_2(coord, m_x_spline_representation.span_cview());
223  }
224 
241  KOKKOS_FUNCTION double jacobian_21(
242  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const& coord) const final
243  {
244  return m_spline_evaluator.deriv_dim_1(coord, m_y_spline_representation.span_cview());
245  }
246 
263  KOKKOS_FUNCTION double jacobian_22(
264  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const& coord) const final
265  {
266  return m_spline_evaluator.deriv_dim_2(coord, m_y_spline_representation.span_cview());
267  }
268 
269 
270 
314  KOKKOS_FUNCTION void to_pseudo_cartesian_jacobian_center_matrix(Matrix_2x2& matrix) const final
315  {
316  matrix[0][0] = 0;
317  matrix[0][1] = 0;
318  matrix[1][0] = 0;
319  matrix[1][1] = 0;
320 
321  // Average the values at (r = 0, theta):
322  for (IdxTheta ip : m_idx_range_theta) {
323  const double th = ddc::coordinate(ip);
324  ddc::Coordinate<curvilinear_tag_r, curvilinear_tag_theta> const coord(0, th);
325  double const deriv_1_x
326  = m_spline_evaluator.deriv_dim_1(coord, m_x_spline_representation.span_cview());
327  double const deriv_1_2_x
328  = m_spline_evaluator
329  .deriv_1_and_2(coord, m_x_spline_representation.span_cview());
330  double const deriv_1_y
331  = m_spline_evaluator.deriv_dim_1(coord, m_y_spline_representation.span_cview());
332  double const deriv_1_2_y
333  = m_spline_evaluator
334  .deriv_1_and_2(coord, m_y_spline_representation.span_cview());
335 
336  // Matrix from pseudo-Cart domain to physical domain by logical domain
337  double const j11 = deriv_1_x * Kokkos::cos(th) - deriv_1_2_x * Kokkos::sin(th);
338  double const j12 = deriv_1_x * Kokkos::sin(th) + deriv_1_2_x * Kokkos::cos(th);
339  double const j21 = deriv_1_y * Kokkos::cos(th) - deriv_1_2_y * Kokkos::sin(th);
340  double const j22 = deriv_1_y * Kokkos::sin(th) + deriv_1_2_y * Kokkos::cos(th);
341 
342  double const jacobian = j11 * j22 - j12 * j21;
343  // Matrix from physical domain to pseudo_cart domain by logical domain
344  assert(fabs(jacobian) >= 1e-16);
345 
346  matrix[0][0] += j22 / jacobian;
347  matrix[0][1] += -j12 / jacobian;
348  matrix[1][0] += -j21 / jacobian;
349  matrix[1][1] += j11 / jacobian;
350  }
351 
352  int const theta_size = m_idx_range_theta.size();
353  matrix[0][0] /= theta_size;
354  matrix[0][1] /= theta_size;
355  matrix[1][0] /= theta_size;
356  matrix[1][1] /= theta_size;
357  }
358 
359 
367  KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_11_center() const final
368  {
371  return jacobian[0][0];
372  }
373 
374 
382  KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_12_center() const final
383  {
386  return jacobian[0][1];
387  }
388 
389 
397  KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_21_center() const final
398  {
401  return jacobian[1][0];
402  }
403 
404 
412  KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_22_center() const final
413  {
416  return jacobian[1][1];
417  }
418 
447  KOKKOS_INLINE_FUNCTION const ddc::Coordinate<X, Y> control_point(
448  ddc::DiscreteElement<BSplineR, BSplineTheta> const& el) const
449  {
450  return ddc::Coordinate<X, Y>(m_x_spline_representation(el), m_y_spline_representation(el));
451  }
452 };
453 
454 
455 namespace mapping_detail {
456 template <
457  class X,
458  class Y,
459  class SplineEvaluator,
460  class R,
461  class Theta,
462  class MemorySpace,
463  class ExecSpace>
464 struct MappingAccessibility<
465  ExecSpace,
466  DiscreteToCartesian<X, Y, SplineEvaluator, R, Theta, MemorySpace>>
467 {
468  static constexpr bool value = Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible;
469 };
470 } // namespace mapping_detail
An operator to convert from the start coordinate type to the end coordinate type.
Definition: coordinate_converter.hpp:13
A class for describing curvilinear 2D mappings from the logical domain to the physical domain.
Definition: curvilinear2d_to_cartesian.hpp:9
A class for describing discrete 2D mappings from the logical domain to the physical domain.
Definition: discrete_to_cartesian.hpp:41
KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_11_center() const final
Compute the (1,1) coefficient of the pseudo-Cartesian Jacobian matrix at the central point.
Definition: discrete_to_cartesian.hpp:367
typename Curvilinear2DToCartesian< X, Y, R, Theta >::curvilinear_tag_theta curvilinear_tag_theta
Indicate the second logical coordinate.
Definition: discrete_to_cartesian.hpp:62
KOKKOS_FUNCTION double jacobian_21(ddc::Coordinate< curvilinear_tag_r, curvilinear_tag_theta > const &coord) const final
Compute the (2,1) coefficient of the Jacobian matrix.
Definition: discrete_to_cartesian.hpp:241
KOKKOS_FUNCTION double jacobian_22(ddc::Coordinate< curvilinear_tag_r, curvilinear_tag_theta > const &coord) const final
Compute the (2,2) coefficient of the Jacobian matrix.
Definition: discrete_to_cartesian.hpp:263
KOKKOS_FUNCTION double jacobian_12(ddc::Coordinate< curvilinear_tag_r, curvilinear_tag_theta > const &coord) const final
Compute the (1,2) coefficient of the Jacobian matrix.
Definition: discrete_to_cartesian.hpp:219
KOKKOS_FUNCTION void to_pseudo_cartesian_jacobian_center_matrix(Matrix_2x2 &matrix) const final
Compute the full Jacobian matrix from the mapping to the pseudo-Cartesian mapping at the central poin...
Definition: discrete_to_cartesian.hpp:314
ddc::Coordinate< X, Y > CoordResult
The type of the result of the function described by this mapping.
Definition: discrete_to_cartesian.hpp:67
typename Curvilinear2DToCartesian< X, Y, R, Theta >::cartesian_tag_y cartesian_tag_y
Indicate the second physical coordinate.
Definition: discrete_to_cartesian.hpp:57
typename SplineEvaluator::bsplines_type1 BSplineR
Indicate the bspline type of the first logical dimension.
Definition: discrete_to_cartesian.hpp:48
typename Curvilinear2DToCartesian< X, Y, R, Theta >::cartesian_tag_x cartesian_tag_x
Indicate the first physical coordinate.
Definition: discrete_to_cartesian.hpp:55
KOKKOS_FUNCTION void jacobian_matrix(ddc::Coordinate< curvilinear_tag_r, curvilinear_tag_theta > const &coord, Matrix_2x2 &matrix) const final
Compute full Jacobian matrix.
Definition: discrete_to_cartesian.hpp:167
typename Curvilinear2DToCartesian< X, Y, R, Theta >::curvilinear_tag_r curvilinear_tag_r
Indicate the first logical coordinate.
Definition: discrete_to_cartesian.hpp:59
KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_12_center() const final
Compute the (1,2) coefficient of the pseudo-Cartesian Jacobian matrix at the central point.
Definition: discrete_to_cartesian.hpp:382
KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_21_center() const final
Compute the (2,1) coefficient of the pseudo-Cartesian Jacobian matrix at the central point.
Definition: discrete_to_cartesian.hpp:397
KOKKOS_FUNCTION double to_pseudo_cartesian_jacobian_22_center() const final
Compute the (2,2) coefficient of the pseudo-Cartesian Jacobian matrix at the central point.
Definition: discrete_to_cartesian.hpp:412
KOKKOS_FUNCTION ddc::Coordinate< X, Y > operator()(ddc::Coordinate< curvilinear_tag_r, curvilinear_tag_theta > const &coord) const final
Compute the physical coordinates from the logical coordinates.
Definition: discrete_to_cartesian.hpp:141
ddc::Coordinate< R, Theta > CoordArg
The type of the argument of the function described by this mapping.
Definition: discrete_to_cartesian.hpp:65
KOKKOS_INLINE_FUNCTION const ddc::Coordinate< X, Y > control_point(ddc::DiscreteElement< BSplineR, BSplineTheta > const &el) const
Get a control point of the mapping on B-splines.
Definition: discrete_to_cartesian.hpp:447
KOKKOS_FUNCTION double jacobian_11(ddc::Coordinate< curvilinear_tag_r, curvilinear_tag_theta > const &coord) const final
Compute the (1,1) coefficient of the Jacobian matrix.
Definition: discrete_to_cartesian.hpp:197
KOKKOS_FUNCTION DiscreteToCartesian(SplineType curvilinear_to_x, SplineType curvilinear_to_y, SplineEvaluator const &evaluator, IdxRangeTheta idx_range_theta)
Instantiate a DiscreteToCartesian from the coefficients of 2D splines approximating the mapping.
Definition: discrete_to_cartesian.hpp:116
typename SplineEvaluator::bsplines_type2 BSplineTheta
Indicate the bspline type of the second logical dimension.
Definition: discrete_to_cartesian.hpp:52
A specialisation of Jacobian to handle non-analytical terms.
Definition: jacobian.hpp:184
KOKKOS_FUNCTION double jacobian(ddc::Coordinate< typename SplineEvaluator::continuous_dimension_type1, typename SplineEvaluator::continuous_dimension_type2 > const &coord) const final
Compute the Jacobian, the determinant of the Jacobian matrix of the mapping.
Definition: jacobian.hpp:194
An operator to calculate the Jacobian matrix of the mapping from the physical domain to the pseudo-Ca...
Definition: pseudo_cartesian_compatible_mapping.hpp:42
std::array< std::array< double, 2 >, 2 > Matrix_2x2
The type of the pseudo-Cartesian Jacobian matrix and its inverse.
Definition: pseudo_cartesian_compatible_mapping.hpp:45
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