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 int NDIM(){return 3;}
58  static constexpr int NPHI(){return 2;}
59  static constexpr int SIZE(){return NDIM()*NPHI();}
60 
68  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const double (&wphi)[2], const FieldCorrection& corr) const{
69  vec.r[i_simd] += wp*(wphi[0]*( corr.r0*V[PIR][0] + corr.z0*V[PIZ][0] )
70  + wphi[1]*( corr.r0*V[PIR][1] + corr.z0*V[PIZ][1] ) );
71  vec.z[i_simd] += wp*(wphi[0]*( corr.r1*V[PIR][0] + corr.z1*V[PIZ][0] )
72  + wphi[1]*( corr.r1*V[PIR][1] + corr.z1*V[PIZ][1] ) );
73  vec.phi[i_simd] += wp*(wphi[0]* V[PIP][0]
74  + wphi[1]* V[PIP][1] );
75  }
76 
85  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{
86 # ifdef NEWGYROMATRIX
87  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])
88  + corr.z0*(wts.rho[0].w[0]*V[PIZ][0] + wts.rho[0].w[1]*field2.V[PIZ][0]) )
89  + wts.phi.w[1]*( corr.r0*(wts.rho[1].w[0]*V[PIR][1] + wts.rho[1].w[1]*field2.V[PIR][1])
90  + corr.z0*(wts.rho[1].w[0]*V[PIZ][1] + wts.rho[1].w[1]*field2.V[PIZ][1]) ) );
91  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])
92  + corr.z1*(wts.rho[0].w[0]*V[PIZ][0] + wts.rho[0].w[1]*field2.V[PIZ][0]) )
93  + wts.phi.w[1]*( corr.r1*(wts.rho[1].w[0]*V[PIR][1] + wts.rho[1].w[1]*field2.V[PIR][1])
94  + corr.z1*(wts.rho[1].w[0]*V[PIZ][1] + wts.rho[1].w[1]*field2.V[PIZ][1]) ) );
95  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])
96  + wts.phi.w[1]* (wts.rho[1].w[0]*V[PIP][1] + wts.rho[1].w[1]*field2.V[PIP][1]) );
97 # else
98  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])
99  + corr.z0*(wts.rho.w[0]*V[PIZ][0] + wts.rho.w[1]*field2.V[PIZ][0]) )
100  + wts.phi.w[1]*( corr.r0*(wts.rho.w[0]*V[PIR][1] + wts.rho.w[1]*field2.V[PIR][1])
101  + corr.z0*(wts.rho.w[0]*V[PIZ][1] + wts.rho.w[1]*field2.V[PIZ][1]) ) );
102  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])
103  + corr.z1*(wts.rho.w[0]*V[PIZ][0] + wts.rho.w[1]*field2.V[PIZ][0]) )
104  + wts.phi.w[1]*( corr.r1*(wts.rho.w[0]*V[PIR][1] + wts.rho.w[1]*field2.V[PIR][1])
105  + corr.z1*(wts.rho.w[0]*V[PIZ][1] + wts.rho.w[1]*field2.V[PIZ][1]) ) );
106  vec.phi[i_simd] += wp*(wts.phi.w[0]* (wts.rho.w[0]*V[PIP][0] + wts.rho.w[1]*field2.V[PIP][0])
107  + wts.phi.w[1]* (wts.rho.w[0]*V[PIP][1] + wts.rho.w[1]*field2.V[PIP][1]) );
108 # endif
109  }
110 
111 };
112 
113 //Struct used for E00_ff. 2 vector components, 2 contributing planes
114 template<>
116  double V[2][2];
117 
118  static constexpr int NDIM(){return 2;}
119  static constexpr int NPHI(){return 2;}
120  static constexpr int SIZE(){return NDIM()*NPHI();}
121 
129  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const double (&wphi)[2], const FieldCorrection& corr) const{
130  vec.r[i_simd] += wp*(wphi[0]*( corr.r0*V[PIR][0] + corr.z0*V[PIZ][0] )
131  + wphi[1]*( corr.r0*V[PIR][1] + corr.z0*V[PIZ][1] ) );
132  vec.z[i_simd] += wp*(wphi[0]*( corr.r1*V[PIR][0] + corr.z1*V[PIZ][0] )
133  + wphi[1]*( corr.r1*V[PIR][1] + corr.z1*V[PIZ][1] ) );
134  }
135 };
136 
137 //Struct used for ddpotdt_phi_ff, As_phi_ff, Ah_phi_ff for EM. 2 contributing planes
138 template<>
140  double S[2];
141 
142  static constexpr int NDIM(){return 1;}
143  static constexpr int NPHI(){return 2;}
144  static constexpr int SIZE(){return NDIM()*NPHI();}
145 
152  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp, const double (&wphi)[2]) const{
153  sca[i_simd] += wp* ( wphi[0]*S[0] + wphi[1]*S[1] );
154  }
155 
163  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{
164 # ifdef NEWGYROMATRIX
165  sca[i_simd] += wp* ( wts.phi.w[0]*wts.rho[0].w[0]*S[0]
166  + wts.phi.w[1]*wts.rho[1].w[0]*S[1]
167  + wts.phi.w[0]*wts.rho[0].w[1]*field2.S[0]
168  + wts.phi.w[1]*wts.rho[1].w[1]*field2.S[1]);
169 # else
170  sca[i_simd] += wp* ( wts.phi.w[0]*wts.rho.w[0]*S[0]
171  + wts.phi.w[1]*wts.rho.w[0]*S[1]
172  + wts.phi.w[0]*wts.rho.w[1]*field2.S[0]
173  + wts.phi.w[1]*wts.rho.w[1]*field2.S[1]);
174 # endif
175  }
176 
177  // Scatter
178  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<DriftKin, PhiInterpType::Planes>& wts, double wp){
179  access_add(&(S[0]), wp*wts.phi.w[0]);
180  access_add(&(S[1]), wp*wts.phi.w[1]);
181  }
182 
183  // Scatter (gyrokinetic)
184  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<GyroKin, PhiInterpType::Planes>& wts, double wp, Field<VarType::Scalar,PhiInterpType::Planes>& field2){
185 #ifdef NEWGYROMATRIX
186  access_add(&(S[0]), wp*wts.phi.w[0]*wts.rho[0].w[0]);
187  access_add(&(S[1]), wp*wts.phi.w[1]*wts.rho[1].w[0]);
188  access_add(&(field2.S[0]), wp*wts.phi.w[0]*wts.rho[0].w[1]);
189  access_add(&(field2.S[1]), wp*wts.phi.w[1]*wts.rho[1].w[1]);
190 #else
191  access_add(&(S[0]), wp*wts.phi.w[0]*wts.rho.w[0]);
192  access_add(&(S[1]), wp*wts.phi.w[1]*wts.rho.w[0]);
193  access_add(&(field2.S[0]), wp*wts.phi.w[0]*wts.rho.w[1]);
194  access_add(&(field2.S[1]), wp*wts.phi.w[1]*wts.rho.w[1]);
195 #endif
196  }
197 
199  S[0] += rhs.S[0];
200  S[1] += rhs.S[1];
201  return *this;
202  }
203 };
204 
205 // Struct used for E_rho, dEr_B2, dEz_B2, and du2_E_rho. 2 vector components (r,z)
206 template<>
208  double E[2];
209 
210  static constexpr int NDIM(){return 2;}
211  static constexpr int NPHI(){return 1;}
212  static constexpr int SIZE(){return NDIM()*NPHI();}
213 
220  KOKKOS_INLINE_FUNCTION void gather(SimdVector& vec, int i_simd, double wp, const FieldCorrection& corr) const{
221  vec.r[i_simd] += wp*( corr.r0*E[PIR] + corr.z0*E[PIZ] );
222  vec.z[i_simd] += wp*( corr.r1*E[PIR] + corr.z1*E[PIZ] );
223  }
224 
233  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{
234  vec.r[i_simd] += wp*( corr.r0*(wts.rho.w[0]*E[PIR] + wts.rho.w[1]*field2.E[PIR])
235  +corr.z0*(wts.rho.w[0]*E[PIZ] + wts.rho.w[1]*field2.E[PIZ]) );
236  vec.z[i_simd] += wp*( corr.r1*(wts.rho.w[0]*E[PIR] + wts.rho.w[1]*field2.E[PIR])
237  +corr.z1*(wts.rho.w[0]*E[PIZ] + wts.rho.w[1]*field2.E[PIZ]) );
238  }
239 
240 };
241 
242 // Struct for scalar without planar interpolation (i.e. just a double)
243 template<>
245  double S;
246 
247  static constexpr int NDIM(){return 1;}
248  static constexpr int NPHI(){return 1;}
249  static constexpr int SIZE(){return NDIM()*NPHI();}
250 
256  KOKKOS_INLINE_FUNCTION void gather(Simd<double>& sca, int i_simd, double wp){
257  sca[i_simd] += wp*S;
258  }
259 
260  // Scatter
261  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<DriftKin, PhiInterpType::None>& wts, double wp){
262  access_add(&S, wp);
263  }
264 
265  // Scatter (gyrokinetic)
266  KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights<GyroKin, PhiInterpType::None>& wts, double wp, Field<VarType::Scalar,PhiInterpType::None>& field2){
267  access_add(&(S),wp*wts.rho.w[0]);
268  access_add(&(field2.S),wp*wts.rho.w[1]);
269  }
270 
272  S += rhs.S;
273  return *this;
274  }
275 };
276 
277 #endif
VarType
Definition: field.hpp:16
static constexpr int SIZE()
Definition: field.hpp:144
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:233
static constexpr int NDIM()
Definition: field.hpp:210
constexpr VarType vec2d_if_axisym()
static constexpr int SIZE()
Definition: field.hpp:120
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< DriftKin, PhiInterpType::Planes > &wts, double wp)
Definition: field.hpp:178
LinearWeights phi
Definition: field_weights.hpp:35
double r1
Definition: field.hpp:33
Field< VarType::Scalar, PhiInterpType::None > & operator+=(const Field< VarType::Scalar, PhiInterpType::None > &rhs)
Definition: field.hpp:271
static constexpr int NPHI()
Definition: field.hpp:143
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< DriftKin, PhiInterpType::None > &wts, double wp)
Definition: field.hpp:261
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< GyroKin, PhiInterpType::None > &wts, double wp, Field< VarType::Scalar, PhiInterpType::None > &field2)
Definition: field.hpp:266
double S[2]
Definition: field.hpp:140
double r0
Definition: field.hpp:32
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:68
LinearWeights rho
Definition: field_weights.hpp:36
r coordinate
Definition: globals.hpp:156
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const FieldCorrection &corr) const
Definition: field.hpp:220
static constexpr int SIZE()
Definition: field.hpp:249
static constexpr int NDIM()
Definition: field.hpp:118
KOKKOS_INLINE_FUNCTION void access_add(T *addr, T val)
Definition: access_add.hpp:30
static constexpr int NPHI()
Definition: field.hpp:248
KOKKOS_INLINE_FUNCTION void gather(SimdVector &vec, int i_simd, double wp, const double(&wphi)[2], const FieldCorrection &corr) const
Definition: field.hpp:129
Definition: field_weights.hpp:62
static constexpr int NPHI()
Definition: field.hpp:211
static constexpr int SIZE()
Definition: field.hpp:212
double z1
Definition: field.hpp:35
double S
Definition: field.hpp:245
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:163
KOKKOS_INLINE_FUNCTION void gather(Simd< double > &sca, int i_simd, double wp)
Definition: field.hpp:256
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:85
static constexpr int NDIM()
Definition: field.hpp:57
Simd< double > z
Definition: simd.hpp:151
Definition: field.hpp:50
static constexpr int SIZE()
Definition: field.hpp:59
static constexpr int NPHI()
Definition: field.hpp:119
Simd< double > r
Definition: simd.hpp:140
static constexpr int NDIM()
Definition: field.hpp:247
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:152
KOKKOS_INLINE_FUNCTION void scatter(const FieldWeights< GyroKin, PhiInterpType::Planes > &wts, double wp, Field< VarType::Scalar, PhiInterpType::Planes > &field2)
Definition: field.hpp:184
static constexpr int NDIM()
Definition: field.hpp:142
phi coordinate
Definition: globals.hpp:158
KOKKOS_INLINE_FUNCTION FieldCorrection(const SimdVector2D &gradpsi, int i_simd)
Definition: field.hpp:37
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:157
double E[2]
Definition: field.hpp:208
double V[3][2]
Definition: field.hpp:55
static constexpr int NPHI()
Definition: field.hpp:58
Field< VarType::Scalar, PhiInterpType::Planes > & operator+=(const Field< VarType::Scalar, PhiInterpType::Planes > &rhs)
Definition: field.hpp:198
Definition: field_weights.hpp:74