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); }
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); }
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 ); } } }
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; } } } }
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)); }
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; } }
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); }
/** * @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; }
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])); } }
// -------------------------------------------------------------------------- // // // 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; } }