40#include <boost/filesystem.hpp>
48#define CHECK_CYC_FSCANF_EOF(arg) if (arg == EOF)\
49throw GeneralClassicException("Cyclotron::getFieldFromFile",\
50 "fscanf returned EOF at " #arg);
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),
76 bscale_m(right.bscale_m),
77 trimcoils_m(right.trimcoils_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) {
99 double* br,
double* bz) {
101 trimcoil->applyField(r, z, tet_rad, br, bz);
106 const double tet_rad,
107 double& br,
double& bz) {
186 "Cyclotron::getFieldMapFN",
187 "The attribute \"FMAPFN\" isn't set for the \"CYCLOTRON\" element!");
188 }
else if (boost::filesystem::exists(
fmapfn_m)) {
192 "Failed to open file '" +
fmapfn_m +
193 "', please check if it exists");
218 "RFPHI not defined for CYCLOTRON!");
231 "RFFREQ not defined for CYCLOTRON!");
244 "SUPERPOSE not defined for CYCLOTRON!");
289 "EScale not defined for CYCLOTRON!");
370 static const std::map<std::string, BFieldType> typeStringToBFieldType_s = {
382 "Cyclotron::setBFieldType",
383 "The attribute \"TYPE\" isn't set for the \"CYCLOTRON\" element!");
395 bool flagNeedUpdate =
false;
402 flagNeedUpdate =
true;
404 <<
" out of the global aperture of cyclotron!" <<
endl;
410 if (flagNeedUpdate) {
412 <<
" out of the field map boundary!" <<
endl;
418 if (flagNeedUpdate) {
425 return flagNeedUpdate;
431 const double rad = std::hypot(
R[0],
R[1]);
438 else if ((
R[0] < 0) && (
R[1] <= 0)) tet =
Physics::pi + tempv;
443 double tet_rad = tet;
452 double brint = 0.0, btint = 0.0, bzint = 0.0;
454 if ( this->
interpolate(rad, tet_rad, brint, btint, bzint) ) {
457 double br = - brint *
R[2];
460 double bt = - btint /
rad *
R[2];
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();
488 double xBegin(0), xEnd(0), yBegin(0), yEnd(0), zBegin(0), zEnd(0);
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;
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;
503 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
505 if ((*fi)->getFieldstrength(temp_R, tmpE, tmpB))
continue;
509 double frequency = (*rffi);
510 double ebscale = (*escali);
514 for (
const double fcoef : (*rffci)) {
516 frequency += fcoef * powert;
519 for (
const double vcoef : (*rfvci)) {
521 ebscale += vcoef * powert;
527 E += ebscale *
std::cos(phase) * tmpE;
528 B -= ebscale *
std::sin(phase) * tmpB;
536 phase_print =
std::fmod(phase_print, 360) - 360.0;
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;
545 phase_print =
std::fmod(phase_print, 360) - 360.0;
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;
561 const double& tet_rad,
double& br,
562 double& bt,
double& bz) {
579 const int krl,
const int lpr) {
581 double C[5][5][3], FAC[3];
682 for (j = 0; j < 5; j++) {
683 result += C[j][krl][kor] * *(f + j * lpr);
686 return result / (FAC[kor] *
std::pow(dx, (kor + 1)));
691 const double& tet_rad,
699 const int ir = (
int)xir;
702 const double wr1 = xir - (double)ir;
704 const double wr2 = 1.0 - wr1;
713 const double wt1 = xit - (double)it;
714 const double wt2 = 1.0 - wt1;
721 int r1t1, r2t1, r1t2, r2t2;
731 r1t1 = it + ntetS * ir - 1;
742 r2t1 =
idx(ir + 1, it);
743 r1t2 =
idx(ir, it + 1);
744 r2t2 =
idx(ir + 1, it + 1);
776 *
gmsg <<
"* Read field data from PSI format field map file" <<
endl;
781 *
gmsg <<
"* Read data from 450MeV Carbon cyclotron field file" <<
endl;
786 *
gmsg <<
"* Read data from 100MeV H- cyclotron CYCIAE-100 field file" <<
endl;
791 *
gmsg <<
"* Read AVFEQ data (Riken)" <<
endl;
796 *
gmsg <<
"* Read FFA data MSU/FNAL" <<
endl;
801 *
gmsg <<
"* Read both median plane B field map and 3D E field map of RF cavity for compact cyclotron" <<
endl;
806 *
gmsg <<
"* Read midplane B-field, 3D RF fieldmaps, and text files with RF frequency/Voltage coefficients for Synchrocyclotron" <<
endl;
812 "Unknown \"TYPE\" for the \"CYCLOTRON\" element!");
848 int dkFromEdge = k - kEdge;
849 int index =
idx(i, k);
850 int indexkEdge =
idx(i, kEdge);
866 int irtak = i - iredg;
867 int index =
idx(i, k);
868 int indexredg =
idx(iredg, k);
897 int istart =
idx(i, 0);
935 for (
int i = 0; i < nrad; i++) {
950 this->
read(scaleFactor);
962 *
gmsg <<
"* ----------------------------------------------" <<
endl;
963 *
gmsg <<
"* READ IN RING FIELD MAP " <<
endl;
964 *
gmsg <<
"* (The first data block is useless) " <<
endl;
965 *
gmsg <<
"* ----------------------------------------------" <<
endl;
969 f = std::fopen(
fmapfn_m.c_str(),
"r");
972 *
gmsg <<
"* Minimal radius of measured field map: " <<
BP_m.
rmin_m <<
" [mm]" <<
endl;
989 for (
int i = 0; i < 13; i++) {
1002 for (
int i = 0; i < 5; i++) {
1008 for (
int i = 0; i < 4; i++) {
1012 for (
int i = 0; i < lpar; i++) {
1015 for (
int i = 0; i < 6; i++) {
1019 for (
int i = 0; i < 10000; i++) {
1021 if (std::strcmp(fout,
"LREC=") == 0)
break;
1024 for (
int i = 0; i < 5; i++) {
1035 *
gmsg <<
"* Read-in loop one block per radius" <<
endl;
1039 for (
int dummy = 0; dummy < 6; dummy++) {
1062 *
gmsg <<
"* Field Map read successfully!" <<
endl <<
endl;
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;
1094 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1095 *
gmsg <<
"* READ IN FFA FIELD MAP " <<
endl;
1096 *
gmsg <<
"* ----------------------------------------------" <<
endl;
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;
1105 for (
int i = 0; i < num_of_header_lines; ++i)
1106 file_to_read.ignore(max_num_of_char_in_a_line,
'\n');
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) {
1121 double maxtheta = 360.0;
1124 double rmax = rv.back();
1127 for (vit = rv.begin(); *vit <=
BP_m.
rmin_m; ++vit) {}
1136 *
gmsg <<
"* Maximal radius of measured field map: " <<
Units::m2mm * rmax <<
" [mm]" <<
endl;
1139 *
gmsg <<
"* Maximal angle of measured field map: " << maxtheta <<
" [deg]" <<
endl;
1168 *
gmsg <<
"* Number of elements read: " << count <<
endl;
1169 *
gmsg <<
"* Field Map read successfully!" <<
endl <<
endl;
1176 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1177 *
gmsg <<
"* READ IN AVFEQ CYCLOTRON FIELD MAP " <<
endl;
1178 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1196 f = std::fopen(
fmapfn_m.c_str(),
"r");
1199 *
gmsg <<
"* Minimal radius of measured field map: " <<
BP_m.
rmin_m <<
" [mm]" <<
endl;
1204 *
gmsg <<
"* Maximal radius of measured field map: " << rmax <<
" [mm]" <<
endl;
1216 *
gmsg <<
"* Maximal angle of measured field map: " << tetmax <<
" [deg]" <<
endl;
1232 *
gmsg <<
"* Total stored grid point number ( ntetS * nrad ): "
1258 *
gmsg <<
"* Number of elements read: " << count <<
endl;
1259 *
gmsg <<
"* Field Map read successfully!" <<
endl <<
endl;
1266 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1267 *
gmsg <<
"* READ IN CARBON CYCLOTRON FIELD MAP " <<
endl;
1268 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1272 f = std::fopen(
fmapfn_m.c_str(),
"r");
1275 *
gmsg <<
"* Minimal radius of measured field map: " <<
BP_m.
rmin_m <<
" [mm]" <<
endl;
1305 *
gmsg <<
"* Adding a guard cell along azimuth" <<
endl;
1326 *
gmsg <<
"* Field Map read successfully!" <<
endl <<
endl;
1336 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1337 *
gmsg <<
"* READ IN CYCIAE-100 CYCLOTRON FIELD MAP " <<
endl;
1338 *
gmsg <<
"* ----------------------------------------------" <<
endl;
1342 f = std::fopen(
fmapfn_m.c_str(),
"r");
1345 *
gmsg <<
"* Minimal radius of measured field map: " <<
BP_m.
rmin_m <<
" [mm]" <<
endl;
1382 for (
int ii = 0; ii < 13; ii++) {
1385 for (
int k = 0; k < nHalfPoints; k++) {
1399 *
gmsg <<
"* Field Map read successfully!" <<
endl <<
endl;
1408 *
gmsg <<
"* Reading '" << fm <<
"'" <<
endl;
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();
1425 FILE *rffcf =
nullptr;
1426 FILE *rfvcf =
nullptr;
1429 *
gmsg <<
"* ------------------------------------------------------------" <<
endl;
1430 *
gmsg <<
"* READ IN 3D RF Fields and Frequency Coefficients " <<
endl;
1431 *
gmsg <<
"* ------------------------------------------------------------" <<
endl;
1433 for (; fm !=
RFfilename_m.end(); ++fm, ++rffcfni, ++rfvcfni, ++fcount) {
1440 *
gmsg <<
"RF Frequency Coefficient Filename: " << (*rffcfni) <<
endl;
1442 rffcf = std::fopen((*rffcfni).c_str(),
"r");
1444 if (rffcf ==
nullptr) {
1446 "Cyclotron::getFieldFromFile_Synchrocyclotron",
1447 "failed to open file '" + *rffcfni +
"', please check if it exists");
1450 std::vector<double> fcoeff;
1455 *
gmsg <<
"* Number of coefficients in file: " << nc <<
endl;
1456 for (
int k = 0; k < nc; k++) {
1458 fcoeff.push_back(value);
1461 rffc_m.push_back(fcoeff);
1466 *
gmsg <<
"RF Voltage Coefficient Filename: " << (*rfvcfni) <<
endl;
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");
1475 std::vector<double> vcoeff;
1478 *
gmsg <<
"* Number of coefficients in file: " << nc <<
endl;
1479 for (
int k = 0; k < nc; k++) {
1481 vcoeff.push_back(value);
1484 rfvc_m.push_back(vcoeff);
1503 fp1.open(fname, std::ios::out);
1521 fp2.open(fname, std::ios::out);
1525 Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0);
1527 Vector_t E(0.0, 0.0, 0.0), B(0.0, 0.0, 0.0);
1528 if (!fi->getFieldstrength(tmpR, tmpE, tmpB)) {
1533 fp2 << tmpR <<
" \t E= " << tmpE <<
"\t B= " << tmpB <<
std::endl;
1536 *
gmsg <<
"\n* Writing 'gnu.out' and 'eb.out' files of cyclotron field maps\n" <<
endl;
1539 *
gmsg <<
"\n* Writing 'gnu.out' file of cyclotron field map\n" <<
endl;
1543#undef CHECK_CYC_FSCANF_EOF
#define CHECK_CYC_FSCANF_EOF(arg)
Tps< T > cos(const Tps< T > &x)
Cosine.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sin(const Tps< T > &x)
Sine.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
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)
void fp1(BareField< T, 1U > &field, bool docomm=true)
Inform & level4(Inform &inf)
Inform & endl(Inform &inf)
constexpr double two_pi
The value of.
constexpr double e
The value of.
constexpr double pi
The value of.
std::string::iterator iterator
T rad(T x)
Convert degrees to radians.
std::string combineFilePath(std::initializer_list< std::string > ilist)
boost::function< boost::tuple< double, bool >(arguments_t)> type
ParticleAttrib< int > Bin
ParticleAttrib< double > M
ParticleAttrib< Vector_t > P
ParticleAttrib< double > Q
ParticleAttrib< short > bunchNum
static OpalData * getInstance()
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
virtual void visitCyclotron(const Cyclotron &)=0
Apply the algorithm to a cyclotron.
Interface for a single beam element.
PartBunchBase< double, 3 > * RefPartBunch_m
std::vector< double > dbrrt_m
std::vector< double > g3_m
std::vector< double > dbtt_m
std::vector< double > dbrtt_m
std::vector< double > f3_m
std::vector< double > dbrr_m
std::vector< double > dbrrr_m
std::vector< double > dbttt_m
std::vector< double > dbrt_m
std::vector< double > dbr_m
std::vector< double > dbt_m
std::vector< double > bfld_m
std::vector< double > f2_m
std::vector< double > rarr_m
virtual std::vector< double > getEScale() const
void setTrimCoilThreshold(double)
void setZinit(double zinit)
virtual double getCyclHarm() const
virtual void getDimensions(double &zBegin, double &zEnd) const
std::vector< std::string > RFfilename_m
virtual bool getSpiralFlag() const
virtual bool bends() const
void getFieldFromFile_CYCIAE(const double &scaleFactor)
void setSpiralFlag(bool spiral_flag)
virtual ElementType getType() const
Get element type std::string.
virtual double getPRinit() const
void getFieldFromFile_BandRF(const double &scaleFactor)
void setSuperpose(std::vector< bool > flag)
virtual double getTrimCoilThreshold() const
void setRfPhi(std::vector< double > f)
void setRFVCoeffFN(std::vector< std::string > rfv_coeff_fn)
void setPZinit(double zinit)
void setCyclotronType(const std::string &type)
virtual void accept(BeamlineVisitor &) const
Apply visitor to Cyclotron.
virtual double getPZinit() const
virtual std::string getFieldMapFN() const
virtual double getRmin() const
void read(const double &scaleFactor)
int idx(int irad, int ktet)
virtual double getMaxR() const
void setEScale(std::vector< double > bs)
void setSymmetry(double symmetry)
std::vector< bool > superpose_m
virtual std::vector< double > getRfFrequ() const
std::vector< double > escale_m
std::vector< std::string > RFVCoeff_fn_m
std::vector< double > rffrequ_m
void getFieldFromFile_AVFEQ(const double &scaleFactor)
virtual double getRmax() const
virtual double getFMHighE() const
double gutdf5d(double *f, double dx, const int kor, const int krl, const int lpr)
void setFieldMapFN(const std::string &fmapfn)
double trimCoilThreshold_m
virtual double getMaxZ() const
virtual double getBScale() const
virtual double getZinit() const
void getFieldFromFile_Carbon(const double &scaleFactor)
void writeOutputFieldFiles()
virtual double getPHIinit() const
std::vector< TrimCoil * > trimcoils_m
std::vector< std::string > RFFCoeff_fn_m
void setTrimCoils(const std::vector< TrimCoil * > &trimcoils)
virtual double getSymmetry() const
void setCyclHarm(double h)
virtual double getMinZ() const
void getFieldFromFile_Synchrocyclotron(const double &scaleFactor)
virtual std::vector< double > getRfPhi() const
void applyTrimCoil_m(const double r, const double z, const double tet_rad, double *br, double *bz)
Apply trim coils (calculate field contributions)
BFieldType getBFieldType() const
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField)
void getFieldFromFile_FFA(const double &scaleFactor)
void initR(double rmin, double dr, int nrad)
void setPHIinit(double phiinit)
void setRfFrequ(std::vector< double > f)
void setPRinit(double prinit)
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.
virtual bool apply(const size_t &id, const double &t, Vector_t &E, Vector_t &B)
void setRfFieldMapFN(std::vector< std::string > rffmapfn)
bool interpolate(const double &rad, const double &tet_rad, double &br, double &bt, double &bz)
void setFMHighE(double e)
std::vector< Fieldmap * > RFfields_m
std::vector< double > rfphi_m
void setRinit(double rinit)
virtual std::vector< bool > getSuperpose() const
std::vector< std::vector< double > > rfvc_m
std::vector< std::vector< double > > rffc_m
virtual double getFMLowE() const
std::unique_ptr< LossDataSink > lossDs_m
unsigned int getNumberOfTrimcoils() const
virtual double getRinit() const
void getFieldFromFile_Ring(const double &scaleFactor)
virtual double getMinR() const
const std::string & getCyclotronType() const
void setRFFCoeffFN(std::vector< std::string > rff_coeff_fn)
void setBScale(double bs)
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)
static void readMap(std::string Filename)
Vektor< double, 3 > Vector_t