void problem_read_restart(MeshS *pM, FILE *fp) { #ifdef RESISTIVITY eta_Ohm = par_getd_def("problem","eta_O",0.0); Q_Hall = par_getd_def("problem","Q_H",0.0); Q_AD = par_getd_def("problem","Q_AD",0.0); #endif #ifdef VISCOSITY nu_iso = par_getd_def("problem","nu_iso",0.0); nu_aniso = par_getd_def("problem","nu_aniso",0.0); #endif return; }
void problem_read_restart(MeshS *pM, FILE *fp) { int nl,nd,BCFlag_ix1,BCFlag_ox1; /* Read Omega, and with viscosity and/or resistivity, read eta_Ohm and nu_V */ #ifdef SHEARING_BOX Omega_0 = par_getd_def("problem","omega",1.0e-3); qshear = par_getd_def("problem","qshear",1.5); #endif Mp = par_getd_def("problem","Mplanet",0.0); Xplanet = par_getd_def("problem","Xplanet",0.0); Yplanet = par_getd_def("problem","Yplanet",0.0); Zplanet = par_getd_def("problem","Zplanet",0.0); Rsoft = par_getd_def("problem","Rsoft",0.1); ramp_time = 0.0; insert_time = par_getd_def("problem","insert_time",0.0); #ifdef VISCOSITY nu_iso = par_getd_def("problem","nu_iso",0.0); nu_aniso = par_getd_def("problem","nu_aniso",0.0); #endif /* enroll gravitational potential of planet & shearing-box potential fns */ StaticGravPot = PlanetPot; ShearingBoxPot = UnstratifiedDisk; /* enroll new history variables */ dump_history_enroll(hst_rho_Vx_dVy, "<rho Vx dVy>"); dump_history_enroll(hst_rho_dVy2, "<rho dVy^2>"); #ifdef ADIABATIC dump_history_enroll(hst_E_total, "<E + rho Phi>"); #endif BCFlag_ix1 = par_geti_def("domain1","bc_ix1",0); BCFlag_ox1 = par_geti_def("domain1","bc_ox1",0); for (nl=0; nl<(pM->NLevels); nl++){ for (nd=0; nd<(pM->DomainsPerLevel[nl]); nd++){ if (pM->Domain[nl][nd].Disp[0] == 0 && BCFlag_ix1 != 4) bvals_mhd_fun(&(pM->Domain[nl][nd]), left_x1, constant_iib); if (pM->Domain[nl][nd].MaxX[0] == pM->Domain[nl][nd].RootMaxX[0] && BCFlag_ox1 != 4) bvals_mhd_fun(&(pM->Domain[nl][nd]), right_x1, constant_oib); } } return; }
void problem_read_restart(MeshS *pM, FILE *fp) { R0 = par_getd_def("problem", "R0",2.0); Hbc = par_getd_def("problem","Hbc",1); Mbc = par_getd_def("problem","Mbc",1); StaticGravPot = grav_pot; x1GravAcc = grav_acc; bvals_mhd_fun(&(pM->Domain[0][0]),left_x1,disk_ir); bvals_mhd_fun(&(pM->Domain[0][0]),right_x1,disk_or); #ifdef FARGO OrbitalProfile = Omega; ShearProfile = Shear; #endif // Enroll history functions // #ifdef MHD dump_history_enroll(Br, "<Br>"); dump_history_enroll(Bp, "<Bp>"); dump_history_enroll(Bz, "<Bz>"); dump_history_enroll(Mrp, "<Mrp>"); dump_history_enroll(Trp, "<Trp>"); dump_history_enroll(MdotR1, "<MdotR1>"); dump_history_enroll(MdotR2, "<MdotR2>"); dump_history_enroll(MdotR3, "<MdotR3>"); dump_history_enroll(MdotR4, "<MdotR4>"); dump_history_enroll(Msub, "<Msub>"); dump_history_enroll(Mrpsub, "<Mrpsub>"); dump_history_enroll(Bpsub, "<Bpsub>"); dump_history_enroll(Bzsub, "<Bzsub>"); dump_history_enroll(Pbsub, "<Pbsub>"); #endif return; }
void problem_read_restart(MeshS *pM, FILE *fp) { DomainS *pD = (DomainS*)&(pM->Domain[0][0]); GridS *pG = pD->Grid; ShearingBoxPot = StratifiedDisk; Omega_0 = par_getd("problem","omega"); qshear = par_getd_def("problem","qshear",1.5); ipert = par_geti_def("problem","ipert",1); x1min = pG->MinX[0]; x1max = pG->MaxX[0]; Lx = x1max - x1min; x2min = pG->MinX[1]; x2max = pG->MaxX[1]; Ly = x2max - x2min; x3min = pM->RootMinX[2]; x3max = pM->RootMaxX[2]; Lz = x3max - x3min; Lg = nghost*pG->dx3; /* size of the ghost zone */ 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; Npar = (int)(sqrt(par_geti("particle","parnumgrid"))); nlis = par_geti_def("problem","nlis",pG->Nx[0]*pG->Nx[1]*pG->Nx[2]); ntrack = par_geti_def("problem","ntrack",2000); dump_history_enroll(hst_rho_Vx_dVy, "<rho Vx dVy>"); return; }
void problem_read_restart(Grid *pG, Domain *pD, FILE *fp) { Omega_0 = par_getd("problem","omega"); qshear = par_getd_def("problem","qshear",1.5); StaticGravPot = ShearingBoxPot; Ly = x2max - x2min; /* for 3D problem */ if (par_geti("grid","Nx3") == 1) { Ly = 0.0; } amp = par_getd("problem","amp"); omg = sqrt(2.0*(2.0-qshear))*Omega_0; fread(name, sizeof(char),50,fp); return; }
void problem(DomainS *pDomain) { GridS *pGrid = pDomain->Grid; int is = pGrid->is, ie = pGrid->ie; int js = pGrid->js, je = pGrid->je; int ks = pGrid->ks, ke = pGrid->ke; int i,j,k,BCFlag; Real x1,x2,x3; Real den = 1.0, pres = 1.0e-6; static int frst=1; /* flag so new history variables enrolled only once */ #ifdef SHEARING_BOX /* specify xy (r-phi) plane */ ShBoxCoord = xy; #endif /* Read problem parameters. Note Omega_0 set to 10^{-3} by default */ #ifdef SHEARING_BOX Omega_0 = par_getd_def("problem","omega",1.0e-3); qshear = par_getd_def("problem","qshear",1.5); #endif Mp = par_getd_def("problem","Mplanet",0.0); Xplanet = par_getd_def("problem","Xplanet",0.0); Yplanet = par_getd_def("problem","Yplanet",0.0); Zplanet = par_getd_def("problem","Zplanet",0.0); Rsoft = par_getd_def("problem","Rsoft",0.1); ramp_time = 0.0; insert_time = par_getd_def("problem","insert_time",0.0); /* Compute field strength based on beta. */ #ifdef ISOTHERMAL pres = Iso_csound2; #endif 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); /* Initialize d, M, and P. With FARGO do not initialize the background shear */ pGrid->U[k][j][i].d = den; // pGrid->U[k][j][i].d = 1.0+.5*(1-.02)*(tanh((x1-10.0)/3.5)-tanh((x1+10.0)/3.5))-.5*1.1*(tanh((x1-10.0)/15.0)-tanh((x1+10.0)/15.0)); pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = 0.0; #ifdef SHEARING_BOX #ifndef FARGO pGrid->U[k][j][i].M2 -= den*(qshear*Omega_0*x1); #endif #endif pGrid->U[k][j][i].M3 = 0.0; #ifdef ADIABATIC pGrid->U[k][j][i].E = pres/Gamma_1 + 0.5*(SQR(pGrid->U[k][j][i].M1) + SQR(pGrid->U[k][j][i].M2) + SQR(pGrid->U[k][j][i].M3))/den; #endif } }} /* enroll gravitational potential of planet & shearing-box potential fns */ StaticGravPot = PlanetPot; ShearingBoxPot = UnstratifiedDisk; /* enroll new history variables, only once */ if (frst == 1) { dump_history_enroll(hst_rho_Vx_dVy, "<rho Vx dVy>"); dump_history_enroll(hst_rho_dVy2, "<rho dVy^2>"); #ifdef ADIABATIC dump_history_enroll(hst_E_total, "<E + rho Phi>"); #endif frst = 0; } /* With viscosity and/or resistivity, read diffusion coeffs */ #ifdef VISCOSITY nu_iso = par_getd_def("problem","nu_iso",0.0); nu_aniso = par_getd_def("problem","nu_aniso",0.0); #endif /* Enroll outflow BCs if perdiodic BCs NOT selected. This assumes the root * level grid is specified by the <domain1> block in the input file */ BCFlag = par_geti_def("domain1","bc_ix1",0); if (BCFlag != 4) { if (pDomain->Disp[0] == 0) bvals_mhd_fun(pDomain, left_x1, constant_iib); } BCFlag = par_geti_def("domain1","bc_ox1",0); if (BCFlag != 4) { if (pDomain->MaxX[0] == pDomain->RootMaxX[0]) bvals_mhd_fun(pDomain, right_x1, constant_oib); } return; }
void problem(DomainS *pDomain) { GridS *pGrid = pDomain->Grid; int i=0,j=0,k=0; int is,ie,js,je,ks,ke,iprob; long int iseed = -1; Real amp,x1,x2,x3,lx,ly,lz,rhoh,L_rot,fact; #ifdef MHD Real b0,angle; #endif int ixs, jxs, kxs; is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; lx = pDomain->RootMaxX[0] - pDomain->RootMinX[0]; ly = pDomain->RootMaxX[1] - pDomain->RootMinX[1]; lz = pDomain->RootMaxX[2] - pDomain->RootMinX[2]; /* Ensure a different initial random seed for each process in an MPI calc. */ ixs = pGrid->Disp[0]; jxs = pGrid->Disp[1]; kxs = pGrid->Disp[2]; iseed = -1 - (ixs + pDomain->Nx[0]*(jxs + pDomain->Nx[1]*kxs)); /* Read perturbation amplitude, problem switch, background density */ amp = par_getd("problem","amp"); iprob = par_geti("problem","iprob"); rhoh = par_getd_def("problem","rhoh",3.0); /* Distance over which field is rotated */ L_rot = par_getd_def("problem","L_rot",0.0); /* Read magnetic field strength, angle [should be in degrees, 0 is along +ve * X-axis (no rotation)] */ #ifdef MHD b0 = par_getd("problem","b0"); angle = par_getd("problem","angle"); angle = (angle/180.)*PI; #endif /* 2D PROBLEM --------------------------------------------------------------- */ /* Initialize two fluids with interface at y=0.0. Pressure scaled to give a * sound speed of 1 at the interface in the light (lower, d=1) fluid * Perturb V2 using single (iprob=1) or multiple (iprob=2) mode */ if (pGrid->Nx[2] == 1) { 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); pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].E = (1.0/Gamma - 0.1*x2)/Gamma_1; pGrid->U[k][j][i].M1 = 0.0; if (iprob == 1) { pGrid->U[k][j][i].M2 = amp/4.0* (1.0+cos(2.0*PI*x1/lx))*(1.0+cos(2.0*PI*x2/ly)); } else { pGrid->U[k][j][i].M2 = amp*(ran2(&iseed) - 0.5)* (1.0+cos(2.0*PI*x2/ly)); } pGrid->U[k][j][i].M3 = 0.0; if (x2 > 0.0) { pGrid->U[k][j][i].d = 2.0; pGrid->U[k][j][i].M2 *= 2.0; pGrid->U[k][j][i].E = (1.0/Gamma - 0.2*x2)/Gamma_1; } pGrid->U[k][j][i].E+=0.5*SQR(pGrid->U[k][j][i].M2)/pGrid->U[k][j][i].d; #ifdef MHD pGrid->B1i[k][j][i] = b0; pGrid->U[k][j][i].B1c = b0; pGrid->U[k][j][i].E += 0.5*b0*b0; #endif } #ifdef MHD pGrid->B1i[k][j][ie+1] = b0; #endif } } /* Enroll gravitational potential to give acceleration in y-direction for 2D * Use special boundary condition routines. In 2D, gravity is in the * y-direction, so special boundary conditions needed for x2 */ StaticGravPot = grav_pot2; if (pDomain->Disp[1] == 0) bvals_mhd_fun(pDomain, left_x2, reflect_ix2); if (pDomain->MaxX[1] == pDomain->RootMaxX[1]) bvals_mhd_fun(pDomain, right_x2, reflect_ox2); } /* end of 2D initialization */ /* 3D PROBLEM ----------------------------------------------------------------*/ /* Initialize two fluids with interface at z=0.0 * Pressure scaled to give a sound speed of 1 at the interface * in the light (lower, d=1) fluid * iprob = 1 -- Perturb V3 using single mode * iprob = 2 -- Perturb V3 using multiple mode * iprob = 3 -- B in light fluid only, with multimode perturbation * iprob = 4 -- B rotated by "angle" at interface, multimode perturbation */ if (pGrid->Nx[2] > 1) { 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); pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].E = (1.0/Gamma - 0.1*x3)/Gamma_1; pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = 0.0; if (iprob == 1) { pGrid->U[k][j][i].M3 = amp/8.0*(1.0+cos(2.0*PI*x1/lx))* (1.0+cos(2.0*PI*x2/ly))*(1.0+cos(2.0*PI*x3/lz)); } else { pGrid->U[k][j][i].M3 = amp*(ran2(&iseed) - 0.5)* (1.0+cos(2.0*PI*x3/lz)); } if (x3 > 0.0) { pGrid->U[k][j][i].d = rhoh; pGrid->U[k][j][i].M3 *= rhoh; pGrid->U[k][j][i].E = (1.0/Gamma - 0.1*rhoh*x3)/Gamma_1; } pGrid->U[k][j][i].E+=0.5*SQR(pGrid->U[k][j][i].M3)/pGrid->U[k][j][i].d; #ifdef MHD switch(iprob){ case 3: /* B only in light fluid, do not add B^2 to E, total P const */ if (x3 <= 0.0) { pGrid->B1i[k][j][i] = b0; if (i == ie) pGrid->B1i[k][j][ie+1] = b0; pGrid->U[k][j][i].B1c = b0; } break; case 4: /* discontinuous rotation of B by angle at interface */ if (x3 <= 0.0) { pGrid->B1i[k][j][i] = b0; if (i == ie) pGrid->B1i[k][j][ie+1] = b0; pGrid->U[k][j][i].B1c = b0; pGrid->U[k][j][i].E += 0.5*b0*b0; } else { pGrid->B1i[k][j][i] = b0*cos(angle); pGrid->B2i[k][j][i] = b0*sin(angle); if (i == ie) pGrid->B1i[k][j][ie+1] = b0*cos(angle); if (j == je) pGrid->B2i[k][je+1][i] = b0*sin(angle); pGrid->U[k][j][i].B1c = b0*cos(angle); pGrid->U[k][j][i].B2c = b0*sin(angle); pGrid->U[k][j][i].E += 0.5*b0*b0; } break; case 5: /* rotation of B by angle over distance L_rot at interface */ if (x3 <= (-L_rot/2.0)) { pGrid->B1i[k][j][i] = b0; if (i == ie) pGrid->B1i[k][j][ie+1] = b0; pGrid->U[k][j][i].B1c = b0; pGrid->U[k][j][i].E += 0.5*b0*b0; } else if (x3 >= (L_rot/2.0)) { pGrid->B1i[k][j][i] = b0*cos(angle); pGrid->B2i[k][j][i] = b0*sin(angle); if (i == ie) pGrid->B1i[k][j][ie+1] = b0*cos(angle); if (j == je) pGrid->B2i[k][je+1][i] = b0*sin(angle); pGrid->U[k][j][i].B1c = b0*cos(angle); pGrid->U[k][j][i].B2c = b0*sin(angle); pGrid->U[k][j][i].E += 0.5*b0*b0; } else { fact = ((L_rot/2.0)+x3)/L_rot; pGrid->B1i[k][j][i] = b0*cos(fact*angle); pGrid->B2i[k][j][i] = b0*sin(fact*angle); if (i == ie) pGrid->B1i[k][j][ie+1] = b0*cos(fact*angle); if (j == je) pGrid->B2i[k][je+1][i] = b0*sin(fact*angle); pGrid->U[k][j][i].B1c = b0*cos(fact*angle); pGrid->U[k][j][i].B2c = b0*sin(fact*angle); pGrid->U[k][j][i].E += 0.5*b0*b0; } break; default: pGrid->B1i[k][j][i] = b0; if (i == ie) pGrid->B1i[k][j][ie+1] = b0; pGrid->U[k][j][i].B1c = b0; pGrid->U[k][j][i].E += 0.5*b0*b0; } #endif } } } /* Enroll gravitational potential to give accn in z-direction for 3D * Use special boundary condition routines. In 3D, gravity is in the * z-direction, so special boundary conditions needed for x3 */ StaticGravPot = grav_pot3; //if (pDomain->Disp[2] == 0) bvals_mhd_fun(pDomain, left_x3, reflect_ix3); //if (pDomain->MaxX[2] == pDomain->RootMaxX[2]) // bvals_mhd_fun(pDomain, right_x3, reflect_ox3); } /* end of 3D initialization */ return; }
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(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; }
void problem(DomainS *pDomain) { GridS *pGrid = pDomain->Grid; int i=0,j=0,k=0; int is,ie,js,je,ks,ke,nx1,nx2,nx3,iprob; Real x1c,x2c,x3c,x1f,x2f,x3f; /* cell- and face-centered coordinates */ Real x1size,x2size,x3size,lambda=0.0,ang_2=0.0,sin_a2=0.0,cos_a2=1.0,x,y; Real rad,amp,vflow,drat,diag; Real ***az,***ay,***ax; #ifdef MHD int ku; #endif #if (NSCALARS > 0) int n; #endif is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; nx1 = (ie-is)+1 + 2*nghost; nx2 = (je-js)+1 + 2*nghost; nx3 = (ke-ks)+1 + 2*nghost; if (((je-js) == 0)) { ath_error("[field_loop]: This problem can only be run in 2D or 3D\n"); } if ((ay = (Real***)calloc_3d_array(nx3, nx2, nx1, sizeof(Real))) == NULL) { ath_error("[field_loop]: Error allocating memory for vector pot\n"); } if ((az = (Real***)calloc_3d_array(nx3, nx2, nx1, sizeof(Real))) == NULL) { ath_error("[field_loop]: Error allocating memory for vector pot\n"); } if ((ax = (Real***)calloc_3d_array(nx3, nx2, nx1, sizeof(Real))) == NULL) { ath_error("[field_loop]: Error allocating memory for vector pot\n"); } /* Read initial conditions, diffusion coefficients (if needed) */ rad = par_getd("problem","rad"); amp = par_getd("problem","amp"); vflow = par_getd("problem","vflow"); drat = par_getd_def("problem","drat",1.0); iprob = par_getd("problem","iprob"); #ifdef RESISTIVITY eta_Ohm = par_getd_def("problem","eta_O",0.0); Q_Hall = par_getd_def("problem","Q_H",0.0); Q_AD = par_getd_def("problem","Q_AD",0.0); #endif #ifdef THERMAL_CONDUCTION kappa_iso = par_getd_def("problem","kappa_iso",0.0); kappa_aniso = par_getd_def("problem","kappa_aniso",0.0); #endif /* For (iprob=4) -- rotated cylinder in 3D -- set up rotation angle and * wavelength of cylinder */ if(iprob == 4){ x1size = pDomain->RootMaxX[0] - pDomain->RootMinX[0]; x3size = pDomain->RootMaxX[2] - pDomain->RootMinX[2]; /* We put 1 wavelength in each direction. Hence the wavelength * lambda = x1size*cos_a; * AND lambda = x3size*sin_a; * are both satisfied. */ if(x1size == x3size){ ang_2 = PI/4.0; cos_a2 = sin_a2 = sqrt(0.5); } else{ ang_2 = atan(x1size/x3size); sin_a2 = sin(ang_2); cos_a2 = cos(ang_2); } /* Use the larger angle to determine the wavelength */ if (cos_a2 >= sin_a2) { lambda = x1size*cos_a2; } else { lambda = x3size*sin_a2; } } /* Use vector potential to initialize field loop */ for (k=ks; k<=ke+1; k++) { for (j=js; j<=je+1; j++) { for (i=is; i<=ie+1; i++) { cc_pos(pGrid,i,j,k,&x1c,&x2c,&x3c); x1f = x1c - 0.5*pGrid->dx1; x2f = x2c - 0.5*pGrid->dx2; x3f = x3c - 0.5*pGrid->dx3; /* (iprob=1): field loop in x1-x2 plane (cylinder in 3D) */ if(iprob==1) { ax[k][j][i] = 0.0; ay[k][j][i] = 0.0; if ((x1f*x1f + x2f*x2f) < rad*rad) { az[k][j][i] = amp*(rad - sqrt(x1f*x1f + x2f*x2f)); } else { az[k][j][i] = 0.0; } } /* (iprob=2): field loop in x2-x3 plane (cylinder in 3D) */ if(iprob==2) { if ((x2f*x2f + x3f*x3f) < rad*rad) { ax[k][j][i] = amp*(rad - sqrt(x2f*x2f + x3f*x3f)); } else { ax[k][j][i] = 0.0; } ay[k][j][i] = 0.0; az[k][j][i] = 0.0; } /* (iprob=3): field loop in x3-x1 plane (cylinder in 3D) */ if(iprob==3) { if ((x1f*x1f + x3f*x3f) < rad*rad) { ay[k][j][i] = amp*(rad - sqrt(x1f*x1f + x3f*x3f)); } else { ay[k][j][i] = 0.0; } ax[k][j][i] = 0.0; az[k][j][i] = 0.0; } /* (iprob=4): rotated cylindrical field loop in 3D. Similar to iprob=1 * with a rotation about the x2-axis. Define coordinate systems (x1,x2,x3) * and (x,y,z) with the following transformation rules: * x = x1*cos(ang_2) + x3*sin(ang_2) * y = x2 * z = -x1*sin(ang_2) + x3*cos(ang_2) * This inverts to: * x1 = x*cos(ang_2) - z*sin(ang_2) * x2 = y * x3 = x*sin(ang_2) + z*cos(ang_2) */ if(iprob==4) { x = x1c*cos_a2 + x3f*sin_a2; y = x2f; /* shift x back to the domain -0.5*lambda <= x <= 0.5*lambda */ while(x > 0.5*lambda) x -= lambda; while(x < -0.5*lambda) x += lambda; if ((x*x + y*y) < rad*rad) { ax[k][j][i] = amp*(rad - sqrt(x*x + y*y))*(-sin_a2); } else { ax[k][j][i] = 0.0; } ay[k][j][i] = 0.0; x = x1f*cos_a2 + x3c*sin_a2; y = x2f; /* shift x back to the domain -0.5*lambda <= x <= 0.5*lambda */ while(x > 0.5*lambda) x -= lambda; while(x < -0.5*lambda) x += lambda; if ((x*x + y*y) < rad*rad) { az[k][j][i] = amp*(rad - sqrt(x*x + y*y))*(cos_a2); } else { az[k][j][i] = 0.0; } } /* (iprob=5): spherical field loop in rotated plane */ if(iprob==5) { ax[k][j][i] = 0.0; if ((x1f*x1f + x2c*x2c + x3f*x3f) < rad*rad) { ay[k][j][i] = amp*(rad - sqrt(x1f*x1f + x2c*x2c + x3f*x3f)); } else { ay[k][j][i] = 0.0; } if ((x1f*x1f + x2f*x2f + x3c*x3c) < rad*rad) { az[k][j][i] = amp*(rad - sqrt(x1f*x1f + x2f*x2f + x3c*x3c)); } else { az[k][j][i] = 0.0; } } }}} /* Initialize density and momenta. If drat != 1, then density and temperature * will be different inside loop than background values */ x1size = pDomain->RootMaxX[0] - pDomain->RootMinX[0]; x2size = pDomain->RootMaxX[1] - pDomain->RootMinX[1]; x3size = pDomain->RootMaxX[2] - pDomain->RootMinX[2]; diag = sqrt(x1size*x1size + x2size*x2size + x3size*x3size); for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].M1 = pGrid->U[k][j][i].d*vflow*x1size/diag; pGrid->U[k][j][i].M2 = pGrid->U[k][j][i].d*vflow*x2size/diag; pGrid->U[k][j][i].M3 = pGrid->U[k][j][i].d*vflow*x3size/diag; cc_pos(pGrid,i,j,k,&x1c,&x2c,&x3c); if ((x1c*x1c + x2c*x2c + x3c*x3c) < rad*rad) { pGrid->U[k][j][i].d = drat; pGrid->U[k][j][i].M1 = pGrid->U[k][j][i].d*vflow*x1size/diag; pGrid->U[k][j][i].M2 = pGrid->U[k][j][i].d*vflow*x2size/diag; pGrid->U[k][j][i].M3 = pGrid->U[k][j][i].d*vflow*x3size/diag; } #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) pGrid->U[k][j][i].s[n] = 0.0; if ((x1c*x1c + x2c*x2c + x3c*x3c) < rad*rad) { for (n=0; n<NSCALARS; n++) pGrid->U[k][j][i].s[n] = 1.0; } #endif }}} /* boundary conditions on interface B */ #ifdef MHD for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie+1; i++) { pGrid->B1i[k][j][i] = (az[k][j+1][i] - az[k][j][i])/pGrid->dx2 - (ay[k+1][j][i] - ay[k][j][i])/pGrid->dx3; }}} for (k=ks; k<=ke; k++) { for (j=js; j<=je+1; j++) { for (i=is; i<=ie; i++) { pGrid->B2i[k][j][i] = (ax[k+1][j][i] - ax[k][j][i])/pGrid->dx3 - (az[k][j][i+1] - az[k][j][i])/pGrid->dx1; }}} if (ke > ks) { ku = ke+1; } else { ku = ke; } for (k=ks; k<=ku; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { pGrid->B3i[k][j][i] = (ay[k][j][i+1] - ay[k][j][i])/pGrid->dx1 - (ax[k][j+1][i] - ax[k][j][i])/pGrid->dx2; }}} #endif /* initialize total energy and cell-centered B */ #if defined MHD || !defined ISOTHERMAL for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { #ifdef MHD pGrid->U[k][j][i].B1c = 0.5*(pGrid->B1i[k][j][i ] + pGrid->B1i[k][j][i+1]); pGrid->U[k][j][i].B2c = 0.5*(pGrid->B2i[k][j ][i] + pGrid->B2i[k][j+1][i]); if (ke > ks) pGrid->U[k][j][i].B3c = 0.5*(pGrid->B3i[k ][j][i] + pGrid->B3i[k+1][j][i]); else pGrid->U[k][j][i].B3c = pGrid->B3i[k][j][i]; #endif #ifndef ISOTHERMAL pGrid->U[k][j][i].E = 1.0/Gamma_1 #ifdef MHD + 0.5*(SQR(pGrid->U[k][j][i].B1c) + SQR(pGrid->U[k][j][i].B2c) + SQR(pGrid->U[k][j][i].B3c)) #endif + 0.5*(SQR(pGrid->U[k][j][i].M1) + SQR(pGrid->U[k][j][i].M2) + SQR(pGrid->U[k][j][i].M3))/pGrid->U[k][j][i].d; #endif /* ISOTHERMAL */ } } } #endif free_3d_array((void***)az); free_3d_array((void***)ay); free_3d_array((void***)ax); }
void problem(Grid *pGrid, Domain *pDomain) { int i,is,ie,j,js,je,ks,nx1,nx2,iprob; long int iseed = -1; /* Initialize on the first call to ran2 */ Real d0,p0,B0,v0,x1,x2,x3,x1min,x1max,Lx,k0,press,amp,kp; is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; nx1 = (ie-is)+1; nx2 = (je-js)+1; if ((nx1 == 1) || (nx2 == 1)) { ath_error("[firehose]: This problem can only be run in 2D\n"); } d0 = 1.0; p0 = 1.0; B0 = par_getd("problem","B0"); v0 = par_getd("problem","v0"); #ifdef VISCOSITY nu_iso = par_getd_def("problem","nu_iso",0.0); nu_aniso = par_getd_def("problem","nu_aniso",0.0); #endif amp = par_getd("problem","amp"); kp = par_getd("problem","kp"); iprob = par_getd("problem","iprob"); /* Initialize wavenumber */ x1min = par_getd("grid","x1min"); x1max = par_getd("grid","x1max"); Lx = x1max - x1min; k0 = 2.0*PI/Lx; /* iprob=1: Cowley/Hammett vortex test ---------------------------------------*/ /* Initialize density, momentum, face-centered fields */ if (iprob == 1) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { /* Calculate the cell center positions */ cc_pos(pGrid,i,j,ks,&x1,&x2,&x3); pGrid->U[ks][j][i].d = d0; pGrid->U[ks][j][i].M1 = -d0*v0*cos(k0*x2)*sin(k0*x1); pGrid->U[ks][j][i].M2 = d0*v0*sin(k0*x2)*cos(k0*x1)+amp*cos(kp*x1); pGrid->U[ks][j][i].M3 = 0.0; #ifdef MHD pGrid->B1i[ks][j][i] = B0; pGrid->B2i[ks][j][i] = 0.0; pGrid->B3i[ks][j][i] = 0.0; pGrid->U[ks][j][i].B1c = B0; pGrid->U[ks][j][i].B2c = 0.0; pGrid->U[ks][j][i].B3c = 0.0; #endif /* MHD */ press = p0 + 0.5*d0*v0*v0*(cos(k0*x1)*cos(k0*x1) + cos(k0*x2)*cos(k0*x2)); pGrid->U[ks][j][i].E = press/Gamma_1 #ifdef MHD + 0.5*(SQR(pGrid->U[ks][j][i].B1c) + SQR(pGrid->U[ks][j][i].B2c) + SQR(pGrid->U[ks][j][i].B3c)) #endif /* MHD */ + 0.5*(SQR(pGrid->U[ks][j][i].M1) + SQR(pGrid->U[ks][j][i].M2) + SQR(pGrid->U[ks][j][i].M3))/pGrid->U[ks][j][i].d; } } #ifdef MHD /* boundary conditions on interface B */ for (j=js; j<=je; j++) { pGrid->B1i[ks][j][ie+1] = B0; } for (i=is; i<=ie; i++) { pGrid->B2i[ks][je+1][i] = 0.0; } #endif /* MHD */ } /* iprob=2: Sharma shear test ----------------------------------------------- */ /* Initialize density, momentum, face-centered fields */ if (iprob == 2) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { /* Calculate the cell center positions */ cc_pos(pGrid,i,j,ks,&x1,&x2,&x3); pGrid->U[ks][j][i].d = d0; pGrid->U[ks][j][i].M1 = d0*amp*(ran2(&iseed) - 0.5); pGrid->U[ks][j][i].M2 = d0*(amp*(ran2(&iseed) - 0.5) - 0.015*x1); pGrid->U[ks][j][i].M3 = 0.0; #ifdef MHD pGrid->B1i[ks][j][i] = B0; pGrid->B2i[ks][j][i] = B0; pGrid->B3i[ks][j][i] = 0.0; pGrid->U[ks][j][i].B1c = B0; pGrid->U[ks][j][i].B2c = B0; pGrid->U[ks][j][i].B3c = 0.0; #endif /* MHD */ pGrid->U[ks][j][i].E = 0.1/Gamma_1 #ifdef MHD + 0.5*(SQR(pGrid->U[ks][j][i].B1c) + SQR(pGrid->U[ks][j][i].B2c) + SQR(pGrid->U[ks][j][i].B3c)) #endif /* MHD */ + 0.5*(SQR(pGrid->U[ks][j][i].M1) + SQR(pGrid->U[ks][j][i].M2) + SQR(pGrid->U[ks][j][i].M3))/pGrid->U[ks][j][i].d; } } #ifdef MHD /* boundary conditions on interface B */ for (j=js; j<=je; j++) { pGrid->B1i[ks][j][ie+1] = B0; } for (i=is; i<=ie; i++) { pGrid->B2i[ks][je+1][i] = B0; } #endif /* MHD */ /* Enroll special BCs for shearing sheet */ set_bvals_mhd_fun(left_x1, pbc_ix1); set_bvals_mhd_fun(right_x1, pbc_ox1); } return; }
void init_output(MeshS *pM) { int i,j,outn,maxout; char block[80], *fmt, defid[10]; OutputS new_out; int usr_expr_flag; maxout = par_geti_def("job","maxout",MAXOUT_DEFAULT); /* allocate output array */ if((OutArray = (OutputS *)malloc(maxout*sizeof(OutputS))) == NULL){ ath_error("[init_output]: Error allocating output array\n"); } /*--- loop over maxout output blocks, reading parameters into a temporary -----* *--- OutputS called new_out --------------------------------------------------*/ for (outn=1; outn<=maxout; outn++) { sprintf(block,"output%d",outn); /* An output format or output name is required. * If neither is present we write an error message and move on. */ if((par_exist(block,"out_fmt") == 0) && (par_exist(block,"name") == 0)){ ath_perr(-1,"[init_output]: neither %s/out_fmt, nor %s/name exist\n", block, block); continue; } /* Zero (NULL) all members of the temporary OutputS structure "new_out" */ memset(&new_out,0,sizeof(OutputS)); /* The next output time and number */ new_out.t = par_getd_def(block,"time",pM->time); new_out.num = par_geti_def(block,"num",0); new_out.dt = par_getd(block,"dt"); new_out.n = outn; /* level and domain number can be specified with SMR */ new_out.nlevel = par_geti_def(block,"level",-1); new_out.ndomain = par_geti_def(block,"domain",-1); if (par_exist(block,"dat_fmt")) new_out.dat_fmt = par_gets(block,"dat_fmt"); /* set id in output filename to input string if present, otherwise use "outN" * as default, where N is output number */ sprintf(defid,"out%d",outn); new_out.id = par_gets_def(block,"id",defid); if(par_exist(block,"out_fmt")) fmt = new_out.out_fmt = par_gets(block,"out_fmt"); /* out: controls what variable can be output (all, prim, or any of expr_*) * out_fmt: controls format of output (single variable) or dump (all cons/prim) * if "out" doesn't exist, we assume 'cons' variables are meant to be dumped */ new_out.out = par_gets_def(block,"out","cons"); #ifdef PARTICLES /* check input for particle binning (=1, default) or not (=0) */ new_out.out_pargrid = par_geti_def(block,"pargrid", check_particle_binning(new_out.out)); if ((new_out.out_pargrid < 0) || (new_out.out_pargrid >1)) { ath_perr(-1,"[init_output]: %s/pargrid must be 0 or 1\n", block); continue; } /* set particle property selection function. By default, will select all the * particles. Used only when particle output is called, otherwise useless. */ if(par_exist(block,"par_prop")) { new_out.par_prop = get_usr_par_prop(par_gets(block,"par_prop")); if (new_out.par_prop == NULL) { ath_pout(0,"[init_output]: Particle selection function not found! \ Now use the default one.\n"); new_out.par_prop = property_all; } }
void problem(DomainS *pDomain) { GridS *pG = pDomain->Grid; int is = pG->is, ie = pG->ie; int js = pG->js, je = pG->je; int ks = pG->ks, ke = pG->ke; int ixs,jxs,kxs,i,j,k; long int iseed = -1; /* Initialize on the first call to ran2 */ Real x1,x2,x3,xmin,xmax,Lx,Ly,Lz; Real rd, rp, rvx, rvy, rvz, rbx, rby, rbz; Real beta,B0,P0,kx,ky,kz,amp,press; Real Q,nJ,cs,cs2; Real time0,kxt; #ifdef SELF_GRAVITY Real Gcons; #endif int nwx,nwy,nwz; /* input number of waves per Lx,Ly,Lz [default=1] */ double rval; if(pG->Nx[2] == 1) ShBoxCoord = xy; /* 2D xy-plane */ /* Read problem parameters. */ Omega_0 = par_getd("problem","omega"); qshear = par_getd("problem","qshear"); amp = par_getd("problem","amp"); /* Read parameters for magnetic field */ beta = par_getd("problem","beta"); /* Read parameters for self gravity */ Q=par_getd("problem","Q"); nJ= par_getd("problem","nJ"); time0=par_getd_def("problem","time0",0.0); cs=sqrt(4.0-2.0*qshear)/PI/nJ/Q; cs2=SQR(cs); #ifdef SELF_GRAVITY Gcons = nJ*cs2; grav_mean_rho = 1.0; #ifndef SELF_GRAVITY_USING_FFT_DISK if(pG->Nx[2] >1) grav_mean_rho = 1.0; #endif /* Set gravity constant*/ four_pi_G = 4.0*PI*Gcons; #endif /* SELF_GRAVITY */ B0 = cs/sqrt(beta); #ifndef BAROTROPIC P0 = cs2/Gamma; #endif /* Ensure a different initial random seed for each process in an MPI calc. */ ixs = pG->Disp[0]; jxs = pG->Disp[1]; kxs = pG->Disp[2]; iseed = -1 - (ixs + pDomain->Nx[0]*(jxs + pDomain->Nx[1]*kxs)); Lx = pDomain->RootMaxX[0] - pDomain->RootMinX[0]; /* initialize wavenumbers, given input number of waves per L */ nwx = par_geti_def("problem","nwx",-6); nwy = par_geti_def("problem","nwy",1); ky = nwy*2.0*PI; kx = nwx*2.0*PI; kxt = kx+qshear*Omega_0*ky*time0; pG->time=time0; for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { cc_pos(pG,i,j,k,&x1,&x2,&x3); if (((i-pG->Disp[0]) == 58) && ((j-pG->Disp[1]) == 16)) printf("i=%d j=%d k=%d x1=%e x2=%e\n",i,j,k,x1,x2); rd = 1.0+amp*cos(kxt*x1+ky*x2); rvx = amp*kx/ky*sin(kxt*x1+ky*x2); rvy = amp*sin(kxt*x1+ky*x2); rvz = 0.0; rp = cs2*(rd-1.0); rbx = amp*nwy*cos(kxt*(x1-0.5*pG->dx1)+ky*x2); rby = -amp*nwx*cos(kxt*x1+ky*(x2-0.5*pG->dx2)); rbz = 0.0; pG->U[k][j][i].d = rd; pG->U[k][j][i].M1 = rd*rvx; pG->U[k][j][i].M2 = rd*rvy; #ifndef FARGO pG->U[k][j][i].M2 -= rd*(qshear*Omega_0*x1); #endif pG->U[k][j][i].M3 = rd*rvz; #ifdef ADIABATIC pG->U[k][j][i].E = (P0+rp)/Gamma_1 + 0.5*(SQR(pG->U[k][j][i].M1) + SQR(pG->U[k][j][i].M2) + SQR(pG->U[k][j][i].M3))/rd; #endif #ifdef MHD pG->B1i[k][j][i] = rbx; pG->B2i[k][j][i] = B0+rby; pG->B3i[k][j][i] = 0.0; if (i==ie) cc_pos(pG,ie+1,j,k,&x1,&x2,&x3); rbx = amp*nwy*cos(kx*(x1-0.5*pG->dx1)+ky*x2); if (j==je) cc_pos(pG,i,je+1,k,&x1,&x2,&x3); rby = -amp*nwx*cos(kx*x1+ky*(x2-0.5*pG->dx2)); if (i==ie) pG->B1i[k][j][ie+1] = rbx; if (j==je) pG->B2i[k][je+1][i] = B0+rby; if (pG->Nx[2] > 1 && k==ke) pG->B3i[ke+1][j][i] = 0.0; #endif /* MHD */ } } } #ifdef MHD for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { pG->U[k][j][i].B1c = 0.5*(pG->B1i[k][j][i]+pG->B1i[k][j][i+1]); pG->U[k][j][i].B2c = 0.5*(pG->B2i[k][j][i]+pG->B2i[k][j+1][i]); if (pG->Nx[2] >1) pG->U[k][j][i].B3c = 0.5*(pG->B3i[k][j][i]+pG->B3i[k+1][j][i]); else pG->U[k][j][i].B3c =pG->B3i[k][j][i]; #ifdef ADIABATIC pG->U[k][j][i].E += 0.5*(SQR(pG->U[k][j][i].B1c) + SQR(pG->U[k][j][i].B2c) + SQR(pG->U[k][j][i].B3c)); #endif } } } #endif /* MHD */ /* enroll gravitational potential function */ ShearingBoxPot = UnstratifiedDisk; /* enroll new history variables, only once with SMR */ dVol = pDomain->Nx[0]*pDomain->Nx[1]*pDomain->Nx[2]; /* history dump for linear perturbation amplitude. See Kim & Ostriker 2001 */ dump_history_enroll(hst_sigma, "<sigma>"); dump_history_enroll(hst_ux, "<ux>"); dump_history_enroll(hst_uy, "<uy>"); #ifdef MHD dump_history_enroll(hst_m1, "<m1>"); dump_history_enroll(hst_m2, "<m2>"); #endif /* history dump for peturbed quantities at a specific grid point */ dump_history_enroll(hst_dSigma, "<dSigma>"); dump_history_enroll(hst_Vx, "<Vx>"); dump_history_enroll(hst_dVy, "<dVy>"); #ifdef MHD dump_history_enroll(hst_Bx, "<Bx>"); dump_history_enroll(hst_dBy, "<dBy>"); #endif /* MHD */ #ifdef SELF_GRAVITY dump_history_enroll(hst_Phi, "<Phi>"); dump_history_enroll(hst_dPhi, "<dPhi>"); #endif #ifdef ADIABATIC dump_history_enroll(hst_dE, "<dE>"); #endif printf("=== end of problem setting ===\n"); return; }
void problem(DomainS *pDomain) { GridS *pGrid = pDomain->Grid; int i=0,j=0,k=0; int is,ie,js,je,ks,ke,iprob; Real amp,drat,vflow,b0,a,sigma,x1,x2,x3; long int iseed = -1; static int frst=1; /* flag so new history variables enrolled only once */ is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; /* Read problem parameters */ iprob = par_geti("problem","iprob"); vflow = par_getd("problem","vflow"); drat = par_getd("problem","drat"); amp = par_getd("problem","amp"); #ifdef MHD b0 = par_getd("problem","b0"); #endif /* iprob=1. Two uniform streams moving at +/- vflow, random perturbations */ if (iprob == 1) { 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); pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].M1 = vflow + amp*(ran2(&iseed) - 0.5); pGrid->U[k][j][i].M2 = amp*(ran2(&iseed) - 0.5); pGrid->U[k][j][i].M3 = 0.0; if (fabs(x2) < 0.25) { pGrid->U[k][j][i].d = drat; pGrid->U[k][j][i].M1 = -drat*(vflow + amp*(ran2(&iseed) - 0.5)); pGrid->U[k][j][i].M2 = drat*amp*(ran2(&iseed) - 0.5); } /* Pressure scaled to give a sound speed of 1 with gamma=1.4 */ #ifndef BAROTROPIC pGrid->U[k][j][i].E = 2.5/Gamma_1 + 0.5*(SQR(pGrid->U[k][j][i].M1) + SQR(pGrid->U[k][j][i].M2) + SQR(pGrid->U[k][j][i].M3))/pGrid->U[k][j][i].d; #endif /* BAROTROPIC */ #ifdef MHD pGrid->B1i[k][j][i] = b0; pGrid->U[k][j][i].B1c = b0; #ifndef BAROTROPIC pGrid->U[k][j][i].E += 0.5*b0*b0; #endif /* BAROTROPIC */ #endif /* MHD */ } #ifdef MHD pGrid->B1i[k][j][ie+1] = b0; #endif } } } /* iprob=2. Test suggested by E. Zweibel, based on Ryu & Jones. * Two uniform density flows with single mode perturbation */ if (iprob == 2) { a = 0.05; sigma = 0.2; 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); pGrid->U[k][j][i].d = 1.0; pGrid->U[k][j][i].M1 = vflow*tanh(x2/a); pGrid->U[k][j][i].M2 = amp*sin(2.0*PI*x1)*exp(-(x2*x2)/(sigma*sigma)); pGrid->U[k][j][i].M3 = 0.0; #ifndef BAROTROPIC pGrid->U[k][j][i].E = 1.0/Gamma_1 + 0.5*(SQR(pGrid->U[k][j][i].M1) + SQR(pGrid->U[k][j][i].M2) + SQR(pGrid->U[k][j][i].M3))/pGrid->U[k][j][i].d; #endif /* BAROTROPIC */ #ifdef MHD pGrid->B1i[k][j][i] = b0; pGrid->U[k][j][i].B1c = b0; #ifndef BAROTROPIC pGrid->U[k][j][i].E += 0.5*b0*b0; #endif /* BAROTROPIC */ #endif /* MHD */ /* Use passive scalar to keep track of the fluids, since densities are same */ #if (NSCALARS > 0) pGrid->U[k][j][i].s[0] = 0.0; if (x2 > 0) pGrid->U[k][j][i].s[0] = 1.0; #endif } #ifdef MHD pGrid->B1i[k][j][ie+1] = b0; #endif } } } /* iprob=3. Test in SR paper, based on iprob=2 */ if (iprob == 3) { a = 0.01; sigma = 0.1; 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); pGrid->U[k][j][i].d = 0.505 + 0.495*tanh((fabs(x2)-0.5)/a); pGrid->U[k][j][i].M1 = vflow*tanh((fabs(x2)-0.5)/a); pGrid->U[k][j][i].M2 = amp*vflow*sin(2.0*PI*x1) *exp(-((fabs(x2)-0.5)*(fabs(x2)-0.5))/(sigma*sigma)); if (x2 < 0.0) pGrid->U[k][j][i].M2 *= -1.0; pGrid->U[k][j][i].M1 *= pGrid->U[k][j][i].d; pGrid->U[k][j][i].M2 *= pGrid->U[k][j][i].d; pGrid->U[k][j][i].M3 = 0.0; #ifndef BAROTROPIC pGrid->U[k][j][i].E = 1.0/Gamma_1 + 0.5*(SQR(pGrid->U[k][j][i].M1) + SQR(pGrid->U[k][j][i].M2) + SQR(pGrid->U[k][j][i].M3))/pGrid->U[k][j][i].d; #endif /* BAROTROPIC */ #ifdef MHD pGrid->B1i[k][j][i] = b0; pGrid->U[k][j][i].B1c = b0; #ifndef BAROTROPIC pGrid->U[k][j][i].E += 0.5*b0*b0; #endif /* BAROTROPIC */ #endif /* MHD */ } #ifdef MHD pGrid->B1i[k][j][ie+1] = b0; #endif } } } /* With viscosity and/or resistivity, read diffusion coeffs */ #ifdef RESISTIVITY eta_Ohm = par_getd_def("problem","eta_O",0.0); Q_Hall = par_getd_def("problem","Q_H",0.0); Q_AD = par_getd_def("problem","Q_AD",0.0); #endif #ifdef VISCOSITY nu_iso = par_getd_def("problem","nu_iso",0.0); nu_aniso = par_getd_def("problem","nu_aniso",0.0); #endif /* enroll new history variables, only once */ if (frst == 1) { #ifdef MHD dump_history_enroll(hst_Bx, "<Bx>"); dump_history_enroll(hst_By, "<By>"); dump_history_enroll(hst_Bz, "<Bz>"); #endif /* MHD */ frst = 0; } }
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(DomainS *pDomain) { GridS *pGrid=(pDomain->Grid); int i,il,iu,j,jl,ju,k,kl,ku; int is,ie,js,je,ks,ke,nx1,nx2,nx3; int shk_dir; /* Shock direction: {1,2,3} -> {x1,x2,x3} */ Real ang_2, ang_3; /* Rotation angles about the y and z' axis */ Real sin_a2, cos_a2, sin_a3, cos_a3; Real x1,x2,x3; Prim1DS Wl, Wr; Cons1DS U1d, Ul, Ur; Real Bxl=0.0, Bxr=0.0, Bxb=0.0; /* speeds of shock, contact, head and foot of rarefaction for Sod test */ /* speeds of slow/fast shocks, Alfven wave and contact in RJ2a test */ Real tlim; int err_test; Real r,xs,xc,xf,xh,vs,vc,vf,vh; Real xfp,xrp,xsp,xsm,xrm,xfm,vfp,vrp,vsp,vsm,vrm,vfm; Real d0,v0,Mx,My,Mz,E0,r0,Bx,By,Bz; #if (NSCALARS > 0) int n; #endif is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; nx1 = (ie-is)+1 + 2*nghost; nx2 = (je-js)+1 + 2*nghost; nx3 = (ke-ks)+1 + 2*nghost; printf("here1\n"); if (pDomain->Level == 0){ if ((RootSoln = (ConsS***)calloc_3d_array(nx3,nx2,nx1,sizeof(ConsS))) == NULL) ath_error("[problem]: Error alloc memory for RootSoln\n"); } /* Parse left state read from input file: dl,pl,ul,vl,wl,bxl,byl,bzl */ Wl.d = par_getd("problem","dl"); #ifdef ADIABATIC Wl.P = par_getd("problem","pl"); #endif Wl.Vx = par_getd("problem","v1l"); Wl.Vy = par_getd("problem","v2l"); Wl.Vz = par_getd("problem","v3l"); #ifdef MHD Bxl = par_getd("problem","b1l"); Wl.By = par_getd("problem","b2l"); Wl.Bz = par_getd("problem","b3l"); #endif #if (NSCALARS > 0) Wl.r[0] = par_getd("problem","r0l"); #endif /* Parse right state read from input file: dr,pr,ur,vr,wr,bxr,byr,bzr */ Wr.d = par_getd("problem","dr"); #ifdef ADIABATIC Wr.P = par_getd("problem","pr"); #endif Wr.Vx = par_getd("problem","v1r"); Wr.Vy = par_getd("problem","v2r"); Wr.Vz = par_getd("problem","v3r"); #ifdef MHD Bxr = par_getd("problem","b1r"); Wr.By = par_getd("problem","b2r"); Wr.Bz = par_getd("problem","b3r"); if (Bxr != Bxl) ath_error(0,"[shkset1d] L/R values of Bx not the same\n"); #endif #if (NSCALARS > 0) Wr.r[0] = par_getd("problem","r0r"); #endif printf("here2\n"); #ifdef SAC_INTEGRATOR Ul = Prim1D_to_Cons1D(&Wl, &Bxl,&Bxb); Ur = Prim1D_to_Cons1D(&Wr, &Bxr,&Bxb); #elif defined SMAUG_INTEGRATOR Ul = Prim1D_to_Cons1D(&Wl, &Bxl,&Bxb); Ur = Prim1D_to_Cons1D(&Wr, &Bxr,&Bxb); #else Ul = Prim1D_to_Cons1D(&Wl, &Bxl); Ur = Prim1D_to_Cons1D(&Wr, &Bxr); #endif printf("here3\n"); /* Parse shock direction */ shk_dir = par_geti("problem","shk_dir"); if (shk_dir != 1 && shk_dir != 2 && shk_dir != 3) { ath_error("[problem]: shk_dir = %d must be either 1,2 or 3\n",shk_dir); } /* Set up the index bounds for initializing the grid */ iu = pGrid->ie + nghost; il = pGrid->is - nghost; if (pGrid->Nx[1] > 1) { ju = pGrid->je + nghost; jl = pGrid->js - nghost; } else { ju = pGrid->je; jl = pGrid->js; } if (pGrid->Nx[2] > 1) { ku = pGrid->ke + nghost; kl = pGrid->ks - nghost; } else { ku = pGrid->ke; kl = pGrid->ks; } printf("here4\n"); /* Initialize the grid including the ghost cells. Discontinuity is always * located at x=0, so xmin/xmax in input file must be set appropriately. */ switch(shk_dir) { /*--- shock in 1-direction ---------------------------------------------------*/ case 1: /* shock in 1-direction */ ang_2 = 0.0; ang_3 = 0.0; for (k=kl; k<=ku; k++) { for (j=jl; j<=ju; j++) { for (i=il; i<=iu; i++) { cc_pos(pGrid, i, j, k, &x1, &x2, &x3); /* set primitive and conserved variables to be L or R state */ if (x1 <= 0.0) { U1d = Ul; } else { U1d = Ur; } /* Initialize conserved (and with SR the primitive) variables in Grid */ pGrid->U[k][j][i].d = U1d.d; pGrid->U[k][j][i].M1 = U1d.Mx; pGrid->U[k][j][i].M2 = U1d.My; pGrid->U[k][j][i].M3 = U1d.Mz; #ifdef MHD pGrid->B1i[k][j][i] = Bxl; pGrid->B2i[k][j][i] = U1d.By; pGrid->B3i[k][j][i] = U1d.Bz; pGrid->U[k][j][i].B1c = Bxl; pGrid->U[k][j][i].B2c = U1d.By; pGrid->U[k][j][i].B3c = U1d.Bz; #endif #ifdef ADIABATIC pGrid->U[k][j][i].E = U1d.E; #endif #if (NSCALARS > 0) pGrid->U[k][j][i].s[0] = U1d.s[0]; #endif } } } break; /*--- shock in 2-direction ---------------------------------------------------*/ case 2: /* shock in 2-direction */ ang_2 = 0.0; ang_3 = PI/2.0; for (k=kl; k<=ku; k++) { for (j=jl; j<=ju; j++) { for (i=il; i<=iu; i++) { cc_pos(pGrid, i, j, k, &x1, &x2, &x3); /* set primitive variables to be L or R state */ if (x2 <= 0.0) { U1d = Ul; } else { U1d = Ur; } /* Initialize conserved (and with SR the primitive) variables in Grid */ pGrid->U[k][j][i].d = U1d.d; pGrid->U[k][j][i].M1 = -U1d.My; pGrid->U[k][j][i].M2 = U1d.Mx; pGrid->U[k][j][i].M3 = U1d.Mz; #ifdef MHD pGrid->B1i[k][j][i] = -U1d.By; pGrid->B2i[k][j][i] = Bxl; pGrid->B3i[k][j][i] = U1d.Bz; pGrid->U[k][j][i].B1c = -U1d.By; pGrid->U[k][j][i].B2c = Bxl; pGrid->U[k][j][i].B3c = U1d.Bz; #endif #ifdef ADIABATIC pGrid->U[k][j][i].E = U1d.E; #endif #if (NSCALARS > 0) pGrid->U[k][j][i].s[0] = U1d.s[0]; #endif } } } break; /*--- shock in 3-direction ---------------------------------------------------*/ case 3: /* shock in 3-direction */ ang_2 = PI/2.0; ang_3 = 0.0; for (k=kl; k<=ku; k++) { for (j=jl; j<=ju; j++) { for (i=il; i<=iu; i++) { cc_pos(pGrid, i, j, k, &x1, &x2, &x3); /* set primitive variables to be L or R state */ if (x3 <= 0.0) { U1d = Ul; } else { U1d = Ur; } /* Initialize conserved (and with SR the primitive) variables in Grid */ pGrid->U[k][j][i].d = U1d.d; pGrid->U[k][j][i].M1 = -U1d.Mz; pGrid->U[k][j][i].M2 = U1d.My; pGrid->U[k][j][i].M3 = U1d.Mx; #ifdef MHD pGrid->B1i[k][j][i] = -U1d.Bz; pGrid->B2i[k][j][i] = U1d.By; pGrid->B3i[k][j][i] = Bxl; pGrid->U[k][j][i].B1c = -U1d.Bz; pGrid->U[k][j][i].B2c = U1d.By; pGrid->U[k][j][i].B3c = Bxl; #endif #ifdef ADIABATIC pGrid->U[k][j][i].E = U1d.E; #endif #if (NSCALARS > 0) pGrid->U[k][j][i].s[0] = U1d.s[0]; #endif } } } break; default: ath_error("[shkset1d]: invalid shk_dir = %i\n",shk_dir); } /* Compute Analytic solution for Sod and RJ4a tests, if required */ tlim = par_getd("time","tlim"); err_test = par_getd_def("problem","error_test",0); if (err_test == 1) { sin_a3 = sin(ang_3); cos_a3 = cos(ang_3); sin_a2 = sin(ang_2); cos_a2 = cos(ang_2); /* wave speeds for Sod test */ #ifdef HYDRO vs = 1.7522; xs = vs*tlim; vc = 0.92745; xc = vc*tlim; vf = -0.07027; xf = vf*tlim; vh = -1.1832; xh = vh*tlim; #endif /* HYDRO */ /* wave speeds for RJ2a test */ #ifdef MHD vfp = 2.2638; xfp = vfp*tlim; vrp = (0.53432 + 1.0/sqrt(PI*1.309)); xrp = vrp*tlim; vsp = (0.53432 + 0.48144/1.309); xsp = vsp*tlim; vc = 0.57538; xc = vc*tlim; vsm = (0.60588 - 0.51594/1.4903); xsm = vsm*tlim; vrm = (0.60588 - 1.0/sqrt(PI*1.4903)); xrm = vrm*tlim; vfm = (1.2 - 2.3305/1.08); xfm = vfm*tlim; #endif /* MHD */ 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); r = cos_a2*(x1*cos_a3 + x2*sin_a3) + x3*sin_a2; /* Sod solution */ #ifdef HYDRO My = Mz = 0.0; if (r > xs) { d0 = 0.125; Mx = 0.0; E0 = 0.25; r0 = 0.0; } else if (r > xc) { d0 = 0.26557; Mx = 0.92745*d0; E0 = 0.87204; r0 = 0.0; } else if (r > xf) { d0 = 0.42632; Mx = 0.92745*d0; E0 = 0.94118; r0 = 1.0; } else if (r > xh) { v0 = 0.92745*(r-xh)/(xf-xh); d0 = 0.42632*pow((1.0+0.20046*(0.92745-v0)),5); E0 = (0.30313*pow((1.0+0.20046*(0.92745-v0)),7))/0.4 + 0.5*d0*v0*v0; r0 = 1.0; Mx = v0*d0; } else { d0 = 1.0; Mx = 0.0; E0 = 2.5; r0 = 1.0; } #endif /* HYDRO */ /* RJ2a solution (Dai & Woodward 1994 Tables Ia and Ib) */ #ifdef MHD Bx = 2.0/sqrt(4.0*PI); if (r > xfp) { d0 = 1.0; Mx = 0.0; My = 0.0; Mz = 0.0; By = 4.0/sqrt(4.0*PI); Bz = 2.0/sqrt(4.0*PI); E0 = 1.0/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 0.0; } else if (r > xrp) { d0 = 1.3090; Mx = 0.53432*d0; My = -0.094572*d0; Mz = -0.047286*d0; By = 5.3452/sqrt(4.0*PI); Bz = 2.6726/sqrt(4.0*PI); E0 = 1.5844/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 0.0; } else if (r > xsp) { d0 = 1.3090; Mx = 0.53432*d0; My = -0.18411*d0; Mz = 0.17554*d0; By = 5.7083/sqrt(4.0*PI); Bz = 1.7689/sqrt(4.0*PI); E0 = 1.5844/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 0.0; } else if (r > xc) { d0 = 1.4735; Mx = 0.57538*d0; My = 0.047601*d0; Mz = 0.24734*d0; By = 5.0074/sqrt(4.0*PI); Bz = 1.5517/sqrt(4.0*PI); E0 = 1.9317/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 0.0; } else if (r > xsm) { d0 = 1.6343; Mx = 0.57538*d0; My = 0.047601*d0; Mz = 0.24734*d0; By = 5.0074/sqrt(4.0*PI); Bz = 1.5517/sqrt(4.0*PI); E0 = 1.9317/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 1.0; } else if (r > xrm) { d0 = 1.4903; Mx = 0.60588*d0; My = 0.22157*d0; Mz = 0.30125*d0; By = 5.5713/sqrt(4.0*PI); Bz = 1.7264/sqrt(4.0*PI); E0 = 1.6558/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 1.0; } else if (r > xfm) { d0 = 1.4903; Mx = 0.60588*d0; My = 0.11235*d0; Mz = 0.55686*d0; By = 5.0987/sqrt(4.0*PI); Bz = 2.8326/sqrt(4.0*PI); E0 = 1.6558/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 1.0; } else { d0 = 1.08; Mx = 1.2*d0; My = 0.01*d0; Mz = 0.5*d0; By = 3.6/sqrt(4.0*PI); Bz = 2.0/sqrt(4.0*PI); E0 = 0.95/Gamma_1 + 0.5*((Mx*Mx+My*My+Mz*Mz)/d0 + (Bx*Bx+By*By+Bz*Bz)); r0 = 1.0; } #endif /* MHD */ RootSoln[k][j][i].d = d0; RootSoln[k][j][i].M1 = Mx*cos_a2*cos_a3 - My*sin_a3 - Mz*sin_a2*cos_a3; RootSoln[k][j][i].M2 = Mx*cos_a2*sin_a3 + My*cos_a3 - Mz*sin_a2*sin_a3; RootSoln[k][j][i].M3 = Mx*sin_a2 + Mz*cos_a2; #ifdef MHD RootSoln[k][j][i].B1c = Bx*cos_a2*cos_a3 - By*sin_a3 - Bz*sin_a2*cos_a3; RootSoln[k][j][i].B2c = Bx*cos_a2*sin_a3 + By*cos_a3 - Bz*sin_a2*sin_a3; RootSoln[k][j][i].B3c = Bx*sin_a2 + Bz*cos_a2; #endif /* MHD */ #ifndef ISOTHERMAL RootSoln[k][j][i].E = E0; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) RootSoln[k][j][i].s[n] = r0*d0; #endif } }} } /* end calculation of analytic (root) solution */ return; }
void Userwork_after_loop(MeshS *pM) { GridS *pGrid; int i=0,j=0,k=0; int is,ie,js,je,ks,ke; Real rms_error=0.0; ConsS error,total_error; FILE *fp; char *fname; int Nx1, Nx2, Nx3, count, min_zones; #if defined MPI_PARALLEL double err[8+(NSCALARS)], tot_err[8+(NSCALARS)]; int ierr,myID; #endif #if (NSCALARS > 0) int n; #endif int err_test = par_getd_def("problem","error_test",0); if (err_test == 0) return; total_error.d = 0.0; total_error.M1 = 0.0; total_error.M2 = 0.0; total_error.M3 = 0.0; #ifdef MHD total_error.B1c = 0.0; total_error.B2c = 0.0; total_error.B3c = 0.0; #endif /* MHD */ #ifndef ISOTHERMAL total_error.E = 0.0; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) total_error.s[n] = 0.0; #endif /* Compute error only on root Grid, which is in Domain[0][0] */ pGrid=pM->Domain[0][0].Grid; if (pGrid == NULL) return; /* compute L1 error in each variable, and rms total error */ is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { error.d = 0.0; error.M1 = 0.0; error.M2 = 0.0; error.M3 = 0.0; #ifdef MHD error.B1c = 0.0; error.B2c = 0.0; error.B3c = 0.0; #endif /* MHD */ #ifndef ISOTHERMAL error.E = 0.0; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) error.s[n] = 0.0; #endif for (i=is; i<=ie; i++) { error.d += fabs(pGrid->U[k][j][i].d - RootSoln[k][j][i].d ); error.M1 += fabs(pGrid->U[k][j][i].M1 - RootSoln[k][j][i].M1); error.M2 += fabs(pGrid->U[k][j][i].M2 - RootSoln[k][j][i].M2); error.M3 += fabs(pGrid->U[k][j][i].M3 - RootSoln[k][j][i].M3); #ifdef MHD error.B1c += fabs(pGrid->U[k][j][i].B1c - RootSoln[k][j][i].B1c); error.B2c += fabs(pGrid->U[k][j][i].B2c - RootSoln[k][j][i].B2c); error.B3c += fabs(pGrid->U[k][j][i].B3c - RootSoln[k][j][i].B3c); #endif /* MHD */ #ifndef ISOTHERMAL error.E += fabs(pGrid->U[k][j][i].E - RootSoln[k][j][i].E ); #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) error.s[n] += fabs(pGrid->U[k][j][i].s[n] - RootSoln[k][j][i].s[n]); #endif } total_error.d += error.d; total_error.M1 += error.M1; total_error.M2 += error.M2; total_error.M3 += error.M3; #ifdef MHD total_error.B1c += error.B1c; total_error.B2c += error.B2c; total_error.B3c += error.B3c; #endif /* MHD */ #ifndef ISOTHERMAL total_error.E += error.E; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) total_error.s[n] += error.s[n]; #endif }} #ifdef MPI_PARALLEL Nx1 = pM->Domain[0][0].Nx[0]; Nx2 = pM->Domain[0][0].Nx[1]; Nx3 = pM->Domain[0][0].Nx[2]; #else Nx1 = ie - is + 1; Nx2 = je - js + 1; Nx3 = ke - ks + 1; #endif count = Nx1*Nx2*Nx3; #ifdef MPI_PARALLEL /* Now we have to use an All_Reduce to get the total error over all the MPI * grids. Begin by copying the error into the err[] array */ err[0] = total_error.d; err[1] = total_error.M1; err[2] = total_error.M2; err[3] = total_error.M3; #ifdef MHD err[4] = total_error.B1c; err[5] = total_error.B2c; err[6] = total_error.B3c; #endif /* MHD */ #ifndef ISOTHERMAL err[7] = total_error.E; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) err[8+n] = total_error.s[n]; #endif /* Sum up the Computed Error */ ierr = MPI_Reduce(err,tot_err,(8+(NSCALARS)),MPI_DOUBLE,MPI_SUM,0, pM->Domain[0][0].Comm_Domain); /* If I'm the parent, copy the sum back to the total_error variable */ ierr = MPI_Comm_rank(pM->Domain[0][0].Comm_Domain, &myID); if(myID == 0){ /* I'm the parent */ total_error.d = tot_err[0]; total_error.M1 = tot_err[1]; total_error.M2 = tot_err[2]; total_error.M3 = tot_err[3]; #ifdef MHD total_error.B1c = tot_err[4]; total_error.B2c = tot_err[5]; total_error.B3c = tot_err[6]; #endif /* MHD */ #ifndef ISOTHERMAL total_error.E = tot_err[7]; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) total_error.s[n] = tot_err.s[8+n]; #endif } else return; /* The child grids do not do any of the following code */ #endif /* MPI_PARALLEL */ /* Compute RMS error over all variables, and print out */ rms_error = SQR(total_error.d) + SQR(total_error.M1) + SQR(total_error.M2) + SQR(total_error.M3); #ifdef MHD rms_error += SQR(total_error.B1c) + SQR(total_error.B2c) + SQR(total_error.B3c); #endif /* MHD */ #ifndef ISOTHERMAL rms_error += SQR(total_error.E); #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) rms_error += SQR(total_error.s[n]); #endif rms_error = sqrt(rms_error)/(double)count; /* Print warning to stdout if rms_error exceeds estimate of 1st-order conv */ /* For 1D, assume shock propagates along direction with MAX number of zones */ min_zones = Nx1; if (Nx2 > 1) min_zones = MAX(min_zones,Nx2); if (Nx3 > 1) min_zones = MAX(min_zones,Nx3); if (rms_error > 8.0/min_zones) printf("WARNING: rms_error=%e exceeds estimate\n",rms_error); /* Print error to file "LinWave-errors.#.dat", where #=wave_flag */ #ifdef MPI_PARALLEL fname = "../shock-errors.dat"; #else fname = "shock-errors.dat"; #endif /* The file exists -- reopen the file in append mode */ if((fp=fopen(fname,"r")) != NULL){ if((fp = freopen(fname,"a",fp)) == NULL){ ath_perr(-1,"[Userwork_after_loop]: Unable to reopen file.\n"); free(fname); return; } } /* The file does not exist -- open the file in write mode */ else{ if((fp = fopen(fname,"w")) == NULL){ ath_perr(-1,"[Userwork_after_loop]: Unable to open file.\n"); free(fname); return; } /* Now write out some header information */ fprintf(fp,"# Nx1 Nx2 Nx3 RMS-Error d M1 M2 M3"); #ifndef ISOTHERMAL fprintf(fp," E"); #endif /* ISOTHERMAL */ #ifdef MHD fprintf(fp," B1c B2c B3c"); #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { fprintf(fp," S[ %d ]",n); } #endif fprintf(fp,"\n#\n"); } fprintf(fp,"%d %d %d %e",Nx1,Nx2,Nx3,rms_error); fprintf(fp," %e %e %e %e", (total_error.d/(double)count), (total_error.M1/(double)count), (total_error.M2/(double)count), (total_error.M3/(double)count) ); #ifndef ISOTHERMAL fprintf(fp," %e",(total_error.E/(double)count) ); #endif /* ISOTHERMAL */ #ifdef MHD fprintf(fp," %e %e %e", (total_error.B1c/(double)count), (total_error.B2c/(double)count), (total_error.B3c/(double)count)); #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { fprintf(fp," %e",total_error.s[n]/(double)count); } #endif fprintf(fp,"\n"); fclose(fp); return; }
void problem(DomainS *pDomain) { int i,j,k; int is,ie,il,iu,js,je,jl,ju,ks,ke,kl,ku; int nx1,nx2,nx3,myid=0; Real x1,x2,x3,y1, r; GridS *pG = pDomain->Grid; is = pG->is; ie = pG->ie; nx1 = ie-is+1; js = pG->js; je = pG->je; nx2 = je-js+1; ks = pG->ks; ke = pG->ke; nx3 = ke-ks+1; il = is-nghost*(nx1>1); iu = ie+nghost*(nx1>1); nx1 = iu-il+1; jl = js-nghost*(nx2>1); ju = je+nghost*(nx2>1); nx2 = ju-jl+1; kl = ks-nghost*(nx3>1); ku = ke+nghost*(nx3>1); nx3 = ku-kl+1; rho0 = par_getd_def("problem", "rho0", 100.0); Amp = par_getd_def("problem", "Amp", 1.0e-2); Beta = par_getd_def("problem", "Beta",100.0); R0 = par_getd_def("problem", "R0",2.0); rhomin = par_getd_def("problem","rhomin",1.0e-3); Field = par_getd_def("problem","Field",0); Hbc = par_getd_def("problem","Hbc",1); Mbc = par_getd_def("problem","Mbc",1); Mc = par_getd_def("problem","Mc",20.0); srand(SEED + myID_Comm_world); for (k=kl; k<=ku; k++) { for (j=jl; j<=ju; j++) { for (i=il; i<=iu; i++) { cc_pos(pG,i,j,k,&x1,&x2,&x3); x1 = x1vc(pG,i); r = 2.0*rand()/((double)RAND_MAX) - 1.0; pG->U[k][j][i].d = rho0; #ifdef FARGO pG->U[k][j][i].M2 = 0.0; #else pG->U[k][j][i].M2 = pG->U[k][j][i].d*avg1d(vphi,pG,i,j,k); #endif pG->U[k][j][i].M2 += pG->U[k][j][i].d*Amp*r*Iso_csound*ChiMag(x1); r = 2.0*rand()/((double)RAND_MAX)-1.0; pG->U[k][j][i].M1 = 0.0; pG->U[k][j][i].M3 = pG->U[k][j][i].d*Amp*r*Iso_csound*ChiMag(x1); #ifdef MHD pG->U[k][j][i].B1c = 0.0; if (Field == 2) { pG->U[k][j][i].B2c = BpNet(x1,x2,x3); } else { pG->U[k][j][i].B2c = 0.0; } if (Field == 0) { pG->U[k][j][i].B3c = BzZero(x1,x2,x3); } else if (Field == 1) { pG->U[k][j][i].B3c = BzNet(x1,x2,x3); } else { pG->U[k][j][i].B3c = 0.0; } pG->B1i[k][j][i] = 0.0; pG->B2i[k][j][i] = pG->U[k][j][i].B2c; pG->B3i[k][j][i] = pG->U[k][j][i].B3c; #endif } } } #ifdef MHD if (Field != 2) { ScaleToBeta(pG,Beta); } #endif /* MHD */ StaticGravPot = grav_pot; x1GravAcc = grav_acc; bvals_mhd_fun(pDomain,left_x1,disk_ir); bvals_mhd_fun(pDomain,right_x1,disk_or); #ifdef FARGO OrbitalProfile = Omega; ShearProfile = Shear; #endif // Enroll history functions // #ifdef MHD dump_history_enroll(Br, "<Br>"); dump_history_enroll(Bp, "<Bp>"); dump_history_enroll(Bz, "<Bz>"); dump_history_enroll(Mrp, "<Mrp>"); dump_history_enroll(Trp, "<Trp>"); dump_history_enroll(MdotR1, "<MdotR1>"); dump_history_enroll(MdotR2, "<MdotR2>"); dump_history_enroll(MdotR3, "<MdotR3>"); dump_history_enroll(MdotR4, "<MdotR4>"); dump_history_enroll(Msub, "<Msub>"); dump_history_enroll(Mrpsub, "<Mrpsub>"); dump_history_enroll(Bpsub, "<Bpsub>"); dump_history_enroll(Bzsub, "<Bzsub>"); dump_history_enroll(Pbsub, "<Pbsub>"); #endif return; }