aboutsummaryrefslogtreecommitdiff
path: root/Source/LaserParticleContainer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/LaserParticleContainer.cpp')
-rw-r--r--Source/LaserParticleContainer.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/Source/LaserParticleContainer.cpp b/Source/LaserParticleContainer.cpp
new file mode 100644
index 000000000..b8b448740
--- /dev/null
+++ b/Source/LaserParticleContainer.cpp
@@ -0,0 +1,176 @@
+
+#include <limits>
+
+#include <WarpX.H>
+#include <WarpXConst.H>
+#include <WarpX_f.H>
+#include <ParticleContainer.H>
+#include <ParticleIterator.H>
+
+LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies)
+ : WarpXParticleContainer(amr_core, ispecies)
+{
+ charge = PhysConst::q_e; // note that q_e is defined to be positive.
+ mass = std::numeric_limits<Real>::max();
+}
+
+void
+LaserParticleContainer::AllocData ()
+{
+ // have to resize here, not in the constructor because GDB was not
+ // ready in constructor.
+ m_particles.resize(GDB().finestLevel()+1);
+}
+
+void
+LaserParticleContainer::InitData ()
+{
+
+}
+
+void
+LaserParticleContainer::Evolve (int lev,
+ const MultiFab&, const MultiFab&, const MultiFab&,
+ const MultiFab&, const MultiFab&, const MultiFab&,
+ MultiFab& jx, MultiFab& jy, MultiFab& jz, Real dt)
+{
+ BL_PROFILE("Laser::Evolve()");
+ BL_PROFILE_VAR_NS("Laser::Evolve::Copy", blp_copy);
+ BL_PROFILE_VAR_NS("PICSAR::LaserParticlePush", blp_pxr_pp);
+ BL_PROFILE_VAR_NS("PICSAR::LaserCurrentDepo", blp_pxr_cd);
+
+ const Geometry& gm = GDB().Geom(lev);
+ const BoxArray& ba = jx.boxArray();
+
+#if (BL_SPACEDIM == 3)
+ const Real* dx = gm.CellSize();
+#elif (BL_SPACEDIM == 2)
+ Real dx[3] = { gm.CellSize(0), std::numeric_limits<Real>::quiet_NaN(), gm.CellSize(1) };
+#endif
+
+#if (BL_SPACEDIM == 3)
+ long ngx_j = jx.nGrow();
+ long ngy_j = ngx_j;
+ long ngz_j = ngx_j;
+#elif (BL_SPACEDIM == 2)
+ long ngx_j = jx.nGrow();;
+ long ngy_j = 0;
+ long ngz_j = ngx_j;
+#endif
+
+ BL_ASSERT(OnSameGrids(lev,jx));
+
+ {
+ Array<Real> xp, yp, zp, wp, uxp, uyp, uzp, giv;
+
+ PartIterInfo info {lev, do_tiling, tile_size};
+ for (PartIter pti(*this, info); pti.isValid(); ++pti)
+ {
+ const int gid = pti.index();
+ const Box& tbx = pti.tilebox();
+ const Box& vbx = pti.validbox();
+ const long np = pti.numParticles();
+
+ // Data on the grid
+ FArrayBox& jxfab = jx[gid];
+ FArrayBox& jyfab = jy[gid];
+ FArrayBox& jzfab = jz[gid];
+
+ xp.resize(np);
+ yp.resize(np);
+ zp.resize(np);
+ wp.resize(np);
+ uxp.resize(np);
+ uyp.resize(np);
+ uzp.resize(np);
+ giv.resize(np);
+
+ //
+ // copy data from particle container to temp arrays
+ //
+ BL_PROFILE_VAR_START(blp_copy);
+ pti.foreach([&](int i, ParticleType& p) {
+#if (BL_SPACEDIM == 3)
+ xp[i] = p.m_pos[0];
+ yp[i] = p.m_pos[1];
+ zp[i] = p.m_pos[2];
+#elif (BL_SPACEDIM == 2)
+ xp[i] = p.m_pos[0];
+ yp[i] = std::numeric_limits<Real>::quiet_NaN();
+ zp[i] = p.m_pos[1];
+#endif
+ wp[i] = p.m_data[PIdx::w];
+ uxp[i] = p.m_data[PIdx::ux];
+ uyp[i] = p.m_data[PIdx::uy];
+ uzp[i] = p.m_data[PIdx::uz];
+ });
+ BL_PROFILE_VAR_STOP(blp_copy);
+
+
+ const Box& box = BoxLib::enclosedCells(ba[gid]);
+ BL_ASSERT(box == vbx);
+#if (BL_SPACEDIM == 3)
+ long nx = box.length(0);
+ long ny = box.length(1);
+ long nz = box.length(2);
+#elif (BL_SPACEDIM == 2)
+ long nx = box.length(0);
+ long ny = 0;
+ long nz = box.length(1);
+#endif
+ RealBox grid_box = RealBox( box, gm.CellSize(), gm.ProbLo() );
+#if (BL_SPACEDIM == 3)
+ const Real* xyzmin = grid_box.lo();
+#elif (BL_SPACEDIM == 2)
+ Real xyzmin[3] = { grid_box.lo(0), std::numeric_limits<Real>::quiet_NaN(), grid_box.lo(1) };
+#endif
+
+ //
+ // Particle Push
+ //
+ BL_PROFILE_VAR_START(blp_pxr_pp);
+ warpx_laser_pusher(&np, xp.data(), yp.data(), zp.data(),
+ uxp.data(), uyp.data(), uzp.data(), giv.data(),
+ &this->charge, &dt,
+ &WarpX::laser_pusher_algo);
+ BL_PROFILE_VAR_STOP(blp_pxr_pp);
+
+ //
+ // Current Deposition
+ // xxxxx this part needs to be thread safe if we have OpenMP over tiles
+ //
+ long lvect = 8;
+ BL_PROFILE_VAR_START(blp_pxr_cd);
+ warpx_current_deposition(jxfab.dataPtr(), jyfab.dataPtr(), jzfab.dataPtr(),
+ &np, xp.data(), yp.data(), zp.data(),
+ uxp.data(), uyp.data(), uzp.data(),
+ giv.data(), wp.data(), &this->charge,
+ &xyzmin[0], &xyzmin[1], &xyzmin[2],
+ &dt, &dx[0], &dx[1], &dx[2], &nx, &ny, &nz,
+ &ngx_j, &ngy_j, &ngz_j,
+ &WarpX::nox,&WarpX::noy,&WarpX::noz,
+ &lvect,&WarpX::current_deposition_algo);
+ BL_PROFILE_VAR_STOP(blp_pxr_cd);
+
+ //
+ // copy particle data back
+ //
+ BL_PROFILE_VAR_START(blp_copy);
+ pti.foreach([&](int i, ParticleType& p) {
+ BL_ASSERT(p.m_id > 0);
+#if (BL_SPACEDIM == 3)
+ p.m_pos[0] = xp[i];
+ p.m_pos[1] = yp[i];
+ p.m_pos[2] = zp[i];
+#elif (BL_SPACEDIM == 2)
+ p.m_pos[0] = xp[i];
+ p.m_pos[1] = zp[i];
+#endif
+ p.m_data[PIdx::ux] = uxp[i];
+ p.m_data[PIdx::uy] = uyp[i];
+ p.m_data[PIdx::uz] = uzp[i];
+ });
+ BL_PROFILE_VAR_STOP(blp_copy);
+ }
+ }
+}