1c4762a1bSJed Brown 2c4762a1bSJed Brown static char help[] = "Tests the various sequential routines in MATSEQSBAIJ format.\n"; 3c4762a1bSJed Brown 4c4762a1bSJed Brown #include <petscmat.h> 5c4762a1bSJed Brown 6*d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 7*d71ae5a4SJacob Faibussowitsch { 8c4762a1bSJed Brown PetscMPIInt size; 9c4762a1bSJed Brown Vec x, y, b, s1, s2; 10c4762a1bSJed Brown Mat A; /* linear system matrix */ 11c4762a1bSJed Brown Mat sA, sB, sFactor, B, C; /* symmetric matrices */ 12c4762a1bSJed Brown PetscInt n, mbs = 16, bs = 1, nz = 3, prob = 1, i, j, k1, k2, col[3], lf, block, row, Ii, J, n1, inc; 13c4762a1bSJed Brown PetscReal norm1, norm2, rnorm, tol = 10 * PETSC_SMALL; 14c4762a1bSJed Brown PetscScalar neg_one = -1.0, four = 4.0, value[3]; 15c4762a1bSJed Brown IS perm, iscol; 16c4762a1bSJed Brown PetscRandom rdm; 17c4762a1bSJed Brown PetscBool doIcc = PETSC_TRUE, equal; 18c4762a1bSJed Brown MatInfo minfo1, minfo2; 19c4762a1bSJed Brown MatFactorInfo factinfo; 20c4762a1bSJed Brown MatType type; 21c4762a1bSJed Brown 22327415f7SBarry Smith PetscFunctionBeginUser; 239566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 25be096a46SBarry Smith PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only!"); 269566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-bs", &bs, NULL)); 279566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-mbs", &mbs, NULL)); 28c4762a1bSJed Brown 29c4762a1bSJed Brown n = mbs * bs; 309566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_SELF, &A)); 319566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, n, n, PETSC_DETERMINE, PETSC_DETERMINE)); 329566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATSEQBAIJ)); 339566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 349566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(A, bs, nz, NULL)); 35c4762a1bSJed Brown 369566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_SELF, &sA)); 379566063dSJacob Faibussowitsch PetscCall(MatSetSizes(sA, n, n, PETSC_DETERMINE, PETSC_DETERMINE)); 389566063dSJacob Faibussowitsch PetscCall(MatSetType(sA, MATSEQSBAIJ)); 399566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(sA)); 409566063dSJacob Faibussowitsch PetscCall(MatGetType(sA, &type)); 419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)sA, MATSEQSBAIJ, &doIcc)); 429566063dSJacob Faibussowitsch PetscCall(MatSeqSBAIJSetPreallocation(sA, bs, nz, NULL)); 439566063dSJacob Faibussowitsch PetscCall(MatSetOption(sA, MAT_IGNORE_LOWER_TRIANGULAR, PETSC_TRUE)); 44c4762a1bSJed Brown 45c4762a1bSJed Brown /* Test MatGetOwnershipRange() */ 469566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &Ii, &J)); 479566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(sA, &i, &j)); 4848a46eb9SPierre Jolivet if (i - Ii || j - J) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatGetOwnershipRange() in MatSBAIJ format\n")); 49c4762a1bSJed Brown 50c4762a1bSJed Brown /* Assemble matrix */ 51c4762a1bSJed Brown if (bs == 1) { 529566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-test_problem", &prob, NULL)); 53c4762a1bSJed Brown if (prob == 1) { /* tridiagonal matrix */ 549371c9d4SSatish Balay value[0] = -1.0; 559371c9d4SSatish Balay value[1] = 2.0; 569371c9d4SSatish Balay value[2] = -1.0; 57c4762a1bSJed Brown for (i = 1; i < n - 1; i++) { 589371c9d4SSatish Balay col[0] = i - 1; 599371c9d4SSatish Balay col[1] = i; 609371c9d4SSatish Balay col[2] = i + 1; 619566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 3, col, value, INSERT_VALUES)); 629566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 3, col, value, INSERT_VALUES)); 63c4762a1bSJed Brown } 649371c9d4SSatish Balay i = n - 1; 659371c9d4SSatish Balay col[0] = 0; 669371c9d4SSatish Balay col[1] = n - 2; 679371c9d4SSatish Balay col[2] = n - 1; 68c4762a1bSJed Brown 699371c9d4SSatish Balay value[0] = 0.1; 709371c9d4SSatish Balay value[1] = -1; 719371c9d4SSatish Balay value[2] = 2; 72c4762a1bSJed Brown 739566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 3, col, value, INSERT_VALUES)); 749566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 3, col, value, INSERT_VALUES)); 75c4762a1bSJed Brown 76c4762a1bSJed Brown i = 0; 779371c9d4SSatish Balay col[0] = n - 1; 789371c9d4SSatish Balay col[1] = 1; 799371c9d4SSatish Balay col[2] = 0; 809371c9d4SSatish Balay value[0] = 0.1; 819371c9d4SSatish Balay value[1] = -1.0; 829371c9d4SSatish Balay value[2] = 2; 83c4762a1bSJed Brown 849566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 3, col, value, INSERT_VALUES)); 859566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 3, col, value, INSERT_VALUES)); 86c4762a1bSJed Brown 87c4762a1bSJed Brown } else if (prob == 2) { /* matrix for the five point stencil */ 88c4762a1bSJed Brown n1 = (PetscInt)(PetscSqrtReal((PetscReal)n) + 0.001); 89bc30f867SBarry Smith PetscCheck(n1 * n1 == n, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "sqrt(n) must be a positive integer!"); 90c4762a1bSJed Brown for (i = 0; i < n1; i++) { 91c4762a1bSJed Brown for (j = 0; j < n1; j++) { 92c4762a1bSJed Brown Ii = j + n1 * i; 93c4762a1bSJed Brown if (i > 0) { 94c4762a1bSJed Brown J = Ii - n1; 959566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 969566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 97c4762a1bSJed Brown } 98c4762a1bSJed Brown if (i < n1 - 1) { 99c4762a1bSJed Brown J = Ii + n1; 1009566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 1019566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 102c4762a1bSJed Brown } 103c4762a1bSJed Brown if (j > 0) { 104c4762a1bSJed Brown J = Ii - 1; 1059566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 1069566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 107c4762a1bSJed Brown } 108c4762a1bSJed Brown if (j < n1 - 1) { 109c4762a1bSJed Brown J = Ii + 1; 1109566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 1119566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &Ii, 1, &J, &neg_one, INSERT_VALUES)); 112c4762a1bSJed Brown } 1139566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &Ii, 1, &Ii, &four, INSERT_VALUES)); 1149566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &Ii, 1, &Ii, &four, INSERT_VALUES)); 115c4762a1bSJed Brown } 116c4762a1bSJed Brown } 117c4762a1bSJed Brown } 118c4762a1bSJed Brown 119c4762a1bSJed Brown } else { /* bs > 1 */ 120c4762a1bSJed Brown for (block = 0; block < n / bs; block++) { 121c4762a1bSJed Brown /* diagonal blocks */ 1229371c9d4SSatish Balay value[0] = -1.0; 1239371c9d4SSatish Balay value[1] = 4.0; 1249371c9d4SSatish Balay value[2] = -1.0; 125c4762a1bSJed Brown for (i = 1 + block * bs; i < bs - 1 + block * bs; i++) { 1269371c9d4SSatish Balay col[0] = i - 1; 1279371c9d4SSatish Balay col[1] = i; 1289371c9d4SSatish Balay col[2] = i + 1; 1299566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 3, col, value, INSERT_VALUES)); 1309566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 3, col, value, INSERT_VALUES)); 131c4762a1bSJed Brown } 1329371c9d4SSatish Balay i = bs - 1 + block * bs; 1339371c9d4SSatish Balay col[0] = bs - 2 + block * bs; 1349371c9d4SSatish Balay col[1] = bs - 1 + block * bs; 135c4762a1bSJed Brown 1369371c9d4SSatish Balay value[0] = -1.0; 1379371c9d4SSatish Balay value[1] = 4.0; 138c4762a1bSJed Brown 1399566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 2, col, value, INSERT_VALUES)); 1409566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 2, col, value, INSERT_VALUES)); 141c4762a1bSJed Brown 1429371c9d4SSatish Balay i = 0 + block * bs; 1439371c9d4SSatish Balay col[0] = 0 + block * bs; 1449371c9d4SSatish Balay col[1] = 1 + block * bs; 145c4762a1bSJed Brown 1469371c9d4SSatish Balay value[0] = 4.0; 1479371c9d4SSatish Balay value[1] = -1.0; 148c4762a1bSJed Brown 1499566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 2, col, value, INSERT_VALUES)); 1509566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 2, col, value, INSERT_VALUES)); 151c4762a1bSJed Brown } 152c4762a1bSJed Brown /* off-diagonal blocks */ 153c4762a1bSJed Brown value[0] = -1.0; 154c4762a1bSJed Brown for (i = 0; i < (n / bs - 1) * bs; i++) { 155c4762a1bSJed Brown col[0] = i + bs; 156c4762a1bSJed Brown 1579566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, 1, col, value, INSERT_VALUES)); 1589566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &i, 1, col, value, INSERT_VALUES)); 159c4762a1bSJed Brown 1609371c9d4SSatish Balay col[0] = i; 1619371c9d4SSatish Balay row = i + bs; 162c4762a1bSJed Brown 1639566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &row, 1, col, value, INSERT_VALUES)); 1649566063dSJacob Faibussowitsch PetscCall(MatSetValues(sA, 1, &row, 1, col, value, INSERT_VALUES)); 165c4762a1bSJed Brown } 166c4762a1bSJed Brown } 1679566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1689566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 169c4762a1bSJed Brown 1709566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(sA, MAT_FINAL_ASSEMBLY)); 1719566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(sA, MAT_FINAL_ASSEMBLY)); 172c4762a1bSJed Brown 173c4762a1bSJed Brown /* Test MatGetInfo() of A and sA */ 1749566063dSJacob Faibussowitsch PetscCall(MatGetInfo(A, MAT_LOCAL, &minfo1)); 1759566063dSJacob Faibussowitsch PetscCall(MatGetInfo(sA, MAT_LOCAL, &minfo2)); 176c4762a1bSJed Brown i = (int)(minfo1.nz_used - minfo2.nz_used); 177c4762a1bSJed Brown j = (int)(minfo1.nz_allocated - minfo2.nz_allocated); 178c4762a1bSJed Brown k1 = (int)(minfo1.nz_allocated - minfo1.nz_used); 179c4762a1bSJed Brown k2 = (int)(minfo2.nz_allocated - minfo2.nz_used); 18048a46eb9SPierre Jolivet if (i < 0 || j < 0 || k1 < 0 || k2 < 0) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error (compare A and sA): MatGetInfo()\n")); 181c4762a1bSJed Brown 182c4762a1bSJed Brown /* Test MatDuplicate() */ 1839566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &norm1)); 1849566063dSJacob Faibussowitsch PetscCall(MatDuplicate(sA, MAT_COPY_VALUES, &sB)); 1859566063dSJacob Faibussowitsch PetscCall(MatEqual(sA, sB, &equal)); 18628b400f6SJacob Faibussowitsch PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMETYPE, "Error in MatDuplicate()"); 187c4762a1bSJed Brown 188c4762a1bSJed Brown /* Test MatNorm() */ 1899566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &norm1)); 1909566063dSJacob Faibussowitsch PetscCall(MatNorm(sB, NORM_FROBENIUS, &norm2)); 191c4762a1bSJed Brown rnorm = PetscAbsReal(norm1 - norm2) / norm2; 19248a46eb9SPierre Jolivet if (rnorm > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatNorm_FROBENIUS, NormA=%16.14e NormsB=%16.14e\n", (double)norm1, (double)norm2)); 1939566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_INFINITY, &norm1)); 1949566063dSJacob Faibussowitsch PetscCall(MatNorm(sB, NORM_INFINITY, &norm2)); 195c4762a1bSJed Brown rnorm = PetscAbsReal(norm1 - norm2) / norm2; 19648a46eb9SPierre Jolivet if (rnorm > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatNorm_INFINITY(), NormA=%16.14e NormsB=%16.14e\n", (double)norm1, (double)norm2)); 1979566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_1, &norm1)); 1989566063dSJacob Faibussowitsch PetscCall(MatNorm(sB, NORM_1, &norm2)); 199c4762a1bSJed Brown rnorm = PetscAbsReal(norm1 - norm2) / norm2; 20048a46eb9SPierre Jolivet if (rnorm > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatNorm_INFINITY(), NormA=%16.14e NormsB=%16.14e\n", (double)norm1, (double)norm2)); 201c4762a1bSJed Brown 202c4762a1bSJed Brown /* Test MatGetInfo(), MatGetSize(), MatGetBlockSize() */ 2039566063dSJacob Faibussowitsch PetscCall(MatGetInfo(A, MAT_LOCAL, &minfo1)); 2049566063dSJacob Faibussowitsch PetscCall(MatGetInfo(sB, MAT_LOCAL, &minfo2)); 205c4762a1bSJed Brown i = (int)(minfo1.nz_used - minfo2.nz_used); 206c4762a1bSJed Brown j = (int)(minfo1.nz_allocated - minfo2.nz_allocated); 207c4762a1bSJed Brown k1 = (int)(minfo1.nz_allocated - minfo1.nz_used); 208c4762a1bSJed Brown k2 = (int)(minfo2.nz_allocated - minfo2.nz_used); 20948a46eb9SPierre Jolivet if (i < 0 || j < 0 || k1 < 0 || k2 < 0) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error(compare A and sB): MatGetInfo()\n")); 210c4762a1bSJed Brown 2119566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &Ii, &J)); 2129566063dSJacob Faibussowitsch PetscCall(MatGetSize(sB, &i, &j)); 21348a46eb9SPierre Jolivet if (i - Ii || j - J) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatGetSize()\n")); 214c4762a1bSJed Brown 2159566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(A, &Ii)); 2169566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(sB, &i)); 21748a46eb9SPierre Jolivet if (i - Ii) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatGetBlockSize()\n")); 218c4762a1bSJed Brown 2199566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PETSC_COMM_SELF, &rdm)); 2209566063dSJacob Faibussowitsch PetscCall(PetscRandomSetFromOptions(rdm)); 2219566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, n, &x)); 2229566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &s1)); 2239566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &s2)); 2249566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &y)); 2259566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &b)); 2269566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, rdm)); 227c4762a1bSJed Brown 228c4762a1bSJed Brown /* Test MatDiagonalScale(), MatGetDiagonal(), MatScale() */ 229c4762a1bSJed Brown #if !defined(PETSC_USE_COMPLEX) 230c4762a1bSJed Brown /* Scaling matrix with complex numbers results non-spd matrix, 231c4762a1bSJed Brown causing crash of MatForwardSolve() and MatBackwardSolve() */ 2329566063dSJacob Faibussowitsch PetscCall(MatDiagonalScale(A, x, x)); 2339566063dSJacob Faibussowitsch PetscCall(MatDiagonalScale(sB, x, x)); 2349566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A, sB, 10, &equal)); 23528b400f6SJacob Faibussowitsch PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMETYPE, "Error in MatDiagonalScale"); 236c4762a1bSJed Brown 2379566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(A, s1)); 2389566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(sB, s2)); 2399566063dSJacob Faibussowitsch PetscCall(VecAXPY(s2, neg_one, s1)); 2409566063dSJacob Faibussowitsch PetscCall(VecNorm(s2, NORM_1, &norm1)); 24148a46eb9SPierre Jolivet if (norm1 > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error:MatGetDiagonal(), ||s1-s2||=%g\n", (double)norm1)); 242c4762a1bSJed Brown 243c4762a1bSJed Brown { 244c4762a1bSJed Brown PetscScalar alpha = 0.1; 2459566063dSJacob Faibussowitsch PetscCall(MatScale(A, alpha)); 2469566063dSJacob Faibussowitsch PetscCall(MatScale(sB, alpha)); 247c4762a1bSJed Brown } 248c4762a1bSJed Brown #endif 249c4762a1bSJed Brown 250c4762a1bSJed Brown /* Test MatGetRowMaxAbs() */ 2519566063dSJacob Faibussowitsch PetscCall(MatGetRowMaxAbs(A, s1, NULL)); 2529566063dSJacob Faibussowitsch PetscCall(MatGetRowMaxAbs(sB, s2, NULL)); 2539566063dSJacob Faibussowitsch PetscCall(VecNorm(s1, NORM_1, &norm1)); 2549566063dSJacob Faibussowitsch PetscCall(VecNorm(s2, NORM_1, &norm2)); 255c4762a1bSJed Brown norm1 -= norm2; 25648a46eb9SPierre Jolivet if (norm1 < -tol || norm1 > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error:MatGetRowMaxAbs() \n")); 257c4762a1bSJed Brown 258c4762a1bSJed Brown /* Test MatMult() */ 259c4762a1bSJed Brown for (i = 0; i < 40; i++) { 2609566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, rdm)); 2619566063dSJacob Faibussowitsch PetscCall(MatMult(A, x, s1)); 2629566063dSJacob Faibussowitsch PetscCall(MatMult(sB, x, s2)); 2639566063dSJacob Faibussowitsch PetscCall(VecNorm(s1, NORM_1, &norm1)); 2649566063dSJacob Faibussowitsch PetscCall(VecNorm(s2, NORM_1, &norm2)); 265c4762a1bSJed Brown norm1 -= norm2; 26648a46eb9SPierre Jolivet if (norm1 < -tol || norm1 > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error: MatMult(), norm1-norm2: %g\n", (double)norm1)); 267c4762a1bSJed Brown } 268c4762a1bSJed Brown 269c4762a1bSJed Brown /* MatMultAdd() */ 270c4762a1bSJed Brown for (i = 0; i < 40; i++) { 2719566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, rdm)); 2729566063dSJacob Faibussowitsch PetscCall(VecSetRandom(y, rdm)); 2739566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, x, y, s1)); 2749566063dSJacob Faibussowitsch PetscCall(MatMultAdd(sB, x, y, s2)); 2759566063dSJacob Faibussowitsch PetscCall(VecNorm(s1, NORM_1, &norm1)); 2769566063dSJacob Faibussowitsch PetscCall(VecNorm(s2, NORM_1, &norm2)); 277c4762a1bSJed Brown norm1 -= norm2; 27848a46eb9SPierre Jolivet if (norm1 < -tol || norm1 > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error:MatMultAdd(), norm1-norm2: %g\n", (double)norm1)); 279c4762a1bSJed Brown } 280c4762a1bSJed Brown 281c20d7725SJed Brown /* Test MatMatMult() for sbaij and dense matrices */ 2829566063dSJacob Faibussowitsch PetscCall(MatCreateSeqDense(PETSC_COMM_SELF, n, 5 * n, NULL, &B)); 2839566063dSJacob Faibussowitsch PetscCall(MatSetRandom(B, rdm)); 2849566063dSJacob Faibussowitsch PetscCall(MatMatMult(sA, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &C)); 2859566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(sA, B, C, 5 * n, &equal)); 28628b400f6SJacob Faibussowitsch PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error: MatMatMult()"); 2879566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2889566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 289c4762a1bSJed Brown 290c4762a1bSJed Brown /* Test MatCholeskyFactor(), MatICCFactor() with natural ordering */ 2919566063dSJacob Faibussowitsch PetscCall(MatGetOrdering(A, MATORDERINGNATURAL, &perm, &iscol)); 2929566063dSJacob Faibussowitsch PetscCall(ISDestroy(&iscol)); 293c4762a1bSJed Brown norm1 = tol; 294c4762a1bSJed Brown inc = bs; 295c4762a1bSJed Brown 296c4762a1bSJed Brown /* initialize factinfo */ 2979566063dSJacob Faibussowitsch PetscCall(PetscMemzero(&factinfo, sizeof(MatFactorInfo))); 298c4762a1bSJed Brown 299c4762a1bSJed Brown for (lf = -1; lf < 10; lf += inc) { 300c4762a1bSJed Brown if (lf == -1) { /* Cholesky factor of sB (duplicate sA) */ 301c4762a1bSJed Brown factinfo.fill = 5.0; 302c4762a1bSJed Brown 3039566063dSJacob Faibussowitsch PetscCall(MatGetFactor(sB, MATSOLVERPETSC, MAT_FACTOR_CHOLESKY, &sFactor)); 3049566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorSymbolic(sFactor, sB, perm, &factinfo)); 305c4762a1bSJed Brown } else if (!doIcc) break; 3069371c9d4SSatish Balay else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; 307c4762a1bSJed Brown factinfo.levels = lf; 308c4762a1bSJed Brown 3099566063dSJacob Faibussowitsch PetscCall(MatGetFactor(sB, MATSOLVERPETSC, MAT_FACTOR_ICC, &sFactor)); 3109566063dSJacob Faibussowitsch PetscCall(MatICCFactorSymbolic(sFactor, sB, perm, &factinfo)); 311c4762a1bSJed Brown } 3129566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorNumeric(sFactor, sB, &factinfo)); 313c4762a1bSJed Brown /* MatView(sFactor, PETSC_VIEWER_DRAW_WORLD); */ 314c4762a1bSJed Brown 315c4762a1bSJed Brown /* test MatGetDiagonal on numeric factor */ 316c4762a1bSJed Brown /* 317c4762a1bSJed Brown if (lf == -1) { 3189566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(sFactor,s1)); 319c4762a1bSJed Brown printf(" in ex74.c, diag: \n"); 3209566063dSJacob Faibussowitsch PetscCall(VecView(s1,PETSC_VIEWER_STDOUT_SELF)); 321c4762a1bSJed Brown } 322c4762a1bSJed Brown */ 323c4762a1bSJed Brown 3249566063dSJacob Faibussowitsch PetscCall(MatMult(sB, x, b)); 325c4762a1bSJed Brown 326c4762a1bSJed Brown /* test MatForwardSolve() and MatBackwardSolve() */ 327c4762a1bSJed Brown if (lf == -1) { 3289566063dSJacob Faibussowitsch PetscCall(MatForwardSolve(sFactor, b, s1)); 3299566063dSJacob Faibussowitsch PetscCall(MatBackwardSolve(sFactor, s1, s2)); 3309566063dSJacob Faibussowitsch PetscCall(VecAXPY(s2, neg_one, x)); 3319566063dSJacob Faibussowitsch PetscCall(VecNorm(s2, NORM_2, &norm2)); 33248a46eb9SPierre Jolivet if (10 * norm1 < norm2) PetscCall(PetscPrintf(PETSC_COMM_SELF, "MatForwardSolve and BackwardSolve: Norm of error=%g, bs=%" PetscInt_FMT "\n", (double)norm2, bs)); 333c4762a1bSJed Brown } 334c4762a1bSJed Brown 335c4762a1bSJed Brown /* test MatSolve() */ 3369566063dSJacob Faibussowitsch PetscCall(MatSolve(sFactor, b, y)); 3379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&sFactor)); 338c4762a1bSJed Brown /* Check the error */ 3399566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, neg_one, x)); 3409566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &norm2)); 34148a46eb9SPierre Jolivet if (10 * norm1 < norm2 && lf - inc != -1) PetscCall(PetscPrintf(PETSC_COMM_SELF, "lf=%" PetscInt_FMT ", %" PetscInt_FMT ", Norm of error=%g, %g\n", lf - inc, lf, (double)norm1, (double)norm2)); 342c4762a1bSJed Brown norm1 = norm2; 343c4762a1bSJed Brown if (norm2 < tol && lf != -1) break; 344c4762a1bSJed Brown } 345c4762a1bSJed Brown 346c4762a1bSJed Brown #if defined(PETSC_HAVE_MUMPS) 3479566063dSJacob Faibussowitsch PetscCall(MatGetFactor(sA, MATSOLVERMUMPS, MAT_FACTOR_CHOLESKY, &sFactor)); 3489566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorSymbolic(sFactor, sA, NULL, NULL)); 3499566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorNumeric(sFactor, sA, NULL)); 350c4762a1bSJed Brown for (i = 0; i < 10; i++) { 3519566063dSJacob Faibussowitsch PetscCall(VecSetRandom(b, rdm)); 3529566063dSJacob Faibussowitsch PetscCall(MatSolve(sFactor, b, y)); 353c4762a1bSJed Brown /* Check the error */ 3549566063dSJacob Faibussowitsch PetscCall(MatMult(sA, y, x)); 3559566063dSJacob Faibussowitsch PetscCall(VecAXPY(x, neg_one, b)); 3569566063dSJacob Faibussowitsch PetscCall(VecNorm(x, NORM_2, &norm2)); 35748a46eb9SPierre Jolivet if (norm2 > tol) PetscCall(PetscPrintf(PETSC_COMM_SELF, "Error:MatSolve(), norm2: %g\n", (double)norm2)); 358c4762a1bSJed Brown } 3599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&sFactor)); 360c4762a1bSJed Brown #endif 361c4762a1bSJed Brown 3629566063dSJacob Faibussowitsch PetscCall(ISDestroy(&perm)); 363c4762a1bSJed Brown 3649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 3659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&sB)); 3669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&sA)); 3679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 3689566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 3699566063dSJacob Faibussowitsch PetscCall(VecDestroy(&s1)); 3709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&s2)); 3719566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b)); 3729566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rdm)); 373c4762a1bSJed Brown 3749566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 375b122ec5aSJacob Faibussowitsch return 0; 376c4762a1bSJed Brown } 377c4762a1bSJed Brown 378c4762a1bSJed Brown /*TEST 379c4762a1bSJed Brown 380c4762a1bSJed Brown test: 381c4762a1bSJed Brown args: -bs {{1 2 3 4 5 6 7 8}} 382c4762a1bSJed Brown 383c4762a1bSJed Brown TEST*/ 384