OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Cyclotron.cpp
Go to the documentation of this file.
1 //
2 // Definitions for class: Cyclotron
3 // Defines the abstract interface for a cyclotron.
4 // Class category: AbsBeamline
5 //
6 // Copyright (c) 2008-2019
7 // Paul Scherrer Institut, Villigen PSI, Switzerland
8 // All rights reserved.
9 //
10 // OPAL is licensed under GNU GPL version 3.
11 //
12 
13 #include "AbsBeamline/Cyclotron.h"
14 
17 #include "Fields/Fieldmap.h"
18 #include "Physics/Physics.h"
19 #include "Structure/LossDataSink.h"
20 #include "TrimCoils/TrimCoil.h"
21 #include "Utilities/Options.h"
23 #include <fstream>
24 
25 #define CHECK_CYC_FSCANF_EOF(arg) if(arg == EOF)\
26 throw GeneralClassicException("Cyclotron::getFieldFromFile",\
27  "fscanf returned EOF at " #arg);
28 
29 extern Inform *gmsg;
30 
31 using Physics::pi;
32 
33 // Class Cyclotron
34 // ------------------------------------------------------------------------
35 
37  Component() {
38 }
39 
40 
42  Component(right),
43  fmapfn_m(right.fmapfn_m),
44  rffrequ_m(right.rffrequ_m),
45  rfphi_m(right.rfphi_m),
46  escale_m(right.escale_m),
47  superpose_m(right.superpose_m),
48  symmetry_m(right.symmetry_m),
49  rinit_m(right.rinit_m),
50  prinit_m(right.prinit_m),
51  phiinit_m(right.phiinit_m),
52  zinit_m(right.zinit_m),
53  pzinit_m(right.pzinit_m),
54  spiral_flag_m(right.spiral_flag_m),
55  trimCoilThreshold_m(right.trimCoilThreshold_m),
56  type_m(right.type_m),
57  harm_m(right.harm_m),
58  bscale_m(right.bscale_m),
59  trimcoils_m(right.trimcoils_m),
60  minr_m(right.minr_m),
61  maxr_m(right.maxr_m),
62  minz_m(right.minz_m),
63  maxz_m(right.maxz_m),
64  fmLowE_m(right.fmLowE_m),
65  fmHighE_m(right.fmHighE_m),
66  RFfilename_m(right.RFfilename_m),
67  RFFCoeff_fn_m(right.RFFCoeff_fn_m),
68  RFVCoeff_fn_m(right.RFVCoeff_fn_m) {
69 }
70 
71 
72 Cyclotron::Cyclotron(const std::string &name):
73  Component(name) {
74 }
75 
76 
78 }
79 
80 
81 void Cyclotron::applyTrimCoil_m(const double r, const double z,
82  const double tet_rad,
83  double *br, double *bz) {
84  for (auto trimcoil : trimcoils_m) {
85  trimcoil->applyField(r,tet_rad,z,br,bz);
86  }
87 }
88 
89 void Cyclotron::applyTrimCoil(const double r, const double z,
90  const double tet_rad,
91  double& br, double& bz) {
92  //Changed from > to >= to include case where bz == 0 and trimCoilThreshold_m == 0 -DW
93  if (std::abs(bz) >= trimCoilThreshold_m) {
94  applyTrimCoil_m(r, z, tet_rad, &br, &bz);
95  }
96  else {
97  // make sure to have a smooth transition
98  double tmp_bz = 0.0;
99  applyTrimCoil_m(r, z, tet_rad, &br, &tmp_bz);
100  bz += tmp_bz * std::abs(bz) / trimCoilThreshold_m;
101  }
102 }
103 
104 void Cyclotron::accept(BeamlineVisitor &visitor) const {
105  visitor.visitCyclotron(*this);
106 }
107 
108 void Cyclotron::setRinit(double rinit) {
109  rinit_m = rinit;
110 }
111 
112 double Cyclotron::getRinit() const {
113  return rinit_m;
114 }
115 
116 void Cyclotron::setPRinit(double prinit) {
117  prinit_m = prinit;
118 }
119 
120 double Cyclotron::getPRinit() const {
121  return prinit_m;
122 }
123 
124 void Cyclotron::setPHIinit(double phiinit) {
125  phiinit_m = phiinit;
126 }
127 
128 double Cyclotron::getPHIinit() const {
129  return phiinit_m;
130 }
131 
132 void Cyclotron::setZinit(double zinit){
133  zinit_m = zinit;
134 }
135 
136 double Cyclotron::getZinit() const {
137  return zinit_m;
138 }
139 
140 void Cyclotron::setPZinit(double pzinit){
141  pzinit_m = pzinit;
142 }
143 
144 double Cyclotron::getPZinit() const {
145  return pzinit_m;
146 }
147 
148 void Cyclotron::setTrimCoilThreshold(double trimCoilThreshold) {
149  trimCoilThreshold_m = 10.0 * trimCoilThreshold; // convert from Tesla to kGauss
150 }
151 
153  return trimCoilThreshold_m;
154 }
155 
156 void Cyclotron::setSpiralFlag(bool spiral_flag) {
157  spiral_flag_m = spiral_flag;
158 }
159 
161  return spiral_flag_m;
162 }
163 
164 void Cyclotron::setFieldMapFN(std::string f) {
165  fmapfn_m = f;
166 }
167 
168 std::string Cyclotron::getFieldMapFN() const {
169  return fmapfn_m;
170 }
171 
172 void Cyclotron::setRfFieldMapFN(std::vector<std::string> f) {
173  RFfilename_m = f;
174 }
175 
176 void Cyclotron::setRFFCoeffFN(std::vector<std::string> f) {
177  RFFCoeff_fn_m = f;
178 }
179 
180 void Cyclotron::setRFVCoeffFN(std::vector<std::string> f) {
181  RFVCoeff_fn_m = f;
182 }
183 
184 int Cyclotron::getFieldFlag(const std::string& type) const {
197  int fieldflag;
198  if(type == std::string("CARBONCYCL")) {
199  fieldflag = 2;
200  } else if(type == std::string("CYCIAE")) {
201  fieldflag = 3;
202  } else if(type == std::string("AVFEQ")) {
203  fieldflag = 4;
204  } else if(type == std::string("FFA")) {
205  fieldflag = 5;
206  } else if(type == std::string("BANDRF")) {
207  fieldflag = 6;
208  } else if(type == std::string("SYNCHROCYCLOTRON")) {
209  fieldflag = 7;
210  } else //(type == "RING")
211  fieldflag = 1;
212  return fieldflag;
213 }
214 
215 void Cyclotron::setRfPhi(std::vector<double> f) {
216  rfphi_m = f;
217 }
218 
219 void Cyclotron::setRfFrequ(std::vector<double> f) {
220  rffrequ_m = f;
221 }
222 
223 double Cyclotron::getRfFrequ() const {
224  if (rffrequ_m.empty() == false)
225  return rffrequ_m[0];
226  else {
227  throw GeneralClassicException("Cyclotron::getRfFrequ",
228  "RFFREQ not defined for CYCLOTRON!");
229  }
230 }
231 
232 void Cyclotron::setSuperpose(std::vector<bool> flag) {
233  superpose_m = flag;
234 }
235 
236 //bool Cyclotron::getSuperpose() const {
237 // return superpose_m;
238 //}
239 
240 void Cyclotron::setSymmetry(double s) {
241  symmetry_m = s;
242 }
243 
244 double Cyclotron::getSymmetry() const {
245  return symmetry_m;
246 }
247 
248 
249 void Cyclotron::setType(std::string t) {
250  type_m = t;
251 }
252 
253 const std::string &Cyclotron::getCyclotronType() const {
254  return type_m;
255 }
256 
258  return CYCLOTRON;
259 }
260 
261 void Cyclotron::setCyclHarm(double h) {
262  harm_m = h;
263 }
264 
265 void Cyclotron::setBScale(double s) {
266  bscale_m = s;
267 }
268 
269 double Cyclotron::getBScale() const {
270  return bscale_m;
271 }
272 
273 void Cyclotron::setEScale(std::vector<double> s) {
274  escale_m = s;
275 }
276 
277 unsigned int Cyclotron::getNumberOfTrimcoils() const {
278  return trimcoils_m.size();
279 }
280 
281 double Cyclotron::getCyclHarm() const {
282  return harm_m;
283 }
284 
285 double Cyclotron::getRmin() const {
286  return BP.rmin;
287 }
288 
289 
290 double Cyclotron::getRmax() const {
291  return BP.rmin + (Bfield.nrad - 1) * BP.delr;
292 }
293 
294 
295 void Cyclotron::setMinR(double r) {
296  // DW: This is to let the user keep using mm in the input file for now
297  // while switching internally to m
298  minr_m = 0.001 * r;
299 }
300 
301 void Cyclotron::setMaxR(double r) {
302  // DW: This is to let the user keep using mm in the input file for now
303  // while switching internally to m
304  maxr_m = 0.001 * r;
305 }
306 double Cyclotron::getMinR() const {
307  return minr_m;
308 }
309 
310 double Cyclotron::getMaxR() const {
311  return maxr_m;
312 }
313 
314 void Cyclotron::setMinZ(double z) {
315  // DW: This is to let the user keep using mm in the input file for now
316  // while switching internally to m
317  minz_m = 0.001 * z;
318 }
319 double Cyclotron::getMinZ() const {
320  return minz_m;
321 }
322 void Cyclotron::setMaxZ(double z) {
323  // DW: This is to let the user keep using mm in the input file for now
324  // while switching internally to m
325  maxz_m = 0.001 * z;
326 }
327 double Cyclotron::getMaxZ() const {
328  return maxz_m;
329 }
330 
331 void Cyclotron::setTrimCoils(const std::vector<TrimCoil*> &trimcoils) {
332  trimcoils_m = trimcoils;
333 }
334 
335 void Cyclotron::setFMLowE(double e) { fmLowE_m = e;}
336 double Cyclotron::getFMLowE() const { return fmLowE_m;}
337 
338 void Cyclotron::setFMHighE(double e) { fmHighE_m = e;}
339 double Cyclotron::getFMHighE() const { return fmHighE_m;}
340 
341 
342 bool Cyclotron::apply(const size_t &id, const double &t, Vector_t &E, Vector_t &B) {
343 
344  bool flagNeedUpdate = false;
345 
346  const double rpos = std::hypot(RefPartBunch_m->R[id](0), RefPartBunch_m->R[id](1));
347  const double zpos = RefPartBunch_m->R[id](2);
348 
349  Inform gmsgALL("OPAL", INFORM_ALL_NODES);
350  if (zpos > maxz_m || zpos < minz_m || rpos > maxr_m || rpos < minr_m){
351  flagNeedUpdate = true;
352  gmsgALL << level4 << getName()
353  << ": Particle " << id
354  << " out of the global aperture of cyclotron!" << endl;
355  gmsgALL << level4 << getName()
356  << ": Coords: "<< RefPartBunch_m->R[id] << " m" << endl;
357 
358  } else{
359  flagNeedUpdate = apply(RefPartBunch_m->R[id], RefPartBunch_m->P[id], t, E, B);
360  if(flagNeedUpdate){
361  gmsgALL << level4 << getName()
362  << ": Particle "<< id
363  << " out of the field map boundary!" << endl;
364  gmsgALL << level4 << getName()
365  << ": Coords: "<< RefPartBunch_m->R[id] << " m" << endl;
366  }
367  }
368 
369  if (flagNeedUpdate) {
370  lossDs_m->addParticle(RefPartBunch_m->R[id], RefPartBunch_m->P[id],
371  id, t, 0, RefPartBunch_m->bunchNum[id]);
372  RefPartBunch_m->Bin[id] = -1;
373  }
374 
375  return flagNeedUpdate;
376 }
377 
378 bool Cyclotron::apply(const Vector_t &R, const Vector_t &P,
379  const double &t, Vector_t &E, Vector_t &B) {
380 
381  const double rad = std::hypot(R[0],R[1]);
382  const double tempv = atan(R[1] / R[0]);
383  double tet = tempv;
384 
385  /* if((R[0] > 0) && (R[1] >= 0)) tet = tempv;
386  else*/
387  if ((R[0] < 0) && (R[1] >= 0)) tet = pi + tempv;
388  else if((R[0] < 0) && (R[1] <= 0)) tet = pi + tempv;
389  else if((R[0] > 0) && (R[1] <= 0)) tet = 2.0 * pi + tempv;
390  else if((R[0] == 0) && (R[1] > 0)) tet = pi / 2.0;
391  else if((R[0] == 0) && (R[1] < 0)) tet = 1.5 * pi;
392 
393  double tet_rad = tet;
394 
395  // the actual angle of particle in degree
396  tet = tet / pi * 180.0;
397 
398  // Necessary for gap phase output -DW
399  if (0 <= tet && tet <= 45) waiting_for_gap = 1;
400 
401  // dB_{z}/dr, dB_{z}/dtheta, B_{z}
402  double brint = 0.0, btint = 0.0, bzint = 0.0;
403 
404  if ( this->interpolate(rad, tet_rad, brint, btint, bzint) ) {
405 
406  /* Br */
407  double br = - brint * R[2];
408 
409  /* Btheta */
410  double bt = - btint / rad * R[2];
411 
412  /* Bz */
413  double bz = - bzint;
414 
415  this->applyTrimCoil(rad, R[2], tet_rad, br, bz);
416 
417  /* Br Btheta -> Bx By */
418  B[0] = br * cos(tet_rad) - bt * sin(tet_rad);
419  B[1] = br * sin(tet_rad) + bt * cos(tet_rad);
420  B[2] = bz;
421  } else {
422  return true;
423  }
424 
426  return false;
427  }
428 
429  //The RF field is supposed to be sampled on a cartesian grid
430  std::vector<Fieldmap *>::const_iterator fi = RFfields_m.begin();
431  std::vector<double>::const_iterator rffi = rffrequ_m.begin();
432  std::vector<double>::const_iterator rfphii = rfphi_m.begin();
433  std::vector<double>::const_iterator escali = escale_m.begin();
434  std::vector<bool>::const_iterator superposei = superpose_m.begin();
435  std::vector<std::vector<double>>::const_iterator rffci = rffc_m.begin();
436  std::vector<std::vector<double>>::const_iterator rfvci = rfvc_m.begin();
437 
438  double xBegin(0), xEnd(0), yBegin(0), yEnd(0), zBegin(0), zEnd(0);
439  int fcount = 0;
440 
441  for(; fi != RFfields_m.end(); ++fi, ++rffi, ++rfphii, ++escali, ++superposei) {
442  (*fi)->getFieldDimensions(xBegin, xEnd, yBegin, yEnd, zBegin, zEnd);
443  if (fcount > 0 && *superposei == false) continue;
444 
445  // Ok, this is a total patch job, but now that the internal cyclotron units are in m, we have to
446  // change stuff here to match with the input units of mm in the fieldmaps. -DW
447  const Vector_t temp_R = R * Vector_t(1000.0); //Keep this until we have transitioned fully to m -DW
448 
449  if (temp_R(0) < xBegin || temp_R(0) > xEnd ||
450  temp_R(1) < yBegin || temp_R(1) > yEnd ||
451  temp_R(2) < zBegin || temp_R(2) > zEnd) continue;
452 
453  Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
454  // out of bounds?
455  if ((*fi)->getFieldstrength(temp_R, tmpE, tmpB)) continue;
456 
457  ++fcount;
458 
459  double frequency = (*rffi); // frequency in MHz
460  double ebscale = (*escali); // E and B field scaling
461 
462  if(myBFieldType_m == SYNCHRO) {
463  double powert = 1;
464  for(const double fcoef : (*rffci)) {
465  powert *= (t * 1e-9);
466  frequency += fcoef * powert; // Add frequency ramp (in MHz/s^n)
467  }
468  powert = 1;
469  for(const double vcoef : (*rfvci)) {
470  powert *= (t * 1e-9);
471  ebscale += vcoef * powert; // Add frequency ramp (in MHz/s^n)
472  }
473  }
474 
475  double phase = 2.0 * pi * 1.0E-3 * frequency * t + (*rfphii); // f in [MHz], t in [ns]
476 
477  E += ebscale * cos(phase) * tmpE;
478  B -= ebscale * sin(phase) * tmpB;
479 
480  if(myBFieldType_m != SYNCHRO)
481  continue;
482 
483  // Some phase output -DW
484  if (tet >= 90.0 && waiting_for_gap == 1) {
485  double phase_print = 180.0 * phase / pi;
486  phase_print = fmod(phase_print, 360) - 360.0;
487 
488  *gmsg << endl << "Gap 1 phase = " << phase_print << " Deg" << endl;
489  *gmsg << "Gap 1 E-Field = (" << E[0] << "/" << E[1] << "/" << E[2] << ")" << endl;
490  *gmsg << "Gap 1 B-Field = (" << B[0] << "/" << B[1] << "/" << B[2] << ")" << endl;
491  *gmsg << "RF Frequency = " << frequency << " MHz" << endl;
492 
493  waiting_for_gap = 2;
494  }
495  else if (tet >= 270.0 && waiting_for_gap == 2) {
496 
497  double phase_print = 180.0 * phase / pi;
498  phase_print = fmod(phase_print, 360) - 360.0;
499 
500  *gmsg << endl << "Gap 2 phase = " << phase_print << " Deg" << endl;
501  *gmsg << "Gap 2 E-Field = (" << E[0] << "/" << E[1] << "/" << E[2] << ")" << endl;
502  *gmsg << "Gap 2 B-Field = (" << B[0] << "/" << B[1] << "/" << B[2] << ")" << endl;
503  *gmsg << "RF Frequency = " << frequency << " MHz" << endl;
504  waiting_for_gap = 0;
505  }
506  if(myBFieldType_m == SYNCHRO) {
507  ++rffci, ++rfvci;
508  }
509  }
510  return false;
511 }
512 
513 void Cyclotron::apply(const double& rad, const double& z,
514  const double& tet_rad, double& br,
515  double& bt, double& bz) {
516  this->interpolate(rad, tet_rad, br, bt, bz);
517  this->applyTrimCoil(rad, z, tet_rad, br, bz);
518 }
519 
521 
522  online_m = false;
523  lossDs_m->save();
524  *gmsg << "* Finalize cyclotron" << endl;
525 
526 }
527 
528 bool Cyclotron::bends() const {
529  return true;
530 }
531 
532 // calculate derivatives with 5-point lagrange's formula.
533 double Cyclotron::gutdf5d(double *f, double dx, const int kor, const int krl, const int lpr)
534 
535 {
536  double C[5][5][3], FAC[3];
537  double result;
538  int j;
539  /* CALCULATE DERIVATIVES WITH 5-POINT LAGRANGE FORMULA
540  * PARAMETERS:
541  * F STARTADDRESS FOR THE 5 SUPPORT POINTS
542  * DX STEPWIDTH FOR ARGUMENT
543  * KOR ORDER OF DERIVATIVE (KOR=1,2,3).
544  * KRL NUMBER OF SUPPORT POINT, WHERE THE DERIVATIVE IS TO BE CALCULATED
545  * (USUALLY 3, USE FOR BOUNDARY 1 ,2, RESP. 4, 5)
546  * LPR DISTANCE OF THE 5 STORAGE POSITIONS (=1 IF THEY ARE NEIGHBORS OR LENGTH
547  * OF COLUMNLENGTH OF A MATRIX, IF THE SUPPORT POINTS ARE ON A LINE).
548  * ATTENTION! THE INDICES ARE NOW IN C-FORMAT AND NOT IN FORTRAN-FORMAT.*/
549 
550  /* COEFFICIENTS FOR THE 1ST DERIVATIVE: */
551  C[0][0][0] = -50.0;
552  C[1][0][0] = 96.0;
553  C[2][0][0] = -72.0;
554  C[3][0][0] = 32.0;
555  C[4][0][0] = -6.0;
556  C[0][1][0] = -6.0;
557  C[1][1][0] = -20.0;
558  C[2][1][0] = 36.0;
559  C[3][1][0] = -12.0;
560  C[4][1][0] = 2.0;
561  C[0][2][0] = 2.0;
562  C[1][2][0] = -16.0;
563  C[2][2][0] = 0.0;
564  C[3][2][0] = 16.0;
565  C[4][2][0] = -2.0;
566  C[0][3][0] = -2.0;
567  C[1][3][0] = 12.0;
568  C[2][3][0] = -36.0;
569  C[3][3][0] = 20.0;
570  C[4][3][0] = 6.0;
571  C[0][4][0] = 6.0;
572  C[1][4][0] = -32.0;
573  C[2][4][0] = 72.0;
574  C[3][4][0] = -96.0;
575  C[4][4][0] = 50.0;
576 
577  /* COEFFICIENTS FOR THE 2ND DERIVATIVE: */
578  C[0][0][1] = 35.0;
579  C[1][0][1] = -104;
580  C[2][0][1] = 114.0;
581  C[3][0][1] = -56.0;
582  C[4][0][1] = 11.0;
583  C[0][1][1] = 11.0;
584  C[1][1][1] = -20.0;
585  C[2][1][1] = 6.0;
586  C[3][1][1] = 4.0;
587  C[4][1][1] = -1.0;
588  C[0][2][1] = -1.0;
589  C[1][2][1] = 16.0;
590  C[2][2][1] = -30.0;
591  C[3][2][1] = 16.0;
592  C[4][2][1] = -1.0;
593  C[0][3][1] = -1.0;
594  C[1][3][1] = 4.0;
595  C[2][3][1] = 6.0;
596  C[3][3][1] = -20.0;
597  C[4][3][1] = 11.0;
598  C[0][4][1] = 11.0;
599  C[1][4][1] = -56.0;
600  C[2][4][1] = 114.0;
601  C[3][4][1] = -104;
602  C[4][4][1] = 35.0;
603 
604 
605  /* COEFFICIENTS FOR THE 3RD DERIVATIVE: */
606  C[0][0][2] = -10.0;
607  C[1][0][2] = 36.0;
608  C[2][0][2] = -48.0;
609  C[3][0][2] = 28.0;
610  C[4][0][2] = -6.0;
611  C[0][1][2] = -6.0;
612  C[1][1][2] = 20.0;
613  C[2][1][2] = -24.0;
614  C[3][1][2] = 12.0;
615  C[4][1][2] = -2.0;
616  C[0][2][2] = -2.0;
617  C[1][2][2] = 4.0;
618  C[2][2][2] = 0.0;
619  C[3][2][2] = -4.0;
620  C[4][2][2] = 2.0;
621  C[0][3][2] = 2.0;
622  C[1][3][2] = -12.0;
623  C[2][3][2] = 24.0;
624  C[3][3][2] = -20.0;
625  C[4][3][2] = 6.0;
626  C[0][4][2] = 6.0;
627  C[1][4][2] = -28.0;
628  C[2][4][2] = 48.0;
629  C[3][4][2] = -36.0;
630  C[4][4][2] = 10.0;
631 
632  /* FACTOR: */
633  FAC[0] = 24.0;
634  FAC[1] = 12.0;
635  FAC[2] = 4.0;
636 
637  result = 0.0;
638  for(j = 0; j < 5; j++) {
639  result += C[j][krl][kor] * *(f + j * lpr);
640  }
641 
642  return result / (FAC[kor] * pow(dx, (kor + 1)));
643 }
644 
645 
646 bool Cyclotron::interpolate(const double& rad,
647  const double& tet_rad,
648  double& brint,
649  double& btint,
650  double& bzint)
651 {
652  const double xir = (rad - BP.rmin) / BP.delr;
653 
654  // ir : the number of path whose radius is less than the 4 points of cell which surround the particle.
655  const int ir = (int)xir;
656 
657  // wr1 : the relative distance to the inner path radius
658  const double wr1 = xir - (double)ir;
659  // wr2 : the relative distance to the outer path radius
660  const double wr2 = 1.0 - wr1;
661 
662  // the corresponding angle on the field map
663  // Note: this does not work if the start point of field map does not equal zero.
664  double tet_map = fmod(tet_rad / Physics::pi * 180.0, 360.0 / symmetry_m);
665 
666  double xit = tet_map / BP.dtet;
667 
668  int it = (int) xit;
669 
670  const double wt1 = xit - (double)it;
671  const double wt2 = 1.0 - wt1;
672 
673  // it : the number of point on the inner path whose angle is less than
674  // the particle' corresponding angle.
675  // include zero degree point
676  it++;
677 
678  int r1t1, r2t1, r1t2, r2t2;
679  int ntetS = Bfield.ntet + 1;
680 
681  // r1t1 : the index of the "min angle, min radius" point in the 2D field array.
682  // considering the array start with index of zero, minus 1.
683 
684  if(myBFieldType_m != FFABF) {
685  /*
686  For FFA this does not work
687  */
688  r1t1 = it + ntetS * ir - 1;
689  r1t2 = r1t1 + 1;
690  r2t1 = r1t1 + ntetS;
691  r2t2 = r2t1 + 1 ;
692 
693  } else {
694  /*
695  With this we have B-field AND this is far more
696  intuitive for me ....
697  */
698  r1t1 = idx(ir, it);
699  r2t1 = idx(ir + 1, it);
700  r1t2 = idx(ir, it + 1);
701  r2t2 = idx(ir + 1, it + 1);
702  }
703 
704  if((it >= 0) && (ir >= 0) && (it < Bfield.ntetS) && (ir < Bfield.nrad)) {
705 
706  // B_{z}
707  double bzf = Bfield.bfld[r1t1] * wr2 * wt2 +
708  Bfield.bfld[r2t1] * wr1 * wt2 +
709  Bfield.bfld[r1t2] * wr2 * wt1 +
710  Bfield.bfld[r2t2] * wr1 * wt1;
711 
712  bzint = /*- */bzf ;
713 
714  // dB_{z}/dr
715  brint = Bfield.dbr[r1t1] * wr2 * wt2 +
716  Bfield.dbr[r2t1] * wr1 * wt2 +
717  Bfield.dbr[r1t2] * wr2 * wt1 +
718  Bfield.dbr[r2t2] * wr1 * wt1;
719 
720 
721  // dB_{z}/dtheta
722  btint = Bfield.dbt[r1t1] * wr2 * wt2 +
723  Bfield.dbt[r2t1] * wr1 * wt2 +
724  Bfield.dbt[r1t2] * wr2 * wt1 +
725  Bfield.dbt[r2t2] * wr1 * wt1;
726 
727  return true;
728  }
729  return false;
730 }
731 
732 
733 void Cyclotron::read(const int &fieldflag, const double &scaleFactor) {
734  // PSIBF, AVFEQBF, ANSYSBF, FFABF
735  // for your own format field, you should add your own getFieldFromFile() function by yourself.
736 
737  if(fieldflag == 1) {
738  //*gmsg<<"Read field data from PSI format field map file."<<endl;
740  getFieldFromFile(scaleFactor);
741 
742  } else if(fieldflag == 2) {
743  // *gmsg<<"Read data from 450MeV Carbon cyclotron field file"<<endl
745  getFieldFromFile_Carbon(scaleFactor);
746 
747  } else if(fieldflag == 3) {
748  // *gmsg<<"Read data from 100MeV H- cyclotron CYCIAE-100 field file"<<endl;
750  getFieldFromFile_CYCIAE(scaleFactor);
751 
752  } else if(fieldflag == 4) {
753  *gmsg << "* Read AVFEQ data (Riken) use bfield scale factor bs = " << getBScale() << endl;
755  getFieldFromFile_AVFEQ(scaleFactor);
756 
757  } else if(fieldflag == 5) {
758  *gmsg << "* Read FFA data MSU/FNAL " << getBScale() << endl;
760  getFieldFromFile_FFA(scaleFactor);
761 
762  } else if(fieldflag == 6) {
763  *gmsg << "* Read both median plane B field map and 3D E field map of RF cavity for compact cyclotron" << getBScale() << endl;
765  getFieldFromFile_BandRF(scaleFactor);
766 
767  } else if(fieldflag == 7) {
768  *gmsg << "* Read midplane B-field, 3D RF fieldmaps, and text files with RF frequency/Voltage coefficients for Synchrocyclotron. (Midplane scaling = " << getBScale() << ")" << endl;
771 
772  } else
773  ERRORMSG("* The field reading function of this TYPE of CYCLOTRON has not implemented yet!" << endl);
774 
775  // calculate the radii of initial grid.
777 
778  // calculate the remaining derivatives
779  getdiffs();
780 }
781 
782 // evaluate other derivative of magnetic field.
784 
785  Bfield.dbr.resize(Bfield.ntot);
786  Bfield.dbrr.resize(Bfield.ntot);
787  Bfield.dbrrr.resize(Bfield.ntot);
788 
789  Bfield.dbrt.resize(Bfield.ntot);
790  Bfield.dbrrt.resize(Bfield.ntot);
791  Bfield.dbrtt.resize(Bfield.ntot);
792 
793  Bfield.f2.resize(Bfield.ntot);
794  Bfield.f3.resize(Bfield.ntot);
795  Bfield.g3.resize(Bfield.ntot);
796 
797  for(int i = 0; i < Bfield.nrad; i++) {
798 
799  for(int k = 0; k < Bfield.ntet; k++) {
800 
801  double dtheta = pi / 180.0 * BP.dtet;
802 
803  int kEdge;
804 
805  kEdge = std::max(k - 2, 0);
806  kEdge = std::min(kEdge, Bfield.ntet - 5);
807 
808  int dkFromEdge = k - kEdge;
809  int index = idx(i, k);
810  int indexkEdge = idx(i, kEdge);
811 
812 
813  Bfield.dbt[index] = gutdf5d(&Bfield.bfld[indexkEdge], dtheta, 0, dkFromEdge, 1);
814  Bfield.dbtt[index] = gutdf5d(&Bfield.bfld[indexkEdge], dtheta, 1, dkFromEdge, 1);
815  Bfield.dbttt[index] = gutdf5d(&Bfield.bfld[indexkEdge], dtheta, 2, dkFromEdge, 1);
816  }
817  }
818 
819 
820 
821  for(int k = 0; k < Bfield.ntet; k++) {
822  // inner loop varies R
823  for(int i = 0; i < Bfield.nrad; i++) {
824  double rac = BP.rarr[i];
825  // define iredg, the reference index for radial interpolation
826  // standard: i-2 minimal: 0 (not negative!) maximal: nrad-4
827  int iredg = std::max(i - 2, 0);
828  iredg = std::min(iredg, Bfield.nrad - 5);
829  int irtak = i - iredg;
830  int index = idx(i, k);
831  int indexredg = idx(iredg, k);
832 
833 
834  Bfield.dbr[index] = gutdf5d(&Bfield.bfld[indexredg], BP.delr, 0, irtak, Bfield.ntetS);
835  Bfield.dbrr[index] = gutdf5d(&Bfield.bfld[indexredg], BP.delr, 1, irtak, Bfield.ntetS);
836  Bfield.dbrrr[index] = gutdf5d(&Bfield.bfld[indexredg], BP.delr, 2, irtak, Bfield.ntetS);
837 
838  Bfield.dbrt[index] = gutdf5d(&Bfield.dbt[indexredg], BP.delr, 0, irtak, Bfield.ntetS);
839  Bfield.dbrrt[index] = gutdf5d(&Bfield.dbt[indexredg], BP.delr, 1, irtak, Bfield.ntetS);
840  Bfield.dbrtt[index] = gutdf5d(&Bfield.dbtt[indexredg], BP.delr, 0, irtak, Bfield.ntetS);
841 
842  // fehlt noch!! f2,f3,g3,
843  Bfield.f2[index] = (Bfield.dbrr[index]
844  + Bfield.dbr[index] / rac
845  + Bfield.dbtt[index] / rac / rac) / 2.0;
846 
847  Bfield.f3[index] = (Bfield.dbrrr[index]
848  + Bfield.dbrr[index] / rac
849  + (Bfield.dbrtt[index] - Bfield.dbr[index]) / rac / rac
850  - 2.0 * Bfield.dbtt[index] / rac / rac / rac) / 6.0;
851 
852  Bfield.g3[index] = (Bfield.dbrrt[index]
853  + Bfield.dbrt[index] / rac
854  + Bfield.dbttt[index] / rac / rac) / 6.0;
855  } // Radius Loop
856  } // Azimuth loop
857 
858  // copy 1st azimuth to last + 1 to always yield an interval
859  for(int i = 0; i < Bfield.nrad; i++) {
860  int iend = idx(i, Bfield.ntet);
861  int istart = idx(i, 0);
862 
863  Bfield.bfld[iend] = Bfield.bfld[istart];
864  Bfield.dbt[iend] = Bfield.dbt[istart];
865  Bfield.dbtt[iend] = Bfield.dbtt[istart];
866  Bfield.dbttt[iend] = Bfield.dbttt[istart];
867 
868  Bfield.dbr[iend] = Bfield.dbr[istart];
869  Bfield.dbrr[iend] = Bfield.dbrr[istart];
870  Bfield.dbrrr[iend] = Bfield.dbrrr[istart];
871 
872  Bfield.dbrt[iend] = Bfield.dbrt[istart];
873  Bfield.dbrtt[iend] = Bfield.dbrtt[istart];
874  Bfield.dbrrt[iend] = Bfield.dbrrt[istart];
875 
876  Bfield.f2[iend] = Bfield.f2[istart];
877  Bfield.f3[iend] = Bfield.f3[istart];
878  Bfield.g3[iend] = Bfield.g3[istart];
879 
880  }
881 
882  /* debug
883 
884  for(int i = 0; i< Bfield.nrad; i++){
885  for(int j = 0; j< Bfield.ntetS; j++){
886  int index = idx(i,j);
887  double x = (BP.rmin+i*BP.delr) * sin(j*BP.dtet*pi/180.0);
888  double y = (BP.rmin+i*BP.delr) * cos(j*BP.dtet*pi/180.0);
889  *gmsg<<"x= "<<x<<" y= "<<y<<" B= "<<Bfield.bfld[index]<<endl;
890  }
891  }
892  */
893 }
894 
895 // read field map from external file.
896 void Cyclotron::getFieldFromFile(const double &scaleFactor) {
897 
898  FILE *f = NULL;
899  int lpar;
900  char fout[100];
901  double dtmp;
902 
903  *gmsg << "* ----------------------------------------------" << endl;
904  *gmsg << "* READ IN RING FIELD MAP " << endl;
905  *gmsg << "* (The first data block is useless) " << endl;
906  *gmsg << "* ----------------------------------------------" << endl;
907 
908  BP.Bfact = scaleFactor;
909 
910  if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) {
911  throw GeneralClassicException("Cyclotron::getFieldFromField",
912  "failed to open file '" + fmapfn_m + "', please check if it exists");
913  }
914 
915  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.rmin));
916  *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl;
917  BP.rmin *= 0.001; // mm --> m
918 
919  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.delr));
920  //if the value is negative, the actual value is its reciprocal.
921  if(BP.delr < 0.0) BP.delr = 1.0 / (-BP.delr);
922  *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl;
923  BP.delr *= 0.001; // mm --> m
924 
925  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.tetmin));
926  *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl;
927 
928  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.dtet));
929  //if the value is negative, the actual value is its reciprocal.
930  if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet);
931  *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl;
932 
933  for(int i = 0; i < 13; i++)
934  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
935 
936  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &Bfield.nrad));
937  *gmsg << "* Index in radial direction: " << Bfield.nrad << endl;
938 
939  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &Bfield.ntet));
940  *gmsg << "* Index in azimuthal direction: " << Bfield.ntet << endl;
941 
942  Bfield.ntetS = Bfield.ntet + 1;
943  *gmsg << "* Accordingly, total grid point along azimuth: " << Bfield.ntetS << endl;
944 
945  for(int i = 0; i < 5; i++) {
946  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
947  }
948  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &lpar));
949  // msg<< "READ"<<lpar<<" DATA ENTRIES"<<endl;
950 
951  for(int i = 0; i < 4; i++) {
952  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
953  }
954 
955  for(int i = 0; i < lpar; i++) {
956  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &dtmp));
957  }
958  for(int i = 0; i < 6; i++) {
959  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
960  }
961  //*gmsg << "* READ FILE DESCRIPTION..." <<endl;
962  for(int i = 0; i < 10000; i++) {
963  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
964  if(strcmp(fout, "LREC=") == 0)break;
965  }
966 
967  for(int i = 0; i < 5; i++) {
968  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
969  }
970  Bfield.ntot = idx(Bfield.nrad - 1, Bfield.ntet) + 1;
971  //jjyang
972  *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << endl;
973 
974  Bfield.bfld.resize(Bfield.ntot);
975  Bfield.dbt.resize(Bfield.ntot);
976  Bfield.dbtt.resize(Bfield.ntot);
977  Bfield.dbttt.resize(Bfield.ntot);
978 
979  *gmsg << "* Read-in loop one block per radius" << endl;
980  *gmsg << "* Rescaling of the fields with factor: " << BP.Bfact << endl;
981  for(int i = 0; i < Bfield.nrad; i++) {
982 
983  if(i > 0) {
984  for(int dummy = 0; dummy < 6; dummy++) {
985  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout)); // INFO-LINE
986  }
987  }
988  for(int k = 0; k < Bfield.ntet; k++) {
989  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &(Bfield.bfld[idx(i, k)])));
990  Bfield.bfld[idx(i, k)] *= BP.Bfact;
991  }
992  for(int k = 0; k < Bfield.ntet; k++) {
993  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &(Bfield.dbt[idx(i, k)])));
994  Bfield.dbt[idx(i, k)] *= BP.Bfact;
995  }
996  for(int k = 0; k < Bfield.ntet; k++) {
997  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &(Bfield.dbtt[idx(i, k)])));
998  Bfield.dbtt[idx(i, k)] *= BP.Bfact;
999  }
1000  for(int k = 0; k < Bfield.ntet; k++) {
1001  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &(Bfield.dbttt[idx(i, k)])));
1002  Bfield.dbttt[idx(i, k)] *= BP.Bfact;
1003  }
1004  }
1005  fclose(f);
1006 
1007 
1008  *gmsg << "* Field Map read successfully!" << endl << endl;
1009 }
1010 
1011 
1012 
1013 // Calculates Radii of initial grid.
1014 // dimensions in [m]!
1015 void Cyclotron::initR(double rmin, double dr, int nrad) {
1016  BP.rarr.resize(nrad);
1017  for(int i = 0; i < nrad; i++) {
1018  BP.rarr[i] = rmin + i * dr;
1019  }
1020  BP.delr = dr;
1021 }
1022 
1023 void Cyclotron::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
1024  RefPartBunch_m = bunch;
1025  online_m = true;
1026 }
1027 
1028 void Cyclotron::initialise(PartBunchBase<double, 3> *bunch, const int &fieldflag, const double &scaleFactor) {
1029  RefPartBunch_m = bunch;
1030  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getName(), !Options::asciidump));
1031 
1032  this->read(fieldflag, scaleFactor);
1033 }
1034 
1035 
1036 void Cyclotron::getFieldFromFile_FFA(const double &scaleFactor) {
1037 
1038  /*
1039  Field is read in from ascii file (COSY output) in the order:
1040  R(m) theta(Deg) x(m) y(m) Bz(T).
1041 
1042  Theta is the fast varying variable
1043 
1044  2.0000 0.0 2.0000 0.0000 0.0000000000000000
1045  2.0000 1.0 1.9997 0.0349 0.0000000000000000
1046  2.0000 2.0 1.9988 0.0698 0.0000000000000000
1047  2.0000 3.0 1.9973 0.1047 0.0000000000000000
1048 
1049  ......
1050  <blank line>
1051 
1052  2.1000 0.0 2.1000 0.0000 0.0000000000000000
1053  2.1000 1.0 2.0997 0.0367 0.0000000000000000
1054  2.1000 2.0 2.0987 0.0733 0.0000000000000000
1055  */
1056 
1057  std::vector<double> rv;
1058  std::vector<double> thv;
1059  std::vector<double> xv;
1060  std::vector<double> yv;
1061  std::vector<double> bzv;
1063 
1064  *gmsg << "* ----------------------------------------------" << endl;
1065  *gmsg << "* READ IN FFA FIELD MAP " << endl;
1066  *gmsg << "* ----------------------------------------------" << endl;
1067 
1068  BP.Bfact = -10.0; // T->kG and H- for the current FNAL FFA
1069 
1070  std::ifstream file_to_read(fmapfn_m.c_str());
1071  const int max_num_of_char_in_a_line = 128;
1072  const int num_of_header_lines = 1;
1073 
1074  // STEP2: SKIP ALL THE HEADER LINES
1075  for(int i = 0; i < num_of_header_lines; ++i)
1076  file_to_read.ignore(max_num_of_char_in_a_line, '\n');
1077 
1078  // TEMP for OPAL 2.0 changing this to m -DW
1079  while(!file_to_read.eof()) {
1080  double r, th, x, y, bz;
1081  file_to_read >> r >> th >> x >> y >> bz;
1082  if((int)th != 360) {
1083  rv.push_back(r);
1084  thv.push_back(th);
1085  xv.push_back(x);
1086  yv.push_back(y);
1087  bzv.push_back(bz);
1088  }
1089  }
1090 
1091  double maxtheta = 360.0;
1092  BP.dtet = thv[1] - thv[0];
1093  BP.rmin = *(rv.begin());
1094  double rmax = rv.back();
1095 
1096  // find out dR
1097  for(vit = rv.begin(); *vit <= BP.rmin; ++vit) {}
1098  BP.delr = *vit - BP.rmin;
1099 
1100  BP.tetmin = thv[0];
1101 
1102  Bfield.ntet = (int)((maxtheta - thv[0]) / BP.dtet);
1103  Bfield.nrad = (int)(rmax - BP.rmin) / BP.delr + 1;
1104  Bfield.ntetS = Bfield.ntet + 1;
1105  *gmsg << "* Minimal radius of measured field map: " << 1000.0 * BP.rmin << " [mm]" << endl;
1106  *gmsg << "* Maximal radius of measured field map: " << 1000.0 * rmax << " [mm]" << endl;
1107  *gmsg << "* Stepsize in radial direction: " << 1000.0 * BP.delr << " [mm]" << endl;
1108  *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl;
1109  *gmsg << "* Maximal angle of measured field map: " << maxtheta << " [deg.]" << endl;
1110 
1111  //if the value is negtive, the actual value is its reciprocal.
1112  if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet);
1113  *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl;
1114  *gmsg << "* Total grid point along azimuth: " << Bfield.ntetS << endl;
1115  *gmsg << "* Total grid point along radius: " << Bfield.nrad << endl;
1116 
1118  *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << endl;
1119 
1120  Bfield.bfld.resize(Bfield.ntot);
1121  Bfield.dbt.resize(Bfield.ntot);
1122  Bfield.dbtt.resize(Bfield.ntot);
1123  Bfield.dbttt.resize(Bfield.ntot);
1124 
1125  *gmsg << "* Rescaling of the fields with factor: " << BP.Bfact << endl;
1126 
1127  int count = 0;
1128  if((Ippl::getNodes()) == 1 && Options::info) {
1129  std::fstream fp;
1130  fp.open("data/gnu.out", std::ios::out);
1131 
1132  for(int r = 0; r < Bfield.nrad; r++) {
1133  for(int k = 0; k < Bfield.ntet; k++) {
1134  Bfield.bfld[idx(r, k)] = bzv[count] * BP.Bfact;
1135  fp << BP.rmin + (r * BP.delr) << " \t "
1136  << k*(BP.tetmin + BP.dtet) << " \t "
1137  << Bfield.bfld[idx(r, k)] << std::endl;
1138  count++;
1139  }
1140  }
1141  fp.close();
1142  }
1143 
1144  *gmsg << "* Field Map read successfully nelem= " << count << endl << endl;
1145 }
1146 
1147 void Cyclotron::getFieldFromFile_AVFEQ(const double &scaleFactor) {
1148 
1149  FILE *f = NULL;
1150  *gmsg << "* ----------------------------------------------" << endl;
1151  *gmsg << "* READ IN AVFEQ CYCLOTRON FIELD MAP " << endl;
1152  *gmsg << "* ----------------------------------------------" << endl;
1153 
1154  /* From Hiroki-san
1155  The first line tells r minimum (500mm),
1156  r maximum(4150mm),
1157  r step(50mm),
1158  theta minimum(0deg),
1159  theta maximum(90deg)
1160  theta step(0.5deg).
1161 
1162  From the next line data repeat the block for a given r which the
1163  first line of the block tells. Each block consists of the data Bz
1164  from theta minimum (0deg) to theta maximum(90deg) with theta
1165  step(0.5deg).
1166  */
1167 
1168  BP.Bfact = scaleFactor / 1000.;
1169 
1170  if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) {
1172  "Cyclotron::getFieldFromFile_AVFEQ",
1173  "failed to open file '" + fmapfn_m + "', please check if it exists");
1174  }
1175 
1176  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.rmin));
1177  *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl;
1178  BP.rmin *= 0.001; // mm --> m
1179 
1180  double rmax;
1181  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &rmax));
1182  *gmsg << "* Maximal radius of measured field map: " << rmax << " [mm]" << endl;
1183  rmax *= 0.001; // mm --> m
1184 
1185  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.delr));
1186  *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl;
1187  BP.delr *= 0.001; // mm --> m
1188 
1189  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.tetmin));
1190  *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl;
1191 
1192  double tetmax;
1193  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &tetmax));
1194  *gmsg << "* Maximal angle of measured field map: " << tetmax << " [deg.]" << endl;
1195 
1196  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.dtet));
1197  //if the value is nagtive, the actual value is its reciprocal.
1198 
1199  if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet);
1200  *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl;
1201 
1202  Bfield.ntetS = (int)((tetmax - BP.tetmin) / BP.dtet + 1);
1203  *gmsg << "* Total grid point along azimuth: " << Bfield.ntetS << endl;
1204 
1205  Bfield.nrad = (int)(rmax - BP.rmin) / BP.delr;
1206 
1207  int ntotidx = idx(Bfield.nrad, Bfield.ntetS) + 1;
1208 
1210  *gmsg << "* Total stored grid point number ( ntetS * nrad ) : "
1211  << Bfield.ntot << " ntot-idx= " << ntotidx << endl;
1212 
1213  Bfield.bfld.resize(Bfield.ntot);
1214  Bfield.dbt.resize(Bfield.ntot);
1215  Bfield.dbtt.resize(Bfield.ntot);
1216  Bfield.dbttt.resize(Bfield.ntot);
1217 
1218  *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl;
1219 
1220  std::fstream fp;
1221  if((Ippl::getNodes()) == 1 && Options::info)
1222  fp.open("data/gnu.out", std::ios::out);
1223 
1224  double tmp;
1225  int count = 0;
1226 
1227  for(int r = 0; r < Bfield.nrad; r++) {
1228  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &tmp)); // over read
1229  for(int k = 0; k < Bfield.ntetS; k++) {
1230  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &(Bfield.bfld[idx(r, k)])));
1231  Bfield.bfld[idx(r, k)] *= BP.Bfact;
1232  if((Ippl::getNodes()) == 1 && Options::info)
1233  fp << BP.rmin + (r * BP.delr) << " \t "
1234  << k*(BP.tetmin + BP.dtet) << " \t "
1235  << Bfield.bfld[idx(r, k)] << " idx= " << idx(r, k) << std::endl;
1236  count++;
1237  }
1238  }
1239  if((Ippl::getNodes()) == 1 && Options::info)
1240  fp.close();
1241  fclose(f);
1242  *gmsg << "* Field Map read successfully nelem= " << count << endl << endl;
1243 }
1244 
1245 
1246 // read field map from external file.
1247 void Cyclotron::getFieldFromFile_Carbon(const double &scaleFactor) {
1248 
1249  FILE *f = NULL;
1250  *gmsg << "* ----------------------------------------------" << endl;
1251  *gmsg << "* READ IN CARBON CYCLOTRON FIELD MAP " << endl;
1252  *gmsg << "* ----------------------------------------------" << endl;
1253 
1254  BP.Bfact = scaleFactor;
1255 
1256  if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) {
1257  throw GeneralClassicException("Cyclotron::getFieldFromFile_Carbon",
1258  "failed to open file '" + fmapfn_m + "', please check if it exists");
1259  }
1260 
1261  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.rmin));
1262  *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl;
1263  BP.rmin *= 0.001; // mm --> m
1264 
1265  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.delr));
1266  //if the value is negative, the actual value is its reciprocal.
1267  if(BP.delr < 0.0) BP.delr = 1.0 / (-BP.delr);
1268  *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl;
1269  BP.delr *= 0.001; // mm --> m
1270 
1271  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.tetmin));
1272  *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg]" << endl;
1273 
1274  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.dtet));
1275  //if the value is negative, the actual value is its reciprocal.
1276  if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet);
1277  *gmsg << "* Stepsize in azimuthal direction: " << BP.dtet << " [deg]" << endl;
1278 
1279  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &Bfield.ntet));
1280  *gmsg << "* Grid points along azimuth (ntet): " << Bfield.ntet << endl;
1281 
1282  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &Bfield.nrad));
1283  *gmsg << "* Grid points along radius (nrad): " << Bfield.nrad << endl;
1284 
1285 // Bfield.ntetS = Bfield.ntet;
1286  Bfield.ntetS = Bfield.ntet + 1;
1287  //*gmsg << "* Accordingly, total grid point along azimuth: " << Bfield.ntetS << endl;
1288 
1289  //Bfield.ntot = idx(Bfield.nrad - 1, Bfield.ntet) + 1;
1291 
1292  *gmsg << "* Adding a guard cell along azimuth" << endl;
1293  *gmsg << "* Total stored grid point number ((ntet+1) * nrad) : " << Bfield.ntot << endl;
1294  Bfield.bfld.resize(Bfield.ntot);
1295  Bfield.dbt.resize(Bfield.ntot);
1296  Bfield.dbtt.resize(Bfield.ntot);
1297  Bfield.dbttt.resize(Bfield.ntot);
1298 
1299  *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl;
1300 
1301  for(int i = 0; i < Bfield.nrad; i++) {
1302  for(int k = 0; k < Bfield.ntet; k++) {
1303  CHECK_CYC_FSCANF_EOF(fscanf(f, "%16lE", &(Bfield.bfld[idx(i, k)])));
1304  Bfield.bfld[idx(i, k)] *= BP.Bfact;
1305  }
1306  }
1307 
1308  if((Ippl::getNodes()) == 1 && Options::info) {
1309  std::fstream fp1, fp2;
1310  fp1.open("data/gnu.out", std::ios::out);
1311  fp2.open("data/eb.out", std::ios::out);
1312  for(int i = 0; i < Bfield.nrad; i++) {
1313  for(int k = 0; k < Bfield.ntet; k++) {
1314  fp1 << BP.rmin + (i * BP.delr) << " \t "
1315  << k * (BP.tetmin + BP.dtet) << " \t "
1316  << Bfield.bfld[idx(i, k)] << std::endl;
1317 
1318  Vector_t tmpR = Vector_t (BP.rmin + (i * BP.delr), 0.0, k * (BP.tetmin + BP.dtet));
1319  Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
1320  tmpR /= 1000.0; // -> mm to m
1321  for (auto& fi: RFfields_m) {
1322  Vector_t E(0.0, 0.0, 0.0), B(0.0, 0.0, 0.0);
1323  if(!fi->getFieldstrength(tmpR, tmpE, tmpB)) {
1324  tmpE += E;
1325  tmpB -= B;
1326  }
1327  }
1328  fp2 << tmpR << " \t E= " << tmpE << "\t B= " << tmpB << std::endl;
1329  }
1330  }
1331  fp1.close();
1332  fp2.close();
1333  }
1334 
1335  fclose(f);
1336 
1337  *gmsg << "* Field Maps read successfully!" << endl << endl;
1338 }
1339 
1340 
1341 // read field map from external file.
1342 void Cyclotron::getFieldFromFile_CYCIAE(const double &scaleFactor) {
1343 
1344  FILE *f = NULL;
1345  char fout[100];
1346  int dtmp;
1347 
1348  *gmsg << "* ----------------------------------------------" << endl;
1349  *gmsg << "* READ IN CYCIAE-100 CYCLOTRON FIELD MAP " << endl;
1350  *gmsg << "* ----------------------------------------------" << endl;
1351 
1352  BP.Bfact = scaleFactor;
1353 
1354  if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) {
1355  throw GeneralClassicException("Cyclotron::getFieldFromFile_CYCIAE",
1356  "failed to open file '" + fmapfn_m + "', please check if it exists");
1357  }
1358 
1359  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.rmin));
1360  *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl;
1361  BP.rmin *= 0.001; // mm --> m
1362 
1363  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.delr));
1364  *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl;
1365  BP.delr *= 0.001; // mm --> m
1366 
1367  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.tetmin));
1368  *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl;
1369 
1370  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &BP.dtet));
1371  //if the value is nagtive, the actual value is its reciprocal.
1372  if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet);
1373  *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl;
1374 
1375  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &Bfield.ntet));
1376  *gmsg << "* Index in azimuthal direction: " << Bfield.ntet << endl;
1377 
1378  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &Bfield.nrad));
1379  *gmsg << "* Index in radial direction: " << Bfield.nrad << endl;
1380 
1381  Bfield.ntetS = Bfield.ntet + 1;
1382  *gmsg << "* Accordingly, total grid point along azimuth: " << Bfield.ntetS << endl;
1383 
1384  Bfield.ntot = idx(Bfield.nrad - 1, Bfield.ntet) + 1;
1385 
1386  *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << endl;
1387  Bfield.bfld.resize(Bfield.ntot);
1388  Bfield.dbt.resize(Bfield.ntot);
1389  Bfield.dbtt.resize(Bfield.ntot);
1390  Bfield.dbttt.resize(Bfield.ntot);
1391 
1392  *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl;
1393 
1394  int nHalfPoints = Bfield.ntet / 2.0 + 1;
1395 
1396  for(int i = 0; i < Bfield.nrad; i++) {
1397 
1398  for(int ii = 0; ii < 13; ii++)
1399  CHECK_CYC_FSCANF_EOF(fscanf(f, "%s", fout));
1400 
1401  for(int k = 0; k < nHalfPoints; k++) {
1402  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &dtmp));
1403  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &dtmp));
1404  CHECK_CYC_FSCANF_EOF(fscanf(f, "%d", &dtmp));
1405  CHECK_CYC_FSCANF_EOF(fscanf(f, "%lf", &(Bfield.bfld[idx(i, k)])));
1406  // T --> kGs, minus for minus hydrogen
1407  Bfield.bfld[idx(i, k)] = Bfield.bfld[idx(i, k)] * (-10.0);
1408  }
1409 
1410  for(int k = nHalfPoints; k < Bfield.ntet; k++) {
1411  Bfield.bfld[idx(i, k)] = Bfield.bfld[idx(i, Bfield.ntet-k)];
1412  }
1413  }
1414 
1415  fclose(f);
1416 
1417  *gmsg << "* Field Map read successfully!" << endl << endl;
1418 }
1419 
1420 void Cyclotron::getFieldFromFile_BandRF(const double &scaleFactor) {
1421 
1422  // read 3D E&B field data file
1423 
1424  // loop over all field maps and superpose fields
1425  for(auto& fm: RFfilename_m) {
1426  *gmsg << "* Reading " << fm << endl;
1427  Fieldmap *f = Fieldmap::getFieldmap(fm, false);
1428  if(f == NULL) {
1430  "Cyclotron::getFieldFromFile_BandRF",
1431  "failed to open file '" + fm + "', please check if it exists");
1432  }
1433  f->readMap();
1434  RFfields_m.push_back(f);
1435  }
1436  // read CARBON type B field
1437  getFieldFromFile_Carbon(scaleFactor);
1438 }
1439 
1440 void Cyclotron::getFieldFromFile_Synchrocyclotron(const double &scaleFactor) {
1441 
1442  // read 3D E&B field data file
1443  std::vector<std::string>::const_iterator fm = RFfilename_m.begin();
1444  std::vector<std::string>::const_iterator rffcfni = RFFCoeff_fn_m.begin();
1445  std::vector<std::string>::const_iterator rfvcfni = RFVCoeff_fn_m.begin();
1446  // loop over all field maps and superpose fields
1447  int fcount = 0;
1448  FILE *rffcf = NULL;
1449  FILE *rfvcf = NULL;
1450 
1451  *gmsg << endl;
1452  *gmsg << "* ------------------------------------------------------------" << endl;
1453  *gmsg << "* READ IN 3D RF Fields and Frequency Coefficients " << endl;
1454  *gmsg << "* ------------------------------------------------------------" << endl;
1455 
1456  for(; fm != RFfilename_m.end(); ++fm, ++rffcfni, ++rfvcfni, ++fcount) {
1457  Fieldmap *f = Fieldmap::getFieldmap(*fm, false);
1458  if(f == NULL) {
1460  "Cyclotron::getFieldFromFile_Synchrocyclotron",
1461  "failed to open file '" + *fm + "', please check if it exists");
1462  }
1463  f->readMap();
1464  // if (IPPL::Comm->getOutputLevel() != 0) f->getInfo(gmsg);
1465  RFfields_m.push_back(f);
1466 
1467  // Read RF Frequency Coefficients from file
1468  *gmsg << "RF Frequency Coefficient Filename: " << (*rffcfni) << endl;
1469 
1470  rffcf = fopen((*rffcfni).c_str(), "r");
1471 
1472  if(rffcf == NULL) {
1474  "Cyclotron::getFieldFromFile_Synchrocyclotron",
1475  "failed to open file '" + *rffcfni + "', please check if it exists");
1476  }
1477 
1478  std::vector<double> fcoeff;
1479 
1480  int nc; //Number of coefficients
1481  double value;
1482 
1483  CHECK_CYC_FSCANF_EOF(fscanf(rffcf, "%d", &nc));
1484  *gmsg << "* Number of coefficients in file: " << nc << endl;
1485  for(int k = 0; k < nc; k++) {
1486  CHECK_CYC_FSCANF_EOF(fscanf(rffcf, "%16lE", &value));
1487  fcoeff.push_back(value);
1488  //*gmsg << "* Coefficient " << k << ": " << value << endl;
1489  }
1490  rffc_m.push_back(fcoeff);
1491 
1492  fclose(rffcf);
1493 
1494  // Read RF Voltage Coefficients from file
1495  *gmsg << "RF Voltage Coefficient Filename: " << (*rfvcfni) << endl;
1496 
1497  rfvcf = fopen((*rfvcfni).c_str(), "r");
1498 
1499  if(rfvcf == NULL) {
1501  "Cyclotron::getFieldFromFile_Synchrocyclotron",
1502  "failed to open file '" + *rfvcfni + "', please check if it exists");
1503  }
1504 
1505  std::vector<double> vcoeff;
1506 
1507  CHECK_CYC_FSCANF_EOF(fscanf(rfvcf, "%d", &nc));
1508  *gmsg << "* Number of coefficients in file: " << nc << endl;
1509  for(int k = 0; k < nc; k++) {
1510  CHECK_CYC_FSCANF_EOF(fscanf(rfvcf, "%16lE", &value));
1511  vcoeff.push_back(value);
1512  //*gmsg << "* Coefficient " << k << ": " << value << endl;
1513  }
1514  rfvc_m.push_back(vcoeff);
1515 
1516  fclose(rfvcf);
1517  }
1518 
1519  // read CARBON type B field for mid-plane field
1520  getFieldFromFile_Carbon(scaleFactor);
1521 }
1522 
1523 void Cyclotron::getDimensions(double &zBegin, double &zEnd) const
1524 { }
1525 
1526 #undef CHECK_CYC_FSCANF_EOF
1527 
1528 // vi: set et ts=4 sw=4 sts=4:
1529 // Local Variables:
1530 // mode:c
1531 // c-basic-offset: 4
1532 // indent-tabs-mode:nil
1533 // End:
virtual double getMaxR() const
Definition: Cyclotron.cpp:310
int nrad
Definition: Cyclotron.h:59
virtual void finalise()
Definition: Cyclotron.cpp:520
static int getNodes()
Definition: IpplInfo.cpp:773
virtual double getRmin() const
Definition: Cyclotron.cpp:285
ParticleAttrib< Vector_t > P
void setFMLowE(double e)
Definition: Cyclotron.cpp:335
std::vector< std::string > RFfilename_m
Definition: Cyclotron.h:289
void fp1(BareField< T, 1U > &field, bool docomm=true)
Definition: FieldDebug.hpp:43
bool interpolate(const double &rad, const double &tet_rad, double &br, double &bt, double &bz)
Definition: Cyclotron.cpp:646
virtual double getTrimCoilThreshold() const
Definition: Cyclotron.cpp:152
double trimCoilThreshold_m
B-field threshold for applying trim coil.
Definition: Cyclotron.h:261
double zinit_m
Definition: Cyclotron.h:257
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
double gutdf5d(double *f, double dx, const int kor, const int krl, const int lpr)
Definition: Cyclotron.cpp:533
double harm_m
Definition: Cyclotron.h:264
constexpr double e
The value of .
Definition: Physics.h:40
void setRinit(double rinit)
Definition: Cyclotron.cpp:108
virtual bool getSpiralFlag() const
Definition: Cyclotron.cpp:160
void setFMHighE(double e)
Definition: Cyclotron.cpp:338
std::string fmapfn_m
Definition: Cyclotron.h:243
std::vector< double > g3
Definition: Cyclotron.h:55
BPositions BP
Definition: Cyclotron.h:304
virtual double getZinit() const
Definition: Cyclotron.cpp:136
#define INFORM_ALL_NODES
Definition: Inform.h:38
void applyTrimCoil_m(const double r, const double z, const double tet_rad, double *br, double *bz)
Apply trim coils (calculate field contributions)
Definition: Cyclotron.cpp:81
Interface for a Cyclotron.
Definition: Cyclotron.h:91
std::vector< Fieldmap * > RFfields_m
Definition: Cyclotron.h:288
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
virtual double getPHIinit() const
Definition: Cyclotron.cpp:128
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
std::vector< std::vector< double > > rfvc_m
Definition: Cyclotron.h:247
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
double fmHighE_m
Definition: Cyclotron.h:278
int ntot
Definition: Cyclotron.h:65
double dtet
Definition: Cyclotron.h:76
void getFieldFromFile_AVFEQ(const double &scaleFactor)
Definition: Cyclotron.cpp:1147
void setTrimCoils(const std::vector< TrimCoil * > &trimcoils)
Definition: Cyclotron.cpp:331
virtual ~Cyclotron()
Definition: Cyclotron.cpp:77
void setFieldMapFN(std::string fmapfn)
Definition: Cyclotron.cpp:164
void setRFFCoeffFN(std::vector< std::string > rff_coeff_fn)
Definition: Cyclotron.cpp:176
Inform * gmsg
Definition: Main.cpp:21
void setSuperpose(std::vector< bool > flag)
Definition: Cyclotron.cpp:232
bool online_m
Definition: Component.h:201
virtual double getSymmetry() const
Definition: Cyclotron.cpp:244
void setMaxR(double r)
Definition: Cyclotron.cpp:301
std::vector< double > f3
Definition: Cyclotron.h:54
double fmLowE_m
Definition: Cyclotron.h:277
void fp2(BareField< T, 2U > &field, bool docomm=true)
Definition: FieldDebug.hpp:56
void getFieldFromFile_CYCIAE(const double &scaleFactor)
Definition: Cyclotron.cpp:1342
double maxz_m
Definition: Cyclotron.h:275
const std::string & getCyclotronType() const
Definition: Cyclotron.cpp:253
virtual const std::string & getName() const
Get element name.
Definition: ElementBase.cpp:95
ParticleAttrib< short > bunchNum
double tetmin
Definition: Cyclotron.h:76
double rmin
Definition: Cyclotron.h:75
std::vector< double > dbt
Definition: Cyclotron.h:39
void applyTrimCoil(const double r, const double z, const double tet_rad, double &br, double &bz)
Apply trim coils (calculate field contributions) with smooth field transition.
Definition: Cyclotron.cpp:89
std::vector< double > dbtt
Definition: Cyclotron.h:40
double rinit_m
Definition: Cyclotron.h:254
double delr
Definition: Cyclotron.h:75
std::vector< double > f2
Definition: Cyclotron.h:53
bool info
Info flag.
Definition: Options.cpp:8
static Fieldmap * getFieldmap(std::string Filename, bool fast=false)
Definition: Fieldmap.cpp:46
double minr_m
Definition: Cyclotron.h:271
int waiting_for_gap
Definition: Cyclotron.h:297
Inform & level4(Inform &inf)
Definition: Inform.cpp:48
double symmetry_m
Definition: Cyclotron.h:252
std::vector< std::vector< double > > rffc_m
Definition: Cyclotron.h:245
void getFieldFromFile_FFA(const double &scaleFactor)
Definition: Cyclotron.cpp:1036
std::vector< double > bfld
Definition: Cyclotron.h:38
std::vector< std::string > RFVCoeff_fn_m
Definition: Cyclotron.h:291
std::vector< double > dbrt
Definition: Cyclotron.h:48
virtual double getMinZ() const
Definition: Cyclotron.cpp:319
virtual bool apply(const size_t &id, const double &t, Vector_t &E, Vector_t &B)
Definition: Cyclotron.cpp:342
void setRfFieldMapFN(std::vector< std::string > rffmapfn)
Definition: Cyclotron.cpp:172
std::vector< double > dbrr
Definition: Cyclotron.h:45
virtual double getFMHighE() const
Definition: Cyclotron.cpp:339
#define CHECK_CYC_FSCANF_EOF(arg)
Definition: Cyclotron.cpp:25
virtual double getCyclHarm() const
Definition: Cyclotron.cpp:281
virtual double getMinR() const
Definition: Cyclotron.cpp:306
bool spiral_flag_m
Definition: Cyclotron.h:260
std::string type_m
Definition: Cyclotron.h:263
void setCyclHarm(double h)
Definition: Cyclotron.cpp:261
virtual void getDimensions(double &zBegin, double &zEnd) const
Definition: Cyclotron.cpp:1523
void getFieldFromFile_Carbon(const double &scaleFactor)
Definition: Cyclotron.cpp:1247
static void readMap(std::string Filename)
Definition: Fieldmap.cpp:416
void setMinZ(double z)
Definition: Cyclotron.cpp:314
void setPZinit(double zinit)
Definition: Cyclotron.cpp:140
std::vector< double > rarr
Definition: Cyclotron.h:79
constexpr double pi
The value of .
Definition: Physics.h:31
virtual double getBScale() const
Definition: Cyclotron.cpp:269
std::vector< double > rfphi_m
Definition: Cyclotron.h:248
void setEScale(std::vector< double > bs)
Definition: Cyclotron.cpp:273
void setPRinit(double prinit)
Definition: Cyclotron.cpp:116
void setMinR(double r)
Definition: Cyclotron.cpp:295
double phiinit_m
Definition: Cyclotron.h:256
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField)
Definition: Cyclotron.cpp:1023
const double pi
Definition: fftpack.cpp:894
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:810
void setRfPhi(std::vector< double > f)
Definition: Cyclotron.cpp:215
void getFieldFromFile_BandRF(const double &scaleFactor)
Definition: Cyclotron.cpp:1420
void setType(std::string t)
Definition: Cyclotron.cpp:249
virtual double getPZinit() const
Definition: Cyclotron.cpp:144
std::vector< std::string > RFFCoeff_fn_m
Definition: Cyclotron.h:290
void setRfFrequ(std::vector< double > f)
Definition: Cyclotron.cpp:219
virtual std::string getFieldMapFN() const
Definition: Cyclotron.cpp:168
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:200
double minz_m
Definition: Cyclotron.h:274
unsigned int getNumberOfTrimcoils() const
Definition: Cyclotron.cpp:277
double bscale_m
Definition: Cyclotron.h:266
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
virtual double getPRinit() const
Definition: Cyclotron.cpp:120
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
void getFieldFromFile(const double &scaleFactor)
Definition: Cyclotron.cpp:896
virtual double getFMLowE() const
Definition: Cyclotron.cpp:336
std::vector< double > dbr
Definition: Cyclotron.h:44
virtual void accept(BeamlineVisitor &) const
Apply visitor to Cyclotron.
Definition: Cyclotron.cpp:104
int getFieldFlag(const std::string &type) const
Definition: Cyclotron.cpp:184
std::unique_ptr< LossDataSink > lossDs_m
Definition: Cyclotron.h:294
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
double maxr_m
Definition: Cyclotron.h:272
void setPHIinit(double phiinit)
Definition: Cyclotron.cpp:124
BFieldType myBFieldType_m
Definition: Cyclotron.h:284
std::vector< double > rffrequ_m
Definition: Cyclotron.h:244
T rad(T x)
Convert degrees to radians.
Definition: matheval.hpp:86
void setZinit(double zinit)
Definition: Cyclotron.cpp:132
virtual double getRmax() const
Definition: Cyclotron.cpp:290
void setRFVCoeffFN(std::vector< std::string > rfv_coeff_fn)
Definition: Cyclotron.cpp:180
bool asciidump
Definition: Options.cpp:18
std::vector< double > escale_m
Definition: Cyclotron.h:249
std::vector< TrimCoil * > trimcoils_m
Trim coils.
Definition: Cyclotron.h:269
virtual double getRinit() const
Definition: Cyclotron.cpp:112
int idx(int irad, int ktet)
Definition: Cyclotron.h:238
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
int ntet
Definition: Cyclotron.h:59
void setMaxZ(double z)
Definition: Cyclotron.cpp:322
double getRfFrequ() const
Definition: Cyclotron.cpp:223
std::vector< double > dbttt
Definition: Cyclotron.h:41
const std::string name
double pzinit_m
Definition: Cyclotron.h:258
int ntetS
Definition: Cyclotron.h:62
void setBScale(double bs)
Definition: Cyclotron.cpp:265
ParticleAttrib< int > Bin
void setSymmetry(double symmetry)
Definition: Cyclotron.cpp:240
ParticlePos_t & R
std::string::iterator iterator
Definition: MSLang.h:16
double Bfact
Definition: Cyclotron.h:82
void setTrimCoilThreshold(double)
Definition: Cyclotron.cpp:148
virtual double getMaxZ() const
Definition: Cyclotron.cpp:327
Interface for a single beam element.
Definition: Component.h:51
Abstract algorithm.
Definition: Inform.h:41
virtual void visitCyclotron(const Cyclotron &)=0
Apply the algorithm to a cyclotron.
std::vector< bool > superpose_m
Definition: Cyclotron.h:250
void setSpiralFlag(bool spiral_flag)
Definition: Cyclotron.cpp:156
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
virtual bool bends() const
Definition: Cyclotron.cpp:528
std::vector< double > dbrrr
Definition: Cyclotron.h:46
void getdiffs()
Definition: Cyclotron.cpp:783
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void initR(double rmin, double dr, int nrad)
Definition: Cyclotron.cpp:1015
void getFieldFromFile_Synchrocyclotron(const double &scaleFactor)
Definition: Cyclotron.cpp:1440
void read(const int &fieldflag, const double &scaleFactor)
Definition: Cyclotron.cpp:733
BfieldData Bfield
Definition: Cyclotron.h:301
std::vector< double > dbrtt
Definition: Cyclotron.h:50
double prinit_m
Definition: Cyclotron.h:255
virtual ElementBase::ElementType getType() const
Get element type std::string.
Definition: Cyclotron.cpp:257
std::vector< double > dbrrt
Definition: Cyclotron.h:49