xref: /petsc/src/mat/tests/ex115.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Tests MatHYPRE\n";
3c4762a1bSJed Brown 
4c4762a1bSJed Brown #include <petscmathypre.h>
5c4762a1bSJed Brown 
6c4762a1bSJed Brown int main(int argc,char **args)
7c4762a1bSJed Brown {
8c4762a1bSJed Brown   Mat                A,B,C,D;
9c4762a1bSJed Brown   Mat                pAB,CD,CAB;
10c4762a1bSJed Brown   hypre_ParCSRMatrix *parcsr;
11c4762a1bSJed Brown   PetscReal          err;
12c4762a1bSJed Brown   PetscInt           i,j,N = 6, M = 6;
13c4762a1bSJed Brown   PetscErrorCode     ierr;
14c4762a1bSJed Brown   PetscBool          flg,testptap = PETSC_TRUE,testmatmatmult = PETSC_TRUE;
15c4762a1bSJed Brown   PetscReal          norm;
16c4762a1bSJed Brown   char               file[256];
17c4762a1bSJed Brown 
18c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
19*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetString(NULL,NULL,"-f",file,sizeof(file),&flg));
20c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX)
21c4762a1bSJed Brown   testptap = PETSC_FALSE;
22c4762a1bSJed Brown   testmatmatmult = PETSC_FALSE;
23*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsInsertString(NULL,"-options_left 0"));
24c4762a1bSJed Brown #endif
25*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-ptap",&testptap,NULL));
26*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-matmatmult",&testmatmatmult,NULL));
27*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreate(PETSC_COMM_WORLD,&A));
28c4762a1bSJed Brown   if (!flg) { /* Create a matrix and test MatSetValues */
29c4762a1bSJed Brown     PetscMPIInt size;
30c4762a1bSJed Brown 
31*5f80ce2aSJacob Faibussowitsch     CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
32*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL));
33*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL));
34*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N));
35*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetType(A,MATAIJ));
36*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSeqAIJSetPreallocation(A,9,NULL));
37*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMPIAIJSetPreallocation(A,9,NULL,9,NULL));
38*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreate(PETSC_COMM_WORLD,&B));
39*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N));
40*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetType(B,MATHYPRE));
41c4762a1bSJed Brown     if (M == N) {
42*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatHYPRESetPreallocation(B,9,NULL,9,NULL));
43c4762a1bSJed Brown     } else {
44*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatHYPRESetPreallocation(B,6,NULL,6,NULL));
45c4762a1bSJed Brown     }
46c4762a1bSJed Brown     if (M == N) {
47c4762a1bSJed Brown       for (i=0; i<M; i++) {
48c4762a1bSJed Brown         PetscInt    cols[] = {0,1,2,3,4,5};
49c4762a1bSJed Brown         PetscScalar vals[] = {0,1./size,2./size,3./size,4./size,5./size};
50c4762a1bSJed Brown         for (j=i-2; j<i+1; j++) {
51c4762a1bSJed Brown           if (j >= N) {
52*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSetValue(A,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES));
53*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSetValue(B,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES));
54c4762a1bSJed Brown           } else if (i > j) {
55*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSetValue(A,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES));
56*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSetValue(B,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES));
57c4762a1bSJed Brown           } else {
58*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSetValue(A,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES));
59*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSetValue(B,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES));
60c4762a1bSJed Brown           }
61c4762a1bSJed Brown         }
62*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES));
63*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSetValues(B,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES));
64c4762a1bSJed Brown       }
65c4762a1bSJed Brown     } else {
66c4762a1bSJed Brown       PetscInt  rows[2];
67c4762a1bSJed Brown       PetscBool test_offproc = PETSC_FALSE;
68c4762a1bSJed Brown 
69*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_offproc",&test_offproc,NULL));
70c4762a1bSJed Brown       if (test_offproc) {
71c4762a1bSJed Brown         const PetscInt *ranges;
72c4762a1bSJed Brown         PetscMPIInt    rank;
73c4762a1bSJed Brown 
74*5f80ce2aSJacob Faibussowitsch         CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
75*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetOwnershipRanges(A,&ranges));
76c4762a1bSJed Brown         rows[0] = ranges[(rank+1)%size];
77c4762a1bSJed Brown         rows[1] = ranges[(rank+1)%size + 1];
78c4762a1bSJed Brown       } else {
79*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetOwnershipRange(A,&rows[0],&rows[1]));
80c4762a1bSJed Brown       }
81c4762a1bSJed Brown       for (i=rows[0];i<rows[1];i++) {
82c4762a1bSJed Brown         PetscInt    cols[] = {0,1,2,3,4,5};
83c4762a1bSJed Brown         PetscScalar vals[] = {-1,1,-2,2,-3,3};
84c4762a1bSJed Brown 
85*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES));
86*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSetValues(B,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES));
87c4762a1bSJed Brown       }
88c4762a1bSJed Brown     }
89c4762a1bSJed Brown     /* MAT_FLUSH_ASSEMBLY currently not supported */
90*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
91*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
92*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
93*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
94c4762a1bSJed Brown 
95c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX)
96c4762a1bSJed Brown     /* make the matrix imaginary */
97*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatScale(A,PETSC_i));
98*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatScale(B,PETSC_i));
99c4762a1bSJed Brown #endif
100c4762a1bSJed Brown 
101c4762a1bSJed Brown     /* MatAXPY further exercises MatSetValues_HYPRE */
102*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAXPY(B,-1.,A,DIFFERENT_NONZERO_PATTERN));
103*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(B,MATMPIAIJ,MAT_INITIAL_MATRIX,&C));
104*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(C,NORM_INFINITY,&err));
10554c59aa7SJacob Faibussowitsch     PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatSetValues %g",err);
106*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&B));
107*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&C));
108c4762a1bSJed Brown   } else {
109c4762a1bSJed Brown     PetscViewer viewer;
110c4762a1bSJed Brown 
111*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&viewer));
112*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetFromOptions(A));
113*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatLoad(A,viewer));
114*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerDestroy(&viewer));
115*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetSize(A,&M,&N));
116c4762a1bSJed Brown   }
117c4762a1bSJed Brown 
118c4762a1bSJed Brown   /* check conversion routines */
119*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B));
120*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(A,MATHYPRE,MAT_REUSE_MATRIX,&B));
121*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultEqual(B,A,4,&flg));
12254c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat HYPRE");
123*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(B,MATIS,MAT_INITIAL_MATRIX,&D));
124*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(B,MATIS,MAT_REUSE_MATRIX,&D));
125*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultEqual(D,A,4,&flg));
12654c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS");
127*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&C));
128*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(B,MATAIJ,MAT_REUSE_MATRIX,&C));
129*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultEqual(C,A,4,&flg));
13054c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ");
131*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN));
132*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(C,NORM_INFINITY,&err));
13354c59aa7SJacob Faibussowitsch   PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ %g",err);
134*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&C));
135*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(D,MATAIJ,MAT_INITIAL_MATRIX,&C));
136*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN));
137*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(C,NORM_INFINITY,&err));
13854c59aa7SJacob Faibussowitsch   PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS %g",err);
139*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&C));
140*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&D));
141c4762a1bSJed Brown 
142c4762a1bSJed Brown   /* check MatCreateFromParCSR */
143*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatHYPREGetParCSR(B,&parcsr));
144*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateFromParCSR(parcsr,MATAIJ,PETSC_COPY_VALUES,&D));
145*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&D));
146*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateFromParCSR(parcsr,MATHYPRE,PETSC_USE_POINTER,&C));
147c4762a1bSJed Brown 
148c4762a1bSJed Brown   /* check MatMult operations */
149*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultEqual(A,B,4,&flg));
15054c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult B");
151*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultEqual(A,C,4,&flg));
15254c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult C");
153*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultAddEqual(A,B,4,&flg));
15454c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd B");
155*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultAddEqual(A,C,4,&flg));
15654c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd C");
157*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTransposeEqual(A,B,4,&flg));
15854c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose B");
159*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTransposeEqual(A,C,4,&flg));
16054c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose C");
161*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTransposeAddEqual(A,B,4,&flg));
16254c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd B");
163*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTransposeAddEqual(A,C,4,&flg));
16454c59aa7SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd C");
165c4762a1bSJed Brown 
166c4762a1bSJed Brown   /* check PtAP */
167c4762a1bSJed Brown   if (testptap && M == N) {
168c4762a1bSJed Brown     Mat pP,hP;
169c4762a1bSJed Brown 
170c4762a1bSJed Brown     /* PETSc MatPtAP -> output is a MatAIJ
171c4762a1bSJed Brown        It uses HYPRE functions when -matptap_via hypre is specified at command line */
172*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAP(A,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pP));
173*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAP(A,A,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pP));
174*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(pP,NORM_INFINITY,&norm));
175*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAPMultEqual(A,A,pP,10,&flg));
17654c59aa7SJacob Faibussowitsch     PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_MatAIJ");
177c4762a1bSJed Brown 
178c4762a1bSJed Brown     /* MatPtAP_HYPRE_HYPRE -> output is a MatHYPRE */
179*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAP(C,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP));
180*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAP(C,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP));
181*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAPMultEqual(C,B,hP,10,&flg));
18254c59aa7SJacob Faibussowitsch     PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_HYPRE_HYPRE");
183c20d7725SJed Brown 
184c20d7725SJed Brown     /* Test MatAXPY_Basic() */
185*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAXPY(hP,-1.,pP,DIFFERENT_NONZERO_PATTERN));
186*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatHasOperation(hP,MATOP_NORM,&flg));
187c4762a1bSJed Brown     if (!flg) { /* TODO add MatNorm_HYPRE */
188*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(hP,MATAIJ,MAT_INPLACE_MATRIX,&hP));
189c4762a1bSJed Brown     }
190*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(hP,NORM_INFINITY,&err));
1912c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err/norm > PETSC_SMALL,PetscObjectComm((PetscObject)hP),PETSC_ERR_PLIB,"Error MatPtAP %g %g",err,norm);
192*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&pP));
193*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&hP));
194c4762a1bSJed Brown 
195c4762a1bSJed Brown     /* MatPtAP_AIJ_HYPRE -> output can be decided at runtime with -matptap_hypre_outtype */
196*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP));
197*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP));
198*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatPtAPMultEqual(A,B,hP,10,&flg));
19954c59aa7SJacob Faibussowitsch     PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_AIJ_HYPRE");
200*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&hP));
201c4762a1bSJed Brown   }
202*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&C));
203*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&B));
204c4762a1bSJed Brown 
205c4762a1bSJed Brown   /* check MatMatMult */
206c4762a1bSJed Brown   if (testmatmatmult) {
207*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatTranspose(A,MAT_INITIAL_MATRIX,&B));
208*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&C));
209*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(B,MATHYPRE,MAT_INITIAL_MATRIX,&D));
210c4762a1bSJed Brown 
211c4762a1bSJed Brown     /* PETSc MatMatMult -> output is a MatAIJ
212c4762a1bSJed Brown        It uses HYPRE functions when -matmatmult_via hypre is specified at command line */
213*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pAB));
214*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pAB));
215*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(pAB,NORM_INFINITY,&norm));
216*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMultEqual(A,B,pAB,10,&flg));
21754c59aa7SJacob Faibussowitsch     PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult_AIJ_AIJ");
218c4762a1bSJed Brown 
219c4762a1bSJed Brown     /* MatMatMult_HYPRE_HYPRE -> output is a MatHYPRE */
220*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(C,D,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CD));
221*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(C,D,MAT_REUSE_MATRIX,PETSC_DEFAULT,&CD));
222*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMultEqual(C,D,CD,10,&flg));
22354c59aa7SJacob Faibussowitsch     PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult_HYPRE_HYPRE");
224c20d7725SJed Brown 
225c20d7725SJed Brown     /* Test MatAXPY_Basic() */
226*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAXPY(CD,-1.,pAB,DIFFERENT_NONZERO_PATTERN));
227c20d7725SJed Brown 
228*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatHasOperation(CD,MATOP_NORM,&flg));
229c4762a1bSJed Brown     if (!flg) { /* TODO add MatNorm_HYPRE */
230*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(CD,MATAIJ,MAT_INPLACE_MATRIX,&CD));
231c4762a1bSJed Brown     }
232*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(CD,NORM_INFINITY,&err));
23354c59aa7SJacob Faibussowitsch     PetscCheck((err/norm) <= PETSC_SMALL,PetscObjectComm((PetscObject)CD),PETSC_ERR_PLIB,"Error MatMatMult %g %g",err,norm);
234c20d7725SJed Brown 
235*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&C));
236*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
237*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&pAB));
238*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&CD));
239c4762a1bSJed Brown 
240c4762a1bSJed Brown     /* When configured with HYPRE, MatMatMatMult is available for the triplet transpose(aij)-aij-aij */
241*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateTranspose(A,&C));
242*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMatMult(C,A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CAB));
243*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&C));
244*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatTranspose(A,MAT_INITIAL_MATRIX,&C));
245*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(C,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D));
246*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&C));
247*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(D,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C));
248*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(C,NORM_INFINITY,&norm));
249*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAXPY(C,-1.,CAB,DIFFERENT_NONZERO_PATTERN));
250*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(C,NORM_INFINITY,&err));
25154c59aa7SJacob Faibussowitsch     PetscCheck((err/norm) <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMatMatMult %g %g",err,norm);
252*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&C));
253*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
254*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&CAB));
255*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&B));
256c4762a1bSJed Brown   }
257c4762a1bSJed Brown 
258c4762a1bSJed Brown   /* Check MatView */
259*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(A,NULL,"-view_A"));
260*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B));
261*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(B,NULL,"-view_B"));
262c4762a1bSJed Brown 
263c4762a1bSJed Brown   /* Check MatDuplicate/MatCopy */
264c4762a1bSJed Brown   for (j=0;j<3;j++) {
265c4762a1bSJed Brown     MatDuplicateOption dop;
266c4762a1bSJed Brown 
267c4762a1bSJed Brown     dop = MAT_COPY_VALUES;
268c4762a1bSJed Brown     if (j==1) dop = MAT_DO_NOT_COPY_VALUES;
269c4762a1bSJed Brown     if (j==2) dop = MAT_SHARE_NONZERO_PATTERN;
270c4762a1bSJed Brown 
271c4762a1bSJed Brown     for (i=0;i<3;i++) {
272c4762a1bSJed Brown       MatStructure str;
273c4762a1bSJed Brown 
274*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Dup/Copy tests: %" PetscInt_FMT " %" PetscInt_FMT "\n",j,i));
275c4762a1bSJed Brown 
276c4762a1bSJed Brown       str = DIFFERENT_NONZERO_PATTERN;
277c4762a1bSJed Brown       if (i==1) str = SAME_NONZERO_PATTERN;
278c4762a1bSJed Brown       if (i==2) str = SUBSET_NONZERO_PATTERN;
279c4762a1bSJed Brown 
280*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(A,dop,&C));
281*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(B,dop,&D));
282c4762a1bSJed Brown       if (dop != MAT_COPY_VALUES) {
283*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCopy(A,C,str));
284*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCopy(B,D,str));
285c4762a1bSJed Brown       }
286c4762a1bSJed Brown       /* AXPY with AIJ and HYPRE */
287*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(C,-1.0,D,str));
288*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(C,NORM_INFINITY,&err));
289c4762a1bSJed Brown       if (err > PETSC_SMALL) {
290*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(A,NULL,"-view_duplicate_diff"));
291*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(B,NULL,"-view_duplicate_diff"));
292*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(C,NULL,"-view_duplicate_diff"));
29398921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 1 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i);
294c4762a1bSJed Brown       }
295c4762a1bSJed Brown       /* AXPY with HYPRE and HYPRE */
296*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(D,-1.0,B,str));
297c4762a1bSJed Brown       if (err > PETSC_SMALL) {
298*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(A,NULL,"-view_duplicate_diff"));
299*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(B,NULL,"-view_duplicate_diff"));
300*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(D,NULL,"-view_duplicate_diff"));
30198921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 2 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i);
302c4762a1bSJed Brown       }
303c4762a1bSJed Brown       /* Copy from HYPRE to AIJ */
304*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCopy(B,C,str));
305c4762a1bSJed Brown       /* Copy from AIJ to HYPRE */
306*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCopy(A,D,str));
307c4762a1bSJed Brown       /* AXPY with HYPRE and AIJ */
308*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(D,-1.0,C,str));
309*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatHasOperation(D,MATOP_NORM,&flg));
310c4762a1bSJed Brown       if (!flg) { /* TODO add MatNorm_HYPRE */
311*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatConvert(D,MATAIJ,MAT_INPLACE_MATRIX,&D));
312c4762a1bSJed Brown       }
313*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(D,NORM_INFINITY,&err));
314c4762a1bSJed Brown       if (err > PETSC_SMALL) {
315*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(A,NULL,"-view_duplicate_diff"));
316*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(C,NULL,"-view_duplicate_diff"));
317*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatViewFromOptions(D,NULL,"-view_duplicate_diff"));
31898921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 3 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i);
319c4762a1bSJed Brown       }
320*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&C));
321*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&D));
322c4762a1bSJed Brown     }
323c4762a1bSJed Brown   }
324*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&B));
325c4762a1bSJed Brown 
326*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatHasCongruentLayouts(A,&flg));
327c4762a1bSJed Brown   if (flg) {
328c4762a1bSJed Brown     Vec y,y2;
329c4762a1bSJed Brown 
330*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B));
331*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateVecs(A,NULL,&y));
332*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateVecs(B,NULL,&y2));
333*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetDiagonal(A,y));
334*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetDiagonal(B,y2));
335*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecAXPY(y2,-1.0,y));
336*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(y2,NORM_INFINITY,&err));
337c4762a1bSJed Brown     if (err > PETSC_SMALL) {
338*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecViewFromOptions(y,NULL,"-view_diagonal_diff"));
339*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecViewFromOptions(y2,NULL,"-view_diagonal_diff"));
34098921bdaSJacob Faibussowitsch       SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatGetDiagonal %g",err);
341c4762a1bSJed Brown     }
342*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&B));
343*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&y));
344*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecDestroy(&y2));
345c4762a1bSJed Brown   }
346c4762a1bSJed Brown 
347*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&A));
348c4762a1bSJed Brown 
349c4762a1bSJed Brown   ierr = PetscFinalize();
350c4762a1bSJed Brown   return ierr;
351c4762a1bSJed Brown }
352c4762a1bSJed Brown 
353c4762a1bSJed Brown /*TEST
354c4762a1bSJed Brown 
355c4762a1bSJed Brown    build:
356c4762a1bSJed Brown       requires: hypre
357c4762a1bSJed Brown 
358c4762a1bSJed Brown    test:
359263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
360c4762a1bSJed Brown       suffix: 1
361c4762a1bSJed Brown       args: -N 11 -M 11
362c4762a1bSJed Brown       output_file: output/ex115_1.out
363c4762a1bSJed Brown 
364c4762a1bSJed Brown    test:
365263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
366c4762a1bSJed Brown       suffix: 2
367c4762a1bSJed Brown       nsize: 3
368c4762a1bSJed Brown       args: -N 13 -M 13 -matmatmult_via hypre
369c4762a1bSJed Brown       output_file: output/ex115_1.out
370c4762a1bSJed Brown 
371c4762a1bSJed Brown    test:
372263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
373c4762a1bSJed Brown       suffix: 3
374c4762a1bSJed Brown       nsize: 4
375c4762a1bSJed Brown       args: -M 13 -N 7 -matmatmult_via hypre
376c4762a1bSJed Brown       output_file: output/ex115_1.out
377c4762a1bSJed Brown 
378c4762a1bSJed Brown    test:
379263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
380c4762a1bSJed Brown       suffix: 4
381c4762a1bSJed Brown       nsize: 2
382c4762a1bSJed Brown       args: -M 12 -N 19
383c4762a1bSJed Brown       output_file: output/ex115_1.out
384c4762a1bSJed Brown 
385c4762a1bSJed Brown    test:
386263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
387c4762a1bSJed Brown       suffix: 5
388c4762a1bSJed Brown       nsize: 3
389c4762a1bSJed Brown       args: -M 13 -N 13 -matptap_via hypre -matptap_hypre_outtype hypre
390c4762a1bSJed Brown       output_file: output/ex115_1.out
391c4762a1bSJed Brown 
392c4762a1bSJed Brown    test:
393263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
394c4762a1bSJed Brown       suffix: 6
395c4762a1bSJed Brown       nsize: 3
396c4762a1bSJed Brown       args: -M 12 -N 19 -test_offproc
397c4762a1bSJed Brown       output_file: output/ex115_1.out
398c4762a1bSJed Brown 
399c4762a1bSJed Brown    test:
400263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
401c4762a1bSJed Brown       suffix: 7
402c4762a1bSJed Brown       nsize: 3
403c4762a1bSJed Brown       args: -M 19 -N 12 -test_offproc -view_B ::ascii_info_detail
404c4762a1bSJed Brown       output_file: output/ex115_7.out
405c4762a1bSJed Brown 
406c4762a1bSJed Brown    test:
407263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
408c4762a1bSJed Brown       suffix: 8
409c4762a1bSJed Brown       nsize: 3
410c4762a1bSJed Brown       args: -M 1 -N 12 -test_offproc
411c4762a1bSJed Brown       output_file: output/ex115_1.out
412c4762a1bSJed Brown 
413c4762a1bSJed Brown    test:
414263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
415c4762a1bSJed Brown       suffix: 9
416c4762a1bSJed Brown       nsize: 3
417c4762a1bSJed Brown       args: -M 1 -N 2 -test_offproc
418c4762a1bSJed Brown       output_file: output/ex115_1.out
419c4762a1bSJed Brown 
420c4762a1bSJed Brown TEST*/
421