@@ -645,28 +645,8 @@ AmrMesh::MakeNewGrids (int lbase, Real time, int& new_finest, Vector<BoxArray>&
645645 for (int levc = max_crse; levc >= lbase; levc--)
646646 {
647647 int levf = levc+1 ;
648- //
649- // Construct TagBoxArray with sufficient grow factor to contain
650- // new levels projected down to this level.
651- //
652- IntVect ngt = n_error_buf[levc];
653- BoxArray ba_proj;
654- if (levf < new_finest)
655- {
656- ba_proj = new_grids[levf+1 ].simplified ();
657- ba_proj.coarsen (ref_ratio[levf]);
658- ba_proj.growcoarsen (n_proper, ref_ratio[levc]);
659648
660- BoxArray levcBA = grids[levc].simplified ();
661- int ngrow = 0 ;
662- while (!levcBA.contains (ba_proj))
663- {
664- levcBA.grow (1 );
665- ++ngrow;
666- }
667- ngt.max (IntVect (ngrow));
668- }
669- TagBoxArray tags (grids[levc],dmap[levc],ngt);
649+ TagBoxArray tags (grids[levc],dmap[levc],n_error_buf[levc]);
670650
671651 //
672652 // Only use error estimation to tag cells for the creation of new grids
@@ -713,12 +693,92 @@ AmrMesh::MakeNewGrids (int lbase, Real time, int& new_finest, Vector<BoxArray>&
713693 ManualTagsPlacement (levc, tags, bf_lev);
714694 //
715695 // If new grids have been constructed above this level, project
716- // those grids down and tag cells on intersections to ensure
717- // proper nesting.
696+ // those grids down and tag cells on intersections to ensure proper
697+ // nesting. Note that the projected BoxArray may contain cells
698+ // outside the TagBoxArray's domain. For those, we collect them in
699+ // Vector tag_proj.
718700 //
701+ Vector<IntVect> tags_proj;
719702 if (levf < new_finest) {
720- ba_proj.coarsen (bf_lev[levc]);
703+ BoxArray ba_tags = tags.boxArray ();
704+ BoxList bl_proj = new_grids[levf+1 ].simplified_list ();
705+ auto & bxs = bl_proj.data ();
706+ Long nbxs = bl_proj.size ();
707+ Vector<Vector<IntVect>> tags_proj_priv (OpenMP::get_max_threads ());
708+ Box domain = Geom (levc).Domain ();
709+ domain.coarsen (bf_lev[levc]);
710+ auto const & domain_lo = domain.smallEnd ();
711+ auto const & domain_hi = domain.bigEnd ();
712+ auto const & domain_len = domain.length ();
713+ auto const & is_periodic = Geom (levc).isPeriodicArray ();
714+ #ifdef AMREX_USE_OMP
715+ #pragma omp parallel
716+ #endif
717+ {
718+ auto & tv = tags_proj_priv[OpenMP::get_thread_num ()];
719+ std::vector<std::pair<int ,Box>> isects;
720+ BoxList bl (ba_tags.ixType ());
721+ BoxList bl2 (ba_tags.ixType ());
722+ BoxList bltmp;
723+ #ifdef AMREX_USE_OMP
724+ #pragma omp for
725+ #endif
726+ for (Long ibx = 0 ; ibx < nbxs; ++ibx) {
727+ Box& b = bxs[ibx];
728+ b.coarsen (ref_ratio[levf]);
729+ b.grow (bf_lev[levf]*n_proper);
730+ b.coarsen (ref_ratio[levc]);
731+ b.coarsen (bf_lev[levc]);
732+
733+ ba_tags.intersections (b, isects, false , tags.nGrowVect ());
734+ bl.clear ();
735+ bl.push_back (b);
736+ for (auto const & kv : isects) {
737+ bl2.clear ();
738+ for (auto & btmp : bl) {
739+ amrex::boxDiff (bltmp, btmp, kv.second );
740+ bl2.join (bltmp);
741+ }
742+ std::swap (bl,bl2);
743+ }
744+ for (auto const & bleft : bl) {
745+ amrex::LoopOnCpu (bleft, [&] (IntVect iv)
746+ {
747+ for (int idim = 0 ; idim < AMREX_SPACEDIM; ++idim) {
748+ if (iv[idim] < domain_lo[idim]) {
749+ if (is_periodic[idim]) {
750+ iv[idim] += domain_len[idim];
751+ } else {
752+ return ;
753+ }
754+ } else if (iv[idim] > domain_hi[idim]) {
755+ if (is_periodic[idim]) {
756+ iv[idim] -= domain_len[idim];
757+ } else {
758+ return ;
759+ }
760+ }
761+ }
762+ tv.push_back (iv);
763+ });
764+ }
765+ }
766+ }
767+
768+ BoxArray ba_proj (std::move (bl_proj));
721769 tags.setVal (ba_proj,TagBox::SET);
770+
771+ Long nextra = 0 ;
772+ for (auto const & tv : tags_proj_priv) {
773+ nextra += tv.size ();
774+ }
775+ if (nextra > 0 ) {
776+ tags_proj.reserve (nextra);
777+ for (auto const & tv : tags_proj_priv) {
778+ tags_proj.insert (std::end (tags_proj), std::begin (tv), std::end (tv));
779+ }
780+ amrex::RemoveDuplicates (tags_proj);
781+ }
722782 }
723783 //
724784 // Map tagged points through periodic boundaries, if any.
@@ -739,6 +799,10 @@ AmrMesh::MakeNewGrids (int lbase, Real time, int& new_finest, Vector<BoxArray>&
739799 tags.collate (tagvec);
740800 tags.clear ();
741801
802+ if (!tags_proj.empty ()) {
803+ tagvec.insert (tagvec.end (), tags_proj.data (), tags_proj.data ()+tags_proj.size ());
804+ }
805+
742806 if (!tagvec.empty ())
743807 {
744808 //
0 commit comments