# Fortran IO of 3D arrays

• Fortran
Hi!

I have a 3D array u(n,m,2), where n=2000, m=200 are the xy-coordinates, and u(n,m,1) and u(n,m,2) store values of variables a and b computed at the coordinates.

(not very familiar with fortran I/O for arrays, when new lines are started, etc).

I'd like to output this array into a text file, and read it in at a later point in the program (fortran 95). The following output works fine, and is set up perfectly for gnuplot:

open(17,file='values.dat',action='write')
do x=1,n
do y=1,m

write(17,'(2(E10.4,1X))') u(x,y,1),u(x,y,2)

enddo

write(17,*) !skip a line

enddo
close(17)

This writes 2000 blocks of 200 x 2 arrays separated by a space, column 1 are 'a' values, column 2 'b' values.

How can I read this from values.dat into another 3D array later in the program, ie, v(n,m,2)? Is there a better way to write to the file (ie make two files, for a and b) that will make reading into v easier?

Thanks! =]

It is possible to save some disk-space by writing the data in binary, such as a direct-access file, or using the binary format. The downside is that the file will not be easily human readable, and portability between systems could be an issue. However, you seem to write sequentially and read sequentially, once per run, so efficiency should not be a big issue.

> write(17,'(2(E10.4,1X))') u(x,y,1),u(x,y,2)

I personally would prefer a little redundancy and write x,y together with the data to ensure integrity. In addition, I would add a header to check for the size of the array before reading data, something like:

Code:
open(17,file='values.dat',action='write')
write(17,'(2I5)') n,m
do x=1,n
do y=1,m
write(17,'(2I5,2E12.4)')x,y,u(x,y,1),u(x,y,2)
enddo
*write(17,*) !skip a line  not required
enddo
close(17)

So when you read back the data, you can double-check the size of the array before reading, you would know when to end the reading (n*m lines) and the x, y coordinates would not be mixed up with rows and columns, or accidentally offset.

You can read it back using something like:

Code:
open(17,file='values.dat',action='read')
C do some array size checking here
do =1,n*m
C or, if preferred
C read(17,'(2I5,2E12.4)')x,y,tmp,v(x,y,2)   skips the first value
enddo
close(17)

I got a runtime error at the line: read(17,'(2I5,2E12.4)')x,y,u(x,y,1),u(x,y,2)
error: Traceback: (Innermost first)

I ended up using:

do x=1,n
do y=1,m
enddo
enddo

which leaves out your useful array size-checking line, and keeping x,y with the data points, but works nonetheless.

Thanks again!

minger
You actually don't even need the do loops. You can simply
Code:
open(11,file='filename.x',form='formatted')
write(11,*) u
!
!
read(11,*) u
As long as the array is the proper size when you're reading it in, it'll be fine.

Thanks minger. The writing works fine without do loops, but I get the "Traceback: (Innermost first)" error again when trying to read back in. Any idea why this error would show up?

Thanks!

Yes, you have the right statement to read the previous file that you wrote without the x,y values.
Basically, you use the same format to read and to write.
Be very careful, though, since you have skipped a line in your previous file after every 200 pairs of data, you would have to read it back in with the line skipping, or else they would show up as a pair if zeroes. This is where the x,y coordinate checking would avoid this problem. You must, however, write the file with the x,y u1, u2 before you can read it back with the x,y.

Okay, great! I left out the skipping a line part, as you mentioned it isn't needed.

Thanks again!

Do print the last values of u1 and u2 to make sure that nothing had been shifted as you read the values back into the program.