diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Diagnostics/ParticleIO.cpp | 2 | ||||
-rw-r--r-- | Source/Evolve/WarpXEvolveEM.cpp | 9 | ||||
-rw-r--r-- | Source/FieldSolver/WarpXPushFieldsEM.cpp | 92 | ||||
-rw-r--r-- | Source/FortranInterface/WarpX_f.H | 32 | ||||
-rw-r--r-- | Source/FortranInterface/WarpX_picsar.F90 | 139 | ||||
-rw-r--r-- | Source/Initialization/InjectorDensity.cpp | 2 | ||||
-rw-r--r-- | Source/Initialization/PlasmaInjector.cpp | 24 | ||||
-rw-r--r-- | Source/Make.WarpX | 3 | ||||
-rw-r--r-- | Source/Parser/GpuParser.cpp | 4 | ||||
-rw-r--r-- | Source/Particles/Deposition/CurrentDeposition.H | 83 | ||||
-rw-r--r-- | Source/Particles/Gather/FieldGather.H | 27 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.cpp | 129 | ||||
-rw-r--r-- | Source/Particles/Pusher/GetAndSetPosition.H | 6 | ||||
-rw-r--r-- | Source/Particles/Pusher/UpdatePosition.H | 2 | ||||
-rw-r--r-- | Source/Particles/RigidInjectedParticleContainer.cpp | 28 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.H | 2 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.cpp | 63 | ||||
-rw-r--r-- | Source/Utils/WarpXAlgorithmSelection.cpp | 2 | ||||
-rw-r--r-- | Source/WarpX.H | 7 | ||||
-rw-r--r-- | Source/WarpX.cpp | 18 |
20 files changed, 283 insertions, 391 deletions
diff --git a/Source/Diagnostics/ParticleIO.cpp b/Source/Diagnostics/ParticleIO.cpp index f2a543ed5..f159e5302 100644 --- a/Source/Diagnostics/ParticleIO.cpp +++ b/Source/Diagnostics/ParticleIO.cpp @@ -98,7 +98,7 @@ MultiParticleContainer::WritePlotFile (const std::string& dir) const real_names.push_back("By"); real_names.push_back("Bz"); -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ real_names.push_back("theta"); #endif diff --git a/Source/Evolve/WarpXEvolveEM.cpp b/Source/Evolve/WarpXEvolveEM.cpp index b32f0068a..a097d8814 100644 --- a/Source/Evolve/WarpXEvolveEM.cpp +++ b/Source/Evolve/WarpXEvolveEM.cpp @@ -482,6 +482,13 @@ WarpX::PushParticlesandDepose (int lev, Real cur_time) Efield_cax[lev][0].get(), Efield_cax[lev][1].get(), Efield_cax[lev][2].get(), Bfield_cax[lev][0].get(), Bfield_cax[lev][1].get(), Bfield_cax[lev][2].get(), cur_time, dt[lev]); +#ifdef WARPX_DIM_RZ + // This is called after all particles have deposited their current. + ApplyInverseVolumeScalingToCurrentDensity(current_fp[lev][0].get(), current_fp[lev][1].get(), current_fp[lev][2].get(), lev); + if (current_buf[lev][0].get()) { + ApplyInverseVolumeScalingToCurrentDensity(current_buf[lev][0].get(), current_buf[lev][1].get(), current_buf[lev][2].get(), lev-1); + } +#endif } void @@ -492,7 +499,7 @@ WarpX::ComputeDt () if (maxwell_fdtd_solver_id == 0) { // CFL time step Yee solver -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ // Derived semi-analytically by R. Lehe deltat = cfl * 1./( std::sqrt((1+0.2105)/(dx[0]*dx[0]) + 1./(dx[1]*dx[1])) * PhysConst::c ); #else diff --git a/Source/FieldSolver/WarpXPushFieldsEM.cpp b/Source/FieldSolver/WarpXPushFieldsEM.cpp index 098e8f189..21000424d 100644 --- a/Source/FieldSolver/WarpXPushFieldsEM.cpp +++ b/Source/FieldSolver/WarpXPushFieldsEM.cpp @@ -580,3 +580,95 @@ WarpX::EvolveF (int lev, PatchType patch_type, Real a_dt, DtType a_dt_type) } } } + +#ifdef WARPX_DIM_RZ +// This scales the current by the inverse volume and wraps around the depostion at negative radius. +// It is faster to apply this on the grid than to do it particle by particle. +// It is put here since there isn't another nice place for it. +void +WarpX::ApplyInverseVolumeScalingToCurrentDensity (MultiFab* Jx, MultiFab* Jy, MultiFab* Jz, int lev) +{ + const long ngJ = Jx->nGrow(); + const std::array<Real,3>& dx = WarpX::CellSize(lev); + const Real dr = dx[0]; + + Box tilebox; + + for ( MFIter mfi(*Jx, TilingIfNotGPU()); mfi.isValid(); ++mfi ) + { + + Array4<Real> const& Jr_arr = Jx->array(mfi); + Array4<Real> const& Jt_arr = Jy->array(mfi); + Array4<Real> const& Jz_arr = Jz->array(mfi); + + tilebox = mfi.tilebox(); + Box tbr = convert(tilebox, WarpX::jx_nodal_flag); + Box tbt = convert(tilebox, WarpX::jy_nodal_flag); + Box tbz = convert(tilebox, WarpX::jz_nodal_flag); + + // Lower corner of tile box physical domain + // Note that this is done before the tilebox.grow so that + // these do not include the guard cells. + const std::array<Real, 3>& xyzmin = WarpX::LowerCorner(tilebox, lev); + const Dim3 lo = lbound(tilebox); + const Real rmin = xyzmin[0]; + const int irmin = lo.x; + + // Rescale current in r-z mode since the inverse volume factor was not + // included in the current deposition. + amrex::ParallelFor(tbr, + [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + // Wrap the current density deposited in the guard cells around + // to the cells above the axis. + // Note that Jr(i==0) is at 1/2 dr. + if (rmin == 0. && 0 <= i && i < ngJ) { + Jr_arr(i,j,0) -= Jr_arr(-1-i,j,0); + } + // Apply the inverse volume scaling + // Since Jr is not cell centered in r, no need for distinction + // between on axis and off-axis factors + const amrex::Real r = std::abs(rmin + (i - irmin + 0.5)*dr); + Jr_arr(i,j,0) /= (2.*MathConst::pi*r); + }); + amrex::ParallelFor(tbt, + [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + // Wrap the current density deposited in the guard cells around + // to the cells above the axis. + // Jt is located on the boundary + if (rmin == 0. && 0 < i && i <= ngJ) { + Jt_arr(i,j,0) += Jt_arr(-i,j,0); + } + + // Apply the inverse volume scaling + // Jt is forced to zero on axis. + const amrex::Real r = std::abs(rmin + (i - irmin)*dr); + if (r == 0.) { + Jt_arr(i,j,0) = 0.; + } else { + Jt_arr(i,j,0) /= (2.*MathConst::pi*r); + } + }); + amrex::ParallelFor(tbz, + [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + // Wrap the current density deposited in the guard cells around + // to the cells above the axis. + // Jz is located on the boundary + if (rmin == 0. && 0 < i && i <= ngJ) { + Jz_arr(i,j,0) += Jz_arr(-i,j,0); + } + + // Apply the inverse volume scaling + const amrex::Real r = std::abs(rmin + (i - irmin)*dr); + if (r == 0.) { + // Verboncoeur JCP 164, 421-427 (2001) : corrected volume on axis + Jz_arr(i,j,0) /= (MathConst::pi*dr/3.); + } else { + Jz_arr(i,j,0) /= (2.*MathConst::pi*r); + } + }); + } +} +#endif diff --git a/Source/FortranInterface/WarpX_f.H b/Source/FortranInterface/WarpX_f.H index 0440148eb..07cfcb42e 100644 --- a/Source/FortranInterface/WarpX_f.H +++ b/Source/FortranInterface/WarpX_f.H @@ -62,7 +62,7 @@ #define WRPX_PUSH_LEAPFROG warpx_push_leapfrog_2d #define WRPX_PUSH_LEAPFROG_POSITIONS warpx_push_leapfrog_positions_2d -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ #define WRPX_COMPUTE_DIVE warpx_compute_dive_rz #else #define WRPX_COMPUTE_DIVE warpx_compute_dive_2d @@ -106,34 +106,6 @@ extern "C" const long* nox, const long* noy,const long* noz, const int* l_nodal, const long* lvect, const long* current_depo_algo); - // Current deposition finalize for RZ - void warpx_current_deposition_rz_volume_scaling( - amrex::Real* jx, const long* jx_ng, const int* jx_ntot, - amrex::Real* jy, const long* jy_ng, const int* jy_ntot, - amrex::Real* jz, const long* jz_ng, const int* jz_ntot, - const amrex::Real* rmin, - const amrex::Real* dr); - - // Field gathering - - void warpx_geteb_energy_conserving(const long* np, - const amrex::Real* xp, const amrex::Real* yp, const amrex::Real* zp, - amrex::Real* exp, amrex::Real* eyp, amrex::Real* ezp, - amrex::Real* bxp, amrex::Real* byp, amrex::Real* bzp, - const int* ixyzmin, - const amrex::Real* xmin, const amrex::Real* ymin, const amrex::Real* zmin, - const amrex::Real* dx, const amrex::Real* dy, const amrex::Real* dz, - const long* nox, const long* noy, const long* noz, - const amrex::Real* exg, const int* exg_lo, const int* exg_hi, - const amrex::Real* eyg, const int* eyg_lo, const int* eyg_hi, - const amrex::Real* ezg, const int* ezg_lo, const int* ezg_hi, - const amrex::Real* bxg, const int* bxg_lo, const int* bxg_hi, - const amrex::Real* byg, const int* byg_lo, const int* byg_hi, - const amrex::Real* bzg, const int* bzg_lo, const int* bzg_hi, - const int* ll4symtry, const int* l_lower_order_in_v, - const int* l_nodal, const long* lvect, - const long* field_gathe_algo); - // Particle pusher (velocity and position) void warpx_particle_pusher(const long* np, @@ -342,7 +314,7 @@ extern "C" const BL_FORT_FAB_ARG_ANYD(ey), const BL_FORT_FAB_ARG_ANYD(ez), const amrex::Real* dx -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ ,const amrex::Real* rmin #endif ); diff --git a/Source/FortranInterface/WarpX_picsar.F90 b/Source/FortranInterface/WarpX_picsar.F90 index 3b2fc97a7..0625d40f9 100644 --- a/Source/FortranInterface/WarpX_picsar.F90 +++ b/Source/FortranInterface/WarpX_picsar.F90 @@ -1,20 +1,16 @@ #if (AMREX_SPACEDIM == 3) -#define WRPX_PXR_GETEB_ENERGY_CONSERVING geteb3d_energy_conserving_generic #define WRPX_PXR_CURRENT_DEPOSITION depose_jxjyjz_generic #elif (AMREX_SPACEDIM == 2) -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ -#define WRPX_PXR_GETEB_ENERGY_CONSERVING geteb2drz_energy_conserving_generic #define WRPX_PXR_CURRENT_DEPOSITION depose_jrjtjz_generic_rz #define WRPX_PXR_RZ_VOLUME_SCALING_RHO apply_rz_volume_scaling_rho -#define WRPX_PXR_RZ_VOLUME_SCALING_J apply_rz_volume_scaling_j #else -#define WRPX_PXR_GETEB_ENERGY_CONSERVING geteb2dxz_energy_conserving_generic #define WRPX_PXR_CURRENT_DEPOSITION depose_jxjyjz_generic_2d #endif @@ -53,84 +49,6 @@ module warpx_to_pxr_module contains - ! _________________________________________________________________ - !> - !> @brief - !> Main subroutine for the field gathering process - !> - !> @param[in] np number of particles - !> @param[in] xp,yp,zp particle position arrays - !> @param[in] ex,ey,ez particle electric fields in each direction - !> @param[in] bx,by,bz particle magnetic fields in each direction - !> @param[in] ixyzmin tile grid minimum index - !> @param[in] xmin,ymin,zmin tile grid minimum position - !> @param[in] dx,dy,dz space discretization steps - !> @param[in] xyzmin grid minimum position - !> @param[in] dxyz space discretization steps - !> @param[in] nox,noy,noz interpolation order - !> @param[in] exg,eyg,ezg electric field grid arrays - !> @param[in] bxg,byg,bzg electric field grid arrays - !> @param[in] lvect vector length - !> - subroutine warpx_geteb_energy_conserving(np,xp,yp,zp, & - ex,ey,ez,bx,by,bz,ixyzmin,xmin,ymin,zmin,dx,dy,dz,nox,noy,noz, & - exg,exg_lo,exg_hi,eyg,eyg_lo,eyg_hi,ezg,ezg_lo,ezg_hi, & - bxg,bxg_lo,bxg_hi,byg,byg_lo,byg_hi,bzg,bzg_lo,bzg_hi, & - ll4symtry,l_lower_order_in_v, l_nodal,& - lvect,field_gathe_algo) & - bind(C, name="warpx_geteb_energy_conserving") - - integer, intent(in) :: exg_lo(AMREX_SPACEDIM), eyg_lo(AMREX_SPACEDIM), ezg_lo(AMREX_SPACEDIM), & - bxg_lo(AMREX_SPACEDIM), byg_lo(AMREX_SPACEDIM), bzg_lo(AMREX_SPACEDIM) - integer, intent(in) :: exg_hi(AMREX_SPACEDIM), eyg_hi(AMREX_SPACEDIM), ezg_hi(AMREX_SPACEDIM), & - bxg_hi(AMREX_SPACEDIM), byg_hi(AMREX_SPACEDIM), bzg_hi(AMREX_SPACEDIM) - integer, intent(in) :: ixyzmin(AMREX_SPACEDIM) - real(amrex_real), intent(in) :: xmin,ymin,zmin,dx,dy,dz - integer(c_long), intent(in) :: field_gathe_algo - integer(c_long), intent(in) :: np,nox,noy,noz - integer(c_int), intent(in) :: ll4symtry,l_lower_order_in_v, l_nodal - integer(c_long),intent(in) :: lvect - real(amrex_real), intent(in), dimension(np) :: xp,yp,zp - real(amrex_real), intent(out), dimension(np) :: ex,ey,ez,bx,by,bz - real(amrex_real),intent(in):: exg(*), eyg(*), ezg(*), bxg(*), byg(*), bzg(*) - logical(pxr_logical) :: pxr_ll4symtry, pxr_l_lower_order_in_v, pxr_l_nodal - - ! Compute the number of valid cells and guard cells - integer(c_long) :: exg_nvalid(AMREX_SPACEDIM), eyg_nvalid(AMREX_SPACEDIM), ezg_nvalid(AMREX_SPACEDIM), & - bxg_nvalid(AMREX_SPACEDIM), byg_nvalid(AMREX_SPACEDIM), bzg_nvalid(AMREX_SPACEDIM), & - exg_nguards(AMREX_SPACEDIM), eyg_nguards(AMREX_SPACEDIM), ezg_nguards(AMREX_SPACEDIM), & - bxg_nguards(AMREX_SPACEDIM), byg_nguards(AMREX_SPACEDIM), bzg_nguards(AMREX_SPACEDIM) - - pxr_ll4symtry = ll4symtry .eq. 1 - pxr_l_lower_order_in_v = l_lower_order_in_v .eq. 1 - pxr_l_nodal = l_nodal .eq. 1 - - exg_nguards = ixyzmin - exg_lo - eyg_nguards = ixyzmin - eyg_lo - ezg_nguards = ixyzmin - ezg_lo - bxg_nguards = ixyzmin - bxg_lo - byg_nguards = ixyzmin - byg_lo - bzg_nguards = ixyzmin - bzg_lo - exg_nvalid = exg_lo + exg_hi - 2_c_long*ixyzmin + 1_c_long - eyg_nvalid = eyg_lo + eyg_hi - 2_c_long*ixyzmin + 1_c_long - ezg_nvalid = ezg_lo + ezg_hi - 2_c_long*ixyzmin + 1_c_long - bxg_nvalid = bxg_lo + bxg_hi - 2_c_long*ixyzmin + 1_c_long - byg_nvalid = byg_lo + byg_hi - 2_c_long*ixyzmin + 1_c_long - bzg_nvalid = bzg_lo + bzg_hi - 2_c_long*ixyzmin + 1_c_long - - CALL WRPX_PXR_GETEB_ENERGY_CONSERVING(np,xp,yp,zp, & - ex,ey,ez,bx,by,bz,xmin,ymin,zmin,dx,dy,dz,nox,noy,noz, & - exg,exg_nguards,exg_nvalid,& - eyg,eyg_nguards,eyg_nvalid,& - ezg,ezg_nguards,ezg_nvalid,& - bxg,bxg_nguards,bxg_nvalid,& - byg,byg_nguards,byg_nvalid,& - bzg,bzg_nguards,bzg_nvalid,& - pxr_ll4symtry, pxr_l_lower_order_in_v, pxr_l_nodal, & - lvect, field_gathe_algo ) - - end subroutine warpx_geteb_energy_conserving - ! _________________________________________________________________ !> !> @brief @@ -220,7 +138,7 @@ subroutine warpx_charge_deposition(rho,np,xp,yp,zp,w,q,xmin,ymin,zmin,dx,dy,dz,n ! Dimension 2 #elif (AMREX_SPACEDIM==2) -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ logical(pxr_logical) :: l_2drz = .TRUE._c_long #else logical(pxr_logical) :: l_2drz = .FALSE._c_long @@ -257,7 +175,7 @@ subroutine warpx_charge_deposition(rho,np,xp,yp,zp,w,q,xmin,ymin,zmin,dx,dy,dz,n real(amrex_real), intent(IN OUT):: rho(*) real(amrex_real), intent(IN) :: rmin, dr -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ integer(c_long) :: type_rz_depose = 1 #endif @@ -266,7 +184,7 @@ subroutine warpx_charge_deposition(rho,np,xp,yp,zp,w,q,xmin,ymin,zmin,dx,dy,dz,n rho_nvalid = rho_ntot - 2*rho_ng rho_nguards = rho_ng -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ CALL WRPX_PXR_RZ_VOLUME_SCALING_RHO( & rho,rho_nguards,rho_nvalid, & rmin,dr,type_rz_depose) @@ -355,53 +273,4 @@ subroutine warpx_charge_deposition(rho,np,xp,yp,zp,w,q,xmin,ymin,zmin,dx,dy,dz,n end subroutine warpx_current_deposition - ! _________________________________________________________________ - !> - !> @brief - !> Applies the inverse volume scaling for RZ current deposition - !> - !> @details - !> The scaling is done for single mode only - ! - !> @param[inout] jx,jy,jz current arrays - !> @param[in] jx_ntot,jy_ntot,jz_ntot vectors with total number of - !> cells (including guard cells) along each axis for each current - !> @param[in] jx_ng,jy_ng,jz_ng vectors with number of guard cells along each - !> axis for each current - !> @param[in] rmin tile grid minimum radius - !> @param[in] dr radial space discretization steps - !> - subroutine warpx_current_deposition_rz_volume_scaling( & - jx,jx_ng,jx_ntot,jy,jy_ng,jy_ntot,jz,jz_ng,jz_ntot, & - rmin,dr) & - bind(C, name="warpx_current_deposition_rz_volume_scaling") - - integer, intent(in) :: jx_ntot(AMREX_SPACEDIM), jy_ntot(AMREX_SPACEDIM), jz_ntot(AMREX_SPACEDIM) - integer(c_long), intent(in) :: jx_ng, jy_ng, jz_ng - real(amrex_real), intent(IN OUT):: jx(*), jy(*), jz(*) - real(amrex_real), intent(IN) :: rmin, dr - -#ifdef WARPX_RZ - integer(c_long) :: type_rz_depose = 1 -#endif - ! Compute the number of valid cells and guard cells - integer(c_long) :: jx_nvalid(AMREX_SPACEDIM), jy_nvalid(AMREX_SPACEDIM), jz_nvalid(AMREX_SPACEDIM), & - jx_nguards(AMREX_SPACEDIM), jy_nguards(AMREX_SPACEDIM), jz_nguards(AMREX_SPACEDIM) - jx_nvalid = jx_ntot - 2*jx_ng - jy_nvalid = jy_ntot - 2*jy_ng - jz_nvalid = jz_ntot - 2*jz_ng - jx_nguards = jx_ng - jy_nguards = jy_ng - jz_nguards = jz_ng - -#ifdef WARPX_RZ - CALL WRPX_PXR_RZ_VOLUME_SCALING_J( & - jx,jx_nguards,jx_nvalid, & - jy,jy_nguards,jy_nvalid, & - jz,jz_nguards,jz_nvalid, & - rmin,dr,type_rz_depose) -#endif - - end subroutine warpx_current_deposition_rz_volume_scaling - end module warpx_to_pxr_module diff --git a/Source/Initialization/InjectorDensity.cpp b/Source/Initialization/InjectorDensity.cpp index 7fed85b75..54df4b14d 100644 --- a/Source/Initialization/InjectorDensity.cpp +++ b/Source/Initialization/InjectorDensity.cpp @@ -64,7 +64,7 @@ InjectorDensityPredefined::InjectorDensityPredefined ( which_profile_s.begin(), ::tolower); if (which_profile_s == "parabolic_channel"){ profile = Profile::parabolic_channel; - AMREX_ALWAYS_ASSERT_WITH_MESSAGE(v.size() > 6, + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(v.size() > 5, "InjectorDensityPredefined::parabolic_channel: not enough parameters"); } } diff --git a/Source/Initialization/PlasmaInjector.cpp b/Source/Initialization/PlasmaInjector.cpp index 280f9e58a..541999789 100644 --- a/Source/Initialization/PlasmaInjector.cpp +++ b/Source/Initialization/PlasmaInjector.cpp @@ -213,7 +213,11 @@ void PlasmaInjector::parseDensity (ParmParse& pp) // Construct InjectorDensity with InjectorDensityPredefined. inj_rho.reset(new InjectorDensity((InjectorDensityPredefined*)nullptr,species_name)); } else if (rho_prof_s == "parse_density_function") { - pp.get("density_function(x,y,z)", str_density_function); + std::vector<std::string> f; + pp.getarr("density_function(x,y,z)", f); + for (auto const& s : f) { + str_density_function += s; + } // Construct InjectorDensity with InjectorDensityParser. inj_rho.reset(new InjectorDensity((InjectorDensityParser*)nullptr, makeParser(str_density_function))); @@ -269,9 +273,21 @@ void PlasmaInjector::parseMomentum (ParmParse& pp) inj_mom.reset(new InjectorMomentum ((InjectorMomentumRadialExpansion*)nullptr, u_over_r)); } else if (mom_dist_s == "parse_momentum_function") { - pp.get("momentum_function_ux(x,y,z)", str_momentum_function_ux); - pp.get("momentum_function_uy(x,y,z)", str_momentum_function_uy); - pp.get("momentum_function_uz(x,y,z)", str_momentum_function_uz); + std::vector<std::string> f; + pp.getarr("momentum_function_ux(x,y,z)", f); + for (auto const& s : f) { + str_momentum_function_ux += s; + } + f.clear(); + pp.getarr("momentum_function_uy(x,y,z)", f); + for (auto const& s : f) { + str_momentum_function_uy += s; + } + f.clear(); + pp.getarr("momentum_function_uz(x,y,z)", f); + for (auto const& s : f) { + str_momentum_function_uz += s; + } // Construct InjectorMomentum with InjectorMomentumParser. inj_mom.reset(new InjectorMomentum((InjectorMomentumParser*)nullptr, makeParser(str_momentum_function_ux), diff --git a/Source/Make.WarpX b/Source/Make.WarpX index b9971491f..e3a33a00f 100644 --- a/Source/Make.WarpX +++ b/Source/Make.WarpX @@ -101,7 +101,7 @@ ifeq ($(USE_OPENPMD), TRUE) ifeq (0, $(shell pkg-config "openPMD >= 0.9.0"; echo $$?)) CXXFLAGS += $(shell pkg-config --cflags openPMD) LDFLAGS += $(shell pkg-config --libs openPMD) - LDFLAGS += -Wl,-rpath,$(shell pkg-config --variable=libdir openPMD) + LDFLAGS += -Xlinker -rpath -Xlinker $(shell pkg-config --variable=libdir openPMD) # fallback to manual settings else OPENPMD_LIB_PATH ?= NOT_SET @@ -141,7 +141,6 @@ endif ifeq ($(USE_RZ),TRUE) USERSuffix := $(USERSuffix).RZ - DEFINES += -DWARPX_RZ endif ifeq ($(DO_ELECTROSTATIC),TRUE) diff --git a/Source/Parser/GpuParser.cpp b/Source/Parser/GpuParser.cpp index 97b96d465..db1c2287d 100644 --- a/Source/Parser/GpuParser.cpp +++ b/Source/Parser/GpuParser.cpp @@ -7,7 +7,7 @@ GpuParser::GpuParser (WarpXParser const& wp) struct wp_parser* a_wp = wp.m_parser; // Initialize GPU parser: allocate memory in CUDA managed memory, // copy all data needed on GPU to m_gpu_parser - m_gpu_parser.sz_mempool = wp_ast_size((struct wp_node*)a_wp); + m_gpu_parser.sz_mempool = wp_ast_size(a_wp->ast); m_gpu_parser.p_root = (struct wp_node*) amrex::The_Managed_Arena()->alloc(m_gpu_parser.sz_mempool); m_gpu_parser.p_free = m_gpu_parser.p_root; @@ -19,7 +19,7 @@ GpuParser::GpuParser (WarpXParser const& wp) // Initialize CPU parser: allocate memory in CUDA managed memory, // copy all data needed on CPU to m_cpu_parser - m_cpu_parser.sz_mempool = wp_ast_size((struct wp_node*)a_wp); + m_cpu_parser.sz_mempool = wp_ast_size(a_wp->ast); m_cpu_parser.p_root = (struct wp_node*) amrex::The_Managed_Arena()->alloc(m_cpu_parser.sz_mempool); m_cpu_parser.p_free = m_cpu_parser.p_root; diff --git a/Source/Particles/Deposition/CurrentDeposition.H b/Source/Particles/Deposition/CurrentDeposition.H index 9b9853902..4a392b57e 100644 --- a/Source/Particles/Deposition/CurrentDeposition.H +++ b/Source/Particles/Deposition/CurrentDeposition.H @@ -42,7 +42,7 @@ void doDepositionShapeN(const amrex::Real * const xp, const amrex::Real dts2dz = 0.5*dt*dzi; #if (AMREX_SPACEDIM == 2) const amrex::Real invvol = dxi*dzi; -#else // (AMREX_SPACEDIM == 3) +#elif (defined WARPX_DIM_3D) const amrex::Real dyi = 1.0/dx[1]; const amrex::Real dts2dy = 0.5*dt*dyi; const amrex::Real invvol = dxi*dyi*dzi; @@ -66,14 +66,37 @@ void doDepositionShapeN(const amrex::Real * const xp, const amrex::Real vy = uyp[ip]*gaminv; const amrex::Real vz = uzp[ip]*gaminv; // wqx, wqy wqz are particle current in each direction +#if (defined WARPX_DIM_RZ) + // In RZ, wqx is actually wqr, and wqy is wqtheta + // Convert to cylinderical at the mid point + const amrex::Real xpmid = xp[ip] - 0.5*dt*vx; + const amrex::Real ypmid = yp[ip] - 0.5*dt*vy; + const amrex::Real rpmid = std::sqrt(xpmid*xpmid + ypmid*ypmid); + amrex::Real costheta; + amrex::Real sintheta; + if (rpmid > 0.) { + costheta = xpmid/rpmid; + sintheta = ypmid/rpmid; + } else { + costheta = 1.; + sintheta = 0.; + } + const amrex::Real wqx = wq*invvol*(+vx*costheta + vy*sintheta); + const amrex::Real wqy = wq*invvol*(-vx*sintheta + vy*costheta); +#else const amrex::Real wqx = wq*invvol*vx; const amrex::Real wqy = wq*invvol*vy; +#endif const amrex::Real wqz = wq*invvol*vz; // --- Compute shape factors // x direction // Get particle position after 1/2 push back in position +#if (defined WARPX_DIM_RZ) + const amrex::Real xmid = (rpmid-xmin)*dxi; +#else const amrex::Real xmid = (xp[ip]-xmin)*dxi-dts2dx*vx; +#endif // Compute shape factors for node-centered quantities amrex::Real AMREX_RESTRICT sx [depos_order + 1]; // j: leftmost grid point (node-centered) that the particle touches @@ -83,7 +106,7 @@ void doDepositionShapeN(const amrex::Real * const xp, // j0: leftmost grid point (cell-centered) that the particle touches const int j0 = compute_shape_factor<depos_order>(sx0, xmid-stagger_shift); -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) // y direction const amrex::Real ymid= (yp[ip]-ymin)*dyi-dts2dy*vy; amrex::Real AMREX_RESTRICT sy [depos_order + 1]; @@ -99,7 +122,7 @@ void doDepositionShapeN(const amrex::Real * const xp, const int l0 = compute_shape_factor<depos_order>(sz0, zmid-stagger_shift); // Deposit current into jx_arr, jy_arr and jz_arr -#if (AMREX_SPACEDIM == 2) +#if (defined WARPX_DIM_2D) || (defined WARPX_DIM_RZ) for (int iz=0; iz<=depos_order; iz++){ for (int ix=0; ix<=depos_order; ix++){ amrex::Gpu::Atomic::Add( @@ -113,7 +136,7 @@ void doDepositionShapeN(const amrex::Real * const xp, sx [ix]*sz0[iz]*wqz); } } -#else // (AMREX_SPACEDIM == 3) +#elif (defined WARPX_DIM_3D) for (int iz=0; iz<=depos_order; iz++){ for (int iy=0; iy<=depos_order; iy++){ for (int ix=0; ix<=depos_order; ix++){ @@ -169,7 +192,7 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, const amrex::Real dxi = 1.0/dx[0]; const amrex::Real dtsdx0 = dt*dxi; const amrex::Real xmin = xyzmin[0]; -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) const amrex::Real dyi = 1.0/dx[1]; const amrex::Real dtsdy0 = dt*dyi; const amrex::Real ymin = xyzmin[1]; @@ -178,11 +201,11 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, const amrex::Real dtsdz0 = dt*dzi; const amrex::Real zmin = xyzmin[2]; -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) const amrex::Real invdtdx = 1.0/(dt*dx[1]*dx[2]); const amrex::Real invdtdy = 1.0/(dt*dx[0]*dx[2]); const amrex::Real invdtdz = 1.0/(dt*dx[0]*dx[1]); -#elif (AMREX_SPACEDIM == 2) +#elif (defined WARPX_DIM_2D) || (defined WARPX_DIM_RZ) const amrex::Real invdtdx = 1.0/(dt*dx[2]); const amrex::Real invdtdz = 1.0/(dt*dx[0]); const amrex::Real invvol = 1.0/(dx[0]*dx[2]); @@ -197,34 +220,57 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, // --- Get particle quantities const amrex::Real gaminv = 1.0/std::sqrt(1.0 + uxp[ip]*uxp[ip]*clightsq - + uyp[ip]*uyp[ip]*clightsq - + uzp[ip]*uzp[ip]*clightsq); + + uyp[ip]*uyp[ip]*clightsq + + uzp[ip]*uzp[ip]*clightsq); // wqx, wqy wqz are particle current in each direction const amrex::Real wq = q*wp[ip]; const amrex::Real wqx = wq*invdtdx; -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) const amrex::Real wqy = wq*invdtdy; #endif const amrex::Real wqz = wq*invdtdz; // computes current and old position in grid units +#if (defined WARPX_DIM_RZ) + const amrex::Real r_new = std::sqrt(xp[ip]*xp[ip] + yp[ip]*yp[ip]); + const amrex::Real r_old = std::sqrt((xp[ip] - dt*uxp[ip]*gaminv)*(xp[ip] - dt*uxp[ip]*gaminv) + + (yp[ip] - dt*uyp[ip]*gaminv)*(yp[ip] - dt*uyp[ip]*gaminv)); + const amrex::Real x_new = (r_new - xmin)*dxi; + const amrex::Real x_old = (r_old - xmin)*dxi; +#else const amrex::Real x_new = (xp[ip] - xmin)*dxi; const amrex::Real x_old = x_new - dtsdx0*uxp[ip]*gaminv; -#if (AMREX_SPACEDIM == 3) +#endif +#if (defined WARPX_DIM_3D) const amrex::Real y_new = (yp[ip] - ymin)*dyi; const amrex::Real y_old = y_new - dtsdy0*uyp[ip]*gaminv; #endif const amrex::Real z_new = (zp[ip] - zmin)*dzi; const amrex::Real z_old = z_new - dtsdz0*uzp[ip]*gaminv; +#if (defined WARPX_DIM_RZ) + amrex::Real costheta; + amrex::Real sintheta; + if (r_new > 0.) { + costheta = xp[ip]/r_new; + sintheta = yp[ip]/r_new; + } else { + costheta = 1.; + sintheta = 0.; + } + const amrex::Real vy = (-uxp[ip]*sintheta + uyp[ip]*costheta)*gaminv; +#elif (defined WARPX_DIM_2D) + const amrex::Real vy = uyp[ip]*gaminv; +#endif + // Shape factor arrays // Note that there are extra values above and below // to possibly hold the factor for the old particle // which can be at a different grid location. amrex::Real AMREX_RESTRICT sx_new[depos_order + 3] = {0.}; amrex::Real AMREX_RESTRICT sx_old[depos_order + 3] = {0.}; -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) amrex::Real AMREX_RESTRICT sy_new[depos_order + 3] = {0.}; amrex::Real AMREX_RESTRICT sy_old[depos_order + 3] = {0.}; #endif @@ -236,7 +282,7 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, // [ijk]_new: leftmost grid point that the particle touches const int i_new = compute_shape_factor<depos_order>(sx_new+1, x_new); const int i_old = compute_shifted_shape_factor<depos_order>(sx_old, x_old, i_new); -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) const int j_new = compute_shape_factor<depos_order>(sy_new+1, y_new); const int j_old = compute_shifted_shape_factor<depos_order>(sy_old, y_old, j_new); #endif @@ -247,7 +293,7 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, int dil = 1, diu = 1; if (i_old < i_new) dil = 0; if (i_old > i_new) diu = 0; -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) int djl = 1, dju = 1; if (j_old < j_new) djl = 0; if (j_old > j_new) dju = 0; @@ -256,7 +302,7 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, if (k_old < k_new) dkl = 0; if (k_old > k_new) dku = 0; -#if (AMREX_SPACEDIM == 3) +#if (defined WARPX_DIM_3D) for (int k=dkl; k<=depos_order+2-dku; k++) { for (int j=djl; j<=depos_order+2-dju; j++) { @@ -289,7 +335,7 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, } } -#elif (AMREX_SPACEDIM == 2) +#elif (defined WARPX_DIM_2D) || (defined WARPX_DIM_RZ) for (int k=dkl; k<=depos_order+2-dku; k++) { amrex::Real sdxi = 0.; @@ -300,8 +346,8 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, } for (int k=dkl; k<=depos_order+2-dku; k++) { for (int i=dil; i<=depos_order+2-diu; i++) { - const amrex::Real sdyj = wq*uyp[ip]*gaminv*invvol*((sz_new[k] + 0.5*(sz_old[k] - sz_new[k]))*sx_new[i] + - (0.5*sz_new[k] + 1./3.*(sz_old[k] - sz_new[k]))*(sx_old[i] - sx_new[i])); + const amrex::Real sdyj = wq*vy*invvol*((sz_new[k] + 0.5*(sz_old[k] - sz_new[k]))*sx_new[i] + + (0.5*sz_new[k] + 1./3.*(sz_old[k] - sz_new[k]))*(sx_old[i] - sx_new[i])); amrex::Gpu::Atomic::Add( &Jy_arr(lo.x+i_new-1+i, lo.y+k_new-1+k, 0), sdyj); } } @@ -313,6 +359,7 @@ void doEsirkepovDepositionShapeN (const amrex::Real * const xp, } } + #endif } ); diff --git a/Source/Particles/Gather/FieldGather.H b/Source/Particles/Gather/FieldGather.H index be96dd393..8f5e8d4cf 100644 --- a/Source/Particles/Gather/FieldGather.H +++ b/Source/Particles/Gather/FieldGather.H @@ -42,7 +42,9 @@ void doGatherShapeN(const amrex::Real * const xp, #endif const amrex::Real xmin = xyzmin[0]; +#if (AMREX_SPACEDIM == 3) const amrex::Real ymin = xyzmin[1]; +#endif const amrex::Real zmin = xyzmin[2]; // Loop over particles and gather fields from @@ -53,7 +55,12 @@ void doGatherShapeN(const amrex::Real * const xp, // --- Compute shape factors // x direction // Get particle position +#ifdef WARPX_DIM_RZ + const amrex::Real r = std::sqrt(xp[ip]*xp[ip] + yp[ip]*yp[ip]); + const amrex::Real x = (r - xmin)*dxi; +#else const amrex::Real x = (xp[ip]-xmin)*dxi; +#endif // Compute shape factors for node-centered quantities amrex::Real AMREX_RESTRICT sx [depos_order + 1]; // j: leftmost grid point (node-centered) that particle touches @@ -126,6 +133,26 @@ void doGatherShapeN(const amrex::Real * const xp, by_arr(lo.x+j0+ix, lo.y+l0+iz, 0); } } + +#ifdef WARPX_DIM_RZ + // Convert Exp and Eyp (which are actually Er and Etheta) to Ex and Ey + amrex::Real costheta; + amrex::Real sintheta; + if (r > 0.) { + costheta = xp[ip]/r; + sintheta = yp[ip]/r; + } else { + costheta = 1.; + sintheta = 0.; + } + const amrex::Real Exp_save = Exp[ip]; + Exp[ip] = costheta*Exp[ip] - sintheta*Eyp[ip]; + Eyp[ip] = costheta*Eyp[ip] + sintheta*Exp_save; + const amrex::Real Bxp_save = Bxp[ip]; + Bxp[ip] = costheta*Bxp[ip] - sintheta*Byp[ip]; + Byp[ip] = costheta*Byp[ip] + sintheta*Bxp_save; +#endif + #else // (AMREX_SPACEDIM == 3) // Gather field on particle Exp[i] from field on grid ex_arr for (int iz=0; iz<=depos_order; iz++){ diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 7d63bd8e7..59d3ce76f 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -148,7 +148,7 @@ PhysicalParticleContainer::AddGaussianBeam(Real x_m, Real y_m, Real z_m, npart /= 4; } for (long i = 0; i < npart; ++i) { -#if ( AMREX_SPACEDIM == 3 | WARPX_RZ) +#if ( AMREX_SPACEDIM == 3 | WARPX_DIM_RZ) Real weight = q_tot/npart/charge; Real x = distx(mt); Real y = disty(mt); @@ -269,7 +269,7 @@ PhysicalParticleContainer::AddPlasma (int lev, RealBox part_realbox) if (!part_realbox.ok()) part_realbox = geom.ProbDomain(); int num_ppc = plasma_injector->num_particles_per_cell; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ Real rmax = std::min(plasma_injector->xmax, part_realbox.hi(0)); #endif @@ -323,7 +323,7 @@ PhysicalParticleContainer::AddPlasma (int lev, RealBox part_realbox) Real density_min = plasma_injector->density_min; Real density_max = plasma_injector->density_max; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ bool radially_weighted = plasma_injector->radially_weighted; #endif @@ -496,11 +496,11 @@ PhysicalParticleContainer::AddPlasma (int lev, RealBox part_realbox) #endif // Save the x and y values to use in the insideBounds checks. - // This is needed with WARPX_RZ since x and y are modified. + // This is needed with WARPX_DIM_RZ since x and y are modified. Real xb = x; Real yb = y; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ // Replace the x and y, choosing the angle randomly. // These x and y are used to get the momentum and density Real theta = 2.*MathConst::pi*amrex::Random(); @@ -574,7 +574,7 @@ PhysicalParticleContainer::AddPlasma (int lev, RealBox part_realbox) // Real weight = dens * scale_fac / (AMREX_D_TERM(fac, *fac, *fac)); Real weight = dens * scale_fac; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ if (radially_weighted) { weight *= 2.*MathConst::pi*xb; } else { @@ -603,7 +603,7 @@ PhysicalParticleContainer::AddPlasma (int lev, RealBox part_realbox) p.pos(1) = y; p.pos(2) = z; #elif (AMREX_SPACEDIM == 2) -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ pa[PIdx::theta][ip] = theta; #endif p.pos(0) = xb; @@ -893,40 +893,13 @@ PhysicalParticleContainer::FieldGather (int lev, // pti.GetPosition(m_xp[thread_num], m_yp[thread_num], m_zp[thread_num]); - const std::array<Real,3>& xyzmin = WarpX::LowerCorner(box, lev); - const int* ixyzmin = box.loVect(); - // // Field Gather // -#ifdef WARPX_RZ - const int ll4symtry = false; - long lvect_fieldgathe = 64; - warpx_geteb_energy_conserving( - &np, - m_xp[thread_num].dataPtr(), - m_yp[thread_num].dataPtr(), - m_zp[thread_num].dataPtr(), - Exp.dataPtr(),Eyp.dataPtr(),Ezp.dataPtr(), - Bxp.dataPtr(),Byp.dataPtr(),Bzp.dataPtr(), - ixyzmin, - &xyzmin[0], &xyzmin[1], &xyzmin[2], - &dx[0], &dx[1], &dx[2], - &WarpX::nox, &WarpX::noy, &WarpX::noz, - BL_TO_FORTRAN_ANYD(exfab), - BL_TO_FORTRAN_ANYD(eyfab), - BL_TO_FORTRAN_ANYD(ezfab), - BL_TO_FORTRAN_ANYD(bxfab), - BL_TO_FORTRAN_ANYD(byfab), - BL_TO_FORTRAN_ANYD(bzfab), - &ll4symtry, &WarpX::l_lower_order_in_v, &WarpX::do_nodal, - &lvect_fieldgathe, &WarpX::field_gathering_algo); -#else int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); -#endif if (cost) { const Box& tbx = pti.tilebox(); @@ -1195,42 +1168,14 @@ PhysicalParticleContainer::Evolve (int lev, // Field Gather of Aux Data (i.e., the full solution) // BL_PROFILE_VAR_START(blp_pxr_fg); -#ifdef WARPX_RZ - const int ll4symtry = false; - long lvect_fieldgathe = 64; - const std::array<Real,3>& xyzmin_grid = WarpX::LowerCorner(box, lev); - const int* ixyzmin_grid = box.loVect(); - warpx_geteb_energy_conserving( - &np_gather, - m_xp[thread_num].dataPtr(), - m_yp[thread_num].dataPtr(), - m_zp[thread_num].dataPtr(), - Exp.dataPtr(),Eyp.dataPtr(),Ezp.dataPtr(), - Bxp.dataPtr(),Byp.dataPtr(),Bzp.dataPtr(), - ixyzmin_grid, - &xyzmin_grid[0], &xyzmin_grid[1], &xyzmin_grid[2], - &dx[0], &dx[1], &dx[2], - &WarpX::nox, &WarpX::noy, &WarpX::noz, - BL_TO_FORTRAN_ANYD(*exfab), - BL_TO_FORTRAN_ANYD(*eyfab), - BL_TO_FORTRAN_ANYD(*ezfab), - BL_TO_FORTRAN_ANYD(*bxfab), - BL_TO_FORTRAN_ANYD(*byfab), - BL_TO_FORTRAN_ANYD(*bzfab), - &ll4symtry, &WarpX::l_lower_order_in_v, &WarpX::do_nodal, - &lvect_fieldgathe, &WarpX::field_gathering_algo); -#else FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, exfab, eyfab, ezfab, bxfab, byfab, bzfab, Ex.nGrow(), e_is_nodal, 0, np_gather, thread_num, lev, lev); -#endif if (np_gather < np) { const IntVect& ref_ratio = WarpX::RefRatio(lev-1); const Box& cbox = amrex::coarsen(box,ref_ratio); - const std::array<Real,3>& cxyzmin_grid = WarpX::LowerCorner(cbox, lev-1); - const int* cixyzmin_grid = cbox.loVect(); // Data on the grid FArrayBox const* cexfab = &(*cEx)[pti]; @@ -1293,29 +1238,6 @@ PhysicalParticleContainer::Evolve (int lev, } // Field gather for particles in gather buffers -#ifdef WARPX_RZ - - long ncrse = np - nfine_gather; - warpx_geteb_energy_conserving( - &ncrse, - m_xp[thread_num].dataPtr()+nfine_gather, - m_yp[thread_num].dataPtr()+nfine_gather, - m_zp[thread_num].dataPtr()+nfine_gather, - Exp.dataPtr()+nfine_gather, Eyp.dataPtr()+nfine_gather, Ezp.dataPtr()+nfine_gather, - Bxp.dataPtr()+nfine_gather, Byp.dataPtr()+nfine_gather, Bzp.dataPtr()+nfine_gather, - cixyzmin_grid, - &cxyzmin_grid[0], &cxyzmin_grid[1], &cxyzmin_grid[2], - &cdx[0], &cdx[1], &cdx[2], - &WarpX::nox, &WarpX::noy, &WarpX::noz, - BL_TO_FORTRAN_ANYD(*cexfab), - BL_TO_FORTRAN_ANYD(*ceyfab), - BL_TO_FORTRAN_ANYD(*cezfab), - BL_TO_FORTRAN_ANYD(*cbxfab), - BL_TO_FORTRAN_ANYD(*cbyfab), - BL_TO_FORTRAN_ANYD(*cbzfab), - &ll4symtry, &WarpX::l_lower_order_in_v, &WarpX::do_nodal, - &lvect_fieldgathe, &WarpX::field_gathering_algo); -#else e_is_nodal = cEx->is_nodal() and cEy->is_nodal() and cEz->is_nodal(); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, cexfab, ceyfab, cezfab, @@ -1323,7 +1245,6 @@ PhysicalParticleContainer::Evolve (int lev, cEx->nGrow(), e_is_nodal, nfine_gather, np-nfine_gather, thread_num, lev, lev-1); -#endif } BL_PROFILE_VAR_STOP(blp_pxr_fg); @@ -1657,38 +1578,10 @@ PhysicalParticleContainer::PushP (int lev, Real dt, // pti.GetPosition(m_xp[thread_num], m_yp[thread_num], m_zp[thread_num]); -#ifdef WARPX_RZ - const std::array<Real,3>& xyzmin_grid = WarpX::LowerCorner(box, lev); - const int* ixyzmin_grid = box.loVect(); - - const int ll4symtry = false; - long lvect_fieldgathe = 64; - - warpx_geteb_energy_conserving( - &np, - m_xp[thread_num].dataPtr(), - m_yp[thread_num].dataPtr(), - m_zp[thread_num].dataPtr(), - Exp.dataPtr(),Eyp.dataPtr(),Ezp.dataPtr(), - Bxp.dataPtr(),Byp.dataPtr(),Bzp.dataPtr(), - ixyzmin_grid, - &xyzmin_grid[0], &xyzmin_grid[1], &xyzmin_grid[2], - &dx[0], &dx[1], &dx[2], - &WarpX::nox, &WarpX::noy, &WarpX::noz, - BL_TO_FORTRAN_ANYD(exfab), - BL_TO_FORTRAN_ANYD(eyfab), - BL_TO_FORTRAN_ANYD(ezfab), - BL_TO_FORTRAN_ANYD(bxfab), - BL_TO_FORTRAN_ANYD(byfab), - BL_TO_FORTRAN_ANYD(bzfab), - &ll4symtry, &WarpX::l_lower_order_in_v, &WarpX::do_nodal, - &lvect_fieldgathe, &WarpX::field_gathering_algo); -#else - int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); - FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, - &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, - Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); -#endif + int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); + FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, + &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, + Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); // This wraps the momentum advance so that inheritors can modify the call. // Extract pointers to the different particle quantities diff --git a/Source/Particles/Pusher/GetAndSetPosition.H b/Source/Particles/Pusher/GetAndSetPosition.H index 42c61343e..3c74baeb2 100644 --- a/Source/Particles/Pusher/GetAndSetPosition.H +++ b/Source/Particles/Pusher/GetAndSetPosition.H @@ -5,7 +5,7 @@ #include <WarpXParticleContainer.H> #include <AMReX_REAL.H> -#ifndef WARPX_RZ +#ifndef WARPX_DIM_RZ /* \brief Extract the particle's coordinates from the ParticleType struct `p`, * and stores them in the variables `x`, `y`, `z`. */ @@ -42,7 +42,7 @@ void SetPosition( #endif } -# else // if WARPX_RZ is True +# elif defined WARPX_DIM_RZ /* \brief Extract the particle's coordinates from `theta` and the attributes * of the ParticleType struct `p` (which contains the radius), @@ -71,6 +71,6 @@ void SetCylindricalPositionFromCartesian( p.pos(1) = z; } -#endif // WARPX_RZ +#endif // WARPX_DIM_RZ #endif // WARPX_PARTICLES_PUSHER_GETANDSETPOSITION_H_ diff --git a/Source/Particles/Pusher/UpdatePosition.H b/Source/Particles/Pusher/UpdatePosition.H index 0a4f579f4..a9df63a30 100644 --- a/Source/Particles/Pusher/UpdatePosition.H +++ b/Source/Particles/Pusher/UpdatePosition.H @@ -20,7 +20,7 @@ void UpdatePosition( const amrex::Real inv_gamma = 1./std::sqrt(1. + (ux*ux + uy*uy + uz*uz)*inv_c2); // Update positions over one time step x += ux * inv_gamma * dt; -#if (AMREX_SPACEDIM == 3) || (defined WARPX_RZ) // RZ pushes particles in 3D +#if (AMREX_SPACEDIM == 3) || (defined WARPX_DIM_RZ) // RZ pushes particles in 3D y += uy * inv_gamma * dt; #endif z += uz * inv_gamma * dt; diff --git a/Source/Particles/RigidInjectedParticleContainer.cpp b/Source/Particles/RigidInjectedParticleContainer.cpp index 83556e69f..f049fdb7c 100644 --- a/Source/Particles/RigidInjectedParticleContainer.cpp +++ b/Source/Particles/RigidInjectedParticleContainer.cpp @@ -421,38 +421,10 @@ RigidInjectedParticleContainer::PushP (int lev, Real dt, // pti.GetPosition(m_xp[thread_num], m_yp[thread_num], m_zp[thread_num]); -#ifdef WARPX_RZ - const std::array<Real,3>& xyzmin_grid = WarpX::LowerCorner(box, lev); - const int* ixyzmin_grid = box.loVect(); - - const int ll4symtry = false; - long lvect_fieldgathe = 64; - - warpx_geteb_energy_conserving( - &np, - m_xp[thread_num].dataPtr(), - m_yp[thread_num].dataPtr(), - m_zp[thread_num].dataPtr(), - Exp.dataPtr(),Eyp.dataPtr(),Ezp.dataPtr(), - Bxp.dataPtr(),Byp.dataPtr(),Bzp.dataPtr(), - ixyzmin_grid, - &xyzmin_grid[0], &xyzmin_grid[1], &xyzmin_grid[2], - &dx[0], &dx[1], &dx[2], - &WarpX::nox, &WarpX::noy, &WarpX::noz, - BL_TO_FORTRAN_ANYD(exfab), - BL_TO_FORTRAN_ANYD(eyfab), - BL_TO_FORTRAN_ANYD(ezfab), - BL_TO_FORTRAN_ANYD(bxfab), - BL_TO_FORTRAN_ANYD(byfab), - BL_TO_FORTRAN_ANYD(bzfab), - &ll4symtry, &WarpX::l_lower_order_in_v, &WarpX::do_nodal, - &lvect_fieldgathe, &WarpX::field_gathering_algo); -#else int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); -#endif // Save the position and momenta, making copies auto uxp_save = uxp; diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index 7cf53260a..a609b4cb3 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -13,7 +13,7 @@ struct PIdx enum { // Particle Attributes stored in amrex::ParticleContainer's struct of array w = 0, // weight ux, uy, uz, Ex, Ey, Ez, Bx, By, Bz, -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ theta, // RZ needs all three position components #endif nattribs diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp index 89f233b2c..8e4adc528 100644 --- a/Source/Particles/WarpXParticleContainer.cpp +++ b/Source/Particles/WarpXParticleContainer.cpp @@ -27,7 +27,7 @@ void WarpXParIter::GetPosition (Cuda::ManagedDeviceVector<Real>& x, Cuda::ManagedDeviceVector<Real>& y, Cuda::ManagedDeviceVector<Real>& z) const { amrex::ParIter<0,0,PIdx::nattribs>::GetPosition(x, z); -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ const auto& attribs = GetAttribs(); const auto& theta = attribs[PIdx::theta]; y.resize(x.size()); @@ -44,10 +44,10 @@ WarpXParIter::GetPosition (Cuda::ManagedDeviceVector<Real>& x, Cuda::ManagedDevi void WarpXParIter::SetPosition (const Cuda::ManagedDeviceVector<Real>& x, const Cuda::ManagedDeviceVector<Real>& y, const Cuda::ManagedDeviceVector<Real>& z) { -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ auto& attribs = GetAttribs(); auto& theta = attribs[PIdx::theta]; - Cuda::DeviceVector<Real> r(x.size()); + Cuda::ManagedDeviceVector<Real> r(x.size()); for (unsigned int i=0 ; i < x.size() ; i++) { theta[i] = std::atan2(y[i], x[i]); r[i] = std::sqrt(x[i]*x[i] + y[i]*y[i]); @@ -80,7 +80,7 @@ WarpXParticleContainer::WarpXParticleContainer (AmrCore* amr_core, int ispecies) particle_comps["Bx"] = PIdx::Bx; particle_comps["By"] = PIdx::By; particle_comps["Bz"] = PIdx::Bz; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ particle_comps["theta"] = PIdx::theta; #endif @@ -163,7 +163,7 @@ WarpXParticleContainer::AddOneParticle (ParticleTileType& particle_tile, p.pos(1) = y; p.pos(2) = z; #elif (AMREX_SPACEDIM == 2) -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ attribs[PIdx::theta] = std::atan2(y, x); x = std::sqrt(x*x + y*y); #endif @@ -209,7 +209,7 @@ WarpXParticleContainer::AddNParticles (int lev, std::size_t np = iend-ibegin; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ Vector<Real> theta(np); #endif @@ -228,7 +228,7 @@ WarpXParticleContainer::AddNParticles (int lev, p.pos(1) = y[i]; p.pos(2) = z[i]; #elif (AMREX_SPACEDIM == 2) -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ theta[i-ibegin] = std::atan2(y[i], x[i]); p.pos(0) = std::sqrt(x[i]*x[i] + y[i]*y[i]); #else @@ -265,7 +265,7 @@ WarpXParticleContainer::AddNParticles (int lev, for (int comp = PIdx::uz+1; comp < PIdx::nattribs; ++comp) { -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ if (comp == PIdx::theta) { particle_tile.push_back_real(comp, theta.front(), theta.back()); } @@ -394,14 +394,6 @@ WarpXParticleContainer::DepositCurrentFortran(WarpXParIter& pti, &WarpX::nox,&WarpX::noy,&WarpX::noz, &j_is_nodal, &lvect,&WarpX::current_deposition_algo); -#ifdef WARPX_RZ - // Rescale current in r-z mode - warpx_current_deposition_rz_volume_scaling( - jx_ptr, &ngJ, jxntot.getVect(), - jy_ptr, &ngJ, jyntot.getVect(), - jz_ptr, &ngJ, jzntot.getVect(), - &xyzmin[0], &dx[0]); -#endif BL_PROFILE_VAR_STOP(blp_pxr_cd); #ifndef AMREX_USE_GPU @@ -503,7 +495,8 @@ WarpXParticleContainer::DepositCurrent(WarpXParIter& pti, Real* AMREX_RESTRICT yp = m_yp[thread_num].dataPtr() + offset; // Lower corner of tile box physical domain - const std::array<Real, 3>& xyzmin = WarpX::LowerCorner(tilebox, depos_lev);; + // Note that this includes guard cells since it is after tilebox.ngrow + const std::array<Real, 3>& xyzmin = WarpX::LowerCorner(tilebox, depos_lev); // xyzmin is built on pti.tilebox(), so it does // not include staggering, so the stagger_shift has to be done by hand. // Alternatively, we could define xyzminx from tbx (and the same for 3 @@ -513,35 +506,35 @@ WarpXParticleContainer::DepositCurrent(WarpXParIter& pti, if (WarpX::current_deposition_algo == CurrentDepositionAlgo::Esirkepov) { if (WarpX::nox == 1){ - doEsirkepovDepositionShapeN<1>(xp, yp, zp, wp.dataPtr(), uxp.dataPtr(), - uyp.dataPtr(), uzp.dataPtr(), jx_arr, jy_arr, + doEsirkepovDepositionShapeN<1>(xp, yp, zp, wp.dataPtr() + offset, uxp.dataPtr() + offset, + uyp.dataPtr() + offset, uzp.dataPtr() + offset, jx_arr, jy_arr, jz_arr, np_to_depose, dt, dx, xyzmin, lo, q); } else if (WarpX::nox == 2){ - doEsirkepovDepositionShapeN<2>(xp, yp, zp, wp.dataPtr(), uxp.dataPtr(), - uyp.dataPtr(), uzp.dataPtr(), jx_arr, jy_arr, + doEsirkepovDepositionShapeN<2>(xp, yp, zp, wp.dataPtr() + offset, uxp.dataPtr() + offset, + uyp.dataPtr() + offset, uzp.dataPtr() + offset, jx_arr, jy_arr, jz_arr, np_to_depose, dt, dx, xyzmin, lo, q); } else if (WarpX::nox == 3){ - doEsirkepovDepositionShapeN<3>(xp, yp, zp, wp.dataPtr(), uxp.dataPtr(), - uyp.dataPtr(), uzp.dataPtr(), jx_arr, jy_arr, + doEsirkepovDepositionShapeN<3>(xp, yp, zp, wp.dataPtr() + offset, uxp.dataPtr() + offset, + uyp.dataPtr() + offset, uzp.dataPtr() + offset, jx_arr, jy_arr, jz_arr, np_to_depose, dt, dx, xyzmin, lo, q); } } else { if (WarpX::nox == 1){ - doDepositionShapeN<1>(xp, yp, zp, wp.dataPtr(), uxp.dataPtr(), - uyp.dataPtr(), uzp.dataPtr(), jx_arr, jy_arr, + doDepositionShapeN<1>(xp, yp, zp, wp.dataPtr() + offset, uxp.dataPtr() + offset, + uyp.dataPtr() + offset, uzp.dataPtr() + offset, jx_arr, jy_arr, jz_arr, np_to_depose, dt, dx, xyzmin, lo, stagger_shift, q); } else if (WarpX::nox == 2){ - doDepositionShapeN<2>(xp, yp, zp, wp.dataPtr(), uxp.dataPtr(), - uyp.dataPtr(), uzp.dataPtr(), jx_arr, jy_arr, + doDepositionShapeN<2>(xp, yp, zp, wp.dataPtr() + offset, uxp.dataPtr() + offset, + uyp.dataPtr() + offset, uzp.dataPtr() + offset, jx_arr, jy_arr, jz_arr, np_to_depose, dt, dx, xyzmin, lo, stagger_shift, q); } else if (WarpX::nox == 3){ - doDepositionShapeN<3>(xp, yp, zp, wp.dataPtr(), uxp.dataPtr(), - uyp.dataPtr(), uzp.dataPtr(), jx_arr, jy_arr, + doDepositionShapeN<3>(xp, yp, zp, wp.dataPtr() + offset, uxp.dataPtr() + offset, + uyp.dataPtr() + offset, uzp.dataPtr() + offset, jx_arr, jy_arr, jz_arr, np_to_depose, dt, dx, xyzmin, lo, stagger_shift, q); } @@ -617,7 +610,7 @@ WarpXParticleContainer::DepositCharge ( WarpXParIter& pti, RealVector& wp, &ngRho, &ngRho, &ngRho, &WarpX::nox,&WarpX::noy,&WarpX::noz, &lvect, &WarpX::charge_deposition_algo); -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ warpx_charge_deposition_rz_volume_scaling( data_ptr, &ngRho, rholen.getVect(), &xyzmin[0], &dx[0]); @@ -677,7 +670,7 @@ WarpXParticleContainer::DepositCharge ( WarpXParIter& pti, RealVector& wp, &ngRho, &ngRho, &ngRho, &WarpX::nox,&WarpX::noy,&WarpX::noz, &lvect, &WarpX::charge_deposition_algo); -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ warpx_charge_deposition_rz_volume_scaling( data_ptr, &ngRho, rholen.getVect(), &cxyzmin_tile[0], &cdx[0]); @@ -837,7 +830,7 @@ WarpXParticleContainer::GetChargeDensity (int lev, bool local) &dx[0], &dx[1], &dx[2], &nx, &ny, &nz, &nxg, &nyg, &nzg, &WarpX::nox,&WarpX::noy,&WarpX::noz, &lvect, &WarpX::charge_deposition_algo); -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ long ngRho = WarpX::nox; warpx_charge_deposition_rz_volume_scaling( data_ptr, &ngRho, rholen.getVect(), @@ -1022,7 +1015,7 @@ WarpXParticleContainer::PushX (int lev, Real dt) Real* AMREX_RESTRICT ux = attribs[PIdx::ux].dataPtr(); Real* AMREX_RESTRICT uy = attribs[PIdx::uy].dataPtr(); Real* AMREX_RESTRICT uz = attribs[PIdx::uz].dataPtr(); -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ Real* AMREX_RESTRICT theta = attribs[PIdx::theta].dataPtr(); #endif // Loop over the particles and update their position @@ -1030,12 +1023,12 @@ WarpXParticleContainer::PushX (int lev, Real dt) [=] AMREX_GPU_DEVICE (long i) { ParticleType& p = pstructs[i]; // Particle object that gets updated Real x, y, z; // Temporary variables -#ifndef WARPX_RZ +#ifndef WARPX_DIM_RZ GetPosition( x, y, z, p ); // Initialize x, y, z UpdatePosition( x, y, z, ux[i], uy[i], uz[i], dt); SetPosition( p, x, y, z ); // Update the object p #else - // For WARPX_RZ, the particles are still pushed in 3D Cartesian + // For WARPX_DIM_RZ, the particles are still pushed in 3D Cartesian GetCartesianPositionFromCylindrical( x, y, z, p, theta[i] ); UpdatePosition( x, y, z, ux[i], uy[i], uz[i], dt); SetCylindricalPositionFromCartesian( p, theta[i], x, y, z ); diff --git a/Source/Utils/WarpXAlgorithmSelection.cpp b/Source/Utils/WarpXAlgorithmSelection.cpp index 2c8038ccd..3aa4eb7b7 100644 --- a/Source/Utils/WarpXAlgorithmSelection.cpp +++ b/Source/Utils/WarpXAlgorithmSelection.cpp @@ -8,7 +8,7 @@ const std::map<std::string, int> maxwell_solver_algo_to_int = { {"yee", MaxwellSolverAlgo::Yee }, -#ifndef WARPX_RZ // Not available in RZ +#ifndef WARPX_DIM_RZ // Not available in RZ {"ckc", MaxwellSolverAlgo::CKC }, #endif {"default", MaxwellSolverAlgo::Yee } diff --git a/Source/WarpX.H b/Source/WarpX.H index 882df04ee..361234f45 100644 --- a/Source/WarpX.H +++ b/Source/WarpX.H @@ -178,6 +178,13 @@ public: void EvolveE (int lev, PatchType patch_type, amrex::Real dt); void EvolveF (int lev, PatchType patch_type, amrex::Real dt, DtType dt_type); +#ifdef WARPX_DIM_RZ + void ApplyInverseVolumeScalingToCurrentDensity(amrex::MultiFab* Jx, + amrex::MultiFab* Jy, + amrex::MultiFab* Jz, + int lev); +#endif + void DampPML (); void DampPML (int lev); void DampPML (int lev, PatchType patch_type); diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index 63fda6d68..07f124820 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -515,9 +515,7 @@ WarpX::ReadParameters () // If not in RZ mode, read use_picsar_deposition // In RZ mode, use_picsar_deposition is on, as the C++ version // of the deposition does not support RZ -#ifndef WARPX_RZ pp.query("use_picsar_deposition", use_picsar_deposition); -#endif current_deposition_algo = GetAlgorithmInteger(pp, "current_deposition"); charge_deposition_algo = GetAlgorithmInteger(pp, "charge_deposition"); field_gathering_algo = GetAlgorithmInteger(pp, "field_gathering"); @@ -1011,7 +1009,7 @@ WarpX::ComputeDivB (MultiFab& divB, int dcomp, { Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2]; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ const Real rmin = GetInstance().Geom(0).ProbLo(0); #endif @@ -1030,7 +1028,7 @@ WarpX::ComputeDivB (MultiFab& divB, int dcomp, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { warpx_computedivb(i, j, k, dcomp, divBfab, Bxfab, Byfab, Bzfab, dxinv, dyinv, dzinv -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ ,rmin #endif ); @@ -1045,7 +1043,7 @@ WarpX::ComputeDivB (MultiFab& divB, int dcomp, { Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2]; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ const Real rmin = GetInstance().Geom(0).ProbLo(0); #endif @@ -1064,7 +1062,7 @@ WarpX::ComputeDivB (MultiFab& divB, int dcomp, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { warpx_computedivb(i, j, k, dcomp, divBfab, Bxfab, Byfab, Bzfab, dxinv, dyinv, dzinv -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ ,rmin #endif ); @@ -1079,7 +1077,7 @@ WarpX::ComputeDivE (MultiFab& divE, int dcomp, { Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2]; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ const Real rmin = GetInstance().Geom(0).ProbLo(0); #endif @@ -1098,7 +1096,7 @@ WarpX::ComputeDivE (MultiFab& divE, int dcomp, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { warpx_computedive(i, j, k, dcomp, divEfab, Exfab, Eyfab, Ezfab, dxinv, dyinv, dzinv -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ ,rmin #endif ); @@ -1113,7 +1111,7 @@ WarpX::ComputeDivE (MultiFab& divE, int dcomp, { Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2]; -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ const Real rmin = GetInstance().Geom(0).ProbLo(0); #endif @@ -1132,7 +1130,7 @@ WarpX::ComputeDivE (MultiFab& divE, int dcomp, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { warpx_computedive(i, j, k, dcomp, divEfab, Exfab, Eyfab, Ezfab, dxinv, dyinv, dzinv -#ifdef WARPX_RZ +#ifdef WARPX_DIM_RZ ,rmin #endif ); |