前提・実現したいこと
燃焼の化学反応解析コードCHEMKIN-II(Fortran77で作成)を使用しております.Pythonのリッチなデータ入出力およびデータ可視化機能を使いたく,PythonからFortran77のsubroutineを使用したいと思っております.
CHEMKIN-IIの内部で実行しているmainのProgramでは装置番号のopenと,装置番号を引数としたサブルーチンの呼び出しが行われております.
質問
PythonでOpenと同等の操作により装置番号を作成し,それを引数としてサブルーチンを呼ぶことは可能でしょうか.可能であればその方法を教えていただきたく.
該当のソースコード
参考までにPythonで再現したい箇所のCHEMKIIN-IIコードを記載します.
Fortran77
1 PROGRAM DRIVER 2C 3C*****DOUBLE PRECISION 4 IMPLICIT DOUBLE PRECISION (A-H, O-Z), INTEGER (I-N) 5C*****END DOUBLE PRECISION 6C*****SINGLE PRECISION 7C IMPLICIT REAL (A-H, O-Z), INTEGER (I-N) 8C*****END SINGLE PRECISION 9 PARAMETER ( LENIWK = 25000, LENRWK = 250000, LENCWK = 200, 10 1 LENSYM = 16) 11 DIMENSION IWORK (LENIWK), RWORK (LENRWK) 12 LOGICAL LEXIST 13 CHARACTER CWORK(LENCWK)*(LENSYM) 14 DATA LIN/5/, LOUT/6/, LINKCK/25/, LSAVE/7/, LIGN/9/, LREST/10/ 15C 16C LIN = Unit number for Keyword input 17C LOUT = Unit number for text output to terminal 18C LIGN = Unit number for text output file 19C LSAVE = Unit number for binary output file 20C LINKCK = Unit number for CHENKIN linking file 21C LREST = Unit number for binary restart file 22C LENIWK = Length of integer work array 23C LENRWK = Length of real work array 24C LENCWK = Length of character work array 25C LENSYM = Length of a character string in character work array 26C IWORK = Integer work array 27C RWORK = Real work array 28C CWORK = Character work array 29C 30C*****vms 31C SET I/O UNITS AND OPEN FILES. OPERATING SYSTEM IS vms VMS. 32C OPEN (LINKCK, STATUS='OLD', FORM='UNFORMATTED') 33C OPEN (LSAVE, STATUS='NEW', FORM='UNFORMATTED') 34C OPEN (LOUT, STATUS='NEW', FORM='FORMATTED') 35C OPEN (LIGN, STATUS='NEW', FORM='FORMATTED') 36C OPEN (LIN, STATUS='OLD', FORM='FORMATTED') 37C INQUIRE (FILE='restart', EXIST=LEXIST) 38C IF (LEXIST) OPEN (LREST,STATUS='OLD',FORM='UNFORMATTED') 39C*****END vms 40C 41C*****unix 42 OPEN (LINKCK, FORM='UNFORMATTED', FILE='cklink') 43 OPEN (LSAVE, FORM='UNFORMATTED', FILE ='save') 44 OPEN (LOUT, FORM='FORMATTED', FILE='terminalout') 45 OPEN (LIGN, FORM='FORMATTED', FILE = 'skout') 46 OPEN (LIN, FORM='FORMATTED', FILE='inp') 47 INQUIRE (FILE='restart', EXIST=LEXIST) 48 IF (LEXIST) THEN 49 OPEN (LREST, FORM='UNFORMATTED', 50 1 FILE='restart') 51 ENDIF 52C*****END unix 53C 54C PASS CONTROL TO SENKIN 55C 56 CALL SENKIN (LIN, LOUT, LINKCK, LSAVE, LIGN, LREST, 57 1 LENRWK, RWORK, LENIWK, IWORK, LENCWK, CWORK) 58C 59 STOP 60 END 61C 62 SUBROUTINE TEMPT (TIME, TEMP) 63 IMPLICIT DOUBLE PRECISION (A-H, O-Z), INTEGER (I-N) 64 RETURN 65 END 66C 67 SUBROUTINE VOLT (TIME, VOL, DVDT) 68 IMPLICIT DOUBLE PRECISION (A-H, O-Z), INTEGER (I-N) 69 RETURN 70 END 71 72
追記20190519
Python上で整数型の値を管理し,Fortranに渡して装置番号として使用するということを考えました.テストのためにPythonからOpen文を含むコードを書いて実行を.結果は以下.
実行環境 | 結果 |
---|---|
Pythonで装置番号を定義,Fortranに渡す | Segmentation fault |
Pythonから引数なしでFortranを呼ぶ,Fortranで装置番号を定義 | 実行可能 |
Fortran上で整数型を定義して渡すうまくいきますが,Pythonで管理しようとするとOPENの過程で怒られました.
参考に使用したコードを置いておきます.
python
1import ctypes 2import numpy as np 3 4# device number as argument 5def call_openfiles(readDN, writeDN): 6 f = np.ctypeslib.load_library("libfort.so", ".") 7 f.openfiles_.argtypes = [ 8 ctypes.c_int32, 9 ctypes.c_int32 10 ] 11 f.openfiles_.restype = ctypes.c_void_p 12 13 f.openfiles_(readDN, writeDN) 14 15# non argument 16def call_fortran(): 17 f = np.ctypeslib.load_library("libfort.so", ".") 18 f.main_.restype = ctypes.c_void_p 19 20 f.main_() 21 22# 装置番号を定義して引数として渡すとき 23readDN = 10 24writeDN = 11 25print("**call fortran from python with device number as argument") 26call_openfiles(readDN, writeDN) 27 28# 引数なしで渡すとき 29# print("**call fortran from python with non argument") 30# call_fortran()
fortran90
1subroutine main() 2 implicit none 3 integer :: readDN = 10 4 integer :: writeDN = 11 5 6 call openFiles(readDN, writeDN) 7 call rwNumbers(readDN, writeDN) 8 call closeFiles(readDN, writeDN) 9end subroutine main 10 11subroutine rwNumbers(readDN, writeDN) 12 implicit none 13 real,dimension(30)::numbers 14 real temp 15 integer i, j 16 integer readDN 17 integer writeDN 18 19 ! read numbers 20 do i = 1, 30 21 read(readDN, *) numbers(i) 22 end do 23 close(10) 24 25 ! baggle sort 26 do i = 2, 30 27 do j = 2, 32-i 28 if (numbers(j) < numbers(j-1)) then 29 temp = numbers(j) 30 numbers(j) = numbers(j-1) 31 numbers(j-1) = temp 32 end if 33 end do 34 end do 35 36 ! print numbers 37 print *, "Sorted numbers is written in sortedNumbers.txt" 38 do i=1, 30 39 write(writeDN,*) numbers(i) 40 end do 41end subroutine 42 43subroutine openFiles(readDN, writeDN) 44 implicit none 45 integer(4),intent(in) :: readDN 46 integer(4),intent(in) :: writeDN 47 48 print *, "Open files from fortran" 49 open(readDN , file='numbers.txt', status='old') 50 open(writeDN , file='sortedNumbers.txt', status='replace') 51end subroutine 52 53subroutine closeFiles(readDN, writeDN) 54 implicit none 55 integer readDN, writeDN 56 close(readDN) 57 close(writeDN) 58end subroutine
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/14 12:40
2019/05/19 01:15
2019/05/19 09:56