First, an important observation. When you pass arrays as arguments to subroutines, the upper and lower bounds of the actual argument are not maintained in the call unless the lower bound is 1. However, when passing pointers, the lower and upper bounds are maintained. See: Fortran subroutine returning wrong values
Second, unlike Java, C/C++, Python, etc, there is no concept of a file in FORTRAN/Fortran. See: http://docs.cray.com/books/S-3695-35/html-S-3695-35/pdollsmg.html
Moreover, hard-coding file identification units is extremely error prone. Instead of using larger integers, I recommend avoiding them altogether; the code below uses the newunit
specifier to read and write arrays into unformatted *.dat
files.
program main
use, intrinsic :: ISO_Fortran_env, only: &
stdout => OUTPUT_UNIT, &
compiler_version, &
compiler_options
! Explicit typing only
implicit none
! Variables
integer, parameter :: NX=2, NY=3
real, pointer :: write_ptr(:,:) => null()
real, allocatable :: read_alloc(:,:)
! Your original post did not have valid array extends
real, target, dimension(-NX:NX, -NY:NY) :: f, g
! Write data to binary files
write_ptr => f
call write_grid_to_file(write_ptr, './file1.dat')
nullify(write_ptr)
write_ptr => g
call write_grid_to_file(write_ptr, './file2.dat')
nullify(write_ptr)
! Allocate memory to read from files
allocate( read_alloc, mold=f)
call read_grid_from_file(read_alloc, './file1.dat')
print *, 'original f array'
print *, f
print *, 'read from *.dat file'
print *, read_alloc
write( stdout, '(/4a/)') &
' This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
contains
subroutine write_grid_to_file(grid, file_name)
! Dummy arguments
real, pointer, intent (in) :: grid(:,:)
character(len=*), intent(in) :: file_name
! Local variable
integer :: file_id_unit
! Write grid to file
open( newunit=file_id_unit, file=file_name, &
status='replace', form='unformatted', &
action='write', access='stream')
write( file_id_unit ) grid
close( file_id_unit )
end subroutine write_grid_to_file
subroutine read_grid_from_file(grid, file_name)
! Dummy arguments
real, intent (out) :: grid(:,:)
character(len=*), intent(in) :: file_name
! Local variable
integer :: file_id_unit
! Write grid to file
open( newunit=file_id_unit, file=file_name, &
status='old', form='unformatted', &
action='read', access='stream')
read( file_id_unit ) grid
close( file_id_unit )
end subroutine read_grid_from_file
end program main
The command line prompt:
gfortran -Wall -o main.exe main.f90; ./main.exe
yields
original f array
0.00000000 0.00000000 0.00000000 0.00000000 -4.64743227E-27 4.59121429E-41 2.93318617E+14 4.56823299E-41 -4.64740762E-27 4.59121429E-41 1.02162904E+15 4.56823299E-41 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
read from *.dat file
0.00000000 0.00000000 0.00000000 0.00000000 -4.64743227E-27 4.59121429E-41 2.93318617E+14 4.56823299E-41 -4.64740762E-27 4.59121429E-41 1.02162904E+15 4.56823299E-41 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
This file was compiled using GCC version 6.2.0 20161010 using the options -mtune=generic -march=x86-64 -Wall