Newer
Older
/*
Current revision $Revision$
On branch $Name$
Latest change $Date$ by $Author$
*/
#define ORDER 1
int no_tps = ORDER; // arbitrary TPSA order is defined locally
//***************************************************************************************
//
// MAIN CODE
//
//****************************************************************************************
int main(int argc, char *argv[]) {
const long seed = 1121;
iniranf(seed);
setrancut(2.0);
// turn on globval.Cavity_on and globval.radiation to get proper synchr radiation damping
// IDs accounted too if: wiggler model and symplectic integrator (method = 1)
globval.H_exact = false;
/*The following values are set in the Read_lattice( ) in soleilcommon.cc*/
// globval.quad_fringe = false; // quadrupole fringe field
// globval.radiation = false; // synchrotron radiation
// globval.emittance = false; // emittance
// globval.pathlength = false;
// globval.bpm = 0;
// const double x_max_FMA = 10e-3, delta_FMA = 10e-2;
// const int n_x = 801, n_dp = 80, n_tr = 2048;
double nux = 0, nuy = 0, ksix = 0, ksiy = 0;
bool chroma;
double dP = 0.0;
long lastpos = -1L;
char str1[S_SIZE];
uint32_t start, stop;
/************************************************************************
read in files and flags
*************************************************************************/
if (argc > 1) {
read_script(argv[1], true);
} else {
fprintf(stdout, "Not enough parameters\nSyntax is program parameter file\n");
/************************************************************************
writes flat file with all the design values of the lattice, very important file for debug
*************************************************************************/
prtmfile("flat_file.dat");
// print cod
getcod(dP, lastpos);
prt_cod("cod.out", globval.bpm, true);
if (RFvoltageFlag == true) {
printf("\nSetting RF voltage:\n");
printf(" Old RF voltage is: %lf [MV]\n", get_RFVoltage(ElemIndex("cav"))
/ 1e6);
set_RFVoltage(ElemIndex("cav"), RFvolt);
printf(" New RF voltage is: %lf [MV]\n", get_RFVoltage(ElemIndex("cav"))
/ 1e6);
}
// Chamber factory
// if (ChamberFlag == false)
// ChamberOff(); // turn off vacuum chamber setting, use the default +-1 meters
if (ReadChamberFlag == true)
ReadCh(chamber_file); /* read vacuum chamber from a file "Apertures.dat" , soleil version*/
PrintCh(); // print chamber into chamber.out
//get_matching_params_scl(); // get tunes and beta functions at entrance
get_alphac2(); // compute up to 3rd order mcf
//cout << endl << "computing tune shifts" << endl;
//dnu_dA(10e-3, 5e-3, 0.002);
//get_ksi2(0.0); // this gets the chromas and writes them into chrom2.out
GetTuneTrac(1026L, 0.0, &nux, &nuy);
fprintf(stdout, "From tracking: nux = % f nuz = % f \n", nux, nuy);
}
// compute chromaticities by tracking (should be the same as by DA)
if (ChromTracFlag == true) {
start = stampstart();
GetChromTrac(2L, 1026L, 1e-5, &ksix, &ksiy);
stop = stampstop(start);
fprintf(stdout, "From tracking: ksix= % f ksiz= % f \n", ksix, ksiy);
//generic function, to fit tunes using 1 family of quadrupoles
if (FitTuneFlag == true) {
double qf_bn = 0.0, qd_bn = 0.0;
double qf_bn_fit = 0.0, qd_bn_fit = 0.0;
qf_bn = Cell[Elem_GetPos(ElemIndex(qf), 1)].Elem.M->PB[HOMmax + 2];
qd_bn = Cell[Elem_GetPos(ElemIndex(qd), 1)].Elem.M->PB[HOMmax + 2];
fprintf(stdout,
"\n Fitting tunes: %s %s, targetnux = %f, targetnuz = %f \n", qf, qd,
targetnux, targetnuz);
FitTune(ElemIndex(qf), ElemIndex(qd), targetnux, targetnuz);
qf_bn_fit = Cell[Elem_GetPos(ElemIndex(qf), 1)].Elem.M->PB[HOMmax + 2];
qd_bn_fit = Cell[Elem_GetPos(ElemIndex(qd), 1)].Elem.M->PB[HOMmax + 2];
printf("Before the fitting, the quadrupole field strengths are: \n");
printf(" %s = %f, %s = %f\n", qf, qf_bn, qd, qd_bn);
printf("After the fitting, the quadrupole field strengths are: \n");
printf(" %s = %f, %s = %f\n", qf, qf_bn_fit, qd, qd_bn_fit);
/* Compute and get Twiss parameters */
Ring_GetTwiss(chroma = true, 0.0);
printglob(); /* print parameter list */
/* specific for soleil ring in which the quadrupole is cut into 2 parts*/
if (FitTune4Flag == true) {
double qf1_bn = 0.0, qf2_bn = 0.0, qd1_bn = 0.0, qd2_bn = 0.0;
double qf1_bn_fit = 0.0, qf2_bn_fit = 0.0, qd1_bn_fit = 0.0, qd2_bn_fit =
0.0;
qf1_bn = Cell[Elem_GetPos(ElemIndex(qf1), 1)].Elem.M->PB[HOMmax + 2];
qf2_bn = Cell[Elem_GetPos(ElemIndex(qf2), 1)].Elem.M->PB[HOMmax + 2];
qd1_bn = Cell[Elem_GetPos(ElemIndex(qd1), 1)].Elem.M->PB[HOMmax + 2];
qd2_bn = Cell[Elem_GetPos(ElemIndex(qd2), 1)].Elem.M->PB[HOMmax + 2];
fprintf(
stdout,
"\n Fitting tunes for Soleil ring: %s %s %s %s, targetnux = %f, targetnuz = %f \n",
qf1, qf2, qd1, qd2, targetnux, targetnuz);
FitTune4(ElemIndex(qf1), ElemIndex(qf2), ElemIndex(qd1), ElemIndex(qd2),
targetnux, targetnuz);
qf1_bn_fit = Cell[Elem_GetPos(ElemIndex(qf1), 1)].Elem.M->PB[HOMmax + 2];
qf2_bn_fit = Cell[Elem_GetPos(ElemIndex(qf2), 1)].Elem.M->PB[HOMmax + 2];
qd1_bn_fit = Cell[Elem_GetPos(ElemIndex(qd1), 1)].Elem.M->PB[HOMmax + 2];
qd2_bn_fit = Cell[Elem_GetPos(ElemIndex(qd2), 1)].Elem.M->PB[HOMmax + 2];
printf("Before the fitting, the quadrupole field strengths are: \n");
printf(" %s = %f, %s = %f, %s = %f, %s = %f\n", qf1, qf1_bn,
qf2, qf2_bn, qd1, qd1_bn, qd2, qd2_bn);
printf("After the fitting, the quadrupole field strengths are: \n");
printf(" %s = %f, %s = %f, %s = %f, %s = %f\n", qf1,
qf1_bn_fit, qf2, qf2_bn_fit, qd1, qd1_bn_fit, qd2, qd2_bn_fit);
/* Compute and get Twiss parameters */
Ring_GetTwiss(chroma = true, 0.0);
printglob(); /* print parameter list */
double sxm1_bn = 0.0, sxm2_bn = 0.0;
double sxm1_bn_fit = 0.0, sxm2_bn_fit = 0.0;
sxm1_bn = Cell[Elem_GetPos(ElemIndex(sxm1), 1)].Elem.M->PB[HOMmax + 3];
sxm2_bn = Cell[Elem_GetPos(ElemIndex(sxm2), 1)].Elem.M->PB[HOMmax + 3];
fprintf(
stdout,
"\n Fitting chromaticities: %s %s, targetksix = %f, targetksiz = %f\n",
sxm1, sxm2, targetksix, targetksiz);
FitChrom(ElemIndex(sxm1), ElemIndex(sxm2), targetksix, targetksiz);
sxm1_bn_fit = Cell[Elem_GetPos(ElemIndex(sxm1), 1)].Elem.M->PB[HOMmax + 3];
sxm2_bn_fit = Cell[Elem_GetPos(ElemIndex(sxm2), 1)].Elem.M->PB[HOMmax + 3];
printf("Before the fitting, the sextupole field strengths are \n");
printf(" %s = %f, %s = %f\n", sxm1, sxm1_bn, sxm2, sxm2_bn);
printf("After the fitting, the sextupole field strengths are: \n");
printf(" %s = %f, %s = %f\n", sxm1, sxm1_bn_fit, sxm2, sxm2_bn_fit);
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printglob(); /* print parameter list */
if (CouplingFlag == true) {
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt(); /* dump linear lattice functions into "linlat.dat" */
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
prtmfile("flat_file.dat"); //print the elements without rotation errors
prtmfile("flat_file_errcoupling_full.dat"); //print the elements with rotation errors
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt(); /* dump linear lattice functions into "linlat.dat" */
// GetEmittance(ElemIndex("cav"), true); //only for test
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
// printlatt();
// add coupling by random rotating of the half quadrupole magnets, delicated for soleil
if (ErrorCoupling2Flag == true) {
prtmfile("flat_file.dat"); //print the elements without rotation errors
prtmfile("flat_file_errcoupling_half.dat"); //print the elements with rotation errors
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt(); /* dump linear lattice functions into "linlat.dat" */
Coupling_Edwards_Teng();
// GetEmittance(ElemIndex("cav"), true);
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
// WARNING Fit tunes and chromaticities before applying errors !!!!
//set multipoles in all magnets
if (ReadMultipoleFlag == true) {
fprintf(stdout,
"\n Read Multipoles file for lattice with thick sextupoles \n");
ReadFieldErr(multipole_file);
//first print the full lattice with error as a flat file
prtmfile("flat_file_errmultipole.dat"); // writes flat file with all element errors /* very important file for debug*/
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printglob();
//Old version to multipole errors in soleil lattice, is obsoleted
if (MultipoleFlag == true) {
if (ThinsextFlag == true) {
fprintf(stdout,
"\n Setting Multipoles for lattice with thin sextupoles \n");
Multipole_thinsext(fic_hcorr, fic_vcorr, fic_skew); /* for thin sextupoles */
prtmfile("flat_file_errmultipole.dat"); // writes flat file /* very important file for debug*/
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printglob();
} else {
fprintf(stdout,
"\n Setting Multipoles for lattice with thick sextupoles \n");
Multipole_thicksext(fic_hcorr, fic_vcorr, fic_skew); /* for thick sextupoles */
prtmfile("flat_file_errmultipole.dat"); // writes flat file /* very important file for debug*/
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printglob();
/******************************************************************************************/
// COMPUTATION PART after setting the model
/******************************************************************************************/
// computes TuneShift with amplitudes
if (AmplitudeTuneShiftFlag == true) {
TunesShiftWithAmplitude(_AmplitudeTuneShift_nxpoint, _AmplitudeTuneShift_nypoint,
_AmplitudeTuneShift_nturn, _AmplitudeTuneShift_xmax,
_AmplitudeTuneShift_ymax, _AmplitudeTuneShift_delta);
} //else { // Utility ?
// TunesShiftWithAmplitude(50L, 30L, 516L, 0.035, 0.02, dP);
// }
TunesShiftWithEnergy(_EnergyTuneShift_npoint, _EnergyTuneShift_nturn,
}// else { // utility ?
// TunesShiftWithEnergy(31L, 1026L, 0.06);
//}
// Computes FMA
if (FmapFlag == true) {
fmap(_FmapFlag_nxpoint, _FmapFlag_nypoint, _FmapFlag_nturn, _FmapFlag_xmax,
_FmapFlag_ymax, _FmapFlag_delta, _FmapFlag_diffusion);
// Compute FMA dp
if (FmapdpFlag == true) {
fmapdp(_FmapdpFlag_nxpoint, _FmapdpFlag_nepoint, _FmapdpFlag_nturn,
_FmapdpFlag_xmax, _FmapdpFlag_emax, _FmapdpFlag_z,
_FmapdpFlag_diffusion);
if (CodeComparaisonFlag) {
fmap(200, 100, 1026, -32e-3, 7e-3, 0.0, true);
}
// MOMENTUM ACCEPTANCE
if (MomentumAccFlag == true) {
bool cavityflag, radiationflag;
/* record the initial values*/
cavityflag = globval.Cavity_on;
radiationflag = globval.radiation;
/* set the dimension for the momentum tracking*/
if (strncmp("6D", TrackDim, 2) == 0) {
globval.Cavity_on = true;
globval.radiation = true;
} else if (strncmp("4D", TrackDim, 2) == 0) {
globval.Cavity_on = false;
globval.radiation = false;
} else {
printf("MomentumAccFlag: Error!!! DimTrack must be '4D' or '6D'\n");
exit_(1);
};
MomentumAcceptance(_MomentumAccFlag_istart, _MomentumAccFlag_istop,
_MomentumAccFlag_deltaminp, _MomentumAccFlag_deltamaxp,
_MomentumAccFlag_nstepp, _MomentumAccFlag_deltaminn,
_MomentumAccFlag_deltamaxn, _MomentumAccFlag_nstepn);
/* restore the initial values*/
globval.Cavity_on = cavityflag;
globval.radiation = radiationflag;
}
if (InducedAmplitudeFlag == true) {
InducedAmplitude(193L);
// compute cod and Twiss parameters for different energy offsets
for (int ii = 0; ii <= 40; ii++) {
dP = -0.02 + 0.001 * ii;
Ring_GetTwiss(chroma = false, dP); /* Compute and get Twiss parameters */
printlatt(); /* dump linear lattice functions into "linlat.dat" */
getcod(dP, lastpos);
// printcod();
prt_cod("cod.out", globval.bpm, true);
//system("mv linlat.out linlat_ooo.out");
sprintf(str1, "mv cod.out cod_%02d.out", ii);
system(str1);
sprintf(str1, "mv linlat.out linlat_%02d.out", ii);
system(str1);
bool cavityflag, radiationflag;
/* record the initial values*/
cavityflag = globval.Cavity_on;
radiationflag = globval.radiation;
/* set the dimension for the momentum tracking*/
if (strncmp("6D", _Phase_Dim, 2) == 0) {
globval.Cavity_on = true;
} else if (strncmp("4D", _Phase_Dim, 2) == 0) {
globval.Cavity_on = false;
} else {
printf("MomentumAccFlag: Error!!! _Phase_Dim must be '4D' or '6D'\n");
exit_(1);
};
/* setting damping */
if (_Phase_Damping == true) {
globval.radiation = true;
} else {
globval.radiation = false;
}
Phase(_Phase_X, _Phase_Px, _Phase_Y, _Phase_Py, _Phase_delta, _Phase_ctau, _Phase_nturn);
printf("the simulation time for phase space in tracy 3 is \n");
/* restore the initial values*/
globval.Cavity_on = cavityflag;
globval.radiation = radiationflag;
// ????????????? NSRL version, Check with Soleil version "MomentumAcceptance"
// IBS & TOUSCHEK
int k, n_turns;
double sigma_s, sigma_delta, tau, alpha_z, beta_z, gamma_z, eps[3];
FILE *outf;
const double Qb = 5e-9; // e charge in one bunch
double sum_delta[globval.Cell_nLoc + 1][2];
double sum2_delta[globval.Cell_nLoc + 1][2];
for (k = 0; k <= globval.Cell_nLoc; k++) {
sum_delta[k][0] = 0.0;
sum_delta[k][1] = 0.0;
sum2_delta[k][0] = 0.0;
sum2_delta[k][1] = 0.0;
alpha_z = -globval.Ascr[ct_][ct_] * globval.Ascr[delta_][ct_]
- globval.Ascr[ct_][delta_] * globval.Ascr[delta_][delta_];
beta_z = sqr(globval.Ascr[ct_][ct_]) + sqr(globval.Ascr[ct_][delta_]);
gamma_z = (1 + sqr(alpha_z)) / beta_z;
sigma_delta = sqrt(gamma_z * globval.eps[Z_]);
sigma_s = sqrt(beta_z * globval.eps[Z_]);//50e-3
beta_z = sqr(sigma_s) / globval.eps[Z_];
alpha_z = sqrt(beta_z * gamma_z - 1);
// INCLUDE LC (LC changes sigma_s and eps_z, but has no influence on sigma_delta)
if (false) {
globval.eps[Z_] = globval.eps[Z_] * bunchLengthening;
beta_z = beta_z * bunchLengthening;
gamma_z = gamma_z / bunchLengthening;
alpha_z = sqrt(beta_z * gamma_z - 1); // this doesn't change
for (k = 0; k < 3; k++)
eps[k] = globval.eps[k];
for (k = 0; k < 20; k++) //prototype (looping because IBS routine doesn't check convergence)
IBS(Qb, globval.eps, eps, alpha_z, beta_z);
}
// TOUSCHEK TRACKING
// Calculate Touschek lifetime
// with the momentum acceptance which is determined by
// the RF acceptance delta_RF and the momentum aperture
// at each element location which is tracked over n turns,
//the vacuum chamber is read from the file "chamber_file"
// finally, write the momentum acceptance to file "mom_aper.out".
ReadCh(chamber_file);
// LoadApers("/home/simon/projects/src/lattice/Apertures.dat", 1, 1);
tau = Touschek(Qb, globval.delta_RF, false, globval.eps[X_],
globval.eps[Y_], sigma_delta, sigma_s, n_turns, true, sum_delta,
sum2_delta); //the TRUE flag requires apertures loaded
printf("Touschek lifetime = %10.3e hrs\n", tau / 3600.0);
for (k = 0; k <= globval.Cell_nLoc; k++)
fprintf(outf, "%4d %7.2f %5.3f %6.3f\n", k, Cell[k].S, 1e2
* sum_delta[k][0], 1e2 * sum_delta[k][1]);