XGCa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
velocity_grid.hpp
Go to the documentation of this file.
1 #ifndef VELOCITY_GRID_HPP
2 #define VELOCITY_GRID_HPP
3 
4 #include "vgrid_weights.hpp"
5 #include "lagrange_weights.hpp"
6 
7 // Specifies the dimensions of the velocity grid
8 struct VelocityGrid{
9  int nvp;
10  double vp_max;
11  double dvp;
12 
13  int nmu;
14  double smu_max;
15  double dsmu;
16 
17  double inv_mu0_factor = 1.0/3.0;
18 
19  int nvr;
20  int nvz;
21 
23 
25 
26  VelocityGrid() = default; // Default constructor for dummy object.
27 
29  // Read in basic velocity grid inputs
30  nlr.use_namelist("f0_param");
31  nvp = nlr.get<int>("f0_nvp", 15); // Resolution of velocity space in parallel direcion. Total parallel grid points is 2*f0_nvp+1
32  nmu = nlr.get<int>("f0_nmu", 31); // Resolution of velocity space in perpendicular direction. Total perpendicular grid points is f0_nmu+1
33  vp_max = nlr.get<double>("f0_vp_max", 3.0); // Maximum parallel velocity of velocity space grid, normalized to thermal velocity
34  smu_max = nlr.get<double>("f0_smu_max", 3.0); // Maximum perpendicular velocity of velocity space grid, normalized to thermal velocity
35 
36  // Derived values
37  dvp = vp_max/nvp;
38  dsmu = smu_max/nmu;
39  nvr = nmu+1;
40  nvz = nvp*2+1;
41 
42  // Pseudo inverse
43  pseudo_inv_on = nlr.get<bool>("f0_velocity_interp_use_pseudo_inv", false); // Whether to use pseudo-inverse interpolation between particles and velocity grid
44  if(pseudo_inv_on){
45  element_order = nlr.get<int>("f0_velocity_interp_pseudo_inv_order", 2); // 1 (linear) or 2 (quadratic) pseudo-inverse interpolation, only used if f0_velocity_interp_use_pseudo_inv = .true.
46 #ifdef NO_PETSC
47  exit_XGC("\nError: Cannot run with f0_velocity_interp_use_pseudo_inv = true without using PETSc.\n");
48 #endif
49  if (element_order < 0){
50  exit_XGC("\nError: f0_velocity_interp_pseudo_inv_order must be 0 or larger.\n");
51  }
53  std::string msg = "\nError: Cannot use f0_velocity_interp_pseudo_inv_order larger than ";
54  msg += std::to_string(LAGRANGE_MAX_ORDER);
55  msg += ", if you really want to use that large order then modify LAGRANGE_MAX_ORDER in the code.\n";
56  exit_XGC(msg);
57  }
58  if (element_order > 0){
59  if(nmu % element_order != 0){
60  exit_XGC("\nError: f0_nmu must be divisible by f0_velocity_interp_pseudo_inv_order when f0_velocity_interp_use_pseudo_inv = true.\n");
61  }
62  if(2*nvp % element_order != 0){
63  exit_XGC("\nError: 2*f0_nvp must be divisible by f0_velocity_interp_pseudo_inv_order when f0_velocity_interp_use_pseudo_inv = true.\n");
64  }
65  }
66  }else{
67  element_order = 1;
68  }
69  }
70 
71  // Returns parallel velocity given a grid index
72  KOKKOS_INLINE_FUNCTION double vpar_n(int ivz) const{
73  return (ivz - nvp)*dvp;
74  }
75 
76  // Returns perpendicular velocity given a grid index
77  KOKKOS_INLINE_FUNCTION double vperp_n(int ivr) const{
78  return ivr*dsmu;
79  }
80 
81  // Returns factor to handle velocity space volume on edge of velocity grid
82  KOKKOS_INLINE_FUNCTION double mu_vol_fac(int ivr) const{
83  return (ivr==0 || ivr==nvr-1) ? 0.5 : 1.0;
84  }
85 
86  // Determine vgrid weights from input smu, vp and vgrid_vol
87  KOKKOS_INLINE_FUNCTION VGridWeights get_weights(double smu, double vp) const{ // double inv_vgrid_vol
88  // Calculate linear weights for velocity grid
89  LinearWeights vr_wt(smu, 1.0/dsmu);
90  LinearWeights vz_wt(vp + vp_max, 1.0/dvp); // Shift so minimum is 0.0
91 
92  //rh For f0_f: conversion from mu-vpar to sqrt(mu)-vpar or vperp-vpar
93  //vr_wt.w[0] *= inv_vgrid_vol * (vr_wt.i==0 ? 2.0 : 1.0);
94  //vr_wt.w[1] *= inv_vgrid_vol * (vr_wt.i==n_vr()-2 ? 2.0 : 1.0);
95 
96  if(vr_wt.i>=nmu || vz_wt.i>=2*nvp || vz_wt.i<0){
97  // Return invalid grid if out of bounds
98  return VGridWeights();
99  }else{
100  return VGridWeights(vr_wt, vz_wt);
101  }
102  }
103 
104  // Divide by dsmu, accounting for difference at edges
105  KOKKOS_INLINE_FUNCTION void weight_by_inv_dsmu(VGridWeights& vgrid_wts) const{
106  double inv_smu0 = 1.0/(dsmu*(vgrid_wts.i_vr==0 ? inv_mu0_factor : vgrid_wts.i_vr));
107  double inv_smu1 = 1.0/(dsmu*(vgrid_wts.i_vr==nmu-1 ? nmu-inv_mu0_factor : vgrid_wts.i_vr+1));
108 
109  vgrid_wts.w_00 *= inv_smu0;
110  vgrid_wts.w_01 *= inv_smu0;
111  vgrid_wts.w_10 *= inv_smu1;
112  vgrid_wts.w_11 *= inv_smu1;
113  }
114 
115  // Multiply by volume, accounting for difference at edges
116  KOKKOS_INLINE_FUNCTION void weight_by_vol(double vol, VGridWeights& vgrid_wts) const{
117  double vol0 = vol*(vgrid_wts.i_vr==0 ? 0.5 : 1.0);
118  double vol1 = vol*(vgrid_wts.i_vr==nmu-1 ? 0.5 : 1.0);
119 
120  vgrid_wts.w_00 *= vol0;
121  vgrid_wts.w_01 *= vol0;
122  vgrid_wts.w_10 *= vol1;
123  vgrid_wts.w_11 *= vol1;
124  }
125 
126  // Divide by volume, accounting for difference at edges
127  KOKKOS_INLINE_FUNCTION void weight_by_inv_vol(double inv_vol, VGridWeights& vgrid_wts) const{
128  double inv_vol0 = inv_vol*(vgrid_wts.i_vr==0 ? 2.0 : 1.0);
129  double inv_vol1 = inv_vol*(vgrid_wts.i_vr==nmu-1 ? 2.0 : 1.0);
130 
131  vgrid_wts.w_00 *= inv_vol0;
132  vgrid_wts.w_01 *= inv_vol0;
133  vgrid_wts.w_10 *= inv_vol1;
134  vgrid_wts.w_11 *= inv_vol1;
135  }
136 };
137 #endif
int element_order
velocity grid finite element order (0 = nearest neighbor), (1 = linear), (2 = quadratic), (3 = cubic), ....
Definition: velocity_grid.hpp:22
double smu_max
max mu
Definition: velocity_grid.hpp:14
int nmu
n points in mu (not including zero)
Definition: velocity_grid.hpp:13
int nvp
n points in parallel velocity (not including zero)
Definition: velocity_grid.hpp:9
T get(const string &param, const T default_val, int val_ind=0)
Definition: NamelistReader.hpp:373
bool pseudo_inv_on
whether pseudo-inverse interpolation is used in velocity space
Definition: velocity_grid.hpp:24
double w_00
Definition: vgrid_weights.hpp:10
Definition: linear_weights.hpp:8
Definition: velocity_grid.hpp:8
KOKKOS_INLINE_FUNCTION void weight_by_inv_vol(double inv_vol, VGridWeights &vgrid_wts) const
Definition: velocity_grid.hpp:127
Definition: NamelistReader.hpp:193
int nvr
full grid size (including zero)
Definition: velocity_grid.hpp:19
double w_01
Definition: vgrid_weights.hpp:11
KOKKOS_INLINE_FUNCTION double vpar_n(int ivz) const
Definition: velocity_grid.hpp:72
double w_11
Definition: vgrid_weights.hpp:13
KOKKOS_INLINE_FUNCTION double mu_vol_fac(int ivr) const
Definition: velocity_grid.hpp:82
void use_namelist(const string &namelist)
Definition: NamelistReader.hpp:355
#define LAGRANGE_MAX_ORDER
Definition: lagrange_weights.hpp:18
int i
Definition: linear_weights.hpp:9
double vp_max
max parallel velocity
Definition: velocity_grid.hpp:10
int i_vr
Definition: vgrid_weights.hpp:8
KOKKOS_INLINE_FUNCTION void weight_by_vol(double vol, VGridWeights &vgrid_wts) const
Definition: velocity_grid.hpp:116
void exit_XGC(std::string msg)
Definition: globals.hpp:37
VelocityGrid(NLReader::NamelistReader &nlr)
Definition: velocity_grid.hpp:28
Definition: vgrid_weights.hpp:7
double dsmu
grid spacing in mu
Definition: velocity_grid.hpp:15
double inv_mu0_factor
Set value of lowest mu in grid –&gt; 1/mu0_factor.
Definition: velocity_grid.hpp:17
int nvz
full grid size (including negative and zero)
Definition: velocity_grid.hpp:20
KOKKOS_INLINE_FUNCTION VGridWeights get_weights(double smu, double vp) const
Definition: velocity_grid.hpp:87
double dvp
grid spacing in parallel velocity
Definition: velocity_grid.hpp:11
double w_10
Definition: vgrid_weights.hpp:12
KOKKOS_INLINE_FUNCTION void weight_by_inv_dsmu(VGridWeights &vgrid_wts) const
Definition: velocity_grid.hpp:105
KOKKOS_INLINE_FUNCTION double vperp_n(int ivr) const
Definition: velocity_grid.hpp:77
VelocityGrid()=default