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