Date: 2026-06-01T23:13:54+00:00

Actual source code: ex21f90.F90

      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: !
      6: ! -----------------------------------------------------------------------
      7: #include <petsc/finclude/petscvec.h>
      8: module ex21module
      9:   use petscsys
     10:   implicit none
     11:   type MyStruct
     12:     sequence
     13:     PetscScalar :: a, b, c
     14:   end type MyStruct
     15: !
     16: !
     17: !   These two routines are defined in ex21.c they create the Fortran pointer to the derived type
     18: !
     19:   interface
     20:     subroutine VecGetArrayMyStruct(v, array, ierr)
     21:       use petscvec
     22:       import MyStruct
     23:       type(MyStruct), pointer :: array(:)
     24:       PetscErrorCode ierr
     25:       Vec v
     26:     end subroutine

     28:     subroutine VecRestoreArrayMyStruct(v, array, ierr)
     29:       use petscvec
     30:       import MyStruct
     31:       type(MyStruct), pointer :: array(:)
     32:       PetscErrorCode ierr
     33:       Vec v
     34:     end subroutine
     35:   end interface
     36: end module

     38: !  These routines are used internally by the C functions VecGetArrayMyStruct() and VecRestoreArrayMyStruct()
     39: !  Because Fortran requires "knowing" exactly what derived types the pointers to point too, these have to be
     40: !  customized for exactly the derived type in question
     41: !
     42: subroutine F90Array1dCreateMyStruct(array, start, len, ptr)
     43:   use petscsys
     44:   use ex21module
     45:   implicit none
     46:   PetscInt start, len
     47:   type(MyStruct), target :: array(start:start + len - 1)
     48:   type(MyStruct), pointer :: ptr(:)

     50:   ptr => array
     51: end subroutine

     53: subroutine F90Array1dAccessMyStruct(ptr, address)
     54:   use petscsys
     55:   use ex21module
     56:   implicit none
     57:   type(MyStruct), pointer :: ptr(:)
     58:   PetscFortranAddr address
     59:   PetscInt start

     61:   start = lbound(ptr, 1)
     62:   call F90Array1dGetAddrMyStruct(ptr(start), address)
     63: end subroutine

     65: subroutine F90Array1dDestroyMyStruct(ptr)
     66:   use ex21module
     67:   implicit none
     68:   type(MyStruct), pointer :: ptr(:)

     70:   nullify (ptr)
     71: end subroutine

     73: program main
     74:   use petscvec
     75:   use ex21module
     76:   implicit none

     78: !
     79: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     80: !                   Variable declarations
     81: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     82: !
     83: !  Variables:
     84: !     x, y, w - vectors
     85: !     z       - array of vectors
     86: !
     87:   Vec x, y
     88:   type(MyStruct), pointer :: xarray(:)
     89:   PetscInt n
     90:   PetscErrorCode ierr
     91:   PetscBool flg
     92:   integer i

     94: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     95: !                 Beginning of program
     96: ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

     98:   PetscCallA(PetscInitialize(ierr))

    100:   n = 30
    101:   PetscCallA(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, '-n', n, flg, ierr))
    102:   PetscCallA(VecCreate(PETSC_COMM_WORLD, x, ierr))
    103:   PetscCallA(VecSetSizes(x, PETSC_DECIDE, n, ierr))
    104:   PetscCallA(VecSetFromOptions(x, ierr))
    105:   PetscCallA(VecDuplicate(x, y, ierr))

    107:   PetscCallA(VecGetArrayMyStruct(x, xarray, ierr))
    108:   do i = 1, 10
    109:     xarray(i)%a = i
    110:     xarray(i)%b = 100*i
    111:     xarray(i)%c = 10000*i
    112:   end do

    114:   PetscCallA(VecRestoreArrayMyStruct(x, xarray, ierr))
    115:   PetscCallA(VecView(x, PETSC_VIEWER_STDOUT_SELF, ierr))
    116:   PetscCallA(VecGetArrayMyStruct(x, xarray, ierr))
    117:   do i = 1, 10
    118:     write (*, *) abs(xarray(i)%a), abs(xarray(i)%b), abs(xarray(i)%c)
    119:   end do
    120:   PetscCallA(VecRestoreArrayMyStruct(x, xarray, ierr))

    122:   PetscCallA(VecDestroy(x, ierr))
    123:   PetscCallA(VecDestroy(y, ierr))
    124:   PetscCallA(PetscFinalize(ierr))

    126: end

    128: !/*TEST
    129: !
    130: !   build:
    131: !     depends: ex21.c
    132: !
    133: !   test:
    134: !
    135: !TEST*/