Line data Source code
1 :
2 : #ifndef AMREX_BNDRYDATA_H_
3 : #define AMREX_BNDRYDATA_H_
4 : #include <AMReX_Config.H>
5 :
6 : #include <AMReX_BndryRegister.H>
7 : #include <AMReX_BoundCond.H>
8 : #include <AMReX_MultiMask.H>
9 :
10 : #include <memory>
11 : #include <map>
12 :
13 : namespace amrex {
14 :
15 : /**
16 : * \brief A BndryData stores and manipulates boundary data information on
17 : * each side of each box in a BoxArray.
18 : *
19 : * A BndryData contains a BndryRegister about each side of each grid in
20 : * a Boxarray. These data are used to store information along the
21 : * outer layer of each grid (at the same level of coarseness), such
22 : * as the value of boundary conditions there. Also, for each
23 : * boundary, this class maintains a BoundCond identifier and a
24 : * location. This "location" often specifies where, in physical
25 : * space, a value, which is stored in the boundary registers, will
26 : * be applied by a solver (although interpretation of this information
27 : * is application-specific).
28 : *
29 : * In addition to boundary condition values, types and locations, and
30 : * BndryDate object maintains a mask for each boundary value. Given
31 : * a Geometry describing the physical "domain" of application, a BndryData
32 : * object fills the mask arrays with a mask value to indicate if the
33 : * node is outside the domain (outside_domain), or, if not, whether it
34 : * lays within the valid region of an adjacent grid (covered), or not
35 : * (not_covered). This mask data is created upon non-default class
36 : * instantiation.
37 : */
38 : template <typename MF>
39 : class BndryDataT
40 : : public BndryRegisterT<MF>
41 : {
42 : public:
43 : //! mask values enumeration
44 : enum MaskVal { covered = 0, not_covered = 1, outside_domain = 2, NumMaskVals = 3 };
45 :
46 : using value_type = typename MF::value_type;
47 :
48 : //! Default constructor
49 : BndryDataT() noexcept = default;
50 :
51 : /**
52 : * \brief constructor specifying number of components and box of physical
53 : * domain (cell-centered)
54 : */
55 : BndryDataT (const BoxArray& grids,
56 : const DistributionMapping& dmap,
57 : int ncomp,
58 : const Geometry& geom);
59 :
60 : //! destructor
61 0 : ~BndryDataT () = default;
62 :
63 : BndryDataT (const BndryDataT<MF>& src) = delete;
64 : BndryDataT (BndryDataT<MF>&& rhs) = delete;
65 : BndryDataT<MF>& operator= (const BndryDataT<MF>& src) = delete;
66 : BndryDataT<MF>& operator= (BndryDataT<MF>&& rhs) = delete;
67 :
68 : //! allocate bndry fabs along given face
69 : void define (const BoxArray& grids,
70 : const DistributionMapping& dmap,
71 : int ncomp,
72 : const Geometry& geom);
73 : //
74 : const MultiMask& bndryMasks (Orientation face) const noexcept { return masks[face]; }
75 :
76 : //! Return FabSet on given face.
77 : const FabSetT<MF>& bndryValues (Orientation face) const noexcept {
78 : return this->bndry[face];
79 : }
80 :
81 : //! Some useful typedefs
82 : using RealTuple = Array<value_type,2*AMREX_SPACEDIM>;
83 :
84 : /**
85 : * \brief Return boundary location on given face for grids we own.
86 : * It's an error if we don't own that grid.
87 : * RealTuple is indexed with Orientation.
88 : */
89 : const RealTuple& bndryLocs (int igrid) const noexcept;
90 : const RealTuple& bndryLocs (const MFIter& mfi) const noexcept;
91 :
92 : /**
93 : * \brief Return boundary type specifier on given face for grids we own.
94 : * It's an error if we don't own that grid.
95 : */
96 : const Vector< Vector<BoundCond> >& bndryConds (int igrid) const noexcept;
97 : const Vector< Vector<BoundCond> >& bndryConds (const MFIter& mfi) const noexcept;
98 :
99 : //! return number of components for which this object is intended
100 : int nComp () const noexcept { return m_ncomp; }
101 :
102 : //! return domain used to define masks
103 : const Box& getDomain () const noexcept { return geom.Domain(); }
104 :
105 : //! return geometry used to define masks
106 : const Geometry& getGeom () const noexcept { return geom; }
107 :
108 : //! set values of boundary Fab for given orientation on nth grid
109 : void setValue (Orientation face, int n, Real val) noexcept;
110 :
111 : //! set boundary type specifier for given orientation on nth grid
112 : void setBoundCond (Orientation face,
113 : int n,
114 : int comp,
115 : const BoundCond& bcn) noexcept;
116 :
117 : void setBoundCond (Orientation face,
118 : const MFIter& mfi,
119 : int comp,
120 : const BoundCond& bcn) noexcept;
121 :
122 : //! set boundary location for given orientation on nth grid
123 : void setBoundLoc (Orientation face,
124 : int n,
125 : value_type val) noexcept;
126 :
127 : void setBoundLoc (Orientation face,
128 : const MFIter& mfi,
129 : value_type val) noexcept;
130 :
131 : //! implement public access to const BndryRegister::operator[]
132 : const FabSetT<MF>& operator[] (Orientation face) const noexcept { return BndryRegisterT<MF>::bndry[face]; }
133 :
134 : //! implement public access to BndryRegister::operator[]
135 : FabSetT<MF>& operator[] (Orientation face) noexcept { return BndryRegisterT<MF>::bndry[face]; }
136 :
137 : protected:
138 : /**
139 : * \brief Map of boundary condition type specifiers.
140 : * The outer Array dimension is over Orientation.
141 : */
142 : LayoutData<Vector< Vector<BoundCond> > > bcond;
143 :
144 : LayoutData<RealTuple> bcloc;
145 : //! Boundary condition mask
146 : Vector<MultiMask> masks;
147 : //! Domain used for mask definitions.
148 : Geometry geom;
149 : int m_ncomp{-1};
150 : bool m_defined{false};
151 :
152 : private:
153 : // Mask info required for this many cells past grid edge (here,
154 : // e.g. ref=4, crse stencil width=3, and let stencil slide 2 past grid
155 : // edge)
156 : static constexpr int NTangHalfWidth = 5; // ref_ratio + 1, so won't work if ref_ratio > 4
157 : };
158 :
159 : template <typename MF>
160 : BndryDataT<MF>::BndryDataT (const BoxArray& _grids,
161 : const DistributionMapping& _dmap,
162 : int _ncomp,
163 : const Geometry& _geom)
164 : :
165 : geom(_geom),
166 : m_ncomp(_ncomp)
167 : {
168 : define(_grids,_dmap,_ncomp,_geom);
169 : }
170 :
171 : template <typename MF>
172 : void
173 : BndryDataT<MF>::setBoundCond (Orientation _face,
174 : int _n,
175 : int _comp,
176 : const BoundCond& _bcn) noexcept
177 : {
178 : bcond[_n][_face][_comp] = _bcn;
179 : }
180 :
181 : template <typename MF>
182 : void
183 : BndryDataT<MF>::setBoundCond (Orientation _face,
184 : const MFIter& mfi,
185 : int _comp,
186 : const BoundCond& _bcn) noexcept
187 : {
188 : bcond[mfi][_face][_comp] = _bcn;
189 : }
190 :
191 : template <typename MF>
192 : void
193 : BndryDataT<MF>::setBoundLoc (Orientation _face,
194 : int _n,
195 : value_type _val) noexcept
196 : {
197 : bcloc[_n][_face] = _val;
198 : }
199 :
200 : template <typename MF>
201 : void
202 : BndryDataT<MF>::setBoundLoc (Orientation _face,
203 : const MFIter& mfi,
204 : value_type _val) noexcept
205 : {
206 : bcloc[mfi][_face] = _val;
207 : }
208 :
209 : template <typename MF>
210 : const Vector< Vector<BoundCond> >&
211 : BndryDataT<MF>::bndryConds (int igrid) const noexcept
212 : {
213 : return bcond[igrid];
214 : }
215 :
216 : template <typename MF>
217 : const Vector< Vector<BoundCond> >&
218 : BndryDataT<MF>::bndryConds (const MFIter& mfi) const noexcept
219 : {
220 : return bcond[mfi];
221 : }
222 :
223 : template <typename MF>
224 : const typename BndryDataT<MF>::RealTuple&
225 : BndryDataT<MF>::bndryLocs (int igrid) const noexcept
226 : {
227 : return bcloc[igrid];
228 : }
229 :
230 : template <typename MF>
231 : const typename BndryDataT<MF>::RealTuple&
232 : BndryDataT<MF>::bndryLocs (const MFIter& mfi) const noexcept
233 : {
234 : return bcloc[mfi];
235 : }
236 :
237 : template <typename MF>
238 : void
239 : BndryDataT<MF>::define (const BoxArray& _grids,
240 : const DistributionMapping& _dmap,
241 : int _ncomp,
242 : const Geometry& _geom)
243 : {
244 : BL_PROFILE("BndryData::define()");
245 :
246 : if (m_defined) {
247 : if (_grids == this->boxes() && m_ncomp == _ncomp && _geom.Domain() == geom.Domain()) {
248 : // We want to allow reuse of BndryDataT objects that were define()d exactly as a previous call.
249 : return;
250 : }
251 : // Otherwise we'll just abort. We could make this work but it's just as easy to start with a fresh Bndrydata object.
252 : amrex::Abort("BndryDataT<MF>::define(): object already built");
253 : }
254 : geom = _geom;
255 : m_ncomp = _ncomp;
256 :
257 : BndryRegisterT<MF>::setBoxes(_grids);
258 :
259 : masks.clear();
260 : masks.resize(2*AMREX_SPACEDIM);
261 :
262 : for (OrientationIter fi; fi; ++fi) {
263 : Orientation face = fi();
264 : BndryRegisterT<MF>::define(face,IndexType::TheCellType(),0,1,1,_ncomp,_dmap);
265 : masks[face].define(_grids, _dmap, geom, face, 0, 2, NTangHalfWidth, 1, true);
266 : }
267 : //
268 : // Define "bcond" and "bcloc".
269 : //
270 : // We note that all orientations of the FabSets have the same distribution.
271 : // We'll use the low 0 side as the model.
272 : //
273 : //
274 :
275 : bcloc.define(_grids, _dmap);
276 : bcond.define(_grids, _dmap);
277 :
278 : for (FabSetIter bfsi(this->bndry[Orientation(0,Orientation::low)]);
279 : bfsi.isValid(); ++bfsi) {
280 : Vector< Vector<BoundCond> >& abc = bcond[bfsi];
281 : abc.resize(2*AMREX_SPACEDIM);
282 : for (OrientationIter fi; fi; ++fi) {
283 : abc[fi()].resize(_ncomp);
284 : }
285 : }
286 :
287 : m_defined = true;
288 : }
289 :
290 : template <typename MF>
291 : void
292 : BndryDataT<MF>::setValue (Orientation face, int n, Real val) noexcept
293 : {
294 : auto& fab = this->bndry[face][n];
295 : auto arr = fab.array();
296 : const Box& bx = fab.box();
297 : const int ncomp = m_ncomp;
298 : AMREX_HOST_DEVICE_PARALLEL_FOR_4D ( bx, ncomp, i, j, k, m,
299 : {
300 : arr(i,j,k,m) = val;
301 : });
302 : }
303 :
304 : using BndryData = BndryDataT<MultiFab>;
305 : using fBndryData = BndryDataT<fMultiFab>;
306 :
307 : }
308 :
309 : #endif /*_BNDRYDATA_H_*/
|