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