Actual source code: ex127.c

petsc-3.8.4 2018-03-24
Report Typos and Errors
  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:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
 25:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
 26:   PetscOptionsHasName(NULL,NULL, "-display_mat", &disp_mat);
 27:   PetscOptionsHasName(NULL,NULL, "-display_vec", &disp_vec);

 29:   PetscOptionsGetReal(NULL,NULL,"-sigma1",&sigma1,NULL);
 30:   PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
 31:   dim  = n*n;

 33:   MatCreate(PETSC_COMM_WORLD,&A);
 34:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,dim,dim);
 35:   MatSetType(A,MATAIJ);
 36:   MatSetFromOptions(A);
 37:   MatSetUp(A);

 39:   PetscOptionsHasName(NULL,NULL,"-norandom",&flg);
 40:   if (!flg) {
 41:     PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
 42:     PetscRandomSetFromOptions(rctx);
 43:     PetscRandomSetInterval(rctx,0.0,PETSC_i);
 44:     PetscRandomGetValue(rctx,&sigma2); /* RealPart(sigma2) == 0.0 */
 45:   } else {
 46:     sigma2 = 10.0*PETSC_i;
 47:   }
 48:   h2 = 1.0/((n+1)*(n+1));

 50:   MatGetOwnershipRange(A,&rstart,&rend);
 51:   for (Ii=rstart; Ii<rend; Ii++) {
 52:     v = -1.0; i = Ii/n; j = Ii - i*n;
 53:     if (i>0) {
 54:       J = Ii-n; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
 55:     }
 56:     if (i<n-1) {
 57:       J = Ii+n; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
 58:     }
 59:     if (j>0) {
 60:       J = Ii-1; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
 61:     }
 62:     if (j<n-1) {
 63:       J = Ii+1; MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
 64:     }
 65:     v    = 4.0 - sigma1*h2;
 66:     MatSetValues(A,1,&Ii,1,&Ii,&v,ADD_VALUES);
 67:   }
 68:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
 69:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);

 71:   /* Check whether A is symmetric */
 72:   PetscOptionsHasName(NULL,NULL, "-check_symmetric", &flg);
 73:   if (flg) {
 74:     Mat Trans;
 75:     MatTranspose(A,MAT_INITIAL_MATRIX, &Trans);
 76:     MatEqual(A, Trans, &flg);
 77:     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"A is not symmetric");
 78:     MatDestroy(&Trans);
 79:   }
 80:   MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);

 82:   /* make A complex Hermitian */
 83:   Ii = 0; J = dim-1;
 84:   if (Ii >= rstart && Ii < rend) {
 85:     v    = sigma2*h2; /* RealPart(v) = 0.0 */
 86:     MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
 87:     v    = -sigma2*h2;
 88:     MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES);
 89:   }

 91:   Ii = dim-2; J = dim-1;
 92:   if (Ii >= rstart && Ii < rend) {
 93:     v    = sigma2*h2; /* RealPart(v) = 0.0 */
 94:     MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
 95:     v    = -sigma2*h2;
 96:     MatSetValues(A,1,&J,1,&Ii,&v,ADD_VALUES);
 97:   }

 99:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
100:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);

102:   /* Check whether A is Hermitian */
103:   PetscOptionsHasName(NULL,NULL, "-check_Hermitian", &flg);
104:   if (flg) {
105:     Mat Hermit;
106:     if (disp_mat) {
107:       PetscPrintf(PETSC_COMM_WORLD," A:\n");
108:       MatView(A,PETSC_VIEWER_STDOUT_WORLD);
109:     }
110:     MatHermitianTranspose(A,MAT_INITIAL_MATRIX, &Hermit);
111:     if (disp_mat) {
112:       PetscPrintf(PETSC_COMM_WORLD," A_Hermitian:\n");
113:       MatView(Hermit,PETSC_VIEWER_STDOUT_WORLD);
114:     }
115:     MatEqual(A, Hermit, &flg);
116:     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"A is not Hermitian");
117:     MatDestroy(&Hermit);
118:   }
119:   MatSetOption(A,MAT_HERMITIAN,PETSC_TRUE);

121:   /* Create a Hermitian matrix As in sbaij format */
122:   MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&As);
123:   if (disp_mat) {
124:     PetscPrintf(PETSC_COMM_WORLD," As:\n");
125:     MatView(As,PETSC_VIEWER_STDOUT_WORLD);
126:   }

128:   MatGetLocalSize(A,&m,&n);
129:   VecCreate(PETSC_COMM_WORLD,&x);
130:   VecSetSizes(x,n,PETSC_DECIDE);
131:   VecSetFromOptions(x);
132:   if (rctx) {
133:     VecSetRandom(x,rctx);
134:   } else {
135:     VecSet(x,1.0);
136:   }

138:   /* Create vectors */
139:   VecCreate(PETSC_COMM_WORLD,&y);
140:   VecSetSizes(y,m,PETSC_DECIDE);
141:   VecSetFromOptions(y);
142:   VecDuplicate(y,&ys);

144:   /* Test MatMult */
145:   MatMult(A,x,y);
146:   MatMult(As,x,ys);
147:   if (disp_vec) {
148:     PetscPrintf(PETSC_COMM_WORLD,"y = A*x:\n");
149:     VecView(y,PETSC_VIEWER_STDOUT_WORLD);
150:     PetscPrintf(PETSC_COMM_WORLD,"ys = As*x:\n");
151:     VecView(ys,PETSC_VIEWER_STDOUT_WORLD);
152:   }
153:   VecAXPY(y,-1.0,ys);
154:   VecNorm(y,NORM_INFINITY,&norm);
155:   if (norm > 100.0*PETSC_MACHINE_EPSILON || disp_vec) {
156:     PetscPrintf(PETSC_COMM_WORLD,"|| A*x - As*x || = %g\n",(double)norm);
157:   }

159:   /* Free spaces */
160:   PetscRandomDestroy(&rctx);
161:   MatDestroy(&A);
162:   MatDestroy(&As);

164:   VecDestroy(&x);
165:   VecDestroy(&y);
166:   VecDestroy(&ys);
167:   PetscFinalize();
168:   return ierr;
169: }