Esempio n. 1
0
/* ********************************************************************** */
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);
}
// older method that has no failures problem CHANGINGMARK
void para4_old(int pl, FTYPE *y, FTYPE *lout, FTYPE *rout)
{
  int mm ;
  FTYPE dq0[5];
  FTYPE *dq;
  FTYPE Dqm, Dqc, Dqp, Dqvanl,aDqm,aDqp,aDqc,aDqvanl,s,l,r,qa, qd, qe;
  void slope_lim_3points(int reallim, FTYPE yl, FTYPE yc, FTYPE yr,FTYPE *dq);

  // shifted dq
  dq=dq0+2;

  /*CW1.7 */
  for(mm=-1 ; mm<=1 ; mm++) {
    Dqm = 2.0 *(y[mm]-y[mm-1]);
    Dqp = 2.0 *(y[mm+1]-y[mm]);
    Dqc = 0.5 *(y[mm+1]-y[mm-1]);
    aDqm = fabs(Dqm) ;
    aDqp = fabs(Dqp) ;
    aDqc = fabs(Dqc) ;
    s = Dqm*Dqp;


#if(PARA2LIM == VANL) 
    Dqvanl=2.0*Dqm*Dqp/(Dqm+Dqp);
    aDqvanl=fabs(Dqvanl);

    if (s <=0.) dq[mm]=0.;
    //else dq[mm] = aDqvanl*sign(Dqc);
    else dq[mm]=min(min(aDqc,aDqvanl),min(aDqm,aDqp))*sign(Dqc);

#elif(PARA2LIM == MC)

#if(0)
    // Jon's version
    dq[mm]=MINMOD(Dqc,MINMOD(Dqm,Dqp));
#else
    // Xioyue's version
    if (s <=0.) dq[mm]=0.;       //CW1.8
    else dq[mm]= min(aDqc,min(aDqm,aDqp))*sign(Dqc);
#endif



#elif(PARA2LIM == MINM_STEEPENER)

    // Xioyue's version (steepeneed version of MINM)
    if (s<=0.) dq[mm] = 0.;
    else if (aDqm<aDqp) dq[mm] = aDqm*sign(Dqc);
    else dq[mm]=aDqp*sign(Dqc);


#elif(PARA2LIM == MINM) // no steepener, normal MINM

#if(0)
    // Jon's version
    dq[mm] = MINMOD(0.5*Dqm,0.5*Dqp); // no steepening    
#elif(1)
    // Jon's steep version
    if (s<=0.) dq[mm] = 0.;
    else if (aDqm<aDqp) dq[mm] = aDqm*sign(Dqc);
    else dq[mm]=aDqp*sign(Dqc);
#elif(0)
    // Xioyue's version
    if (s<=0.) dq[mm] = 0.;
    else if (aDqm<aDqp) dq[mm] = 0.5*aDqm*sign(Dqc);
    else dq[mm]=0.5*aDqp*sign(Dqc);
#endif

#elif(PARA2LIM == NLIM) //w/o slope limiter

    dq[mm] = Dqc;
#endif
  }

#if(JONPARAREDUCE)
  //  if(pl==U1){
  if(pl!=RHO){
    if(
       (fabs(dq[-1]-dq[0])/(fabs(dq[-1])+fabs(dq[0])+SMALL)>0.1)||
       (fabs(dq[1]-dq[0])/(fabs(dq[1])+fabs(dq[0])+SMALL)>0.1)
       ){
      slope_lim_3points(MINM, y[-1], y[0], y[1], dq);
      *lout =y[0] - 0.5* (*dq);
      *rout=y[0] + 0.5* (*dq);
      return;
    }
  }

#endif

  /* CW1.6 */

  // modified as per Matt's paper
  l=0.5*(y[0]+y[-1])-(dq[0]-dq[-1])/8.0;
  r=0.5*(y[1]+y[0])-(dq[1]-dq[0])/8.0;


  l=max(min(y[0],y[-1]),l);
  l=min(max(y[0],y[-1]),l);
  r=max(min(y[0],y[1]),r);
  r=min(max(y[0],y[1]),r);


  // modified as per Matt's paper
  qa=(r-y[0])*(y[0]-l);
  qd=(r-l);
  qe=6.0*(y[0]-0.5*(l+r));


  if (qa <=0. ) {
    l=y[0];
    r=y[0];
  }
  else{

    if (qd*(qd-qe)<0.0) 
      l=3.0*y[0]-2.0*r;


    if (qd*(qd+qe)<0.0) 
      r=3.0*y[0]-2.0*l;
  }


  *lout=l;   //a_L,j
  *rout=r;

  //  *dqleft=dq[-1];
  //  *dqcenter=dq[0];
  //  *dqright=dq[1];

}