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*/