예제 #1
0
// 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;          
    }
}
예제 #2
0
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;          
    }
  
}
예제 #3
0
파일: mark.c 프로젝트: meh/screen
/* tx, ty: WINDOW,  line: DISPLAY */
void revto_line(int tx, int ty, int line)
{
	int fx, fy;
	int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
	int ystart = 0, yend = fore->w_height - 1;
	int i, ry;
	uint32_t *wi;
	struct mline *ml;
	struct mchar mc;

	if (tx < 0)
		tx = 0;
	else if (tx > fore->w_width - 1)
		tx = fore->w_width - 1;
	if (ty < 0)
		ty = 0;
	else if (ty > fore->w_histheight + fore->w_height - 1)
		ty = fore->w_histheight + fore->w_height - 1;

	fx = markdata->cx;
	fy = markdata->cy;

	/* don't just move inside of a kanji, the user wants to see something */
	ml = WIN(ty);
	if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1)
		tx++;
	if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx)
		tx--;

	markdata->cx = tx;
	markdata->cy = ty;

	/*
	 * if we go to a position that is currently offscreen
	 * then scroll the screen
	 */
	i = 0;
	if (line >= 0 && line < fore->w_height)
		i = W2D(ty) - line;
	else if (ty < markdata->hist_offset)
		i = ty - markdata->hist_offset;
	else if (ty > markdata->hist_offset + (fore->w_height - 1))
		i = ty - markdata->hist_offset - (fore->w_height - 1);
	if (i > 0)
		yend -= MarkScrollUpDisplay(i);
	else if (i < 0)
		ystart += MarkScrollDownDisplay(-i);

	if (markdata->second == 0) {
		flayer->l_x = tx;
		flayer->l_y = W2D(ty);
		LGotoPos(flayer, tx, W2D(ty));
		return;
	}

	qq = markdata->x1 + markdata->y1 * fore->w_width;
	ff = fx + fy * fore->w_width;	/* "from" offset in WIN coords */
	tt = tx + ty * fore->w_width;	/* "to" offset  in WIN coords */

	if (ff > tt) {
		st = tt;
		en = ff;
		x = tx;
		y = ty;
	} else {
		st = ff;
		en = tt;
		x = fx;
		y = fy;
	}
	if (st > qq) {
		st++;
		x++;
	}
	if (en < qq)
		en--;
	if (tt > qq) {
		revst = qq;
		reven = tt;
	} else {
		revst = tt;
		reven = qq;
	}
	ry = y - markdata->hist_offset;
	if (ry < ystart) {
		y += (ystart - ry);
		x = 0;
		st = y * fore->w_width;
		ry = ystart;
	}
	ml = WIN(y);
	for (t = st; t <= en; t++, x++) {
		if (x >= fore->w_width) {
			x = 0;
			y++, ry++;
			ml = WIN(y);
		}
		if (ry > yend)
			break;
		if (t == st || x == 0) {
			wi = ml->image + fore->w_width;
			for (ce = fore->w_width; ce >= 0; ce--, wi--)
				if (*wi != ' ')
					break;
		}
		if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar) {
			if (dw_right(ml, x, fore->w_encoding)) {
				if (t == revst)
					revst--;
				t--;
				x--;
			}
			if (t >= revst && t <= reven) {
				mc = mchar_so;
				if (pastefont) {
					mc.font = ml->font[x];
					mc.fontx = ml->fontx[x];
				}
				mc.image = ml->image[x];
			} else
				copy_mline2mchar(&mc, ml, x);
			if (dw_left(ml, x, fore->w_encoding)) {
				mc.mbcs = ml->image[x + 1];
				LPutChar(flayer, &mc, x, W2D(y));
				t++;
			}
			LPutChar(flayer, &mc, x, W2D(y));
			if (dw_left(ml, x, fore->w_encoding))
				x++;
		}
	}
	flayer->l_x = tx;
	flayer->l_y = W2D(ty);
	LGotoPos(flayer, tx, W2D(ty));
}
예제 #4
0
파일: mark.c 프로젝트: meh/screen
static int rem(int x1, int y1, int x2, int y2, int redisplay, char *pt, int yend)
{
	int i, j, from, to, ry, c;
	int l = 0;
	uint32_t *im;
	struct mline *ml;
	int cf, cfx, font;
	uint32_t *fo, *fox;

	markdata->second = 0;
	if (y2 < y1 || ((y2 == y1) && (x2 < x1))) {
		i = y2;
		y2 = y1;
		y1 = i;
		i = x2;
		x2 = x1;
		x1 = i;
	}
	ry = y1 - markdata->hist_offset;

	i = y1;
	if (redisplay != 2 && pt == 0 && ry < 0) {
		i -= ry;
		ry = 0;
	}
	for (; i <= y2; i++, ry++) {
		if (redisplay != 2 && pt == 0 && ry > yend)
			break;
		ml = WIN(i);
		from = (i == y1) ? x1 : 0;
		if (from < markdata->left_mar)
			from = markdata->left_mar;
		for (to = fore->w_width, im = ml->image + to; to >= 0; to--)
			if (*im-- != ' ')
				break;
		if (i == y2 && x2 < to)
			to = x2;
		if (to > markdata->right_mar)
			to = markdata->right_mar;
		if (redisplay == 1 && from <= to && ry >= 0 && ry <= yend)
			MarkRedisplayLine(ry, from, to, 0);
		if (redisplay != 2 && pt == 0)	/* don't count/copy */
			continue;
		j = from;
		if (dw_right(ml, j, fore->w_encoding))
			j--;
		im = ml->image + j;
		fo = ml->font + j;
		fox = ml->fontx + j;
		font = ASCII;
		for (; j <= to; j++) {
			c = (unsigned char)*im++;
			cf = (unsigned char)*fo++;
			cfx = (unsigned char)*fox++;
			if (fore->w_encoding == UTF8) {
				c |= cf << 8 | cfx << 16;
				if (c == UCS_HIDDEN)
					continue;
				c = ToUtf8_comb(pt, c);
				l += c;
				if (pt)
					pt += c;
				continue;
			}
			if (is_dw_font(cf)) {
				c = c << 8 | (unsigned char)*im++;
				fo++;
				j++;
			}
			if (pastefont) {
				c = EncodeChar(pt, c | cf << 16, fore->w_encoding, &font);
				l += c;
				if (pt)
					pt += c;
				continue;
			}
			if (pt)
				*pt++ = c;
			l++;
		}
		if (pastefont && font != ASCII) {
			if (pt) {
				strncpy(pt, "\033(B", 4);
				pt += 3;
			}
			l += 3;
		}
		if (i != y2 && (to != fore->w_width - 1 || ml->image[to + 1] == ' ')) {
			/*
			 * this code defines, what glues lines together
			 */
			switch (markdata->nonl) {
			case 0:	/* lines separated by newlines */
				if (pt)
					*pt++ = '\r';
				l++;
				if (join_with_cr) {
					if (pt)
						*pt++ = '\n';
					l++;
				}
				break;
			case 1:	/* nothing to separate lines */
				break;
			case 2:	/* lines separated by blanks */
				if (pt)
					*pt++ = ' ';
				l++;
				break;
			case 3:	/* seperate by comma, for csh junkies */
				if (pt)
					*pt++ = ',';
				l++;
				break;
			}
		}
	}
	return l;
}
예제 #5
0
파일: mark.c 프로젝트: meh/screen
static void MarkRedisplayLine(int y, int xs, int xe, int isblank)
/* NOTE: y is in DISPLAY coords system! */
{
	int wy, x, i, rm;
	int sta, sto, cp;	/* NOTE: these 3 are in WINDOW coords system */
	uint32_t *wi;
	struct mline *ml;
	struct mchar mchar_marked;

	if (y < 0)		/* No special full page handling */
		return;

	markdata = (struct markdata *)flayer->l_data;
	fore = markdata->md_window;

	mchar_marked = mchar_so;

	wy = D2W(y);
	ml = WIN(wy);

	if (markdata->second == 0) {
		if (dw_right(ml, xs, fore->w_encoding) && xs > 0)
			xs--;
		if (dw_left(ml, xe, fore->w_encoding) && xe < fore->w_width - 1)
			xe++;
		if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0)
			LCDisplayLineWrap(flayer, ml, y, xs, xe, isblank);
		else
			LCDisplayLine(flayer, ml, y, xs, xe, isblank);
		return;
	}

	sta = markdata->y1 * fore->w_width + markdata->x1;
	sto = markdata->cy * fore->w_width + markdata->cx;
	if (sta > sto) {
		i = sta;
		sta = sto;
		sto = i;
	}
	cp = wy * fore->w_width + xs;

	rm = markdata->right_mar;
	for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--)
		if (*wi != ' ')
			break;
	if (x < rm)
		rm = x;

	for (x = xs; x <= xe; x++, cp++)
		if (cp >= sta && x >= markdata->left_mar)
			break;
	if (dw_right(ml, x, fore->w_encoding))
		x--;
	if (x > xs)
		LCDisplayLine(flayer, ml, y, xs, x - 1, isblank);
	for (; x <= xe; x++, cp++) {
		if (cp > sto || x > rm)
			break;
		if (pastefont) {
			mchar_marked.font = ml->font[x];
			mchar_marked.fontx = ml->fontx[x];
		}
		mchar_marked.image = ml->image[x];
		mchar_marked.mbcs = 0;
		if (dw_left(ml, x, fore->w_encoding)) {
			mchar_marked.mbcs = ml->image[x + 1];
			cp++;
		}
		LPutChar(flayer, &mchar_marked, x, y);
		if (dw_left(ml, x, fore->w_encoding))
			x++;
	}
	if (x <= xe)
		LCDisplayLine(flayer, ml, y, x, xe, isblank);
}
예제 #6
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;          

    }

}