Skip to content
Snippets Groups Projects
soltracy.cc 16.2 KiB
Newer Older
zhang's avatar
zhang committed
#define ORDER 1          

int no_tps = ORDER; // arbitrary TPSA order is defined locally

nadolski's avatar
nadolski committed
extern bool freq_map;
zhang's avatar
zhang committed

#include "tracy_lib.h"
zhang's avatar
zhang committed
//***************************************************************************************
//
//  MAIN CODE
//
//****************************************************************************************
nadolski's avatar
nadolski committed
int main(int argc, char *argv[]) {
  const long seed = 1121;
  iniranf(seed);
  setrancut(2.0);
zhang's avatar
zhang committed

  // 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)
nadolski's avatar
nadolski committed
  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;
zhang's avatar
zhang committed
  bool chroma;
  double dP = 0.0;
  long lastpos = -1L;
  char str1[S_SIZE];

  // for time handling
nadolski's avatar
nadolski committed
  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 parameterfile\n");
    exit_(1);
nadolski's avatar
nadolski committed
  /************************************************************************
   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);

zhang's avatar
zhang committed
  // Flag factory
nadolski's avatar
nadolski committed

zhang's avatar
zhang committed
  //set RF voltage  
nadolski's avatar
nadolski committed
  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
zhang's avatar
zhang committed
  if (ChamberFlag == false)
nadolski's avatar
nadolski committed
    ChamberOff(); // turn off vacuum chamber setting, use the default one
zhang's avatar
zhang committed
  else if (ChamberNoU20Flag == true)
nadolski's avatar
nadolski committed
    DefineChNoU20(); // using vacuum chamber setting but without undulator U20
zhang's avatar
zhang committed
  else if (ReadChamberFlag == true)
nadolski's avatar
nadolski committed
    ReadCh(chamber_file); /* read vacuum chamber from a file "Apertures.dat" , soleil version*/
  PrintCh(); // print chamber into chamber.out
nadolski's avatar
nadolski committed

nadolski's avatar
nadolski committed
  //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

nadolski's avatar
nadolski committed

  // compute tunes by tracking (should be the same as by tps)
zhang's avatar
zhang committed
  if (TuneTracFlag == true) {
nadolski's avatar
nadolski committed
    GetTuneTrac(1026L, 0.0, &nux, &nuy);
    fprintf(stdout, "From tracking: nux = % f nuz = % f \n", nux, nuy);
zhang's avatar
zhang committed
  }

  // compute chromaticities by tracking (should be the same as by DA)
nadolski's avatar
nadolski committed
  if (ChromTracFlag == true) {
    start = stampstart();
    GetChromTrac(2L, 1026L, 1e-5, &ksix, &ksiy);
    stop = stampstop(start);
nadolski's avatar
nadolski committed
    fprintf(stdout, "From tracking: ksix= % f ksiz= % f \n", ksix, ksiy);
zhang's avatar
zhang committed
  }

nadolski's avatar
nadolski committed
  //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;
zhang's avatar
zhang committed

zhang's avatar
zhang committed
    /* quadrupole field strength before fitting*/
nadolski's avatar
nadolski committed
    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];

zhang's avatar
zhang committed
    /* fitting tunes*/
nadolski's avatar
nadolski committed
    fprintf(stdout,
        "\n Fitting tunes: %s %s, targetnux = %f, targetnuz = %f \n", qf, qd,
        targetnux, targetnuz);
    FitTune(ElemIndex(qf), ElemIndex(qd), targetnux, targetnuz);

zhang's avatar
zhang committed
    /* integrated field strength after fitting*/
nadolski's avatar
nadolski committed
    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];
zhang's avatar
zhang committed
    /* print out the quadrupole strengths before and after the fitting*/
nadolski's avatar
nadolski committed
    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 */
zhang's avatar
zhang committed
  }
nadolski's avatar
nadolski committed

  /* 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;

zhang's avatar
zhang committed
    /* quadrupole field strength before fitting*/
nadolski's avatar
nadolski committed
    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];

zhang's avatar
zhang committed
    /* fitting tunes*/
nadolski's avatar
nadolski committed
    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);

zhang's avatar
zhang committed
    /* integrated field strength after fitting*/
nadolski's avatar
nadolski committed
    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];
zhang's avatar
zhang committed
    /* print out the quadrupole strengths before and after the fitting*/
