xref: /petsc/src/mat/tests/ex218.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
1 static char help[] = "Tests MatShellTestMult()\n\n";
2 
3 #include <petscmat.h>
4 
5 typedef struct _n_User *User;
6 struct _n_User {
7   Mat B;
8 };
9 
MatMult_User(Mat A,Vec X,Vec Y)10 static PetscErrorCode MatMult_User(Mat A, Vec X, Vec Y)
11 {
12   User user;
13 
14   PetscFunctionBegin;
15   PetscCall(MatShellGetContext(A, &user));
16   PetscCall(MatMult(user->B, X, Y));
17   PetscFunctionReturn(PETSC_SUCCESS);
18 }
19 
MatMultTranspose_User(Mat A,Vec X,Vec Y)20 static PetscErrorCode MatMultTranspose_User(Mat A, Vec X, Vec Y)
21 {
22   User user;
23 
24   PetscFunctionBegin;
25   PetscCall(MatShellGetContext(A, &user));
26   PetscCall(MatMultTranspose(user->B, X, Y));
27   PetscFunctionReturn(PETSC_SUCCESS);
28 }
29 
MyFunction(PetscCtx ctx,Vec x,Vec y)30 static PetscErrorCode MyFunction(PetscCtx ctx, Vec x, Vec y)
31 {
32   User user = (User)ctx;
33 
34   PetscFunctionBegin;
35   PetscCall(MatMult(user->B, x, y));
36   PetscFunctionReturn(PETSC_SUCCESS);
37 }
38 
main(int argc,char ** args)39 int main(int argc, char **args)
40 {
41   const PetscInt inds[]  = {0, 1};
42   PetscScalar    avals[] = {2, 3, 5, 7};
43   Mat            S;
44   User           user;
45   Vec            base;
46 
47   PetscFunctionBeginUser;
48   PetscCall(PetscInitialize(&argc, &args, NULL, help));
49   PetscCall(PetscNew(&user));
50   PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, 2, 2, 2, NULL, &user->B));
51   PetscCall(MatSetUp(user->B));
52   PetscCall(MatSetValues(user->B, 2, inds, 2, inds, avals, INSERT_VALUES));
53   PetscCall(MatAssemblyBegin(user->B, MAT_FINAL_ASSEMBLY));
54   PetscCall(MatAssemblyEnd(user->B, MAT_FINAL_ASSEMBLY));
55   PetscCall(MatCreateVecs(user->B, &base, NULL));
56   PetscCall(MatCreateShell(PETSC_COMM_WORLD, 2, 2, 2, 2, user, &S));
57   PetscCall(MatSetUp(S));
58   PetscCall(MatShellSetOperation(S, MATOP_MULT, (PetscErrorCodeFn *)MatMult_User));
59   PetscCall(MatShellSetOperation(S, MATOP_MULT_TRANSPOSE, (PetscErrorCodeFn *)MatMultTranspose_User));
60 
61   PetscCall(MatShellTestMult(S, MyFunction, base, user, NULL));
62   PetscCall(MatShellTestMultTranspose(S, MyFunction, base, user, NULL));
63 
64   PetscCall(VecDestroy(&base));
65   PetscCall(MatDestroy(&user->B));
66   PetscCall(MatDestroy(&S));
67   PetscCall(PetscFree(user));
68   PetscCall(PetscFinalize());
69   return 0;
70 }
71 
72 /*TEST
73 
74    test:
75      args: -mat_shell_test_mult_view -mat_shell_test_mult_transpose_view
76 
77 TEST*/
78