Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28602 Discussions

Outputing an allocatable array from a subroutine

ucdavisprgmer
Beginner
383 Views
-just can't seem to do it.
My goal: makea simple subroutine that reads in a text file with 1 column of numbers and outputs an array with those numbers.
I can do it no problem in the main program but have been going nuts trying to output an array for which I don't know the dimensions in advance. I know you can use the allocatable inside a subroutine, but I haven't seen it used when the array is an output of the subroutine.
I've tried assumed shape and assumed size arrays but have had no luck.
The code I would like to put into a subroutine (that works in the main) is found below.
thanks for any help,
-J
*******************************************************
!_____________________________________________________
! Declaration of Variables
CHARACTER(len=20):: InputFile = 'keran.dat'
INTEGER::status ! status = 0 for success
INTEGER::nflows ! No. of flow data values
REAL:: temp ! temp var to read in data
! Arrays:
REAL, Allocatable, dimension(:) :: FlowArray
!______________________________________________________

! Open input file:
OPEN (unit=20, File=InputFile, STATUS='OLD', ACTION='READ', POSITION='REWIND',IOSTAT=status)
! Check if file is open
fileopen: If (status /= 0) THEN
WRITE (*,*) 'Hey, I failed to open the file'
GO TO 999
END IF fileopen
! Open was succesful -> count how much data
DO
READ(20, *,IOSTAT=status) temp
IF (status /= 0) EXIT
nflows = nflows + 1
END DO
! Read input file into an array
ALLOCATE ( FlowArray(nflows),STAT=status)
REWIND (Unit=20)
READ (20,*) FlowArray
0 Kudos
3 Replies
larsm
Beginner
383 Views

Here are two solutions, read_file and read_file2.

The first one is not Fortran 95 standard compliant, it is Fortran 2003 standard, however. But this construct is already implemented in the Compaq and Intel compilers. So in this context it is perfectly legitimate to have ALLOCATABLE as an attribute to a dummy (and actual, of course) argument.

The second solution is Fortran 90, 95 and 2003 standard compliant. It uses pointers.

Lars M

PROGRAM t1
IMPLICIT NONE
REAL, DIMENSION(:), ALLOCATABLE :: Flowarray
REAL, DIMENSION(:), POINTER :: Flowarray2 => NULL()

CALL read_file (Flowarray)
CALL read_file2 (Flowarray2)

CONTAINS

SUBROUTINE read_file (Flowarray)
REAL, DIMENSION(:), INTENT(OUT), ALLOCATABLE :: Flowarray

CHARACTER(len=20):: InputFile = 'keran.dat'
INTEGER::status ! status = 0 for success
INTEGER::nflows ! No. of flow data values
REAL:: temp ! temp var to read in data
! Arrays:
!______________________________________________________

! Open input file:
OPEN (unit=20, File=InputFile, STATUS='OLD', ACTION='READ', POSITION='REWIND',IOSTAT=status)
! Check if file is open
fileopen: If (status /= 0) THEN
WRITE (*,*) 'Hey, I failed to open the file'
STOP
END IF fileopen
! Open was succesful -> count how much data
DO
READ(20, *,IOSTAT=status) temp
IF (status /= 0) EXIT
nflows = nflows + 1
END DO
! Read input file into an array
ALLOCATE ( FlowArray(nflows),STAT=status)
REWIND (Unit=20)
READ (20,*) FlowArray
CLOSE (UNIT=20)
END SUBROUTINE read_file

SUBROUTINE read_file2 (Flowarray)
REAL, DIMENSION(:), POINTER :: Flowarray

CHARACTER(len=20):: InputFile = 'keran.dat'
INTEGER::status ! status = 0 for success
INTEGER::nflows ! No. of flow data values
REAL:: temp ! temp var to read in data
! Arrays:
!______________________________________________________

! Open input file:
OPEN (unit=20, File=InputFile, STATUS='OLD', ACTION='READ', POSITION='REWIND',IOSTAT=status)
! Check if file is open
fileopen: If (status /= 0) THEN
WRITE (*,*) 'Hey, I failed to open the file'
STOP
END IF fileopen
! Open was succesful -> count how much data
DO
READ(20, *,IOSTAT=status) temp
IF (status /= 0) EXIT
nflows = nflows + 1
END DO
! Read input file into an array
ALLOCATE ( FlowArray(nflows),STAT=status)
REWIND (Unit= 20)
READ (20,*) FlowArray
CLOSE (UNIT=20)
END SUBROUTINE read_file2
END PROGRAM t1

0 Kudos
andrew_s
Beginner
383 Views
The pointer solution also seems to work quite nicely when using functions that return automatically sized arrays as it seems to overcome the dreaded stack overflow problems.
0 Kudos
ucdavisprgmer
Beginner
383 Views
Thanks LarsM, as you said the first subroutine didn't work because CVF 6.1 runs Fortran 95. However, the second subroutine did the job nicely. I appreciate your post. Thanks. -J
0 Kudos
Reply