PetscErrorCode FormJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) { AppCtx *user = (AppCtx *) ptr; PetscErrorCode ierr; KSP ksp; PC pc; PetscBool ismg; *flag = SAME_NONZERO_PATTERN; ierr = FormJacobian_Grid(user,&user->fine,X,J,B);CHKERRQ(ierr); /* create coarse grid jacobian for preconditioner */ ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)pc,PCMG,&ismg);CHKERRQ(ierr); if (ismg) { ierr = KSPSetOperators(user->ksp_fine,user->fine.J,user->fine.J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* restrict X to coarse grid */ ierr = MatMult(user->R,X,user->coarse.x);CHKERRQ(ierr); ierr = VecPointwiseMult(user->coarse.x,user->coarse.x,user->Rscale);CHKERRQ(ierr); /* form Jacobian on coarse grid */ if (user->redundant_build) { /* get copy of coarse X onto each processor */ ierr = VecScatterBegin(user->tolocalall,user->coarse.x,user->localall,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(user->tolocalall,user->coarse.x,user->localall,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = FormJacobian_Coarse(user,&user->coarse,user->localall,&user->coarse.J,&user->coarse.J);CHKERRQ(ierr); } else { /* coarse grid Jacobian computed in parallel */ ierr = FormJacobian_Grid(user,&user->coarse,user->coarse.x,&user->coarse.J,&user->coarse.J);CHKERRQ(ierr); } ierr = KSPSetOperators(user->ksp_coarse,user->coarse.J,user->coarse.J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); } return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt its,n,Nx=PETSC_DECIDE,Ny=PETSC_DECIDE,nlocal; PetscMPIInt size; PetscScalar one = 1.0; PetscInt mx,my; Mat A; GridCtx fine_ctx; KSP ksp; PetscBool flg; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* set up discretization matrix for fine grid */ fine_ctx.mx = 9; fine_ctx.my = 9; ierr = PetscOptionsGetInt(NULL,NULL,"-mx",&mx,&flg);CHKERRQ(ierr); if (flg) fine_ctx.mx = mx; ierr = PetscOptionsGetInt(NULL,NULL,"-my",&my,&flg);CHKERRQ(ierr); if (flg) fine_ctx.my = my; ierr = PetscPrintf(PETSC_COMM_WORLD,"Fine grid size %D by %D\n",fine_ctx.mx,fine_ctx.my);CHKERRQ(ierr); n = fine_ctx.mx*fine_ctx.my; MPI_Comm_size(PETSC_COMM_WORLD,&size); ierr = PetscOptionsGetInt(NULL,NULL,"-Nx",&Nx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-Ny",&Ny,NULL);CHKERRQ(ierr); /* Set up distributed array for fine grid */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,fine_ctx.mx, fine_ctx.my,Nx,Ny,1,1,NULL,NULL,&fine_ctx.da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(fine_ctx.da,&fine_ctx.x);CHKERRQ(ierr); ierr = VecDuplicate(fine_ctx.x,&fine_ctx.b);CHKERRQ(ierr); ierr = VecGetLocalSize(fine_ctx.x,&nlocal);CHKERRQ(ierr); ierr = DMCreateLocalVector(fine_ctx.da,&fine_ctx.localX);CHKERRQ(ierr); ierr = VecDuplicate(fine_ctx.localX,&fine_ctx.localF);CHKERRQ(ierr); ierr = MatCreateAIJ(PETSC_COMM_WORLD,nlocal,nlocal,n,n,5,NULL,3,NULL,&A);CHKERRQ(ierr); ierr = FormJacobian_Grid(&fine_ctx,&A);CHKERRQ(ierr); /* create linear solver */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); /* set values for rhs vector */ ierr = VecSet(fine_ctx.b,one);CHKERRQ(ierr); /* set options, then solve system */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* calls PCSetFromOptions_ML if 'pc_type=ml' */ ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); ierr = KSPSolve(ksp,fine_ctx.b,fine_ctx.x);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of iterations = %D\n",its);CHKERRQ(ierr); /* free data structures */ ierr = VecDestroy(&fine_ctx.x);CHKERRQ(ierr); ierr = VecDestroy(&fine_ctx.b);CHKERRQ(ierr); ierr = DMDestroy(&fine_ctx.da);CHKERRQ(ierr); ierr = VecDestroy(&fine_ctx.localX);CHKERRQ(ierr); ierr = VecDestroy(&fine_ctx.localF);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt its,n,Nx=PETSC_DECIDE,Ny=PETSC_DECIDE,nlocal,i; PetscMPIInt size; PC pc; PetscInt mx,my; Mat A; GridCtx fine_ctx; KSP ksp; PetscBool flg; PetscInitialize(&argc,&argv,NULL,help); /* set up discretization matrix for fine grid */ /* ML requires input of fine-grid matrix. It determines nlevels. */ fine_ctx.mx = 9; fine_ctx.my = 9; ierr = PetscOptionsGetInt(NULL,"-mx",&mx,&flg);CHKERRQ(ierr); if (flg) fine_ctx.mx = mx; ierr = PetscOptionsGetInt(NULL,"-my",&my,&flg);CHKERRQ(ierr); if (flg) fine_ctx.my = my; ierr = PetscPrintf(PETSC_COMM_WORLD,"Fine grid size %D by %D\n",fine_ctx.mx,fine_ctx.my);CHKERRQ(ierr); n = fine_ctx.mx*fine_ctx.my; MPI_Comm_size(PETSC_COMM_WORLD,&size); ierr = PetscOptionsGetInt(NULL,"-Nx",&Nx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-Ny",&Ny,NULL);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,fine_ctx.mx, fine_ctx.my,Nx,Ny,1,1,NULL,NULL,&fine_ctx.da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(fine_ctx.da,&fine_ctx.x);CHKERRQ(ierr); ierr = VecDuplicate(fine_ctx.x,&fine_ctx.b);CHKERRQ(ierr); ierr = VecGetLocalSize(fine_ctx.x,&nlocal);CHKERRQ(ierr); ierr = DMCreateLocalVector(fine_ctx.da,&fine_ctx.localX);CHKERRQ(ierr); ierr = VecDuplicate(fine_ctx.localX,&fine_ctx.localF);CHKERRQ(ierr); ierr = MatCreateAIJ(PETSC_COMM_WORLD,nlocal,nlocal,n,n,5,NULL,3,NULL,&A);CHKERRQ(ierr); ierr = FormJacobian_Grid(&fine_ctx,&A);CHKERRQ(ierr); /* create linear solver */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCML);CHKERRQ(ierr); /* set options, then solve system */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* calls PCSetFromOptions_MG/ML */ for (i=0; i<3; i++) { if (i<2) { /* test DIFFERENT_NONZERO_PATTERN */ /* set values for rhs vector */ ierr = VecSet(fine_ctx.b,i+1.0);CHKERRQ(ierr); /* modify A */ ierr = MatShift(A,1.0);CHKERRQ(ierr); ierr = MatScale(A,2.0);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } else { /* test SAME_NONZERO_PATTERN */ ierr = KSPSetOperators(ksp,A,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr); } ierr = KSPSolve(ksp,fine_ctx.b,fine_ctx.x);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of iterations = %D\n",its);CHKERRQ(ierr); } /* free data structures */ ierr = VecDestroy(&fine_ctx.x);CHKERRQ(ierr); ierr = VecDestroy(&fine_ctx.b);CHKERRQ(ierr); ierr = DMDestroy(&fine_ctx.da);CHKERRQ(ierr); ierr = VecDestroy(&fine_ctx.localX);CHKERRQ(ierr); ierr = VecDestroy(&fine_ctx.localF);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }