diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index 9bd1d99ce2..279939291f 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -809,9 +809,6 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start The names of the laser pulses, separated by a space. To run without a laser, choose the name ``no_laser``. -* ``lasers.lambda0`` (`float`) - Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. - * ``lasers.use_phase`` (`bool`) optional (default `true`) Whether the phase terms (:math:`\theta` in Eq. (6) of [C. Benedetti et al. Plasma Phys. Control. Fusion 60.1: 014002 (2017)]) are computed and used in the laser envelope advance. Keeping the phase should be more accurate, but can cause numerical issues in the presence of strong depletion/frequency shift. @@ -837,22 +834,23 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start * ``lasers.MG_average_rhs`` (`0` or `1`) optional (default `1`) Whether to use the most stable discretization for the envelope solver. -* ``lasers.input_file`` (`string`) optional (default `""`) - Path to an openPMD file containing a laser envelope. - The file should comply with the `LaserEnvelope extension of the openPMD-standard `__, as generated by `LASY `__. - Currently supported geometries: 3D or cylindrical profiles with azimuthal decomposition. - The laser pulse is injected in the HiPACE++ simulation so that the beginning of the temporal profile from the file corresponds to the head of the simulation box, and time (in the file) is converted to space (HiPACE++ longitudinal coordinate) with ``z = -c*t + const``. - If this parameter is set, then the file is used to initialize all lasers instead of using a gaussian profile. +* ``.init_type`` (list of `string`) optional (default `gaussian`) + The initializing method of laser. Possible options are: -* ``lasers.openPMD_laser_name`` (`string`) optional (default `laserEnvelope`) - Name of the laser envelope field inside the openPMD file to be read in. + * ``gaussian``(default) the laser is iniliatized with an ideal gaussian pulse. -* ``lasers.iteration`` (`int`) optional (default `0`) - Iteration of the openPMD file to be read in. + * ``from_file``, the laser is loaded from an openPMD file. + + * ``parser``, the laser is initialized with the expression of the complex envelope function. + +Option: ``gaussian`` * ``.a0`` (`float`) optional (default `0`) Peak normalized vector potential of the laser pulse. +* ``lasers.lambda0`` (`float`) + Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. + * ``.position_mean`` (3 `float`) optional (default `0 0 0`) The mean position of the laser in `x, y, z`. @@ -876,6 +874,32 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start Pulse front tilt angle on yz plane - the angle between the pulse front (maximum intensity contour)and the propagation direction defined by [Selcuk Akturk Opt. Express 12 (2004)](pi/2 is no PFT) +Option: ``from_file`` + +* ``lasers.input_file`` (`string`) optional (default `""`) + Path to an openPMD file containing a laser envelope. + The file should comply with the `LaserEnvelope extension of the openPMD-standard `__, as generated by `LASY `__. + Currently supported geometries: 3D or cylindrical profiles with azimuthal decomposition. + The laser pulse is injected in the HiPACE++ simulation so that the beginning of the temporal profile from the file corresponds to the head of the simulation box, and time (in the file) is converted to space (HiPACE++ longitudinal coordinate) with ``z = -c*t + const``. + If this parameter is set, then the file is used to initialize all lasers instead of using a gaussian profile. + +* ``lasers.openPMD_laser_name`` (`string`) optional (default `laserEnvelope`) + Name of the laser envelope field inside the openPMD file to be read in. + +* ``lasers.iteration`` (`int`) optional (default `0`) + Iteration of the openPMD file to be read in. + +Option: ``parser`` + +* ``.laser_real(x,y,z)`` (`string`) + Expression for the real part of the laser evelope in `x, y, z`. + +* ``.laser_imag(x,y,z)`` (`string`) + Expression for the imaginary part of the laser evelope `x, y, z`. + +* ``lasers.lambda0`` (`float`) + Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. + Diagnostic parameters --------------------- diff --git a/src/laser/Laser.H b/src/laser/Laser.H index 6a81aac7b4..cd4db39466 100644 --- a/src/laser/Laser.H +++ b/src/laser/Laser.H @@ -13,6 +13,7 @@ #include #include #include "utils/Constants.H" +#include "utils/Parser.H" class Laser { @@ -21,6 +22,8 @@ public: Laser (std::string name, bool laser_from_file); std::string m_name {""}; + /** The way to initialize a laser (from_file/gaussian/parser)*/ + std::string m_laser_init_type = "gaussian"; amrex::Real m_a0 {0.}; /**< Laser peak normalized amplitude */ amrex::Real m_w0 {0.}; /**< Laser waist */ amrex::Real m_CEP {0.}; /**< Laser carrier-envelope phase (CEP) */ @@ -34,6 +37,13 @@ public: amrex::Real m_focal_distance {0.}; /** Average position of the Gaussian laser pulse */ amrex::RealVect m_position_mean {0., 0., 0.}; + /** Custom profile*/ + amrex::Parser m_parser_lr;/**< owns data for profile_real_str */ + amrex::Parser m_parser_li;/**< owns data for profile_imag_str */ + /** stores the output function of makeFunctionWithParser for profile_real_str */ + amrex::ParserExecutor<3> m_profile_real; + /** stores the output function of makeFunctionWithParser for profile_imag_str */ + amrex::ParserExecutor<3> m_profile_imag; }; #endif // LASER_H_ diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp index 8a26e4e055..acee4a4316 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -17,19 +17,31 @@ Laser::Laser (std::string name, bool laser_from_file) { m_name = name; - if (laser_from_file) return; amrex::ParmParse pp(m_name); - queryWithParser(pp, "a0", m_a0); - queryWithParser(pp, "w0", m_w0); - queryWithParser(pp, "CEP", m_CEP); - queryWithParser(pp, "propagation_angle_yz", m_propagation_angle_yz); - queryWithParser(pp, "PFT_yz", m_PFT_yz); - bool length_is_specified = queryWithParser(pp, "L0", m_L0); - bool duration_is_specified = queryWithParser(pp, "tau", m_tau); - AMREX_ALWAYS_ASSERT_WITH_MESSAGE( length_is_specified + duration_is_specified == 1, + queryWithParser(pp, "init_type", m_laser_init_type); + if (m_laser_init_type == "from_file") return; + else if (m_laser_init_type == "gaussian"){ + queryWithParser(pp, "a0", m_a0); + queryWithParser(pp, "w0", m_w0); + queryWithParser(pp, "CEP", m_CEP); + queryWithParser(pp, "propagation_angle_yz", m_propagation_angle_yz); + queryWithParser(pp, "PFT_yz", m_PFT_yz); + bool length_is_specified = queryWithParser(pp, "L0", m_L0); + bool duration_is_specified = queryWithParser(pp, "tau", m_tau); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( length_is_specified + duration_is_specified == 1, "Please specify exlusively either the pulse length L0 or the duration tau of the laser"); - if (duration_is_specified) m_L0 = m_tau*get_phys_const().c; - queryWithParser(pp, "focal_distance", m_focal_distance); - - queryWithParser(pp, "position_mean", m_position_mean); + if (duration_is_specified) m_L0 = m_tau*get_phys_const().c; + queryWithParser(pp, "focal_distance", m_focal_distance); + queryWithParser(pp, "position_mean", m_position_mean); + return; + } + else if (m_laser_init_type == "parser"){ + std::string profile_real_str = ""; + std::string profile_imag_str = ""; + getWithParser(pp, "laser_real(x,y,z)", profile_real_str); + getWithParser(pp, "laser_imag(x,y,z)", profile_imag_str); + m_profile_real = makeFunctionWithParser<3>( profile_real_str, m_parser_lr, {"x", "y", "z"}); + m_profile_imag = makeFunctionWithParser<3>( profile_imag_str, m_parser_li, {"x", "y", "z"}); + return; + } } diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index ac84172959..5e5cb79d30 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -21,7 +21,6 @@ #ifdef HIPACE_USE_OPENPMD # include #endif - #include void @@ -1139,19 +1138,40 @@ MultiLaser::InitLaserSlice (const int islice, const int comp) const amrex::Box& bx = mfi.tilebox(); amrex::Array4 const & arr = m_slices.array(mfi); // Initialize a Gaussian laser envelope on slice islice - for (int ilaser=0; ilaser