void problem(Grid *pGrid, Domain *pDomain) { int in,i,j,k; Real x1,x2,x3; long p; Vector parpos, parvel; if (par_geti("grid","Nx2") == 1) { ath_error("[par_epicycle]: par_epicycle must work in 2D or 3D.\n"); } /* Initialize boxsize */ x1min = par_getd("grid","x1min"); x1max = par_getd("grid","x1max"); Lx = x1max - x1min; x2min = par_getd("grid","x2min"); x2max = par_getd("grid","x2max"); Ly = x2max - x2min; /* for 3D problem */ if (par_geti("grid","Nx3") == 1) { Ly = 0.0; } /* Read initial conditions */ Omega_0 = par_getd("problem","omega"); qshear = par_getd_def("problem","qshear",1.5); amp = par_getd("problem","amp"); omg = sqrt(2.0*(2.0-qshear))*Omega_0; /* particle type */ if (par_geti("particle","partypes") != 1) ath_error("[par_epicycle]: This test only allows ONE particle species!\n"); /* particle stopping time */ tstop0[0] = par_getd_def("problem","tstop",1.0e20); /* in code unit */ if (par_geti("particle","tsmode") != 3) ath_error("[par_epicycle]: This test only allows fixed stopping time!\n"); /* particle position */ parpos = ParticlePosition(0.0); parvel = ParticleVelocity(parpos, 0.0); in = ParticleLocator(parpos); pGrid->nparticle = in; pGrid->grproperty[0].num = in; if (pGrid->nparticle+2 > pGrid->arrsize) particle_realloc(pGrid, pGrid->nparticle+2); /* Now set initial conditions for the gas */ for (k=pGrid->ks; k<=pGrid->ke; k++) { for (j=pGrid->js; j<=pGrid->je; j++) { for (i=pGrid->is; i<=pGrid->ie; i++) { cc_pos(pGrid,i,j,k,&x1,&x2,&x3); pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = 0.0; pGrid->U[k][j][i].M3 = 0.0; #ifndef FARGO if (Ly>0.0) /* 3D */ pGrid->U[k][j][i].M2 -= qshear*Omega_0*x1; else /* 2D */ pGrid->U[k][j][i].M3 -= qshear*Omega_0*x1; #endif }}} /* Now set initial conditions for the particles */ for (p=0; p<in; p++) { pGrid->particle[p].property = 0; pGrid->particle[p].x1 = parpos.x1; pGrid->particle[p].x2 = parpos.x2; pGrid->particle[p].x3 = parpos.x3; pGrid->particle[p].v1 = parvel.x1; pGrid->particle[p].v2 = parvel.x2; pGrid->particle[p].v3 = parvel.x3; pGrid->particle[p].pos = 1; /* grid particle */ pGrid->particle[p].my_id = p; #ifdef MPI_PARALLEL pGrid->particle[p].init_id = pGrid->my_id; #endif } /* enroll gravitational potential function, shearing sheet BC functions */ StaticGravPot = ShearingBoxPot; if (pGrid->my_id == 0) { /* flush output file */ sprintf(name, "%s_Traj.dat", pGrid->outfilename); FILE *fid = fopen(name,"w"); fclose(fid); #ifdef MPI_PARALLEL sprintf(name, "../%s_Traj.dat", pGrid->outfilename); #else sprintf(name, "%s_Traj.dat", pGrid->outfilename); #endif } #ifdef MPI_PARALLEL MPI_Bcast(name,50,MPI_CHAR,0,MPI_COMM_WORLD); #endif return; }
void problem(Grid *pGrid, Domain *pDomain) { int i=0,j=0,k=0; int is,ie,js,je,ks,ke,n,wavedir,nwave,samp; Real x1,x2,x3,x1max,x1min,x2max,x2min,amp,vflow,kw; #ifdef PARTICLES long p; int Npar,ip,jp; Real x1p,x2p,x3p,x1l,x1u,x2l,x2u; Real par_amp, factor2; #endif if ((par_geti("grid","Nx2") == 1) || (par_geti("grid","Nx3") > 1)) { ath_error("[par_linearwave1d]: par_linearwave1d must work in 2D grid.\n"); } is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; /* Read initial conditions */ amp = par_getd("problem","amp"); wavedir = par_geti("problem","wavedir"); vflow = par_getd("problem","vflow"); nwave = par_geti("problem","nwave"); samp = par_geti("problem","sample"); x1min = par_getd("grid","x1min"); x1max = par_getd("grid","x1max"); x2min = par_getd("grid","x2min"); x2max = par_getd("grid","x2max"); if (wavedir == 1) kw = 2.0*(PI)*nwave/(x1max-x1min); else if (wavedir == 2) kw = 2.0*(PI)*nwave/(x2max-x2min); /* Now set initial conditions to wave solution */ for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { cc_pos(pGrid,i,j,k,&x1,&x2,&x3); switch(wavedir){ case 1: pGrid->U[k][j][i].d = 1.0+amp*sin(kw*x1); pGrid->U[k][j][i].M1 = pGrid->U[k][j][i].d* (vflow+amp*Iso_csound*sin(kw*x1)); pGrid->U[k][j][i].M2 = 0.0; break; case 2: pGrid->U[k][j][i].d = 1.0+amp*sin(kw*x2); pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = pGrid->U[k][j][i].d* (vflow+amp*Iso_csound*sin(kw*x2)); break; default: ath_error("[par_linearwave1d]: wavedir must be either 1 or 2!\n"); } pGrid->U[k][j][i].M3 = 0.0; #if (NSCALARS > 0) if (samp == 1) for (n=0; n<NSCALARS; n++) pGrid->U[k][j][i].s[n] = pGrid->U[k][j][i].d; else for (n=0; n<NSCALARS; n++) pGrid->U[k][j][i].s[n] = 1.0; #endif }}} /* Read initial conditions for the particles */ #ifdef PARTICLES /* basic parameters */ if (par_geti("particle","partypes") != 1) ath_error("[par_linwave1d]: This test only allows ONE particle species!\n"); Npar = (int)(sqrt(par_geti("particle","parnumcell"))); pGrid->nparticle = Npar*Npar*pGrid->Nx1*pGrid->Nx2; pGrid->grproperty[0].num = pGrid->nparticle; if (pGrid->nparticle+2 > pGrid->arrsize) particle_realloc(pGrid, pGrid->nparticle+2); /* particle stopping time */ tstop0[0] = par_getd_def("problem","tstop",0.0); /* in code unit */ if (par_geti("particle","tsmode") != 3) ath_error("[par_linwave1d]: This test only allows fixed stopping time!\n"); /* particle perturbation amplitude */ switch(wavedir){ case 1: par_amp = amp*kw*pGrid->dx1/sin(kw*pGrid->dx1); factor2 = 0.5*tan(kw*pGrid->dx1)/(kw*pGrid->dx1); break; case 2: par_amp = amp*kw*pGrid->dx2/sin(kw*pGrid->dx2); factor2 = 0.5*tan(kw*pGrid->dx2)/(kw*pGrid->dx2); break; default: ath_error("[par_linearwave1d]: wavedir must be either 1 or 2!\n"); } //par_amp=amp; //factor2 = 0.5; /* Now set initial conditions for the particles */ p = 0; x3p = pGrid->x3_0 + (pGrid->ks+pGrid->kdisp)*pGrid->dx3; for (j=pGrid->js; j<=pGrid->je; j++) { x2l = pGrid->x2_0 + (j+pGrid->jdisp)*pGrid->dx2; x2u = pGrid->x2_0 + ((j+pGrid->jdisp)+1.0)*pGrid->dx2; for (i=pGrid->is; i<=pGrid->ie; i++) { x1l = pGrid->x1_0 + (i + pGrid->idisp)*pGrid->dx1; x1u = pGrid->x1_0 + ((i + pGrid->idisp) + 1.0)*pGrid->dx1; for (ip=0;ip<Npar;ip++) { x1p = x1l+(x1u-x1l)/Npar*(ip+0.5); for (jp=0;jp<Npar;jp++) { x2p = x2l+(x2u-x2l)/Npar*(jp+0.5); pGrid->particle[p].property = 0; switch(wavedir){ case 1: pGrid->particle[p].x1 = x1p; if (samp == 1) { pGrid->particle[p].x1 += par_amp*cos(kw*x1p)/kw - factor2*SQR(par_amp)*sin(2.0*kw*x1p)/kw; } pGrid->particle[p].x2 = x2p; pGrid->particle[p].v1 = vflow+amp*Iso_csound*sin(kw*x1p); pGrid->particle[p].v2 = 0.0; break; case 2: pGrid->particle[p].x1 = x1p; pGrid->particle[p].x2 = x2p; if (samp == 1) { pGrid->particle[p].x2 += par_amp*cos(kw*x2p)/kw - factor2*SQR(par_amp)*sin(2.0*kw*x2p)/kw; } pGrid->particle[p].v1 = 0.0; pGrid->particle[p].v2 = vflow+amp*Iso_csound*sin(kw*x2p); break; default: ath_error("[par_linearwave1d]: wavedir must be either 1 or 2!\n"); } pGrid->particle[p].x3 = x3p; pGrid->particle[p].v3 = 0.0; pGrid->particle[p].pos = GetPosition(&pGrid->particle[p]); pGrid->particle[p].my_id = p; #ifdef MPI_PARALLEL pGrid->particle[p].init_id = pGrid->my_id; #endif p += 1; } } } } #endif /* PARTICLES */ return; }
void problem(Grid *pGrid, Domain *pDomain) { int i,j,k; long p,in; if (par_geti("grid","Nx1") == 1 || par_geti("grid","Nx2") == 1) { ath_error("[par_fric]: this test only works with Nx1 & Nx2 > 1\n"); } /* Initialize boxsize */ x1min = par_getd("grid","x1min"); x1max = par_getd("grid","x1max"); x2min = par_getd("grid","x2min"); x2max = par_getd("grid","x2max"); x3min = par_getd("grid","x3min"); x3max = par_getd("grid","x3max"); x1c = 0.5*(x1min+x1max); x2c = 0.5*(x2min+x2max); x3c = 0.5*(x3min+x3max); /* Read initial conditions for the gas */ v01 = par_getd("problem","v1"); v02 = par_getd("problem","v2"); v03 = par_getd("problem","v3"); /* particle type */ if (par_geti("particle","partypes") != 1) ath_error("[par_fric]: number of particle types must be 1!\n"); /* particle stopping time */ tstop0 = par_getd("problem","tstop"); /* in code unit */ if (par_geti("particle","tsmode") != 3) ath_error("[par_fric]: This test works only for fixed stopping time!\n"); /* initial particle position */ in = ParticleLocator(x1c, x2c, x3c); pGrid->nparticle = in; pGrid->grproperty[0].num = in; if (pGrid->nparticle+2 > pGrid->arrsize) particle_realloc(pGrid, pGrid->nparticle+2); /* Now set initial conditions for the gas */ for (k=pGrid->ks; k<=pGrid->ke; k++) { for (j=pGrid->js; j<=pGrid->je; j++) { for (i=pGrid->is; i<=pGrid->ie; i++) { pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = 0.0; pGrid->U[k][j][i].M3 = 0.0; }}} /* Now set initial conditions for the particles */ for (p=0; p<in; p++) { pGrid->particle[p].property = 0; pGrid->particle[p].x1 = x1c; pGrid->particle[p].x2 = x2c; pGrid->particle[p].x3 = x3c; pGrid->particle[p].v1 = v01; pGrid->particle[p].v2 = v02; pGrid->particle[p].v3 = v03; pGrid->particle[p].pos = 1; /* grid particle */ pGrid->particle[p].my_id = p; #ifdef MPI_PARALLEL pGrid->particle[p].init_id = pGrid->my_id; #endif } if (pGrid->my_id == 0) { /* flush output file */ sprintf(name, "%s_Err.dat", pGrid->outfilename); FILE *fid = fopen(name,"w"); fclose(fid); #ifdef MPI_PARALLEL sprintf(name, "../%s_Err.dat", pGrid->outfilename); #else sprintf(name, "%s_Err.dat", pGrid->outfilename); #endif } #ifdef MPI_PARALLEL MPI_Bcast(name,50,MPI_CHAR,0,MPI_COMM_WORLD); #endif return; }
void problem(DomainS *pDomain) { GridS *pGrid = pDomain->Grid; int i,j,k,ks,pt,tsmode; long p,q; Real ScaleHg,tsmin,tsmax,tscrit,amin,amax,Hparmin,Hparmax; Real *ep,*ScaleHpar,epsum,mratio,pwind,rhoaconv,etavk; Real *epsilon,*uxNSH,*uyNSH,**wxNSH,**wyNSH; Real rhog,h,x1,x2,x3,t,x1p,x2p,x3p,zmin,zmax,dx3_1,b; long int iseed = myID_Comm_world; /* Initialize on the first call to ran2 */ if (pDomain->Nx[2] == 1) { ath_error("[par_strat3d]: par_strat3d only works for 3D problem.\n"); } #ifdef MPI_PARALLEL if (pDomain->NGrid[2] > 2) { ath_error( "[par_strat3d]: The z-domain can not be decomposed into more than 2 grids\n"); } #endif /* Initialize boxsize */ x1min = pGrid->MinX[0]; x1max = pGrid->MaxX[0]; Lx = x1max - x1min; x2min = pGrid->MinX[1]; x2max = pGrid->MaxX[1]; Ly = x2max - x2min; x3min = par_getd("domain1","x3min"); x3max = par_getd("domain1","x3max"); Lz = x3max - x3min; Lg = nghost*pGrid->dx3; /* size of the ghost zone */ ks = pGrid->ks; /* Read initial conditions */ Omega_0 = par_getd("problem","omega"); qshear = par_getd_def("problem","qshear",1.5); ipert = par_geti_def("problem","ipert",1); vsc1 = par_getd_def("problem","vsc1",0.05); /* in unit of iso_sound (N.B.!) */ vsc2 = par_getd_def("problem","vsc2",0.0); vsc1 = vsc1 * Iso_csound; vsc2 = vsc2 * Iso_csound; ScaleHg = Iso_csound/Omega_0; /* particle number */ Npar = (long)(par_geti("particle","parnumgrid")); pGrid->nparticle = Npar*npartypes; for (i=0; i<npartypes; i++) grproperty[i].num = Npar; if (pGrid->nparticle+2 > pGrid->arrsize) particle_realloc(pGrid, pGrid->nparticle+2); ep = (Real*)calloc_1d_array(npartypes, sizeof(Real)); ScaleHpar = (Real*)calloc_1d_array(npartypes, sizeof(Real)); epsilon = (Real*)calloc_1d_array(npartypes, sizeof(Real)); wxNSH = (Real**)calloc_2d_array(pGrid->Nx[2]+1, npartypes,sizeof(Real)); wyNSH = (Real**)calloc_2d_array(pGrid->Nx[2]+1, npartypes,sizeof(Real)); uxNSH = (Real*)calloc_1d_array(pGrid->Nx[2]+1, sizeof(Real)); uyNSH = (Real*)calloc_1d_array(pGrid->Nx[2]+1, sizeof(Real)); /* particle stopping time */ tsmode = par_geti("particle","tsmode"); if (tsmode == 3) {/* fixed stopping time */ tsmin = par_getd("problem","tsmin"); /* in code unit */ tsmax = par_getd("problem","tsmax"); tscrit= par_getd("problem","tscrit"); for (i=0; i<npartypes; i++) { tstop0[i] = tsmin*exp(i*log(tsmax/tsmin)/MAX(npartypes-1,1.0)); grproperty[i].rad = tstop0[i]; /* use fully implicit integrator for well coupled particles */ if (tstop0[i] < tscrit) grproperty[i].integrator = 3; } } else { amin = par_getd("problem","amin"); amax = par_getd("problem","amax"); for (i=0; i<npartypes; i++) grproperty[i].rad = amin*exp(i*log(amax/amin)/MAX(npartypes-1,1.0)); if (tsmode <= 2) {/* Epstein/General regime */ /* conversion factor for rhoa */ rhoaconv = par_getd_def("problem","rhoaconv",1.0); for (i=0; i<npartypes; i++) grrhoa[i]=grproperty[i].rad*rhoaconv; } if (tsmode == 1) /* General drag formula */ alamcoeff = par_getd("problem","alamcoeff"); } /* particle scale height */ Hparmax = par_getd("problem","hparmax"); /* in unit of gas scale height */ Hparmin = par_getd("problem","hparmin"); for (i=0; i<npartypes; i++) ScaleHpar[i] = Hparmax* exp(-i*log(Hparmax/Hparmin)/MAX(npartypes-1,1.0)); #ifdef FEEDBACK mratio = par_getd_def("problem","mratio",0.0); /* total mass fraction */ pwind = par_getd_def("problem","pwind",0.0); /* power law index */ if (mratio < 0.0) ath_error("[par_strat2d]: mratio must be positive!\n"); epsum = 0.0; for (i=0; i<npartypes; i++) { ep[i] = pow(grproperty[i].rad,pwind); epsum += ep[i]; } for (i=0; i<npartypes; i++) { ep[i] = mratio*ep[i]/epsum; grproperty[i].m = sqrt(2.0*PI)*ScaleHg/Lz*ep[i]* pGrid->Nx[0]*pGrid->Nx[1]*pGrid->Nx[2]/Npar; } #else mratio = 0.0; for (i=0; i<npartypes; i++) ep[i] = 0.0; #endif /* NSH equilibrium */ for (k=pGrid->ks; k<=pGrid->ke+1; k++) { h = pGrid->MinX[2] + (k-pGrid->ks)*pGrid->dx3; q = k - ks; etavk = fabs(vsc1+vsc2*SQR(h)); for (i=0; i<npartypes; i++) { epsilon[i] = ep[i]/ScaleHpar[i]*exp(-0.5*SQR(h/ScaleHg) *(SQR(1.0/ScaleHpar[i])-1.0))/erf(Lz/(sqrt(8.0)*ScaleHpar[i]*ScaleHg)); if (tsmode != 3) tstop0[i] = get_ts(pGrid,i,exp(-0.5*SQR(h/ScaleHg)),Iso_csound,etavk); } MultiNSH(npartypes, tstop0, epsilon, etavk, &uxNSH[q], &uyNSH[q], wxNSH[q], wyNSH[q]); } /* Now set initial conditions for the gas */ for (k=pGrid->ks; k<=pGrid->ke; k++) { for (j=pGrid->js; j<=pGrid->je; j++) { for (i=pGrid->is; i<=pGrid->ie; i++) { cc_pos(pGrid,i,j,k,&x1,&x2,&x3); rhog = exp(-0.5*SQR(x3/ScaleHg)); pGrid->U[k][j][i].d = rhog; if (ipert != 1) {/* NSH velocity */ pGrid->U[k][j][i].M1 = 0.5*rhog*(uxNSH[k-ks]+uxNSH[k-ks+1]); pGrid->U[k][j][i].M2 = 0.5*rhog*(uyNSH[k-ks]+uyNSH[k-ks+1]); } else { pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = 0.0; } pGrid->U[k][j][i].M3 = 0.0; #ifndef FARGO pGrid->U[k][j][i].M2 -= qshear*rhog*Omega_0*x1; #endif }}} /* Now set initial conditions for the particles */ p = 0; dx3_1 = 1.0/pGrid->dx3; zmin = pGrid->MinX[2]; zmax = pGrid->MaxX[2]; for (q=0; q<Npar; q++) { for (pt=0; pt<npartypes; pt++) { x1p = x1min + Lx*ran2(&iseed); x2p = x2min + Ly*ran2(&iseed); x3p = ScaleHpar[pt]*ScaleHg*Normal(&iseed); while ((x3p >= zmax) || (x3p < zmin)) x3p = ScaleHpar[pt]*ScaleHg*Normal(&iseed); pGrid->particle[p].property = pt; pGrid->particle[p].x1 = x1p; pGrid->particle[p].x2 = x2p; pGrid->particle[p].x3 = x3p; if (ipert != 1) {/* NSH velocity */ cellk(pGrid, x3p, dx3_1, &k, &b); k = k-pGrid->ks; b = b - pGrid->ks; pGrid->particle[p].v1 = (k+1-b)*wxNSH[k][pt]+(b-k)*wxNSH[k+1][pt]; pGrid->particle[p].v2 = (k+1-b)*wyNSH[k][pt]+(b-k)*wyNSH[k+1][pt]; } else { pGrid->particle[p].v1 = 0.0; pGrid->particle[p].v2 = vsc1+vsc2*SQR(x2p); } pGrid->particle[p].v3 = 0.0; #ifndef FARGO pGrid->particle[p].v2 -= qshear*Omega_0*x1p; #endif pGrid->particle[p].pos = 1; /* grid particle */ pGrid->particle[p].my_id = p; #ifdef MPI_PARALLEL pGrid->particle[p].init_id = myID_Comm_world; #endif p++; }} /* enroll gravitational potential function, shearing sheet BC functions */ ShearingBoxPot = StratifiedDisk; dump_history_enroll(hst_rho_Vx_dVy, "<rho Vx dVy>"); /* set the # of the particles in list output * (by default, output 1 particle per cell) */ nlis = par_geti_def("problem","nlis",pGrid->Nx[0]*pGrid->Nx[1]*pGrid->Nx[2]); /* set the number of particles to keep track of */ ntrack = par_geti_def("problem","ntrack",2000); /* set the threshold particle density */ dpar_thresh = par_geti_def("problem","dpar_thresh",10.0); /* finalize */ free(ep); free(ScaleHpar); free(epsilon); free_2d_array(wxNSH); free_2d_array(wyNSH); free(uxNSH); free(uyNSH); return; }