Line data Source code
1 : //
2 : // Functor ParticleBC
3 : // Functors specifying particle boundary conditions.
4 : //
5 : #ifndef IPPL_PARTICLE_BC_H
6 : #define IPPL_PARTICLE_BC_H
7 :
8 : #include "Region/NDRegion.h"
9 :
10 : namespace ippl {
11 : enum BC {
12 : PERIODIC,
13 : REFLECTIVE,
14 : SINK,
15 : NO
16 : };
17 :
18 : namespace detail {
19 :
20 : template <typename T, unsigned Dim, class ViewType>
21 : struct ParticleBC {
22 : using value_type = typename ViewType::value_type::value_type;
23 :
24 : //! Kokkos view containing the field data
25 : ViewType view_m;
26 : //! The dimension along which this boundary condition
27 : // is applied
28 : size_t dim_m;
29 : //! Minimum and maximum coordinates of the domain along the given dimension
30 : double minval_m;
31 : double maxval_m;
32 : //! Whether the boundary conditions are being applied for an upper
33 : // face (i.e. with greater coordinate values)
34 : bool isUpper_m;
35 :
36 : //! The length of the domain along the given dimension
37 : double extent_m;
38 : //! The coordinate of the midpoint of the domain along the given dimension
39 : double middle_m;
40 :
41 : KOKKOS_DEFAULTED_FUNCTION
42 : ParticleBC() = default;
43 :
44 924 : KOKKOS_INLINE_FUNCTION ParticleBC(const ViewType& view, const NDRegion<T, Dim>& nr,
45 : const unsigned& dim, const bool& isUpper)
46 924 : : view_m(view)
47 924 : , dim_m(dim)
48 924 : , minval_m(nr[dim].min())
49 924 : , maxval_m(nr[dim].max())
50 924 : , isUpper_m(isUpper) {
51 924 : extent_m = nr[dim].length();
52 924 : middle_m = (minval_m + maxval_m) / 2;
53 924 : }
54 :
55 : KOKKOS_DEFAULTED_FUNCTION
56 1848 : ~ParticleBC() = default;
57 : };
58 :
59 : template <typename T, unsigned Dim, class ViewType>
60 : struct PeriodicBC : public ParticleBC<T, Dim, ViewType> {
61 : using value_type = typename ParticleBC<T, Dim, ViewType>::value_type;
62 :
63 : using ParticleBC<T, Dim, ViewType>::extent_m;
64 : using ParticleBC<T, Dim, ViewType>::middle_m;
65 :
66 : KOKKOS_DEFAULTED_FUNCTION
67 : PeriodicBC() = default;
68 :
69 252 : KOKKOS_INLINE_FUNCTION PeriodicBC(const ViewType& view, const NDRegion<T, Dim>& nr,
70 : const unsigned& dim, const bool& isUpper)
71 252 : : ParticleBC<T, Dim, ViewType>(view, nr, dim, isUpper) {}
72 :
73 173376 : KOKKOS_INLINE_FUNCTION void operator()(const size_t& i) const {
74 346752 : value_type& value = this->view_m(i)[this->dim_m];
75 173376 : value = value - extent_m * (int)((value - middle_m) * 2 / extent_m);
76 173376 : }
77 :
78 : KOKKOS_DEFAULTED_FUNCTION
79 504 : ~PeriodicBC() = default;
80 : };
81 :
82 : template <typename T, unsigned Dim, class ViewType>
83 : struct ReflectiveBC : public ParticleBC<T, Dim, ViewType> {
84 : using value_type = typename ParticleBC<T, Dim, ViewType>::value_type;
85 :
86 : using ParticleBC<T, Dim, ViewType>::maxval_m;
87 : using ParticleBC<T, Dim, ViewType>::minval_m;
88 : using ParticleBC<T, Dim, ViewType>::isUpper_m;
89 :
90 : KOKKOS_DEFAULTED_FUNCTION
91 : ReflectiveBC() = default;
92 :
93 336 : KOKKOS_INLINE_FUNCTION ReflectiveBC(const ViewType& view, const NDRegion<T, Dim>& nr,
94 : const unsigned& dim, const bool& isUpper)
95 336 : : ParticleBC<T, Dim, ViewType>(view, nr, dim, isUpper) {}
96 :
97 336000 : KOKKOS_INLINE_FUNCTION void operator()(const size_t& i) const {
98 672000 : value_type& value = this->view_m(i)[this->dim_m];
99 336000 : bool tooHigh = value >= maxval_m;
100 336000 : bool tooLow = value < minval_m;
101 672000 : value += 2
102 336000 : * ((tooHigh && isUpper_m) * (maxval_m - value)
103 336000 : + (tooLow && !isUpper_m) * (minval_m - value));
104 336000 : }
105 :
106 : KOKKOS_DEFAULTED_FUNCTION
107 672 : ~ReflectiveBC() = default;
108 : };
109 :
110 : template <typename T, unsigned Dim, class ViewType>
111 : struct SinkBC : public ParticleBC<T, Dim, ViewType> {
112 : using value_type = typename ParticleBC<T, Dim, ViewType>::value_type;
113 :
114 : using ParticleBC<T, Dim, ViewType>::maxval_m;
115 : using ParticleBC<T, Dim, ViewType>::minval_m;
116 : using ParticleBC<T, Dim, ViewType>::isUpper_m;
117 :
118 : KOKKOS_DEFAULTED_FUNCTION
119 : SinkBC() = default;
120 :
121 336 : KOKKOS_INLINE_FUNCTION SinkBC(const ViewType& view, const NDRegion<T, Dim>& nr,
122 : const unsigned& dim, const bool& isUpper)
123 336 : : ParticleBC<T, Dim, ViewType>(view, nr, dim, isUpper) {}
124 :
125 336000 : KOKKOS_INLINE_FUNCTION void operator()(const size_t& i) const {
126 672000 : value_type& value = this->view_m(i)[this->dim_m];
127 336000 : bool tooHigh = value >= maxval_m;
128 336000 : bool tooLow = value < minval_m;
129 336000 : value += (tooHigh && isUpper_m) * (maxval_m - value)
130 336000 : + (tooLow && !isUpper_m) * (minval_m - value);
131 336000 : }
132 :
133 : KOKKOS_DEFAULTED_FUNCTION
134 672 : ~SinkBC() = default;
135 : };
136 :
137 : } // namespace detail
138 : } // namespace ippl
139 :
140 : #endif
|