示例#1
0
Vars U_R(Vars Ui, Vars Uipo, Vars Uipt){//does U_L for the right state
  Vars UR;
  UR.mass = Uipo.mass - 0.5*minmod(thet*(Uipo.mass-Ui.mass),0.5*(Uipt.mass-Ui.mass),thet*(Uipt.mass-Uipo.mass));
  UR.xvelocity = Uipo.xvelocity - 0.5*minmod(thet*(Uipo.xvelocity-Ui.xvelocity),.5*(Uipt.xvelocity-Ui.xvelocity),thet*(Uipt.xvelocity-Uipo.xvelocity));
  UR.yvelocity = Uipo.yvelocity - 0.5*minmod(thet*(Uipo.yvelocity-Ui.yvelocity),.5*(Uipt.yvelocity-Ui.yvelocity),thet*(Uipt.yvelocity-Uipo.yvelocity));
  UR.press = Uipo.press - 0.5*minmod(thet*(Uipo.press-Ui.press), 0.5*(Uipt.press-Ui.press), thet*(Uipt.press-Uipo.press));
  UR.energy = Et(UR.mass, UR.xvelocity, UR.yvelocity, UR.press);
  return(UR);
}
示例#2
0
Vars U_L(Vars Ui, Vars Uimo, Vars Uipo){//interpolates the conserved variables at interface for the left state
  Vars UL;
  UL.mass = Ui.mass + 0.5*minmod(thet*(Ui.mass - Uimo.mass), 0.5*(Uipo.mass - Uimo.mass),thet*(Uipo.mass-Ui.mass));
  UL.xvelocity = Ui.xvelocity + 0.5*minmod(thet*(Ui.xvelocity - Uimo.xvelocity), 0.5*(Uipo.xvelocity - Uimo.xvelocity),thet*(Uipo.xvelocity-Ui.xvelocity));
  UL.yvelocity = Ui.yvelocity + 0.5*minmod(thet*(Ui.yvelocity - Uimo.yvelocity), 0.5*(Uipo.yvelocity - Uimo.yvelocity),thet*(Uipo.yvelocity-Ui.yvelocity));
  UL.press = Ui.press + 0.5*minmod(thet*(Ui.press - Uimo.press), 0.5*(Uipo.press - Uimo.press),thet*(Uipo.press-Ui.press));
  UL.energy = Et(UL.mass, UL.xvelocity, UL.yvelocity, UL.press);
  return(UL);
}
示例#3
0
文件: plm.c 项目: duffell/RT1D
void plm( struct domain * theDomain ){

   struct cell * theCells = theDomain->theCells;
   int Nr = theDomain->Nr;
   double PLM = theDomain->theParList.PLM;
   int i,q;
   for( i=0 ; i<Nr ; ++i ){
      int im = i-1;
      int ip = i+1;
      if( i==0 ) im = 0;
      if( i==Nr-1 ) ip = Nr-1;
      struct cell * c  = theCells+i;
      struct cell * cL = theCells+im;
      struct cell * cR = theCells+ip;
      double drL = cL->dr;
      double drC = c->dr;
      double drR = cR->dr;
      for( q=0 ; q<NUM_Q ; ++q ){
         double pL = cL->prim[q];
         double pC = c->prim[q];
         double pR = cR->prim[q];
         double sL = pC - pL;
         sL /= .5*( drC + drL );
         double sR = pR - pC;
         sR /= .5*( drR + drC );
         double sC = pR - pL;
         sC /= .5*( drL + drR ) + drC;
         c->grad[q] = minmod( PLM*sL , sC , PLM*sR );
      }
   }
}
示例#4
0
文件: project.c 项目: ChaliZhg/cfdlab
void Project(CELL * cell)
{
   REAL minmod(REAL, REAL, REAL);
   REAL minmod2(REAL, REAL, REAL, REAL, REAL);
   UINT i, j, k;
   REAL u[NVAR], ux[NVAR], uxb[NVAR], dul[NVAR], dur[NVAR], R[NVAR][NVAR],
      Ri[NVAR][NVAR], fact;

   fact = sqrt(3.0);

   for(i = 1; i < NC - 1; i++) {
      for(j = 0; j < NVAR; j++) {
         dul[j] = cell[i].Un[j][0] - cell[i - 1].Un[j][0];
         dur[j] = cell[i + 1].Un[j][0] - cell[i].Un[j][0];
         u[j] = cell[i].Un[j][0];
         ux[j] = fact * cell[i].Un[j][1];
      }

      EigMat(u, R, Ri);
      Multi(Ri, ux);
      Multi(Ri, dul);
      Multi(Ri, dur);
      for(j = 0; j < NVAR; j++) {
         if(fabs(ux[j]) <= Mfact * cell[i].h * cell[i].h)
            uxb[j] = ux[j];
         else
            uxb[j] = minmod(ux[j], dul[j], dur[j]);
      }
      Multi(R, uxb);

      for(j = 0; j < NVAR; j++) {
         uxb[j] = uxb[j] / fact;
         if(cell[i].Un[j][1] != uxb[j]) {
            cell[i].Un[j][1] = uxb[j];
            for(k = 2; k < cell[i].p; k++)
               cell[i].Un[j][k] = 0.0;
         }

      }
   }
}
示例#5
0
inline __device__ float derivative(float& left, float& center, float& right) {
	return minmod(KPSIMULATOR_MINMOD_THETA*(center-left),
			0.5f*(right-left),
			KPSIMULATOR_MINMOD_THETA*(right-center));
}
示例#6
0
void evolve(double *G, double *h, double *u, double g, double dx, double dt, int nBC, int n,double *nG, double *nh, double theta)
{
    //modifies nh and nG to give the new values of h and G after a single time step
    double idx = 1.0 / dx;
    double ithree = 1.0 / 3.0;
    int i = nBC - 1;

    //calculate gradients
    double dhib = (h[i] - h[i-1]);
    double dhim = 0.5*(h[i+1] - h[i-1]);
    double dhif = (h[i+1] - h[i]);

    //double duib = (u[i] - u[i-1]);
    //double dui = 0.5*(u[i+1] - u[i-1]);
    //double duif = (u[i+1] - u[i]);

    double dGib = (G[i] - G[i-1]);
    double dGim = 0.5*(G[i+1] - G[i-1]);
    double dGif = (G[i+1] - G[i]);


    //calculate values at right of i cell
    double dhi = minmod(theta*dhib, dhim, theta*dhif);
    //double dui = minmod(theta*duib, duim, theta*duif);
    double dGi = minmod(theta*dGib, dGim, theta*dGif);

    double ue = 0.5*(u[i+1]+u[i]);

    double hir = h[i] + 0.5*dhi;
    double Gir = G[i] + 0.5*dGi;
    double uir = ue;

    //calculate values at left of i+1 cell

    //calculate gradients
    double dhip1b = (h[i+1] - h[i]);
    double dhip1m = 0.5*(h[i+2] - h[i]);
    double dhip1f = (h[i+2] - h[i+1]);

    //double duip1b = (u[i+1] - u[i]);
    //double duip1m = 0.5*(u[i+2] - u[i]);
    //double duip1f = (u[i+2] - u[i+1]);

    double dGip1b = (G[i+1] - G[i]);
    double dGip1m = 0.5*(G[i+2] - G[i]);
    double dGip1f = (G[i+2] - G[i+1]);

    double dhip1 = minmod(theta*dhip1b, dhip1m, theta*dhip1f);
    //double duip1 = minmod(theta*duip1b, duip1m, theta*duip1f);
    double dGip1 = minmod(theta*dGip1b, dGip1m, theta*dGip1f);

    double hip1l = h[i+1] - 0.5*dhip1;
    double Gip1l = G[i+1] - 0.5*dGip1;
    double uip1l = ue;

    //right force
    double duer = idx*(u[i+1] - u[i]);

    double sqrtghel = sqrt(g*hir);
    double sqrtgher = sqrt(g*hip1l);

    double sl = fmin(0,fmin(uir - sqrtghel, uip1l - sqrtgher));
    double sr = fmax(0,fmax(uir + sqrtghel, uip1l + sqrtgher));

    double felh = uir*hir;
    double felG = Gir*uir + 0.5*g*hir*hir - 2*ithree*hir*hir*hir*duer*duer;
    double ferh = uip1l*hip1l;
    double ferG = Gip1l*uip1l + 0.5*g*hip1l*hip1l -2*ithree*hip1l*hip1l*hip1l*duer*duer;

    double isrmsl = 0.0;

    if(sr != sl) isrmsl = 1.0 / (sr - sl);
   
    double foh = isrmsl*(sr*felh - sl*ferh + sl*sr*(hip1l - hir));

    double foG = isrmsl*(sr*felG - sl*ferG + sl*sr*(Gip1l - Gir));

    double fih = foh;
    double fiG = foG;

    dhi = dhip1;
    //dui = duip1;
    dGi = dGip1;

    for (i = nBC ; i < n +nBC;i++)
    {
        ue = 0.5*(u[i+1]+u[i]);
        //i right

        hir = h[i] + 0.5*dhi;
        Gir = G[i] + 0.5*dGi;
        uir = ue;

        //calculate gradients
        dhip1b = (h[i+1] - h[i]);
        dhip1m = 0.5*(h[i+2] - h[i]);
        dhip1f = (h[i+2] - h[i+1]);

        //duip1b = (u[i+1] - u[i]);
        //duip1m = 0.5*(u[i+2] - u[i]);
        //duip1f = (u[i+2] - u[i+1]);

        dGip1b = (G[i+1] - G[i]);
        dGip1m = 0.5*(G[i+2] - G[i]);
        dGip1f = (G[i+2] - G[i+1]);

        dhip1 = minmod(theta*dhip1b, dhip1m, theta*dhip1f);
        //duip1 = minmod(theta*duip1b, duip1m, theta*duip1f);
        dGip1 = minmod(theta*dGip1b, dGip1m, theta*dGip1f);

        hip1l = h[i+1] - 0.5*dhip1;
        Gip1l = G[i+1] - 0.5*dGip1;
        uip1l = ue;

        duer = idx*(u[i+1] - u[i]);

        sqrtghel = sqrt(g*hir);
        sqrtgher = sqrt(g*hip1l);

        sl = fmin(0,fmin(uir - sqrtghel, uip1l - sqrtgher));
        sr = fmax(0,fmax(uir + sqrtghel, uip1l + sqrtgher));

        felh = uir*hir;
        felG = Gir*uir + 0.5*g*hir*hir - 2*ithree*hir*hir*hir*duer*duer;
        ferh = uip1l*hip1l;
        ferG = Gip1l*uip1l + 0.5*g*hip1l*hip1l -2*ithree*hip1l*hip1l*hip1l*duer*duer;

        isrmsl = 0.0;

        if(sr != sl) isrmsl = 1.0 / (sr - sl);
   
        foh = isrmsl*(sr*felh - sl*ferh + sl*sr*(hip1l - hir));
        foG = isrmsl*(sr*felG - sl*ferG + sl*sr*(Gip1l - Gir));

        //source term

        nh[i -nBC] = h[i] -dt*idx*(foh - fih);
        nG[i -nBC] = G[i] -dt*idx*(foG -fiG);

        fih = foh;
        fiG = foG;

        dhi = dhip1;
        //dui = duip1;
        dGi = dGip1;   
 
    }
    
   
}
// moved here from apps/plasma/lib/2d/ApplyLimiter_divfree.cpp
// (which I copied and modified from lib/2d/cart; I changed
// the coefficients to limiter more aggressively.)
//
void ApplyLimiterKrivodonova_modified(dTensorBC4& aux, dTensorBC4& q,
                  void (*ProjectRightEig)(int,const dTensor1&,
                                          const dTensor1&,const dTensor2&,
                                          dTensor2&),
                  void (*ProjectLeftEig)(int,const dTensor1&,
                                         const dTensor1&,const dTensor2&,
                                         dTensor2&))
{
  // -------------------------------------------------------------  
  // Limiter based on a modification of the following paper:
  //      L. Krivodonova. "Limiters for high-order discontinuous
  //      Galerkin methods." J. Comp. Phys., Vol. 226, pg 879-896.
  // ------------------------------------------------------------- 
  const int   mx = q.getsize(1);
  const int   my = q.getsize(2);
  const int meqn = q.getsize(3);
  const int kmax = q.getsize(4);
  const int mbc  = q.getmbc();
  const int maux = aux.getsize(2);
  const int method1 = int((sqrt(1+8*kmax)-1)/2);
  const int ksize = (method1==2) ? 1 : 3;
  dTensorBC4  wx_cent(mx,my,meqn,ksize,mbc);
  dTensorBC4  wy_cent(mx,my,meqn,ksize,mbc);
  dTensorBC4 dw_right(mx,my,meqn,ksize,mbc);
  dTensorBC4  dw_left(mx,my,meqn,ksize,mbc);
  dTensorBC4    dw_up(mx,my,meqn,ksize,mbc);
  dTensorBC4  dw_down(mx,my,meqn,ksize,mbc);
  void ConvertQtoW(int ixy, const dTensorBC4& aux, const dTensorBC4& qold, 
                   dTensorBC4& dwp, dTensorBC4& dwm, dTensorBC4& w_cent,
                   void (*ProjectLeftEig)(int,const dTensor1&,
                                          const dTensor1&,const dTensor2&,
                                          dTensor2&));
  void ConvertWtoQ(int ixy, const dTensorBC4& aux, const dTensorBC4& qold,
                   const dTensorBC4& win, dTensorBC4& qout,
                   void (*ProjectRightEig)(int,const dTensor1&,
                                           const dTensor1&,const dTensor2&,
                                           dTensor2&));
  
  // ----------------------------------------------------------
  // Key: storage of characteristic variables
  //       
  //      wx_cent(i,j,me,1)  = Lx * q(i,j,me,2)
  //      wx_cent(i,j,me,2)  = Lx * q(i,j,me,4)
  //      wx_cent(i,j,me,3)  = Lx * q(i,j,me,5)
  //
  //      dw_right(i,j,me,1) = Lx * (q(i+1,j,me,1)-q(i,j,me,1))
  //      dw_right(i,j,me,2) = Lx * (q(i+1,j,me,2)-q(i,j,me,2))
  //      dw_right(i,j,me,3) = Lx * (q(i,j+1,me,2)-q(i,j,me,2))
  //
  //      dw_left(i,j,me,1)  = Lx * (q(i,j,me,1)-q(i-1,j,me,1))
  //      dw_left(i,j,me,2)  = Lx * (q(i,j,me,2)-q(i-1,j,me,2))
  //      dw_left(i,j,me,3)  = Lx * (q(i,j,me,2)-q(i,j-1,me,2))
  //
  //      wy_cent(i,j,me,1)  = Ly * q(i,j,me,3)
  //      wy_cent(i,j,me,2)  = Ly * q(i,j,me,4)
  //      wy_cent(i,j,me,3)  = Ly * q(i,j,me,6)
  //
  //      dw_up(i,j,me,1)    = Ly * (q(i,j+1,me,1)-q(i,j,me,1))
  //      dw_up(i,j,me,2)    = Ly * (q(i+1,j,me,3)-q(i,j,me,3))
  //      dw_up(i,j,me,3)    = Ly * (q(i,j+1,me,3)-q(i,j,me,3))
  //
  //      dw_down(i,j,me,1)  = Ly * (q(i,j,me,1)-q(i,j-1,me,1))
  //      dw_down(i,j,me,2)  = Ly * (q(i,j,me,3)-q(i-1,j,me,3))
  //      dw_down(i,j,me,3)  = Ly * (q(i,j,me,3)-q(i,j-1,me,3))
  //
  // ---------------------------------------------------------- 
  
  // apply Krivodonova limiter to suppress oscillations
  //
  // Moment limiter (highest to lowest)
  switch ( method1 )
    {
    default: unsupported_value_error(method1);
    case 2:  // 2nd order in space   
      
      // Convert to characteristic variables in x-direction
      ConvertQtoW(1,aux,q,dw_right,dw_left,wx_cent,ProjectLeftEig);
      
      // Convert to characteristic variables in y-direction
      ConvertQtoW(2,aux,q,dw_up,dw_down,wy_cent,ProjectLeftEig);
      
      // Limit in both the x-direction and the y-direction
      #pragma omp parallel for
      for (int i=(3-mbc); i<=(mx+mbc-2); i++)          
        for (int j=(3-mbc); j<=(my+mbc-2); j++)       
          for (int m=1; m<=meqn; m++)
            {
              // x-direction: limit linear term
              {
                const double        dwp = dw_right.get(i,j,m,1);
                const double        dwm =  dw_left.get(i,j,m,1);
                const double     wx_now =  wx_cent.get(i,j,m,1);
                const double wx_limited = minmod(wx_now, dwp/sq3, dwm/sq3);
                
                wx_cent.set(i,j,m,1, wx_limited );
              }
              
              // y-direction: limit linear term
              {
                const double dwp        =    dw_up.get(i,j,m,1);
                const double dwm        =  dw_down.get(i,j,m,1);
                const double wy_now     =  wy_cent.get(i,j,m,1);
                const double wy_limited = minmod(wy_now, dwp/sq3, dwm/sq3);
              
                wy_cent.set(i,j,m,1, wy_limited );
              }
            }
      
      // Convert back to conserved variables in x-direction
      ConvertWtoQ(1,aux,q,wx_cent,q,ProjectRightEig);
      
      // Convert back to conserved variables in y-direction
      ConvertWtoQ(2,aux,q,wy_cent,q,ProjectRightEig);
      
      break;
      
    case 3:  // 3rd order in space
      
      // Convert to characteristic variables in x-direction
      ConvertQtoW(1,aux,q,dw_right,dw_left,wx_cent,ProjectLeftEig);
      
      // Convert to characteristic variables in y-direction
      ConvertQtoW(2,aux,q,dw_up,dw_down,wy_cent,ProjectLeftEig);

      // Limit in the x-direction
      #pragma omp parallel for
      for (int i=(3-mbc); i<=(mx+mbc-2); i++)   
        for (int j=(3-mbc); j<=(my+mbc-2); j++)   
          for (int m=1; m<=meqn; m++)
            {
              bool limited_x2=false;
              // x-direction: limit quadratic term
              {
                const double dwp        = dw_right.get(i,j,m,2);
                const double dwm        =  dw_left.get(i,j,m,2);
                const double wx_now     =  wx_cent.get(i,j,m,3);
//              const double wx_limited = minmod(wx_now, 0.5*(sq3/sq5)*dwp, 
//                                          0.5*(sq3/sq5)*dwm);
                const double wx_limited = minmod(wx_now, (0.5/sq3)*dwp, 
                                            (0.5/sq3)*dwm);
                if(wx_limited!=wx_now)
                {
                  limited_x2=true;
                  wx_cent.set(i,j,m,3, wx_limited );
                }
              }
              
              //if(limited_x2)
              // x-direction: limit mixed term
              { 
                const double dwp        = dw_right.get(i,j,m,3);
                const double dwm        =  dw_left.get(i,j,m,3);
                const double wx_now     =  wx_cent.get(i,j,m,2);
                const double wx_limited = minmod(wx_now, dwp/sq3, dwm/sq3);
                
                if(wx_limited!=wx_now)
                {
                  limited_x2=true;
                  wx_cent.set(i,j,m,2, wx_limited );
                }
              } 
                  
              if(limited_x2)
              // x-direction: limit linear term
              { 
                const double dwp        = dw_right.get(i,j,m,1);
                const double dwm        =  dw_left.get(i,j,m,1);
                const double wx_now     =  wx_cent.get(i,j,m,1);
                const double wx_limited = minmod(wx_now, dwp/sq3, dwm/sq3);
                
                if(wx_limited!=wx_now)
                {
                  wx_cent.set(i,j,m,1, wx_limited );
                }
              }
                      
              bool limited_y2=false;
              // y-direction: limit quadratic term
              {
                const double dwp    =    dw_up.get(i,j,m,3);
                const double dwm    =  dw_down.get(i,j,m,3);
                const double wy_now =  wy_cent.get(i,j,m,3);
//              const double wy_limited = minmod(wy_now, 0.5*(sq3/sq5)*dwp, 
//                                         0.5*(sq3/sq5)*dwm);
                const double wy_limited = minmod(wy_now, (0.5/sq3)*dwp, 
                                           (0.5/sq3)*dwm);
                if(wy_limited!=wy_now)
                {
                  limited_y2=true;
                  wy_cent.set(i,j,m,3, wy_limited );
                }
              }
              
              //if(limited_y2)
              // y-direction: limit mixed term
              {
                const double dwp        =    dw_up.get(i,j,m,2);
                const double dwm        =  dw_down.get(i,j,m,2);
                const double wy_now     =  wy_cent.get(i,j,m,2);
                const double wy_limited = minmod(wy_now, dwp/sq3, dwm/sq3);
                
                if(wy_limited!=wy_now)
                {
                  limited_y2=true;
                  wy_cent.set(i,j,m,2, wy_limited);
                }
              }
                
              if(limited_y2)
              // y-direction: limit linear term
              {
                const double dwp        =    dw_up.get(i,j,m,1);
                const double dwm        =  dw_down.get(i,j,m,1);
                const double wy_now     =  wy_cent.get(i,j,m,1);
                const double wy_limited = minmod(wy_now, dwp/sq3, dwm/sq3);
                
                if(wy_limited!=wy_now)
                {
                  wy_cent.set(i,j,m,1, wy_limited );
                }
              }
            }

      // Convert back to conserved variables in x-direction
      ConvertWtoQ(1,aux,q,wx_cent,q,ProjectRightEig);
      
      // Convert back to conserved variables in y-direction
      ConvertWtoQ(2,aux,q,wy_cent,q,ProjectRightEig);
      
      break;          
    }
}
/*
    Computes the undivided differences with limiter.
*/
static double slopefit(double left, double center, double right, double theta)
{
    return minmod(theta*(right-center),
                  minmod(0.5*(right-left), theta*(center-left)) );
}
void ApplyLimiter(dTensorBC4& aux, dTensorBC4& q,
		  void (*ProjectRightEig)(int,const dTensor1&,
					  const dTensor1&,const dTensor2&,
					  dTensor2&),
		  void (*ProjectLeftEig)(int,const dTensor1&,
					 const dTensor1&,const dTensor2&,
					 dTensor2&))
{
  // -------------------------------------------------------------  
  // Limiter based on a modification of the following paper:
  //      L. Krivodonova. "Limiters for high-order discontinuous
  //      Galerkin methods." J. Comp. Phys., Vol. 226, pg 879-896.
  // ------------------------------------------------------------- 
  const int   mx = q.getsize(1);
  const int   my = q.getsize(2);
  const int meqn = q.getsize(3);
  const int kmax = q.getsize(4);
  const int mbc  = q.getmbc();
  const int maux = aux.getsize(2);
  const int method1 = int((sqrt(1+8*kmax)-1)/2);
  //const int ksize = (method1==2)?1:3;
  int ksize;
  if (method1==2)
    {  ksize = 1;  }
  else
    {  ksize = 3;  }
  dTensorBC4  wx_cent(mx,my,meqn,ksize,mbc);
  dTensorBC4  wy_cent(mx,my,meqn,ksize,mbc);
  dTensorBC4 dw_right(mx,my,meqn,ksize,mbc);
  dTensorBC4  dw_left(mx,my,meqn,ksize,mbc);
  dTensorBC4    dw_up(mx,my,meqn,ksize,mbc);
  dTensorBC4  dw_down(mx,my,meqn,ksize,mbc);
  void ConvertQtoW(int ixy, const dTensorBC4& aux, const dTensorBC4& qold, 
		   dTensorBC4& dwp, dTensorBC4& dwm, dTensorBC4& w_cent,
		   void (*ProjectLeftEig)(int,const dTensor1&,
					  const dTensor1&,const dTensor2&,
					  dTensor2&));
  void ConvertWtoQ(int ixy, const dTensorBC4& aux, const dTensorBC4& qold,
		   const dTensorBC4& win, dTensorBC4& qout,
		   void (*ProjectRightEig)(int,const dTensor1&,
					   const dTensor1&,const dTensor2&,
					   dTensor2&));
  
  // ----------------------------------------------------------
  // Key: storage of characteristic variables
  //       
  //      wx_cent(i,j,me,1)  = Lx * q(i,j,me,2)
  //      wx_cent(i,j,me,2)  = Lx * q(i,j,me,4)
  //      wx_cent(i,j,me,3)  = Lx * q(i,j,me,5)
  //
  //      dw_right(i,j,me,1) = Lx * (q(i+1,j,me,1)-q(i,j,me,1))
  //      dw_right(i,j,me,2) = Lx * (q(i+1,j,me,2)-q(i,j,me,2))
  //      dw_right(i,j,me,3) = Lx * (q(i,j+1,me,2)-q(i,j,me,2))
  //
  //      dw_left(i,j,me,1)  = Lx * (q(i,j,me,1)-q(i-1,j,me,1))
  //      dw_left(i,j,me,2)  = Lx * (q(i,j,me,2)-q(i-1,j,me,2))
  //      dw_left(i,j,me,3)  = Lx * (q(i,j,me,2)-q(i,j-1,me,2))
  //
  //      wy_cent(i,j,me,1)  = Ly * q(i,j,me,3)
  //      wy_cent(i,j,me,2)  = Ly * q(i,j,me,4)
  //      wy_cent(i,j,me,3)  = Ly * q(i,j,me,6)
  //
  //      dw_up(i,j,me,1)    = Ly * (q(i,j+1,me,1)-q(i,j,me,1))
  //      dw_up(i,j,me,2)    = Ly * (q(i+1,j,me,3)-q(i,j,me,3))
  //      dw_up(i,j,me,3)    = Ly * (q(i,j+1,me,3)-q(i,j,me,3))
  //
  //      dw_down(i,j,me,1)  = Ly * (q(i,j,me,1)-q(i,j-1,me,1))
  //      dw_down(i,j,me,2)  = Ly * (q(i,j,me,3)-q(i-1,j,me,3))
  //      dw_down(i,j,me,3)  = Ly * (q(i,j,me,3)-q(i,j-1,me,3))
  //
  // ---------------------------------------------------------- 
  
  // Moment limiter (highest to lowest)
  switch ( method1 )
    {
    case 2:  // 2nd order in space   
      
      // Convert to characteristic variables in x-direction
      ConvertQtoW(1,aux,q,dw_right,dw_left,wx_cent,ProjectLeftEig);
      
      // Convert to characteristic variables in y-direction
      ConvertQtoW(2,aux,q,dw_up,dw_down,wy_cent,ProjectLeftEig);
      
      // Limit in both the x-direction and the y-direction
#pragma omp parallel for
      for (int i=(3-mbc); i<=(mx+mbc-2); i++)	
	for (int j=(3-mbc); j<=(my+mbc-2); j++)	  
	  for (int m=1; m<=meqn; m++)
	    {
	      // x-direction: limit linear term
	      double dwp        = dw_right.get(i,j,m,1);
	      double dwm        =  dw_left.get(i,j,m,1);
	      double wx_now     =  wx_cent.get(i,j,m,1);
	      double wx_limited = minmod(wx_now, dwp/sq3, dwm/sq3);
              
	      wx_cent.set(i,j,m,1, wx_limited );
	      
	      // y-direction: limit linear term
	      dwp        =    dw_up.get(i,j,m,1);
	      dwm        =  dw_down.get(i,j,m,1);
	      double wy_now     =  wy_cent.get(i,j,m,1);
	      double wy_limited = minmod(wy_now, dwp/sq3, dwm/sq3);
	      
	      wy_cent.set(i,j,m,1, wy_limited );
	    }

      // Convert back to conserved variables in x-direction
      ConvertWtoQ(1,aux,q,wx_cent,q,ProjectRightEig);
      
      // Convert back to conserved variables in y-direction
      ConvertWtoQ(2,aux,q,wy_cent,q,ProjectRightEig);
      
      break;

    case 3:  // 3rd order in space
      
      // for this limiter there is actually no reason to
      // transform the higher-order terms.  This should
      // be changed to accelerate the code.
      //
      // Convert to characteristic variables in x-direction
      ConvertQtoW(1,aux,q,dw_right,dw_left,wx_cent,ProjectLeftEig);
      //
      // Convert to characteristic variables in y-direction
      ConvertQtoW(2,aux,q,dw_up,dw_down,wy_cent,ProjectLeftEig);
      
#undef report_stats
// so that we don't waste computation time if we won't report
#ifdef report_stats
  #define increment(a) a++
#else
  #define increment(a) (void)0
#endif
      const double dx=dogParamsCart2.get_dx();
      const double dy=dogParamsCart2.get_dy();
      // this should be made a configurable parameter
      const double M=0.; //.01; //M=.000050;
      const double Mdx2=M*dx*dx;
      const double Mdy2=M*dy*dy;
#ifdef report_stats
// the accumulation of these variables is not parallelized
      int nx_steep = 0;
      int nxL1 = 0;
      int nxL_mxd = 0;
      int nxL_quad = 0;
      int nxL_1and2 = 0;
      int n = 0;

      int ny_steep = 0;
      int nyL1 = 0;
      int nyL_mxd = 0;
      int nyL_quad = 0;
      int nyL_1and2 = 0;
#endif
#pragma omp parallel for
      for (int i=(3-mbc); i<=(mx+mbc-2); i++)	
	for (int j=(3-mbc); j<=(my+mbc-2); j++)	      
	  for (int m=1; m<=meqn; m++)
	    {
              increment(n);
              // limit terms in x direction
              bool limited_linear = false;
              if(1)
              {
		// x-direction: limit linear term
                bool limited_linear_x=false;
                if(1)
                {
		  double wx_now     =  wx_cent.get(i,j,m,1);
                  if(fabs(wx_now) > Mdx2) // so the peaks aren't clipped
                  {
                    increment(nx_steep);
		    double dwp        = dw_right.get(i,j,m,1);
		    double dwm        =  dw_left.get(i,j,m,1);
		    double wx_limited = minmod(wx_now, dwp/sq3, dwm/sq3);
                    if(wx_now!=wx_limited)
                    {
                      increment(nxL1);
                      limited_linear_x=true;
                      limited_linear=true;
		      wx_cent.set(i,j,m,1, wx_limited );
                      // zero out higher-order terms
                      //{
		      //  wx_cent.set(i,j,m,2, 0. );
		      //  wx_cent.set(i,j,m,3, 0. );
                      //}
                    }
                  }
                }
              }
	      
              // limit terms in y direction
              if(1)
              {
		// y-direction: limit linear term
                bool limited_linear_y = false;
                if(1)
                {
		  double wy_now     =  wy_cent.get(i,j,m,1);
                  if(fabs(wy_now) > Mdy2) // so the peaks aren't clipped
                  {
                    increment(ny_steep);
		    double dwp        =    dw_up.get(i,j,m,1);
		    double dwm        =  dw_down.get(i,j,m,1);
		    double wy_limited = minmod(wy_now, dwp/sq3, dwm/sq3);
                    if(wy_now!=wy_limited)
                    {
                      increment(nyL1);
                      limited_linear_y = true;
                      limited_linear = true;
		      wy_cent.set(i,j,m,1, wy_limited );
                      // zero out higher-order terms
                      //{
		      //  wy_cent.set(i,j,m,2, 0. );
		      //  wy_cent.set(i,j,m,3, 0. );
                      //}
                    }
                  }
                }

                if(limited_linear)
                {
		  wx_cent.set(i,j,m,2, 0. );
		  wx_cent.set(i,j,m,3, 0. );
		  wy_cent.set(i,j,m,2, 0. );
		  wy_cent.set(i,j,m,3, 0. );
                }
	      }
	    }
#ifdef report_stats
      if(nx_steep > 0)
      {
        printf("n=%4d, nx_steep=%4d, nxL1=%4d"
               "\n",
          n, nx_steep, nxL1);
      }
      if(ny_steep > 0)
      {
        printf("n=%4d, ny_steep=%4d, nyL1=%4d"
               "\n",
          n, ny_steep, nyL1);
      }
#endif
           	    
      // Convert back to conserved variables in x-direction
      ConvertWtoQ(1,aux,q,wx_cent,q,ProjectRightEig);

      // Convert back to conserved variables in y-direction
      ConvertWtoQ(2,aux,q,wy_cent,q,ProjectRightEig);
      
      break;          
    }
  
}
示例#10
0
void evolve(double *h,double *G, double *hblank,double *Gblank,double *bed,double g,double *u0,double *u1,double *h0,double *h1,double *b0,double *b1,double theta, int n, int nBC,double dx,double dt)
{
    
    //get averages
    double idx = 1.0 / dx;  

	double *u = malloc(n*sizeof(double));
	int i,j;
	int nBCn = 3;
    double th,hx,bx,bxx,D,ai,bi,ci,gb1,gb2,gb3,ge1,ge2,ge3;
    
    //calculate u at time step
	//getufromG(h,G,bed, u, u0[nBC - 1], u1[0], h0[nBC - 1], h1[0], b0[nBC - 1], b1[0], n,dx);
	// u seems to be the problem here
	getufromG(h,G,bed,u0[nBC - 1], u1[0], h0[nBC - 1], h1[0],b0[nBC - 1], b1[0],dx,n,u);
    
    //boundaries
    //beginning
    //i=-1
    i = -1;
    j = nBC-1;
    th = h0[j];
    hx = 0.5*idx*(h[i+1] - h0[j-1]);
    bx = 0.5*idx*(bed[i+1] - b0[j-1]);
    bxx =idx*idx*(bed[i+1] -2*b0[j] + b0[j-1]);
    
    D = th + th*hx*bx + 0.5*th*th*bxx + th*bx*bx;
    
    ai = th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    bi = D + 2.0*i3*th*th*th*(idx*idx);
    ci = -1.0*th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    
    gb3 = ai*u0[j-1] + bi*u0[j] +ci*u[i+1];
	//printf("uim1 : %f | ui : %f | uip1 : %f\n",u0[j-1],u0[j],u[i+1]);
	//printf("uip2 : %f | uip3 : %f | uip4 : %f\n",u[i+2],u[i+3], u[i+4]);
    
    //i=-2
    i = -2;
    j = nBC -2;
    th = h0[j];
    hx = 0.5*idx*(h0[j+1] - h0[j-1]);
    bx = 0.5*idx*(b0[j+1] - b0[j-1]);
    bxx = idx*idx*(b0[j+1] - 2*b0[j] + b0[j+1]);
    
    D = th + th*hx*bx + 0.5*th*th*bxx + th*bx*bx;
    
    ai = th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    bi = D + 2.0*i3*th*th*th*(idx*idx);
    ci = -1.0*th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    
    gb2 = ai*u0[j-1] + bi*u0[j] +ci*u0[j+1];
    
    //i=-3
    i = -3;
    j = nBC -3;
    th = h0[j];
    hx = 0.5*idx*(h0[j+1] - h0[j-1]);
    bx = 0.5*idx*(b0[j+1] - b0[j-1]);
    bxx = idx*idx*(b0[j+1] - 2*b0[j] + b0[j+1]);
    
    D = th + th*hx*bx + 0.5*th*th*bxx + th*bx*bx;
    
    ai = th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    bi = D + 2.0*i3*th*th*th*(idx*idx);
    ci = -1.0*th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    
    gb1 = ai*u0[j-1] + bi*u0[j] +ci*u0[j+1];
    
    //i = n
    i = n;
    j = 0;
    th = h1[j];
    hx = 0.5*idx*(h1[j+1] - h[i-1]);
    bx = 0.5*idx*(b1[j+1] - bed[i-1]);
    bxx = idx*idx*(b1[j+1] - 2*b1[j] + bed[i-1]);
    
    D = th + th*hx*bx + 0.5*th*th*bxx + th*bx*bx;
    
    ai = th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    bi = D + 2.0*i3*th*th*th*(idx*idx);
    ci = -1.0*th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    
    ge1 = ai*u[i-1] + bi*u1[j] + ci*u1[j+1];
    
    //i = n+1
    j = 1;
    th = h1[j];
    hx = 0.5*idx*(h1[j+1] - h1[j-1]);
    bx = 0.5*idx*(b1[j+1] - b1[j-1]);
    bxx = idx*idx*(b1[j+1] - 2*b1[j] + b1[j-1]);
    
    D = th + th*hx*bx + 0.5*th*th*bxx + th*bx*bx;
    
    ai = th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    bi = D + 2.0*i3*th*th*th*(idx*idx);
    ci = -1.0*th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    
    ge2 = ai*u1[j-1] + bi*u1[j] +ci*u1[j+1];
    
    //i = n+2    
    j = 2;
    th = h1[j];
    hx = 0.5*idx*(h1[j+1] - h1[j-1]);
    bx = 0.5*idx*(b1[j+1] - b1[j-1]);
    bxx = idx*idx*(b1[j+1] - 2*b1[j] + b1[j-1]);
    
    D = th + th*hx*bx + 0.5*th*th*bxx + th*bx*bx;
    
    ai = th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    bi = D + 2.0*i3*th*th*th*(idx*idx);
    ci = -1.0*th*th*hx*(0.5*idx) - i3*th*th*th*(idx*idx);
    
    ge3 = ai*u1[j-1] + bi*u1[j] +ci*u1[j+1];
    
    

    double *ubeg = malloc(nBCn*sizeof(double));
    double *uend = malloc(nBCn*sizeof(double));
    double *bbeg = malloc(nBCn*sizeof(double));
    double *bend = malloc(nBCn*sizeof(double));
    double *hbeg = malloc(nBCn*sizeof(double));
    double *hend = malloc(nBCn*sizeof(double));
    double *gbeg = malloc(nBCn*sizeof(double));
    double *gend = malloc(nBCn*sizeof(double));


	ubeg[0] = u0[1];
	ubeg[1] = u0[2];
	ubeg[2] = u0[3];

	hbeg[0] = h0[1];
	hbeg[1] = h0[2];
	hbeg[2] = h0[3];

	bbeg[0] = b0[1];
	bbeg[1] = b0[2];
	bbeg[2] = b0[3];

	uend[0] = u1[0];
	uend[1] = u1[1];
	uend[2] = u1[2];

	hend[0] = h1[0];
	hend[1] = h1[1];
	hend[2] = h1[2];

	bend[0] = b1[0];
	bend[1] = b1[1];
	bend[2] = b1[2];

    gbeg[0] = gb1;
    gbeg[1] = gb2;
    gbeg[2] = gb3;
    
    gend[0] = ge1;
    gend[1] = ge2;
    gend[2] = ge3;

	//printf("gb1 : %f | gb2 : %f | gb3 : %f \n",gb1,gb2,gb3);
	//printf("ge1 : %f | ge2 : %f | ge3 : %f \n",ge1,ge2,ge3);
    
    double *Gbc = malloc((n + 2*nBCn)*sizeof(double));
    double *hbc = malloc((n + 2*nBCn)*sizeof(double));
    double *ubc = malloc((n + 2*nBCn)*sizeof(double));
    double *bedbc = malloc((n + 2*nBCn)*sizeof(double));

    conc(gbeg,G,gend,nBCn,n,nBCn,Gbc);
    conc(hbeg,h,hend,nBCn,n,nBCn,hbc);
    conc(bbeg,bed,bend,nBCn,n,nBCn,bedbc);
    conc(ubeg,u,uend,nBCn,n,nBCn,ubc);
        
    //do normal stuff 

    double wi,wip1,wip2,wip3,wim1,wim2,dwib,dwif,dwim,dhib,dhif,dhim,dGib,dGif,dGim;
    double duib,duif,duim, dwi,dhi, dGi, dui;
    double hir,wir,Gir,uir,bir,hil,wil,Gil,uil,bil;  
        
    //i = 2
    i = nBCn -1;
    //define the stage
    wi = hbc[i] + bedbc[i];
    wip1 = hbc[i+1] + bedbc[i+1];
    wip2 = hbc[i+2] + bedbc[i+2];
    wip3 = hbc[i+3] + bedbc[i+3];
    wim1 = hbc[i-1] + bedbc[i-1];
    wim2 = hbc[i-2] + bedbc[i-2];
        
    //reconstruct common values first
        
    //i left and right
        
    //gradients
    dwib = (wi - wim1);
    dwif = (wip1 - wi);
    dwim = 0.5*(wip1 - wim1);
    dhib = (hbc[i] - hbc[i-1]);
    dhif = (hbc[i+1] - hbc[i]);
    dhim = 0.5*(hbc[i+1] - hbc[i-1]);
    dGib = (Gbc[i] - Gbc[i-1]);
    dGif = (Gbc[i+1] - Gbc[i]);
    dGim = 0.5*(Gbc[i+1] - Gbc[i-1]);
    duib = (ubc[i] - ubc[i-1]);
    duif = (ubc[i+1] - ubc[i]);
    duim = 0.5*(ubc[i+1] - ubc[i-1]);
        
    //limiting
    dwi = minmod(theta*dwib,theta*dwif,dwim);
    dhi = minmod(theta*dhib,theta*dhif,dhim);
    dGi = minmod(theta*dGib,theta*dGif,dGim);
    dui = minmod(theta*duib,theta*duif,duim);
      
    //reconstruct right
    hir = hbc[i]+ 0.5*dhi;
    wir = wi + 0.5*dwi;
    Gir = Gbc[i] + 0.5*dGi;
    uir = ubc[i] + 0.5*dui;
    bir = wir - hir;
        
    //reconstruct left
    hil = hbc[i] - 0.5*dhi;
    wil = wi - 0.5*dwi;
    Gil = Gbc[i] - 0.5*dGi;
    uil = ubc[i] - 0.5*dui;
    bil = wil - hil;
        
    //only left of i+1 common but do both

    double dwip1b,dwip1f,dwip1m,dhip1b,dhip1f,dhip1m,dGip1b,dGip1f,dGip1m;
    double duip1b,duip1f,duip1m, dwip1,dhip1, dGip1, duip1;
    double hip1r,wip1r,Gip1r,uip1r,bip1r,hip1l,wip1l,Gip1l,uip1l,bip1l; 
        
    //gradients
    dwip1b = (wip1 - wi);
    dwip1f = (wip2 - wip1);
    dwip1m = 0.5*(wip2 - wi);
    dhip1b = (hbc[i+1] - hbc[i]);
    dhip1f = (hbc[i+2] - hbc[i+1]);
    dhip1m = 0.5*(hbc[i+2] - hbc[i]);
    dGip1b = (Gbc[i+1] - Gbc[i]);
    dGip1f = (Gbc[i+2] - Gbc[i+1]);
    dGip1m = 0.5*(Gbc[i+2] - Gbc[i]);
    duip1b = (ubc[i+1] - ubc[i]);
    duip1f = (ubc[i+2] - ubc[i+1]);
    duip1m = 0.5*(ubc[i+2] - ubc[i]);
        
    //limiting
    dwip1 = minmod(theta*dwip1b,theta*dwip1f,dwip1m);
    dhip1 = minmod(theta*dhip1b,theta*dhip1f,dhip1m);
    dGip1 = minmod(theta*dGip1b,theta*dGip1f,dGip1m);
    duip1 = minmod(theta*duip1b,theta*duip1f,duip1m);
        
    //reconstruct right
    hip1r = hbc[i+1] + 0.5*dhip1;
    wip1r = wip1 + 0.5*dwip1;
    Gip1r = Gbc[i+1] + 0.5*dGip1;
    uip1r = ubc[i+1] + 0.5*duip1;
    bip1r = wip1r - hip1r;
        
    //reconstruct left
    hip1l = hbc[i+1] - 0.5*dhip1;
    wip1l = wip1 - 0.5*dwip1;
    Gip1l = Gbc[i+1] - 0.5*dGip1;
    uip1l = ubc[i+1] - 0.5*duip1;
    bip1l = wip1l - hip1l;
        
        
    //only right of i-1
    //i-1  right

    double dwim1b,dwim1f,dwim1m,dhim1b,dhim1f,dhim1m,dGim1b,dGim1f,dGim1m;
    double duim1b,duim1f,duim1m, dwim1,dhim1, dGim1, duim1;
    double him1r,wim1r,Gim1r,uim1r,bim1r,him1l,wim1l,Gim1l,uim1l,bim1l; 
        
    //gradients
    dwim1b = (wim1 - wim2);
    dwim1f = (wi - wim1);
    dwim1m = 0.5*(wi - wim2);
    dhim1b = (hbc[i-1] - hbc[i-2]);
    dhim1f = (hbc[i] - hbc[i-1]);
    dhim1m = 0.5*(hbc[i] - hbc[i-2]);
    dGim1b = (Gbc[i-1] - Gbc[i-2]);
    dGim1f = (Gbc[i] - Gbc[i-1]);
    dGim1m = 0.5*(Gbc[i] - Gbc[i-2]);
    duim1b = (ubc[i-1] - ubc[i-2]);
    duim1f = (ubc[i] - ubc[i-1]);
    duim1m = 0.5*(ubc[i] - ubc[i-2]);
        
    //limiting
    dwim1 = minmod(theta*dwim1b,theta*dwim1f,dwim1m);
    dhim1 = minmod(theta*dhim1b,theta*dhim1f,dhim1m);
    dGim1 = minmod(theta*dGim1b,theta*dGim1f,dGim1m);
    duim1 = minmod(theta*duim1b,theta*duim1f,duim1m);
        
    //reconstruct right
    him1r = hbc[i-1] + 0.5*dhim1;
    wim1r = wim1 + 0.5*dwim1;
    Gim1r = Gbc[i-1] + 0.5*dGim1;
    uim1r = ubc[i-1] + 0.5*duim1;
    bim1r = wim1r - him1r;
        
    //reconstruct i+2 left
    double dwip2b,dwip2f,dwip2m,dhip2b,dhip2f,dhip2m,dGip2b,dGip2f,dGip2m;
    double duip2b,duip2f,duip2m,dwip2,dhip2, dGip2, duip2;
    double hip2r,wip2r,Gip2r,uip2r,bip2r,hip2l,wip2l,Gip2l,uip2l,bip2l; 
    
    //gradients
    dwip2b = (wip2 - wip1);
    dwip2f = (wip3 - wip2);
    dwip2m = 0.5*(wip3 - wip1);
    dhip2b = (hbc[i+2] - hbc[i+1]);
    dhip2f = (hbc[i+3] - hbc[i+2]);
    dhip2m = 0.5*(hbc[i+3] - hbc[i+1]);
    dGip2b = (Gbc[i+2] - Gbc[i+1]);
    dGip2f = (Gbc[i+3] - Gbc[i+2]);
    dGip2m = 0.5*(Gbc[i+3] - Gbc[i+1]);
    duip2b = (ubc[i+2] - ubc[i+1]);
    duip2f = (ubc[i+3] - ubc[i+2]);
    duip2m = 0.5*(ubc[i+3] - ubc[i+1]);
        
    //limiting
    dwip2 = minmod(theta*dwip2b,theta*dwip2f,dwip2m);
    dhip2 = minmod(theta*dhip2b,theta*dhip2f,dhip2m);
    dGip2 = minmod(theta*dGip2b,theta*dGip2f,dGip2m);
    duip2 = minmod(theta*duip2b,theta*duip2f,duip2m);
                
    //reconstruct left
    hip2l = hbc[i+2] - 0.5*dhip2;
    wip2l = wip2 - 0.5*dwip2;
    Gip2l = Gbc[i+2] - 0.5*dGip2;
    uip2l = ubc[i+2] - 0.5*duip2;
    bip2l = wip2l - hip2l;
    
    //calculate forces          
    double nbi,hihm,hihp,her,Ger,uer,hel,Gel,uel, himhp; 
    double duer,duel,dber,dbel,sqrtghel,sqrtgher,sl,sr,felh,felG,ferh,ferG,isrmsl;   
    double foh,foG,fih,fiG;
        
    //right force i
    nbi = fmax(bip1l,bir);
    hihm = fmax(0,wir-nbi);
    hihp = fmax(0,wip1l-nbi);

    her = hihp;
    Ger = Gip1l;
    uer = uip1l;
        
    hel = hihm;
    Gel = Gir;
    uel = uir;

	//do u like o2fix
	double ue = 0.5*(ubc[i+1]+ubc[i]);
	double due = idx*(ubc[i+1] - ubc[i]);

	double dbe = idx*(bedbc[i+1] - bedbc[i]);

	uer = ue;
	uel = ue;
	duer = due;
	duel = due;
	dber = dbe;
	dbel = dbe;

        
    //duer = idx*(uip2l - uip1l);
    dber = idx*(bip2l - bip1l);
            
    //duel = idx*(uir - uim1r);
    dbel = idx*(bir - bim1r);
        
    sqrtghel = sqrt(g*hel);
    sqrtgher = sqrt(g*her);
    sl = fmin(0, fmin(uel - sqrtghel, uer - sqrtgher));
    sr = fmax(0,fmax(uel + sqrtghel, uer + sqrtgher));
        
    felh = uel*hel;
    felG = Gel*uel + 0.5*g*hel*hel - 2*i3*hel*hel*hel*duel*duel + hel*hel*uel*duel*dbel;
    ferh = uer*her;
    ferG = Ger*uer + 0.5*g*her*her - 2*i3*her*her*her*duer*duer + her*her*uer*duer*dber;

	//printf("%d || hihm - hir : %e || hihp - wip1l : %e\n", i, hihm - hir,hihp - wip1l);
  
    isrmsl = 0.0;

    if(sr != sl) isrmsl = 1.0 / (sr - sl);

    foh = isrmsl*(sr*felh - sl*ferh + sl*sr*(her - hel ));
    foG = isrmsl*(sr*felG - sl*ferG + sl*sr*(Ger - Gel ));
    
    fih = foh;
    fiG = foG;
    himhp = hihp;
        
    him1r = hir;
    wim1r = wir;
    bim1r = bir;
    Gim1r = Gir;
    uim1r = uir;
        
    hil = hip1l;
    wil = wip1l;
    bil = bip1l;
    Gil = Gip1l;
    uil = uip1l;
        
    hir = hip1r;
    wir = wip1r;
    bir = bip1r;
    Gir = Gip1r;
    uir = uip1r;
    
    hip1l = hip2l;
    wip1l = wip2l;
    bip1l = bip2l;
    Gip1l = Gip2l;
    uip1l = uip2l;      
    
    dhip1 = dhip2;
    dwip1 = dwip2;
    duip1 = duip2;
    dGip1 = dGip2;
    
	for(i = nBCn; i < n + nBCn; i++)
    {
        //update both forces at same time

        //define the stage
        wi = hbc[i] + bedbc[i];
        wip1 = hbc[i+1]  + bedbc[i+1];
        wip2 = hbc[i+2]  + bedbc[i+2];
        wip3 = hbc[i+3] + bedbc[i+3];
        wim1 = hbc[i-1]  + bedbc[i-1];
        wim2 = hbc[i-2]  + bedbc[i-2];
        
        //reconstruct common values first
                
        //only left of i+1 common but do both   
        
        //reconstruct right
        hip1r = hbc[i+1] + 0.5*dhip1;
        wip1r = wip1 + 0.5*dwip1;
        Gip1r = Gbc[i+1] + 0.5*dGip1;
        uip1r = ubc[i+1] + 0.5*duip1;
        bip1r = wip1r - hip1r;
        
        
        //reconstruct i+2 left
        
        //gradients
        dwip2b = (wip2 - wip1);
        dwip2f = (wip3 - wip2);
        dwip2m = 0.5*(wip3 - wip1);
        dhip2b = (hbc[i+2] - hbc[i+1]);
        dhip2f = (hbc[i+3] - hbc[i+2]);
        dhip2m = 0.5*(hbc[i+3] - hbc[i+1]);
        dGip2b = (Gbc[i+2] - Gbc[i+1]);
        dGip2f = (Gbc[i+3] - Gbc[i+2]);
        dGip2m = 0.5*(Gbc[i+3] - Gbc[i+1]);
        duip2b = (ubc[i+2] - ubc[i+1]);
        duip2f = (ubc[i+3] - ubc[i+2]);
        duip2m = 0.5*(ubc[i+3] - ubc[i+1]);
        
        //limiting
        dwip2 = minmod(theta*dwip2b,theta*dwip2f,dwip2m);
        dhip2 = minmod(theta*dhip2b,theta*dhip2f,dhip2m);
        dGip2 = minmod(theta*dGip2b,theta*dGip2f,dGip2m);
        duip2 = minmod(theta*duip2b,theta*duip2f,duip2m);
                
        //reconstruct left
        hip2l = hbc[i+2] - 0.5*dhip2;
        wip2l = wip2 - 0.5*dwip2;
        Gip2l = Gbc[i+2] - 0.5*dGip2;
        uip2l = ubc[i+2] - 0.5*duip2;
        bip2l = wip2l - hip2l;


                
        //calculate forces              
        
        //right force i
        nbi = fmax(bip1l,bir);
        hihm = fmax(0.0,wir-nbi);
        hihp = fmax(0.0,wip1l-nbi);

		//printf("%d || hihm - hir : %e || hihp - wip1l : %e\n", i, hihm - hir,hihp - wip1l);

        her = hihp;
        Ger = Gip1l;
        uer = uip1l;
        
        hel = hihm;
        Gel = Gir;
        uel = uir;
        
        duer = idx*(uip2l - uip1l);
        dber = idx*(bip2l - bip1l);

            
        duel = idx*(uir - uim1r);
        dbel = idx*(bir - bim1r);

		ue = 0.5*(ubc[i+1]+ubc[i]);
		due = idx*(ubc[i+1] - ubc[i]);

		dbe = idx*(bedbc[i+1] - bedbc[i]);

		uer = ue;
		uel = ue;
		duer = due;
		duel = due;
		dber = dbe;
		dbel = dbe;
        
        sqrtghel = sqrt(g*hel);
        sqrtgher = sqrt(g*her);
        sl = fmin(0,fmin(uel - sqrtghel, uer - sqrtgher));
        sr = fmax(0,fmax(uel + sqrtghel, uer + sqrtgher));
        
        felh = uel*hel;
        felG = Gel*uel + 0.5*g*hel*hel - 2*i3*hel*hel*hel*duel*duel + hel*hel*uel*duel*dbel;
        ferh = uer*her;
        ferG = Ger*uer + 0.5*g*her*her - 2*i3*her*her*her*duer*duer + her*her*uer*duer*dber;

        isrmsl = 0.0;

        if(sr != sl) isrmsl = 1.0 / (sr - sl);
        foh = isrmsl*(sr*felh - sl*ferh + sl*sr*(her - hel ));
        foG = isrmsl*(sr*felG - sl*ferG + sl*sr*(Ger - Gel ));
        
        double th,tu,tux,tbx,tbxx, sourcer, sourcec, sourcel;
        //calculate the source term
        th = hbc[i];
        tu = ubc[i];
        tux = 0.5*idx*(ubc[i+1] - ubc[i-1]);
        tbx = 0.5*idx*(bedbc[i+1] - bedbc[i-1]);
        tbxx = idx*idx*(bedbc[i+1] - 2*bedbc[i] + bedbc[i-1]);
        
        sourcer = g*0.5*(hihm*hihm - hir*hir);
        sourcec = g*th*tbx +  0.5*th*th*tu*tux*tbxx - th*tu*tu*tbx*tbxx ;
        sourcel = g*0.5*(hil*hil - himhp*himhp);

		//printf("%d | Source: %e\n",i, dt*idx*(sourcer+sourcel + sourcec));
        
        hblank[i-nBCn] = hbc[i] - dt*idx*(foh - fih);
        Gblank[i-nBCn] = Gbc[i] - dt*idx*(foG - fiG) + dt*idx*(sourcer+sourcel + sourcec);
        
        fih = foh;
        fiG = foG;
        himhp = hihp;
        
        him1r = hir;
        wim1r = wir;
        bim1r = bir;
        Gim1r = Gir;
        uim1r = uir;
        
        hil = hip1l;
        wil = wip1l;
        bil = bip1l;
        Gil = Gip1l;
        uil = uip1l;
        
        hir = hip1r;
        wir = wip1r;
        bir = bip1r;
        Gir = Gip1r;
        uir = uip1r;
    
        hip1l = hip2l;
        wip1l = wip2l;
        bip1l = bip2l;
        Gip1l = Gip2l;
        uip1l = uip2l;      
        
    
        dhip1 = dhip2;
        dwip1 = dwip2;
        duip1 = duip2;
        dGip1 = dGip2;
    }
        
    free(u);
    free(ubeg);
    free(uend);
    free(bbeg);
    free(bend);
    free(hbeg);
    free(hend);
    free(gbeg);
    free(gend);
    free(Gbc);
    free(hbc);
    free(ubc);
    free(bedbc);

}
示例#11
0
/**
 * @brief
 * Use minmod function to limit the gradient and get the linear 
 * limited result.
 * 
 * Usages:
 *		shape = mesh.Shape;
 * 		hlim  = Minmod1d_Mex...
 *			(h, mesh.J, shape.M, shape.Fmask, mesh.EToE, mesh.x)
 */
