XGCa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
magnetic_field.hpp
Go to the documentation of this file.
1 #ifndef MAGNETIC_FIELD_HPP
2 #define MAGNETIC_FIELD_HPP
3 #include "analytic_psi.hpp"
4 #include "analytic_I.hpp"
6 #include "equil.hpp"
7 #include "bicub.hpp"
8 #include "cub_interp.hpp"
9 
10 // Magnetic field class
11 template<class Device>
13 
14  KOKKOS_INLINE_FUNCTION void derivs(const double (&x)[2],double phi,double (&dx)[2]) const;
15 
16  public:
17 
18  // Field variables
19  double bt_sign;
20  double bp_sign;
21  int ff_step;
22  int ff_order;
24 
25  double inpsi;
26  double outpsi;
27 
28 
29  // Structures inside B-field
33 
34  inline MagneticField(NLReader::NamelistReader& nlr, const MagneticEquilFiles& equil_files, const View<Equil::XPoint*, HostType>& xpts);
35 
36  // Create a mirror with a different device type
37  template<class Device2>
40  m.bt_sign = bt_sign;
41  m.bp_sign = bp_sign;
42  m.ff_step = ff_step;
43  m.ff_order = ff_order;
44  m.bounds = bounds;
45 
46  m.inpsi = inpsi;
47  m.outpsi = outpsi;
48 
49  m.equil = equil;
50 
51  m.psi_bicub = psi_bicub.template mirror<Device2>();
52  m.I_interp = I_interp.template mirror<Device2>();
53 
54  return m;
55  }
56 
57  /* Constructor for analytic test field
58  * Note safety_factor_coeff is not the safety factor, it just scales with it.
59  * If eq_mz and eq_mpsi are not provided, they will be set to eq_mr.
60  */
61  MagneticField(PsiOption psi_opt, double safety_factor_coeff=1.0, int eq_mr_in=-1, int eq_mz_in=-1, int eq_mpsi_in=-1)
62  : inpsi(0.0),
63  outpsi(2.0),
64 
65  bt_sign(-1),
66  bp_sign(1),
67 
68  bounds(0.5, 2.5, -1.0, 1.0),
69 
70  ff_step(3),
71  ff_order(4),
72 
73  equil(psi_opt)
74  {
75  // eq_mr = 100 as default
76  int eq_mr = (eq_mr_in==-1 ? 100 : eq_mr_in);
77 
78  /* Set up psi_bicub */
79  // Set eq_mz to eq_mr if not provided
80  int eq_mz = (eq_mz_in==-1 ? eq_mr : eq_mz_in);
81 
82  // Set up linear grid in r and z
83  auto rgrid = create_range_view("rgrid", equil.bounds.min_r, equil.bounds.max_r, eq_mr);
84  auto zgrid = create_range_view("zgrid", equil.bounds.min_z, equil.bounds.max_z, eq_mz);
85 
86  // Get psi and initialize object
87  psi_bicub = Bicub<Device>(rgrid, zgrid, analytic_psi_grid(equil, rgrid, zgrid));
88 
89  /* Set up I_interp */
90  // Set eq_mpsi to eq_mr if not provided
91  int eq_mpsi = (eq_mpsi_in==-1 ? eq_mr : eq_mpsi_in);
92 
93  // Set up linear grid in psi using inpsi and outpsi as psi bounds
94  auto psigrid = create_range_view("psigrid", inpsi, outpsi, eq_mpsi);
95 
96  // Get I and initialize object
97  I_interp = CubInterp<Device>(psigrid, analytic_I_grid(safety_factor_coeff, psigrid));
98  }
99 
100  // Default constructor
102 
103  KOKKOS_INLINE_FUNCTION void get_psi(const SimdVector2D& x,Simd<double>& psi_out) const;
104 
105  KOKKOS_INLINE_FUNCTION double get_psi(double r, double z) const;
106 
107  KOKKOS_INLINE_FUNCTION void get_psi_unit_vec(const SimdVector2D& x, Simd<double>& cosa, Simd<double>& sina) const;
108 
109  KOKKOS_INLINE_FUNCTION double I_value(double psi_in,int rgn3) const;
110 
111  KOKKOS_INLINE_FUNCTION double I_deriv(double psi_in,int rgn3) const;
112 
113  KOKKOS_INLINE_FUNCTION double geometry_r(double r) const;
114 
115  // Get complete B-field info
116  KOKKOS_INLINE_FUNCTION void field(const SimdVector2D& x, SimdVector &bvec, SimdVector (&jacb)[3], Simd<double>& psivec, SimdVector2D &gradpsi, SimdVector &tdb, Simd<bool>& rz_outside) const;
117 
118  KOKKOS_INLINE_FUNCTION void bvec_interpol(double r,double z,double phi,double &br,double &bz,double &bphi) const;
119 
120  KOKKOS_INLINE_FUNCTION void bmag_interpol(const SimdVector& v, Simd<double>& bmag) const;
121 
122  KOKKOS_INLINE_FUNCTION void bmag_interpol(const SimdVector2D& x, const Simd<double>& phi,Simd<double>& bmag) const;
123 
124  KOKKOS_INLINE_FUNCTION void follow_field(const SimdVector2D &x_org,const Simd<double>& phi_org, const Simd<double>& phi_dest,SimdVector2D &x_dest) const;
125 };
126 
127 #include "magnetic_field.tpp"
128 #endif
double inpsi
Boundary condition used in a few spots.
Definition: magnetic_field.hpp:25
CubInterp< Device > I_interp
The object for interpolating I (for deriving toroidal magnetic field)
Definition: magnetic_field.hpp:31
KOKKOS_INLINE_FUNCTION void bvec_interpol(double r, double z, double phi, double &br, double &bz, double &bphi) const
Definition: magnetic_field.tpp:204
Definition: simd.hpp:149
Definition: magnetic_equil_files.hpp:16
PsiOption
Definition: equil.hpp:10
KOKKOS_INLINE_FUNCTION void follow_field(const SimdVector2D &x_org, const Simd< double > &phi_org, const Simd< double > &phi_dest, SimdVector2D &x_dest) const
Definition: magnetic_field.tpp:270
KOKKOS_INLINE_FUNCTION double geometry_r(double r) const
Definition: magnetic_field.tpp:117
Definition: rz_bounds.hpp:4
int ff_order
Order of RK scheme used for field following. Can be 1, 2, or 4.
Definition: magnetic_field.hpp:22
View< double *, HostType > create_range_view(std::string name, double x_min, double x_max, int n)
Definition: range_view.hpp:6
Definition: NamelistReader.hpp:193
Definition: magnetic_field.hpp:12
KOKKOS_INLINE_FUNCTION double I_deriv(double psi_in, int rgn3) const
Definition: magnetic_field.tpp:102
RZBounds bounds
Simulation boundary.
Definition: magnetic_field.hpp:23
MagneticField(PsiOption psi_opt, double safety_factor_coeff=1.0, int eq_mr_in=-1, int eq_mz_in=-1, int eq_mpsi_in=-1)
Definition: magnetic_field.hpp:61
Equilibrium equil
The object containing information about the magnetic equilibrium.
Definition: magnetic_field.hpp:32
KOKKOS_INLINE_FUNCTION void bmag_interpol(const SimdVector &v, Simd< double > &bmag) const
Definition: magnetic_field.tpp:239
Definition: cub_interp.hpp:12
MagneticField()
Definition: magnetic_field.hpp:101
KOKKOS_INLINE_FUNCTION double I_value(double psi_in, int rgn3) const
Definition: magnetic_field.tpp:91
KOKKOS_INLINE_FUNCTION void get_psi(const SimdVector2D &x, Simd< double > &psi_out) const
Definition: magnetic_field.tpp:57
double outpsi
Boundary condition used in a few spots.
Definition: magnetic_field.hpp:26
double max_z
Definition: rz_bounds.hpp:8
double bt_sign
Whether toroidal field is reversed?
Definition: magnetic_field.hpp:19
double min_r
Definition: rz_bounds.hpp:5
Definition: bicub.hpp:14
RZBounds bounds
Min and max for r and z.
Definition: equil.hpp:78
double bp_sign
Whether poloidal field is reversed?
Definition: magnetic_field.hpp:20
Definition: simd.hpp:139
KOKKOS_INLINE_FUNCTION void field(const SimdVector2D &x, SimdVector &bvec, SimdVector(&jacb)[3], Simd< double > &psivec, SimdVector2D &gradpsi, SimdVector &tdb, Simd< bool > &rz_outside) const
Definition: magnetic_field.tpp:131
KOKKOS_INLINE_FUNCTION void get_psi_unit_vec(const SimdVector2D &x, Simd< double > &cosa, Simd< double > &sina) const
Definition: magnetic_field.tpp:76
double min_z
Definition: rz_bounds.hpp:7
Bicub< Device > psi_bicub
The object for interpolating psi (magnetic flux surfaces)
Definition: magnetic_field.hpp:30
int ff_step
Number of steps taken when projecting the particle location onto the midplane.
Definition: magnetic_field.hpp:21
KOKKOS_INLINE_FUNCTION void derivs(const double(&x)[2], double phi, double(&dx)[2]) const
Definition: magnetic_field.tpp:384
Definition: equil.hpp:28
MagneticField< Device2 > mirror() const
Definition: magnetic_field.hpp:38
double max_r
Definition: rz_bounds.hpp:6