Actual source code: ex8.c
petsc-3.7.1 2016-05-15
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: }