2017-04-21 107 views
1

有幾個線程的標題類似,但我不相信它們是相同的。其中一個非常類似於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時:

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

請注意,您在代碼中使用的可分配參數是Fortran 2003標準功能。 – IanH

+0

這是很好的知道。謝謝!有沒有關於如何在Fortran 90/95中傳遞數組的簡單描述?我不太喜歡的一種方式是先創建一個子程序,然後獲取我所處理的事物的大小,然後就不需要分配了。那是Fortran 90/95方法嗎? –

回答

0

事實證明,我犯的錯誤是在將子程序傳遞給主程序之前,在釋放子程序中的數組。通過不釋放,數組被送回。另外,我也不會在主程序中釋放。

+0

注意您收到的反饋很少。沒有評論或答案。試着讓你的問題更加簡潔。包含所有代碼是很好的,不要改變它,但是嘗試製作一個仍然存在問題的較短代碼(a [mcve])。刪除代碼的一部分,直到它停止執行所需的任務。 *最重要的事情:不要包含那麼多的文本,直接點。 –

+0

我很好奇,如果我應該保持它,因爲我發佈後自己解決它。看起來多餘。也許這對其他人會有用,但正如你所說的那樣,它有點笨重。 –

相關問題