XGC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 exec_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 
63  : f(NoInit("f"), nsp, vgrid.nvr, pol_decomp.nnodes, vgrid.nvz),
64  f_1D(f.data(), f.size()),
65  vp_max(vgrid.vp_max),
66  dvp(vgrid.dvp),
67  smu_max(vgrid.smu_max),
68  dsmu(vgrid.dsmu),
70  {
71  if(option==VGridDistributionOption::ViewInit) Kokkos::deep_copy(f, 0.0);
72  }
73 
74  template<class Device2>
76  : f(NoInit("f"), nsp, dist_in.n_vr(), dist_in.n_nodes(), dist_in.n_vz()),
77  f_1D(f.data(), f.size()),
78  vp_max(dist_in.vp_max),
79  dvp(dist_in.dvp),
80  smu_max(dist_in.smu_max),
81  dsmu(dist_in.dsmu),
83  {
84  if(option==VGridDistributionOption::ViewInit) Kokkos::deep_copy(f, 0.0);
85  }
86 
87  // () operator: behave as if accessing the View directly
88  KOKKOS_INLINE_FUNCTION double& operator()(int isp, int ivr, int inode, int ivz) const { return f(isp, ivr, inode, ivz);}
89 
90  // [] operator: access the data as if it has been squashed to 1 dimension
91  KOKKOS_INLINE_FUNCTION double& operator[](int i) const { return f_1D(i);}
92 
93  double* data() const {return f.data();}
94 
100  template<typename F>
101  inline void for_all_elements(const std::string label, F lambda_func) const {
102  Kokkos::parallel_for(label, Kokkos::RangePolicy<exec_space>(0, f.size()), lambda_func);
103  }
104 
110  template<typename F>
111  inline void for_each_element(const std::string label, F lambda_func) const {
112  Kokkos::parallel_for(label, Kokkos::MDRangePolicy<Kokkos::Rank<4>, exec_space>({0, 0, 0, 0}, {f.extent(0), f.extent(1), f.extent(2), f.extent(3)}), lambda_func);
113  }
114 
115 
116  // Scatter value onto vgrid distribution
117  KOKKOS_INLINE_FUNCTION void scatter(int i_node, const VGridWeights& wt, double value) const{
118  constexpr int ISP_ZERO = 0;
119  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+0,i_node,wt.i_vz+0)),value*wt.w_00);
120  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+0,i_node,wt.i_vz+1)),value*wt.w_01);
121  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+1,i_node,wt.i_vz+0)),value*wt.w_10);
122  Kokkos::atomic_add(&(f(ISP_ZERO, wt.i_vr+1,i_node,wt.i_vz+1)),value*wt.w_11);
123  }
124 
125  // Temporary scatter for views not yet converted to VGridDistribution
126  KOKKOS_INLINE_FUNCTION static void scatter(const View<double***,CLayout,Device>& view, int i_node, const VGridWeights& wt, double value){
127  Kokkos::atomic_add(&(view(wt.i_vr+0,i_node,wt.i_vz+0)),value*wt.w_00);
128  Kokkos::atomic_add(&(view(wt.i_vr+0,i_node,wt.i_vz+1)),value*wt.w_01);
129  Kokkos::atomic_add(&(view(wt.i_vr+1,i_node,wt.i_vz+0)),value*wt.w_10);
130  Kokkos::atomic_add(&(view(wt.i_vr+1,i_node,wt.i_vz+1)),value*wt.w_11);
131  }
132 
133  // Temporary scatter for views not yet converted to VGridDistribution
134  KOKKOS_INLINE_FUNCTION static void scatter(const View<double****,CLayout,Device>& view, int i_node, const VGridWeights& wt, double value){
135  constexpr int ISP_ZERO = 0;
136  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+0)),value*wt.w_00);
137  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+1)),value*wt.w_01);
138  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+0)),value*wt.w_10);
139  Kokkos::atomic_add(&(view(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+1)),value*wt.w_11);
140  }
141 
142  // Gather value from vgrid distribution
143  KOKKOS_INLINE_FUNCTION double gather(int i_node, const VGridWeights& wt) const{
144  constexpr int ISP_ZERO = 0;
145  return ( f(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+0)*wt.w_00 +
146  f(ISP_ZERO,wt.i_vr+0,i_node,wt.i_vz+1)*wt.w_01 +
147  f(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+0)*wt.w_10 +
148  f(ISP_ZERO,wt.i_vr+1,i_node,wt.i_vz+1)*wt.w_11 );
149  }
150 
151  // Temporary gather for views not yet converted to VGridDistribution
152  template<class T>
153  KOKKOS_INLINE_FUNCTION static double gather(const T& view, int i_node, const VGridWeights& wt){
154  return ( view(wt.i_vr+0,i_node,wt.i_vz+0)*wt.w_00 +
155  view(wt.i_vr+0,i_node,wt.i_vz+1)*wt.w_01 +
156  view(wt.i_vr+1,i_node,wt.i_vz+0)*wt.w_10 +
157  view(wt.i_vr+1,i_node,wt.i_vz+1)*wt.w_11 );
158  }
159 
160  // Temporary gather for views not yet converted to VGridDistribution
161  // Divides by normalization view
162  template<class T>
163  KOKKOS_INLINE_FUNCTION static double normed_gather(const T& view, int i_node, const VGridWeights& wt, const T& norm_view){
164  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) +
165  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) +
166  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) +
167  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));
168  }
169 
170  // Access dimensions
171  KOKKOS_INLINE_FUNCTION int n_species() const{
172  return f.extent(0);
173  }
174 
175  KOKKOS_INLINE_FUNCTION int n_vr() const {
176  return f.extent(1);
177  }
178 
179  KOKKOS_INLINE_FUNCTION int n_nodes() const{
180  return f.extent(2);
181  }
182 
183  KOKKOS_INLINE_FUNCTION int n_vz() const{
184  return f.extent(3);
185  }
186 
187  KOKKOS_INLINE_FUNCTION int size() const{
188  return f.size();
189  }
190 
191  // Miscellaneous
192  inline double get_smu_n(int imu) const{
193  return (imu>0 ? dsmu*imu : dsmu*inv_mu0_factor);
194  }
195 
196  // Returns factor to handle velocity space volume on edge of velocity grid
197  KOKKOS_INLINE_FUNCTION double mu_vol_fac(int ivr) const{
198  return (ivr==0 || ivr==n_vr()-1) ? 0.5 : 1.0;
199  }
200 
202  return UniformRange(n_vr(), 0.0, smu_max);
203  }
204 
206  return UniformRange(n_vz(), -vp_max, vp_max);
207  }
208 
209  // inode is the vertex to access
210  // ip is the index of all other dimensions collapsed
211  KOKKOS_INLINE_FUNCTION double& pull_node_index(int inode, int ip) const{
212  int ivp = ip%n_vz(); // Fastest index
213  int itmp = ip/n_vz();
214  int imu = itmp%n_vr();
215  int isp = itmp/n_vr(); // Slowest index
216  return f(isp,imu,inode,ivp);
217  }
218 };
219 
220 #endif
KOKKOS_INLINE_FUNCTION int n_vr() const
Definition: vgrid_distribution.hpp:175
VGridDistribution(int nsp, const VelocityGrid &vgrid, const DomainDecomposition< DeviceType > &pol_decomp, VGridDistributionOption option=VGridDistributionOption::ViewInit)
Definition: vgrid_distribution.hpp:62
double * data() const
Definition: vgrid_distribution.hpp:93
KOKKOS_INLINE_FUNCTION int size() const
Definition: vgrid_distribution.hpp:187
UniformRange vz_range() const
Definition: vgrid_distribution.hpp:205
double w_00
Definition: vgrid_weights.hpp:10
Definition: velocity_grid.hpp:8
double get_smu_n(int imu) const
Definition: vgrid_distribution.hpp:192
UniformRange vr_range() const
Definition: vgrid_distribution.hpp:201
VGridDistribution(const VelocityGrid &vgrid, const DomainDecomposition< DeviceType > &pol_decomp, const std::vector< Maxwellian > &maxwellians)
Definition: vgrid_distribution.hpp:40
KOKKOS_INLINE_FUNCTION double gather(int i_node, const VGridWeights &wt) const
Definition: vgrid_distribution.hpp:143
double smu_max
max mu
Definition: vgrid_distribution.hpp:33
static KOKKOS_INLINE_FUNCTION double gather(const T &view, int i_node, const VGridWeights &wt)
Definition: vgrid_distribution.hpp:153
double dvp
grid spacing in parallel velocity
Definition: vgrid_distribution.hpp:32
double w_01
Definition: vgrid_weights.hpp:11
View< double ****, CLayout, Device > f
Definition: vgrid_distribution.hpp:23
KOKKOS_INLINE_FUNCTION int n_species() const
Definition: vgrid_distribution.hpp:171
KOKKOS_INLINE_FUNCTION double & operator()(int isp, int ivr, int inode, int ivz) const
Definition: vgrid_distribution.hpp:88
static KOKKOS_INLINE_FUNCTION void scatter(const View< double ***, CLayout, Device > &view, int i_node, const VGridWeights &wt, double value)
Definition: vgrid_distribution.hpp:126
double inv_mu0_factor
Definition: vgrid_distribution.hpp:35
double w_11
Definition: vgrid_weights.hpp:13
VGridDistribution()
Definition: vgrid_distribution.hpp:37
KOKKOS_INLINE_FUNCTION int n_vz() const
Definition: vgrid_distribution.hpp:183
View< double *, CLayout, Device, Kokkos::MemoryTraits< Kokkos::Unmanaged > > f_1D
Definition: vgrid_distribution.hpp:26
static KOKKOS_INLINE_FUNCTION void scatter(const View< double ****, CLayout, Device > &view, int i_node, const VGridWeights &wt, double value)
Definition: vgrid_distribution.hpp:134
typename HostType::execution_space exec_space
Definition: vgrid_distribution.hpp:21
Definition: vgrid_distribution.hpp:18
int i_vr
Definition: vgrid_weights.hpp:8
int i_vz
Definition: vgrid_weights.hpp:9
double dsmu
grid spacing in mu
Definition: vgrid_distribution.hpp:34
void for_each_element(const std::string label, F lambda_func) const
Definition: vgrid_distribution.hpp:111
VGridDistribution(int nsp, const VGridDistribution< Device2 > &dist_in, VGridDistributionOption option=VGridDistributionOption::ViewInit)
Definition: vgrid_distribution.hpp:75
Definition: vgrid_weights.hpp:7
Definition: uniform_range.hpp:6
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_INLINE_FUNCTION int n_nodes() const
Definition: vgrid_distribution.hpp:179
KOKKOS_INLINE_FUNCTION double & pull_node_index(int inode, int ip) const
Definition: vgrid_distribution.hpp:211
static KOKKOS_INLINE_FUNCTION double normed_gather(const T &view, int i_node, const VGridWeights &wt, const T &norm_view)
Definition: vgrid_distribution.hpp:163
void for_all_elements(const std::string label, F lambda_func) const
Definition: vgrid_distribution.hpp:101
VGridDistributionOption
Definition: vgrid_distribution.hpp:12
KOKKOS_INLINE_FUNCTION double & operator[](int i) const
Definition: vgrid_distribution.hpp:91
Kokkos::ViewAllocateWithoutInitializing NoInit
Definition: space_settings.hpp:69
double w_10
Definition: vgrid_weights.hpp:12
KOKKOS_INLINE_FUNCTION double mu_vol_fac(int ivr) const
Definition: vgrid_distribution.hpp:197
double vp_max
max parallel velocity
Definition: vgrid_distribution.hpp:31
KOKKOS_INLINE_FUNCTION void scatter(int i_node, const VGridWeights &wt, double value) const
Definition: vgrid_distribution.hpp:117