Line data Source code
1 : #ifndef AMREX_MLMGBNDRY_H_
2 : #define AMREX_MLMGBNDRY_H_
3 : #include <AMReX_Config.H>
4 :
5 : #include <AMReX_InterpBndryData.H>
6 :
7 : namespace amrex {
8 :
9 : template <typename MF>
10 : class MLMGBndryT
11 : : public InterpBndryDataT<MF>
12 : {
13 : public:
14 :
15 : using BCTuple = Array<BoundCond,2*BL_SPACEDIM>;
16 : using RealTuple = typename BndryDataT<MF>::RealTuple;
17 :
18 : MLMGBndryT (const BoxArray& _grids, const DistributionMapping& _dmap,
19 : int _ncomp, const Geometry& _geom);
20 :
21 0 : ~MLMGBndryT () = default;
22 :
23 : MLMGBndryT (MLMGBndryT<MF>&& rhs) = delete;
24 : MLMGBndryT (const MLMGBndryT<MF>& rhs) = delete;
25 : MLMGBndryT<MF>& operator= (const MLMGBndryT<MF>& rhs) = delete;
26 : MLMGBndryT<MF>& operator= (MLMGBndryT<MF>&& rhs) = delete;
27 :
28 : void setLOBndryConds (const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& lo,
29 : const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& hi,
30 : int ratio, const RealVect& a_loc,
31 : LinOpBCType a_crse_fine_bc_type = LinOpBCType::Dirichlet);
32 :
33 : void setLOBndryConds (const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& lo,
34 : const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& hi,
35 : IntVect const& ratio, const RealVect& a_loc,
36 : LinOpBCType a_crse_fine_bc_type = LinOpBCType::Dirichlet);
37 :
38 : static void setBoxBC (RealTuple& bloc, BCTuple& bctag, const Box& bx,
39 : const Box& domain,
40 : const Array<LinOpBCType,AMREX_SPACEDIM>& lo,
41 : const Array<LinOpBCType,AMREX_SPACEDIM>& hi,
42 : const Real* dx, IntVect const& ratio,
43 : const RealVect& interior_bloc,
44 : const Array<Real,AMREX_SPACEDIM>& domain_bloc_lo,
45 : const Array<Real,AMREX_SPACEDIM>& domain_bloc_hi,
46 : const GpuArray<int,AMREX_SPACEDIM>& is_periodic,
47 : LinOpBCType a_crse_fine_bc_type);
48 : };
49 :
50 : template <typename MF>
51 : MLMGBndryT<MF>::MLMGBndryT (const BoxArray& _grids, const DistributionMapping& _dmap,
52 : int _ncomp, const Geometry& _geom)
53 : : InterpBndryDataT<MF>(_grids,_dmap,_ncomp,_geom)
54 : {}
55 :
56 : template <typename MF>
57 : void
58 : MLMGBndryT<MF>::setLOBndryConds (const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& lo,
59 : const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& hi,
60 : int ratio, const RealVect& a_loc,
61 : LinOpBCType a_crse_fine_bc_type)
62 : {
63 : setLOBndryConds(lo, hi, IntVect(ratio), a_loc, a_crse_fine_bc_type);
64 : }
65 :
66 : template <typename MF>
67 : void
68 : MLMGBndryT<MF>::setLOBndryConds (const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& lo,
69 : const Vector<Array<LinOpBCType,AMREX_SPACEDIM> >& hi,
70 : IntVect const& ratio, const RealVect& a_loc,
71 : LinOpBCType a_crse_fine_bc_type)
72 : {
73 : const BoxArray& ba = this->boxes();
74 : const Real* dx = this->geom.CellSize();
75 : const Box& domain = this->geom.Domain();
76 : const GpuArray<int,AMREX_SPACEDIM>& is_periodic = this->geom.isPeriodicArray();
77 :
78 : AMREX_ASSERT(a_crse_fine_bc_type == LinOpBCType::Dirichlet ||
79 : a_crse_fine_bc_type == LinOpBCType::Neumann);
80 :
81 : #ifdef AMREX_USE_OMP
82 : #pragma omp parallel
83 : #endif
84 : for (FabSetIter fsi(this->bndry[Orientation(0,Orientation::low)]);
85 : fsi.isValid(); ++fsi)
86 : {
87 : const int i = fsi.index();
88 : const Box& grd = ba[i];
89 : RealTuple& bloc = this->bcloc[fsi];
90 : Vector< Vector<BoundCond> >& bctag = this->bcond[fsi];
91 :
92 : for (int icomp = 0; icomp < this->nComp(); ++icomp) {
93 : BCTuple bct;
94 : setBoxBC(bloc, bct, grd, domain, lo[icomp], hi[icomp], dx, ratio, a_loc,
95 : {{AMREX_D_DECL(Real(0.),Real(0.),Real(0.))}},
96 : {{AMREX_D_DECL(Real(0.),Real(0.),Real(0.))}},
97 : is_periodic, a_crse_fine_bc_type);
98 : for (int idim = 0; idim < 2*AMREX_SPACEDIM; ++idim) {
99 : bctag[idim][icomp] = bct[idim];
100 : }
101 : }
102 : }
103 : }
104 :
105 : template <typename MF>
106 : void
107 : MLMGBndryT<MF>::setBoxBC (RealTuple& bloc, BCTuple& bctag,
108 : const Box& bx, const Box& domain,
109 : const Array<LinOpBCType,AMREX_SPACEDIM>& lo,
110 : const Array<LinOpBCType,AMREX_SPACEDIM>& hi,
111 : const Real* dx, IntVect const& ratio,
112 : const RealVect& interior_bloc,
113 : const Array<Real,AMREX_SPACEDIM>& domain_bloc_lo,
114 : const Array<Real,AMREX_SPACEDIM>& domain_bloc_hi,
115 : const GpuArray<int,AMREX_SPACEDIM>& is_periodic,
116 : LinOpBCType a_crse_fine_bc_type)
117 : {
118 : using T = typename MF::value_type;
119 :
120 : for (OrientationIter fi; fi; ++fi)
121 : {
122 : const Orientation face = fi();
123 : const int dir = face.coordDir();
124 :
125 : if (domain[face] == bx[face] && !is_periodic[dir])
126 : {
127 : // All physical bc values are located on face.
128 : bloc[face] = static_cast<T>
129 : (face.isLow() ? domain_bloc_lo[dir] : domain_bloc_hi[dir]);
130 : const auto linop_bc = face.isLow() ? lo[dir] : hi[dir];
131 : if (linop_bc == LinOpBCType::Dirichlet) {
132 : bctag[face] = AMREX_LO_DIRICHLET;
133 : } else if (linop_bc == LinOpBCType::Neumann) {
134 : bctag[face] = AMREX_LO_NEUMANN;
135 : } else if (linop_bc == LinOpBCType::reflect_odd) {
136 : bctag[face] = AMREX_LO_REFLECT_ODD;
137 : } else {
138 : amrex::Abort("MLMGBndry::setBoxBC: Unknown LinOpBCType");
139 : }
140 : }
141 : else
142 : {
143 : // Internal bndry.
144 : bctag[face] = static_cast<int>(a_crse_fine_bc_type);
145 : bloc[face] = static_cast<T>(ratio[dir] > 0 ? Real(0.5)*static_cast<Real>(ratio[dir])*dx[dir]
146 : : interior_bloc[dir]);
147 : // If this is next to another same level box, BC type is wrong
148 : // and bloc is wrong. But it doesn't matter, because we also
149 : // have mask. It is used only if mask says it is next to coarse
150 : // cells.
151 : }
152 : }
153 : }
154 :
155 : using MLMGBndry = MLMGBndryT<MultiFab>;
156 :
157 : }
158 :
159 : #endif
|