Сообщение об ошибке, которое выдает gfortran, так же хорошо, как и они. Он указывает на nib
в строке
real, dimension (nb,nib,njb,nkb)::x,y,z
nib
объявлен как массив. Это не разрешено. (Каковы будут размеры x
, y
и z
в этом измерении?)
Помимо этого, я не очень понимаю ваше описание того, что вы пытаетесь сделать, и пример кода, который вы показываете, не имеет для меня особого смысла.
common/iteration/nb
integer, dimension (:),allocatable::nib,njb,nkb
real, dimension (:,:,:,:),allocatable::x,y,z
allocate (nib(nb),njb(nb),nkb(nb))
При написании нового кода крайне предпочтительно использовать модули для связи между программными модулями. Следует избегать общих блоков старого стиля.
Вы пытаетесь выделить nib
, njb
и nkb
размером nb
. Проблема в том, что nb
еще не было присвоено значение (и не будет присвоено нигде в коде).
do l=1,nb
ni=nib(l)
nj=njb(l)
nk=nkb(l)
allocate (x(l,ni,nj,nk),y(l,ni,nj,nk),z(l,ni,nj,nk))
enddo
Опять проблема с тем, что nb
не имеет значения. Этот цикл выполняется неизвестное количество раз. Вы также используете массивы nib
, njb
и nkb
, которые еще не содержат никаких значений.
В каждой итерации цикла выделяются x
, y
и z
. Это приведет к ошибке выполнения во второй итерации, потому что вы не можете выделить уже выделенную переменную. Даже если бы распределения работали, этот цикл был бы бесполезен, потому что три массива будут сбрасываться на каждой итерации и в конечном итоге будут установлены в размеры последнего распределения.
Теперь, когда я пишу это, я начинаю думать, что то, что вы пытаетесь сделать, это создать так называемые «зубчатые массивы»: вы хотите создать блок в x(1,:,:,:)
, который отличается по размеру во втором, третье и/или четвертое измерение из блока в x(2,:,:,:)
и так далее. Это просто невозможно в фортране.
Одним из способов добиться этого было бы создание определяемого пользователем типа с выделяемым компонентом трехмерного массива и создание массива этого типа. Затем вы можете выделить компонент массива до нужного размера для каждого элемента массива пользовательского типа. Это будет выглядеть примерно так (отказ от ответственности: непроверенный и только один из возможных способов достижения вашей цели).
type :: blocktype
real, dimension(:, :, :), allocatable :: x, y, z
end type blocktype
type(blocktype), dimension(nb) :: myblocks
Затем вы можете запустить цикл, чтобы выделить x
, y
и z
разного размера для каждого элемента массива. Предполагается, что для nb
установлено требуемое значение, а nib
, njb
и nkb
содержат желаемые размеры для разных блоков.
do block = 1, nb
ni = nib(block)
nj = njb(block)
nk = nkb(block)
allocate(myblocks(block)%x(ni, nj, nk))
allocate(myblocks(block)%y(ni, nj, nk))
allocate(myblocks(block)%z(ni, nj, nk))
enddo
Если вы хотите сделать это таким образом, вы определенно захотите поместить свои процедуры в модули, потому что таким образом вы автоматически получите явные интерфейсы, которые необходимы для передачи таких массивов пользовательского типа.
Одно замечание: не используйте неявную типизацию даже в примере кода. Всегда используйте implicit none
.
person
eriktous
schedule
24.06.2012
Expression at (1)
? - person Hristo Iliev   schedule 24.06.2012