似たタイトルのスレッドがいくつかありますが、それらは同じではないと思います。 1つは非常によく似たfortran pass allocated array to main procedureでしたが、答えにはFortran 2008が必要でした。私はFortran 90/95ソリューションの後です。SUBTROUTINEから割り当てられた配列をFortranのメインプログラムに渡す
もう1つの非常によく、非常によく似たスレッドはDynamic array allocation in fortran90です。しかし、このメソッドでは、サブルーチンで割り振りをしている間に割り振りを解除するように見えることはありません。私のメソッドは、少なくとも同じになるように表面を見ていますが、メインプログラムで配列を印刷すると、空白だけが表示されます。サブルーチン自体で印刷すると、配列は正しい値と正しい数の値を画面に表示します。
以下では、MAINプログラムがサブルーチンを呼び出します。このサブルーチンは、データを割り当て可能な配列に読み込み、配列をメインプログラムに戻します。私は、入力ファイルの特定の用語を探すために設計された小さなサブルーチンを使用してこれを行います。これらのサブルーチンはすべて1つのモジュールファイルにあります。したがって、Main.f90、input_read.f90、およびfilename.inpという3つのファイルがあります。
プログラムMain.f90で割り当て可能な配列と、プログラムのMainに渡される前に実際に割り当てられ、サイズが割り当てられ、割り当てが解除された呼び出されたサブルーチンの配列を渡す方法がわかりません。これはおそらく混乱するように聞こえるので、ここでは3つのプログラムすべてのコードを示します。私はそれを貼り付けたときの貧弱な書式設定についてお詫び申し上げます。私はすべての行を分離しようとしました。
main.f90の:
Program main
use input_read ! the module with the subroutines used for reading filename.inp
implicit none
REAL, Allocatable :: epsilstar(:)
INTEGER :: natoms
call Obtain_LJ_Epsilon(epsilstar, natoms)
print*, 'LJ Epsilon : ', epsilstar
END Program main
次はサブルーチンとモジュールです(私はすべてが、スペースのために必要なものを削除)、input_read.f90:
module input_read
contains
!===============================================================
!===============================================================
Subroutine Obtain_LJ_Epsilon(epsilstar,natoms)
! Reads epsilon and sigma parameters for Lennard-Jones Force-Field and also
! counts the number of types of atoms in the system
!===============================================================
!===============================================================
INTEGER :: error,line_number,natoms_eps,i
CHARACTER(120) :: string, next_line, next_next_line,dummy_char
CHARACTER(8) :: dummy_na,dummy_eps
INTEGER,intent(out) :: natoms
LOGICAL :: Proceed
real, intent(out), allocatable :: epsilstar(:)
error = 0
line_number = 0
Proceed = .true.
open(10,file='filename.inp',status='old')
!=============================================
! Find key word LJ_Epsilon
!=============================================
DO
line_number = line_number + 1
Read(10,'(A120)',iostat=error) string
IF (error .NE. 0) THEN
print*, "Error, stopping read input due to an error reading line"
exit
END IF
IF (string(1:12) == '$ LJ_epsilon') THEN
line_number = line_number + 1
exit
ELSE IF (string(1:3) == 'END' .or. line_number > 2000) THEN
print*, "Hit end of file before reading '$ LJ_epsilon' "
Proceed = .false.
exit
ENDIF
ENDDO
!========================================================
! Key word found, now determine number of parameters
! needing to be read
!========================================================
natoms_eps = -1
dummy_eps = 'iii'
do while ((dummy_eps(1:1) .ne. '$') .and. (dummy_eps(1:1) .ne. ' '))
natoms_eps = natoms_eps + 1
read(10,*) dummy_eps
enddo !we now know the number of atoms in the system (# of parameters)
close(10)
Allocate(epsilstar(natoms_eps))
epsilstar = 0.0
!============================================================
! Number of parameters found, now read their values
!============================================================
if(Proceed) then
open(11,file='filename.inp',status='old')
do i = 1,line_number-1
read(11,*) ! note it is not recording anything for this do loop
enddo
do i = 1,natoms_eps
read(11,*) dummy_char
read(dummy_char,*) epsilstar(i) ! convert string read in to real, and store in epsilstar
enddo
close(11)
PRINT*, 'LJ_epsilon: ', epsilstar ! printing to make sure it worked
endif
deallocate(epsilstar)
END Subroutine Obtain_LJ_Epsilon
end module input_read
そして最後に、入力ファイル:filename.inp
# Run_Type
NVT
# Run_Name
Test_Name
# Pressure
1.0
# Temperature
298.15
# Number_Species
# LJ_epsilon
117.1
117.1
117.1
# LJ_sigma
3.251
3.251
3.251
END
そして再び、私は渡す方法を見つけ出すことはできません割り当てられました0配列をメインプログラムに追加します。割り当てられていない配列をmain.f90からサブルーチンに渡してみました。内側に配置し、戻し、main.f90で割り当てを解除しましたが、うまくいきませんでした。コードが現在動作しているので、試しましたが、コードは動作します(つまりバグがありません)が、正しく見つけて配列を作成するサブルーチンからepsilstar
を渡しません。
コードで使用している割り当て可能な引数は、Fortran 2003の標準機能です。 – IanH
これは知っておきたいことです。ありがとう! Fortran 90/95で配列を渡す方法を簡単に説明していますか?私が本当に気に入らない方法の1つは、最初にサブルーチンを実行して、後にあるもののサイズを取得することです。割り当てが不要です。これはFortran 90/95方式ですか? –