xref: /petsc/src/mat/tests/ex221.c (revision b122ec5aa1bd4469eb4e0673542fb7de3f411254)
1c4762a1bSJed Brown static char help[] = "Tests various routines for MATSHELL\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown #include <petscmat.h>
4c4762a1bSJed Brown 
5c4762a1bSJed Brown typedef struct _n_User *User;
6c4762a1bSJed Brown struct _n_User {
7c4762a1bSJed Brown   Mat B;
8c4762a1bSJed Brown };
9c4762a1bSJed Brown 
10c4762a1bSJed Brown static PetscErrorCode MatGetDiagonal_User(Mat A,Vec X)
11c4762a1bSJed Brown {
12c4762a1bSJed Brown   User           user;
13c4762a1bSJed Brown 
14c4762a1bSJed Brown   PetscFunctionBegin;
155f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellGetContext(A,&user));
165f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetDiagonal(user->B,X));
17c4762a1bSJed Brown   PetscFunctionReturn(0);
18c4762a1bSJed Brown }
19c4762a1bSJed Brown 
20c4762a1bSJed Brown static PetscErrorCode MatMult_User(Mat A,Vec X,Vec Y)
21c4762a1bSJed Brown {
22c4762a1bSJed Brown   User           user;
23c4762a1bSJed Brown 
24c4762a1bSJed Brown   PetscFunctionBegin;
255f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellGetContext(A,&user));
265f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMult(user->B,X,Y));
27c4762a1bSJed Brown   PetscFunctionReturn(0);
28c4762a1bSJed Brown }
29c4762a1bSJed Brown 
30c4762a1bSJed Brown static PetscErrorCode MatMultTranspose_User(Mat A,Vec X,Vec Y)
31c4762a1bSJed Brown {
32c4762a1bSJed Brown   User           user;
33c4762a1bSJed Brown 
34c4762a1bSJed Brown   PetscFunctionBegin;
355f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellGetContext(A,&user));
365f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTranspose(user->B,X,Y));
37c4762a1bSJed Brown   PetscFunctionReturn(0);
38c4762a1bSJed Brown }
39c4762a1bSJed Brown 
40c4762a1bSJed Brown static PetscErrorCode MatCopy_User(Mat A,Mat X,MatStructure str)
41c4762a1bSJed Brown {
42c4762a1bSJed Brown   User           user,userX;
43c4762a1bSJed Brown 
44c4762a1bSJed Brown   PetscFunctionBegin;
455f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellGetContext(A,&user));
465f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellGetContext(X,&userX));
472c71b3e2SJacob Faibussowitsch   PetscCheckFalse(user != userX,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"This should not happen");
485f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectReference((PetscObject)user->B));
49c4762a1bSJed Brown   PetscFunctionReturn(0);
50c4762a1bSJed Brown }
51c4762a1bSJed Brown 
52c4762a1bSJed Brown static PetscErrorCode MatDestroy_User(Mat A)
53c4762a1bSJed Brown {
54c4762a1bSJed Brown   User           user;
55c4762a1bSJed Brown 
56c4762a1bSJed Brown   PetscFunctionBegin;
575f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellGetContext(A,&user));
585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectDereference((PetscObject)user->B));
59c4762a1bSJed Brown   PetscFunctionReturn(0);
60c4762a1bSJed Brown }
61c4762a1bSJed Brown 
62c4762a1bSJed Brown int main(int argc,char **args)
63c4762a1bSJed Brown {
64c4762a1bSJed Brown   User           user;
65c4762a1bSJed Brown   Mat            A,S;
66c4762a1bSJed Brown   PetscScalar    *data,diag = 1.3;
67c4762a1bSJed Brown   PetscReal      tol = PETSC_SMALL;
68c4762a1bSJed Brown   PetscInt       i,j,m = PETSC_DECIDE,n = PETSC_DECIDE,M = 17,N = 15,s1,s2;
69c4762a1bSJed Brown   PetscInt       test, ntest = 2;
70c4762a1bSJed Brown   PetscMPIInt    rank,size;
71c4762a1bSJed Brown   PetscBool      nc = PETSC_FALSE, cong, flg;
72c4762a1bSJed Brown   PetscBool      ronl = PETSC_TRUE;
73c4762a1bSJed Brown   PetscBool      randomize = PETSC_FALSE, submat = PETSC_FALSE;
74c4762a1bSJed Brown   PetscBool      keep = PETSC_FALSE;
75c4762a1bSJed Brown   PetscBool      testzerorows = PETSC_TRUE, testdiagscale = PETSC_TRUE, testgetdiag = PETSC_TRUE, testsubmat = PETSC_TRUE;
76c4762a1bSJed Brown   PetscBool      testshift = PETSC_TRUE, testscale = PETSC_TRUE, testdup = PETSC_TRUE, testreset = PETSC_TRUE;
77c4762a1bSJed Brown   PetscBool      testaxpy = PETSC_TRUE, testaxpyd = PETSC_TRUE, testaxpyerr = PETSC_FALSE;
78c4762a1bSJed Brown 
79*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscInitialize(&argc,&args,(char*)0,help));
805f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
815f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL));
835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL));
845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-ml",&m,NULL));
855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-nl",&n,NULL));
865f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-square_nc",&nc,NULL));
875f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-rows_only",&ronl,NULL));
885f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-randomize",&randomize,NULL));
895f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-submat",&submat,NULL));
905f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_zerorows",&testzerorows,NULL));
915f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_diagscale",&testdiagscale,NULL));
925f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_getdiag",&testgetdiag,NULL));
935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_shift",&testshift,NULL));
945f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_scale",&testscale,NULL));
955f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_dup",&testdup,NULL));
965f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_reset",&testreset,NULL));
975f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_submat",&testsubmat,NULL));
985f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_axpy",&testaxpy,NULL));
995f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_axpy_different",&testaxpyd,NULL));
1005f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-test_axpy_error",&testaxpyerr,NULL));
1015f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-loop",&ntest,NULL));
1025f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-tol",&tol,NULL));
1035f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetScalar(NULL,NULL,"-diag",&diag,NULL));
1045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-keep",&keep,NULL));
105c4762a1bSJed Brown   /* This tests square matrices with different row/col layout */
106c4762a1bSJed Brown   if (nc && size > 1) {
107c4762a1bSJed Brown     M = PetscMax(PetscMax(N,M),1);
108c4762a1bSJed Brown     N = M;
109c4762a1bSJed Brown     m = n = 0;
110c4762a1bSJed Brown     if (rank == 0) { m = M-1; n = 1; }
111c4762a1bSJed Brown     else if (rank == 1) { m = 1; n = N-1; }
112c4762a1bSJed Brown   }
1135f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateDense(PETSC_COMM_WORLD,m,n,M,N,NULL,&A));
1145f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetLocalSize(A,&m,&n));
1155f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetSize(A,&M,&N));
1165f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetOwnershipRange(A,&s1,NULL));
117c4762a1bSJed Brown   s2   = 1;
118c4762a1bSJed Brown   while (s2 < M) s2 *= 10;
1195f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseGetArray(A,&data));
120c4762a1bSJed Brown   for (j = 0; j < N; j++) {
121c4762a1bSJed Brown     for (i = 0; i < m; i++) {
122c4762a1bSJed Brown       data[j*m + i] = s2*j + i + s1 + 1;
123c4762a1bSJed Brown     }
124c4762a1bSJed Brown   }
1255f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
1265f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
127c4762a1bSJed Brown 
128c4762a1bSJed Brown   if (submat) {
129c4762a1bSJed Brown     Mat      A2;
130c4762a1bSJed Brown     IS       r,c;
131c4762a1bSJed Brown     PetscInt rst,ren,cst,cen;
132c4762a1bSJed Brown 
1335f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetOwnershipRange(A,&rst,&ren));
1345f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetOwnershipRangeColumn(A,&cst,&cen));
1355f80ce2aSJacob Faibussowitsch     CHKERRQ(ISCreateStride(PetscObjectComm((PetscObject)A),(ren-rst)/2,rst,1,&r));
1365f80ce2aSJacob Faibussowitsch     CHKERRQ(ISCreateStride(PetscObjectComm((PetscObject)A),(cen-cst)/2,cst,1,&c));
1375f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateSubMatrix(A,r,c,MAT_INITIAL_MATRIX,&A2));
1385f80ce2aSJacob Faibussowitsch     CHKERRQ(ISDestroy(&r));
1395f80ce2aSJacob Faibussowitsch     CHKERRQ(ISDestroy(&c));
1405f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&A));
141c4762a1bSJed Brown     A = A2;
142c4762a1bSJed Brown   }
143c4762a1bSJed Brown 
1445f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetSize(A,&M,&N));
1455f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetLocalSize(A,&m,&n));
1465f80ce2aSJacob Faibussowitsch   CHKERRQ(MatHasCongruentLayouts(A,&cong));
147c4762a1bSJed Brown 
1485f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvert(A,MATAIJ,MAT_INPLACE_MATRIX,&A));
1495f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetOption(A,MAT_KEEP_NONZERO_PATTERN,keep));
1505f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetName((PetscObject)A,"initial"));
1515f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(A,NULL,"-view_mat"));
152c4762a1bSJed Brown 
1535f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&user));
1545f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateShell(PETSC_COMM_WORLD,m,n,M,N,user,&S));
1555f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User));
1565f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User));
157c4762a1bSJed Brown   if (cong) {
1585f80ce2aSJacob Faibussowitsch     CHKERRQ(MatShellSetOperation(S,MATOP_GET_DIAGONAL,(void (*)(void))MatGetDiagonal_User));
159c4762a1bSJed Brown   }
1605f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellSetOperation(S,MATOP_COPY,(void (*)(void))MatCopy_User));
1615f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShellSetOperation(S,MATOP_DESTROY,(void (*)(void))MatDestroy_User));
1625f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDuplicate(A,MAT_COPY_VALUES,&user->B));
163c4762a1bSJed Brown 
164c4762a1bSJed Brown   /* Square and rows only scaling */
165c4762a1bSJed Brown   ronl = cong ? ronl : PETSC_TRUE;
166c4762a1bSJed Brown 
167c4762a1bSJed Brown   for (test = 0; test < ntest; test++) {
168c4762a1bSJed Brown     PetscReal err;
169c4762a1bSJed Brown 
1705f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultAddEqual(A,S,10,&flg));
171c4762a1bSJed Brown     if (!flg) {
1725f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mult add\n",test));
173c4762a1bSJed Brown     }
1745f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTransposeAddEqual(A,S,10,&flg));
175c4762a1bSJed Brown     if (!flg) {
1765f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mult add (T)\n",test));
177c4762a1bSJed Brown     }
178c4762a1bSJed Brown     if (testzerorows) {
179c4762a1bSJed Brown       Mat       ST,B,C,BT,BTT;
180c4762a1bSJed Brown       IS        zr;
181c4762a1bSJed Brown       Vec       x = NULL, b1 = NULL, b2 = NULL;
182c4762a1bSJed Brown       PetscInt  *idxs = NULL, nr = 0;
183c4762a1bSJed Brown 
184c4762a1bSJed Brown       if (rank == (test%size)) {
185c4762a1bSJed Brown         nr = 1;
1865f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscMalloc1(nr,&idxs));
187c4762a1bSJed Brown         if (test%2) {
188c4762a1bSJed Brown           idxs[0] = (2*M - 1 - test/2)%M;
189c4762a1bSJed Brown         } else {
190c4762a1bSJed Brown           idxs[0] = (test/2)%M;
191c4762a1bSJed Brown         }
192c4762a1bSJed Brown         idxs[0] = PetscMax(idxs[0],0);
193c4762a1bSJed Brown       }
1945f80ce2aSJacob Faibussowitsch       CHKERRQ(ISCreateGeneral(PETSC_COMM_WORLD,nr,idxs,PETSC_OWN_POINTER,&zr));
1955f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject)zr,"ZR"));
1965f80ce2aSJacob Faibussowitsch       CHKERRQ(ISViewFromOptions(zr,NULL,"-view_is"));
1975f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(A,&x,&b1));
198c4762a1bSJed Brown       if (randomize) {
1995f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSetRandom(x,NULL));
2005f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSetRandom(b1,NULL));
201c4762a1bSJed Brown       } else {
2025f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSet(x,11.4));
2035f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSet(b1,-14.2));
204c4762a1bSJed Brown       }
2055f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDuplicate(b1,&b2));
2065f80ce2aSJacob Faibussowitsch       CHKERRQ(VecCopy(b1,b2));
2075f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject)b1,"A_B1"));
2085f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject)b2,"A_B2"));
209c4762a1bSJed Brown       if (size > 1 && !cong) { /* MATMPIAIJ ZeroRows and ZeroRowsColumns are buggy in this case */
2105f80ce2aSJacob Faibussowitsch         CHKERRQ(VecDestroy(&b1));
211c4762a1bSJed Brown       }
212c4762a1bSJed Brown       if (ronl) {
2135f80ce2aSJacob Faibussowitsch         CHKERRQ(MatZeroRowsIS(A,zr,diag,x,b1));
2145f80ce2aSJacob Faibussowitsch         CHKERRQ(MatZeroRowsIS(S,zr,diag,x,b2));
215c4762a1bSJed Brown       } else {
2165f80ce2aSJacob Faibussowitsch         CHKERRQ(MatZeroRowsColumnsIS(A,zr,diag,x,b1));
2175f80ce2aSJacob Faibussowitsch         CHKERRQ(MatZeroRowsColumnsIS(S,zr,diag,x,b2));
2185f80ce2aSJacob Faibussowitsch         CHKERRQ(ISDestroy(&zr));
219c4762a1bSJed Brown         /* Mix zerorows and zerorowscols */
220c4762a1bSJed Brown         nr   = 0;
221c4762a1bSJed Brown         idxs = NULL;
222dd400576SPatrick Sanan         if (rank == 0) {
223c4762a1bSJed Brown           nr   = 1;
2245f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscMalloc1(nr,&idxs));
225c4762a1bSJed Brown           if (test%2) {
226c4762a1bSJed Brown             idxs[0] = (3*M - 2 - test/2)%M;
227c4762a1bSJed Brown           } else {
228c4762a1bSJed Brown             idxs[0] = (test/2+1)%M;
229c4762a1bSJed Brown           }
230c4762a1bSJed Brown           idxs[0] = PetscMax(idxs[0],0);
231c4762a1bSJed Brown         }
2325f80ce2aSJacob Faibussowitsch         CHKERRQ(ISCreateGeneral(PETSC_COMM_WORLD,nr,idxs,PETSC_OWN_POINTER,&zr));
2335f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectSetName((PetscObject)zr,"ZR2"));
2345f80ce2aSJacob Faibussowitsch         CHKERRQ(ISViewFromOptions(zr,NULL,"-view_is"));
2355f80ce2aSJacob Faibussowitsch         CHKERRQ(MatZeroRowsIS(A,zr,diag*2.0+PETSC_SMALL,NULL,NULL));
2365f80ce2aSJacob Faibussowitsch         CHKERRQ(MatZeroRowsIS(S,zr,diag*2.0+PETSC_SMALL,NULL,NULL));
237c4762a1bSJed Brown       }
2385f80ce2aSJacob Faibussowitsch       CHKERRQ(ISDestroy(&zr));
239c4762a1bSJed Brown 
240c4762a1bSJed Brown       if (b1) {
241c4762a1bSJed Brown         Vec b;
242c4762a1bSJed Brown 
2435f80ce2aSJacob Faibussowitsch         CHKERRQ(VecViewFromOptions(b1,NULL,"-view_b"));
2445f80ce2aSJacob Faibussowitsch         CHKERRQ(VecViewFromOptions(b2,NULL,"-view_b"));
2455f80ce2aSJacob Faibussowitsch         CHKERRQ(VecDuplicate(b1,&b));
2465f80ce2aSJacob Faibussowitsch         CHKERRQ(VecCopy(b1,b));
2475f80ce2aSJacob Faibussowitsch         CHKERRQ(VecAXPY(b,-1.0,b2));
2485f80ce2aSJacob Faibussowitsch         CHKERRQ(VecNorm(b,NORM_INFINITY,&err));
249c4762a1bSJed Brown         if (err >= tol) {
2505f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error b %g\n",test,(double)err));
251c4762a1bSJed Brown         }
2525f80ce2aSJacob Faibussowitsch         CHKERRQ(VecDestroy(&b));
253c4762a1bSJed Brown       }
2545f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&b1));
2555f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&b2));
2565f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&x));
2575f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(S,MATDENSE,MAT_INITIAL_MATRIX,&B));
258c4762a1bSJed Brown 
2595f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateTranspose(S,&ST));
2605f80ce2aSJacob Faibussowitsch       CHKERRQ(MatComputeOperator(ST,MATDENSE,&BT));
2615f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(BT,MAT_INITIAL_MATRIX,&BTT));
2625f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject)B,"S"));
2635f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject)BTT,"STT"));
2645f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&C));
2655f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject)C,"A"));
266c4762a1bSJed Brown 
2675f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(C,NULL,"-view_mat"));
2685f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(B,NULL,"-view_mat"));
2695f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(BTT,NULL,"-view_mat"));
270c4762a1bSJed Brown 
2715f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN));
2725f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(C,NORM_FROBENIUS,&err));
273c4762a1bSJed Brown       if (err >= tol) {
2745f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mat mult after %s %g\n",test,ronl ? "MatZeroRows" : "MatZeroRowsColumns",(double)err));
275c4762a1bSJed Brown       }
276c4762a1bSJed Brown 
2775f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(A,MATDENSE,MAT_REUSE_MATRIX,&C));
2785f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(C,-1.0,BTT,SAME_NONZERO_PATTERN));
2795f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(C,NORM_FROBENIUS,&err));
280c4762a1bSJed Brown       if (err >= tol) {
2815f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mat mult transpose after %s %g\n",test,ronl ? "MatZeroRows" : "MatZeroRowsColumns",(double)err));
282c4762a1bSJed Brown       }
283c4762a1bSJed Brown 
2845f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&ST));
2855f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&BTT));
2865f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&BT));
2875f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&B));
2885f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&C));
289c4762a1bSJed Brown     }
290c4762a1bSJed Brown     if (testdiagscale) { /* MatDiagonalScale() */
291c4762a1bSJed Brown       Vec vr,vl;
292c4762a1bSJed Brown 
2935f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(A,&vr,&vl));
294c4762a1bSJed Brown       if (randomize) {
2955f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSetRandom(vr,NULL));
2965f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSetRandom(vl,NULL));
297c4762a1bSJed Brown       } else {
2985f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSet(vr,test%2 ? 0.15 : 1.0/0.15));
2995f80ce2aSJacob Faibussowitsch         CHKERRQ(VecSet(vl,test%2 ? -1.2 : 1.0/-1.2));
300c4762a1bSJed Brown       }
3015f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDiagonalScale(A,vl,vr));
3025f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDiagonalScale(S,vl,vr));
3035f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&vr));
3045f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&vl));
305c4762a1bSJed Brown     }
306c4762a1bSJed Brown 
307c4762a1bSJed Brown     if (testscale) { /* MatScale() */
3085f80ce2aSJacob Faibussowitsch       CHKERRQ(MatScale(A,test%2 ? 1.4 : 1.0/1.4));
3095f80ce2aSJacob Faibussowitsch       CHKERRQ(MatScale(S,test%2 ? 1.4 : 1.0/1.4));
310c4762a1bSJed Brown     }
311c4762a1bSJed Brown 
312c4762a1bSJed Brown     if (testshift && cong) { /* MatShift() : MATSHELL shift is broken when row/cols layout are not congruent and left/right scaling have been applied */
3135f80ce2aSJacob Faibussowitsch       CHKERRQ(MatShift(A,test%2 ? -77.5 : 77.5));
3145f80ce2aSJacob Faibussowitsch       CHKERRQ(MatShift(S,test%2 ? -77.5 : 77.5));
315c4762a1bSJed Brown     }
316c4762a1bSJed Brown 
317c4762a1bSJed Brown     if (testgetdiag && cong) { /* MatGetDiagonal() */
318c4762a1bSJed Brown       Vec dA,dS;
319c4762a1bSJed Brown 
3205f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(A,&dA,NULL));
3215f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(S,&dS,NULL));
3225f80ce2aSJacob Faibussowitsch       CHKERRQ(MatGetDiagonal(A,dA));
3235f80ce2aSJacob Faibussowitsch       CHKERRQ(MatGetDiagonal(S,dS));
3245f80ce2aSJacob Faibussowitsch       CHKERRQ(VecAXPY(dA,-1.0,dS));
3255f80ce2aSJacob Faibussowitsch       CHKERRQ(VecNorm(dA,NORM_INFINITY,&err));
326c4762a1bSJed Brown       if (err >= tol) {
3275f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error diag %g\n",test,(double)err));
328c4762a1bSJed Brown       }
3295f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&dA));
3305f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&dS));
331c4762a1bSJed Brown     }
332c4762a1bSJed Brown 
333c4762a1bSJed Brown     if (testdup && !test) {
334c4762a1bSJed Brown       Mat A2, S2;
335c4762a1bSJed Brown 
3365f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(A,MAT_COPY_VALUES,&A2));
3375f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(S,MAT_COPY_VALUES,&S2));
3385f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&A));
3395f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&S));
340c4762a1bSJed Brown       A = A2;
341c4762a1bSJed Brown       S = S2;
342c4762a1bSJed Brown     }
343c4762a1bSJed Brown 
344c4762a1bSJed Brown     if (testsubmat) {
345c4762a1bSJed Brown       Mat      sA,sS,dA,dS,At,St;
346c4762a1bSJed Brown       IS       r,c;
347c4762a1bSJed Brown       PetscInt rst,ren,cst,cen;
348c4762a1bSJed Brown 
3495f80ce2aSJacob Faibussowitsch       CHKERRQ(MatGetOwnershipRange(A,&rst,&ren));
3505f80ce2aSJacob Faibussowitsch       CHKERRQ(MatGetOwnershipRangeColumn(A,&cst,&cen));
3515f80ce2aSJacob Faibussowitsch       CHKERRQ(ISCreateStride(PetscObjectComm((PetscObject)A),(ren-rst)/2,rst,1,&r));
3525f80ce2aSJacob Faibussowitsch       CHKERRQ(ISCreateStride(PetscObjectComm((PetscObject)A),(cen-cst)/2,cst,1,&c));
3535f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateSubMatrix(A,r,c,MAT_INITIAL_MATRIX,&sA));
3545f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateSubMatrix(S,r,c,MAT_INITIAL_MATRIX,&sS));
3555f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultAddEqual(sA,sS,10,&flg));
356c4762a1bSJed Brown       if (!flg) {
3575f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error submatrix mult add\n",test));
358c4762a1bSJed Brown       }
3595f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultTransposeAddEqual(sA,sS,10,&flg));
360c4762a1bSJed Brown       if (!flg) {
3615f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error submatrix mult add (T)\n",test));
362c4762a1bSJed Brown       }
3635f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(sA,MATDENSE,MAT_INITIAL_MATRIX,&dA));
3645f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(sS,MATDENSE,MAT_INITIAL_MATRIX,&dS));
3655f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(dA,-1.0,dS,SAME_NONZERO_PATTERN));
3665f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(dA,NORM_FROBENIUS,&err));
367c4762a1bSJed Brown       if (err >= tol) {
3685f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mat submatrix %g\n",test,(double)err));
369c4762a1bSJed Brown       }
3705f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&sA));
3715f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&sS));
3725f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&dA));
3735f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&dS));
3745f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateTranspose(A,&At));
3755f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateTranspose(S,&St));
3765f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateSubMatrix(At,c,r,MAT_INITIAL_MATRIX,&sA));
3775f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateSubMatrix(St,c,r,MAT_INITIAL_MATRIX,&sS));
3785f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultAddEqual(sA,sS,10,&flg));
379c4762a1bSJed Brown       if (!flg) {
3805f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error submatrix (T) mult add\n",test));
381c4762a1bSJed Brown       }
3825f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultTransposeAddEqual(sA,sS,10,&flg));
383c4762a1bSJed Brown       if (!flg) {
3845f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error submatrix (T) mult add (T)\n",test));
385c4762a1bSJed Brown       }
3865f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(sA,MATDENSE,MAT_INITIAL_MATRIX,&dA));
3875f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(sS,MATDENSE,MAT_INITIAL_MATRIX,&dS));
3885f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(dA,-1.0,dS,SAME_NONZERO_PATTERN));
3895f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(dA,NORM_FROBENIUS,&err));
390c4762a1bSJed Brown       if (err >= tol) {
3915f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mat submatrix (T) %g\n",test,(double)err));
392c4762a1bSJed Brown       }
3935f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&sA));
3945f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&sS));
3955f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&dA));
3965f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&dS));
3975f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&At));
3985f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&St));
3995f80ce2aSJacob Faibussowitsch       CHKERRQ(ISDestroy(&r));
4005f80ce2aSJacob Faibussowitsch       CHKERRQ(ISDestroy(&c));
401c4762a1bSJed Brown     }
402c4762a1bSJed Brown 
403c4762a1bSJed Brown     if (testaxpy) {
404c4762a1bSJed Brown       Mat          tA,tS,dA,dS;
405c4762a1bSJed Brown       MatStructure str[3] = { SAME_NONZERO_PATTERN, SUBSET_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN };
406c4762a1bSJed Brown 
4075f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(A,MAT_COPY_VALUES,&tA));
408c4762a1bSJed Brown       if (testaxpyd && !(test%2)) {
4095f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectReference((PetscObject)tA));
410c4762a1bSJed Brown         tS   = tA;
411c4762a1bSJed Brown       } else {
4125f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectReference((PetscObject)S));
413c4762a1bSJed Brown         tS   = S;
414c4762a1bSJed Brown       }
4155f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(A,0.5,tA,str[test%3]));
4165f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(S,0.5,tS,str[test%3]));
417c4762a1bSJed Brown       /* this will trigger an error the next MatMult or MatMultTranspose call for S */
4185f80ce2aSJacob Faibussowitsch       if (testaxpyerr) CHKERRQ(MatScale(tA,0));
4195f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&tA));
4205f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&tS));
4215f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultAddEqual(A,S,10,&flg));
422c4762a1bSJed Brown       if (!flg) {
4235f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error axpy mult add\n",test));
424c4762a1bSJed Brown       }
4255f80ce2aSJacob Faibussowitsch       CHKERRQ(MatMultTransposeAddEqual(A,S,10,&flg));
426c4762a1bSJed Brown       if (!flg) {
4275f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error axpy mult add (T)\n",test));
428c4762a1bSJed Brown       }
4295f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&dA));
4305f80ce2aSJacob Faibussowitsch       CHKERRQ(MatConvert(S,MATDENSE,MAT_INITIAL_MATRIX,&dS));
4315f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(dA,-1.0,dS,SAME_NONZERO_PATTERN));
4325f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(dA,NORM_FROBENIUS,&err));
433c4762a1bSJed Brown       if (err >= tol) {
4345f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"[test %" PetscInt_FMT "] Error mat submatrix %g\n",test,(double)err));
435c4762a1bSJed Brown       }
4365f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&dA));
4375f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&dS));
438c4762a1bSJed Brown     }
439c4762a1bSJed Brown 
440c4762a1bSJed Brown     if (testreset && (ntest == 1 || test == ntest-2)) {
441c4762a1bSJed Brown       /* reset MATSHELL */
4425f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAssemblyBegin(S,MAT_FINAL_ASSEMBLY));
4435f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAssemblyEnd(S,MAT_FINAL_ASSEMBLY));
444c4762a1bSJed Brown       /* reset A */
4455f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCopy(user->B,A,DIFFERENT_NONZERO_PATTERN));
446c4762a1bSJed Brown     }
447c4762a1bSJed Brown   }
448c4762a1bSJed Brown 
4495f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&A));
4505f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&S));
4515f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(user));
452*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscFinalize());
453*b122ec5aSJacob Faibussowitsch   return 0;
454c4762a1bSJed Brown }
455c4762a1bSJed Brown 
456c4762a1bSJed Brown /*TEST
457c4762a1bSJed Brown 
458c4762a1bSJed Brown    testset:
459c4762a1bSJed Brown      suffix: rect
460c4762a1bSJed Brown      requires: !single
461c4762a1bSJed Brown      output_file: output/ex221_1.out
462c4762a1bSJed Brown      nsize: {{1 3}}
463c4762a1bSJed Brown      args: -loop 3 -keep {{0 1}} -M {{12 19}} -N {{19 12}} -submat {{0 1}} -test_axpy_different {{0 1}}
464c4762a1bSJed Brown 
465c4762a1bSJed Brown    testset:
466c4762a1bSJed Brown      suffix: square
467c4762a1bSJed Brown      requires: !single
468c4762a1bSJed Brown      output_file: output/ex221_1.out
469c4762a1bSJed Brown      nsize: {{1 3}}
470c4762a1bSJed Brown      args: -M 21 -N 21 -loop 4 -rows_only {{0 1}} -keep {{0 1}} -submat {{0 1}} -test_axpy_different {{0 1}}
471c4762a1bSJed Brown TEST*/
472