Actual source code: ex8.c

petsc-3.7.5 2017-01-01
Report Typos and Errors
  2: static char help[] = "Solves a linear system in parallel with KSP. \n\
  3: Contributed by Jose E. Roman, SLEPc developer, for testing repeated call of KSPSetOperators(), 2014 \n\n";

  5: #include <petscksp.h>
  8: int main(int argc,char **args)
  9: {
 10:   Vec            x,b,u;    /* approx solution, RHS, exact solution */
 11:   Mat            A;        /* linear system matrix */
 12:   KSP            ksp;      /* linear solver context */
 13:   PetscRandom    rctx;     /* random number generator context */
 14:   PetscInt       i,j,Ii,J,Istart,Iend,m = 8,n = 7;
 16:   PetscBool      flg = PETSC_FALSE;
 17:   PetscScalar    v;
 18:   PC             pc;
 19:   PetscInt       in;
 20:   Mat            F,B;
 21:   PetscBool      solve=PETSC_FALSE,sameA=PETSC_FALSE;
 22: #if defined(PETSC_USE_LOG)
 23:   PetscLogStage stage;
 24: #endif
 25: #if !defined(PETSC_HAVE_MUMPS)
 26:   PetscMPIInt    size;
 27: #endif

 29:   PetscInitialize(&argc,&args,(char*)0,help);
 30:   PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);
 31:   PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
 32:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 33:          Compute the matrix and right-hand-side vector that define
 34:          the linear system, Ax = b.
 35:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 36:   MatCreate(PETSC_COMM_WORLD,&A);
 37:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
 38:   MatSetFromOptions(A);
 39:   MatMPIAIJSetPreallocation(A,5,NULL,5,NULL);
 40:   MatSeqAIJSetPreallocation(A,5,NULL);
 41:   MatSetUp(A);

 43:   MatGetOwnershipRange(A,&Istart,&Iend);

 45:   PetscLogStageRegister("Assembly", &stage);
 46:   PetscLogStagePush(stage);
 47:   for (Ii=Istart; Ii<Iend; Ii++) {
 48:     v = -1.0; i = Ii/n; j = Ii - i*n;
 49:     if (i>0)   {J = Ii - n; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
 50:     if (i<m-1) {J = Ii + n; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
 51:     if (j>0)   {J = Ii - 1; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
 52:     if (j<n-1) {J = Ii + 1; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
 53:     v = 4.0; MatSetValues(A,1,&Ii,1,&Ii,&v,INSERT_VALUES);
 54:   }
 55:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
 56:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
 57:   PetscLogStagePop();

 59:   /* A is symmetric. Set symmetric flag to enable ICC/Cholesky preconditioner */
 60:   MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);

 62:   /* Create parallel vectors. */
 63:   VecCreate(PETSC_COMM_WORLD,&u);
 64:   VecSetSizes(u,PETSC_DECIDE,m*n);
 65:   VecSetFromOptions(u);
 66:   VecDuplicate(u,&b);
 67:   VecDuplicate(b,&x);

 69:   /*
 70:      Set exact solution; then compute right-hand-side vector.
 71:      By default we use an exact solution of a vector with all
 72:      elements of 1.0;  Alternatively, using the runtime option
 73:      -random_sol forms a solution vector with random components.
 74:   */
 75:   PetscOptionsGetBool(NULL,NULL,"-random_exact_sol",&flg,NULL);
 76:   if (flg) {
 77:     PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
 78:     PetscRandomSetFromOptions(rctx);
 79:     VecSetRandom(u,rctx);
 80:     PetscRandomDestroy(&rctx);
 81:   } else {
 82:     VecSet(u,1.0);
 83:   }
 84:   MatMult(A,u,b);

 86:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 87:                 Create the linear solver and set various options
 88:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 89:   /* Create linear solver context */
 90:   KSPCreate(PETSC_COMM_WORLD,&ksp);

 92:   /* Set operators. */
 93:   KSPSetOperators(ksp,A,A);

 95:   KSPSetTolerances(ksp,1.e-2/((m+1)*(n+1)),1.e-50,PETSC_DEFAULT,PETSC_DEFAULT);

 97:   KSPSetType(ksp,KSPPREONLY);
 98:   KSPGetPC(ksp, &pc);
 99:   PCSetType(pc,PCCHOLESKY);
100: #if defined(PETSC_HAVE_MUMPS)
101: #if defined(PETSC_USE_COMPLEX)
102:   SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Spectrum slicing with MUMPS is not available for complex scalars");
103: #endif
104:   PCFactorSetMatSolverPackage(pc,MATSOLVERMUMPS);
105:   /*
106:      must use runtime option '-mat_mumps_icntl_13 1' (turn off scaLAPACK for
107:      matrix inertia), currently there is no better way of setting this in program
108:   */
109:   PetscOptionsInsertString(NULL,"-mat_mumps_icntl_13 1");
110: #else
111:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
112:   if (size>1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Configure with MUMPS if you want to run this example in parallel");
113: #endif

115:   KSPSetFromOptions(ksp);

117:   /* get inertia */
118:   PetscOptionsGetBool(NULL,NULL,"-solve",&solve,NULL);
119:   PetscOptionsGetBool(NULL,NULL,"-sameA",&sameA,NULL);
120:   KSPSetUp(ksp);
121:   PCFactorGetMatrix(pc,&F);
122:   MatGetInertia(F,&in,NULL,NULL);
123:   PetscPrintf(PETSC_COMM_WORLD,"INERTIA=%D\n",in);
124:   if (solve) {
125:     PetscPrintf(PETSC_COMM_WORLD,"Solving the intermediate KSP\n");
126:     KSPSolve(ksp,b,x);
127:   } else {PetscPrintf(PETSC_COMM_WORLD,"NOT Solving the intermediate KSP\n");}

129:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
130:                       Solve the linear system
131:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
132:   MatDuplicate(A,MAT_COPY_VALUES,&B);
133:   if (sameA) {
134:     PetscPrintf(PETSC_COMM_WORLD,"Seting A\n");
135:     MatAXPY(A,1.1,B,DIFFERENT_NONZERO_PATTERN);
136:     KSPSetOperators(ksp,A,A);
137:   } else {
138:     PetscPrintf(PETSC_COMM_WORLD,"Seting B\n");
139:     MatAXPY(B,1.1,A,DIFFERENT_NONZERO_PATTERN);
140:     KSPSetOperators(ksp,B,B);
141:   }
142:   KSPSetUp(ksp);
143:   PCFactorGetMatrix(pc,&F);
144:   MatGetInertia(F,&in,NULL,NULL);
145:   PetscPrintf(PETSC_COMM_WORLD,"INERTIA=%D\n",in);
146:   KSPSolve(ksp,b,x);
147:   MatDestroy(&B);

149:   /* Free work space.*/
150:   KSPDestroy(&ksp);
151:   VecDestroy(&u);  VecDestroy(&x);
152:   VecDestroy(&b);  MatDestroy(&A);

154:   PetscFinalize();
155:   return 0;
156: }