/* DMDA/KSP solving a system of linear equations. Poisson equation in 2D: div(grad p) = f, 0 < x,y < 1 with forcing function f = -cos(m*pi*x)*cos(n*pi*y), Periodic boundary conditions p(x=0) = p(x=1) Neuman boundary conditions dp/dy = 0 for y = 0, y = 1. This example uses the DM_BOUNDARY_MIRROR to implement the Neumann boundary conditions, see the manual pages for DMBoundaryType Compare to ex50.c */ static char help[] = "Solves 2D Poisson equation using multigrid.\n\n"; #include #include #include #include #include extern PetscErrorCode ComputeJacobian(KSP,Mat,Mat,void*); extern PetscErrorCode ComputeRHS(KSP,Vec,void*); typedef struct { PetscScalar uu, tt; } UserContext; int main(int argc,char **argv) { KSP ksp; DM da; UserContext user; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_MIRROR,DMDA_STENCIL_STAR,11,11,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = KSPSetDM(ksp,(DM)da);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); user.uu = 1.0; user.tt = 1.0; ierr = KSPSetComputeRHS(ksp,ComputeRHS,&user);CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeJacobian,&user);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,NULL,NULL);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; } PetscErrorCode ComputeRHS(KSP ksp,Vec b,void *ctx) { UserContext *user = (UserContext*)ctx; PetscErrorCode ierr; PetscInt i,j,M,N,xm,ym,xs,ys; PetscScalar Hx,Hy,pi,uu,tt; PetscScalar **array; DM da; MatNullSpace nullspace; PetscFunctionBeginUser; ierr = KSPGetDM(ksp,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &M, &N, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); uu = user->uu; tt = user->tt; pi = 4*PetscAtanReal(1.0); Hx = 1.0/(PetscReal)(M); Hy = 1.0/(PetscReal)(N); ierr = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr); /* Fine grid */ ierr = DMDAVecGetArray(da, b, &array);CHKERRQ(ierr); for (j=ys; j