nadolski's avatar
nadolski committed
    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 */
zhang's avatar
zhang committed
  }

zhang's avatar
zhang committed
  /* fit the chromaticities*/
nadolski's avatar
nadolski committed
  if (FitChromFlag == true) {

zhang's avatar
zhang committed
    double sxm1_bn = 0.0, sxm2_bn = 0.0;
    double sxm1_bn_fit = 0.0, sxm2_bn_fit = 0.0;
nadolski's avatar
nadolski committed
    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];

nadolski's avatar
nadolski committed
    /* fit the chromaticities*/
nadolski's avatar
nadolski committed
    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];
zhang's avatar
zhang committed
    /* print out the sextupole strengths before and after the fitting*/
nadolski's avatar
nadolski committed
    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 */
zhang's avatar
zhang committed
  }

  // coupling calculation
nadolski's avatar
nadolski committed
  if (CouplingFlag == true) {
    Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
    printlatt(); /* dump linear lattice functions into "linlat.dat" */
    GetEmittance(ElemIndex("cav"), true);
    Coupling_Edwards_Teng();
    printglob(); /* print parameter list */
  }
zhang's avatar
zhang committed

nadolski's avatar
nadolski committed
  // add coupling by random rotating of the quadrupole magnets
nadolski's avatar
nadolski committed
  if (ErrorCouplingFlag == true) {
    SetErr(err_seed, err_rms);
    Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
    printlatt(); /* dump linear lattice functions into "linlat.dat" */
nadolski's avatar
nadolski committed
    Coupling_Edwards_Teng();
    GetEmittance(ElemIndex("cav"), true);
nadolski's avatar
nadolski committed
    printglob(); /* print parameter list */
zhang's avatar
zhang committed
  }

  // WARNING Fit tunes and chromaticities before applying errors !!!!
  //set multipoles in all magnets
zhang's avatar
zhang committed
  // read multipole error from a file
nadolski's avatar
nadolski committed
  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_error.dat"); // writes flat file   /* very important file for debug*/
    Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
    printglob();
zhang's avatar
zhang committed
  }
nadolski's avatar
nadolski committed

  //Old version to multipole errors in soleil lattice, is obsoleted
nadolski's avatar
nadolski committed
  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_error.dat"); // writes flat file   /* very important file for debug*/
nadolski's avatar
nadolski committed
      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_error.dat"); // writes flat file   /* very important file for debug*/
nadolski's avatar
nadolski committed
      Ring_GetTwiss(chroma = true, 0.0); /* Compute and get Twiss parameters */
      printglob();
zhang's avatar
zhang committed
    }
  }
nadolski's avatar
nadolski committed

nadolski's avatar
nadolski committed
  /******************************************************************************************/
  // COMPUTATION PART after setting the model
  /******************************************************************************************/

  // computes TuneShift with amplitudes
  if (AmplitudeTuneShiftFlag == true) {
    if (ChamberFlag == true) {
      NuDx(_AmplitudeTuneShift_nxpoint, _AmplitudeTuneShift_nypoint,
          _AmplitudeTuneShift_nturn, _AmplitudeTuneShift_xmax,
          _AmplitudeTuneShift_ymax, _AmplitudeTuneShift_delta);
nadolski's avatar
nadolski committed
      //NuDx(31L,21L,516L,0.025,0.005,dP);
nadolski's avatar
nadolski committed
    } else { // Utility ?
      NuDx(50L, 30L, 516L, 0.035, 0.02, dP);
    }
nadolski's avatar
nadolski committed

  }
nadolski's avatar
nadolski committed
  if (EnergyTuneShiftFlag == true) {
    if (ChamberFlag == true) {
      NuDp(_EnergyTuneShift_npoint, _EnergyTuneShift_nturn,
          _EnergyTuneShift_deltamax);
nadolski's avatar
nadolski committed
      //NuDp(31L,1026L,0.06);
nadolski's avatar
nadolski committed
    } else { // utility ?
      NuDp(31L, 1026L, 0.06);
    }
nadolski's avatar
nadolski committed

  }

nadolski's avatar
nadolski committed
  // Computes FMA
  if (FmapFlag == true) {
    fmap(_FmapFlag_nxpoint, _FmapFlag_nypoint, _FmapFlag_nturn, _FmapFlag_xmax,
        _FmapFlag_ymax, _FmapFlag_delta, _FmapFlag_diffusion);
zhang's avatar
zhang committed
  }

