// ------------------------------------------------------------------------ // $RCSfile: Cyclotron.cpp,v $ // ------------------------------------------------------------------------ // $Revision: 1.1.1.1 $ // ------------------------------------------------------------------------ // Copyright: see Copyright.readme // ------------------------------------------------------------------------ // // Definitions for class: Cyclotron // Defines the abstract interface for a sector bend magnet. // // ------------------------------------------------------------------------ // Class category: AbsBeamline // ------------------------------------------------------------------------ // // $Date: 2007/08/01 $ // $Author: Yang, Adelmann $ // // ------------------------------------------------------------------------ #include "AbsBeamline/Cyclotron.h" #include "AbsBeamline/BeamlineVisitor.h" #include "Physics/Physics.h" #include "Fields/Fieldmap.hh" #include extern Inform *gmsg; using Physics::pi; using namespace std; // Class Cyclotron // ------------------------------------------------------------------------ Cyclotron::Cyclotron(): Component() { Bfield.bfld = 0; Bfield.dbt = 0; Bfield.dbtt = 0; Bfield.dbttt = 0; BP.rarr = 0; Bfield.dbr = 0; Bfield.dbrr = 0; Bfield.dbrrr = 0; Bfield.dbrt = 0; Bfield.dbrrt = 0; Bfield.dbrtt = 0; Bfield.f2 = 0; Bfield.f3 = 0; Bfield.g3 = 0; } Cyclotron::Cyclotron(const Cyclotron &right): Component(right), fmapfn_m(right.fmapfn_m), rffrequ_m(right.rffrequ_m), rfphi_m(right.rfphi_m), escale_m(right.escale_m), symmetry_m(right.symmetry_m), rinit_m(right.rinit_m), prinit_m(right.prinit_m), phiinit_m(right.phiinit_m), type_m(right.type_m), harm_m(right.harm_m), bscale_m(right.bscale_m), tcr1_m(right.tcr1_m), tcr2_m(right.tcr2_m), mbtc_m(right.mbtc_m), slptc_m(right.slptc_m), superpose_m(right.superpose_m), RFfilename_m(right.RFfilename_m) { Bfield.bfld = 0; Bfield.dbt = 0; Bfield.dbtt = 0; Bfield.dbttt = 0; BP.rarr = 0; Bfield.dbr = 0; Bfield.dbrr = 0; Bfield.dbrrr = 0; Bfield.dbrt = 0; Bfield.dbrrt = 0; Bfield.dbrtt = 0; Bfield.f2 = 0; Bfield.f3 = 0; Bfield.g3 = 0; } Cyclotron::Cyclotron(const string &name): Component(name) { Bfield.bfld = 0; Bfield.dbt = 0; Bfield.dbtt = 0; Bfield.dbttt = 0; BP.rarr = 0; Bfield.dbr = 0; Bfield.dbrr = 0; Bfield.dbrrr = 0; Bfield.dbrt = 0; Bfield.dbrrt = 0; Bfield.dbrtt = 0; Bfield.f2 = 0; Bfield.f3 = 0; Bfield.g3 = 0; } Cyclotron::~Cyclotron() { if(Bfield.bfld) delete[] Bfield.bfld; if(Bfield.dbt) delete[] Bfield.dbt; if(Bfield.dbtt) delete[] Bfield.dbtt; if(Bfield.dbttt) delete[] Bfield.dbttt; if(BP.rarr) delete[] BP.rarr; if(Bfield.dbr) delete[] Bfield.dbr; if(Bfield.dbrr) delete[] Bfield.dbrr; if(Bfield.dbrrr) delete[] Bfield.dbrrr; if(Bfield.dbrt) delete[] Bfield.dbrt; if(Bfield.dbrrt) delete[] Bfield.dbrrt; if(Bfield.dbrtt) delete[] Bfield.dbrtt; if(Bfield.f2) delete[] Bfield.f2; if(Bfield.f3) delete[] Bfield.f3; if(Bfield.g3) delete[] Bfield.g3; } void Cyclotron::accept(BeamlineVisitor &visitor) const { visitor.visitCyclotron(*this); } void Cyclotron::setRinit(double rinit) { rinit_m = rinit; } double Cyclotron::getRinit() const { return rinit_m; } void Cyclotron::setPRinit(double prinit) { prinit_m = prinit; } double Cyclotron::getPRinit() const { return prinit_m; } void Cyclotron::setPHIinit(double phiinit) { phiinit_m = phiinit; } double Cyclotron::getPHIinit() const { return phiinit_m; } void Cyclotron::setFieldMapFN(string f) { fmapfn_m = f; } string Cyclotron::getFieldMapFN() const { return fmapfn_m; } void Cyclotron::setRfFieldMapFN(vector f) { RFfilename_m = f; } void Cyclotron::setRfPhi(vector f) { rfphi_m = f; } void Cyclotron::setRfFrequ(vector f) { rffrequ_m = f; } void Cyclotron::setSuperpose(bool flag) { superpose_m = flag; } bool Cyclotron::getSuperpose() const { return superpose_m; } void Cyclotron::setSymmetry(double s) { symmetry_m = s; } double Cyclotron::getSymmetry() const { return symmetry_m; } void Cyclotron::setType(string t) { type_m = t; } const string &Cyclotron::getType() const { return type_m; } void Cyclotron::setCyclHarm(double h) { harm_m = h; } void Cyclotron::setBScale(double s) { bscale_m = s; } double Cyclotron::getBScale() const { return bscale_m; } void Cyclotron::setEScale(vector s) { escale_m = s; } double Cyclotron::getCyclHarm() const { return harm_m; } double Cyclotron::getRmin() const { return BP.rmin; } double Cyclotron::getRmax() const { return BP.rmin + (Bfield.nrad - 1) * BP.delr; } // This function aims at obtaining magentic field at any given location R by interpolation. // arguments t is useless here. // arguments E is set to zero. void Cyclotron::setTCr1(double tcr1) { tcr1_m = tcr1; } double Cyclotron::getTCr1() const { return tcr1_m; } void Cyclotron::setTCr2(double tcr2) { tcr2_m = tcr2; } double Cyclotron::getTCr2() const { return tcr2_m; } void Cyclotron::setMBtc(double mbtc) { mbtc_m = mbtc; } double Cyclotron::getMBtc() const { return mbtc_m; } void Cyclotron::setSLPtc(double slptc) { slptc_m = slptc; } double Cyclotron::getSLPtc() const { return slptc_m; } bool Cyclotron::apply(const int &i, const double &t, double E[], double B[]) { Vector_t Ev(0, 0, 0), Bv(0, 0, 0); if(apply(RefPartBunch_m->R[i], Vector_t(0.0), t, Ev, Bv)) return true; E[0] = Ev(0); E[1] = Ev(1); E[2] = Ev(2); B[0] = Bv(0); B[1] = Bv(1); B[2] = Bv(2); return false; } bool Cyclotron::apply(const int &i, const double &t, Vector_t &E, Vector_t &B) { return apply(RefPartBunch_m->R[i], Vector_t(0.0), t, E, B); } bool Cyclotron::apply(const Vector_t &R, const Vector_t ¢roid, const double &t, Vector_t &E, Vector_t &B) { const double rad = sqrt(R[0] * R[0] + R[1] * R[1]); const double xir = (rad - BP.rmin) / BP.delr; // ir : the mumber of path whoes radius is less then the 4 points of cell which surrond particle. const int ir = (int)xir; // wr1 : the relative distance to the inner path radius const double wr1 = xir - (double)ir; // wr2 : the relative distance to the outer path radius const double wr2 = 1.0 - wr1; const double tempv = atan(R[1] / R[0]); double tet = tempv, tet_map, xit; /* if((R[0] > 0) && (R[1] >= 0)) tet = tempv; else*/ if((R[0] < 0) && (R[1] >= 0)) tet = pi + tempv; else if((R[0] < 0) && (R[1] <= 0)) tet = pi + tempv; else if((R[0] > 0) && (R[1] <= 0)) tet = 2.0 * pi + tempv; else if((R[0] == 0) && (R[1] > 0)) tet = pi / 2.0; else if((R[0] == 0) && (R[1] < 0)) tet = 1.5 * pi; double tet_rad = tet; // the actual angle of particle tet = tet / pi * 180.0; // the corresponding angle on the field map // Note: this does not work if the start point of field map does not equal zero. tet_map = fmod(tet, 360.0 / symmetry_m); xit = tet_map / BP.dtet; int it = (int) xit; // *gmsg << R << " tet_map= " << tet_map << " ir= " << ir << " it= " << it << " bf= " << Bfield.bfld[idx(ir,it)] << endl; const double wt1 = xit - (double)it; const double wt2 = 1.0 - wt1; // it : the number of point on the inner path whoes angle is less then the particle' corresponding angle. // include zero degree point it = it + 1; int r1t1, r2t1, r1t2, r2t2; int ntetS = Bfield.ntet + 1; // r1t1 : the index of the "min angle, min radius" point in the 2D field array. // considering the array start with index of zero, minus 1. if(myBFieldType_m != FFAGBF) { /* For FFAG this does not work */ r1t1 = it + ntetS * ir - 1; r1t2 = r1t1 + 1; r2t1 = r1t1 + ntetS; r2t2 = r2t1 + 1 ; } else { /* With t his we have B-field AND this is far more intuitive for me .... */ r1t1 = idx(ir, it); r2t1 = idx(ir + 1, it); r1t2 = idx(ir, it + 1); r2t2 = idx(ir + 1, it + 1); } double bzf = 0.0, bz = 0.0 /*, bzcub = 0.0*/; double brf = 0.0, br = 0.0 /*, brcub = 0.0*/; double btf = 0.0, bt = 0.0 /*, btcub = 0.0*/; if((it >= 0) && (ir >= 0) && (it < Bfield.ntetS) && (ir < Bfield.nrad)) { /* Bz */ bzf = (Bfield.bfld[r1t1] * wr2 * wt2 + Bfield.bfld[r2t1] * wr1 * wt2 + Bfield.bfld[r1t2] * wr2 * wt1 + Bfield.bfld[r2t2] * wr1 * wt1); // bzcub = (Bfield.f2[r1t1] * wr2 * wt2 + // Bfield.f2[r2t1] * wr1 * wt2 + // Bfield.f2[r1t2] * wr2 * wt1 + // Bfield.f2[r2t2] * wr1 * wt1) * pow(R[2], 2.0); // bz = -( bzf - bzcub ); bz = - bzf ; /* Br */ brf = (Bfield.dbr[r1t1] * wr2 * wt2 + Bfield.dbr[r2t1] * wr1 * wt2 + Bfield.dbr[r1t2] * wr2 * wt1 + Bfield.dbr[r2t2] * wr1 * wt1) * R[2]; // brcub = (Bfield.f3[r1t1] * wr2 * wt2 + // Bfield.f3[r2t1] * wr1 * wt2 + // Bfield.f3[r1t2] * wr2 * wt1 + // Bfield.f3[r2t2] * wr1 * wt1) * pow(R[2], 3.0); // br = -( brf - brcub ); br = - brf; /* Btheta */ btf = (Bfield.dbt[r1t1] * wr2 * wt2 + Bfield.dbt[r2t1] * wr1 * wt2 + Bfield.dbt[r1t2] * wr2 * wt1 + Bfield.dbt[r2t2] * wr1 * wt1) / rad * R[2]; // btcub = (Bfield.g3[r1t1] * wr2 * wt2 + // Bfield.g3[r2t1] * wr1 * wt2 + // Bfield.g3[r1t2] * wr2 * wt1 + // Bfield.g3[r2t2] * wr1 * wt1) / rad * pow(R[2], 3.0); // bt = -( btf - btcub ); bt = - btf; /* Br Btheta -> Bx By */ if(tcr1_m != 0.0 && tcr2_m != 0.0) { double partR = sqrt(R[0] * R[0] + R[1] * R[1]); double Amax1 = 1; double Amax2 = 3; double Amin = -2; double x01 = 4; double x02 = 8; double h1 = 0.03; double h2 = 0.2; double ftc = slptc_m; double part1 = pow(10.0, (partR / ftc - tcr1_m / ftc - x01) * h1); double part2 = pow(10.0, (x02 - partR / ftc + tcr1_m / ftc) * h2); double part3 = -(Amax1 - Amin) * h1 * log(10) / ftc / (1 + part1) / (1 + part1) * part1; double part4 = (Amax2 - Amin) * h2 * log(10) / ftc / (1 + part2) / (1 + part2) * part2; double dr = mbtc_m / 2.78 * (part3 + part4); double btr = mbtc_m / 2.78 * (Amin + (Amax1 - Amin) / (1 + part1) + (Amax2 - Amin) / (1 + part2) - 1.0); // trim coil // double tca1 = 4; // double tca2 = 22; // bz=bz*(1-btr/20); //for (int kk=0;kk<8;++kk) { //if (tet>tca1+kk&&tet 0) { for(int dummy = 0; dummy < 6; dummy++) { fscanf(f, "%s", fout); // INFO-LINE } } for(int k = 0; k < Bfield.ntet; k++) { fscanf(f, "%16lE", &(Bfield.bfld[idx(i, k)])); Bfield.bfld[idx(i, k)] *= BP.Bfact; } for(int k = 0; k < Bfield.ntet; k++) { fscanf(f, "%16lE", &(Bfield.dbt[idx(i, k)])); Bfield.dbt[idx(i, k)] *= BP.Bfact; } for(int k = 0; k < Bfield.ntet; k++) { fscanf(f, "%16lE", &(Bfield.dbtt[idx(i, k)])); Bfield.dbtt[idx(i, k)] *= BP.Bfact; } for(int k = 0; k < Bfield.ntet; k++) { fscanf(f, "%16lE", &(Bfield.dbttt[idx(i, k)])); Bfield.dbttt[idx(i, k)] *= BP.Bfact; } } fclose(f); *gmsg << "* Field Map read successfully!" << endl << endl; } // Calculates Radiae of initial grid. // dimensions in [mm]! void Cyclotron::initR(double rmin, double dr, int nrad) { BP.rarr = new double[nrad]; for(int i = 0; i < nrad; i++) { BP.rarr[i] = rmin + i * dr; } BP.delr = dr; } void Cyclotron::initialise(PartBunch *bunch, const int &fieldflag, const double &scaleFactor) { RefPartBunch_m = bunch; // PSIBF, AVFEQBF, ANSYSBF, FFAGBF // for your own format field, you should add your own getFieldFromFile() function by yourself. if(fieldflag == 1) { //*gmsg<<"Read field data from PSI format field map file."< 2.1000 0.0 2.1000 0.0000 0.0000000000000000 2.1000 1.0 2.0997 0.0367 0.0000000000000000 2.1000 2.0 2.0987 0.0733 0.0000000000000000 */ vector rv; vector thv; vector xv; vector yv; vector bzv; vector::iterator vit; *gmsg << "* ----------------------------------------------" << endl; *gmsg << "* READ IN FFAG FIELD MAP " << endl; *gmsg << "* ----------------------------------------------" << endl; BP.Bfact = -10.0; // T->kG and H- for the current FNAL FFAG ifstream file_to_read(fmapfn_m.c_str()); const int max_num_of_char_in_a_line = 128; const int num_of_header_lines = 1; // STEP2: SKIP ALL THE HEADER LINES for(int i = 0; i < num_of_header_lines; ++i) file_to_read.ignore(max_num_of_char_in_a_line, '\n'); while(!file_to_read.eof()) { double r, th, x, y, bz; file_to_read >> r >> th >> x >> y >> bz; if((int)th != 360) { rv.push_back(r * 1000.0); thv.push_back(th); xv.push_back(x * 1000.0); yv.push_back(y * 1000.0); bzv.push_back(bz); } } double maxtheta = 360.0; BP.dtet = thv[1] - thv[0]; BP.rmin = *(rv.begin()); double rmax = rv.back(); // find out dR for(vit = rv.begin(); *vit <= BP.rmin; vit++) {} BP.delr = *vit - BP.rmin; BP.tetmin = thv[0]; Bfield.ntet = (int)((maxtheta - thv[0]) / BP.dtet); Bfield.nrad = (int)(rmax - BP.rmin) / BP.delr + 1; Bfield.ntetS = Bfield.ntet + 1; *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl; *gmsg << "* Maximal radius of measured field map: " << rmax << " [mm]" << endl; *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl; *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl; *gmsg << "* Maximal angle of measured field map: " << maxtheta << " [deg.]" << endl; //if the value is negtive, the actual value is its reciprocal. if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet); *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl; *gmsg << "* Total grid point along azimuth: " << Bfield.ntetS << endl; *gmsg << "* Total grid point along radius: " << Bfield.nrad << endl; Bfield.ntot = Bfield.ntetS * Bfield.nrad; *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << endl; if(Bfield.bfld) delete[] Bfield.bfld; Bfield.bfld = new double[Bfield.ntot]; if(Bfield.dbt) delete[] Bfield.dbt; Bfield.dbt = new double[Bfield.ntot]; if(Bfield.dbtt) delete[] Bfield.dbtt; Bfield.dbtt = new double[Bfield.ntot]; if(Bfield.dbttt) delete[] Bfield.dbttt; Bfield.dbttt = new double[Bfield.ntot]; *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl; int count = 0; if(Ippl::getNodes() == 1) { fstream fp; fp.open("gnu.out", ios::out); for(int r = 0; r < Bfield.nrad; r++) { for(int k = 0; k < Bfield.ntet; k++) { Bfield.bfld[idx(r, k)] = bzv[count] * BP.Bfact; fp << BP.rmin + (r * BP.delr) << " \t " << k*(BP.tetmin + BP.dtet) << " \t " << Bfield.bfld[idx(r, k)] << endl; count++; } } fp.close(); } *gmsg << "* Field Map read successfully nelem= " << count << endl << endl; } void Cyclotron::getFieldFromFile_AVFEQ(const double &scaleFactor) { FILE *f = NULL; *gmsg << "* ----------------------------------------------" << endl; *gmsg << "* READ IN AVFEQ CYCLOTRON FIELD MAP " << endl; *gmsg << "* ----------------------------------------------" << endl; /* From Hiroki-san The first line tells r minimum (500mm), r maximum(4150mm), r step(50mm), theta minimum(0deg), theta maximum(90deg) theta step(0.5deg). From the next line data repeat the block for a given r which the first line of the block tells. Each block consists of the data Bz from theta minimum (0deg) to theta maximum(90deg) with theta step(0.5deg). */ BP.Bfact = scaleFactor / 1000.; if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) { ERRORMSG("Error in Cyclotron::getFieldFromFile_AVFEQ()!" << endl); ERRORMSG(" Cannot open file, please check if it really exists." << endl); exit(1); } fscanf(f, "%lf", &BP.rmin); *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl; double rmax; fscanf(f, "%lf", &rmax); *gmsg << "* Maximal radius of measured field map: " << rmax << " [mm]" << endl; fscanf(f, "%lf", &BP.delr); *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl; fscanf(f, "%lf", &BP.tetmin); *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl; double tetmax; fscanf(f, "%lf", &tetmax); *gmsg << "* Maximal angle of measured field map: " << tetmax << " [deg.]" << endl; fscanf(f, "%lf", &BP.dtet); //if the value is nagtive, the actual value is its reciprocal. if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet); *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl; Bfield.ntetS = (int)((tetmax - BP.tetmin) / BP.dtet + 1); *gmsg << "* Total grid point along azimuth: " << Bfield.ntetS << endl; Bfield.nrad = (int)(rmax - BP.rmin) / BP.delr; int ntotidx = idx(Bfield.nrad, Bfield.ntetS) + 1; Bfield.ntot = Bfield.ntetS * Bfield.nrad; *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << " ntot-idx= " << ntotidx << endl; if(Bfield.bfld) delete[] Bfield.bfld; Bfield.bfld = new double[Bfield.ntot]; if(Bfield.dbt) delete[] Bfield.dbt; Bfield.dbt = new double[Bfield.ntot]; if(Bfield.dbtt) delete[] Bfield.dbtt; Bfield.dbtt = new double[Bfield.ntot]; if(Bfield.dbttt) delete[] Bfield.dbttt; Bfield.dbttt = new double[Bfield.ntot]; *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl; fstream fp; if(Ippl::getNodes() == 1) fp.open("gnu.out", ios::out); double tmp; int count = 0; for(int r = 0; r < Bfield.nrad; r++) { fscanf(f, "%16lE", &tmp); // over read for(int k = 0; k < Bfield.ntetS; k++) { fscanf(f, "%16lE", &(Bfield.bfld[idx(r, k)])); Bfield.bfld[idx(r, k)] *= BP.Bfact; if(Ippl::getNodes() == 1) fp << BP.rmin + (r * BP.delr) << " \t " << k*(BP.tetmin + BP.dtet) << " \t " << Bfield.bfld[idx(r, k)] << " idx= " << idx(r, k) << endl; count++; } } if(Ippl::getNodes() == 1) fp.close(); fclose(f); *gmsg << "* Field Map read successfully nelem= " << count << endl << endl; } // read field map from external file. void Cyclotron::getFieldFromFile_Carbon(const double &scaleFactor) { FILE *f = NULL; *gmsg << "* ----------------------------------------------" << endl; *gmsg << "* READ IN CARBON CYCLOTRON FIELD MAP " << endl; *gmsg << "* ----------------------------------------------" << endl; BP.Bfact = scaleFactor; if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) { ERRORMSG("* Error in Cyclotron::getFieldFromFile_Carbon()!" << endl); ERRORMSG(" Cannot open file, please check if it really exists." << endl); exit(1); } fscanf(f, "%lf", &BP.rmin); *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl; fscanf(f, "%lf", &BP.delr); *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl; fscanf(f, "%lf", &BP.tetmin); *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl; fscanf(f, "%lf", &BP.dtet); //if the value is nagtive, the actual value is its reciprocal. if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet); *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl; fscanf(f, "%d", &Bfield.ntet); *gmsg << "* Index in azimuthal direction: " << Bfield.ntet << endl; fscanf(f, "%d", &Bfield.nrad); *gmsg << "* Index in radial direction: " << Bfield.nrad << endl; Bfield.ntetS = Bfield.ntet + 1; *gmsg << "* Accordingly, total grid point along azimuth: " << Bfield.ntetS << endl; Bfield.ntot = idx(Bfield.nrad - 1, Bfield.ntet) + 1; *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << endl; if(Bfield.bfld) delete[] Bfield.bfld; Bfield.bfld = new double[Bfield.ntot]; if(Bfield.dbt) delete[] Bfield.dbt; Bfield.dbt = new double[Bfield.ntot]; if(Bfield.dbtt) delete[] Bfield.dbtt; Bfield.dbtt = new double[Bfield.ntot]; if(Bfield.dbttt) delete[] Bfield.dbttt; Bfield.dbttt = new double[Bfield.ntot]; *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl; for(int i = 0; i < Bfield.nrad; i++) { for(int k = 0; k < Bfield.ntet; k++) { fscanf(f, "%16lE", &(Bfield.bfld[idx(i, k)])); Bfield.bfld[idx(i, k)] *= BP.Bfact; } } if(Ippl::getNodes() == 1) { fstream fp1, fp2; fp1.open("gnu.out", ios::out); fp2.open("eb.out", ios::out); for(int i = 0; i < Bfield.nrad; i++) { for(int k = 0; k < Bfield.ntet; k++) { fp1 << BP.rmin + (i * BP.delr) << " \t " << k*(BP.tetmin + BP.dtet) << " \t " << Bfield.bfld[idx(i, k)] << endl; Vector_t tmpR = Vector_t (BP.rmin + (i * BP.delr), 0.0, k * (BP.tetmin + BP.dtet)); Vector_t tmpE(0.0, 0.0, 0.0), tmpB(0.0, 0.0, 0.0); tmpR /= 1000.0; // -> mm to m vector::const_iterator fi = RFfields_m.begin(); vector::const_iterator rffi = rffrequ_m.begin(); vector::const_iterator rfphii = rfphi_m.begin(); vector::const_iterator escali = escale_m.begin(); for(; fi != RFfields_m.end(); ++fi, ++rffi, ++rfphii, ++escali) { Vector_t E(0.0, 0.0, 0.0), B(0.0, 0.0, 0.0); if(!(*fi)->getFieldstrength(tmpR, tmpE, tmpB)) { tmpE += E; tmpB -= B; } } fp2 << tmpR << " \t E= " << tmpE << "\t B= " << tmpB << endl; } } fp1.close(); fp2.close(); } fclose(f); *gmsg << "* Field Maps read successfully!" << endl << endl; } // read field map from external file. void Cyclotron::getFieldFromFile_CYCIAE(const double &scaleFactor) { FILE *f = NULL; char fout[100]; int dtmp; *gmsg << "* ----------------------------------------------" << endl; *gmsg << "* READ IN CYCIAE-100 CYCLOTRON FIELD MAP " << endl; *gmsg << "* ----------------------------------------------" << endl; BP.Bfact = scaleFactor; if((f = fopen(fmapfn_m.c_str(), "r")) == NULL) { ERRORMSG("* Error in Cyclotron::getFieldFromFile_Carbon()!" << endl); ERRORMSG(" Cannot open file, please check if it really exists." << endl); exit(1); } fscanf(f, "%lf", &BP.rmin); *gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl; fscanf(f, "%lf", &BP.delr); *gmsg << "* Stepsize in radial direction: " << BP.delr << " [mm]" << endl; fscanf(f, "%lf", &BP.tetmin); *gmsg << "* Minimal angle of measured field map: " << BP.tetmin << " [deg.]" << endl; fscanf(f, "%lf", &BP.dtet); //if the value is nagtive, the actual value is its reciprocal. if(BP.dtet < 0.0) BP.dtet = 1.0 / (-BP.dtet); *gmsg << "* Stepsize in azimuth direction: " << BP.dtet << " [deg.]" << endl; fscanf(f, "%d", &Bfield.ntet); *gmsg << "* Index in azimuthal direction: " << Bfield.ntet << endl; fscanf(f, "%d", &Bfield.nrad); *gmsg << "* Index in radial direction: " << Bfield.nrad << endl; Bfield.ntetS = Bfield.ntet + 1; *gmsg << "* Accordingly, total grid point along azimuth: " << Bfield.ntetS << endl; Bfield.ntot = idx(Bfield.nrad - 1, Bfield.ntet) + 1; *gmsg << "* Total stored grid point number ( ntetS * nrad ) : " << Bfield.ntot << endl; if(Bfield.bfld) delete[] Bfield.bfld; Bfield.bfld = new double[Bfield.ntot]; if(Bfield.dbt) delete[] Bfield.dbt; Bfield.dbt = new double[Bfield.ntot]; if(Bfield.dbtt) delete[] Bfield.dbtt; Bfield.dbtt = new double[Bfield.ntot]; if(Bfield.dbttt) delete[] Bfield.dbttt; Bfield.dbttt = new double[Bfield.ntot]; *gmsg << "* rescaling of the fields with factor: " << BP.Bfact << endl; int nHalfPoints = Bfield.ntet / 2.0 + 1; for(int i = 0; i < Bfield.nrad; i++) { for(int ii = 0; ii < 13; ii++)fscanf(f, "%s", fout); for(int k = 0; k < nHalfPoints; k++) { fscanf(f, "%d", &dtmp); fscanf(f, "%d", &dtmp); fscanf(f, "%d", &dtmp); fscanf(f, "%lf", &(Bfield.bfld[idx(i, k)])); Bfield.bfld[idx(i, k)] = Bfield.bfld[idx(i, k)] * (-10.0); // T --> kGs, minus for minus hydrongen } for(int k = nHalfPoints; k < Bfield.ntet; k++) { Bfield.bfld[idx(i, k)] = Bfield.bfld[idx(i, Bfield.ntet-k)]; } } // for(int i=0; i < 300; i++) msg <<"i="<::const_iterator fm = RFfilename_m.begin(); // loop over all field maps and superpose fields vector::const_iterator rffi = rffrequ_m.begin(); vector::const_iterator rfphii = rfphi_m.begin(); vector::const_iterator escali = escale_m.begin(); int fcount = 0; for(; fm != RFfilename_m.end(); ++fm, ++rffi, ++rfphii, ++escali, ++fcount) { msg << "Load field map " << fcount << " - " << *fm << endl; Fieldmap *f = Fieldmap::getFieldmap(*fm, false); if(f == NULL) { ERRORMSG("* Error in Cyclotron::getFieldFromFile_BandRF()!" << endl); ERRORMSG(" Cannot open file, please check if it really exists." << endl); exit(1); } f->readMap(); f->getInfo(&msg); RFfields_m.push_back(f); } // read CARBON type B field getFieldFromFile_Carbon(scaleFactor); } void Cyclotron::getDimensions(double &zBegin, double &zEnd) const { }