Actual source code: ex21.c
petsc-3.8.4 2018-03-24
1: static const char help[] = "Tests MatGetSchurComplement\n";
3: #include <petscksp.h>
6: PetscErrorCode Create(MPI_Comm comm,Mat *inA,IS *is0,IS *is1)
7: {
9: Mat A;
10: PetscInt r,rend,M;
11: PetscMPIInt rank;
14: *inA = 0;
15: MatCreate(comm,&A);
16: MatSetSizes(A,4,4,PETSC_DETERMINE,PETSC_DETERMINE);
17: MatSetFromOptions(A);
18: MatSetUp(A);
19: MatGetOwnershipRange(A,&r,&rend);
20: MatGetSize(A,&M,NULL);
22: ISCreateStride(comm,2,r,1,is0);
23: ISCreateStride(comm,2,r+2,1,is1);
25: MPI_Comm_rank(comm,&rank);
27: {
28: PetscInt rows[4],cols0[5],cols1[5],cols2[3],cols3[3];
29: PetscScalar RR = 1000.*rank,vals0[5],vals1[4],vals2[3],vals3[3];
31: rows[0] = r;
32: rows[1] = r+1;
33: rows[2] = r+2;
34: rows[3] = r+3;
36: cols0[0] = r+0;
37: cols0[1] = r+1;
38: cols0[2] = r+3;
39: cols0[3] = (r+4)%M;
40: cols0[4] = (r+M-4)%M;
42: cols1[0] = r+1;
43: cols1[1] = r+2;
44: cols1[2] = (r+4+1)%M;
45: cols1[3] = (r+M-4+1)%M;
47: cols2[0] = r;
48: cols2[1] = r+2;
49: cols2[2] = (r+4+2)%M;
51: cols3[0] = r+1;
52: cols3[1] = r+3;
53: cols3[2] = (r+4+3)%M;
55: vals0[0] = RR+1.;
56: vals0[1] = RR+2.;
57: vals0[2] = RR+3.;
58: vals0[3] = RR+4.;
59: vals0[4] = RR+5.;
61: vals1[0] = RR+6.;
62: vals1[1] = RR+7.;
63: vals1[2] = RR+8.;
64: vals1[3] = RR+9.;
66: vals2[0] = RR+10.;
67: vals2[1] = RR+11.;
68: vals2[2] = RR+12.;
70: vals3[0] = RR+13.;
71: vals3[1] = RR+14.;
72: vals3[2] = RR+15.;
73: MatSetValues(A,1,&rows[0],5,cols0,vals0,INSERT_VALUES);
74: MatSetValues(A,1,&rows[1],4,cols1,vals1,INSERT_VALUES);
75: MatSetValues(A,1,&rows[2],3,cols2,vals2,INSERT_VALUES);
76: MatSetValues(A,1,&rows[3],3,cols3,vals3,INSERT_VALUES);
77: }
78: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
79: MatAssemblyEnd (A,MAT_FINAL_ASSEMBLY);
80: *inA = A;
81: return(0);
82: }
84: PetscErrorCode Destroy(Mat *A,IS *is0,IS *is1)
85: {
89: MatDestroy(A);
90: ISDestroy(is0);
91: ISDestroy(is1);
92: return(0);
93: }
95: int main(int argc,char *argv[])
96: {
98: Mat A,S = NULL,Sexplicit = NULL;
99: IS is0,is1;
101: PetscInitialize(&argc,&argv,0,help);if (ierr) return ierr;
103: /* Test the Schur complement one way */
104: Create(PETSC_COMM_WORLD,&A,&is0,&is1);
105: MatView(A,PETSC_VIEWER_STDOUT_WORLD);
106: ISView(is0,PETSC_VIEWER_STDOUT_WORLD);
107: ISView(is1,PETSC_VIEWER_STDOUT_WORLD);
108: MatGetSchurComplement(A,is0,is0,is1,is1,MAT_INITIAL_MATRIX,&S,MAT_SCHUR_COMPLEMENT_AINV_DIAG,MAT_IGNORE_MATRIX,NULL);
109: MatComputeExplicitOperator(S,&Sexplicit);
110: PetscPrintf(PETSC_COMM_WORLD,"\nExplicit Schur complement of (0,0) in (1,1)\n");
111: MatView(Sexplicit,PETSC_VIEWER_STDOUT_WORLD);
112: Destroy(&A,&is0,&is1);
113: MatDestroy(&S);
114: MatDestroy(&Sexplicit);
116: /* And the other */
117: Create(PETSC_COMM_WORLD,&A,&is0,&is1);
118: MatGetSchurComplement(A,is1,is1,is0,is0,MAT_INITIAL_MATRIX,&S,MAT_SCHUR_COMPLEMENT_AINV_DIAG,MAT_IGNORE_MATRIX,NULL);
119: MatComputeExplicitOperator(S,&Sexplicit);
120: PetscPrintf(PETSC_COMM_WORLD,"\nExplicit Schur complement of (1,1) in (0,0)\n");
121: MatView(Sexplicit,PETSC_VIEWER_STDOUT_WORLD);
122: Destroy(&A,&is0,&is1);
123: MatDestroy(&S);
124: MatDestroy(&Sexplicit);
126: /* This time just the preconditioning matrix. */
127: Create(PETSC_COMM_WORLD,&A,&is0,&is1);
128: MatGetSchurComplement(A,is0,is0,is1,is1,MAT_IGNORE_MATRIX,NULL,MAT_SCHUR_COMPLEMENT_AINV_DIAG,MAT_INITIAL_MATRIX,&S);
129: PetscPrintf(PETSC_COMM_WORLD,"\nPreconditioning Schur complement of (0,0) in (1,1)\n");
130: MatView(S,PETSC_VIEWER_STDOUT_WORLD);
131: /* Modify and refresh */
132: MatShift(A,1.);
133: MatGetSchurComplement(A,is0,is0,is1,is1,MAT_IGNORE_MATRIX,NULL,MAT_SCHUR_COMPLEMENT_AINV_DIAG,MAT_REUSE_MATRIX,&S);
134: PetscPrintf(PETSC_COMM_WORLD,"\nAfter update\n");
135: MatView(S,PETSC_VIEWER_STDOUT_WORLD);
136: Destroy(&A,&is0,&is1);
137: MatDestroy(&S);
139: PetscFinalize();
140: return ierr;
141: }