Передача переменных в Fortran из python приводит к неправильным значениям - PullRequest
0 голосов
/ 05 ноября 2018

Основываясь на этом минимальном примере , я хочу манипулировать переменными модуля Fortran с помощью подпрограмм Python и Fortran. Пожалуйста, взгляните на следующий пример:

vars.f90

module vars
implicit none
real(kind=selected_real_kind(p=15))      :: fk(10)
end module vars

sub.f90

subroutine sub
    use vars
    print *, "sub: fk(1) = ", fk(1)
    print *, "adding 1 to fk(1)"
    fk(1) = fk(1) + 1
    print *, "fk(1) = ", fk(1)
end

mytest.f90

include "vars.f90"
include "sub.f90"

Компиляция выполняется с помощью следующей команды и gfortran:

f2py -c -m mytest mytest.f90

Наконец, вот тестовый сценарий для воспроизведения проблемы в консоли Python 3.6.5:

>>> import mytest
>>> mytest.vars.fk[1]
0.0
>>> mytest.vars.fk[1]=1.5000
>>> mytest.vars.fk[1]
1.5
>>> mytest.sub()
 sub: fk(1) =   0.12500000000000000     
 adding 1 to fk(1)
 fk(1) =    1.1250000000000000     
>>> mytest.vars.fk[1]
1.890625
>>> 

С моей точки зрения, fk (1) должно быть 2,5 в конце. Но, к сожалению, Fortran неправильно читает переменную в подпрограмме, хотя прямой доступ к переменной через консоль python отображает правильное значение. После изменения переменной консоль python также отображает неправильный номер.

Любой совет или предложение, чтобы решить / обосновать это поведение? Я ценю любую помощь! Спасибо!

P.S .: Сначала я подумал, что это зависит от того, как Python и Fortran по-разному обрабатывают массивы (Python начинается с индекса 0, а Fortran с индекса 1), но это не ошибка. mytest.vars.fk [0] не изменяется после вызова подпрограммы (начальное значение 0.0).

1 Ответ

0 голосов
/ 05 ноября 2018

Есть две проблемы с кодом:

  1. Индексация означает, что вы отметили. Вам все еще необходимо получить доступ к fk[0] в Python, чтобы получить желаемое поведение.

  2. Использование selected_real_kind(p=15) для спецификации вида. См. FAQ F2PY и связанный с этим SO ответ .

В настоящее время f2py рассматривает вашу переменную как действительную переменную по умолчанию (здесь 32-разрядная) вместо двойной точности. Это можно исправить, создав файл .f2py_f2cmap (в текущем рабочем каталоге) с содержимым:

{'real':{'selected_real_kind(p=15)': 'double'}}

, который выберет "double" в качестве соответствующего типа C для вашего параметра. К сожалению, F2PY не может обнаружить современные типы Фортрана.

Я пометил это как дубликат f2py: указание реальной точности в фортране при взаимодействии с питоном? но здесь также есть проблема с индексацией. Посмотрим, что подумают другие.

...