Actual source code: ex127.c
petsc-3.10.5 2019-03-28
1: static char help[] = "Test MatMult() for Hermitian matrix.\n\n";
2: /*
3: Example of usage
4: ./ex127 -check_Hermitian -display_mat -display_vec
5: mpiexec -n 2 ./ex127
6: */
8: #include <petscmat.h>
10: int main(int argc,char **args)
11: {
12: Mat A,As;
13: Vec x,y,ys;
14: PetscBool flg,disp_mat=PETSC_FALSE,disp_vec=PETSC_FALSE;
16: PetscMPIInt size,rank;
17: PetscInt m,i,j;
18: PetscScalar v,sigma2;
19: PetscRandom rctx = NULL;
20: PetscReal h2,sigma1=100.0,norm;
21: PetscInt dim,Ii,J,n = 3,rstart,rend;
23: PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
24: #if !defined(PETSC_USE_COMPLEX)
25: SETERRQ(PETSC_COMM_WORLD,1,"This example requires complex build");
26: #endif
28: MPI_Comm_size(PETSC_COMM_WORLD,&size);
29: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
30: PetscOptionsHasName(NULL,NULL, "-display_mat", &disp_mat);
31: PetscOptionsHasName(NULL,NULL, "-display_vec", &disp_vec);
33: PetscOptionsGetReal(NULL,NULL,"-sigma1",&sigma1,NULL);
34: PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
35: dim = n*n;
37: MatCreate(PETSC_COMM_WORLD,&A);
38: MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,dim,dim);
39: MatSetType(A,MATAIJ);
40: MatSetFromOptions(A);
41: MatSetUp(A);
43: PetscOptionsHasName(NULL,NULL,"-norandom",&flg);
44: if (!flg) {
45: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
46: PetscRandomSetFromOptions(rctx);
47: PetscRandomSetInterval(rctx,0.0,PETSC_i);
48: PetscRandomGetValue(rctx,&sigma2); /* RealPart(sigma2) == 0.0 */
49: } else {
50: sigma2 = 10.0*PETSC_i;
51: }
52: h2 = 1.0/((n+1)*(n+1));
54: MatGetOwnershipRange(A,&rstart,&rend);
55: for (Ii=rstart; Ii<rend; Ii++) {
56: v = -1.0; i = Ii/n; j = Ii - i*n;
57: if (i>0) {
58: J = Ii-n; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
59: }
60: if (i<n-1) {
61: J = Ii+n; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
62: }
63: if (j>0) {
64: J = Ii-1; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
65: }
66: if (j<n-1) {
67: J = Ii+1; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
68: }
69: v = 4.0 - sigma1*h2;
70: MatSetValues(A,1,&Ii,1,&Ii,&v,ADD_VALUES);
71: }
72: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
73: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
75: /* Check whether A is symmetric */
76: PetscOptionsHasName(NULL,NULL, "-check_symmetric", &flg);
77: if (flg) {
78: MatIsSymmetric(A,0.0,&flg);
79: if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"A is not symmetric");
80: }
81: MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);
83: /* make A complex Hermitian */
84: Ii = 0; J = dim-1;
85: if (Ii >= rstart && Ii < rend) {
86: v = sigma2*h2; /* RealPart(v) = 0.0 */
87: MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
88: v = -sigma2*h2;
89: MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES);
90: }
92: Ii = dim-2; J = dim-1;
93: if (Ii >= rstart && Ii < rend) {
94: v = sigma2*h2; /* RealPart(v) = 0.0 */
95: MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
96: v = -sigma2*h2;
97: MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES);
98: }
100: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
101: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
103: /* Check whether A is Hermitian, then set A->hermitian flag */
104: PetscOptionsHasName(NULL,NULL, "-check_Hermitian", &flg);
105: if (flg && size == 1) {
106: MatIsHermitian(A,0.0,&flg);
107: if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"A is not Hermitian");
108: }
109: MatSetOption(A,MAT_HERMITIAN,PETSC_TRUE);
111: #if defined(PETSC_HAVE_SUPERLU_DIST)
112: /* Test Cholesky factorization */
113: PetscOptionsHasName(NULL,NULL, "-test_choleskyfactor", &flg);
114: if (flg) {
115: Mat F;
116: IS perm,iperm;
117: MatFactorInfo info;
118: PetscInt nneg,nzero,npos;
120: MatGetFactor(A,MATSOLVERSUPERLU_DIST,MAT_FACTOR_CHOLESKY,&F);
121: MatGetOrdering(A,MATORDERINGND,&perm,&iperm);
122: MatCholeskyFactorSymbolic(F,A,perm,&info);
123: MatCholeskyFactorNumeric(F,A,&info);
125: MatGetInertia(F,&nneg,&nzero,&npos);
126: if (!rank) {
127: PetscPrintf(PETSC_COMM_SELF," MatInertia: nneg: %D, nzero: %D, npos: %D\n",nneg,nzero,npos);
128: }
129: MatDestroy(&F);
130: ISDestroy(&perm);
131: ISDestroy(&iperm);
132: }
133: #endif
135: /* Create a Hermitian matrix As in sbaij format */
136: MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&As);
137: if (disp_mat) {
138: PetscPrintf(PETSC_COMM_WORLD," As:\n");
139: MatView(As,PETSC_VIEWER_STDOUT_WORLD);
140: }
142: MatGetLocalSize(A,&m,&n);
143: VecCreate(PETSC_COMM_WORLD,&x);
144: VecSetSizes(x,n,PETSC_DECIDE);
145: VecSetFromOptions(x);
146: if (rctx) {
147: VecSetRandom(x,rctx);
148: } else {
149: VecSet(x,1.0);
150: }
152: /* Create vectors */
153: VecCreate(PETSC_COMM_WORLD,&y);
154: VecSetSizes(y,m,PETSC_DECIDE);
155: VecSetFromOptions(y);
156: VecDuplicate(y,&ys);
158: /* Test MatMult */
159: MatMult(A,x,y);
160: MatMult(As,x,ys);
161: if (disp_vec) {
162: PetscPrintf(PETSC_COMM_WORLD,"y = A*x:\n");
163: VecView(y,PETSC_VIEWER_STDOUT_WORLD);
164: PetscPrintf(PETSC_COMM_WORLD,"ys = As*x:\n");
165: VecView(ys,PETSC_VIEWER_STDOUT_WORLD);
166: }
167: VecAXPY(y,-1.0,ys);
168: VecNorm(y,NORM_INFINITY,&norm);
169: if (norm > 100.0*PETSC_MACHINE_EPSILON || disp_vec) {
170: PetscPrintf(PETSC_COMM_WORLD,"|| A*x - As*x || = %g\n",(double)norm);
171: }
173: /* Free spaces */
174: PetscRandomDestroy(&rctx);
175: MatDestroy(&A);
176: MatDestroy(&As);
178: VecDestroy(&x);
179: VecDestroy(&y);
180: VecDestroy(&ys);
181: PetscFinalize();
182: return ierr;
183: }
186: /*TEST
188: build:
189: requires: complex
191: test:
192: args: -n 1000
193: output_file: output/ex127.out
195: test:
196: suffix: 2
197: nsize: 3
198: args: -n 1000
199: output_file: output/ex127.out
202: test:
203: suffix: superlu_dist
204: nsize: 3
205: requires: superlu_dist
206: args: -test_choleskyfactor -mat_superlu_dist_rowperm NOROWPERM
207: output_file: output/ex127_superlu_dist.out
208: TEST*/