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