28 const IntVect vdim(IntVect::TheDimensionVector(a_idim));
30 const BoxArray& grids = amrex::convert(a_grids, vdim);
32 m_cellflags =
new FabArray<EBCellFlagFab>(grids, a_dmap, 1, a_ngrow[0], MFInfo(),
33 DefaultFabFactory<EBCellFlagFab>());
37 m_volfrac =
new MultiFab(grids, a_dmap, 1, a_ngrow[1], MFInfo(), FArrayBoxFactory());
41 m_centroid =
new MultiCutFab(a_ba, a_dm, AMREX_SPACEDIM, m_ngrow[1], *
m_cellflags);
42 m_bndrycent =
new MultiCutFab(a_ba, a_dm, AMREX_SPACEDIM, m_grow[2], *
m_cellflags);
44 m_bndryarea =
new MultiCutFab(a_ba, a_dm, 1, m_grow[2], *
m_cellflags);
45 m_bndrynorm =
new MultiCutFab(a_ba, a_dm, AMREX_SPACEDIM, m_grow[2], *
m_cellflags);
47 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
48 const BoxArray& faceba = amrex::convert(a_ba, IntVect::TheDimensionVector(idim));
49 m_areafrac[idim] =
new MultiCutFab(faceba, a_dm, 1, m_grow[2], *
m_cellflags);
50 m_facecent[idim] =
new MultiCutFab(faceba, a_dm, AMREX_SPACEDIM-1, m_grow[2], *
m_cellflags);
54 const auto& FlagFab = a_factory->getMultiEBCellFlagFab();
56 for (MFIter mfi(*
m_cellflags,
false); mfi.isValid(); ++mfi) {
58 const Box& bx = mfi.validbox();
60 if (FlagFab[mfi].getType(bx) == FabType::singlevalued ) {
62 Array4<EBCellFlag const>
const& flag = FlagFab.const_array(mfi);
64 Array4<Real const>
const& vfrac = (a_factory->getVolFrac()).const_array(mfi);
67 Array4<Real const>
const& afrac = (a_factory->getAreaFrac()[a_idim])->const_array(mfi);
70 Array4<Real const>
const& bnorm = a_factory->getBndryNormal()[mfi].const_array();
71 Array4<Real const>
const& bcent = a_factory->getBndryCent()[mfi].const_array();
73 Array4<EBCellFlag>
const& aux_flag =
m_cellflags->array(mfi);
74 Array4<Real>
const& aux_vfrac =
m_volfrac->array(mfi);
80 vfrac, afrac, bnorm, bcent, flag,
81 aux_flag, aux_vfrac, vdim, idim=a_idim ]
82 AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
84 aux_flag(i,j,k).setCovered();
85 aux_flag(i,j,k).setDisconnected();
87 aux_vfrac(i,j,k) = 0.0;
89 IntVect
const iv_hi(i,j,k);
90 IntVect
const iv_lo(iv_hi - vdim);
92 if ( flag(iv_lo).isRegular() && flag(iv_hi).isRegular()) {
94 aux_flag(i,j,k).setRegular();
95 aux_flag(i,j,k).setConnected(vdim);
97 aux_vfrac(i,j,k) = 1.0;
99 }
else if ( flag(iv_lo).isCovered() && flag(iv_hi).isCovered()) {
106 #ifndef AMREX_USE_GPU
107 if (verbose) { Print() <<
"\ncell: " << amrex::IntVect(i,j,k) <<
"\n"; }
109 Array<Real,AMREX_SPACEDIM> lo_arr = {-0.5,-0.5,-0.5};
110 Array<Real,AMREX_SPACEDIM> hi_arr = { 0.5, 0.5, 0.5};
113 RealVect lo_point(bcent(iv_lo,0), bcent(iv_lo,1), bcent(iv_lo,2));
114 RealVect lo_normal(bnorm(iv_lo,0), bnorm(iv_lo,1), bnorm(iv_lo,2));
119 RealBox lo_rbx(lo_arr.data(), hi_arr.data());
121 eb_cut_cell_ lo_eb_cc(flag(iv_lo), lo_rbx, lo_point, lo_normal);
125 AMREX_ASSERT( !flag(iv_lo).isCovered() || lo_eb_cc.isCovered() );
126 AMREX_ASSERT( !flag(iv_lo).isRegular() || lo_eb_cc.isRegular() );
129 RealVect hi_point(bcent(iv_hi,0), bcent(iv_hi,1), bcent(iv_hi,2));
130 RealVect hi_normal(bnorm(iv_hi,0), bnorm(iv_hi,1), bnorm(iv_hi,2));
135 RealBox hi_rbx(lo_arr.data(), hi_arr.data());
137 eb_cut_cell_ hi_eb_cc(flag(iv_hi), hi_rbx, hi_point, hi_normal);
141 AMREX_ASSERT( !flag(iv_hi).isCovered() || hi_eb_cc.isCovered() );
142 AMREX_ASSERT( !flag(iv_hi).isRegular() || hi_eb_cc.isRegular() );
144 #if defined(AMREX_DEBUG) || defined(AMREX_TESTING) || 1
154 eb_cut_cell_ hi_hi_eb_cc(flag(iv_hi), lo_rbx, hi_point, hi_normal);
158 #ifndef AMREX_USE_GPU
159 if ( !(!flag(iv_hi).isRegular() || hi_hi_eb_cc.isRegular()) ||
160 !(!flag(iv_hi).isCovered() || hi_hi_eb_cc.isCovered()) ) {
161 Print() <<
"flag(iv_hi) and hi_hi_eb_cc flags do not agree\n"
162 <<
"\n isRegular() " << flag(iv_hi).isRegular() <<
" " << hi_hi_eb_cc.isRegular()
163 <<
"\n isCovered() " << flag(iv_hi).isCovered() <<
" " << hi_hi_eb_cc.isCovered()
169 AMREX_ALWAYS_ASSERT( !flag(iv_hi).isRegular() || hi_hi_eb_cc.isRegular() );
170 AMREX_ALWAYS_ASSERT( !flag(iv_hi).isCovered() || hi_hi_eb_cc.isCovered() );
177 if ( flag(iv_hi).isSingleValued() ) {
179 Real
const adx = (idim == 0)
180 ? (hi_eb_cc.areaLo(0) - hi_hi_eb_cc.areaHi(0))
181 : (hi_eb_cc.areaLo(0) + hi_hi_eb_cc.areaLo(0))
182 - (hi_eb_cc.areaHi(0) + hi_hi_eb_cc.areaHi(0));
184 Real
const ady = (idim == 1)
185 ? (hi_eb_cc.areaLo(1) - hi_hi_eb_cc.areaHi(1))
186 : (hi_eb_cc.areaLo(1) + hi_hi_eb_cc.areaLo(1))
187 - (hi_eb_cc.areaHi(1) + hi_hi_eb_cc.areaHi(1));
189 Real
const adz = (idim == 2)
190 ? (hi_eb_cc.areaLo(2) - hi_hi_eb_cc.areaHi(2))
191 : (hi_eb_cc.areaLo(2) + hi_hi_eb_cc.areaLo(2))
192 - (hi_eb_cc.areaHi(2) + hi_hi_eb_cc.areaHi(2));
194 Real
const apnorm = std::sqrt(adx*adx + ady*ady + adz*adz);
197 Real
const apnorminv = 1. / apnorm;
198 RealVect
const normal(adx*apnorminv, ady*apnorminv, adz*apnorminv);
199 Real
const dot_normals = normal.dotProduct(hi_normal);
201 #ifndef AMREX_USE_GPU
202 if ( !amrex::almostEqual(dot_normals, 1.0) ) {
203 Print() <<
"\nFail: check-1 dot_normals " << dot_normals
209 }
else if (verbose) {
210 Print() <<
"Pass: dot_normals = 1.0\n";
214 AMREX_ALWAYS_ASSERT( amrex::almostEqual(dot_normals, 1.0) );
219 #ifndef AMREX_USE_GPU
220 Real
const abs_err = std::abs( hi_eb_cc.areaHi(idim) - hi_hi_eb_cc.areaLo(idim) );
221 Real machine_tol = 10.0*std::numeric_limits<amrex::Real>::epsilon();
222 if ( abs_err >= machine_tol ) {
223 Print() <<
"\nFail: check-4 area abs_err: " << abs_err
224 <<
"\n hi_eb_cc.areaHi " << hi_eb_cc.areaHi(idim)
225 <<
"\n hi_hi_eb_cc.areaLo " << hi_hi_eb_cc.areaLo(idim)
227 }
else if (verbose) {
228 Print() <<
"Pass: hi_eb_cc.areaHi = hi_hi_eb_cc.areaLo"
229 <<
" abs_err: " << abs_err <<
"\n";
231 AMREX_ALWAYS_ASSERT( abs_err < machine_tol );
236 { Real
const abs_err = amrex::min(std::abs(lo_eb_cc.areaHi(idim) - afrac(iv_hi)),
237 std::abs(hi_eb_cc.areaLo(idim) - afrac(iv_hi)));
238 Real compare_tol = 5.0e-6;
239 #ifndef AMREX_USE_GPU
240 if ( abs_err >= compare_tol ) {
242 Print() <<
"\nFail: check-2 area abs_err " << abs_err
243 <<
"\n hi_eb_cc.areaLo(" << idim <<
") = " << hi_eb_cc.areaLo(idim)
244 <<
"\n lo_eb_cc.areaHi(" << idim <<
") = " << lo_eb_cc.areaHi(idim)
245 <<
"\n afrac" << iv_hi <<
" = " << afrac(iv_hi)
247 }
else if (verbose) {
248 Print() <<
"Pass: hi_eb_cc.areaLo = afrac = " << afrac(iv_hi)
249 <<
" abs_err: " << abs_err <<
"\n";
252 AMREX_ALWAYS_ASSERT( abs_err < compare_tol );
257 { Real
const vol = hi_eb_cc.volume() + hi_hi_eb_cc.volume();
258 Real
const abs_err = amrex::Math::abs(vfrac(iv_hi) - vol);
259 Real compare_tol = 5.0e-6;
260 #ifndef AMREX_USE_GPU
261 if ( abs_err >= compare_tol ) {
264 amrex::Print() <<
"\nFail: check-4 volume abs_err: " << abs_err
265 <<
"\n point: " << hi_point
266 <<
"\n normal: " << hi_normal
267 <<
"\n hi_eb_cc.volume() " << hi_eb_cc.volume()
268 <<
"\n hi_hi_eb_cc.volume() " << hi_hi_eb_cc.volume()
269 <<
"\n vfrac: " << vfrac(iv_hi)
271 }
else if (verbose) {
272 Print() <<
"Pass: hi_eb_cc + hi_hi_eb_cc = vfrac = " << vfrac(iv_hi)
273 <<
" abs_err: " << abs_err <<
"\n";
276 AMREX_ALWAYS_ASSERT( abs_err < compare_tol );
281 if (lo_eb_cc.isCovered() && hi_eb_cc.isCovered()) {
285 }
else if (lo_eb_cc.isRegular() && hi_eb_cc.isRegular()) {
287 aux_flag(i,j,k).setRegular();
288 aux_flag(i,j,k).setConnected(vdim);
290 aux_vfrac(i,j,k) = 1.0;
294 if (lo_eb_cc.isCovered()) { }
295 if (hi_eb_cc.isCovered()) { }
amrex::FabArray< amrex::EBCellFlagFab > * m_cellflags
Definition: ERF_EBAux.H:33
amrex::MultiFab * m_volfrac
Definition: ERF_EBAux.H:35
Definition: ERF_EBCutCell.H:12