Since Fortran does not allow arrays to be returned in routine
arguments, all PETSc routines that return arrays, such as
VecGetArray(), MatGetArray(),
ISGetIndices(), and DAGetGlobalIndices()
are defined slightly differently in Fortran than in C.
Instead of returning the array itself, these routines
accept as input a user-specified array of dimension one and return an
integer index to the actual array used for data storage within PETSc.
The Fortran interface for several routines is as follows:
double precision xx_v(1), aa_v(1) integer ss_v(1), dd_v(1), ierr, nloc PetscOffset ss_i, xx_i, aa_i, dd_i Vec x Mat A IS s DA dTo access array elements directly, both the user-specified array and the integer index must then be used together. For example, the following Fortran program fragment illustrates directly setting the values of a vector array instead of using VecSetValues(). Note the (optional) use of the preprocessor #define statement to enable array manipulations in the conventional Fortran manner.call VecGetArray(x,xx_v,xx_i,ierr) call MatGetArray(A,aa_v,aa_i,ierr) call ISGetIndices(s,ss_v,ss_i,ierr) call DAGetGlobalIndices(d,nloc,dd_v,dd_i,ierr)
#define xx_a(ib) xx_v(xx_i + (ib))Figure 16 contains an example of using VecGetArray() within a Fortran routine.double precision xx_v(1) PetscOffset xx_i integer i, ierr, n Vec x call VecGetArray(x,xx_v,xx_i,ierr) call VecGetLocalSize(x,n,ierr) do 10, i=1,n xx_a(i) = 3*i + 1 10 continue call VecRestoreArray(x,xx_v,xx_i,ierr)
Since in this case the array is accessed directly from Fortran, indexing begins with 1, not 0 (unless the array is declared as xx_v(0:1)). This is different from the use of VecSetValues() where, indexing always starts with 0.
Note: If using VecGetArray(), MatGetArray(), ISGetIndices(), or DAGetGlobalIndices() from Fortran, the user must not compile the Fortran code with options to check for ``array entries out of bounds'' (e.g., on the IBM RS/6000 this is done with the -C compiler option, so never use the -C option with this).