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