@@ -18,9 +18,12 @@ struct elem
18
18
double PhaseLag ;
19
19
double SigPhi ;
20
20
double SigVV ;
21
+ long HarmNumber ;
21
22
};
22
23
23
- static void track_cavity (double * r_in , double nvx , double nvy , double k , double phi )
24
+ typedef void (* kickfun )(double * r_in , double nvx , double nvy , double k , double betgam0 , double phi );
25
+
26
+ static void relativistic_kick (double * r_in , double nvx , double nvy , double k , double betgam0 , double phi )
24
27
{
25
28
double omega_t = k * r_in [5 ] + phi ;
26
29
double cos_ot = cos (omega_t );
@@ -32,38 +35,53 @@ static void track_cavity(double *r_in, double nvx, double nvy, double k, double
32
35
r_in [4 ] += ddpp ;
33
36
}
34
37
35
- static void CrabCavityPass (double * r_in , double le , double nvx , double nvy ,
36
- double freq , double phi , double sigphi , double sigvv , pcg32_random_t * rng , int num_particles )
38
+ static void non_relativistic_kick (double * r_in , double nvx , double nvy , double k , double betgam0 , double phi )
37
39
{
38
- double k = TWOPI * freq /C0 ;
40
+ double betgami = betgam0 * (1.0 + r_in [4 ]);
41
+ double betai = betgami /sqrt (1.0 + betgami * betgami );
42
+ double omega_t = k * r_in [5 ]/betai + phi ;
43
+ double cos_ot = cos (omega_t );
44
+ double sin_ot = sin (omega_t );
45
+ double ddpp = - (nvy * r_in [2 ]+ nvx * r_in [0 ])* k * cos_ot /(1.0 + r_in [4 ]);
39
46
40
- if (sigphi > 0.0 )
41
- phi += atrandn_r (rng , 0.0 , sigphi );
42
- if (sigvv > 0.0 ) {
43
- nvx *= atrandn_r (rng , 1.0 , sigvv );
44
- nvy *= atrandn_r (rng , 1.0 , sigvv );
45
- }
47
+ r_in [1 ] += nvx * sin_ot ;
48
+ r_in [3 ] += nvy * sin_ot ;
49
+ r_in [4 ] += ddpp ;
50
+ }
51
+
52
+ static void CrabCavityPass (
53
+ double * r_in ,
54
+ double le ,
55
+ double nvx ,
56
+ double nvy ,
57
+ double freq ,
58
+ double betgam0 ,
59
+ double phiref ,
60
+ int num_particles )
61
+ {
62
+ double k = TWOPI * freq /C0 ;
63
+ kickfun ff = isfinite (betgam0 ) ? & non_relativistic_kick : & relativistic_kick ;
46
64
47
65
if (le == 0 ) {
48
66
#pragma omp parallel for if (num_particles > OMP_PARTICLE_THRESHOLD) \
49
- default(none) shared(r_in, num_particles, nvx, nvy, k, phi )
67
+ default(none) shared(r_in, num_particles, nvx, nvy, k, phiref )
50
68
for (int c = 0 ; c < num_particles ; c ++ ) {
51
69
double * r6 = r_in + c * 6 ;
52
70
if (!atIsNaN (r6 [0 ])) {
53
- track_cavity (r6 , nvx , nvy , k , phi );
71
+ ff (r6 , nvx , nvy , k , betgam0 , phiref );
54
72
}
55
73
}
56
74
}
57
75
else {
58
76
double halflength = le /2.0 ;
59
77
60
78
#pragma omp parallel for if (num_particles > OMP_PARTICLE_THRESHOLD) \
61
- default(none) shared(r_in, num_particles, nvx, nvy, k, phi , halflength)
79
+ default(none) shared(r_in, num_particles, nvx, nvy, k, phiref , halflength)
62
80
for (int c = 0 ; c < num_particles ; c ++ ) {
63
81
double * r6 = r_in + c * 6 ;
64
82
if (!atIsNaN (r6 [0 ])) {
65
83
drift6 (r6 , halflength );
66
- track_cavity (r6 , nvx , nvy , k , phi );
84
+ ff (r6 , nvx , nvy , k , betgam0 , phiref );
67
85
drift6 (r6 , halflength );
68
86
}
69
87
}
@@ -75,18 +93,21 @@ static void CrabCavityPass(double *r_in, double le, double nvx, double nvy,
75
93
ExportMode struct elem * trackFunction (const atElem * ElemData ,struct elem * Elem ,
76
94
double * r_in , int num_particles , struct parameters * Param )
77
95
{
78
- double energy ;
79
- double lag , t0f , phiref ;
96
+ double energy , beta0 , gamma0 , betgam0 ;
97
+ double t0f , lag , phiref , nvx , nvy ;
98
+ long HarmNumber ;
99
+ double SigPhi , SigVV ;
80
100
81
101
if (!Elem ) {
82
- double Length , * Voltages , Energy , Frequency , TimeLag , PhaseLag , SigPhi , SigVV ;
102
+ double Length , * Voltages , Energy , Frequency , TimeLag , PhaseLag ;
83
103
Length = atGetDouble (ElemData ,"Length" ); check_error ();
84
104
Voltages = atGetDoubleArray (ElemData ,"Voltages" ); check_error ();
85
105
Frequency = atGetDouble (ElemData ,"Frequency" ); check_error ();
86
106
/* Optional fields */
87
107
Energy = atGetOptionalDouble (ElemData ,"Energy" ,Param -> energy ); check_error ();
88
108
TimeLag = atGetOptionalDouble (ElemData ,"TimeLag" ,0.0 ); check_error ();
89
109
PhaseLag = atGetOptionalDouble (ElemData ,"PhaseLag" ,0.0 ); check_error ();
110
+ HarmNumber = atGetOptionalLong (ElemData ,"HarmNumber" , lround (Frequency * Param -> T0 )); check_error ();
90
111
SigPhi = atGetOptionalDouble (ElemData ,"SigPhi" ,0.0 ); check_error ();
91
112
SigVV = atGetOptionalDouble (ElemData ,"SigVV" ,0.0 ); check_error ();
92
113
@@ -101,12 +122,35 @@ ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
101
122
Elem -> SigPhi = SigPhi ;
102
123
Elem -> SigVV = SigVV ;
103
124
}
125
+ else {
126
+ SigPhi = Elem -> SigPhi ;
127
+ SigVV = Elem -> SigVV ;
128
+ }
104
129
energy = atEnergy (Param -> energy , Elem -> Energy );
130
+ gamma0 = energy /Param -> rest_energy ;
131
+
132
+ if (isfinite (gamma0 )) {
133
+ betgam0 = sqrt (gamma0 * gamma0 - 1.0 );
134
+ beta0 = betgam0 / gamma0 ;
135
+ }
136
+ else {
137
+ betgam0 = gamma0 ;
138
+ beta0 = 1.0 ;
139
+ }
105
140
t0f = Elem -> Frequency * Param -> T0 ;
106
- lag = TWOPI * Elem -> Frequency * Elem -> TimeLag /C0 + Elem -> PhaseLag ;
107
- phiref = TWOPI * (t0f - round (t0f )) * Param -> nturn - lag ;
108
- CrabCavityPass (r_in , Elem -> Length , Elem -> Vx /energy , Elem -> Vy /energy ,
109
- Elem -> Frequency , phiref , Elem -> SigPhi , Elem -> SigVV , Param -> common_rng , num_particles );
141
+ lag = TWOPI * Elem -> Frequency * Elem -> TimeLag /beta0 /C0 + Elem -> PhaseLag ;
142
+ phiref = TWOPI * (t0f - Elem -> HarmNumber ) * Param -> nturn - lag ;
143
+ nvx = Elem -> Vx /energy /beta0 /beta0 ;
144
+ nvy = Elem -> Vy /energy /beta0 /beta0 ;
145
+
146
+ if (SigPhi > 0.0 )
147
+ phiref += atrandn_r (Param -> common_rng , 0.0 , SigPhi );
148
+ if (SigVV > 0.0 ) {
149
+ nvx *= atrandn_r (Param -> common_rng , 1.0 , SigVV );
150
+ nvy *= atrandn_r (Param -> common_rng , 1.0 , SigVV );
151
+ }
152
+
153
+ CrabCavityPass (r_in , Elem -> Length , nvx , nvy , Elem -> Frequency , betgam0 , phiref , num_particles );
110
154
return Elem ;
111
155
}
112
156
@@ -118,6 +162,7 @@ MODULE_DEF(CrabCavityPass) /* Dummy module initialisation */
118
162
void mexFunction (int nlhs , mxArray * plhs [], int nrhs , const mxArray * prhs [])
119
163
{
120
164
if (nrhs >= 2 ) {
165
+ double betgam0 , beta0 , gamma0 ;
121
166
double lag , phiref ;
122
167
double * r_in ;
123
168
double rest_energy = 0.0 ;
@@ -131,18 +176,26 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
131
176
double Energy = atGetOptionalDouble (ElemData ,"Energy" ,0.0 ); check_error ();
132
177
double TimeLag = atGetOptionalDouble (ElemData ,"TimeLag" ,0.0 ); check_error ();
133
178
double PhaseLag = atGetOptionalDouble (ElemData ,"PhaseLag" ,0.0 ); check_error ();
134
- double SigPhi = atGetOptionalDouble (ElemData ,"SigPhi" ,0.0 ); check_error ();
135
- double SigVV = atGetOptionalDouble (ElemData ,"SigVV" ,0.0 ); check_error ();
136
179
if (nrhs > 2 ) atProperties (prhs [2 ], & Energy , & rest_energy , & charge );
180
+ gamma0 = Energy /rest_energy ;
137
181
138
182
if (mxGetM (prhs [1 ]) != 6 ) mexErrMsgIdAndTxt ("AT:WrongArg" ,"Second argument must be a 6 x N matrix" );
139
183
/* ALLOCATE memory for the output array of the same size as the input */
140
184
plhs [0 ] = mxDuplicateArray (prhs [1 ]);
141
185
r_in = mxGetDoubles (plhs [0 ]);
142
- lag = TWOPI * Frequency * TimeLag /C0 + PhaseLag ;
186
+ if (isfinite (gamma0 )) {
187
+ betgam0 = sqrt (gamma0 * gamma0 - 1.0 );
188
+ beta0 = betgam0 / gamma0 ;
189
+ }
190
+ else {
191
+ betgam0 = gamma0 ;
192
+ beta0 = 1.0 ;
193
+ }
194
+ lag = TWOPI * Frequency * TimeLag /beta0 /C0 + PhaseLag ;
143
195
phiref = - lag ;
144
- CrabCavityPass (r_in , Length , Voltages [0 ]/Energy , Voltages [1 ]/Energy ,
145
- Frequency , phiref , SigPhi , SigVV , & pcg32_global , num_particles );
196
+ normvx = Voltages [0 ] / Energy / beta0 / beta0 ;
197
+ normvy = Voltages [1 ] / Energy / beta0 / beta0 ;
198
+ CrabCavityPass (r_in , Length , normvx , normvy , Frequency , betgam0 , phiref , num_particles );
146
199
}
147
200
else if (nrhs == 0 ) {
148
201
plhs [0 ] = mxCreateCellMatrix (3 ,1 );
0 commit comments