1e77315bcSPatrick Sanan 2e77315bcSPatrick Sanan static char help[] = "Nonlinear Radiative Transport PDE with multigrid in 3d.\n\ 3e77315bcSPatrick Sanan Uses 3-dimensional distributed arrays.\n\ 4e77315bcSPatrick Sanan A 3-dim simplified Radiative Transport test problem is used, with analytic Jacobian. \n\ 5e77315bcSPatrick Sanan \n\ 6e77315bcSPatrick Sanan Solves the linear systems via multilevel methods \n\ 7e77315bcSPatrick Sanan \n\ 8e77315bcSPatrick Sanan The command line\n\ 9e77315bcSPatrick Sanan options are:\n\ 10e77315bcSPatrick Sanan -tleft <tl>, where <tl> indicates the left Diriclet BC \n\ 11e77315bcSPatrick Sanan -tright <tr>, where <tr> indicates the right Diriclet BC \n\ 12e77315bcSPatrick Sanan -beta <beta>, where <beta> indicates the exponent in T \n\n"; 13e77315bcSPatrick Sanan 14e77315bcSPatrick Sanan /* 15e77315bcSPatrick Sanan 16e77315bcSPatrick Sanan This example models the partial differential equation 17e77315bcSPatrick Sanan 18e77315bcSPatrick Sanan - Div(alpha* T^beta (GRAD T)) = 0. 19e77315bcSPatrick Sanan 20e77315bcSPatrick Sanan where beta = 2.5 and alpha = 1.0 21e77315bcSPatrick Sanan 22e77315bcSPatrick Sanan BC: T_left = 1.0, T_right = 0.1, dT/dn_top = dTdn_bottom = dT/dn_up = dT/dn_down = 0. 23e77315bcSPatrick Sanan 24e77315bcSPatrick Sanan in the unit square, which is uniformly discretized in each of x and 25e77315bcSPatrick Sanan y in this simple encoding. The degrees of freedom are cell centered. 26e77315bcSPatrick Sanan 27e77315bcSPatrick Sanan A finite volume approximation with the usual 7-point stencil 28e77315bcSPatrick Sanan is used to discretize the boundary value problem to obtain a 29e77315bcSPatrick Sanan nonlinear system of equations. 30e77315bcSPatrick Sanan 31e77315bcSPatrick Sanan This code was contributed by Nickolas Jovanovic based on ex18.c 32e77315bcSPatrick Sanan 33e77315bcSPatrick Sanan */ 34e77315bcSPatrick Sanan 35e77315bcSPatrick Sanan #include <petscsnes.h> 36e77315bcSPatrick Sanan #include <petscdm.h> 37e77315bcSPatrick Sanan #include <petscdmda.h> 38e77315bcSPatrick Sanan 39e77315bcSPatrick Sanan /* User-defined application context */ 40e77315bcSPatrick Sanan 41e77315bcSPatrick Sanan typedef struct { 42e77315bcSPatrick Sanan PetscReal tleft, tright; /* Dirichlet boundary conditions */ 43e77315bcSPatrick Sanan PetscReal beta, bm1, coef; /* nonlinear diffusivity parameterizations */ 44e77315bcSPatrick Sanan } AppCtx; 45e77315bcSPatrick Sanan 46e77315bcSPatrick Sanan #define POWFLOP 5 /* assume a pow() takes five flops */ 47e77315bcSPatrick Sanan 48e77315bcSPatrick Sanan extern PetscErrorCode FormInitialGuess(SNES, Vec, void *); 49e77315bcSPatrick Sanan extern PetscErrorCode FormFunction(SNES, Vec, Vec, void *); 50e77315bcSPatrick Sanan extern PetscErrorCode FormJacobian(SNES, Vec, Mat, Mat, void *); 51e77315bcSPatrick Sanan 52*9371c9d4SSatish Balay int main(int argc, char **argv) { 53e77315bcSPatrick Sanan SNES snes; 54e77315bcSPatrick Sanan AppCtx user; 55e77315bcSPatrick Sanan PetscInt its, lits; 56e77315bcSPatrick Sanan PetscReal litspit; 57e77315bcSPatrick Sanan DM da; 58e77315bcSPatrick Sanan 59327415f7SBarry Smith PetscFunctionBeginUser; 609566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 61e77315bcSPatrick Sanan /* set problem parameters */ 62e77315bcSPatrick Sanan user.tleft = 1.0; 63e77315bcSPatrick Sanan user.tright = 0.1; 64e77315bcSPatrick Sanan user.beta = 2.5; 659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, NULL, "-tleft", &user.tleft, NULL)); 669566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, NULL, "-tright", &user.tright, NULL)); 679566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, NULL, "-beta", &user.beta, NULL)); 68e77315bcSPatrick Sanan user.bm1 = user.beta - 1.0; 69e77315bcSPatrick Sanan user.coef = user.beta / 2.0; 70e77315bcSPatrick Sanan 71e77315bcSPatrick Sanan /* 72e77315bcSPatrick Sanan Set the DMDA (grid structure) for the grids. 73e77315bcSPatrick Sanan */ 749566063dSJacob Faibussowitsch PetscCall(DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, 5, 5, 5, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 1, 1, 0, 0, 0, &da)); 759566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(da)); 769566063dSJacob Faibussowitsch PetscCall(DMSetUp(da)); 779566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(da, &user)); 78e77315bcSPatrick Sanan 79e77315bcSPatrick Sanan /* 80e77315bcSPatrick Sanan Create the nonlinear solver 81e77315bcSPatrick Sanan */ 829566063dSJacob Faibussowitsch PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes)); 839566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, da)); 849566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, NULL, FormFunction, &user)); 859566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, NULL, NULL, FormJacobian, &user)); 869566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes)); 879566063dSJacob Faibussowitsch PetscCall(SNESSetComputeInitialGuess(snes, FormInitialGuess, NULL)); 88e77315bcSPatrick Sanan 899566063dSJacob Faibussowitsch PetscCall(SNESSolve(snes, NULL, NULL)); 909566063dSJacob Faibussowitsch PetscCall(SNESGetIterationNumber(snes, &its)); 919566063dSJacob Faibussowitsch PetscCall(SNESGetLinearSolveIterations(snes, &lits)); 92e77315bcSPatrick Sanan litspit = ((PetscReal)lits) / ((PetscReal)its); 9363a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Number of SNES iterations = %" PetscInt_FMT "\n", its)); 9463a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Number of Linear iterations = %" PetscInt_FMT "\n", lits)); 959566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Average Linear its / SNES = %e\n", (double)litspit)); 96e77315bcSPatrick Sanan 979566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes)); 989566063dSJacob Faibussowitsch PetscCall(DMDestroy(&da)); 999566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 100b122ec5aSJacob Faibussowitsch return 0; 101e77315bcSPatrick Sanan } 102e77315bcSPatrick Sanan /* -------------------- Form initial approximation ----------------- */ 103*9371c9d4SSatish Balay PetscErrorCode FormInitialGuess(SNES snes, Vec X, void *ctx) { 104e77315bcSPatrick Sanan AppCtx *user; 105e77315bcSPatrick Sanan PetscInt i, j, k, xs, ys, xm, ym, zs, zm; 106e77315bcSPatrick Sanan PetscScalar ***x; 107e77315bcSPatrick Sanan DM da; 108e77315bcSPatrick Sanan 109e77315bcSPatrick Sanan PetscFunctionBeginUser; 1109566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &da)); 1119566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(da, &user)); 1129566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 1139566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(da, X, &x)); 114e77315bcSPatrick Sanan 115e77315bcSPatrick Sanan /* Compute initial guess */ 116e77315bcSPatrick Sanan for (k = zs; k < zs + zm; k++) { 117e77315bcSPatrick Sanan for (j = ys; j < ys + ym; j++) { 118*9371c9d4SSatish Balay for (i = xs; i < xs + xm; i++) { x[k][j][i] = user->tleft; } 119e77315bcSPatrick Sanan } 120e77315bcSPatrick Sanan } 1219566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(da, X, &x)); 122e77315bcSPatrick Sanan PetscFunctionReturn(0); 123e77315bcSPatrick Sanan } 124e77315bcSPatrick Sanan /* -------------------- Evaluate Function F(x) --------------------- */ 125*9371c9d4SSatish Balay PetscErrorCode FormFunction(SNES snes, Vec X, Vec F, void *ptr) { 126e77315bcSPatrick Sanan AppCtx *user = (AppCtx *)ptr; 127e77315bcSPatrick Sanan PetscInt i, j, k, mx, my, mz, xs, ys, zs, xm, ym, zm; 128e77315bcSPatrick Sanan PetscScalar zero = 0.0, one = 1.0; 129e77315bcSPatrick Sanan PetscScalar hx, hy, hz, hxhydhz, hyhzdhx, hzhxdhy; 130e77315bcSPatrick Sanan PetscScalar t0, tn, ts, te, tw, an, as, ae, aw, dn, ds, de, dw, fn = 0.0, fs = 0.0, fe = 0.0, fw = 0.0; 131e77315bcSPatrick Sanan PetscScalar tleft, tright, beta, td, ad, dd, fd = 0.0, tu, au, du = 0.0, fu = 0.0; 132e77315bcSPatrick Sanan PetscScalar ***x, ***f; 133e77315bcSPatrick Sanan Vec localX; 134e77315bcSPatrick Sanan DM da; 135e77315bcSPatrick Sanan 136e77315bcSPatrick Sanan PetscFunctionBeginUser; 1379566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &da)); 1389566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(da, &localX)); 1399566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, NULL, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 140*9371c9d4SSatish Balay hx = one / (PetscReal)(mx - 1); 141*9371c9d4SSatish Balay hy = one / (PetscReal)(my - 1); 142*9371c9d4SSatish Balay hz = one / (PetscReal)(mz - 1); 143*9371c9d4SSatish Balay hxhydhz = hx * hy / hz; 144*9371c9d4SSatish Balay hyhzdhx = hy * hz / hx; 145*9371c9d4SSatish Balay hzhxdhy = hz * hx / hy; 146*9371c9d4SSatish Balay tleft = user->tleft; 147*9371c9d4SSatish Balay tright = user->tright; 148e77315bcSPatrick Sanan beta = user->beta; 149e77315bcSPatrick Sanan 150e77315bcSPatrick Sanan /* Get ghost points */ 1519566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(da, X, INSERT_VALUES, localX)); 1529566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(da, X, INSERT_VALUES, localX)); 1539566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 1549566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(da, localX, &x)); 1559566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(da, F, &f)); 156e77315bcSPatrick Sanan 157e77315bcSPatrick Sanan /* Evaluate function */ 158e77315bcSPatrick Sanan for (k = zs; k < zs + zm; k++) { 159e77315bcSPatrick Sanan for (j = ys; j < ys + ym; j++) { 160e77315bcSPatrick Sanan for (i = xs; i < xs + xm; i++) { 161e77315bcSPatrick Sanan t0 = x[k][j][i]; 162e77315bcSPatrick Sanan 163e77315bcSPatrick Sanan if (i > 0 && i < mx - 1 && j > 0 && j < my - 1 && k > 0 && k < mz - 1) { 164e77315bcSPatrick Sanan /* general interior volume */ 165e77315bcSPatrick Sanan 166e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 167e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 168e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 169e77315bcSPatrick Sanan fw = dw * (t0 - tw); 170e77315bcSPatrick Sanan 171e77315bcSPatrick Sanan te = x[k][j][i + 1]; 172e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 173e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 174e77315bcSPatrick Sanan fe = de * (te - t0); 175e77315bcSPatrick Sanan 176e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 177e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 178e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 179e77315bcSPatrick Sanan fs = ds * (t0 - ts); 180e77315bcSPatrick Sanan 181e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 182e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 183e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 184e77315bcSPatrick Sanan fn = dn * (tn - t0); 185e77315bcSPatrick Sanan 186e77315bcSPatrick Sanan td = x[k - 1][j][i]; 187e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 188e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 189e77315bcSPatrick Sanan fd = dd * (t0 - td); 190e77315bcSPatrick Sanan 191e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 192e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 193e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 194e77315bcSPatrick Sanan fu = du * (tu - t0); 195e77315bcSPatrick Sanan 196e77315bcSPatrick Sanan } else if (i == 0) { 197e77315bcSPatrick Sanan /* left-hand (west) boundary */ 198e77315bcSPatrick Sanan tw = tleft; 199e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 200e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 201e77315bcSPatrick Sanan fw = dw * (t0 - tw); 202e77315bcSPatrick Sanan 203e77315bcSPatrick Sanan te = x[k][j][i + 1]; 204e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 205e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 206e77315bcSPatrick Sanan fe = de * (te - t0); 207e77315bcSPatrick Sanan 208e77315bcSPatrick Sanan if (j > 0) { 209e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 210e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 211e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 212e77315bcSPatrick Sanan fs = ds * (t0 - ts); 213e77315bcSPatrick Sanan } else { 214e77315bcSPatrick Sanan fs = zero; 215e77315bcSPatrick Sanan } 216e77315bcSPatrick Sanan 217e77315bcSPatrick Sanan if (j < my - 1) { 218e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 219e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 220e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 221e77315bcSPatrick Sanan fn = dn * (tn - t0); 222e77315bcSPatrick Sanan } else { 223e77315bcSPatrick Sanan fn = zero; 224e77315bcSPatrick Sanan } 225e77315bcSPatrick Sanan 226e77315bcSPatrick Sanan if (k > 0) { 227e77315bcSPatrick Sanan td = x[k - 1][j][i]; 228e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 229e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 230e77315bcSPatrick Sanan fd = dd * (t0 - td); 231e77315bcSPatrick Sanan } else { 232e77315bcSPatrick Sanan fd = zero; 233e77315bcSPatrick Sanan } 234e77315bcSPatrick Sanan 235e77315bcSPatrick Sanan if (k < mz - 1) { 236e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 237e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 238e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 239e77315bcSPatrick Sanan fu = du * (tu - t0); 240e77315bcSPatrick Sanan } else { 241e77315bcSPatrick Sanan fu = zero; 242e77315bcSPatrick Sanan } 243e77315bcSPatrick Sanan 244e77315bcSPatrick Sanan } else if (i == mx - 1) { 245e77315bcSPatrick Sanan /* right-hand (east) boundary */ 246e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 247e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 248e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 249e77315bcSPatrick Sanan fw = dw * (t0 - tw); 250e77315bcSPatrick Sanan 251e77315bcSPatrick Sanan te = tright; 252e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 253e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 254e77315bcSPatrick Sanan fe = de * (te - t0); 255e77315bcSPatrick Sanan 256e77315bcSPatrick Sanan if (j > 0) { 257e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 258e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 259e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 260e77315bcSPatrick Sanan fs = ds * (t0 - ts); 261e77315bcSPatrick Sanan } else { 262e77315bcSPatrick Sanan fs = zero; 263e77315bcSPatrick Sanan } 264e77315bcSPatrick Sanan 265e77315bcSPatrick Sanan if (j < my - 1) { 266e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 267e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 268e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 269e77315bcSPatrick Sanan fn = dn * (tn - t0); 270e77315bcSPatrick Sanan } else { 271e77315bcSPatrick Sanan fn = zero; 272e77315bcSPatrick Sanan } 273e77315bcSPatrick Sanan 274e77315bcSPatrick Sanan if (k > 0) { 275e77315bcSPatrick Sanan td = x[k - 1][j][i]; 276e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 277e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 278e77315bcSPatrick Sanan fd = dd * (t0 - td); 279e77315bcSPatrick Sanan } else { 280e77315bcSPatrick Sanan fd = zero; 281e77315bcSPatrick Sanan } 282e77315bcSPatrick Sanan 283e77315bcSPatrick Sanan if (k < mz - 1) { 284e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 285e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 286e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 287e77315bcSPatrick Sanan fu = du * (tu - t0); 288e77315bcSPatrick Sanan } else { 289e77315bcSPatrick Sanan fu = zero; 290e77315bcSPatrick Sanan } 291e77315bcSPatrick Sanan 292e77315bcSPatrick Sanan } else if (j == 0) { 293e77315bcSPatrick Sanan /* bottom (south) boundary, and i <> 0 or mx-1 */ 294e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 295e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 296e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 297e77315bcSPatrick Sanan fw = dw * (t0 - tw); 298e77315bcSPatrick Sanan 299e77315bcSPatrick Sanan te = x[k][j][i + 1]; 300e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 301e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 302e77315bcSPatrick Sanan fe = de * (te - t0); 303e77315bcSPatrick Sanan 304e77315bcSPatrick Sanan fs = zero; 305e77315bcSPatrick Sanan 306e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 307e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 308e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 309e77315bcSPatrick Sanan fn = dn * (tn - t0); 310e77315bcSPatrick Sanan 311e77315bcSPatrick Sanan if (k > 0) { 312e77315bcSPatrick Sanan td = x[k - 1][j][i]; 313e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 314e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 315e77315bcSPatrick Sanan fd = dd * (t0 - td); 316e77315bcSPatrick Sanan } else { 317e77315bcSPatrick Sanan fd = zero; 318e77315bcSPatrick Sanan } 319e77315bcSPatrick Sanan 320e77315bcSPatrick Sanan if (k < mz - 1) { 321e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 322e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 323e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 324e77315bcSPatrick Sanan fu = du * (tu - t0); 325e77315bcSPatrick Sanan } else { 326e77315bcSPatrick Sanan fu = zero; 327e77315bcSPatrick Sanan } 328e77315bcSPatrick Sanan 329e77315bcSPatrick Sanan } else if (j == my - 1) { 330e77315bcSPatrick Sanan /* top (north) boundary, and i <> 0 or mx-1 */ 331e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 332e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 333e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 334e77315bcSPatrick Sanan fw = dw * (t0 - tw); 335e77315bcSPatrick Sanan 336e77315bcSPatrick Sanan te = x[k][j][i + 1]; 337e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 338e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 339e77315bcSPatrick Sanan fe = de * (te - t0); 340e77315bcSPatrick Sanan 341e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 342e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 343e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 344e77315bcSPatrick Sanan fs = ds * (t0 - ts); 345e77315bcSPatrick Sanan 346e77315bcSPatrick Sanan fn = zero; 347e77315bcSPatrick Sanan 348e77315bcSPatrick Sanan if (k > 0) { 349e77315bcSPatrick Sanan td = x[k - 1][j][i]; 350e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 351e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 352e77315bcSPatrick Sanan fd = dd * (t0 - td); 353e77315bcSPatrick Sanan } else { 354e77315bcSPatrick Sanan fd = zero; 355e77315bcSPatrick Sanan } 356e77315bcSPatrick Sanan 357e77315bcSPatrick Sanan if (k < mz - 1) { 358e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 359e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 360e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 361e77315bcSPatrick Sanan fu = du * (tu - t0); 362e77315bcSPatrick Sanan } else { 363e77315bcSPatrick Sanan fu = zero; 364e77315bcSPatrick Sanan } 365e77315bcSPatrick Sanan 366e77315bcSPatrick Sanan } else if (k == 0) { 367e77315bcSPatrick Sanan /* down boundary (interior only) */ 368e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 369e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 370e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 371e77315bcSPatrick Sanan fw = dw * (t0 - tw); 372e77315bcSPatrick Sanan 373e77315bcSPatrick Sanan te = x[k][j][i + 1]; 374e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 375e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 376e77315bcSPatrick Sanan fe = de * (te - t0); 377e77315bcSPatrick Sanan 378e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 379e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 380e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 381e77315bcSPatrick Sanan fs = ds * (t0 - ts); 382e77315bcSPatrick Sanan 383e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 384e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 385e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 386e77315bcSPatrick Sanan fn = dn * (tn - t0); 387e77315bcSPatrick Sanan 388e77315bcSPatrick Sanan fd = zero; 389e77315bcSPatrick Sanan 390e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 391e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 392e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 393e77315bcSPatrick Sanan fu = du * (tu - t0); 394e77315bcSPatrick Sanan 395e77315bcSPatrick Sanan } else if (k == mz - 1) { 396e77315bcSPatrick Sanan /* up boundary (interior only) */ 397e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 398e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 399e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 400e77315bcSPatrick Sanan fw = dw * (t0 - tw); 401e77315bcSPatrick Sanan 402e77315bcSPatrick Sanan te = x[k][j][i + 1]; 403e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 404e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 405e77315bcSPatrick Sanan fe = de * (te - t0); 406e77315bcSPatrick Sanan 407e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 408e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 409e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 410e77315bcSPatrick Sanan fs = ds * (t0 - ts); 411e77315bcSPatrick Sanan 412e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 413e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 414e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 415e77315bcSPatrick Sanan fn = dn * (tn - t0); 416e77315bcSPatrick Sanan 417e77315bcSPatrick Sanan td = x[k - 1][j][i]; 418e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 419e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 420e77315bcSPatrick Sanan fd = dd * (t0 - td); 421e77315bcSPatrick Sanan 422e77315bcSPatrick Sanan fu = zero; 423e77315bcSPatrick Sanan } 424e77315bcSPatrick Sanan 425e77315bcSPatrick Sanan f[k][j][i] = -hyhzdhx * (fe - fw) - hzhxdhy * (fn - fs) - hxhydhz * (fu - fd); 426e77315bcSPatrick Sanan } 427e77315bcSPatrick Sanan } 428e77315bcSPatrick Sanan } 4299566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(da, localX, &x)); 4309566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(da, F, &f)); 4319566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(da, &localX)); 4329566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((22.0 + 4.0 * POWFLOP) * ym * xm)); 433e77315bcSPatrick Sanan PetscFunctionReturn(0); 434e77315bcSPatrick Sanan } 435e77315bcSPatrick Sanan /* -------------------- Evaluate Jacobian F(x) --------------------- */ 436*9371c9d4SSatish Balay PetscErrorCode FormJacobian(SNES snes, Vec X, Mat J, Mat jac, void *ptr) { 437e77315bcSPatrick Sanan AppCtx *user = (AppCtx *)ptr; 438e77315bcSPatrick Sanan PetscInt i, j, k, mx, my, mz, xs, ys, zs, xm, ym, zm; 439e77315bcSPatrick Sanan PetscScalar one = 1.0; 440e77315bcSPatrick Sanan PetscScalar hx, hy, hz, hxhydhz, hyhzdhx, hzhxdhy; 441e77315bcSPatrick Sanan PetscScalar t0, tn, ts, te, tw, an, as, ae, aw, dn, ds, de, dw; 442e77315bcSPatrick Sanan PetscScalar tleft, tright, beta, td, ad, dd, tu, au, du, v[7], bm1, coef; 443e77315bcSPatrick Sanan PetscScalar ***x, bn, bs, be, bw, bu, bd, gn, gs, ge, gw, gu, gd; 444e77315bcSPatrick Sanan Vec localX; 445e77315bcSPatrick Sanan MatStencil c[7], row; 446e77315bcSPatrick Sanan DM da; 447e77315bcSPatrick Sanan 448e77315bcSPatrick Sanan PetscFunctionBeginUser; 4499566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &da)); 4509566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(da, &localX)); 4519566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, NULL, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 452*9371c9d4SSatish Balay hx = one / (PetscReal)(mx - 1); 453*9371c9d4SSatish Balay hy = one / (PetscReal)(my - 1); 454*9371c9d4SSatish Balay hz = one / (PetscReal)(mz - 1); 455*9371c9d4SSatish Balay hxhydhz = hx * hy / hz; 456*9371c9d4SSatish Balay hyhzdhx = hy * hz / hx; 457*9371c9d4SSatish Balay hzhxdhy = hz * hx / hy; 458*9371c9d4SSatish Balay tleft = user->tleft; 459*9371c9d4SSatish Balay tright = user->tright; 460*9371c9d4SSatish Balay beta = user->beta; 461*9371c9d4SSatish Balay bm1 = user->bm1; 462*9371c9d4SSatish Balay coef = user->coef; 463e77315bcSPatrick Sanan 464e77315bcSPatrick Sanan /* Get ghost points */ 4659566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(da, X, INSERT_VALUES, localX)); 4669566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(da, X, INSERT_VALUES, localX)); 4679566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 4689566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(da, localX, &x)); 469e77315bcSPatrick Sanan 470e77315bcSPatrick Sanan /* Evaluate Jacobian of function */ 471e77315bcSPatrick Sanan for (k = zs; k < zs + zm; k++) { 472e77315bcSPatrick Sanan for (j = ys; j < ys + ym; j++) { 473e77315bcSPatrick Sanan for (i = xs; i < xs + xm; i++) { 474e77315bcSPatrick Sanan t0 = x[k][j][i]; 475*9371c9d4SSatish Balay row.k = k; 476*9371c9d4SSatish Balay row.j = j; 477*9371c9d4SSatish Balay row.i = i; 478e77315bcSPatrick Sanan if (i > 0 && i < mx - 1 && j > 0 && j < my - 1 && k > 0 && k < mz - 1) { 479e77315bcSPatrick Sanan /* general interior volume */ 480e77315bcSPatrick Sanan 481e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 482e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 483e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 484e77315bcSPatrick Sanan /* dw = bw * aw */ 485e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 486e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 487e77315bcSPatrick Sanan 488e77315bcSPatrick Sanan te = x[k][j][i + 1]; 489e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 490e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 491e77315bcSPatrick Sanan /* de = be * ae; */ 492e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 493e77315bcSPatrick Sanan ge = coef * be * (te - t0); 494e77315bcSPatrick Sanan 495e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 496e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 497e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 498e77315bcSPatrick Sanan /* ds = bs * as; */ 499e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 500e77315bcSPatrick Sanan gs = coef * bs * (t0 - ts); 501e77315bcSPatrick Sanan 502e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 503e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 504e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 505e77315bcSPatrick Sanan /* dn = bn * an; */ 506e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 507e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 508e77315bcSPatrick Sanan 509e77315bcSPatrick Sanan td = x[k - 1][j][i]; 510e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 511e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 512e77315bcSPatrick Sanan /* dd = bd * ad; */ 513e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 514e77315bcSPatrick Sanan gd = coef * bd * (t0 - td); 515e77315bcSPatrick Sanan 516e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 517e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 518e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 519e77315bcSPatrick Sanan /* du = bu * au; */ 520e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 521e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 522e77315bcSPatrick Sanan 523*9371c9d4SSatish Balay c[0].k = k - 1; 524*9371c9d4SSatish Balay c[0].j = j; 525*9371c9d4SSatish Balay c[0].i = i; 526*9371c9d4SSatish Balay v[0] = -hxhydhz * (dd - gd); 527*9371c9d4SSatish Balay c[1].k = k; 528*9371c9d4SSatish Balay c[1].j = j - 1; 529*9371c9d4SSatish Balay c[1].i = i; 530e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 531*9371c9d4SSatish Balay c[2].k = k; 532*9371c9d4SSatish Balay c[2].j = j; 533*9371c9d4SSatish Balay c[2].i = i - 1; 534e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 535*9371c9d4SSatish Balay c[3].k = k; 536*9371c9d4SSatish Balay c[3].j = j; 537*9371c9d4SSatish Balay c[3].i = i; 538e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 539*9371c9d4SSatish Balay c[4].k = k; 540*9371c9d4SSatish Balay c[4].j = j; 541*9371c9d4SSatish Balay c[4].i = i + 1; 542e77315bcSPatrick Sanan v[4] = -hyhzdhx * (de + ge); 543*9371c9d4SSatish Balay c[5].k = k; 544*9371c9d4SSatish Balay c[5].j = j + 1; 545*9371c9d4SSatish Balay c[5].i = i; 546e77315bcSPatrick Sanan v[5] = -hzhxdhy * (dn + gn); 547*9371c9d4SSatish Balay c[6].k = k + 1; 548*9371c9d4SSatish Balay c[6].j = j; 549*9371c9d4SSatish Balay c[6].i = i; 550e77315bcSPatrick Sanan v[6] = -hxhydhz * (du + gu); 5519566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 7, c, v, INSERT_VALUES)); 552e77315bcSPatrick Sanan 553e77315bcSPatrick Sanan } else if (i == 0) { 554e77315bcSPatrick Sanan /* left-hand plane boundary */ 555e77315bcSPatrick Sanan tw = tleft; 556e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 557e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 558e77315bcSPatrick Sanan /* dw = bw * aw */ 559e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 560e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 561e77315bcSPatrick Sanan 562e77315bcSPatrick Sanan te = x[k][j][i + 1]; 563e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 564e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 565e77315bcSPatrick Sanan /* de = be * ae; */ 566e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 567e77315bcSPatrick Sanan ge = coef * be * (te - t0); 568e77315bcSPatrick Sanan 569e77315bcSPatrick Sanan /* left-hand bottom edge */ 570e77315bcSPatrick Sanan if (j == 0) { 571e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 572e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 573e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 574e77315bcSPatrick Sanan /* dn = bn * an; */ 575e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 576e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 577e77315bcSPatrick Sanan 578e77315bcSPatrick Sanan /* left-hand bottom down corner */ 579e77315bcSPatrick Sanan if (k == 0) { 580e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 581e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 582e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 583e77315bcSPatrick Sanan /* du = bu * au; */ 584e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 585e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 586e77315bcSPatrick Sanan 587*9371c9d4SSatish Balay c[0].k = k; 588*9371c9d4SSatish Balay c[0].j = j; 589*9371c9d4SSatish Balay c[0].i = i; 590e77315bcSPatrick Sanan v[0] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 591*9371c9d4SSatish Balay c[1].k = k; 592*9371c9d4SSatish Balay c[1].j = j; 593*9371c9d4SSatish Balay c[1].i = i + 1; 594e77315bcSPatrick Sanan v[1] = -hyhzdhx * (de + ge); 595*9371c9d4SSatish Balay c[2].k = k; 596*9371c9d4SSatish Balay c[2].j = j + 1; 597*9371c9d4SSatish Balay c[2].i = i; 598e77315bcSPatrick Sanan v[2] = -hzhxdhy * (dn + gn); 599*9371c9d4SSatish Balay c[3].k = k + 1; 600*9371c9d4SSatish Balay c[3].j = j; 601*9371c9d4SSatish Balay c[3].i = i; 602e77315bcSPatrick Sanan v[3] = -hxhydhz * (du + gu); 6039566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 604e77315bcSPatrick Sanan 605e77315bcSPatrick Sanan /* left-hand bottom interior edge */ 606e77315bcSPatrick Sanan } else if (k < mz - 1) { 607e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 608e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 609e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 610e77315bcSPatrick Sanan /* du = bu * au; */ 611e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 612e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 613e77315bcSPatrick Sanan 614e77315bcSPatrick Sanan td = x[k - 1][j][i]; 615e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 616e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 617e77315bcSPatrick Sanan /* dd = bd * ad; */ 618e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 619e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 620e77315bcSPatrick Sanan 621*9371c9d4SSatish Balay c[0].k = k - 1; 622*9371c9d4SSatish Balay c[0].j = j; 623*9371c9d4SSatish Balay c[0].i = i; 624e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 625*9371c9d4SSatish Balay c[1].k = k; 626*9371c9d4SSatish Balay c[1].j = j; 627*9371c9d4SSatish Balay c[1].i = i; 628e77315bcSPatrick Sanan v[1] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 629*9371c9d4SSatish Balay c[2].k = k; 630*9371c9d4SSatish Balay c[2].j = j; 631*9371c9d4SSatish Balay c[2].i = i + 1; 632e77315bcSPatrick Sanan v[2] = -hyhzdhx * (de + ge); 633*9371c9d4SSatish Balay c[3].k = k; 634*9371c9d4SSatish Balay c[3].j = j + 1; 635*9371c9d4SSatish Balay c[3].i = i; 636e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 637*9371c9d4SSatish Balay c[4].k = k + 1; 638*9371c9d4SSatish Balay c[4].j = j; 639*9371c9d4SSatish Balay c[4].i = i; 640e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 6419566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 642e77315bcSPatrick Sanan 643e77315bcSPatrick Sanan /* left-hand bottom up corner */ 644e77315bcSPatrick Sanan } else { 645e77315bcSPatrick Sanan td = x[k - 1][j][i]; 646e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 647e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 648e77315bcSPatrick Sanan /* dd = bd * ad; */ 649e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 650e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 651e77315bcSPatrick Sanan 652*9371c9d4SSatish Balay c[0].k = k - 1; 653*9371c9d4SSatish Balay c[0].j = j; 654*9371c9d4SSatish Balay c[0].i = i; 655e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 656*9371c9d4SSatish Balay c[1].k = k; 657*9371c9d4SSatish Balay c[1].j = j; 658*9371c9d4SSatish Balay c[1].i = i; 659e77315bcSPatrick Sanan v[1] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 660*9371c9d4SSatish Balay c[2].k = k; 661*9371c9d4SSatish Balay c[2].j = j; 662*9371c9d4SSatish Balay c[2].i = i + 1; 663e77315bcSPatrick Sanan v[2] = -hyhzdhx * (de + ge); 664*9371c9d4SSatish Balay c[3].k = k; 665*9371c9d4SSatish Balay c[3].j = j + 1; 666*9371c9d4SSatish Balay c[3].i = i; 667e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 6689566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 669e77315bcSPatrick Sanan } 670e77315bcSPatrick Sanan 671e77315bcSPatrick Sanan /* left-hand top edge */ 672e77315bcSPatrick Sanan } else if (j == my - 1) { 673e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 674e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 675e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 676e77315bcSPatrick Sanan /* ds = bs * as; */ 677e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 678e77315bcSPatrick Sanan gs = coef * bs * (ts - t0); 679e77315bcSPatrick Sanan 680e77315bcSPatrick Sanan /* left-hand top down corner */ 681e77315bcSPatrick Sanan if (k == 0) { 682e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 683e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 684e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 685e77315bcSPatrick Sanan /* du = bu * au; */ 686e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 687e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 688e77315bcSPatrick Sanan 689*9371c9d4SSatish Balay c[0].k = k; 690*9371c9d4SSatish Balay c[0].j = j - 1; 691*9371c9d4SSatish Balay c[0].i = i; 692e77315bcSPatrick Sanan v[0] = -hzhxdhy * (ds - gs); 693*9371c9d4SSatish Balay c[1].k = k; 694*9371c9d4SSatish Balay c[1].j = j; 695*9371c9d4SSatish Balay c[1].i = i; 696e77315bcSPatrick Sanan v[1] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 697*9371c9d4SSatish Balay c[2].k = k; 698*9371c9d4SSatish Balay c[2].j = j; 699*9371c9d4SSatish Balay c[2].i = i + 1; 700e77315bcSPatrick Sanan v[2] = -hyhzdhx * (de + ge); 701*9371c9d4SSatish Balay c[3].k = k + 1; 702*9371c9d4SSatish Balay c[3].j = j; 703*9371c9d4SSatish Balay c[3].i = i; 704e77315bcSPatrick Sanan v[3] = -hxhydhz * (du + gu); 7059566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 706e77315bcSPatrick Sanan 707e77315bcSPatrick Sanan /* left-hand top interior edge */ 708e77315bcSPatrick Sanan } else if (k < mz - 1) { 709e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 710e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 711e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 712e77315bcSPatrick Sanan /* du = bu * au; */ 713e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 714e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 715e77315bcSPatrick Sanan 716e77315bcSPatrick Sanan td = x[k - 1][j][i]; 717e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 718e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 719e77315bcSPatrick Sanan /* dd = bd * ad; */ 720e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 721e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 722e77315bcSPatrick Sanan 723*9371c9d4SSatish Balay c[0].k = k - 1; 724*9371c9d4SSatish Balay c[0].j = j; 725*9371c9d4SSatish Balay c[0].i = i; 726e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 727*9371c9d4SSatish Balay c[1].k = k; 728*9371c9d4SSatish Balay c[1].j = j - 1; 729*9371c9d4SSatish Balay c[1].i = i; 730e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 731*9371c9d4SSatish Balay c[2].k = k; 732*9371c9d4SSatish Balay c[2].j = j; 733*9371c9d4SSatish Balay c[2].i = i; 734e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 735*9371c9d4SSatish Balay c[3].k = k; 736*9371c9d4SSatish Balay c[3].j = j; 737*9371c9d4SSatish Balay c[3].i = i + 1; 738e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 739*9371c9d4SSatish Balay c[4].k = k + 1; 740*9371c9d4SSatish Balay c[4].j = j; 741*9371c9d4SSatish Balay c[4].i = i; 742e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 7439566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 744e77315bcSPatrick Sanan 745e77315bcSPatrick Sanan /* left-hand top up corner */ 746e77315bcSPatrick Sanan } else { 747e77315bcSPatrick Sanan td = x[k - 1][j][i]; 748e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 749e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 750e77315bcSPatrick Sanan /* dd = bd * ad; */ 751e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 752e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 753e77315bcSPatrick Sanan 754*9371c9d4SSatish Balay c[0].k = k - 1; 755*9371c9d4SSatish Balay c[0].j = j; 756*9371c9d4SSatish Balay c[0].i = i; 757e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 758*9371c9d4SSatish Balay c[1].k = k; 759*9371c9d4SSatish Balay c[1].j = j - 1; 760*9371c9d4SSatish Balay c[1].i = i; 761e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 762*9371c9d4SSatish Balay c[2].k = k; 763*9371c9d4SSatish Balay c[2].j = j; 764*9371c9d4SSatish Balay c[2].i = i; 765e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 766*9371c9d4SSatish Balay c[3].k = k; 767*9371c9d4SSatish Balay c[3].j = j; 768*9371c9d4SSatish Balay c[3].i = i + 1; 769e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 7709566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 771e77315bcSPatrick Sanan } 772e77315bcSPatrick Sanan 773e77315bcSPatrick Sanan } else { 774e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 775e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 776e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 777e77315bcSPatrick Sanan /* ds = bs * as; */ 778e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 779e77315bcSPatrick Sanan gs = coef * bs * (t0 - ts); 780e77315bcSPatrick Sanan 781e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 782e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 783e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 784e77315bcSPatrick Sanan /* dn = bn * an; */ 785e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 786e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 787e77315bcSPatrick Sanan 788e77315bcSPatrick Sanan /* left-hand down interior edge */ 789e77315bcSPatrick Sanan if (k == 0) { 790e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 791e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 792e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 793e77315bcSPatrick Sanan /* du = bu * au; */ 794e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 795e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 796e77315bcSPatrick Sanan 797*9371c9d4SSatish Balay c[0].k = k; 798*9371c9d4SSatish Balay c[0].j = j - 1; 799*9371c9d4SSatish Balay c[0].i = i; 800e77315bcSPatrick Sanan v[0] = -hzhxdhy * (ds - gs); 801*9371c9d4SSatish Balay c[1].k = k; 802*9371c9d4SSatish Balay c[1].j = j; 803*9371c9d4SSatish Balay c[1].i = i; 804e77315bcSPatrick Sanan v[1] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 805*9371c9d4SSatish Balay c[2].k = k; 806*9371c9d4SSatish Balay c[2].j = j; 807*9371c9d4SSatish Balay c[2].i = i + 1; 808e77315bcSPatrick Sanan v[2] = -hyhzdhx * (de + ge); 809*9371c9d4SSatish Balay c[3].k = k; 810*9371c9d4SSatish Balay c[3].j = j + 1; 811*9371c9d4SSatish Balay c[3].i = i; 812e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 813*9371c9d4SSatish Balay c[4].k = k + 1; 814*9371c9d4SSatish Balay c[4].j = j; 815*9371c9d4SSatish Balay c[4].i = i; 816e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 8179566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 818e77315bcSPatrick Sanan 819e77315bcSPatrick Sanan } else if (k == mz - 1) { /* left-hand up interior edge */ 820e77315bcSPatrick Sanan 821e77315bcSPatrick Sanan td = x[k - 1][j][i]; 822e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 823e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 824e77315bcSPatrick Sanan /* dd = bd * ad; */ 825e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 826e77315bcSPatrick Sanan gd = coef * bd * (t0 - td); 827e77315bcSPatrick Sanan 828*9371c9d4SSatish Balay c[0].k = k - 1; 829*9371c9d4SSatish Balay c[0].j = j; 830*9371c9d4SSatish Balay c[0].i = i; 831e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 832*9371c9d4SSatish Balay c[1].k = k; 833*9371c9d4SSatish Balay c[1].j = j - 1; 834*9371c9d4SSatish Balay c[1].i = i; 835e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 836*9371c9d4SSatish Balay c[2].k = k; 837*9371c9d4SSatish Balay c[2].j = j; 838*9371c9d4SSatish Balay c[2].i = i; 839e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 840*9371c9d4SSatish Balay c[3].k = k; 841*9371c9d4SSatish Balay c[3].j = j; 842*9371c9d4SSatish Balay c[3].i = i + 1; 843e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 844*9371c9d4SSatish Balay c[4].k = k; 845*9371c9d4SSatish Balay c[4].j = j + 1; 846*9371c9d4SSatish Balay c[4].i = i; 847e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 8489566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 849e77315bcSPatrick Sanan } else { /* left-hand interior plane */ 850e77315bcSPatrick Sanan 851e77315bcSPatrick Sanan td = x[k - 1][j][i]; 852e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 853e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 854e77315bcSPatrick Sanan /* dd = bd * ad; */ 855e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 856e77315bcSPatrick Sanan gd = coef * bd * (t0 - td); 857e77315bcSPatrick Sanan 858e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 859e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 860e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 861e77315bcSPatrick Sanan /* du = bu * au; */ 862e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 863e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 864e77315bcSPatrick Sanan 865*9371c9d4SSatish Balay c[0].k = k - 1; 866*9371c9d4SSatish Balay c[0].j = j; 867*9371c9d4SSatish Balay c[0].i = i; 868e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 869*9371c9d4SSatish Balay c[1].k = k; 870*9371c9d4SSatish Balay c[1].j = j - 1; 871*9371c9d4SSatish Balay c[1].i = i; 872e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 873*9371c9d4SSatish Balay c[2].k = k; 874*9371c9d4SSatish Balay c[2].j = j; 875*9371c9d4SSatish Balay c[2].i = i; 876e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 877*9371c9d4SSatish Balay c[3].k = k; 878*9371c9d4SSatish Balay c[3].j = j; 879*9371c9d4SSatish Balay c[3].i = i + 1; 880e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 881*9371c9d4SSatish Balay c[4].k = k; 882*9371c9d4SSatish Balay c[4].j = j + 1; 883*9371c9d4SSatish Balay c[4].i = i; 884e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 885*9371c9d4SSatish Balay c[5].k = k + 1; 886*9371c9d4SSatish Balay c[5].j = j; 887*9371c9d4SSatish Balay c[5].i = i; 888e77315bcSPatrick Sanan v[5] = -hxhydhz * (du + gu); 8899566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 6, c, v, INSERT_VALUES)); 890e77315bcSPatrick Sanan } 891e77315bcSPatrick Sanan } 892e77315bcSPatrick Sanan 893e77315bcSPatrick Sanan } else if (i == mx - 1) { 894e77315bcSPatrick Sanan /* right-hand plane boundary */ 895e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 896e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 897e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 898e77315bcSPatrick Sanan /* dw = bw * aw */ 899e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 900e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 901e77315bcSPatrick Sanan 902e77315bcSPatrick Sanan te = tright; 903e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 904e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 905e77315bcSPatrick Sanan /* de = be * ae; */ 906e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 907e77315bcSPatrick Sanan ge = coef * be * (te - t0); 908e77315bcSPatrick Sanan 909e77315bcSPatrick Sanan /* right-hand bottom edge */ 910e77315bcSPatrick Sanan if (j == 0) { 911e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 912e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 913e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 914e77315bcSPatrick Sanan /* dn = bn * an; */ 915e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 916e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 917e77315bcSPatrick Sanan 918e77315bcSPatrick Sanan /* right-hand bottom down corner */ 919e77315bcSPatrick Sanan if (k == 0) { 920e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 921e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 922e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 923e77315bcSPatrick Sanan /* du = bu * au; */ 924e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 925e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 926e77315bcSPatrick Sanan 927*9371c9d4SSatish Balay c[0].k = k; 928*9371c9d4SSatish Balay c[0].j = j; 929*9371c9d4SSatish Balay c[0].i = i - 1; 930e77315bcSPatrick Sanan v[0] = -hyhzdhx * (dw - gw); 931*9371c9d4SSatish Balay c[1].k = k; 932*9371c9d4SSatish Balay c[1].j = j; 933*9371c9d4SSatish Balay c[1].i = i; 934e77315bcSPatrick Sanan v[1] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 935*9371c9d4SSatish Balay c[2].k = k; 936*9371c9d4SSatish Balay c[2].j = j + 1; 937*9371c9d4SSatish Balay c[2].i = i; 938e77315bcSPatrick Sanan v[2] = -hzhxdhy * (dn + gn); 939*9371c9d4SSatish Balay c[3].k = k + 1; 940*9371c9d4SSatish Balay c[3].j = j; 941*9371c9d4SSatish Balay c[3].i = i; 942e77315bcSPatrick Sanan v[3] = -hxhydhz * (du + gu); 9439566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 944e77315bcSPatrick Sanan 945e77315bcSPatrick Sanan /* right-hand bottom interior edge */ 946e77315bcSPatrick Sanan } else if (k < mz - 1) { 947e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 948e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 949e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 950e77315bcSPatrick Sanan /* du = bu * au; */ 951e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 952e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 953e77315bcSPatrick Sanan 954e77315bcSPatrick Sanan td = x[k - 1][j][i]; 955e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 956e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 957e77315bcSPatrick Sanan /* dd = bd * ad; */ 958e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 959e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 960e77315bcSPatrick Sanan 961*9371c9d4SSatish Balay c[0].k = k - 1; 962*9371c9d4SSatish Balay c[0].j = j; 963*9371c9d4SSatish Balay c[0].i = i; 964e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 965*9371c9d4SSatish Balay c[1].k = k; 966*9371c9d4SSatish Balay c[1].j = j; 967*9371c9d4SSatish Balay c[1].i = i - 1; 968e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 969*9371c9d4SSatish Balay c[2].k = k; 970*9371c9d4SSatish Balay c[2].j = j; 971*9371c9d4SSatish Balay c[2].i = i; 972e77315bcSPatrick Sanan v[2] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 973*9371c9d4SSatish Balay c[3].k = k; 974*9371c9d4SSatish Balay c[3].j = j + 1; 975*9371c9d4SSatish Balay c[3].i = i; 976e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 977*9371c9d4SSatish Balay c[4].k = k + 1; 978*9371c9d4SSatish Balay c[4].j = j; 979*9371c9d4SSatish Balay c[4].i = i; 980e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 9819566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 982e77315bcSPatrick Sanan 983e77315bcSPatrick Sanan /* right-hand bottom up corner */ 984e77315bcSPatrick Sanan } else { 985e77315bcSPatrick Sanan td = x[k - 1][j][i]; 986e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 987e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 988e77315bcSPatrick Sanan /* dd = bd * ad; */ 989e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 990e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 991e77315bcSPatrick Sanan 992*9371c9d4SSatish Balay c[0].k = k - 1; 993*9371c9d4SSatish Balay c[0].j = j; 994*9371c9d4SSatish Balay c[0].i = i; 995e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 996*9371c9d4SSatish Balay c[1].k = k; 997*9371c9d4SSatish Balay c[1].j = j; 998*9371c9d4SSatish Balay c[1].i = i - 1; 999e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1000*9371c9d4SSatish Balay c[2].k = k; 1001*9371c9d4SSatish Balay c[2].j = j; 1002*9371c9d4SSatish Balay c[2].i = i; 1003e77315bcSPatrick Sanan v[2] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 1004*9371c9d4SSatish Balay c[3].k = k; 1005*9371c9d4SSatish Balay c[3].j = j + 1; 1006*9371c9d4SSatish Balay c[3].i = i; 1007e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 10089566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 1009e77315bcSPatrick Sanan } 1010e77315bcSPatrick Sanan 1011e77315bcSPatrick Sanan /* right-hand top edge */ 1012e77315bcSPatrick Sanan } else if (j == my - 1) { 1013e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 1014e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 1015e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 1016e77315bcSPatrick Sanan /* ds = bs * as; */ 1017e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 1018e77315bcSPatrick Sanan gs = coef * bs * (ts - t0); 1019e77315bcSPatrick Sanan 1020e77315bcSPatrick Sanan /* right-hand top down corner */ 1021e77315bcSPatrick Sanan if (k == 0) { 1022e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1023e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1024e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1025e77315bcSPatrick Sanan /* du = bu * au; */ 1026e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1027e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1028e77315bcSPatrick Sanan 1029*9371c9d4SSatish Balay c[0].k = k; 1030*9371c9d4SSatish Balay c[0].j = j - 1; 1031*9371c9d4SSatish Balay c[0].i = i; 1032e77315bcSPatrick Sanan v[0] = -hzhxdhy * (ds - gs); 1033*9371c9d4SSatish Balay c[1].k = k; 1034*9371c9d4SSatish Balay c[1].j = j; 1035*9371c9d4SSatish Balay c[1].i = i - 1; 1036e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1037*9371c9d4SSatish Balay c[2].k = k; 1038*9371c9d4SSatish Balay c[2].j = j; 1039*9371c9d4SSatish Balay c[2].i = i; 1040e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 1041*9371c9d4SSatish Balay c[3].k = k + 1; 1042*9371c9d4SSatish Balay c[3].j = j; 1043*9371c9d4SSatish Balay c[3].i = i; 1044e77315bcSPatrick Sanan v[3] = -hxhydhz * (du + gu); 10459566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 1046e77315bcSPatrick Sanan 1047e77315bcSPatrick Sanan /* right-hand top interior edge */ 1048e77315bcSPatrick Sanan } else if (k < mz - 1) { 1049e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1050e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1051e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1052e77315bcSPatrick Sanan /* du = bu * au; */ 1053e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1054e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1055e77315bcSPatrick Sanan 1056e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1057e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1058e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1059e77315bcSPatrick Sanan /* dd = bd * ad; */ 1060e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1061e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 1062e77315bcSPatrick Sanan 1063*9371c9d4SSatish Balay c[0].k = k - 1; 1064*9371c9d4SSatish Balay c[0].j = j; 1065*9371c9d4SSatish Balay c[0].i = i; 1066e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1067*9371c9d4SSatish Balay c[1].k = k; 1068*9371c9d4SSatish Balay c[1].j = j - 1; 1069*9371c9d4SSatish Balay c[1].i = i; 1070e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1071*9371c9d4SSatish Balay c[2].k = k; 1072*9371c9d4SSatish Balay c[2].j = j; 1073*9371c9d4SSatish Balay c[2].i = i - 1; 1074e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1075*9371c9d4SSatish Balay c[3].k = k; 1076*9371c9d4SSatish Balay c[3].j = j; 1077*9371c9d4SSatish Balay c[3].i = i; 1078e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 1079*9371c9d4SSatish Balay c[4].k = k + 1; 1080*9371c9d4SSatish Balay c[4].j = j; 1081*9371c9d4SSatish Balay c[4].i = i; 1082e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 10839566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1084e77315bcSPatrick Sanan 1085e77315bcSPatrick Sanan /* right-hand top up corner */ 1086e77315bcSPatrick Sanan } else { 1087e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1088e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1089e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1090e77315bcSPatrick Sanan /* dd = bd * ad; */ 1091e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1092e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 1093e77315bcSPatrick Sanan 1094*9371c9d4SSatish Balay c[0].k = k - 1; 1095*9371c9d4SSatish Balay c[0].j = j; 1096*9371c9d4SSatish Balay c[0].i = i; 1097e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1098*9371c9d4SSatish Balay c[1].k = k; 1099*9371c9d4SSatish Balay c[1].j = j - 1; 1100*9371c9d4SSatish Balay c[1].i = i; 1101e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1102*9371c9d4SSatish Balay c[2].k = k; 1103*9371c9d4SSatish Balay c[2].j = j; 1104*9371c9d4SSatish Balay c[2].i = i - 1; 1105e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1106*9371c9d4SSatish Balay c[3].k = k; 1107*9371c9d4SSatish Balay c[3].j = j; 1108*9371c9d4SSatish Balay c[3].i = i; 1109e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 11109566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 4, c, v, INSERT_VALUES)); 1111e77315bcSPatrick Sanan } 1112e77315bcSPatrick Sanan 1113e77315bcSPatrick Sanan } else { 1114e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 1115e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 1116e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 1117e77315bcSPatrick Sanan /* ds = bs * as; */ 1118e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 1119e77315bcSPatrick Sanan gs = coef * bs * (t0 - ts); 1120e77315bcSPatrick Sanan 1121e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 1122e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 1123e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 1124e77315bcSPatrick Sanan /* dn = bn * an; */ 1125e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 1126e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 1127e77315bcSPatrick Sanan 1128e77315bcSPatrick Sanan /* right-hand down interior edge */ 1129e77315bcSPatrick Sanan if (k == 0) { 1130e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1131e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1132e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1133e77315bcSPatrick Sanan /* du = bu * au; */ 1134e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1135e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1136e77315bcSPatrick Sanan 1137*9371c9d4SSatish Balay c[0].k = k; 1138*9371c9d4SSatish Balay c[0].j = j - 1; 1139*9371c9d4SSatish Balay c[0].i = i; 1140e77315bcSPatrick Sanan v[0] = -hzhxdhy * (ds - gs); 1141*9371c9d4SSatish Balay c[1].k = k; 1142*9371c9d4SSatish Balay c[1].j = j; 1143*9371c9d4SSatish Balay c[1].i = i - 1; 1144e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1145*9371c9d4SSatish Balay c[2].k = k; 1146*9371c9d4SSatish Balay c[2].j = j; 1147*9371c9d4SSatish Balay c[2].i = i; 1148e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 1149*9371c9d4SSatish Balay c[3].k = k; 1150*9371c9d4SSatish Balay c[3].j = j + 1; 1151*9371c9d4SSatish Balay c[3].i = i; 1152e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 1153*9371c9d4SSatish Balay c[4].k = k + 1; 1154*9371c9d4SSatish Balay c[4].j = j; 1155*9371c9d4SSatish Balay c[4].i = i; 1156e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 11579566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1158e77315bcSPatrick Sanan 1159e77315bcSPatrick Sanan } else if (k == mz - 1) { /* right-hand up interior edge */ 1160e77315bcSPatrick Sanan 1161e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1162e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1163e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1164e77315bcSPatrick Sanan /* dd = bd * ad; */ 1165e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1166e77315bcSPatrick Sanan gd = coef * bd * (t0 - td); 1167e77315bcSPatrick Sanan 1168*9371c9d4SSatish Balay c[0].k = k - 1; 1169*9371c9d4SSatish Balay c[0].j = j; 1170*9371c9d4SSatish Balay c[0].i = i; 1171e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1172*9371c9d4SSatish Balay c[1].k = k; 1173*9371c9d4SSatish Balay c[1].j = j - 1; 1174*9371c9d4SSatish Balay c[1].i = i; 1175e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1176*9371c9d4SSatish Balay c[2].k = k; 1177*9371c9d4SSatish Balay c[2].j = j; 1178*9371c9d4SSatish Balay c[2].i = i - 1; 1179e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1180*9371c9d4SSatish Balay c[3].k = k; 1181*9371c9d4SSatish Balay c[3].j = j; 1182*9371c9d4SSatish Balay c[3].i = i; 1183e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 1184*9371c9d4SSatish Balay c[4].k = k; 1185*9371c9d4SSatish Balay c[4].j = j + 1; 1186*9371c9d4SSatish Balay c[4].i = i; 1187e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 11889566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1189e77315bcSPatrick Sanan 1190e77315bcSPatrick Sanan } else { /* right-hand interior plane */ 1191e77315bcSPatrick Sanan 1192e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1193e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1194e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1195e77315bcSPatrick Sanan /* dd = bd * ad; */ 1196e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1197e77315bcSPatrick Sanan gd = coef * bd * (t0 - td); 1198e77315bcSPatrick Sanan 1199e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1200e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1201e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1202e77315bcSPatrick Sanan /* du = bu * au; */ 1203e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1204e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1205e77315bcSPatrick Sanan 1206*9371c9d4SSatish Balay c[0].k = k - 1; 1207*9371c9d4SSatish Balay c[0].j = j; 1208*9371c9d4SSatish Balay c[0].i = i; 1209e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1210*9371c9d4SSatish Balay c[1].k = k; 1211*9371c9d4SSatish Balay c[1].j = j - 1; 1212*9371c9d4SSatish Balay c[1].i = i; 1213e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1214*9371c9d4SSatish Balay c[2].k = k; 1215*9371c9d4SSatish Balay c[2].j = j; 1216*9371c9d4SSatish Balay c[2].i = i - 1; 1217e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1218*9371c9d4SSatish Balay c[3].k = k; 1219*9371c9d4SSatish Balay c[3].j = j; 1220*9371c9d4SSatish Balay c[3].i = i; 1221e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 1222*9371c9d4SSatish Balay c[4].k = k; 1223*9371c9d4SSatish Balay c[4].j = j + 1; 1224*9371c9d4SSatish Balay c[4].i = i; 1225e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 1226*9371c9d4SSatish Balay c[5].k = k + 1; 1227*9371c9d4SSatish Balay c[5].j = j; 1228*9371c9d4SSatish Balay c[5].i = i; 1229e77315bcSPatrick Sanan v[5] = -hxhydhz * (du + gu); 12309566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 6, c, v, INSERT_VALUES)); 1231e77315bcSPatrick Sanan } 1232e77315bcSPatrick Sanan } 1233e77315bcSPatrick Sanan 1234e77315bcSPatrick Sanan } else if (j == 0) { 1235e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 1236e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 1237e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 1238e77315bcSPatrick Sanan /* dw = bw * aw */ 1239e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 1240e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 1241e77315bcSPatrick Sanan 1242e77315bcSPatrick Sanan te = x[k][j][i + 1]; 1243e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 1244e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 1245e77315bcSPatrick Sanan /* de = be * ae; */ 1246e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 1247e77315bcSPatrick Sanan ge = coef * be * (te - t0); 1248e77315bcSPatrick Sanan 1249e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 1250e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 1251e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 1252e77315bcSPatrick Sanan /* dn = bn * an; */ 1253e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 1254e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 1255e77315bcSPatrick Sanan 1256e77315bcSPatrick Sanan /* bottom down interior edge */ 1257e77315bcSPatrick Sanan if (k == 0) { 1258e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1259e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1260e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1261e77315bcSPatrick Sanan /* du = bu * au; */ 1262e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1263e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1264e77315bcSPatrick Sanan 1265*9371c9d4SSatish Balay c[0].k = k; 1266*9371c9d4SSatish Balay c[0].j = j; 1267*9371c9d4SSatish Balay c[0].i = i - 1; 1268e77315bcSPatrick Sanan v[0] = -hyhzdhx * (dw - gw); 1269*9371c9d4SSatish Balay c[1].k = k; 1270*9371c9d4SSatish Balay c[1].j = j; 1271*9371c9d4SSatish Balay c[1].i = i; 1272e77315bcSPatrick Sanan v[1] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 1273*9371c9d4SSatish Balay c[2].k = k; 1274*9371c9d4SSatish Balay c[2].j = j; 1275*9371c9d4SSatish Balay c[2].i = i + 1; 1276e77315bcSPatrick Sanan v[2] = -hyhzdhx * (de + ge); 1277*9371c9d4SSatish Balay c[3].k = k; 1278*9371c9d4SSatish Balay c[3].j = j + 1; 1279*9371c9d4SSatish Balay c[3].i = i; 1280e77315bcSPatrick Sanan v[3] = -hzhxdhy * (dn + gn); 1281*9371c9d4SSatish Balay c[4].k = k + 1; 1282*9371c9d4SSatish Balay c[4].j = j; 1283*9371c9d4SSatish Balay c[4].i = i; 1284e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 12859566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1286e77315bcSPatrick Sanan 1287e77315bcSPatrick Sanan } else if (k == mz - 1) { /* bottom up interior edge */ 1288e77315bcSPatrick Sanan 1289e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1290e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1291e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1292e77315bcSPatrick Sanan /* dd = bd * ad; */ 1293e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1294e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 1295e77315bcSPatrick Sanan 1296*9371c9d4SSatish Balay c[0].k = k - 1; 1297*9371c9d4SSatish Balay c[0].j = j; 1298*9371c9d4SSatish Balay c[0].i = i; 1299e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1300*9371c9d4SSatish Balay c[1].k = k; 1301*9371c9d4SSatish Balay c[1].j = j; 1302*9371c9d4SSatish Balay c[1].i = i - 1; 1303e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1304*9371c9d4SSatish Balay c[2].k = k; 1305*9371c9d4SSatish Balay c[2].j = j; 1306*9371c9d4SSatish Balay c[2].i = i; 1307e77315bcSPatrick Sanan v[2] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 1308*9371c9d4SSatish Balay c[3].k = k; 1309*9371c9d4SSatish Balay c[3].j = j; 1310*9371c9d4SSatish Balay c[3].i = i + 1; 1311e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 1312*9371c9d4SSatish Balay c[4].k = k; 1313*9371c9d4SSatish Balay c[4].j = j + 1; 1314*9371c9d4SSatish Balay c[4].i = i; 1315e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 13169566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1317e77315bcSPatrick Sanan 1318e77315bcSPatrick Sanan } else { /* bottom interior plane */ 1319e77315bcSPatrick Sanan 1320e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1321e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1322e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1323e77315bcSPatrick Sanan /* du = bu * au; */ 1324e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1325e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1326e77315bcSPatrick Sanan 1327e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1328e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1329e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1330e77315bcSPatrick Sanan /* dd = bd * ad; */ 1331e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1332e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 1333e77315bcSPatrick Sanan 1334*9371c9d4SSatish Balay c[0].k = k - 1; 1335*9371c9d4SSatish Balay c[0].j = j; 1336*9371c9d4SSatish Balay c[0].i = i; 1337e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1338*9371c9d4SSatish Balay c[1].k = k; 1339*9371c9d4SSatish Balay c[1].j = j; 1340*9371c9d4SSatish Balay c[1].i = i - 1; 1341e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1342*9371c9d4SSatish Balay c[2].k = k; 1343*9371c9d4SSatish Balay c[2].j = j; 1344*9371c9d4SSatish Balay c[2].i = i; 1345e77315bcSPatrick Sanan v[2] = hzhxdhy * (dn - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 1346*9371c9d4SSatish Balay c[3].k = k; 1347*9371c9d4SSatish Balay c[3].j = j; 1348*9371c9d4SSatish Balay c[3].i = i + 1; 1349e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 1350*9371c9d4SSatish Balay c[4].k = k; 1351*9371c9d4SSatish Balay c[4].j = j + 1; 1352*9371c9d4SSatish Balay c[4].i = i; 1353e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 1354*9371c9d4SSatish Balay c[5].k = k + 1; 1355*9371c9d4SSatish Balay c[5].j = j; 1356*9371c9d4SSatish Balay c[5].i = i; 1357e77315bcSPatrick Sanan v[5] = -hxhydhz * (du + gu); 13589566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 6, c, v, INSERT_VALUES)); 1359e77315bcSPatrick Sanan } 1360e77315bcSPatrick Sanan 1361e77315bcSPatrick Sanan } else if (j == my - 1) { 1362e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 1363e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 1364e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 1365e77315bcSPatrick Sanan /* dw = bw * aw */ 1366e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 1367e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 1368e77315bcSPatrick Sanan 1369e77315bcSPatrick Sanan te = x[k][j][i + 1]; 1370e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 1371e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 1372e77315bcSPatrick Sanan /* de = be * ae; */ 1373e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 1374e77315bcSPatrick Sanan ge = coef * be * (te - t0); 1375e77315bcSPatrick Sanan 1376e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 1377e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 1378e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 1379e77315bcSPatrick Sanan /* ds = bs * as; */ 1380e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 1381e77315bcSPatrick Sanan gs = coef * bs * (t0 - ts); 1382e77315bcSPatrick Sanan 1383e77315bcSPatrick Sanan /* top down interior edge */ 1384e77315bcSPatrick Sanan if (k == 0) { 1385e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1386e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1387e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1388e77315bcSPatrick Sanan /* du = bu * au; */ 1389e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1390e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1391e77315bcSPatrick Sanan 1392*9371c9d4SSatish Balay c[0].k = k; 1393*9371c9d4SSatish Balay c[0].j = j - 1; 1394*9371c9d4SSatish Balay c[0].i = i; 1395e77315bcSPatrick Sanan v[0] = -hzhxdhy * (ds - gs); 1396*9371c9d4SSatish Balay c[1].k = k; 1397*9371c9d4SSatish Balay c[1].j = j; 1398*9371c9d4SSatish Balay c[1].i = i - 1; 1399e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1400*9371c9d4SSatish Balay c[2].k = k; 1401*9371c9d4SSatish Balay c[2].j = j; 1402*9371c9d4SSatish Balay c[2].i = i; 1403e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 1404*9371c9d4SSatish Balay c[3].k = k; 1405*9371c9d4SSatish Balay c[3].j = j; 1406*9371c9d4SSatish Balay c[3].i = i + 1; 1407e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 1408*9371c9d4SSatish Balay c[4].k = k + 1; 1409*9371c9d4SSatish Balay c[4].j = j; 1410*9371c9d4SSatish Balay c[4].i = i; 1411e77315bcSPatrick Sanan v[4] = -hxhydhz * (du + gu); 14129566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1413e77315bcSPatrick Sanan 1414e77315bcSPatrick Sanan } else if (k == mz - 1) { /* top up interior edge */ 1415e77315bcSPatrick Sanan 1416e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1417e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1418e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1419e77315bcSPatrick Sanan /* dd = bd * ad; */ 1420e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1421e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 1422e77315bcSPatrick Sanan 1423*9371c9d4SSatish Balay c[0].k = k - 1; 1424*9371c9d4SSatish Balay c[0].j = j; 1425*9371c9d4SSatish Balay c[0].i = i; 1426e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1427*9371c9d4SSatish Balay c[1].k = k; 1428*9371c9d4SSatish Balay c[1].j = j - 1; 1429*9371c9d4SSatish Balay c[1].i = i; 1430e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1431*9371c9d4SSatish Balay c[2].k = k; 1432*9371c9d4SSatish Balay c[2].j = j; 1433*9371c9d4SSatish Balay c[2].i = i - 1; 1434e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1435*9371c9d4SSatish Balay c[3].k = k; 1436*9371c9d4SSatish Balay c[3].j = j; 1437*9371c9d4SSatish Balay c[3].i = i; 1438e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 1439*9371c9d4SSatish Balay c[4].k = k; 1440*9371c9d4SSatish Balay c[4].j = j; 1441*9371c9d4SSatish Balay c[4].i = i + 1; 1442e77315bcSPatrick Sanan v[4] = -hyhzdhx * (de + ge); 14439566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 5, c, v, INSERT_VALUES)); 1444e77315bcSPatrick Sanan 1445e77315bcSPatrick Sanan } else { /* top interior plane */ 1446e77315bcSPatrick Sanan 1447e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1448e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1449e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1450e77315bcSPatrick Sanan /* du = bu * au; */ 1451e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1452e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1453e77315bcSPatrick Sanan 1454e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1455e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1456e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1457e77315bcSPatrick Sanan /* dd = bd * ad; */ 1458e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1459e77315bcSPatrick Sanan gd = coef * bd * (td - t0); 1460e77315bcSPatrick Sanan 1461*9371c9d4SSatish Balay c[0].k = k - 1; 1462*9371c9d4SSatish Balay c[0].j = j; 1463*9371c9d4SSatish Balay c[0].i = i; 1464e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1465*9371c9d4SSatish Balay c[1].k = k; 1466*9371c9d4SSatish Balay c[1].j = j - 1; 1467*9371c9d4SSatish Balay c[1].i = i; 1468e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1469*9371c9d4SSatish Balay c[2].k = k; 1470*9371c9d4SSatish Balay c[2].j = j; 1471*9371c9d4SSatish Balay c[2].i = i - 1; 1472e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1473*9371c9d4SSatish Balay c[3].k = k; 1474*9371c9d4SSatish Balay c[3].j = j; 1475*9371c9d4SSatish Balay c[3].i = i; 1476e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + gs) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + du + gd - gu); 1477*9371c9d4SSatish Balay c[4].k = k; 1478*9371c9d4SSatish Balay c[4].j = j; 1479*9371c9d4SSatish Balay c[4].i = i + 1; 1480e77315bcSPatrick Sanan v[4] = -hyhzdhx * (de + ge); 1481*9371c9d4SSatish Balay c[5].k = k + 1; 1482*9371c9d4SSatish Balay c[5].j = j; 1483*9371c9d4SSatish Balay c[5].i = i; 1484e77315bcSPatrick Sanan v[5] = -hxhydhz * (du + gu); 14859566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 6, c, v, INSERT_VALUES)); 1486e77315bcSPatrick Sanan } 1487e77315bcSPatrick Sanan 1488e77315bcSPatrick Sanan } else if (k == 0) { 1489e77315bcSPatrick Sanan /* down interior plane */ 1490e77315bcSPatrick Sanan 1491e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 1492e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 1493e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 1494e77315bcSPatrick Sanan /* dw = bw * aw */ 1495e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 1496e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 1497e77315bcSPatrick Sanan 1498e77315bcSPatrick Sanan te = x[k][j][i + 1]; 1499e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 1500e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 1501e77315bcSPatrick Sanan /* de = be * ae; */ 1502e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 1503e77315bcSPatrick Sanan ge = coef * be * (te - t0); 1504e77315bcSPatrick Sanan 1505e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 1506e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 1507e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 1508e77315bcSPatrick Sanan /* ds = bs * as; */ 1509e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 1510e77315bcSPatrick Sanan gs = coef * bs * (t0 - ts); 1511e77315bcSPatrick Sanan 1512e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 1513e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 1514e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 1515e77315bcSPatrick Sanan /* dn = bn * an; */ 1516e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 1517e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 1518e77315bcSPatrick Sanan 1519e77315bcSPatrick Sanan tu = x[k + 1][j][i]; 1520e77315bcSPatrick Sanan au = 0.5 * (t0 + tu); 1521e77315bcSPatrick Sanan bu = PetscPowScalar(au, bm1); 1522e77315bcSPatrick Sanan /* du = bu * au; */ 1523e77315bcSPatrick Sanan du = PetscPowScalar(au, beta); 1524e77315bcSPatrick Sanan gu = coef * bu * (tu - t0); 1525e77315bcSPatrick Sanan 1526*9371c9d4SSatish Balay c[0].k = k; 1527*9371c9d4SSatish Balay c[0].j = j - 1; 1528*9371c9d4SSatish Balay c[0].i = i; 1529e77315bcSPatrick Sanan v[0] = -hzhxdhy * (ds - gs); 1530*9371c9d4SSatish Balay c[1].k = k; 1531*9371c9d4SSatish Balay c[1].j = j; 1532*9371c9d4SSatish Balay c[1].i = i - 1; 1533e77315bcSPatrick Sanan v[1] = -hyhzdhx * (dw - gw); 1534*9371c9d4SSatish Balay c[2].k = k; 1535*9371c9d4SSatish Balay c[2].j = j; 1536*9371c9d4SSatish Balay c[2].i = i; 1537e77315bcSPatrick Sanan v[2] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (du - gu); 1538*9371c9d4SSatish Balay c[3].k = k; 1539*9371c9d4SSatish Balay c[3].j = j; 1540*9371c9d4SSatish Balay c[3].i = i + 1; 1541e77315bcSPatrick Sanan v[3] = -hyhzdhx * (de + ge); 1542*9371c9d4SSatish Balay c[4].k = k; 1543*9371c9d4SSatish Balay c[4].j = j + 1; 1544*9371c9d4SSatish Balay c[4].i = i; 1545e77315bcSPatrick Sanan v[4] = -hzhxdhy * (dn + gn); 1546*9371c9d4SSatish Balay c[5].k = k + 1; 1547*9371c9d4SSatish Balay c[5].j = j; 1548*9371c9d4SSatish Balay c[5].i = i; 1549e77315bcSPatrick Sanan v[5] = -hxhydhz * (du + gu); 15509566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 6, c, v, INSERT_VALUES)); 1551e77315bcSPatrick Sanan 1552e77315bcSPatrick Sanan } else if (k == mz - 1) { 1553e77315bcSPatrick Sanan /* up interior plane */ 1554e77315bcSPatrick Sanan 1555e77315bcSPatrick Sanan tw = x[k][j][i - 1]; 1556e77315bcSPatrick Sanan aw = 0.5 * (t0 + tw); 1557e77315bcSPatrick Sanan bw = PetscPowScalar(aw, bm1); 1558e77315bcSPatrick Sanan /* dw = bw * aw */ 1559e77315bcSPatrick Sanan dw = PetscPowScalar(aw, beta); 1560e77315bcSPatrick Sanan gw = coef * bw * (t0 - tw); 1561e77315bcSPatrick Sanan 1562e77315bcSPatrick Sanan te = x[k][j][i + 1]; 1563e77315bcSPatrick Sanan ae = 0.5 * (t0 + te); 1564e77315bcSPatrick Sanan be = PetscPowScalar(ae, bm1); 1565e77315bcSPatrick Sanan /* de = be * ae; */ 1566e77315bcSPatrick Sanan de = PetscPowScalar(ae, beta); 1567e77315bcSPatrick Sanan ge = coef * be * (te - t0); 1568e77315bcSPatrick Sanan 1569e77315bcSPatrick Sanan ts = x[k][j - 1][i]; 1570e77315bcSPatrick Sanan as = 0.5 * (t0 + ts); 1571e77315bcSPatrick Sanan bs = PetscPowScalar(as, bm1); 1572e77315bcSPatrick Sanan /* ds = bs * as; */ 1573e77315bcSPatrick Sanan ds = PetscPowScalar(as, beta); 1574e77315bcSPatrick Sanan gs = coef * bs * (t0 - ts); 1575e77315bcSPatrick Sanan 1576e77315bcSPatrick Sanan tn = x[k][j + 1][i]; 1577e77315bcSPatrick Sanan an = 0.5 * (t0 + tn); 1578e77315bcSPatrick Sanan bn = PetscPowScalar(an, bm1); 1579e77315bcSPatrick Sanan /* dn = bn * an; */ 1580e77315bcSPatrick Sanan dn = PetscPowScalar(an, beta); 1581e77315bcSPatrick Sanan gn = coef * bn * (tn - t0); 1582e77315bcSPatrick Sanan 1583e77315bcSPatrick Sanan td = x[k - 1][j][i]; 1584e77315bcSPatrick Sanan ad = 0.5 * (t0 + td); 1585e77315bcSPatrick Sanan bd = PetscPowScalar(ad, bm1); 1586e77315bcSPatrick Sanan /* dd = bd * ad; */ 1587e77315bcSPatrick Sanan dd = PetscPowScalar(ad, beta); 1588e77315bcSPatrick Sanan gd = coef * bd * (t0 - td); 1589e77315bcSPatrick Sanan 1590*9371c9d4SSatish Balay c[0].k = k - 1; 1591*9371c9d4SSatish Balay c[0].j = j; 1592*9371c9d4SSatish Balay c[0].i = i; 1593e77315bcSPatrick Sanan v[0] = -hxhydhz * (dd - gd); 1594*9371c9d4SSatish Balay c[1].k = k; 1595*9371c9d4SSatish Balay c[1].j = j - 1; 1596*9371c9d4SSatish Balay c[1].i = i; 1597e77315bcSPatrick Sanan v[1] = -hzhxdhy * (ds - gs); 1598*9371c9d4SSatish Balay c[2].k = k; 1599*9371c9d4SSatish Balay c[2].j = j; 1600*9371c9d4SSatish Balay c[2].i = i - 1; 1601e77315bcSPatrick Sanan v[2] = -hyhzdhx * (dw - gw); 1602*9371c9d4SSatish Balay c[3].k = k; 1603*9371c9d4SSatish Balay c[3].j = j; 1604*9371c9d4SSatish Balay c[3].i = i; 1605e77315bcSPatrick Sanan v[3] = hzhxdhy * (ds + dn + gs - gn) + hyhzdhx * (dw + de + gw - ge) + hxhydhz * (dd + gd); 1606*9371c9d4SSatish Balay c[4].k = k; 1607*9371c9d4SSatish Balay c[4].j = j; 1608*9371c9d4SSatish Balay c[4].i = i + 1; 1609e77315bcSPatrick Sanan v[4] = -hyhzdhx * (de + ge); 1610*9371c9d4SSatish Balay c[5].k = k; 1611*9371c9d4SSatish Balay c[5].j = j + 1; 1612*9371c9d4SSatish Balay c[5].i = i; 1613e77315bcSPatrick Sanan v[5] = -hzhxdhy * (dn + gn); 16149566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(jac, 1, &row, 6, c, v, INSERT_VALUES)); 1615e77315bcSPatrick Sanan } 1616e77315bcSPatrick Sanan } 1617e77315bcSPatrick Sanan } 1618e77315bcSPatrick Sanan } 16199566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY)); 16209566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY)); 1621e77315bcSPatrick Sanan if (jac != J) { 16229566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 16239566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 1624e77315bcSPatrick Sanan } 16259566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(da, localX, &x)); 16269566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(da, &localX)); 1627e77315bcSPatrick Sanan 16289566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((41.0 + 8.0 * POWFLOP) * xm * ym)); 1629e77315bcSPatrick Sanan PetscFunctionReturn(0); 1630e77315bcSPatrick Sanan } 1631e77315bcSPatrick Sanan 1632e77315bcSPatrick Sanan /*TEST 1633e77315bcSPatrick Sanan 1634e77315bcSPatrick Sanan test: 1635e77315bcSPatrick Sanan nsize: 4 1636e77315bcSPatrick Sanan args: -snes_monitor_short -pc_mg_type full -ksp_type fgmres -pc_type mg -snes_view -pc_mg_levels 2 -pc_mg_galerkin pmat 1637e77315bcSPatrick Sanan requires: !single 1638e77315bcSPatrick Sanan 1639e77315bcSPatrick Sanan TEST*/ 1640