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