Подпрограмма Fortran: Как загрузить данные только при первом вызове - PullRequest
2 голосов
/ 09 июля 2019

Я программирую модуль Fortran, который связан с внешней основной программой.Я могу только изменить подпрограмму.Я должен детализировать много данных, но всегда одно и то же.Это занимает слишком много времени, чтобы сделать это при каждом вызове подпрограммы.Как я могу инициализировать данные только при первом вызове?В настоящее время это подпрограмма:

subroutine sdvini(statev,coords,nstatv,ncrds,noel,npt,layer,kspt)
implicit none  

integer imdat(100,100,50)

imdat(1,1,1:33)=(/1,8,13,24,48,72,111,148,156,165,182&
&,189,194,207,210,216,236,247,254,270,311,319,339,343,367,376&
&,393,397,421,438,447,473,492/)
.
. lots of data
. 

do something
return
end

1 Ответ

2 голосов
/ 09 июля 2019

Эта установка значений при первом вызове процедуры и сохранении значений может быть выполнена явной инициализацией . Мы часто используем термин инициализация, как в этом вопросе, чтобы обозначить назначение как часть процесса настройки. Однако инициализация означает нечто более точное в терминах Фортрана.

Явная инициализация, подходящая для этого вопроса, будет чем-то вроде очень простого случая

integer, save :: i=1   ! SAVE attribute would be implied, but made explicit

Это похоже на применение назначения при первом вводе процедуры.

Мы также можем использовать оператор данных:

integer, save :: i
data i /1/

Атрибут SAVE обеспечивает сохранение значения между записями в процедуре.

Для массивов идея та же, возможно, с использованием конструкторов массива и reshape.

Для очень больших массивов нецелесообразно использовать операторы данных или инициализаторы. Кроме того, существуют ограничения на то, что может появиться при инициализации сохраненной локальной переменной. Тем не менее, другая идиома будет выглядеть как

subroutine sub
  logical, save :: firsttime=.TRUE.
  integer, save :: obj(100,100,50)

  if (firsttime) then
    obj = ...  ! Setting the value somehow, maybe even with a read
    firsttime = .FALSE.
  end if
end subroutine
...