diff options
Diffstat (limited to 'Source/FieldSolver/WarpXPushFieldsEM.cpp')
-rw-r--r-- | Source/FieldSolver/WarpXPushFieldsEM.cpp | 130 |
1 files changed, 68 insertions, 62 deletions
diff --git a/Source/FieldSolver/WarpXPushFieldsEM.cpp b/Source/FieldSolver/WarpXPushFieldsEM.cpp index 222a6ae6f..672eaec0c 100644 --- a/Source/FieldSolver/WarpXPushFieldsEM.cpp +++ b/Source/FieldSolver/WarpXPushFieldsEM.cpp @@ -11,6 +11,7 @@ #include "BoundaryConditions/WarpX_PML_kernels.H" #include "BoundaryConditions/PML_current.H" #include "WarpX_FDTD.H" +#include "WarpXPushFieldsEM_K.H" #ifdef BL_USE_SENSEI_INSITU # include <AMReX_AmrMeshInSituBridge.H> @@ -161,8 +162,16 @@ WarpX::PushPSATD (int lev, amrex::Real /* dt */) { PushPSATDSinglePatch( lev, *spectral_solver_cp[lev], Efield_cp[lev], Bfield_cp[lev], Efield_avg_cp[lev], Bfield_avg_cp[lev], current_cp[lev], rho_cp[lev] ); } - if (use_damp_fields_in_z_guard) { - DampFieldsInGuards( Efield_fp[lev], Bfield_fp[lev] ); + + // Damp the fields in the guard cells along z + if (use_damp_fields_in_z_guard) + { + DampFieldsInGuards(Efield_fp[lev], Bfield_fp[lev]); + + if (WarpX::fft_do_time_averaging) + { + DampFieldsInGuards(Efield_avg_fp[lev], Bfield_avg_fp[lev]); + } } #endif } @@ -419,7 +428,6 @@ WarpX::DampFieldsInGuards(std::array<std::unique_ptr<amrex::MultiFab>,3>& Efield for ( amrex::MFIter mfi(*Efield[0], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi ) { - amrex::Array4<amrex::Real> const& Ex_arr = Efield[0]->array(mfi); amrex::Array4<amrex::Real> const& Ey_arr = Efield[1]->array(mfi); amrex::Array4<amrex::Real> const& Ez_arr = Efield[2]->array(mfi); @@ -427,74 +435,72 @@ WarpX::DampFieldsInGuards(std::array<std::unique_ptr<amrex::MultiFab>,3>& Efield amrex::Array4<amrex::Real> const& By_arr = Bfield[1]->array(mfi); amrex::Array4<amrex::Real> const& Bz_arr = Bfield[2]->array(mfi); - // Get the tilebox from Efield so that it includes the guard cells. - amrex::Box tilebox = (*Efield[0])[mfi].box(); - int const nz_tile = tilebox.bigEnd(zdir); + // Get the tileboxes from Efield and Bfield so that they include the guard cells + // and take the staggering of each MultiFab into account + amrex::Box tex = amrex::convert((*Efield[0])[mfi].box(), Efield[0]->ixType().toIntVect()); + amrex::Box tey = amrex::convert((*Efield[1])[mfi].box(), Efield[1]->ixType().toIntVect()); + amrex::Box tez = amrex::convert((*Efield[2])[mfi].box(), Efield[2]->ixType().toIntVect()); + amrex::Box tbx = amrex::convert((*Bfield[0])[mfi].box(), Bfield[0]->ixType().toIntVect()); + amrex::Box tby = amrex::convert((*Bfield[1])[mfi].box(), Bfield[1]->ixType().toIntVect()); + amrex::Box tbz = amrex::convert((*Bfield[2])[mfi].box(), Bfield[2]->ixType().toIntVect()); + + // Get smallEnd of tileboxes + const int tex_smallEnd_z = tex.smallEnd(zdir); + const int tey_smallEnd_z = tey.smallEnd(zdir); + const int tez_smallEnd_z = tez.smallEnd(zdir); + const int tbx_smallEnd_z = tbx.smallEnd(zdir); + const int tby_smallEnd_z = tby.smallEnd(zdir); + const int tbz_smallEnd_z = tbz.smallEnd(zdir); + + // Get bigEnd of tileboxes + const int tex_bigEnd_z = tex.bigEnd(zdir); + const int tey_bigEnd_z = tey.bigEnd(zdir); + const int tez_bigEnd_z = tez.bigEnd(zdir); + const int tbx_bigEnd_z = tbx.bigEnd(zdir); + const int tby_bigEnd_z = tby.bigEnd(zdir); + const int tbz_bigEnd_z = tbz.bigEnd(zdir); // Box for the whole simulation domain amrex::Box const& domain = Geom(0).Domain(); int const nz_domain = domain.bigEnd(zdir); - if (tilebox.smallEnd(zdir) < 0) { - - // Apply damping factor in guards cells below the lower end of the domain - int const nz_guard = -tilebox.smallEnd(zdir); + // Set the tileboxes so that they only cover the lower/upper half of the guard cells + constrain_tilebox_to_guards(tex, zdir, nz_domain, tex_smallEnd_z, tex_bigEnd_z); + constrain_tilebox_to_guards(tey, zdir, nz_domain, tey_smallEnd_z, tey_bigEnd_z); + constrain_tilebox_to_guards(tez, zdir, nz_domain, tez_smallEnd_z, tez_bigEnd_z); + constrain_tilebox_to_guards(tbx, zdir, nz_domain, tbx_smallEnd_z, tbx_bigEnd_z); + constrain_tilebox_to_guards(tby, zdir, nz_domain, tby_smallEnd_z, tby_bigEnd_z); + constrain_tilebox_to_guards(tbz, zdir, nz_domain, tbz_smallEnd_z, tbz_bigEnd_z); - // Set so the box only covers the lower half of the guard cells - tilebox.setBig(zdir, -nz_guard/2-1); - - amrex::ParallelFor(tilebox, Efield[0]->nComp(), - [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + amrex::ParallelFor( + tex, Efield[0]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) { -#if (AMREX_SPACEDIM == 3) - amrex::Real zcell = static_cast<amrex::Real>(k + nz_guard); -#else - amrex::Real zcell = static_cast<amrex::Real>(j + nz_guard); -#endif - const amrex::Real phase = MathConst::pi*zcell/nz_guard; - const amrex::Real sin_phase = std::sin(phase); - const amrex::Real damp_factor = sin_phase*sin_phase; - - Ex_arr(i,j,k,icomp) *= damp_factor; - Ey_arr(i,j,k,icomp) *= damp_factor; - Ez_arr(i,j,k,icomp) *= damp_factor; - Bx_arr(i,j,k,icomp) *= damp_factor; - By_arr(i,j,k,icomp) *= damp_factor; - Bz_arr(i,j,k,icomp) *= damp_factor; - - }); - - } - else if (nz_tile > nz_domain) { - - // Apply damping factor in guards cells above the upper end of the domain - int nz_guard = nz_tile - nz_domain; - - // Set so the box only covers the upper half of the guard cells - tilebox.setSmall(zdir, nz_domain + nz_guard/2 + 1); - - amrex::ParallelFor(tilebox, Efield[0]->nComp(), - [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + damp_field_in_guards(Ex_arr, i, j, k, icomp, zdir, nz_domain, tex_smallEnd_z, tex_bigEnd_z); + }, + tey, Efield[1]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) { -#if (AMREX_SPACEDIM == 3) - amrex::Real zcell = static_cast<amrex::Real>(nz_tile - k); -#else - amrex::Real zcell = static_cast<amrex::Real>(nz_tile - j); -#endif - const amrex::Real phase = MathConst::pi*zcell/nz_guard; - const amrex::Real sin_phase = std::sin(phase); - const amrex::Real damp_factor = sin_phase*sin_phase; - - Ex_arr(i,j,k,icomp) *= damp_factor; - Ey_arr(i,j,k,icomp) *= damp_factor; - Ez_arr(i,j,k,icomp) *= damp_factor; - Bx_arr(i,j,k,icomp) *= damp_factor; - By_arr(i,j,k,icomp) *= damp_factor; - Bz_arr(i,j,k,icomp) *= damp_factor; - - }); + damp_field_in_guards(Ey_arr, i, j, k, icomp, zdir, nz_domain, tey_smallEnd_z, tey_bigEnd_z); + }, + tez, Efield[2]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Ez_arr, i, j, k, icomp, zdir, nz_domain, tez_smallEnd_z, tez_bigEnd_z); + } + ); - } + amrex::ParallelFor( + tbx, Bfield[0]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Bx_arr, i, j, k, icomp, zdir, nz_domain, tbx_smallEnd_z, tbx_bigEnd_z); + }, + tby, Bfield[1]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(By_arr, i, j, k, icomp, zdir, nz_domain, tby_smallEnd_z, tby_bigEnd_z); + }, + tbz, Bfield[2]->nComp(), [=] AMREX_GPU_DEVICE (int i, int j, int k, int icomp) + { + damp_field_in_guards(Bz_arr, i, j, k, icomp, zdir, nz_domain, tbz_smallEnd_z, tbz_bigEnd_z); + } + ); } } |