/* Copyright 2019 Andrew Myers, Axel Huebl, David Grote * Luca Fedeli, Maxence Thevenet, Remi Lehe * Weiqun Zhang * * This file is part of WarpX. * * License: BSD-3-Clause-LBNL */ #ifndef WARPX_LaserParticleContainer_H_ #define WARPX_LaserParticleContainer_H_ #include "Evolve/WarpXDtType.H" #include "Laser/LaserProfiles.H" #include "WarpXParticleContainer.H" #include #include #include #include #include #include #include #include #include #include /** * The main method to inject a laser pulse in WarpX is to use an artificial * antenna: particles evenly distributed in a given plane (one particle per * cell) move at each iteration and deposit a current J onto the grid, which * in turns creates an electromagnetic field on the grid. The particles' * displacements are prescribed to create the field requested by the user. * * These artificial particles are contained in the LaserParticleContainer. * LaserParticleContainer derives directly from WarpXParticleContainer. It * requires a DepositCurrent function, but no FieldGather function. */ class LaserParticleContainer : public WarpXParticleContainer { public: LaserParticleContainer (amrex::AmrCore* amr_core, int ispecies, const std::string& name); virtual ~LaserParticleContainer () {} virtual void InitData () final; /** * \brief Method to initialize runtime attributes. Does nothing for LaserParticleContainer. */ virtual void DefaultInitializeRuntimeAttributes ( amrex::ParticleTile& /*pinned_tile*/, const int /*n_external_attr_real*/, const int /*n_external_attr_int*/, const amrex::RandomEngine& /*engine*/) override final {} virtual void ReadHeader (std::istream& is) final; virtual void WriteHeader (std::ostream& os) const final; virtual void Evolve (int lev, const amrex::MultiFab&, const amrex::MultiFab&, const amrex::MultiFab&, const amrex::MultiFab&, const amrex::MultiFab&, const amrex::MultiFab&, amrex::MultiFab& jx, amrex::MultiFab& jy, amrex::MultiFab& jz, amrex::MultiFab*, amrex::MultiFab*, amrex::MultiFab*, amrex::MultiFab* rho, amrex::MultiFab* crho, const amrex::MultiFab*, const amrex::MultiFab*, const amrex::MultiFab*, const amrex::MultiFab*, const amrex::MultiFab*, const amrex::MultiFab*, amrex::Real t, amrex::Real dt, DtType a_dt_type=DtType::Full, bool skip_deposition=false) final; virtual void PushP (int lev, amrex::Real dt, const amrex::MultiFab& , const amrex::MultiFab& , const amrex::MultiFab& , const amrex::MultiFab& , const amrex::MultiFab& , const amrex::MultiFab& ) final; virtual void PostRestart () final; void calculate_laser_plane_coordinates (const WarpXParIter& pti, const int np, amrex::Real * AMREX_RESTRICT const pplane_Xp, amrex::Real * AMREX_RESTRICT const pplane_Yp); void update_laser_particle (WarpXParIter& pti, const int np, amrex::ParticleReal * AMREX_RESTRICT const puxp, amrex::ParticleReal * AMREX_RESTRICT const puyp, amrex::ParticleReal * AMREX_RESTRICT const puzp, amrex::ParticleReal const * AMREX_RESTRICT const pwp, amrex::Real const * AMREX_RESTRICT const amplitude, const amrex::Real dt); protected: std::string m_laser_name; private: // runtime paramters amrex::Vector m_position; //! Coordinates of one of the point of the antenna amrex::Vector m_nvec; //! Normal of the plane of the antenna amrex::Vector m_p_X;// ! Polarization amrex::Real m_e_max = std::numeric_limits::quiet_NaN(); amrex::Real m_wavelength = std::numeric_limits::quiet_NaN(); amrex::Real m_Z0_lab = 0; // Position of the antenna in the lab frame long m_min_particles_per_mode = 4; // computed using runtime parameters amrex::Vector m_p_Y; amrex::Vector m_u_X; amrex::Vector m_u_Y; amrex::Real m_weight = std::numeric_limits::quiet_NaN(); amrex::Real m_mobility = std::numeric_limits::quiet_NaN(); // laser particle domain amrex::RealBox m_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::Vector m_updated_position; void ComputeSpacing (int lev, amrex::Real& Sx, amrex::Real& Sy) const; void ComputeWeightMobility (amrex::Real Sx, amrex::Real Sy); void InitData (int lev); // Inject the laser antenna during the simulation, if it started // outside of the simulation domain and enters it. void ContinuousInjection(const amrex::RealBox& injection_box) override; // Update position of the antenna void UpdateContinuousInjectionPosition(amrex::Real dt) override; // Unique (smart) pointer to the laser profile std::unique_ptr m_up_laser_profile; // Flag to disable the laser (e.g., if e_max is 0) bool m_enabled = true; }; #endif