1919 */
2020
2121
22-
23- #ifndef LASERPLANEWAVE_HPP
24- #define LASERPLANEWAVE_HPP
22+ #pragma once
2523
2624#include " types.h"
2725#include " simulation_defines.hpp"
@@ -30,13 +28,38 @@ namespace picongpu
3028{
3129 /* * plane wave (use periodic boundaries!)
3230 *
33- * no phase shifts, no spacial envelope
31+ * no transverse spacial envelope
32+ * based on the electric potential
33+ * Phi = Phi_0 * exp(0.5 * (x-x_0)^2 / sigma^2) * cos(k*(x - x_0) - phi)
34+ * by applying -grad Phi = -d/dx Phi = E(x)
35+ * we get:
36+ * E = -Phi_0 * exp(0.5 * (x-x_0)^2 / sigma^2) * [k*sin(k*(x - x_0) - phi) + x/sigma^2 * cos(k*(x - x_0) - phi)]
37+ *
38+ * This approach ensures that int_{-infinity}^{+infinity} E(x) = 0 for any phase
39+ * if we have no transverse profile as we have with this plane wave train
40+ *
41+ * Since PIConGPU requires a temporally defined electric field, we use:
42+ * t = x/c and (x-x_0)/sigma = (t-t_0)/tau and k*(x-x_0) = omega*(t-t_0) with omega/k = c and tau * c = sigma
43+ * and get:
44+ * E = -Phi_0*omega/c * exp(0.5 * (t-t_0)^2 / tau^2) * [sin(omega*(t - t_0) - phi) + t/(omega*tau^2) * cos(omega*(t - t_0) - phi)]
45+ * and define:
46+ * E_0 = -Phi_0*omega/c
47+ * integrationCorrectionFactor = t/(omega*tau^2)
48+ *
49+ * Please consider:
50+ * 1) The above formulae does only apply to a Gaussian envelope. If the plateau length is
51+ * not zero, the integral over the volume will only vanish if the plateau length is
52+ * a multiple of the wavelength.
53+ * 2) Since we define our envelope by a sigma of the laser intensity,
54+ * tau = PULSE_LENGTH / sqrt(2)
3455 */
3556 namespace laserPlaneWave
3657 {
37-
38- /* * Compute the
58+ /* * calculates longitudinal field distribution
3959 *
60+ * @param currentStep
61+ * @param phase
62+ * @return
4063 */
4164 HINLINE float3_X laserLongitudinal ( uint32_t currentStep, float_X& phase )
4265 {
@@ -46,48 +69,50 @@ namespace picongpu
4669 double envelope = double (AMPLITUDE );
4770 float3_X elong (float3_X::create (0.0 ));
4871
49- // a NON-symmetric (starting with phase=0) pulse will be initialized at position z=0 for
50- // a time of RAMP_INIT * PULSE_LENGTH + LASER_NOFOCUS_CONSTANT = INIT_TIME.
51- // we shift the complete pulse for the half of this time to start with
52- // the front of the laser pulse.
5372 const double mue = 0.5 * RAMP_INIT * PULSE_LENGTH;
5473
5574 const double w = 2.0 * PI * f;
75+ const double tau = PULSE_LENGTH / sqrt ( 2.0 );
5676
5777 const double endUpramp = mue;
5878 const double startDownramp = mue + LASER_NOFOCUS_CONSTANT;
5979
60-
80+ double integrationCorrectionFactor = 0.0 ;
6181
6282 if ( runTime > startDownramp )
6383 {
6484 // downramp = end
65- const double exponent =
66- ( ( runTime - startDownramp )
67- / PULSE_LENGTH / sqrt ( 2.0 ) );
85+ const double exponent = (runTime - startDownramp) / tau;
6886 envelope *= exp ( -0.5 * exponent * exponent );
87+ integrationCorrectionFactor = ( runTime - startDownramp )/ (w*tau*tau);
6988 }
7089 else if ( runTime < endUpramp )
7190 {
7291 // upramp = start
73- const double exponent = ( ( runTime - endUpramp ) / PULSE_LENGTH / sqrt ( 2.0 ) ) ;
92+ const double exponent = (runTime - endUpramp) / tau ;
7493 envelope *= exp ( -0.5 * exponent * exponent );
75-
94+ integrationCorrectionFactor = ( runTime - endUpramp )/ (w*tau*tau);
7695 }
7796
7897 const double timeOszi = runTime - endUpramp;
98+ const double t_and_phase = w * timeOszi + LASER_PHASE;
99+ // to understand both components [sin(...) + t/tau^2 * cos(...)] see description above
79100 if ( Polarisation == LINEAR_X )
80101 {
81- elong.x () = float_X ( envelope * math::sin ( w * timeOszi + LASER_PHASE));
102+ elong.x () = float_X ( envelope * (math::sin (t_and_phase)
103+ + math::cos (t_and_phase) * integrationCorrectionFactor));
82104 }
83105 else if ( Polarisation == LINEAR_Z)
84106 {
85- elong.z () = float_X ( envelope * math::sin ( w * timeOszi + LASER_PHASE));
107+ elong.z () = float_X ( envelope * (math::sin (t_and_phase)
108+ + math::cos (t_and_phase) * integrationCorrectionFactor));
86109 }
87110 else if ( Polarisation == CIRCULAR )
88111 {
89- elong.x () = float_X ( envelope / sqrt (2.0 ) * math::sin ( w * timeOszi + LASER_PHASE));
90- elong.z () = float_X ( envelope / sqrt (2.0 ) * math::cos ( w * timeOszi + LASER_PHASE));
112+ elong.x () = float_X ( envelope / sqrt (2.0 ) * (math::sin (t_and_phase)
113+ + math::cos (t_and_phase) * integrationCorrectionFactor));
114+ elong.z () = float_X ( envelope / sqrt (2.0 ) * (math::cos (t_and_phase)
115+ - math::sin (t_and_phase) * integrationCorrectionFactor));
91116 }
92117
93118
@@ -96,7 +121,7 @@ namespace picongpu
96121 return elong;
97122 }
98123
99- /* *
124+ /* * calculates transverse field distribution
100125 *
101126 * @param elong
102127 * @param phase
@@ -112,7 +137,3 @@ namespace picongpu
112137 }
113138}
114139
115- #endif /* LASERPLANEWAVE_HPP */
116-
117-
118-
0 commit comments