Actual source code: ex205.c

  1: static char help[] = "Tests MatCopy() for SHELL matrices\n\n";

  3: #include <petscmat.h>

  5: typedef struct _n_User *User;
  6: struct _n_User {
  7:   Mat A;
  8: };

 10: static PetscErrorCode MatMult_User(Mat A, Vec X, Vec Y)
 11: {
 12:   User user;

 14:   MatShellGetContext(A, &user);
 15:   MatMult(user->A, X, Y);
 16:   return 0;
 17: }

 19: static PetscErrorCode MatCopy_User(Mat A, Mat B, MatStructure str)
 20: {
 21:   User userA, userB;

 23:   MatShellGetContext(A, &userA);
 24:   if (userA) {
 25:     PetscNew(&userB);
 26:     MatDuplicate(userA->A, MAT_COPY_VALUES, &userB->A);
 27:     MatShellSetContext(B, userB);
 28:   }
 29:   return 0;
 30: }

 32: static PetscErrorCode MatDestroy_User(Mat A)
 33: {
 34:   User user;

 36:   MatShellGetContext(A, &user);
 37:   if (user) {
 38:     MatDestroy(&user->A);
 39:     PetscFree(user);
 40:   }
 41:   return 0;
 42: }

 44: int main(int argc, char **args)
 45: {
 46:   const PetscScalar xvals[] = {11, 13}, yvals[] = {17, 19};
 47:   const PetscInt    inds[]  = {0, 1};
 48:   PetscScalar       avals[] = {2, 3, 5, 7};
 49:   Mat               S1, S2;
 50:   Vec               X, Y;
 51:   User              user;

 54:   PetscInitialize(&argc, &args, (char *)0, help);

 56:   PetscNew(&user);
 57:   MatCreateSeqAIJ(PETSC_COMM_WORLD, 2, 2, 2, NULL, &user->A);
 58:   MatSetUp(user->A);
 59:   MatSetValues(user->A, 2, inds, 2, inds, avals, INSERT_VALUES);
 60:   MatAssemblyBegin(user->A, MAT_FINAL_ASSEMBLY);
 61:   MatAssemblyEnd(user->A, MAT_FINAL_ASSEMBLY);
 62:   VecCreateSeq(PETSC_COMM_WORLD, 2, &X);
 63:   VecSetValues(X, 2, inds, xvals, INSERT_VALUES);
 64:   VecAssemblyBegin(X);
 65:   VecAssemblyEnd(X);
 66:   VecDuplicate(X, &Y);
 67:   VecSetValues(Y, 2, inds, yvals, INSERT_VALUES);
 68:   VecAssemblyBegin(Y);
 69:   VecAssemblyEnd(Y);

 71:   MatCreateShell(PETSC_COMM_WORLD, 2, 2, 2, 2, user, &S1);
 72:   MatSetUp(S1);
 73:   MatShellSetOperation(S1, MATOP_MULT, (void (*)(void))MatMult_User);
 74:   MatShellSetOperation(S1, MATOP_COPY, (void (*)(void))MatCopy_User);
 75:   MatShellSetOperation(S1, MATOP_DESTROY, (void (*)(void))MatDestroy_User);
 76:   MatCreateShell(PETSC_COMM_WORLD, 2, 2, 2, 2, NULL, &S2);
 77:   MatSetUp(S2);
 78:   MatShellSetOperation(S2, MATOP_MULT, (void (*)(void))MatMult_User);
 79:   MatShellSetOperation(S2, MATOP_COPY, (void (*)(void))MatCopy_User);
 80:   MatShellSetOperation(S2, MATOP_DESTROY, (void (*)(void))MatDestroy_User);

 82:   MatScale(S1, 31);
 83:   MatShift(S1, 37);
 84:   MatDiagonalScale(S1, X, Y);
 85:   MatCopy(S1, S2, SAME_NONZERO_PATTERN);
 86:   MatMult(S1, X, Y);
 87:   VecView(Y, PETSC_VIEWER_STDOUT_WORLD);
 88:   MatMult(S2, X, Y);
 89:   VecView(Y, PETSC_VIEWER_STDOUT_WORLD);

 91:   MatDestroy(&S1);
 92:   MatDestroy(&S2);
 93:   VecDestroy(&X);
 94:   VecDestroy(&Y);
 95:   PetscFinalize();
 96:   return 0;
 97: }

 99: /*TEST

101:    test:
102:       args: -malloc_dump

104: TEST*/