Actual source code: ex20f.F90

  1: !
  2: !     Demonstrates use of MatDuplicate() for a shell matrix with a context
  3: !
  4: MODULE solver_context_ex20f
  5: #include "petsc/finclude/petscmat.h"
  6:   USE petscmat
  7:   IMPLICIT NONE
  8:   TYPE :: MatCtx
  9:     PetscReal :: lambda
 10:   END TYPE MatCtx
 11: END MODULE solver_context_ex20f

 13: MODULE solver_context_interfaces_ex20f
 14:   USE solver_context_ex20f
 15:   IMPLICIT NONE

 17:   INTERFACE MatCreateShell
 18:     SUBROUTINE MatCreateShell(comm, mloc, nloc, m, n, ctx, mat, ierr)
 19:       USE solver_context_ex20f
 20:       MPI_Comm :: comm
 21:       PetscInt :: mloc, nloc, m, n
 22:       TYPE(MatCtx) :: ctx
 23:       Mat :: mat
 24:       PetscErrorCode :: ierr
 25:     END SUBROUTINE MatCreateShell
 26:   END INTERFACE MatCreateShell

 28:   INTERFACE MatShellSetContext
 29:     SUBROUTINE MatShellSetContext(mat, ctx, ierr)
 30:       USE solver_context_ex20f
 31:       Mat :: mat
 32:       TYPE(MatCtx) :: ctx
 33:       PetscErrorCode :: ierr
 34:     END SUBROUTINE MatShellSetContext
 35:   END INTERFACE MatShellSetContext

 37:   INTERFACE MatShellGetContext
 38:     SUBROUTINE MatShellGetContext(mat, ctx, ierr)
 39:       USE solver_context_ex20f
 40:       Mat :: mat
 41:       TYPE(MatCtx), POINTER :: ctx
 42:       PetscErrorCode :: ierr
 43:     END SUBROUTINE MatShellGetContext
 44:   END INTERFACE MatShellGetContext

 46: END MODULE solver_context_interfaces_ex20f

 48: ! ----------------------------------------------------
 49: !                    main program
 50: ! ----------------------------------------------------
 51: PROGRAM main
 52: #include "petsc/finclude/petscmat.h"
 53:   USE solver_context_interfaces_ex20f
 54:   IMPLICIT NONE
 55:   Mat                  :: F, Fcopy
 56:   TYPE(MatCtx)         :: ctxF
 57:   TYPE(MatCtx), POINTER :: ctxF_pt, ctxFcopy_pt
 58:   PetscErrorCode       :: ierr
 59:   PetscInt             :: n = 128
 60:   external MatDuplicate_F

 62:   PetscCallA(PetscInitialize(ierr))
 63:   ctxF%lambda = 3.14d0
 64:   PetscCallA(MatCreateShell(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_DECIDE, n, n, ctxF, F, ierr))
 65:   PetscCallA(MatShellSetOperation(F, MATOP_DUPLICATE, MatDuplicate_F, ierr))
 66:   PRINT *, 'ctxF%lambda = ', ctxF%lambda

 68:   PetscCallA(MatShellGetContext(F, ctxF_pt, ierr))
 69:   PRINT *, 'ctxF_pt%lambda = ', ctxF_pt%lambda

 71:   PetscCallA(MatDuplicate(F, MAT_DO_NOT_COPY_VALUES, Fcopy, ierr))
 72:   PetscCallA(MatShellGetContext(Fcopy, ctxFcopy_pt, ierr))
 73:   PRINT *, 'ctxFcopy_pt%lambda = ', ctxFcopy_pt%lambda

 75:   PetscCallA(MatDestroy(F, ierr))
 76:   PetscCallA(MatDestroy(Fcopy, ierr))
 77:   PetscCallA(PetscFinalize(ierr))
 78: END PROGRAM main

 80: SUBROUTINE MatDuplicate_F(F, opt, M, ierr)
 81:   USE solver_context_interfaces_ex20f
 82:   IMPLICIT NONE

 84:   Mat                  :: F, M
 85:   MatDuplicateOption   :: opt
 86:   PetscErrorCode       :: ierr
 87:   PetscInt             :: ml, nl
 88:   TYPE(MatCtx), POINTER :: ctxM, ctxF_pt
 89:   external MatDestroy_F

 91:   PetscCall(MatGetLocalSize(F, ml, nl, ierr))
 92:   PetscCall(MatShellGetContext(F, ctxF_pt, ierr))
 93:   allocate (ctxM)
 94:   ctxM%lambda = ctxF_pt%lambda
 95:   PetscCall(MatCreateShell(PETSC_COMM_WORLD, ml, nl, PETSC_DETERMINE, PETSC_DETERMINE, ctxM, M, ierr))
 96: !        PetscCall(MatShellSetOperation(M,MATOP_DUPLICATE,MatDuplicate_F,ierr))
 97:   PetscCall(MatShellSetOperation(M, MATOP_DESTROY, MatDestroy_F, ierr))
 98: END SUBROUTINE MatDuplicate_F

100: SUBROUTINE MatDestroy_F(F, ierr)
101:   USE solver_context_interfaces_ex20f
102:   IMPLICIT NONE

104:   Mat                  :: F
105:   PetscErrorCode       :: ierr
106:   TYPE(MatCtx), POINTER :: ctxF_pt
107:   PetscCall(MatShellGetContext(F, ctxF_pt, ierr))
108:   deallocate (ctxF_pt)
109: END SUBROUTINE MatDestroy_F

111: !/*TEST
112: !
113: !     build:
114: !       requires: double
115: !
116: !     test:
117: !
118: !TEST*/