xref: /petsc/src/mat/tests/ex23.c (revision e432b41dc02bf0734625665660df6f79e3b54e76)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Tests the use of interface functions for MATIS matrices.\n\
3c4762a1bSJed Brown This example tests: MatZeroRows(), MatZeroRowsLocal(), MatView(), MatDuplicate(),\n\
4c4762a1bSJed Brown MatCopy(), MatCreateSubMatrix(), MatGetLocalSubMatrix(), MatAXPY(), MatShift()\n\
5c4762a1bSJed Brown MatDiagonalSet(), MatTranspose() and MatPtAP(). It also tests some\n\
6c4762a1bSJed Brown conversion routines.\n";
7c4762a1bSJed Brown 
8c4762a1bSJed Brown #include <petscmat.h>
9c4762a1bSJed Brown 
10c4762a1bSJed Brown PetscErrorCode TestMatZeroRows(Mat,Mat,PetscBool,IS,PetscScalar);
11c4762a1bSJed Brown PetscErrorCode CheckMat(Mat,Mat,PetscBool,const char*);
12c4762a1bSJed Brown 
13c4762a1bSJed Brown int main(int argc,char **args)
14c4762a1bSJed Brown {
15c4762a1bSJed Brown   Mat                    A,B,A2,B2,T;
16c4762a1bSJed Brown   Mat                    Aee,Aeo,Aoe,Aoo;
17c4762a1bSJed Brown   Mat                    *mats;
18c4762a1bSJed Brown   Vec                    x,y;
19c4762a1bSJed Brown   MatInfo                info;
20c4762a1bSJed Brown   ISLocalToGlobalMapping cmap,rmap;
21c4762a1bSJed Brown   IS                     is,is2,reven,rodd,ceven,codd;
22c4762a1bSJed Brown   IS                     *rows,*cols;
23c4762a1bSJed Brown   MatType                lmtype;
24c4762a1bSJed Brown   PetscScalar            diag = 2.;
25*e432b41dSStefano Zampini   PetscInt               n,m,i,lm,ln;
26c4762a1bSJed Brown   PetscInt               rst,ren,cst,cen,nr,nc;
27c4762a1bSJed Brown   PetscMPIInt            rank,size;
28c4762a1bSJed Brown   PetscBool              testT,squaretest,isaij;
29*e432b41dSStefano Zampini   PetscBool              permute = PETSC_FALSE, negmap = PETSC_FALSE, repmap = PETSC_FALSE;
30*e432b41dSStefano Zampini   PetscBool              diffmap = PETSC_TRUE, symmetric = PETSC_FALSE, issymmetric;
31c4762a1bSJed Brown   PetscErrorCode         ierr;
32c4762a1bSJed Brown 
33c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
34ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
35ffc4695bSBarry Smith   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr);
36c4762a1bSJed Brown   m = n = 2*size;
37c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-symmetric",&symmetric,NULL);CHKERRQ(ierr);
38c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr);
39c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr);
40*e432b41dSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-negmap",&negmap,NULL);CHKERRQ(ierr);
41*e432b41dSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-repmap",&repmap,NULL);CHKERRQ(ierr);
42*e432b41dSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-permmap",&permute,NULL);CHKERRQ(ierr);
43*e432b41dSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-diffmap",&diffmap,NULL);CHKERRQ(ierr);
442c71b3e2SJacob Faibussowitsch   PetscCheckFalse(size > 1 && m < 4,PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Number of rows should be larger or equal 4 for parallel runs");
452c71b3e2SJacob Faibussowitsch   PetscCheckFalse(size == 1 && m < 2,PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Number of rows should be larger or equal 2 for uniprocessor runs");
462c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n < 2,PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Number of cols should be larger or equal 2");
47c4762a1bSJed Brown 
48c4762a1bSJed Brown   /* create a MATIS matrix */
49c4762a1bSJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
50c4762a1bSJed Brown   ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr);
51c4762a1bSJed Brown   ierr = MatSetType(A,MATIS);CHKERRQ(ierr);
52c4762a1bSJed Brown   ierr = MatSetFromOptions(A);CHKERRQ(ierr);
53*e432b41dSStefano Zampini   if (!negmap && !repmap) {
54fc989267SStefano Zampini     /* This is not the proper setting for MATIS for finite elements, it is just used to test the routines
55fc989267SStefano Zampini        Here we use a one-to-one correspondence between local row/column spaces and global row/column spaces
56fc989267SStefano Zampini        Equivalent to passing NULL for the mapping */
57c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,n,0,1,&is);CHKERRQ(ierr);
58*e432b41dSStefano Zampini   } else if (negmap && !repmap) { /* non repeated but with negative indices */
59*e432b41dSStefano Zampini     ierr = ISCreateStride(PETSC_COMM_WORLD,n+2,-2,1,&is);CHKERRQ(ierr);
60*e432b41dSStefano Zampini   } else if (!negmap && repmap) { /* non negative but repeated indices */
61*e432b41dSStefano Zampini     IS isl[2];
62*e432b41dSStefano Zampini 
63*e432b41dSStefano Zampini     ierr = ISCreateStride(PETSC_COMM_WORLD,n,0,1,&isl[0]);CHKERRQ(ierr);
64*e432b41dSStefano Zampini     ierr = ISCreateStride(PETSC_COMM_WORLD,n,n-1,-1,&isl[1]);CHKERRQ(ierr);
65*e432b41dSStefano Zampini     ierr = ISConcatenate(PETSC_COMM_WORLD,2,isl,&is);CHKERRQ(ierr);
66*e432b41dSStefano Zampini     ierr = ISDestroy(&isl[0]);CHKERRQ(ierr);
67*e432b41dSStefano Zampini     ierr = ISDestroy(&isl[1]);CHKERRQ(ierr);
68*e432b41dSStefano Zampini   } else { /* negative and repeated indices */
69*e432b41dSStefano Zampini     IS isl[2];
70*e432b41dSStefano Zampini 
71*e432b41dSStefano Zampini     ierr = ISCreateStride(PETSC_COMM_WORLD,n+1,-1,1,&isl[0]);CHKERRQ(ierr);
72*e432b41dSStefano Zampini     ierr = ISCreateStride(PETSC_COMM_WORLD,n+1,n-1,-1,&isl[1]);CHKERRQ(ierr);
73*e432b41dSStefano Zampini     ierr = ISConcatenate(PETSC_COMM_WORLD,2,isl,&is);CHKERRQ(ierr);
74*e432b41dSStefano Zampini     ierr = ISDestroy(&isl[0]);CHKERRQ(ierr);
75*e432b41dSStefano Zampini     ierr = ISDestroy(&isl[1]);CHKERRQ(ierr);
76*e432b41dSStefano Zampini   }
77c4762a1bSJed Brown   ierr = ISLocalToGlobalMappingCreateIS(is,&cmap);CHKERRQ(ierr);
78c4762a1bSJed Brown   ierr = ISDestroy(&is);CHKERRQ(ierr);
79c4762a1bSJed Brown 
80*e432b41dSStefano Zampini   if (m != n || diffmap) {
81c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,m,permute ? m-1 : 0,permute ? -1 : 1,&is);CHKERRQ(ierr);
82c4762a1bSJed Brown     ierr = ISLocalToGlobalMappingCreateIS(is,&rmap);CHKERRQ(ierr);
83c4762a1bSJed Brown     ierr = ISDestroy(&is);CHKERRQ(ierr);
84c4762a1bSJed Brown   } else {
85c4762a1bSJed Brown     ierr = PetscObjectReference((PetscObject)cmap);CHKERRQ(ierr);
86c4762a1bSJed Brown     rmap = cmap;
87c4762a1bSJed Brown   }
88*e432b41dSStefano Zampini 
89c4762a1bSJed Brown   ierr = MatSetLocalToGlobalMapping(A,rmap,cmap);CHKERRQ(ierr);
90c4762a1bSJed Brown   ierr = MatISStoreL2L(A,PETSC_FALSE);CHKERRQ(ierr);
91*e432b41dSStefano Zampini   ierr = MatISSetPreallocation(A,3,NULL,3,NULL);CHKERRQ(ierr);
92*e432b41dSStefano Zampini   ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,(PetscBool)!(repmap || negmap));CHKERRQ(ierr); /* I do not want to precompute the pattern */
93*e432b41dSStefano Zampini   ierr = ISLocalToGlobalMappingGetSize(rmap,&lm);CHKERRQ(ierr);
94*e432b41dSStefano Zampini   ierr = ISLocalToGlobalMappingGetSize(cmap,&ln);CHKERRQ(ierr);
95*e432b41dSStefano Zampini   for (i=0; i<lm; i++) {
96c4762a1bSJed Brown     PetscScalar v[3];
97c4762a1bSJed Brown     PetscInt    cols[3];
98c4762a1bSJed Brown 
99c4762a1bSJed Brown     cols[0] = (i-1+n)%n;
100c4762a1bSJed Brown     cols[1] = i%n;
101c4762a1bSJed Brown     cols[2] = (i+1)%n;
102c4762a1bSJed Brown     v[0] = -1.*(symmetric ? PetscMin(i+1,cols[0]+1) : i+1);
103c4762a1bSJed Brown     v[1] =  2.*(symmetric ? PetscMin(i+1,cols[1]+1) : i+1);
104c4762a1bSJed Brown     v[2] = -1.*(symmetric ? PetscMin(i+1,cols[2]+1) : i+1);
105*e432b41dSStefano Zampini     ierr = ISGlobalToLocalMappingApply(cmap,IS_GTOLM_MASK,3,cols,NULL,cols);CHKERRQ(ierr);
106c4762a1bSJed Brown     ierr = MatSetValuesLocal(A,1,&i,3,cols,v,ADD_VALUES);CHKERRQ(ierr);
107c4762a1bSJed Brown   }
108c4762a1bSJed Brown   ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
109c4762a1bSJed Brown   ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
110c4762a1bSJed Brown 
111*e432b41dSStefano Zampini   /* activate tests for square matrices with same maps only */
112*e432b41dSStefano Zampini   ierr = MatHasCongruentLayouts(A,&squaretest);CHKERRQ(ierr);
113*e432b41dSStefano Zampini   if (squaretest && rmap != cmap) {
114*e432b41dSStefano Zampini     PetscInt nr, nc;
115*e432b41dSStefano Zampini 
116*e432b41dSStefano Zampini     ierr = ISLocalToGlobalMappingGetSize(rmap,&nr);CHKERRQ(ierr);
117*e432b41dSStefano Zampini     ierr = ISLocalToGlobalMappingGetSize(cmap,&nc);CHKERRQ(ierr);
118*e432b41dSStefano Zampini     if (nr != nc) squaretest = PETSC_FALSE;
119*e432b41dSStefano Zampini     else {
120*e432b41dSStefano Zampini       const PetscInt *idxs1,*idxs2;
121*e432b41dSStefano Zampini 
122*e432b41dSStefano Zampini       ierr = ISLocalToGlobalMappingGetIndices(rmap,&idxs1);CHKERRQ(ierr);
123*e432b41dSStefano Zampini       ierr = ISLocalToGlobalMappingGetIndices(cmap,&idxs2);CHKERRQ(ierr);
124*e432b41dSStefano Zampini       ierr = PetscArraycmp(idxs1,idxs2,nr,&squaretest);CHKERRQ(ierr);
125*e432b41dSStefano Zampini       ierr = ISLocalToGlobalMappingRestoreIndices(rmap,&idxs1);CHKERRQ(ierr);
126*e432b41dSStefano Zampini       ierr = ISLocalToGlobalMappingRestoreIndices(cmap,&idxs2);CHKERRQ(ierr);
127*e432b41dSStefano Zampini     }
128*e432b41dSStefano Zampini     ierr = MPIU_Allreduce(MPI_IN_PLACE,&squaretest,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr);
129*e432b41dSStefano Zampini   }
130*e432b41dSStefano Zampini 
131*e432b41dSStefano Zampini   /* test MatISGetLocalMat */
132c4762a1bSJed Brown   ierr = MatISGetLocalMat(A,&B);CHKERRQ(ierr);
133c4762a1bSJed Brown   ierr = MatGetType(B,&lmtype);CHKERRQ(ierr);
134c4762a1bSJed Brown 
135c4762a1bSJed Brown   /* test MatGetInfo */
136c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatGetInfo\n");CHKERRQ(ierr);
137c4762a1bSJed Brown   ierr = MatGetInfo(A,MAT_LOCAL,&info);CHKERRQ(ierr);
138c4762a1bSJed Brown   ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1398fffc762SJacob Faibussowitsch   ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"Process  %2d: %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",PetscGlobalRank,(PetscInt)info.nz_used,
140c4762a1bSJed Brown                                             (PetscInt)info.nz_allocated,(PetscInt)info.nz_unneeded,(PetscInt)info.assemblies,(PetscInt)info.mallocs);CHKERRQ(ierr);
141c4762a1bSJed Brown   ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
142c4762a1bSJed Brown   ierr = MatGetInfo(A,MAT_GLOBAL_MAX,&info);CHKERRQ(ierr);
1438fffc762SJacob Faibussowitsch   ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"GlobalMax  : %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",(PetscInt)info.nz_used,
144c4762a1bSJed Brown                                 (PetscInt)info.nz_allocated,(PetscInt)info.nz_unneeded,(PetscInt)info.assemblies,(PetscInt)info.mallocs);CHKERRQ(ierr);
145c4762a1bSJed Brown   ierr = MatGetInfo(A,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1468fffc762SJacob Faibussowitsch   ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"GlobalSum  : %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",(PetscInt)info.nz_used,
147c4762a1bSJed Brown                                 (PetscInt)info.nz_allocated,(PetscInt)info.nz_unneeded,(PetscInt)info.assemblies,(PetscInt)info.mallocs);CHKERRQ(ierr);
148c4762a1bSJed Brown 
149*e432b41dSStefano Zampini   /* test MatIsSymmetric */
150*e432b41dSStefano Zampini   ierr = MatIsSymmetric(A,0.0,&issymmetric);CHKERRQ(ierr);
151*e432b41dSStefano Zampini   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatIsSymmetric: %d\n",issymmetric);CHKERRQ(ierr);
152c4762a1bSJed Brown 
153c4762a1bSJed Brown   /* Create a MPIAIJ matrix, same as A */
154c4762a1bSJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr);
155c4762a1bSJed Brown   ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr);
156c4762a1bSJed Brown   ierr = MatSetType(B,MATAIJ);CHKERRQ(ierr);
157c4762a1bSJed Brown   ierr = MatSetFromOptions(B);CHKERRQ(ierr);
158c4762a1bSJed Brown   ierr = MatSetUp(B);CHKERRQ(ierr);
159c4762a1bSJed Brown   ierr = MatSetLocalToGlobalMapping(B,rmap,cmap);CHKERRQ(ierr);
160c4762a1bSJed Brown   ierr = MatMPIAIJSetPreallocation(B,3,NULL,3,NULL);CHKERRQ(ierr);
161c4762a1bSJed Brown   ierr = MatMPIBAIJSetPreallocation(B,1,3,NULL,3,NULL);CHKERRQ(ierr);
162c4762a1bSJed Brown #if defined(PETSC_HAVE_HYPRE)
163c4762a1bSJed Brown   ierr = MatHYPRESetPreallocation(B,3,NULL,3,NULL);CHKERRQ(ierr);
164c4762a1bSJed Brown #endif
165c4762a1bSJed Brown   ierr = MatISSetPreallocation(B,3,NULL,3,NULL);CHKERRQ(ierr);
166*e432b41dSStefano Zampini   ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,(PetscBool)!(repmap || negmap));CHKERRQ(ierr); /* I do not want to precompute the pattern */
167*e432b41dSStefano Zampini   for (i=0; i<lm; i++) {
168c4762a1bSJed Brown     PetscScalar v[3];
169c4762a1bSJed Brown     PetscInt    cols[3];
170c4762a1bSJed Brown 
171c4762a1bSJed Brown     cols[0] = (i-1+n)%n;
172c4762a1bSJed Brown     cols[1] = i%n;
173c4762a1bSJed Brown     cols[2] = (i+1)%n;
174c4762a1bSJed Brown     v[0] = -1.*(symmetric ? PetscMin(i+1,cols[0]+1) : i+1);
175c4762a1bSJed Brown     v[1] =  2.*(symmetric ? PetscMin(i+1,cols[1]+1) : i+1);
176c4762a1bSJed Brown     v[2] = -1.*(symmetric ? PetscMin(i+1,cols[2]+1) : i+1);
177*e432b41dSStefano Zampini     ierr = ISGlobalToLocalMappingApply(cmap,IS_GTOLM_MASK,3,cols,NULL,cols);CHKERRQ(ierr);
178c4762a1bSJed Brown     ierr = MatSetValuesLocal(B,1,&i,3,cols,v,ADD_VALUES);CHKERRQ(ierr);
179c4762a1bSJed Brown   }
180c4762a1bSJed Brown   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
181c4762a1bSJed Brown   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
182*e432b41dSStefano Zampini 
183*e432b41dSStefano Zampini   /* test MatView */
184*e432b41dSStefano Zampini   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatView\n");CHKERRQ(ierr);
185*e432b41dSStefano Zampini   ierr = MatView(A,NULL);CHKERRQ(ierr);
186*e432b41dSStefano Zampini   ierr = MatView(B,NULL);CHKERRQ(ierr);
187c4762a1bSJed Brown 
188c4762a1bSJed Brown   /* test CheckMat */
189c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test CheckMat\n");CHKERRQ(ierr);
190c4762a1bSJed Brown   ierr = CheckMat(A,B,PETSC_FALSE,"CheckMat");CHKERRQ(ierr);
191c4762a1bSJed Brown 
192c4762a1bSJed Brown   /* test MatDuplicate and MatAXPY */
193c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatDuplicate and MatAXPY\n");CHKERRQ(ierr);
194c4762a1bSJed Brown   ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
195c4762a1bSJed Brown   ierr = CheckMat(A,A2,PETSC_FALSE,"MatDuplicate and MatAXPY");CHKERRQ(ierr);
196c4762a1bSJed Brown 
197c4762a1bSJed Brown   /* test MatConvert */
198c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatConvert_IS_XAIJ\n");CHKERRQ(ierr);
199c4762a1bSJed Brown   ierr = MatConvert(A2,MATAIJ,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr);
200c4762a1bSJed Brown   ierr = CheckMat(B,B2,PETSC_TRUE,"MatConvert_IS_XAIJ MAT_INITIAL_MATRIX");CHKERRQ(ierr);
201c4762a1bSJed Brown   ierr = MatConvert(A2,MATAIJ,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr);
202c4762a1bSJed Brown   ierr = CheckMat(B,B2,PETSC_TRUE,"MatConvert_IS_XAIJ MAT_REUSE_MATRIX");CHKERRQ(ierr);
203c4762a1bSJed Brown   ierr = MatConvert(A2,MATAIJ,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr);
204c4762a1bSJed Brown   ierr = CheckMat(B,A2,PETSC_TRUE,"MatConvert_IS_XAIJ MAT_INPLACE_MATRIX");CHKERRQ(ierr);
205c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
206c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
207c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatConvert_XAIJ_IS\n");CHKERRQ(ierr);
208c4762a1bSJed Brown   ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
209c4762a1bSJed Brown   ierr = MatConvert(B2,MATIS,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr);
210c4762a1bSJed Brown   ierr = CheckMat(A,A2,PETSC_TRUE,"MatConvert_XAIJ_IS MAT_INITIAL_MATRIX");CHKERRQ(ierr);
211c4762a1bSJed Brown   ierr = MatConvert(B2,MATIS,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr);
212c4762a1bSJed Brown   ierr = CheckMat(A,A2,PETSC_TRUE,"MatConvert_XAIJ_IS MAT_REUSE_MATRIX");CHKERRQ(ierr);
213c4762a1bSJed Brown   ierr = MatConvert(B2,MATIS,MAT_INPLACE_MATRIX,&B2);CHKERRQ(ierr);
214c4762a1bSJed Brown   ierr = CheckMat(A,B2,PETSC_TRUE,"MatConvert_XAIJ_IS MAT_INPLACE_MATRIX");CHKERRQ(ierr);
215c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
216c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
217c4762a1bSJed Brown   ierr = PetscStrcmp(lmtype,MATSEQAIJ,&isaij);CHKERRQ(ierr);
218c4762a1bSJed Brown   if (size == 1 && isaij) { /* tests special code paths in MatConvert_IS_XAIJ */
219c4762a1bSJed Brown     PetscInt               ri, ci, rr[3] = {0,1,0}, cr[4] = {1,2,0,1}, rk[3] = {0,2,1}, ck[4] = {1,0,3,2};
220*e432b41dSStefano Zampini     ISLocalToGlobalMapping tcmap,trmap;
221c4762a1bSJed Brown 
222c4762a1bSJed Brown     for (ri = 0; ri < 2; ri++) {
223c4762a1bSJed Brown       PetscInt *r;
224c4762a1bSJed Brown 
225c4762a1bSJed Brown       r = (PetscInt*)(ri == 0 ? rr : rk);
226c4762a1bSJed Brown       for (ci = 0; ci < 2; ci++) {
227c4762a1bSJed Brown         PetscInt *c,rb,cb;
228c4762a1bSJed Brown 
229c4762a1bSJed Brown         c = (PetscInt*)(ci == 0 ? cr : ck);
230c4762a1bSJed Brown         for (rb = 1; rb < 4; rb++) {
231c4762a1bSJed Brown           ierr = ISCreateBlock(PETSC_COMM_SELF,rb,3,r,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
232*e432b41dSStefano Zampini           ierr = ISLocalToGlobalMappingCreateIS(is,&trmap);CHKERRQ(ierr);
233c4762a1bSJed Brown           ierr = ISDestroy(&is);CHKERRQ(ierr);
234c4762a1bSJed Brown           for (cb = 1; cb < 4; cb++) {
235c4762a1bSJed Brown             Mat  T,lT,T2;
236c4762a1bSJed Brown             char testname[256];
237c4762a1bSJed Brown 
2388fffc762SJacob Faibussowitsch             ierr = PetscSNPrintf(testname,sizeof(testname),"MatConvert_IS_XAIJ special case (%" PetscInt_FMT " %" PetscInt_FMT ", bs %" PetscInt_FMT " %" PetscInt_FMT ")",ri,ci,rb,cb);CHKERRQ(ierr);
239c4762a1bSJed Brown             ierr = PetscPrintf(PETSC_COMM_WORLD,"Test %s\n",testname);CHKERRQ(ierr);
240c4762a1bSJed Brown 
241c4762a1bSJed Brown             ierr = ISCreateBlock(PETSC_COMM_SELF,cb,4,c,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
242*e432b41dSStefano Zampini             ierr = ISLocalToGlobalMappingCreateIS(is,&tcmap);CHKERRQ(ierr);
243c4762a1bSJed Brown             ierr = ISDestroy(&is);CHKERRQ(ierr);
244c4762a1bSJed Brown 
245c4762a1bSJed Brown             ierr = MatCreate(PETSC_COMM_SELF,&T);CHKERRQ(ierr);
246c4762a1bSJed Brown             ierr = MatSetSizes(T,PETSC_DECIDE,PETSC_DECIDE,rb*3,cb*4);CHKERRQ(ierr);
247c4762a1bSJed Brown             ierr = MatSetType(T,MATIS);CHKERRQ(ierr);
248*e432b41dSStefano Zampini             ierr = MatSetLocalToGlobalMapping(T,trmap,tcmap);CHKERRQ(ierr);
249*e432b41dSStefano Zampini             ierr = ISLocalToGlobalMappingDestroy(&tcmap);CHKERRQ(ierr);
250c4762a1bSJed Brown             ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr);
251c4762a1bSJed Brown             ierr = MatSetType(lT,MATSEQAIJ);CHKERRQ(ierr);
252c4762a1bSJed Brown             ierr = MatSeqAIJSetPreallocation(lT,cb*4,NULL);CHKERRQ(ierr);
253c4762a1bSJed Brown             ierr = MatSetRandom(lT,NULL);CHKERRQ(ierr);
254c4762a1bSJed Brown             ierr = MatConvert(lT,lmtype,MAT_INPLACE_MATRIX,&lT);CHKERRQ(ierr);
255c4762a1bSJed Brown             ierr = MatISRestoreLocalMat(T,&lT);CHKERRQ(ierr);
256c4762a1bSJed Brown             ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
257c4762a1bSJed Brown             ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
258c4762a1bSJed Brown 
259c4762a1bSJed Brown             ierr = MatConvert(T,MATAIJ,MAT_INITIAL_MATRIX,&T2);CHKERRQ(ierr);
260c4762a1bSJed Brown             ierr = CheckMat(T,T2,PETSC_TRUE,"MAT_INITIAL_MATRIX");CHKERRQ(ierr);
261c4762a1bSJed Brown             ierr = MatConvert(T,MATAIJ,MAT_REUSE_MATRIX,&T2);CHKERRQ(ierr);
262c4762a1bSJed Brown             ierr = CheckMat(T,T2,PETSC_TRUE,"MAT_REUSE_MATRIX");CHKERRQ(ierr);
263c4762a1bSJed Brown             ierr = MatDestroy(&T2);CHKERRQ(ierr);
264c4762a1bSJed Brown             ierr = MatDuplicate(T,MAT_COPY_VALUES,&T2);CHKERRQ(ierr);
265c4762a1bSJed Brown             ierr = MatConvert(T2,MATAIJ,MAT_INPLACE_MATRIX,&T2);CHKERRQ(ierr);
266c4762a1bSJed Brown             ierr = CheckMat(T,T2,PETSC_TRUE,"MAT_INPLACE_MATRIX");CHKERRQ(ierr);
267c4762a1bSJed Brown             ierr = MatDestroy(&T);CHKERRQ(ierr);
268c4762a1bSJed Brown             ierr = MatDestroy(&T2);CHKERRQ(ierr);
269c4762a1bSJed Brown           }
270*e432b41dSStefano Zampini           ierr = ISLocalToGlobalMappingDestroy(&trmap);CHKERRQ(ierr);
271c4762a1bSJed Brown         }
272c4762a1bSJed Brown       }
273c4762a1bSJed Brown     }
274c4762a1bSJed Brown   }
275c4762a1bSJed Brown 
276c4762a1bSJed Brown   /* test MatDiagonalScale */
277c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatDiagonalScale\n");CHKERRQ(ierr);
278c4762a1bSJed Brown   ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
279c4762a1bSJed Brown   ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
280c4762a1bSJed Brown   ierr = MatCreateVecs(A,&x,&y);CHKERRQ(ierr);
281c4762a1bSJed Brown   ierr = VecSetRandom(x,NULL);CHKERRQ(ierr);
282*e432b41dSStefano Zampini   if (issymmetric) {
283c4762a1bSJed Brown     ierr = VecCopy(x,y);CHKERRQ(ierr);
284c4762a1bSJed Brown   } else {
285c4762a1bSJed Brown     ierr = VecSetRandom(y,NULL);CHKERRQ(ierr);
286c4762a1bSJed Brown     ierr = VecScale(y,8.);CHKERRQ(ierr);
287c4762a1bSJed Brown   }
288c4762a1bSJed Brown   ierr = MatDiagonalScale(A2,y,x);CHKERRQ(ierr);
289c4762a1bSJed Brown   ierr = MatDiagonalScale(B2,y,x);CHKERRQ(ierr);
290c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_FALSE,"MatDiagonalScale");CHKERRQ(ierr);
291c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
292c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
293c4762a1bSJed Brown   ierr = VecDestroy(&x);CHKERRQ(ierr);
294c4762a1bSJed Brown   ierr = VecDestroy(&y);CHKERRQ(ierr);
295c4762a1bSJed Brown 
296c4762a1bSJed Brown   /* test MatPtAP (A IS and B AIJ) */
297c4762a1bSJed Brown   if (isaij && m == n) {
298c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatPtAP\n");CHKERRQ(ierr);
299c4762a1bSJed Brown     ierr = MatISStoreL2L(A,PETSC_TRUE);CHKERRQ(ierr);
300c4762a1bSJed Brown     ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&A2);CHKERRQ(ierr);
301c4762a1bSJed Brown     ierr = MatPtAP(B,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B2);CHKERRQ(ierr);
302c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"MatPtAP MAT_INITIAL_MATRIX");CHKERRQ(ierr);
303c4762a1bSJed Brown     ierr = MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&A2);CHKERRQ(ierr);
304c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"MatPtAP MAT_REUSE_MATRIX");CHKERRQ(ierr);
305c4762a1bSJed Brown     ierr = MatDestroy(&A2);CHKERRQ(ierr);
306c4762a1bSJed Brown     ierr = MatDestroy(&B2);CHKERRQ(ierr);
307c4762a1bSJed Brown   }
308c4762a1bSJed Brown 
309c4762a1bSJed Brown   /* test MatGetLocalSubMatrix */
310c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatGetLocalSubMatrix\n");CHKERRQ(ierr);
311c4762a1bSJed Brown   ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&A2);CHKERRQ(ierr);
312*e432b41dSStefano Zampini   ierr = ISCreateStride(PETSC_COMM_SELF,lm/2+lm%2,0,2,&reven);CHKERRQ(ierr);
313*e432b41dSStefano Zampini   ierr = ISComplement(reven,0,lm,&rodd);CHKERRQ(ierr);
314*e432b41dSStefano Zampini   ierr = ISCreateStride(PETSC_COMM_SELF,ln/2+ln%2,0,2,&ceven);CHKERRQ(ierr);
315*e432b41dSStefano Zampini   ierr = ISComplement(ceven,0,ln,&codd);CHKERRQ(ierr);
316c4762a1bSJed Brown   ierr = MatGetLocalSubMatrix(A2,reven,ceven,&Aee);CHKERRQ(ierr);
317c4762a1bSJed Brown   ierr = MatGetLocalSubMatrix(A2,reven,codd,&Aeo);CHKERRQ(ierr);
318c4762a1bSJed Brown   ierr = MatGetLocalSubMatrix(A2,rodd,ceven,&Aoe);CHKERRQ(ierr);
319c4762a1bSJed Brown   ierr = MatGetLocalSubMatrix(A2,rodd,codd,&Aoo);CHKERRQ(ierr);
320*e432b41dSStefano Zampini   for (i=0; i<lm; i++) {
321c4762a1bSJed Brown     PetscInt    j,je,jo,colse[3], colso[3];
322c4762a1bSJed Brown     PetscScalar ve[3], vo[3];
323c4762a1bSJed Brown     PetscScalar v[3];
324c4762a1bSJed Brown     PetscInt    cols[3];
325*e432b41dSStefano Zampini     PetscInt    row = i/2;
326c4762a1bSJed Brown 
327c4762a1bSJed Brown     cols[0] = (i-1+n)%n;
328c4762a1bSJed Brown     cols[1] = i%n;
329c4762a1bSJed Brown     cols[2] = (i+1)%n;
330c4762a1bSJed Brown     v[0] = -1.*(symmetric ? PetscMin(i+1,cols[0]+1) : i+1);
331c4762a1bSJed Brown     v[1] =  2.*(symmetric ? PetscMin(i+1,cols[1]+1) : i+1);
332c4762a1bSJed Brown     v[2] = -1.*(symmetric ? PetscMin(i+1,cols[2]+1) : i+1);
333*e432b41dSStefano Zampini     ierr = ISGlobalToLocalMappingApply(cmap,IS_GTOLM_MASK,3,cols,NULL,cols);CHKERRQ(ierr);
334c4762a1bSJed Brown     for (j=0,je=0,jo=0;j<3;j++) {
335c4762a1bSJed Brown       if (cols[j]%2) {
336c4762a1bSJed Brown         vo[jo] = v[j];
337c4762a1bSJed Brown         colso[jo++] = cols[j]/2;
338c4762a1bSJed Brown       } else {
339c4762a1bSJed Brown         ve[je] = v[j];
340c4762a1bSJed Brown         colse[je++] = cols[j]/2;
341c4762a1bSJed Brown       }
342c4762a1bSJed Brown     }
343c4762a1bSJed Brown     if (i%2) {
344c4762a1bSJed Brown       ierr = MatSetValuesLocal(Aoe,1,&row,je,colse,ve,ADD_VALUES);CHKERRQ(ierr);
345c4762a1bSJed Brown       ierr = MatSetValuesLocal(Aoo,1,&row,jo,colso,vo,ADD_VALUES);CHKERRQ(ierr);
346c4762a1bSJed Brown     } else {
347c4762a1bSJed Brown       ierr = MatSetValuesLocal(Aee,1,&row,je,colse,ve,ADD_VALUES);CHKERRQ(ierr);
348c4762a1bSJed Brown       ierr = MatSetValuesLocal(Aeo,1,&row,jo,colso,vo,ADD_VALUES);CHKERRQ(ierr);
349c4762a1bSJed Brown     }
350c4762a1bSJed Brown   }
351c4762a1bSJed Brown   ierr = MatRestoreLocalSubMatrix(A2,reven,ceven,&Aee);CHKERRQ(ierr);
352c4762a1bSJed Brown   ierr = MatRestoreLocalSubMatrix(A2,reven,codd,&Aeo);CHKERRQ(ierr);
353c4762a1bSJed Brown   ierr = MatRestoreLocalSubMatrix(A2,rodd,ceven,&Aoe);CHKERRQ(ierr);
354c4762a1bSJed Brown   ierr = MatRestoreLocalSubMatrix(A2,rodd,codd,&Aoo);CHKERRQ(ierr);
355c4762a1bSJed Brown   ierr = ISDestroy(&reven);CHKERRQ(ierr);
356c4762a1bSJed Brown   ierr = ISDestroy(&ceven);CHKERRQ(ierr);
357c4762a1bSJed Brown   ierr = ISDestroy(&rodd);CHKERRQ(ierr);
358c4762a1bSJed Brown   ierr = ISDestroy(&codd);CHKERRQ(ierr);
359c4762a1bSJed Brown   ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
360c4762a1bSJed Brown   ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
361c4762a1bSJed Brown   ierr = MatAXPY(A2,-1.,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
362c4762a1bSJed Brown   ierr = CheckMat(A2,NULL,PETSC_FALSE,"MatGetLocalSubMatrix");CHKERRQ(ierr);
363c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
364c4762a1bSJed Brown 
365c4762a1bSJed Brown   /* test MatConvert_Nest_IS */
366c4762a1bSJed Brown   testT = PETSC_FALSE;
367c4762a1bSJed Brown   ierr  = PetscOptionsGetBool(NULL,NULL,"-test_trans",&testT,NULL);CHKERRQ(ierr);
368c4762a1bSJed Brown 
369c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatConvert_Nest_IS\n");CHKERRQ(ierr);
370c4762a1bSJed Brown   nr   = 2;
371c4762a1bSJed Brown   nc   = 2;
372c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-nr",&nr,NULL);CHKERRQ(ierr);
373c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-nc",&nc,NULL);CHKERRQ(ierr);
374c4762a1bSJed Brown   if (testT) {
375c4762a1bSJed Brown     ierr = MatGetOwnershipRange(A,&cst,&cen);CHKERRQ(ierr);
376c4762a1bSJed Brown     ierr = MatGetOwnershipRangeColumn(A,&rst,&ren);CHKERRQ(ierr);
377c4762a1bSJed Brown   } else {
378c4762a1bSJed Brown     ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr);
379c4762a1bSJed Brown     ierr = MatGetOwnershipRangeColumn(A,&cst,&cen);CHKERRQ(ierr);
380c4762a1bSJed Brown   }
381c4762a1bSJed Brown   ierr = PetscMalloc3(nr,&rows,nc,&cols,2*nr*nc,&mats);CHKERRQ(ierr);
382c4762a1bSJed Brown   for (i=0;i<nr*nc;i++) {
383c4762a1bSJed Brown     if (testT) {
384c4762a1bSJed Brown       ierr = MatCreateTranspose(A,&mats[i]);CHKERRQ(ierr);
385c4762a1bSJed Brown       ierr = MatTranspose(B,MAT_INITIAL_MATRIX,&mats[i+nr*nc]);CHKERRQ(ierr);
386c4762a1bSJed Brown     } else {
387c4762a1bSJed Brown       ierr = MatDuplicate(A,MAT_COPY_VALUES,&mats[i]);CHKERRQ(ierr);
388c4762a1bSJed Brown       ierr = MatDuplicate(B,MAT_COPY_VALUES,&mats[i+nr*nc]);CHKERRQ(ierr);
389c4762a1bSJed Brown     }
390c4762a1bSJed Brown   }
391c4762a1bSJed Brown   for (i=0;i<nr;i++) {
392c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,ren-rst,i+rst,nr,&rows[i]);CHKERRQ(ierr);
393c4762a1bSJed Brown   }
394c4762a1bSJed Brown   for (i=0;i<nc;i++) {
395c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,cen-cst,i+cst,nc,&cols[i]);CHKERRQ(ierr);
396c4762a1bSJed Brown   }
397c4762a1bSJed Brown   ierr = MatCreateNest(PETSC_COMM_WORLD,nr,rows,nc,cols,mats,&A2);CHKERRQ(ierr);
398c4762a1bSJed Brown   ierr = MatCreateNest(PETSC_COMM_WORLD,nr,rows,nc,cols,mats+nr*nc,&B2);CHKERRQ(ierr);
399c4762a1bSJed Brown   for (i=0;i<nr;i++) {
400c4762a1bSJed Brown     ierr = ISDestroy(&rows[i]);CHKERRQ(ierr);
401c4762a1bSJed Brown   }
402c4762a1bSJed Brown   for (i=0;i<nc;i++) {
403c4762a1bSJed Brown     ierr = ISDestroy(&cols[i]);CHKERRQ(ierr);
404c4762a1bSJed Brown   }
405c4762a1bSJed Brown   for (i=0;i<2*nr*nc;i++) {
406c4762a1bSJed Brown     ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);
407c4762a1bSJed Brown   }
408c4762a1bSJed Brown   ierr = PetscFree3(rows,cols,mats);CHKERRQ(ierr);
409c4762a1bSJed Brown   ierr = MatConvert(B2,MATAIJ,MAT_INITIAL_MATRIX,&T);CHKERRQ(ierr);
410c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
411c4762a1bSJed Brown   ierr = MatConvert(A2,MATIS,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr);
412c4762a1bSJed Brown   ierr = CheckMat(B2,T,PETSC_TRUE,"MatConvert_Nest_IS MAT_INITIAL_MATRIX");CHKERRQ(ierr);
413c4762a1bSJed Brown   ierr = MatConvert(A2,MATIS,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr);
414c4762a1bSJed Brown   ierr = CheckMat(B2,T,PETSC_TRUE,"MatConvert_Nest_IS MAT_REUSE_MATRIX");CHKERRQ(ierr);
415c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
416c4762a1bSJed Brown   ierr = MatConvert(A2,MATIS,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr);
417c4762a1bSJed Brown   ierr = CheckMat(A2,T,PETSC_TRUE,"MatConvert_Nest_IS MAT_INPLACE_MATRIX");CHKERRQ(ierr);
418c4762a1bSJed Brown   ierr = MatDestroy(&T);CHKERRQ(ierr);
419c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
420c4762a1bSJed Brown 
421c4762a1bSJed Brown   /* test MatCreateSubMatrix */
422c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatCreateSubMatrix\n");CHKERRQ(ierr);
423dd400576SPatrick Sanan   if (rank == 0) {
424c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,1,1,1,&is);CHKERRQ(ierr);
425c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,2,0,1,&is2);CHKERRQ(ierr);
426c4762a1bSJed Brown   } else if (rank == 1) {
427c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,1,0,1,&is);CHKERRQ(ierr);
428c4762a1bSJed Brown     if (n > 3) {
429c4762a1bSJed Brown       ierr = ISCreateStride(PETSC_COMM_WORLD,1,3,1,&is2);CHKERRQ(ierr);
430c4762a1bSJed Brown     } else {
431c4762a1bSJed Brown       ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is2);CHKERRQ(ierr);
432c4762a1bSJed Brown     }
433c4762a1bSJed Brown   } else if (rank == 2 && n > 4) {
434c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is);CHKERRQ(ierr);
435c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,n-4,4,1,&is2);CHKERRQ(ierr);
436c4762a1bSJed Brown   } else {
437c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is);CHKERRQ(ierr);
438c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is2);CHKERRQ(ierr);
439c4762a1bSJed Brown   }
440c4762a1bSJed Brown   ierr = MatCreateSubMatrix(A,is,is,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr);
441c4762a1bSJed Brown   ierr = MatCreateSubMatrix(B,is,is,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr);
442c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_TRUE,"first MatCreateSubMatrix");CHKERRQ(ierr);
443c4762a1bSJed Brown 
444c4762a1bSJed Brown   ierr = MatCreateSubMatrix(A,is,is,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr);
445c4762a1bSJed Brown   ierr = MatCreateSubMatrix(B,is,is,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr);
446c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse MatCreateSubMatrix");CHKERRQ(ierr);
447c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
448c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
449c4762a1bSJed Brown 
450*e432b41dSStefano Zampini   if (!issymmetric) {
451c4762a1bSJed Brown     ierr = MatCreateSubMatrix(A,is,is2,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr);
452c4762a1bSJed Brown     ierr = MatCreateSubMatrix(B,is,is2,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr);
453c4762a1bSJed Brown     ierr = MatCreateSubMatrix(A,is,is2,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr);
454c4762a1bSJed Brown     ierr = MatCreateSubMatrix(B,is,is2,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr);
455c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"second MatCreateSubMatrix");CHKERRQ(ierr);
456c4762a1bSJed Brown   }
457c4762a1bSJed Brown 
458c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
459c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
460c4762a1bSJed Brown   ierr = ISDestroy(&is);CHKERRQ(ierr);
461c4762a1bSJed Brown   ierr = ISDestroy(&is2);CHKERRQ(ierr);
462c4762a1bSJed Brown 
463c4762a1bSJed Brown   /* Create an IS required by MatZeroRows(): just rank zero provides the rows to be eliminated */
464c4762a1bSJed Brown   if (size > 1) {
465dd400576SPatrick Sanan     if (rank == 0) {
466c4762a1bSJed Brown       PetscInt st,len;
467c4762a1bSJed Brown 
468c4762a1bSJed Brown       st   = (m+1)/2;
469c4762a1bSJed Brown       len  = PetscMin(m/2,PetscMax(m-(m+1)/2-1,0));
470c4762a1bSJed Brown       ierr = ISCreateStride(PETSC_COMM_WORLD,len,st,1,&is);CHKERRQ(ierr);
471c4762a1bSJed Brown     } else {
472c4762a1bSJed Brown       ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is);CHKERRQ(ierr);
473c4762a1bSJed Brown     }
474c4762a1bSJed Brown   } else {
475c4762a1bSJed Brown     ierr = ISCreateStride(PETSC_COMM_WORLD,1,0,1,&is);CHKERRQ(ierr);
476c4762a1bSJed Brown   }
477c4762a1bSJed Brown 
478c4762a1bSJed Brown   if (squaretest) { /* tests for square matrices only, with same maps for rows and columns */
479c4762a1bSJed Brown     /* test MatDiagonalSet */
480c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatDiagonalSet\n");CHKERRQ(ierr);
481c4762a1bSJed Brown     ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
482c4762a1bSJed Brown     ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
483c4762a1bSJed Brown     ierr = MatCreateVecs(A,NULL,&x);CHKERRQ(ierr);
484c4762a1bSJed Brown     ierr = VecSetRandom(x,NULL);CHKERRQ(ierr);
485c4762a1bSJed Brown     ierr = MatDiagonalSet(A2,x,INSERT_VALUES);CHKERRQ(ierr);
486c4762a1bSJed Brown     ierr = MatDiagonalSet(B2,x,INSERT_VALUES);CHKERRQ(ierr);
487c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"MatDiagonalSet");CHKERRQ(ierr);
488c4762a1bSJed Brown     ierr = VecDestroy(&x);CHKERRQ(ierr);
489c4762a1bSJed Brown     ierr = MatDestroy(&A2);CHKERRQ(ierr);
490c4762a1bSJed Brown     ierr = MatDestroy(&B2);CHKERRQ(ierr);
491c4762a1bSJed Brown 
492c4762a1bSJed Brown     /* test MatShift (MatShift_IS internally uses MatDiagonalSet_IS with ADD_VALUES) */
493c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatShift\n");CHKERRQ(ierr);
494c4762a1bSJed Brown     ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
495c4762a1bSJed Brown     ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
496c4762a1bSJed Brown     ierr = MatShift(A2,2.0);CHKERRQ(ierr);
497c4762a1bSJed Brown     ierr = MatShift(B2,2.0);CHKERRQ(ierr);
498c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"MatShift");CHKERRQ(ierr);
499c4762a1bSJed Brown     ierr = MatDestroy(&A2);CHKERRQ(ierr);
500c4762a1bSJed Brown     ierr = MatDestroy(&B2);CHKERRQ(ierr);
501c4762a1bSJed Brown 
502c4762a1bSJed Brown     /* nonzero diag value is supported for square matrices only */
503c4762a1bSJed Brown     ierr = TestMatZeroRows(A,B,PETSC_TRUE,is,diag);CHKERRQ(ierr);
504c4762a1bSJed Brown   }
505c4762a1bSJed Brown   ierr = TestMatZeroRows(A,B,squaretest,is,0.0);CHKERRQ(ierr);
506c4762a1bSJed Brown   ierr = ISDestroy(&is);CHKERRQ(ierr);
507c4762a1bSJed Brown 
508c4762a1bSJed Brown   /* test MatTranspose */
509c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatTranspose\n");CHKERRQ(ierr);
510c4762a1bSJed Brown   ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr);
511c4762a1bSJed Brown   ierr = MatTranspose(B,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr);
512c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_FALSE,"initial matrix MatTranspose");CHKERRQ(ierr);
513c4762a1bSJed Brown 
514c4762a1bSJed Brown   ierr = MatTranspose(A,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr);
515c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse matrix (not in place) MatTranspose");CHKERRQ(ierr);
516c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
517c4762a1bSJed Brown 
518c4762a1bSJed Brown   ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
519c4762a1bSJed Brown   ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr);
520c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse matrix (in place) MatTranspose");CHKERRQ(ierr);
521c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
522c4762a1bSJed Brown 
523c4762a1bSJed Brown   ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr);
524c4762a1bSJed Brown   ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse matrix (different type) MatTranspose");CHKERRQ(ierr);
525c4762a1bSJed Brown   ierr = MatDestroy(&A2);CHKERRQ(ierr);
526c4762a1bSJed Brown   ierr = MatDestroy(&B2);CHKERRQ(ierr);
527c4762a1bSJed Brown 
528c4762a1bSJed Brown   /* test MatISFixLocalEmpty */
529c4762a1bSJed Brown   if (isaij) {
530c4762a1bSJed Brown     PetscInt r[2];
531c4762a1bSJed Brown 
532c4762a1bSJed Brown     r[0] = 0;
533c4762a1bSJed Brown     r[1] = PetscMin(m,n)-1;
534c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatISFixLocalEmpty\n");CHKERRQ(ierr);
535c4762a1bSJed Brown     ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
536*e432b41dSStefano Zampini 
537c4762a1bSJed Brown     ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr);
538c4762a1bSJed Brown     ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
539c4762a1bSJed Brown     ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
540c4762a1bSJed Brown     ierr = CheckMat(A2,B,PETSC_FALSE,"MatISFixLocalEmpty (null)");CHKERRQ(ierr);
541c4762a1bSJed Brown 
542c4762a1bSJed Brown     ierr = MatZeroRows(A2,2,r,0.0,NULL,NULL);CHKERRQ(ierr);
543c4762a1bSJed Brown     ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr);
544c4762a1bSJed Brown     ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
545c4762a1bSJed Brown     ierr = MatZeroRows(B2,2,r,0.0,NULL,NULL);CHKERRQ(ierr);
546c4762a1bSJed Brown     ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr);
547c4762a1bSJed Brown     ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
548c4762a1bSJed Brown     ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
549c4762a1bSJed Brown     ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr);
550c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"MatISFixLocalEmpty (rows)");CHKERRQ(ierr);
551c4762a1bSJed Brown     ierr = MatDestroy(&A2);CHKERRQ(ierr);
552c4762a1bSJed Brown 
553c4762a1bSJed Brown     ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
554c4762a1bSJed Brown     ierr = MatZeroRows(A2,2,r,0.0,NULL,NULL);CHKERRQ(ierr);
555c4762a1bSJed Brown     ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr);
556c4762a1bSJed Brown     ierr = MatTranspose(B2,MAT_INPLACE_MATRIX,&B2);CHKERRQ(ierr);
557c4762a1bSJed Brown     ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr);
558c4762a1bSJed Brown     ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr);
559c4762a1bSJed Brown     ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
560c4762a1bSJed Brown     ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
561c4762a1bSJed Brown     ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr);
562c4762a1bSJed Brown     ierr = CheckMat(A2,B2,PETSC_FALSE,"MatISFixLocalEmpty (cols)");CHKERRQ(ierr);
563c4762a1bSJed Brown 
564c4762a1bSJed Brown     ierr = MatDestroy(&A2);CHKERRQ(ierr);
565c4762a1bSJed Brown     ierr = MatDestroy(&B2);CHKERRQ(ierr);
566c4762a1bSJed Brown 
567c4762a1bSJed Brown     if (squaretest) {
568c4762a1bSJed Brown       ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
569c4762a1bSJed Brown       ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
570c4762a1bSJed Brown       ierr = MatZeroRowsColumns(A2,2,r,0.0,NULL,NULL);CHKERRQ(ierr);
571c4762a1bSJed Brown       ierr = MatZeroRowsColumns(B2,2,r,0.0,NULL,NULL);CHKERRQ(ierr);
572c4762a1bSJed Brown       ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr);
573c4762a1bSJed Brown       ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr);
574c4762a1bSJed Brown       ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
575c4762a1bSJed Brown       ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
576c4762a1bSJed Brown       ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr);
577c4762a1bSJed Brown       ierr = CheckMat(A2,B2,PETSC_FALSE,"MatISFixLocalEmpty (rows+cols)");CHKERRQ(ierr);
578c4762a1bSJed Brown       ierr = MatDestroy(&A2);CHKERRQ(ierr);
579c4762a1bSJed Brown       ierr = MatDestroy(&B2);CHKERRQ(ierr);
580c4762a1bSJed Brown     }
581c4762a1bSJed Brown 
582c4762a1bSJed Brown   }
583c4762a1bSJed Brown 
584c4762a1bSJed Brown   /* test MatInvertBlockDiagonal
585c4762a1bSJed Brown        special cases for block-diagonal matrices */
586c4762a1bSJed Brown   if (m == n) {
587c4762a1bSJed Brown     ISLocalToGlobalMapping map;
588c4762a1bSJed Brown     Mat                    Abd,Bbd;
589c4762a1bSJed Brown     IS                     is,bis;
590c4762a1bSJed Brown     const PetscScalar      *isbd,*aijbd;
591c4762a1bSJed Brown     PetscScalar            *vals;
592c4762a1bSJed Brown     const PetscInt         *sts,*idxs;
593c4762a1bSJed Brown     PetscInt               *idxs2,diff,perm,nl,bs,st,en,in;
594c4762a1bSJed Brown     PetscBool              ok;
595c4762a1bSJed Brown 
596c4762a1bSJed Brown     for (diff = 0; diff < 3; diff++) {
597c4762a1bSJed Brown       for (perm = 0; perm < 3; perm++) {
598c4762a1bSJed Brown         for (bs = 1; bs < 4; bs++) {
5998fffc762SJacob Faibussowitsch           ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatInvertBlockDiagonal blockdiag %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",n,diff,perm,bs);CHKERRQ(ierr);
600c4762a1bSJed Brown           ierr = PetscMalloc1(bs*bs,&vals);CHKERRQ(ierr);
601c4762a1bSJed Brown           ierr = MatGetOwnershipRanges(A,&sts);CHKERRQ(ierr);
602c4762a1bSJed Brown           switch (diff) {
603c4762a1bSJed Brown           case 1: /* inverted layout by processes */
604c4762a1bSJed Brown             in = 1;
605c4762a1bSJed Brown             st = sts[size - rank - 1];
606c4762a1bSJed Brown             en = sts[size - rank];
607c4762a1bSJed Brown             nl = en - st;
608c4762a1bSJed Brown             break;
609c4762a1bSJed Brown           case 2: /* round-robin layout */
610c4762a1bSJed Brown             in = size;
611c4762a1bSJed Brown             st = rank;
612c4762a1bSJed Brown             nl = n/size;
613c4762a1bSJed Brown             if (rank < n%size) nl++;
614c4762a1bSJed Brown             break;
615c4762a1bSJed Brown           default: /* same layout */
616c4762a1bSJed Brown             in = 1;
617c4762a1bSJed Brown             st = sts[rank];
618c4762a1bSJed Brown             en = sts[rank + 1];
619c4762a1bSJed Brown             nl = en - st;
620c4762a1bSJed Brown             break;
621c4762a1bSJed Brown           }
622c4762a1bSJed Brown           ierr = ISCreateStride(PETSC_COMM_WORLD,nl,st,in,&is);CHKERRQ(ierr);
623c4762a1bSJed Brown           ierr = ISGetLocalSize(is,&nl);CHKERRQ(ierr);
624c4762a1bSJed Brown           ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr);
625c4762a1bSJed Brown           ierr = PetscMalloc1(nl,&idxs2);CHKERRQ(ierr);
626c4762a1bSJed Brown           for (i=0;i<nl;i++) {
627c4762a1bSJed Brown             switch (perm) { /* invert some of the indices */
628c4762a1bSJed Brown             case 2:
629c4762a1bSJed Brown               idxs2[i] = rank%2 ? idxs[i] : idxs[nl-i-1];
630c4762a1bSJed Brown               break;
631c4762a1bSJed Brown             case 1:
632c4762a1bSJed Brown               idxs2[i] = rank%2 ? idxs[nl-i-1] : idxs[i];
633c4762a1bSJed Brown               break;
634c4762a1bSJed Brown             default:
635c4762a1bSJed Brown               idxs2[i] = idxs[i];
636c4762a1bSJed Brown               break;
637c4762a1bSJed Brown             }
638c4762a1bSJed Brown           }
639c4762a1bSJed Brown           ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr);
640c4762a1bSJed Brown           ierr = ISCreateBlock(PETSC_COMM_WORLD,bs,nl,idxs2,PETSC_OWN_POINTER,&bis);CHKERRQ(ierr);
641c4762a1bSJed Brown           ierr = ISLocalToGlobalMappingCreateIS(bis,&map);CHKERRQ(ierr);
642fc989267SStefano Zampini           ierr = MatCreateIS(PETSC_COMM_WORLD,bs,PETSC_DECIDE,PETSC_DECIDE,bs*n,bs*n,map,map,&Abd);CHKERRQ(ierr);
643c4762a1bSJed Brown           ierr = ISLocalToGlobalMappingDestroy(&map);CHKERRQ(ierr);
644c4762a1bSJed Brown           ierr = MatISSetPreallocation(Abd,bs,NULL,0,NULL);CHKERRQ(ierr);
645c4762a1bSJed Brown           for (i=0;i<nl;i++) {
646c4762a1bSJed Brown             PetscInt b1,b2;
647c4762a1bSJed Brown 
648c4762a1bSJed Brown             for (b1=0;b1<bs;b1++) {
649c4762a1bSJed Brown               for (b2=0;b2<bs;b2++) {
650c4762a1bSJed Brown                 vals[b1*bs + b2] = i*bs*bs + b1*bs + b2 + 1 + (b1 == b2 ? 1.0 : 0);
651c4762a1bSJed Brown               }
652c4762a1bSJed Brown             }
653c4762a1bSJed Brown             ierr = MatSetValuesBlockedLocal(Abd,1,&i,1,&i,vals,INSERT_VALUES);CHKERRQ(ierr);
654c4762a1bSJed Brown           }
655c4762a1bSJed Brown           ierr = MatAssemblyBegin(Abd,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
656c4762a1bSJed Brown           ierr = MatAssemblyEnd(Abd,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
657c4762a1bSJed Brown           ierr = MatConvert(Abd,MATAIJ,MAT_INITIAL_MATRIX,&Bbd);CHKERRQ(ierr);
658c4762a1bSJed Brown           ierr = MatInvertBlockDiagonal(Abd,&isbd);CHKERRQ(ierr);
659c4762a1bSJed Brown           ierr = MatInvertBlockDiagonal(Bbd,&aijbd);CHKERRQ(ierr);
660c4762a1bSJed Brown           ierr = MatGetLocalSize(Bbd,&nl,NULL);CHKERRQ(ierr);
661c4762a1bSJed Brown           ok   = PETSC_TRUE;
662c4762a1bSJed Brown           for (i=0;i<nl/bs;i++) {
663c4762a1bSJed Brown             PetscInt b1,b2;
664c4762a1bSJed Brown 
665c4762a1bSJed Brown             for (b1=0;b1<bs;b1++) {
666c4762a1bSJed Brown               for (b2=0;b2<bs;b2++) {
667c4762a1bSJed Brown                 if (PetscAbsScalar(isbd[i*bs*bs+b1*bs + b2]-aijbd[i*bs*bs+b1*bs + b2]) > PETSC_SMALL) ok = PETSC_FALSE;
668c4762a1bSJed Brown                 if (!ok) {
6698fffc762SJacob Faibussowitsch                   ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] ERROR block %" PetscInt_FMT ", entry %" PetscInt_FMT " %" PetscInt_FMT ": %g %g\n",rank,i,b1,b2,(double)PetscAbsScalar(isbd[i*bs*bs+b1*bs + b2]),(double)PetscAbsScalar(aijbd[i*bs*bs+b1*bs + b2]));CHKERRQ(ierr);
670c4762a1bSJed Brown                   break;
671c4762a1bSJed Brown                 }
672c4762a1bSJed Brown               }
673c4762a1bSJed Brown               if (!ok) break;
674c4762a1bSJed Brown             }
675c4762a1bSJed Brown             if (!ok) break;
676c4762a1bSJed Brown           }
677c4762a1bSJed Brown           ierr = MatDestroy(&Abd);CHKERRQ(ierr);
678c4762a1bSJed Brown           ierr = MatDestroy(&Bbd);CHKERRQ(ierr);
679c4762a1bSJed Brown           ierr = PetscFree(vals);CHKERRQ(ierr);
680c4762a1bSJed Brown           ierr = ISDestroy(&is);CHKERRQ(ierr);
681c4762a1bSJed Brown           ierr = ISDestroy(&bis);CHKERRQ(ierr);
682c4762a1bSJed Brown         }
683c4762a1bSJed Brown       }
684c4762a1bSJed Brown     }
685c4762a1bSJed Brown   }
686c4762a1bSJed Brown   /* free testing matrices */
687*e432b41dSStefano Zampini   ierr = ISLocalToGlobalMappingDestroy(&cmap);CHKERRQ(ierr);
688*e432b41dSStefano Zampini   ierr = ISLocalToGlobalMappingDestroy(&rmap);CHKERRQ(ierr);
689c4762a1bSJed Brown   ierr = MatDestroy(&A);CHKERRQ(ierr);
690c4762a1bSJed Brown   ierr = MatDestroy(&B);CHKERRQ(ierr);
691c4762a1bSJed Brown   ierr = PetscFinalize();
692c4762a1bSJed Brown   return ierr;
693c4762a1bSJed Brown }
694c4762a1bSJed Brown 
695c4762a1bSJed Brown PetscErrorCode CheckMat(Mat A, Mat B, PetscBool usemult, const char* func)
696c4762a1bSJed Brown {
697c4762a1bSJed Brown   Mat            Bcheck;
698c4762a1bSJed Brown   PetscReal      error;
699c4762a1bSJed Brown   PetscErrorCode ierr;
700c4762a1bSJed Brown 
701c4762a1bSJed Brown   PetscFunctionBeginUser;
702c4762a1bSJed Brown   if (!usemult && B) {
703c4762a1bSJed Brown     PetscBool hasnorm;
704c4762a1bSJed Brown 
705c4762a1bSJed Brown     ierr = MatHasOperation(B,MATOP_NORM,&hasnorm);CHKERRQ(ierr);
706c4762a1bSJed Brown     if (!hasnorm) usemult = PETSC_TRUE;
707c4762a1bSJed Brown   }
708c4762a1bSJed Brown   if (!usemult) {
709c4762a1bSJed Brown     if (B) {
710c4762a1bSJed Brown       MatType Btype;
711c4762a1bSJed Brown 
712c4762a1bSJed Brown       ierr = MatGetType(B,&Btype);CHKERRQ(ierr);
713c4762a1bSJed Brown       ierr = MatConvert(A,Btype,MAT_INITIAL_MATRIX,&Bcheck);CHKERRQ(ierr);
714c4762a1bSJed Brown     } else {
715c4762a1bSJed Brown       ierr = MatConvert(A,MATAIJ,MAT_INITIAL_MATRIX,&Bcheck);CHKERRQ(ierr);
716c4762a1bSJed Brown     }
717c4762a1bSJed Brown     if (B) { /* if B is present, subtract it */
718c4762a1bSJed Brown       ierr = MatAXPY(Bcheck,-1.,B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
719c4762a1bSJed Brown     }
720c4762a1bSJed Brown     ierr = MatNorm(Bcheck,NORM_INFINITY,&error);CHKERRQ(ierr);
721c4762a1bSJed Brown     if (error > PETSC_SQRT_MACHINE_EPSILON) {
722c4762a1bSJed Brown       ISLocalToGlobalMapping rl2g,cl2g;
723c4762a1bSJed Brown 
724c4762a1bSJed Brown       ierr = PetscObjectSetName((PetscObject)Bcheck,"Assembled Bcheck");CHKERRQ(ierr);
725c4762a1bSJed Brown       ierr = MatView(Bcheck,NULL);CHKERRQ(ierr);
726c4762a1bSJed Brown       if (B) {
727c4762a1bSJed Brown         ierr = PetscObjectSetName((PetscObject)B,"Assembled AIJ");CHKERRQ(ierr);
728c4762a1bSJed Brown         ierr = MatView(B,NULL);CHKERRQ(ierr);
729c4762a1bSJed Brown         ierr = MatDestroy(&Bcheck);CHKERRQ(ierr);
730c4762a1bSJed Brown         ierr = MatConvert(A,MATAIJ,MAT_INITIAL_MATRIX,&Bcheck);CHKERRQ(ierr);
731c4762a1bSJed Brown         ierr = PetscObjectSetName((PetscObject)Bcheck,"Assembled IS");CHKERRQ(ierr);
732c4762a1bSJed Brown         ierr = MatView(Bcheck,NULL);CHKERRQ(ierr);
733c4762a1bSJed Brown       }
734c4762a1bSJed Brown       ierr = MatDestroy(&Bcheck);CHKERRQ(ierr);
735c4762a1bSJed Brown       ierr = PetscObjectSetName((PetscObject)A,"MatIS");CHKERRQ(ierr);
736c4762a1bSJed Brown       ierr = MatView(A,NULL);CHKERRQ(ierr);
737c4762a1bSJed Brown       ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr);
738c4762a1bSJed Brown       ierr = ISLocalToGlobalMappingView(rl2g,NULL);CHKERRQ(ierr);
739c4762a1bSJed Brown       ierr = ISLocalToGlobalMappingView(cl2g,NULL);CHKERRQ(ierr);
74098921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR ON %s: %g",func,(double)error);
741c4762a1bSJed Brown     }
742c4762a1bSJed Brown     ierr = MatDestroy(&Bcheck);CHKERRQ(ierr);
743c4762a1bSJed Brown   } else {
744c4762a1bSJed Brown     PetscBool ok,okt;
745c4762a1bSJed Brown 
746c4762a1bSJed Brown     ierr = MatMultEqual(A,B,3,&ok);CHKERRQ(ierr);
747c4762a1bSJed Brown     ierr = MatMultTransposeEqual(A,B,3,&okt);CHKERRQ(ierr);
7482c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!ok || !okt,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR ON %s: mult ok ?  %d, multtranspose ok ? %d",func,ok,okt);
749c4762a1bSJed Brown   }
750c4762a1bSJed Brown   PetscFunctionReturn(0);
751c4762a1bSJed Brown }
752c4762a1bSJed Brown 
753c4762a1bSJed Brown PetscErrorCode TestMatZeroRows(Mat A, Mat Afull, PetscBool squaretest, IS is, PetscScalar diag)
754c4762a1bSJed Brown {
755c4762a1bSJed Brown   Mat                    B,Bcheck,B2 = NULL,lB;
756c4762a1bSJed Brown   Vec                    x = NULL, b = NULL, b2 = NULL;
757c4762a1bSJed Brown   ISLocalToGlobalMapping l2gr,l2gc;
758c4762a1bSJed Brown   PetscReal              error;
759c4762a1bSJed Brown   char                   diagstr[16];
760c4762a1bSJed Brown   const PetscInt         *idxs;
761c4762a1bSJed Brown   PetscInt               rst,ren,i,n,N,d;
762c4762a1bSJed Brown   PetscMPIInt            rank;
763c4762a1bSJed Brown   PetscBool              miss,haszerorows;
764c4762a1bSJed Brown   PetscErrorCode         ierr;
765c4762a1bSJed Brown 
766c4762a1bSJed Brown   PetscFunctionBeginUser;
767c4762a1bSJed Brown   if (diag == 0.) {
768c4762a1bSJed Brown     ierr = PetscStrcpy(diagstr,"zero");CHKERRQ(ierr);
769c4762a1bSJed Brown   } else {
770c4762a1bSJed Brown     ierr = PetscStrcpy(diagstr,"nonzero");CHKERRQ(ierr);
771c4762a1bSJed Brown   }
772c4762a1bSJed Brown   ierr = ISView(is,NULL);CHKERRQ(ierr);
773c4762a1bSJed Brown   ierr = MatGetLocalToGlobalMapping(A,&l2gr,&l2gc);CHKERRQ(ierr);
774c4762a1bSJed Brown   /* tests MatDuplicate and MatCopy */
775c4762a1bSJed Brown   if (diag == 0.) {
776c4762a1bSJed Brown     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
777c4762a1bSJed Brown   } else {
778c4762a1bSJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&B);CHKERRQ(ierr);
779c4762a1bSJed Brown     ierr = MatCopy(A,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
780c4762a1bSJed Brown   }
781c4762a1bSJed Brown   ierr = MatISGetLocalMat(B,&lB);CHKERRQ(ierr);
782c4762a1bSJed Brown   ierr = MatHasOperation(lB,MATOP_ZERO_ROWS,&haszerorows);CHKERRQ(ierr);
783c4762a1bSJed Brown   if (squaretest && haszerorows) {
784c4762a1bSJed Brown 
785c4762a1bSJed Brown     ierr = MatCreateVecs(B,&x,&b);CHKERRQ(ierr);
786c4762a1bSJed Brown     ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
787c4762a1bSJed Brown     ierr = VecSetLocalToGlobalMapping(b,l2gr);CHKERRQ(ierr);
788c4762a1bSJed Brown     ierr = VecSetLocalToGlobalMapping(x,l2gc);CHKERRQ(ierr);
789c4762a1bSJed Brown     ierr = VecSetRandom(x,NULL);CHKERRQ(ierr);
790c4762a1bSJed Brown     ierr = VecSetRandom(b,NULL);CHKERRQ(ierr);
791c4762a1bSJed Brown     /* mimic b[is] = x[is] */
792c4762a1bSJed Brown     ierr = VecDuplicate(b,&b2);CHKERRQ(ierr);
793c4762a1bSJed Brown     ierr = VecSetLocalToGlobalMapping(b2,l2gr);CHKERRQ(ierr);
794c4762a1bSJed Brown     ierr = VecCopy(b,b2);CHKERRQ(ierr);
795c4762a1bSJed Brown     ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr);
796c4762a1bSJed Brown     ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr);
797c4762a1bSJed Brown     ierr = VecGetSize(x,&N);CHKERRQ(ierr);
798c4762a1bSJed Brown     for (i=0;i<n;i++) {
799c4762a1bSJed Brown       if (0 <= idxs[i] && idxs[i] < N) {
800c4762a1bSJed Brown         ierr = VecSetValue(b2,idxs[i],diag,INSERT_VALUES);CHKERRQ(ierr);
801c4762a1bSJed Brown         ierr = VecSetValue(x,idxs[i],1.,INSERT_VALUES);CHKERRQ(ierr);
802c4762a1bSJed Brown       }
803c4762a1bSJed Brown     }
804c4762a1bSJed Brown     ierr = VecAssemblyBegin(b2);CHKERRQ(ierr);
805c4762a1bSJed Brown     ierr = VecAssemblyEnd(b2);CHKERRQ(ierr);
806c4762a1bSJed Brown     ierr = VecAssemblyBegin(x);CHKERRQ(ierr);
807c4762a1bSJed Brown     ierr = VecAssemblyEnd(x);CHKERRQ(ierr);
808c4762a1bSJed Brown     ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr);
809c4762a1bSJed Brown     /*  test ZeroRows on MATIS */
810c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr);
811c4762a1bSJed Brown     ierr = MatZeroRowsIS(B,is,diag,x,b);CHKERRQ(ierr);
812c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRowsColumns (diag %s)\n",diagstr);CHKERRQ(ierr);
813c4762a1bSJed Brown     ierr = MatZeroRowsColumnsIS(B2,is,diag,NULL,NULL);CHKERRQ(ierr);
814c4762a1bSJed Brown   } else if (haszerorows) {
815c4762a1bSJed Brown     /*  test ZeroRows on MATIS */
816c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr);
817c4762a1bSJed Brown     ierr = MatZeroRowsIS(B,is,diag,NULL,NULL);CHKERRQ(ierr);
818c4762a1bSJed Brown     b = b2 = x = NULL;
819c4762a1bSJed Brown   } else {
820c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Skipping MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr);
821c4762a1bSJed Brown     b = b2 = x = NULL;
822c4762a1bSJed Brown   }
823c4762a1bSJed Brown 
824c4762a1bSJed Brown   if (squaretest && haszerorows) {
825c4762a1bSJed Brown     ierr = VecAXPY(b2,-1.,b);CHKERRQ(ierr);
826c4762a1bSJed Brown     ierr = VecNorm(b2,NORM_INFINITY,&error);CHKERRQ(ierr);
8272c71b3e2SJacob Faibussowitsch     PetscCheckFalse(error > PETSC_SQRT_MACHINE_EPSILON,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR IN ZEROROWS ON B %g (diag %s)",(double)error,diagstr);
828c4762a1bSJed Brown   }
829c4762a1bSJed Brown 
830c4762a1bSJed Brown   /* test MatMissingDiagonal */
831c4762a1bSJed Brown   ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatMissingDiagonal\n");CHKERRQ(ierr);
832ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
833c4762a1bSJed Brown   ierr = MatMissingDiagonal(B,&miss,&d);CHKERRQ(ierr);
834c4762a1bSJed Brown   ierr = MatGetOwnershipRange(B,&rst,&ren);CHKERRQ(ierr);
835c4762a1bSJed Brown   ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
8368fffc762SJacob Faibussowitsch   ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD, "[%d] [%" PetscInt_FMT ",%" PetscInt_FMT ") Missing %d, row %" PetscInt_FMT " (diag %s)\n",rank,rst,ren,(int)miss,d,diagstr);CHKERRQ(ierr);
837c4762a1bSJed Brown   ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
838c4762a1bSJed Brown   ierr = PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
839c4762a1bSJed Brown 
840c4762a1bSJed Brown   ierr = VecDestroy(&x);CHKERRQ(ierr);
841c4762a1bSJed Brown   ierr = VecDestroy(&b);CHKERRQ(ierr);
842c4762a1bSJed Brown   ierr = VecDestroy(&b2);CHKERRQ(ierr);
843c4762a1bSJed Brown 
844c4762a1bSJed Brown   /* check the result of ZeroRows with that from MPIAIJ routines
845c4762a1bSJed Brown      assuming that MatConvert_IS_XAIJ and MatZeroRows_MPIAIJ work fine */
846c4762a1bSJed Brown   if (haszerorows) {
847c4762a1bSJed Brown     ierr = MatDuplicate(Afull,MAT_COPY_VALUES,&Bcheck);CHKERRQ(ierr);
848c4762a1bSJed Brown     ierr = MatSetOption(Bcheck,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
849c4762a1bSJed Brown     ierr = MatZeroRowsIS(Bcheck,is,diag,NULL,NULL);CHKERRQ(ierr);
850c4762a1bSJed Brown     ierr = CheckMat(B,Bcheck,PETSC_FALSE,"Zerorows");CHKERRQ(ierr);
851c4762a1bSJed Brown     ierr = MatDestroy(&Bcheck);CHKERRQ(ierr);
852c4762a1bSJed Brown   }
853c4762a1bSJed Brown   ierr = MatDestroy(&B);CHKERRQ(ierr);
854c4762a1bSJed Brown 
855c4762a1bSJed Brown   if (B2) { /* test MatZeroRowsColumns */
856c4762a1bSJed Brown     ierr = MatDuplicate(Afull,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
857c4762a1bSJed Brown     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
858c4762a1bSJed Brown     ierr = MatZeroRowsColumnsIS(B,is,diag,NULL,NULL);CHKERRQ(ierr);
859c4762a1bSJed Brown     ierr = CheckMat(B2,B,PETSC_FALSE,"MatZeroRowsColumns");CHKERRQ(ierr);
860c4762a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
861c4762a1bSJed Brown     ierr = MatDestroy(&B2);CHKERRQ(ierr);
862c4762a1bSJed Brown   }
863c4762a1bSJed Brown   PetscFunctionReturn(0);
864c4762a1bSJed Brown }
865c4762a1bSJed Brown 
866c4762a1bSJed Brown /*TEST
867c4762a1bSJed Brown 
868c4762a1bSJed Brown    test:
869c4762a1bSJed Brown       args: -test_trans
870c4762a1bSJed Brown 
871c4762a1bSJed Brown    test:
872c4762a1bSJed Brown       suffix: 2
873c4762a1bSJed Brown       nsize: 4
874c4762a1bSJed Brown       args: -matis_convert_local_nest -nr 3 -nc 4
875c4762a1bSJed Brown 
876c4762a1bSJed Brown    test:
877c4762a1bSJed Brown       suffix: 3
878c4762a1bSJed Brown       nsize: 5
879c4762a1bSJed Brown       args: -m 11 -n 10 -matis_convert_local_nest -nr 2 -nc 1
880c4762a1bSJed Brown 
881c4762a1bSJed Brown    test:
882c4762a1bSJed Brown       suffix: 4
883c4762a1bSJed Brown       nsize: 6
884c4762a1bSJed Brown       args: -m 9 -n 12 -test_trans -nr 2 -nc 7
885c4762a1bSJed Brown 
886c4762a1bSJed Brown    test:
887c4762a1bSJed Brown       suffix: 5
888c4762a1bSJed Brown       nsize: 6
889c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 3 -nc 1
890c4762a1bSJed Brown 
891c4762a1bSJed Brown    test:
892c4762a1bSJed Brown       suffix: 6
893c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap
894c4762a1bSJed Brown 
895c4762a1bSJed Brown    test:
896c4762a1bSJed Brown       suffix: 7
897c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap
898c4762a1bSJed Brown 
899c4762a1bSJed Brown    test:
900c4762a1bSJed Brown       suffix: 8
901c4762a1bSJed Brown       args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap
902c4762a1bSJed Brown 
903c4762a1bSJed Brown    test:
904c4762a1bSJed Brown       suffix: 9
905c4762a1bSJed Brown       nsize: 5
906c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap
907c4762a1bSJed Brown 
908c4762a1bSJed Brown    test:
909c4762a1bSJed Brown       suffix: 10
910c4762a1bSJed Brown       nsize: 5
911c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap
912c4762a1bSJed Brown 
913c20d7725SJed Brown    test:
914c20d7725SJed Brown       suffix: vscat_default
915c4762a1bSJed Brown       nsize: 5
916c4762a1bSJed Brown       args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap
917c4762a1bSJed Brown       output_file: output/ex23_11.out
918c4762a1bSJed Brown 
919c4762a1bSJed Brown    test:
920c4762a1bSJed Brown       suffix: 12
921c4762a1bSJed Brown       nsize: 3
922c4762a1bSJed Brown       args: -m 12 -n 12 -symmetric -matis_localmat_type sbaij -test_trans -nr 2 -nc 3
923c4762a1bSJed Brown 
924c4762a1bSJed Brown    testset:
925c4762a1bSJed Brown       output_file: output/ex23_13.out
926c4762a1bSJed Brown       nsize: 3
927c4762a1bSJed Brown       args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -diffmap -permmap
928c4762a1bSJed Brown       filter: grep -v "type:"
929c4762a1bSJed Brown       test:
930c4762a1bSJed Brown         suffix: baij
931c4762a1bSJed Brown         args: -matis_localmat_type baij
932c4762a1bSJed Brown       test:
933c4762a1bSJed Brown         requires: viennacl
934c4762a1bSJed Brown         suffix: viennacl
935c4762a1bSJed Brown         args: -matis_localmat_type aijviennacl
936c4762a1bSJed Brown       test:
937c4762a1bSJed Brown         requires: cuda
938c4762a1bSJed Brown         suffix: cusparse
939c4762a1bSJed Brown         args: -matis_localmat_type aijcusparse
940c4762a1bSJed Brown 
941*e432b41dSStefano Zampini    test:
942*e432b41dSStefano Zampini       suffix: negrep
943*e432b41dSStefano Zampini       nsize: {{1 3}separate output}
944*e432b41dSStefano Zampini       args: -m {{5 7}separate output} -n {{5 7}separate output} -test_trans -nr 2 -nc 3 -negmap {{0 1}separate output} -repmap {{0 1}separate output} -permmap -diffmap {{0 1}separate output}
945*e432b41dSStefano Zampini 
946c4762a1bSJed Brown TEST*/
947