void HLLE_FUNCTION(const Cons1DS Ul, const Cons1DS Ur, const Prim1DS Wl, const Prim1DS Wr, const Real Bxi, Cons1DS *pFlux) { Real sqrtdl,sqrtdr,isdlpdr,droe,v1roe,v2roe,v3roe,pbl=0.0,pbr=0.0; Real asq,vaxsq=0.0,qsq,cfsq,cfl,cfr,bp,bm,ct2=0.0,tmp; #ifndef ISOTHERMAL Real hroe; #endif #ifdef MHD Real b2roe,b3roe,x,y; #endif Real ev[NWAVE],al,ar; Real *pFl, *pFr, *pF; Cons1DS Fl,Fr; int n; /*--- Step 1. ------------------------------------------------------------------ * Convert left- and right- states in conserved to primitive variables. */ /* pbl = Cons1D_to_Prim1D(&Ul,&Wl,&Bxi); pbr = Cons1D_to_Prim1D(&Ur,&Wr,&Bxi); */ /*--- Step 2. ------------------------------------------------------------------ * Compute Roe-averaged data from left- and right-states */ sqrtdl = sqrt((double)Wl.d); sqrtdr = sqrt((double)Wr.d); isdlpdr = 1.0/(sqrtdl + sqrtdr); droe = sqrtdl*sqrtdr; v1roe = (sqrtdl*Wl.Vx + sqrtdr*Wr.Vx)*isdlpdr; v2roe = (sqrtdl*Wl.Vy + sqrtdr*Wr.Vy)*isdlpdr; v3roe = (sqrtdl*Wl.Vz + sqrtdr*Wr.Vz)*isdlpdr; /* The Roe average of the magnetic field is defined differently. */ #ifdef MHD b2roe = (sqrtdr*Wl.By + sqrtdl*Wr.By)*isdlpdr; b3roe = (sqrtdr*Wl.Bz + sqrtdl*Wr.Bz)*isdlpdr; x = 0.5*(SQR(Wl.By - Wr.By) + SQR(Wl.Bz - Wr.Bz))/(SQR(sqrtdl + sqrtdr)); y = 0.5*(Wl.d + Wr.d)/droe; pbl = 0.5*(SQR(Bxi) + SQR(Wl.By) + SQR(Wl.Bz)); pbr = 0.5*(SQR(Bxi) + SQR(Wr.By) + SQR(Wr.Bz)); #endif /* * Following Roe(1981), the enthalpy H=(E+P)/d is averaged for adiabatic flows, * rather than E or P directly. sqrtdl*hl = sqrtdl*(el+pl)/dl = (el+pl)/sqrtdl */ #ifndef ISOTHERMAL hroe = ((Ul.E + Wl.P + pbl)/sqrtdl + (Ur.E + Wr.P + pbr)/sqrtdr)*isdlpdr; #endif /*--- Step 3. ------------------------------------------------------------------ * Compute eigenvalues using Roe-averaged values, needed in step 4. */ #ifdef HYDRO #ifdef ISOTHERMAL esys_roe_iso_hyd(v1roe, v2roe, v3roe, ev, NULL, NULL); #else esys_roe_adb_hyd(v1roe, v2roe, v3roe, hroe, ev, NULL, NULL); #endif /* ISOTHERMAL */ #endif /* HYDRO */ #ifdef MHD #ifdef ISOTHERMAL esys_roe_iso_mhd(droe,v1roe,v2roe,v3roe, Bxi,b2roe,b3roe,x,y,ev,NULL,NULL); #else esys_roe_adb_mhd(droe,v1roe,v2roe,v3roe,hroe,Bxi,b2roe,b3roe,x,y,ev,NULL,NULL); #endif /* ISOTHERMAL */ #endif /* MHD */ /*--- Step 4. ------------------------------------------------------------------ * Compute the max and min wave speeds */ /* left state */ #ifdef ISOTHERMAL asq = Iso_csound2; #else asq = Gamma*Wl.P/Wl.d; #endif #ifdef MHD vaxsq = Bxi*Bxi/Wl.d; ct2 = (Ul.By*Ul.By + Ul.Bz*Ul.Bz)/Wl.d; #endif qsq = vaxsq + ct2 + asq; tmp = vaxsq + ct2 - asq; cfsq = 0.5*(qsq + sqrt((double)(tmp*tmp + 4.0*asq*ct2))); cfl = sqrt((double)cfsq); /* right state */ #ifdef ISOTHERMAL asq = Iso_csound2; #else asq = Gamma*Wr.P/Wr.d; #endif #ifdef MHD vaxsq = Bxi*Bxi/Wr.d; ct2 = (Ur.By*Ur.By + Ur.Bz*Ur.Bz)/Wr.d; #endif qsq = vaxsq + ct2 + asq; tmp = vaxsq + ct2 - asq; cfsq = 0.5*(qsq + sqrt((double)(tmp*tmp + 4.0*asq*ct2))); cfr = sqrt((double)cfsq); /* take max/min of Roe eigenvalues and L/R state wave speeds */ ar = MAX(ev[NWAVE-1],(Wr.Vx + cfr)); al = MIN(ev[0] ,(Wl.Vx - cfl)); bp = MAX(ar, 0.0); bm = MIN(al, 0.0); /*--- Step 5. ------------------------------------------------------------------ * Compute L/R fluxes along the lines bm/bp: F_{L}-S_{L}U_{L}; F_{R}-S_{R}U_{R} */ Fl.d = Ul.Mx - bm*Ul.d; Fr.d = Ur.Mx - bp*Ur.d; Fl.Mx = Ul.Mx*(Wl.Vx - bm); Fr.Mx = Ur.Mx*(Wr.Vx - bp); Fl.My = Ul.My*(Wl.Vx - bm); Fr.My = Ur.My*(Wr.Vx - bp); Fl.Mz = Ul.Mz*(Wl.Vx - bm); Fr.Mz = Ur.Mz*(Wr.Vx - bp); #ifdef ISOTHERMAL Fl.Mx += Wl.d*Iso_csound2; Fr.Mx += Wr.d*Iso_csound2; #else Fl.Mx += Wl.P; Fr.Mx += Wr.P; Fl.E = Ul.E*(Wl.Vx - bm) + Wl.P*Wl.Vx; Fr.E = Ur.E*(Wr.Vx - bp) + Wr.P*Wr.Vx; #endif /* ISOTHERMAL */ #ifdef MHD Fl.Mx -= 0.5*(Bxi*Bxi - SQR(Wl.By) - SQR(Wl.Bz)); Fr.Mx -= 0.5*(Bxi*Bxi - SQR(Wr.By) - SQR(Wr.Bz)); Fl.My -= Bxi*Wl.By; Fr.My -= Bxi*Wr.By; Fl.Mz -= Bxi*Wl.Bz; Fr.Mz -= Bxi*Wr.Bz; #ifndef ISOTHERMAL Fl.E += (pbl*Wl.Vx - Bxi*(Bxi*Wl.Vx + Wl.By*Wl.Vy + Wl.Bz*Wl.Vz)); Fr.E += (pbr*Wr.Vx - Bxi*(Bxi*Wr.Vx + Wr.By*Wr.Vy + Wr.Bz*Wr.Vz)); #endif /* ISOTHERMAL */ Fl.By = Wl.By*(Wl.Vx - bm) - Bxi*Wl.Vy; Fr.By = Wr.By*(Wr.Vx - bp) - Bxi*Wr.Vy; Fl.Bz = Wl.Bz*(Wl.Vx - bm) - Bxi*Wl.Vz; Fr.Bz = Wr.Bz*(Wr.Vx - bp) - Bxi*Wr.Vz; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { Fl.s[n] = Fl.d*Wl.r[n]; Fr.s[n] = Fr.d*Wr.r[n]; } #endif #ifdef CYLINDRICAL #ifndef ISOTHERMAL Fl.Pflux = Wl.P; Fr.Pflux = Wr.P; #ifdef MHD Fl.Pflux += pbl; Fr.Pflux += pbr; #endif /* MHD */ #endif /* ISOTHERMAL */ #endif /* CYLINDRICAL */ /*--- Step 6. ------------------------------------------------------------------ * Compute the HLLE flux at interface. */ pFl = (Real *)&(Fl); pFr = (Real *)&(Fr); pF = (Real *)pFlux; tmp = 0.5*(bp + bm)/(bp - bm); for (n=0; n<(NWAVE+NSCALARS); n++){ pF[n] = 0.5*(pFl[n] + pFr[n]) + (pFl[n] - pFr[n])*tmp; } #ifdef CYLINDRICAL n = NWAVE+NSCALARS; pF[n] = 0.5*(pFl[n] + pFr[n]) + (pFl[n] - pFr[n])*tmp; #endif return; }
void _fill_grid_linearwave_1d(Grid *pGrid, Domain *pDomain, int wave_flag, double amp, double vflow, int wave_dir){ int i=0,j=0,k=0; int is,ie,js,je,ks,ke,n,m,nx1,nx2,nx3; Real d0,p0,u0,v0,w0,h0; Real x1,x2,x3,r,ev[NWAVE],rem[NWAVE][NWAVE],lem[NWAVE][NWAVE]; Real x1max,x2max,lambda; #ifdef MHD Real bx0,by0,bz0,xfact,yfact; #endif /* MHD */ is = pGrid->is; ie = pGrid->ie; js = pGrid->js; je = pGrid->je; ks = pGrid->ks; ke = pGrid->ke; nx1 = (ie-is)+1 + 2*nghost; nx2 = (je-js)+1 + 2*nghost; nx3 = (ke-ks)+1 + 2*nghost; if ((Soln = (Gas***)calloc_3d_array(nx3,nx2,nx1,sizeof(Gas))) == NULL) ath_error("[linear_wave1d]: Error allocating memory\n"); /* Get eigenmatrix, where the quantities u0 and bx0 are parallel to the * wavevector, and v0,w0,by0,bz0 are perpendicular. Background state chosen * carefully so wave speeds are well-separated: Va=1, Vf=2, Vs=0.5 */ d0 = 1.0; #ifndef ISOTHERMAL p0 = 1.0/Gamma; u0 = vflow*sqrt(Gamma*p0/d0); #else u0 = vflow*Iso_csound; #endif v0 = 0.0; w0 = 0.0; #ifdef MHD bx0 = 1.0; by0 = sqrt(2.0); bz0 = 0.5; xfact = 0.0; yfact = 1.0; #endif for (n=0; n<NWAVE; n++) { for (m=0; m<NWAVE; m++) { rem[n][m] = 0.0; lem[n][m] = 0.0; } } #ifdef HYDRO #ifdef ISOTHERMAL esys_roe_iso_hyd(u0,v0,w0, ev,rem,lem); #else h0 = ((p0/Gamma_1 + 0.5*d0*(u0*u0+v0*v0+w0*w0)) + p0)/d0; esys_roe_adb_hyd(u0,v0,w0,h0,ev,rem,lem); ath_pout(0,"Ux - Cs = %e, %e\n",ev[0],rem[0][wave_flag]); ath_pout(0,"Ux = %e, %e\n",ev[1],rem[1][wave_flag]); ath_pout(0,"Ux + Cs = %e, %e\n",ev[4],rem[4][wave_flag]); #endif /* ISOTHERMAL */ #endif /* HYDRO */ #ifdef MHD #if defined(ISOTHERMAL) esys_roe_iso_mhd(d0,u0,v0,w0,bx0,by0,bz0,xfact,yfact,ev,rem,lem); ath_pout(0,"Ux - Cf = %e, %e\n",ev[0],rem[0][wave_flag]); ath_pout(0,"Ux - Ca = %e, %e\n",ev[1],rem[1][wave_flag]); ath_pout(0,"Ux - Cs = %e, %e\n",ev[2],rem[2][wave_flag]); ath_pout(0,"Ux + Cs = %e, %e\n",ev[3],rem[3][wave_flag]); ath_pout(0,"Ux + Ca = %e, %e\n",ev[4],rem[4][wave_flag]); ath_pout(0,"Ux + Cf = %e, %e\n",ev[5],rem[5][wave_flag]); #else h0 = ((p0/Gamma_1+0.5*(bx0*bx0+by0*by0+bz0*bz0)+0.5*d0*(u0*u0+v0*v0+w0*w0)) + (p0+0.5*(bx0*bx0+by0*by0+bz0*bz0)))/d0; esys_roe_adb_mhd(d0,u0,v0,w0,h0,bx0,by0,bz0,xfact,yfact,ev,rem,lem); ath_pout(0,"Ux - Cf = %e, %e\n",ev[0],rem[0][wave_flag]); ath_pout(0,"Ux - Ca = %e, %e\n",ev[1],rem[1][wave_flag]); ath_pout(0,"Ux - Cs = %e, %e\n",ev[2],rem[2][wave_flag]); ath_pout(0,"Ux = %e, %e\n",ev[3],rem[3][wave_flag]); ath_pout(0,"Ux + Cs = %e, %e\n",ev[4],rem[4][wave_flag]); ath_pout(0,"Ux + Ca = %e, %e\n",ev[5],rem[5][wave_flag]); ath_pout(0,"Ux + Cf = %e, %e\n",ev[6],rem[6][wave_flag]); #endif /* ISOTHERMAL */ #endif /* MHD */ /* Now initialize 1D solution vector */ for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { /* Set background state */ cc_pos(pGrid,i,j,k,&x1,&x2,&x3); Soln[k][j][i].d = d0; #ifndef ISOTHERMAL Soln[k][j][i].E = p0/Gamma_1 + 0.5*d0*u0*u0; #ifdef MHD Soln[k][j][i].E += 0.5*(bx0*bx0 + by0*by0 + bz0*bz0); #endif /* MHD */ #endif /* ISOTHERMAL */ /* Select appropriate solution based on direction of wavevector */ switch(wave_dir){ /* wave in x1-direction */ case 1: Soln[k][j][i].d += amp*sin(2.0*PI*x1)*rem[0][wave_flag]; #ifndef ISOTHERMAL Soln[k][j][i].E += amp*sin(2.0*PI*x1)*rem[4][wave_flag]; #endif /* ISOTHERMAL */ Soln[k][j][i].M1 = d0*vflow; Soln[k][j][i].M2 = 0.0; Soln[k][j][i].M3 = 0.0; Soln[k][j][i].M1 += amp*sin(2.0*PI*x1)*rem[1][wave_flag]; Soln[k][j][i].M2 += amp*sin(2.0*PI*x1)*rem[2][wave_flag]; Soln[k][j][i].M3 += amp*sin(2.0*PI*x1)*rem[3][wave_flag]; #ifdef MHD Soln[k][j][i].B1c = bx0; Soln[k][j][i].B2c = by0 + amp*sin(2.0*PI*x1)*rem[NWAVE-2][wave_flag]; Soln[k][j][i].B3c = bz0 + amp*sin(2.0*PI*x1)*rem[NWAVE-1][wave_flag]; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) Soln[k][j][i].s[n] = amp*(1.0 + sin(2.0*PI*x1)); #endif break; /* Wave in x2-direction */ case 2: Soln[k][j][i].d += amp*sin(2.0*PI*x2)*rem[0][wave_flag]; #ifndef ISOTHERMAL Soln[k][j][i].E += amp*sin(2.0*PI*x2)*rem[4][wave_flag]; #endif /* ISOTHERMAL */ Soln[k][j][i].M1 = 0.0; Soln[k][j][i].M2 = d0*vflow; Soln[k][j][i].M3 = 0.0; Soln[k][j][i].M1 += amp*sin(2.0*PI*x2)*rem[3][wave_flag]; Soln[k][j][i].M2 += amp*sin(2.0*PI*x2)*rem[1][wave_flag]; Soln[k][j][i].M3 += amp*sin(2.0*PI*x2)*rem[2][wave_flag]; #ifdef MHD Soln[k][j][i].B1c = bz0 + amp*sin(2.0*PI*x2)*rem[NWAVE-1][wave_flag]; Soln[k][j][i].B2c = bx0; Soln[k][j][i].B3c = by0 + amp*sin(2.0*PI*x2)*rem[NWAVE-2][wave_flag]; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) Soln[k][j][i].s[n] = amp*(1.0 + sin(2.0*PI*x2)); #endif break; /* Wave in x3-direction */ case 3: Soln[k][j][i].d += amp*sin(2.0*PI*x3)*rem[0][wave_flag]; #ifndef ISOTHERMAL Soln[k][j][i].E += amp*sin(2.0*PI*x3)*rem[4][wave_flag]; #endif /* ISOTHERMAL */ Soln[k][j][i].M1 = 0.0; Soln[k][j][i].M2 = 0.0; Soln[k][j][i].M3 = d0*vflow; Soln[k][j][i].M1 += amp*sin(2.0*PI*x3)*rem[2][wave_flag]; Soln[k][j][i].M2 += amp*sin(2.0*PI*x3)*rem[3][wave_flag]; Soln[k][j][i].M3 += amp*sin(2.0*PI*x3)*rem[1][wave_flag]; #ifdef MHD Soln[k][j][i].B1c = by0 + amp*sin(2.0*PI*x3)*rem[NWAVE-2][wave_flag]; Soln[k][j][i].B2c = bz0 + amp*sin(2.0*PI*x3)*rem[NWAVE-1][wave_flag]; Soln[k][j][i].B3c = bx0; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) Soln[k][j][i].s[n] = amp*(1.0 + sin(2.0*PI*x3)); #endif break; default: ath_error("[linear_wave1d]: wave direction %d not allowed\n",wave_dir); } }}} /* Now set initial conditions to wave solution */ for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { pGrid->U[k][j][i].d = Soln[k][j][i].d; #ifndef ISOTHERMAL pGrid->U[k][j][i].E = Soln[k][j][i].E; #endif /* ISOTHERMAL */ pGrid->U[k][j][i].M1 = Soln[k][j][i].M1; pGrid->U[k][j][i].M2 = Soln[k][j][i].M2; pGrid->U[k][j][i].M3 = Soln[k][j][i].M3; #ifdef MHD pGrid->U[k][j][i].B1c = Soln[k][j][i].B1c; pGrid->U[k][j][i].B2c = Soln[k][j][i].B2c; pGrid->U[k][j][i].B3c = Soln[k][j][i].B3c; pGrid->B1i[k][j][i] = Soln[k][j][i].B1c; pGrid->B2i[k][j][i] = Soln[k][j][i].B2c; pGrid->B3i[k][j][i] = Soln[k][j][i].B3c; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) pGrid->U[k][j][i].s[n] = Soln[k][j][i].s[n]; #endif }}} #ifdef MHD if (pGrid->Nx1 > 1) { for (k=ks; k<=ke; k++) { for (j=js; j<=je; j++) { pGrid->B1i[k][j][ie+1] = pGrid->B1i[k][j][ie]; } } } if (pGrid->Nx2 > 1) { for (k=ks; k<=ke; k++) { for (i=is; i<=ie; i++) { pGrid->B2i[k][je+1][i] = pGrid->B2i[k][je][i]; } } } if (pGrid->Nx3 > 1) { for (j=js; j<=je; j++) { for (i=is; i<=ie; i++) { pGrid->B3i[ke+1][j][i] = pGrid->B3i[ke][j][i]; } } } #endif /* MHD */ /* For self-gravitating problems, read 4\piG and compute mean density */ #ifdef SELF_GRAVITY four_pi_G = par_getd("problem","four_pi_G"); grav_mean_rho = d0; #endif /* SELF_GRAVITY */ return; }
void fluxes(const Cons1DS Ul, const Cons1DS Ur, const Prim1DS Wl, const Prim1DS Wr, const Real Bxi, Cons1DS *pFlux) { Real sqrtdl,sqrtdr,isdlpdr,droe,v1roe,v2roe,v3roe,pbl=0.0,pbr=0.0; Real asq,vaxsq=0.0,qsq,cfsq,cfl,cfr,bp,bm,ct2=0.0,tmp; #ifndef ISOTHERMAL Real hroe; #endif #ifdef MHD Real b2roe,b3roe,x,y; #endif Real ev[NWAVE],al,ar; Real *pFl, *pFc, *pFr, *pUc, *pF; Prim1DS Wc; Cons1DS Fl, Fc, Fr, Uc; int n; /* The first 5 steps are identical to those in hlle fluxes */ /*--- Step 1. ------------------------------------------------------------------ * Convert left- and right- states in conserved to primitive variables. */ /* pbl = Cons1D_to_Prim1D(&Ul,&Wl,&Bxi); pbr = Cons1D_to_Prim1D(&Ur,&Wr,&Bxi); */ /*--- Step 2. ------------------------------------------------------------------ * Compute Roe-averaged data from left- and right-states */ sqrtdl = sqrt((double)Wl.d); sqrtdr = sqrt((double)Wr.d); isdlpdr = 1.0/(sqrtdl + sqrtdr); droe = sqrtdl*sqrtdr; v1roe = (sqrtdl*Wl.Vx + sqrtdr*Wr.Vx)*isdlpdr; v2roe = (sqrtdl*Wl.Vy + sqrtdr*Wr.Vy)*isdlpdr; v3roe = (sqrtdl*Wl.Vz + sqrtdr*Wr.Vz)*isdlpdr; /* * The Roe average of the magnetic field is defined differently. */ #ifdef MHD b2roe = (sqrtdr*Wl.By + sqrtdl*Wr.By)*isdlpdr; b3roe = (sqrtdr*Wl.Bz + sqrtdl*Wr.Bz)*isdlpdr; x = 0.5*(SQR(Wl.By - Wr.By) + SQR(Wl.Bz - Wr.Bz))/(SQR(sqrtdl + sqrtdr)); y = 0.5*(Wl.d + Wr.d)/droe; pbl = 0.5*(SQR(Bxi) + SQR(Wl.By) + SQR(Wl.Bz)); pbr = 0.5*(SQR(Bxi) + SQR(Wr.By) + SQR(Wr.Bz)); #endif /* * Following Roe(1981), the enthalpy H=(E+P)/d is averaged for adiabatic flows, * rather than E or P directly. sqrtdl*hl = sqrtdl*(el+pl)/dl = (el+pl)/sqrtdl */ #ifndef ISOTHERMAL hroe = ((Ul.E + Wl.P + pbl)/sqrtdl + (Ur.E + Wr.P + pbr)/sqrtdr)*isdlpdr; #endif /*--- Step 3. ------------------------------------------------------------------ * Compute eigenvalues using Roe-averaged values */ #ifdef HYDRO #ifdef ISOTHERMAL esys_roe_iso_hyd(v1roe, v2roe, v3roe, ev, NULL, NULL); #else esys_roe_adb_hyd(v1roe, v2roe, v3roe, hroe, ev, NULL, NULL); #endif /* ISOTHERMAL */ #endif /* HYDRO */ #ifdef MHD #ifdef ISOTHERMAL esys_roe_iso_mhd(droe,v1roe,v2roe,v3roe, Bxi,b2roe,b3roe,x,y,ev,NULL,NULL); #else esys_roe_adb_mhd(droe,v1roe,v2roe,v3roe,hroe,Bxi,b2roe,b3roe,x,y,ev,NULL,NULL); #endif /* ISOTHERMAL */ #endif /* MHD */ /*--- Step 4. ------------------------------------------------------------------ * Compute the max and min wave speeds */ /* left state */ #ifdef ISOTHERMAL asq = Iso_csound2; #else asq = Gamma*Wl.P/Wl.d; #endif #ifdef MHD vaxsq = Bxi*Bxi/Wl.d; ct2 = (Ul.By*Ul.By + Ul.Bz*Ul.Bz)/Wl.d; #endif qsq = vaxsq + ct2 + asq; tmp = vaxsq + ct2 - asq; cfsq = 0.5*(qsq + sqrt((double)(tmp*tmp + 4.0*asq*ct2))); cfl = sqrt((double)cfsq); /* right state */ #ifdef ISOTHERMAL asq = Iso_csound2; #else asq = Gamma*Wr.P/Wr.d; #endif #ifdef MHD vaxsq = Bxi*Bxi/Wr.d; ct2 = (Ur.By*Ur.By + Ur.Bz*Ur.Bz)/Wr.d; #endif qsq = vaxsq + ct2 + asq; tmp = vaxsq + ct2 - asq; cfsq = 0.5*(qsq + sqrt((double)(tmp*tmp + 4.0*asq*ct2))); cfr = sqrt((double)cfsq); /* take max/min of Roe eigenvalues and L/R state wave speeds */ ar = MAX(ev[NWAVE-1],(Wr.Vx + cfr)); al = MIN(ev[0] ,(Wl.Vx - cfl)); bp = MAX(ar, 0.0); bm = MIN(al, 0.0); /*--- Step 5. ------------------------------------------------------------------ * Compute L/R fluxes along the line bm, bp */ Fl.d = Ul.Mx - bm*Ul.d; Fr.d = Ur.Mx - bp*Ur.d; Fl.Mx = Ul.Mx*(Wl.Vx - bm); Fr.Mx = Ur.Mx*(Wr.Vx - bp); Fl.My = Ul.My*(Wl.Vx - bm); Fr.My = Ur.My*(Wr.Vx - bp); Fl.Mz = Ul.Mz*(Wl.Vx - bm); Fr.Mz = Ur.Mz*(Wr.Vx - bp); #ifdef ISOTHERMAL Fl.Mx += Wl.d*Iso_csound2; Fr.Mx += Wr.d*Iso_csound2; #else Fl.Mx += Wl.P; Fr.Mx += Wr.P; Fl.E = Ul.E*(Wl.Vx - bm) + Wl.P*Wl.Vx; Fr.E = Ur.E*(Wr.Vx - bp) + Wr.P*Wr.Vx; #endif /* ISOTHERMAL */ #ifdef MHD Fl.Mx -= 0.5*(Bxi*Bxi - SQR(Wl.By) - SQR(Wl.Bz)); Fr.Mx -= 0.5*(Bxi*Bxi - SQR(Wr.By) - SQR(Wr.Bz)); Fl.My -= Bxi*Wl.By; Fr.My -= Bxi*Wr.By; Fl.Mz -= Bxi*Wl.Bz; Fr.Mz -= Bxi*Wr.Bz; #ifndef ISOTHERMAL Fl.E += (pbl*Wl.Vx - Bxi*(Bxi*Wl.Vx + Wl.By*Wl.Vy + Wl.Bz*Wl.Vz)); Fr.E += (pbr*Wr.Vx - Bxi*(Bxi*Wr.Vx + Wr.By*Wr.Vy + Wr.Bz*Wr.Vz)); #endif /* ISOTHERMAL */ Fl.By = Wl.By*(Wl.Vx - bm) - Bxi*Wl.Vy; Fr.By = Wr.By*(Wr.Vx - bp) - Bxi*Wr.Vy; Fl.Bz = Wl.Bz*(Wl.Vx - bm) - Bxi*Wl.Vz; Fr.Bz = Wr.Bz*(Wr.Vx - bp) - Bxi*Wr.Vz; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { Fl.s[n] = Fl.d*Wl.x[n]; Fr.s[n] = Fr.d*Wr.x[n]; } #endif /*--- Step 6. ------------------------------------------------------------------ * For supersonic flow, return the upwind flux. */ if(al >= 0.0){ *pFlux = Fl; return; } if(ar <= 0.0){ *pFlux = Fr; return; } /*--- Step 7. ------------------------------------------------------------------ * Compute the LW flux, start with the HLL mean state */ pFl = (Real *)&(Fl); pFr = (Real *)&(Fr); pUc = (Real *)&(Uc); tmp = 1.0/(ar - al); for (n=0; n<(NWAVE+NSCALARS); n++){ pUc[n] = (pFl[n] - pFr[n])*tmp; } /* Convert the HLL mean state to primitive variables */ Cons1D_to_Prim1D(&Uc,&Wc,&Bxi); /* Compute the LW flux along the line dx/dt = 0 */ Fc.d = Uc.Mx; Fc.Mx = Uc.Mx*Wc.Vx; Fc.My = Uc.My*Wc.Vx; Fc.Mz = Uc.Mz*Wc.Vx; #ifdef ISOTHERMAL Fc.Mx += Wc.d*Iso_csound2; #else Fc.Mx += Wc.P; Fc.E = Uc.E*Wc.Vx + Wc.P*Wc.Vx; #endif /* ISOTHERMAL */ #ifdef MHD Fc.Mx -= 0.5*(Bxi*Bxi - SQR(Wc.By) - SQR(Wc.Bz)); Fc.My -= Bxi*Wc.By; Fc.Mz -= Bxi*Wc.Bz; #ifndef ISOTHERMAL Fc.E += (pbl*Wc.Vx - Bxi*(Bxi*Wc.Vx + Wc.By*Wc.Vy + Wc.Bz*Wc.Vz)); #endif /* ISOTHERMAL */ Fc.By = Wc.By*Wc.Vx - Bxi*Wc.Vy; Fc.Bz = Wc.Bz*Wc.Vx - Bxi*Wc.Vz; #endif /* MHD */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { Fc.s[n] = Fc.d*Wc.x[n]; } #endif /*--- Step 8. ------------------------------------------------------------------ * Compute the average of the Lax-Wendroff & HLLE flux */ pFl = (Real *)&(Fl); pFc = (Real *)&(Fc); pFr = (Real *)&(Fr); pF = (Real *)pFlux; tmp = 0.25*(bp + bm)/(bp - bm); for (n=0; n<(NWAVE+NSCALARS); n++){ pF[n] = 0.5*pFc[n] + 0.25*(pFl[n] + pFr[n]) + (pFl[n] - pFr[n])*tmp; } return; }
void fluxes(const Cons1DS Ul, const Cons1DS Ur, const Prim1DS Wl, const Prim1DS Wr, const Real Bxi, Cons1DS *pFlux) { Real sqrtdl,sqrtdr,isdlpdr,droe,v1roe,v2roe,v3roe; #ifndef BAROTROPIC Real hroe; #endif Real ev[NWAVE]; Real *pFl, *pFr, *pF; Cons1DS Fl,Fr; int n; Real cfl,cfr,bp,bm,tmp; Real al,ar; /* Min and Max wave speeds */ Real am,cp; /* Contact wave speed and pressure */ Real tl,tr,dl,dr,sl,sm,sr; /*--- Step 1. ------------------------------------------------------------------ * Convert left- and right- states in conserved to primitive variables. */ /* pbl = Cons1D_to_Prim1D(&Ul,&Wl,&Bxi); pbr = Cons1D_to_Prim1D(&Ur,&Wr,&Bxi); */ /*--- Step 2. ------------------------------------------------------------------ * Compute Roe-averaged data from left- and right-states */ sqrtdl = sqrt((double)Wl.d); sqrtdr = sqrt((double)Wr.d); isdlpdr = 1.0/(sqrtdl + sqrtdr); droe = sqrtdl*sqrtdr; v1roe = (sqrtdl*Wl.Vx + sqrtdr*Wr.Vx)*isdlpdr; v2roe = (sqrtdl*Wl.Vy + sqrtdr*Wr.Vy)*isdlpdr; v3roe = (sqrtdl*Wl.Vz + sqrtdr*Wr.Vz)*isdlpdr; /* * Following Roe(1981), the enthalpy H=(E+P)/d is averaged for adiabatic flows, * rather than E or P directly. sqrtdl*hl = sqrtdl*(el+pl)/dl = (el+pl)/sqrtdl */ #ifndef ISOTHERMAL hroe = ((Ul.E + Wl.P)/sqrtdl + (Ur.E + Wr.P)/sqrtdr)*isdlpdr; #endif /*--- Step 3. ------------------------------------------------------------------ * Compute eigenvalues using Roe-averaged values */ #ifdef ISOTHERMAL esys_roe_iso_hyd(v1roe, v2roe, v3roe, ev, NULL, NULL); #else esys_roe_adb_hyd(v1roe, v2roe, v3roe, hroe, ev, NULL, NULL); #endif /* ISOTHERMAL */ /*--- Step 4. ------------------------------------------------------------------ * Compute the max and min wave speeds */ #ifdef ISOTHERMAL cfl = cfr = Iso_csound; #else cfl = sqrt((double)(Gamma*Wl.P/Wl.d)); cfr = sqrt((double)(Gamma*Wr.P/Wr.d)); #endif ar = MAX(ev[NWAVE-1],(Wr.Vx + cfr)); al = MIN(ev[0] ,(Wl.Vx - cfl)); bp = ar > 0.0 ? ar : 0.0; bm = al < 0.0 ? al : 0.0; /*--- Step 5. ------------------------------------------------------------------ * Compute the contact wave speed and Pressure */ #ifdef ISOTHERMAL tl = Wl.d*Iso_csound2 + (Wl.Vx - al)*Ul.Mx; tr = Wr.d*Iso_csound2 + (Wr.Vx - ar)*Ur.Mx; #else tl = Wl.P + (Wl.Vx - al)*Ul.Mx; tr = Wr.P + (Wr.Vx - ar)*Ur.Mx; #endif dl = Ul.Mx - Ul.d*al; dr = -(Ur.Mx - Ur.d*ar); tmp = 1.0/(dl + dr); /* Determine the contact wave speed... */ am = (tl - tr)*tmp; /* ...and the pressure at the contact surface */ cp = (dl*tr + dr*tl)*tmp; if(cp < 0.0) ath_perr(1,"[hllc flux]: Contact Pressure = %g\n",cp); cp = cp > 0.0 ? cp : 0.0; /*--- Step 6. ------------------------------------------------------------------ * Compute L/R fluxes along the line bm, bp */ Fl.d = Ul.Mx - bm*Ul.d; Fr.d = Ur.Mx - bp*Ur.d; Fl.Mx = Ul.Mx*(Wl.Vx - bm); Fr.Mx = Ur.Mx*(Wr.Vx - bp); Fl.My = Ul.My*(Wl.Vx - bm); Fr.My = Ur.My*(Wr.Vx - bp); Fl.Mz = Ul.Mz*(Wl.Vx - bm); Fr.Mz = Ur.Mz*(Wr.Vx - bp); #ifdef ISOTHERMAL Fl.Mx += Wl.d*Iso_csound2; Fr.Mx += Wr.d*Iso_csound2; #else Fl.Mx += Wl.P; Fr.Mx += Wr.P; Fl.E = Ul.E*(Wl.Vx - bm) + Wl.P*Wl.Vx; Fr.E = Ur.E*(Wr.Vx - bp) + Wr.P*Wr.Vx; #endif /* ISOTHERMAL */ #if (NSCALARS > 0) for (n=0; n<NSCALARS; n++) { Fl.s[n] = Fl.d*Wl.r[n]; Fr.s[n] = Fr.d*Wr.r[n]; } #endif /*--- Step 7. ------------------------------------------------------------------ * Compute flux weights or scales */ if (am >= 0.0) { sl = am/(am - bm); sr = 0.0; sm = -bm/(am - bm); } else { sl = 0.0; sr = -am/(bp - am); sm = bp/(bp - am); } /*--- Step 8. ------------------------------------------------------------------ * Compute the HLLC flux at interface */ pFl = (Real *)&(Fl); pFr = (Real *)&(Fr); pF = (Real *)pFlux; for (n=0; n<NWAVE; n++) pF[n] = sl*pFl[n] + sr*pFr[n]; /* Add the weighted contribution of the flux along the contact */ pFlux->Mx += sm*cp; #ifndef ISOTHERMAL pFlux->E += sm*cp*am; #endif /* ISOTHERMAL */ /* Fluxes of passively advected scalars, computed from density flux */ #if (NSCALARS > 0) if (pFlux->d >= 0.0) { for (n=0; n<NSCALARS; n++) pFlux->s[n] = pFlux->d*Wl.r[n]; } else { for (n=0; n<NSCALARS; n++) pFlux->s[n] = pFlux->d*Wr.r[n]; } #endif #ifdef CYLINDRICAL if (al > 0.0) { #ifndef ISOTHERMAL pFlux->Pflux = Wl.P; #else /* ISOTHERMAL */ pFlux->Pflux = Wl.d*Iso_csound2; #endif /* ISOTHERMAL */ } else if (ar < 0.0) { #ifndef ISOTHERMAL pFlux->Pflux = Wr.P; #else /* ISOTHERMAL */ pFlux->Pflux = Wr.d*Iso_csound2; #endif /* ISOTHERMAL */ } else { #ifndef ISOTHERMAL pFlux->Pflux = cp; #else /* ISOTHERMAL */ if (am >= 0.0) { pFlux->Pflux = Wl.d*(al-Wl.Vx)/(al-am); } else { pFlux->Pflux = Wr.d*(ar-Wr.Vx)/(ar-am); } #endif /* ISOTHERMAL */ } #endif /* CYLINDRICAL */ return; }