/* ********************************************************************* */ double CompEquil (double N, double T, double *v0) /*! * Compute the equilibrium ionization balance for (rho,T) * * *********************************************************************** */ { int nlev, ind_start, i,j, k, nv, nrt; double d, n_el, n_el_old, sT; double v[NVAR]; static double **M; static double *rhs; static int *p; /* ---- start index in the ions matrix for each element ---- */ int ind_starts[] = {X_HI, X_HeI, X_CI, X_NI, X_OI, X_NeI, X_SI, X_SI+S_IONS}; /* ---- number of ions for each element ---- */ int nlevs[] = {1, 2, C_IONS, N_IONS, O_IONS, Ne_IONS, S_IONS, Fe_IONS}; /* -- Copy solution vector before any modification -- */ VAR_LOOP(nv) v[nv] = v0[nv]; sT = sqrt(T); /* N = find_N(rho); -- Total number density -- */ if (M == NULL) { /* -- Allocate matrices for the linear eq system -- */ M = ARRAY_2D(MAX_NLEVEL, MAX_NLEVEL, double); rhs = ARRAY_1D(MAX_NLEVEL, double); p = ARRAY_1D(MAX_NLEVEL, int); }
/* ********************************************************************* */ void EntropyOhmicHeating (const Data *d, Data_Arr UU, double dt, Grid *grid) /*! * Add Ohmic heating term to the conservative entropy equation when * RESISTIVITY is set to YES. * * \return This function has no return value. *********************************************************************** */ { #if PHYSICS == MHD && (RESISTIVITY == EXPLICIT) /* at the moment ... remove later ! */ int i,j,k,nv; double rho, rhog, gm1, vc[NVAR]; double Jc[3], eta[3], J2eta; double ***Jx1, *x1, *dx1; double ***Jx2, *x2, *dx2; double ***Jx3, *x3, *dx3; Data_Arr V; /* --------------------------------------------- 1. Set pointer shortcuts --------------------------------------------- */ V = d->Vc; Jx1 = d->J[IDIR]; x1 = grid[IDIR].x ; dx1 = grid[IDIR].dx; Jx2 = d->J[JDIR]; x2 = grid[JDIR].x ; dx2 = grid[JDIR].dx; Jx3 = d->J[KDIR]; x3 = grid[KDIR].x ; dx3 = grid[KDIR].dx; gm1 = g_gamma - 1.0; Jc[IDIR] = Jc[JDIR] = Jc[KDIR] = 0.0; /* --------------------------------------------- 2. Main spatial loop --------------------------------------------- */ DOM_LOOP(k,j,i){ /* --------------------------------- 2a. compute currents at cell center --------------------------------- */ #ifdef STAGGERED_MHD /* Staggered MHD */ #if COMPONENTS == 3 Jc[IDIR] = AVERAGE_YZ(Jx1,k-1,j-1,i); Jc[JDIR] = AVERAGE_XZ(Jx2,k-1,j,i-1); #endif Jc[KDIR] = AVERAGE_XY(Jx3,k,j-1,i-1); #else /* Cell-centered MHD */ #if COMPONENTS == 3 Jc[IDIR] = CDIFF_X2(V[BX3],k,j,i)/dx2[j] - CDIFF_X3(V[BX2],k,j,i)/dx3[k]; Jc[JDIR] = CDIFF_X3(V[BX1],k,j,i)/dx3[k] - CDIFF_X1(V[BX3],k,j,i)/dx1[i]; #endif Jc[KDIR] = CDIFF_X1(V[BX2],k,j,i)/dx1[i] - CDIFF_X2(V[BX1],k,j,i)/dx2[j]; #if GEOMETRY != CARTESIAN print1 ("! EntropyOhmicHeating: only CT supported in this geometry.\n") QUIT_PLUTO(1); #endif #endif /* ---------------------------------------- 2b. compute resistivity at cell center. ---------------------------------------- */ VAR_LOOP(nv) vc[nv] = V[nv][k][j][i]; rho = vc[RHO]; rhog = pow(rho,-gm1); Resistive_eta (vc, x1[i], x2[j], x3[k], Jc, eta); J2eta = 0.0; for (nv = 0; nv < 3; nv++) J2eta += Jc[nv]*Jc[nv]*eta[nv]; /* ---------------------------------------- 2c. Update conserved entropy ---------------------------------------- */ UU[k][j][i][ENTR] += dt*rhog*gm1*J2eta; }
/* ********************************************************************** */ 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); }