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