xref: /petsc/src/mat/tests/ex127.c (revision b122ec5aa1bd4469eb4e0673542fb7de3f411254)
1 static char help[] = "Test MatMult() for Hermitian matrix.\n\n";
2 
3 #include <petscmat.h>
4 
5 int main(int argc,char **args)
6 {
7   Mat            A,As;
8   PetscBool      flg;
9   PetscMPIInt    size;
10   PetscInt       i,j;
11   PetscScalar    v,sigma2;
12   PetscReal      h2,sigma1=100.0;
13   PetscInt       dim,Ii,J,n = 3,rstart,rend;
14 
15   CHKERRQ(PetscInitialize(&argc,&args,(char*)0,help));
16   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
17   CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-sigma1",&sigma1,NULL));
18   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
19   dim  = n*n;
20 
21   CHKERRQ(MatCreate(PETSC_COMM_WORLD,&A));
22   CHKERRQ(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,dim,dim));
23   CHKERRQ(MatSetType(A,MATAIJ));
24   CHKERRQ(MatSetFromOptions(A));
25   CHKERRQ(MatSetUp(A));
26 
27   sigma2 = 10.0*PETSC_i;
28   h2 = 1.0/((n+1)*(n+1));
29 
30   CHKERRQ(MatGetOwnershipRange(A,&rstart,&rend));
31   for (Ii=rstart; Ii<rend; Ii++) {
32     v = -1.0; i = Ii/n; j = Ii - i*n;
33     if (i>0) {
34       J = Ii-n; CHKERRQ(MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES));
35     }
36     if (i<n-1) {
37       J = Ii+n; CHKERRQ(MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES));
38     }
39     if (j>0) {
40       J = Ii-1; CHKERRQ(MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES));
41     }
42     if (j<n-1) {
43       J = Ii+1; CHKERRQ(MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES));
44     }
45     v    = 4.0 - sigma1*h2;
46     CHKERRQ(MatSetValues(A,1,&Ii,1,&Ii,&v,ADD_VALUES));
47   }
48   CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
49   CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
50 
51   /* Check whether A is symmetric */
52   CHKERRQ(PetscOptionsHasName(NULL,NULL, "-check_symmetric", &flg));
53   if (flg) {
54     CHKERRQ(MatIsSymmetric(A,0.0,&flg));
55     PetscCheck(flg,PETSC_COMM_SELF,PETSC_ERR_USER,"A is not symmetric");
56   }
57   CHKERRQ(MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE));
58 
59   /* make A complex Hermitian */
60   Ii = 0; J = dim-1;
61   if (Ii >= rstart && Ii < rend) {
62     v    = sigma2*h2; /* RealPart(v) = 0.0 */
63     CHKERRQ(MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES));
64     v    = -sigma2*h2;
65     CHKERRQ(MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES));
66   }
67 
68   Ii = dim-2; J = dim-1;
69   if (Ii >= rstart && Ii < rend) {
70     v    = sigma2*h2; /* RealPart(v) = 0.0 */
71     CHKERRQ(MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES));
72     v    = -sigma2*h2;
73     CHKERRQ(MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES));
74   }
75 
76   CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
77   CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
78   CHKERRQ(MatViewFromOptions(A,NULL,"-disp_mat"));
79 
80   /* Check whether A is Hermitian, then set A->hermitian flag */
81   CHKERRQ(PetscOptionsHasName(NULL,NULL, "-check_Hermitian", &flg));
82   if (flg && size == 1) {
83     CHKERRQ(MatIsHermitian(A,0.0,&flg));
84     PetscCheck(flg,PETSC_COMM_SELF,PETSC_ERR_USER,"A is not Hermitian");
85   }
86   CHKERRQ(MatSetOption(A,MAT_HERMITIAN,PETSC_TRUE));
87 
88 #if defined(PETSC_HAVE_SUPERLU_DIST)
89   /* Test Cholesky factorization */
90   CHKERRQ(PetscOptionsHasName(NULL,NULL, "-test_choleskyfactor", &flg));
91   if (flg) {
92     Mat      F;
93     IS       perm,iperm;
94     MatFactorInfo info;
95     PetscInt nneg,nzero,npos;
96 
97     CHKERRQ(MatGetFactor(A,MATSOLVERSUPERLU_DIST,MAT_FACTOR_CHOLESKY,&F));
98     CHKERRQ(MatGetOrdering(A,MATORDERINGND,&perm,&iperm));
99     CHKERRQ(MatCholeskyFactorSymbolic(F,A,perm,&info));
100     CHKERRQ(MatCholeskyFactorNumeric(F,A,&info));
101 
102     CHKERRQ(MatGetInertia(F,&nneg,&nzero,&npos));
103     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD," MatInertia: nneg: %" PetscInt_FMT ", nzero: %" PetscInt_FMT ", npos: %" PetscInt_FMT "\n",nneg,nzero,npos));
104     CHKERRQ(MatDestroy(&F));
105     CHKERRQ(ISDestroy(&perm));
106     CHKERRQ(ISDestroy(&iperm));
107   }
108 #endif
109 
110   /* Create a Hermitian matrix As in sbaij format */
111   CHKERRQ(MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&As));
112   CHKERRQ(MatViewFromOptions(As,NULL,"-disp_mat"));
113 
114   /* Test MatMult */
115   CHKERRQ(MatMultEqual(A,As,10,&flg));
116   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"MatMult not equal");
117   CHKERRQ(MatMultAddEqual(A,As,10,&flg));
118   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"MatMultAdd not equal");
119 
120   /* Free spaces */
121   CHKERRQ(MatDestroy(&A));
122   CHKERRQ(MatDestroy(&As));
123   CHKERRQ(PetscFinalize());
124   return 0;
125 }
126 
127 /*TEST
128 
129    build:
130       requires: complex
131 
132    test:
133       args: -n 1000
134       output_file: output/ex127.out
135 
136    test:
137       suffix: 2
138       nsize: 3
139       args: -n 1000
140       output_file: output/ex127.out
141 
142    test:
143       suffix: superlu_dist
144       nsize: 3
145       requires: superlu_dist
146       args: -test_choleskyfactor -mat_superlu_dist_rowperm NOROWPERM
147       output_file: output/ex127_superlu_dist.out
148 TEST*/
149