aboutsummaryrefslogtreecommitdiff
path: root/Source/Particles/PhysicalParticleContainer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Particles/PhysicalParticleContainer.cpp')
-rw-r--r--Source/Particles/PhysicalParticleContainer.cpp129
1 files changed, 112 insertions, 17 deletions
diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp
index 8c0aa7c23..785454e09 100644
--- a/Source/Particles/PhysicalParticleContainer.cpp
+++ b/Source/Particles/PhysicalParticleContainer.cpp
@@ -17,6 +17,8 @@
#include <UpdatePosition.H>
#include <UpdateMomentumBoris.H>
#include <UpdateMomentumVay.H>
+#include <UpdateMomentumBorisWithRadiationReaction.H>
+#include <UpdateMomentumHigueraCary.H>
using namespace amrex;
@@ -44,6 +46,23 @@ PhysicalParticleContainer::PhysicalParticleContainer (AmrCore* amr_core, int isp
pp.query("do_boosted_frame_diags", do_boosted_frame_diags);
pp.query("do_field_ionization", do_field_ionization);
+
+ //check if Radiation Reaction is enabled and do consistency checks
+ pp.query("do_classical_radiation_reaction", do_classical_radiation_reaction);
+ //if the species is not a lepton, do_classical_radiation_reaction
+ //should be false
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
+ !(do_classical_radiation_reaction && !AmIALepton()),
+ "Can't enable classical radiation reaction for non lepton species. " );
+
+ //Only Boris pusher is compatible with radiation reaction
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
+ !(do_classical_radiation_reaction &&
+ WarpX::particle_pusher_algo != ParticlePusherAlgo::Boris),
+ "Radiation reaction can be enabled only if Boris pusher is used");
+ //_____________________________
+
+
#ifdef AMREX_USE_GPU
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
do_field_ionization == 0,
@@ -993,12 +1012,12 @@ PhysicalParticleContainer::FieldGather (int lev,
const FArrayBox& byfab = By[pti];
const FArrayBox& bzfab = Bz[pti];
- Exp.assign(np,0.0);
- Eyp.assign(np,0.0);
- Ezp.assign(np,0.0);
- Bxp.assign(np,0.0);
- Byp.assign(np,0.0);
- Bzp.assign(np,0.0);
+ Exp.assign(np,WarpX::E_external[0]);
+ Eyp.assign(np,WarpX::E_external[1]);
+ Ezp.assign(np,WarpX::E_external[2]);
+ Bxp.assign(np,WarpX::B_external[0]);
+ Byp.assign(np,WarpX::B_external[1]);
+ Bzp.assign(np,WarpX::B_external[2]);
//
// copy data from particle container to temp arrays
@@ -1129,9 +1148,10 @@ PhysicalParticleContainer::Evolve (int lev,
exfab, eyfab, ezfab, bxfab, byfab, bzfab);
}
- Exp.assign(np,0.0);
- Eyp.assign(np,0.0);
- Ezp.assign(np,0.0);
+ Exp.assign(np,WarpX::E_external[0]);
+ Eyp.assign(np,WarpX::E_external[1]);
+ Ezp.assign(np,WarpX::E_external[2]);
+
Bxp.assign(np,WarpX::B_external[0]);
Byp.assign(np,WarpX::B_external[1]);
Bzp.assign(np,WarpX::B_external[2]);
@@ -1578,7 +1598,23 @@ PhysicalParticleContainer::PushPX(WarpXParIter& pti,
// Loop over the particles and update their momentum
const Real q = this->charge;
const Real m = this-> mass;
- if (WarpX::particle_pusher_algo == ParticlePusherAlgo::Boris){
+
+
+ //Assumes that all consistency checks have been done at initialization
+ if(do_classical_radiation_reaction){
+ amrex::ParallelFor(
+ pti.numParticles(),
+ [=] AMREX_GPU_DEVICE (long i) {
+ Real qp = q;
+ if (ion_lev){ qp *= ion_lev[i]; }
+ UpdateMomentumBorisWithRadiationReaction( ux[i], uy[i], uz[i],
+ Ex[i], Ey[i], Ez[i], Bx[i],
+ By[i], Bz[i], qp, m, dt);
+ UpdatePosition( x[i], y[i], z[i],
+ ux[i], uy[i], uz[i], dt );
+ }
+ );
+ } else if (WarpX::particle_pusher_algo == ParticlePusherAlgo::Boris){
amrex::ParallelFor(
pti.numParticles(),
[=] AMREX_GPU_DEVICE (long i) {
@@ -1604,6 +1640,19 @@ PhysicalParticleContainer::PushPX(WarpXParIter& pti,
ux[i], uy[i], uz[i], dt );
}
);
+ } else if (WarpX::particle_pusher_algo == ParticlePusherAlgo::HigueraCary) {
+ amrex::ParallelFor(
+ pti.numParticles(),
+ [=] AMREX_GPU_DEVICE (long i) {
+ Real qp = q;
+ if (ion_lev){ qp *= ion_lev[i]; }
+ UpdateMomentumHigueraCary( ux[i], uy[i], uz[i],
+ Ex[i], Ey[i], Ez[i], Bx[i],
+ By[i], Bz[i], qp, m, dt);
+ UpdatePosition( x[i], y[i], z[i],
+ ux[i], uy[i], uz[i], dt );
+ }
+ );
} else {
amrex::Abort("Unknown particle pusher");
};
@@ -1652,9 +1701,10 @@ PhysicalParticleContainer::PushP (int lev, Real dt,
const FArrayBox& byfab = By[pti];
const FArrayBox& bzfab = Bz[pti];
- Exp.assign(np,0.0);
- Eyp.assign(np,0.0);
- Ezp.assign(np,0.0);
+ Exp.assign(np,WarpX::E_external[0]);
+ Eyp.assign(np,WarpX::E_external[1]);
+ Ezp.assign(np,WarpX::E_external[2]);
+
Bxp.assign(np,WarpX::B_external[0]);
Byp.assign(np,WarpX::B_external[1]);
Bzp.assign(np,WarpX::B_external[2]);
@@ -1685,17 +1735,55 @@ PhysicalParticleContainer::PushP (int lev, Real dt,
// Loop over the particles and update their momentum
const Real q = this->charge;
const Real m = this-> mass;
- if (WarpX::particle_pusher_algo == ParticlePusherAlgo::Boris){
+
+ int* AMREX_RESTRICT ion_lev = nullptr;
+ if (do_field_ionization){
+ ion_lev = pti.GetiAttribs(particle_icomps["ionization_level"]).dataPtr();
+ }
+
+
+ //Assumes that all consistency checks have been done at initialization
+ if(do_classical_radiation_reaction){
+ amrex::ParallelFor(
+ pti.numParticles(),
+ [=] AMREX_GPU_DEVICE (long i) {
+ Real qp = q;
+ if (ion_lev){ qp *= ion_lev[i]; }
+ UpdateMomentumBorisWithRadiationReaction(
+ ux[i], uy[i], uz[i],
+ Expp[i], Eypp[i], Ezpp[i],
+ Bxpp[i], Bypp[i], Bzpp[i],
+ qp, m, dt);
+ }
+ );
+ } else if (WarpX::particle_pusher_algo == ParticlePusherAlgo::Boris){
amrex::ParallelFor( pti.numParticles(),
[=] AMREX_GPU_DEVICE (long i) {
- UpdateMomentumBoris( ux[i], uy[i], uz[i],
- Expp[i], Eypp[i], Ezpp[i], Bxpp[i], Bypp[i], Bzpp[i], q, m, dt);
+ Real qp = q;
+ if (ion_lev){ qp *= ion_lev[i]; }
+ UpdateMomentumBoris(
+ ux[i], uy[i], uz[i],
+ Expp[i], Eypp[i], Ezpp[i],
+ Bxpp[i], Bypp[i], Bzpp[i],
+ qp, m, dt);
}
);
} else if (WarpX::particle_pusher_algo == ParticlePusherAlgo::Vay) {
amrex::ParallelFor( pti.numParticles(),
[=] AMREX_GPU_DEVICE (long i) {
- UpdateMomentumVay( ux[i], uy[i], uz[i],
+ Real qp = q;
+ if (ion_lev){ qp *= ion_lev[i]; }
+ UpdateMomentumVay(
+ ux[i], uy[i], uz[i],
+ Expp[i], Eypp[i], Ezpp[i],
+ Bxpp[i], Bypp[i], Bzpp[i],
+ qp, m, dt);
+ }
+ );
+ } else if (WarpX::particle_pusher_algo == ParticlePusherAlgo::HigueraCary) {
+ amrex::ParallelFor( pti.numParticles(),
+ [=] AMREX_GPU_DEVICE (long i) {
+ UpdateMomentumHigueraCary( ux[i], uy[i], uz[i],
Expp[i], Eypp[i], Ezpp[i], Bxpp[i], Bypp[i], Bzpp[i], q, m, dt);
}
);
@@ -2216,6 +2304,13 @@ PhysicalParticleContainer::buildIonizationMask (const amrex::MFIter& mfi, const
);
}
+//This function return true if the PhysicalParticleContainer contains electrons
+//or positrons, false otherwise
+bool
+PhysicalParticleContainer::AmIALepton(){
+ return (this-> mass == PhysConst::m_e);
+}
+
#ifdef WARPX_QED
bool PhysicalParticleContainer::has_quantum_sync()