XGCa
boundary.hpp
Go to the documentation of this file.
1 #ifndef BOUNDARY_HPP
2 #define BOUNDARY_HPP
3 
4 #include "field.hpp"
5 #include "vertex_list.hpp"
6 #include "grid.hpp"
7 #include "natural_boundary.hpp"
8 
10  double in_bd_psi;
11  double out_bd_psi;
15  bool excl_inner;
16  bool excl_outer;
19  bool excl_wall;
22 
23  void extend(double inner_ext, double outer_ext){
24  in_bd_psi += inner_ext;
25  out_bd_psi -= outer_ext;
26  out_bd_psi_priv1 += outer_ext;
27  out_bd_psi_priv2 += outer_ext;
28  }
29 };
30 
31 static KOKKOS_INLINE_FUNCTION bool exclude_node(const MagneticField<DeviceType>& magnetic_field, const Grid<DeviceType>& grid,
32  const View<int*,CLayout,DeviceType>& num_t_node, const View<int**,CLayout,DeviceType>& tr_node,
33  const BoundarySettings& s, int i){
34  constexpr double epsilon = 1.0e-8;
35  if(s.excl_inner && grid.psi(i) - epsilon < s.in_bd_psi) return true;
36 
37  if(s.excl_outer && grid.psi(i) > s.out_bd_psi) return true;
38 
39  double r,z;
40  grid.get_rz_coordinates(i, r, z);
41 
42  if((s.excl_private
43  || (grid.psi(i) < s.out_bd_psi_priv1 && magnetic_field.is_below_xpt_tangent(r, z))
44  || (grid.psi(i) < s.out_bd_psi_priv2 && magnetic_field.is_above_xpt2_tangent(r, z)))
45  && !grid.node_is_in_region_1_or_2_no_wall(i) ) return true;
46 
47  // Use this condition only if the private region is also excluded
48  if(s.excl_sep_leg && grid.midplane.node_is_on_separatrix_leg(magnetic_field, i)) return true;
49 
50  if(s.excl_near_wall){
51  // check if i-node is connected to wall
52  for (int j=0; j<num_t_node(i); j++){
53  int itr = tr_node(j,i) + 1;
54  for(int ip=0; ip<3; ip++){
55  int i_nd = grid.get_node_index(itr, ip);
56  if(grid.midplane.node_is_on_wall(i_nd)) return true;
57  }
58  }
59 #ifndef XGCA
60  // check if i-node is near wall (bd_ext_near_wall)
61  if(s.bd_ext_near_wall>0.0){
62  for(int j=0; j<grid.nwall; j++){
63  RZPair x2 = grid.get_wall_rz(j);
64  double dist = grid.midplane.get_dist2_from_node(i, x2);
65  if(dist < s.bd_ext_near_wall*s.bd_ext_near_wall){
66  return true;
67  }
68  }
69  }
70 #endif
71  } else if(s.excl_wall && grid.midplane.node_is_on_wall(i)) return true;
72 
73  return false;
74 }
75 
76 inline VertexList get_excluded_vertex_list(const MagneticField<DeviceType>& magnetic_field, const Grid<DeviceType>& grid, const View<int*,CLayout,DeviceType>& num_t_node, const View<int**,CLayout,DeviceType>& tr_node, const BoundarySettings& settings){
77  // Create vertex list that excludes the boundary
78  return VertexList(grid.nnode, KOKKOS_LAMBDA(const int i){
79  return exclude_node(magnetic_field, grid, num_t_node, tr_node, settings, i);
80  });
81 }
82 
83 class Boundary : public VertexList{
84 
85  public:
86 
88  NaturalBoundary natural; // Optional matrix setup for natural boundary settings
89 
91 
92  Boundary(const MagneticField<DeviceType>& magnetic_field, const Grid<DeviceType>& grid, const View<int*,CLayout,DeviceType>& num_t_node, const View<int**,CLayout,DeviceType>& tr_node, const BoundarySettings& settings)
93  : VertexList(get_excluded_vertex_list(magnetic_field, grid, num_t_node, tr_node, settings)),
94  use_natural(settings.use_natural)
95  {
96  if(use_natural) natural = NaturalBoundary(grid, static_cast<VertexList>(*this));
97  }
98 };
99 
100 #endif
static KOKKOS_INLINE_FUNCTION bool exclude_node(const MagneticField< DeviceType > &magnetic_field, const Grid< DeviceType > &grid, const View< int *, CLayout, DeviceType > &num_t_node, const View< int **, CLayout, DeviceType > &tr_node, const BoundarySettings &s, int i)
Definition: boundary.hpp:31
VertexList get_excluded_vertex_list(const MagneticField< DeviceType > &magnetic_field, const Grid< DeviceType > &grid, const View< int *, CLayout, DeviceType > &num_t_node, const View< int **, CLayout, DeviceType > &tr_node, const BoundarySettings &settings)
Definition: boundary.hpp:76
Definition: boundary.hpp:83
bool use_natural
Definition: boundary.hpp:87
Boundary()
Definition: boundary.hpp:90
NaturalBoundary natural
Definition: boundary.hpp:88
Boundary(const MagneticField< DeviceType > &magnetic_field, const Grid< DeviceType > &grid, const View< int *, CLayout, DeviceType > &num_t_node, const View< int **, CLayout, DeviceType > &tr_node, const BoundarySettings &settings)
Definition: boundary.hpp:92
Kokkos::View< double *, Kokkos::LayoutRight, Device > psi
An array of psi coordinates.
Definition: grid.hpp:185
int nwall
Definition: grid.hpp:179
KOKKOS_INLINE_FUNCTION void get_rz_coordinates(const int inode, double &r, double &z) const
Definition: grid.tpp:299
KOKKOS_INLINE_FUNCTION int get_node_index(int triangle_index, int tri_vertex_index) const
Definition: grid.tpp:172
KOKKOS_INLINE_FUNCTION bool node_is_in_region_1_or_2_no_wall(const int inode) const
Definition: grid.tpp:216
KOKKOS_INLINE_FUNCTION RZPair get_wall_rz(int i_wall) const
Definition: grid.tpp:309
int nnode
Number of grid nodes.
Definition: grid.hpp:174
Plane< Device > midplane
Definition: grid.hpp:169
Definition: magnetic_field.hpp:12
Definition: natural_boundary.hpp:8
Definition: vertex_list.hpp:53
Definition: magnetic_field.F90:1
Definition: boundary.hpp:9
bool excl_sep_leg
Definition: boundary.hpp:20
void extend(double inner_ext, double outer_ext)
Definition: boundary.hpp:23
bool use_natural
Definition: boundary.hpp:21
bool excl_inner
Definition: boundary.hpp:15
double out_bd_psi_priv1
Definition: boundary.hpp:12
bool excl_near_wall
Definition: boundary.hpp:18
double bd_ext_near_wall
Definition: boundary.hpp:14
bool excl_private
Definition: boundary.hpp:17
bool excl_wall
Definition: boundary.hpp:19
bool excl_outer
Definition: boundary.hpp:16
double out_bd_psi
Definition: boundary.hpp:11
double in_bd_psi
Definition: boundary.hpp:10
double out_bd_psi_priv2
Definition: boundary.hpp:13
Definition: grid_structs.hpp:28