Доступ к данным, хранящимся в сложных массивах - PullRequest
2 голосов
/ 22 июня 2019

Я пишу некоторый фортран-код, в котором мне трудно представить, как хранятся данные в иерархии массивов, что вызывает у меня проблемы с тем, как манипулировать подмножеством этих данных. Я прочитал некоторые данные, хранящиеся в неформатированном двоичном файле PLOT3D. Формат данных выглядит следующим образом:

  1. 1 int (nblocks): количество блоков (или зон) в вычислительной сетке
  2. 4 x nblocks ints: (ni (m), nj (m), nk (m), nvars (m)): количество точек i, j и k в каждом блоке вместе с количеством переменных решения в каждый блок.
  3. цикл по блокам (м)
  4. ni (m) x nj (m) x nk (m) x nvars (m) плавает (q (ni, nj, nk, nv, m)): переменные решения в каждой точке i, j и k для каждый блок.
  5. конец цикла над блоками
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

В моем случае меня интересует извлечение подмножества или просто изменение значений одной переменной решения во всех точках каждого блока. Похоже, я должен получить значения решения для этой переменной в каждой точке i, j и k для каждого блока в массиве 3 x nblocks.

Однако во время выполнения я получаю ошибку сегмента, которая указывает мне, что я неправильно определяю размер массива.

1 Ответ

1 голос
/ 24 июня 2019

В вашем блоке кода

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

Вы читаете только 4 значения вместо qq вместо ni(m) x nj(m) x nk(m) x nvars(m).Затем вы пытаетесь скопировать эти значения в q, который не соответствует.

Мне кажется, что правильный цикл должен быть

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

Я не уверен, что это решит вашу проблему, но здесь есть что-то подозрительное .

...