aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/FortranInterface/WarpX_f.H1
-rw-r--r--Source/Make.WarpX19
-rw-r--r--Source/Particles/Make.package6
-rw-r--r--Source/Particles/MultiParticleContainer.H41
-rw-r--r--Source/Particles/MultiParticleContainer.cpp82
-rw-r--r--Source/Particles/PhotonParticleContainer.H83
-rw-r--r--Source/Particles/PhotonParticleContainer.cpp115
-rw-r--r--Source/Particles/WarpXParticleContainer.cpp14
-rw-r--r--Source/QED/Make.package6
-rw-r--r--Source/QED/amrex_rng_wrapper.cpp18
-rw-r--r--Source/QED/amrex_rng_wrapper.h20
-rw-r--r--Source/QED/breit_wheeler_engine_wrapper.h24
12 files changed, 395 insertions, 34 deletions
diff --git a/Source/FortranInterface/WarpX_f.H b/Source/FortranInterface/WarpX_f.H
index 60a9817a2..26da42606 100644
--- a/Source/FortranInterface/WarpX_f.H
+++ b/Source/FortranInterface/WarpX_f.H
@@ -63,6 +63,7 @@
extern "C"
{
#endif
+
// Laser pusher
void warpx_gaussian_laser( const long* np,
amrex::Real* Xp, amrex::Real* Yp, amrex::Real* t, amrex::Real* wavelength, amrex::Real* e_max, amrex::Real* waist,
diff --git a/Source/Make.WarpX b/Source/Make.WarpX
index ea06f8e06..d369e38e2 100644
--- a/Source/Make.WarpX
+++ b/Source/Make.WarpX
@@ -81,6 +81,21 @@ ifeq ($(USE_SENSEI_INSITU),TRUE)
include $(AMREX_HOME)/Src/Extern/SENSEI/Make.package
endif
+ifeq ($(QED),TRUE)
+ BOOST_ROOT ?= NOT_SET
+ ifneq ($(BOOST_ROOT),NOT_SET)
+ VPATH_LOCATIONS += $(BOOST_ROOT)
+ INCLUDE_LOCATIONS += $(BOOST_ROOT)
+ endif
+ INCLUDE_LOCATIONS += $(PICSAR_HOME)/src/multi_physics/QED/src
+ CXXFLAGS += -DWARPX_QED
+ CFLAGS += -DWARPX_QED
+ FFLAGS += -DWARPX_QED
+ F90FLAGS += -DWARPX_QED
+ include $(WARPX_HOME)/Source/QED/Make.package
+endif
+
+
include $(PICSAR_HOME)/src/Make.package
WARPX_GIT_VERSION := $(shell cd $(WARPX_HOME); git describe --abbrev=12 --dirty --always --tags)
@@ -160,7 +175,11 @@ ifeq ($(USE_HDF5),TRUE)
LIBRARY_LOCATIONS += $(HDF5_HOME)/lib
endif
DEFINES += -DWARPX_USE_HDF5
+<<<<<<< HEAD
+ LIBRARIES += -lhdf5 -lz
+=======
libraries += -lhdf5 -lz
+>>>>>>> dev
endif
# job_info support
diff --git a/Source/Particles/Make.package b/Source/Particles/Make.package
index db90de1dc..95f36cf65 100644
--- a/Source/Particles/Make.package
+++ b/Source/Particles/Make.package
@@ -1,14 +1,18 @@
F90EXE_sources += deposit_cic.F90
F90EXE_sources += interpolate_cic.F90
F90EXE_sources += push_particles_ES.F90
-CEXE_sources += PhysicalParticleContainer.cpp
+
CEXE_sources += MultiParticleContainer.cpp
CEXE_sources += WarpXParticleContainer.cpp
CEXE_sources += RigidInjectedParticleContainer.cpp
+CEXE_sources += PhysicalParticleContainer.cpp
+CEXE_sources += PhotonParticleContainer.cpp
+
CEXE_headers += MultiParticleContainer.H
CEXE_headers += WarpXParticleContainer.H
CEXE_headers += RigidInjectedParticleContainer.H
CEXE_headers += PhysicalParticleContainer.H
+CEXE_headers += PhotonParticleContainer.H
CEXE_headers += ShapeFactors.H
include $(WARPX_HOME)/Source/Particles/Pusher/Make.package
diff --git a/Source/Particles/MultiParticleContainer.H b/Source/Particles/MultiParticleContainer.H
index 1aff7edfb..67392c449 100644
--- a/Source/Particles/MultiParticleContainer.H
+++ b/Source/Particles/MultiParticleContainer.H
@@ -10,6 +10,7 @@
#include <WarpXParticleContainer.H>
#include <PhysicalParticleContainer.H>
#include <RigidInjectedParticleContainer.H>
+#include <PhotonParticleContainer.H>
#include <LaserParticleContainer.H>
//
@@ -20,6 +21,11 @@
// concrete class dervied from WarpXParticlContainer.
//
+//
+#ifdef WARPX_QED
+ #include "breit_wheeler_engine_wrapper.h"
+#endif
+
class MultiParticleContainer
{
@@ -50,24 +56,24 @@ public:
const amrex::Vector<std::unique_ptr<amrex::FabArray<amrex::BaseFab<int> > > >& masks);
///
- /// This evolves all the particles by one PIC time step, including charge deposition, the
+ /// This evolves all the particles by one PIC time step, including charge deposition, the
/// field solve, and pushing the particles, for all the species in the MultiParticleContainer.
/// This is the electrostatic version.
///
- void EvolveES (const amrex::Vector<std::array<std::unique_ptr<amrex::MultiFab>, 3> >& E,
- amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho,
+ void EvolveES (const amrex::Vector<std::array<std::unique_ptr<amrex::MultiFab>, 3> >& E,
+ amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho,
amrex::Real t, amrex::Real dt);
///
- /// This pushes the particle positions by one half time step for all the species in the
+ /// This pushes the particle positions by one half time step for all the species in the
/// MultiParticleContainer. It is used to desynchronize the particles after initializaton
/// or when restarting from a checkpoint. This is the electrostatic version.
- ///
+ ///
void PushXES (amrex::Real dt);
///
/// This deposits the particle charge onto rho, accumulating the value for all the species
- /// in the MultiParticleContainer. rho is assumed to contain node-centered multifabs.
+ /// in the MultiParticleContainer. rho is assumed to contain node-centered multifabs.
/// This version is hard-coded for CIC deposition.
///
void DepositCharge(amrex::Vector<std::unique_ptr<amrex::MultiFab> >& rho, bool local = false);
@@ -78,7 +84,7 @@ public:
///
amrex::Real sumParticleCharge(bool local = false);
#endif // WARPX_DO_ELECTROSTATIC
-
+
///
/// Performs the field gather operation using the input fields E and B, for all the species
/// in the MultiParticleContainer. This is the electromagnetic version of the field gather.
@@ -96,8 +102,8 @@ public:
void Evolve (int lev,
const amrex::MultiFab& Ex, const amrex::MultiFab& Ey, const amrex::MultiFab& Ez,
const amrex::MultiFab& Bx, const amrex::MultiFab& By, const amrex::MultiFab& Bz,
- amrex::MultiFab& jx, amrex::MultiFab& jy, amrex::MultiFab& jz,
- amrex::MultiFab* cjx, amrex::MultiFab* cjy, amrex::MultiFab* cjz,
+ amrex::MultiFab& jx, amrex::MultiFab& jy, amrex::MultiFab& jz,
+ amrex::MultiFab* cjx, amrex::MultiFab* cjy, amrex::MultiFab* cjz,
amrex::MultiFab* rho, amrex::MultiFab* crho,
const amrex::MultiFab* cEx, const amrex::MultiFab* cEy, const amrex::MultiFab* cEz,
const amrex::MultiFab* cBx, const amrex::MultiFab* cBy, const amrex::MultiFab* cBz,
@@ -107,7 +113,7 @@ public:
/// This pushes the particle positions by one half time step for all the species in the
/// MultiParticleContainer. It is used to desynchronize the particles after initializaton
/// or when restarting from a checkpoint. This is the electromagnetic version.
- ///
+ ///
void PushX (amrex::Real dt);
///
@@ -115,7 +121,7 @@ public:
/// MultiParticleContainer. It is used to desynchronize the particles after initializaton
/// or when restarting from a checkpoint. It is also used to synchronize particles at the
/// the end of the run. This is the electromagnetic version.
- ///
+ ///
void PushP (int lev, amrex::Real dt,
const amrex::MultiFab& Ex, const amrex::MultiFab& Ey, const amrex::MultiFab& Ez,
const amrex::MultiFab& Bx, const amrex::MultiFab& By, const amrex::MultiFab& Bz);
@@ -173,7 +179,7 @@ public:
const amrex::Real t_boost, const amrex::Real t_lab, const amrex::Real dt,
amrex::Vector<WarpXParticleContainer::DiagnosticParticleData>& parts) const;
- // Inject particles during the simulation (for particles entering the
+ // Inject particles during the simulation (for particles entering the
// simulation domain after some iterations, due to flowing plasma and/or
// moving window).
void ContinuousInjection(const amrex::RealBox& injection_box) const;
@@ -184,11 +190,16 @@ public:
std::vector<std::string> GetSpeciesNames() const { return species_names; }
PhysicalParticleContainer& GetPCtmp () { return *pc_tmp; }
-
+
+ //bw_engine is a public member of the MultiParticleContainer object
+#ifdef WARPX_QED
+ warpx_breit_wheeler_engine bw_engine;
+#endif
+
protected:
// Particle container types
- enum struct PCTypes {Physical, RigidInjected};
+ enum struct PCTypes {Physical, RigidInjected, Photon};
std::vector<std::string> species_names;
@@ -212,7 +223,7 @@ private:
// Number of species dumped in BoostedFrameDiagnostics
int nspecies_boosted_frame_diags = 0;
- // map_species_boosted_frame_diags[i] is the species ID in
+ // map_species_boosted_frame_diags[i] is the species ID in
// MultiParticleContainer for 0<i<nspecies_boosted_frame_diags
std::vector<int> map_species_boosted_frame_diags;
int do_boosted_frame_diags = 0;
diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp
index 143f4b7f9..da09adbf2 100644
--- a/Source/Particles/MultiParticleContainer.cpp
+++ b/Source/Particles/MultiParticleContainer.cpp
@@ -8,8 +8,16 @@
using namespace amrex;
+#ifdef WARPX_QED
+MultiParticleContainer::MultiParticleContainer (AmrCore* amr_core):
+ bw_engine{std::move(init_warpx_breit_wheeler_engine())}
+#else
MultiParticleContainer::MultiParticleContainer (AmrCore* amr_core)
+#endif
{
+
+
+
ReadParameters();
allcontainers.resize(nspecies + nlasers);
@@ -20,9 +28,12 @@ MultiParticleContainer::MultiParticleContainer (AmrCore* amr_core)
else if (species_types[i] == PCTypes::RigidInjected) {
allcontainers[i].reset(new RigidInjectedParticleContainer(amr_core, i, species_names[i]));
}
+ else if (species_types[i] == PCTypes::Photon) {
+ allcontainers[i].reset(new PhotonParticleContainer(amr_core, i, species_names[i]));
+ }
allcontainers[i]->deposit_on_main_grid = deposit_on_main_grid[i];
}
-
+
for (int i = nspecies; i < nspecies+nlasers; ++i) {
allcontainers[i].reset(new LaserParticleContainer(amr_core,i, lasers_names[i-nspecies]));
}
@@ -56,9 +67,11 @@ MultiParticleContainer::ReadParameters ()
BL_ASSERT(nspecies >= 0);
if (nspecies > 0) {
+ // Get species names
pp.getarr("species_names", species_names);
BL_ASSERT(species_names.size() == nspecies);
+ // Get species to deposit on main grid
deposit_on_main_grid.resize(nspecies, 0);
std::vector<std::string> tmp;
pp.queryarr("deposit_on_main_grid", tmp);
@@ -71,9 +84,9 @@ MultiParticleContainer::ReadParameters ()
species_types.resize(nspecies, PCTypes::Physical);
+ // Get rigid-injected species
std::vector<std::string> rigid_injected_species;
pp.queryarr("rigid_injected_species", rigid_injected_species);
-
if (!rigid_injected_species.empty()) {
for (auto const& name : rigid_injected_species) {
auto it = std::find(species_names.begin(), species_names.end(), name);
@@ -82,6 +95,18 @@ MultiParticleContainer::ReadParameters ()
species_types[i] = PCTypes::RigidInjected;
}
}
+ // Get photon species
+ std::vector<std::string> photon_species;
+ pp.queryarr("photon_species", photon_species);
+ if (!photon_species.empty()) {
+ for (auto const& name : photon_species) {
+ auto it = std::find(species_names.begin(), species_names.end(), name);
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(it != species_names.end(), "ERROR: species in particles.rigid_injected_species must be part of particles.species_names");
+ int i = std::distance(species_names.begin(), it);
+ species_types[i] = PCTypes::Photon;
+ }
+ }
+
}
pp.query("use_fdtd_nci_corr", WarpX::use_fdtd_nci_corr);
@@ -118,6 +143,31 @@ MultiParticleContainer::InitData ()
// For each species, get the ID of its product species.
// This is used for ionization and pair creation processes.
mapSpeciesProduct();
+
+#ifdef WARPX_QED
+
+ //Helper function
+ auto does_file_exist = [](const char *fileName)
+ {return (std::ifstream{fileName}).good(); };
+
+ //Initialize the lookup tables
+ //Generates tables if they do not exist
+ if(!does_file_exist("bw_engine_dndt.bin")){
+ bw_engine.compute_dN_dt_lookup_table(&std::cout);
+ bw_engine.write_dN_dt_table("bw_engine_dndt.bin");
+ }
+ else{
+ bw_engine.read_dN_dt_table("bw_engine_dndt.bin");
+ }
+
+ if(!does_file_exist("bw_engine_pair.bin")){
+ bw_engine.compute_cumulative_pair_table(&std::cout);
+ bw_engine.write_cumulative_pair_table("bw_engine_pair.bin");
+ }
+ else{
+ bw_engine.read_cumulative_pair_table("bw_engine_pair.bin");
+ }
+#endif
}
@@ -348,7 +398,7 @@ MultiParticleContainer
{
BL_PROFILE("MultiParticleContainer::GetLabFrameData");
-
+
// Loop over particle species
for (int i = 0; i < nspecies_boosted_frame_diags; ++i){
int isp = map_species_boosted_frame_diags[i];
@@ -357,41 +407,41 @@ MultiParticleContainer
pc->GetParticleSlice(direction, z_old, z_new, t_boost, t_lab, dt, diagnostic_particles);
// Here, diagnostic_particles[lev][index] is a WarpXParticleContainer::DiagnosticParticleData
// where "lev" is the AMR level and "index" is a [grid index][tile index] pair.
-
+
// Loop over AMR levels
for (int lev = 0; lev <= pc->finestLevel(); ++lev){
- // Loop over [grid index][tile index] pairs
- // and Fills parts[species number i] with particle data from all grids and
- // tiles in diagnostic_particles. parts contains particles from all
+ // Loop over [grid index][tile index] pairs
+ // and Fills parts[species number i] with particle data from all grids and
+ // tiles in diagnostic_particles. parts contains particles from all
// AMR levels indistinctly.
for (auto it = diagnostic_particles[lev].begin(); it != diagnostic_particles[lev].end(); ++it){
// it->first is the [grid index][tile index] key
- // it->second is the corresponding
+ // it->second is the corresponding
// WarpXParticleContainer::DiagnosticParticleData value
parts[i].GetRealData(DiagIdx::w).insert( parts[i].GetRealData(DiagIdx::w ).end(),
it->second.GetRealData(DiagIdx::w ).begin(),
it->second.GetRealData(DiagIdx::w ).end());
-
+
parts[i].GetRealData(DiagIdx::x).insert( parts[i].GetRealData(DiagIdx::x ).end(),
it->second.GetRealData(DiagIdx::x ).begin(),
it->second.GetRealData(DiagIdx::x ).end());
-
+
parts[i].GetRealData(DiagIdx::y).insert( parts[i].GetRealData(DiagIdx::y ).end(),
it->second.GetRealData(DiagIdx::y ).begin(),
it->second.GetRealData(DiagIdx::y ).end());
-
+
parts[i].GetRealData(DiagIdx::z).insert( parts[i].GetRealData(DiagIdx::z ).end(),
it->second.GetRealData(DiagIdx::z ).begin(),
it->second.GetRealData(DiagIdx::z ).end());
-
+
parts[i].GetRealData(DiagIdx::ux).insert( parts[i].GetRealData(DiagIdx::ux).end(),
it->second.GetRealData(DiagIdx::ux).begin(),
it->second.GetRealData(DiagIdx::ux).end());
-
+
parts[i].GetRealData(DiagIdx::uy).insert( parts[i].GetRealData(DiagIdx::uy).end(),
it->second.GetRealData(DiagIdx::uy).begin(),
it->second.GetRealData(DiagIdx::uy).end());
-
+
parts[i].GetRealData(DiagIdx::uz).insert( parts[i].GetRealData(DiagIdx::uz).end(),
it->second.GetRealData(DiagIdx::uz).begin(),
it->second.GetRealData(DiagIdx::uz).end());
@@ -402,7 +452,7 @@ MultiParticleContainer
/* \brief Continuous injection for particles initially outside of the domain.
* \param injection_box: Domain where new particles should be injected.
- * Loop over all WarpXParticleContainer in MultiParticleContainer and
+ * Loop over all WarpXParticleContainer in MultiParticleContainer and
* calls virtual function ContinuousInjection.
*/
void
@@ -418,7 +468,7 @@ MultiParticleContainer::ContinuousInjection(const RealBox& injection_box) const
/* \brief Update position of continuous injection parameters.
* \param dt: simulation time step (level 0)
- * All classes inherited from WarpXParticleContainer do not have
+ * All classes inherited from WarpXParticleContainer do not have
* a position to update (PhysicalParticleContainer does not do anything).
*/
void
diff --git a/Source/Particles/PhotonParticleContainer.H b/Source/Particles/PhotonParticleContainer.H
new file mode 100644
index 000000000..966fc1e2d
--- /dev/null
+++ b/Source/Particles/PhotonParticleContainer.H
@@ -0,0 +1,83 @@
+#ifndef WARPX_PhotonParticleContainer_H_
+#define WARPX_PhotonParticleContainer_H_
+
+#include <PhysicalParticleContainer.H>
+#include <AMReX_Vector.H>
+
+#ifdef WARPX_QED
+ #include "breit_wheeler_engine_wrapper.h"
+#endif
+
+class PhotonParticleContainer
+ : public PhysicalParticleContainer
+{
+public:
+ PhotonParticleContainer (amrex::AmrCore* amr_core,
+ int ispecies,
+ const std::string& name);
+ virtual ~PhotonParticleContainer () {}
+
+ virtual void InitData() override;
+
+ virtual void Evolve (int lev,
+ const amrex::MultiFab& Ex,
+ const amrex::MultiFab& Ey,
+ const amrex::MultiFab& Ez,
+ const amrex::MultiFab& Bx,
+ const amrex::MultiFab& By,
+ const amrex::MultiFab& Bz,
+ amrex::MultiFab& jx,
+ amrex::MultiFab& jy,
+ amrex::MultiFab& jz,
+ amrex::MultiFab* cjx,
+ amrex::MultiFab* cjy,
+ amrex::MultiFab* cjz,
+ amrex::MultiFab* rho,
+ amrex::MultiFab* crho,
+ const amrex::MultiFab* cEx,
+ const amrex::MultiFab* cEy,
+ const amrex::MultiFab* cEz,
+ const amrex::MultiFab* cBx,
+ const amrex::MultiFab* cBy,
+ const amrex::MultiFab* cBz,
+ amrex::Real t,
+ amrex::Real dt) override;
+
+ virtual void PushPX(WarpXParIter& pti,
+ amrex::Cuda::ManagedDeviceVector<amrex::Real>& xp,
+ amrex::Cuda::ManagedDeviceVector<amrex::Real>& yp,
+ amrex::Cuda::ManagedDeviceVector<amrex::Real>& zp,
+ amrex::Cuda::ManagedDeviceVector<amrex::Real>& giv,
+ amrex::Real dt) override;
+
+ virtual void DepositCurrent(WarpXParIter& pti,
+ RealVector& wp,
+ RealVector& uxp,
+ RealVector& uyp,
+ RealVector& uzp,
+ amrex::MultiFab& jx,
+ amrex::MultiFab& jy,
+ amrex::MultiFab& jz,
+ amrex::MultiFab* cjx,
+ amrex::MultiFab* cjy,
+ amrex::MultiFab* cjz,
+ const long np_current,
+ const long np,
+ int thread_num,
+ int lev,
+ amrex::Real dt ) override {};
+
+//This function initialises the optical depth of the photons
+#ifdef WARPX_QED
+ virtual void InitOpticalDepth(
+ WarpXParIter& pti,
+ warpx_breit_wheeler_engine& engine);
+#endif
+
+private:
+
+ amrex::Real size_in_inches = 1.;
+
+};
+
+#endif // #ifndef WARPX_PhotonParticleContainer_H_
diff --git a/Source/Particles/PhotonParticleContainer.cpp b/Source/Particles/PhotonParticleContainer.cpp
new file mode 100644
index 000000000..2bcf87d6a
--- /dev/null
+++ b/Source/Particles/PhotonParticleContainer.cpp
@@ -0,0 +1,115 @@
+#include <limits>
+#include <sstream>
+#include <algorithm>
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#include <PhotonParticleContainer.H>
+#include <WarpX_f.H>
+#include <WarpX.H>
+#include <WarpXConst.H>
+
+using namespace amrex;
+
+PhotonParticleContainer::PhotonParticleContainer (AmrCore* amr_core, int ispecies,
+ const std::string& name)
+ : PhysicalParticleContainer(amr_core, ispecies, name)
+{
+
+ // This will read <species>.[...] from the inputs file
+ // where <species> is the name of your species
+ ParmParse pp(species_name);
+
+ // read <species>.size_in_inches in the input file, and
+ // store it into member data.
+ pp.query("size_in_inches", size_in_inches);
+
+#ifdef WARPX_QED
+ AddRealComp("tau");
+ plot_flags.resize(PIdx::nattribs + 1, 1);
+#endif
+
+}
+
+void PhotonParticleContainer::InitData()
+{
+ AddParticles(0); // Note - add on level 0
+
+ if (maxLevel() > 0) {
+ Redistribute(); // We then redistribute
+ }
+}
+
+void
+PhotonParticleContainer::PushPX(WarpXParIter& pti,
+ Cuda::ManagedDeviceVector<Real>& xp,
+ Cuda::ManagedDeviceVector<Real>& yp,
+ Cuda::ManagedDeviceVector<Real>& zp,
+ Cuda::ManagedDeviceVector<Real>& giv,
+ Real dt)
+{
+ // This wraps the call to warpx_particle_pusher so that inheritors can modify the call.
+ auto& attribs = pti.GetAttribs();
+ auto& uxp = attribs[PIdx::ux];
+ auto& uyp = attribs[PIdx::uy];
+ auto& uzp = attribs[PIdx::uz];
+ auto& Exp = attribs[PIdx::Ex];
+ auto& Eyp = attribs[PIdx::Ey];
+ auto& Ezp = attribs[PIdx::Ez];
+ auto& Bxp = attribs[PIdx::Bx];
+ auto& Byp = attribs[PIdx::By];
+ auto& Bzp = attribs[PIdx::Bz];
+ const long np = pti.numParticles();
+
+ // Using new pusher for positions
+ const amrex_real zero_mass = 0.0;
+ warpx_particle_pusher_positions(&np,
+ xp.dataPtr(),
+ yp.dataPtr(),
+ zp.dataPtr(),
+ uxp.dataPtr(), uyp.dataPtr(), uzp.dataPtr(),
+ giv.dataPtr(),
+ &zero_mass, &dt,
+ &WarpX::particle_pusher_algo);
+}
+
+void
+PhotonParticleContainer::Evolve (int lev,
+ const MultiFab& Ex, const MultiFab& Ey, const MultiFab& Ez,
+ const MultiFab& Bx, const MultiFab& By, const MultiFab& Bz,
+ MultiFab& jx, MultiFab& jy, MultiFab& jz,
+ MultiFab* cjx, MultiFab* cjy, MultiFab* cjz,
+ MultiFab* rho, MultiFab* crho,
+ const MultiFab* cEx, const MultiFab* cEy, const MultiFab* cEz,
+ const MultiFab* cBx, const MultiFab* cBy, const MultiFab* cBz,
+ Real t, Real dt)
+{
+ // This does gather, push and depose.
+ // Push and depose have been re-written for photon,
+ // so they do not do anything.
+ // Currently, I guess photons do gather fields from the mesh.
+ PhysicalParticleContainer::Evolve (lev,
+ Ex, Ey, Ez,
+ Bx, By, Bz,
+ jx, jy, jz,
+ cjx, cjy, cjz,
+ rho, crho,
+ cEx, cEy, cEz,
+ cBx, cBy, cBz,
+ t, dt);
+
+}
+
+
+#ifdef WARPX_QED
+void PhotonParticleContainer::InitOpticalDepth(
+ WarpXParIter& pti,
+ warpx_breit_wheeler_engine& engine)
+{
+ auto& taus = pti.GetAttribs(particle_comps["tau"]);
+ for(auto& tau: taus)
+ tau = engine.get_optical_depth();
+}
+#endif
diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp
index 80d1caa0f..6d5b51264 100644
--- a/Source/Particles/WarpXParticleContainer.cpp
+++ b/Source/Particles/WarpXParticleContainer.cpp
@@ -136,7 +136,7 @@ WarpXParticleContainer::AddOneParticle (int lev, int grid, int tile,
Real x, Real y, Real z,
std::array<Real,PIdx::nattribs>& attribs)
{
- auto& particle_tile = GetParticles(lev)[std::make_pair(grid,tile)];
+ auto& particle_tile = DefineAndReturnParticleTile(lev, grid, tile);
AddOneParticle(particle_tile, x, y, z, attribs);
}
@@ -163,6 +163,11 @@ WarpXParticleContainer::AddOneParticle (ParticleTileType& particle_tile,
particle_tile.push_back(p);
particle_tile.push_back_real(attribs);
+
+ for (int i = PIdx::nattribs; i < NumRealComps(); ++i)
+ {
+ particle_tile.push_back_real(i, 0.0);
+ }
}
void
@@ -195,7 +200,7 @@ WarpXParticleContainer::AddNParticles (int lev,
// Add to grid 0 and tile 0
// Redistribute() will move them to proper places.
std::pair<int,int> key {0,0};
- auto& particle_tile = GetParticles(lev)[key];
+ auto& particle_tile = DefineAndReturnParticleTile(0, 0, 0);
std::size_t np = iend-ibegin;
@@ -258,6 +263,11 @@ WarpXParticleContainer::AddNParticles (int lev,
particle_tile.push_back_real(comp, np, 0.0);
#endif
}
+
+ for (int i = PIdx::nattribs; i < NumRealComps(); ++i)
+ {
+ particle_tile.push_back_real(i, 0.0);
+ }
}
Redistribute();
diff --git a/Source/QED/Make.package b/Source/QED/Make.package
new file mode 100644
index 000000000..6e38efb9e
--- /dev/null
+++ b/Source/QED/Make.package
@@ -0,0 +1,6 @@
+CEXE_headers += amrex_rng_wrapper.h
+CEXE_headers += breit_wheeler_engine_wrapper.h
+CEXE_sources += amrex_rng_wrapper.cpp
+
+INCLUDE_LOCATIONS += $(WARPX_HOME)/Source/QED
+VPATH_LOCATIONS += $(WARPX_HOME)/Source/QED
diff --git a/Source/QED/amrex_rng_wrapper.cpp b/Source/QED/amrex_rng_wrapper.cpp
new file mode 100644
index 000000000..955144c4c
--- /dev/null
+++ b/Source/QED/amrex_rng_wrapper.cpp
@@ -0,0 +1,18 @@
+//This file provides a wrapper aroud the RNG
+//provided by the amrex library
+
+#include "amrex_rng_wrapper.h"
+
+//RNG wrapper BW engine
+//Get rnd number uniformly distributed in [a,b)
+amrex::Real amrex_rng_wrapper::unf(amrex::Real a, amrex::Real b)
+{
+ return (b-a)*amrex::Random() + a;
+}
+
+//Get rnd number with exponential distribution
+amrex::Real amrex_rng_wrapper::exp(amrex::Real l)
+{
+ amrex::Real zero_plus_to_one = 1.0 - unf(0.0, 1.0);
+ return -log(zero_plus_to_one)/l;
+}
diff --git a/Source/QED/amrex_rng_wrapper.h b/Source/QED/amrex_rng_wrapper.h
new file mode 100644
index 000000000..f9818c589
--- /dev/null
+++ b/Source/QED/amrex_rng_wrapper.h
@@ -0,0 +1,20 @@
+#ifndef WARPX_amrex_rng_wrapper_h_
+#define WARPX_rng_wrapper_h_
+
+//This file provides a wrapper aroud the RNG
+//provided by the amrex library
+
+#include <AMReX_AmrCore.H>
+
+//RNG wrapper BW engine
+class amrex_rng_wrapper
+{
+public:
+ //Get rnd number uniformly distributed in [a,b)
+ amrex::Real unf(amrex::Real a, amrex::Real b);
+
+ //Get rnd number with exponential distribution
+ amrex::Real exp(amrex::Real l);
+};
+
+#endif //amrex_rng_wrapper_hpp_
diff --git a/Source/QED/breit_wheeler_engine_wrapper.h b/Source/QED/breit_wheeler_engine_wrapper.h
new file mode 100644
index 000000000..3bb3ea740
--- /dev/null
+++ b/Source/QED/breit_wheeler_engine_wrapper.h
@@ -0,0 +1,24 @@
+#ifndef WARPX_breit_wheeler_engine_wrapper_h_
+#define WARPX_breit_wheeler_engine_wrapper_h_
+
+//This file provides a wrapper aroud the breit_wheeler engine
+//provided by the standard template library
+
+//BW ENGINE
+//#define PXRMP_GPU __host__ __device__
+#define PXRMP_WITH_SI_UNITS
+#include "breit_wheeler_engine.hpp"
+
+#include "amrex_rng_wrapper.h"
+
+using warpx_breit_wheeler_engine =
+ picsar::multi_physics::breit_wheeler_engine<amrex::Real, amrex_rng_wrapper>;
+
+//Helper function to initialize the engine
+inline warpx_breit_wheeler_engine init_warpx_breit_wheeler_engine(){
+ return warpx_breit_wheeler_engine{std::move(amrex_rng_wrapper{})};
+}
+
+//___________________________________________
+
+#endif //WARPX_breit_wheeler_engine_wrapper_H_