XGC1
vgrid_distribution.hpp
Go to the documentation of this file.
1 #ifndef VGRID_DISTRIBUTION_HPP
2 #define VGRID_DISTRIBUTION_HPP
3 
4 #include "space_settings.hpp"
5 #include "NamelistReader.hpp"
6 #include "velocity_grid.hpp"
7 #include "view_arithmetic.hpp"
9 #include "maxwellian.hpp"
10 #include "uniform_range.hpp"
11 
13  NoViewInit=0,
14  ViewInit
15 };
16 
17 template<class Device>
19  public:
20 
21  using execution_space = typename Device::execution_space;
22 
23  View<double****,CLayout, Device> f;
24 
25  // Create a 1D unmanaged view looking at the same address
26  View<double*,CLayout, Device, Kokkos::MemoryTraits<Kokkos::Unmanaged>> f_1D;
27 
28  // Make f private when possible - ALS
29  //public:
30 
31  double vp_max;
32  double dvp;
33  double smu_max;
34  double dsmu;
36 
38 
39  // Analytical distribution for testing
40  VGridDistribution(const VelocityGrid& vgrid, const DomainDecomposition<DeviceType>& pol_decomp, const std::vector<Maxwellian>& maxwellians)
41  : f("f", maxwellians.size(), vgrid.nvr, pol_decomp.nnodes, vgrid.nvz),
42  f_1D(f.data(), f.size()),
43  vp_max(vgrid.vp_max),
44  dvp(vgrid.dvp),
45  smu_max(vgrid.smu_max),
46  dsmu(vgrid.dsmu),
48  {
49  for (int i=0; i<f.extent(0); i++){
50  for (int imu=0; imu<f.extent(1); imu++){
51  double vperp = imu*dsmu;
52  for (int inode=0; inode<f.extent(2); inode++){
53  for (int ivp=0; ivp<f.extent(3); ivp++){
54  double vpara = ivp*dvp - vp_max;
55  f(i,imu,inode,ivp) = maxwellians[i].get_f(vpara, vperp);
56  }
57  }
58  }
59  }
60  }
61 
62  // Standard constructor: Input species, velocity grid, domain decomposition, and option to skip view initialization
64  : f(NoInit("f"), nsp, vgrid.nvr, pol_decomp.nnodes, vgrid.nvz),
65  f_1D(f.data(), f.size()),
66  vp_max(vgrid.vp_max),
67  dvp(vgrid.dvp),
68  smu_max(vgrid.smu_max),
69  dsmu(vgrid.dsmu),
71  {
72  if(option==VGridDistributionOption::ViewInit) Kokkos::deep_copy(f, 0.0);
73  }
74 
75  // Initialize from another VGridDistribution. nspecies set separately.
76  template<class Device2>
78  : f(NoInit("f"), nsp, dist_in.n_vr(), dist_in.n_nodes(), dist_in.n_vz()),
79  f_1D(f.data(), f.size()),
80  vp_max(dist_in.vp_max),
81  dvp(dist_in.dvp),
82  smu_max(dist_in.smu_max),
83  dsmu(dist_in.dsmu),
85  {
86  if(option==VGridDistributionOption::ViewInit) Kokkos::deep_copy(f, 0.0);
87  }
88 
89  // Initialize from another VGridDistribution. nspecies and nnode set separately.
90  template<class Device2>
92  : f(NoInit("f"), nsp, dist_in.n_vr(), nnode, dist_in.n_vz()),
93  f_1D(f.data(), f.size()),
94  vp_max(dist_in.vp_max),
95  dvp(dist_in.dvp),
96  smu_max(dist_in.smu_max),
97  dsmu(dist_in.dsmu),
99  {
100  if(option==VGridDistributionOption::ViewInit) Kokkos::deep_copy(f, 0.0);
101  }
102 
103  // () operator: behave as if accessing the View directly
104  KOKKOS_INLINE_FUNCTION double& operator()(int isp, int ivr, int inode, int ivz) const { return f(isp, ivr, inode, ivz);}
105 
106  // [] operator: access the data as if it has been squashed to 1 dimension
107  KOKKOS_INLINE_FUNCTION double& operator[](int i) const { return f_1D(i);}
108 
109  double* data() const {return f.data();}
110 
116  template<typename F>
117  inline void for_all_elements(const std::string label, F lambda_func) const {
118  Kokkos::parallel_for(label, Kokkos::RangePolicy<execution_space>(0, f.size()), lambda_func);
119  }
120 
126  template<typename F>
127  inline void for_each_element(const std::string label, F lambda_func) const {
128  Kokkos::parallel_for(label, Kokkos::MDRangePolicy<Kokkos::Rank<4>, execution_space>({0, 0, 0, 0}, {f.extent(0), f.extent(1), f.extent(2), f.extent(3)}), lambda_func);
129  }
130 
131 
132  // Scatter value onto vgrid distribution
133  KOKKOS_INLINE_FUNCTION void scatter(int i_node, const VGridWeights& wt, double value) const{
134  constexpr int ISP_ZERO = 0;
135  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+0,i_node,wt.i_vz+0)),value*wt.w_00);
136  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+0,i_node,wt.i_vz+1)),value*wt.w_01);
137  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+1,i_node,wt.i_vz+0)),value*wt.w_10);
138  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+1,i_node,wt.i_vz+1)),value*wt.w_11);
139  }
140 
141  // Temporary scatter for views not yet converted to VGridDistribution
142  KOKKOS_INLINE_FUNCTION static void scatter(const View<double***,CLayout,Device>& view, int i_node, const VGridWeights& wt, double value){
143  Kokkos::atomic_add(&(view(wt.i_vr+0,i_node,wt.i_vz+0)),value*wt.w_00);
144  Kokkos::atomic_add(&(view(wt.i_vr+0,i_node,wt.i_vz+1)),value*wt.w_01);
145  Kokkos::atomic_add(&(view(wt.i_vr+1,i_node,wt.i_vz+0)),value*wt.w_10);
146  Kokkos::atomic_add(&(view(wt.i_vr+1,i_node,wt.i_vz+1)),value*wt.w_11);
147  }
148 
149  // Temporary scatter for views not yet converted to VGridDistribution
150  KOKKOS_INLINE_FUNCTION static void scatter(const View<double****,CLayout,Device>& view, int i_node, const VGridWeights& wt, double value){
151  constexpr int ISP_ZERO = 0;
152  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+0)),value*wt.w_00);
153  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+1)),value*wt.w_01);
154  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+0)),value*wt.w_10);
155  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+1)),value*wt.w_11);
156  }
157 
158  // Gather value from vgrid distribution
159  KOKKOS_INLINE_FUNCTION double gather(int i_node, const VGridWeights& wt) const{
160  constexpr int ISP_ZERO = 0;
161  return ( f(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+0)*wt.w_00 +
162  f(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+1)*wt.w_01 +
163  f(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+0)*wt.w_10 +
164  f(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+1)*wt.w_11 );
165  }
166 
167  // Temporary gather for views not yet converted to VGridDistribution
168  template<class T>
169  KOKKOS_INLINE_FUNCTION static double gather(const T& view, int i_node, const VGridWeights& wt){
170  return ( view(wt.i_vr+0,i_node,wt.i_vz+0)*wt.w_00 +
171  view(wt.i_vr+0,i_node,wt.i_vz+1)*wt.w_01 +
172  view(wt.i_vr+1,i_node,wt.i_vz+0)*wt.w_10 +
173  view(wt.i_vr+1,i_node,wt.i_vz+1)*wt.w_11 );
174  }
175 
176  // Temporary gather for views not yet converted to VGridDistribution
177  // Divides by normalization view
178  template<class T>
179  KOKKOS_INLINE_FUNCTION static double normed_gather(const T& view, int i_node, const VGridWeights& wt, const T& norm_view){
180  return (view(wt.i_vr+0,i_node,wt.i_vz+0)*wt.w_00/norm_view(wt.i_vr+0,i_node,wt.i_vz+0) +
181  view(wt.i_vr+0,i_node,wt.i_vz+1)*wt.w_01/norm_view(wt.i_vr+0,i_node,wt.i_vz+1) +
182  view(wt.i_vr+1,i_node,wt.i_vz+0)*wt.w_10/norm_view(wt.i_vr+1,i_node,wt.i_vz+0) +
183  view(wt.i_vr+1,i_node,wt.i_vz+1)*wt.w_11/norm_view(wt.i_vr+1,i_node,wt.i_vz+1));
184  }
185 
186  // Access dimensions
187  KOKKOS_INLINE_FUNCTION int n_species() const{
188  return f.extent(0);
189  }
190 
191  KOKKOS_INLINE_FUNCTION int n_vr() const {
192  return f.extent(1);
193  }
194 
195  KOKKOS_INLINE_FUNCTION int n_nodes() const{
196  return f.extent(2);
197  }
198 
199  KOKKOS_INLINE_FUNCTION int n_vz() const{
200  return f.extent(3);
201  }
202 
203  KOKKOS_INLINE_FUNCTION int size() const{
204  return f.size();
205  }
206 
207  // Miscellaneous
208  inline double get_smu_n(int imu) const{
209  return (imu>0 ? dsmu*imu : dsmu*inv_mu0_factor);
210  }
211 
212  // Returns factor to handle velocity space volume on edge of the v_perp velocity grid
213  KOKKOS_INLINE_FUNCTION double mu_vol_fac(int ivr) const{
214  return (ivr==0 || ivr==n_vr()-1) ? 0.5 : 1.0;
215  }
216 
217  // Returns factor to handle velocity space volume on the v_parallel edge of velocity grid
218  KOKKOS_INLINE_FUNCTION double vp_vol_fac(int ivz) const{
219  return (ivz==0 || ivz==n_vz()-1) ? 0.5 : 1.0;
220  }
221 
223  return UniformRange(n_vr(), 0.0, smu_max);
224  }
225 
227  return UniformRange(n_vz(), -vp_max, vp_max);
228  }
229 
230  // inode is the vertex to access
231  // ip is the index of all other dimensions collapsed
232  KOKKOS_INLINE_FUNCTION double& pull_node_index(int inode, int ip) const{
233  int ivp = ip%n_vz(); // Fastest index
234  int itmp = ip/n_vz();
235  int imu = itmp%n_vr();
236  int isp = itmp/n_vr(); // Slowest index
237  return f(isp,imu,inode,ivp);
238  }
239 
240  // Resize to new number of vertices
241  void resize_n_vertices(int new_n_nodes){
242  Kokkos::resize(f, n_species(), n_vr(), new_n_nodes, n_vz());
243  f_1D = View<double*,CLayout, Device, Kokkos::MemoryTraits<Kokkos::Unmanaged>>(f.data(), f.size());
244  }
245 };
246 
247 #endif
Definition: vgrid_distribution.hpp:18
KOKKOS_INLINE_FUNCTION int n_species() const
Definition: vgrid_distribution.hpp:187
VGridDistribution(int nsp, const VelocityGrid &vgrid, const DomainDecomposition< DeviceType > &pol_decomp, VGridDistributionOption option=VGridDistributionOption::ViewInit)
Definition: vgrid_distribution.hpp:63
double * data() const
Definition: vgrid_distribution.hpp:109
void resize_n_vertices(int new_n_nodes)
Definition: vgrid_distribution.hpp:241
KOKKOS_INLINE_FUNCTION double mu_vol_fac(int ivr) const
Definition: vgrid_distribution.hpp:213
void for_all_elements(const std::string label, F lambda_func) const
Definition: vgrid_distribution.hpp:117
VGridDistribution(const VelocityGrid &vgrid, const DomainDecomposition< DeviceType > &pol_decomp, const std::vector< Maxwellian > &maxwellians)
Definition: vgrid_distribution.hpp:40
KOKKOS_INLINE_FUNCTION void scatter(int i_node, const VGridWeights &wt, double value) const
Definition: vgrid_distribution.hpp:133
VGridDistribution()
Definition: vgrid_distribution.hpp:37
double get_smu_n(int imu) const
Definition: vgrid_distribution.hpp:208
double vp_max
max parallel velocity
Definition: vgrid_distribution.hpp:31
static KOKKOS_INLINE_FUNCTION void scatter(const View< double ***, CLayout, Device > &view, int i_node, const VGridWeights &wt, double value)
Definition: vgrid_distribution.hpp:142
UniformRange vz_range() const
Definition: vgrid_distribution.hpp:226
KOKKOS_INLINE_FUNCTION double vp_vol_fac(int ivz) const
Definition: vgrid_distribution.hpp:218
KOKKOS_INLINE_FUNCTION int size() const
Definition: vgrid_distribution.hpp:203
View< double ****, CLayout, Device > f
Definition: vgrid_distribution.hpp:23
KOKKOS_INLINE_FUNCTION double gather(int i_node, const VGridWeights &wt) const
Definition: vgrid_distribution.hpp:159
View< double *, CLayout, Device, Kokkos::MemoryTraits< Kokkos::Unmanaged > > f_1D
Definition: vgrid_distribution.hpp:26
static KOKKOS_INLINE_FUNCTION double gather(const T &view, int i_node, const VGridWeights &wt)
Definition: vgrid_distribution.hpp:169
double dsmu
grid spacing in mu
Definition: vgrid_distribution.hpp:34
VGridDistribution(int nsp, const VGridDistribution< Device2 > &dist_in, VGridDistributionOption option=VGridDistributionOption::ViewInit)
Definition: vgrid_distribution.hpp:77
void for_each_element(const std::string label, F lambda_func) const
Definition: vgrid_distribution.hpp:127
KOKKOS_INLINE_FUNCTION double & operator[](int i) const
Definition: vgrid_distribution.hpp:107
static KOKKOS_INLINE_FUNCTION void scatter(const View< double ****, CLayout, Device > &view, int i_node, const VGridWeights &wt, double value)
Definition: vgrid_distribution.hpp:150
UniformRange vr_range() const
Definition: vgrid_distribution.hpp:222
KOKKOS_INLINE_FUNCTION double & operator()(int isp, int ivr, int inode, int ivz) const
Definition: vgrid_distribution.hpp:104
KOKKOS_INLINE_FUNCTION double & pull_node_index(int inode, int ip) const
Definition: vgrid_distribution.hpp:232
double dvp
grid spacing in parallel velocity
Definition: vgrid_distribution.hpp:32
double inv_mu0_factor
Definition: vgrid_distribution.hpp:35
VGridDistribution(int nsp, int nnode, const VGridDistribution< Device2 > &dist_in, VGridDistributionOption option=VGridDistributionOption::ViewInit)
Definition: vgrid_distribution.hpp:91
static KOKKOS_INLINE_FUNCTION double normed_gather(const T &view, int i_node, const VGridWeights &wt, const T &norm_view)
Definition: vgrid_distribution.hpp:179
KOKKOS_INLINE_FUNCTION int n_vr() const
Definition: vgrid_distribution.hpp:191
typename Device::execution_space execution_space
Definition: vgrid_distribution.hpp:21
KOKKOS_INLINE_FUNCTION int n_nodes() const
Definition: vgrid_distribution.hpp:195
double smu_max
max mu
Definition: vgrid_distribution.hpp:33
KOKKOS_INLINE_FUNCTION int n_vz() const
Definition: vgrid_distribution.hpp:199
void parallel_for(const std::string name, int n_ptl, Function func, Option option, HostAoSoA aosoa_h, DeviceAoSoA aosoa_d)
Definition: streamed_parallel_for.hpp:252
Kokkos::ViewAllocateWithoutInitializing NoInit
Definition: space_settings.hpp:69
Definition: uniform_range.hpp:8
Definition: vgrid_weights.hpp:7
double w_00
Definition: vgrid_weights.hpp:10
double w_10
Definition: vgrid_weights.hpp:12
double w_11
Definition: vgrid_weights.hpp:13
int i_vr
Definition: vgrid_weights.hpp:8
double w_01
Definition: vgrid_weights.hpp:11
int i_vz
Definition: vgrid_weights.hpp:9
Definition: velocity_grid.hpp:8
VGridDistributionOption
Definition: vgrid_distribution.hpp:12