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 "gyro_radius.hpp"
12 
13 /* VarType specifies whether the field is a vector, a 2D vector, or a scalar
14  * */
15 enum class VarType{
16  Vector,
17  Vector2D,
18  Scalar
19 };
20 
21 /* Compile-time function to use 2D vector if field-following planes are not used (i.e. XGCa) */
22 template<PhiInterpType PIT> constexpr VarType vec2d_if_axisym();
23 template<> constexpr VarType vec2d_if_axisym<PhiInterpType::Planes>(){return VarType::Vector;}
24 template<> constexpr VarType vec2d_if_axisym<PhiInterpType::None>(){return VarType::Vector2D;}
25 
26 /* Coordinate correction for field interpolations */
28  const double gamma_psi;
29 
30  public:
31  double r0;
32  double r1;
33  double z0;
34  double z1;
35 
36  KOKKOS_INLINE_FUNCTION FieldCorrection(const SimdVector2D& gradpsi, int i_simd)
37  : gamma_psi(1.0/gradpsi.magnitude(i_simd)) {}
38 
39  KOKKOS_INLINE_FUNCTION void set(int i_simd, double basis, const SimdVector2D &gradpsi){
40  r0 = basis + (1.0-basis) * gamma_psi * gradpsi.r[i_simd];
41  r1 = (1.0-basis) * gamma_psi * gradpsi.z[i_simd];
42  z0 = (1.0-basis) * gamma_psi *(-gradpsi.z[i_simd]);
43  z1 = basis + (1.0-basis) * gamma_psi * gradpsi.r[i_simd];
44  }
45 };
46 
47 
48 template<VarType VT, PhiInterpType PIT>
49 struct Field{};
50 
51 //Struct used for E_phi_ff, dAs_phi_ff, dAh_phi_ff, As_phi_ff, Ah_phi_ff. 3 vector components, 2 contributing planes
52 template<>
54  double V[3][2];
55 
56  static constexpr PhiInterpType PIT = PhiInterpType::Planes;
57  static constexpr VarType VT = VarType::Vector;
58 
59  static constexpr int NDIM(){return 3;}
60  static constexpr int NPHI(){return 2;}
61  static constexpr int SIZE(){return NDIM()*NPHI();}
62 
70  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, const FieldCorrection& corr) const{
71  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
72  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
73  vec.r[i_simd] += wp*(phi_w0*( corr.r0*V[PIR][0] + corr.z0*V[PIZ][0] )
74  + phi_w1*( corr.r0*V[PIR][1] + corr.z0*V[PIZ][1] ) );
75  vec.z[i_simd] += wp*(phi_w0*( corr.r1*V[PIR][0] + corr.z1*V[PIZ][0] )
76  + phi_w1*( corr.r1*V[PIR][1] + corr.z1*V[PIZ][1] ) );
77  vec.phi[i_simd] += wp*(phi_w0* V[PIP][0]
78  + phi_w1* V[PIP][1] );
79  }
80 
89  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const SimdGyroWeights<GyroKin>& rho_wts, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, const FieldCorrection& corr, const Field<VarType::Vector,PhiInterpType::Planes>& field2) const{
90  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
91  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
92 #ifdef NEWGYROMATRIX
93  const double& rho_w00 = rho_wts.rho_wts[0].w[0][i_simd];
94  const double& rho_w01 = rho_wts.rho_wts[0].w[1][i_simd];
95  const double& rho_w10 = rho_wts.rho_wts[1].w[0][i_simd];
96  const double& rho_w11 = rho_wts.rho_wts[1].w[1][i_simd];
97 #else
98  const double& rho_w00 = rho_wts.rho_wts.w[0][i_simd];
99  const double& rho_w01 = rho_wts.rho_wts.w[1][i_simd];
100  const double& rho_w10 = rho_wts.rho_wts.w[0][i_simd]; // = w00
101  const double& rho_w11 = rho_wts.rho_wts.w[1][i_simd]; // = w01
102 #endif
103 
104  vec.r[i_simd] += wp*(phi_w0*( corr.r0*(rho_w00*V[PIR][0] + rho_w01*field2.V[PIR][0])
105  + corr.z0*(rho_w00*V[PIZ][0] + rho_w01*field2.V[PIZ][0]) )
106  + phi_w1*( corr.r0*(rho_w10*V[PIR][1] + rho_w11*field2.V[PIR][1])
107  + corr.z0*(rho_w10*V[PIZ][1] + rho_w11*field2.V[PIZ][1]) ) );
108  vec.z[i_simd] += wp*(phi_w0*( corr.r1*(rho_w00*V[PIR][0] + rho_w01*field2.V[PIR][0])
109  + corr.z1*(rho_w00*V[PIZ][0] + rho_w01*field2.V[PIZ][0]) )
110  + phi_w1*( corr.r1*(rho_w10*V[PIR][1] + rho_w11*field2.V[PIR][1])
111  + corr.z1*(rho_w10*V[PIZ][1] + rho_w11*field2.V[PIZ][1]) ) );
112  vec.phi[i_simd] += wp*(phi_w0* (rho_w00*V[PIP][0] + rho_w01*field2.V[PIP][0])
113  + phi_w1* (rho_w10*V[PIP][1] + rho_w11*field2.V[PIP][1]) );
114  }
115 
116 };
117 
118 //Struct used for E00_ff. 2 vector components, 2 contributing planes
119 template<>
121  double V[2][2];
122 
123  static constexpr PhiInterpType PIT = PhiInterpType::Planes;
124  static constexpr VarType VT = VarType::Vector2D;
125 
126  static constexpr int NDIM(){return 2;}
127  static constexpr int NPHI(){return 2;}
128  static constexpr int SIZE(){return NDIM()*NPHI();}
129 
137  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, const FieldCorrection& corr) const{
138  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
139  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
140  vec.r[i_simd] += wp*(phi_w0*( corr.r0*V[PIR][0] + corr.z0*V[PIZ][0] )
141  + phi_w1*( corr.r0*V[PIR][1] + corr.z0*V[PIZ][1] ) );
142  vec.z[i_simd] += wp*(phi_w0*( corr.r1*V[PIR][0] + corr.z1*V[PIZ][0] )
143  + phi_w1*( corr.r1*V[PIR][1] + corr.z1*V[PIZ][1] ) );
144  }
145 };
146 
147 //Struct used for ddpotdt_phi_ff, As_phi_ff, Ah_phi_ff for EM. 2 contributing planes
148 template<>
150  double S[2];
151 
152  static constexpr PhiInterpType PIT = PhiInterpType::Planes;
153  static constexpr VarType VT = VarType::Scalar;
154 
155  static constexpr int NDIM(){return 1;}
156  static constexpr int NPHI(){return 2;}
157  static constexpr int SIZE(){return NDIM()*NPHI();}
158 
165  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts) const{
166  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
167  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
168  sca[i_simd] += wp* ( phi_w0*S[0] + phi_w1*S[1] );
169  }
170 
178  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp, const SimdGyroWeights<GyroKin>& rho_wts, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, const Field<VarType::Scalar,PhiInterpType::Planes>& field2) const{
179  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
180  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
181 #ifdef NEWGYROMATRIX
182  const double& rho_w00 = rho_wts.rho_wts[0].w[0][i_simd];
183  const double& rho_w01 = rho_wts.rho_wts[0].w[1][i_simd];
184  const double& rho_w10 = rho_wts.rho_wts[1].w[0][i_simd];
185  const double& rho_w11 = rho_wts.rho_wts[1].w[1][i_simd];
186 #else
187  const double& rho_w00 = rho_wts.rho_wts.w[0][i_simd];
188  const double& rho_w01 = rho_wts.rho_wts.w[1][i_simd];
189  const double& rho_w10 = rho_wts.rho_wts.w[0][i_simd]; // = w00
190  const double& rho_w11 = rho_wts.rho_wts.w[1][i_simd]; // = w01
191 #endif
192 
193  sca[i_simd] += wp* ( phi_w0*rho_w00*S[0]
194  + phi_w1*rho_w10*S[1]
195  + phi_w0*rho_w01*field2.S[0]
196  + phi_w1*rho_w11*field2.S[1]);
197  }
198 
199  // Scatter
200  KOKKOS_INLINE_FUNCTION void scatter(const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, int i_simd, double wp){
201  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
202  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
203  access_add(&(S[0]), wp*phi_w0);
204  access_add(&(S[1]), wp*phi_w1);
205  }
206 
207  // Scatter (gyrokinetic)
208  KOKKOS_INLINE_FUNCTION void scatter(const SimdGyroWeights<GyroKin>& rho_wts, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, int i_simd, double wp, Field<VarType::Scalar,PhiInterpType::Planes>& field2){
209  const double& phi_w0 = phi_wts.phi.w[0][i_simd];
210  const double& phi_w1 = phi_wts.phi.w[1][i_simd];
211 #ifdef NEWGYROMATRIX
212  const double& rho_w00 = rho_wts.rho_wts[0].w[0][i_simd];
213  const double& rho_w01 = rho_wts.rho_wts[0].w[1][i_simd];
214  const double& rho_w10 = rho_wts.rho_wts[1].w[0][i_simd];
215  const double& rho_w11 = rho_wts.rho_wts[1].w[1][i_simd];
216 #else
217  const double& rho_w00 = rho_wts.rho_wts.w[0][i_simd];
218  const double& rho_w01 = rho_wts.rho_wts.w[1][i_simd];
219  const double& rho_w10 = rho_wts.rho_wts.w[0][i_simd]; // = w00
220  const double& rho_w11 = rho_wts.rho_wts.w[1][i_simd]; // = w01
221 #endif
222 
223  access_add(&(S[0]), wp*phi_w0*rho_w00);
224  access_add(&(S[1]), wp*phi_w1*rho_w10);
225  access_add(&(field2.S[0]), wp*phi_w0*rho_w01);
226  access_add(&(field2.S[1]), wp*phi_w1*rho_w11);
227  }
228 
230  S[0] += rhs.S[0];
231  S[1] += rhs.S[1];
232  return *this;
233  }
234 };
235 
236 // Struct used for E_rho, dEr_B2, dEz_B2, and du2_E_rho. 2 vector components (r,z)
237 template<>
239  double E[2];
240 
241  static constexpr PhiInterpType PIT = PhiInterpType::None;
242  static constexpr VarType VT = VarType::Vector2D;
243 
244  static constexpr int NDIM(){return 2;}
245  static constexpr int NPHI(){return 1;}
246  static constexpr int SIZE(){return NDIM()*NPHI();}
247 
254  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const FieldCorrection& corr) const{
255  vec.r[i_simd] += wp*( corr.r0*E[PIR] + corr.z0*E[PIZ] );
256  vec.z[i_simd] += wp*( corr.r1*E[PIR] + corr.z1*E[PIZ] );
257  }
258 
267  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const SimdGyroWeights<GyroKin>& rho_wts, const FieldCorrection& corr, const Field<VarType::Vector2D,PhiInterpType::None>& field2) const{
268  const double& rho_w00 = rho_wts.rho_wts.w[0][i_simd];
269  const double& rho_w01 = rho_wts.rho_wts.w[1][i_simd];
270  vec.r[i_simd] += wp*( corr.r0*(rho_w00*E[PIR] + rho_w01*field2.E[PIR])
271  +corr.z0*(rho_w00*E[PIZ] + rho_w01*field2.E[PIZ]) );
272  vec.z[i_simd] += wp*( corr.r1*(rho_w00*E[PIR] + rho_w01*field2.E[PIR])
273  +corr.z1*(rho_w00*E[PIZ] + rho_w01*field2.E[PIZ]) );
274  }
275 
276 };
277 
278 // Struct for vector without planar interpolation
279 template<>
281  double V[3];
282 
283  static constexpr PhiInterpType PIT = PhiInterpType::None;
284  static constexpr VarType VT = VarType::Vector;
285 
286  static constexpr int NDIM(){return 3;}
287  static constexpr int NPHI(){return 1;}
288  static constexpr int SIZE(){return NDIM()*NPHI();}
289 
296  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp) const{
297  vec.r[i_simd] += wp*V[PIR];
298  vec.z[i_simd] += wp*V[PIZ];
299  vec.phi[i_simd] += wp*V[PIP];
300  }
301 };
302 
303 // Struct for scalar without planar interpolation (i.e. just a double)
304 template<>
306  double S;
307 
308  static constexpr PhiInterpType PIT = PhiInterpType::None;
309  static constexpr VarType VT = VarType::Scalar;
310 
311  static constexpr int NDIM(){return 1;}
312  static constexpr int NPHI(){return 1;}
313  static constexpr int SIZE(){return NDIM()*NPHI();}
314 
320  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp){
321  sca[i_simd] += wp*S;
322  }
323 
324  // Scatter
325  KOKKOS_INLINE_FUNCTION void scatter(const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, int i_simd, double wp){
326  access_add(&S, wp);
327  }
328 
329  // Scatter (gyrokinetic)
330  KOKKOS_INLINE_FUNCTION void scatter(const SimdGyroWeights<GyroKin>& rho_wts, const SimdPhiWeights<get_phi_wt_usage(PIT)>& phi_wts, int i_simd, double wp, Field<VarType::Scalar,PhiInterpType::None>& field2){
331  const double& rho_w00 = rho_wts.rho_wts.w[0][i_simd];
332  const double& rho_w01 = rho_wts.rho_wts.w[1][i_simd];
333  access_add(&( S),wp*rho_w00);
334  access_add(&(field2.S),wp*rho_w01);
335  }
336 
337  /* Cleaner access patterns if interacting with the same type */
338 
339  KOKKOS_INLINE_FUNCTION void operator += (const Field<VarType::Scalar,PhiInterpType::None>& rhs){
340  S += rhs.S;
341  }
342 
343  /* Cleaner access patterns if interacting with a double */
344 
345  // Conversion to double
346  KOKKOS_INLINE_FUNCTION explicit operator double() const {
347  return S;
348  }
349 
350  // Assignment from double
351  KOKKOS_INLINE_FUNCTION void operator = (const double val) {
352  S = val;
353  }
354 
355  // Add double
356  KOKKOS_INLINE_FUNCTION void operator += (const double val){
357  S += val;
358  }
359 };
360 
361 #endif
KOKKOS_INLINE_FUNCTION void scatter(const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, int i_simd, double wp)
Definition: field.hpp:200
VarType
Definition: field.hpp:15
static constexpr int SIZE()
Definition: field.hpp:157
KOKKOS_INLINE_FUNCTION void set(int i_simd, double basis, const SimdVector2D &gradpsi)
Definition: field.hpp:39
Simd< double > r
Definition: simd.hpp:150
Definition: simd.hpp:149
static constexpr int SIZE()
Definition: field.hpp:288
static constexpr int NDIM()
Definition: field.hpp:244
constexpr VarType vec2d_if_axisym()
static constexpr int SIZE()
Definition: field.hpp:128
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const SimdGyroWeights< GyroKin > &rho_wts, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, const FieldCorrection &corr, const Field< VarType::Vector, PhiInterpType::Planes > &field2) const
Definition: field.hpp:89
KOKKOS_INLINE_FUNCTION void scatter(const SimdGyroWeights< GyroKin > &rho_wts, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, int i_simd, double wp, Field< VarType::Scalar, PhiInterpType::Planes > &field2)
Definition: field.hpp:208
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, const FieldCorrection &corr) const
Definition: field.hpp:137
KOKKOS_INLINE_FUNCTION void scatter(const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, int i_simd, double wp)
Definition: field.hpp:325
double r1
Definition: field.hpp:32
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts) const
Definition: field.hpp:165
static constexpr int NPHI()
Definition: field.hpp:156
constexpr KOKKOS_INLINE_FUNCTION PhiWtUsage get_phi_wt_usage(PhiInterpType PIT)
Definition: grid_weights.hpp:15
double S[2]
Definition: field.hpp:150
SimdLinearWeights rho_wts
Definition: gyro_radius.hpp:87
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const SimdGyroWeights< GyroKin > &rho_wts, const FieldCorrection &corr, const Field< VarType::Vector2D, PhiInterpType::None > &field2) const
Definition: field.hpp:267
Definition: grid_weights.hpp:18
double r0
Definition: field.hpp:31
Simd< double > w[2]
Definition: linear_weights.hpp:48
PhiInterpType
Definition: globals.hpp:95
Definition: gyro_radius.hpp:84
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:254
static constexpr int SIZE()
Definition: field.hpp:313
static constexpr int NDIM()
Definition: field.hpp:126
KOKKOS_INLINE_FUNCTION void access_add(T *addr, T val)
Definition: access_add.hpp:30
static constexpr int NPHI()
Definition: field.hpp:312
static constexpr int NPHI()
Definition: field.hpp:245
static constexpr int NPHI()
Definition: field.hpp:287
static constexpr int SIZE()
Definition: field.hpp:246
double z1
Definition: field.hpp:34
double S
Definition: field.hpp:306
Definition: field.hpp:27
Simd< double > z
Definition: simd.hpp:141
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp)
Definition: field.hpp:320
Simd< double > phi
Definition: simd.hpp:152
static constexpr int NDIM()
Definition: field.hpp:59
Simd< double > z
Definition: simd.hpp:151
Definition: field.hpp:49
KOKKOS_INLINE_FUNCTION void scatter(const SimdGyroWeights< GyroKin > &rho_wts, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, int i_simd, double wp, Field< VarType::Scalar, PhiInterpType::None > &field2)
Definition: field.hpp:330
static constexpr int SIZE()
Definition: field.hpp:61
static constexpr int NPHI()
Definition: field.hpp:127
Simd< double > r
Definition: simd.hpp:140
static constexpr int NDIM()
Definition: field.hpp:311
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp, const SimdGyroWeights< GyroKin > &rho_wts, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, const Field< VarType::Scalar, PhiInterpType::Planes > &field2) const
Definition: field.hpp:178
Definition: simd.hpp:139
static constexpr int NDIM()
Definition: field.hpp:155
phi coordinate
Definition: globals.hpp:164
KOKKOS_INLINE_FUNCTION FieldCorrection(const SimdVector2D &gradpsi, int i_simd)
Definition: field.hpp:36
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp) const
Definition: field.hpp:296
const double gamma_psi
Definition: field.hpp:28
double z0
Definition: field.hpp:33
z coordinate
Definition: globals.hpp:163
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const SimdPhiWeights< get_phi_wt_usage(PIT)> &phi_wts, const FieldCorrection &corr) const
Definition: field.hpp:70
double E[2]
Definition: field.hpp:239
double V[3][2]
Definition: field.hpp:54
static constexpr int NPHI()
Definition: field.hpp:60
Field< VarType::Scalar, PhiInterpType::Planes > & operator+=(const Field< VarType::Scalar, PhiInterpType::Planes > &rhs)
Definition: field.hpp:229
static constexpr int NDIM()
Definition: field.hpp:286