1c4762a1bSJed Brown static const char help[] = "Time-dependent PDE in 1d. Simplified from ex15.c for illustrating how to solve DAEs. \n"; 2c4762a1bSJed Brown /* 3c4762a1bSJed Brown u_t = uxx 4c4762a1bSJed Brown 0 < x < 1; 5c4762a1bSJed Brown At t=0: u(x) = exp(c*r*r*r), if r=PetscSqrtReal((x-.5)*(x-.5)) < .125 6c4762a1bSJed Brown u(x) = 0.0 if r >= .125 7c4762a1bSJed Brown 8c4762a1bSJed Brown Boundary conditions: 9c4762a1bSJed Brown Dirichlet BC: 10c4762a1bSJed Brown At x=0, x=1, u = 0.0 11c4762a1bSJed Brown 12c4762a1bSJed Brown Neumann BC: 13c4762a1bSJed Brown At x=0, x=1: du(x,t)/dx = 0 14c4762a1bSJed Brown 15c4762a1bSJed Brown mpiexec -n 2 ./ex17 -da_grid_x 40 -ts_max_steps 2 -snes_monitor -ksp_monitor 16c4762a1bSJed Brown ./ex17 -da_grid_x 40 -monitor_solution 17c4762a1bSJed Brown ./ex17 -da_grid_x 100 -ts_type theta -ts_theta_theta 0.5 # Midpoint is not L-stable 18c4762a1bSJed Brown ./ex17 -jac_type fd_coloring -da_grid_x 500 -boundary 1 19c4762a1bSJed Brown ./ex17 -da_grid_x 100 -ts_type gl -ts_adapt_type none -ts_max_steps 2 20c4762a1bSJed Brown */ 21c4762a1bSJed Brown 22c4762a1bSJed Brown #include <petscdm.h> 23c4762a1bSJed Brown #include <petscdmda.h> 24c4762a1bSJed Brown #include <petscts.h> 25c4762a1bSJed Brown 269371c9d4SSatish Balay typedef enum { 279371c9d4SSatish Balay JACOBIAN_ANALYTIC, 289371c9d4SSatish Balay JACOBIAN_FD_COLORING, 299371c9d4SSatish Balay JACOBIAN_FD_FULL 309371c9d4SSatish Balay } JacobianType; 31c4762a1bSJed Brown static const char *const JacobianTypes[] = {"analytic", "fd_coloring", "fd_full", "JacobianType", "fd_", 0}; 32c4762a1bSJed Brown 33c4762a1bSJed Brown /* 34c4762a1bSJed Brown User-defined data structures and routines 35c4762a1bSJed Brown */ 36c4762a1bSJed Brown typedef struct { 37c4762a1bSJed Brown PetscReal c; 38c4762a1bSJed Brown PetscInt boundary; /* Type of boundary condition */ 39c4762a1bSJed Brown PetscBool viewJacobian; 40c4762a1bSJed Brown } AppCtx; 41c4762a1bSJed Brown 42c4762a1bSJed Brown static PetscErrorCode FormIFunction(TS, PetscReal, Vec, Vec, Vec, void *); 43c4762a1bSJed Brown static PetscErrorCode FormIJacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *); 44c4762a1bSJed Brown static PetscErrorCode FormInitialSolution(TS, Vec, void *); 45c4762a1bSJed Brown 46d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 47d71ae5a4SJacob Faibussowitsch { 48c4762a1bSJed Brown TS ts; /* nonlinear solver */ 49c4762a1bSJed Brown Vec u; /* solution, residual vectors */ 50c4762a1bSJed Brown Mat J; /* Jacobian matrix */ 51c4762a1bSJed Brown PetscInt nsteps; 52c4762a1bSJed Brown PetscReal vmin, vmax, norm; 53c4762a1bSJed Brown DM da; 54c4762a1bSJed Brown PetscReal ftime, dt; 55c4762a1bSJed Brown AppCtx user; /* user-defined work context */ 56c4762a1bSJed Brown JacobianType jacType; 57c4762a1bSJed Brown 58327415f7SBarry Smith PetscFunctionBeginUser; 59c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 60c4762a1bSJed Brown 61c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 62c4762a1bSJed Brown Create distributed array (DMDA) to manage parallel grid and vectors 63c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 649566063dSJacob Faibussowitsch PetscCall(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 11, 1, 1, NULL, &da)); 659566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(da)); 669566063dSJacob Faibussowitsch PetscCall(DMSetUp(da)); 67c4762a1bSJed Brown 68c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 69c4762a1bSJed Brown Extract global vectors from DMDA; 70c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 719566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(da, &u)); 72c4762a1bSJed Brown 73c4762a1bSJed Brown /* Initialize user application context */ 74c4762a1bSJed Brown user.c = -30.0; 75c4762a1bSJed Brown user.boundary = 0; /* 0: Dirichlet BC; 1: Neumann BC */ 76c4762a1bSJed Brown user.viewJacobian = PETSC_FALSE; 77c4762a1bSJed Brown 789566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-boundary", &user.boundary, NULL)); 799566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(NULL, NULL, "-viewJacobian", &user.viewJacobian)); 80c4762a1bSJed Brown 81c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 82c4762a1bSJed Brown Create timestepping solver context 83c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 849566063dSJacob Faibussowitsch PetscCall(TSCreate(PETSC_COMM_WORLD, &ts)); 859566063dSJacob Faibussowitsch PetscCall(TSSetProblemType(ts, TS_NONLINEAR)); 869566063dSJacob Faibussowitsch PetscCall(TSSetType(ts, TSTHETA)); 879566063dSJacob Faibussowitsch PetscCall(TSThetaSetTheta(ts, 1.0)); /* Make the Theta method behave like backward Euler */ 889566063dSJacob Faibussowitsch PetscCall(TSSetIFunction(ts, NULL, FormIFunction, &user)); 89c4762a1bSJed Brown 909566063dSJacob Faibussowitsch PetscCall(DMSetMatType(da, MATAIJ)); 919566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(da, &J)); 92c4762a1bSJed Brown jacType = JACOBIAN_ANALYTIC; /* use user-provide Jacobian */ 93c4762a1bSJed Brown 949566063dSJacob Faibussowitsch PetscCall(TSSetDM(ts, da)); /* Use TSGetDM() to access. Setting here allows easy use of geometric multigrid. */ 95c4762a1bSJed Brown 96c4762a1bSJed Brown ftime = 1.0; 979566063dSJacob Faibussowitsch PetscCall(TSSetMaxTime(ts, ftime)); 989566063dSJacob Faibussowitsch PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER)); 99c4762a1bSJed Brown 100c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 101c4762a1bSJed Brown Set initial conditions 102c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1039566063dSJacob Faibussowitsch PetscCall(FormInitialSolution(ts, u, &user)); 1049566063dSJacob Faibussowitsch PetscCall(TSSetSolution(ts, u)); 105c4762a1bSJed Brown dt = .01; 1069566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, dt)); 107c4762a1bSJed Brown 108c4762a1bSJed Brown /* Use slow fd Jacobian or fast fd Jacobian with colorings. 109145b44c9SPierre Jolivet Note: this requires snes which is not created until TSSetUp()/TSSetFromOptions() is called */ 110d0609cedSBarry Smith PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "Options for Jacobian evaluation", NULL); 1119566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-jac_type", "Type of Jacobian", "", JacobianTypes, (PetscEnum)jacType, (PetscEnum *)&jacType, 0)); 112d0609cedSBarry Smith PetscOptionsEnd(); 113c4762a1bSJed Brown if (jacType == JACOBIAN_ANALYTIC) { 1149566063dSJacob Faibussowitsch PetscCall(TSSetIJacobian(ts, J, J, FormIJacobian, &user)); 115c4762a1bSJed Brown } else if (jacType == JACOBIAN_FD_COLORING) { 116c4762a1bSJed Brown SNES snes; 1179566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 1189566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, SNESComputeJacobianDefaultColor, 0)); 119c4762a1bSJed Brown } else if (jacType == JACOBIAN_FD_FULL) { 120c4762a1bSJed Brown SNES snes; 1219566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 1229566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, SNESComputeJacobianDefault, &user)); 123c4762a1bSJed Brown } 124c4762a1bSJed Brown 125c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 126c4762a1bSJed Brown Set runtime options 127c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1289566063dSJacob Faibussowitsch PetscCall(TSSetFromOptions(ts)); 129c4762a1bSJed Brown 130c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 131c4762a1bSJed Brown Integrate ODE system 132c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1339566063dSJacob Faibussowitsch PetscCall(TSSolve(ts, u)); 134c4762a1bSJed Brown 135c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 136c4762a1bSJed Brown Compute diagnostics of the solution 137c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1389566063dSJacob Faibussowitsch PetscCall(VecNorm(u, NORM_1, &norm)); 1399566063dSJacob Faibussowitsch PetscCall(VecMax(u, NULL, &vmax)); 1409566063dSJacob Faibussowitsch PetscCall(VecMin(u, NULL, &vmin)); 1419566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts, &nsteps)); 1429566063dSJacob Faibussowitsch PetscCall(TSGetTime(ts, &ftime)); 14363a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "timestep %" PetscInt_FMT ": time %g, solution norm %g, max %g, min %g\n", nsteps, (double)ftime, (double)norm, (double)vmax, (double)vmin)); 144c4762a1bSJed Brown 145c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 146c4762a1bSJed Brown Free work space. 147c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1489566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 1499566063dSJacob Faibussowitsch PetscCall(VecDestroy(&u)); 1509566063dSJacob Faibussowitsch PetscCall(TSDestroy(&ts)); 1519566063dSJacob Faibussowitsch PetscCall(DMDestroy(&da)); 1529566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 153b122ec5aSJacob Faibussowitsch return 0; 154c4762a1bSJed Brown } 155c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 156d71ae5a4SJacob Faibussowitsch static PetscErrorCode FormIFunction(TS ts, PetscReal ftime, Vec U, Vec Udot, Vec F, void *ptr) 157d71ae5a4SJacob Faibussowitsch { 158c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr; 159c4762a1bSJed Brown DM da; 160c4762a1bSJed Brown PetscInt i, Mx, xs, xm; 161c4762a1bSJed Brown PetscReal hx, sx; 162c4762a1bSJed Brown PetscScalar *u, *udot, *f; 163c4762a1bSJed Brown Vec localU; 164c4762a1bSJed Brown 165c4762a1bSJed Brown PetscFunctionBeginUser; 1669566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &da)); 1679566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(da, &localU)); 1689566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, PETSC_IGNORE, &Mx, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE)); 169c4762a1bSJed Brown 1709371c9d4SSatish Balay hx = 1.0 / (PetscReal)(Mx - 1); 1719371c9d4SSatish Balay sx = 1.0 / (hx * hx); 172c4762a1bSJed Brown 173c4762a1bSJed Brown /* 174c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 175c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 176c4762a1bSJed Brown By placing code between these two statements, computations can be 177c4762a1bSJed Brown done while messages are in transition. 178c4762a1bSJed Brown */ 1799566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(da, U, INSERT_VALUES, localU)); 1809566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(da, U, INSERT_VALUES, localU)); 181c4762a1bSJed Brown 182c4762a1bSJed Brown /* Get pointers to vector data */ 1839566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayRead(da, localU, &u)); 1849566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayRead(da, Udot, &udot)); 1859566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(da, F, &f)); 186c4762a1bSJed Brown 187c4762a1bSJed Brown /* Get local grid boundaries */ 1889566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, NULL, NULL, &xm, NULL, NULL)); 189c4762a1bSJed Brown 190c4762a1bSJed Brown /* Compute function over the locally owned part of the grid */ 191c4762a1bSJed Brown for (i = xs; i < xs + xm; i++) { 192c4762a1bSJed Brown if (user->boundary == 0) { /* Dirichlet BC */ 193c4762a1bSJed Brown if (i == 0 || i == Mx - 1) f[i] = u[i]; /* F = U */ 194c4762a1bSJed Brown else f[i] = udot[i] + (2. * u[i] - u[i - 1] - u[i + 1]) * sx; 195c4762a1bSJed Brown } else { /* Neumann BC */ 196c4762a1bSJed Brown if (i == 0) f[i] = u[0] - u[1]; 197c4762a1bSJed Brown else if (i == Mx - 1) f[i] = u[i] - u[i - 1]; 198c4762a1bSJed Brown else f[i] = udot[i] + (2. * u[i] - u[i - 1] - u[i + 1]) * sx; 199c4762a1bSJed Brown } 200c4762a1bSJed Brown } 201c4762a1bSJed Brown 202c4762a1bSJed Brown /* Restore vectors */ 2039566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayRead(da, localU, &u)); 2049566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayRead(da, Udot, &udot)); 2059566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(da, F, &f)); 2069566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(da, &localU)); 2073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208c4762a1bSJed Brown } 209c4762a1bSJed Brown 210c4762a1bSJed Brown /* --------------------------------------------------------------------- */ 211c4762a1bSJed Brown /* 212c4762a1bSJed Brown IJacobian - Compute IJacobian = dF/dU + a dF/dUdot 213c4762a1bSJed Brown */ 214*2a8381b2SBarry Smith PetscErrorCode FormIJacobian(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal a, Mat J, Mat Jpre, PetscCtx ctx) 215d71ae5a4SJacob Faibussowitsch { 216c4762a1bSJed Brown PetscInt i, rstart, rend, Mx; 217c4762a1bSJed Brown PetscReal hx, sx; 218c4762a1bSJed Brown AppCtx *user = (AppCtx *)ctx; 219c4762a1bSJed Brown DM da; 220c4762a1bSJed Brown MatStencil col[3], row; 221c4762a1bSJed Brown PetscInt nc; 222c4762a1bSJed Brown PetscScalar vals[3]; 223c4762a1bSJed Brown 224c4762a1bSJed Brown PetscFunctionBeginUser; 2259566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &da)); 2269566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(Jpre, &rstart, &rend)); 2279566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, PETSC_IGNORE, &Mx, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE)); 2289371c9d4SSatish Balay hx = 1.0 / (PetscReal)(Mx - 1); 2299371c9d4SSatish Balay sx = 1.0 / (hx * hx); 230c4762a1bSJed Brown for (i = rstart; i < rend; i++) { 231c4762a1bSJed Brown nc = 0; 232c4762a1bSJed Brown row.i = i; 233c4762a1bSJed Brown if (user->boundary == 0 && (i == 0 || i == Mx - 1)) { 2349371c9d4SSatish Balay col[nc].i = i; 2359371c9d4SSatish Balay vals[nc++] = 1.0; 236c4762a1bSJed Brown } else if (user->boundary > 0 && i == 0) { /* Left Neumann */ 2379371c9d4SSatish Balay col[nc].i = i; 2389371c9d4SSatish Balay vals[nc++] = 1.0; 2399371c9d4SSatish Balay col[nc].i = i + 1; 2409371c9d4SSatish Balay vals[nc++] = -1.0; 241c4762a1bSJed Brown } else if (user->boundary > 0 && i == Mx - 1) { /* Right Neumann */ 2429371c9d4SSatish Balay col[nc].i = i - 1; 2439371c9d4SSatish Balay vals[nc++] = -1.0; 2449371c9d4SSatish Balay col[nc].i = i; 2459371c9d4SSatish Balay vals[nc++] = 1.0; 246c4762a1bSJed Brown } else { /* Interior */ 2479371c9d4SSatish Balay col[nc].i = i - 1; 2489371c9d4SSatish Balay vals[nc++] = -1.0 * sx; 2499371c9d4SSatish Balay col[nc].i = i; 2509371c9d4SSatish Balay vals[nc++] = 2.0 * sx + a; 2519371c9d4SSatish Balay col[nc].i = i + 1; 2529371c9d4SSatish Balay vals[nc++] = -1.0 * sx; 253c4762a1bSJed Brown } 2549566063dSJacob Faibussowitsch PetscCall(MatSetValuesStencil(Jpre, 1, &row, nc, col, vals, INSERT_VALUES)); 255c4762a1bSJed Brown } 256c4762a1bSJed Brown 2579566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY)); 2589566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY)); 259c4762a1bSJed Brown if (J != Jpre) { 2609566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 2619566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 262c4762a1bSJed Brown } 263c4762a1bSJed Brown if (user->viewJacobian) { 2649566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Jpre:\n")); 2659566063dSJacob Faibussowitsch PetscCall(MatView(Jpre, PETSC_VIEWER_STDOUT_WORLD)); 266c4762a1bSJed Brown } 2673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 268c4762a1bSJed Brown } 269c4762a1bSJed Brown 270c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 271d71ae5a4SJacob Faibussowitsch PetscErrorCode FormInitialSolution(TS ts, Vec U, void *ptr) 272d71ae5a4SJacob Faibussowitsch { 273c4762a1bSJed Brown AppCtx *user = (AppCtx *)ptr; 274c4762a1bSJed Brown PetscReal c = user->c; 275c4762a1bSJed Brown DM da; 276c4762a1bSJed Brown PetscInt i, xs, xm, Mx; 277c4762a1bSJed Brown PetscScalar *u; 278c4762a1bSJed Brown PetscReal hx, x, r; 279c4762a1bSJed Brown 280c4762a1bSJed Brown PetscFunctionBeginUser; 2819566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &da)); 2829566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, PETSC_IGNORE, &Mx, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE)); 283c4762a1bSJed Brown 284c4762a1bSJed Brown hx = 1.0 / (PetscReal)(Mx - 1); 285c4762a1bSJed Brown 286c4762a1bSJed Brown /* Get pointers to vector data */ 2879566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArray(da, U, &u)); 288c4762a1bSJed Brown 289c4762a1bSJed Brown /* Get local grid boundaries */ 2909566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, NULL, NULL, &xm, NULL, NULL)); 291c4762a1bSJed Brown 292c4762a1bSJed Brown /* Compute function over the locally owned part of the grid */ 293c4762a1bSJed Brown for (i = xs; i < xs + xm; i++) { 294c4762a1bSJed Brown x = i * hx; 295c4762a1bSJed Brown r = PetscSqrtReal((x - .5) * (x - .5)); 296c4762a1bSJed Brown if (r < .125) u[i] = PetscExpReal(c * r * r * r); 297c4762a1bSJed Brown else u[i] = 0.0; 298c4762a1bSJed Brown } 299c4762a1bSJed Brown 300c4762a1bSJed Brown /* Restore vectors */ 3019566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArray(da, U, &u)); 3023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 303c4762a1bSJed Brown } 304c4762a1bSJed Brown 305c4762a1bSJed Brown /*TEST 306c4762a1bSJed Brown 307c4762a1bSJed Brown test: 308c4762a1bSJed Brown requires: !single 309c4762a1bSJed Brown args: -da_grid_x 40 -ts_max_steps 2 -snes_monitor_short -ksp_monitor_short -ts_monitor 310c4762a1bSJed Brown 311c4762a1bSJed Brown test: 312c4762a1bSJed Brown suffix: 2 313c4762a1bSJed Brown requires: !single 314c4762a1bSJed Brown args: -da_grid_x 100 -ts_type theta -ts_theta_theta 0.5 315c4762a1bSJed Brown 316c4762a1bSJed Brown TEST*/ 317