aboutsummaryrefslogtreecommitdiff
path: root/Source/Laser/LaserProfilesImpl/LaserProfileHarris.cpp
blob: 6ea8070dbd9b74df134d762bd974929a2bf976fe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* Copyright 2019 Luca Fedeli
 *
 * This file is part of WarpX.
 *
 * License: BSD-3-Clause-LBNL
 */
#include "Laser/LaserProfiles.H"

#include "Utils/WarpXConst.H"
#include "Utils/WarpXUtil.H"
#include "Utils/WarpX_Complex.H"

#include <AMReX_Extension.H>
#include <AMReX_GpuLaunch.H>
#include <AMReX_GpuQualifiers.H>
#include <AMReX_REAL.H>

#include <cmath>

using namespace amrex;

void
WarpXLaserProfiles::HarrisLaserProfile::init (
    const amrex::ParmParse& ppl,
    const amrex::ParmParse& /* ppc */,
    CommonLaserParameters params)
{
    // Parse the properties of the Harris profile
    getWithParser(ppl, "profile_waist", m_params.waist);
    getWithParser(ppl, "profile_duration", m_params.duration);
    getWithParser(ppl, "profile_focal_distance", m_params.focal_distance);
    //Copy common params
    m_common_params = params;
}

/* \brief compute field amplitude for a Harris laser function, at particles' position
 *
 * Both Xp and Yp are given in laser plane coordinate.
 * For each particle with position Xp and Yp, this routine computes the
 * amplitude of the laser electric field, stored in array amplitude.
 *
 * \param np: number of laser particles
 * \param Xp: pointer to first component of positions of laser particles
 * \param Yp: pointer to second component of positions of laser particles
 * \param t: Current physical time
 * \param amplitude: pointer to array of field amplitude.
 */
void
WarpXLaserProfiles::HarrisLaserProfile::fill_amplitude (
    const int np, Real const * AMREX_RESTRICT const Xp, Real const * AMREX_RESTRICT const Yp,
    Real t, Real * AMREX_RESTRICT const amplitude) const
{
    // This function uses the Harris function as the temporal profile of the pulse
    const Real omega0 =
        2._rt*MathConst::pi*PhysConst::c/m_common_params.wavelength;
    const Real zR = MathConst::pi * m_params.waist*m_params.waist
        / m_common_params.wavelength;
    const Real wz = m_params.waist *
        std::sqrt(1._rt + m_params.focal_distance*m_params.focal_distance/(zR*zR));
    const Real inv_wz_2 = 1._rt/(wz*wz);
    Real inv_Rz;
    if (m_params.focal_distance == 0.){
        inv_Rz = 0.;
    } else {
        inv_Rz = -m_params.focal_distance /
            ( m_params.focal_distance*m_params.focal_distance + zR*zR );
    }
    const Real arg_env = 2._rt*MathConst::pi*t/m_params.duration;

    // time envelope is given by the Harris function
    Real time_envelope = 0.;

    constexpr auto norm = 1._rt/32._rt;
    constexpr auto c_0 = 10._rt;
    constexpr auto c_1 = -15._rt;
    constexpr auto c_2 = 6._rt;
    constexpr auto c_3 = -1._rt;
    constexpr auto a_1 = 1._rt;
    constexpr auto a_2 = 2._rt;
    constexpr auto a_3 = 3._rt;

    if (t < m_params.duration)
        time_envelope =  norm * (c_0 +
                                 c_1*std::cos(a_1*arg_env) +
                                 c_2*std::cos(a_2*arg_env) +
                                 c_3*std::cos(a_3*arg_env));

    // Copy member variables to tmp copies for GPU runs.
    const auto tmp_e_max = m_common_params.e_max;
    // Loop through the macroparticle to calculate the proper amplitude
    amrex::ParallelFor(
        np,
        [=] AMREX_GPU_DEVICE (int i) {
            const Real space_envelope =
                std::exp(- ( Xp[i]*Xp[i] + Yp[i]*Yp[i] ) * inv_wz_2);
            const Real arg_osc = omega0*t - omega0/PhysConst::c*
                (Xp[i]*Xp[i] + Yp[i]*Yp[i]) * inv_Rz / 2._rt;
            const Real oscillations = std::cos(arg_osc);
            amplitude[i] = tmp_e_max * time_envelope *
                space_envelope * oscillations;
        }
        );
}