Skip to content

Commit ac8df3b

Browse files
committed
reorganisation
1 parent 99ec260 commit ac8df3b

File tree

1 file changed

+79
-26
lines changed

1 file changed

+79
-26
lines changed

atintegrators/CrabCavityPass.c

+79-26
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ struct elem
1818
double PhaseLag;
1919
double SigPhi;
2020
double SigVV;
21+
long HarmNumber;
2122
};
2223

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)
2427
{
2528
double omega_t = k*r_in[5] + phi;
2629
double cos_ot = cos(omega_t);
@@ -32,38 +35,53 @@ static void track_cavity(double *r_in, double nvx, double nvy, double k, double
3235
r_in[4] += ddpp;
3336
}
3437

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)
3739
{
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]);
3946

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;
4664

4765
if (le == 0) {
4866
#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)
5068
for (int c = 0; c<num_particles; c++) {
5169
double *r6 = r_in + c*6;
5270
if (!atIsNaN(r6[0])) {
53-
track_cavity(r6, nvx, nvy, k, phi);
71+
ff(r6, nvx, nvy, k, betgam0, phiref);
5472
}
5573
}
5674
}
5775
else {
5876
double halflength = le/2.0;
5977

6078
#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)
6280
for (int c = 0; c<num_particles; c++) {
6381
double *r6 = r_in + c*6;
6482
if (!atIsNaN(r6[0])) {
6583
drift6(r6, halflength);
66-
track_cavity(r6, nvx, nvy, k, phi);
84+
ff(r6, nvx, nvy, k, betgam0, phiref);
6785
drift6(r6, halflength);
6886
}
6987
}
@@ -75,18 +93,21 @@ static void CrabCavityPass(double *r_in, double le, double nvx, double nvy,
7593
ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
7694
double *r_in, int num_particles, struct parameters *Param)
7795
{
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;
80100

81101
if (!Elem) {
82-
double Length, *Voltages, Energy, Frequency, TimeLag, PhaseLag, SigPhi, SigVV;
102+
double Length, *Voltages, Energy, Frequency, TimeLag, PhaseLag;
83103
Length = atGetDouble(ElemData,"Length"); check_error();
84104
Voltages = atGetDoubleArray(ElemData,"Voltages"); check_error();
85105
Frequency = atGetDouble(ElemData,"Frequency"); check_error();
86106
/* Optional fields */
87107
Energy = atGetOptionalDouble(ElemData,"Energy",Param->energy); check_error();
88108
TimeLag=atGetOptionalDouble(ElemData,"TimeLag",0.0); check_error();
89109
PhaseLag=atGetOptionalDouble(ElemData,"PhaseLag",0.0); check_error();
110+
HarmNumber=atGetOptionalLong(ElemData,"HarmNumber", lround(Frequency*Param->T0)); check_error();
90111
SigPhi = atGetOptionalDouble(ElemData,"SigPhi",0.0); check_error();
91112
SigVV = atGetOptionalDouble(ElemData,"SigVV",0.0); check_error();
92113

@@ -101,12 +122,35 @@ ExportMode struct elem *trackFunction(const atElem *ElemData,struct elem *Elem,
101122
Elem->SigPhi=SigPhi;
102123
Elem->SigVV=SigVV;
103124
}
125+
else {
126+
SigPhi=Elem->SigPhi;
127+
SigVV=Elem->SigVV;
128+
}
104129
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+
}
105140
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);
110154
return Elem;
111155
}
112156

@@ -118,6 +162,7 @@ MODULE_DEF(CrabCavityPass) /* Dummy module initialisation */
118162
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
119163
{
120164
if (nrhs >= 2) {
165+
double betgam0, beta0, gamma0;
121166
double lag, phiref;
122167
double *r_in;
123168
double rest_energy = 0.0;
@@ -131,18 +176,26 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
131176
double Energy = atGetOptionalDouble(ElemData,"Energy",0.0); check_error();
132177
double TimeLag = atGetOptionalDouble(ElemData,"TimeLag",0.0); check_error();
133178
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();
136179
if (nrhs > 2) atProperties(prhs[2], &Energy, &rest_energy, &charge);
180+
gamma0 = Energy/rest_energy;
137181

138182
if (mxGetM(prhs[1]) != 6) mexErrMsgIdAndTxt("AT:WrongArg","Second argument must be a 6 x N matrix");
139183
/* ALLOCATE memory for the output array of the same size as the input */
140184
plhs[0] = mxDuplicateArray(prhs[1]);
141185
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;
143195
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);
146199
}
147200
else if (nrhs == 0) {
148201
plhs[0] = mxCreateCellMatrix(3,1);

0 commit comments

Comments
 (0)