diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Evolve/WarpXEvolveEM.cpp | 4 | ||||
-rw-r--r-- | Source/Laser/LaserParticleContainer.H | 8 | ||||
-rw-r--r-- | Source/Laser/LaserParticleContainer.cpp | 134 | ||||
-rw-r--r-- | Source/Particles/MultiParticleContainer.H | 8 | ||||
-rw-r--r-- | Source/Particles/MultiParticleContainer.cpp | 32 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.H | 6 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.cpp | 13 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.H | 7 | ||||
-rw-r--r-- | Source/Utils/WarpXMovingWindow.cpp | 29 | ||||
-rw-r--r-- | Source/WarpX.cpp | 12 |
10 files changed, 98 insertions, 155 deletions
diff --git a/Source/Evolve/WarpXEvolveEM.cpp b/Source/Evolve/WarpXEvolveEM.cpp index 7fe47d261..e98561be1 100644 --- a/Source/Evolve/WarpXEvolveEM.cpp +++ b/Source/Evolve/WarpXEvolveEM.cpp @@ -88,10 +88,6 @@ WarpX::EvolveEM (int numsteps) UpdateAuxilaryData(); } - // Performs continuous injection of all WarpXParticleContainer - // in mypc. - // mypc->ContinuousInjection(dt[0], geom[0].ProbDomain()); - if (do_subcycling == 0 || finest_level == 0) { OneStep_nosub(cur_time); } else if (do_subcycling == 1 && finest_level == 1) { diff --git a/Source/Laser/LaserParticleContainer.H b/Source/Laser/LaserParticleContainer.H index bb36f4795..ccd48f3b5 100644 --- a/Source/Laser/LaserParticleContainer.H +++ b/Source/Laser/LaserParticleContainer.H @@ -84,10 +84,11 @@ private: std::string field_function; // laser particle domain - amrex::RealBox laser_prob_domain; + amrex::RealBox laser_injection_box; // Theoretical position of the antenna. Used if do_continuous_injection=1. // Track the position of the antenna until it enters the simulation domain. - amrex::Real z_antenna_th; + amrex::Vector<amrex::Real> updated_position; + // Avoid injecting the antenna several times. int done_injecting=1; void ComputeSpacing (int lev, amrex::Real& Sx, amrex::Real& Sy) const; @@ -95,7 +96,8 @@ private: void InitData (int lev); // Inject the laser antenna during the simulation, if it started // outside of the simulation domain and enters it. - void ContinuousInjection(amrex::Real dt, const amrex::RealBox& prob_domain) override; + void ContinuousInjection(const amrex::RealBox& injection_box) override; + // Update position of the antenna void UpdateContinuousInjectionPosition(amrex::Real dt) override; }; diff --git a/Source/Laser/LaserParticleContainer.cpp b/Source/Laser/LaserParticleContainer.cpp index 8499455de..a7fe9042d 100644 --- a/Source/Laser/LaserParticleContainer.cpp +++ b/Source/Laser/LaserParticleContainer.cpp @@ -149,42 +149,42 @@ LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies, u_Y = {0., 1., 0.}; #endif - laser_prob_domain = Geometry::ProbDomain(); + laser_injection_box= Geometry::ProbDomain(); { Vector<Real> lo, hi; if (pp.queryarr("prob_lo", lo)) { - laser_prob_domain.setLo(lo); + laser_injection_box.setLo(lo); } if (pp.queryarr("prob_hi", hi)) { - laser_prob_domain.setHi(hi); + laser_injection_box.setHi(hi); } } if (do_continuous_injection){ // If laser antenna initially outside of the box, store its theoretical // position in z_antenna_th, and set done_injecting to 0. - z_antenna_th = position[2]; - const Real prob_lo_z = laser_prob_domain.lo()[AMREX_SPACEDIM-1]; - const Real prob_hi_z = laser_prob_domain.hi()[AMREX_SPACEDIM-1]; - if ( z_antenna_th<prob_lo_z || z_antenna_th>prob_hi_z ){ + updated_position = position; + // Convert updated position to Real* to use RealBox.contains() +#if (AMREX_SPACEDIM == 3) + const Real* p_pos = updated_position.dataPtr(); +#else + const Real p_pos[2] = {updated_position[0], updated_position[2]}; +#endif + if ( not laser_injection_box.contains(p_pos) ){ done_injecting = 0; } - // Sanity checks: do_continuous_injection can be used only if the - // laser, the moving window and the boost are all in z direction. + + // Sanity checks + std::Vector<Real> windir(3, 0.0); +#if (AMREX_SPACEDIM==2) + windir[2*dir] = 1.0; +#else + windir[dir] = 1.0; +#endif AMREX_ALWAYS_ASSERT_WITH_MESSAGE( - (nvec[0]-0)*(nvec[0]-0) + - (nvec[1]-0)*(nvec[1]-0) + - (nvec[2]-1)*(nvec[2]-1) < 1.e-12, - "do_continous_injection for laser particle only works if " + - "laser.direction = 0 0 1 (laser along z). TODO: all directions."); - AMREX_ALWAYS_ASSERT_WITH_MESSAGE( - WarpX::moving_window_dir == AMREX_SPACEDIM-1, - "do_continous_injection for laser particle only works if " + - "moving window along z. TODO: all directions."); - AMREX_ALWAYS_ASSERT_WITH_MESSAGE( - maxLevel() == 0, - "do_continous_injection for laser particle only works if " + - "max level = 0."); + (nvec[0]-windir[0]) + (nvec[1]-windor[1]) + (nvec[2]-windor[2]) + < 1.e-12, "do_continous_injection for laser particle only works" + + " if moving window direction and laser propagation direction are the same"); if ( WarpX::gamma_boost>1 ){ AMREX_ALWAYS_ASSERT_WITH_MESSAGE( (WarpX::boost_direction[0]-0)*(WarpX::boost_direction[0]-0) + @@ -197,86 +197,60 @@ LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies, } /* \brief Check if laser particles enter the box, and inject if necessary. - * \param dt: time step (assume no MR for now) - * \param prob_domain: a RealBox that contains current simulation boundaries. - * This function checks if the laser antenna should be injected at this - * iteration. If so, it injects it and set done_injecting to 1. + * \param injection_box: a RealBox where particles should be injected. */ void -LaserParticleContainer::ContinuousInjection (Real dt, const RealBox& prob_domain) +LaserParticleContainer::ContinuousInjection (const RealBox& injection_box) { - Print()<<" --- In LaserParticleContainer::ContinuousInjection"<<std::endl; - Print()<<"z_antenna_th "<<z_antenna_th<<std::endl; - // If laser antenna particles have not been injected yet, - // check if they should be injected at this iteration. If - // so, inject them and set done_injecting to 0 (false). if (done_injecting==0) { - // Input parameter prob_domain contains up-to-date properties of the - // simulation domain (i.e. including moving window shift). - // So far, LaserParticleContainer::laser_prob_domain contains the - // outdated prob_domain at t=0. - - // Get domain boundaries in the z direction - const Real prob_lo_z = prob_domain.lo()[AMREX_SPACEDIM-1]; - const Real prob_hi_z = prob_domain.hi()[AMREX_SPACEDIM-1]; - Print()<<"prob_lo_z "<<prob_lo_z<<std::endl; - Print()<<"prob_hi_z "<<prob_hi_z<<std::endl; - if ( z_antenna_th>=prob_lo_z && z_antenna_th<prob_hi_z ){ - // Update laser_prob_domain with current value - laser_prob_domain = prob_domain; + // Input parameter injection_box contains small box where injection + // should occur. + // So far, LaserParticleContainer::laser_injection_box contains the + // outdated full problem domain at t=0. + + // Convert updated_position to Real* to use RealBox::contains(). +#if (AMREX_SPACEDIM == 3) + const Real* p_pos = updated_position.dataPtr(); +#else + const Real p_pos[2] = {updated_position[0], updated_position[2]}; +#endif + if ( injection_box.contains(p_pos) ){ + // Update laser_injection_box with current value + laser_injection_box = injection_box; // Inject laser particles. LaserParticleContainer::InitData // is called only once, when the antenna enters the simulation // domain. - InitData(maxLevel()); - // Set done_injecting to 1, to avoid re-injecting particles. + InitData(); done_injecting = 1; } } } +/* \brief update position of the antenna if running in boosted frame. + * \param dt time step (level 0). + * The up-to-date antenna position is stored in updated_position. + */ void LaserParticleContainer::UpdateContinuousInjectionPosition(Real dt) { int dir = WarpX::moving_window_dir; - // update position of the antenna (outside of the box) - // Continuously inject plasma in new cells (by default only on level 0) if (do_continuous_injection and (WarpX::gamma_boost > 1)){ - // In boosted-frame simulations, the plasma has moved since the last + // In boosted-frame simulations, the antenna has moved since the last // call to this function, and injection position needs to be updated - z_antenna_th -= WarpX::beta_boost * #if ( AMREX_SPACEDIM == 3 ) + updated_position[dir] -= WarpX::beta_boost * WarpX::boost_direction[dir] * PhysConst::c * dt; #elif ( AMREX_SPACEDIM == 2 ) - // In 2D, dir=0 corresponds to x and dir=1 corresponds to z - // This needs to be converted in order to index `boost_direction` - // which has 3 components, for both 2D and 3D simulations. + // In 2D, dir=0 corresponds to x and dir=1 corresponds to z + // This needs to be converted in order to index `boost_direction` + // which has 3 components, for both 2D and 3D simulations. + updated_position[2*dir] -= WarpX::beta_boost * WarpX::boost_direction[2*dir] * PhysConst::c * dt; #endif } - - /* - if (WarpX::do_plasma_injection and (WarpX::gamma_boost > 1){ - z_antenna_th -= PhysConst::c * WarpX::beta_boost * dt; - } - */ } - - - - - - - - - - - - - - - void LaserParticleContainer::InitData () { @@ -294,9 +268,9 @@ LaserParticleContainer::InitData (int lev) // LaserParticleContainer::position contains the initial position of the // laser antenna. In the boosted frame, the antenna is moving. - // Update its position. + // Update its position with updated_position. if (do_continuous_injection){ - position[2] = z_antenna_th; + position = updated_position; } auto Transform = [&](int i, int j) -> Vector<Real>{ @@ -334,8 +308,8 @@ LaserParticleContainer::InitData (int lev) plane_hi[1] = std::max(plane_hi[1], j); }; - const Real* prob_lo = laser_prob_domain.lo(); - const Real* prob_hi = laser_prob_domain.hi(); + const Real* prob_lo = laser_injection_box.lo(); + const Real* prob_hi = laser_injection_box.hi(); #if (AMREX_SPACEDIM == 3) compute_min_max(prob_lo[0], prob_lo[1], prob_lo[2]); compute_min_max(prob_hi[0], prob_lo[1], prob_lo[2]); @@ -396,7 +370,7 @@ LaserParticleContainer::InitData (int lev) #else const Real x[2] = {pos[0], pos[2]}; #endif - if (laser_prob_domain.contains(x)) + if (laser_injection_box.contains(x)) { for (int k = 0; k<2; ++k) { particle_x.push_back(pos[0]); diff --git a/Source/Particles/MultiParticleContainer.H b/Source/Particles/MultiParticleContainer.H index f48daf9bb..49a79231c 100644 --- a/Source/Particles/MultiParticleContainer.H +++ b/Source/Particles/MultiParticleContainer.H @@ -170,9 +170,11 @@ public: const amrex::Real t_boost, const amrex::Real t_lab, const amrex::Real dt, amrex::Vector<WarpXParticleContainer::DiagnosticParticleData>& parts) const; - void ContinuousInjection(amrex::Real dt, - const amrex::RealBox& prob_domain) 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; // diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index 9810a168f..a5f695c69 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -416,45 +416,33 @@ MultiParticleContainer } /* \brief Continuous injection for particles initially outside of the domain. - * \param dt: timestep (so far, this only works without MR) - * \param prob_domain: current boundaries of the full 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(Real dt, const RealBox& prob_domain) const +MultiParticleContainer::ContinuousInjection(const RealBox& injection_box) const { for (int i=0; i<nspecies+nlasers; i++){ auto& pc = allcontainers[i]; - Print()<<"i "<<i<<" pc->do_continuous_injection "<<pc->do_continuous_injection<<std::endl; - if (pc->do_continuous_injection) - { - Print()<<"i "<<i<<" pc->do_continuous_injection "<<pc->do_continuous_injection<<std::endl; - pc->ContinuousInjection(dt, prob_domain); + 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]; - Print()<<"i "<<i<<" pc->do_continuous_injection "<<pc->do_continuous_injection<<std::endl; - if (pc->do_continuous_injection) - { - Print()<<"i "<<i<<" pc->do_continuous_injection "<<pc->do_continuous_injection<<std::endl; + if (pc->do_continuous_injection){ pc->UpdateContinuousInjectionPosition(dt); } } - /* - for (int i=nspecies; i<nspecies+nlasers; i++){ - // WarpXParticleContainer& pc = allcontainers[i]; - WarpXParticleContainer& pc = GetParticleContainer(i); - auto& lpc = dynamic_cast<LaserParticleContainer&>(pc); - // auto& pc = allcontainers[i]; - // auto& lpc = dynamic_cast<LaserParticleContainer&>(pc); - lpc.UpdateContinuousInjectionPosition(dt); - } - */ } diff --git a/Source/Particles/PhysicalParticleContainer.H b/Source/Particles/PhysicalParticleContainer.H index 253aa58cd..4f365768b 100644 --- a/Source/Particles/PhysicalParticleContainer.H +++ b/Source/Particles/PhysicalParticleContainer.H @@ -101,9 +101,6 @@ public: const amrex::Real t_lab, const amrex::Real dt, DiagnosticParticles& diagnostic_particles) final; - // bool injected = false; - // int do_continuous_injection = false; - protected: std::string species_name; @@ -123,7 +120,8 @@ 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; - void ContinuousInjection(amrex::Real dt, const amrex::RealBox& prob_domain) override; + // Inject particles during the whole simulation + void ContinuousInjection(const amrex::RealBox& injection_box) override; }; diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index c28aacd28..2fa39d87d 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -24,7 +24,6 @@ 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]; @@ -363,9 +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) { - Print()<<"in AddPlasmaCPU if do_continuous_injection"<<std::endl; #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]; @@ -606,7 +603,6 @@ 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]; @@ -2010,10 +2006,13 @@ 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(Real dt, const RealBox& prob_domain) +PhysicalParticleContainer::ContinuousInjection(const RealBox& injection_box) { + // Inject plasma on level 0. Paticles will be redistributed. const int lev=0; - Print()<<"in PhysicalParticleContainer::ContinuousInjection"<<std::endl; - AddPlasma(lev, prob_domain); + AddPlasma(lev, injection_box); } diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index 51238907d..6fa02b824 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -188,11 +188,11 @@ public: // makes sure that they are initialized when they enter the domain, and // NOT before. Virtual function, overriden by derived classes. // Current status: - // PhysicalParticleContainer: not implemented. + // PhysicalParticleContainer: implemented. // LaserParticleContainer: implemented. // RigidInjectedParticleContainer: not implemented. - virtual void ContinuousInjection(amrex::Real dt, - const amrex::RealBox& prob_domain) {} + virtual void ContinuousInjection(const amrex::RealBox& injection_box) {} + // Update optional sub-class-specific injection location. virtual void UpdateContinuousInjectionPosition(amrex::Real dt) {} /// @@ -264,7 +264,6 @@ protected: // This is currently required because continuous injection does not // support all features allowed by direct injection. int do_continuous_injection = 0; - // int done_injecting = 1; amrex::Vector<amrex::FArrayBox> local_rho; amrex::Vector<amrex::FArrayBox> local_jx; diff --git a/Source/Utils/WarpXMovingWindow.cpp b/Source/Utils/WarpXMovingWindow.cpp index 2ba1d2f59..38bde5e92 100644 --- a/Source/Utils/WarpXMovingWindow.cpp +++ b/Source/Utils/WarpXMovingWindow.cpp @@ -34,9 +34,16 @@ WarpX::MoveWindow (bool move_j) moving_window_x += moving_window_v * dt[0]; int dir = moving_window_dir; + // Update warpx.current_injection_position + // PhysicalParticleContainer uses this injection position UpdatePlasmaInjectionPosition( dt[0] ); - mypc->UpdateContinuousInjectionPosition( dt[0] ); - + if (WarpX::do_plasma_injection){ + // Update injection position for WarpXParticleContainer in mypc. + // Nothing to do for PhysicalParticleContainers + // For LaserParticleContainer, need to update the antenna position. + mypc->UpdateContinuousInjectionPosition( dt[0] ); + } + // compute the number of cells to shift on the base level Real new_lo[AMREX_SPACEDIM]; Real new_hi[AMREX_SPACEDIM]; @@ -164,21 +171,11 @@ WarpX::MoveWindow (bool move_j) particleBox.setLo( dir, new_injection_position ); particleBox.setHi( dir, current_injection_position ); } - // Perform the injection of new particles in particleBox - // Performs continuous injection of all WarpXParticleContainer - // in mypc. - + if (particleBox.ok() and (current_injection_position != new_injection_position)){ - mypc->ContinuousInjection(dt[0], particleBox); - /* - for (int i = 0; i < num_injected_species; ++i) { - int ispecies = injected_plasma_species[i]; - WarpXParticleContainer& pc = mypc->GetParticleContainer(ispecies); - auto& ppc = dynamic_cast<PhysicalParticleContainer&>(pc); - ppc.AddPlasma(lev, particleBox); - } - */ - // Update the injection position + // Performs continuous injection of all WarpXParticleContainer + // in mypc. + mypc->ContinuousInjection(particleBox); current_injection_position = new_injection_position; } } diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index 645e92161..bea91f1ba 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -146,18 +146,6 @@ WarpX::WarpX () // Particle Container mypc = std::unique_ptr<MultiParticleContainer> (new MultiParticleContainer(this)); - /* - if (do_plasma_injection) { - for (int i = 0; i < num_injected_species; ++i) { - int ispecies = injected_plasma_species[i]; - WarpXParticleContainer& pc = mypc->GetParticleContainer(ispecies); - auto& ppc = dynamic_cast<PhysicalParticleContainer&>(pc); - // ppc.injected = true; - ppc.do_continuous_injection = 1; - } - } - */ - Efield_aux.resize(nlevs_max); Bfield_aux.resize(nlevs_max); |