void mexFunction (int nlhs, mxArray *plhs[], 
	int nrhs, const mxArray *prhs[]){

	/* check input & output */
	if (nrhs != 6)
		mexErrMsgTxt("Wrong number of input arguments.");
	if (nlhs != 1)
		mexErrMsgTxt("Wrong number of output arguments");

	/* get inputs */
	real *h    = mxGetPr(prhs[0]);
	real *J    = mxGetPr(prhs[1]);
	real *M    = mxGetPr(prhs[2]);
	real *Fmask= mxGetPr(prhs[3]);
	real *EToE = mxGetPr(prhs[4]);
	real *x    = mxGetPr(prhs[5]);
	
	/* get dimensions */
	size_t Np, K;
	Np = mxGetM(prhs[0]); 
	K  = mxGetN(prhs[0]);
	size_t Nfaces,Nfp;
	Nfaces = mxGetM(prhs[3]);
	Nfp    = mxGetN(prhs[3]);

	/* allocation of output */
	plhs[0] = mxCreateDoubleMatrix((mwSize)Np, (mwSize)K, mxREAL);
	real *hlim = mxGetPr(plhs[0]);

	/* cell averages */
	real *hmean = (real*) malloc(sizeof(real)*K );
	real *area  = (real*) malloc(sizeof(real)*K );
	//elemental integral coefficient
	real *w     = (real*) malloc(sizeof(real)*Np); 
	int i,j,k,sk;
	for(i=0;i<Np;i++){
		w[i] = 0.0;
		for(j=0;j<Np;j++){
			w[i] += M[i*Np + j];
		}
	}
	for (k=0;k<K;k++){
		area [k] = 0.0;
		hmean[k] = 0.0;
		for(i=0;i<Np;i++){
			sk = (k*Np + i);
			hmean[k] += w[i]*J[sk]*h[sk];
			area [k] += w[i]*J[sk];
		}
		hmean[k] /= area[k];
	}

	// reconstruct over each cell
	int  v1  = (int) Fmask[0] - 1;
	int  v2  = (int) Fmask[1] - 1;
	for(k=0;k<K;k++){
		/* cell gradient */
		int sk1 = k*Np + v1;
		int sk2 = k*Np + v2;
		real xc  =(x[sk2] + x[sk1])/2.0;
		real dh  = h[sk2] - h[sk1];
		/* limited gradient */
		int e1 = (int)EToE[k  ] - 1;
		int e2 = (int)EToE[k+K] - 1;
		real a[3];
		a[0] = dh/area[k];
		a[1] = (hmean[e2] - hmean[k] )/area[k];
		a[2] = (hmean[k]  - hmean[e1])/area[k];
		real dhlim;
		minmod(3, a, &dhlim);
		/* reconstruction */
		for(i=0;i<Np;i++){
			sk = (k*Np + i);
            real delta = (real)(x[sk] - xc);
            hlim[sk] = hmean[k] + delta*dhlim;
		}
	}

	free(w); free(hmean); free(area);
	return;
}
示例#12
0
void test_minmod()
{
  double a[3];
  double b[3];
  a[2] = 2.;
  a[1] = 1.;
  a[0] = 0.;
  b[2] = -2.;
  b[1] = -1.;
  b[0] = -0.;
  for(int i=0;i<3;i++)
  {
    printf(
      " signbit(a[%d]) = %d"
      " signbit(b[%d]) = %d\n",
      i, signbit(a[i]),
      i, signbit(b[i])
    );
    for(int j=0;j<3;j++)
    {
      printf(
        " minmod(a[%d],b[%d]) = %f "
        " minmod(a[%d],a[%d]) = %f "
        " minmod(b[%d],b[%d]) = %f "
        " minmod(b[%d],a[%d]) = %f \n",
        i,j, minmod(a[i],b[j]),
        i,j, minmod(a[i],a[j]),
        i,j, minmod(b[i],b[j]),
        i,j, minmod(b[i],a[j])
      );
    }
  }
  for(int i=0;i<3;i++)
  for(int j=0;j<3;j++)
  for(int k=0;k<3;k++)
  {
      printf(
        " minmod(a[%d],a[%d],a[%d]) = %f "
        " minmod(b[%d],b[%d],b[%d]) = %f \n",
        i,j,k, minmod(a[i],a[j],a[k]),
        i,j,k, minmod(b[i],b[j],b[k]));
  }
  for(int i=0;i<3;i++)
  for(int j=0;j<3;j++)
  {
      printf(
        " minmod(a[ 0],a[%d],a[%d]) = %f "
        " minmod(a[%d],a[ 0],a[%d]) = %f "
        " minmod(a[%d],a[%d],a[ 0]) = %f "
        " minmod(b[ 0],b[%d],b[%d]) = %f "
        " minmod(b[%d],b[ 0],b[%d]) = %f "
        " minmod(b[%d],b[%d],b[ 0]) = %f \n",
        i,j, minmod(a[ 0],a[ i],a[ j]),
        i,j, minmod(a[ i],a[ 0],a[ j]),
        i,j, minmod(a[ i],a[ j],a[ 0]),
        i,j, minmod(b[ 0],b[ i],b[ j]),
        i,j, minmod(b[ i],b[ 0],b[ j]),
        i,j, minmod(b[ i],b[ j],b[ 0]));
  }
}
示例#13
0
// -------------------------------------------------------------------------- //
//
// Limiter based on a modification of the following paper:
//      L. Krivodonova. "Limiters for high-order discontinuous
//      Galerkin methods." J. Comp. Phys., Vol. 226, pg 879-896.
//
// For systems, we have orders 1--3 implemented.  For scalar problems, we have
// orders 1--5 implemented.  This routine calls ApplyScalarLimiter in the scalar
// case.
//
// -------------------------------------------------------------------------- //
void ApplyLimiterKrivodonova(dTensorBC4& aux, dTensorBC4& q,
     void (*ProjectRightEig)(int ixy, // Component of flux function (1 or 2)
            const dTensor1& Aux_ave, const dTensor1& Q_ave,   // Riemann states
            const dTensor2& Wvals,    // Characteristic variables
            dTensor2& Qvals           // Conserved variables
            ),
     void (*ProjectLeftEig)(int ixy,  // Component of flux function (1 or 2)
            const dTensor1& Aux_ave, const dTensor1& Q_ave,   // Riemann states
            const dTensor2& Qvals,    // Conserved variables
            dTensor2& Wvals)          // Characteristic variables
    )
{

    // Problem dimensions
    const int   mx = q.getsize(1);
    const int   my = q.getsize(2);
    const int meqn = q.getsize(3);
    const int kmax = q.getsize(4);
    const int mbc  = q.getmbc();
    const int maux = aux.getsize(3);

    // Number of basis functions
    const int space_order = dogParams.get_space_order();
    assert_eq(int((sqrt(1+8*kmax)-1)/2),space_order);
    const int ksize = (space_order==2)?1:3;

    // Nothing to limit in the first-order case
    if(space_order==1)
      { return; }

    // Scalar limiter is implemented for all orders up to 5.  Call this routine
    // instead if this is a scalar problem.
    if( meqn == 1 ) 
    {
        void ApplyScalarLimiter(const dTensorBC4& aux, dTensorBC4& q);
        ApplyScalarLimiter(aux, q);
        return;
    }

    // Storage
    dTensorBC4  wx_cent(mx,my,meqn,ksize,mbc);
    dTensorBC4  wy_cent(mx,my,meqn,ksize,mbc);
    dTensorBC4 dw_right(mx,my,meqn,ksize,mbc);
    dTensorBC4  dw_left(mx,my,meqn,ksize,mbc);
    dTensorBC4    dw_up(mx,my,meqn,ksize,mbc);
    dTensorBC4  dw_down(mx,my,meqn,ksize,mbc);
    void ConvertQtoW(int ixy, 
            const dTensorBC4& aux, 
            const dTensorBC4& qold, 
            dTensorBC4& dwp, 
            dTensorBC4& dwm, 
            dTensorBC4& w_cent,
            void (*ProjectLeftEig)(int,
                const dTensor1&,
                const dTensor1&,
                const dTensor2&,
                dTensor2&));
    void ConvertWtoQ(int ixy, 
            const dTensorBC4& aux, 
            const dTensorBC4& qold,
            const dTensorBC4& win, 
            dTensorBC4& qout,
            void (*ProjectRightEig)(int,
                const dTensor1&,
                const dTensor1&,
                const dTensor2&,
                dTensor2&));

    // ----------------------------------------------------------
    // Key: storage of characteristic variables
    //       
    //      wx_cent(i,j,me,1)  = Lx * q(i,j,me,2)
    //      wx_cent(i,j,me,2)  = Lx * q(i,j,me,4)
    //      wx_cent(i,j,me,3)  = Lx * q(i,j,me,5)
    //
    //      dw_right(i,j,me,1) = Lx * (q(i+1,j,me,1)-q(i,j,me,1))
    //      dw_right(i,j,me,2) = Lx * (q(i+1,j,me,2)-q(i,j,me,2))
    //      dw_right(i,j,me,3) = Lx * (q(i,j+1,me,2)-q(i,j,me,2))
    //
    //      dw_left(i,j,me,1)  = Lx * (q(i,j,me,1)-q(i-1,j,me,1))
    //      dw_left(i,j,me,2)  = Lx * (q(i,j,me,2)-q(i-1,j,me,2))
    //      dw_left(i,j,me,3)  = Lx * (q(i,j,me,2)-q(i,j-1,me,2))
    //
    //      wy_cent(i,j,me,1)  = Ly * q(i,j,me,3)
    //      wy_cent(i,j,me,2)  = Ly * q(i,j,me,4)
    //      wy_cent(i,j,me,3)  = Ly * q(i,j,me,6)
    //
    //      dw_up(i,j,me,1)    = Ly * (q(i,j+1,me,1)-q(i,j,me,1))
    //      dw_up(i,j,me,2)    = Ly * (q(i+1,j,me,3)-q(i,j,me,3))
    //      dw_up(i,j,me,3)    = Ly * (q(i,j+1,me,3)-q(i,j,me,3))
    //
    //      dw_down(i,j,me,1)  = Ly * (q(i,j,me,1)-q(i,j-1,me,1))
    //      dw_down(i,j,me,2)  = Ly * (q(i,j,me,3)-q(i-1,j,me,3))
    //      dw_down(i,j,me,3)  = Ly * (q(i,j,me,3)-q(i,j-1,me,3))
    //
    // ---------------------------------------------------------- 

    // Moment limiter (highest to lowest)
    // Reminder: this is for 3rd and 2nd-order case only.
    switch ( space_order )
    {

        default:
            unsupported_value_error(space_order);
            break;

        case 2:  // 2nd order in space   

            // Convert to characteristic variables in x-direction
            ConvertQtoW(1,aux,q,dw_right,dw_left,wx_cent,ProjectLeftEig);

            // Convert to characteristic variables in y-direction
            ConvertQtoW(2,aux,q,dw_up,dw_down,wy_cent,ProjectLeftEig);

            // Limit in both the x-direction and the y-direction
#pragma omp parallel for
            for (int i=(3-mbc); i<=(mx+mbc-2); i++)   
            for (int j=(3-mbc); j<=(my+mbc-2); j++)   
            for (int m=1; m<=meqn; m++)
            {
                // x-direction: limit linear term
                {
                    const double        dwp = dw_right.get(i,j,m,1);
                    const double        dwm =  dw_left.get(i,j,m,1);
                    const double     wx_now =  wx_cent.get(i,j,m,1);
                    const double wx_limited = minmod(wx_now, dwp/sq3, dwm/sq3);

                    wx_cent.set(i,j,m,1, wx_limited );
                }

                // y-direction: limit linear term
                {
                    const double dwp        =    dw_up.get(i,j,m,1);
                    const double dwm        =  dw_down.get(i,j,m,1);
                    const double wy_now     =  wy_cent.get(i,j,m,1);
                    const double wy_limited = minmod(wy_now, dwp/sq3, dwm/sq3);

                    wy_cent.set(i,j,m,1, wy_limited );
                }
            }

            // Convert back to conserved variables in x-direction
            ConvertWtoQ(1,aux,q,wx_cent,q,ProjectRightEig);

            // Convert back to conserved variables in y-direction
            ConvertWtoQ(2,aux,q,wy_cent,q,ProjectRightEig);

            break;

        case 3:  // 3rd order in space

            // Convert to characteristic variables in x-direction
            ConvertQtoW(1, aux, q, dw_right, dw_left, wx_cent, ProjectLeftEig);

            // Convert to characteristic variables in y-direction
            ConvertQtoW(2, aux, q, dw_up, dw_down, wy_cent, ProjectLeftEig);

            // Limit
            const double molifier = 0.6;
            const double fac1 = molifier*sq3*osq5; // osq3*osq5
            const double fac2 = molifier*osq3;     // osq3

#pragma omp parallel for
            for (int i=(3-mbc); i<=(mx+mbc-2); i++)   
            for (int j=(3-mbc); j<=(my+mbc-2); j++)       
            for (int m=1; m<=meqn; m++)
            {
                int mflag = 0;
                double dwp,dwm,wx_limited,wx_now,wy_limited,wy_now;

                // ---------------------------------------------------
                // x-direction: limit quadratic term
                dwp        = dw_right.get(i,j,m,2);
                dwm        =  dw_left.get(i,j,m,2);
                wx_now     =  wx_cent.get(i,j,m,3);
                wx_limited = minmod(wx_now, fac1*dwp, fac1*dwm);

                wx_cent.set(i,j,m,3, wx_limited );

                if (fabs(wx_now - wx_limited)>=1.0e-14 || 
                        fabs(wx_limited)<1.0e-14)
                {  mflag = 1;  }
                // ---------------------------------------------------	      

                // ---------------------------------------------------
                // y-direction: limit quadratic term
                dwp        =    dw_up.get(i,j,m,3);
                dwm        =  dw_down.get(i,j,m,3);
                wy_now     =  wy_cent.get(i,j,m,3);
                wy_limited = minmod(wy_now, fac1*dwp, fac1*dwm);

                wy_cent.set(i,j,m,3, wy_limited );

                if (fabs(wy_now - wy_limited)>=1.0e-14 ||
                        fabs(wy_limited)<1.0e-14)
                {  mflag = 1;  }
                // ---------------------------------------------------        

                if (mflag==1)
                {       
                    // ---------------------------------------------------
                    // x-direction: limit mixed term
                    dwp        = dw_right.get(i,j,m,3);
                    dwm        =  dw_left.get(i,j,m,3);
                    wx_now     =  wx_cent.get(i,j,m,2);
                    wx_limited = minmod(wx_now, fac1*dwp, fac1*dwm);

                    wx_cent.set(i,j,m,2, wx_limited );
                    // ---------------------------------------------------

                    // ---------------------------------------------------
                    // x-direction: limit linear term
                    dwp        = dw_right.get(i,j,m,1);
                    dwm        =  dw_left.get(i,j,m,1);
                    wx_now     =  wx_cent.get(i,j,m,1);
                    wx_limited = minmod(wx_now, fac2*dwp, fac2*dwm);

                    wx_cent.set(i,j,m,1, wx_limited );
                    // ---------------------------------------------------

                    // ---------------------------------------------------
                    // y-direction: limit mixed term
                    dwp        =    dw_up.get(i,j,m,2);
                    dwm        =  dw_down.get(i,j,m,2);
                    wy_now     =  wy_cent.get(i,j,m,2);
                    wy_limited = minmod(wy_now, fac1*dwp, fac1*dwm);

                    wy_cent.set(i,j,m,2, wy_limited );
                    // ---------------------------------------------------

                    // ---------------------------------------------------
                    // y-direction: limit linear term
                    dwp        =    dw_up.get(i,j,m,1);
                    dwm        =  dw_down.get(i,j,m,1);
                    wy_now     =  wy_cent.get(i,j,m,1);
                    wy_limited = minmod(wy_now, fac2*dwp, fac2*dwm);

                    wy_cent.set(i,j,m,1, wy_limited );
                    // ---------------------------------------------------
                }
            }

            // Convert back to conserved variables in x-direction
            ConvertWtoQ(1, aux, q, wx_cent, q, ProjectRightEig);

            // Convert back to conserved variables in y-direction
            ConvertWtoQ(2, aux, q, wy_cent, q, ProjectRightEig);

            break;          

    }

}