Exemple #1
0
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;
}
Exemple #2
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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
      }
    }
  }
}
Exemple #5
0
/*! \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;
}
Exemple #6
0
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;
}
Exemple #7
0
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
}
Exemple #8
0
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
}
Exemple #9
0
/*! \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;
}
Exemple #10
0
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);
}
Exemple #11
0
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;
}
Exemple #12
0
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);

}
Exemple #13
0
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);
      }
    }
}
Exemple #14
0
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);
}
Exemple #15
0
/*! \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;
}
Exemple #16
0
/*! \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;
}
Exemple #17
0
/*! \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;
}
Exemple #18
0
/*! \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;
}
Exemple #19
0
/*! \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;
}
Exemple #20
0
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;
            }
        }
    }
}
Exemple #21
0
/*! \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 */
}
Exemple #22
0
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;
            }
        }
    }
}
Exemple #23
0
/*! \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;
    
}
Exemple #25
0
/* 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;
}
Exemple #26
0
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;
}
Exemple #27
0
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;
}
Exemple #28
0
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;
}
Exemple #29
0
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;
}
Exemple #30
0
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;

}