XGC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
field.hpp
Go to the documentation of this file.
1 #ifndef FIELD_HPP
2 #define 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 
14 /* VarType specifies whether the field is a vector, a 2D vector, or a scalar
15  * */
16 enum class VarType{
17  Vector,
18  Vector2D,
19  Scalar
20 };
21 
22 /* Compile-time function to use 2D vector if field-following planes are not used (i.e. XGCa) */
23 template<PhiInterpType PIT> constexpr VarType vec2d_if_axisym();
24 template<> constexpr VarType vec2d_if_axisym<PhiInterpType::Planes>(){return VarType::Vector;}
25 template<> constexpr VarType vec2d_if_axisym<PhiInterpType::None>(){return VarType::Vector2D;}
26 
27 /* Coordinate correction for field interpolations */
29  const double gamma_psi;
30 
31  public:
32  double r0;
33  double r1;
34  double z0;
35  double z1;
36 
37  KOKKOS_INLINE_FUNCTION FieldCorrection(const SimdVector2D& gradpsi, int i_simd)
38  : gamma_psi(1.0/gradpsi.magnitude(i_simd)) {}
39 
40  KOKKOS_INLINE_FUNCTION void set(int i_simd, double basis, const SimdVector2D &gradpsi){
41  r0 = basis + (1.0-basis) * gamma_psi * gradpsi.r[i_simd];
42  r1 = (1.0-basis) * gamma_psi * gradpsi.z[i_simd];
43  z0 = (1.0-basis) * gamma_psi *(-gradpsi.z[i_simd]);
44  z1 = basis + (1.0-basis) * gamma_psi * gradpsi.r[i_simd];
45  }
46 };
47 
48 
49 template<VarType VT, PhiInterpType PIT>
50 struct Field{};
51 
52 //Struct used for E_phi_ff, dAs_phi_ff, dAh_phi_ff, As_phi_ff, Ah_phi_ff. 3 vector components, 2 contributing planes
53 template<>
55  double V[3][2];
56 
57  static constexpr PhiInterpType PIT = PhiInterpType::Planes;
58  static constexpr VarType VT = VarType::Vector;
59 
60  static constexpr int NDIM(){return 3;}
61  static constexpr int NPHI(){return 2;}
62  static constexpr int SIZE(){return NDIM()*NPHI();}
63 
71  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const double (&wphi)[2], const FieldCorrection& corr) const{
72  vec.r[i_simd] += wp*(wphi[0]*( corr.r0*V[PIR][0] + corr.z0*V[PIZ][0] )
73  + wphi[1]*( corr.r0*V[PIR][1] + corr.z0*V[PIZ][1] ) );
74  vec.z[i_simd] += wp*(wphi[0]*( corr.r1*V[PIR][0] + corr.z1*V[PIZ][0] )
75  + wphi[1]*( corr.r1*V[PIR][1] + corr.z1*V[PIZ][1] ) );
76  vec.phi[i_simd] += wp*(wphi[0]* V[PIP][0]
77  + wphi[1]* V[PIP][1] );
78  }
79 
88  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const FieldWeights<GyroKin, PhiInterpType::Planes>& wts, const FieldCorrection& corr, const Field<VarType::Vector,PhiInterpType::Planes>& field2) const{
89 # ifdef NEWGYROMATRIX
90  vec.r[i_simd] += wp*(wts.phi.w[0]*( corr.r0*(wts.rho[0].w[0]*V[PIR][0] + wts.rho[0].w[1]*field2.V[PIR][0])
91  + corr.z0*(wts.rho[0].w[0]*V[PIZ][0] + wts.rho[0].w[1]*field2.V[PIZ][0]) )
92  + wts.phi.w[1]*( corr.r0*(wts.rho[1].w[0]*V[PIR][1] + wts.rho[1].w[1]*field2.V[PIR][1])
93  + corr.z0*(wts.rho[1].w[0]*V[PIZ][1] + wts.rho[1].w[1]*field2.V[PIZ][1]) ) );
94  vec.z[i_simd] += wp*(wts.phi.w[0]*( corr.r1*(wts.rho[0].w[0]*V[PIR][0] + wts.rho[0].w[1]*field2.V[PIR][0])
95  + corr.z1*(wts.rho[0].w[0]*V[PIZ][0] + wts.rho[0].w[1]*field2.V[PIZ][0]) )
96  + wts.phi.w[1]*( corr.r1*(wts.rho[1].w[0]*V[PIR][1] + wts.rho[1].w[1]*field2.V[PIR][1])
97  + corr.z1*(wts.rho[1].w[0]*V[PIZ][1] + wts.rho[1].w[1]*field2.V[PIZ][1]) ) );
98  vec.phi[i_simd] += wp*(wts.phi.w[0]* (wts.rho[0].w[0]*V[PIP][0] + wts.rho[0].w[1]*field2.V[PIP][0])
99  + wts.phi.w[1]* (wts.rho[1].w[0]*V[PIP][1] + wts.rho[1].w[1]*field2.V[PIP][1]) );
100 # else
101  vec.r[i_simd] += wp*(wts.phi.w[0]*( corr.r0*(wts.rho.w[0]*V[PIR][0] + wts.rho.w[1]*field2.V[PIR][0])
102  + corr.z0*(wts.rho.w[0]*V[PIZ][0] + wts.rho.w[1]*field2.V[PIZ][0]) )
103  + wts.phi.w[1]*( corr.r0*(wts.rho.w[0]*V[PIR][1] + wts.rho.w[1]*field2.V[PIR][1])
104  + corr.z0*(wts.rho.w[0]*V[PIZ][1] + wts.rho.w[1]*field2.V[PIZ][1]) ) );
105  vec.z[i_simd] += wp*(wts.phi.w[0]*( corr.r1*(wts.rho.w[0]*V[PIR][0] + wts.rho.w[1]*field2.V[PIR][0])
106  + corr.z1*(wts.rho.w[0]*V[PIZ][0] + wts.rho.w[1]*field2.V[PIZ][0]) )
107  + wts.phi.w[1]*( corr.r1*(wts.rho.w[0]*V[PIR][1] + wts.rho.w[1]*field2.V[PIR][1])
108  + corr.z1*(wts.rho.w[0]*V[PIZ][1] + wts.rho.w[1]*field2.V[PIZ][1]) ) );
109  vec.phi[i_simd] += wp*(wts.phi.w[0]* (wts.rho.w[0]*V[PIP][0] + wts.rho.w[1]*field2.V[PIP][0])
110  + wts.phi.w[1]* (wts.rho.w[0]*V[PIP][1] + wts.rho.w[1]*field2.V[PIP][1]) );
111 # endif
112  }
113 
114 };
115 
116 //Struct used for E00_ff. 2 vector components, 2 contributing planes
117 template<>
119  double V[2][2];
120 
121  static constexpr PhiInterpType PIT = PhiInterpType::Planes;
122  static constexpr VarType VT = VarType::Vector2D;
123 
124  static constexpr int NDIM(){return 2;}
125  static constexpr int NPHI(){return 2;}
126  static constexpr int SIZE(){return NDIM()*NPHI();}
127 
135  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const double (&wphi)[2], const FieldCorrection& corr) const{
136  vec.r[i_simd] += wp*(wphi[0]*( corr.r0*V[PIR][0] + corr.z0*V[PIZ][0] )
137  + wphi[1]*( corr.r0*V[PIR][1] + corr.z0*V[PIZ][1] ) );
138  vec.z[i_simd] += wp*(wphi[0]*( corr.r1*V[PIR][0] + corr.z1*V[PIZ][0] )
139  + wphi[1]*( corr.r1*V[PIR][1] + corr.z1*V[PIZ][1] ) );
140  }
141 };
142 
143 //Struct used for ddpotdt_phi_ff, As_phi_ff, Ah_phi_ff for EM. 2 contributing planes
144 template<>
146  double S[2];
147 
148  static constexpr PhiInterpType PIT = PhiInterpType::Planes;
149  static constexpr VarType VT = VarType::Scalar;
150 
151  static constexpr int NDIM(){return 1;}
152  static constexpr int NPHI(){return 2;}
153  static constexpr int SIZE(){return NDIM()*NPHI();}
154 
161  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp, const double (&wphi)[2]) const{
162  sca[i_simd] += wp* ( wphi[0]*S[0] + wphi[1]*S[1] );
163  }
164 
172  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp, const FieldWeights<GyroKin, PhiInterpType::Planes>& wts, const Field<VarType::Scalar,PhiInterpType::Planes>& field2) const{
173 # ifdef NEWGYROMATRIX
174  sca[i_simd] += wp* ( wts.phi.w[0]*wts.rho[0].w[0]*S[0]
175  + wts.phi.w[1]*wts.rho[1].w[0]*S[1]
176  + wts.phi.w[0]*wts.rho[0].w[1]*field2.S[0]
177  + wts.phi.w[1]*wts.rho[1].w[1]*field2.S[1]);
178 # else
179  sca[i_simd] += wp* ( wts.phi.w[0]*wts.rho.w[0]*S[0]
180  + wts.phi.w[1]*wts.rho.w[0]*S[1]
181  + wts.phi.w[0]*wts.rho.w[1]*field2.S[0]
182  + wts.phi.w[1]*wts.rho.w[1]*field2.S[1]);
183 # endif
184  }
185 
186  // Scatter
187  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<DriftKin, PhiInterpType::Planes>& wts, double wp){
188  access_add(&(S[0]), wp*wts.phi.w[0]);
189  access_add(&(S[1]), wp*wts.phi.w[1]);
190  }
191 
192  // Scatter (gyrokinetic)
193  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<GyroKin, PhiInterpType::Planes>& wts, double wp, Field<VarType::Scalar,PhiInterpType::Planes>& field2){
194 #ifdef NEWGYROMATRIX
195  access_add(&(S[0]), wp*wts.phi.w[0]*wts.rho[0].w[0]);
196  access_add(&(S[1]), wp*wts.phi.w[1]*wts.rho[1].w[0]);
197  access_add(&(field2.S[0]), wp*wts.phi.w[0]*wts.rho[0].w[1]);
198  access_add(&(field2.S[1]), wp*wts.phi.w[1]*wts.rho[1].w[1]);
199 #else
200  access_add(&(S[0]), wp*wts.phi.w[0]*wts.rho.w[0]);
201  access_add(&(S[1]), wp*wts.phi.w[1]*wts.rho.w[0]);
202  access_add(&(field2.S[0]), wp*wts.phi.w[0]*wts.rho.w[1]);
203  access_add(&(field2.S[1]), wp*wts.phi.w[1]*wts.rho.w[1]);
204 #endif
205  }
206 
208  S[0] += rhs.S[0];
209  S[1] += rhs.S[1];
210  return *this;
211  }
212 };
213 
214 // Struct used for E_rho, dEr_B2, dEz_B2, and du2_E_rho. 2 vector components (r,z)
215 template<>
217  double E[2];
218 
219  static constexpr PhiInterpType PIT = PhiInterpType::None;
220  static constexpr VarType VT = VarType::Vector2D;
221 
222  static constexpr int NDIM(){return 2;}
223  static constexpr int NPHI(){return 1;}
224  static constexpr int SIZE(){return NDIM()*NPHI();}
225 
232  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const FieldCorrection& corr) const{
233  vec.r[i_simd] += wp*( corr.r0*E[PIR] + corr.z0*E[PIZ] );
234  vec.z[i_simd] += wp*( corr.r1*E[PIR] + corr.z1*E[PIZ] );
235  }
236 
245  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const FieldWeights<GyroKin, PhiInterpType::None>& wts, const FieldCorrection& corr, const Field<VarType::Vector2D,PhiInterpType::None>& field2) const{
246  vec.r[i_simd] += wp*( corr.r0*(wts.rho.w[0]*E[PIR] + wts.rho.w[1]*field2.E[PIR])
247  +corr.z0*(wts.rho.w[0]*E[PIZ] + wts.rho.w[1]*field2.E[PIZ]) );
248  vec.z[i_simd] += wp*( corr.r1*(wts.rho.w[0]*E[PIR] + wts.rho.w[1]*field2.E[PIR])
249  +corr.z1*(wts.rho.w[0]*E[PIZ] + wts.rho.w[1]*field2.E[PIZ]) );
250  }
251 
252 };
253 
254 // Struct for vector without planar interpolation
255 template<>
257  double V[3];
258 
259  static constexpr PhiInterpType PIT = PhiInterpType::None;
260  static constexpr VarType VT = VarType::Vector;
261 
262  static constexpr int NDIM(){return 3;}
263  static constexpr int NPHI(){return 1;}
264  static constexpr int SIZE(){return NDIM()*NPHI();}
265 
272  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp) const{
273  vec.r[i_simd] += wp*V[PIR];
274  vec.z[i_simd] += wp*V[PIZ];
275  vec.phi[i_simd] += wp*V[PIP];
276  }
277 };
278 
279 // Struct for scalar without planar interpolation (i.e. just a double)
280 template<>
282  double S;
283 
284  static constexpr PhiInterpType PIT = PhiInterpType::None;
285  static constexpr VarType VT = VarType::Scalar;
286 
287  static constexpr int NDIM(){return 1;}
288  static constexpr int NPHI(){return 1;}
289  static constexpr int SIZE(){return NDIM()*NPHI();}
290 
296  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp){
297  sca[i_simd] += wp*S;
298  }
299 
300  // Scatter
301  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<DriftKin, PhiInterpType::None>& wts, double wp){
302  access_add(&S, wp);
303  }
304 
305  // Scatter (gyrokinetic)
306  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<GyroKin, PhiInterpType::None>& wts, double wp, Field<VarType::Scalar,PhiInterpType::None>& field2){
307  access_add(&(S),wp*wts.rho.w[0]);
308  access_add(&(field2.S),wp*wts.rho.w[1]);
309  }
310 
311  /* Cleaner access patterns if interacting with the same type */
312 
313  KOKKOS_INLINE_FUNCTION void operator += (const Field<VarType::Scalar,PhiInterpType::None>& rhs){
314  S += rhs.S;
315  }
316 
317  /* Cleaner access patterns if interacting with a double */
318 
319  // Conversion to double
320  KOKKOS_INLINE_FUNCTION explicit operator double() const {
321  return S;
322  }
323 
324  // Assignment from double
325  KOKKOS_INLINE_FUNCTION void operator = (const double val) {
326  S = val;
327  }
328 
329  // Add double
330  KOKKOS_INLINE_FUNCTION void operator += (const double val){
331  S += val;
332  }
333 };
334 
335 #endif
VarType
Definition: field.hpp:16
static constexpr int SIZE()
Definition: field.hpp:153
KOKKOS_INLINE_FUNCTION void set(int i_simd, double basis, const SimdVector2D &gradpsi)
Definition: field.hpp:40
Simd< double > r
Definition: simd.hpp:150
Definition: simd.hpp:149
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const FieldWeights< GyroKin, PhiInterpType::None > &wts, const FieldCorrection &corr, const Field< VarType::Vector2D, PhiInterpType::None > &field2) const
Definition: field.hpp:245
static constexpr int SIZE()
Definition: field.hpp:264
static constexpr int NDIM()
Definition: field.hpp:222
constexpr VarType vec2d_if_axisym()
static constexpr int SIZE()
Definition: field.hpp:126
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< DriftKin, PhiInterpType::Planes > &wts, double wp)
Definition: field.hpp:187
LinearWeights phi
Definition: field_weights.hpp:35
double r1
Definition: field.hpp:33
static constexpr int NPHI()
Definition: field.hpp:152
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< DriftKin, PhiInterpType::None > &wts, double wp)
Definition: field.hpp:301
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< GyroKin, PhiInterpType::None > &wts, double wp, Field< VarType::Scalar, PhiInterpType::None > &field2)
Definition: field.hpp:306
double S[2]
Definition: field.hpp:146
double r0
Definition: field.hpp:32
PhiInterpType
Definition: globals.hpp:95
Definition: field_weights.hpp:33
Definition: field_weights.hpp:49
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const double(&wphi)[2], const FieldCorrection &corr) const
Definition: field.hpp:71
LinearWeights rho
Definition: field_weights.hpp:36
r coordinate
Definition: globals.hpp:162
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const FieldCorrection &corr) const
Definition: field.hpp:232
static constexpr int SIZE()
Definition: field.hpp:289
static constexpr int NDIM()
Definition: field.hpp:124
KOKKOS_INLINE_FUNCTION void access_add(T *addr, T val)
Definition: access_add.hpp:30
static constexpr int NPHI()
Definition: field.hpp:288
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const double(&wphi)[2], const FieldCorrection &corr) const
Definition: field.hpp:135
Definition: field_weights.hpp:62
static constexpr int NPHI()
Definition: field.hpp:223
static constexpr int NPHI()
Definition: field.hpp:263
static constexpr int SIZE()
Definition: field.hpp:224
double z1
Definition: field.hpp:35
double S
Definition: field.hpp:282
Definition: field.hpp:28
Simd< double > z
Definition: simd.hpp:141
double w[2]
Definition: linear_weights.hpp:9
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp, const FieldWeights< GyroKin, PhiInterpType::Planes > &wts, const Field< VarType::Scalar, PhiInterpType::Planes > &field2) const
Definition: field.hpp:172
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp)
Definition: field.hpp:296
Simd< double > phi
Definition: simd.hpp:152
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const FieldWeights< GyroKin, PhiInterpType::Planes > &wts, const FieldCorrection &corr, const Field< VarType::Vector, PhiInterpType::Planes > &field2) const
Definition: field.hpp:88
static constexpr int NDIM()
Definition: field.hpp:60
Simd< double > z
Definition: simd.hpp:151
Definition: field.hpp:50
static constexpr int SIZE()
Definition: field.hpp:62
static constexpr int NPHI()
Definition: field.hpp:125
Simd< double > r
Definition: simd.hpp:140
static constexpr int NDIM()
Definition: field.hpp:287
Definition: simd.hpp:139
LinearWeights phi
Definition: field_weights.hpp:51
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp, const double(&wphi)[2]) const
Definition: field.hpp:161
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< GyroKin, PhiInterpType::Planes > &wts, double wp, Field< VarType::Scalar, PhiInterpType::Planes > &field2)
Definition: field.hpp:193
static constexpr int NDIM()
Definition: field.hpp:151
phi coordinate
Definition: globals.hpp:164
KOKKOS_INLINE_FUNCTION FieldCorrection(const SimdVector2D &gradpsi, int i_simd)
Definition: field.hpp:37
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp) const
Definition: field.hpp:272
LinearWeights rho
Definition: field_weights.hpp:64
const double gamma_psi
Definition: field.hpp:29
double z0
Definition: field.hpp:34
z coordinate
Definition: globals.hpp:163
double E[2]
Definition: field.hpp:217
double V[3][2]
Definition: field.hpp:55
static constexpr int NPHI()
Definition: field.hpp:61
Field< VarType::Scalar, PhiInterpType::Planes > & operator+=(const Field< VarType::Scalar, PhiInterpType::Planes > &rhs)
Definition: field.hpp:207
Definition: field_weights.hpp:74
static constexpr int NDIM()
Definition: field.hpp:262