예제 #1
0
void FDTD2D::updateH(){
  // Bulk update, Hz
  for( int ii=0; ii<Nx-1; ii++){
    for( int jj=0; jj<Ny-1; jj++){
      Hz(ii,jj) += HzC(ii,jj)*(Ex(ii,jj+1) - Ex(ii,jj)
                             - Ey(ii+1,jj) + Ey(ii,jj));
    }
  }
  // No need to account for boundary conditions here; they are included in the E update equations.
  return;
}
예제 #2
0
void FDTD2D::updateE(){
  int ii,jj;
  double CFL2 = CFL;///2.;
  // Bulk update, Ex
  for( jj=1; jj<Ny-1; jj++){
    for( ii=0; ii<Nx-1; ii++){
      Ex(ii,jj) += ExC(ii,jj)*(Hz(ii,jj) - Hz(ii,jj-1));
    }
  }
  // Bulk update, Ey
  for( jj=0; jj<Ny-1; jj++){
    for( ii=1; ii<Nx-1; ii++){
      Ey(ii,jj) -= EyC(ii,jj)*(Hz(ii,jj) - Hz(ii-1,jj));
    }
  }
  // Boundary update, Ex
  for( ii=0; ii<Nx-1; ii++){
    Ex(ii,0)    = (1.-CFL2)*Ex(ii,0)    + CFL2*Ex(ii,1);
    Ex(ii,Ny-1) = (1.-CFL2)*Ex(ii,Ny-1) + CFL2*Ex(ii,Ny-2);
  }
  // Boundary update, Ey
  for( jj=0; jj<Ny-1; jj++){
    Ey(0,jj)    = (1.-CFL2)*Ey(0,jj)    + CFL2*Ey(1,jj);
    Ey(Nx-1,jj) = (1.-CFL2)*Ey(Nx-1,jj) + CFL2*Ey(Nx-2,jj);
  }
  return;
}
예제 #3
0
파일: updatetez.c 프로젝트: aitatanit/uFDTD
/* update magnetic field */
void updateH2d(Grid *g) {
  int mm, nn;

  if (Type == oneDGrid) {

    for (mm = 0; mm < SizeX - 1; mm++)
      Hz1(mm) = Chzh1(mm) * Hz1(mm) 
	- Chze1(mm) * (Ey1(mm + 1) - Ey1(mm));

  } else { 

    for (mm = 0; mm < SizeX - 1; mm++)    /*@ \label{updatetezA} @*/
      for (nn = 0; nn < SizeY - 1; nn++)
	Hz(mm, nn) = Chzh(mm, nn) * Hz(mm, nn) +
	  Chze(mm, nn) * ((Ex(mm, nn + 1) - Ex(mm, nn))
			  - (Ey(mm + 1, nn) - Ey(mm, nn)));
  }

  return;
}
예제 #4
0
void FDTD2D::correctFieldsE(){
  static double eta = sqrt(mu/eps);
  // Left partition at Lx+0.5. Right at Nx-Lx+0.5.
  double l_source = (1./eta)*gauss_der_source(t-(Lx+0.5)*ds/c, sigma, mean);
  double r_source = (1./eta)*gauss_der_source(t-(Nx-Lx+0.5)*ds/c, sigma, mean);
  for( int jj=Ly; jj <= Ny-Ly; jj++){
    Ey(Lx,jj)      += EyC(Lx,jj)      * l_source;
    Ey(Nx-Lx+1,jj) -= EyC(Nx-Lx+1,jj) * r_source; 
  }
  // Bottom partition at Ly+0.5. Top at Ny-Ly+0.5.
  // Note: v.costly, need to evaluate source function at every point!
  double source;
  for( int ii=Lx; ii <= Nx-Lx; ii++){
    if(ii<0) std::cerr << "ii = " << ii << std::endl;
    source = (1./eta)*gauss_der_source(t-(ii+0.5)*ds/c, sigma, mean);
    Ex(ii,Ly)      -= ExC(ii,Ly)      * source;
    Ex(ii,Ny-Ly+1) += ExC(ii,Ny-Ly+1) * source;
  }
  return;
}
예제 #5
0
void FDTD2D::print( std::ofstream& outFile, int spacing){
  // Prints data in a format compatible with gnuplot vector
  // Skips boundary data, doesn't plot Hz
  double length_x, length_y, mean_x, mean_y;
  // MAX OVERRIDE
  // Being printing
  outFile << "# FDTD2D data file\n# x y dx dy Ex Ey" << std::endl;
  for( int jj=0; jj<Ny-1; jj+=spacing){
    for( int ii=0; ii<Nx-1; ii+=spacing){
      mean_x   = 0.5*(Ex(ii,jj)+Ex(ii,jj+1));
      mean_y   = 0.5*(Ey(ii,jj)+Ey(ii+1,jj));
      length_x = spacing*ds*Ex(ii,jj);//mean_x;
      length_y = spacing*ds*Ey(ii,jj);//mean_y;
      outFile << (ii+0.5)*ds << '\t'
              << (jj+0.5)*ds << '\t'
              << length_x    << '\t'
              << length_y    << '\t'
              << mean_x      << '\t'
              << mean_y      << std::endl;
    }
  }
  return;
}
예제 #6
0
파일: updatetez.c 프로젝트: aitatanit/uFDTD
/* update electric field */
void updateE2d(Grid *g) {
  int mm, nn;

  if (Type == oneDGrid) {

    for (mm = 1; mm < SizeX - 1; mm++)
      Ey1(mm) = Ceye1(mm) * Ey1(mm) 
	- Ceyh1(mm) * (Hz1(mm) - Hz1(mm - 1));

  } else { 

    for (mm = 0; mm < SizeX - 1; mm++)    /*@ \label{updatetezB} @*/
      for (nn = 1; nn < SizeY - 1; nn++)
	Ex(mm, nn) = Cexe(mm, nn) * Ex(mm, nn) +
	  Cexh(mm, nn) * (Hz(mm, nn) - Hz(mm, nn - 1));

    for (mm = 1; mm < SizeX - 1; mm++)
      for (nn = 0; nn < SizeY - 1; nn++)
	Ey(mm, nn) = Ceye(mm, nn) * Ey(mm, nn) -
	  Ceyh(mm, nn) * (Hz(mm, nn) - Hz(mm - 1, nn));
  }

  return;
}
예제 #7
0
void FDTD2D::zeroICs(){
  for(int jj=0; jj<Ny; jj++){
    for(int ii=0; ii<Nx; ii++){
      if(ii<Nx-1){ 
        Ex(ii,jj)  = 0.;
        ExC(ii,jj) = dt / (eps*ds);
      }
      if(jj<Ny-1){
        Ey(ii,jj)  = 0.;
        EyC(ii,jj) = dt / (eps*ds);
      }
      if(ii<Nx-1 && jj<Ny-1){
        Hz(ii,jj)   = 0.;
        HzC(ii,jj)  = dt / (mu*ds);
      }
    }
  }
  return;
}
예제 #8
0
/* function that applies ABC -- called once per time step */
void abc(Grid *g)
{
  int mm, nn, pp;
  
  if (abccoef == 0.0) {
    fprintf(stderr,
	    "abc: abcInit must be called before abc.  Terminating...\n");
    exit(-1);
  }

  /* ABC at "x0" */
  mm = 0;
  for (nn = 0; nn < SizeY - 1; nn++)
    for (pp = 0; pp < SizeZ; pp++) {
      Ey(mm, nn, pp) = Eyx0(nn, pp) +
	abccoef * (Ey(mm + 1, nn, pp) - Ey(mm, nn, pp));
      Eyx0(nn, pp) = Ey(mm + 1, nn, pp);
    }
  for (nn = 0; nn < SizeY; nn++)
    for (pp = 0; pp < SizeZ - 1; pp++) {
      Ez(mm, nn, pp) = Ezx0(nn, pp) +
	abccoef * (Ez(mm + 1, nn, pp) - Ez(mm, nn, pp));
      Ezx0(nn, pp) = Ez(mm + 1, nn, pp);
    }
  
  /* ABC at "x1" */
  mm = SizeX - 1;
  for (nn = 0; nn < SizeY - 1; nn++)
    for (pp = 0; pp < SizeZ; pp++) {
      Ey(mm, nn, pp) = Eyx1(nn, pp) +
	abccoef * (Ey(mm - 1, nn, pp) - Ey(mm, nn, pp));
      Eyx1(nn, pp) = Ey(mm - 1, nn, pp);
    }
  for (nn = 0; nn < SizeY; nn++)
    for (pp = 0; pp < SizeZ - 1; pp++) {
      Ez(mm, nn, pp) = Ezx1(nn, pp) +
	abccoef * (Ez(mm - 1, nn, pp) - Ez(mm, nn, pp));
      Ezx1(nn, pp) = Ez(mm - 1, nn, pp);
    }
  
  /* ABC at "y0" */
  nn = 0;
  for (mm = 0; mm < SizeX - 1; mm++)
    for (pp = 0; pp < SizeZ; pp++) {
      Ex(mm, nn, pp) = Exy0(mm, pp) +
	abccoef * (Ex(mm, nn + 1, pp) - Ex(mm, nn, pp));
      Exy0(mm, pp) = Ex(mm, nn + 1, pp);
    }
  for (mm = 0; mm < SizeX; mm++)
    for (pp = 0; pp < SizeZ - 1; pp++) {
      Ez(mm, nn, pp) = Ezy0(mm, pp) +
	abccoef * (Ez(mm, nn + 1, pp) - Ez(mm, nn, pp));
      Ezy0(mm, pp) = Ez(mm, nn + 1, pp);
    }
  
  /* ABC at "y1" */
  nn = SizeY - 1;
  for (mm = 0; mm < SizeX - 1; mm++)
    for (pp = 0; pp < SizeZ; pp++) {
      Ex(mm, nn, pp) = Exy1(mm, pp) +
	abccoef * (Ex(mm, nn - 1, pp) - Ex(mm, nn, pp));
      Exy1(mm, pp) = Ex(mm, nn - 1, pp);
    }
  for (mm = 0; mm < SizeX; mm++)
    for (pp = 0; pp < SizeZ - 1; pp++) {
      Ez(mm, nn, pp) = Ezy1(mm, pp) +
	abccoef * (Ez(mm, nn - 1, pp) - Ez(mm, nn, pp));
      Ezy1(mm, pp) = Ez(mm, nn - 1, pp);
    }
  
  /* ABC at "z0" (bottom) */
  pp = 0;
  for (mm = 0; mm < SizeX - 1; mm++)
    for (nn = 0; nn < SizeY; nn++) {
      Ex(mm, nn, pp) = Exz0(mm, nn) +
	abccoef * (Ex(mm, nn, pp + 1) - Ex(mm, nn, pp));
      Exz0(mm, nn) = Ex(mm, nn, pp + 1);
    }
  for (mm = 0; mm < SizeX; mm++)
    for (nn = 0; nn < SizeY - 1; nn++) {
      Ey(mm, nn, pp) = Eyz0(mm, nn) +
	abccoef * (Ey(mm, nn, pp + 1) - Ey(mm, nn, pp));
      Eyz0(mm, nn) = Ey(mm, nn, pp + 1);
    }
  
  /* ABC at "z1" (top) */
  pp = SizeZ - 1;
  for (mm = 0; mm < SizeX - 1; mm++)
    for (nn = 0; nn < SizeY; nn++) {
      Ex(mm, nn, pp) = Exz1(mm, nn) +
	abccoef * (Ex(mm, nn, pp - 1) - Ex(mm, nn, pp));
      Exz1(mm, nn) = Ex(mm, nn, pp - 1);
    }
  for (mm = 0; mm < SizeX; mm++)
    for (nn = 0; nn < SizeY - 1; nn++) {
      Ey(mm, nn, pp) = Eyz1(mm, nn) +
	abccoef * (Ey(mm, nn, pp - 1) - Ey(mm, nn, pp));
      Eyz1(mm, nn) = Ey(mm, nn, pp - 1);
    }
  
  return;
}  /* end abc() */
예제 #9
0
파일: Main.cpp 프로젝트: sappel/patric_mti
main(int argc, char* argv[]){
  time_t time1 = time(0), time2;

  //-------MPI initialzation-------------

  int numprocs, myid, namelen;
  char processor_name[MPI_MAX_PROCESSOR_NAME];

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);

  MPI_Get_processor_name(processor_name, &namelen);
  fprintf(stderr, "Process %d running on %s\n", myid, processor_name);

  string numbers = "0123456789";  // !!!!! np <= 10
  string myid_str(numbers, myid, 1);

  MPI_Status status;

  // define a new MPI data type for particles
  MPI_Datatype particletype;
  MPI_Type_contiguous(18, MPI_DOUBLE, &particletype);  // !!! 14->18 changed
  MPI_Type_commit(&particletype);

  //-------- end MPI init----------------

  // wait for gdb
  waitforgdb(myid);

  // read input file (e.g. patric.cfg):

  if(argv[1] == 0){
    printf("No input file name !\n");
    MPI_Abort(MPI_COMM_WORLD, 0);
  }
  input_from_file(argv[1], myid);
  double eps_x = rms_emittance_x0;  // handy abbreviation
  double eps_y = rms_emittance_y0;  // same

  // Synchronous particle:

  SynParticle SP;
  SP.Z = Z;
  SP.A = A;
  SP.gamma0 = 1.0 + (e_kin*1e6*qe)/(mp*clight*clight) ;
  SP.beta0 = sqrt((SP.gamma0*SP.gamma0-1.0)/(SP.gamma0*SP.gamma0)) ;
  SP.eta0 = 1.0/pow(gamma_t, 2)-1.0/pow(SP.gamma0, 2);

  //-------Init Lattice-------

  BeamLine lattice;
  double tunex, tuney; 
  SectorMap CF(CF_advance_h/NCF, CF_advance_v/NCF, CF_R, CF_length/NCF, SP.gamma0);
  BeamLine CF_cell;
  if(madx_input_file == 1){
    // read madx sectormap and twiss files 
	cout << "madx sectormap" << endl;
    string data_dir_in = input;
    lattice.init(data_dir_in+"/mad/", circum, tunex, tuney); 
  }
  else{
    // init constant focusing (CF) sectormap and cell:
	cout << "constsnt focusing" << endl;
    for(int j=0; j<NCF; j++)
      CF_cell.add_map(CF);
    lattice.init(CF_cell);
  }

  // Other variables:
  double dx = 2.0*piperadius/(NX-1.0);  // needed for Poisson solver and grids
  double dy = 2.0*piperadius/(NY-1.0);  // needed for Poisson solver and grids
  double dz = circum/NZ;
  double ds = 0.4;  // value needed here only for setting dxs, dys.
  double dxs = 4.0*(dx/ds)/(NX-1.0);  // only for plotting xs, not for tracking
  double dys = 4.0*(dx/ds)/(NX-1.0);  // only for plotting ys, not for tracking
  double charge = current*circum/(NPIC*SP.beta0*clight*qe);  // macro-particle charge Q/e
  double zm = 0.5*circum*bunchfactor;  // (initial) bunch length
  if(init_pic_z == 1 || init_pic_z == 3 || init_pic_z == 4 || init_pic_z == 6)
    zm = 1.5*0.5*circum*bunchfactor;  // for parabolic bunch
  double zm1 = -zm*1.0;  // left bunch boundary
  double zm2 = zm*1.0;  // right bunch boundary
  if(init_pic_z==7)
	zm=0.25;
  double rmsToFull;  // ratio of rms to full emittance for Bump; SP

  // open output file patric.dat:

  string data_dir = ausgabe;
  data_dir = data_dir + "/";
  string outfile = data_dir + "patric.dat";
  FILE *out = fopen(outfile.c_str(), "w"); 

  // init random number generator:
  long d = -11*(myid+1);  // was -1021  transverse distribution: each slice needs a different initialization !
  long dl = -103;  // was -103   longitudinal plane: same random set needed
  long dran = -101;  // for BTF noise excitation: same random sets needed


  // set some global lattice parameters

  double cell_length = lattice.get_L();
  int Nelements = lattice.get_size();
  if(myid == 0){
    cout << "Nelements:" << Nelements << endl;
    cout << "Cell length:" << cell_length << endl;
  }

  // define pointers to first/last element in beam line:

  const list<SectorMap>::iterator first_elem = lattice.get_first_element();
  const list<SectorMap>::iterator last_elem = --lattice.get_end_element();

  TwissP twiss0, twiss_TK;
  lattice.first_element();
  twiss0 = last_elem->get_twiss();
  twiss_TK = first_elem->get_twiss();
  double Ds0 = 0.0;  // Dispersion derivative

  if(madx_input_file == 0){
    // machine tunes from lattice
    lattice.phase_advance(tunex, tuney);
    tunex = circum/cell_length*tunex/(2.0*PI);
    tuney = circum/cell_length*tuney/(2.0*PI);
	bumpI=0;
    if(myid == 0){
      cout << "advancex: " << tunex*180.0/PI << endl;
      cout << "tunex0: " << tunex << endl;
      cout << "tuney0: " << tuney << endl;
    }
  }

  // Chromatic correction kick:
  Chrom Chrom0;


  // Octupole:
  Octupole Oct0(koct);

  // Amplitude detuning; works only for constant focusing; SA
  //if(madx_input_file == 0)
    //AmplitudeDetuning Amp0(tunex, tuney, dqx_detune/(1.0e-6*eps_x), dqy_detune/(1.0e-6*eps_y), circum/(2.0*PI), CF);

  //--------end lattice----------

  // set matched RF voltage:

  int linrf = 0;
  if (cavity == 3) linrf = 1;
  double Ym = circum/(2.0*PI)*(1.0-cos(2.0*PI*zm/circum));
  if (linrf == 1) Ym = circum/(2.0*PI)*0.5*pow(2.0*PI*zm/circum, 2);
  double velm = abs(SP.eta0)*SP.beta0*clight*sqrt(5.0)*momentum_spread*2.0*PI/(circum);
  double fsyn = 1.0/(2.0*PI)*velm*sqrt(circum/(2.0*PI))/sqrt(2.0*Ym);
  double V0rf = pow(2.0*PI*fsyn, 2)*pow(circum, 2)/(2.0*PI)*mp*SP.A*SP.gamma0/(qe*SP.Z*abs(SP.eta0));

  // Init particle distribution:

  Pic Pics(&SP, charge, NPIC/numprocs, data_dir + "pics_" + myid_str + ".dat");
  Pics.z1 = zm1+myid*(zm2-zm1)/numprocs;  // left boundary in z for this slice
  Pics.z2 = Pics.z1+(zm2-zm1)/numprocs;  // right boundary
  double slice_length = Pics.z2-Pics.z1;  // slice length

  Pic NewPics(&SP, charge, NPIC/numprocs);
  NewPics.z1 = Pics.z1;
  NewPics.z2 = Pics.z2;

  // Init 1D longitudinal grids

  Grid1D rho_z_tmp(NZ, dz, -0.5*circum);
  Grid1D rho_z(NZ, dz, -0.5*circum, data_dir + "rho_z.dat");
  Grid1D dipole_current_x_tmp(NZ, dz, -0.5*circum);
  Grid1D dipole_current_x(NZ, dz, -0.5*circum, data_dir + "dipole_x.dat");
  Grid1D dipole_current_xs_tmp(NZ, dz, -0.5*circum);
  Grid1D dipole_current_xs(NZ, dz, -0.5*circum);
  Grid1D dipole_kick_x(NZ, dz, -0.5*circum, data_dir + "dipole_kick_x.dat");
  Grid1D dipole_current_y_tmp(NZ, dz, -0.5*circum);
  Grid1D dipole_current_y(NZ, dz, -0.5*circum, data_dir + "dipole_y.dat");

  // Init 2D transverse grids:

  Grid2D rho_xy(NX, NY, dx, dy, data_dir + "rho_xy.dat");
  Grid2D rho_xy_tmp(NX, NY, dx, dy);
  Grid2D xxs(NX, NX, dx, dxs, data_dir + "xxs.dat");
  Grid2D xxs_tmp(NX, NX, dx, dxs);
  Grid2D yys(NY, NY, dy, dys, data_dir + "yys.dat");
  Grid2D yys_tmp(NY, NY, dy, dys);
  Grid2D xsys(NX, NY, dxs, dys, data_dir + "xsys.dat");
  Grid2D xsys_tmp(NX, NY, dxs, dys);
  Grid2D zx(NZ, NX, dz, dx, data_dir + "zx.dat");
  Grid2D zx_tmp(NZ, NX, dz, dx);

  Grid2D Ex(NX, NY, dx, dy, data_dir + "Ex.dat");
  Grid2D Ey(NX, NY, dx, dy, data_dir + "Ey.dat");

  // Init 3D sliced grids (for 3D space charge calculation)

  if( fmod((float)NZ_bunch, (float)numprocs) != 0.0 ){
    cout << "NZ_bunch kein Vielfaches von numprocs" << endl;
    MPI_Abort(MPI_COMM_WORLD, 0);
  }
  Grid3D rho_xyz(NZ_bunch/numprocs, Pics.z1, Pics.z2, rho_xy);
  Grid3D Ey3(NZ_bunch/numprocs, Pics.z1, Pics.z2, rho_xy);
  Grid3D Ex3(NZ_bunch/numprocs, Pics.z1, Pics.z2, rho_xy);

  // Init 2D Greens function for poisson solver

  Greenfb gf1(rho_xy, image_x, image_y);  // open boundary condition

  // for the beam radius cacluation;  factor for rms equivalent 
  switch(init_pic_xy){
  case 0:  // Waterbag
	rmsToFull = 6;
    break;
  case 1:  // KV
	rmsToFull = 4;
    break;
  case 2:  // Semi-Gauss
    rmsToFull = 4;  // approximate
    break;
  case 3:  // Gauss
  	rmsToFull = 4;  // approximate
    break;
  default:
    printf("Invalid option for transverse particle distribution. Aborting.\n");
    MPI_Abort(MPI_COMM_WORLD, 0);
  }

  // injection bump initialize 
  Bump lob(tunex);     
  double a; // beam radius horizontal
 
  switch(bumpI){
	case 0:
	  cout << "no mti"  << endl;
	  max_inj = 1;
	  amp0=0;
	  break;
	case 1:
	  // The bump height is defined by user given offcenter parameter. The injection angle is equal to the septum tilt angle (as done in SIS18). 
	  cout << "mti version SP" << endl; 
	  a = sqrt(twiss_TK.betx*eps_x*rmsToFull)*0.001+twiss_TK.Dx*momentum_spread;  // half width of injected beam [m] with WB distribution, change to Main, SA 
	  offcenter_x=x_septum + d_septum + a; 
	  amp0=offcenter_x;
	  amp=amp0;
	  ampp0=inj_angle;
	  delAmp=(amp0-2*a)/double(max_inj);   //0.0041*3;//    
	  lob.BumpSp(&lattice,max_inj, myid, amp0, ampp0, delAmp); // local orbit bump for beam injection; SP
	  break;
	case 2:
	  amp=amp0;
	  cout << "mti flexibility version" << endl; 
	  lob.BumpModi(&lattice,amp);
	  break;
	case 3:
	  amp=amp0;
	  cout << "mti flexibility version exponential decrease" << "tau" << tau << endl; 
	  lob.BumpModi(&lattice,amp);
	  break;
	case 4:
	  amp=amp0;
	  cout << "mti flexibility version sin decrease" << "tau" << tau << endl; 
	  lob.BumpModi(&lattice,amp);
	  break;
	default:
	   printf("Invalid option for bump injection. Aborting.\n");
	   MPI_Abort(MPI_COMM_WORLD, 0);
  }
	 
  //if(myid == 0)
    //cout << "Expected single beamlett tune shifts: dQ_x="
	 //<< rp*SP.Z*current*circum / (rmsToFull*PI*clight*qe*SP.A*pow(SP.beta0*SP.gamma0, 3)*(eps_x+sqrt(eps_x*eps_y*tunex/tuney)))*1e6
	 //<< ", dQ_y="
	 //<< rp*SP.Z*current*circum / (rmsToFull*PI*clight*qe*SP.A*pow(SP.beta0*SP.gamma0, 3)*(eps_y+sqrt(eps_x*eps_y*tuney/tunex)))*1e6
	 //<< endl;            
		

  // print IDL parameter file idl.dat:       
  if(myid == 0){
    //cout << "Vrf [kV]: " << V0rf*1.0e-3 << "  fsyn [kHz]: " << fsyn*1.0e-3 << endl; 
    print_IDL(data_dir, numprocs, cell_length, Nelements, tunex, tuney, lattice, cells, max_inj); 
  }


  //----------------counters and other variables--------------------------

  int Nexchange = 1;  // exchange of particles between slices after every sector map.
  int Nprint = print_cell*Nelements;  // output of particles every cell*print_cell
  //int Nibs = 1;  // correct for IBS every Nibs steps
  double Ntot;  // total number of particles: for screen output
  int counter = 0;  // counts sector maps
  double s = 0.0;  // path length
  double Nslice;  // total number of slices
  double emitx;  // emittance: for screen output
  double dtheta = 0.0;  // btf dipole kick
  double pickup_h, pickup_v;  // horizontal/vertical pickup signals
  double rms_advancex = 0.0, rms_advancey = 0.0;  // rms phase advance: for output
  int inj_counter = 0;  // number of injected beamletts; SP
  long N_inj = 0;  // number of injected particles

  //---------parameters for exchange of particles between slices-------

  int destl;  //!< ID of left neighbour slice (-1: no neighbour).
  int destr;  //!< ID of right neighbour



  //---finite bunch: no exchange between ends---
  if(bc_end == 0){
    if(myid == 0){
      destl =-1;
      destr = myid+1;
    }else
      if(myid == numprocs-1){
	destl = myid-1;
	destr =-1;
      }else{
	destl = myid-1;
	destr = myid+1;
      }
  }
  //---periodic (in z) boundary condition---
  if(bc_end == 1){
    if(myid == 0){
      destl = numprocs-1;
      destr = myid+1;
    }else
      if(myid == numprocs-1){
	destl = myid-1;
	destr = 0;
      }
      else{
	destl = myid-1;
	destr = myid+1;
      }
  }



  //--------------------- end-parameters for particle exchange ---------------

  long *septLoss = new long;
  long *sl_slice = new long;
  double *momenta = new double[19];
  double *momenta_tot = new double[19];       
  double tmp=0;
  long size_old;	
  offcenter_y=0.0;  
  inj_phase_y=0.0e-3;
  
  //--------------------------------------------------------------------------
  //----------------------- start loop (do...while) --------------------------
  //--------------------------------------------------------------------------
   double z0;
   do{  // injection; SP
    if(!(counter%Nelements))
	{  // at beginning each turn...
	  	
	if(inj_counter < max_inj)
	{
 	  size_old=Pics.get_size();
	  // set longitudinal distribution:
	  switch(init_pic_z){
	  case 0:  //  coasting + Elliptic
	    Pics.parabolic_dc(bunchfactor, circum, momentum_spread, NPIC, &dl);
	    break;
	  case 1:  //  bunch + Elliptic  (1.5 correction factor for bunching)
	    Pics.parabolic(zm, 0, momentum_spread, NPIC, &dl);
	    break;
	  case 2:  //  coasting + Gauss
	    Pics.coast_gauss(bunchfactor, circum, momentum_spread, NPIC, &dl); 
	    break;
	  case 3:  //  bunch + Gauss
	    Pics.bunch_gauss(zm, circum, momentum_spread, NPIC, &dl);
	    break;
	  case 4:  //  const. bunch dist.		
	    Pics.bunch_const(zm, circum, momentum_spread, NPIC, &dl,linrf);
	    break;
	  case 5:  //  air bag dist.
	    Pics.barrier_air_bag(zm, momentum_spread, NPIC, &dl);
	    break;
	  case 6:  //  bunch air bag dist.
	    Pics.bunch_air_bag(zm, circum, momentum_spread, NPIC, &dl);
	    break;
	  case 7:  //  168 mirco bunches, injection
		z0=-circum/2.;
		int l;
		for (l=0; l<168; l++){
	    	Pics.parabolic(zm, z0, momentum_spread, NPIC/168, &dl);
			z0+=1.286;
		}
	    break;
	  default:
	    printf("Invalid option for longitudinal particle distribution. Aborting.\n");
	    MPI_Abort(MPI_COMM_WORLD, 0);
	  }
		
	  // set transverse distribution:
	  switch(init_pic_xy){
	  case 0:  // Waterbag
		rmsToFull = 6;
	    Pics.waterbag_xy(1.e-6*eps_x, 1.0e-6*eps_y, twiss_TK.alpx, twiss_TK.alpy, pow(mismatch_x, 2)*twiss_TK.betx, pow(mismatch_y, 2)*twiss_TK.bety, 
				        twiss_TK.Dx, Ds0, offcenter_x, inj_angle, offcenter_y, inj_phase_y, size_old, &d);
	    break;
	  case 1:  // KV
		rmsToFull = 4;
	    Pics.KV_xy(1.e-6*eps_x, 1.0e-6*eps_y, twiss_TK.alpx, twiss_TK.alpy, pow(mismatch_x, 2)*twiss_TK.betx, pow(mismatch_y, 2)*twiss_TK.bety, 
				   twiss_TK.Dx, Ds0, offcenter_x, inj_angle, offcenter_y, inj_phase_y, size_old, &d);
	    break;
	  case 2:  // Semi-Gauss
	    rmsToFull = 4;  // approximate
		Pics.SG(1.e-6*eps_x, 1.0e-6*eps_y, twiss_TK.alpx, twiss_TK.alpy, pow(mismatch_x, 2)*twiss_TK.betx, pow(mismatch_y, 2)*twiss_TK.bety, 
				twiss_TK.Dx, Ds0, offcenter_x, inj_angle, offcenter_y, inj_phase_y, size_old, &d);
	    break;
	  case 3:  // Gauss
	  	rmsToFull = 4;  // approximate
	    Pics.Gauss_xy(1.e-6*eps_x, 1.0e-6*eps_y, twiss_TK.alpx, twiss_TK.alpy, pow(mismatch_x, 2)*twiss_TK.betx, pow(mismatch_y, 2)*twiss_TK.bety, 
					  twiss_TK.Dx, Ds0, offcenter_x, inj_angle, offcenter_y, inj_phase_y, size_old, &d);
	    break;
	  default:
	    printf("Invalid option for transverse particle distribution. Aborting.\n");
	    MPI_Abort(MPI_COMM_WORLD, 0);
	  }
	  
	  if (bumpI!=0)
	  {
	  	*sl_slice = NewPics.localLoss_x(x_septum, 100.);  // loss on septum  
      	loss+=*sl_slice; 
      	MPI_Reduce(sl_slice, septLoss, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
	  	if(myid == 0)
     		cout<<"The incoming beamlett number "<<inj_counter+1<< " lost "<<loss<< " macro particles on the septum.\n";
      }
	  N_inj += NPIC; 
	  inj_counter +=1;
	}
	

	// bump reduction
    if (amp > 0.001 )
	{    
	   if(bumpI==1)
	   {   
		amp-=delAmp;                                 
	   	ampp0-=delAmp*ampp0/amp0;     
	   	lob.decrement();     
	   }
	   if (bumpI==2)
		{
		 amp-=delAmp;                                 
		 lob.decrementModi(amp);
		}
	   if (bumpI==3)
	    {
		 amp=amp0*exp(-tau*counter/Nelements);
		 lob.decrementModi(amp);
		}
	   if (bumpI==4)
	    {
		 amp=amp0*(1+sin(-tau*counter/Nelements));
		 lob.decrementModi(amp);
		}
	}	
   }
	
	
    //------------ Start Output----------------------------------------
    // store rms momenta every time step in patric.dat:
    
    if(counter%1 == 0){
      Nslice = Pics.get_size();  // number of particles in this slice
      momenta[0] = Nslice*Pics.rms_emittance_x();
      momenta[1] = Nslice*Pics.rms_emittance_y();
      momenta[2] = Nslice*Pics.x_max();
      momenta[3] = Nslice*Pics.y_max();
      momenta[4] = Nslice*Pics.x_rms();
      momenta[5] = Nslice*Pics.y_rms();
      momenta[6] = Nslice*Pics.rms_momentum_spread();
      momenta[7] = Nslice*Pics.xzn(2.0, zm);
      momenta[8] = Nslice*Pics.xzn(1.0, zm);
      momenta[9] = Nslice;
      momenta[10] = Nslice*rms_advancex;  // rms phase advance in x
      momenta[11] = Nslice*rms_advancey;
      momenta[12] = Nslice*Pics.offset_x();
      momenta[13] = Nslice*Pics.offset_y();
      momenta[14] = Nslice*dtheta;  // btf noise signal
      momenta[15] = Nslice*pickup_h;
      momenta[16] = Nslice*pickup_v; 
	  momenta[17] = Nslice*loss;   
	  momenta[18] = Nslice*N_inj;  
      // mpi_reduce for summation of all 17 moments over all slices
      MPI_Reduce(momenta, momenta_tot, 19, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
	 		
      Ntot = momenta_tot[9];  // total number of particles over all slices
      emitx = momenta_tot[0]/Ntot;  // total rms emittance    

 
      // stop when loss tolerance level is exceeded                            (1-Ntot/(max_inj*NPIC))*100.
	  
      if(myid == 0 && Ntot/N_inj <= lossTol){  // test on numer of injected particles; SP
		cout<<"Loss tolerance exceeded within "<<counter/Nelements+1<<" turns ("<<
	    Ntot<<" of "<<N_inj<<" macro particles left). Exiting.\n";
	    cout.flush();
	MPI_Abort(MPI_COMM_WORLD, 0);
      }  
      //      cout<<counter<<' '<<lattice.get_element()->get_name()<<' '<<lattice.get_element()->get_K(1)<<endl;  //tmp
      // write momenta
      if(myid == 0){
	fprintf(out, "%g", s);
	for(int i=0; i<19; i++)
	  if(i != 9){
	    fprintf(out, "%15g", momenta_tot[i]/Ntot);}
	  else{
	    fprintf(out, "%15g", momenta_tot[i]);}
	fprintf(out, "\n");
	fflush(out);
      }
}


    //------output every Nprint*sectormap---------

    if(counter%Nprint == 0){
      if(myid == 0){
	// to screen
	//printf("saving at s=%g (m) eps_t=%g dp/p=%g zm2=%g Ntotal=%g\n", s, 1.0e6*emitx, Pics.rms_momentum_spread(), zm2, Ntot);
	cout.flush();
	
	// electric fields
	Ex.print();
	Ey.print();
      }
	
      // paricle coordinates to pic.dat:
      Pics.print(pic_subset);
   	
      // collect densities for output only:

      Pics.gatherZ(charge*qe/dz, rho_z_tmp);
      Pics.gatherX(SP.beta0*clight*charge*qe/dz, dipole_current_x_tmp);
      Pics.gatherY(SP.beta0*clight*charge*qe/dz, dipole_current_y_tmp);
      Pics.gatherXY(charge*qe/circum, rho_xy_tmp);
      Pics.gatherXXs(charge*qe/circum, xxs_tmp);
      Pics.gatherYYs(charge*qe/circum, yys_tmp);
      Pics.gatherXsYs(charge*qe/circum, xsys_tmp);
      Pics.gatherZX(charge*qe/circum, zx_tmp);

      // summation over all slices:

      MPI_Allreduce(rho_z_tmp.get_grid(), rho_z.get_grid(),
		    NZ, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(dipole_current_x_tmp.get_grid(), dipole_current_x.get_grid(),
		    NZ, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(dipole_current_y_tmp.get_grid(), dipole_current_y.get_grid(),
		    NZ, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(rho_xy_tmp.get_grid(), rho_xy.get_grid(),
		    NX*NY, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(xxs_tmp.get_grid(), xxs.get_grid(),
		    NX*NX, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(yys_tmp.get_grid(), yys.get_grid(),
		    NY*NY, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(xsys_tmp.get_grid(), xsys.get_grid(),
		    NX*NY, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
      MPI_Allreduce(zx_tmp.get_grid(), zx.get_grid(),
		    NZ*NX, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
		  
		
      // output to density files:

      if(myid == 0){
	dipole_current_x.print();
	dipole_kick_x.print();
	dipole_current_y.print();
	rho_z.print();
	rho_xy.print();
	xxs.print();
	yys.print();
	xsys.print();
	zx.print();
      }
    } 
    //-----------------end output--------------------------------------------		
	
    // at beginning of a cell: calculate advance per (last) cell,
    // store old coordinates 
    if(lattice.get_element() == first_elem){
      rms_advancex = Pics.rms_phaseadvance_h();  // Pics.rms_wavelength_h();
      rms_advancey = Pics.rms_phaseadvance_v();  // Pics.rms_wavelength_v();
      if(footprint == 0)
	Pics.store_old_coordinates();
    }

	
    if(lattice.get_element()->get_name() == "\"SEPTUM\""){  // losses at septum; SP
      loss += Pics.localLoss_x(-piperadius, coll_halfgap);	  
	}  
  

   if(lattice.get_element()->get_name() == "\"ACCEPTANCE\""){  // losses at limiting acceptance; SA
	  double tmp = lattice.get_element()->get_betx();
      Pics.localLoss_x(-sqrt(180e-6*tmp), sqrt(180e-6*tmp));      
	}

	// Transport particles through sectormap, update slice position s: 
    ds = lattice.get_element()->get_L();

    s += ds;
    Pics.transport(lattice.get_element()->get_map(), piperadius);



    //-----exchange particles between slices------------------------

    if(counter != 0 && counter%Nexchange == 0 && numprocs > 1){
      int Npl;  //!< Number of particles to be exchanged with left neighbour
      int Npr;  //!< particles exchanged with right neighbour

      //! vector of particles to be exchanged
      vector<Particle> pl, pr;

      // send particle to neighbor slices:
	
      if(destl >= 0){
	pl = Pics.get_particles_left(circum);
	Npl = pl.size();
	MPI_Send(&Npl, 1, MPI_INT, destl, 1, MPI_COMM_WORLD);
	MPI_Send(&pl[0], Npl, particletype, destl, 1, MPI_COMM_WORLD);
      }
      if(destr >= 0){
	pr = Pics.get_particles_right(circum);
	Npr = pr.size();
	MPI_Send(&Npr, 1, MPI_INT, destr, 0, MPI_COMM_WORLD);
	MPI_Send(&pr[0], Npr, particletype, destr, 0, MPI_COMM_WORLD);
      }

      // receive from neighbour slices:
	
      Npl = 0; Npr = 0;
      vector<Particle> pl_in, pr_in;
      if( destl >= 0 ){
	MPI_Recv(&Npl, 1, MPI_INT, destl, 0, MPI_COMM_WORLD, &status);
	pl_in = vector<Particle>(Npl);
	MPI_Recv(&pl_in[0], Npl, particletype, destl, 0, MPI_COMM_WORLD, &status);
      }
      if(destr >= 0){
	MPI_Recv(&Npr, 1, MPI_INT, destr, 1, MPI_COMM_WORLD, &status);
	pr_in = vector<Particle>(Npr);
	MPI_Recv(&pr_in[0], Npr, particletype, destr, 1, MPI_COMM_WORLD, &status);
      }
      Pics.add_particles(pl_in);
      Pics.add_particles(pr_in);
    }

    //-----end exchange of particles-------------



    // periodic bc without exchange
    if(numprocs == 1)
      Pics.periodic_bc(circum);	

    // update wave lengths

    //if( footprint == 1){
    //Pics.update_wavelength_h(ds, 0.0);
    //Pics.update_wavelength_v(ds);}

    // nonlinear thin lens kick:
    if(octupole_kick == 1)
      Pics.kick(Oct0, lattice.get_element()->get_twiss(), ds);

    //if(ampdetun_kick == 1)  // works only for constant focusing
    //Pics.kick(Amp0, lattice.get_element()->get_twiss()ds);

    // correct for chromaticity
     if(chroma == 1)  
		Pics.kick(Chrom0,lattice.get_element()->get_twiss(), ds);
			
    // cavity kick every cell:

    if(cavity == 1 && counter%Nelements == 0.0)
      Pics.cavity_kick(V0rf*cell_length/circum, 1, circum/(2.0*PI));
    if(cavity == 2 && counter%Nelements == 0.0)
      Pics.barrier_kick(zm1, zm2);
    if(cavity == 3 && counter%Nelements == 0.0)
      Pics.cavity_kick_linear(V0rf*cell_length/circum, 1, circum/(2.0*PI));

    // Pickup signals

    Pics.gatherX(SP.beta0*clight*charge*qe/dz, dipole_current_x_tmp);
    Pics.gatherY(SP.beta0*clight*charge*qe/dz, dipole_current_y_tmp);
    MPI_Allreduce(dipole_current_x_tmp.get_grid(), dipole_current_x.get_grid(), NZ,
		  MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);	
    MPI_Allreduce(dipole_current_y_tmp.get_grid(), dipole_current_y.get_grid(), NZ,
		  MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);

    pickup_h = Pics.pickup_signal(dipole_current_x, circum,
				  s/(SP.beta0*clight))/current;
    pickup_v = Pics.pickup_signal(dipole_current_y, circum,
				  s/(SP.beta0*clight))/current;


    //---------------impedance kicks-----------------------

    komplex dqc_t(dqcr, dqci);  // for sliced == 0

    if(imp_kick == 1){
      if(sliced == 0)
	Pics.kick(ds/circum*InducedKick(Pics.offset_x(), ds, dqc_t, SP.beta0,
					tunex, circum), 0.0);
      else{
	dipole_kick_x.reset(); 	
	if(Rs > 0.0 || leit > 0.0){
	  Pics.gatherXs(SP.beta0*clight*charge*qe/dz, dipole_current_xs_tmp);
	  MPI_Allreduce(dipole_current_xs_tmp.get_grid(), dipole_current_xs.get_grid(),
			NZ, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);	
	  InducedWakeKick(dipole_kick_x, dipole_current_x, dipole_current_xs, tunex,
			  2.0*PI*SP.beta0*clight/circum, nres, Rs, Qs, piperadius,
			  leit, SP.beta0, SP.gamma0*mp*SP.A*pow(clight, 2), SP.Z*qe);
	}
	if(Zimage != 0.0)
	  InducedKick(dipole_kick_x, dipole_current_x, Zimage, SP.beta0,
		      SP.gamma0*mp*SP.A*pow(clight, 2), SP.Z*qe);
	Pics.impedance_kick(dipole_kick_x, circum, ds);
      }
    }


    //---------------end impedance kicks-----------------------

    //------------self-consistent space charge kicks after every sectormap----
    if(space_charge == 1){    
      // PIC -> charge density for Poisson solver:
      if (sliced == 0){
	Pics.gatherXY(charge*qe/circum, rho_xy_tmp);		
	MPI_Allreduce(rho_xy_tmp.get_grid(), rho_xy.get_grid(), NX*NY, MPI_DOUBLE,
		      MPI_SUM, MPI_COMM_WORLD);	
      }else{	
	Pics.gatherXYZ(charge*qe/rho_xyz.get_dz(), rho_xyz);

	// send and receive density ghost grids to neighbor slices:
	// what is exchanged here ???
	if(destl >= 0)
	  MPI_Send(rho_xyz.get_ghostl(), NX*NY, MPI_DOUBLE, destl, 2, MPI_COMM_WORLD);
	if(destr >= 0){
	  MPI_Recv(rho_xy_tmp.get_grid(), NX*NY, MPI_DOUBLE, destr, 2, MPI_COMM_WORLD,
		   &status);
	  rho_xyz[NZ_bunch/numprocs-1] += rho_xy_tmp;
	}
	if(destr >= 0)
	  MPI_Send(rho_xyz.get_ghostr(), NX*NY, MPI_DOUBLE, destr, 3, MPI_COMM_WORLD);
	if(destl >= 0){
	  MPI_Recv(rho_xy_tmp.get_grid(), NX*NY, MPI_DOUBLE, destl, 3, MPI_COMM_WORLD,
		   &status);
	  rho_xyz[0]+= rho_xy_tmp;
	}
      }
       // Poisson solver
      if(sliced == 0)
	poisson_xy(Ex, Ey, rho_xy, gf1);
      else{
	poisson_xyz(Ex3, Ey3, rho_xyz, gf1);
	
	// send and receive efield ghost grids to neighbor slices:
	if(destl >= 0){
	  MPI_Send(Ex3.get_ghostl(), NX*NY, MPI_DOUBLE, destl, 2,
		   MPI_COMM_WORLD);
	  MPI_Send(Ey3.get_ghostl(), NX*NY, MPI_DOUBLE, destl, 4,
		   MPI_COMM_WORLD);
	}
	if(destr >= 0){
	  MPI_Recv(Ex3[NZ_bunch/numprocs-1].get_grid(), NX*NY, MPI_DOUBLE,
		   destr, 2, MPI_COMM_WORLD, &status);
	  MPI_Recv(Ey3[NZ_bunch/numprocs-1].get_grid(), NX*NY, MPI_DOUBLE,
		   destr, 4, MPI_COMM_WORLD, &status);
	}
	if(destr >= 0){
	  MPI_Send(Ex3.get_ghostr(), NX*NY, MPI_DOUBLE, destr, 3, MPI_COMM_WORLD);
	  MPI_Send(Ey3.get_ghostr(), NX*NY, MPI_DOUBLE, destr, 5, MPI_COMM_WORLD);
	}
	if(destl >= 0){
	  MPI_Recv(Ex3[0].get_grid(), NX*NY, MPI_DOUBLE, destl, 3, MPI_COMM_WORLD, &status);
	  MPI_Recv(Ey3[0].get_grid(), NX*NY, MPI_DOUBLE, destl, 5, MPI_COMM_WORLD, &status);
	}
      }
    }
    
    // Shift xs and ys:
    
    if(space_charge == 1 && ds > 0.0){
      if(sliced == 0)
	Pics.kick(Ex, Ey, ds);
      else
	Pics.kick(Ex3, Ey3, ds);
    }
    
    //---------------end self-consistent space charge kicks---------------

    // linear sc kicks:
    
    if(space_charge == 2 && ds > 0.0)
      Pics.linear_SC_kick(dQxm, dQym, tunex, tuney, rho_z, current/(SP.beta0*clight),
			  dipole_current_x, dipole_current_y, circum, ds);
	
    // nonlinear sc kicks:

    if(space_charge == 3 && ds > 0.0)
      Pics.nonlinear_SC_kick(sqrt(1.0e-6*twiss0.betx*eps_x), sqrt(1.0e-6*twiss0.bety*eps_y),
			     dQxm, dQym, tunex, tuney, rho_z, current/(SP.beta0*clight),
			     circum, ds);

    // dipole noise modulation kick:
    double dnoiseamp = 1.0e-6;
    double nus = fsyn/(SP.beta0*clight/circum);
    if(btf == 1)
      dtheta = Pics.dipole_mod_kick(s/(SP.beta0*clight), ds, circum, dnoiseamp,
				    (tunex+nus)*SP.beta0*clight/circum, btf_harmonic);	
						
    // correct for ibs:

    /*if(counter != 0 && counter%Nibs == 0){
      double rate_ibs = 1.0e4;
      double Dz = rate_ibs*pow(Pics.rms_momentum_spread(), 2);
      double Dxy = rate_ibs*0.5*(Pics.rms_emittance_x()+Pics.rms_emittance_y());
      double betx = lattice.get_element()->get_betx();
      double bety = lattice.get_element()->get_bety();
      Pics.langevin(rate_ibs, rate_ibs*0.0, Dxy, Dz*0.0, Nibs*ds, betx, bety,
        &d);
      }*/

    // For bunch compression: Update slice boundaries z1 and z2 from
    // new bunch boundaries zm1, zm2:

    /*if(counter != 0 && counter%Nexchange == 0){
      if(myid == 0)
      zm1 = Pics.z_min();
      MPI_Bcast(&zm1, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      if(myid == numprocs-1)
      zm2 = Pics.z_max();
      MPI_Bcast(&zm2, 1, MPI_DOUBLE, numprocs-1, MPI_COMM_WORLD);

      Pics.z1 = zm1+myid*(zm2-zm1)/numprocs;
      Pics.z2 = Pics.z1+(zm2-zm1)/numprocs;
      slice_length = Pics.z2-Pics.z1;

      rho_xyz.get_zleft() = zm1;
      rho_xyz.get_zright() = zm2;
      Ex3.get_zleft() = zm1;
      Ex3.get_zright() = zm2;
      Ey3.get_zleft() = zm1;
      Ey3.get_zright() = zm2;
      }*/


    // advance in beam line, go to next element:

    lattice.next_element();
    ++counter;

  }while(counter != cells*Nelements);          //loop check, cells (turns) given by user  SA

  //------------------end of loop-------------------------------

  // close files, free heap:

  delete septLoss, sl_slice;
  delete[] momenta, momenta_tot;  // [] needed here!; SP
  fclose(out);

  // MPI end:

  MPI_Finalize();

  time2 = time(0);
  double sec = difftime(time2, time1);
  double h = floor(sec/3600);
  double min = floor(sec/60-60.*h);
  sec -= 3600.*h+60.*min;
    
  if(myid == 0)  
    {cout << "Total losses: " << (1-Ntot/(max_inj*NPIC))*100. << " \%\n" <<
      "Stored particles: " << current*circum*Ntot/(qe*Z*SP.beta0*clight*NPIC) << endl <<
      "Computation time: " << h << ":" << min << ":" << sec << endl;   
	}
   }
예제 #10
0
파일: abc-3d.c 프로젝트: aitatanit/uFDTD
/* function which applies ABC -- called once per time step */
void abc_3d()
{
  int m, n, p;

  /* ABC at "x0" */
  m=0;
  for (n=0; n<size_y-1; n++)
    for (p=0; p<size_z; p++) {
      Ey(m,n,p) = Eyx0(n,p) + abccoef*(Ey(m+1,n,p)-Ey(m,n,p));
      Eyx0(n,p) = Ey(m+1,n,p);
    }
  for (n=0; n<size_y; n++)
    for (p=0; p<size_z-1; p++) {
      Ez(m,n,p) = Ezx0(n,p) + abccoef*(Ez(m+1,n,p)-Ez(m,n,p));
      Ezx0(n,p) = Ez(m+1,n,p);
    }
  
  /* ABC at "x1" */
  m=size_x-1;
  for (n=0; n<size_y-1; n++)
    for (p=0; p<size_z; p++) {
      Ey(m,n,p) = Eyx1(n,p) + abccoef*(Ey(m-1,n,p)-Ey(m,n,p));
      Eyx1(n,p) = Ey(m-1,n,p);
    }
  for (n=0; n<size_y; n++)
    for (p=0; p<size_z-1; p++) {
      Ez(m,n,p) = Ezx1(n,p) + abccoef*(Ez(m-1,n,p)-Ez(m,n,p));
      Ezx1(n,p) = Ez(m-1,n,p);
    }
  
  /* ABC at "y0" */
  n=0;
  for (m=0; m<size_x-1; m++)
    for (p=0; p<size_z; p++) {
      Ex(m,n,p) = Exy0(m,p) + abccoef*(Ex(m,n+1,p)-Ex(m,n,p));
      Exy0(m,p) = Ex(m,n+1,p);
    }
  for (m=0; m<size_x; m++)
    for (p=0; p<size_z-1; p++) {
      Ez(m,n,p) = Ezy0(m,p) + abccoef*(Ez(m,n+1,p)-Ez(m,n,p));
      Ezy0(m,p) = Ez(m,n+1,p);
    }

  /* ABC at "y1" */
  n=size_y-1;
  for (m=0; m<size_x-1; m++)
    for (p=0; p<size_z; p++) {
      Ex(m,n,p) = Exy1(m,p) + abccoef*(Ex(m,n-1,p)-Ex(m,n,p));
      Exy1(m,p) = Ex(m,n-1,p);
    }
  for (m=0; m<size_x; m++)
    for (p=0; p<size_z-1; p++) {
      Ez(m,n,p) = Ezy1(m,p) + abccoef*(Ez(m,n-1,p)-Ez(m,n,p));
      Ezy1(m,p) = Ez(m,n-1,p);
    }
  
  /* ABC at "z0" (bottom) */
  p=0;
  for (m=0; m<size_x-1; m++)
    for (n=0; n<size_y; n++) {
      Ex(m,n,p) = Exz0(m,n) + abccoef*(Ex(m,n,p+1)-Ex(m,n,p));
      Exz0(m,n) = Ex(m,n,p+1);
    }
  for (m=0; m<size_x; m++)
    for (n=0; n<size_y-1; n++) {
      Ey(m,n,p) = Eyz0(m,n) + abccoef*(Ey(m,n,p+1)-Ey(m,n,p));
      Eyz0(m,n) = Ey(m,n,p+1);
    }
  
  /* ABC at "z1" (top) */
  p=size_z-1;
  for (m=0; m<size_x-1; m++)
    for (n=0; n<size_y; n++) {
      Ex(m,n,p) = Exz1(m,n) + abccoef*(Ex(m,n,p-1)-Ex(m,n,p));
      Exz1(m,n) = Ex(m,n,p-1);
    }
  for (m=0; m<size_x; m++)
    for (n=0; n<size_y-1; n++) {
      Ey(m,n,p) = Eyz1(m,n) + abccoef*(Ey(m,n,p-1)-Ey(m,n,p));
      Eyz1(m,n) = Ey(m,n,p-1);
    }
  
  return;
} /* end abc_3d() */