Code owners
Assign users and groups as approvers for specific file changes. Learn more.
soltracy.cc 38.48 KiB
/************************************
Current revision $Revision$
On branch $Name$
Latest change $Date$ by $Author$
*************************************/
#define ORDER 1
//#define ORDER 4
int no_tps = ORDER; // arbitrary TPSA order is defined locally
extern bool freq_map;
#if HAVE_CONFIG_H
#include <config.h>
#endif
#if MPI_EXEC
//library of parallel computation,must be before "stdio.h"
#include <mpi.h>
#endif
#include "tracy_lib.h"
//***************************************************************************************
//
// MAIN CODE
//
//****************************************************************************************
int main(int argc, char *argv[]) {
/* for time handling */
uint32_t start, stop;
/*set the random value for random generator*/
const long seed = 1121; //the default random seed number
iniranf(seed); //initialize the seed
setrancut(2.0); //default value of the normal cut for the normal distribution
// turn on globval.Cavity_on and globval.radiation to get proper synchro radiation damping
// IDs accounted too if: wiggler model and symplectic integrator (method = 1)
globval.H_exact = false;
/* parameters to read the user input script .prm */
long i=0L; //initialize the for loop to read command string
//long j=0L; //initialize the for loop to read the files from parallel computing
char CommandStr[max_str];
double nux = 0.0, nuy = 0.0, ksix = 0.0, ksiy = 0.0;
bool chroma=true;
double dP = 0.0;
long lastpos = -1L;
char str1[S_SIZE];
// paramters to read the command line in user input script
long CommandNo = -1L; //the number of commands, since this value is also
// the index of array UserCommandFlag[], so this
// value is always less than 1 in the really case.
const int NCOMMAND = 500;
UserCommand UserCommandFlag[NCOMMAND];
#if MPI_EXEC
//Initialize parallel computation
MPI_Init(&argc, &argv);
#endif
/************************************************************************
read in files and flags
*************************************************************************/
if (argc > 1) {
read_script(argv[1], true, CommandNo, UserCommandFlag);
}
else {
fprintf(stdout, "Not enough parameters\nSyntax is program parameter file\n");
exit_(1);
}
/* get the family index of the special elements, prepare for printglob()*/
if(strcmp(bpm_name,"")==0)
globval.bpm = 0;
else
globval.bpm = ElemIndex(bpm_name);
if(strcmp(skew_quad_name,"")==0)
globval.qt = 0;
else
globval.qt = ElemIndex(skew_quad_name);
if(strcmp(hcorr_name,"")==0)
globval.hcorr = 0;
else
globval.hcorr = ElemIndex(hcorr_name);
if(strcmp(vcorr_name,"")==0)
globval.vcorr = 0;
else
globval.vcorr = ElemIndex(vcorr_name);
if(strcmp(gs_name,"")==0)
globval.gs = 0;
else
globval.gs = ElemIndex(gs_name);
if(strcmp(ge_name,"")==0)
globval.ge = 0;
else
globval.ge = ElemIndex(ge_name);
// globval.g = ElemIndex("g"); /* get family index of girder*/
/* print the summary of the element in lattice */
printglob();
/************************************************************************
print files, very important file for debug
*************************************************************************/
//print flat file with all the design values of the lattice,
prtmfile("flat_file.out");
// print location, twiss parameters and close orbit at all elements position to a file
getcod(dP, lastpos);
prt_cod("cod.out", globval.bpm, true);
//get_matching_params_scl(); // get tunes and beta functions at entrance
// compute up to 3rd order momentum compact factor
get_alphac2();
//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
/*********************************************************************
Flag factory
*********************************************************************/
for(i=0; i<=CommandNo; i++){//read user defined command by sequence
//assign user defined command
strcpy(CommandStr,UserCommandFlag[i].CommandStr);
//turn on flag for quadrupole fringe field
if(strcmp(CommandStr,"QuadFringeOnFlag") == 0) {
globval.quad_fringe = true;
cout << "\n";
cout << "globval.quad_fringe is " << globval.quad_fringe << "\n";
}
//deactive quadrupole fringe field
else if(strcmp(CommandStr,"QuadFringeOffFlag") == 0) {
globval.quad_fringe = false;
cout << "\n";
cout << "globval.quad_fringe is " << globval.quad_fringe << "\n";
}
//set RF voltage
else if(strcmp(CommandStr,"RFvoltageFlag") == 0) {
fprintf(stdout, "\nSetting RF voltage:\n");
fprintf(stdout, " Old RF voltage is: %lf [MV]\n", get_RFVoltage(globval.cav)
/ 1e6);
set_RFVoltage(globval.cav, UserCommandFlag[i].RFvolt);
fprintf(stdout, " New RF voltage is: %lf [MV]\n", get_RFVoltage(globval.cav)
/ 1e6);
}
// Chamber factory
else if(strcmp(CommandStr,"ReadChamberFlag") == 0) {
ReadCh(UserCommandFlag[i].chamber_file); /* read vacuum chamber from a file "Apertures.dat" , soleil version*/
PrintCh(); // print chamber into chamber.out
}
// read the misalignment errors to the elements
// Based on the function error_and_correction() in nsls-ii_lib_templ.h
else if (strcmp(CommandStr,"ReadaefileFlag") == 0) {
// load misalignments
cout << "Read misalignment errors from file: " << UserCommandFlag[i].ae_file << endl;
LoadAlignTol(UserCommandFlag[i].ae_file, true, 1.0, true, 0);
Ring_GetTwiss(true, 0.0);
}
//do COD correction using SVD method.
else if(strcmp(CommandStr,"CODCorrectFlag") == 0) {
cout << "Begin Closed Orbit correction: " << endl;
if(n_orbit < 1){
cout << "interation number n_obit should NOT small than 1!!!" << endl;
exit_(1);
}
CODCorrect(hcorr_file,vcorr_file, n_orbit,nwh,nwv);
Ring_GetTwiss(true, 0.0);
prt_cod("summary_miserr_codcorr.out", globval.bpm, true);
}
// set the field error into the lattice
// The corresponding field error is replaced by the new value.
// This feature is generic, works for all lattices
else if (strcmp(CommandStr,"ReadfefileFlag") == 0) {
fprintf(stdout,"\n Read multipole field errors from file: %s \n", UserCommandFlag[i].fe_file);
LoadFieldErrs(UserCommandFlag[i].fe_file, true, 1.0, true, 1);
Ring_GetTwiss(true, 0.0);
prtmfile("flat_file_fefile.out");
}
// read multipole errors from a file; specific for soleil lattice
else if(strcmp(CommandStr,"ReadMultipoleFlag") == 0) {
fprintf(stdout,"\n Read Multipoles field error for SOLEIL lattice with thick sextupoles, from file:\n");
fprintf(stdout," %s\n",multipole_file);
ReadFieldErr(multipole_file);
//first print the full lattice with error as a flat file
prtmfile("flat_file_errmultipole.out"); // writes flat file with all element errors /* very important file for debug*/
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printglob();
}
// read the sources of coupling from a file; for soleil lattice
else if(strcmp(CommandStr,"ReadVirtualSkewquadFlag") == 0) {
fprintf(stdout,"\n Read virtual skew quadrupole setting of SOLEIL lattice from file:\n");
fprintf(stdout," %s \n",virtualskewquad_file);
ReadVirtualSkewQuad(virtualskewquad_file);
//first print the full lattice with sources of coupling as a flat file
prtmfile("flat_file_skewquad.out"); /* very important file for debug*/
//get the coupling
Coupling_Edwards_Teng();
}
//print the twiss paramaters in a file defined by the name
else if(strcmp(CommandStr,"PrintTwissFlag") == 0) {
cout << "\n";
cout << "print the twiss parameters to file: "
<< UserCommandFlag[i]._PrintTwiss_twiss_file << "\n";
printlatt(UserCommandFlag[i]._PrintTwiss_twiss_file);
}
//print the closed orbit
else if(strcmp(CommandStr,"PrintCODFlag") == 0) {
cout << "\n";
cout << "print the closed orbit to file: "
<< UserCommandFlag[i]._PrintCOD_cod_file << "\n";
getcod(dP, lastpos);
prt_cod(UserCommandFlag[i]._PrintCOD_cod_file, globval.bpm, true);
}
//print coordinates at lattice elements obtained by tracking
else if(strcmp(CommandStr,"PrintTrackFlag") == 0) {
cout << "\n";
cout << "print the tracked coordinates to file: "
<< UserCommandFlag[i]._PrintTrack_track_file << "\n";
PrintTrack(UserCommandFlag[i]._PrintTrack_track_file,
UserCommandFlag[i]._PrintTrack_x, UserCommandFlag[i]._PrintTrack_px,
UserCommandFlag[i]._PrintTrack_y, UserCommandFlag[i]._PrintTrack_py,
UserCommandFlag[i]._PrintTrack_delta,UserCommandFlag[i]._PrintTrack_ctau,
UserCommandFlag[i]._PrintTrack_nmax);
}
//print the girder
// else if(strcmp(CommandStr,"PrintGirderFlag") == 0) {
// cout << "\n";
// cout << "print the information of girder to file: "<< girder_file << "\n";
// getcod(dP, lastpos);
// prt_cod(cod_file, globval.bpm, true);
// }
// compute tunes by tracking (should be the same as by tps)
else if (strcmp(CommandStr,"TuneTracFlag") == 0) {
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)
else if(strcmp(CommandStr,"ChromTracFlag") == 0) {
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) {
else if(strcmp(CommandStr,"FitTuneFlag") == 0) {
double qf_bn = 0.0, qd_bn = 0.0;
double qf_bn_fit = 0.0, qd_bn_fit = 0.0;
/* quadrupole field strength before fitting*/
qf_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qf), 1)].Elem.M->PB[HOMmax + 2];
qd_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qd), 1)].Elem.M->PB[HOMmax + 2];
/* fitting tunes*/
fprintf(stdout,
"\n Fitting tunes: %s %s, targetnux = %f, targetnuz = %f \n", UserCommandFlag[i].qf,
UserCommandFlag[i].qd,UserCommandFlag[i].targetnux, UserCommandFlag[i].targetnuz);
FitTune(ElemIndex(UserCommandFlag[i].qf), ElemIndex(UserCommandFlag[i].qd),
UserCommandFlag[i].targetnux, UserCommandFlag[i].targetnuz);
/* integrated field strength after fitting*/
qf_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qf), 1)].Elem.M->PB[HOMmax + 2];
qd_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qd), 1)].Elem.M->PB[HOMmax + 2];
/* print out the quadrupole strengths before and after the fitting*/
fprintf(stdout, "Before the fitting, the quadrupole field strengths are: \n");
fprintf(stdout, " %s = %f, %s = %f\n", UserCommandFlag[i].qf, qf_bn, UserCommandFlag[i].qd, qd_bn);
fprintf(stdout, "After the fitting, the quadrupole field strengths are: \n");
fprintf(stdout, " %s = %f, %s = %f\n", UserCommandFlag[i].qf, qf_bn_fit, UserCommandFlag[i].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) {
else if(strcmp(CommandStr,"FitTune4Flag") == 0) {
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;
/* quadrupole field strength before fitting*/
qf1_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qf1), 1)].Elem.M->PB[HOMmax + 2];
qf2_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qf2), 1)].Elem.M->PB[HOMmax + 2];
qd1_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qd1), 1)].Elem.M->PB[HOMmax + 2];
qd2_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qd2), 1)].Elem.M->PB[HOMmax + 2];
/* fitting tunes*/
fprintf(
stdout,
"\n Fitting tunes for Soleil ring: %s %s %s %s, targetnux = %f, targetnuz = %f \n",
UserCommandFlag[i].qf1, UserCommandFlag[i].qf2, UserCommandFlag[i].qd1, UserCommandFlag[i].qd2,
UserCommandFlag[i].targetnux, UserCommandFlag[i].targetnuz);
FitTune4(ElemIndex(UserCommandFlag[i].qf1), ElemIndex(UserCommandFlag[i].qf2),
ElemIndex(UserCommandFlag[i].qd1), ElemIndex(UserCommandFlag[i].qd2),
UserCommandFlag[i].targetnux, UserCommandFlag[i].targetnuz);
/* integrated field strength after fitting*/
qf1_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qf1), 1)].Elem.M->PB[HOMmax + 2];
qf2_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qf2), 1)].Elem.M->PB[HOMmax + 2];
qd1_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qd1), 1)].Elem.M->PB[HOMmax + 2];
qd2_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].qd2), 1)].Elem.M->PB[HOMmax + 2];
/* print out the quadrupole strengths before and after the fitting*/
printf("Before the fitting, the quadrupole field strengths are: \n");
fprintf(stdout, " %s = %f, %s = %f, %s = %f, %s = %f\n", UserCommandFlag[i].qf1, qf1_bn,
UserCommandFlag[i].qf2, qf2_bn, UserCommandFlag[i].qd1, qd1_bn, UserCommandFlag[i].qd2, qd2_bn);
printf("After the fitting, the quadrupole field strengths are: \n");
fprintf(stdout, " %s = %f, %s = %f, %s = %f, %s = %f\n", UserCommandFlag[i].qf1,
qf1_bn_fit, UserCommandFlag[i].qf2, qf2_bn_fit, UserCommandFlag[i].qd1, qd1_bn_fit,
UserCommandFlag[i].qd2, qd2_bn_fit);
/* Compute and get Twiss parameters */
Ring_GetTwiss(chroma = true, 0.0);
printglob(); /* print parameter list */
}
/* fit the chromaticities*/
else if(strcmp(CommandStr,"FitChromFlag") == 0) {
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(UserCommandFlag[i].sxm1), 1)].Elem.M->PB[HOMmax + 3];
sxm2_bn = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].sxm2), 1)].Elem.M->PB[HOMmax + 3];
fprintf(stdout,"\n Fitting chromaticities: %s %s, targetksix = %f, targetksiz = %f\n",
UserCommandFlag[i].sxm1, UserCommandFlag[i].sxm2, UserCommandFlag[i].targetksix,
UserCommandFlag[i].targetksiz);
FitChrom(ElemIndex(UserCommandFlag[i].sxm1), ElemIndex(UserCommandFlag[i].sxm2),
UserCommandFlag[i].targetksix, UserCommandFlag[i].targetksiz);
sxm1_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].sxm1), 1)].Elem.M->PB[HOMmax + 3];
sxm2_bn_fit = Cell[Elem_GetPos(ElemIndex(UserCommandFlag[i].sxm2), 1)].Elem.M->PB[HOMmax + 3];
/* print out the sextupole strengths before and after the fitting*/
fprintf(stdout, "Before the fitting, the sextupole field strengths are \n");
fprintf(stdout, " %s = %f, %s = %f\n", UserCommandFlag[i].sxm1, sxm1_bn, UserCommandFlag[i].sxm2, sxm2_bn);
fprintf(stdout, "After the fitting, the sextupole field strengths are: \n");
fprintf(stdout, " %s = %f, %s = %f\n", UserCommandFlag[i].sxm1, sxm1_bn_fit, UserCommandFlag[i].sxm2, sxm2_bn_fit);
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printglob(); /* print parameter list */
}
// coupling calculation
else if(strcmp(CommandStr,"CouplingFlag") == 0) {
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt("linlat_coupling.out"); /* dump linear lattice functions into "linlat.dat" */
// GetEmittance(ElemIndex("cav"), true); //only for test
Coupling_Edwards_Teng();
// Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
// printglob(); /* print parameter list */
}
// add coupling by random rotating of the full quadrupole magnets
//if (ErrorCouplingFlag == true) {
else if(strcmp(CommandStr,"ErrorCouplingFlag") == 0) {
prtmfile("flat_file.out"); //print the elements without rotation errors
SetErr(UserCommandFlag[i].err_seed, UserCommandFlag[i].err_rms);
prtmfile("flat_file_errcoupling_full.out"); //print the elements with rotation errors
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt("linlat_errcoupling.out"); /* dump linear lattice functions into "linlat.dat" */
Coupling_Edwards_Teng();
// GetEmittance(ElemIndex("cav"), true); //only for test
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
// printlatt();
printglob(); /* print parameter list */
}
// add coupling by random rotating of the half quadrupole magnets, delicated for soleil
else if(strcmp(CommandStr,"ErrorCoupling2Flag") == 0) {
prtmfile("flat_file.out"); //print the elements without rotation errors
SetErr2(UserCommandFlag[i].err_seed, UserCommandFlag[i].err_rms);
prtmfile("flat_file_errcoupling_half.out"); //print the elements with rotation errors
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt("linlat_errcoupling2.out"); /* 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 */
printglob(); /* print parameter list */
}
/******************************************************************************************/
// COMPUTATION PART after setting the model
/******************************************************************************************/
// computes TuneShift with amplitudes
else if(strcmp(CommandStr,"AmplitudeTuneShiftFlag") == 0) {
TunesShiftWithAmplitude(UserCommandFlag[i]._AmplitudeTuneShift_nudx_file,
UserCommandFlag[i]._AmplitudeTuneShift_nudz_file,
UserCommandFlag[i]._AmplitudeTuneShift_nxpoint,
UserCommandFlag[i]._AmplitudeTuneShift_nypoint,
UserCommandFlag[i]._AmplitudeTuneShift_nturn,
UserCommandFlag[i]._AmplitudeTuneShift_xmax,
UserCommandFlag[i]._AmplitudeTuneShift_ymax,
UserCommandFlag[i]._AmplitudeTuneShift_delta);
}
// compute tuneshift with energy
else if(strcmp(CommandStr,"EnergyTuneShiftFlag") == 0) {
TunesShiftWithEnergy(UserCommandFlag[i]._EnergyTuneShift_nudp_file,
UserCommandFlag[i]._EnergyTuneShift_npoint,
UserCommandFlag[i]._EnergyTuneShift_nturn,
UserCommandFlag[i]._EnergyTuneShift_deltamax);
}
// Computes FMA
else if(strcmp(CommandStr,"FmapFlag") == 0) {
fprintf(stdout, "\n begin Fmap calculation for on momentum particles: \n");
#if MPI_EXEC
//initialization for parallel computing
int myid = 0, numprocs = 0;
int namelen = 0;
char processor_name[MPI_MAX_PROCESSOR_NAME]="";
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Get_processor_name(processor_name, &namelen);
fprintf(stdout, "\n Beginning parallel computing: %d of %d is on %s\n", myid, numprocs, processor_name);
fprintf(stdout, "\n Begin Fmap calculation for on momentum particles: \n");
//Each core or process, characterized by myid, will track different region of fmap
fmap_p(UserCommandFlag[i]._FmapFlag_fmap_file,
UserCommandFlag[i]._FmapFlag_nxpoint,
UserCommandFlag[i]._FmapFlag_nypoint,
UserCommandFlag[i]._FmapFlag_nturn,
UserCommandFlag[i]._FmapFlag_xmax,
UserCommandFlag[i]._FmapFlag_ymax,
UserCommandFlag[i]._FmapFlag_delta,
UserCommandFlag[i]._FmapFlag_diffusion,
UserCommandFlag[i]._FmapFlag_printloss,
numprocs, myid);
//Synchronize all cores, till all cores finish fmap of different region,then all cores will proceed.
MPI_Barrier(MPI_COMM_WORLD);
//Collecting data from all files generated by cores, then write to fmap_p.out
if(myid == 0){
FILE *outf;
FILE *outf_loss;
char FmapLossFile[max_str+5]=" ";
// open frequency map file for final results
if ((outf = fopen(UserCommandFlag[i]._FmapFlag_fmap_file, "w")) == NULL){
fprintf(stdout, "psoltracy: error while opening file %s\n", UserCommandFlag[i]._FmapFlag_fmap_file);
exit_(1);
}
// open frequency map loss file for final results
if (UserCommandFlag[i]._FmapFlag_printloss){
strcpy(FmapLossFile, UserCommandFlag[i]._FmapFlag_fmap_file);
strcat(FmapLossFile, ".loss");
if ((outf_loss = fopen(FmapLossFile, "w")) == NULL){
fprintf(stdout, "psoltracy: error while opening file %s\n", UserCommandFlag[i]._FmapFlag_fmap_file);
exit_(1);
}
}
FILE *fp, *fp_loss;
char buffer[81];
char FmapFile[max_str];
for(int j = 0; j < numprocs; j++){
FmapFile[0]='\0';
sprintf(FmapFile,"%d",j);
strcat(FmapFile, UserCommandFlag[i]._FmapFlag_fmap_file);
if((fp = fopen(FmapFile, "r")) == NULL) {
fprintf(stdout, "%s: error while opening file.\n", FmapFile);
exit_(1);
}
// concatanation of the results, add current j-file to the master file
while(fgets(buffer, max_str, fp) != NULL){
fputs(buffer, outf);
buffer[0]='\0';
}
fclose(fp);
if (UserCommandFlag[i]._FmapFlag_printloss){
strcpy(FmapLossFile,FmapFile);
strcat(FmapLossFile,".loss");
if((fp_loss = fopen(FmapLossFile, "r")) == NULL) {
fprintf(stdout, "%s: error while opening file.\n", FmapLossFile);
exit_(1);
}
// concatanation of the results, add current j-file to the master file
while(fgets(buffer, max_str, fp_loss) != NULL){
fputs(buffer, outf_loss);
buffer[0]='\0';
}
fclose(fp_loss);
}
}
fclose(outf);
if (UserCommandFlag[i]._FmapFlag_printloss){
fclose(outf_loss);
}
}
MPI_Barrier(MPI_COMM_WORLD);
printf("Process %d finished for on momentum fmap.\n", myid);
#else // Single processor
fmap(UserCommandFlag[i]._FmapFlag_fmap_file,
UserCommandFlag[i]._FmapFlag_nxpoint,
UserCommandFlag[i]._FmapFlag_nypoint,
UserCommandFlag[i]._FmapFlag_nturn,
UserCommandFlag[i]._FmapFlag_xmax,
UserCommandFlag[i]._FmapFlag_ymax,
UserCommandFlag[i]._FmapFlag_delta,
UserCommandFlag[i]._FmapFlag_diffusion,
UserCommandFlag[i]._FmapFlag_printloss);
#endif // MPI
}
// Compute FMA dp
else if(strcmp(CommandStr,"FmapdpFlag") == 0) {
fprintf(stdout, "\n begin Fmap calculation for off momentum particles: \n");
#if MPI_EXEC
//initialization for parallel computing
int myid=0, numprocs=0;
int namelen=0;
char processor_name[MPI_MAX_PROCESSOR_NAME]="";
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Get_processor_name(processor_name, &namelen);
printf("Beginning parallel computing: %d of %d is on %s\n", myid, numprocs, processor_name);
fprintf(stdout, "\n begin Fmap calculation for off momentum particles: \n");
fmapdp_p(UserCommandFlag[i]._FmapdpFlag_fmapdp_file,
UserCommandFlag[i]._FmapdpFlag_nxpoint,
UserCommandFlag[i]._FmapdpFlag_nepoint,
UserCommandFlag[i]._FmapdpFlag_nturn,
UserCommandFlag[i]._FmapdpFlag_xmax,
UserCommandFlag[i]._FmapdpFlag_emax,
UserCommandFlag[i]._FmapdpFlag_z,
UserCommandFlag[i]._FmapdpFlag_diffusion,
UserCommandFlag[i]._FmapdpFlag_printloss, numprocs, myid);
//Synchronize all cores, till all cores finish fmap of different region,then all cores will proceed.
MPI_Barrier(MPI_COMM_WORLD);
//Collecting data from all files generated by cores, then write to fmap_p.out
if(myid == 0){
FILE *outf, *outf_loss;
char FmapdpLossFile[max_str+5]=" ";
if ((outf = fopen(UserCommandFlag[i]._FmapdpFlag_fmapdp_file, "w")) == NULL){
fprintf(stdout, "psoltracy: error while opening file %s\n",
UserCommandFlag[i]._FmapdpFlag_fmapdp_file);
exit_(1);
}
// open frequency map loss file for final results
if (UserCommandFlag[i]._FmapdpFlag_printloss){
strcpy(FmapdpLossFile, UserCommandFlag[i]._FmapdpFlag_fmapdp_file);
strcat(FmapdpLossFile, ".loss");
if ((outf_loss = fopen(FmapdpLossFile, "w")) == NULL){
fprintf(stdout, "psoltracy: error while opening file %s\n",
UserCommandFlag[i]._FmapdpFlag_fmapdp_file);
exit_(1);
}
}
FILE *fp, *fp_loss;
char buffer[81];
char FmapdpFile[50];
for(int j = 0; j < numprocs; j++){
FmapdpFile[0]='\0';
sprintf(FmapdpFile,"%d",j);
strcat(FmapdpFile, UserCommandFlag[i]._FmapdpFlag_fmapdp_file);
if((fp = fopen(FmapdpFile, "r")) == NULL){
fprintf(stdout, "%s: error while opening file.\n", FmapdpFile);
exit_(1);
}
// concatanation of the results, add current j-file to the master file
while(fgets(buffer, max_str, fp) != NULL){
fputs(buffer, outf);
buffer[0]='\0';
}
fclose(fp);
if (UserCommandFlag[i]._FmapdpFlag_printloss){
strcpy(FmapdpLossFile, FmapdpFile);
strcat(FmapdpLossFile,".loss");
if((fp_loss = fopen(FmapdpLossFile, "r")) == NULL) {
fprintf(stdout, "%s: error while opening file.\n", FmapdpLossFile);
exit_(1);
}
// concatanation of the results, add current j-file to the master file
while(fgets(buffer, max_str, fp_loss) != NULL){
fputs(buffer, outf_loss);
buffer[0]='\0';
}
fclose(fp_loss);
} // if printloss
} // for loop
fclose(outf);
if (UserCommandFlag[i]._FmapFlag_printloss){
fclose(outf_loss);
}
} // if myid
MPI_Barrier(MPI_COMM_WORLD);
fprintf(stdout, "Process %d finished off momentum fmap.\n", myid);
#else //single processor
fmapdp(UserCommandFlag[i]._FmapdpFlag_fmapdp_file,
UserCommandFlag[i]._FmapdpFlag_nxpoint,
UserCommandFlag[i]._FmapdpFlag_nepoint,
UserCommandFlag[i]._FmapdpFlag_nturn,
UserCommandFlag[i]._FmapdpFlag_xmax,
UserCommandFlag[i]._FmapdpFlag_emax,
UserCommandFlag[i]._FmapdpFlag_z,
UserCommandFlag[i]._FmapdpFlag_diffusion,
UserCommandFlag[i]._FmapdpFlag_printloss);
#endif
}
// // if (CodeComparaisonFlag) {
// else if(strcmp(CommandStr,"CodeComparaisonFlag") == 0) {
// fmap(200, 100, 1026, -32e-3, 7e-3, 0.0, true);
// }
// MOMENTUM ACCEPTANCE
else if(strcmp(CommandStr,"MomentumAccFlag") == 0) {
bool cavityflag, radiationflag;
/* record the initial values*/
cavityflag = globval.Cavity_on;
radiationflag = globval.radiation;
if (strcmp(UserCommandFlag[i]._MomentumAccFlag_TrackDim,"6D") == 0) {
globval.Cavity_on = true;
globval.radiation = true;
}else if (strcmp(UserCommandFlag[i]._MomentumAccFlag_TrackDim,"4D") == 0) {
globval.Cavity_on = false;
globval.radiation = false;
} else {
printf("MomentumAccFlag: Error!!! DimTrack must be '4D' or '6D'\n");
exit_(1);
};
/* calculate momentum acceptance*/
fprintf(stdout, "\n Calculate momentum acceptance: \n");
#if MPI_EXEC
/* calculate momentum acceptance*/
//initialization for parallel computing
int myid=0, numprocs=0;
int namelen=0;
char processor_name[MPI_MAX_PROCESSOR_NAME]="";
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Get_processor_name(processor_name, &namelen);
printf("Beginning parallel computing: %d of %d is on %s\n", myid, numprocs, processor_name);
fprintf(stdout, "\n Calculate momentum acceptance: \n");
MomentumAcceptance_p(UserCommandFlag[i]._MomentumAccFlag_momacc_file,
UserCommandFlag[i]._MomentumAccFlag_istart,
UserCommandFlag[i]._MomentumAccFlag_istop,
UserCommandFlag[i]._MomentumAccFlag_deltaminp,
UserCommandFlag[i]._MomentumAccFlag_deltamaxp,
UserCommandFlag[i]._MomentumAccFlag_nstepp,
UserCommandFlag[i]._MomentumAccFlag_deltaminn,
UserCommandFlag[i]._MomentumAccFlag_deltamaxn,
UserCommandFlag[i]._MomentumAccFlag_nstepn,
UserCommandFlag[i]._MomentumAccFlag_nturn,
UserCommandFlag[i]._MomentumAccFlag_zmax,
numprocs,myid);
//merge the files
//Synchronize all cores, till finish cal of different region,
//then files from the cores will be processed.
MPI_Barrier(MPI_COMM_WORLD);
//Collect data from all files generated by different cores, then write to user defined file
if(myid==0){
//merge the phase.out from different cpus
FILE *outf1; //phase.out, for debugging
FILE *fp1;
char buffer1[81];
char PhaseFile[50];
if ((outf1 = fopen("phase_p.out", "w")) == NULL){
fprintf(stdout, "psoltracy: error while opening file %s\n", "phase_p.out");
exit_(1);
}
for(int j=0; j<numprocs; j++){
PhaseFile[0]='\0';
sprintf(PhaseFile,"%d",j);
strcat(PhaseFile,"phase.out");
if((fp1 = fopen(PhaseFile, "r")) == NULL){
fprintf(stdout, "%s: error while opening file.\n", PhaseFile);
exit_(1);
}
while(fgets(buffer1, 80, fp1) != NULL){
fputs(buffer1, outf1);
buffer1[0]='\0';
}
fclose(fp1);
} // for loop
//collect data for the momentum acceptance
FILE *outf2; //momentum acceptance
FILE *fp2;
char buffer2[81];
char MAFile[50];
if ((outf2 = fopen(UserCommandFlag[i]._MomentumAccFlag_momacc_file, "w")) == NULL){
fprintf(stdout, "psoltracy: error while opening file %s\n", UserCommandFlag[i]._MomentumAccFlag_momacc_file);
exit_(1);
}
//Collect data in Positive region
for(int j=0; j<numprocs; j++){
MAFile[0]='\0';
sprintf(MAFile,"%d",j);
strcat(MAFile,UserCommandFlag[i]._MomentumAccFlag_momacc_file);
if((fp2 = fopen(MAFile, "r")) == NULL){
fprintf(stdout, "%s: error while opening file.\n", MAFile);
exit_(1);
}
while(fgets(buffer2, 80, fp2) != NULL){
if(strstr(buffer2,"Negative")!=0) break;
fputs(buffer2, outf2);
buffer2[0]='\0'; //reset buffer to NULL
}
buffer2[0]='\0';
fclose(fp2);
}
fprintf(outf2,"\n"); // A void line
//Collect data in Nagative region
for(int j=0; j<numprocs; j++){
MAFile[0]='\0';
sprintf(MAFile,"%d",j);
strcat(MAFile,UserCommandFlag[i]._MomentumAccFlag_momacc_file);
if((fp2 = fopen(MAFile, "r")) == NULL){
fprintf(stdout, "%s: error while opening file.\n", MAFile);
exit_(1);
}
bool found=false;
while(fgets(buffer2, 80, fp2) != NULL){
if((strstr(buffer2,"Negative")==0) && (!found)) { buffer2[0]='\0'; continue;}
if((strstr(buffer2,"Negative")!=0) ) { found=true; buffer2[0]='\0'; continue;}
fputs(buffer2, outf2);
buffer2[0]='\0';
} // while
buffer2[0]='\0';
fclose(fp2);
} // for
fclose(outf2);
}
MPI_Barrier(MPI_COMM_WORLD);
printf("process %d finished momentum acceptance.\n", myid);
#else // single processor coputation
MomentumAcceptance(UserCommandFlag[i]._MomentumAccFlag_momacc_file,
UserCommandFlag[i]._MomentumAccFlag_istart,
UserCommandFlag[i]._MomentumAccFlag_istop,
UserCommandFlag[i]._MomentumAccFlag_deltaminp,
UserCommandFlag[i]._MomentumAccFlag_deltamaxp,
UserCommandFlag[i]._MomentumAccFlag_nstepp,
UserCommandFlag[i]._MomentumAccFlag_deltaminn,
UserCommandFlag[i]._MomentumAccFlag_deltamaxn,
UserCommandFlag[i]._MomentumAccFlag_nstepn,
UserCommandFlag[i]._MomentumAccFlag_nturn,
UserCommandFlag[i]._MomentumAccFlag_zmax);
#endif
/* restore the initial values*/
globval.Cavity_on = cavityflag;
globval.radiation = radiationflag;
}
// induced amplitude
else if(strcmp(CommandStr,"InducedAmplitudeFlag") == 0) {
fprintf(stdout, "\n Calculate induced amplitude: \n");
InducedAmplitude(193L);
}
else if(strcmp(CommandStr,"EtaFlag") == 0) {
// 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("linlat_eta.out"); /* 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);
}
}
// track to get phase space
else if(strcmp(CommandStr,"PhaseSpaceFlag") == 0) {
bool cavityflag, radiationflag;
/* record the initial values*/
cavityflag = globval.Cavity_on;
radiationflag = globval.radiation;
/* set the dimension for the momentum tracking*/
if (strcmp("6D", UserCommandFlag[i]._Phase_Dim) == 0) {
globval.Cavity_on = true;
} else if (strcmp("4D", UserCommandFlag[i]._Phase_Dim) == 0) {
globval.Cavity_on = false;
} else {
printf("MomentumAccFlag: Error!!! _Phase_Dim must be '4D' or '6D'\n");
exit_(1);
};
/* setting damping */
if ( UserCommandFlag[i]._Phase_Damping == true) {
globval.radiation = true;
} else {
globval.radiation = false;
}
start = stampstart();
Phase(UserCommandFlag[i]._Phase_phase_file,
UserCommandFlag[i]._Phase_X,
UserCommandFlag[i]._Phase_Px,
UserCommandFlag[i]._Phase_Y,
UserCommandFlag[i]._Phase_Py,
UserCommandFlag[i]._Phase_delta,
UserCommandFlag[i]._Phase_ctau,
UserCommandFlag[i]._Phase_nturn);
printf("6D phase space tracking: \n the simulation time for phase space in tracy 3 is \n");
stop = stampstop(start);
/* restore the initial values*/
globval.Cavity_on = cavityflag;
globval.radiation = radiationflag;
}
else if (strcmp(CommandStr,"TouschekFlag") == 0 ||strcmp(CommandStr,"IBSFlag") == 0 ||
strcmp(CommandStr,"TousTrackFlag") == 0 ){
// ????????????? 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
// else if(strcmp(CommandStr,"TouschekFlag") == 0) {
double sum_delta[globval.Cell_nLoc + 1][2];
double sum2_delta[globval.Cell_nLoc + 1][2];
GetEmittance(globval.cav, true);
// initialize momentum aperture arrays
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;
}
globval.eps[Y_] = 0.008e-9;
n_turns = 40;
// get the twiss parameters
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) {
double newLength, bunchLengthening;
newLength = 50e-3;
bunchLengthening = newLength / sigma_s;
sigma_s = newLength;
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
}
Touschek(Qb, globval.delta_RF, globval.eps[X_], globval.eps[Y_],
sigma_delta, sigma_s);
// Intra Beam Scattering(IBS)
if (strcmp(CommandStr,"IBSFlag") == 0) {
// initialize eps_IBS with eps_SR
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".
if (strcmp(CommandStr,"TousTrackFlag") == 0) {
// globval.Aperture_on = true;
// ReadCh(UserCommandFlag[i].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);
outf = file_write("mom_aper.out");
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]);
fclose(outf);
}
}
/*
To do ID correction.
Based on parts of functions get_param( ) & ID_corr(), etc in nsls-ii_lib.cc
*/
else if(strcmp(CommandStr,"IDCorrFlag") == 0) {
int k = 0;
cout << endl;
cout << "************ Begin ID matching: **********" <<endl;
// read the family index of quadrupoles used for ID correction
if (N_calls > 0) {
if (N_Fam > N_Fam_max) {
printf("get_param: N_Fam > N_Fam_max: %d (%d)\n",
N_Fam, N_Fam_max);
exit_(0);
}
for (k = 0; k < N_Fam; k++)
Q_Fam[k] = ElemIndex(IDCq_name[k]);
}
//For debug
if(trace){
cout << "scl_dbetax = " << scl_dbetax << " scl_dbetay = " << scl_dbetay <<endl;
cout << "scl_dnux = " << scl_dnux << " scl_dnuy = " << scl_dnuy << endl;
cout << "scl_nux = " << scl_nux << " scl_nuy = " << scl_nuy << endl;
cout << "ID_step = " << ID_step <<endl;
cout << "N_calls = " << N_calls << " N_steps = " << N_steps <<endl;
cout << "Number of quadrupole families used for ID correction: " << N_Fam << endl;
cout << "Quadrupoles used for ID correction: " << endl;
for (k = 0; k < N_Fam; k++)
fprintf(stdout, "%d\n",Q_Fam[k]);
}
//initialization
ini_ID_corr();
printlatt("linlat00.out");
ID_corr0();
printlatt("linlat01.out");
// exit(0);
ini_ID_corr();
printlatt("linlat0.out");
ID_corr(N_calls,N_steps);
printlatt("linlat1.out");
}
else{
printf("Command string %s is invalid!!!!!\n ",CommandStr);
exit_(1);
}//give an error message
}//end of looking for user defined flag
#if MPI_EXEC
MPI_Finalize(); //finish parallel computation
#endif
return 0;
}//end of main()