static char help[] = "Uses a different preconditioner matrix and linear system matrix in the KSP solvers.\n\ Note that different storage formats\n\ can be used for the different matrices.\n\n"; /*T Concepts: KSP^different matrices for linear system and preconditioner; Processors: n T*/ /* Include "petscksp.h" so that we can use KSP solvers. Note that this file automatically includes: petsc.h - base PETSc routines petscvec.h - vectors petscsys.h - system routines petscmat.h - matrices petscis.h - index sets petscksp.h - Krylov subspace methods petscviewer.h - viewers petscpc.h - preconditioners */ #include "petscksp.h" #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **args) { KSP ksp; /* linear solver context */ Mat A,B; /* linear system matrix, preconditioning matrix */ PetscRandom rctx; /* random number generator context */ Vec x,b,u; /* approx solution, RHS, exact solution */ Vec tmp; /* work vector */ PetscScalar v,one = 1.0,scale = 0.0; PetscInt i,j,m = 15,n = 17,Ii,J,Istart,Iend; PetscErrorCode ierr; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(PETSC_NULL,"-scale",&scale,PETSC_NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the matrix and right-hand-side vector that define the linear system,Ax = b. Also, create a different preconditioner matrix. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create the linear system matrix (A). - Here we use a block diagonal matrix format (MATBDIAG) and specify only the global size. The parallel partitioning of the matrix will be determined at runtime by PETSc. */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr); ierr = MatSetType(A,MATBDIAG);CHKERRQ(ierr); ierr = MatSeqBDiagSetPreallocation(A,0,1,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = MatMPIBDiagSetPreallocation(A,0,1,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* Create a different preconditioner matrix (B). This is usually done to form a cheaper (or sparser) preconditioner matrix compared to the linear system matrix. - Here we use MatCreate() followed by MatSetFromOptions(), so that the matrix format and parallel partitioning will be determined at runtime. */ ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); /* Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. Determine which rows of the matrix are locally owned. */ ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr); /* Set entries within the two matrices */ for (Ii=Istart; Ii0) { J=Ii-n; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr); } if (i0) { J=Ii-1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr); } if (j1) { J=Ii-(n+1); ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr); } if (i -pc_type ) */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* Free work space. All PETSc objects should be destroyed when they are no longer needed. */ ierr = KSPDestroy(ksp);CHKERRQ(ierr); ierr = VecDestroy(u);CHKERRQ(ierr); ierr = MatDestroy(B);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = VecDestroy(b);CHKERRQ(ierr); /* Always call PetscFinalize() before exiting a program. This routine - finalizes the PETSc libraries as well as MPI - provides summary and diagnostic information if certain runtime options are chosen (e.g., -log_summary). */ ierr = PetscFinalize();CHKERRQ(ierr); return 0; }