diff options
Diffstat (limited to 'Source/Particles')
-rw-r--r-- | Source/Particles/MultiParticleContainer.H | 10 | ||||
-rw-r--r-- | Source/Particles/MultiParticleContainer.cpp | 45 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.H | 5 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.cpp | 18 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.H | 20 |
5 files changed, 91 insertions, 7 deletions
diff --git a/Source/Particles/MultiParticleContainer.H b/Source/Particles/MultiParticleContainer.H index f3fd522a9..0c5e49c04 100644 --- a/Source/Particles/MultiParticleContainer.H +++ b/Source/Particles/MultiParticleContainer.H @@ -169,7 +169,15 @@ public: const amrex::Real z_old, const amrex::Real z_new, 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 + // simulation domain after some iterations, due to flowing plasma and/or + // moving window). + void ContinuousInjection(const amrex::RealBox& injection_box) const; + // Update injection position for continuously-injected species. + void UpdateContinuousInjectionPosition(amrex::Real dt) const; + int doContinuousInjection() const; + // // Parameters for the Cherenkov corrector in the FDTD solver. // Both stencils are calculated ar runtime. diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index a4df1f83a..440906348 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -414,3 +414,48 @@ 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 + * calls virtual function ContinuousInjection. + */ +void +MultiParticleContainer::ContinuousInjection(const RealBox& injection_box) const +{ + for (int i=0; i<nspecies+nlasers; i++){ + auto& pc = allcontainers[i]; + if (pc->do_continuous_injection){ + pc->ContinuousInjection(injection_box); + } + } +} + +/* \brief Update position of continuous injection parameters. + * \param dt: simulation time step (level 0) + * All classes inherited from WarpXParticleContainer do not have + * a position to update (PhysicalParticleContainer does not do anything). + */ +void +MultiParticleContainer::UpdateContinuousInjectionPosition(Real dt) const +{ + for (int i=0; i<nspecies+nlasers; i++){ + auto& pc = allcontainers[i]; + if (pc->do_continuous_injection){ + pc->UpdateContinuousInjectionPosition(dt); + } + } +} + +int +MultiParticleContainer::doContinuousInjection() const +{ + int warpx_do_continuous_injection = 0; + for (int i=0; i<nspecies+nlasers; i++){ + auto& pc = allcontainers[i]; + if (pc->do_continuous_injection){ + warpx_do_continuous_injection = 1; + } + } + return warpx_do_continuous_injection; +} diff --git a/Source/Particles/PhysicalParticleContainer.H b/Source/Particles/PhysicalParticleContainer.H index 362683879..4f365768b 100644 --- a/Source/Particles/PhysicalParticleContainer.H +++ b/Source/Particles/PhysicalParticleContainer.H @@ -101,8 +101,6 @@ public: const amrex::Real t_lab, const amrex::Real dt, DiagnosticParticles& diagnostic_particles) final; - bool injected = false; - protected: std::string species_name; @@ -122,6 +120,9 @@ protected: int GetRefineFac(const amrex::Real x, const amrex::Real y, const amrex::Real z); std::unique_ptr<amrex::IArrayBox> m_refined_injection_mask = nullptr; + // Inject particles during the whole simulation + void ContinuousInjection(const amrex::RealBox& injection_box) override; + }; #endif diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 17e6d98d9..2fa39d87d 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -24,7 +24,7 @@ NumParticlesToAdd(const Box& overlap_box, const RealBox& overlap_realbox, for (IntVect iv = overlap_box.smallEnd(); iv <= overlap_box.bigEnd(); overlap_box.next(iv)) { int fac; - if (injected) { + if (do_continuous_injection) { #if ( AMREX_SPACEDIM == 3 ) Real x = overlap_corner[0] + (iv[0] + 0.5)*dx[0]; Real y = overlap_corner[1] + (iv[1] + 0.5)*dx[1]; @@ -81,6 +81,7 @@ PhysicalParticleContainer::PhysicalParticleContainer (AmrCore* amr_core, int isp pp.query("do_backward_propagation", do_backward_propagation); pp.query("do_splitting", do_splitting); pp.query("split_type", split_type); + pp.query("do_continuous_injection", do_continuous_injection); } PhysicalParticleContainer::PhysicalParticleContainer (AmrCore* amr_core) @@ -361,7 +362,7 @@ PhysicalParticleContainer::AddPlasmaCPU (int lev, RealBox part_realbox) for (IntVect iv = overlap_box.smallEnd(); iv <= overlap_box.bigEnd(); overlap_box.next(iv)) { int fac; - if (injected) { + if (do_continuous_injection) { #if ( AMREX_SPACEDIM == 3 ) Real x = overlap_corner[0] + (iv[0] + 0.5)*dx[0]; Real y = overlap_corner[1] + (iv[1] + 0.5)*dx[1]; @@ -602,7 +603,7 @@ PhysicalParticleContainer::AddPlasmaGPU (int lev, RealBox part_realbox) for (IntVect iv = overlap_box.smallEnd(); iv <= overlap_box.bigEnd(); overlap_box.next(iv)) { int fac; - if (injected) { + if (do_continuous_injection) { #if ( AMREX_SPACEDIM == 3 ) Real x = overlap_corner[0] + (iv[0] + 0.5)*dx[0]; Real y = overlap_corner[1] + (iv[1] + 0.5)*dx[1]; @@ -2004,3 +2005,14 @@ int PhysicalParticleContainer::GetRefineFac(const Real x, const Real y, const Re return ref_fac; } + +/* \brief Inject particles during the simulation + * \param injection_box: domain where particles should be injected. + */ +void +PhysicalParticleContainer::ContinuousInjection(const RealBox& injection_box) +{ + // Inject plasma on level 0. Paticles will be redistributed. + const int lev=0; + AddPlasma(lev, injection_box); +} diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index 275554cd8..6fa02b824 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -183,7 +183,18 @@ public: int thread_num, int lev, amrex::Real dt ); - + + // If particles start outside of the domain, ContinuousInjection + // makes sure that they are initialized when they enter the domain, and + // NOT before. Virtual function, overriden by derived classes. + // Current status: + // PhysicalParticleContainer: implemented. + // LaserParticleContainer: implemented. + // RigidInjectedParticleContainer: not implemented. + virtual void ContinuousInjection(const amrex::RealBox& injection_box) {} + // Update optional sub-class-specific injection location. + virtual void UpdateContinuousInjectionPosition(amrex::Real dt) {} + /// /// This returns the total charge for all the particles in this ParticleContainer. /// This is needed when solving Poisson's equation with periodic boundary conditions. @@ -248,6 +259,12 @@ protected: static int do_not_push; + // Whether to allow particles outside of the simulation domain to be + // initialized when they enter the domain. + // This is currently required because continuous injection does not + // support all features allowed by direct injection. + int do_continuous_injection = 0; + amrex::Vector<amrex::FArrayBox> local_rho; amrex::Vector<amrex::FArrayBox> local_jx; amrex::Vector<amrex::FArrayBox> local_jy; @@ -258,6 +275,7 @@ protected: private: virtual void particlePostLocate(ParticleType& p, const amrex::ParticleLocData& pld, const int lev) override; + }; #endif |