Как передать массивы предполагаемого размера из fortran90/95 в fortran77 и обратно?

Я работаю над проектом, в котором результаты программы численного моделирования должны быть оптимизированы для соответствия измеряемому поведению. Я написал несколько подпрограмм произвольной формы на Фортране для извлечения определенных данных и выполнения некоторых предварительных вычислений, которые отлично работают. В целях оптимизации я планирую использовать алгоритм локального поиска, представленный здесь: http://mat.uc.pt/~zhang/software.html#bobyqa

Я передаю некоторые аргументы, такие как размеры и векторы параметров, в подпрограмму Fortran 77, и проблема в том, что переданные массивы аргументов не достигают другой стороны. Только первый элемент будет отображаться в массиве с размерностью 1.

Я нашел несколько полезных ответов в разделе Как использовать подпрограммы Fortran 77. в Fortran 90/95? и попытался поместить весь код 77 в модуль, но у меня все еще не получается. Явный интерфейс помогает получить все переменные в подпрограмме уровня 1 f77, но когда данные передаются на другой уровень (уровень 2), где должны быть построены массивы предполагаемого размера, одномерные массивы генерируются, если вообще генерируются.

Сначала я компилирую код f77, используя ifort -c -fixed (и пробовал -f77rtl), затем f90 и связываю все вместе.

Почему массивы предполагаемого размера не генерируются должным образом?? Тестовая программа от производителя работает нормально!

Как я могу передавать все необходимые данные через и обратно определенным образом, не используя явные интерфейсы? Или есть способ определить подходящие интерфейсы?

Вот пример кода:

  program main_f90
     use types
     implicit none
     real(dp) :: array(N)

     interface 
        subroutine sub77_level1(array)
           implicit real*8 (a-h,o-z)
           real*8, intent(inout) :: array
           dimension array(:)
        end subroutine
     end interface

     [...fill array...]
     call sub77_level1(array)
  end


  subroutine sub77_level1(array)
     implicit real*8 (a-h,o-z)
     integer i1, i2, i3, i4
     dimension array(:)

     [...modify array...]

     call sub77_level2(array(i1), array(i2), array(i3), i4)
     return
  end


  subroutine sub77_level2(array_1, array_2, array_3, i4)
     implicit real*8 (a-h,o-z)
     dimension array_1(*) array_2(*) array_3( i4, * )

     [...modify...]
     call sub_f90( <some other arrays, intent(in / out)> )

     return
  end

person cclem    schedule 26.01.2016    source источник
comment
Это помогло бы увидеть фактические ошибки, которые вы получили. Я действительно мало что получаю от но когда материал передается другому (уровень 2), где должны быть построены массивы предполагаемого размера, одномерные массивы генерируются, если вообще генерируются.. Вы должны показать ожидаемый результат и фактический результат и быть в состоянии сказать нам, что вы считаете неправильным в отношении вывода.   -  person Vladimir F    schedule 26.01.2016
comment
Я не вижу i4 в списке аргументов sub77_level2. Откуда оно оттуда. У вас есть какая-то особая причина не использовать implicit none? Это реальный код, который у вас есть (вы должны должны отображаться как один)? Обязательно скомпилируйте с -g -warn -check -traceback.   -  person Vladimir F    schedule 26.01.2016
comment
Процедура sub77_level1 использует массивы предполагаемых форм (спецификация измерения (:)). Это не Fortran 77 - это, по крайней мере, Fortran 90. Использование этого фиктивного аргумента предполагаемой формы - вот почему этой процедуре требуется тело интерфейса в вызывающей области. (Существует несоответствие в спецификации INTENT между телом интерфейса для этой процедуры и подпрограммой для процедуры.)   -  person IanH    schedule 26.01.2016
comment
Как я могу передавать все необходимые данные через и обратно определенным образом, не используя явные интерфейсы? Или есть способ определить подходящие интерфейсы? Ответ: поместите свои процедуры в модули. Причины использования интерфейсов: если у вас нет исходного кода или он на другом языке. В остальном модули проще и лучше. См. stackoverflow.com/questions/8412834/   -  person M. S. B.    schedule 27.01.2016
comment
Фактическая ошибка, которая возникает, не сильно поможет: два из переданных массивов содержат верхнюю и нижнюю границы, подпрограмма f77 проверяет, остается ли их разница достаточно большой для работы. Если нет, он выводит на консоль, что границы неверны. При отладке кода причина, очевидно, в пропущенных записях в неправильно созданных одномерных массивах. Ожидается, что это upper_bounds(6) и lower_bounds(6), но оба содержат только 1 запись   -  person cclem    schedule 27.01.2016
comment
А мой вопрос про i4?   -  person Vladimir F    schedule 27.01.2016
comment
пропустил, сейчас исправил   -  person cclem    schedule 27.01.2016
comment
интерфейс, как показано, был моей единственной успешной попыткой получить полные массивы на уровне 1, так что это больше не первоначальный дизайн. Вы предлагаете оставить код f77 нетронутым, убрать интерфейсы, а весь код f77 поместить в модули? Или просто подпрограмма верхнего уровня, которая вызывает дальнейший код f77?   -  person cclem    schedule 27.01.2016
comment
Является ли sub77_level1 точкой входа в bobyqa?   -  person why.n0t    schedule 27.01.2016
comment
Верно, я старался не делиться здесь чужим кодом, так как не уверен, что это законно...   -  person cclem    schedule 27.01.2016
comment
бобика бесплатна. (Ограниченная стандартная общественная лицензия GNU) Что такое sub77_level2? И вы изменили вызывающие аргументы?   -  person why.n0t    schedule 27.01.2016
comment
Хорошо, я поместил весь нетронутый код f77 bobyqa в один файл модуля, обернув вокруг MODULE BOB ; IMPLICIT REAL*8 (A-H,O-Z) ; PRIVATE ; PUBLIC BOBYQA ; CONTAINS ; [...Subroutines...] ; END MODULE, но возникает та же проблема, предполагаемые массивы размеров 1-d. Может быть, мой заголовок модуля неверен? Компиляция выполняется в Windows с использованием ifort -c bob_module.f -debug:full -check:all -fixed -f77rtl . Сначала модуль, затем линковка с ifort -o program.exe $(OBJECTS) bob_module.obj -debug:full -check:all   -  person cclem    schedule 27.01.2016
comment
level2 — это подпрограмма bobyqB, которая затем вызывает подпрограммы f77 altmov, prelim, update, save, trsbox и calfun (где я хочу разместить свою функциональную подпрограмму качества f90). Я не менял никаких аргументов   -  person cclem    schedule 27.01.2016
comment
я не использовал никаких модулей, у меня были все подпрограммы bobyq в том же исходном файле, что и мой код. Я использовал Fortran 90/95, но в фиксированном формате. (это беспорядок, но он работает и не требует обслуживания).   -  person why.n0t    schedule 27.01.2016
comment
Использование модулей помогло восстановить поток данных от подпрограмм f90 через f77 к подпрограммам f90 и обратно, и теперь программа работает. Но мне пришлось исключить все определения предполагаемого размера, сначала вычислив длины моих массивов, а затем дополнительно передав их подпрограммам, где определены массивы фиксированного размера. Спасибо за все ваши усилия!   -  person cclem    schedule 27.01.2016