int get_position_of_index(int i, int j, int k, double * x, double * y, double * z){ if (level0_Domain.grid_block == NULL) { return -1; } if (i < (level0_Domain.ixs - nghost) || i > (level0_Domain.ixe + nghost)) { return -1; } if (j < (level0_Domain.jxs - nghost) || j > (level0_Domain.jxe + nghost)) { return -1; } if (k < (level0_Domain.kxs - nghost) || k > (level0_Domain.kxe + nghost)) { return -1; } cc_pos( &level0_Grid, i + level0_Grid.is, j + level0_Grid.js, k + level0_Grid.ks, x,y,z ); return 0; }
static Real hst_dPhi(const GridS *pG, const int i, const int j, const int k) { Real nJ,Q,cs,dPhi,Phi1; Real kx,kxt,ky,k2,k20; Real x1,x2,x3,zmax; int nwx,nwy; int ks = pG->ks, ke = pG->ke; cc_pos(pG,i,j,k,&x1,&x2,&x3); nJ = par_getd("problem","nJ"); Q = par_getd("problem","Q"); nwx = par_geti_def("problem","nwx",-6); nwy = par_geti_def("problem","nwy",1); zmax = par_getd("domain1","x3max"); kx = nwx*2*PI; ky = nwy*2*PI; kxt = kx+qshear*ky*pG->time; k2 =kxt*kxt+ky*ky; k20 =kx*kx+ky*ky; cs = sqrt(4.0-2.0*qshear)/(PI*nJ*Q); Phi1 = -4.0*PI*nJ*cs*cs/k20*(pG->U[k][j][i].d-1.0); #ifdef SELF_GRAVITY_USING_FFT_DISK Phi1 *= 1-0.5*(exp(-sqrt(k20)*(zmax-fabs(x3)))+exp(-sqrt(k20)*(zmax+fabs(x3)))); #endif dPhi = (pG->Phi[k][j][i]-Phi1)/(pG->U[k][j][i].d-1)*k2; dPhi /= 1-0.5*(exp(-sqrt(k2)*(zmax-fabs(x3)))+exp(-sqrt(k2)*(zmax+fabs(x3)))); return dPhi; }
static Real hst_m2(const GridS *pG, const int i, const int j, const int k) { Real kx,kxt,ky; Real x1,x2,x3; int nwx,nwy; Real nJ,Q,beta,cs,B0; nJ = par_getd("problem","nJ"); Q = par_getd("problem","Q"); beta = par_getd("problem","beta"); cs = sqrt(4.0-2.0*qshear)/PI/nJ/Q; B0 = cs/sqrt(beta); cc_pos(pG,i,j,k,&x1,&x2,&x3); nwx = par_geti_def("problem","nwx",-6); nwy = par_geti_def("problem","nwy",1); kx = nwx*2*PI; ky = nwy*2*PI; kxt = kx+qshear*ky*pG->time; return -(pG->U[k][j][i].B2c-B0)/kxt/B0/cos(kxt*x1+ky*x2); }
void constant_oib(GridS *pGrid) { 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; Real x1,x2,x3; Real den = 1.0, pres = 1.0e-6; for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=1; i<=nghost; i++) { cc_pos(pGrid,(ie+i),j,k,&x1,&x2,&x3); /* Initialize d, M, and P. With FARGO do not initialize the background shear */ pGrid->U[k][j][ie+i].d = den; pGrid->U[k][j][ie+i].M1 = 0.0; pGrid->U[k][j][ie+i].M2 = 0.0; #ifdef SHEARING_BOX #ifndef FARGO pGrid->U[k][j][ie+i].M2 -= den*(qshear*Omega_0*x1); #endif #endif pGrid->U[k][j][ie+i].M3 = 0.0; #ifdef ADIABATIC pGrid->U[k][j][ie+i].E = pres/Gamma_1 + 0.5*(SQR(pGrid->U[k][j][ie+i].M1) + SQR(pGrid->U[k][j][ie+i].M2) + SQR(pGrid->U[k][j][ie+i].M3))/den; #endif } } } }
/*! \fn static Real hst_E_total(const GridS *pG, const int i, const int j, * const int k) * \brief total energy (including tidal potential). */ static Real hst_E_total(const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,phi; cc_pos(pG,i,j,k,&x1,&x2,&x3); phi = UnstratifiedDisk(x1, x2, x3); return pG->U[k][j][i].E + pG->U[k][j][i].d*phi; }
static Real MdotR4(const GridS *pG, const int i, const int j, const int k) { Real dR=pG->dx1, R0=4.0, R, phi, z, Md; cc_pos(pG,i,j,k,&R,&phi,&z); if ((R0 > (R-dR)) && (R0 < (R+dR))) { Md = -1.0*pG->U[k][j][i].M1/dR; } else { Md = 0.0; } return Md; }
static Real expr_dV2(const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3; cc_pos(pG,i,j,k,&x1,&x2,&x3); #ifdef SHEARING_BOX #ifdef FARGO return (pG->U[k][j][i].M2/pG->U[k][j][i].d); #else return (pG->U[k][j][i].M2/pG->U[k][j][i].d + qshear*Omega_0*x1); #endif #endif }
static Real hst_rho_Vx_dVy(const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3; cc_pos(pG,i,j,k,&x1,&x2,&x3); #ifdef FARGO return pG->U[k][j][i].M1*pG->U[k][j][i].M2/pG->U[k][j][i].d; #else return pG->U[k][j][i].M1*(pG->U[k][j][i].M2/pG->U[k][j][i].d + qshear*Omega_0*x1); #endif }
/*! \fn static Real hst_rho_dVy2(const GridS *pG, const int i, const int j, * const int k) * \brief KE in y-velocity fluctuations */ static Real hst_rho_dVy2(const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,dVy; cc_pos(pG,i,j,k,&x1,&x2,&x3); #ifdef SHEARING_BOX #ifdef FARGO dVy = (pG->U[k][j][i].M2/pG->U[k][j][i].d); #else dVy = (pG->U[k][j][i].M2/pG->U[k][j][i].d + qshear*Omega_0*x1); #endif #endif return pG->U[k][j][i].d*dVy*dVy; }
void problem(DomainS *pDomain) { GridS *pGrid = pDomain->Grid; int i=0,j=0; int is,ie,js,je,ks; Real d0,e0,u0,v0,x1_shock,x1,x2,x3; is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; if (pGrid->Nx[0] == 1 || pGrid->Nx[1] == 1) { ath_error("[dmr]: this test only works with Nx1 & Nx2 > 1\n"); } if (pGrid->Nx[2] > 1) { ath_error("[dmr]: this test only works for 2D problems, with Nx3=1\n"); } /* Initialize shock using parameters defined in Woodward & Colella */ d0 = 8.0; e0 = 291.25; u0 = 8.25*sqrt(3.0)/2.0; v0 = -8.25*0.5; for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { cc_pos(pGrid,i,j,ks,&x1,&x2,&x3); x1_shock = 0.1666666666 + x2/sqrt((double)3.0); /* upstream conditions */ pGrid->U[ks][j][i].d = 1.4; pGrid->U[ks][j][i].E = 2.5; pGrid->U[ks][j][i].M1 = 0.0; pGrid->U[ks][j][i].M2 = 0.0; /* downstream conditions */ if (x1 < x1_shock) { pGrid->U[ks][j][i].d = d0; pGrid->U[ks][j][i].E = e0 + 0.5*d0*(u0*u0+v0*v0); pGrid->U[ks][j][i].M1 = d0*u0; pGrid->U[ks][j][i].M2 = d0*v0; } } } /* Set boundary value function pointers */ if (pDomain->Disp[0] == 0) bvals_mhd_fun(pDomain, left_x1, dmrbv_iib); if (pDomain->Disp[1] == 0) bvals_mhd_fun(pDomain, left_x2, dmrbv_ijb); if (pDomain->MaxX[1] == pDomain->RootMaxX[1]) bvals_mhd_fun(pDomain, right_x2, dmrbv_ojb); }
static Real hst_dVy(const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,dVy=0.; int ii=i-pG->Disp[0],jj=j-pG->Disp[1],kk=k-pG->Disp[2]; int ks = pG->ks, ke = pG->ke; if(ii == 58 && jj == 16 && kk == ks) { cc_pos(pG,ii,jj,kk,&x1,&x2,&x3); #ifndef FARGO dVy = (pG->U[kk][jj][ii].M2/pG->U[kk][jj][ii].d + qshear*Omega_0*x1); #else dVy = (pG->U[kk][jj][ii].M2/pG->U[kk][jj][ii].d); #endif } return dVy*dVol; }
Real avgXZ(Real (*func)(Real, Real, Real), const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3; Real fXZ(Real z); nrfunc=func; cc_pos(pG,i,j,k,&x1,&x2,&x3); xmin = x1 - 0.5*pG->dx1; xmax = x1 + 0.5*pG->dx1; zmin = x3 - 0.5*pG->dx3; zmax = x3 + 0.5*pG->dx3; ysav = x2; return qsimp(fXZ,zmin,zmax)/(pG->dx1*pG->dx3); }
void problem(Grid *pGrid) { int i, is = pGrid->is, ie = pGrid->ie; int j, js = pGrid->js, je = pGrid->je; Real pressure,prat,rad,da,pa,ua,va,wa,x1,x2,x3; Real bxa,bya,bza,b0=0.0; Real rin; double theta; rin = par_getd("problem","radius"); pa = par_getd("problem","pamb"); prat = par_getd("problem","prat"); b0 = par_getd("problem","b0"); theta = (PI/180.0)*par_getd("problem","angle"); /* setup uniform ambient medium with spherical over-pressured region */ da = 1.0; ua = 0.0; va = 0.0; wa = 0.0; bxa = b0*cos(theta); bya = b0*sin(theta); bza = 0.0; for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { pGrid->U[j][i].d = da; pGrid->U[j][i].M1 = da*ua; pGrid->U[j][i].M2 = da*va; pGrid->U[j][i].M3 = da*wa; pGrid->B1i[j][i] = bxa; pGrid->B2i[j][i] = bya; pGrid->B3i[j][i] = bza; pGrid->U[j][i].B1c = bxa; pGrid->U[j][i].B2c = bya; pGrid->U[j][i].B3c = bza; if (i == ie && ie > is) pGrid->B1i[j][i+1] = bxa; if (j == je && je > js) pGrid->B2i[j+1][i] = bya; cc_pos(pGrid,i,j,&x1,&x2); rad = sqrt(x1*x1 + x2*x2); pressure = pa; if (rad < rin) pressure = prat*pa; pGrid->U[j][i].E = pressure/Gamma_1 + 0.5*(bxa*bxa + bya*bya + bza*bza) + 0.5*da*(ua*ua + va*va + wa*wa); } } }
static Real hst_uy(const GridS *pG, const int i, const int j, const int k) { Real kx,kxt,ky; Real x1,x2,x3; int nwx,nwy; cc_pos(pG,i,j,k,&x1,&x2,&x3); nwx = par_geti_def("problem","nwx",-6); nwy = par_geti_def("problem","nwy",1); kx = nwx*2*PI; ky = nwy*2*PI; kxt = kx+qshear*ky*pG->time; return (pG->U[k][j][i].M2/pG->U[k][j][i].d-1)/sin(kxt*x1+ky*x2); }
/*! \fn Real vecpot2b3i(Real (*A1)(Real,Real,Real), Real (*A2)(Real,Real,Real), * const GridS *pG, const int i, const int j, const int k) * \brief Compute B-field components from a vector potential. * * THESE FUNCTIONS COMPUTE MAGNETIC FIELD COMPONENTS FROM COMPONENTS OF A * SPECIFIED VECTOR POTENTIAL USING STOKES' THEOREM AND SIMPSON'S QUADRATURE. * NOTE: THIS IS ONLY GUARANTEED TO WORK IF THE POTENTIAL IS OF CLASS C^1. * WRITTEN BY AARON SKINNER. */ Real vecpot2b3i(Real (*A1)(Real,Real,Real), Real (*A2)(Real,Real,Real), const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,b3i=0.0,lsf=1.0,rsf=1.0,dx2=pG->dx2; Real f1(Real x); Real f2(Real y); a1func = A1; a2func = A2; cc_pos(pG,i,j,k,&x1,&x2,&x3); xmin = x1 - 0.5*pG->dx1; xmax = x1 + 0.5*pG->dx1; ymin = x2 - 0.5*pG->dx2; ymax = x2 + 0.5*pG->dx2; zmin = x3 - 0.5*pG->dx3; zmax = x3 + 0.5*pG->dx3; zsav = zmin; #ifdef CYLINDRICAL rsf = xmax; lsf = xmin; dx2 = x1*pG->dx2; #endif if (A1 != NULL) { if (xmin == xmax) b3i += A1(xmin,ymin,zmin) - A1(xmin,ymax,zmin); else { ysav = ymin; b3i += qsimp(f1,xmin,xmax); ysav = ymax; b3i -= qsimp(f1,xmin,xmax); } } if (A2 != NULL) { if (ymin == ymax) b3i += rsf*A2(xmax,ymin,zmin) - lsf*A2(xmin,ymin,zmin); else { xsav = xmax; b3i += rsf*qsimp(f2,ymin,ymax); xsav = xmin; b3i -= lsf*qsimp(f2,ymin,ymax); } } if (pG->dx1 > 0.0) b3i /= pG->dx1; if (pG->dx2 > 0.0) b3i /= dx2; return b3i; }
/*! \fn Real vecpot2b1i(Real (*A2)(Real,Real,Real), Real (*A3)(Real,Real,Real), * const GridS *pG, const int i, const int j, const int k) * \brief Compute B-field components from a vector potential. * * THESE FUNCTIONS COMPUTE MAGNETIC FIELD COMPONENTS FROM COMPONENTS OF A * SPECIFIED VECTOR POTENTIAL USING STOKES' THEOREM AND SIMPSON'S QUADRATURE. * NOTE: THIS IS ONLY GUARANTEED TO WORK IF THE POTENTIAL IS OF CLASS C^1. * WRITTEN BY AARON SKINNER. */ Real vecpot2b1i(Real (*A2)(Real,Real,Real), Real (*A3)(Real,Real,Real), const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,b1i=0.0,lsf=1.0,rsf=1.0,dx2=pG->dx2; Real f2(Real y); Real f3(Real z); a2func = A2; a3func = A3; cc_pos(pG,i,j,k,&x1,&x2,&x3); xmin = x1 - 0.5*pG->dx1; xmax = x1 + 0.5*pG->dx1; ymin = x2 - 0.5*pG->dx2; ymax = x2 + 0.5*pG->dx2; zmin = x3 - 0.5*pG->dx3; zmax = x3 + 0.5*pG->dx3; xsav = xmin; #ifdef CYLINDRICAL lsf = xmin; rsf = xmin; dx2 = xmin*pG->dx2; #endif if (A2 != NULL) { if (ymin == ymax) b1i += rsf*A2(xmin,ymin,zmin) - lsf*A2(xmin,ymin,zmax); else { zsav = zmin; b1i += rsf*qsimp(f2,ymin,ymax); zsav = zmax; b1i -= lsf*qsimp(f2,ymin,ymax); } } if (A3 != NULL) { if (zmin == zmax) b1i += A3(xmin,ymax,zmin) - A3(xmin,ymin,zmin); else { ysav = ymax; b1i += qsimp(f3,zmin,zmax); ysav = ymin; b1i -= qsimp(f3,zmin,zmax); } } if (pG->dx2 > 0.0) b1i /= dx2; if (pG->dx3 > 0.0) b1i /= pG->dx3; return b1i; }
/*! \fn Real avg1d(Real (*func)(Real, Real, Real), const GridS *pG, * const int i, const int j, const int k) * \brief RETURNS THE INTEGRAL OF A USER-SUPPLIED FUNCTION func OVER THE ONE- * DIMENSIONAL GRID CELL (i,j,k). * * INTEGRATION IS PERFORMED USING qsimp. * ADAPTED FROM NUMERICAL RECIPES BY AARON SKINNER */ Real avg1d(Real (*func)(Real, Real, Real), const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,dvol=pG->dx1; Real fx(Real x); nrfunc=func; cc_pos(pG,i,j,k,&x1,&x2,&x3); xmin = x1 - 0.5*pG->dx1; xmax = x1 + 0.5*pG->dx1; ysav = x2; zsav = x3; #ifdef CYLINDRICAL dvol *= x1; #endif return qsimp(fx,xmin,xmax)/dvol; }
/*! \fn Real avg3d(Real (*func)(Real, Real, Real), const GridS *pG, * const int i, const int j, const int k) * \brief RETURNS THE INTEGRAL OF A USER-SUPPLIED FUNCTION func OVER THE * THREE-DIMENSIONAL GRID CELL (i,j,k). * * INTEGRATION IS PERFORMED USING qsimp. * ADAPTED FROM NUMERICAL RECIPES BY AARON SKINNER */ Real avg3d(Real (*func)(Real, Real, Real), const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,dvol=pG->dx1*pG->dx2*pG->dx3; Real fz(Real z); nrfunc=func; cc_pos(pG,i,j,k,&x1,&x2,&x3); xmin = x1 - 0.5*pG->dx1; xmax = x1 + 0.5*pG->dx1; ymin = x2 - 0.5*pG->dx2; ymax = x2 + 0.5*pG->dx2; zmin = x3 - 0.5*pG->dx3; zmax = x3 + 0.5*pG->dx3; #ifdef CYLINDRICAL dvol *= x1; #endif return qsimp(fz,zmin,zmax)/dvol; }
/*! \fn Real vecpot2b2i(Real (*A1)(Real,Real,Real), Real (*A3)(Real,Real,Real), * const GridS *pG, const int i, const int j, const int k) * \brief Compute B-field components from a vector potential. * * THESE FUNCTIONS COMPUTE MAGNETIC FIELD COMPONENTS FROM COMPONENTS OF A * SPECIFIED VECTOR POTENTIAL USING STOKES' THEOREM AND SIMPSON'S QUADRATURE. * NOTE: THIS IS ONLY GUARANTEED TO WORK IF THE POTENTIAL IS OF CLASS C^1. * WRITTEN BY AARON SKINNER. */ Real vecpot2b2i(Real (*A1)(Real,Real,Real), Real (*A3)(Real,Real,Real), const GridS *pG, const int i, const int j, const int k) { Real x1,x2,x3,b2i=0.0; Real f1(Real x); Real f3(Real z); a1func = A1; a3func = A3; cc_pos(pG,i,j,k,&x1,&x2,&x3); xmin = x1 - 0.5*pG->dx1; xmax = x1 + 0.5*pG->dx1; ymin = x2 - 0.5*pG->dx2; ymax = x2 + 0.5*pG->dx2; zmin = x3 - 0.5*pG->dx3; zmax = x3 + 0.5*pG->dx3; ysav = ymin; if (A1 != NULL) { if (xmin == xmax) b2i += A1(xmin,ymin,zmax) - A1(xmin,ymin,zmin); else { zsav = zmax; b2i += qsimp(f1,xmin,xmax); zsav = zmin; b2i -= qsimp(f1,xmin,xmax); } } if (A3 != NULL) { if (zmin == zmax) b2i += A3(xmin,ymin,zmin) - A3(xmax,ymin,zmin); else { xsav = xmin; b2i += qsimp(f3,zmin,zmax); xsav = xmax; b2i -= qsimp(f3,zmin,zmax); } } if (pG->dx1 > 0.0) b2i /= pG->dx1; if (pG->dx3 > 0.0) b2i /= pG->dx3; return b2i; }
void dmrbv_ojb(GridS *pGrid) { int i=0,j=0; int is,ie,js,je,ks,il,iu; Real d0,e0,u0,v0,x1_shock,x1,x2,x3; d0 = 8.0; e0 = 291.25; u0 = 8.25*sqrt(3.0)/2.0; v0 = -8.25*0.5; x1_shock = 0.1666666666 + (1.0 + 20.0*pGrid->time)/sqrt(3.0); is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; iu = pGrid->ie + nghost; il = pGrid->is - nghost; for (j=1; j<=nghost; j++) { for (i=il; i<=iu; i++) { cc_pos(pGrid,i,j,ks,&x1,&x2,&x3); if (x1 < x1_shock) { /* fixed at downstream state */ pGrid->U[ks][je+j][i].d = d0; pGrid->U[ks][je+j][i].M1 = d0*u0; pGrid->U[ks][je+j][i].M2 = d0*v0; pGrid->U[ks][je+j][i].E = e0 + 0.5*d0*(u0*u0+v0*v0); } else { /* fixed at upstream state */ pGrid->U[ks][je+j][i].d = 1.4; pGrid->U[ks][je+j][i].M1 = 0.0; pGrid->U[ks][je+j][i].M2 = 0.0; pGrid->U[ks][je+j][i].E = 2.5; } } } }
/*! \fn Real compute_div_b(GridS *pG) * \brief COMPUTE THE DIVERGENCE OF THE MAGNETIC FIELD USING FACE-CENTERED * FIELDS OVER THE ENTIRE ACTIVE GRID. RETURNS THE MAXIMUM OF |DIV B|. */ Real compute_div_b(GridS *pG) { #ifdef MHD int i,j,k,is,ie,js,je,ks,ke; Real x1,x2,x3,divB,maxdivB=0.0; Real lsf=1.0,rsf=1.0,dx2=pG->dx2; is = pG->is; ie = pG->ie; js = pG->js; je = pG->je; ks = pG->ks; ke = pG->ke; 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); #ifdef CYLINDRICAL rsf = (x1+0.5*pG->dx1)/x1; lsf = (x1-0.5*pG->dx1)/x1; dx2 = x1*pG->dx2; #endif divB = (rsf*pG->B1i[k][j][i+1] - lsf*pG->B1i[k][j][i])/pG->dx1; if (je > js) divB += (pG->B2i[k][j+1][i] - pG->B2i[k][j][i])/dx2; if (ke > ks) divB += (pG->B3i[k+1][j][i] - pG->B3i[k][j][i])/pG->dx3; maxdivB = MAX(maxdivB,fabs(divB)); } } } return maxdivB; #else fprintf(stderr,"[compute_div_b]: This only works for MHD!\n"); exit(EXIT_FAILURE); return 0.0; #endif /* MHD */ }
void dmrbv_ijb(GridS *pGrid) { int i=0,j=0; int is,ie,js,je,ks,il,iu; Real d0,e0,u0,v0,x1,x2,x3; d0 = 8.0; e0 = 291.25; u0 = 8.25*sqrt(3.0)/2.0; v0 = -8.25*0.5; is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; iu = pGrid->ie + nghost; il = pGrid->is - nghost; for (j=1; j<=nghost; j++) { for (i=il; i<=iu; i++) { cc_pos(pGrid,i,j,ks,&x1,&x2,&x3); if (x1 < 0.1666666666) { /* fixed at downstream state */ pGrid->U[ks][js-j][i].d = d0; pGrid->U[ks][js-j][i].M1 = d0*u0; pGrid->U[ks][js-j][i].M2 = d0*v0; pGrid->U[ks][js-j][i].E = e0 + 0.5*d0*(u0*u0+v0*v0); } else { /* reflected */ pGrid->U[ks][js-j][i].d = pGrid->U[ks][js+(j-1)][i].d; pGrid->U[ks][js-j][i].M1 = pGrid->U[ks][js+(j-1)][i].M1; pGrid->U[ks][js-j][i].M2 = -pGrid->U[ks][js+(j-1)][i].M2; pGrid->U[ks][js-j][i].E = pGrid->U[ks][js+(j-1)][i].E; } } } }
/*! \fn static void flux_output_func(MeshS *pM, OutputS *pOut) * \brief New output format which outputs y-integrated angular momentum fluxes * Currently can only be used with 1 proc and 1 domain. */ static void flux_output_func(MeshS *pM, OutputS *pOut) { GridS *pG=pM->Domain[0][0].Grid; int nx1,nx2,nx3, ind, i,j,k, ind_i,ind_k; Real lx1, lx2, lx3; PrimS W[7],Ws[7],We[7]; Real x1[7],x2[7],x3[7],xs1[7],xs2[7],xs3[7],xe1[7],xe2[7],xe3[7]; Real dmin, dmax; Real **Fluxx=NULL; Real **FluxH=NULL; Real **FluxNu=NULL; Real **Th=NULL; Real **outCoordsx1=NULL; Real **outCoordsx3=NULL; Real **vx=NULL; Real **vy=NULL; Real **sigvx=NULL; Real **osigx=NULL; Real **davg=NULL; FILE *pfile; char *fname; nx1 = pG->Nx[0]; nx3 = pG->Nx[2]; nx2 = pG->Nx[1]; lx1 = pG->MaxX[0] - pG->MinX[0]; lx2 = pG->MaxX[1] - pG->MinX[1]; lx3 = pG->MaxX[2] - pG->MinX[2]; printf("%d, %d, %d, %g, %g, %g\n",nx1,nx2,nx3,lx1,lx2,lx3); #ifdef MPI_PARALLEL printf("%d, %d, %d, %g, %g, %g \n", myID_Comm_world,nx1,nx3,lx1,lx2,lx3); printf("IND %d: (%d,%d), (%d,%d)\n",myID_Comm_world,pG->is,pG->js,pG->ie,pG->je); #endif Fluxx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (Fluxx == NULL) return; FluxH=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (FluxH == NULL) return; FluxNu=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (FluxNu == NULL) return; Th=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (Th == NULL) return; outCoordsx1=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (outCoordsx1 == NULL) return; outCoordsx3=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (outCoordsx3 == NULL) return; vx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (vx == NULL) return; vy=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (vy == NULL) return; sigvx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (sigvx == NULL) return; osigx=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (osigx == NULL) return; davg=(Real **)calloc_2d_array(nx3,nx1,sizeof(Real)); if (davg == NULL) return; /* Open file and write header */ if((fname = ath_fname(NULL,pM->outfilename,NULL,NULL,num_digit, pOut->num,pOut->id,"tab")) == NULL){ ath_error("[dump_tab]: Error constructing filename\n"); } if((pfile = fopen(fname,"w")) == NULL){ ath_error("[dump_tab]: Unable to open ppm file %s\n",fname); } free(fname); #ifdef MPI_PARALLEL if(myID_Comm_world == 0) #endif fprintf(pfile,"#t=%12.8e x,FH,Fx,Fnu,Th,vx,vy,davg,sigvx,omsigx \n", pOut->t); /* Compute y-integrated fluxes explicitly. * For the derivatives use a central difference method. * For the integration use a composite trapezoid method. * Both of these make use of the ghost cells for the boundary values. * 1 FluxH = < d * vx1 *vx2 > * 2 Fluxx = < 0.5 * omega * d * x1 * vx1 > * 3 FluxNu = - < nu_iso * d/dx vx2 > * 4 Th = - < d * d/dy phi > * 5 vx = < vx1 > * 6 vy = < vx2 > * 7 davg = < d > * 8 sigvx = < d * vx1 > * 9 osigx = < 0.5 * sig * omega * x1 > * * * x 4 x * 1 0 2 * x 3 x * * The variables are stored up as arrays of primitives W[7]. * W = ( W[k][j][i], W[k][j][i-1], W[k][j][i+1], W[k][j-1][i], * W[k][j+1][i], W[k-1][j][i], W[k+1][j][i] ) * This is needed for the integration and differentiation. * * The background shear is taken out of vy when doing computations. */ for(k=pG->ks; k <=pG->ke; k++) { for(i=pG->is; i<= pG->ie; i++) { ind_i=i-pG->is; ind_k=k-pG->ks; for(ind=0; ind < 7; ind++) { if (ind==0) { cc_pos(pG,i,pG->js,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js][i])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je][i])); } if (ind > 0 && ind < 3) { cc_pos(pG,i+2*ind-3,pG->js,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i+2*ind-3,pG->je,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js][i+2*ind-3])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je][i+2*ind-3])); } if (ind > 2 && ind < 5) { cc_pos(pG,i,pG->js+2*ind-7,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je+2*ind-7,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js+2*ind-7][i])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je+2*ind-7][i])); } if (ind > 4 && ind < 7) { if (pG->MinX[2] == pG->MaxX[2]) { cc_pos(pG,i,pG->js,k,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je,k,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k][pG->js][i])); We[ind] = Cons_to_Prim(&(pG->U[k][pG->je][i])); } else { cc_pos(pG,i,pG->js,k+2*ind-11,&xs1[ind],&xs2[ind],&xs3[ind]); cc_pos(pG,i,pG->je,k+2*ind-11,&xe1[ind],&xe2[ind],&xe3[ind]); Ws[ind] = Cons_to_Prim(&(pG->U[k+2*ind-11][pG->js][i])); We[ind] = Cons_to_Prim(&(pG->U[k+2*ind-11][pG->je][i])); } } Ws[ind].V2 = Ws[ind].V2 + qshear*Omega_0*xs1[ind]; We[ind].V2 = We[ind].V2 + qshear*Omega_0*xe1[ind]; /* If using d' instead of d then put in * W[ind] = W[ind]->d - d0; */ } /* Set initial values for the integration */ FluxH[ind_k][ind_i] = 0.5*( Ws[0].d * Ws[0].V1 * Ws[0].V2 + We[0].d * We[0].V1 * We[0].V2 ); Fluxx[ind_k][ind_i] = 0.5*( Ws[0].d * Ws[0].V1 * xs1[0] + We[0].d * We[0].V1 * xe1[0] ); #ifdef VISCOSITY FluxNu[ind_k][ind_i] = 0.5*( Ws[2].V2 - Ws[1].V2 + We[2].V2 - We[1].V2 ); #else FluxNu[ind_k][ind_i] = 0; #endif Th[ind_k][ind_i] = 0.5*( Ws[0].d * dx2PlanetPot(xs1[0],xs2[0],xs3[0]) + We[0].d * dx2PlanetPot(xe1[0],xe2[0],xe3[0]) ); vx[ind_k][ind_i] = 0.5*( Ws[0].V1 + We[0].V1 ); vy[ind_k][ind_i] = 0.5*( Ws[0].V2 + We[0].V2 ); sigvx[ind_k][ind_i] = 0.5*( Ws[0].d * Ws[0].V1 + We[0].d * We[0].V1 ); osigx[ind_k][ind_i] = 0.5*( Ws[0].d * xs1[0] + We[0].d * xe1[0] ); davg[ind_k][ind_i] = 0.5*(Ws[0].d + We[0].d); for(j=(pG->js)+1; j < pG->je; j++) { for(ind=0; ind < 7; ind++) { if (ind==0) { cc_pos(pG,i,j,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j][i])); } if (ind > 0 && ind < 3) { cc_pos(pG,i+2*ind-3,j,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j][i+2*ind-3])); } if (ind > 2 && ind < 5) { cc_pos(pG,i,j+2*ind-7,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j+2*ind-7][i])); } if (ind > 4 && ind < 7) { if (pG->MinX[2] == pG->MaxX[2]) { cc_pos(pG,i,j,k,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k][j][i])); } else { cc_pos(pG,i,j,k+2*ind-11,&x1[ind],&x2[ind],&x3[ind]); W[ind] = Cons_to_Prim(&(pG->U[k+2*ind-11][j][i])); } } W[ind].V2 = W[ind].V2 + qshear*Omega_0*x1[ind]; } FluxH[ind_k][ind_i] += W[0].d * W[0].V1 * W[0].V2; Fluxx[ind_k][ind_i] += W[0].d * W[0].V1 * x1[0]; #ifdef VISCOSITY FluxNu[ind_k][ind_i] += W[0].d * (W[2].V2 - W[1].V1); #endif Th[ind_k][ind_i] += W[0].d * dx2PlanetPot(x1[0],x2[0],x3[0]); vx[ind_k][ind_i] += W[0].V1; vy[ind_k][ind_i] += W[0].V2; sigvx[ind_k][ind_i] += W[0].d * W[0].V1; osigx[ind_k][ind_i] += W[0].d * x1[0]; davg[ind_k][ind_i] += W[0].d; } FluxH[ind_k][ind_i] *= (pG->dx2)/lx2; Fluxx[ind_k][ind_i] *= .5*Omega_0*(pG->dx2)/lx2; #ifdef VISCOSITY FluxNu[ind_k][ind_i] *= -nu_iso*(pG->dx2)/(2*lx2*(pG->dx1)); #endif Th[ind_k][ind_i] *= -1.0*(pG->dx2)/lx2; vx[ind_k][ind_i] *= (pG->dx2)/lx2; vy[ind_k][ind_i] *= (pG->dx2)/lx2; sigvx[ind_k][ind_i] *= (pG->dx2)/lx2; osigx[ind_k][ind_i] *= (0.5*Omega_0*(pG->dx2))/lx2; davg[ind_k][ind_i] *= (pG->dx2)/lx2; outCoordsx1[ind_k][ind_i]=x1[0]; outCoordsx3[ind_k][ind_i]=x3[0]; } } /* Quantities are ready to be written to output file * Format (Not outputting x3 at the moment: * x1 (x3) FluxH Fluxx Fluxnu Th vx vy davg sigvx osigx */ for(k=pG->ks; k<=pG->ke; k++) { for(i=pG->is; i<=pG->ie; i++) { ind_k=k-pG->ks; ind_i=i-pG->is; if (lx3==0) { fprintf(pfile,"%12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e\n", outCoordsx1[ind_k][ind_i],FluxH[ind_k][ind_i], Fluxx[ind_k][ind_i],FluxNu[ind_k][ind_i],Th[ind_k][ind_i], vx[ind_k][ind_i],vy[ind_k][ind_i],davg[ind_k][ind_i],sigvx[ind_k][ind_i], osigx[ind_k][ind_i]); } else { fprintf(pfile,"%12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e %12.8e\n", outCoordsx1[ind_k][ind_i],outCoordsx3[ind_k][ind_i],FluxH[ind_k][ind_i], Fluxx[ind_k][ind_i],FluxNu[ind_k][ind_i],Th[ind_k][ind_i], vx[ind_k][ind_i],vy[ind_k][ind_i],davg[ind_k][ind_i],sigvx[ind_k][ind_i], osigx[ind_k][ind_i]); } } } fclose(pfile); free_2d_array(Fluxx); free_2d_array(FluxH); free_2d_array(FluxNu); free_2d_array(Th); free_2d_array(outCoordsx1); free_2d_array(outCoordsx3); free_2d_array(vx); free_2d_array(vy); free_2d_array(sigvx); free_2d_array(osigx); free_2d_array(davg); return; }
void problem(DomainS *pDomain) { GridS *pGrid=(pDomain->Grid); int i, is = pGrid->is, ie = pGrid->ie; int j, js = pGrid->js, je = pGrid->je; int k, ks = pGrid->ks, ke = pGrid->ke; Real x1,x2,x3; Real rho, p, prat, density, pressure, pi, vel, n, amp, lx, ly; dt_line_integral_output = par_getd("problem", "dt_line_integral"); /* size of the domain (in physical coordinates) */ lx = pDomain->RootMaxX[0] - pDomain->RootMinX[0]; ly = pDomain->RootMaxX[1] - pDomain->RootMinX[1]; p = 1.0; /* if prat=0.8, vx = -1.8965 (t&e find other vals)*/ pi=3.14159; n = 2; /*Oscillations of perturbation*/ amp = 0.05 ; /* Size of perturbation ~ 0.05 */ /* setup uniform ambient medium with spherical over-pressured region */ 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); if (x1 > amp*sin(n*pi*x2/ly)) { pressure = 0.1175; } else { pressure = 1; } if (x1 > amp*sin(n*pi*x2/ly)) { vel= -1.96071; } else { vel= -0.7; } if (x1 > amp*sin(n*pi*x2/ly)) { density= 0.357013; } else { density= 1; } pGrid->U[0][j][i].d = density; pGrid->U[0][j][i].M1 = density*vel; pGrid->U[0][j][i].M2 = 0.0; #ifndef ISOTHERMAL pGrid->U[0][j][i].E = pressure/Gamma_1 + (SQR(pGrid->U[0][j][i].M1) + SQR(pGrid->U[0][j][i].M2))/(2.0*(pGrid->U[0][j][i].d)); #endif } } } /* Adding history dumps*/ void dump_history_enroll(const ConsFun_t pfun, const char *label); dump_history_enroll(pleft, "<pbvals>"); dump_history_enroll(vyintegral, "<vyintegral>"); /* enroll special functions */ bvals_mhd_fun(pDomain,left_x1, bc_ix1); return; }
/* problem: */ void problem(DomainS *pDomain) { GridS *pG = pDomain->Grid; int i,j,k,n,converged; int is,ie,il,iu,js,je,jl,ju,ks,ke,kl,ku; int nx1, nx2, nx3; Real x1, x2, x3; Real a,b,c,d,xmin,xmax,ymin,ymax; Real x,y,xslow,yslow,xfast,yfast; Real R0,R1,R2,rho,Mdot,K,Omega,Pgas,beta,vR,BR,vphi,Bphi; ConsS *Wind=NULL; Real *pU=NULL,*pUl=NULL,*pUr=NULL; Real lsf,rsf; 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; #ifndef CYLINDRICAL ath_error("[cylwindrotb]: This problem only works in cylindrical!\n"); #endif #ifndef MHD ath_error("[cylwindrotb]: This problem only works in MHD!\n"); #endif if (nx1==1) { ath_error("[cylwindrotb]: Only R can be used in 1D!\n"); } else if (nx2==1 && nx3>1) { ath_error("[cylwindrotb]: Only (R,phi) can be used in 2D!\n"); } /* Allocate memory for wind solution */ if ((Wind = (ConsS*)calloc_1d_array(nx1+1,sizeof(ConsS))) == NULL) ath_error("[cylwindrotb]: Error allocating memory\n"); /* Allocate memory for grid solution */ if ((RootSoln = (ConsS***)calloc_3d_array(nx3,nx2,nx1,sizeof(ConsS))) == NULL) ath_error("[cylwindrotb]: Error allocating memory\n"); theta = par_getd("problem","theta"); omega = par_getd("problem","omega"); vz = par_getd("problem","vz"); /* This numerical solution was obtained from MATLAB. * Ideally, we replace this with a nonlinear solver... */ xslow = 0.5243264128; yslow = 2.4985859152; xfast = 1.6383327831; yfast = 0.5373957134; E = 7.8744739104; eta = 2.3608500383; xmin = par_getd("domain1","x1min")/R_A; xmax = par_getd("domain1","x1max")/R_A; ymin = 0.45/rho_A; ymax = 2.6/rho_A; printf("theta = %f,\t omega = %f,\t eta = %f,\t E = %f\n", theta,omega,eta,E); printf("xslow = %f,\t yslow = %f,\t xfast = %f,\t yfast = %f\n", xslow,yslow,xfast,yfast); printf("xmin = %f,\t ymin = %f,\t xmax = %f,\t ymax = %f\n", xmin,ymin,xmax,ymax); /* Calculate the 1D wind solution at cell-interfaces */ for (i=il; i<=iu+1; i++) { memset(&(Wind[i]),0.0,sizeof(ConsS)); cc_pos(pG,i,js,ks,&x1,&x2,&x3); /* Want the solution at R-interfaces */ R0 = x1 - 0.5*pG->dx1; x = R0/R_A; /* Look for a sign change interval */ if (x < xslow) { sign_change(myfunc,yslow,10.0*ymax,x,&a,&b); sign_change(myfunc,b,10.0*ymax,x,&a,&b); } else if (x < 1.0) { sign_change(myfunc,1.0+TINY_NUMBER,yslow,x,&a,&b); } else if (x < xfast) { sign_change(myfunc,yfast,1.0-TINY_NUMBER,x,&a,&b); if (!sign_change(myfunc,b,1.0-TINY_NUMBER,x,&a,&b)) { a = yfast; b = 1.0-TINY_NUMBER; } } else { sign_change(myfunc,0.5*ymin,yfast,x,&a,&b); } /* Use bisection to find the root */ converged = bisection(myfunc,a,b,x,&y); if(!converged) { ath_error("[cylwindrotb]: Bisection did not converge!\n"); } /* Construct the solution */ rho = rho_A*y; Mdot = sqrt(R_A*SQR(rho_A)*GM*eta); Omega = sqrt((GM*omega)/pow(R_A,3)); K = (GM*theta)/(Gamma*pow(rho_A,Gamma_1)*R_A); Pgas = K*pow(rho,Gamma); vR = Mdot/(R0*rho); beta = sqrt(1.0/rho_A); BR = beta*rho*vR; vphi = R0*Omega*(1.0/SQR(x)-y)/(1.0-y); Bphi = beta*rho*(vphi-R0*Omega); Wind[i].d = rho; Wind[i].M1 = rho*vR; Wind[i].M2 = rho*vphi; Wind[i].M3 = rho*vz; Wind[i].B1c = BR; Wind[i].B2c = Bphi; Wind[i].B3c = 0.0; Wind[i].E = Pgas/Gamma_1 + 0.5*(SQR(Wind[i].B1c) + SQR(Wind[i].B2c) + SQR(Wind[i].B3c)) + 0.5*(SQR(Wind[i].M1 ) + SQR(Wind[i].M2 ) + SQR(Wind[i].M3 ))/Wind[i].d; } /* Average the wind solution across the zone for cc variables */ for (i=il; i<=iu; i++) { memset(&(pG->U[ks][js][i]),0.0,sizeof(ConsS)); cc_pos(pG,i,js,ks,&x1,&x2,&x3); lsf = (x1 - 0.5*pG->dx1)/x1; rsf = (x1 + 0.5*pG->dx1)/x1; pU = (Real*)&(pG->U[ks][js][i]); pUl = (Real*)&(Wind[i]); pUr = (Real*)&(Wind[i+1]); for (n=0; n<NWAVE; n++) { pU[n] = 0.5*(lsf*pUl[n] + rsf*pUr[n]); } pG->B1i[ks][js][i] = Wind[i].B1c; pG->B2i[ks][js][i] = 0.5*(lsf*Wind[i].B2c + rsf*Wind[i+1].B2c); pG->B3i[ks][js][i] = 0.5*(lsf*Wind[i].B3c + rsf*Wind[i+1].B3c); } /* Copy 1D solution across the grid and save */ for (k=kl; k<=ku; k++) { for (j=jl; j<=ju; j++) { for (i=il; i<=iu; i++) { pG->U[k][j][i] = pG->U[ks][js][i]; pG->B1i[k][j][i] = pG->B1i[ks][js][i]; pG->B2i[k][j][i] = pG->B2i[ks][js][i]; pG->B3i[k][j][i] = pG->B3i[ks][js][i]; RootSoln[k][j][i] = pG->U[ks][js][i]; } } } StaticGravPot = grav_pot; bvals_mhd_fun(pDomain,left_x1,do_nothing_bc); bvals_mhd_fun(pDomain,right_x1,do_nothing_bc); free_1d_array((void *)Wind); 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(DomainS *pDomain) { GridS *pGrid=(pDomain->Grid); int i,il,iu,j,jl,ju,k,kl,ku; int shk_dir; /* Shock direction: {1,2,3} -> {x1,x2,x3} */ Real x1,x2,x3; Prim1DS Wl, Wr; Cons1DS U1d, Ul, Ur; Real Bxl=0.0, Bxr=0.0; /* 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","r[0]l"); #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","r[0]r"); #endif Ul = Prim1D_to_Cons1D(&Wl, &Bxl); Ur = Prim1D_to_Cons1D(&Wr, &Bxr); /* 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; } /* 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 */ 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 */ 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.Mz; pGrid->U[k][j][i].M2 = U1d.Mx; pGrid->U[k][j][i].M3 = U1d.My; #ifdef MHD pGrid->B1i[k][j][i] = U1d.Bz; pGrid->B2i[k][j][i] = Bxl; pGrid->B3i[k][j][i] = U1d.By; pGrid->U[k][j][i].B1c = U1d.Bz; pGrid->U[k][j][i].B2c = Bxl; pGrid->U[k][j][i].B3c = U1d.By; #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 */ 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.My; pGrid->U[k][j][i].M2 = U1d.Mz; pGrid->U[k][j][i].M3 = U1d.Mx; #ifdef MHD pGrid->B1i[k][j][i] = U1d.By; pGrid->B2i[k][j][i] = U1d.Bz; pGrid->B3i[k][j][i] = Bxl; pGrid->U[k][j][i].B1c = U1d.By; pGrid->U[k][j][i].B2c = U1d.Bz; 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); } 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,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_in_loop(MeshS *pM) { DomainS *pDomain = (DomainS*)&(pM->Domain[0][0]); GridS *pGrid = pM->Domain[0][0].Grid; int i, is=pGrid->is, ie = pGrid->ie; int j, js=pGrid->js, je = pGrid->je; int k, ks=pGrid->ks, ke = pGrid->ke; Real newtime; Real qt,tdep,s_period,AA; Real delta_x, delta_z, xxmax, yymax, xxmin, yymin; Real exp_x,exp_y,exp_z,exp_xyz; Real r1,r2,xp, yp,zp; Real vvz; Real x1,x2,x3; Real xcz,xcx; int n1,n2; n1=0; n2=0; s_period=30.0; //Driver period AA=350.0; //Driver amplitude //AA=1; xcz=0.5e6; xcx=2.0e6; delta_z=0.004e6; delta_x=0.016e6; if (isnan(pGrid->dt)) ath_error("Time step is NaN!"); qt=pGrid->time; tdep=sin(qt*2.0*PI/s_period); if (pM->Nx[2] == 1) { cc_pos(pGrid,ie,je,ke,&x1,&x2,&x3); xxmax=x1; yymax=x3; cc_pos(pGrid,is,js,ks,&x1,&x2,&x3); xxmax=xxmax-x1; yymax=yymax-x3; xxmin=x1; yymin=x3; } /*printf("%d %d %d \n",is,js,ks); printf("%d %d %d \n",ie,je,ke); printf("%d %d %d \n", pGrid->Nx[0],pGrid->Nx[1], pGrid->Nx[2]);*/ 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); xp=x1-xxmin; yp=x3-yymin; zp=x2; r2=(zp-xcz)*(zp-xcz); r1=(xp-xcx)*(xp-xcx); exp_y=exp(-r1/(delta_x*delta_x)); exp_z=exp(-r2/(delta_z*delta_z)); exp_xyz=sin(PI*xp*(n1+1)/xxmax)*exp_z; //exp_xyz=exp_y*exp_z; vvz=100*AA*exp_xyz*tdep; vvz=0; //if(j==12) // printf("%d %d %d %f %f %f %f %f %f\n",i,j,k,xp,yp,zp,xcz,exp_y,exp_z); //if(i>60 && i<68) //if(i>is && i<ie) //{ //if(j==12) // printf("%d %d %d %g %g %g \n",i,j,k,vvz,(pGrid->dt),(pGrid->dt)*vvz*(pGrid->U[k][j][i].d)); pGrid->U[k][j][i].M2 += (pGrid->dt)*vvz*(pGrid->U[k][j][i].d); pGrid->U[k][j][i].E += (pGrid->dt)*vvz*vvz*(pGrid->U[k][j][i].d)/2.0; //} } //printf("\n"); } } } //for 3D model if (pM->Nx[2] > 1) { cc_pos(pGrid,ie,je,ke,&x1,&x2,&x3); xxmax=x1; yymax=x2; cc_pos(pGrid,is,js,ks,&x1,&x2,&x3); xxmax=xxmax-x1; yymax=yymax-x2; xxmin=x1; yymin=x2; } 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); xp=x1-xxmin; yp=x2-yymin; zp=x3; r2=(x3-xcz)*(x3-xcz); exp_z=exp(-r2/(delta_z*delta_z)); exp_xyz=sin(PI*xp*(n1+1)/xxmax)*sin(PI*yp*(n2+1)/yymax)*exp_z; vvz=AA*exp_xyz*tdep; vvz=0; pGrid->U[k][j][i].M3 += (pGrid->dt)*vvz*(pGrid->U[k][j][i].d); pGrid->U[k][j][i].E += (pGrid->dt)*vvz*vvz*(pGrid->U[k][j][i].d)/2.0; } } } } //newtime = pGrid->time + pGrid->dt; return; }