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 26c4762a1bSJed Brown typedef enum {JACOBIAN_ANALYTIC,JACOBIAN_FD_COLORING,JACOBIAN_FD_FULL} JacobianType; 27c4762a1bSJed Brown static const char *const JacobianTypes[] = {"analytic","fd_coloring","fd_full","JacobianType","fd_",0}; 28c4762a1bSJed Brown 29c4762a1bSJed Brown /* 30c4762a1bSJed Brown User-defined data structures and routines 31c4762a1bSJed Brown */ 32c4762a1bSJed Brown typedef struct { 33c4762a1bSJed Brown PetscReal c; 34c4762a1bSJed Brown PetscInt boundary; /* Type of boundary condition */ 35c4762a1bSJed Brown PetscBool viewJacobian; 36c4762a1bSJed Brown } AppCtx; 37c4762a1bSJed Brown 38c4762a1bSJed Brown static PetscErrorCode FormIFunction(TS,PetscReal,Vec,Vec,Vec,void*); 39c4762a1bSJed Brown static PetscErrorCode FormIJacobian(TS,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*); 40c4762a1bSJed Brown static PetscErrorCode FormInitialSolution(TS,Vec,void*); 41c4762a1bSJed Brown 42c4762a1bSJed Brown int main(int argc,char **argv) 43c4762a1bSJed Brown { 44c4762a1bSJed Brown TS ts; /* nonlinear solver */ 45c4762a1bSJed Brown Vec u; /* solution, residual vectors */ 46c4762a1bSJed Brown Mat J; /* Jacobian matrix */ 47c4762a1bSJed Brown PetscInt nsteps; 48c4762a1bSJed Brown PetscReal vmin,vmax,norm; 49c4762a1bSJed Brown PetscErrorCode ierr; 50c4762a1bSJed Brown DM da; 51c4762a1bSJed Brown PetscReal ftime,dt; 52c4762a1bSJed Brown AppCtx user; /* user-defined work context */ 53c4762a1bSJed Brown JacobianType jacType; 54c4762a1bSJed Brown 55*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscInitialize(&argc,&argv,(char*)0,help)); 56c4762a1bSJed Brown 57c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 58c4762a1bSJed Brown Create distributed array (DMDA) to manage parallel grid and vectors 59c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 605f80ce2aSJacob Faibussowitsch CHKERRQ(DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,11,1,1,NULL,&da)); 615f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetFromOptions(da)); 625f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetUp(da)); 63c4762a1bSJed Brown 64c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 65c4762a1bSJed Brown Extract global vectors from DMDA; 66c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 675f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateGlobalVector(da,&u)); 68c4762a1bSJed Brown 69c4762a1bSJed Brown /* Initialize user application context */ 70c4762a1bSJed Brown user.c = -30.0; 71c4762a1bSJed Brown user.boundary = 0; /* 0: Dirichlet BC; 1: Neumann BC */ 72c4762a1bSJed Brown user.viewJacobian = PETSC_FALSE; 73c4762a1bSJed Brown 745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-boundary",&user.boundary,NULL)); 755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-viewJacobian",&user.viewJacobian)); 76c4762a1bSJed Brown 77c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 78c4762a1bSJed Brown Create timestepping solver context 79c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 805f80ce2aSJacob Faibussowitsch CHKERRQ(TSCreate(PETSC_COMM_WORLD,&ts)); 815f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetProblemType(ts,TS_NONLINEAR)); 825f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetType(ts,TSTHETA)); 835f80ce2aSJacob Faibussowitsch CHKERRQ(TSThetaSetTheta(ts,1.0)); /* Make the Theta method behave like backward Euler */ 845f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetIFunction(ts,NULL,FormIFunction,&user)); 85c4762a1bSJed Brown 865f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetMatType(da,MATAIJ)); 875f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateMatrix(da,&J)); 88c4762a1bSJed Brown jacType = JACOBIAN_ANALYTIC; /* use user-provide Jacobian */ 89c4762a1bSJed Brown 905f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetDM(ts,da)); /* Use TSGetDM() to access. Setting here allows easy use of geometric multigrid. */ 91c4762a1bSJed Brown 92c4762a1bSJed Brown ftime = 1.0; 935f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxTime(ts,ftime)); 945f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); 95c4762a1bSJed Brown 96c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 97c4762a1bSJed Brown Set initial conditions 98c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 995f80ce2aSJacob Faibussowitsch CHKERRQ(FormInitialSolution(ts,u,&user)); 1005f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetSolution(ts,u)); 101c4762a1bSJed Brown dt = .01; 1025f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTimeStep(ts,dt)); 103c4762a1bSJed Brown 104c4762a1bSJed Brown /* Use slow fd Jacobian or fast fd Jacobian with colorings. 105c4762a1bSJed Brown Note: this requirs snes which is not created until TSSetUp()/TSSetFromOptions() is called */ 106c4762a1bSJed Brown ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for Jacobian evaluation",NULL);CHKERRQ(ierr); 1075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsEnum("-jac_type","Type of Jacobian","",JacobianTypes,(PetscEnum)jacType,(PetscEnum*)&jacType,0)); 108c4762a1bSJed Brown ierr = PetscOptionsEnd();CHKERRQ(ierr); 109c4762a1bSJed Brown if (jacType == JACOBIAN_ANALYTIC) { 1105f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetIJacobian(ts,J,J,FormIJacobian,&user)); 111c4762a1bSJed Brown } else if (jacType == JACOBIAN_FD_COLORING) { 112c4762a1bSJed Brown SNES snes; 1135f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSNES(ts,&snes)); 1145f80ce2aSJacob Faibussowitsch CHKERRQ(SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,0)); 115c4762a1bSJed Brown } else if (jacType == JACOBIAN_FD_FULL) { 116c4762a1bSJed Brown SNES snes; 1175f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSNES(ts,&snes)); 1185f80ce2aSJacob Faibussowitsch CHKERRQ(SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,&user)); 119c4762a1bSJed Brown } 120c4762a1bSJed Brown 121c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 122c4762a1bSJed Brown Set runtime options 123c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1245f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetFromOptions(ts)); 125c4762a1bSJed Brown 126c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 127c4762a1bSJed Brown Integrate ODE system 128c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1295f80ce2aSJacob Faibussowitsch CHKERRQ(TSSolve(ts,u)); 130c4762a1bSJed Brown 131c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 132c4762a1bSJed Brown Compute diagnostics of the solution 133c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1345f80ce2aSJacob Faibussowitsch CHKERRQ(VecNorm(u,NORM_1,&norm)); 1355f80ce2aSJacob Faibussowitsch CHKERRQ(VecMax(u,NULL,&vmax)); 1365f80ce2aSJacob Faibussowitsch CHKERRQ(VecMin(u,NULL,&vmin)); 1375f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetStepNumber(ts,&nsteps)); 1385f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetTime(ts,&ftime)); 1395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"timestep %D: time %g, solution norm %g, max %g, min %g\n",nsteps,(double)ftime,(double)norm,(double)vmax,(double)vmin)); 140c4762a1bSJed Brown 141c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 142c4762a1bSJed Brown Free work space. 143c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1445f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&J)); 1455f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&u)); 1465f80ce2aSJacob Faibussowitsch CHKERRQ(TSDestroy(&ts)); 1475f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&da)); 148*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscFinalize()); 149*b122ec5aSJacob Faibussowitsch return 0; 150c4762a1bSJed Brown } 151c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 152c4762a1bSJed Brown static PetscErrorCode FormIFunction(TS ts,PetscReal ftime,Vec U,Vec Udot,Vec F,void *ptr) 153c4762a1bSJed Brown { 154c4762a1bSJed Brown AppCtx *user=(AppCtx*)ptr; 155c4762a1bSJed Brown DM da; 156c4762a1bSJed Brown PetscInt i,Mx,xs,xm; 157c4762a1bSJed Brown PetscReal hx,sx; 158c4762a1bSJed Brown PetscScalar *u,*udot,*f; 159c4762a1bSJed Brown Vec localU; 160c4762a1bSJed Brown 161c4762a1bSJed Brown PetscFunctionBeginUser; 1625f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 1635f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalVector(da,&localU)); 1645f80ce2aSJacob Faibussowitsch CHKERRQ(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)); 165c4762a1bSJed Brown 166c4762a1bSJed Brown hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); 167c4762a1bSJed Brown 168c4762a1bSJed Brown /* 169c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 170c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 171c4762a1bSJed Brown By placing code between these two statements, computations can be 172c4762a1bSJed Brown done while messages are in transition. 173c4762a1bSJed Brown */ 1745f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU)); 1755f80ce2aSJacob Faibussowitsch CHKERRQ(DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU)); 176c4762a1bSJed Brown 177c4762a1bSJed Brown /* Get pointers to vector data */ 1785f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,localU,&u)); 1795f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArrayRead(da,Udot,&udot)); 1805f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArray(da,F,&f)); 181c4762a1bSJed Brown 182c4762a1bSJed Brown /* Get local grid boundaries */ 1835f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 184c4762a1bSJed Brown 185c4762a1bSJed Brown /* Compute function over the locally owned part of the grid */ 186c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 187c4762a1bSJed Brown if (user->boundary == 0) { /* Dirichlet BC */ 188c4762a1bSJed Brown if (i == 0 || i == Mx-1) f[i] = u[i]; /* F = U */ 189c4762a1bSJed Brown else f[i] = udot[i] + (2.*u[i] - u[i-1] - u[i+1])*sx; 190c4762a1bSJed Brown } else { /* Neumann BC */ 191c4762a1bSJed Brown if (i == 0) f[i] = u[0] - u[1]; 192c4762a1bSJed Brown else if (i == Mx-1) f[i] = u[i] - u[i-1]; 193c4762a1bSJed Brown else f[i] = udot[i] + (2.*u[i] - u[i-1] - u[i+1])*sx; 194c4762a1bSJed Brown } 195c4762a1bSJed Brown } 196c4762a1bSJed Brown 197c4762a1bSJed Brown /* Restore vectors */ 1985f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,localU,&u)); 1995f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArrayRead(da,Udot,&udot)); 2005f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArray(da,F,&f)); 2015f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreLocalVector(da,&localU)); 202c4762a1bSJed Brown PetscFunctionReturn(0); 203c4762a1bSJed Brown } 204c4762a1bSJed Brown 205c4762a1bSJed Brown /* --------------------------------------------------------------------- */ 206c4762a1bSJed Brown /* 207c4762a1bSJed Brown IJacobian - Compute IJacobian = dF/dU + a dF/dUdot 208c4762a1bSJed Brown */ 209c4762a1bSJed Brown PetscErrorCode FormIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat J,Mat Jpre,void *ctx) 210c4762a1bSJed Brown { 211c4762a1bSJed Brown PetscInt i,rstart,rend,Mx; 212c4762a1bSJed Brown PetscReal hx,sx; 213c4762a1bSJed Brown AppCtx *user = (AppCtx*)ctx; 214c4762a1bSJed Brown DM da; 215c4762a1bSJed Brown MatStencil col[3],row; 216c4762a1bSJed Brown PetscInt nc; 217c4762a1bSJed Brown PetscScalar vals[3]; 218c4762a1bSJed Brown 219c4762a1bSJed Brown PetscFunctionBeginUser; 2205f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 2215f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOwnershipRange(Jpre,&rstart,&rend)); 2225f80ce2aSJacob Faibussowitsch CHKERRQ(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)); 223c4762a1bSJed Brown hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); 224c4762a1bSJed Brown for (i=rstart; i<rend; i++) { 225c4762a1bSJed Brown nc = 0; 226c4762a1bSJed Brown row.i = i; 227c4762a1bSJed Brown if (user->boundary == 0 && (i == 0 || i == Mx-1)) { 228c4762a1bSJed Brown col[nc].i = i; vals[nc++] = 1.0; 229c4762a1bSJed Brown } else if (user->boundary > 0 && i == 0) { /* Left Neumann */ 230c4762a1bSJed Brown col[nc].i = i; vals[nc++] = 1.0; 231c4762a1bSJed Brown col[nc].i = i+1; vals[nc++] = -1.0; 232c4762a1bSJed Brown } else if (user->boundary > 0 && i == Mx-1) { /* Right Neumann */ 233c4762a1bSJed Brown col[nc].i = i-1; vals[nc++] = -1.0; 234c4762a1bSJed Brown col[nc].i = i; vals[nc++] = 1.0; 235c4762a1bSJed Brown } else { /* Interior */ 236c4762a1bSJed Brown col[nc].i = i-1; vals[nc++] = -1.0*sx; 237c4762a1bSJed Brown col[nc].i = i; vals[nc++] = 2.0*sx + a; 238c4762a1bSJed Brown col[nc].i = i+1; vals[nc++] = -1.0*sx; 239c4762a1bSJed Brown } 2405f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValuesStencil(Jpre,1,&row,nc,col,vals,INSERT_VALUES)); 241c4762a1bSJed Brown } 242c4762a1bSJed Brown 2435f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(Jpre,MAT_FINAL_ASSEMBLY)); 2445f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(Jpre,MAT_FINAL_ASSEMBLY)); 245c4762a1bSJed Brown if (J != Jpre) { 2465f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY)); 2475f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY)); 248c4762a1bSJed Brown } 249c4762a1bSJed Brown if (user->viewJacobian) { 2505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Jpre:\n")); 2515f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(Jpre,PETSC_VIEWER_STDOUT_WORLD)); 252c4762a1bSJed Brown } 253c4762a1bSJed Brown PetscFunctionReturn(0); 254c4762a1bSJed Brown } 255c4762a1bSJed Brown 256c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 257c4762a1bSJed Brown PetscErrorCode FormInitialSolution(TS ts,Vec U,void *ptr) 258c4762a1bSJed Brown { 259c4762a1bSJed Brown AppCtx *user=(AppCtx*)ptr; 260c4762a1bSJed Brown PetscReal c =user->c; 261c4762a1bSJed Brown DM da; 262c4762a1bSJed Brown PetscInt i,xs,xm,Mx; 263c4762a1bSJed Brown PetscScalar *u; 264c4762a1bSJed Brown PetscReal hx,x,r; 265c4762a1bSJed Brown 266c4762a1bSJed Brown PetscFunctionBeginUser; 2675f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetDM(ts,&da)); 2685f80ce2aSJacob Faibussowitsch CHKERRQ(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)); 269c4762a1bSJed Brown 270c4762a1bSJed Brown hx = 1.0/(PetscReal)(Mx-1); 271c4762a1bSJed Brown 272c4762a1bSJed Brown /* Get pointers to vector data */ 2735f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecGetArray(da,U,&u)); 274c4762a1bSJed Brown 275c4762a1bSJed Brown /* Get local grid boundaries */ 2765f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL)); 277c4762a1bSJed Brown 278c4762a1bSJed Brown /* Compute function over the locally owned part of the grid */ 279c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 280c4762a1bSJed Brown x = i*hx; 281c4762a1bSJed Brown r = PetscSqrtReal((x-.5)*(x-.5)); 282c4762a1bSJed Brown if (r < .125) u[i] = PetscExpReal(c*r*r*r); 283c4762a1bSJed Brown else u[i] = 0.0; 284c4762a1bSJed Brown } 285c4762a1bSJed Brown 286c4762a1bSJed Brown /* Restore vectors */ 2875f80ce2aSJacob Faibussowitsch CHKERRQ(DMDAVecRestoreArray(da,U,&u)); 288c4762a1bSJed Brown PetscFunctionReturn(0); 289c4762a1bSJed Brown } 290c4762a1bSJed Brown 291c4762a1bSJed Brown /*TEST 292c4762a1bSJed Brown 293c4762a1bSJed Brown test: 294c4762a1bSJed Brown requires: !single 295c4762a1bSJed Brown args: -da_grid_x 40 -ts_max_steps 2 -snes_monitor_short -ksp_monitor_short -ts_monitor 296c4762a1bSJed Brown 297c4762a1bSJed Brown test: 298c4762a1bSJed Brown suffix: 2 299c4762a1bSJed Brown requires: !single 300c4762a1bSJed Brown args: -da_grid_x 100 -ts_type theta -ts_theta_theta 0.5 301c4762a1bSJed Brown 302c4762a1bSJed Brown TEST*/ 303