! ! Demonstrates use of MatDuplicate() for a shell matrix with a context ! MODULE solver_context_ex20f #include "petsc/finclude/petscmat.h" USE petscmat IMPLICIT NONE TYPE :: MatCtx PetscReal :: lambda END TYPE MatCtx END MODULE solver_context_ex20f MODULE solver_context_interfaces_ex20f USE solver_context_ex20f IMPLICIT NONE INTERFACE MatCreateShell SUBROUTINE MatCreateShell(comm,mloc,nloc,m,n,ctx,mat,ierr) USE solver_context_ex20f MPI_Comm :: comm PetscInt :: mloc,nloc,m,n TYPE(MatCtx) :: ctx Mat :: mat PetscErrorCode :: ierr END SUBROUTINE MatCreateShell END INTERFACE MatCreateShell INTERFACE MatShellSetContext SUBROUTINE MatShellSetContext(mat,ctx,ierr) USE solver_context_ex20f Mat :: mat TYPE(MatCtx) :: ctx PetscErrorCode :: ierr END SUBROUTINE MatShellSetContext END INTERFACE MatShellSetContext INTERFACE MatShellGetContext SUBROUTINE MatShellGetContext(mat,ctx,ierr) USE solver_context_ex20f Mat :: mat TYPE(MatCtx), POINTER :: ctx PetscErrorCode :: ierr END SUBROUTINE MatShellGetContext END INTERFACE MatShellGetContext END MODULE solver_context_interfaces_ex20f ! ---------------------------------------------------- ! main program ! ---------------------------------------------------- PROGRAM main #include "petsc/finclude/petscmat.h" USE solver_context_interfaces_ex20f IMPLICIT NONE Mat :: F, Fcopy TYPE(MatCtx) :: ctxF TYPE(MatCtx),POINTER :: ctxF_pt, ctxFcopy_pt PetscErrorCode :: ierr PetscInt :: n=128 external MatDuplicate_F PetscCallA(PetscInitialize(ierr)) ctxF%lambda = 3.14d0 PetscCallA(MatCreateShell(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,n,n,ctxF,F,ierr)) PetscCallA(MatShellSetOperation(F,MATOP_DUPLICATE,MatDuplicate_F,ierr)) PRINT*,'ctxF%lambda = ',ctxF%lambda PetscCallA(MatShellGetContext(F,ctxF_pt,ierr)) PRINT*,'ctxF_pt%lambda = ',ctxF_pt%lambda PetscCallA(MatDuplicate(F,MAT_DO_NOT_COPY_VALUES,Fcopy,ierr)) PetscCallA(MatShellGetContext(Fcopy,ctxFcopy_pt,ierr)) PRINT*,'ctxFcopy_pt%lambda = ',ctxFcopy_pt%lambda PetscCallA(MatDestroy(F,ierr)) PetscCallA(MatDestroy(Fcopy,ierr)) PetscCallA(PetscFinalize(ierr)) END PROGRAM main SUBROUTINE MatDuplicate_F(F, opt, M, ierr) USE solver_context_interfaces_ex20f IMPLICIT NONE Mat :: F, M MatDuplicateOption :: opt PetscErrorCode :: ierr PetscInt :: ml,nl TYPE(MatCtx),POINTER :: ctxM,ctxF_pt external MatDestroy_F PetscCall(MatGetLocalSize(F,ml,nl,ierr)) PetscCall(MatShellGetContext(F,ctxF_pt,ierr)) allocate(ctxM) ctxM%lambda = ctxF_pt%lambda PetscCall(MatCreateShell(PETSC_COMM_WORLD,ml,nl,PETSC_DETERMINE,PETSC_DETERMINE,ctxM,M,ierr)) ! PetscCall(MatShellSetOperation(M,MATOP_DUPLICATE,MatDuplicate_F,ierr)) PetscCall(MatShellSetOperation(M,MATOP_DESTROY,MatDestroy_F,ierr)) END SUBROUTINE MatDuplicate_F SUBROUTINE MatDestroy_F(F, ierr) USE solver_context_interfaces_ex20f IMPLICIT NONE Mat :: F PetscErrorCode :: ierr TYPE(MatCtx),POINTER :: ctxF_pt PetscCall(MatShellGetContext(F,ctxF_pt,ierr)) deallocate(ctxF_pt) END SUBROUTINE MatDestroy_F !/*TEST ! ! build: ! requires: double ! ! test: ! !TEST*/