Gyselalib++
 
Loading...
Searching...
No Matches
CollisionSpVparMu.hpp
1// SPDX-License-Identifier: MIT
2#pragma once
3#include <ddc/ddc.hpp>
4
5#include "assert.hpp"
6#include "collisions_dimensions.hpp"
7#include "ddc_alias_inline_functions.hpp"
8#include "ddc_aliases.hpp"
9#include "ddc_helper.hpp"
10#include "koliop_interface.hpp"
11#include "species_info.hpp"
12
16template <
17 class CollInfo,
18 class IdxRangeFDistrib,
19 class GridVpar,
20 class GridMu,
21 class InputDFieldThetaR>
22class CollisionSpVparMu /* : public IRightHandSide */
23{
24private:
25 using InputDFieldR = typename CollInfo::radial_chunk_type;
26 using fdistrib_grids = ddc::to_type_seq_t<IdxRangeFDistrib>;
28 using GridTheta =
30 using InputThetaRTags =
32 using InputSpThetaRVparTags = ddc::type_seq_merge_t<
33 ddc::detail::TypeSeq<Species>,
34 ddc::type_seq_merge_t<InputThetaRTags, ddc::detail::TypeSeq<GridVpar>>>;
35 using InputIdxRangeSpThetaRVpar
36 = ddc::detail::convert_type_seq_to_discrete_domain_t<InputSpThetaRVparTags>;
37
38 // Validate template types
39 static_assert(ddc::is_discrete_domain_v<IdxRangeFDistrib>);
40 static_assert(IdxRangeFDistrib::rank() >= 3 && IdxRangeFDistrib::rank() <= 6);
41 static_assert((std::is_same_v<InputDFieldR, double>) || ddc::is_borrowed_chunk_v<InputDFieldR>);
42 static_assert(
43 (std::is_same_v<InputDFieldThetaR, double>)
44 || (ddc::is_borrowed_chunk_v<InputDFieldThetaR>));
45 // Ensure expected types appear in distribution index range
46 static_assert(
47 ddc::in_tags_v<Species, fdistrib_grids>,
48 "The distribution function must be defined over the species");
49 static_assert(
50 ddc::in_tags_v<GridVpar, fdistrib_grids>,
51 "The distribution function must be defined over the Vpar direction");
52 static_assert(
53 ddc::in_tags_v<GridMu, fdistrib_grids>,
54 "The distribution function must be defined over the Mu direction");
55 // Ensure that uniform
56 static_assert(
57 ddc::is_uniform_point_sampling_v<GridVpar>,
58 "The grid must be uniform in the vpar direction.");
59 static_assert(
60 ddc::is_uniform_point_sampling_v<GridMu>,
61 "The grid must be uniform in the mu direction.");
62
63 static_assert(
64 ddc::type_seq_rank_v<Species, fdistrib_grids> == 0,
65 "Species should be the first index in the distribution function index set");
66 static_assert(
67 collisions_dimensions::
68 order_of_last_grids<fdistrib_grids, GridTheta, GridR, GridVpar, GridMu>(),
69 "Misordered inex set for the distribution function. Koliop expects (Sp, Phi, Theta, R, "
70 "Vpar, Mu)");
71
72public:
74 using InputDFieldSpThetaRVpar = DConstField<InputIdxRangeSpThetaRVpar>;
75
77 using IdxRangeR = IdxRange<GridR>;
79 using IdxRangeThetaR = IdxRange<GridTheta, GridR>;
81 using IdxRangeSpThetaRVpar = IdxRange<Species, GridTheta, GridR, GridVpar>;
83 using IdxRangeMu = IdxRange<GridMu>;
85 using IdxRangeVpar = IdxRange<GridVpar>;
86
88 using IdxThetaR = Idx<GridTheta, GridR>;
90 using IdxSpThetaRVpar = Idx<Species, GridTheta, GridR, GridVpar>;
91
93 using DFieldMemR = DFieldMem<IdxRangeR>;
95 using DFieldMemMu = DFieldMem<IdxRangeMu>;
97 using DFieldMemVpar = DFieldMem<IdxRangeVpar>;
99 using DFieldMemThetaR = DFieldMem<IdxRangeThetaR>;
101 using DFieldMemSpThetaRVpar = DFieldMem<IdxRangeSpThetaRVpar>;
103 using DFieldR = DField<IdxRangeR>;
105 using DFieldThetaR = DField<IdxRangeThetaR>;
107 using DFieldSpThetaRVpar = DField<IdxRangeSpThetaRVpar>;
109 using DConstFieldMu = DConstField<
111 Kokkos::DefaultExecutionSpace::
112 memory_space>; // Equivalent to Field<double const, IdxRangeMu>
114 using DConstFieldVpar = DConstField<
116 Kokkos::DefaultExecutionSpace::
117 memory_space>; // Equivalent to Field<double const, IdxRangeMu>
118
120 using FDistribField = DField<IdxRangeFDistrib>;
121
122private:
129 void deepcopy_radial_profile(DFieldR dst, InputDFieldR src)
130 {
131 if constexpr (collisions_dimensions::is_spoofed_dim_v<GridR>) {
132 // If InputDFieldR is a double because R is not provided
133 ddc::parallel_fill(Kokkos::DefaultExecutionSpace(), dst, src);
134 } else {
135 // If InputDFieldR and DFieldR are the same type
136 ddc::parallel_deepcopy(dst, src);
137 }
138 }
139
140public:
149 void deepcopy_poloidal_plane(DFieldThetaR dst, InputDFieldThetaR src)
150 {
151 if constexpr ((collisions_dimensions::is_spoofed_dim_v<GridR>)&&(
152 collisions_dimensions::is_spoofed_dim_v<GridTheta>)) {
153 // If InputDFieldThetaR is a double because R and Theta are not provided
154 ddc::parallel_fill(Kokkos::DefaultExecutionSpace(), dst, src);
155 } else if constexpr ((!collisions_dimensions::is_spoofed_dim_v<GridR>)&&(
156 !collisions_dimensions::is_spoofed_dim_v<GridTheta>)) {
157 // If InputDFieldThetaR and DFieldThetaR are the same type
158 ddc::parallel_deepcopy(dst, src);
159 } else {
160 using NonSpoofDim = std::
161 conditional_t<collisions_dimensions::is_spoofed_dim_v<GridR>, GridTheta, GridR>;
162 ddc::parallel_for_each(
163 Kokkos::DefaultExecutionSpace(),
164 get_idx_range(dst),
165 KOKKOS_LAMBDA(Idx<GridTheta, GridR> idx) {
166 dst(idx) = src(ddc::select<NonSpoofDim>(idx));
167 });
168 }
169 }
170
180 {
181 if constexpr (std::is_same_v<DFieldSpThetaRVpar, InputDFieldSpThetaRVpar>) {
182 ddc::parallel_deepcopy(dst, src);
183 } else {
184 using InputIdxSpThetaRVpar = typename InputIdxRangeSpThetaRVpar::discrete_element_type;
185 ddc::parallel_for_each(
186 Kokkos::DefaultExecutionSpace(),
187 get_idx_range(dst),
188 KOKKOS_LAMBDA(IdxSpThetaRVpar idx) {
189 InputIdxSpThetaRVpar src_idx(idx);
190 dst(idx) = src(src_idx);
191 });
192 }
193 }
194
195public:
214 CollInfo const& collision_info,
215 IdxRangeFDistrib idxrange_fdistrib,
216 DConstFieldMu coeff_intdmu,
217 DConstFieldVpar coeff_intdvpar,
218 InputDFieldThetaR B_norm,
221 , m_hat_As {"m_hat_As", collisions_dimensions::get_expanded_idx_range<Species>(idxrange_fdistrib)}
222 , m_hat_Zs {"m_hat_Zs", collisions_dimensions::get_expanded_idx_range<Species>(idxrange_fdistrib)}
223 , m_mask_buffer_r {"m_mask_buffer_r", collisions_dimensions::get_expanded_idx_range<GridR>(idxrange_fdistrib)}
224 , m_mask_LIM {"m_mask_LIM", IdxRangeThetaR {collisions_dimensions::get_expanded_idx_range<GridTheta, GridR>(idxrange_fdistrib)}}
225 , m_B_norm {"m_B_norm", IdxRangeThetaR {collisions_dimensions::get_expanded_idx_range<GridTheta, GridR>(idxrange_fdistrib)}}
226 , m_Bstar_s {"m_Bstar_s", IdxRangeSpThetaRVpar {collisions_dimensions::get_expanded_idx_range<Species, GridTheta, GridR, GridVpar>(idxrange_fdistrib)}}
227 , m_coeff_AD {"m_coeff_AD", collisions_dimensions::get_expanded_idx_range<GridR>(idxrange_fdistrib)}
228 , m_mug {"m_mug", ddc::select<GridMu>(idxrange_fdistrib)}
229 , m_vparg {"m_vparg", ddc::select<GridVpar>(idxrange_fdistrib)}
230 {
231 IdxRangeVpar idxrange_vpar(idxrange_fdistrib);
232 if (idxrange_vpar.size() % 2 != 0) {
233 throw std::runtime_error("The number of points in the vpar direction must be a "
234 "multiple of 2. This ensures that there is no grid point at "
235 "vpar=0 (this would cause division by 0).");
236 }
237 IdxRangeSp idxrange_sp(idxrange_fdistrib);
238 // --> Initialize the mass species
239 host_t<DConstFieldSp> hat_As_host
240 = ddc::host_discrete_space<Species>().masses()[idxrange_sp];
241 ddc::parallel_deepcopy(get_field(m_hat_As), hat_As_host);
242 // --> Initialize the charge species
243 host_t<DConstFieldSp> hat_Zs_host
244 = ddc::host_discrete_space<Species>().charges()[idxrange_sp];
245 ddc::parallel_deepcopy(get_field(m_hat_Zs), hat_Zs_host);
246
247 // --> Initialize the other quantities needed in koliop
248 deepcopy_radial_profile(get_field(m_coeff_AD), collision_info.coeff_AD());
249 deepcopy_poloidal_plane(get_field(m_B_norm), B_norm);
250 deepcopy_Bstar(get_field(m_Bstar_s), Bstar_s);
251
252 // --> Initialization of the masks that have no sense here to 0.
253 ddc::parallel_fill(get_field(m_mask_buffer_r), 0.0); // Masked if >= 0.99
254 ddc::parallel_fill(get_field(m_mask_LIM), 0.0); // Masked if >= 0.99
255
256 // --> Initialization of vpar and mu grids
257 ddcHelper::dump_coordinates(Kokkos::DefaultExecutionSpace(), get_field(m_mug));
258 ddcHelper::dump_coordinates(Kokkos::DefaultExecutionSpace(), get_field(m_vparg));
259
260 // NOTE: We need to fence because DumpCoordinates is asynchronous on GPUs.
261 Kokkos::fence();
262
263 std::size_t const n_mu = ddc::select<GridMu>(idxrange_fdistrib).size();
264 std::size_t const n_vpar = idxrange_vpar.size();
265 std::size_t const n_r = get_idx_range<GridR>(m_mask_buffer_r).size();
266 std::size_t const n_theta = get_idx_range<GridTheta>(m_B_norm).size();
267 std::size_t const n_sp = idxrange_sp.size();
268 std::size_t const n_batch
269 = idxrange_fdistrib.size() / (n_mu * n_vpar * n_r * n_theta * n_sp);
270
272 n_mu,
273 n_vpar,
274 n_r,
275 n_theta,
276 n_batch,
277 n_sp,
278 collision_info.collisions_interspecies(),
279 /* the_local_index range_r_offset */ 0 + n_r - 1,
280 m_hat_As.data_handle(),
281 m_hat_Zs.data_handle(),
282 m_mug.data_handle(),
283 m_vparg.data_handle(),
284 coeff_intdmu.data_handle(),
285 coeff_intdvpar.data_handle(),
286 m_coeff_AD.data_handle(),
287 m_mask_buffer_r.data_handle(),
288 m_mask_LIM.data_handle(),
289 m_B_norm.data_handle(),
290 m_Bstar_s.data_handle());
291 }
292
294 {
296 static_cast<::koliop_Operator>(m_operator_handle));
297 }
298
307 void operator()(FDistribField all_f_distribution, double deltat_coll) const
308 {
309 if (::koliop_Collision(
310 static_cast<::koliop_Operator>(m_operator_handle),
311 deltat_coll,
312 all_f_distribution.data_handle())
313 != KOLIOP_STATUS_SUCCESS) {
314 GSLX_ASSERT(false);
315 }
316
317 // NOTE: While gslx is not fully stream compatible, just fence at the end of
318 // the computation.
319 if (::koliop_Fence(static_cast<::koliop_Operator>(m_operator_handle))
320 != KOLIOP_STATUS_SUCCESS) {
321 GSLX_ASSERT(false);
322 }
323 }
324
325protected:
329 ::koliop_Operator m_operator_handle;
330 // NOTE: Some of these arrays should come from a parent class or manager.
331 // They resides in this class while we wait for their implementation.
335 DFieldMemSp m_hat_As;
337 DFieldMemSp m_hat_Zs;
341 // [TODO]: This mask should maybe be deleted in C++ version
346 // [TODO] Attention this must be 3D for generalization to 3D geometry--> transfer it in a 1D array ?
349 // [TODO] Must be 5D for full 3D geometry
355};
A class which computes the collision operator in (vpar,mu)
Definition CollisionSpVparMu.hpp:23
DConstField< InputIdxRangeSpThetaRVpar > InputDFieldSpThetaRVpar
Type alias for a field on a grid of (species, theta, r, vpar) or a subset.
Definition CollisionSpVparMu.hpp:74
void deepcopy_poloidal_plane(DFieldThetaR dst, InputDFieldThetaR src)
Copy the information in src (received as an input to the class) into a 2D field defined over (r,...
Definition CollisionSpVparMu.hpp:149
Idx< Species, GridTheta, GridR, GridVpar > IdxSpThetaRVpar
Type alias for the index containing (species, theta, r, vpar)
Definition CollisionSpVparMu.hpp:90
DFieldMemThetaR m_mask_LIM
Limiter mask in (r,theta)
Definition CollisionSpVparMu.hpp:344
DFieldMemMu m_mug
grid in mu direction
Definition CollisionSpVparMu.hpp:352
DFieldMemVpar m_vparg
grid in vpar direction
Definition CollisionSpVparMu.hpp:354
IdxRange< Species, GridTheta, GridR, GridVpar > IdxRangeSpThetaRVpar
Type alias for the index range containing (species, theta, r, vpar)
Definition CollisionSpVparMu.hpp:81
DFieldMem< IdxRangeMu > DFieldMemMu
Type alias for a field memory block on a grid of magnetic moments.
Definition CollisionSpVparMu.hpp:95
DFieldMemSp m_hat_As
Normalized masses for all species.
Definition CollisionSpVparMu.hpp:335
DFieldMem< IdxRangeR > DFieldMemR
Type alias for a field memory block on a grid of radial values.
Definition CollisionSpVparMu.hpp:93
DFieldMemR m_mask_buffer_r
Mask used to avoid to apply collision in certain region.
Definition CollisionSpVparMu.hpp:342
DFieldMemR m_coeff_AD
Radial AD coefficients.
Definition CollisionSpVparMu.hpp:339
koliop_interface::MDL< double[6][6]> m_comb_mat
Combinatory (6x6) matrix computed only one times at initialisation. Rk: 6 = 2*(Npolmax-1) + 1 + 1.
Definition CollisionSpVparMu.hpp:333
void operator()(FDistribField all_f_distribution, double deltat_coll) const
Apply the collision operator to the distribution functions of all species on all species.
Definition CollisionSpVparMu.hpp:307
void deepcopy_Bstar(DFieldSpThetaRVpar dst, InputDFieldSpThetaRVpar src)
Copy the information in src (received as an input to the class) into a 4D field defined over (species...
Definition CollisionSpVparMu.hpp:179
DConstField< IdxRangeMu, Kokkos::DefaultExecutionSpace::memory_space > DConstFieldMu
Type alias for a constant field on GPU defined on a grid of magnetic moments.
Definition CollisionSpVparMu.hpp:112
DField< IdxRangeSpThetaRVpar > DFieldSpThetaRVpar
Type alias for a field on a grid of species, poloidal plane and parallel velocities.
Definition CollisionSpVparMu.hpp:107
IdxRange< GridR > IdxRangeR
Type alias for the index range of the radial points.
Definition CollisionSpVparMu.hpp:77
::koliop_Operator m_operator_handle
Opaque type representing the operator (due to the C interface)
Definition CollisionSpVparMu.hpp:329
Idx< GridTheta, GridR > IdxThetaR
Type alias for the index of the poloidal plane.
Definition CollisionSpVparMu.hpp:88
IdxRange< GridVpar > IdxRangeVpar
Type alias for the index range of the velocity parallel to the magnetic field.
Definition CollisionSpVparMu.hpp:85
IdxRange< GridTheta, GridR > IdxRangeThetaR
Type alias for the index range of the poloidal plane.
Definition CollisionSpVparMu.hpp:79
DField< IdxRangeFDistrib > FDistribField
Type alias for the distribution function stored on GPU.
Definition CollisionSpVparMu.hpp:120
DFieldMemThetaR m_B_norm
B norm in (r,theta)
Definition CollisionSpVparMu.hpp:347
DFieldMemSp m_hat_Zs
Normalized charges for all species.
Definition CollisionSpVparMu.hpp:337
CollisionSpVparMu(CollInfo const &collision_info, IdxRangeFDistrib idxrange_fdistrib, DConstFieldMu coeff_intdmu, DConstFieldVpar coeff_intdvpar, InputDFieldThetaR B_norm, InputDFieldSpThetaRVpar Bstar_s)
Create instance of CollisionSpVparMu class.
Definition CollisionSpVparMu.hpp:213
DFieldMem< IdxRangeSpThetaRVpar > DFieldMemSpThetaRVpar
Type alias for a field memory block on a grid of species, poloidal plane and parallel velocities.
Definition CollisionSpVparMu.hpp:101
DFieldMemSpThetaRVpar m_Bstar_s
Bstar(species,r,theta,vpar)
Definition CollisionSpVparMu.hpp:350
DField< IdxRangeThetaR > DFieldThetaR
Type alias for a field defined on a grid on a poloidal plane.
Definition CollisionSpVparMu.hpp:105
DFieldMem< IdxRangeThetaR > DFieldMemThetaR
Type alias for a field memory block on a grid on a poloidal plane.
Definition CollisionSpVparMu.hpp:99
IdxRange< GridMu > IdxRangeMu
Type alias for the index range of the magnetic moment.
Definition CollisionSpVparMu.hpp:83
DFieldMem< IdxRangeVpar > DFieldMemVpar
Type alias for a field memory block on a grid of parallel velocities.
Definition CollisionSpVparMu.hpp:97
DConstField< IdxRangeVpar, Kokkos::DefaultExecutionSpace::memory_space > DConstFieldVpar
Type alias for a constant field on GPU defined on a grid of parallel velocities.
Definition CollisionSpVparMu.hpp:117
DField< IdxRangeR > DFieldR
Type alias for a field defined on a grid of radial values.
Definition CollisionSpVparMu.hpp:103
A namespace to collect classes which are necessary to create Fields with the correct number of dimens...
Definition collisions_dimensions.hpp:10
Class to get the type of the radial dimension from a field containing a radial profile.
Definition collisions_dimensions.hpp:41
Class to get a DDC TypeSeq containing the input radial and theta tags.
Definition collisions_dimensions.hpp:185
Class to get the type of the poloidal dimension from a field containing a profile on the poloidal pla...
Definition collisions_dimensions.hpp:52
void DoOperatorDeinitialization(::koliop_Operator the_operator_handle)
Destructor for koliop.
::koliop_Operator DoOperatorInitialization(std::size_t the_mu_extent, std::size_t the_vpar_extent, std::size_t the_r_extent, std::size_t the_theta_extent, std::size_t the_phi_extent, std::size_t the_species_extent, std::int8_t collision_interspecies, std::int64_t ir_SOL_separatrix, const double *hat_As, const double *hat_Zs, const double *mug, const double *vparg, const double *coeff_intdmu, const double *coeff_intdvpar, const double *coeff_AD_r, const double *mask_buffer_r, const double *mask_LIM, const double *B_norm, const double *Bstar_s)
Initialise the collision operator defined in koliop.
Kokkos::View< Extent, Kokkos::LayoutLeft, Kokkos::DefaultExecutionSpace::memory_space, Kokkos::MemoryTraits< Kokkos::Restrict > > MDL
MDL is a helper type which avoids repetition of a lengthy type name.
Definition koliop_interface.hpp:27
Definition geometry.hpp:78
Definition geometry.hpp:116
Definition geometry.hpp:119
Definition geometry.hpp:75
Definition species_info.hpp:141