@@ -560,40 +560,56 @@ PML::PML (const int lev, const BoxArray& grid_ba, const DistributionMapping& gri
560
560
m_geom(geom),
561
561
m_cgeom(cgeom)
562
562
{
563
- // When `do_pml_in_domain` is true, the PML overlap with the last `ncell` of the physical domain
564
- // (instead of extending `ncell` outside of the physical domain)
565
- // In order to implement this, a reduced domain is created here (decreased by ncells in all direction)
566
- // and passed to `MakeBoxArray`, which surrounds it by PML boxes
567
- // (thus creating the PML boxes at the right position, where they overlap with the original domain)
568
- // minimalBox provides the bounding box around grid_ba for level, lev.
569
- // Note that this is okay to build pml inside domain for a single patch, or joint patches
570
- // with same [min,max]. But it does not support multiple disjoint refinement patches.
571
- Box domain0 = grid_ba.minimalBox ();
563
+ // When `do_pml_in_domain` is true, the PML overlap with the last `ncell` of the physical domain or fine patch(es)
564
+ // (instead of extending `ncell` outside of the physical domain or fine patch(es))
565
+ // In order to implement this, we define a new reduced Box Array ensuring that it does not
566
+ // include ncells from the edges of the physical domain or fine patch.
567
+ // (thus creating the PML boxes at the right position, where they overlap with the original domain or fine patch(es))
568
+
569
+ BoxArray grid_ba_reduced = grid_ba;
572
570
if (do_pml_in_domain) {
573
- for (int idim = 0 ; idim < AMREX_SPACEDIM; ++idim) {
574
- if (do_pml_Lo[idim]){
575
- domain0.growLo (idim, -ncell);
576
- }
577
- if (do_pml_Hi[idim]){
578
- domain0.growHi (idim, -ncell);
571
+ BoxList bl = grid_ba.boxList ();
572
+ // Here we loop over all the boxes in the original grid_ba BoxArray
573
+ // For each box, we find if its in the edge (or boundary), and the size of those boxes are decreased by ncell
574
+ for (auto & b : bl) {
575
+ for (int idim = 0 ; idim < AMREX_SPACEDIM; ++idim) {
576
+ if (do_pml_Lo[idim]) {
577
+ // Get neighboring box on lower side in direction idim and check if it intersects with any of the boxes
578
+ // in grid_ba. If no intersection, then the box, b, in the boxlist, is in the edge and we decrase
579
+ // the size by ncells using growLo(idim,-ncell)
580
+ Box const & bb = amrex::adjCellLo (b, idim);
581
+ if ( ! grid_ba.intersects (bb) ) {
582
+ WARPX_ALWAYS_ASSERT_WITH_MESSAGE (b.length (idim) > ncell, " box length must be greater that pml size" );
583
+ b.growLo (idim, -ncell);
584
+ }
585
+ }
586
+ if (do_pml_Hi[idim]) {
587
+ // Get neighboring box on higher side in direction idim and check if it intersects with any of the boxes
588
+ // in grid_ba. If no intersection, then the box, b, in the boxlist, is in the edge and we decrase
589
+ // the size by ncells using growHi(idim,-ncell)
590
+ Box const & bb = amrex::adjCellHi (b, idim);
591
+ if ( ! grid_ba.intersects (bb) ) {
592
+ WARPX_ALWAYS_ASSERT_WITH_MESSAGE (b.length (idim) > ncell, " box length must be greater that pml size" );
593
+ b.growHi (idim, -ncell);
594
+ }
595
+ }
579
596
}
580
597
}
598
+ grid_ba_reduced = BoxArray (std::move (bl));
581
599
}
582
- const BoxArray grid_ba_reduced = (do_pml_in_domain) ?
583
- BoxArray (grid_ba.boxList ().intersect (domain0)) : grid_ba;
584
-
600
+ Box const domain0 = grid_ba_reduced.minimalBox ();
585
601
const bool is_single_box_domain = domain0.numPts () == grid_ba_reduced.numPts ();
586
602
const BoxArray& ba = MakeBoxArray (is_single_box_domain, domain0, *geom, grid_ba_reduced,
587
603
IntVect (ncell), do_pml_in_domain, do_pml_Lo, do_pml_Hi);
588
604
605
+
589
606
if (ba.empty ()) {
590
607
m_ok = false ;
591
608
return ;
592
609
} else {
593
610
m_ok = true ;
594
611
}
595
-
596
- // Define the number of guard cells in each direction, for E, B, and F
612
+ // Define the number of guard cells in each di;rection, for E, B, and F
597
613
auto nge = IntVect (AMREX_D_DECL (2 , 2 , 2 ));
598
614
auto ngb = IntVect (AMREX_D_DECL (2 , 2 , 2 ));
599
615
int ngf_int = 0 ;
@@ -760,24 +776,28 @@ PML::PML (const int lev, const BoxArray& grid_ba, const DistributionMapping& gri
760
776
BoxArray grid_cba = grid_ba;
761
777
grid_cba.coarsen (ref_ratio);
762
778
763
- // assuming that the bounding box around grid_cba is a single patch, and not disjoint patches, similar to fine patch.
764
- amrex::Box cdomain = grid_cba.minimalBox ();
779
+ BoxArray grid_cba_reduced = grid_cba;
765
780
if (do_pml_in_domain) {
766
- for (int idim = 0 ; idim < AMREX_SPACEDIM; ++idim) {
767
- if (do_pml_Lo[idim]){
768
- // ncell is divided by refinement ratio to ensure that the
769
- // physical width of the PML region is equal in fine and coarse patch
770
- cdomain.growLo (idim, -ncell/ref_ratio[idim]);
771
- }
772
- if (do_pml_Hi[idim]){
773
- // ncell is divided by refinement ratio to ensure that the
774
- // physical width of the PML region is equal in fine and coarse patch
775
- cdomain.growHi (idim, -ncell/ref_ratio[idim]);
781
+ BoxList bl = grid_cba.boxList ();
782
+ for (auto & b : bl) {
783
+ for (int idim = 0 ; idim < AMREX_SPACEDIM; ++idim) {
784
+ if (do_pml_Lo[idim]) {
785
+ Box const & bb = amrex::adjCellLo (b, idim);
786
+ if ( ! grid_cba.intersects (bb) ) {
787
+ b.growLo (idim, -ncell/ref_ratio[idim]);
788
+ }
789
+ }
790
+ if (do_pml_Hi[idim]) {
791
+ Box const & bb = amrex::adjCellHi (b, idim);
792
+ if ( ! grid_cba.intersects (bb) ) {
793
+ b.growHi (idim, -ncell/ref_ratio[idim]);
794
+ }
795
+ }
776
796
}
777
797
}
798
+ grid_cba_reduced = BoxArray (std::move (bl));
778
799
}
779
- const BoxArray grid_cba_reduced = (do_pml_in_domain) ?
780
- BoxArray (grid_cba.boxList ().intersect (cdomain)) : grid_cba;
800
+ Box const cdomain = grid_cba_reduced.minimalBox ();
781
801
782
802
const IntVect cncells = IntVect (ncell)/ref_ratio;
783
803
const IntVect cdelta = IntVect (delta)/ref_ratio;
@@ -792,7 +812,6 @@ PML::PML (const int lev, const BoxArray& grid_ba, const DistributionMapping& gri
792
812
} else {
793
813
cdm.define (cba);
794
814
}
795
-
796
815
const amrex::BoxArray cba_Ex = amrex::convert (cba, WarpX::GetInstance ().getEfield_cp (1 ,0 ).ixType ().toIntVect ());
797
816
const amrex::BoxArray cba_Ey = amrex::convert (cba, WarpX::GetInstance ().getEfield_cp (1 ,1 ).ixType ().toIntVect ());
798
817
const amrex::BoxArray cba_Ez = amrex::convert (cba, WarpX::GetInstance ().getEfield_cp (1 ,2 ).ixType ().toIntVect ());
0 commit comments