372 BL_PROFILE(
"Operator::Elastic::Diagonal()");
377 const amrex::IntVect diagonal_nghost = m_conservative_face_flux
378 ? amrex::IntVect::TheZeroVector() : a_diag.nGrowVect();
379 amrex::Box domain(m_geom[amrlev][mglev].growPeriodicDomain(
380 diagonal_nghost.max()));
381 domain.convert(amrex::IntVect::TheNodeVector());
383 amrex::Box stencilbox(m_geom[amrlev][mglev].growPeriodicDomain(
384 diagonal_nghost.max() + 1));
385 stencilbox.convert(amrex::IntVect::TheNodeVector());
387 const Real* DX = m_geom[amrlev][mglev].CellSize();
389 for (MFIter mfi(a_diag,
false); mfi.isValid(); ++mfi)
391 Box bx = mfi.validbox().grow(diagonal_nghost) & domain;
392 amrex::Box tilebox = mfi.grownnodaltilebox() & bx;
394 amrex::Array4<MATRIX4>
const& DDW = (*(m_ddw_mf[amrlev][mglev])).array(mfi);
395 amrex::Array4<Set::Scalar>
const& diag = a_diag.array(mfi);
396 amrex::Array4<Set::Scalar>
const& psi = m_psi_mf[amrlev][mglev]->array(mfi);
398 if (m_conservative_face_flux)
400 const Dim3 lo = amrex::lbound(stencilbox), hi = amrex::ubound(stencilbox);
401 amrex::LoopConcurrentOnCpu(tilebox, [=] (
int i,
int j,
int k)
405 Numeric::Gradient_Diagonal<Set::Matrix>(DX, sten);
408 psi_avg = (1.0 - m_psi_small) *
410 psi, i, j, k, 0) + m_psi_small;
411 const int index[3] = {i, j, k};
412 const int lower[3] = {lo.x, lo.y, lo.z};
413 const int upper[3] = {hi.x, hi.y, hi.z};
414 bool on_boundary =
false;
415 for (
int dir = 0; dir < AMREX_SPACEDIM; ++dir)
416 on_boundary = on_boundary ||
417 index[dir] == lower[dir] || index[dir] == upper[dir];
419 for (
int p = 0; p < AMREX_SPACEDIM; ++p)
421 diag(i, j, k, p) = 0.0;
425 DDW(i, j, k) * gradu[p] * psi_avg;
429 (*m_bc)(u, gradu[p], sig, i, j, k, stencilbox)(p);
433 for (
int face = 0; face < AMREX_SPACEDIM; ++face)
435 const int im = i - (face == 0);
436 const int jm = j - (face == 1);
437 const int km = k - (face == 2);
439 (DDW(i, j, k, face + 1)(p, face, p, face)
440 + DDW(im, jm, km, face + 1)(
442 / (DX[face] * DX[face]);
450 const Dim3 lo = amrex::lbound(stencilbox), hi = amrex::ubound(stencilbox);
452 amrex::ParallelFor(tilebox, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
456 std::array<Numeric::StencilType, AMREX_SPACEDIM>
460 std::array<Set::Matrix,AMREX_SPACEDIM> gradu = Numeric::Gradient_Diagonal<Set::Matrix>(DX, sten);
463 std::array<Set::Matrix3,AMREX_SPACEDIM> gradgradu = Numeric::Gradient_Diagonal<Set::Matrix3>(DX);
469 AMREX_D_DECL(xmin = (i == lo.x), ymin = (j == lo.y), zmin = (k == lo.z)),
470 AMREX_D_DECL(xmax = (i == hi.x), ymax = (j == hi.y), zmax = (k == hi.z));
477 for (
int p = 0; p < AMREX_SPACEDIM; p++)
480 diag(i, j, k, p) = 0.0;
484 if (AMREX_D_TERM(xmax || xmin, || ymax || ymin, || zmax || zmin))
486 Set::Matrix sig = DDW(i, j, k) * gradu[p] * psi_avg;
489 f = (*m_bc)(u, gradu[p], sig, i, j, k, stencilbox);
490 diag(i, j, k, p) = f(p);
494 Set::Vector f = (DDW(i, j, k) * gradgradu[p]) * psi_avg;
495 diag(i, j, k, p) += f(p);
499 if (std::isnan(diag(i, j, k, p)))
Util::Abort(
INFO,
"diagonal is nan at (", i,
",", j,
",", k,
"), amrlev=", amrlev,
", mglev=", mglev);
500 if (std::isinf(diag(i, j, k, p)))
Util::Abort(
INFO,
"diagonal is inf at (", i,
",", j,
",", k,
"), amrlev=", amrlev,
", mglev=", mglev);
501 if (diag(i, j, k, p) == 0)
Util::Abort(
INFO,
"diagonal is zero at (", i,
",", j,
",", k,
"), amrlev=", amrlev,
", mglev=", mglev);
508 a_diag.FillBoundaryAndSync(Geom(amrlev,mglev).periodicity());
509 nodalSync(amrlev,mglev,a_diag);
560 amrex::MultiFab& a_eps,
561 const amrex::MultiFab& a_u,
564 BL_PROFILE(
"Operator::Elastic::Strain()");
566 const amrex::Real* DX = m_geom[amrlev][0].CellSize();
567 amrex::Box domain(m_geom[amrlev][0].Domain());
568 domain.convert(amrex::IntVect::TheNodeVector());
571 for (MFIter mfi(a_u, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
573 const Box& bx = mfi.tilebox();
574 amrex::Array4<amrex::Real>
const& epsilon = a_eps.array(mfi);
575 amrex::Array4<const amrex::Real>
const& u = a_u.array(mfi);
576 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
580 std::array<Numeric::StencilType, AMREX_SPACEDIM> sten
584 for (
int p = 0; p < AMREX_SPACEDIM; p++)
586 AMREX_D_TERM(gradu(p, 0) = (
Numeric::Stencil<Set::Scalar, 1, 0, 0>::D(u, i, j, k, p, DX, sten));,
587 gradu(p, 1) = (
Numeric::Stencil<Set::Scalar, 0, 1, 0>::D(u, i, j, k, p, DX, sten));,
588 gradu(p, 2) = (
Numeric::Stencil<Set::Scalar, 0, 0, 1>::D(u, i, j, k, p, DX, sten)););
591 Set::Matrix eps = 0.5 * (gradu + gradu.transpose());
595 AMREX_D_PICK(epsilon(i, j, k, 0) = eps(0, 0);
597 epsilon(i, j, k, 0) = eps(0, 0); epsilon(i, j, k, 1) = eps(1, 1); epsilon(i, j, k, 2) = eps(0, 1);
599 epsilon(i, j, k, 0) = eps(0, 0); epsilon(i, j, k, 1) = eps(1, 1); epsilon(i, j, k, 2) = eps(2, 2);
600 epsilon(i, j, k, 3) = eps(1, 2); epsilon(i, j, k, 4) = eps(2, 0); epsilon(i, j, k, 5) = eps(0, 1););
604 AMREX_D_PICK(epsilon(i, j, k, 0) = eps(0, 0);
606 epsilon(i, j, k, 0) = eps(0, 0); epsilon(i, j, k, 1) = eps(0, 1);
607 epsilon(i, j, k, 2) = eps(1, 0); epsilon(i, j, k, 3) = eps(1, 1);
609 epsilon(i, j, k, 0) = eps(0, 0); epsilon(i, j, k, 1) = eps(0, 1); epsilon(i, j, k, 2) = eps(0, 2);
610 epsilon(i, j, k, 3) = eps(1, 0); epsilon(i, j, k, 4) = eps(1, 1); epsilon(i, j, k, 5) = eps(1, 2);
611 epsilon(i, j, k, 6) = eps(2, 0); epsilon(i, j, k, 7) = eps(2, 1); epsilon(i, j, k, 8) = eps(2, 2););
621 amrex::MultiFab& a_sigma,
622 const amrex::MultiFab& a_u,
623 bool voigt,
bool a_homogeneous)
625 BL_PROFILE(
"Operator::Elastic::Stress()");
626 SetHomogeneous(a_homogeneous);
628 const amrex::Real* DX = m_geom[amrlev][0].CellSize();
629 amrex::Box domain(m_geom[amrlev][0].Domain());
630 domain.convert(amrex::IntVect::TheNodeVector());
632 for (MFIter mfi(a_u, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
634 const Box& bx = mfi.tilebox();
635 amrex::Array4<Set::Matrix4<AMREX_SPACEDIM, SYM>>
const& DDW = (*(m_ddw_mf[amrlev][0])).array(mfi);
636 amrex::Array4<amrex::Real>
const& sigma = a_sigma.array(mfi);
637 amrex::Array4<Set::Scalar>
const& psi = m_psi_mf[amrlev][0]->array(mfi);
638 amrex::Array4<const amrex::Real>
const& u = a_u.array(mfi);
639 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
643 std::array<Numeric::StencilType, AMREX_SPACEDIM> sten
647 for (
int p = 0; p < AMREX_SPACEDIM; p++)
649 AMREX_D_TERM(gradu(p, 0) = (
Numeric::Stencil<Set::Scalar, 1, 0, 0>::D(u, i, j, k, p, DX, sten));,
650 gradu(p, 1) = (
Numeric::Stencil<Set::Scalar, 0, 1, 0>::D(u, i, j, k, p, DX, sten));,
651 gradu(p, 2) = (
Numeric::Stencil<Set::Scalar, 0, 0, 1>::D(u, i, j, k, p, DX, sten)););
656 Set::Matrix sig = (DDW(i, j, k) * gradu) * psi_avg;
660 AMREX_D_PICK(sigma(i, j, k, 0) = sig(0, 0);
662 sigma(i, j, k, 0) = sig(0, 0); sigma(i, j, k, 1) = sig(1, 1); sigma(i, j, k, 2) = sig(0, 1);
664 sigma(i, j, k, 0) = sig(0, 0); sigma(i, j, k, 1) = sig(1, 1); sigma(i, j, k, 2) = sig(2, 2);
665 sigma(i, j, k, 3) = sig(1, 2); sigma(i, j, k, 4) = sig(2, 0); sigma(i, j, k, 5) = sig(0, 1););
669 AMREX_D_PICK(sigma(i, j, k, 0) = sig(0, 0);
671 sigma(i, j, k, 0) = sig(0, 0); sigma(i, j, k, 1) = sig(0, 1);
672 sigma(i, j, k, 2) = sig(1, 0); sigma(i, j, k, 3) = sig(1, 1);
674 sigma(i, j, k, 0) = sig(0, 0); sigma(i, j, k, 1) = sig(0, 1); sigma(i, j, k, 2) = sig(0, 2);
675 sigma(i, j, k, 3) = sig(1, 0); sigma(i, j, k, 4) = sig(1, 1); sigma(i, j, k, 5) = sig(1, 2);
676 sigma(i, j, k, 6) = sig(2, 0); sigma(i, j, k, 7) = sig(2, 1); sigma(i, j, k, 8) = sig(2, 2););
763 BL_PROFILE(
"Operator::Elastic::averageDownCoeffsDifferentAmrLevels()");
766 const int crse_amrlev = fine_amrlev - 1;
768 MultiTab& crse_ddw = *m_ddw_mf[crse_amrlev][0];
769 MultiTab& fine_ddw = *m_ddw_mf[fine_amrlev][0];
770 const int ncomp = crse_ddw.nComp();
772 amrex::Box cdomain(m_geom[crse_amrlev][0].Domain());
773 cdomain.convert(amrex::IntVect::TheNodeVector());
775 const Geometry& cgeom = m_geom[crse_amrlev][0];
777 const BoxArray& fba = fine_ddw.boxArray();
778 const DistributionMapping& fdm = fine_ddw.DistributionMap();
780 MultiTab fine_ddw_for_coarse(amrex::coarsen(fba, 2), fdm, ncomp, 2);
781 fine_ddw_for_coarse.ParallelCopy(crse_ddw, 0, 0, ncomp, 0, 0, cgeom.periodicity());
783 const int coarse_fine_node = 1;
784 const int fine_fine_node = 2;
786 amrex::iMultiFab nodemask(amrex::coarsen(fba, 2), fdm, 1, 2);
787 nodemask.ParallelCopy(*m_nd_fine_mask[crse_amrlev], 0, 0, 1, 0, 0, cgeom.periodicity());
789 amrex::iMultiFab cellmask(amrex::convert(amrex::coarsen(fba, 2), amrex::IntVect::TheCellVector()), fdm, 1, 2);
790 cellmask.ParallelCopy(*m_cc_fine_mask[crse_amrlev], 0, 0, 1, 1, 1, cgeom.periodicity());
792 for (MFIter mfi(fine_ddw_for_coarse,
false); mfi.isValid(); ++mfi)
794 const Box& bx = mfi.validbox();
796 amrex::Array4<const int>
const& nmask = nodemask.array(mfi);
799 amrex::Array4<MATRIX4>
const& cdata = fine_ddw_for_coarse.array(mfi);
800 amrex::Array4<const MATRIX4>
const& fdata = fine_ddw.array(mfi);
802 const Dim3 lo = amrex::lbound(cdomain), hi = amrex::ubound(cdomain);
804 for (
int n = 0; n < ncomp; n++)
808 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int I,
int J,
int K) {
809 int i = I * 2, j = J * 2, k = K * 2;
811 if (nmask(I, J, K) == fine_fine_node || nmask(I, J, K) == coarse_fine_node)
815 const int face = n - 1;
816 cdata(I, J, K, n) = 0.5 * (
818 + fdata(i + (face == 0), j + (face == 1),
819 k + (face == 2), n));
822 if ((I == lo.x || I == hi.x) &&
823 (J == lo.y || J == hi.y) &&
824 (K == lo.z || K == hi.z))
825 cdata(I, J, K, n) = fdata(i, j, k, n);
826 else if ((J == lo.y || J == hi.y) &&
827 (K == lo.z || K == hi.z))
828 cdata(I, J, K, n) = fdata(i - 1, j, k, n) * 0.25 + fdata(i, j, k, n) * 0.5 + fdata(i + 1, j, k, n) * 0.25;
829 else if ((K == lo.z || K == hi.z) &&
830 (I == lo.x || I == hi.x))
831 cdata(I, J, K, n) = fdata(i, j - 1, k, n) * 0.25 + fdata(i, j, k, n) * 0.5 + fdata(i, j + 1, k, n) * 0.25;
832 else if ((I == lo.x || I == hi.x) &&
833 (J == lo.y || J == hi.y))
834 cdata(I, J, K, n) = fdata(i, j, k - 1, n) * 0.25 + fdata(i, j, k, n) * 0.5 + fdata(i, j, k + 1, n) * 0.25;
835 else if (I == lo.x || I == hi.x)
837 (fdata(i, j - 1, k - 1, n) + fdata(i, j, k - 1, n) * 2.0 + fdata(i, j + 1, k - 1, n)
838 + fdata(i, j - 1, k, n) * 2.0 + fdata(i, j, k, n) * 4.0 + fdata(i, j + 1, k, n) * 2.0
839 + fdata(i, j - 1, k + 1, n) + fdata(i, j, k + 1, n) * 2.0 + fdata(i, j + 1, k + 1, n)) / 16.0;
840 else if (J == lo.y || J == hi.y)
842 (fdata(i - 1, j, k - 1, n) + fdata(i - 1, j, k, n) * 2.0 + fdata(i - 1, j, k + 1, n)
843 + fdata(i, j, k - 1, n) * 2.0 + fdata(i, j, k, n) * 4.0 + fdata(i, j, k + 1, n) * 2.0
844 + fdata(i + 1, j, k - 1, n) + fdata(i + 1, j, k, n) * 2.0 + fdata(i + 1, j, k + 1, n)) / 16.0;
845 else if (K == lo.z || K == hi.z)
847 (fdata(i - 1, j - 1, k, n) + fdata(i, j - 1, k, n) * 2.0 + fdata(i + 1, j - 1, k, n)
848 + fdata(i - 1, j, k, n) * 2.0 + fdata(i, j, k, n) * 4.0 + fdata(i + 1, j, k, n) * 2.0
849 + fdata(i - 1, j + 1, k, n) + fdata(i, j + 1, k, n) * 2.0 + fdata(i + 1, j + 1, k, n)) / 16.0;
852 (fdata(i - 1, j - 1, k - 1, n) + fdata(i - 1, j - 1, k + 1, n) + fdata(i - 1, j + 1, k - 1, n) + fdata(i - 1, j + 1, k + 1, n) +
853 fdata(i + 1, j - 1, k - 1, n) + fdata(i + 1, j - 1, k + 1, n) + fdata(i + 1, j + 1, k - 1, n) + fdata(i + 1, j + 1, k + 1, n)) / 64.0
855 (fdata(i, j - 1, k - 1, n) + fdata(i, j - 1, k + 1, n) + fdata(i, j + 1, k - 1, n) + fdata(i, j + 1, k + 1, n) +
856 fdata(i - 1, j, k - 1, n) + fdata(i + 1, j, k - 1, n) + fdata(i - 1, j, k + 1, n) + fdata(i + 1, j, k + 1, n) +
857 fdata(i - 1, j - 1, k, n) + fdata(i - 1, j + 1, k, n) + fdata(i + 1, j - 1, k, n) + fdata(i + 1, j + 1, k, n)) / 32.0
859 (fdata(i - 1, j, k, n) + fdata(i, j - 1, k, n) + fdata(i, j, k - 1, n) +
860 fdata(i + 1, j, k, n) + fdata(i, j + 1, k, n) + fdata(i, j, k + 1, n)) / 16.0
862 fdata(i, j, k, n) / 8.0;
865 if (cdata(I, J, K, n).contains_nan())
Util::Abort(
INFO,
"restricted model is nan at (", i,
",", j,
",", k,
"), fine_amrlev=", fine_amrlev);
876 crse_ddw.ParallelCopy(fine_ddw_for_coarse, 0, 0, ncomp, 0, 0, cgeom.periodicity());
880 FillBoundaryCoeff(crse_ddw,Geom(fine_amrlev,0).periodicity());
890 BL_PROFILE(
"Elastic::averageDownCoeffsSameAmrLevel()");
892 for (
int mglev = 1; mglev < m_num_mg_levels[amrlev]; ++mglev)
894 amrex::Box cdomain(m_geom[amrlev][mglev].growPeriodicDomain(2));
895 cdomain.convert(amrex::IntVect::TheNodeVector());
896 amrex::Box fdomain(m_geom[amrlev][mglev - 1].Domain());
897 fdomain.convert(amrex::IntVect::TheNodeVector());
899 MultiTab& crse = *m_ddw_mf[amrlev][mglev];
900 MultiTab& fine = *m_ddw_mf[amrlev][mglev - 1];
901 const int ncomp = crse.nComp();
903 amrex::BoxArray crseba = crse.boxArray();
904 amrex::BoxArray fineba = fine.boxArray();
906 BoxArray newba = crseba;
909 fine_on_crseba.define(newba, crse.DistributionMap(), ncomp, 4);
910 fine_on_crseba.ParallelCopy(fine, 0, 0, ncomp, 2, 4,
911 m_geom[amrlev][mglev-1].periodicity());
914 for (MFIter mfi(crse,
false); mfi.isValid(); ++mfi)
917 Box bx = mfi.grownnodaltilebox() & cdomain;
920 amrex::Array4<const Set::Matrix4<AMREX_SPACEDIM, SYM>>
const& fdata = fine_on_crseba.array(mfi);
921 amrex::Array4<Set::Matrix4<AMREX_SPACEDIM, SYM>>
const& cdata = crse.array(mfi);
923 const Dim3 lo = amrex::lbound(bx), hi = amrex::ubound(bx);
928 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int I,
int J,
int K) {
929 int i = 2 * I, j = 2 * J, k = 2 * K;
931 if ((I == lo.x || I == hi.x) &&
932 (J == lo.y || J == hi.y) &&
933 (K == lo.z || K == hi.z))
934 cdata(I, J, K) = fdata(i, j, k);
935 else if ((J == lo.y || J == hi.y) &&
936 (K == lo.z || K == hi.z))
937 cdata(I, J, K) = fdata(i - 1, j, k) * 0.25 + fdata(i, j, k) * 0.5 + fdata(i + 1, j, k) * 0.25;
938 else if ((K == lo.z || K == hi.z) &&
939 (I == lo.x || I == hi.x))
940 cdata(I, J, K) = fdata(i, j - 1, k) * 0.25 + fdata(i, j, k) * 0.5 + fdata(i, j + 1, k) * 0.25;
941 else if ((I == lo.x || I == hi.x) &&
942 (J == lo.y || J == hi.y))
943 cdata(I, J, K) = fdata(i, j, k - 1) * 0.25 + fdata(i, j, k) * 0.5 + fdata(i, j, k + 1) * 0.25;
944 else if (I == lo.x || I == hi.x)
946 (fdata(i, j - 1, k - 1) + fdata(i, j, k - 1) * 2.0 + fdata(i, j + 1, k - 1)
947 + fdata(i, j - 1, k) * 2.0 + fdata(i, j, k) * 4.0 + fdata(i, j + 1, k) * 2.0
948 + fdata(i, j - 1, k + 1) + fdata(i, j, k + 1) * 2.0 + fdata(i, j + 1, k + 1)) / 16.0;
949 else if (J == lo.y || J == hi.y)
951 (fdata(i - 1, j, k - 1) + fdata(i - 1, j, k) * 2.0 + fdata(i - 1, j, k + 1)
952 + fdata(i, j, k - 1) * 2.0 + fdata(i, j, k) * 4.0 + fdata(i, j, k + 1) * 2.0
953 + fdata(i + 1, j, k - 1) + fdata(i + 1, j, k) * 2.0 + fdata(i + 1, j, k + 1)) / 16.0;
954 else if (K == lo.z || K == hi.z)
956 (fdata(i - 1, j - 1, k) + fdata(i, j - 1, k) * 2.0 + fdata(i + 1, j - 1, k)
957 + fdata(i - 1, j, k) * 2.0 + fdata(i, j, k) * 4.0 + fdata(i + 1, j, k) * 2.0
958 + fdata(i - 1, j + 1, k) + fdata(i, j + 1, k) * 2.0 + fdata(i + 1, j + 1, k)) / 16.0;
961 (fdata(i - 1, j - 1, k - 1) + fdata(i - 1, j - 1, k + 1) + fdata(i - 1, j + 1, k - 1) + fdata(i - 1, j + 1, k + 1) +
962 fdata(i + 1, j - 1, k - 1) + fdata(i + 1, j - 1, k + 1) + fdata(i + 1, j + 1, k - 1) + fdata(i + 1, j + 1, k + 1)) / 64.0
964 (fdata(i, j - 1, k - 1) + fdata(i, j - 1, k + 1) + fdata(i, j + 1, k - 1) + fdata(i, j + 1, k + 1) +
965 fdata(i - 1, j, k - 1) + fdata(i + 1, j, k - 1) + fdata(i - 1, j, k + 1) + fdata(i + 1, j, k + 1) +
966 fdata(i - 1, j - 1, k) + fdata(i - 1, j + 1, k) + fdata(i + 1, j - 1, k) + fdata(i + 1, j + 1, k)) / 32.0
968 (fdata(i - 1, j, k) + fdata(i, j - 1, k) + fdata(i, j, k - 1) +
969 fdata(i + 1, j, k) + fdata(i, j + 1, k) + fdata(i, j, k + 1)) / 16.0
971 fdata(i, j, k) / 8.0;
974 if (cdata(I, J, K).contains_nan())
Util::Abort(
INFO,
"restricted model is nan at crse coordinates (I=", I,
",J=", J,
",K=", k,
"), amrlev=", amrlev,
" interpolating from mglev", mglev - 1,
" to ", mglev);
978 for (
int n = 1; n < ncomp; ++n)
980 const int face = n - 1;
981 amrex::LoopConcurrentOnCpu(bx, [=] (
int I,
int J,
int K)
983 const int i = 2 * I, j = 2 * J, k = 2 * K;
984 cdata(I, J, K, n) = 0.5 * (
986 + fdata(i + (face == 0), j + (face == 1),
987 k + (face == 2), n));
991 FillBoundaryCoeff(crse, Geom(amrlev,mglev).periodicity());
994 if (!m_psi_set)
continue;
996 amrex::Box cdomain_cell(m_geom[amrlev][mglev].Domain());
997 amrex::Box fdomain_cell(m_geom[amrlev][mglev - 1].Domain());
998 MultiFab& crse_psi = *m_psi_mf[amrlev][mglev];
999 MultiFab& fine_psi = *m_psi_mf[amrlev][mglev - 1];
1000 MultiFab fine_psi_on_crseba;
1001 fine_psi_on_crseba.define(newba.convert(amrex::IntVect::TheCellVector()), crse_psi.DistributionMap(), 1, 1);
1002 fine_psi_on_crseba.ParallelCopy(fine_psi, 0, 0, 1, 1, 1, m_geom[amrlev][mglev].periodicity());
1004 for (MFIter mfi(crse_psi, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
1006 Box bx = mfi.tilebox();
1007 bx = bx & cdomain_cell;
1009 amrex::Array4<const Set::Scalar>
const& fdata = fine_psi_on_crseba.array(mfi);
1010 amrex::Array4<Set::Scalar>
const& cdata = crse_psi.array(mfi);
1012 const Dim3 lo = amrex::lbound(cdomain), hi = amrex::ubound(cdomain);
1016 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int I,
int J,
int K) {
1017 int i = 2 * I, j = 2 * J, k = 2 * K;
1019 if ((I == lo.x || I == hi.x) &&
1020 (J == lo.y || J == hi.y) &&
1021 (K == lo.z || K == hi.z))
1022 cdata(I, J, K) = fdata(i, j, k);
1023 else if ((J == lo.y || J == hi.y) &&
1024 (K == lo.z || K == hi.z))
1025 cdata(I, J, K) = fdata(i - 1, j, k) * 0.25 + fdata(i, j, k) * 0.5 + fdata(i + 1, j, k) * 0.25;
1026 else if ((K == lo.z || K == hi.z) &&
1027 (I == lo.x || I == hi.x))
1028 cdata(I, J, K) = fdata(i, j - 1, k) * 0.25 + fdata(i, j, k) * 0.5 + fdata(i, j + 1, k) * 0.25;
1029 else if ((I == lo.x || I == hi.x) &&
1030 (J == lo.y || J == hi.y))
1031 cdata(I, J, K) = fdata(i, j, k - 1) * 0.25 + fdata(i, j, k) * 0.5 + fdata(i, j, k + 1) * 0.25;
1032 else if (I == lo.x || I == hi.x)
1034 (fdata(i, j - 1, k - 1) + fdata(i, j, k - 1) * 2.0 + fdata(i, j + 1, k - 1)
1035 + fdata(i, j - 1, k) * 2.0 + fdata(i, j, k) * 4.0 + fdata(i, j + 1, k) * 2.0
1036 + fdata(i, j - 1, k + 1) + fdata(i, j, k + 1) * 2.0 + fdata(i, j + 1, k + 1)) / 16.0;
1037 else if (J == lo.y || J == hi.y)
1039 (fdata(i - 1, j, k - 1) + fdata(i - 1, j, k) * 2.0 + fdata(i - 1, j, k + 1)
1040 + fdata(i, j, k - 1) * 2.0 + fdata(i, j, k) * 4.0 + fdata(i, j, k + 1) * 2.0
1041 + fdata(i + 1, j, k - 1) + fdata(i + 1, j, k) * 2.0 + fdata(i + 1, j, k + 1)) / 16.0;
1042 else if (K == lo.z || K == hi.z)
1044 (fdata(i - 1, j - 1, k) + fdata(i, j - 1, k) * 2.0 + fdata(i + 1, j - 1, k)
1045 + fdata(i - 1, j, k) * 2.0 + fdata(i, j, k) * 4.0 + fdata(i + 1, j, k) * 2.0
1046 + fdata(i - 1, j + 1, k) + fdata(i, j + 1, k) * 2.0 + fdata(i + 1, j + 1, k)) / 16.0;
1049 (fdata(i - 1, j - 1, k - 1) + fdata(i - 1, j - 1, k + 1) + fdata(i - 1, j + 1, k - 1) + fdata(i - 1, j + 1, k + 1) +
1050 fdata(i + 1, j - 1, k - 1) + fdata(i + 1, j - 1, k + 1) + fdata(i + 1, j + 1, k - 1) + fdata(i + 1, j + 1, k + 1)) / 64.0
1052 (fdata(i, j - 1, k - 1) + fdata(i, j - 1, k + 1) + fdata(i, j + 1, k - 1) + fdata(i, j + 1, k + 1) +
1053 fdata(i - 1, j, k - 1) + fdata(i + 1, j, k - 1) + fdata(i - 1, j, k + 1) + fdata(i + 1, j, k + 1) +
1054 fdata(i - 1, j - 1, k) + fdata(i - 1, j + 1, k) + fdata(i + 1, j - 1, k) + fdata(i + 1, j + 1, k)) / 32.0
1056 (fdata(i - 1, j, k) + fdata(i, j - 1, k) + fdata(i, j, k - 1) +
1057 fdata(i + 1, j, k) + fdata(i, j + 1, k) + fdata(i, j, k + 1)) / 16.0
1059 fdata(i, j, k) / 8.0;
1062 FillBoundaryCoeff(crse_psi, Geom(amrlev,mglev).periodicity());