xref: /petsc/src/mat/tests/ex205.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 static char help[] = "Tests MatCopy() for SHELL matrices\n\n";
2 
3 #include <petscmat.h>
4 
5 typedef struct _n_User *User;
6 struct _n_User {
7   Mat A;
8 };
9 
10 static PetscErrorCode MatMult_User(Mat A, Vec X, Vec Y) {
11   User user;
12 
13   PetscFunctionBegin;
14   PetscCall(MatShellGetContext(A, &user));
15   PetscCall(MatMult(user->A, X, Y));
16   PetscFunctionReturn(0);
17 }
18 
19 static PetscErrorCode MatCopy_User(Mat A, Mat B, MatStructure str) {
20   User userA, userB;
21 
22   PetscFunctionBegin;
23   PetscCall(MatShellGetContext(A, &userA));
24   if (userA) {
25     PetscCall(PetscNew(&userB));
26     PetscCall(MatDuplicate(userA->A, MAT_COPY_VALUES, &userB->A));
27     PetscCall(MatShellSetContext(B, userB));
28   }
29   PetscFunctionReturn(0);
30 }
31 
32 static PetscErrorCode MatDestroy_User(Mat A) {
33   User user;
34 
35   PetscFunctionBegin;
36   PetscCall(MatShellGetContext(A, &user));
37   if (user) {
38     PetscCall(MatDestroy(&user->A));
39     PetscCall(PetscFree(user));
40   }
41   PetscFunctionReturn(0);
42 }
43 
44 int main(int argc, char **args) {
45   const PetscScalar xvals[] = {11, 13}, yvals[] = {17, 19};
46   const PetscInt    inds[]  = {0, 1};
47   PetscScalar       avals[] = {2, 3, 5, 7};
48   Mat               S1, S2;
49   Vec               X, Y;
50   User              user;
51 
52   PetscFunctionBeginUser;
53   PetscCall(PetscInitialize(&argc, &args, (char *)0, help));
54 
55   PetscCall(PetscNew(&user));
56   PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, 2, 2, 2, NULL, &user->A));
57   PetscCall(MatSetUp(user->A));
58   PetscCall(MatSetValues(user->A, 2, inds, 2, inds, avals, INSERT_VALUES));
59   PetscCall(MatAssemblyBegin(user->A, MAT_FINAL_ASSEMBLY));
60   PetscCall(MatAssemblyEnd(user->A, MAT_FINAL_ASSEMBLY));
61   PetscCall(VecCreateSeq(PETSC_COMM_WORLD, 2, &X));
62   PetscCall(VecSetValues(X, 2, inds, xvals, INSERT_VALUES));
63   PetscCall(VecAssemblyBegin(X));
64   PetscCall(VecAssemblyEnd(X));
65   PetscCall(VecDuplicate(X, &Y));
66   PetscCall(VecSetValues(Y, 2, inds, yvals, INSERT_VALUES));
67   PetscCall(VecAssemblyBegin(Y));
68   PetscCall(VecAssemblyEnd(Y));
69 
70   PetscCall(MatCreateShell(PETSC_COMM_WORLD, 2, 2, 2, 2, user, &S1));
71   PetscCall(MatSetUp(S1));
72   PetscCall(MatShellSetOperation(S1, MATOP_MULT, (void (*)(void))MatMult_User));
73   PetscCall(MatShellSetOperation(S1, MATOP_COPY, (void (*)(void))MatCopy_User));
74   PetscCall(MatShellSetOperation(S1, MATOP_DESTROY, (void (*)(void))MatDestroy_User));
75   PetscCall(MatCreateShell(PETSC_COMM_WORLD, 2, 2, 2, 2, NULL, &S2));
76   PetscCall(MatSetUp(S2));
77   PetscCall(MatShellSetOperation(S2, MATOP_MULT, (void (*)(void))MatMult_User));
78   PetscCall(MatShellSetOperation(S2, MATOP_COPY, (void (*)(void))MatCopy_User));
79   PetscCall(MatShellSetOperation(S2, MATOP_DESTROY, (void (*)(void))MatDestroy_User));
80 
81   PetscCall(MatScale(S1, 31));
82   PetscCall(MatShift(S1, 37));
83   PetscCall(MatDiagonalScale(S1, X, Y));
84   PetscCall(MatCopy(S1, S2, SAME_NONZERO_PATTERN));
85   PetscCall(MatMult(S1, X, Y));
86   PetscCall(VecView(Y, PETSC_VIEWER_STDOUT_WORLD));
87   PetscCall(MatMult(S2, X, Y));
88   PetscCall(VecView(Y, PETSC_VIEWER_STDOUT_WORLD));
89 
90   PetscCall(MatDestroy(&S1));
91   PetscCall(MatDestroy(&S2));
92   PetscCall(VecDestroy(&X));
93   PetscCall(VecDestroy(&Y));
94   PetscCall(PetscFinalize());
95   return 0;
96 }
97 
98 /*TEST
99 
100    test:
101       args: -malloc_dump
102 
103 TEST*/
104