Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran IO of 3D arrays

  1. May 13, 2009 #1

    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:

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

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


    write(17,*) !skip a line


    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! =]
  2. jcsd
  3. May 13, 2009 #2
    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 (Text):
    write(17,'(2I5)') n,m
    do x=1,n
    do y=1,m
    *write(17,*) !skip a line  not required
    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 (Text):
    read(17,'(2I5)') n,m
    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
  4. May 13, 2009 #3
    Thanks mathmate, your info was very helpful!

    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

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

    Thanks again! :smile:
  5. May 13, 2009 #4


    User Avatar
    Science Advisor

    You actually don't even need the do loops. You can simply
    Code (Text):

    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.
  6. May 13, 2009 #5
    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?

  7. May 13, 2009 #6
    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.
  8. May 13, 2009 #7
    Okay, great! I left out the skipping a line part, as you mentioned it isn't needed.

    Thanks again!
  9. May 13, 2009 #8
    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.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook