void Greenfb::add_boundary_potential(Grid2D& rho) { if (a0 > 0.0 && b0 > 0.0) return; int i,j, u=0; int NX=rho.get_NX(); int NY=rho.get_NY(); double dx=rho.get_dx(); double dy=rho.get_dy(); Grid2D rho_tmp(NX,NY,dx,dy); double* rhotg =rho_tmp.grid; double* rhog =rho.grid; for(i=0; i<NX; i++) for(j=0; j<NY; j++) rhotg[j+i*NY]=rhog[j+i*NY]; for(i=1; i<NX; i++) { rhog[NY-1+i*NY]+=eps0*get_potential_b(u,rho_tmp); u=u+1; } for(j=1; j<NY-1; j++) { rhog[(j)+(NX-1)*NY]+=eps0*get_potential_b(u,rho_tmp); u=u+1; } for(i=1; i<NX-1; i++) { rhog[(1)+(i)*NY]+=eps0*get_potential_b(u,rho_tmp); u=u+1; } for(j=2; j<NY-1; j++) { rhog[(j)+(1)*NY]+=eps0*get_potential_b(u,rho_tmp); u=u+1; } }
void PIC::densityXY(Grid2D& target) { long j; target.reset(); for(j=0; j<part.size(); j++) target.Pic2Grid(macroN*charge_p/length,part[j].x,part[j].y); }
void PIC::Boris_uxy(Grid2D& Bx, Grid2D& By, double dt) { long j; double tx, ty, tabs2, Bxj, Byj, Babs, u2, gamma, ux0, uy0, uz0; for(j=0; j<part.size(); j++) { Bxj=Bx.Grid2PIC(part[j].x,part[j].y); Byj=By.Grid2PIC(part[j].x,part[j].y); Babs=sqrt(pow(Bxj,2)+pow(Byj,2)); u2=pow(part[j].uy,2)+pow(part[j].ux,2)+pow(part[j].uz,2); gamma=sqrt(1.0+u2/pow(clight,2)); ux0=part[j].ux;uy0=part[j].uy;uz0=part[j].uz; if (Babs > 0.0) { tx=Bxj/Babs*tan(charge_p*dt*Babs/(2.0*gamma*mass_p)); ty=Byj/Babs*tan(charge_p*dt*Babs/(2.0*gamma*mass_p)); } else {tx=0.0; ty=0.0;} tabs2=pow(tx,2)+pow(ty,2); part[j].ux+=-part[j].uz*ty; part[j].uy+=part[j].uz*tx; part[j].uz+=part[j].ux*ty-part[j].uy*tx; part[j].ux=ux0-part[j].uz*ty*2.0/(1.0+tabs2); part[j].uy=uy0+part[j].uz*tx*2.0/(1.0+tabs2); part[j].uz=uz0+part[j].ux*ty*2.0/(1.0+tabs2)-part[j].uy*tx*2.0/(1.0+tabs2); } }
void poisson_xy(Grid2D& rho, Greenfb& gf) { int j, l,NX=rho.get_NX(),NY=rho.get_NX(); double dx=rho.get_dx(), dy=rho.get_dy(); double *temx, *temy; temx=new double[NX]; temy=new double[NY]; gf.add_boundary_potential(rho); for(j=0; j<NX; j++) { for(l=0;l<NY;l++) temy[l]=rho[l+NY*j]; sinft(temy-1,NY); for(l=0;l<NY;l++) rho[l+NY*j]=temy[l]; } for(l=0; l<NY; l++) { for(j=0;j<NX;j++) temx[j]=rho[l+j*NY]; sinft(temx-1,NX); for(j=0;j<NX;j++) rho[l+NY*j]=temx[j]; } for(j=1;j<NX;j++) for(l=1;l<NY;l++) rho[l+j*NY]*=-1.0/eps0 *0.5*dx*dy/(cos(PI*j/NX)+cos(PI*l/NY)-2.0); for(j=0; j<NX; j++) { for(l=0;l<NY;l++) temy[l]=rho[l+NY*j]; sinft(temy-1,NY); for(l=0;l<NY;l++) rho[l+NY*j]=2.0*temy[l]/NY; } for(l=0; l<NY; l++) { for(j=0;j<NX;j++) temx[j]=rho[l+j*NY]; sinft(temx-1,NX); for(j=0;j<NX;j++) rho[l+NY*j]=2.0*temx[j]/NX; } delete temx; delete temy; }
Greenfb::Greenfb(Grid2D& g, double a, double b) : greenf(2*g.get_NX()+2*g.get_NY()-8) { int i, j, v, u=0; int Nb=greenf.size(); int NX=g.get_NX(); int NY=g.get_NY(); xb=vektor(Nb); yb=vektor(Nb); a0=a; b0=b; for(j=0; j<Nb; j++) { greenf[j]=g; greenf[j].reset(); } for(i=1; i<NX; i++) { xb[u]=g.x[i]; yb[u]=g.y[NY-1]; u=u+1; } for(j=1; j<NY-1; j++) { xb[u]=g.x[NX-1]; yb[u]=g.y[j]; u=u+1; } for(i=1; i<NX-1; i++) { xb[u]=g.x[i]; yb[u]=g.y[1]; u=u+1; } for(j=2; j<NY-1; j++) { xb[u]=g.x[1]; yb[u]=g.y[j]; u=u+1; } for(int j=0; j<Nb; j++) for (u=0; u<NX; u++) for(v=0; v<NY; v++) { if (a0 == 0.0) greenf[j](u,v)=open_2D( g.x[u], xb[j], g.y[v], yb[j]); else if (a0 > 0.0 && b0 == 0.0) greenf[j](u,v)=circle_2D( g.x[u], xb[j], g.y[v], yb[j]); else greenf[j](u,v)=0.0; } }
void PIC::shift_uxy(Grid2D& pot, double dt) { long j; double Ex, Ey; for(j=0; j<part.size(); j++) { Ex=-pot.Grid2dx(part[j].x,part[j].y); Ey=-pot.Grid2dy(part[j].x,part[j].y); part[j].ux+=charge_p*Ex*dt/mass_p; part[j].uy+=charge_p*Ey*dt/mass_p; } }
double Greenfb::get_potential_b(int j, Grid2D& rho) { double tem=0.0; int NX=rho.get_NX(); int NY=rho.get_NY(); int u,v; double* rhog=rho.grid; double* greeng=greenf[j].grid; for (u=0; u<NX; u++) for(v=0; v<NY; v++) tem+=greeng[v+u*NY]*rhog[v+u*NY]; return tem; }
void Pic::kick(Grid2D& Ex, Grid2D& Ey, double ds){ double beta0 = SP->beta0, gamma0 = SP->gamma0, A = SP->A, Z = SP->Z; double temp = qe*Z/(mp*A*pow(gamma0, 3)*pow(beta0*clight, 2))*ds; double ex, ey; for(long j=0; j < pics.size(); ++j){ ex = temp*Ex.Grid2PIC(pics[j].x, pics[j].y); ey = temp*Ey.Grid2PIC(pics[j].x, pics[j].y); //momenta: pics[j].xs += ex; pics[j].ys += ey; } }
double Pic::entropy(Grid2D& target){ double Hfunc = 0.0; int NPIC = get_size(); int Nxs = target.get_NX(); int Nys = target.get_NY(); double dxs = target.get_dx(); double dys = target.get_dy(); gatherXsYs(1.0/(double)NPIC, target); for(int j=0; j<Nxs; ++j) for(int l=0; l<Nys; ++l){ if(target(j, l) > 0.0) Hfunc += target(j, l)*log(target(j, l))*dxs*dys; } return Hfunc; }
void Kriging2D::krigSurface(Grid2D & trend, const KrigingData2D & krigingData, const CovGrid2D & cov, bool getResiduals) { // // This routine by default returns z(x) = m(x) + k(x)K^{-1}(d - m). If only // residuals are wanted a copy of the input trend // int md = krigingData.getNumberOfData(); const std::vector<int> & indexi = krigingData.getIndexI(); const std::vector<int> & indexj = krigingData.getIndexJ(); std::vector<float> data = krigingData.getData(); // Take an editable copy int nx = static_cast<int>(trend.GetNI()); int ny = static_cast<int>(trend.GetNJ()); if (md > 0 && md < nx*ny) { NRLib::SymmetricMatrix K(md); NRLib::Vector residual(md); NRLib::Vector k(md); NRLib::Vector x(md); subtractTrend(residual, data, trend, indexi, indexj); fillKrigingMatrix(K, cov, indexi, indexj); NRLib::CholeskySolve(K, residual, x); for (int i = 0 ; i < nx ; i++) { for (int j = 0 ; j < ny ; j++) { fillKrigingVector(k, cov, indexi, indexj, i, j); if (getResiduals) { // Only get the residuals trend(i,j) = k * x; } else { trend(i,j) += k * x; } } } } }
void poisson_xy(Grid2D& Ex, Grid2D& Ey, Grid2D& rho, Greenfb& gf) { int NX=rho.get_NX(),NY=rho.get_NX(); double dx=rho.get_dx(), dy=rho.get_dy(); //rho.filtering(); poisson_xy(rho,gf); double* rhog=rho.grid; double* Exg=Ex.grid; double* Eyg=Ey.grid; for(int j=3;j<NX-2;j++) for(int l=3;l<NY-2;l++) { /* Ex(j,l)=-(rho(j+1,l,1)-rho(j-1,l,1))/(2.0*dx); Ey(j,l)=-(rho(j,l+1,1)-rho(j,l-1,1))/(2.0*dy);*/ Exg[l+j*NY]=-(rhog[l+(j+1)*NY]-rhog[l+(j-1)*NY])/(2.0*dx); Eyg[l+j*NY]=-(rhog[l+1+j*NY]-rhog[l-1+j*NY])/(2.0*dy); } }
double PIC::total_energy(Grid2D& pot) { long j, n=part.size(); double ekin=total_kinetic_energy(); double epot=0.0; for(j=0; j<n; j++) epot+=macroN*pot.Grid2PIC(part[j].x,part[j].y); return ekin+epot; }
void init_rho(Grid2D& rho, double rho0, double rbeam) { int l,i; int NX=rho.get_NX(), NY=rho.get_NY(); for(l=0; l<NX; l++) for(i=0; i<NY; i++) { if ( sqrt(pow(rho.x[l],2)+pow(rho.y[i],2)) < rbeam ) rho(l,i)=rho0; else rho(l,i)=0.0; } for(l=0; l<NX; l++) for(i=0; i<NY; i++) { if ( sqrt(pow(rho.x[l],2)+pow(rho.y[i],2)) < 0.8*rbeam ) rho(l,i)=0.0; } }
void poisson_xy(Grid2D& Ex, Grid2D& Ey, Grid2D& rho, Greenfb& gf) { // pTimer ffT; int NX=rho.get_NX(),NY=rho.get_NX(); double dx=rho.get_dx(), dy=rho.get_dy(); poisson_xy(rho,gf); double* rhog=rho.grid; double* Exg=Ex.grid; double* Eyg=Ey.grid; //ffT.start(); for(int j=3;j<NX-2;j++) for(int l=3;l<NY-2;l++) { /* Ex(j,l)=-(rho(j+1,l,1)-rho(j-1,l,1))/(2.0*dx); Ey(j,l)=-(rho(j,l+1,1)-rho(j,l-1,1))/(2.0*dy);*/ Exg[l+j*NY]=-(rhog[l+(j+1)*NY]-rhog[l+(j-1)*NY])/(2.0*dx); Eyg[l+j*NY]=-(rhog[l+1+j*NY]-rhog[l-1+j*NY])/(2.0*dy); } //ffT.stop(); // printf("doubleforloop: %f\n",ffT.t/1000); }
void poisson_rz(Grid2D& rho) { int j,m; int NR=rho.get_NX(); int NZ=rho.get_NY(); double dr=rho.get_dx(); double dz=rho.get_dy(); double *q1=new double[NR]; double *q2=new double[NR]; double *tem=new double[NZ]; for(j=0; j<NR; j++) { for(m=0;m<NZ;m++) tem[m]=rho[m+NZ*j]; realft(tem-1,NZ,1); //cosft1(tem-1,NZ); //sinft(tem-1,NZ); for(m=0;m<NZ;m++) rho[m+NZ*j]=tem[m]; } for(m=2;m<NZ;m+=2) { for(j=0;j<NR;j++) { q1[j]=rho[m+NZ*j]; q2[j]=rho[m+1+NZ*j]; } poisson_r(q1,(int)(0.5*m),NR,NZ,dr,dz); poisson_r(q2,(int)(0.5*m),NR,NZ,dr,dz); for(j=0;j<NR;j++) { rho[m+NZ*j]=q1[j]; rho[m+1+NZ*j]=q2[j]; } } for(j=0;j<NR;j++) q1[j]=rho[1+NZ*j]; poisson_r(q1,(int)(0.5*NZ),NR,NZ,dr,dz); for(j=0;j<NR;j++) rho[1+NZ*j]=q1[j]; for(j=0;j<NR;j++) q1[j]=rho[j*NZ]; poisson_r(q1,0,NR,NZ,dr,dz); for(j=0;j<NR;j++) rho[0+NZ*j]=q1[j]; for(j=0; j<NR; j++) { for(m=0;m<NZ;m++) tem[m]=rho[m+NZ*j]; realft(tem-1,NZ,-1); //cosft1(tem-1,NZ); //sinft(tem-1,NZ); for(m=0;m<NZ;m++) rho[m+NZ*j]=2.0*tem[m]/NZ; } delete q1; delete q2; delete tem; }
void Pic::gatherXsYs(double pic_charge, Grid2D& target){ long j; target.reset(); for(j=0; j<pics.size(); ++j) target.Pic2Grid(pic_charge, pics[j].xs, pics[j].ys); }