有几个类似我的头衔的线程,但我不相信它们是相同的。一个非常相似fortran pass allocated array to main procedure,但答案需要Fortran 2008.我正在使用Fortran 90/95解决方案。
另一个非常好的,非常相似的主题是Dynamic array allocation in fortran90。然而,在这个方法中,当它们在子程序中分配时,它们似乎从未出现解除分配,这看起来很奇怪。我的方法在表面看起来至少是相同的,但是当我在主程序中打印数组时,只打印空格。当我在子程序中打印时,数组会打印以筛选正确的值和正确的数值。
在下面的MAIN程序中调用子程序。此子例程将数据读入可分配的数组,并将数组传递回主程序。我这样做是通过使用小的子程序,每个子程序设计用于在输入文件中查找特定的术语。所有这些子例程都在一个模块文件中。所以有三个文件:Main.f90,input_read.f90和filename.inp。
似乎我不知道如何传递一个可在程序Main.f90中分配的数组,以及在被调用的子程序中,在该子程序中实际分配,调整大小,然后在传递给程序Main之前取消分配。这可能听起来令人困惑,所以这里是所有三个程序的代码。当我粘贴它时,我为糟糕的格式道歉。我试图将所有行分开。
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
再一次,我无法弄清楚如何将分配的epsilstar
数组传递给主程序。我已经尝试将未分配的数组传递给main.f90中的子例程,将其分配到内部,将其传回,并在main.f90中取消分配,但这不起作用。我已经尝试了它,因为代码当前是...代码可以工作(即没有bug),但是它没有从正常找到它的子例程传递epsilstar
并创建一个数组。
答案 0 :(得分:0)
事实证明,我犯的错误是在将子程序传递给主程序之前解除子程序中的数组。通过NOT解除分配,阵列被发送回来了。另外,我也没有在主程序中解除分配。