Actual source code: ex21f90.F90

petsc-3.8.4 2018-03-24
Report Typos and Errors
  1: !
  2: !
  3: !    Demonstrates how one may access entries of a PETSc Vec as if it was an array of Fortran derived types
  4: !
  5: !/*T
  6: !   Concepts: vectors^basic routines;
  7: !   Processors: n
  8: !   depends: ex21.c
  9: !T*/
 10: !
 11: ! -----------------------------------------------------------------------

 13:       module mymodule
 14:  #include <petsc/finclude/petscsys.h>
 15:       type MyStruct
 16:         sequence
 17:         PetscScalar :: a,b,c
 18:       end type MyStruct
 19:       end module

 21: !
 22: !  These routines are used internally by the C functions VecGetArrayMyStruct() and VecRestoreArrayMyStruct()
 23: !  Because Fortran requires "knowing" exactly what derived types the pointers to point too, these have to be
 24: !  customized for exactly the derived type in question
 25: !
 26:       subroutine F90Array1dCreateMyStruct(array,start,len,ptr)
 27:  #include <petsc/finclude/petscsys.h>
 28:       use petscsys
 29:       use mymodule
 30:       implicit none
 31:       PetscInt start,len
 32:       type(MyStruct), target :: array(start:start+len-1)
 33:       type(MyStruct), pointer :: ptr(:)

 35:       ptr => array
 36:       end subroutine

 38:       subroutine F90Array1dAccessMyStruct(ptr,address)
 39:  #include <petsc/finclude/petscsys.h>
 40:       use petscsys
 41:       use mymodule
 42:       implicit none
 43:       type(MyStruct), pointer :: ptr(:)
 44:       PetscFortranAddr address
 45:       PetscInt start

 47:       start = lbound(ptr,1)
 48:       call F90Array1dGetAddrMyStruct(ptr(start),address)
 49:       end subroutine

 51:       subroutine F90Array1dDestroyMyStruct(ptr)
 52:  #include <petsc/finclude/petscsys.h>
 53:       use petscsys
 54:       use mymodule
 55:       implicit none
 56:       type(MyStruct), pointer :: ptr(:)

 58:       nullify(ptr)
 59:       end subroutine


 62:       program main
 63:  #include <petsc/finclude/petscvec.h>
 64:       use petscvec
 65:       use mymodule
 66:       implicit none

 68: !
 69: !
 70: !   These two routines are defined in ex21.c they create the Fortran pointer to the derived type
 71: !
 72:       Interface
 73:         Subroutine VecGetArrayMyStruct(v,array,ierr)
 74:           use petscvec
 75:           use mymodule
 76:           type(MyStruct), pointer :: array(:)
 77:           PetscErrorCode ierr
 78:           Vec     v
 79:         End Subroutine
 80:       End Interface

 82:       Interface
 83:         Subroutine VecRestoreArrayMyStruct(v,array,ierr)
 84:           use petscvec
 85:           use mymodule
 86:           type(MyStruct), pointer :: array(:)
 87:           PetscErrorCode ierr
 88:           Vec     v
 89:         End Subroutine
 90:       End Interface

 92: !
 93: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 94: !                   Variable declarations
 95: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 96: !
 97: !  Variables:
 98: !     x, y, w - vectors
 99: !     z       - array of vectors
100: !
101:       Vec              x,y
102:       type(MyStruct),  pointer :: xarray(:)
103:       PetscInt         n
104:       PetscErrorCode   ierr
105:       PetscBool        flg
106:       integer          i

108: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
109: !                 Beginning of program
110: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

112:       call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
113:       if (ierr .ne. 0) then
114:         print*,'PetscInitialize failed'
115:         stop
116:       endif
117:       n     = 30

119:       call PetscOptionsGetInt(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-n',n,flg,ierr);CHKERRA(ierr)
120:       call VecCreate(PETSC_COMM_WORLD,x,ierr);CHKERRA(ierr)
121:       call VecSetSizes(x,PETSC_DECIDE,n,ierr);CHKERRA(ierr)
122:       call VecSetFromOptions(x,ierr);CHKERRA(ierr)
123:       call VecDuplicate(x,y,ierr);CHKERRA(ierr)

125:       call VecGetArrayMyStruct(x,xarray,ierr);CHKERRA(ierr)
126:       do i=1,10
127:       xarray(i)%a = i
128:       xarray(i)%b = 100*i
129:       xarray(i)%c = 10000*i
130:       enddo

132:       call VecRestoreArrayMyStruct(x,xarray,ierr);CHKERRA(ierr)
133:       call VecView(x,PETSC_VIEWER_STDOUT_SELF,ierr);CHKERRA(ierr)
134:       call VecGetArrayMyStruct(x,xarray,ierr);CHKERRA(ierr)
135:       do i = 1 , 10
136:         write(*,*) abs(xarray(i)%a),abs(xarray(i)%b),abs(xarray(i)%c)
137:       end do
138:       call VecRestoreArrayMyStruct(x,xarray,ierr);CHKERRA(ierr)


141:       call VecDestroy(x,ierr);CHKERRA(ierr)
142:       call VecDestroy(y,ierr);CHKERRA(ierr)
143:       call PetscFinalize(ierr)

145:       end