将分配的数组从 SUBTROUTINE 传递到 Fortran 中的主程序

Passing an allocated array from a SUBTROUTINE to the main program in Fortran

我的帖子有几个标题相似,但我不认为它们是相同的。一个非常相似 fortran pass allocated array to main procedure,但答案需要 Fortran 2008。我正在寻求 Fortran 90/95 解决方案。

另一个非常好且非常相似的线程是 Dynamic array allocation in fortran90。然而,在这种方法中,当它们在子例程中进行分配时,它们似乎从未解除分配,这看起来很奇怪。我的方法至少在表面上看起来是一样的,但是当我在主程序中打印数组时,只打印空白 spaces 。当我在子例程本身中打印时,数组会打印以筛选正确的值和正确的值数。

下面一个主程序调用一个子程序。该子例程将数据读入可分配数组,并将该数组传回主程序。我通过使用小的子程序来做到这一点,每个子程序都设计用于在输入文件中查找特定的术语。所有这些子程序都在一个模块文件中。所以有三个文件: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

接下来是带有子例程的模块(我删除了 space 所需的所有子程序),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 中释放它,但这没有用。我已经尝试过它,因为当前代码是......代码有效(即没有错误)但它没有从正确找到它并创建数组的子例程中传递 epsilstar

原来我犯的错误是在将数组传递给主程序之前在子程序中释放了数组。通过不解除分配,数组被正常发回。另外,我也不在主程序中释放。