aboutsummaryrefslogtreecommitdiff
path: root/Source/Parallelization/WarpXRegrid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Parallelization/WarpXRegrid.cpp')
-rw-r--r--Source/Parallelization/WarpXRegrid.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/Source/Parallelization/WarpXRegrid.cpp b/Source/Parallelization/WarpXRegrid.cpp
new file mode 100644
index 000000000..8d7873041
--- /dev/null
+++ b/Source/Parallelization/WarpXRegrid.cpp
@@ -0,0 +1,234 @@
+
+#include <WarpX.H>
+#include <AMReX_BLProfiler.H>
+
+using namespace amrex;
+
+void
+WarpX::LoadBalance ()
+{
+ BL_PROFILE_REGION("LoadBalance");
+ BL_PROFILE("WarpX::LoadBalance()");
+
+ AMREX_ALWAYS_ASSERT(costs[0] != nullptr);
+
+ for (int lev = 0; lev <= finestLevel(); ++lev)
+ {
+ const Real nboxes = costs[lev]->size();
+ const Real nprocs = ParallelDescriptor::NProcs();
+ const int nmax = static_cast<int>(std::ceil(nboxes/nprocs*load_balance_knapsack_factor));
+ const DistributionMapping newdm = (load_balance_with_sfc)
+ ? DistributionMapping::makeSFC(*costs[lev], false)
+ : DistributionMapping::makeKnapSack(*costs[lev], nmax);
+ RemakeLevel(lev, t_new[lev], boxArray(lev), newdm);
+ }
+
+ mypc->Redistribute();
+}
+
+void
+WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapping& dm)
+{
+ if (ba == boxArray(lev))
+ {
+ if (ParallelDescriptor::NProcs() == 1) return;
+
+#ifdef WARPX_DO_ELECTROSTATIC
+ AMREX_ALWAYS_ASSERT(masks[lev] == nullptr);
+ AMREX_ALWAYS_ASSERT(gather_masks[lev] == nullptr);
+#endif // WARPX_DO_ELECTROSTATIC
+
+ // Fine patch
+
+ const auto& period = Geom(lev).periodicity();
+ for (int idim=0; idim < 3; ++idim)
+ {
+ {
+ const IntVect& ng = Bfield_fp[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_fp[lev][idim]->boxArray(),
+ dm, 1, ng));
+ pmf->Redistribute(*Bfield_fp[lev][idim], 0, 0, 1, ng);
+ Bfield_fp[lev][idim] = std::move(pmf);
+ }
+ {
+ const IntVect& ng = Efield_fp[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_fp[lev][idim]->boxArray(),
+ dm, 1, ng));
+ pmf->Redistribute(*Efield_fp[lev][idim], 0, 0, 1, ng);
+ Efield_fp[lev][idim] = std::move(pmf);
+ }
+ {
+ const IntVect& ng = current_fp[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(current_fp[lev][idim]->boxArray(),
+ dm, 1, ng));
+ current_fp[lev][idim] = std::move(pmf);
+ current_fp_owner_masks[lev][idim] = std::move(current_fp[lev][idim]->OwnerMask(period));
+ }
+ if (current_store[lev][idim])
+ {
+ const IntVect& ng = current_store[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(current_store[lev][idim]->boxArray(),
+ dm, 1, ng));
+ // no need to redistribute
+ current_store[lev][idim] = std::move(pmf);
+ }
+ }
+
+ if (F_fp[lev] != nullptr) {
+ const IntVect& ng = F_fp[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(F_fp[lev]->boxArray(),
+ dm, 1, ng));
+ pmf->Redistribute(*F_fp[lev], 0, 0, 1, ng);
+ F_fp[lev] = std::move(pmf);
+ }
+
+ if (rho_fp[lev] != nullptr) {
+ const int nc = rho_fp[lev]->nComp();
+ const IntVect& ng = rho_fp[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(rho_fp[lev]->boxArray(),
+ dm, nc, ng));
+ rho_fp[lev] = std::move(pmf);
+ rho_fp_owner_masks[lev] = std::move(rho_fp[lev]->OwnerMask(period));
+ }
+
+ // Aux patch
+
+ if (lev == 0)
+ {
+ for (int idim = 0; idim < 3; ++idim) {
+ Bfield_aux[lev][idim].reset(new MultiFab(*Bfield_fp[lev][idim], amrex::make_alias, 0, 1));
+ Efield_aux[lev][idim].reset(new MultiFab(*Efield_fp[lev][idim], amrex::make_alias, 0, 1));
+ }
+ } else {
+ for (int idim=0; idim < 3; ++idim)
+ {
+ {
+ const IntVect& ng = Bfield_aux[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_aux[lev][idim]->boxArray(),
+ dm, 1, ng));
+ // pmf->Redistribute(*Bfield_aux[lev][idim], 0, 0, 1, ng);
+ Bfield_aux[lev][idim] = std::move(pmf);
+ }
+ {
+ const IntVect& ng = Efield_aux[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_aux[lev][idim]->boxArray(),
+ dm, 1, ng));
+ // pmf->Redistribute(*Efield_aux[lev][idim], 0, 0, 1, ng);
+ Efield_aux[lev][idim] = std::move(pmf);
+ }
+ }
+ }
+
+ // Coarse patch
+ if (lev > 0) {
+ const auto& cperiod = Geom(lev-1).periodicity();
+ for (int idim=0; idim < 3; ++idim)
+ {
+ {
+ const IntVect& ng = Bfield_cp[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_cp[lev][idim]->boxArray(),
+ dm, 1, ng));
+ pmf->Redistribute(*Bfield_cp[lev][idim], 0, 0, 1, ng);
+ Bfield_cp[lev][idim] = std::move(pmf);
+ }
+ {
+ const IntVect& ng = Efield_cp[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_cp[lev][idim]->boxArray(),
+ dm, 1, ng));
+ pmf->Redistribute(*Efield_cp[lev][idim], 0, 0, 1, ng);
+ Efield_cp[lev][idim] = std::move(pmf);
+ }
+ {
+ const IntVect& ng = current_cp[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>( new MultiFab(current_cp[lev][idim]->boxArray(),
+ dm, 1, ng));
+ current_cp[lev][idim] = std::move(pmf);
+ current_cp_owner_masks[lev][idim] = std::move(
+ current_cp[lev][idim]->OwnerMask(cperiod));
+ }
+ }
+
+ if (F_cp[lev] != nullptr) {
+ const IntVect& ng = F_cp[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(F_cp[lev]->boxArray(),
+ dm, 1, ng));
+ pmf->Redistribute(*F_cp[lev], 0, 0, 1, ng);
+ F_cp[lev] = std::move(pmf);
+ }
+
+ if (rho_cp[lev] != nullptr) {
+ const int nc = rho_cp[lev]->nComp();
+ const IntVect& ng = rho_cp[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(rho_cp[lev]->boxArray(),
+ dm, nc, ng));
+ rho_cp[lev] = std::move(pmf);
+ rho_cp_owner_masks[lev] = std::move(rho_cp[lev]->OwnerMask(cperiod));
+ }
+ }
+
+ if (lev > 0 && (n_field_gather_buffer > 0 || n_current_deposition_buffer > 0)) {
+ for (int idim=0; idim < 3; ++idim)
+ {
+ if (Bfield_cax[lev][idim])
+ {
+ const IntVect& ng = Bfield_cax[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_cax[lev][idim]->boxArray(),
+ dm, 1, ng));
+ // pmf->ParallelCopy(*Bfield_cax[lev][idim], 0, 0, 1, ng, ng);
+ Bfield_cax[lev][idim] = std::move(pmf);
+ }
+ if (Efield_cax[lev][idim])
+ {
+ const IntVect& ng = Efield_cax[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_cax[lev][idim]->boxArray(),
+ dm, 1, ng));
+ // pmf->ParallelCopy(*Efield_cax[lev][idim], 0, 0, 1, ng, ng);
+ Efield_cax[lev][idim] = std::move(pmf);
+ }
+ if (current_buf[lev][idim])
+ {
+ const IntVect& ng = current_buf[lev][idim]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(current_buf[lev][idim]->boxArray(),
+ dm, 1, ng));
+ // pmf->ParallelCopy(*current_buf[lev][idim], 0, 0, 1, ng, ng);
+ current_buf[lev][idim] = std::move(pmf);
+ }
+ }
+ if (charge_buf[lev])
+ {
+ const IntVect& ng = charge_buf[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<MultiFab>(new MultiFab(charge_buf[lev]->boxArray(),
+ dm, 1, ng));
+ // pmf->ParallelCopy(*charge_buf[lev][idim], 0, 0, 1, ng, ng);
+ charge_buf[lev] = std::move(pmf);
+ }
+ if (current_buffer_masks[lev])
+ {
+ const IntVect& ng = current_buffer_masks[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<iMultiFab>(new iMultiFab(current_buffer_masks[lev]->boxArray(),
+ dm, 1, ng));
+ // pmf->ParallelCopy(*current_buffer_masks[lev], 0, 0, 1, ng, ng);
+ current_buffer_masks[lev] = std::move(pmf);
+ }
+ if (gather_buffer_masks[lev])
+ {
+ const IntVect& ng = gather_buffer_masks[lev]->nGrowVect();
+ auto pmf = std::unique_ptr<iMultiFab>(new iMultiFab(gather_buffer_masks[lev]->boxArray(),
+ dm, 1, ng));
+ // pmf->ParallelCopy(*gather_buffer_masks[lev], 0, 0, 1, ng, ng);
+ gather_buffer_masks[lev] = std::move(pmf);
+ }
+ }
+
+ if (costs[lev] != nullptr) {
+ costs[lev].reset(new MultiFab(costs[lev]->boxArray(), dm, 1, 0));
+ costs[lev]->setVal(0.0);
+ }
+
+ SetDistributionMap(lev, dm);
+ }
+ else
+ {
+ amrex::Abort("RemakeLevel: to be implemented");
+ }
+}