19
19
*/
20
20
21
21
22
-
23
- #ifndef LASERPLANEWAVE_HPP
24
- #define LASERPLANEWAVE_HPP
22
+ #pragma once
25
23
26
24
#include " types.h"
27
25
#include " simulation_defines.hpp"
@@ -30,13 +28,38 @@ namespace picongpu
30
28
{
31
29
/* * plane wave (use periodic boundaries!)
32
30
*
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)
34
55
*/
35
56
namespace laserPlaneWave
36
57
{
37
-
38
- /* * Compute the
58
+ /* * calculates longitudinal field distribution
39
59
*
60
+ * @param currentStep
61
+ * @param phase
62
+ * @return
40
63
*/
41
64
HINLINE float3_X laserLongitudinal ( uint32_t currentStep, float_X& phase )
42
65
{
@@ -46,48 +69,50 @@ namespace picongpu
46
69
double envelope = double (AMPLITUDE );
47
70
float3_X elong (float3_X::create (0.0 ));
48
71
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.
53
72
const double mue = 0.5 * RAMP_INIT * PULSE_LENGTH;
54
73
55
74
const double w = 2.0 * PI * f;
75
+ const double tau = PULSE_LENGTH / sqrt ( 2.0 );
56
76
57
77
const double endUpramp = mue;
58
78
const double startDownramp = mue + LASER_NOFOCUS_CONSTANT;
59
79
60
-
80
+ double integrationCorrectionFactor = 0.0 ;
61
81
62
82
if ( runTime > startDownramp )
63
83
{
64
84
// downramp = end
65
- const double exponent =
66
- ( ( runTime - startDownramp )
67
- / PULSE_LENGTH / sqrt ( 2.0 ) );
85
+ const double exponent = (runTime - startDownramp) / tau;
68
86
envelope *= exp ( -0.5 * exponent * exponent );
87
+ integrationCorrectionFactor = ( runTime - startDownramp )/ (w*tau*tau);
69
88
}
70
89
else if ( runTime < endUpramp )
71
90
{
72
91
// upramp = start
73
- const double exponent = ( ( runTime - endUpramp ) / PULSE_LENGTH / sqrt ( 2.0 ) ) ;
92
+ const double exponent = (runTime - endUpramp) / tau ;
74
93
envelope *= exp ( -0.5 * exponent * exponent );
75
-
94
+ integrationCorrectionFactor = ( runTime - endUpramp )/ (w*tau*tau);
76
95
}
77
96
78
97
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
79
100
if ( Polarisation == LINEAR_X )
80
101
{
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));
82
104
}
83
105
else if ( Polarisation == LINEAR_Z)
84
106
{
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));
86
109
}
87
110
else if ( Polarisation == CIRCULAR )
88
111
{
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));
91
116
}
92
117
93
118
@@ -96,7 +121,7 @@ namespace picongpu
96
121
return elong;
97
122
}
98
123
99
- /* *
124
+ /* * calculates transverse field distribution
100
125
*
101
126
* @param elong
102
127
* @param phase
@@ -112,7 +137,3 @@ namespace picongpu
112
137
}
113
138
}
114
139
115
- #endif /* LASERPLANEWAVE_HPP */
116
-
117
-
118
-
0 commit comments