nadolski's avatar
nadolski committed
  // Compute FMA dp
  if (FmapdpFlag == true) {
    fmapdp(_FmapdpFlag_nxpoint, _FmapdpFlag_nepoint, _FmapdpFlag_nturn,
        _FmapdpFlag_xmax, _FmapdpFlag_emax, _FmapdpFlag_z,
        _FmapdpFlag_diffusion);
zhang's avatar
zhang committed
  }

nadolski's avatar
nadolski committed
  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);
    };

    /* calculate momentum accepetance*/
    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;
  }
zhang's avatar
zhang committed

  // induced amplitude 
nadolski's avatar
nadolski committed
  if (InducedAmplitudeFlag == true) {
    InducedAmplitude(193L);
zhang's avatar
zhang committed
  }
nadolski's avatar
nadolski committed

  if (EtaFlag == true) {
    // 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);
zhang's avatar
zhang committed
    }
  }
zhang's avatar
zhang committed

nadolski's avatar
nadolski committed
  if (PhaseSpaceFlag == true) {
    start = stampstart();
    Phase(0.001, 0, 0.001, 0, 0.001, 0, 1);
    printf("the simulation time for phase space in tracy 3 is \n");
    stop = stampstop(start);
  }

  //  ????????????? 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
zhang's avatar
zhang committed

  if (TouschekFlag == true) {
nadolski's avatar
nadolski committed
    double sum_delta[globval.Cell_nLoc + 1][2];
    double sum2_delta[globval.Cell_nLoc + 1][2];

zhang's avatar
zhang committed
    GetEmittance(ElemIndex("cav"), true);
nadolski's avatar
nadolski committed

zhang's avatar
zhang committed
    // initialize momentum aperture arrays
nadolski's avatar
nadolski committed
    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;
zhang's avatar
zhang committed
    }
nadolski's avatar
nadolski committed

zhang's avatar
zhang committed
    globval.eps[Y_] = 0.008e-9;
nadolski's avatar
nadolski committed
    n_turns = 40;

zhang's avatar
zhang committed
    // get the twiss parameters
nadolski's avatar
nadolski committed
    alpha_z = -globval.Ascr[ct_][ct_] * globval.Ascr[delta_][ct_]
        - globval.Ascr[ct_][delta_] * globval.Ascr[delta_][delta_];
zhang's avatar
zhang committed
    beta_z = sqr(globval.Ascr[ct_][ct_]) + sqr(globval.Ascr[ct_][delta_]);
nadolski's avatar
nadolski committed
    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);
zhang's avatar
zhang committed

    // INCLUDE LC (LC changes sigma_s and eps_z, but has no influence on sigma_delta)
    if (false) {
nadolski's avatar
nadolski committed
      double newLength, bunchLengthening;
zhang's avatar
zhang committed
      newLength = 50e-3;
nadolski's avatar
nadolski committed
      bunchLengthening = newLength / sigma_s;
zhang's avatar
zhang committed
      sigma_s = newLength;
nadolski's avatar
nadolski committed
      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
zhang's avatar
zhang committed
    }
nadolski's avatar
nadolski committed

zhang's avatar
zhang committed
    Touschek(Qb, globval.delta_RF, globval.eps[X_], globval.eps[Y_],
nadolski's avatar
nadolski committed
        sigma_delta, sigma_s);

zhang's avatar
zhang committed
    // Intra Beam Scattering(IBS)
nadolski's avatar
nadolski committed
    if (IBSFlag == true) {
zhang's avatar
zhang committed
      // initialize eps_IBS with eps_SR
nadolski's avatar
nadolski committed
      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);
    }
zhang's avatar
zhang committed

    // 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".
nadolski's avatar
nadolski committed
    if (TousTrackFlag == true) {
zhang's avatar
zhang committed
      globval.Aperture_on = true;
nadolski's avatar
nadolski committed
      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);

zhang's avatar
zhang committed
      outf = file_write("mom_aper.out");
nadolski's avatar
nadolski committed
      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]);
zhang's avatar
zhang committed
      fclose(outf);
    }
nadolski's avatar
nadolski committed

zhang's avatar
zhang committed
  }
nadolski's avatar
nadolski committed

  return 0;
nadolski's avatar
nadolski committed
}