Newer
Older
/************************************
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
#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
//
//****************************************************************************************
/*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)
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
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
*************************************************************************/
fprintf(stdout, "Not enough parameters\nSyntax is program parameter file\n");
/* 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 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
*********************************************************************/
//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_RFVoltage(globval.cav, UserCommandFlag[i].RFvolt);
printf(" New RF voltage is: %lf [MV]\n", get_RFVoltage(globval.cav)
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);
// 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.dat");
}
// read multipole errors from a file; specific for soleil lattice
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.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();
}
// 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.dat"); /* 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 close orbit
else if(strcmp(CommandStr,"PrintCODFlag") == 0) {
cout << "\n";
cout << "print the close orbit to file: "
<< UserCommandFlag[i]._PrintCOD_cod_file << "\n";
//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);
// }
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)
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;
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];
"\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);
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];
printf("Before the fitting, the quadrupole field strengths are: \n");
printf(" %s = %f, %s = %f\n", UserCommandFlag[i].qf, qf_bn, UserCommandFlag[i].qd, qd_bn);
printf("After the fitting, the quadrupole field strengths are: \n");
printf(" %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;
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];
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);
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];
printf("Before the fitting, the quadrupole field strengths are: \n");
printf(" %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");
printf(" %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 */
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];
printf("Before the fitting, the sextupole field strengths are \n");
printf(" %s = %f, %s = %f\n", UserCommandFlag[i].sxm1, sxm1_bn, UserCommandFlag[i].sxm2, sxm2_bn);
printf("After the fitting, the sextupole field strengths are: \n");
printf(" %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 */
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
printlatt("linlat_coupling.out"); /* dump linear lattice functions into "linlat.dat" */
// Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
// printglob(); /* print parameter list */
//if (ErrorCouplingFlag == true) {
else if(strcmp(CommandStr,"ErrorCouplingFlag") == 0) {
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("linlat_errcoupling.out"); /* 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
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("linlat_errcoupling2.out"); /* dump linear lattice functions into "linlat.dat" */
// GetEmittance(ElemIndex("cav"), true);
Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
/******************************************************************************************/
// COMPUTATION PART after setting the model
/******************************************************************************************/
// computes TuneShift with amplitudes
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);
}
else if(strcmp(CommandStr,"FmapFlag") == 0) {
printf("\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);
printf("\n Beginning parallel computing: %d of %d is on %s\n", myid, numprocs, processor_name);
printf("\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);
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
//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)
{
// system("cp 0fmap.out fmap_p.out");
FILE *outf;
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);
}
FILE *fp;
char buffer[81];
char FmapFile[50];
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);
}
while(fgets(buffer, 80, fp) != NULL)
{
fputs(buffer, outf);
buffer[0]='\0';
}
fclose(fp);
}
fclose(outf);
}
MPI_Barrier(MPI_COMM_WORLD);
printf("Process %d finished for on momentum fmap.\n", myid);
#else
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);
else if(strcmp(CommandStr,"FmapdpFlag") == 0) {
printf("\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);
printf("\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]._FmapFlag_printloss
numprocs,myid);
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
//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)
{
// system("cp 0fmap.out fmap_p.out");
FILE *outf;
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);
}
FILE *fp;
char buffer[81];
char FmapFile[50];
for(int j=0; j<numprocs; j++)
{
FmapFile[0]='\0';
sprintf(FmapFile,"%d",j);
strcat(FmapFile,UserCommandFlag[i]._FmapdpFlag_fmapdp_file);
if((fp = fopen(FmapFile, "r")) == NULL)
{
fprintf(stdout, "%s: error while opening file.\n", FmapFile);
exit_(1);
}
while(fgets(buffer, 80, fp) != NULL)
{
fputs(buffer, outf);
buffer[0]='\0';
}
fclose(fp);
}
fclose(outf);
}
MPI_Barrier(MPI_COMM_WORLD);
printf("Process %d finished off momentum fmap.\n", myid);
#else
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);
// }
/* record the initial values*/
cavityflag = globval.Cavity_on;
radiationflag = globval.radiation;
if (strcmp(UserCommandFlag[i]._MomentumAccFlag_TrackDim,"6D") == 0) {
}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*/
printf("\n Calculate momentum acceptance: \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);
MomentumAcceptance_p(UserCommandFlag[i]._MomentumAccFlag_momacc_file,
UserCommandFlag[i]._MomentumAccFlag_istop,
UserCommandFlag[i]._MomentumAccFlag_deltaminp,
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
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);
}
//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';
}
buffer2[0]='\0';
fclose(fp2);
}
fclose(outf2);
}
MPI_Barrier(MPI_COMM_WORLD);
printf("process %d finished momentum acceptance.\n", myid);
#else
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;
}
else if(strcmp(CommandStr,"InducedAmplitudeFlag") == 0) {
printf("\n Calculate induced amplitude: \n");
// 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);
bool cavityflag, radiationflag;
/* record the initial values*/
cavityflag = globval.Cavity_on;
radiationflag = globval.radiation;
/* set the dimension for the momentum tracking*/
globval.Cavity_on = false;
} else {
printf("MomentumAccFlag: Error!!! _Phase_Dim must be '4D' or '6D'\n");
exit_(1);
};
/* setting damping */
globval.radiation = true;
} else {
globval.radiation = false;
}
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");
/* 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
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".
// 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);
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]);
}
/*
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 (int k = 0; k < N_Fam; k++)
printf("%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
#if MPI_EXEC
MPI_Finalize(); //finish parallel computation
#endif