1*c4762a1bSJed Brown static char help[] = "Demonstrates adjoint sensitivity analysis for Reaction-Diffusion Equations.\n"; 2*c4762a1bSJed Brown 3*c4762a1bSJed Brown /* 4*c4762a1bSJed Brown See ex5.c for details on the equation. 5*c4762a1bSJed Brown This code demonestrates the TSAdjoint interface to a system of time-dependent partial differential equations. 6*c4762a1bSJed Brown It computes the sensitivity of a component in the final solution, which locates in the center of the 2D domain, w.r.t. the initial conditions. 7*c4762a1bSJed Brown The user does not need to provide any additional functions. The required functions in the original simulation are reused in the adjoint run. 8*c4762a1bSJed Brown 9*c4762a1bSJed Brown Runtime options: 10*c4762a1bSJed Brown -forwardonly - run the forward simulation without adjoint 11*c4762a1bSJed Brown -implicitform - provide IFunction and IJacobian to TS, if not set, RHSFunction and RHSJacobian will be used 12*c4762a1bSJed Brown -aijpc - set the preconditioner matrix to be aij (the Jacobian matrix can be of a different type such as ELL) 13*c4762a1bSJed Brown */ 14*c4762a1bSJed Brown 15*c4762a1bSJed Brown #include <petscsys.h> 16*c4762a1bSJed Brown #include <petscdm.h> 17*c4762a1bSJed Brown #include <petscdmda.h> 18*c4762a1bSJed Brown #include <petscts.h> 19*c4762a1bSJed Brown 20*c4762a1bSJed Brown typedef struct { 21*c4762a1bSJed Brown PetscScalar u,v; 22*c4762a1bSJed Brown } Field; 23*c4762a1bSJed Brown 24*c4762a1bSJed Brown typedef struct { 25*c4762a1bSJed Brown PetscReal D1,D2,gamma,kappa; 26*c4762a1bSJed Brown PetscBool aijpc; 27*c4762a1bSJed Brown } AppCtx; 28*c4762a1bSJed Brown 29*c4762a1bSJed Brown /* 30*c4762a1bSJed Brown User-defined routines 31*c4762a1bSJed Brown */ 32*c4762a1bSJed Brown PetscErrorCode RHSFunction(TS,PetscReal,Vec,Vec,void*); 33*c4762a1bSJed Brown PetscErrorCode InitialConditions(DM,Vec); 34*c4762a1bSJed Brown PetscErrorCode RHSJacobian(TS,PetscReal,Vec,Mat,Mat,void*); 35*c4762a1bSJed Brown PetscErrorCode IFunction(TS,PetscReal,Vec,Vec,Vec,void*); 36*c4762a1bSJed Brown PetscErrorCode IJacobian(TS,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*); 37*c4762a1bSJed Brown 38*c4762a1bSJed Brown PetscErrorCode InitializeLambda(DM da,Vec lambda,PetscReal x,PetscReal y) 39*c4762a1bSJed Brown { 40*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 41*c4762a1bSJed Brown PetscErrorCode ierr; 42*c4762a1bSJed Brown Field **l; 43*c4762a1bSJed Brown PetscFunctionBegin; 44*c4762a1bSJed Brown 45*c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 46*c4762a1bSJed Brown /* locate the global i index for x and j index for y */ 47*c4762a1bSJed Brown i = (PetscInt)(x*(Mx-1)); 48*c4762a1bSJed Brown j = (PetscInt)(y*(My-1)); 49*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 50*c4762a1bSJed Brown 51*c4762a1bSJed Brown if (xs <= i && i < xs+xm && ys <= j && j < ys+ym) { 52*c4762a1bSJed Brown /* the i,j vertex is on this process */ 53*c4762a1bSJed Brown ierr = DMDAVecGetArray(da,lambda,&l);CHKERRQ(ierr); 54*c4762a1bSJed Brown l[j][i].u = 1.0; 55*c4762a1bSJed Brown l[j][i].v = 1.0; 56*c4762a1bSJed Brown ierr = DMDAVecRestoreArray(da,lambda,&l);CHKERRQ(ierr); 57*c4762a1bSJed Brown } 58*c4762a1bSJed Brown PetscFunctionReturn(0); 59*c4762a1bSJed Brown } 60*c4762a1bSJed Brown 61*c4762a1bSJed Brown int main(int argc,char **argv) 62*c4762a1bSJed Brown { 63*c4762a1bSJed Brown TS ts; /* ODE integrator */ 64*c4762a1bSJed Brown Vec x; /* solution */ 65*c4762a1bSJed Brown PetscErrorCode ierr; 66*c4762a1bSJed Brown DM da; 67*c4762a1bSJed Brown AppCtx appctx; 68*c4762a1bSJed Brown Vec lambda[1]; 69*c4762a1bSJed Brown PetscBool forwardonly=PETSC_FALSE,implicitform=PETSC_TRUE; 70*c4762a1bSJed Brown 71*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 72*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-forwardonly",&forwardonly,NULL);CHKERRQ(ierr); 73*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-implicitform",&implicitform,NULL);CHKERRQ(ierr); 74*c4762a1bSJed Brown appctx.aijpc = PETSC_FALSE; 75*c4762a1bSJed Brown ierr = PetscOptionsGetBool(NULL,NULL,"-aijpc",&appctx.aijpc,NULL);CHKERRQ(ierr); 76*c4762a1bSJed Brown 77*c4762a1bSJed Brown appctx.D1 = 8.0e-5; 78*c4762a1bSJed Brown appctx.D2 = 4.0e-5; 79*c4762a1bSJed Brown appctx.gamma = .024; 80*c4762a1bSJed Brown appctx.kappa = .06; 81*c4762a1bSJed Brown 82*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 83*c4762a1bSJed Brown Create distributed array (DMDA) to manage parallel grid and vectors 84*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 85*c4762a1bSJed Brown ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,DM_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,64,64,PETSC_DECIDE,PETSC_DECIDE,2,1,NULL,NULL,&da);CHKERRQ(ierr); 86*c4762a1bSJed Brown ierr = DMSetFromOptions(da);CHKERRQ(ierr); 87*c4762a1bSJed Brown ierr = DMSetUp(da);CHKERRQ(ierr); 88*c4762a1bSJed Brown ierr = DMDASetFieldName(da,0,"u");CHKERRQ(ierr); 89*c4762a1bSJed Brown ierr = DMDASetFieldName(da,1,"v");CHKERRQ(ierr); 90*c4762a1bSJed Brown 91*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 92*c4762a1bSJed Brown Extract global vectors from DMDA; then duplicate for remaining 93*c4762a1bSJed Brown vectors that are the same types 94*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 95*c4762a1bSJed Brown ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); 96*c4762a1bSJed Brown 97*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 98*c4762a1bSJed Brown Create timestepping solver context 99*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 100*c4762a1bSJed Brown ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); 101*c4762a1bSJed Brown ierr = TSSetDM(ts,da);CHKERRQ(ierr); 102*c4762a1bSJed Brown ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); 103*c4762a1bSJed Brown ierr = TSSetEquationType(ts,TS_EQ_ODE_EXPLICIT);CHKERRQ(ierr); /* less Jacobian evaluations when adjoint BEuler is used, otherwise no effect */ 104*c4762a1bSJed Brown if (!implicitform) { 105*c4762a1bSJed Brown ierr = TSSetType(ts,TSRK);CHKERRQ(ierr); 106*c4762a1bSJed Brown ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&appctx);CHKERRQ(ierr); 107*c4762a1bSJed Brown ierr = TSSetRHSJacobian(ts,NULL,NULL,RHSJacobian,&appctx);CHKERRQ(ierr); 108*c4762a1bSJed Brown } else { 109*c4762a1bSJed Brown ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); 110*c4762a1bSJed Brown ierr = TSSetIFunction(ts,NULL,IFunction,&appctx);CHKERRQ(ierr); 111*c4762a1bSJed Brown if (appctx.aijpc) { 112*c4762a1bSJed Brown Mat A,B; 113*c4762a1bSJed Brown 114*c4762a1bSJed Brown ierr = DMSetMatType(da,MATSELL);CHKERRQ(ierr); 115*c4762a1bSJed Brown ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); 116*c4762a1bSJed Brown ierr = MatConvert(A,MATAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 117*c4762a1bSJed Brown /* FIXME do we need to change viewer to display matrix in natural ordering as DMCreateMatrix_DA does? */ 118*c4762a1bSJed Brown ierr = TSSetIJacobian(ts,A,B,IJacobian,&appctx);CHKERRQ(ierr); 119*c4762a1bSJed Brown ierr = MatDestroy(&A);CHKERRQ(ierr); 120*c4762a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 121*c4762a1bSJed Brown } else { 122*c4762a1bSJed Brown ierr = TSSetIJacobian(ts,NULL,NULL,IJacobian,&appctx);CHKERRQ(ierr); 123*c4762a1bSJed Brown } 124*c4762a1bSJed Brown } 125*c4762a1bSJed Brown 126*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 127*c4762a1bSJed Brown Set initial conditions 128*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 129*c4762a1bSJed Brown ierr = InitialConditions(da,x);CHKERRQ(ierr); 130*c4762a1bSJed Brown ierr = TSSetSolution(ts,x);CHKERRQ(ierr); 131*c4762a1bSJed Brown 132*c4762a1bSJed Brown /* 133*c4762a1bSJed Brown Have the TS save its trajectory so that TSAdjointSolve() may be used 134*c4762a1bSJed Brown */ 135*c4762a1bSJed Brown if (!forwardonly) { ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); } 136*c4762a1bSJed Brown 137*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 138*c4762a1bSJed Brown Set solver options 139*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 140*c4762a1bSJed Brown ierr = TSSetMaxTime(ts,200.0);CHKERRQ(ierr); 141*c4762a1bSJed Brown ierr = TSSetTimeStep(ts,0.5);CHKERRQ(ierr); 142*c4762a1bSJed Brown ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); 143*c4762a1bSJed Brown ierr = TSSetFromOptions(ts);CHKERRQ(ierr); 144*c4762a1bSJed Brown 145*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 146*c4762a1bSJed Brown Solve ODE system 147*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 148*c4762a1bSJed Brown ierr = TSSolve(ts,x);CHKERRQ(ierr); 149*c4762a1bSJed Brown if (!forwardonly) { 150*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 151*c4762a1bSJed Brown Start the Adjoint model 152*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 153*c4762a1bSJed Brown ierr = VecDuplicate(x,&lambda[0]);CHKERRQ(ierr); 154*c4762a1bSJed Brown /* Reset initial conditions for the adjoint integration */ 155*c4762a1bSJed Brown ierr = InitializeLambda(da,lambda[0],0.5,0.5);CHKERRQ(ierr); 156*c4762a1bSJed Brown ierr = TSSetCostGradients(ts,1,lambda,NULL);CHKERRQ(ierr); 157*c4762a1bSJed Brown ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 158*c4762a1bSJed Brown ierr = VecDestroy(&lambda[0]);CHKERRQ(ierr); 159*c4762a1bSJed Brown } 160*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 161*c4762a1bSJed Brown Free work space. All PETSc objects should be destroyed when they 162*c4762a1bSJed Brown are no longer needed. 163*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 164*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 165*c4762a1bSJed Brown ierr = TSDestroy(&ts);CHKERRQ(ierr); 166*c4762a1bSJed Brown ierr = DMDestroy(&da);CHKERRQ(ierr); 167*c4762a1bSJed Brown ierr = PetscFinalize(); 168*c4762a1bSJed Brown return ierr; 169*c4762a1bSJed Brown } 170*c4762a1bSJed Brown 171*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 172*c4762a1bSJed Brown /* 173*c4762a1bSJed Brown RHSFunction - Evaluates nonlinear function, F(x). 174*c4762a1bSJed Brown 175*c4762a1bSJed Brown Input Parameters: 176*c4762a1bSJed Brown . ts - the TS context 177*c4762a1bSJed Brown . X - input vector 178*c4762a1bSJed Brown . ptr - optional user-defined context, as set by TSSetRHSFunction() 179*c4762a1bSJed Brown 180*c4762a1bSJed Brown Output Parameter: 181*c4762a1bSJed Brown . F - function vector 182*c4762a1bSJed Brown */ 183*c4762a1bSJed Brown PetscErrorCode RHSFunction(TS ts,PetscReal ftime,Vec U,Vec F,void *ptr) 184*c4762a1bSJed Brown { 185*c4762a1bSJed Brown AppCtx *appctx = (AppCtx*)ptr; 186*c4762a1bSJed Brown DM da; 187*c4762a1bSJed Brown PetscErrorCode ierr; 188*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 189*c4762a1bSJed Brown PetscReal hx,hy,sx,sy; 190*c4762a1bSJed Brown PetscScalar uc,uxx,uyy,vc,vxx,vyy; 191*c4762a1bSJed Brown Field **u,**f; 192*c4762a1bSJed Brown Vec localU; 193*c4762a1bSJed Brown 194*c4762a1bSJed Brown PetscFunctionBegin; 195*c4762a1bSJed Brown ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 196*c4762a1bSJed Brown ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); 197*c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 198*c4762a1bSJed Brown hx = 2.50/(PetscReal)Mx; sx = 1.0/(hx*hx); 199*c4762a1bSJed Brown hy = 2.50/(PetscReal)My; sy = 1.0/(hy*hy); 200*c4762a1bSJed Brown 201*c4762a1bSJed Brown /* 202*c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 203*c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 204*c4762a1bSJed Brown By placing code between these two statements, computations can be 205*c4762a1bSJed Brown done while messages are in transition. 206*c4762a1bSJed Brown */ 207*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 208*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 209*c4762a1bSJed Brown 210*c4762a1bSJed Brown /* 211*c4762a1bSJed Brown Get pointers to vector data 212*c4762a1bSJed Brown */ 213*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); 214*c4762a1bSJed Brown ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); 215*c4762a1bSJed Brown 216*c4762a1bSJed Brown /* 217*c4762a1bSJed Brown Get local grid boundaries 218*c4762a1bSJed Brown */ 219*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 220*c4762a1bSJed Brown 221*c4762a1bSJed Brown /* 222*c4762a1bSJed Brown Compute function over the locally owned part of the grid 223*c4762a1bSJed Brown */ 224*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 225*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 226*c4762a1bSJed Brown uc = u[j][i].u; 227*c4762a1bSJed Brown uxx = (-2.0*uc + u[j][i-1].u + u[j][i+1].u)*sx; 228*c4762a1bSJed Brown uyy = (-2.0*uc + u[j-1][i].u + u[j+1][i].u)*sy; 229*c4762a1bSJed Brown vc = u[j][i].v; 230*c4762a1bSJed Brown vxx = (-2.0*vc + u[j][i-1].v + u[j][i+1].v)*sx; 231*c4762a1bSJed Brown vyy = (-2.0*vc + u[j-1][i].v + u[j+1][i].v)*sy; 232*c4762a1bSJed Brown f[j][i].u = appctx->D1*(uxx + uyy) - uc*vc*vc + appctx->gamma*(1.0 - uc); 233*c4762a1bSJed Brown f[j][i].v = appctx->D2*(vxx + vyy) + uc*vc*vc - (appctx->gamma + appctx->kappa)*vc; 234*c4762a1bSJed Brown } 235*c4762a1bSJed Brown } 236*c4762a1bSJed Brown ierr = PetscLogFlops(16*xm*ym);CHKERRQ(ierr); 237*c4762a1bSJed Brown 238*c4762a1bSJed Brown /* 239*c4762a1bSJed Brown Restore vectors 240*c4762a1bSJed Brown */ 241*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,localU,&u);CHKERRQ(ierr); 242*c4762a1bSJed Brown ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); 243*c4762a1bSJed Brown ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); 244*c4762a1bSJed Brown PetscFunctionReturn(0); 245*c4762a1bSJed Brown } 246*c4762a1bSJed Brown 247*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 248*c4762a1bSJed Brown PetscErrorCode InitialConditions(DM da,Vec U) 249*c4762a1bSJed Brown { 250*c4762a1bSJed Brown PetscErrorCode ierr; 251*c4762a1bSJed Brown PetscInt i,j,xs,ys,xm,ym,Mx,My; 252*c4762a1bSJed Brown Field **u; 253*c4762a1bSJed Brown PetscReal hx,hy,x,y; 254*c4762a1bSJed Brown 255*c4762a1bSJed Brown PetscFunctionBegin; 256*c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 257*c4762a1bSJed Brown 258*c4762a1bSJed Brown hx = 2.5/(PetscReal)Mx; 259*c4762a1bSJed Brown hy = 2.5/(PetscReal)My; 260*c4762a1bSJed Brown 261*c4762a1bSJed Brown /* 262*c4762a1bSJed Brown Get pointers to vector data 263*c4762a1bSJed Brown */ 264*c4762a1bSJed Brown ierr = DMDAVecGetArray(da,U,&u);CHKERRQ(ierr); 265*c4762a1bSJed Brown 266*c4762a1bSJed Brown /* 267*c4762a1bSJed Brown Get local grid boundaries 268*c4762a1bSJed Brown */ 269*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 270*c4762a1bSJed Brown 271*c4762a1bSJed Brown /* 272*c4762a1bSJed Brown Compute function over the locally owned part of the grid 273*c4762a1bSJed Brown */ 274*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 275*c4762a1bSJed Brown y = j*hy; 276*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 277*c4762a1bSJed Brown x = i*hx; 278*c4762a1bSJed Brown if ((1.0 <= x) && (x <= 1.5) && (1.0 <= y) && (y <= 1.5)) u[j][i].v = .25*PetscPowReal(PetscSinReal(4.0*PETSC_PI*x),2.0)*PetscPowReal(PetscSinReal(4.0*PETSC_PI*y),2.0); 279*c4762a1bSJed Brown else u[j][i].v = 0.0; 280*c4762a1bSJed Brown 281*c4762a1bSJed Brown u[j][i].u = 1.0 - 2.0*u[j][i].v; 282*c4762a1bSJed Brown } 283*c4762a1bSJed Brown } 284*c4762a1bSJed Brown 285*c4762a1bSJed Brown /* 286*c4762a1bSJed Brown Restore vectors 287*c4762a1bSJed Brown */ 288*c4762a1bSJed Brown ierr = DMDAVecRestoreArray(da,U,&u);CHKERRQ(ierr); 289*c4762a1bSJed Brown PetscFunctionReturn(0); 290*c4762a1bSJed Brown } 291*c4762a1bSJed Brown 292*c4762a1bSJed Brown PetscErrorCode RHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat BB,void *ctx) 293*c4762a1bSJed Brown { 294*c4762a1bSJed Brown AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */ 295*c4762a1bSJed Brown DM da; 296*c4762a1bSJed Brown PetscErrorCode ierr; 297*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 298*c4762a1bSJed Brown PetscReal hx,hy,sx,sy; 299*c4762a1bSJed Brown PetscScalar uc,vc; 300*c4762a1bSJed Brown Field **u; 301*c4762a1bSJed Brown Vec localU; 302*c4762a1bSJed Brown MatStencil stencil[6],rowstencil; 303*c4762a1bSJed Brown PetscScalar entries[6]; 304*c4762a1bSJed Brown 305*c4762a1bSJed Brown PetscFunctionBegin; 306*c4762a1bSJed Brown ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 307*c4762a1bSJed Brown ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); 308*c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 309*c4762a1bSJed Brown 310*c4762a1bSJed Brown hx = 2.50/(PetscReal)Mx; sx = 1.0/(hx*hx); 311*c4762a1bSJed Brown hy = 2.50/(PetscReal)My; sy = 1.0/(hy*hy); 312*c4762a1bSJed Brown 313*c4762a1bSJed Brown /* 314*c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 315*c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 316*c4762a1bSJed Brown By placing code between these two statements, computations can be 317*c4762a1bSJed Brown done while messages are in transition. 318*c4762a1bSJed Brown */ 319*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 320*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 321*c4762a1bSJed Brown 322*c4762a1bSJed Brown /* 323*c4762a1bSJed Brown Get pointers to vector data 324*c4762a1bSJed Brown */ 325*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); 326*c4762a1bSJed Brown 327*c4762a1bSJed Brown /* 328*c4762a1bSJed Brown Get local grid boundaries 329*c4762a1bSJed Brown */ 330*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 331*c4762a1bSJed Brown 332*c4762a1bSJed Brown stencil[0].k = 0; 333*c4762a1bSJed Brown stencil[1].k = 0; 334*c4762a1bSJed Brown stencil[2].k = 0; 335*c4762a1bSJed Brown stencil[3].k = 0; 336*c4762a1bSJed Brown stencil[4].k = 0; 337*c4762a1bSJed Brown stencil[5].k = 0; 338*c4762a1bSJed Brown rowstencil.k = 0; 339*c4762a1bSJed Brown /* 340*c4762a1bSJed Brown Compute function over the locally owned part of the grid 341*c4762a1bSJed Brown */ 342*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 343*c4762a1bSJed Brown 344*c4762a1bSJed Brown stencil[0].j = j-1; 345*c4762a1bSJed Brown stencil[1].j = j+1; 346*c4762a1bSJed Brown stencil[2].j = j; 347*c4762a1bSJed Brown stencil[3].j = j; 348*c4762a1bSJed Brown stencil[4].j = j; 349*c4762a1bSJed Brown stencil[5].j = j; 350*c4762a1bSJed Brown rowstencil.k = 0; rowstencil.j = j; 351*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 352*c4762a1bSJed Brown uc = u[j][i].u; 353*c4762a1bSJed Brown vc = u[j][i].v; 354*c4762a1bSJed Brown 355*c4762a1bSJed Brown /* uxx = (-2.0*uc + u[j][i-1].u + u[j][i+1].u)*sx; 356*c4762a1bSJed Brown uyy = (-2.0*uc + u[j-1][i].u + u[j+1][i].u)*sy; 357*c4762a1bSJed Brown 358*c4762a1bSJed Brown vxx = (-2.0*vc + u[j][i-1].v + u[j][i+1].v)*sx; 359*c4762a1bSJed Brown vyy = (-2.0*vc + u[j-1][i].v + u[j+1][i].v)*sy; 360*c4762a1bSJed Brown f[j][i].u = appctx->D1*(uxx + uyy) - uc*vc*vc + appctx->gamma*(1.0 - uc);*/ 361*c4762a1bSJed Brown 362*c4762a1bSJed Brown stencil[0].i = i; stencil[0].c = 0; entries[0] = appctx->D1*sy; 363*c4762a1bSJed Brown stencil[1].i = i; stencil[1].c = 0; entries[1] = appctx->D1*sy; 364*c4762a1bSJed Brown stencil[2].i = i-1; stencil[2].c = 0; entries[2] = appctx->D1*sx; 365*c4762a1bSJed Brown stencil[3].i = i+1; stencil[3].c = 0; entries[3] = appctx->D1*sx; 366*c4762a1bSJed Brown stencil[4].i = i; stencil[4].c = 0; entries[4] = -2.0*appctx->D1*(sx + sy) - vc*vc - appctx->gamma; 367*c4762a1bSJed Brown stencil[5].i = i; stencil[5].c = 1; entries[5] = -2.0*uc*vc; 368*c4762a1bSJed Brown rowstencil.i = i; rowstencil.c = 0; 369*c4762a1bSJed Brown 370*c4762a1bSJed Brown ierr = MatSetValuesStencil(A,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 371*c4762a1bSJed Brown if (appctx->aijpc) { 372*c4762a1bSJed Brown ierr = MatSetValuesStencil(BB,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 373*c4762a1bSJed Brown } 374*c4762a1bSJed Brown stencil[0].c = 1; entries[0] = appctx->D2*sy; 375*c4762a1bSJed Brown stencil[1].c = 1; entries[1] = appctx->D2*sy; 376*c4762a1bSJed Brown stencil[2].c = 1; entries[2] = appctx->D2*sx; 377*c4762a1bSJed Brown stencil[3].c = 1; entries[3] = appctx->D2*sx; 378*c4762a1bSJed Brown stencil[4].c = 1; entries[4] = -2.0*appctx->D2*(sx + sy) + 2.0*uc*vc - appctx->gamma - appctx->kappa; 379*c4762a1bSJed Brown stencil[5].c = 0; entries[5] = vc*vc; 380*c4762a1bSJed Brown rowstencil.c = 1; 381*c4762a1bSJed Brown 382*c4762a1bSJed Brown ierr = MatSetValuesStencil(A,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 383*c4762a1bSJed Brown if (appctx->aijpc) { 384*c4762a1bSJed Brown ierr = MatSetValuesStencil(BB,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 385*c4762a1bSJed Brown } 386*c4762a1bSJed Brown /* f[j][i].v = appctx->D2*(vxx + vyy) + uc*vc*vc - (appctx->gamma + appctx->kappa)*vc; */ 387*c4762a1bSJed Brown } 388*c4762a1bSJed Brown } 389*c4762a1bSJed Brown 390*c4762a1bSJed Brown /* 391*c4762a1bSJed Brown Restore vectors 392*c4762a1bSJed Brown */ 393*c4762a1bSJed Brown ierr = PetscLogFlops(19*xm*ym);CHKERRQ(ierr); 394*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,localU,&u);CHKERRQ(ierr); 395*c4762a1bSJed Brown ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); 396*c4762a1bSJed Brown ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 397*c4762a1bSJed Brown ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 398*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 399*c4762a1bSJed Brown if (appctx->aijpc) { 400*c4762a1bSJed Brown ierr = MatAssemblyBegin(BB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 401*c4762a1bSJed Brown ierr = MatAssemblyEnd(BB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 402*c4762a1bSJed Brown ierr = MatSetOption(BB,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 403*c4762a1bSJed Brown } 404*c4762a1bSJed Brown 405*c4762a1bSJed Brown PetscFunctionReturn(0); 406*c4762a1bSJed Brown } 407*c4762a1bSJed Brown 408*c4762a1bSJed Brown /* 409*c4762a1bSJed Brown IFunction - Evaluates implicit nonlinear function, xdot - F(x). 410*c4762a1bSJed Brown 411*c4762a1bSJed Brown Input Parameters: 412*c4762a1bSJed Brown . ts - the TS context 413*c4762a1bSJed Brown . U - input vector 414*c4762a1bSJed Brown . Udot - input vector 415*c4762a1bSJed Brown . ptr - optional user-defined context, as set by TSSetRHSFunction() 416*c4762a1bSJed Brown 417*c4762a1bSJed Brown Output Parameter: 418*c4762a1bSJed Brown . F - function vector 419*c4762a1bSJed Brown */ 420*c4762a1bSJed Brown PetscErrorCode IFunction(TS ts,PetscReal ftime,Vec U,Vec Udot,Vec F,void *ptr) 421*c4762a1bSJed Brown { 422*c4762a1bSJed Brown AppCtx *appctx = (AppCtx*)ptr; 423*c4762a1bSJed Brown DM da; 424*c4762a1bSJed Brown PetscErrorCode ierr; 425*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 426*c4762a1bSJed Brown PetscReal hx,hy,sx,sy; 427*c4762a1bSJed Brown PetscScalar uc,uxx,uyy,vc,vxx,vyy; 428*c4762a1bSJed Brown Field **u,**f,**udot; 429*c4762a1bSJed Brown Vec localU; 430*c4762a1bSJed Brown 431*c4762a1bSJed Brown PetscFunctionBegin; 432*c4762a1bSJed Brown ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 433*c4762a1bSJed Brown ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); 434*c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 435*c4762a1bSJed Brown hx = 2.50/(PetscReal)Mx; sx = 1.0/(hx*hx); 436*c4762a1bSJed Brown hy = 2.50/(PetscReal)My; sy = 1.0/(hy*hy); 437*c4762a1bSJed Brown 438*c4762a1bSJed Brown /* 439*c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 440*c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 441*c4762a1bSJed Brown By placing code between these two statements, computations can be 442*c4762a1bSJed Brown done while messages are in transition. 443*c4762a1bSJed Brown */ 444*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 445*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 446*c4762a1bSJed Brown 447*c4762a1bSJed Brown /* 448*c4762a1bSJed Brown Get pointers to vector data 449*c4762a1bSJed Brown */ 450*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); 451*c4762a1bSJed Brown ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); 452*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,Udot,&udot);CHKERRQ(ierr); 453*c4762a1bSJed Brown 454*c4762a1bSJed Brown /* 455*c4762a1bSJed Brown Get local grid boundaries 456*c4762a1bSJed Brown */ 457*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 458*c4762a1bSJed Brown 459*c4762a1bSJed Brown /* 460*c4762a1bSJed Brown Compute function over the locally owned part of the grid 461*c4762a1bSJed Brown */ 462*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 463*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 464*c4762a1bSJed Brown uc = u[j][i].u; 465*c4762a1bSJed Brown uxx = (-2.0*uc + u[j][i-1].u + u[j][i+1].u)*sx; 466*c4762a1bSJed Brown uyy = (-2.0*uc + u[j-1][i].u + u[j+1][i].u)*sy; 467*c4762a1bSJed Brown vc = u[j][i].v; 468*c4762a1bSJed Brown vxx = (-2.0*vc + u[j][i-1].v + u[j][i+1].v)*sx; 469*c4762a1bSJed Brown vyy = (-2.0*vc + u[j-1][i].v + u[j+1][i].v)*sy; 470*c4762a1bSJed Brown f[j][i].u = udot[j][i].u - ( appctx->D1*(uxx + uyy) - uc*vc*vc + appctx->gamma*(1.0 - uc) ); 471*c4762a1bSJed Brown f[j][i].v = udot[j][i].v - ( appctx->D2*(vxx + vyy) + uc*vc*vc - (appctx->gamma + appctx->kappa)*vc ); 472*c4762a1bSJed Brown } 473*c4762a1bSJed Brown } 474*c4762a1bSJed Brown ierr = PetscLogFlops(16*xm*ym);CHKERRQ(ierr); 475*c4762a1bSJed Brown 476*c4762a1bSJed Brown /* 477*c4762a1bSJed Brown Restore vectors 478*c4762a1bSJed Brown */ 479*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,localU,&u);CHKERRQ(ierr); 480*c4762a1bSJed Brown ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); 481*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,Udot,&udot);CHKERRQ(ierr); 482*c4762a1bSJed Brown ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); 483*c4762a1bSJed Brown PetscFunctionReturn(0); 484*c4762a1bSJed Brown } 485*c4762a1bSJed Brown 486*c4762a1bSJed Brown PetscErrorCode IJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat A,Mat BB,void *ctx) 487*c4762a1bSJed Brown { 488*c4762a1bSJed Brown AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */ 489*c4762a1bSJed Brown DM da; 490*c4762a1bSJed Brown PetscErrorCode ierr; 491*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 492*c4762a1bSJed Brown PetscReal hx,hy,sx,sy; 493*c4762a1bSJed Brown PetscScalar uc,vc; 494*c4762a1bSJed Brown Field **u; 495*c4762a1bSJed Brown Vec localU; 496*c4762a1bSJed Brown MatStencil stencil[6],rowstencil; 497*c4762a1bSJed Brown PetscScalar entries[6]; 498*c4762a1bSJed Brown 499*c4762a1bSJed Brown PetscFunctionBegin; 500*c4762a1bSJed Brown ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 501*c4762a1bSJed Brown ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); 502*c4762a1bSJed Brown ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); 503*c4762a1bSJed Brown 504*c4762a1bSJed Brown hx = 2.50/(PetscReal)Mx; sx = 1.0/(hx*hx); 505*c4762a1bSJed Brown hy = 2.50/(PetscReal)My; sy = 1.0/(hy*hy); 506*c4762a1bSJed Brown 507*c4762a1bSJed Brown /* 508*c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 509*c4762a1bSJed Brown DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). 510*c4762a1bSJed Brown By placing code between these two statements, computations can be 511*c4762a1bSJed Brown done while messages are in transition. 512*c4762a1bSJed Brown */ 513*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 514*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 515*c4762a1bSJed Brown 516*c4762a1bSJed Brown /* 517*c4762a1bSJed Brown Get pointers to vector data 518*c4762a1bSJed Brown */ 519*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); 520*c4762a1bSJed Brown 521*c4762a1bSJed Brown /* 522*c4762a1bSJed Brown Get local grid boundaries 523*c4762a1bSJed Brown */ 524*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 525*c4762a1bSJed Brown 526*c4762a1bSJed Brown stencil[0].k = 0; 527*c4762a1bSJed Brown stencil[1].k = 0; 528*c4762a1bSJed Brown stencil[2].k = 0; 529*c4762a1bSJed Brown stencil[3].k = 0; 530*c4762a1bSJed Brown stencil[4].k = 0; 531*c4762a1bSJed Brown stencil[5].k = 0; 532*c4762a1bSJed Brown rowstencil.k = 0; 533*c4762a1bSJed Brown /* 534*c4762a1bSJed Brown Compute function over the locally owned part of the grid 535*c4762a1bSJed Brown */ 536*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 537*c4762a1bSJed Brown 538*c4762a1bSJed Brown stencil[0].j = j-1; 539*c4762a1bSJed Brown stencil[1].j = j+1; 540*c4762a1bSJed Brown stencil[2].j = j; 541*c4762a1bSJed Brown stencil[3].j = j; 542*c4762a1bSJed Brown stencil[4].j = j; 543*c4762a1bSJed Brown stencil[5].j = j; 544*c4762a1bSJed Brown rowstencil.k = 0; rowstencil.j = j; 545*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 546*c4762a1bSJed Brown uc = u[j][i].u; 547*c4762a1bSJed Brown vc = u[j][i].v; 548*c4762a1bSJed Brown 549*c4762a1bSJed Brown /* uxx = (-2.0*uc + u[j][i-1].u + u[j][i+1].u)*sx; 550*c4762a1bSJed Brown uyy = (-2.0*uc + u[j-1][i].u + u[j+1][i].u)*sy; 551*c4762a1bSJed Brown 552*c4762a1bSJed Brown vxx = (-2.0*vc + u[j][i-1].v + u[j][i+1].v)*sx; 553*c4762a1bSJed Brown vyy = (-2.0*vc + u[j-1][i].v + u[j+1][i].v)*sy; 554*c4762a1bSJed Brown f[j][i].u = appctx->D1*(uxx + uyy) - uc*vc*vc + appctx->gamma*(1.0 - uc);*/ 555*c4762a1bSJed Brown 556*c4762a1bSJed Brown stencil[0].i = i; stencil[0].c = 0; entries[0] = -appctx->D1*sy; 557*c4762a1bSJed Brown stencil[1].i = i; stencil[1].c = 0; entries[1] = -appctx->D1*sy; 558*c4762a1bSJed Brown stencil[2].i = i-1; stencil[2].c = 0; entries[2] = -appctx->D1*sx; 559*c4762a1bSJed Brown stencil[3].i = i+1; stencil[3].c = 0; entries[3] = -appctx->D1*sx; 560*c4762a1bSJed Brown stencil[4].i = i; stencil[4].c = 0; entries[4] = 2.0*appctx->D1*(sx + sy) + vc*vc + appctx->gamma + a; 561*c4762a1bSJed Brown stencil[5].i = i; stencil[5].c = 1; entries[5] = 2.0*uc*vc; 562*c4762a1bSJed Brown rowstencil.i = i; rowstencil.c = 0; 563*c4762a1bSJed Brown 564*c4762a1bSJed Brown ierr = MatSetValuesStencil(A,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 565*c4762a1bSJed Brown if (appctx->aijpc) { 566*c4762a1bSJed Brown ierr = MatSetValuesStencil(BB,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 567*c4762a1bSJed Brown } 568*c4762a1bSJed Brown stencil[0].c = 1; entries[0] = -appctx->D2*sy; 569*c4762a1bSJed Brown stencil[1].c = 1; entries[1] = -appctx->D2*sy; 570*c4762a1bSJed Brown stencil[2].c = 1; entries[2] = -appctx->D2*sx; 571*c4762a1bSJed Brown stencil[3].c = 1; entries[3] = -appctx->D2*sx; 572*c4762a1bSJed Brown stencil[4].c = 1; entries[4] = 2.0*appctx->D2*(sx + sy) - 2.0*uc*vc + appctx->gamma + appctx->kappa + a; 573*c4762a1bSJed Brown stencil[5].c = 0; entries[5] = -vc*vc; 574*c4762a1bSJed Brown rowstencil.c = 1; 575*c4762a1bSJed Brown 576*c4762a1bSJed Brown ierr = MatSetValuesStencil(A,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 577*c4762a1bSJed Brown if (appctx->aijpc) { 578*c4762a1bSJed Brown ierr = MatSetValuesStencil(BB,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 579*c4762a1bSJed Brown } 580*c4762a1bSJed Brown /* f[j][i].v = appctx->D2*(vxx + vyy) + uc*vc*vc - (appctx->gamma + appctx->kappa)*vc; */ 581*c4762a1bSJed Brown } 582*c4762a1bSJed Brown } 583*c4762a1bSJed Brown 584*c4762a1bSJed Brown /* 585*c4762a1bSJed Brown Restore vectors 586*c4762a1bSJed Brown */ 587*c4762a1bSJed Brown ierr = PetscLogFlops(19*xm*ym);CHKERRQ(ierr); 588*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,localU,&u);CHKERRQ(ierr); 589*c4762a1bSJed Brown ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); 590*c4762a1bSJed Brown ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 591*c4762a1bSJed Brown ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 592*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 593*c4762a1bSJed Brown if (appctx->aijpc) { 594*c4762a1bSJed Brown ierr = MatAssemblyBegin(BB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 595*c4762a1bSJed Brown ierr = MatAssemblyEnd(BB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 596*c4762a1bSJed Brown ierr = MatSetOption(BB,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 597*c4762a1bSJed Brown } 598*c4762a1bSJed Brown PetscFunctionReturn(0); 599*c4762a1bSJed Brown } 600*c4762a1bSJed Brown 601*c4762a1bSJed Brown 602*c4762a1bSJed Brown /*TEST 603*c4762a1bSJed Brown 604*c4762a1bSJed Brown build: 605*c4762a1bSJed Brown requires: !complex !single 606*c4762a1bSJed Brown 607*c4762a1bSJed Brown test: 608*c4762a1bSJed Brown args: -ts_max_steps 10 -ts_monitor -ts_adjoint_monitor -da_grid_x 20 -da_grid_y 20 609*c4762a1bSJed Brown output_file: output/ex5adj_1.out 610*c4762a1bSJed Brown 611*c4762a1bSJed Brown test: 612*c4762a1bSJed Brown suffix: 2 613*c4762a1bSJed Brown nsize: 2 614*c4762a1bSJed Brown args: -ts_max_steps 10 -ts_dt 10 -ts_monitor -ts_adjoint_monitor -ksp_monitor_short -da_grid_x 20 -da_grid_y 20 -ts_trajectory_dirname Test-dir -ts_trajectory_file_template test-%06D.cp 615*c4762a1bSJed Brown 616*c4762a1bSJed Brown test: 617*c4762a1bSJed Brown suffix: 3 618*c4762a1bSJed Brown nsize: 2 619*c4762a1bSJed Brown args: -ts_max_steps 10 -ts_dt 10 -ts_adjoint_monitor_draw_sensi 620*c4762a1bSJed Brown 621*c4762a1bSJed Brown test: 622*c4762a1bSJed Brown suffix: 4 623*c4762a1bSJed Brown nsize: 2 624*c4762a1bSJed Brown args: -ts_max_steps 10 -ts_dt 10 -ts_monitor -ts_adjoint_monitor -ksp_monitor_short -da_grid_x 20 -da_grid_y 20 -snes_fd_color 625*c4762a1bSJed Brown output_file: output/ex5adj_2.out 626*c4762a1bSJed Brown 627*c4762a1bSJed Brown test: 628*c4762a1bSJed Brown suffix: 5 629*c4762a1bSJed Brown nsize: 2 630*c4762a1bSJed Brown args: -ts_max_steps 10 -implicitform 0 -ts_type rk -ts_rk_type 4 -ts_monitor -ts_adjoint_monitor -da_grid_x 20 -da_grid_y 20 -snes_fd_color 631*c4762a1bSJed Brown output_file: output/ex5adj_1.out 632*c4762a1bSJed Brown 633*c4762a1bSJed Brown test: 634*c4762a1bSJed Brown suffix: knl 635*c4762a1bSJed Brown args: -ts_max_steps 10 -ts_monitor -ts_adjoint_monitor -ts_trajectory_type memory -ts_trajectory_solution_only 0 -malloc_hbw -ts_trajectory_use_dram 1 636*c4762a1bSJed Brown output_file: output/ex5adj_3.out 637*c4762a1bSJed Brown requires: knl 638*c4762a1bSJed Brown 639*c4762a1bSJed Brown test: 640*c4762a1bSJed Brown suffix: sell 641*c4762a1bSJed Brown nsize: 4 642*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type sell -pc_type none 643*c4762a1bSJed Brown output_file: output/ex5adj_sell_1.out 644*c4762a1bSJed Brown 645*c4762a1bSJed Brown test: 646*c4762a1bSJed Brown suffix: aijsell 647*c4762a1bSJed Brown nsize: 4 648*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type aijsell -pc_type none 649*c4762a1bSJed Brown output_file: output/ex5adj_sell_1.out 650*c4762a1bSJed Brown 651*c4762a1bSJed Brown test: 652*c4762a1bSJed Brown suffix: sell2 653*c4762a1bSJed Brown nsize: 4 654*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type sell -pc_type mg -pc_mg_levels 2 -mg_coarse_pc_type sor 655*c4762a1bSJed Brown output_file: output/ex5adj_sell_2.out 656*c4762a1bSJed Brown 657*c4762a1bSJed Brown test: 658*c4762a1bSJed Brown suffix: aijsell2 659*c4762a1bSJed Brown nsize: 4 660*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type aijsell -pc_type mg -pc_mg_levels 2 -mg_coarse_pc_type sor 661*c4762a1bSJed Brown output_file: output/ex5adj_sell_2.out 662*c4762a1bSJed Brown 663*c4762a1bSJed Brown test: 664*c4762a1bSJed Brown suffix: sell3 665*c4762a1bSJed Brown nsize: 4 666*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type sell -pc_type mg -pc_mg_levels 2 -mg_coarse_pc_type bjacobi -mg_levels_pc_type bjacobi 667*c4762a1bSJed Brown output_file: output/ex5adj_sell_3.out 668*c4762a1bSJed Brown 669*c4762a1bSJed Brown test: 670*c4762a1bSJed Brown suffix: sell4 671*c4762a1bSJed Brown nsize: 4 672*c4762a1bSJed Brown args: -forwardonly -implicitform -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type sell -pc_type mg -pc_mg_levels 2 -mg_coarse_pc_type bjacobi -mg_levels_pc_type bjacobi 673*c4762a1bSJed Brown output_file: output/ex5adj_sell_4.out 674*c4762a1bSJed Brown 675*c4762a1bSJed Brown test: 676*c4762a1bSJed Brown suffix: sell5 677*c4762a1bSJed Brown nsize: 4 678*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type sell -aijpc 679*c4762a1bSJed Brown output_file: output/ex5adj_sell_5.out 680*c4762a1bSJed Brown 681*c4762a1bSJed Brown test: 682*c4762a1bSJed Brown suffix: aijsell5 683*c4762a1bSJed Brown nsize: 4 684*c4762a1bSJed Brown args: -forwardonly -ts_max_steps 10 -ts_monitor -snes_monitor_short -dm_mat_type aijsell 685*c4762a1bSJed Brown output_file: output/ex5adj_sell_5.out 686*c4762a1bSJed Brown 687*c4762a1bSJed Brown test: 688*c4762a1bSJed Brown suffix: sell6 689*c4762a1bSJed Brown args: -ts_max_steps 10 -ts_monitor -ts_adjoint_monitor -ts_trajectory_type memory -ts_trajectory_solution_only 0 -dm_mat_type sell -pc_type jacobi 690*c4762a1bSJed Brown output_file: output/ex5adj_sell_6.out 691*c4762a1bSJed Brown 692*c4762a1bSJed Brown TEST*/ 693