2

I'm writing some fortran code where I'm having difficulty visualizing how the data in a hierarchy of arrays is stored, which is causing me troubles with how to manipulate a subset of this data. I've read-in some data stored in an unformatted binary PLOT3D file. The data format looks like the following:

  1. 1 int (nblocks): number of blocks (or zones) in a computational mesh
  2. 4 x nblocks ints: (ni(m), nj(m), nk(m), nvars(m)): number of i, j, and k points in each block along with a number of solution variables in each block.
  3. loop over blocks (m)
  4. ni(m) x nj(m) x nk(m)x nvars(m) floats (q(ni,nj,nk,nv,m)): solution variables at each i, j, and k points for each block.
  5. end loop over blocks
program my_program

use iso_fortran_env

implicit none

character(*), parameter :: soln_file = 'my_file_name.q'

integer :: nblks, io_stat, imax, jmax, kmax, nv, m

integer, dimension (:), allocatable :: ni, nj, nk, nvars

real(real64), dimension (:,:,:,:), allocatable :: qq
real(real64), dimension (:,:,:,:,:), allocatable :: q

open(unit=10, form='unformatted', file=soln_file, status='old', iostat=io_stat)

if ( io_stat /= 0 ) then
    write(*,*) '*** Error reading solution file ', soln_file, ' ***'
    stop
end if

read(10) nblks

allocate( ni(nblks), nj(nblks), nk(nblks) )

read(10) ( ni(m), nj(m), nk(m), nvars(m), m = 1, nblks )

imax = maxval(ni)
jmax = maxval(nj)
kmax = maxval(nk)
nv = maxval(nvars)

allocate( q(imax,jmax,kmax,nv,nblks) )

do m = 1, nblks
    allocate( qq(ni(m),nj(m),nk(m),nvars(m)) )

    read(10) qq(ni(m),nj(m),nk(m),nvars(m))

    q(1:ni(m),1:nj(m),1:nk(m),1:nvars(m),m) = qq

    deallocate( qq )
end do

close(10)

deallocate( ni, nj, nk, nvars, q )

stop

end program my_program

In my case, I'm interested in extracting a subset, or just modifying the values in place, of a single solution variable at all of the points in every block. It seems like I should end up with the solution values for that variable at each i, j, and k point for every block in a 3 x nblocks array.

However, I get a seg fault at run time which indicates to me that I'm not sizing the array correctly.

5
  • I've updated my original comment with the snippet of relevant code from my program to illustrate how the array is being formed. The array q holds solution data at each i, j, and k point in a block for multiple blocks. Further, the solution data exists in any number of variables. I'm interested in how to extract a subset of the of the solution data for just a single variable. Commented Jun 22, 2019 at 14:37
  • Your code cannot be compiled. Prepare a real minimal reproducible example, test it and make sure it exhibits the right error. There is really nothing special about complex arrays, most likely you have some kind of error that can happen anywhere. To find it you must show the actual code. Commented Jun 22, 2019 at 14:41
  • Code should compile now. Commented Jun 22, 2019 at 15:11
  • Yes, but no-one can test it, because we do not have the required data files. Can't you really make a minimal example that does not require external data? Commented Jun 22, 2019 at 16:11
  • No, I can't provide the actual solution file, or a working sample of it. It's a a very large unformatted binary file, and I don't have a visual understanding of how the data within it is structured beyond the simple header which lists the number of blocks, and the i-, j-, and k-extents for each block. My question is more fundamental in how to extract a subset of a multidimensional array. In this specific example, I'm looking for an answer as to how to extract all of the solution data for 1 variable. Commented Jun 22, 2019 at 17:20

1 Answer 1

1

In your block of code

do m = 1, nblks
    allocate( qq(ni(m),nj(m),nk(m),nvars(m)) )

    read(10) qq(ni(m),nj(m),nk(m),nvars(m))

    q(1:ni(m),1:nj(m),1:nk(m),1:nvars(m),m) = qq

    deallocate( qq )
end do

You're only reading 4 values pour qq, instead of ni(m) x nj(m) x nk(m) x nvars(m). Then you're trying to copy theses values into q wich is not conformant.

It seems to me that the correct loop should be

do m = 1, nblks
    allocate( qq(ni(m),nj(m),nk(m),nvars(m)) )

    do iv = 1 ,nvars(m)
      do ik = 1 ,nk(m)
        do ij = 1 ,nj(m)
          do ii = 1 ,ni(m)
             read(10) qq(ii,ij,ik,iv)
          end do
        end do
      end do
    end do

    q(1:ni(m),1:nj(m),1:nk(m),1:nvars(m),m) = qq

    deallocate( qq )
end do

I'm not sure this will solve your problem, but there's something fishy here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.