1*c4762a1bSJed Brown 2*c4762a1bSJed Brown static char help[] = "Demonstrates Pattern Formation with Reaction-Diffusion Equations.\n"; 3*c4762a1bSJed Brown 4*c4762a1bSJed Brown /*F 5*c4762a1bSJed Brown This example is taken from the book, Numerical Solution of Time-Dependent Advection-Diffusion-Reaction Equations by 6*c4762a1bSJed Brown W. Hundsdorf and J.G. Verwer, Page 21, Pattern Formation with Reaction-Diffusion Equations 7*c4762a1bSJed Brown \begin{eqnarray*} 8*c4762a1bSJed Brown u_t = D_1 (u_{xx} + u_{yy}) - u*v^2 + \gamma(1 -u) \\ 9*c4762a1bSJed Brown v_t = D_2 (v_{xx} + v_{yy}) + u*v^2 - (\gamma + \kappa)v 10*c4762a1bSJed Brown \end{eqnarray*} 11*c4762a1bSJed Brown Unlike in the book this uses periodic boundary conditions instead of Neumann 12*c4762a1bSJed Brown (since they are easier for finite differences). 13*c4762a1bSJed Brown F*/ 14*c4762a1bSJed Brown 15*c4762a1bSJed Brown /* 16*c4762a1bSJed Brown Helpful runtime monitor options: 17*c4762a1bSJed Brown -ts_monitor_draw_solution 18*c4762a1bSJed Brown -draw_save -draw_save_movie 19*c4762a1bSJed Brown 20*c4762a1bSJed Brown Helpful runtime linear solver options: 21*c4762a1bSJed Brown -pc_type mg -pc_mg_galerkin pmat -da_refine 1 -snes_monitor -ksp_monitor -ts_view (note that these Jacobians are so well-conditioned multigrid may not be the best solver) 22*c4762a1bSJed Brown 23*c4762a1bSJed Brown Point your browser to localhost:8080 to monitor the simulation 24*c4762a1bSJed Brown ./ex5 -ts_view_pre saws -stack_view saws -draw_save -draw_save_single_file -x_virtual -ts_monitor_draw_solution -saws_root . 25*c4762a1bSJed Brown 26*c4762a1bSJed Brown */ 27*c4762a1bSJed Brown 28*c4762a1bSJed Brown /* 29*c4762a1bSJed Brown 30*c4762a1bSJed Brown Include "petscdmda.h" so that we can use distributed arrays (DMDAs). 31*c4762a1bSJed Brown Include "petscts.h" so that we can use SNES numerical (ODE) integrators. Note that this 32*c4762a1bSJed Brown file automatically includes: 33*c4762a1bSJed Brown petscsys.h - base PETSc routines petscvec.h - vectors 34*c4762a1bSJed Brown petscmat.h - matrices petscis.h - index sets 35*c4762a1bSJed Brown petscksp.h - Krylov subspace methods petscpc.h - preconditioners 36*c4762a1bSJed Brown petscviewer.h - viewers petscsnes.h - nonlinear solvers 37*c4762a1bSJed Brown */ 38*c4762a1bSJed Brown #include <petscdm.h> 39*c4762a1bSJed Brown #include <petscdmda.h> 40*c4762a1bSJed Brown #include <petscts.h> 41*c4762a1bSJed Brown 42*c4762a1bSJed Brown /* Simple C struct that allows us to access the two velocity (x and y directions) values easily in the code */ 43*c4762a1bSJed Brown typedef struct { 44*c4762a1bSJed Brown PetscScalar u,v; 45*c4762a1bSJed Brown } Field; 46*c4762a1bSJed Brown 47*c4762a1bSJed Brown /* Data structure to store the model parameters */ 48*c4762a1bSJed Brown typedef struct { 49*c4762a1bSJed Brown PetscReal D1,D2,gamma,kappa; 50*c4762a1bSJed Brown } AppCtx; 51*c4762a1bSJed Brown 52*c4762a1bSJed Brown /* 53*c4762a1bSJed Brown User-defined routines 54*c4762a1bSJed Brown */ 55*c4762a1bSJed Brown extern PetscErrorCode RHSFunction(TS,PetscReal,Vec,Vec,void*),InitialConditions(DM,Vec); 56*c4762a1bSJed Brown extern PetscErrorCode RHSJacobian(TS,PetscReal,Vec,Mat,Mat,void*); 57*c4762a1bSJed Brown 58*c4762a1bSJed Brown int main(int argc,char **argv) 59*c4762a1bSJed Brown { 60*c4762a1bSJed Brown TS ts; /* ODE integrator */ 61*c4762a1bSJed Brown Vec x; /* solution */ 62*c4762a1bSJed Brown PetscErrorCode ierr; 63*c4762a1bSJed Brown DM da; 64*c4762a1bSJed Brown AppCtx appctx; 65*c4762a1bSJed Brown 66*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 67*c4762a1bSJed Brown Initialize program 68*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 69*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 70*c4762a1bSJed Brown PetscFunctionBeginUser; 71*c4762a1bSJed Brown appctx.D1 = 8.0e-5; 72*c4762a1bSJed Brown appctx.D2 = 4.0e-5; 73*c4762a1bSJed Brown appctx.gamma = .024; 74*c4762a1bSJed Brown appctx.kappa = .06; 75*c4762a1bSJed Brown 76*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 77*c4762a1bSJed Brown Create distributed array (DMDA) to manage parallel grid and vectors 78*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 79*c4762a1bSJed Brown ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,DM_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,65,65,PETSC_DECIDE,PETSC_DECIDE,2,1,NULL,NULL,&da);CHKERRQ(ierr); 80*c4762a1bSJed Brown ierr = DMSetFromOptions(da);CHKERRQ(ierr); 81*c4762a1bSJed Brown ierr = DMSetUp(da);CHKERRQ(ierr); 82*c4762a1bSJed Brown ierr = DMDASetFieldName(da,0,"u");CHKERRQ(ierr); 83*c4762a1bSJed Brown ierr = DMDASetFieldName(da,1,"v");CHKERRQ(ierr); 84*c4762a1bSJed Brown 85*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 86*c4762a1bSJed Brown Create global vector from DMDA; this will be used to store the solution 87*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 88*c4762a1bSJed Brown ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); 89*c4762a1bSJed Brown 90*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 91*c4762a1bSJed Brown Create timestepping solver context 92*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 93*c4762a1bSJed Brown ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); 94*c4762a1bSJed Brown ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr); 95*c4762a1bSJed Brown ierr = TSARKIMEXSetFullyImplicit(ts,PETSC_TRUE);CHKERRQ(ierr); 96*c4762a1bSJed Brown ierr = TSSetDM(ts,da);CHKERRQ(ierr); 97*c4762a1bSJed Brown ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); 98*c4762a1bSJed Brown ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&appctx);CHKERRQ(ierr); 99*c4762a1bSJed Brown ierr = TSSetRHSJacobian(ts,NULL,NULL,RHSJacobian,&appctx);CHKERRQ(ierr); 100*c4762a1bSJed Brown 101*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 102*c4762a1bSJed Brown Set initial conditions 103*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 104*c4762a1bSJed Brown ierr = InitialConditions(da,x);CHKERRQ(ierr); 105*c4762a1bSJed Brown ierr = TSSetSolution(ts,x);CHKERRQ(ierr); 106*c4762a1bSJed Brown 107*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 108*c4762a1bSJed Brown Set solver options 109*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 110*c4762a1bSJed Brown ierr = TSSetMaxTime(ts,2000.0);CHKERRQ(ierr); 111*c4762a1bSJed Brown ierr = TSSetTimeStep(ts,.0001);CHKERRQ(ierr); 112*c4762a1bSJed Brown ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); 113*c4762a1bSJed Brown ierr = TSSetFromOptions(ts);CHKERRQ(ierr); 114*c4762a1bSJed Brown 115*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 116*c4762a1bSJed Brown Solve ODE system 117*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 118*c4762a1bSJed Brown ierr = TSSolve(ts,x);CHKERRQ(ierr); 119*c4762a1bSJed Brown 120*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 121*c4762a1bSJed Brown Free work space. 122*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 123*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 124*c4762a1bSJed Brown ierr = TSDestroy(&ts);CHKERRQ(ierr); 125*c4762a1bSJed Brown ierr = DMDestroy(&da);CHKERRQ(ierr); 126*c4762a1bSJed Brown 127*c4762a1bSJed Brown ierr = PetscFinalize(); 128*c4762a1bSJed Brown return ierr; 129*c4762a1bSJed Brown } 130*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 131*c4762a1bSJed Brown /* 132*c4762a1bSJed Brown RHSFunction - Evaluates nonlinear function, that defines the right 133*c4762a1bSJed Brown hand side of the ODE 134*c4762a1bSJed Brown 135*c4762a1bSJed Brown Input Parameters: 136*c4762a1bSJed Brown . ts - the TS context 137*c4762a1bSJed Brown . time - current time 138*c4762a1bSJed Brown . U - input vector 139*c4762a1bSJed Brown . ptr - optional user-defined context, as set by TSSetRHSFunction() 140*c4762a1bSJed Brown 141*c4762a1bSJed Brown Output Parameter: 142*c4762a1bSJed Brown . F - function vector 143*c4762a1bSJed Brown */ 144*c4762a1bSJed Brown PetscErrorCode RHSFunction(TS ts,PetscReal time,Vec U,Vec F,void *ptr) 145*c4762a1bSJed Brown { 146*c4762a1bSJed Brown AppCtx *appctx = (AppCtx*)ptr; 147*c4762a1bSJed Brown DM da; 148*c4762a1bSJed Brown PetscErrorCode ierr; 149*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 150*c4762a1bSJed Brown PetscReal hx,hy,sx,sy; 151*c4762a1bSJed Brown PetscScalar uc,uxx,uyy,vc,vxx,vyy; 152*c4762a1bSJed Brown Field **u,**f; 153*c4762a1bSJed Brown Vec localU; 154*c4762a1bSJed Brown 155*c4762a1bSJed Brown PetscFunctionBegin; 156*c4762a1bSJed Brown ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 157*c4762a1bSJed Brown /* Get local (ghosted) work vector */ 158*c4762a1bSJed Brown ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); 159*c4762a1bSJed Brown /* Get information about mesh needed for discretization */ 160*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); 161*c4762a1bSJed Brown 162*c4762a1bSJed Brown hx = 2.50/(PetscReal)(Mx); sx = 1.0/(hx*hx); 163*c4762a1bSJed Brown hy = 2.50/(PetscReal)(My); sy = 1.0/(hy*hy); 164*c4762a1bSJed Brown 165*c4762a1bSJed Brown /* 166*c4762a1bSJed Brown Scatter ghost points to local vector, using the 2-step process 167*c4762a1bSJed Brown */ 168*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 169*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 170*c4762a1bSJed Brown 171*c4762a1bSJed Brown /* 172*c4762a1bSJed Brown Get pointers to actual vector data 173*c4762a1bSJed Brown */ 174*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); 175*c4762a1bSJed Brown ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); 176*c4762a1bSJed Brown 177*c4762a1bSJed Brown /* 178*c4762a1bSJed Brown Get local grid boundaries; this is the region that this process owns and must operate on 179*c4762a1bSJed Brown */ 180*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 181*c4762a1bSJed Brown 182*c4762a1bSJed Brown /* 183*c4762a1bSJed Brown Compute function over the locally owned part of the grid with standard finite differences 184*c4762a1bSJed Brown */ 185*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 186*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 187*c4762a1bSJed Brown uc = u[j][i].u; 188*c4762a1bSJed Brown uxx = (-2.0*uc + u[j][i-1].u + u[j][i+1].u)*sx; 189*c4762a1bSJed Brown uyy = (-2.0*uc + u[j-1][i].u + u[j+1][i].u)*sy; 190*c4762a1bSJed Brown vc = u[j][i].v; 191*c4762a1bSJed Brown vxx = (-2.0*vc + u[j][i-1].v + u[j][i+1].v)*sx; 192*c4762a1bSJed Brown vyy = (-2.0*vc + u[j-1][i].v + u[j+1][i].v)*sy; 193*c4762a1bSJed Brown f[j][i].u = appctx->D1*(uxx + uyy) - uc*vc*vc + appctx->gamma*(1.0 - uc); 194*c4762a1bSJed Brown f[j][i].v = appctx->D2*(vxx + vyy) + uc*vc*vc - (appctx->gamma + appctx->kappa)*vc; 195*c4762a1bSJed Brown } 196*c4762a1bSJed Brown } 197*c4762a1bSJed Brown ierr = PetscLogFlops(16*xm*ym);CHKERRQ(ierr); 198*c4762a1bSJed Brown 199*c4762a1bSJed Brown /* 200*c4762a1bSJed Brown Restore access to vectors and return no longer needed work vector 201*c4762a1bSJed Brown */ 202*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,localU,&u);CHKERRQ(ierr); 203*c4762a1bSJed Brown ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); 204*c4762a1bSJed Brown ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); 205*c4762a1bSJed Brown PetscFunctionReturn(0); 206*c4762a1bSJed Brown } 207*c4762a1bSJed Brown 208*c4762a1bSJed Brown /* ------------------------------------------------------------------- */ 209*c4762a1bSJed Brown PetscErrorCode InitialConditions(DM da,Vec U) 210*c4762a1bSJed Brown { 211*c4762a1bSJed Brown PetscErrorCode ierr; 212*c4762a1bSJed Brown PetscInt i,j,xs,ys,xm,ym,Mx,My; 213*c4762a1bSJed Brown Field **u; 214*c4762a1bSJed Brown PetscReal hx,hy,x,y; 215*c4762a1bSJed Brown 216*c4762a1bSJed Brown PetscFunctionBegin; 217*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); 218*c4762a1bSJed Brown 219*c4762a1bSJed Brown hx = 2.5/(PetscReal)(Mx); 220*c4762a1bSJed Brown hy = 2.5/(PetscReal)(My); 221*c4762a1bSJed Brown 222*c4762a1bSJed Brown /* 223*c4762a1bSJed Brown Get pointers to actual vector data 224*c4762a1bSJed Brown */ 225*c4762a1bSJed Brown ierr = DMDAVecGetArray(da,U,&u);CHKERRQ(ierr); 226*c4762a1bSJed Brown 227*c4762a1bSJed Brown /* 228*c4762a1bSJed Brown Get local grid boundaries 229*c4762a1bSJed Brown */ 230*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 231*c4762a1bSJed Brown 232*c4762a1bSJed Brown /* 233*c4762a1bSJed Brown Compute function over the locally owned part of the grid 234*c4762a1bSJed Brown */ 235*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 236*c4762a1bSJed Brown y = j*hy; 237*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 238*c4762a1bSJed Brown x = i*hx; 239*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); 240*c4762a1bSJed Brown else u[j][i].v = 0.0; 241*c4762a1bSJed Brown 242*c4762a1bSJed Brown u[j][i].u = 1.0 - 2.0*u[j][i].v; 243*c4762a1bSJed Brown } 244*c4762a1bSJed Brown } 245*c4762a1bSJed Brown 246*c4762a1bSJed Brown /* 247*c4762a1bSJed Brown Restore access to vector 248*c4762a1bSJed Brown */ 249*c4762a1bSJed Brown ierr = DMDAVecRestoreArray(da,U,&u);CHKERRQ(ierr); 250*c4762a1bSJed Brown PetscFunctionReturn(0); 251*c4762a1bSJed Brown } 252*c4762a1bSJed Brown 253*c4762a1bSJed Brown /* 254*c4762a1bSJed Brown RHSJacobian - Evaluates the Jacobian of the right hand side 255*c4762a1bSJed Brown function of the ODE. 256*c4762a1bSJed Brown 257*c4762a1bSJed Brown Input Parameters: 258*c4762a1bSJed Brown . ts - the TS context 259*c4762a1bSJed Brown . time - current time 260*c4762a1bSJed Brown . U - input vector 261*c4762a1bSJed Brown . ptr - optional user-defined context, as set by TSSetRHSJacobian() 262*c4762a1bSJed Brown 263*c4762a1bSJed Brown Output Parameter: 264*c4762a1bSJed Brown . A - the Jacobian 265*c4762a1bSJed Brown . BB - optional additional matrix where an approximation to the Jacobian 266*c4762a1bSJed Brown may be stored from which the preconditioner is constructed 267*c4762a1bSJed Brown */ 268*c4762a1bSJed Brown PetscErrorCode RHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat BB,void *ctx) 269*c4762a1bSJed Brown { 270*c4762a1bSJed Brown AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */ 271*c4762a1bSJed Brown DM da; 272*c4762a1bSJed Brown PetscErrorCode ierr; 273*c4762a1bSJed Brown PetscInt i,j,Mx,My,xs,ys,xm,ym; 274*c4762a1bSJed Brown PetscReal hx,hy,sx,sy; 275*c4762a1bSJed Brown PetscScalar uc,vc; 276*c4762a1bSJed Brown Field **u; 277*c4762a1bSJed Brown Vec localU; 278*c4762a1bSJed Brown MatStencil stencil[6],rowstencil; 279*c4762a1bSJed Brown PetscScalar entries[6]; 280*c4762a1bSJed Brown 281*c4762a1bSJed Brown PetscFunctionBegin; 282*c4762a1bSJed Brown ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 283*c4762a1bSJed Brown ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); 284*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); 285*c4762a1bSJed Brown 286*c4762a1bSJed Brown hx = 2.50/(PetscReal)(Mx); sx = 1.0/(hx*hx); 287*c4762a1bSJed Brown hy = 2.50/(PetscReal)(My); sy = 1.0/(hy*hy); 288*c4762a1bSJed Brown 289*c4762a1bSJed Brown /* 290*c4762a1bSJed Brown Scatter ghost points to local vector,using the 2-step process 291*c4762a1bSJed Brown */ 292*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 293*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); 294*c4762a1bSJed Brown 295*c4762a1bSJed Brown /* 296*c4762a1bSJed Brown Get pointers to vector data 297*c4762a1bSJed Brown */ 298*c4762a1bSJed Brown ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); 299*c4762a1bSJed Brown 300*c4762a1bSJed Brown /* 301*c4762a1bSJed Brown Get local grid boundaries 302*c4762a1bSJed Brown */ 303*c4762a1bSJed Brown ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); 304*c4762a1bSJed Brown 305*c4762a1bSJed Brown stencil[0].k = 0; 306*c4762a1bSJed Brown stencil[1].k = 0; 307*c4762a1bSJed Brown stencil[2].k = 0; 308*c4762a1bSJed Brown stencil[3].k = 0; 309*c4762a1bSJed Brown stencil[4].k = 0; 310*c4762a1bSJed Brown stencil[5].k = 0; 311*c4762a1bSJed Brown rowstencil.k = 0; 312*c4762a1bSJed Brown /* 313*c4762a1bSJed Brown Compute function over the locally owned part of the grid 314*c4762a1bSJed Brown */ 315*c4762a1bSJed Brown for (j=ys; j<ys+ym; j++) { 316*c4762a1bSJed Brown 317*c4762a1bSJed Brown stencil[0].j = j-1; 318*c4762a1bSJed Brown stencil[1].j = j+1; 319*c4762a1bSJed Brown stencil[2].j = j; 320*c4762a1bSJed Brown stencil[3].j = j; 321*c4762a1bSJed Brown stencil[4].j = j; 322*c4762a1bSJed Brown stencil[5].j = j; 323*c4762a1bSJed Brown rowstencil.k = 0; rowstencil.j = j; 324*c4762a1bSJed Brown for (i=xs; i<xs+xm; i++) { 325*c4762a1bSJed Brown uc = u[j][i].u; 326*c4762a1bSJed Brown vc = u[j][i].v; 327*c4762a1bSJed Brown 328*c4762a1bSJed Brown /* uxx = (-2.0*uc + u[j][i-1].u + u[j][i+1].u)*sx; 329*c4762a1bSJed Brown uyy = (-2.0*uc + u[j-1][i].u + u[j+1][i].u)*sy; 330*c4762a1bSJed Brown 331*c4762a1bSJed Brown vxx = (-2.0*vc + u[j][i-1].v + u[j][i+1].v)*sx; 332*c4762a1bSJed Brown vyy = (-2.0*vc + u[j-1][i].v + u[j+1][i].v)*sy; 333*c4762a1bSJed Brown f[j][i].u = appctx->D1*(uxx + uyy) - uc*vc*vc + appctx->gamma*(1.0 - uc);*/ 334*c4762a1bSJed Brown 335*c4762a1bSJed Brown stencil[0].i = i; stencil[0].c = 0; entries[0] = appctx->D1*sy; 336*c4762a1bSJed Brown stencil[1].i = i; stencil[1].c = 0; entries[1] = appctx->D1*sy; 337*c4762a1bSJed Brown stencil[2].i = i-1; stencil[2].c = 0; entries[2] = appctx->D1*sx; 338*c4762a1bSJed Brown stencil[3].i = i+1; stencil[3].c = 0; entries[3] = appctx->D1*sx; 339*c4762a1bSJed Brown stencil[4].i = i; stencil[4].c = 0; entries[4] = -2.0*appctx->D1*(sx + sy) - vc*vc - appctx->gamma; 340*c4762a1bSJed Brown stencil[5].i = i; stencil[5].c = 1; entries[5] = -2.0*uc*vc; 341*c4762a1bSJed Brown rowstencil.i = i; rowstencil.c = 0; 342*c4762a1bSJed Brown 343*c4762a1bSJed Brown ierr = MatSetValuesStencil(A,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 344*c4762a1bSJed Brown 345*c4762a1bSJed Brown stencil[0].c = 1; entries[0] = appctx->D2*sy; 346*c4762a1bSJed Brown stencil[1].c = 1; entries[1] = appctx->D2*sy; 347*c4762a1bSJed Brown stencil[2].c = 1; entries[2] = appctx->D2*sx; 348*c4762a1bSJed Brown stencil[3].c = 1; entries[3] = appctx->D2*sx; 349*c4762a1bSJed Brown stencil[4].c = 1; entries[4] = -2.0*appctx->D2*(sx + sy) + 2.0*uc*vc - appctx->gamma - appctx->kappa; 350*c4762a1bSJed Brown stencil[5].c = 0; entries[5] = vc*vc; 351*c4762a1bSJed Brown rowstencil.c = 1; 352*c4762a1bSJed Brown 353*c4762a1bSJed Brown ierr = MatSetValuesStencil(A,1,&rowstencil,6,stencil,entries,INSERT_VALUES);CHKERRQ(ierr); 354*c4762a1bSJed Brown /* f[j][i].v = appctx->D2*(vxx + vyy) + uc*vc*vc - (appctx->gamma + appctx->kappa)*vc; */ 355*c4762a1bSJed Brown } 356*c4762a1bSJed Brown } 357*c4762a1bSJed Brown 358*c4762a1bSJed Brown /* 359*c4762a1bSJed Brown Restore vectors 360*c4762a1bSJed Brown */ 361*c4762a1bSJed Brown ierr = PetscLogFlops(19*xm*ym);CHKERRQ(ierr); 362*c4762a1bSJed Brown ierr = DMDAVecRestoreArrayRead(da,localU,&u);CHKERRQ(ierr); 363*c4762a1bSJed Brown ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); 364*c4762a1bSJed Brown ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 365*c4762a1bSJed Brown ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 366*c4762a1bSJed Brown ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 367*c4762a1bSJed Brown PetscFunctionReturn(0); 368*c4762a1bSJed Brown } 369*c4762a1bSJed Brown 370*c4762a1bSJed Brown 371*c4762a1bSJed Brown /*TEST 372*c4762a1bSJed Brown 373*c4762a1bSJed Brown test: 374*c4762a1bSJed Brown args: -ts_view -ts_monitor -ts_max_time 500 375*c4762a1bSJed Brown requires: double 376*c4762a1bSJed Brown timeoutfactor: 3 377*c4762a1bSJed Brown 378*c4762a1bSJed Brown test: 379*c4762a1bSJed Brown suffix: 2 380*c4762a1bSJed Brown args: -ts_view -ts_monitor -ts_max_time 500 -ts_monitor_draw_solution 381*c4762a1bSJed Brown requires: x double 382*c4762a1bSJed Brown output_file: output/ex5_1.out 383*c4762a1bSJed Brown timeoutfactor: 3 384*c4762a1bSJed Brown 385*c4762a1bSJed Brown TEST*/ 386