aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/WarpX.cpp8
-rw-r--r--Source/WarpXEvolve.cpp32
2 files changed, 34 insertions, 6 deletions
diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp
index 1891bc7cb..4da208aac 100644
--- a/Source/WarpX.cpp
+++ b/Source/WarpX.cpp
@@ -522,7 +522,7 @@ WarpX::AllocLevelData (int lev, const BoxArray& ba, const DistributionMapping& d
// E and B have the same number of ghost cells as j and rho if NCI filter is not used,
// but different number of ghost cells in z-direction if NCI filter is used.
// The number of cells should be even, in order to easily perform the
- // interpolation from fine grid to coarse grid.
+ // interpolation from coarse grid to fine grid.
int ngx = (ngx_tmp % 2) ? ngx_tmp+1 : ngx_tmp; // Always even number
int ngy = (ngy_tmp % 2) ? ngy_tmp+1 : ngy_tmp; // Always even number
int ngz_nonci = (ngz_tmp % 2) ? ngz_tmp+1 : ngz_tmp; // Always even number
@@ -534,6 +534,8 @@ WarpX::AllocLevelData (int lev, const BoxArray& ba, const DistributionMapping& d
ngz = ngz_nonci;
}
+ // J is only interpolated from fine to coarse (not coarse to fine)
+ // and therefore does not need to be even.
int ngJx = ngx_tmp;
int ngJy = ngy_tmp;
int ngJz = ngz_tmp;
@@ -687,6 +689,8 @@ WarpX::AllocLevelData (int lev, const BoxArray& ba, const DistributionMapping& d
Efield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,1,ngE));
gather_buffer_masks[lev].reset( new iMultiFab(ba, dm, 1, 1) );
+ // Gather buffer masks have 1 ghost cell, because of the fact
+ // that particles may move by more than one cell when using subcycling.
}
if (n_current_deposition_buffer > 0) {
@@ -697,6 +701,8 @@ WarpX::AllocLevelData (int lev, const BoxArray& ba, const DistributionMapping& d
charge_buf[lev].reset( new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2,ngRho));
}
current_buffer_masks[lev].reset( new iMultiFab(ba, dm, 1, 1) );
+ // Current buffer masks have 1 ghost cell, because of the fact
+ // that particles may move by more than one cell when using subcycling.
}
}
diff --git a/Source/WarpXEvolve.cpp b/Source/WarpXEvolve.cpp
index e3af72cf4..693029297 100644
--- a/Source/WarpXEvolve.cpp
+++ b/Source/WarpXEvolve.cpp
@@ -222,6 +222,10 @@ WarpX::EvolveEM (int numsteps)
}
}
+/* /brief Perform one PIC iteration, without subcycling
+* i.e. all levels/patches use the same timestep (that of the finest level)
+* for the field advance and particle pusher.
+*/
void
WarpX::OneStep_nosub (Real cur_time)
{
@@ -266,6 +270,21 @@ WarpX::OneStep_nosub (Real cur_time)
#endif
}
+/* /brief Perform one PIC iteration, with subcycling
+* i.e. The fine patch uses a smaller timestep (and steps more often)
+* than the coarse patch, for the field advance and particle pusher.
+*
+* This version of subcycling only works for 2 levels and with a refinement
+* ratio of 2.
+* The particles and fields of the fine patch are pushed twice
+* (with dt[coarse]/2) in this routine.
+* The particles of the coarse patch and mother grid are pushed only once
+* (with dt[coarse]). The fields on the coarse patch and mother grid
+* are pushed in a way which is equivalent to pushing once only, with
+* a current which is the average of the coarse + fine current at the 2
+* steps of the fine grid.
+*
+*/
void
WarpX::OneStep_sub1 (Real curtime)
{
@@ -275,7 +294,7 @@ WarpX::OneStep_sub1 (Real curtime)
const int fine_lev = 1;
const int coarse_lev = 0;
- // i)
+ // i) Push particles and fields on the fine patch (first fine step)
PushParticlesandDepose(fine_lev, curtime);
RestrictCurrentFromFineToCoarsePatch(fine_lev);
RestrictRhoFromFineToCoarsePatch(fine_lev);
@@ -302,7 +321,9 @@ WarpX::OneStep_sub1 (Real curtime)
FillBoundaryB(fine_lev, PatchType::fine);
- // ii)
+ // ii) Push particles on the coarse patch and mother grid.
+ // Push the fields on the coarse patch and mother grid
+ // by only half a coarse step (first half)
PushParticlesandDepose(coarse_lev, curtime);
StoreCurrent(coarse_lev);
AddCurrentFromFineLevelandSumBoundary(coarse_lev);
@@ -324,10 +345,10 @@ WarpX::OneStep_sub1 (Real curtime)
EvolveE(coarse_lev, PatchType::fine, 0.5*dt[coarse_lev]);
FillBoundaryE(coarse_lev, PatchType::fine);
- // iii)
+ // iii) Get auxiliary fields on the fine grid, at dt[fine_lev]
UpdateAuxilaryData();
- // iv)
+ // iv) Push particles and fields on the fine patch (second fine step)
PushParticlesandDepose(fine_lev, curtime+dt[fine_lev]);
RestrictCurrentFromFineToCoarsePatch(fine_lev);
RestrictRhoFromFineToCoarsePatch(fine_lev);
@@ -355,7 +376,8 @@ WarpX::OneStep_sub1 (Real curtime)
FillBoundaryB(fine_lev, PatchType::fine);
FillBoundaryF(fine_lev, PatchType::fine);
- // v)
+ // v) Push the fields on the coarse patch and mother grid
+ // by only half a coarse step (second half)
RestoreCurrent(coarse_lev);
AddCurrentFromFineLevelandSumBoundary(coarse_lev);
AddRhoFromFineLevelandSumBoundary(coarse_lev, 1, 1);