The meaning of the input parameters on the command "perturbation"
Posted: 09 Jul 2020, 02:27
The elegant code offers the function that can generate random multipole error coefficients with the input parameters
I saw the example PAR/randomMultipoles
There, by using the sddsrandmult code, the multipole coeffecients are calculated.
However, I am confused the meaning of the input parameters such as "dx_pole", "dy_pole", "dradius", "dx_split", "dy_split", and "dphi_halves".
First of all, please let me know the exact definition of input parameters : "dx_pole", "dy_pole", "dradius", "dx_split", "dy_split", and "dphi_halves".
I read the reference paper (K. Halbach, NIM Vol. 74, No. 1, 1969) and the source code of the sddsrandmult.c but the meaning of input parameters are still unclear to me.
N = coefs[iN].N;
crot = cos(PI/2./N);
srot = sin(PI/2./N);
for (i_case=0; i_case<n_cases; i_case++) {
/* calculate the parameters for the halves */
dxh = gauss_rn_lim(0.0, dx_split, 2.0, random_1);
dyh = gauss_rn_lim(0.0, dy_split, 2.0, random_1);
dr = gauss_rn_lim(0.0, dradius, 2.0, random_1);
dphi = gauss_rn_lim(0.0, dphi_halves, 2.0, random_1);
for (i=0; i<n_harm+1; i++)
f = g = 0;
for (m=0; m<2*N; m++) {
/* sum over all poles */
/* -- fractional dx and dy in coordinate system N, for which magnet looks normally oriented */
fdx = gauss_rn_lim(0.0, dx_pole, 2.0, random_1) + (m<N?dxh:-dxh);
fdy = gauss_rn_lim(0.0, dy_pole, 2.0, random_1) + (m<N?dyh:-dyh);
/* -- angle of pole in system S, where magnet has a pole on the x axis */
alpha = (PI/N)*m;
/* -- (fdx, fdy) rotated into system S, with radial errors */
fdX = crot*fdx + srot*fdy + dr*cos(alpha) ;
fdY = -srot*fdx + crot*fdy + dr*sin(alpha) ;
/* -- angle and magnitude of displacement vector in S system */
if (fdX==0 && fdY==0)
gamma = eps = 0;
else {
gamma = atan2(fdY, fdX);
eps = hypot(fdY, fdX);
}
exp1 = cexpi(gamma-alpha);
exp2 = std::conj(exp1);
for (i=1; i<=n_harm; i++) {
/* loop over all harmonics */
dHn = (exp1*(coefs[iN].bm[i-1]-coefs[iN].am[i-1])*eps/2.0 +
exp2*(coefs[iN].bm[i-1]+coefs[iN].am[i-1])*eps/2.0)
*cexpi(-(N+i)*alpha)*cexpi(PI/2-(PI*i)/(2.*N));
f[i-1] += dHn.real();
g[i-1] += dHn.imag();
}
}
/* add rotation error contribution */
if (dphi_halves) {
for (i=1; i<=n_harm; i++) {
/* loop over all harmonics */
if ((i+N)%2 && dphi_halves && coefs[iN].rhom[i-1])
f[i-1] += dphi*coefs[iN].rhom[i-1]/cos(PI*i/(2*N));
}
}
/* find maximum total error for all harmonics greater in harmonic number to the fundamental */
for (i=N; i<n_harm; i++) {
f[n_harm] += fabs(f);
g[n_harm] += fabs(g);
}
/* keep statistics on rms for each harmonic */
for (i=0; i<n_harm; i++) {
frms += sqr(f);
grms += sqr(g);
}
for (i=0; i<n_harm; i++)
fprintf(fpSDDS, "%13.6le ", f*ipow(reference_radius/bore_radius, i));
fprintf(fpSDDS, "%13.6le ", f);
for (i=0; i<n_harm; i++)
fprintf(fpSDDS, "%13.6le ", g[i]*ipow(reference_radius/bore_radius, i));
fprintf(fpSDDS, "%13.6le ", g[i]);
fputc('\n', fpSDDS);
}
I think this part is the key of the code.
In calculating dfX or dfY, why the crot and srot are constant regardless of the pole (m=0,1,2,..)? and on the other hand, why alpha is varied with the pole (m=0,1,2...)?
All contribution of the poles are the summation of each pole's perturbation.
f[i-1] += dHn.real();
g[i-1] += dHn.imag();
This two lines do it? Do I understand the code in the right way?
I saw the example PAR/randomMultipoles
There, by using the sddsrandmult code, the multipole coeffecients are calculated.
However, I am confused the meaning of the input parameters such as "dx_pole", "dy_pole", "dradius", "dx_split", "dy_split", and "dphi_halves".
First of all, please let me know the exact definition of input parameters : "dx_pole", "dy_pole", "dradius", "dx_split", "dy_split", and "dphi_halves".
I read the reference paper (K. Halbach, NIM Vol. 74, No. 1, 1969) and the source code of the sddsrandmult.c but the meaning of input parameters are still unclear to me.
N = coefs[iN].N;
crot = cos(PI/2./N);
srot = sin(PI/2./N);
for (i_case=0; i_case<n_cases; i_case++) {
/* calculate the parameters for the halves */
dxh = gauss_rn_lim(0.0, dx_split, 2.0, random_1);
dyh = gauss_rn_lim(0.0, dy_split, 2.0, random_1);
dr = gauss_rn_lim(0.0, dradius, 2.0, random_1);
dphi = gauss_rn_lim(0.0, dphi_halves, 2.0, random_1);
for (i=0; i<n_harm+1; i++)
f = g = 0;
for (m=0; m<2*N; m++) {
/* sum over all poles */
/* -- fractional dx and dy in coordinate system N, for which magnet looks normally oriented */
fdx = gauss_rn_lim(0.0, dx_pole, 2.0, random_1) + (m<N?dxh:-dxh);
fdy = gauss_rn_lim(0.0, dy_pole, 2.0, random_1) + (m<N?dyh:-dyh);
/* -- angle of pole in system S, where magnet has a pole on the x axis */
alpha = (PI/N)*m;
/* -- (fdx, fdy) rotated into system S, with radial errors */
fdX = crot*fdx + srot*fdy + dr*cos(alpha) ;
fdY = -srot*fdx + crot*fdy + dr*sin(alpha) ;
/* -- angle and magnitude of displacement vector in S system */
if (fdX==0 && fdY==0)
gamma = eps = 0;
else {
gamma = atan2(fdY, fdX);
eps = hypot(fdY, fdX);
}
exp1 = cexpi(gamma-alpha);
exp2 = std::conj(exp1);
for (i=1; i<=n_harm; i++) {
/* loop over all harmonics */
dHn = (exp1*(coefs[iN].bm[i-1]-coefs[iN].am[i-1])*eps/2.0 +
exp2*(coefs[iN].bm[i-1]+coefs[iN].am[i-1])*eps/2.0)
*cexpi(-(N+i)*alpha)*cexpi(PI/2-(PI*i)/(2.*N));
f[i-1] += dHn.real();
g[i-1] += dHn.imag();
}
}
/* add rotation error contribution */
if (dphi_halves) {
for (i=1; i<=n_harm; i++) {
/* loop over all harmonics */
if ((i+N)%2 && dphi_halves && coefs[iN].rhom[i-1])
f[i-1] += dphi*coefs[iN].rhom[i-1]/cos(PI*i/(2*N));
}
}
/* find maximum total error for all harmonics greater in harmonic number to the fundamental */
for (i=N; i<n_harm; i++) {
f[n_harm] += fabs(f);
g[n_harm] += fabs(g);
}
/* keep statistics on rms for each harmonic */
for (i=0; i<n_harm; i++) {
frms += sqr(f);
grms += sqr(g);
}
for (i=0; i<n_harm; i++)
fprintf(fpSDDS, "%13.6le ", f*ipow(reference_radius/bore_radius, i));
fprintf(fpSDDS, "%13.6le ", f);
for (i=0; i<n_harm; i++)
fprintf(fpSDDS, "%13.6le ", g[i]*ipow(reference_radius/bore_radius, i));
fprintf(fpSDDS, "%13.6le ", g[i]);
fputc('\n', fpSDDS);
}
I think this part is the key of the code.
In calculating dfX or dfY, why the crot and srot are constant regardless of the pole (m=0,1,2,..)? and on the other hand, why alpha is varied with the pole (m=0,1,2...)?
All contribution of the poles are the summation of each pole's perturbation.
f[i-1] += dHn.real();
g[i-1] += dHn.imag();
This two lines do it? Do I understand the code in the right way?