diff options
-rw-r--r-- | Source/WarpX.cpp | 8 | ||||
-rw-r--r-- | Source/WarpXEvolve.cpp | 32 |
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); |