OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Harmonics.h
Go to the documentation of this file.
1 
10 #ifndef HARMONICS_H
11 #define HARMONICS_H
12 
13 #include <cmath>
14 #include <fstream>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "Physics/Physics.h"
20 
21 #include <boost/numeric/ublas/matrix.hpp>
22 
24 
25 template<typename Value_type, typename Size_type>
26 class Harmonics
27 {
28 public:
30  typedef Value_type value_type;
32  typedef Size_type size_type;
34  typedef boost::numeric::ublas::matrix<value_type> matrix_type;
35 
36 
39 
41 
52 
54 
59  std::vector<matrix_type> computeMap(const std::string, const std::string, const int);
60 
62  std::pair<value_type, value_type> getTunes();
63 
66 
69 
70 private:
71 
85  std::pair<value_type, value_type> tunes_m;
94 
103 };
104 
105 // -----------------------------------------------------------------------------------------------------------------------
106 // PUBLIC MEMBER FUNCTIONS
107 // -----------------------------------------------------------------------------------------------------------------------
108 
109 template<typename Value_type, typename Size_type>
111  size_type nth, size_type nr, size_type nSector, value_type E, value_type E0)
112  : wo_m(wo), Emin_m(Emin), Emax_m(Emax), nth_m(nth), nr_m(nr), nSector_m(nSector), E_m(E), E0_m(E0)
113 {}
114 
115 template<typename Value_type, typename Size_type>
116 std::vector<typename Harmonics<Value_type, Size_type>::matrix_type> Harmonics<Value_type, Size_type>::computeMap(const std::string filename1, const std::string filename2, const int startmod) {
117  // i --> different energies
118  // j --> different angles
119 
120  // ---------------
121 
122 
123 // unsigned int nth_m = 360; //270;
124  unsigned int N = 4;
125  value_type two_pi = 2.0 * M_PI;
126  value_type tpiN = two_pi / value_type(N);
127  value_type piN = M_PI / value_type(N);
128 // unsigned int nr_m = 180;
129  unsigned int cnt = 0;
130  bool set = false;
131 
132  value_type gap = 0.05;
133  value_type K1 = 0.45;
134 
135  std::vector<matrix_type> Mcyc(nth_m);
136 
137  value_type beta_m;
138 
139  std::vector<value_type> gamma(nr_m), E(nr_m), PC(nr_m), nur(nr_m), nuz(nr_m);
140 
141  std::vector<value_type> R(nr_m), r(nr_m);
142  std::vector<value_type> Bmag(nr_m), k(nr_m);
143  std::vector<value_type> alpha(nr_m), beta(nr_m);
144 
145  //----------------------------------------------------------------------
146  // read files
147  std::ifstream infile2(filename2);
148  std::ifstream infile1(filename1);
149 
150  if (!infile1.is_open() || !infile2.is_open()) {
151  std::cerr << "Couldn't open files!" << std::endl;
152  std::exit(0);
153  }
154 
155  unsigned int n = 0;
156  value_type rN1, cN1, sN1, aN1, phN1, rN2, cN2, sN2, aN2, phN2;
157 
158  while (infile1 >> rN1 >> cN1 >> sN1 >> aN1 >> phN1 &&
159  infile2 >> rN2 >> cN2 >> sN2 >> aN2 >> phN2) {
160 
161  R[n] = rN1 * 0.01;
162  alpha[n] = 2.0 * std::acos(aN2 / aN1) / value_type(N);
163  beta[n] = std::atan(sN1 / cN1) / value_type(N);
164  value_type f4 = aN1 * M_PI * 0.5 / std::sin(0.5 * alpha[n] * value_type(N));
165  value_type f8 = aN2 * M_PI / std::sin(alpha[n] * value_type(N));
166 
167  Bmag[n] = 0.5 * (f4 + f8);
168 
169  n++;
170  }
171 
172  infile1.close();
173  infile2.close();
174  //----------------------------------------------------------------------
175 
176  value_type s = std::sin(piN);
177  value_type c = std::cos(piN);
178 
179  std::vector<value_type> dalp(nr_m), dbet(nr_m), len2(nr_m), len(nr_m), t1eff(nr_m), t2eff(nr_m);
180  std::vector<value_type> t1(nr_m), t2(nr_m), t3(nr_m);
181 
182  dalp[0] = (alpha[1] - alpha[0]) / (R[1] - R[0]);
183  dalp[n-1] = (alpha[n-1] - alpha[n-2]) / (R[n-1] - R[n-2]);
184  dbet[0] = (beta[1] - alpha[0]) / (R[1] - R[0]);
185  dbet[n-1] = (beta[n-1] - beta[n-2]) / (R[n-1] - R[n-2]);
186 
187  for (unsigned int i = 1; i < n - 1; ++i) {
188  dalp[i] = R[i] * (alpha[i+1] - alpha[i-1]) / (R[i+1] - R[i-1]);
189  dbet[i] = R[i] * (beta[i+1] - beta[i-1]) / (R[i+1] - R[i-1]);
190  }
191 
192  for (unsigned int i = 0; i < n; ++i) {
193  value_type cot = 1.0 / std::tan(0.5 * alpha[i]);
194 
195  value_type eps1 = std::atan(dbet[i] - 0.5 * dalp[i]);
196  value_type eps2 = std::atan(dbet[i] + 0.5 * dalp[i]);
197 
198  value_type phi = piN - 0.5 * alpha[i];
199 
200  // bending radius
201  r[i] = R[i] * sin(0.5 * alpha[i]) / s;
202  len2[i] = R[i] * std::sin(phi);
203  len[i] = two_pi * r[i] + 2.0 * len2[i] * value_type(N);
204 
205  value_type g1 = phi + eps1;
206  value_type g2 = - phi + eps2;
207 
208  t1[i] = std::tan(g1);
209  t2[i] = std::tan(g2);
210  t3[i] = std::tan(phi);
211 
212  value_type fac = gap / r[i] * K1;
213  value_type psi = fac * (1.0 + std::sin(g1) * std::sin(g1)) / std::cos(g1);
214 
215  t1eff[i] = std::tan(g1 - psi);
216 
217  psi = fac * (1.0 + std::sin(g2) * std::sin(g2)) / std::cos(g2);
218  t2eff[i] = std::tan(g2 + psi);
219 
220  beta_m = wo_m / Physics::c * len[i] / two_pi;
221  gamma[i] = 1.0 / std::sqrt(1.0 - beta_m * beta_m);
222  E[i] = E0_m * (gamma[i] - 1.0);
223  PC[i] = E0_m * gamma[i] * beta_m;
224  Bmag[i] = E0_m * 1.0e6 / Physics::c * beta_m * gamma[i] / r[i] * 10.0;
225 
226  if (!set && E[i] >= E_m) {
227  set = true;
228  cnt = i;
229  }
230  }
231 
232  // (average) field gradient
233  for (unsigned int i = 0; i < n; ++i) {
234  value_type dBdr;
235  if (i == 0)
236  dBdr = (Bmag[1] - Bmag[0]) / (R[1] - R[0]);
237  else if (i == n - 1)
238  dBdr = (Bmag[n-1] - Bmag[n-2]) / (R[n-1] - R[n-2]);
239  else
240  dBdr = (Bmag[i+1] - Bmag[i-1]) / (R[i+1] - R[i-1]);
241 
242  value_type bb = std::sin(piN - 0.5 * alpha[i]) / std::sin(0.5 * alpha[i]);
243  value_type eps = 2.0 * bb / (1.0 + bb * bb);
244  value_type BaV = Bmag[i];
245 
246  k[i] = r[i] * r[i] / (R[i] * BaV) * dBdr * (1.0 + bb * value_type(N) / M_PI * s);
247  }
248 
249  for (unsigned int i = 0; i < n; ++i) {
250  if ((k[1] > -0.999) && (E[i] > Emin_m) && (E[i] < Emax_m + 1.0)) {
251  value_type kx = std::sqrt(1.0 + k[i]);
252  value_type Cx = std::cos(tpiN * kx);
253  value_type Sx = std::sin(tpiN * kx);
254  value_type pm, ky, Cy, Sy;
255 
256  if (k[i] >= 0.0) {
257  pm = 1.0;
258  ky = std::sqrt(std::fabs(k[i]));
259  Cy = std::cosh(tpiN * ky);
260  Sy = std::sinh(tpiN * ky);
261  } else {
262  pm = -1.0;
263  ky = std::sqrt(std::fabs(k[i]));
264  Cy = std::cos(tpiN * ky);
265  Sy = std::sin(tpiN * ky);
266  }
267 
268  value_type tav = 0.5 * (t1[i] - t2[i]);
269  value_type tmul = t1[i] * t2[i];
270  value_type lrho = 2.0 * len2[i] / r[i];
271 
272  nur[i] = std::acos(Cx * (1.0 + lrho * tav) + Sx / kx * (tav - lrho * 0.5 * (kx * kx + tmul))) / tpiN;
273 
274  tav = 0.5 * (t1eff[i] - t2eff[i]);
275  tmul = t1eff[i] * t2eff[i];
276 
277  nuz[i] = std::acos(Cy * (1.0 - lrho * tav) + Sy / ky * (0.5 * lrho * (pm * ky * ky - tmul) - tav)) / tpiN;
278 
279 // std::cout << E[i] << " " << R[i] << " " << nur[i] << " " << nuz[i] << std::endl;
280  }
281  }
282  // -------------------------------------------------------------------------
283 
284  int i = cnt;
285 
286  tunes_m = { nur[i], nuz[i] };
287  radius_m = R[i];
288 
289 // for (int i = 9; i < 10; ++i) { // n = 1 --> only for one energy
290  value_type smax, slim, ss, gam2;
291 
292  smax = len[i] / value_type(N);
293  slim = r[i] * tpiN;
294  ds_m = smax / value_type(nth_m);
295  ss = 0.0;
296  gam2 = gamma[i] * gamma[i];
297 
298  matrix_type Mi = __Mix6( t1[i], t1eff[i], r[i]);
299  matrix_type Mx = __Mix6(- t2[i], - t2eff[i], r[i]);
300  matrix_type Md = __Md6(ds_m, gam2);
301  matrix_type Mb = __Mb6k(ds_m / r[i], r[i], k[i], gam2);
302 
303  unsigned int j = 0;
304 
305  matrix_type M0 = boost::numeric::ublas::zero_matrix<value_type>(6);
306  matrix_type M1 = boost::numeric::ublas::zero_matrix<value_type>(6);
307 
308  switch (startmod) {
309  case 0: // SECTOR_ENTRANCE
310  ss = slim - ds_m;
311  Mcyc[j++] = boost::numeric::ublas::prod(Mb, Mi);
312 
313  while (ss > ds_m) {
314  Mcyc[j++] = Mb;
315  ss -= ds_m;
316  }
317 
318  M0 = __Mb6k(ss / r[i], r[i], k[i], gam2);
319  M1 = __Md6(ds_m - ss, gam2);
320 
321  Mcyc[j++] = matt_boost::gemmm<matrix_type>(M1, Mx, M0);
322 
323  ss = smax - slim - (ds_m - ss);
324 
325  while ((ss > ds_m) && (j < nth_m)) {
326  Mcyc[j++] = Md;
327  ss -= ds_m;
328  }
329 
330  if (j < nth_m)
331  Mcyc[j++] = __Md6(ss, gam2);
332 
333  break;
334 
335  case 1: // SECTOR_CENTER
336  j = 0;
337  ss = slim * 0.5;
338 
339  while (ss > ds_m) {
340  Mcyc[j++] = Mb;
341  ss -= ds_m;
342  }
343 
344  M0 = __Mb6k(ss / r[i], r[i], k[i], gam2);
345  M1 = __Md6(ds_m - ss, gam2);
346 
347  Mcyc[j++] = matt_boost::gemmm<matrix_type>(M1, Mx, M0);
348 
349  ss = smax - slim - (ds_m - ss);
350 
351  while (ss > ds_m) {
352  Mcyc[j++] = Md;
353  ss -= ds_m;
354  }
355 
356  M0 = __Md6(ss, gam2);
357  M1 = __Mb6k((ds_m - ss) / r[i], r[i], k[i], gam2);
358 
359  Mcyc[j++] = matt_boost::gemmm<matrix_type>(M1, Mi, M0);
360 
361  ss = slim * 0.5 - (ds_m - ss);
362 
363  while ((ss > ds_m) && (j < nth_m)) {
364  Mcyc[j++] = Mb;
365  ss -= ds_m;
366  }
367 
368  if (j < nth_m)
369  Mcyc[j++] = __Mb6k(ss / r[i], r[i], k[i], gam2);
370 
371  break;
372 
373  case 2: // SECTOR_EXIT
374  j = 0;
375 
376  Mcyc[j++] = boost::numeric::ublas::prod(Md,Mx);
377 
378  ss = smax - slim - ds_m;
379 
380  while (ss > ds_m) {
381  Mcyc[j++] = Md;
382  ss -= ds_m;
383  }
384 
385  M0 = __Md6(ss, gam2);
386  M1 = __Mb6k((ds_m - ss) / r[i], r[i], k[i], gam2);
387 
388  Mcyc[j++] = matt_boost::gemmm<matrix_type>(M1, Mi, M0);
389 
390  ss = slim - (ds_m - ss);
391 
392  while ((ss > ds_m) && (j < nth_m)) {
393  Mcyc[j++] = Mb;
394  ss -= ds_m;
395  }
396 
397  if (j < nth_m)
398  Mcyc[j++] = __Mb6k(ss / r[i], r[i], k[i], gam2);
399 
400  break;
401 
402  case 3: // VALLEY_CENTER
403  default:
404  j = 0;
405  ss = (smax - slim) * 0.5;
406 
407  while (ss > ds_m) {
408  Mcyc[j++] = Md;
409  ss -= ds_m;
410  }
411 
412  M0 = __Md6(ss, gam2);
413  M1 = __Mb6k((ds_m - ss) / r[i], r[i], k[i], gam2);
414 
415  Mcyc[j++] = matt_boost::gemmm<matrix_type>(M1, Mi, M0);
416 
417  ss = slim - (ds_m - ss);
418  while (ss > ds_m) {
419  Mcyc[j++] = Mb;
420  ss -= ds_m;
421  }
422 
423  M0 = __Mb6k(ss / r[i], r[i], k[i], gam2);
424  M1 = __Md6(ds_m - ss, gam2);
425 
426  Mcyc[j++] = matt_boost::gemmm<matrix_type>(M1, Mx, M0);
427 
428  ss = (smax - slim) * 0.5 - (ds_m - ss);
429  while ((ss > ds_m) && (j < nth_m)) {
430  Mcyc[j++] = Md;
431  ss -= ds_m;
432  }
433 
434  if (j < nth_m)
435  Mcyc[j++] = __Md6(ss, gam2);
436 
437  break;
438  } // end of switch
439 // } // end of for
440 
441  return std::vector<matrix_type>(Mcyc);
442 }
443 
444 template<typename Value_type, typename Size_type>
445 inline std::pair<Value_type, Value_type> Harmonics<Value_type, Size_type>::getTunes() {
446  return tunes_m;
447 }
448 
449 template<typename Value_type, typename Size_type>
451  return radius_m;
452 }
453 
454 template<typename Value_type, typename Size_type>
456  return ds_m;
457 }
458 
459 
460 // -----------------------------------------------------------------------------------------------------------------------
461 // PRIVATE MEMBER FUNCTIONS
462 // -----------------------------------------------------------------------------------------------------------------------
463 
464 template<typename Value_type, typename Size_type>
466  matrix_type M = boost::numeric::ublas::identity_matrix<value_type>(6);
467 
468  M(1,0) = tx / r;
469  M(3,2) = - ty / r;
470 
471  return M;
472 }
473 
474 template<typename Value_type, typename Size_type>
476  matrix_type M = boost::numeric::ublas::identity_matrix<value_type>(6);
477 
478  M(0,1) = l;
479  M(2,3) = l;
480  M(4,5) = l / gam2;
481 
482  return M;
483 }
484 
485 template<typename Value_type, typename Size_type>
487  matrix_type M = boost::numeric::ublas::identity_matrix<value_type>(6);
488 
489  value_type C = std::cos(phi);
490  value_type S = std::sin(phi);
491  value_type l =r * phi;
492 
493  M(0,0) = M(1,1) = C;
494  M(0,1) = S * r;
495  M(1,0) = - S / r;
496  M(2,3) = l;
497  M(4,5) = l / gam2 - l + r * S;
498  M(4,0) = - (M(1,5) = S);
499  M(4,1) = - (M(0,5) = r * (1.0 - C));
500 
501  return M;
502 }
503 
504 template<typename Value_type, typename Size_type>
506  matrix_type M = boost::numeric::ublas::identity_matrix<value_type>(6);
507 
508  value_type C,S;
509 
510  if (k == 0.0) return __Mb6(phi,r,gam2);
511 
512  value_type fx = std::sqrt(1.0 + k);
513  value_type fy = std::sqrt(std::fabs(k));
514  value_type c = std::cos(phi * fx);
515  value_type s = std::sin(phi * fx);
516  value_type l = r * phi;
517 
518 
519  if (k > 0.0) {
520  C = std::cosh(phi * fy);
521  S = std::sinh(phi * fy);
522  } else {
523  C = std::cos(phi * fy);
524  S = std::sin(phi * fy);
525  }
526 
527  M(0,0) = M(1,1) = c;
528  M(0,1) = s * r / fx;
529  M(1,0) = - s * fx / r;
530  M(2,2) = M(3,3) = C;
531  M(2,3) = S * r / fy;
532 
533  value_type sign = (std::signbit(k)) ? value_type(-1) : value_type(1);
534 
535  M(3,2) = sign * S * fy / r;
536  M(4,5) = l / gam2 - r / (1.0 + k) * (phi - s / fx);
537  M(4,0)= - (M(1,5) = s / fx);
538  M(4,1)= - (M(0,5) = r * (1.0 - c) / (1.0 + k));
539 
540  return M;
541 }
542 
543 #endif
matrix_type __Md6(value_type, value_type)
Compute some matrix (ask Dr. C. Baumgarten)
Definition: Harmonics.h:475
boost::numeric::ublas::matrix< value_type > matrix_type
Type for specifying matrices.
Definition: Harmonics.h:34
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
Definition: PETE.h:808
value_type E0_m
Stores the potential energy [MeV].
Definition: Harmonics.h:93
Value_type value_type
Type of variable.
Definition: Harmonics.h:30
value_type Emin_m
Stores the minimum energy in MeV.
Definition: Harmonics.h:75
value_type getRadius()
Returns the radius.
Definition: Harmonics.h:450
std::pair< value_type, value_type > tunes_m
Stores the tunes (radial, vertical)
Definition: Harmonics.h:85
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
value_type Emax_m
Stores the maximum energy in MeV.
Definition: Harmonics.h:77
constexpr double two_pi
The value of .
Definition: Physics.h:34
const int nr
Definition: ClassicRandom.h:24
value_type ds_m
Stores the path length.
Definition: Harmonics.h:89
Harmonics(value_type, value_type, value_type, size_type, size_type, size_type, value_type, value_type)
Constructor.
Definition: Harmonics.h:110
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
Tps< T > cot(const Tps< T > &x)
Cotangent.
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
Definition: TpsMath.h:222
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:79
Size_type size_type
Type of size.
Definition: Harmonics.h:32
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:810
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
value_type wo_m
Stores the nominal orbital frequency in Hz.
Definition: Harmonics.h:73
value_type getPathLength()
Returns step size.
Definition: Harmonics.h:455
matrix_type __Mb6k(value_type, value_type, value_type, value_type)
Compute some matrix (ask Dr. C. Baumgarten)
Definition: Harmonics.h:505
matrix_type __Mix6(value_type, value_type, value_type)
Compute some matrix (ask Dr. C. Baumgarten)
Definition: Harmonics.h:465
T * value_type(const SliceIterator< T > &)
size_type nSector_m
Stores the number of sectors.
Definition: Harmonics.h:83
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
FnArg FnReal sign(a))
value_type radius_m
Stores the radius.
Definition: Harmonics.h:87
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
START
Defines starting point of computation.
Definition: Harmonics.h:38
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Definition: PETE.h:1243
matrix_type __Mb6(value_type, value_type, value_type)
Compute some matrix (ask Dr. C. Baumgarten)
Definition: Harmonics.h:486
size_type nth_m
Stores the number of angle splits.
Definition: Harmonics.h:79
size_type nr_m
Stores the number of radial splits.
Definition: Harmonics.h:81
std::pair< value_type, value_type > getTunes()
Returns the radial and vertical tunes.
Definition: Harmonics.h:445
std::vector< matrix_type > computeMap(const std::string, const std::string, const int)
Compute all maps of the cyclotron using harmonics.
Definition: Harmonics.h:116
Tps< T > sinh(const Tps< T > &x)
Hyperbolic sine.
Definition: TpsMath.h:204
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
value_type E_m
Stores the energy for which we perform the computation.
Definition: Harmonics.h:91