Line data Source code
1 : // This file contains the abstract base class for
2 : // field boundary conditions and other child classes
3 : // which represent specific BCs. At the moment the
4 : // following field BCs are supported
5 : //
6 : // 1. Periodic BC
7 : // 2. Zero BC
8 : // 3. Specifying a constant BC
9 : // 4. No BC (default option)
10 : // 5. Constant extrapolation BC
11 : // Only cell-centered field BCs are implemented
12 : // at the moment.
13 : //
14 : #ifndef IPPL_FIELD_BC_TYPES_H
15 : #define IPPL_FIELD_BC_TYPES_H
16 :
17 : #include "Types/IpplTypes.h"
18 : #include "Types/ViewTypes.h"
19 :
20 : #include "Communicate/Archive.h"
21 : #include "FieldLayout/FieldLayout.h"
22 : #include "Index/NDIndex.h"
23 : #include "Meshes/UniformCartesian.h"
24 :
25 : namespace ippl {
26 : /*
27 : * Enum type to identify different kinds of
28 : * field boundary conditions. Since ZeroFace is
29 : * a special case of ConstantFace, both will match
30 : * a bitwise AND with CONSTANT_FACE
31 : * (to avoid conflict with particle BC enum, add _FACE)
32 : */
33 : enum FieldBC {
34 : PERIODIC_FACE = 0b0000,
35 : CONSTANT_FACE = 0b0001,
36 : ZERO_FACE = 0b0011,
37 : EXTRAPOLATE_FACE = 0b0100,
38 : NO_FACE = 0b1000,
39 : };
40 :
41 : namespace detail {
42 : template <typename Field>
43 : class BCondBase {
44 : constexpr static unsigned Dim = Field::dim;
45 :
46 : public:
47 : using Layout_t = FieldLayout<Dim>;
48 :
49 : // Constructor takes:
50 : // face: the face to apply the boundary condition on.
51 : // i : what component of T to apply the boundary condition to.
52 : // The components default to setting all components.
53 : BCondBase(unsigned int face);
54 :
55 6112 : virtual ~BCondBase() = default;
56 :
57 0 : virtual FieldBC getBCType() const { return NO_FACE; }
58 :
59 : virtual void findBCNeighbors(Field& field) = 0;
60 : virtual void apply(Field& field) = 0;
61 : virtual void assignGhostToPhysical(Field& field) = 0;
62 : virtual void write(std::ostream&) const = 0;
63 :
64 : // Return face on which BC applies
65 : unsigned int getFace() const { return face_m; }
66 :
67 : // Returns whether or not this BC changes physical cells.
68 : bool changesPhysicalCells() const { return changePhysical_m; }
69 :
70 : protected:
71 : // What face to apply the boundary condition to.
72 : unsigned int face_m;
73 :
74 : // True if this boundary condition changes physical cells.
75 : bool changePhysical_m;
76 : };
77 :
78 : template <typename Field>
79 : std::ostream& operator<<(std::ostream&, const BCondBase<Field>&);
80 :
81 : } // namespace detail
82 :
83 : template <typename Field>
84 : class ExtrapolateFace : public detail::BCondBase<Field> {
85 : constexpr static unsigned Dim = Field::dim;
86 : using T = typename Field::value_type;
87 :
88 : public:
89 : // Constructor takes zero, one, or two int's specifying components of
90 : // multicomponent types like Vector this BC applies to.
91 : // Zero int's specified means apply to all components; one means apply to
92 : // component (i), and two means apply to component (i,j),
93 : using base_type = detail::BCondBase<Field>;
94 : using Layout_t = typename detail::BCondBase<Field>::Layout_t;
95 :
96 384 : ExtrapolateFace(unsigned face, T offset, T slope)
97 : : base_type(face)
98 384 : , offset_m(offset)
99 384 : , slope_m(slope) {}
100 :
101 1392 : virtual ~ExtrapolateFace() = default;
102 :
103 0 : virtual FieldBC getBCType() const { return EXTRAPOLATE_FACE; }
104 :
105 540 : virtual void findBCNeighbors(Field& /*field*/) {}
106 : virtual void apply(Field& field);
107 : virtual void assignGhostToPhysical(Field& field);
108 :
109 : virtual void write(std::ostream& out) const;
110 :
111 : const T& getOffset() const { return offset_m; }
112 : const T& getSlope() const { return slope_m; }
113 :
114 : protected:
115 : T offset_m;
116 : T slope_m;
117 : };
118 :
119 : template <typename Field>
120 : class NoBcFace : public detail::BCondBase<Field> {
121 : public:
122 3524 : NoBcFace(int face)
123 3524 : : detail::BCondBase<Field>(face) {}
124 :
125 84 : virtual void findBCNeighbors(Field& /*field*/) {}
126 348 : virtual void apply(Field& /*field*/) {}
127 0 : virtual void assignGhostToPhysical(Field& /*field*/) {}
128 :
129 : virtual void write(std::ostream& out) const;
130 : };
131 :
132 : template <typename Field>
133 : class ConstantFace : public ExtrapolateFace<Field> {
134 : using T = typename Field::value_type;
135 :
136 : public:
137 300 : ConstantFace(unsigned int face, T constant)
138 300 : : ExtrapolateFace<Field>(face, constant, 0) {}
139 :
140 0 : virtual FieldBC getBCType() const { return CONSTANT_FACE; }
141 :
142 : virtual void write(std::ostream& out) const;
143 : };
144 :
145 : template <typename Field>
146 : class ZeroFace : public ConstantFace<Field> {
147 : public:
148 132 : ZeroFace(unsigned face)
149 132 : : ConstantFace<Field>(face, 0.0) {}
150 :
151 18 : virtual FieldBC getBCType() const { return ZERO_FACE; }
152 :
153 : virtual void write(std::ostream& out) const;
154 : };
155 :
156 : template <typename Field>
157 : class PeriodicFace : public detail::BCondBase<Field> {
158 : constexpr static unsigned Dim = Field::dim;
159 : using T = typename Field::value_type;
160 :
161 : public:
162 : using face_neighbor_type = std::array<std::vector<int>, 2 * Dim>;
163 : using Layout_t = typename detail::BCondBase<Field>::Layout_t;
164 :
165 252 : PeriodicFace(unsigned face)
166 252 : : detail::BCondBase<Field>(face) {}
167 :
168 0 : virtual FieldBC getBCType() const { return PERIODIC_FACE; }
169 :
170 : virtual void findBCNeighbors(Field& field);
171 : virtual void apply(Field& field);
172 : virtual void assignGhostToPhysical(Field& field);
173 :
174 : virtual void write(std::ostream& out) const;
175 :
176 : private:
177 : face_neighbor_type faceNeighbors_m;
178 : typename Field::halo_type::databuffer_type haloData_m;
179 : };
180 : } // namespace ippl
181 :
182 : #include "Field/BcTypes.hpp"
183 :
184 : #endif
|