Conserved RiemannSolver(const Primitive *Pl, const Primitive *Pr, int dimension) { Conserved Ul = PrimToCons(Pl); Conserved Ur = PrimToCons(Pr); Conserved Fl = FluxFunction(Pl, dimension); Conserved Fr = FluxFunction(Pr, dimension); double lamL[5]={0,0,0,0,0}, lamR[5]={0,0,0,0,0}; Eigenvalues(Pl, dimension, lamL); Eigenvalues(Pr, dimension, lamR); const double am = minval3(lamL[0], lamR[0], 0.0); // left going wave speed const double ap = maxval3(lamL[4], lamR[4], 0.0); // right MaxWavespeed = maxval3(fabs(ap), fabs(am), MaxWavespeed); Conserved F; F.D = (ap*Fl.D - am*Fr.D + ap*am*(Ur.D - Ul.D )) / (ap - am); F.tau = (ap*Fl.tau - am*Fr.tau + ap*am*(Ur.tau - Ul.tau)) / (ap - am); F.Sx = (ap*Fl.Sx - am*Fr.Sx + ap*am*(Ur.Sx - Ul.Sx )) / (ap - am); F.Sy = (ap*Fl.Sy - am*Fr.Sy + ap*am*(Ur.Sy - Ul.Sy )) / (ap - am); F.Sz = (ap*Fl.Sz - am*Fr.Sz + ap*am*(Ur.Sz - Ul.Sz )) / (ap - am); return F; }
/* ********************************************************************** */ void AUSMp_Solver (const State_1D *state, real *cmax, Grid *grid) /* * * PURPOSE * * - Solve riemann problem for the Euler equations using the AUSM+ * scheme given in * * "A Sequel to AUSM: AUSM+" * Liou, M.S., JCP (1996), 129, 364 * * LAST_MODIFIED * * July 17th 2006, by Andrea Mignone ([email protected]) * * ************************************************************************ */ { int i, nv, beg, end; real aL, asL2, asL, atL, phiL[NFLX]; real aR, asR2, asR, atR, phiR[NFLX]; real ML, Mp1L, Mp2L, Mm2L, Mp4L, Pp5L; real MR, Mm1R, Mp2R, Mm2R, Mm4R, Pm5R; real a, m; real Ku, Kp, sigma, fa, Mm2, Mo2, Mo, M, scrh; real *vL, *vR, *uL, *uR; real alpha = 3.0/16.0, beta = 0.125; static real **fl, **fr, **ul, **ur; beg = grid[g_dir].lbeg - 1; end = grid[g_dir].lend; if (fl == NULL){ fl = array_2D(NMAX_POINT, NFLX); fr = array_2D(NMAX_POINT, NFLX); ul = array_2D(NMAX_POINT, NVAR); ur = array_2D(NMAX_POINT, NVAR); } PrimToCons (state->vL, ul, beg, end); PrimToCons (state->vR, ur, beg, end); Ku = 0.75; Kp = 0.25; sigma = 1.0; for (i = beg; i <= end; i++) { vL = state->vL[i]; vR = state->vR[i]; uL = ul[i]; uR = ur[i]; phiL[RHO] = 1.0; EXPAND(phiL[MX1] = vL[VX1]; , phiL[MX2] = vL[VX2]; ,
Conserved FluxFunction(const Primitive *P, int dimension) // ----------------------------------------------------------------------------- // This function returns the flux of the conserved variables in the cartesian // direction specified by the input parameter 'dimension' = 0,1,2 // ----------------------------------------------------------------------------- { Conserved U = PrimToCons(P); Conserved F = { 0,0,0,0,0 }; switch (dimension) { case 0: F.D = U.D * P->vx; F.Sx = U.Sx * P->vx + P->p; F.Sy = U.Sy * P->vx; F.Sz = U.Sz * P->vx; F.tau = (U.tau + P->p) * P->vx; break; case 1: F.D = U.D * P->vy ; F.Sx = U.Sx * P->vy ; F.Sy = U.Sy * P->vy + P->p; F.Sz = U.Sz * P->vy ; F.tau = (U.tau + P->p) * P->vy; break; case 2: F.D = U.D * P->vz; F.Sx = U.Sx * P->vz; F.Sy = U.Sy * P->vz; F.Sz = U.Sz * P->vz + P->p; F.tau = (U.tau + P->p) * P->vz; break; } return F; }
/* ********************************************************************** */ void States (const State_1D *state, int beg, int end, Grid *grid) /*! * * \param [in] state pointer to State_1D structure * \param [in] beg initial index of computation * \param [in] end final index of computation * \param [in] grid pointer to an array of Grid structures * ************************************************************************ */ { int i, nv; double dv, **v; double dvp, cp, *wp, *hp, **vp; double dvm, cm, *wm, *hm, **vm; PPM_Coeffs ppm_coeffs; PLM_Coeffs plm_coeffs; /* --------------------------------------------------------- 1. Set pointers, compute geometrical coefficients --------------------------------------------------------- */ v = state->v; vm = state->vm; vp = state->vp; PPM_CoefficientsGet(&ppm_coeffs, g_dir); #if SHOCK_FLATTENING == MULTID PLM_CoefficientsGet(&plm_coeffs, g_dir); #endif hp = ppm_coeffs.hp; hm = ppm_coeffs.hm; /* --------------------------------------------------------- 2. Define unlimited left and right interface values and make sure they lie between adjacent cell averages. --------------------------------------------------------- */ #if PPM_VERSION == PPM3 || PPM_VERSION == PPM5 for (i = beg; i <= end; i++) { wp = ppm_coeffs.wp[i]; wm = ppm_coeffs.wm[i]; VAR_LOOP(nv){ #if PPM_VERSION == PPM3 vp[i][nv] = wp[-1]*v[i-1][nv] + wp[0]*v[i][nv] + wp[1]*v[i+1][nv]; vm[i][nv] = wm[-1]*v[i-1][nv] + wm[0]*v[i][nv] + wm[1]*v[i+1][nv]; #elif PPM_VERSION == PPM5 vp[i][nv] = wp[-2]*v[i-2][nv] + wp[-1]*v[i-1][nv] + wp[ 0]*v[i][nv] + wp[ 1]*v[i+1][nv] + wp[ 2]*v[i+2][nv]; vm[i][nv] = wm[-2]*v[i-2][nv] + wm[-1]*v[i-1][nv] + wm[0]*v[i][nv] + wm[ 1]*v[i+1][nv] + wm[ 2]*v[i+2][nv]; #endif dvp = vp[i][nv] - v[i][nv]; dvm = vm[i][nv] - v[i][nv]; dv = v[i+1][nv] - v[i][nv]; vp[i][nv] = v[i][nv] + MINMOD(dvp, dv); dv = v[i][nv] - v[i-1][nv]; vm[i][nv] = v[i][nv] + MINMOD(dvm, -dv); } } #elif PPM_VERSION == PPM4 /* -- set a unique interface value -- */ for (i = beg-1; i <= end; i++) { wp = ppm_coeffs.wp[i]; VAR_LOOP(nv){ vp[i][nv] = wp[-1]*v[i-1][nv] + wp[0]*v[i][nv] + wp[ 1]*v[i+1][nv] + wp[2]*v[i+2][nv]; dv = v[i+1][nv] - v[i][nv]; dvp = vp[i][nv] - v[i][nv]; vp[i][nv] = v[i][nv] + MINMOD(dvp, dv); } } for (i = beg; i <= end; i++) VAR_LOOP(nv) vm[i][nv] = vp[i-1][nv]; #endif /* --------------------------------------------------------- 3. Apply parabolic limiter: no new extrema should appear in the parabola defined by vp, vm and v. --------------------------------------------------------- */ for (i = beg; i <= end; i++) { #if SHOCK_FLATTENING == MULTID if (CheckZone (i, FLAG_MINMOD)) { wp = plm_coeffs.wp; wm = plm_coeffs.wm; VAR_LOOP(nv) { dvp = (v[i+1][nv] - v[i][nv])*wp[i]; dvm = (v[i][nv] - v[i-1][nv])*wm[i]; dv = MINMOD(dvp, dvm); vp[i][nv] = v[i][nv] + dv*plm_coeffs.dp[i]; vm[i][nv] = v[i][nv] - dv*plm_coeffs.dm[i]; } #if PHYSICS == RHD || PHYSICS == RMHD VelocityLimiter (v[i], vp[i], vm[i]); #endif continue; } #endif #if PPM_VERSION == PPM0 cm = cp = 2.0; #else cm = (hm[i] + 1.0)/(hp[i] - 1.0); cp = (hp[i] + 1.0)/(hm[i] - 1.0); #endif for (nv = 0; nv < NVAR; nv++){ dvp = vp[i][nv] - v[i][nv]; dvm = vm[i][nv] - v[i][nv]; if (dvp*dvm >= 0.0) dvp = dvm = 0.0; else{ if (fabs(dvp) >= cm*fabs(dvm)) dvp = -cm*dvm; else if (fabs(dvm) >= cp*fabs(dvp)) dvm = -cp*dvp; } vp[i][nv] = v[i][nv] + dvp; vm[i][nv] = v[i][nv] + dvm; } #if PHYSICS == RHD || PHYSICS == RMHD VelocityLimiter (v[i], vp[i], vm[i]); #endif } /* -------------------------------------------------------- 1D shock flattening -------------------------------------------------------- */ #if SHOCK_FLATTENING == YES Flatten (state, beg, end, grid); #endif /* ------------------------------------------- Assign face-centered magnetic field ------------------------------------------- */ #ifdef STAGGERED_MHD for (i = beg-1; i <= end; i++) { state->vR[i][BXn] = state->vL[i][BXn] = state->bn[i]; } #endif #if TIME_STEPPING == CHARACTERISTIC_TRACING CharTracingStep(state, beg, end, grid); #endif /* ------------------------------------------- compute states in conservative variables ------------------------------------------- */ PrimToCons (state->vp, state->up, beg, end); PrimToCons (state->vm, state->um, beg, end); }
int main(int argc, char **argv) // ============================================================================= // Main program // ============================================================================= { RunUserMenu(); FILE *OutputFile = fopen("euler.dat", "w"); double *x = (double*) malloc((Nx+2*Ng)*sizeof(double)); Conserved *U = (Conserved*) malloc((Nx+2*Ng)*sizeof(Conserved)); int i; // --------------------------------------------------------------------------- // Initial conditions setup. for (i=0; i<Nx+2*Ng; ++i) { // Here we initialize the array of x coordinates, and set the initial // conditions on the conserved array. x[i] = -0.5 + (i-Ng+0.5) / Nx; Primitive P = testProblem->InitialCondition(x[i]); U[i] = PrimToCons(&P); } int CycleCounter = 0; double CurrentTime = 0.0; double EndTime = OutputTime; double dt = 0.0; double dx = 1.0 / Nx; // --------------------------------------------------------------------------- // This is the main iteration loop. while (CurrentTime < EndTime) { MaxWavespeed = 0.0; integrationMethod->AdvanceSolution(U, dt); CurrentTime += dt; CycleCounter++; dt = CFL * dx / MaxWavespeed; printf("\r[%s]", ProgressBar(CurrentTime/EndTime)); fflush(stdout); } // --------------------------------------------------------------------------- // Output solution. for (i=Ng; i<Nx+Ng; ++i) { // This loop prints an ASCII table of x-coordinate values with their // associated primitive variables. Primitive P = ConsToPrim(&U[i]); fprintf(OutputFile, "%+8.6e %+8.6e %+8.6e %+8.6e %+8.6e %+8.6e\n", x[i], P.rho, P.p, P.vx, P.vy, P.vz); } free(x); free(U); fclose(OutputFile); // --------------------------------------------------------------------------- // Create a simple GNUplot script. FILE *gnuplot = fopen("plot.gp", "w"); fprintf(gnuplot, "set title \"%s %s t=%3.2f PLM=%3.2f\"\n", testProblem->Name, integrationMethod->Name, OutputTime, PlmTheta); fprintf(gnuplot, "set xlabel \"x\"\n"); fprintf(gnuplot, "plot \\\n"); fprintf(gnuplot, "\"euler.dat\" u 1:2 title \"Density \",\\\n"); fprintf(gnuplot, "\"euler.dat\" u 1:3 title \"Pressure\",\\\n"); fprintf(gnuplot, "\"euler.dat\" u 1:4 title \"Velocity\" \n"); fprintf(gnuplot, "pause(-1)\\\n"); fclose(gnuplot); printf("\n\n"); printf("All done. Data is in euler.dat, but if you have gnuplot simply run\n" "$> gnuplot plot.gp\n\n"); return 0; }