void LCDisplayLineWrap(Layer *l, struct mline *ml, int y, int from, int to, int isblank) { struct mchar nc; copy_mline2mchar(&nc, ml, 0); if (dw_left(ml, 0, l->l_encoding)) { nc.mbcs = ml->image[1]; from++; } LWrapChar(l, &nc, y - 1, -1, -1, false); from++; if (from <= to) LCDisplayLine(l, ml, y, from, to, isblank); }
// 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; } }
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; } }
/* 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)); }
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); }
// -------------------------------------------------------------------------- // // // 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; } }
void LayPause(Layer *layer, bool pause) { Window *win; if (layer->l_pause.d == pause) return; if ((layer->l_pause.d = pause)) { /* Start pausing */ layer->l_pause.top = layer->l_pause.bottom = -1; return; } /* Unpause. So refresh the regions in the displays! */ if (layer->l_pause.top == -1 && layer->l_pause.bottom == -1) return; if (layer->l_layfn == &WinLf) /* Currently, this will always be the case! */ win = layer->l_data; else win = NULL; for (Canvas *cv = layer->l_cvlist; cv; cv = cv->c_lnext) { if (!cv->c_slorient) continue; /* Wasn't split, so already updated. */ display = cv->c_display; for (Viewport *vp = cv->c_vplist; vp; vp = vp->v_next) { for (int line = layer->l_pause.top; line <= layer->l_pause.bottom; line++) { int xs, xe; if (line + vp->v_yoff >= vp->v_ys && line + vp->v_yoff <= vp->v_ye && ((xs = layer->l_pause.left[line]) >= 0) && ((xe = layer->l_pause.right[line]) >= 0)) { xs += vp->v_xoff; xe += vp->v_xoff; if (xs < vp->v_xs) xs = vp->v_xs; if (xe > vp->v_xe) xe = vp->v_xe; if (layer->l_encoding == UTF8 && xe < vp->v_xe && win) { struct mline *ml = win->w_mlines + line; if (dw_left(ml, xe, UTF8)) xe++; } if (xs <= xe) RefreshLine(line + vp->v_yoff, xs, xe, 0); } } } if (cv == D_forecv) { int cx = layer->l_x + cv->c_xoff; int cy = layer->l_y + cv->c_yoff; if (cx < cv->c_xs) cx = cv->c_xs; if (cy < cv->c_ys) cy = cv->c_ys; if (cx > cv->c_xe) cx = cv->c_xe; if (cy > cv->c_ye) cy = cv->c_ye; GotoPos(cx, cy); } } for (int line = layer->l_pause.top; line <= layer->l_pause.bottom; line++) layer->l_pause.left[line] = layer->l_pause.right[line] = -1; }