비슷한 제목의 스레드가 여러 개 있지만 그 중 하나가 같지 않다고 생각합니다. 하나는 fortran pass allocated array to main procedure과 매우 비슷하지만 답변에는 Fortran 2008이 필요합니다. 저는 Fortran 90/95 솔루션을 따릅니다.SUBTROUTINE에서 할당 된 배열을 Fortran의 주 프로그램에 넘김
아주 좋은 또 다른 스레드는 Dynamic array allocation in fortran90입니다. 그러나이 방법에서는 서브 루틴에 할당하는 동안 할당이 해제 된 것처럼 보이지 않으므로 이상하게 보입니다. 내 방법은 적어도 동일하게 보이지만, 주 프로그램에서 배열을 인쇄 할 때 공백 만 인쇄됩니다. 서브 루틴 자체에서 인쇄 할 때 배열은 올바른 값과 올바른 수의 값을 화면에 인쇄합니다.
다음에서는 MAIN 프로그램이 서브 루틴을 호출합니다. 이 서브 루틴은 데이터를 할당 가능한 배열로 읽어 들여 배열을 다시 주 프로그램으로 전달합니다. 필자는 입력 파일에서 특정 용어를 찾도록 설계된 작은 서브 루틴을 사용하여이 작업을 수행합니다. 이러한 모든 서브 루틴은 하나의 모듈 파일에 있습니다. 따라서 세 개의 파일이 있습니다 : Main.f90, input_read.f90 및 filename.inp.
그러면 프로그램 Main.f90에서 할당 할 수있는 배열을 전달하는 방법과 실제로 할당되고 크기가 지정되고 할당되지 않은 다음 호출 된 서브 루틴을 프로그램 Main으로 전달하는 방법을 모르겠습니다. 이것은 아마도 혼란스럽게 들릴 것입니다. 그래서 여기에 세 가지 프로그램 모두에 대한 코드가 있습니다. 부적절한 서식을 붙일 때 사과드립니다. 모든 행을 분리하려고했습니다.
main.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
마지막 입력 파일 :
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
다음 서브 루틴 (I 공간에 필요한 하나를 제외한 모두를 제거) input_read.f90와 모듈 : 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
그리고 또, 내가 전달하는 방법을 알아낼 수,984,614,321 할당 0 배열을 주 프로그램에 추가합니다. 할당되지 않은 배열을 main.f90에서 서브 루틴으로 전달하여 내부에 할당하고 다시 전달하고 main.f90에서 할당을 해제하려고 시도했지만 작동하지 않았습니다. 코드가 현재 작동 중입니다. 코드가 작동합니다 (즉, 버그가 없습니다). 제대로 찾았고 배열을 만드는 서브 루틴에서 epsilstar
을 전달하지 않습니다.
코드에서 사용하는 할당 가능 인수는 Fortran 2003 표준 기능입니다. – IanH
알아두면 좋을 것 같습니다. 감사! Fortran 90/95에서 배열을 전달하는 방법에 대한 간단한 설명이 있습니까? 제가 정말로 싫어하는 한 가지 방법은 처음부터 끝까지 통과하고 내가 가진 것의 크기를 얻는 서브 루틴을 가지는 것입니다. 그러면 할당 할 필요가 없습니다. 이것이 Fortran 90/95 방법일까요? –