XGC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
grid_field.hpp
Go to the documentation of this file.
1 #ifndef GRID_FIELD_HPP
2 #define GRID_FIELD_HPP
3 #include "space_settings.hpp"
4 #include "NamelistReader.hpp"
5 
6 #include "globals.hpp"
7 #include "grid.hpp"
8 #include "linear_weights.hpp"
9 #include "local_fields.hpp"
10 #include "push_controls.hpp"
11 #include "field_weights.hpp"
12 #include "gyro_radius.hpp"
13 #include "field.hpp"
14 
15 /* TorType specifies whether the field is a single plane or needs a plane dimension
16  * */
17 enum class TorType{
18  OnePlane,
20 };
21 
22 // General declaration
23 // 2x2 = 4 types of GridField available: With and without gyroaverage dimension, with and without plane dimension
24 template<class Device, VarType VT, PhiInterpType PIT, TorType TT, KinType KT, ScatterType ST = ScatterType::Atomic>
25 struct GridField;
26 
27 template<class Device, VarType VT, PhiInterpType PIT>
30  Kokkos::View<field_type*,Kokkos::LayoutRight,Device> f;
31 
33  GridField(std::string name, int nphi, int nrho, int nnode) : f(name,nnode) {}
34  GridField(std::string name, int nnode) : f(name,nnode) {}
35  field_type* data() const {return f.data();}
36  int size() const {return f.size();}
37  int nnode() const {return f.extent(0);}
38  int nrhop1() const {return 1;}
39  int nphi() const {return 1;}
40  KOKKOS_INLINE_FUNCTION field_type& operator ()(int inode) const {return f(inode);}
41 
42  // Scatter to a node
43  KOKKOS_INLINE_FUNCTION void scatter(int node, const FieldWeights<DriftKin, PIT>& wts, double particle_weight) const{
44  f(node).scatter(wts, particle_weight);
45  }
46 
47  // Scatter to a triangle
48  KOKKOS_INLINE_FUNCTION void scatter(const Grid<DeviceType>& grid, int ithread, const Simd<int>& itr, const SimdGridVec& p, int i_simd, const FieldWeights<DriftKin, PIT>& wts, double particle_weight) const{
49  for (int j = 0; j<3; j++){
50  // Find triangle's nodes
51  int node=grid.get_node_index(itr[i_simd], j);
52  double wp=p[j][i_simd];
53 
54  // Scatter to node
55  scatter(node, wts, wp*particle_weight);
56  }
57  }
58 
59  void reset_to_zero(){
60  int ndoubles_in_grid_field = f.size()*field_type::SIZE();
61  Kokkos::View<double*,Kokkos::LayoutRight,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1d_double((double*)(data()), ndoubles_in_grid_field);
62  Kokkos::deep_copy(view_1d_double, 0.0);
63  }
64 
65  // TODO: Generalize this copy and these transposes for ndim etc
66  // Fill View with transposed data where inode is the contiguous index
67  // Ultimately, there should probably be an implementation GridField that has the transposed indices
68  void copy_to_double_view(const View<double*,CLayout,Device>& dest_view) const{
69  // Make an unmanaged view around the input field
70  View<double*,CLayout,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> f_unmanaged((double*)data(),nnode());
71 
72  Kokkos::deep_copy(dest_view, f_unmanaged);
73  }
74 
75  // Fill View with transposed data where inode is the contiguous index
76  // Ultimately, there should probably be an implementation GridField that has the transposed indices
77  void transpose_copy_to_double_view(const View<double**,CLayout,Device>& dest_view) const{
78  // Retrieve nphi from the Field of this GridField
79  constexpr int n_phi = field_type::NPHI();
80 
81  // Make an unmanaged view around the input field
82  View<double**,CLayout,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> f_unmanaged((double*)data(),nnode(), n_phi);
83 
84  // Copy f_unmanaged into iphi = 0 and iphi = 1 of dest_view
85  Kokkos::parallel_for("var_transpose_copy", Kokkos::RangePolicy<ExSpace>( 0, nnode()), KOKKOS_LAMBDA(const int inode){
86  for(int iphi=0; iphi<n_phi; iphi++){
87  dest_view(iphi, inode) = f_unmanaged(inode, iphi);
88  }
89  });
90  Kokkos::fence();
91  }
92 
93  // Transpose and copy data from a view where inode is the contiguous index
94  void transpose_copy_from_double_view(const View<double**,CLayout,Device>& src_view) const{
95  // Retrieve nphi from the Field of this GridField
96  constexpr int n_phi = field_type::NPHI();
97 
98  // Make an unmanaged view of the data
99  View<double**,CLayout,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> f_unmanaged((double*)data(),nnode(), n_phi);
100 
101  // Transpose from src_view into this gridfield
102  Kokkos::parallel_for("var_transpose_copy", Kokkos::RangePolicy<ExSpace>( 0, nnode()), KOKKOS_LAMBDA(const int inode){
103  for(int iphi=0; iphi<n_phi; iphi++){
104  f_unmanaged(inode, iphi) = src_view(iphi, inode);
105  }
106  });
107  Kokkos::fence();
108  }
109 };
110 
111 template<class Device, VarType VT, PhiInterpType PIT>
114  Kokkos::View<field_type**,Kokkos::LayoutRight,Device> f;
115 
117  GridField(std::string name, int nphi, int nrho, int nnode) : f(name,nnode, nrho+1) {}
118  GridField(std::string name, int nrho, int nnode) : f(name,nnode, nrho+1) {}
119  field_type* data() const {return f.data();}
120  int size() const {return f.size();}
121  int nnode() const {return f.extent(0);}
122  int nrhop1() const {return f.extent(1);}
123  int nphi() const {return 1;}
124  KOKKOS_INLINE_FUNCTION field_type& operator ()(int inode, int irho) const {return f(inode, irho);}
125 
126  // Scatter to a node
127  KOKKOS_INLINE_FUNCTION void scatter(int node, const FieldWeights<GyroKin, PIT>& wts, double particle_weight) const{
128 #ifdef NEWGYROMATRIX
129  // If NEWGYROMATRIX, there are 2 rho wts so must specify (even though the i indices are identical)
130  int irho = wts.rho[0].i;
131 #else
132  int irho = wts.rho.i;
133 #endif
134  f(node,irho).scatter(wts, particle_weight, f(node,irho+1));
135  }
136 
137  // Scatter to a triangle (same as for DriftKin - consolidate)
138  KOKKOS_INLINE_FUNCTION void scatter(const Grid<DeviceType>& grid, int ithread, const Simd<int>& itr, const SimdGridVec& p, int i_simd, const FieldWeights<GyroKin, PIT>& wts, double particle_weight) const{
139  for (int j = 0; j<3; j++){
140  // Find triangle's nodes
141  int node=grid.get_node_index(itr[i_simd], j);
142  double wp=p[j][i_simd];
143 
144  // Scatter to node
145  scatter(node, wts, wp*particle_weight);
146  }
147  }
148 
150  int ndoubles_in_grid_field = f.size()*field_type::SIZE();
151  Kokkos::View<double*,Kokkos::LayoutRight,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1d_double((double*)(f.data()), ndoubles_in_grid_field);
152  Kokkos::deep_copy(view_1d_double, 0.0);
153  }
154 };
155 
156 /******** GridField with array replication ********/
157 template<class Device, VarType VT, PhiInterpType PIT>
160  Kokkos::View<field_type**,Kokkos::LayoutRight,Device> f;
161 
163  GridField(std::string name, int nphi, int nrho, int nnode) : f(name,get_num_cpu_threads(), nnode) {}
164  GridField(std::string name, int nnode) : f(name,get_num_cpu_threads(), nnode) {}
165  field_type* data() const {return f.data();}
166  int size() const {return f.size();}
167  int nnode() const {return f.extent(1);}
168  int nrhop1() const {return 1;}
169  int nphi() const {return 1;}
170  KOKKOS_INLINE_FUNCTION field_type& operator ()(int ithread, int inode) const {return f(ithread, inode);}
171 
172  // Scatter to a node
173  KOKKOS_INLINE_FUNCTION void scatter(int ithread, int node, const FieldWeights<DriftKin, PIT>& wts, double particle_weight) const{
174  f(ithread,node).scatter(wts, particle_weight);
175  }
176 
177  // Scatter to a triangle
178  KOKKOS_INLINE_FUNCTION void scatter(const Grid<DeviceType>& grid, int ithread, const Simd<int>& itr, const SimdGridVec& p, int i_simd, const FieldWeights<DriftKin, PIT>& wts, double particle_weight) const{
179  for (int j = 0; j<3; j++){
180  // Find triangle's nodes
181  int node=grid.get_node_index(itr[i_simd], j);
182  double wp=p[j][i_simd];
183 
184  // Scatter to node
185  scatter(ithread, node, wts, wp*particle_weight);
186  }
187  }
188 
190  int ndoubles_in_grid_field = f.size()*field_type::SIZE();
191  Kokkos::View<double*,Kokkos::LayoutRight,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1d_double((double*)(f.data()), ndoubles_in_grid_field);
192  Kokkos::deep_copy(view_1d_double, 0.0);
193  }
194 };
195 
196 template<class Device, VarType VT, PhiInterpType PIT>
199  Kokkos::View<field_type***,Kokkos::LayoutRight,Device> f;
200 
202  GridField(std::string name, int nphi, int nrho, int nnode) : f(name,get_num_cpu_threads(),nnode, nrho+1) {}
203  GridField(std::string name, int nrho, int nnode) : f(name,get_num_cpu_threads(),nnode, nrho+1) {}
204  field_type* data() const {return f.data();}
205  int size() const {return f.size();}
206  int nnode() const {return f.extent(1);}
207  int nrhop1() const {return f.extent(2);}
208  int nphi() const {return 1;}
209  KOKKOS_INLINE_FUNCTION field_type& operator ()(int ithread, int inode, int irho) const {return f(ithread,inode, irho);}
210 
211  // Scatter to a node
212  KOKKOS_INLINE_FUNCTION void scatter(int ithread, int node, const FieldWeights<GyroKin, PIT>& wts, double particle_weight) const{
213 #ifdef NEWGYROMATRIX
214  // If NEWGYROMATRIX, there are 2 rho wts so must specify (even though the i indices are identical)
215  int irho = wts.rho[0].i;
216 #else
217  int irho = wts.rho.i;
218 #endif
219  f(ithread,node,irho).scatter(wts, particle_weight, f(ithread,node,irho+1));
220  }
221 
222  // Scatter to a triangle (same as for DriftKin - consolidate)
223  KOKKOS_INLINE_FUNCTION void scatter(const Grid<DeviceType>& grid, int ithread, const Simd<int>& itr, const SimdGridVec& p, int i_simd, const FieldWeights<GyroKin, PIT>& wts, double particle_weight) const{
224  for (int j = 0; j<3; j++){
225  // Find triangle's nodes
226  int node=grid.get_node_index(itr[i_simd], j);
227  double wp=p[j][i_simd];
228 
229  // Scatter to node
230  scatter(ithread, node, wts, wp*particle_weight);
231  }
232  }
233 
235  int ndoubles_in_grid_field = f.size()*field_type::SIZE();
236  Kokkos::View<double*,Kokkos::LayoutRight,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> view_1d_double((double*)(f.data()), ndoubles_in_grid_field);
237  Kokkos::deep_copy(view_1d_double, 0.0);
238  }
239 };
240 /************/
241 
242 template<class Device, VarType VT, PhiInterpType PIT>
245  Kokkos::View<field_type**,Kokkos::LayoutRight,Device> f;
246 
248  GridField(std::string name, int nphi, int nrho, int nnode) : f(name,nphi, nnode) {}
249  GridField(std::string name, int nphi, int nnode) : f(name,nphi, nnode) {}
250  field_type* data() const {return f.data();}
251  int size() const {return f.size();}
252  int nnode() const {return f.extent(1);}
253  int nrhop1() const {return 1;}
254  int nphi() const {return f.extent(0);}
255  KOKKOS_INLINE_FUNCTION field_type& operator ()(int iphi, int inode) const {return f(iphi, inode);}
256 
259  new_field.f = my_subview(f, subfield_idx);
260  return new_field;
261  }
262 
263  Kokkos::View<double**,Kokkos::LayoutRight,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>> unmanaged(){
264  return Kokkos::View<double**,Kokkos::LayoutRight,Device,Kokkos::MemoryTraits<Kokkos::Unmanaged>>((double*)(f.data()), f.layout());
265  }
266 };
267 
268 template<class Device, VarType VT, PhiInterpType PIT>
271  Kokkos::View<field_type***,Kokkos::LayoutRight,Device> f;
272 
274  GridField(std::string name, int nphi, int nrho, int nnode) : f(name,nphi, nnode, nrho+1) {}
275  field_type* data() const {return f.data();}
276  int size() const {return f.size();}
277  int nnode() const {return f.extent(1);}
278  int nrhop1() const {return f.extent(2);}
279  int nphi() const {return f.extent(0);}
280  KOKKOS_INLINE_FUNCTION field_type& operator ()(int iphi, int inode, int irho) const {return f(iphi, inode, irho);}
281 };
282 
283 // For convenience
285 
286 #endif
GridField(std::string name, int nphi, int nrho, int nnode)
Definition: grid_field.hpp:33
GridField(std::string name, int nphi, int nrho, int nnode)
Definition: grid_field.hpp:248
KOKKOS_INLINE_FUNCTION void scatter(const Grid< DeviceType > &grid, int ithread, const Simd< int > &itr, const SimdGridVec &p, int i_simd, const FieldWeights< GyroKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:223
KOKKOS_INLINE_FUNCTION void scatter(const Grid< DeviceType > &grid, int ithread, const Simd< int > &itr, const SimdGridVec &p, int i_simd, const FieldWeights< DriftKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:48
GridField(std::string name, int nrho, int nnode)
Definition: grid_field.hpp:118
void transpose_copy_to_double_view(const View< double **, CLayout, Device > &dest_view) const
Definition: grid_field.hpp:77
KOKKOS_INLINE_FUNCTION void scatter(const Grid< DeviceType > &grid, int ithread, const Simd< int > &itr, const SimdGridVec &p, int i_simd, const FieldWeights< GyroKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:138
GridField(std::string name, int nrho, int nnode)
Definition: grid_field.hpp:203
KOKKOS_INLINE_FUNCTION void scatter(int node, const FieldWeights< GyroKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:127
void copy_to_double_view(const View< double *, CLayout, Device > &dest_view) const
Definition: grid_field.hpp:68
KOKKOS_INLINE_FUNCTION void scatter(const Grid< DeviceType > &grid, int ithread, const Simd< int > &itr, const SimdGridVec &p, int i_simd, const FieldWeights< DriftKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:178
Definition: field_weights.hpp:13
Kokkos::View< field_type **, Kokkos::LayoutRight, Device > f
Definition: grid_field.hpp:114
Definition: globals.hpp:83
GridField(std::string name, int nphi, int nnode)
Definition: grid_field.hpp:249
GridField(std::string name, int nnode)
Definition: grid_field.hpp:34
void scatter(const Simulation< DeviceType > &sml, const Grid< DeviceType > &grid, const MagneticField< DeviceType > &magnetic_field, const GridFieldPack< DeviceType, PIT > &gfpack, const Species< DeviceType > &species, const Charge< DeviceType, KT > &charge)
Definition: scatter.cpp:240
KOKKOS_INLINE_FUNCTION void scatter(int node, const FieldWeights< DriftKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:43
GridField(std::string name, int nphi, int nrho, int nnode)
Definition: grid_field.hpp:163
Definition: grid_field.hpp:25
TorType
Definition: grid_field.hpp:17
Kokkos::View< field_type *, Kokkos::LayoutRight, Device > f
Definition: grid_field.hpp:30
void transpose_copy_from_double_view(const View< double **, CLayout, Device > &src_view) const
Definition: grid_field.hpp:94
KOKKOS_INLINE_FUNCTION int get_node_index(int triangle_index, int tri_vertex_index) const
Definition: grid.tpp:792
GridField(std::string name, int nphi, int nrho, int nnode)
Definition: grid_field.hpp:117
Definition: globals.hpp:84
GridField< DeviceType, VarType::Scalar, PhiInterpType::None, TorType::OnePlane, KinType::DriftKin > ScalarGridField
Definition: grid_field.hpp:284
GridField< Device, VT, PIT, TorType::OnePlane, KinType::DriftKin > subfield(int subfield_idx) const
Definition: grid_field.hpp:257
Definition: field.hpp:50
Kokkos::View< field_type ***, Kokkos::LayoutRight, Device > f
Definition: grid_field.hpp:271
Definition: grid_structs.hpp:7
Kokkos::View< field_type **, Kokkos::LayoutRight, Device > f
Definition: grid_field.hpp:160
Kokkos::View< T *, Kokkos::LayoutRight, Device > my_subview(const Kokkos::View< T ****, Kokkos::LayoutRight, Device > &view, int i, int j, int k)
Definition: my_subview.hpp:8
Definition: simd.hpp:18
int get_num_cpu_threads()
Definition: globals.hpp:17
Kokkos::View< field_type ***, Kokkos::LayoutRight, Device > f
Definition: grid_field.hpp:199
GridField(std::string name, int nphi, int nrho, int nnode)
Definition: grid_field.hpp:274
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 void scatter(int ithread, int node, const FieldWeights< DriftKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:173
Kokkos::View< field_type **, Kokkos::LayoutRight, Device > f
Definition: grid_field.hpp:245
Kokkos::View< double **, Kokkos::LayoutRight, Device, Kokkos::MemoryTraits< Kokkos::Unmanaged > > unmanaged()
Definition: grid_field.hpp:263
GridField(std::string name, int nphi, int nrho, int nnode)
Definition: grid_field.hpp:202
KOKKOS_INLINE_FUNCTION void scatter(int ithread, int node, const FieldWeights< GyroKin, PIT > &wts, double particle_weight) const
Definition: grid_field.hpp:212