142dc13f1SHong Zhang #include "pipe.h" 242dc13f1SHong Zhang 342dc13f1SHong Zhang /* Initial Function for PIPE */ 442dc13f1SHong Zhang /*-------------------------------- */ 542dc13f1SHong Zhang /* 642dc13f1SHong Zhang Q(x) = Q0 (constant) 742dc13f1SHong Zhang H(x) = H0 - (R/gA) Q0*|Q0|* x 842dc13f1SHong Zhang */ 942dc13f1SHong Zhang /* ----------------------------------- */ 10*9371c9d4SSatish Balay PetscErrorCode PipeComputeSteadyState(Pipe pipe, PetscScalar Q0, PetscScalar H0) { 1142dc13f1SHong Zhang DM cda; 1242dc13f1SHong Zhang PipeField *x; 1342dc13f1SHong Zhang PetscInt i, start, n; 1442dc13f1SHong Zhang Vec local; 1542dc13f1SHong Zhang PetscScalar *coords, c = pipe->R / (GRAV * pipe->A); 1642dc13f1SHong Zhang 1742dc13f1SHong Zhang PetscFunctionBegin; 189566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(pipe->da, &cda)); 199566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(pipe->da, &local)); 209566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(pipe->da, pipe->x, &x)); 219566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayRead(cda, local, &coords)); 229566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(pipe->da, &start, 0, 0, &n, 0, 0)); 2342dc13f1SHong Zhang 2442dc13f1SHong Zhang for (i = start; i < start + n; i++) { 2542dc13f1SHong Zhang x[i].q = Q0; 2642dc13f1SHong Zhang x[i].h = H0 - c * Q0 * PetscAbsScalar(Q0) * coords[i]; 2742dc13f1SHong Zhang } 2842dc13f1SHong Zhang 299566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(pipe->da, pipe->x, &x)); 309566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayRead(cda, local, &coords)); 3142dc13f1SHong Zhang PetscFunctionReturn(0); 3242dc13f1SHong Zhang } 3342dc13f1SHong Zhang 3442dc13f1SHong Zhang /* Function evalutions for PIPE */ 3542dc13f1SHong Zhang /*-------------------------------- */ 3642dc13f1SHong Zhang /* consider using a one-sided higher order fd derivative at boundary. */ 37*9371c9d4SSatish Balay static inline PetscScalar dqdx(PipeField *x, PetscInt i, PetscInt ilast, PetscReal dx) { 3842dc13f1SHong Zhang if (i == 0) { 3942dc13f1SHong Zhang return (x[i + 1].q - x[i].q) / dx; 4042dc13f1SHong Zhang } else if (i == ilast) { 4142dc13f1SHong Zhang return (x[i].q - x[i - 1].q) / dx; 4242dc13f1SHong Zhang } else { 4342dc13f1SHong Zhang return (x[i + 1].q - x[i - 1].q) / (2 * dx); 4442dc13f1SHong Zhang } 4542dc13f1SHong Zhang } 4642dc13f1SHong Zhang 47*9371c9d4SSatish Balay static inline PetscScalar dhdx(PipeField *x, PetscInt i, PetscInt ilast, PetscReal dx) { 4842dc13f1SHong Zhang if (i == 0) { 4942dc13f1SHong Zhang return (x[i + 1].h - x[i].h) / dx; 5042dc13f1SHong Zhang } else if (i == ilast) { 5142dc13f1SHong Zhang return (x[i].h - x[i - 1].h) / dx; 5242dc13f1SHong Zhang } else { 5342dc13f1SHong Zhang return (x[i + 1].h - x[i - 1].h) / (2 * dx); 5442dc13f1SHong Zhang } 5542dc13f1SHong Zhang } 5642dc13f1SHong Zhang 57*9371c9d4SSatish Balay PetscErrorCode PipeIFunctionLocal_Lax(DMDALocalInfo *info, PetscReal ptime, PipeField *x, PipeField *xdot, PetscScalar *f, Pipe pipe) { 5842dc13f1SHong Zhang PetscInt i, start, n, ilast; 5942dc13f1SHong Zhang PetscReal a = pipe->a, A = pipe->A, R = pipe->R, c = a * a / (GRAV * A); 6042dc13f1SHong Zhang PetscReal dx = pipe->length / (info->mx - 1), dt = pipe->dt; 6142dc13f1SHong Zhang PetscScalar qavg, xold_i, ha, hb, qa, qb; 6242dc13f1SHong Zhang PipeField *xold = pipe->xold; 6342dc13f1SHong Zhang 6442dc13f1SHong Zhang PetscFunctionBegin; 659566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(pipe->da, &start, 0, 0, &n, 0, 0)); 6642dc13f1SHong Zhang 6742dc13f1SHong Zhang /* interior and boundary */ 6842dc13f1SHong Zhang ilast = start + n - 1; 6942dc13f1SHong Zhang for (i = start + 1; i < start + n - 1; i++) { 7042dc13f1SHong Zhang qavg = (xold[i + 1].q + xold[i - 1].q) / 2.0; 71*9371c9d4SSatish Balay qa = xold[i - 1].q; 72*9371c9d4SSatish Balay qb = xold[i + 1].q; 73*9371c9d4SSatish Balay ha = xold[i - 1].h; 74*9371c9d4SSatish Balay hb = xold[i + 1].h; 7542dc13f1SHong Zhang 7642dc13f1SHong Zhang /* xdot[i].q = (x[i].q - old_i)/dt */ 7742dc13f1SHong Zhang xold_i = 0.5 * (qa + qb); 7842dc13f1SHong Zhang f[2 * (i - 1) + 2] = (x[i].q - xold_i) + dt * (GRAV * pipe->A * dhdx(xold, i, ilast, dx) + pipe->R * qavg * PetscAbsScalar(qavg)); 7942dc13f1SHong Zhang 8042dc13f1SHong Zhang /* xdot[i].h = (x[i].h - xold_i)/dt */ 8142dc13f1SHong Zhang xold_i = 0.5 * (ha + hb); 8242dc13f1SHong Zhang f[2 * (i - 1) + 3] = (x[i].h - xold_i) + dt * c * dqdx(xold, i, ilast, dx); 8342dc13f1SHong Zhang } 8442dc13f1SHong Zhang 8542dc13f1SHong Zhang /* Characteristic equations */ 8642dc13f1SHong Zhang f[start + 1] = x[start].q - xold[start + 1].q - ((GRAV * A) / a) * (x[start].h - xold[start + 1].h) + dt * R * xold[start + 1].q * PetscAbsScalar(xold[start + 1].q); 8742dc13f1SHong Zhang f[2 * ilast] = x[ilast].q - xold[ilast - 1].q + ((GRAV * A) / a) * (x[ilast].h - xold[ilast - 1].h) + dt * R * xold[ilast - 1].q * PetscAbsScalar(xold[ilast - 1].q); 8842dc13f1SHong Zhang PetscFunctionReturn(0); 8942dc13f1SHong Zhang } 90