Actual source code: ex8.c
petsc-3.12.1 2019-10-22
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>
6: int main(int argc,char **args)
7: {
8: Vec x,b,u; /* approx solution, RHS, exact solution */
9: Mat A; /* linear system matrix */
10: KSP ksp; /* linear solver context */
11: PetscRandom rctx; /* random number generator context */
12: PetscInt i,j,Ii,J,Istart,Iend,m = 8,n = 7;
14: PetscBool flg = PETSC_FALSE;
15: PetscScalar v;
16: PC pc;
17: PetscInt in;
18: Mat F,B;
19: PetscBool solve=PETSC_FALSE,sameA=PETSC_FALSE;
20: #if defined(PETSC_USE_LOG)
21: PetscLogStage stage;
22: #endif
23: #if !defined(PETSC_HAVE_MUMPS)
24: PetscMPIInt size;
25: #endif
27: PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
28: PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);
29: PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
30: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
31: Compute the matrix and right-hand-side vector that define
32: the linear system, Ax = b.
33: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34: MatCreate(PETSC_COMM_WORLD,&A);
35: MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
36: MatSetFromOptions(A);
37: MatMPIAIJSetPreallocation(A,5,NULL,5,NULL);
38: MatSeqAIJSetPreallocation(A,5,NULL);
39: MatSetUp(A);
41: MatGetOwnershipRange(A,&Istart,&Iend);
43: PetscLogStageRegister("Assembly", &stage);
44: PetscLogStagePush(stage);
45: for (Ii=Istart; Ii<Iend; Ii++) {
46: v = -1.0; i = Ii/n; j = Ii - i*n;
47: if (i>0) {J = Ii - n; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
48: if (i<m-1) {J = Ii + n; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
49: if (j>0) {J = Ii - 1; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
50: if (j<n-1) {J = Ii + 1; MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);}
51: v = 4.0; MatSetValues(A,1,&Ii,1,&Ii,&v,INSERT_VALUES);
52: }
53: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
54: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
55: PetscLogStagePop();
57: /* A is symmetric. Set symmetric flag to enable ICC/Cholesky preconditioner */
58: MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);
60: /* Create parallel vectors. */
61: VecCreate(PETSC_COMM_WORLD,&u);
62: VecSetSizes(u,PETSC_DECIDE,m*n);
63: VecSetFromOptions(u);
64: VecDuplicate(u,&b);
65: VecDuplicate(b,&x);
67: /*
68: Set exact solution; then compute right-hand-side vector.
69: By default we use an exact solution of a vector with all
70: elements of 1.0; Alternatively, using the runtime option
71: -random_sol forms a solution vector with random components.
72: */
73: PetscOptionsGetBool(NULL,NULL,"-random_exact_sol",&flg,NULL);
74: if (flg) {
75: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
76: PetscRandomSetFromOptions(rctx);
77: VecSetRandom(u,rctx);
78: PetscRandomDestroy(&rctx);
79: } else {
80: VecSet(u,1.0);
81: }
82: MatMult(A,u,b);
84: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
85: Create the linear solver and set various options
86: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
87: /* Create linear solver context */
88: KSPCreate(PETSC_COMM_WORLD,&ksp);
90: /* Set operators. */
91: KSPSetOperators(ksp,A,A);
93: KSPSetTolerances(ksp,1.e-2/((m+1)*(n+1)),1.e-50,PETSC_DEFAULT,PETSC_DEFAULT);
95: KSPSetType(ksp,KSPPREONLY);
96: KSPGetPC(ksp, &pc);
97: PCSetType(pc,PCCHOLESKY);
98: #if defined(PETSC_HAVE_MUMPS)
99: #if defined(PETSC_USE_COMPLEX)
100: SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Spectrum slicing with MUMPS is not available for complex scalars");
101: #endif
102: PCFactorSetMatSolverType(pc,MATSOLVERMUMPS);
103: /*
104: must use runtime option '-mat_mumps_icntl_13 1' (turn off scaLAPACK for
105: matrix inertia), currently there is no better way of setting this in program
106: */
107: PetscOptionsInsertString(NULL,"-mat_mumps_icntl_13 1");
108: #else
109: MPI_Comm_size(PETSC_COMM_WORLD,&size);
110: if (size>1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Configure with MUMPS if you want to run this example in parallel");
111: #endif
113: KSPSetFromOptions(ksp);
115: /* get inertia */
116: PetscOptionsGetBool(NULL,NULL,"-solve",&solve,NULL);
117: PetscOptionsGetBool(NULL,NULL,"-sameA",&sameA,NULL);
118: KSPSetUp(ksp);
119: PCFactorGetMatrix(pc,&F);
120: MatGetInertia(F,&in,NULL,NULL);
121: PetscPrintf(PETSC_COMM_WORLD,"INERTIA=%D\n",in);
122: if (solve) {
123: PetscPrintf(PETSC_COMM_WORLD,"Solving the intermediate KSP\n");
124: KSPSolve(ksp,b,x);
125: } else {PetscPrintf(PETSC_COMM_WORLD,"NOT Solving the intermediate KSP\n");}
127: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
128: Solve the linear system
129: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
130: MatDuplicate(A,MAT_COPY_VALUES,&B);
131: if (sameA) {
132: PetscPrintf(PETSC_COMM_WORLD,"Seting A\n");
133: MatAXPY(A,1.1,B,DIFFERENT_NONZERO_PATTERN);
134: KSPSetOperators(ksp,A,A);
135: } else {
136: PetscPrintf(PETSC_COMM_WORLD,"Seting B\n");
137: MatAXPY(B,1.1,A,DIFFERENT_NONZERO_PATTERN);
138: KSPSetOperators(ksp,B,B);
139: }
140: KSPSetUp(ksp);
141: PCFactorGetMatrix(pc,&F);
142: MatGetInertia(F,&in,NULL,NULL);
143: PetscPrintf(PETSC_COMM_WORLD,"INERTIA=%D\n",in);
144: KSPSolve(ksp,b,x);
145: MatDestroy(&B);
147: /* Free work space.*/
148: KSPDestroy(&ksp);
149: VecDestroy(&u); VecDestroy(&x);
150: VecDestroy(&b); MatDestroy(&A);
152: PetscFinalize();
153: return ierr;
154: }
156: /*TEST
158: build:
159: requires: !complex
161: test:
162: args:
164: test:
165: suffix: 2
166: args: -sameA
168: TEST*/