Gyselalib++
 
Loading...
Searching...
No Matches
discrete_mapping_builder.hpp
1// SPDX-License-Identifier: MIT
2#pragma once
3
4#include <ddc/ddc.hpp>
5#include <ddc/kernels/splines.hpp>
6
7#include "discrete_to_cartesian.hpp"
8
19template <class X, class Y, class SplineBuilder, class SplineEvaluator>
21{
22 static_assert(std::is_same_v<
23 typename SplineBuilder::memory_space,
24 typename SplineEvaluator::memory_space>);
25 static_assert(std::is_same_v<
26 typename SplineBuilder::exec_space,
27 typename SplineEvaluator::exec_space>);
28 static_assert(std::is_same_v<typename SplineBuilder::batch_domain_type, ddc::DiscreteDomain<>>);
29
30public:
33
34private:
35 using ExecSpace = typename SplineBuilder::exec_space;
36 using MemorySpace = typename SplineBuilder::memory_space;
37
38 using BSplinesR = typename SplineBuilder::bsplines_type1;
39 using BSplinesTheta = typename SplineBuilder::bsplines_type2;
40
41 using GridR = typename SplineBuilder::interpolation_domain_type1;
42 using GridTheta = typename SplineBuilder::interpolation_domain_type2;
43
44 using IdxRangeSplines = ddc::DiscreteDomain<BSplinesR, BSplinesTheta>;
45 using IdxRangeInterpolationPoints = typename SplineBuilder::interpolation_domain_type;
46 using IdxInterpolationPoints = typename IdxRangeInterpolationPoints::discrete_element_type;
47
48 using SplineCoeffsMem
49 = ddc::Chunk<double, IdxRangeSplines, ddc::KokkosAllocator<double, MemorySpace>>;
50
51 using SplineCoeffs = typename SplineCoeffsMem::span_type;
52
53 using InterpolationFieldMem = ddc::
54 Chunk<double, IdxRangeInterpolationPoints, ddc::KokkosAllocator<double, MemorySpace>>;
55
56 using InterpolationField = typename InterpolationFieldMem::span_type;
57
58private:
59 SplineCoeffsMem m_curvilinear_to_x_spline_alloc;
60 SplineCoeffsMem m_curvilinear_to_y_spline_alloc;
61 SplineEvaluator m_evaluator;
62 ddc::DiscreteDomain<GridR, GridTheta> m_idx_range_singular_point;
63
64public:
73 template <class Mapping>
75 ExecSpace exec_space,
76 Mapping const& analytical_mapping,
77 SplineBuilder const& builder,
78 SplineEvaluator const& evaluator)
79 : m_curvilinear_to_x_spline_alloc(builder.spline_domain())
80 , m_curvilinear_to_y_spline_alloc(builder.spline_domain())
81 , m_evaluator(evaluator)
82 {
83 SplineCoeffs curvilinear_to_x_spline = m_curvilinear_to_x_spline_alloc.span_view();
84 SplineCoeffs curvilinear_to_y_spline = m_curvilinear_to_y_spline_alloc.span_view();
85 InterpolationFieldMem curvilinear_to_x_vals_alloc(builder.interpolation_domain());
86 InterpolationFieldMem curvilinear_to_y_vals_alloc(builder.interpolation_domain());
87 InterpolationField curvilinear_to_x_vals = curvilinear_to_x_vals_alloc.span_view();
88 InterpolationField curvilinear_to_y_vals = curvilinear_to_y_vals_alloc.span_view();
89
91 curvilinear_to_x_vals,
92 curvilinear_to_y_vals,
93 analytical_mapping,
94 builder.interpolation_domain());
95
96 builder(curvilinear_to_x_spline.span_view(), curvilinear_to_x_vals.span_cview());
97 builder(curvilinear_to_y_spline.span_view(), curvilinear_to_y_vals.span_cview());
98
99 ddc::DiscreteDomain<GridR, GridTheta> interp_domain(builder.interpolation_domain());
100 ddc::DiscreteVector<GridR, GridTheta>
101 n_points_singular_domain(1, interp_domain.template extent<GridTheta>().value());
102 m_idx_range_singular_point = interp_domain.take_first(n_points_singular_domain);
103 }
104
111 {
113 m_curvilinear_to_x_spline_alloc.span_cview(),
114 m_curvilinear_to_y_spline_alloc.span_cview(),
115 m_evaluator,
116 m_idx_range_singular_point);
117 }
118
131 template <class Mapping>
133 InterpolationField const& curvilinear_to_x_vals,
134 InterpolationField const& curvilinear_to_y_vals,
135 Mapping const& analytical_mapping,
136 IdxRangeInterpolationPoints const& interpolation_idx_range)
137 {
138 using CurvilinearCoeff = ddc::Coordinate<
139 typename Mapping::curvilinear_tag_r,
140 typename Mapping::curvilinear_tag_theta>;
141 using CartesianCoeff = ddc::Coordinate<X, Y>;
142
143 ddc::parallel_for_each(
144 ExecSpace(),
145 interpolation_idx_range,
146 KOKKOS_LAMBDA(IdxInterpolationPoints el) {
147 CurvilinearCoeff polar_coord(ddc::coordinate(el));
148 CartesianCoeff cart_coord = analytical_mapping(polar_coord);
149 curvilinear_to_x_vals(el) = ddc::select<X>(cart_coord);
150 curvilinear_to_y_vals(el) = ddc::select<Y>(cart_coord);
151 });
152 }
153};
154
169template <
170 class X,
171 class Y,
172 class SplineBuilder,
173 class SplineEvaluator,
174 int ncells_r,
175 int ncells_theta>
177{
178 static_assert(std::is_same_v<
179 typename SplineBuilder::memory_space,
180 typename SplineEvaluator::memory_space>);
181 static_assert(std::is_same_v<
182 typename SplineBuilder::exec_space,
183 typename SplineEvaluator::exec_space>);
184
185private:
186 using ExecSpace = typename SplineBuilder::exec_space;
187 using MemorySpace = typename SplineBuilder::memory_space;
188
189 using BSplinesROriginal = typename SplineBuilder::bsplines_type1;
190 using BSplinesThetaOriginal = typename SplineBuilder::bsplines_type2;
191
192 using R = typename BSplinesROriginal::continuous_dimension_type;
193 using Theta = typename BSplinesThetaOriginal::continuous_dimension_type;
194
195public:
198 : std::conditional_t<
199 BSplinesROriginal::is_uniform(),
200 ddc::UniformBSplines<R, BSplinesROriginal::degree()>,
201 ddc::NonUniformBSplines<R, BSplinesROriginal::degree()>>
202 {
203 };
204
207 : std::conditional_t<
208 BSplinesThetaOriginal::is_uniform(),
209 ddc::UniformBSplines<Theta, BSplinesThetaOriginal::degree()>,
210 ddc::NonUniformBSplines<Theta, BSplinesThetaOriginal::degree()>>
211 {
212 };
213
214private:
215 using GrevillePointsR = ddc::GrevilleInterpolationPoints<
217 SplineBuilder::builder_type1::s_bc_xmin,
218 SplineBuilder::builder_type1::s_bc_xmax>;
219
220 using GrevillePointsTheta = ddc::GrevilleInterpolationPoints<
222 SplineBuilder::builder_type2::s_bc_xmin,
223 SplineBuilder::builder_type2::s_bc_xmax>;
224
225public:
227 struct GridRRefined : GrevillePointsR::interpolation_discrete_dimension_type
228 {
229 };
230
232 struct GridThetaRefined : GrevillePointsTheta::interpolation_discrete_dimension_type
233 {
234 };
235
236private:
237 using GridROriginal = typename SplineBuilder::interpolation_domain_type1;
238 using GridThetaOriginal = typename SplineBuilder::interpolation_domain_type2;
239
240 template <class Builder>
241 struct Build_BuilderType;
242
243 template <
244 ddc::BoundCond BcLower1,
245 ddc::BoundCond BcUpper1,
246 ddc::BoundCond BcLower2,
247 ddc::BoundCond BcUpper2,
248 ddc::SplineSolver Solver>
249 struct Build_BuilderType<ddc::SplineBuilder2D<
250 ExecSpace,
251 MemorySpace,
252 BSplinesROriginal,
253 BSplinesThetaOriginal,
254 GridROriginal,
255 GridThetaOriginal,
256 BcLower1,
257 BcUpper1,
258 BcLower2,
259 BcUpper2,
260 Solver,
261 GridROriginal,
262 GridThetaOriginal>>
263 {
264 using type = ddc::SplineBuilder2D<
265 ExecSpace,
266 MemorySpace,
271 BcLower1,
272 BcUpper1,
273 BcLower2,
274 BcUpper2,
275 Solver,
278 };
279
280 using RefinedSplineBuilder = typename Build_BuilderType<SplineBuilder>::type;
281
282 using RefinedSplineEvaluator = ddc::SplineEvaluator2D<
283 ExecSpace,
284 MemorySpace,
285 BSplinesRRefined,
286 BSplinesThetaRefined,
287 GridRRefined,
288 GridThetaRefined,
289 typename SplineEvaluator::lower_extrapolation_rule_1_type,
290 typename SplineEvaluator::upper_extrapolation_rule_1_type,
291 typename SplineEvaluator::lower_extrapolation_rule_2_type,
292 typename SplineEvaluator::upper_extrapolation_rule_2_type,
293 GridRRefined,
294 GridThetaRefined>;
295
296 using IdxRangeSplines = ddc::DiscreteDomain<BSplinesRRefined, BSplinesThetaRefined>;
297 using IdxRangeInterpolationPoints = ddc::DiscreteDomain<GridRRefined, GridThetaRefined>;
298 using IdxInterpolationPoints = typename IdxRangeInterpolationPoints::discrete_element_type;
299
300 using SplineCoeffsMem
301 = ddc::Chunk<double, IdxRangeSplines, ddc::KokkosAllocator<double, MemorySpace>>;
302
303 using SplineCoeffs = typename SplineCoeffsMem::span_type;
304
305 using InterpolationFieldMem = ddc::
306 Chunk<double, IdxRangeInterpolationPoints, ddc::KokkosAllocator<double, MemorySpace>>;
307
308 using InterpolationField = typename InterpolationFieldMem::span_type;
309
310public:
313
314private:
315 SplineCoeffsMem m_curvilinear_to_x_spline_alloc;
316 SplineCoeffsMem m_curvilinear_to_y_spline_alloc;
317 RefinedSplineEvaluator m_evaluator;
318 ddc::DiscreteDomain<GridRRefined, GridThetaRefined> m_idx_range_singular_point;
319
320public:
329 template <class Mapping>
331 ExecSpace exec_space,
332 Mapping const& analytical_mapping,
333 SplineBuilder const& builder,
334 SplineEvaluator const& evaluator)
335 : m_evaluator(
336 evaluator.lower_extrapolation_rule_dim_1(),
337 evaluator.upper_extrapolation_rule_dim_1(),
338 evaluator.lower_extrapolation_rule_dim_2(),
339 evaluator.upper_extrapolation_rule_dim_2())
340 {
341 using CoordR = ddc::Coordinate<R>;
342 using CoordTheta = ddc::Coordinate<Theta>;
343
344 const CoordR r_min = ddc::discrete_space<BSplinesROriginal>().rmin();
345 const CoordR r_max = ddc::discrete_space<BSplinesROriginal>().rmax();
346
347 const CoordTheta theta_min = ddc::discrete_space<BSplinesThetaOriginal>().rmin();
348 const CoordTheta theta_max = ddc::discrete_space<BSplinesThetaOriginal>().rmax();
349
350 ddc::DiscreteVector<BSplinesRRefined> const r_ncells_idx_step(ncells_r);
351 ddc::DiscreteVector<BSplinesThetaRefined> const theta_ncells_idx_step(ncells_theta);
352
353 if constexpr (BSplinesRRefined::is_uniform()) {
354 ddc::init_discrete_space<BSplinesRRefined>(r_min, r_max, r_ncells_idx_step);
355 ddc::init_discrete_space<
356 BSplinesThetaRefined>(theta_min, theta_max, theta_ncells_idx_step);
357 } else {
358 double const dr((r_max - r_min) / ncells_r);
359 double const dp((theta_max - theta_min) / ncells_theta);
360
361 std::vector<CoordR> r_break_points(ncells_r + 1);
362 std::vector<CoordTheta> theta_break_points(ncells_theta + 1);
363
364 for (int i(0); i < ncells_r + 1; ++i) {
365 r_break_points[i] = r_min + i * dr;
366 }
367 for (int i(0); i < ncells_theta + 1; ++i) {
368 theta_break_points[i] = theta_min + i * dp;
369 }
370
371 ddc::init_discrete_space<BSplinesRRefined>(r_break_points);
372 ddc::init_discrete_space<BSplinesThetaRefined>(theta_break_points);
373 }
374
375 ddc::init_discrete_space<GridRRefined>(
376 GrevillePointsR::template get_sampling<GridRRefined>());
377 ddc::init_discrete_space<GridThetaRefined>(
378 GrevillePointsTheta::template get_sampling<GridThetaRefined>());
379
380 ddc::DiscreteDomain<GridRRefined> const interpolation_domain_r(
381 GrevillePointsR::template get_domain<GridRRefined>());
382 ddc::DiscreteDomain<GridThetaRefined> const interpolation_domain_theta(
383 GrevillePointsTheta::template get_domain<GridThetaRefined>());
384 ddc::DiscreteDomain<GridRRefined, GridThetaRefined> const
385 refined_domain(interpolation_domain_r, interpolation_domain_theta);
386
387 ddc::DiscreteVector<GridRRefined, GridThetaRefined> n_points_singular_domain(
388 1,
389 refined_domain.template extent<GridThetaRefined>().value());
390 m_idx_range_singular_point = refined_domain.take_first(n_points_singular_domain);
391
392 // Operators on the refined grid
393 RefinedSplineBuilder refined_builder(refined_domain);
394
395 ddc::DiscreteDomain<BSplinesRRefined, BSplinesThetaRefined> const spline_domain
396 = refined_builder.spline_domain();
397
398 // Compute the B-splines coefficients of the analytical mapping
399 m_curvilinear_to_x_spline_alloc = SplineCoeffsMem(spline_domain);
400 m_curvilinear_to_y_spline_alloc = SplineCoeffsMem(spline_domain);
401 SplineCoeffs curvilinear_to_x_spline = m_curvilinear_to_x_spline_alloc.span_view();
402 SplineCoeffs curvilinear_to_y_spline = m_curvilinear_to_y_spline_alloc.span_view();
403 InterpolationFieldMem curvilinear_to_x_vals_alloc(refined_domain);
404 InterpolationFieldMem curvilinear_to_y_vals_alloc(refined_domain);
405 InterpolationField curvilinear_to_x_vals = curvilinear_to_x_vals_alloc.span_view();
406 InterpolationField curvilinear_to_y_vals = curvilinear_to_y_vals_alloc.span_view();
407
409 curvilinear_to_x_vals,
410 curvilinear_to_y_vals,
411 analytical_mapping,
412 refined_builder.interpolation_domain());
413
414 refined_builder(curvilinear_to_x_spline, curvilinear_to_x_vals.span_cview());
415 refined_builder(curvilinear_to_y_spline, curvilinear_to_y_vals.span_cview());
416 }
417
424 {
426 m_curvilinear_to_x_spline_alloc.span_cview(),
427 m_curvilinear_to_y_spline_alloc.span_cview(),
428 m_evaluator,
429 m_idx_range_singular_point);
430 }
431
444 template <class Mapping>
446 InterpolationField curvilinear_to_x_vals,
447 InterpolationField curvilinear_to_y_vals,
448 Mapping const& analytical_mapping,
449 IdxRangeInterpolationPoints const& interpolation_idx_range)
450 {
451 using CurvilinearCoeff = ddc::Coordinate<
452 typename Mapping::curvilinear_tag_r,
453 typename Mapping::curvilinear_tag_theta>;
454 using CartesianCoeff = ddc::Coordinate<X, Y>;
455
456 ddc::parallel_for_each(
457 ExecSpace(),
458 interpolation_idx_range,
459 KOKKOS_LAMBDA(IdxInterpolationPoints el) {
460 CurvilinearCoeff polar_coord(ddc::coordinate(el));
461 CartesianCoeff cart_coord = analytical_mapping(polar_coord);
462 curvilinear_to_x_vals(el) = ddc::select<X>(cart_coord);
463 curvilinear_to_y_vals(el) = ddc::select<Y>(cart_coord);
464 });
465 }
466};
A class to create a DiscreteToCartesian instance from an analytical mapping.
Definition discrete_mapping_builder.hpp:21
void set_curvilinear_to_cartesian_values(InterpolationField const &curvilinear_to_x_vals, InterpolationField const &curvilinear_to_y_vals, Mapping const &analytical_mapping, IdxRangeInterpolationPoints const &interpolation_idx_range)
Fill in the curvilinear fields with interpolation points mapped with the given analytical mapping.
Definition discrete_mapping_builder.hpp:132
DiscreteToCartesianBuilder(ExecSpace exec_space, Mapping const &analytical_mapping, SplineBuilder const &builder, SplineEvaluator const &evaluator)
Create an instance of the class capable of providing a DiscreteToCartesian class instance.
Definition discrete_mapping_builder.hpp:74
DiscreteToCartesian< X, Y, SplineEvaluator > operator()() const
Get a DiscreteToCartesian class instance.
Definition discrete_mapping_builder.hpp:110
A class for describing discrete 2D mappings from the logical domain to the physical domain.
Definition discrete_to_cartesian.hpp:32
A class to create a DiscreteToCartesian instance from an analytical mapping.
Definition discrete_mapping_builder.hpp:177
RefinedDiscreteToCartesianBuilder(ExecSpace exec_space, Mapping const &analytical_mapping, SplineBuilder const &builder, SplineEvaluator const &evaluator)
Create an instance of the class capable of providing a DiscreteToCartesian class instance.
Definition discrete_mapping_builder.hpp:330
DiscreteToCartesian< X, Y, RefinedSplineEvaluator > operator()() const
Get a DiscreteToCartesian class instance.
Definition discrete_mapping_builder.hpp:423
void set_curvilinear_to_cartesian_values(InterpolationField curvilinear_to_x_vals, InterpolationField curvilinear_to_y_vals, Mapping const &analytical_mapping, IdxRangeInterpolationPoints const &interpolation_idx_range)
Fill in the curvilinear fields with interpolation points mapped with the given analytical mapping.
Definition discrete_mapping_builder.hpp:445
Definition geometry.hpp:93
Definition geometry.hpp:100
Definition geometry.hpp:116
Definition geometry.hpp:119
Define non periodic real R dimension.
Definition geometry.hpp:31
The type of the radial bsplines on which the new mapping will be defined.
Definition discrete_mapping_builder.hpp:202
The type of the poloidal bsplines on which the new mapping will be defined.
Definition discrete_mapping_builder.hpp:211
The type of the grid of radial points on which the new mapping will be defined.
Definition discrete_mapping_builder.hpp:228
The type of the grid of poloidal points on which the new mapping will be defined.
Definition discrete_mapping_builder.hpp:233
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