Actual source code: ex218.c


  2: static char help[] = "Tests MatShellTestMult()\n\n";

  4: #include <petscmat.h>

  6: typedef struct _n_User *User;
  7: struct _n_User {
  8:   Mat B;
  9: };

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

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

 20: static PetscErrorCode MatMultTranspose_User(Mat A, Vec X, Vec Y)
 21: {
 22:   User user;

 24:   MatShellGetContext(A, &user);
 25:   MatMultTranspose(user->B, X, Y);
 26:   return 0;
 27: }

 29: static PetscErrorCode MyFunction(void *ctx, Vec x, Vec y)
 30: {
 31:   User user = (User)ctx;

 33:   MatMult(user->B, x, y);
 34:   return 0;
 35: }

 37: int main(int argc, char **args)
 38: {
 39:   const PetscInt inds[]  = {0, 1};
 40:   PetscScalar    avals[] = {2, 3, 5, 7};
 41:   Mat            S;
 42:   User           user;
 43:   Vec            base;

 46:   PetscInitialize(&argc, &args, (char *)0, help);
 47:   PetscNew(&user);
 48:   MatCreateSeqAIJ(PETSC_COMM_WORLD, 2, 2, 2, NULL, &user->B);
 49:   MatSetUp(user->B);
 50:   MatSetValues(user->B, 2, inds, 2, inds, avals, INSERT_VALUES);
 51:   MatAssemblyBegin(user->B, MAT_FINAL_ASSEMBLY);
 52:   MatAssemblyEnd(user->B, MAT_FINAL_ASSEMBLY);
 53:   MatCreateVecs(user->B, &base, NULL);
 54:   MatCreateShell(PETSC_COMM_WORLD, 2, 2, 2, 2, user, &S);
 55:   MatSetUp(S);
 56:   MatShellSetOperation(S, MATOP_MULT, (void (*)(void))MatMult_User);
 57:   MatShellSetOperation(S, MATOP_MULT_TRANSPOSE, (void (*)(void))MatMultTranspose_User);

 59:   MatShellTestMult(S, MyFunction, base, user, NULL);
 60:   MatShellTestMultTranspose(S, MyFunction, base, user, NULL);

 62:   VecDestroy(&base);
 63:   MatDestroy(&user->B);
 64:   MatDestroy(&S);
 65:   PetscFree(user);
 66:   PetscFinalize();
 67:   return 0;
 68: }

 70: /*TEST

 72:    test:
 73:      args: -mat_shell_test_mult_view -mat_shell_test_mult_transpose_view

 75: TEST*/