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

时间:2017-04-21 03:16:01

标签: fortran gfortran fortran90 dynamic-arrays fortran95

有几个类似我的头衔的线程,但我不相信它们是相同的。一个非常相似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并创建一个数组。

1 个答案:

答案 0 :(得分:0)

事实证明,我犯的错误是在将子程序传递给主程序之前解除子程序中的数组。通过NOT解除分配,阵列被发送回来了。另外,我也没有在主程序中解除分配。