xref: /petsc/src/mat/tests/ex140.c (revision 58d68138c660dfb4e9f5b03334792cd4f2ffd7cc)
1 static char help[] = "Tests MATPYTHON from C\n\n";
2 
3 #include <petscmat.h>
4 /* MATPYTHON has support for wrapping these operations
5    MatHasOperation_Python inspects the user's Python class and checks
6    if the methods are provided */
7 MatOperation optenum[] = {MATOP_MULT, MATOP_MULT_ADD, MATOP_MULT_TRANSPOSE, MATOP_MULT_TRANSPOSE_ADD, MATOP_SOLVE, MATOP_SOLVE_ADD, MATOP_SOLVE_TRANSPOSE, MATOP_SOLVE_TRANSPOSE_ADD, MATOP_SOR, MATOP_GET_DIAGONAL, MATOP_DIAGONAL_SCALE, MATOP_NORM, MATOP_ZERO_ENTRIES, MATOP_GET_DIAGONAL_BLOCK, MATOP_DUPLICATE, MATOP_COPY, MATOP_SCALE, MATOP_SHIFT, MATOP_DIAGONAL_SET, MATOP_ZERO_ROWS_COLUMNS, MATOP_CREATE_SUBMATRIX, MATOP_CREATE_VECS, MATOP_CONJUGATE, MATOP_REAL_PART, MATOP_IMAGINARY_PART, MATOP_MISSING_DIAGONAL, MATOP_MULT_DIAGONAL_BLOCK, MATOP_MULT_HERMITIAN_TRANSPOSE, MATOP_MULT_HERMITIAN_TRANS_ADD};
8 
9 /* Name of the methods in the user's Python class */
10 const char *const optstr[] = {"mult", "multAdd", "multTranspose", "multTransposeAdd", "solve", "solveAdd", "solveTranspose", "solveTransposeAdd", "SOR", "getDiagonal", "diagonalScale", "norm", "zeroEntries", "getDiagonalBlock", "duplicate", "copy", "scale", "shift", "setDiagonal", "zeroRowsColumns", "createSubMatrix", "getVecs", "conjugate", "realPart", "imagPart", "missingDiagonal", "multDiagonalBlock", "multHermitian", "multHermitianAdd"};
11 
12 PetscErrorCode RunHasOperationTest() {
13   Mat      A;
14   PetscInt matop, nop = PETSC_STATIC_ARRAY_LENGTH(optenum);
15 
16   PetscFunctionBegin;
17   for (matop = 0; matop < nop; matop++) {
18     char      opts[256];
19     PetscBool hasop;
20     PetscInt  i;
21 
22     PetscCall(PetscSNPrintf(opts, 256, "-enable %s", optstr[matop]));
23     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Testing with %s\n", opts));
24     PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
25     PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, 0, 0));
26     PetscCall(MatSetType(A, MATPYTHON));
27     PetscCall(MatPythonSetType(A, "ex140.py:Matrix"));
28     /* default case, no user implementation */
29     for (i = 0; i < nop; i++) {
30       PetscCall(MatHasOperation(A, optenum[i], &hasop));
31       if (hasop) {
32         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Error: %s present\n", optstr[i]));
33       } else {
34         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Pass: %s\n", optstr[i]));
35       }
36     }
37     /* customize Matrix class at a later stage and add support for optenum[matop] */
38     PetscCall(PetscOptionsInsertString(NULL, opts));
39     PetscCall(MatSetFromOptions(A));
40     for (i = 0; i < nop; i++) {
41       PetscCall(MatHasOperation(A, optenum[i], &hasop));
42       if (hasop && i != matop) {
43         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Error: %s present\n", optstr[i]));
44       } else if (!hasop && i == matop) {
45         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Error: %s not present\n", optstr[i]));
46       } else {
47         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Pass: %s\n", optstr[i]));
48       }
49     }
50     PetscCall(MatDestroy(&A));
51     PetscCall(PetscOptionsClearValue(NULL, opts));
52   }
53   PetscFunctionReturn(0);
54 }
55 
56 int main(int argc, char **argv) {
57   PetscFunctionBeginUser;
58   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
59   PetscCall(PetscPythonInitialize(NULL, NULL));
60   PetscCall(RunHasOperationTest(); PetscPythonPrintError());
61   PetscCall(PetscFinalize());
62   return 0;
63 }
64 
65 /*TEST
66 
67    test:
68       requires: petsc4py
69       localrunfiles: ex140.py
70 
71 TEST*/
72