2014-10-11 91 views
0

我正在嘗試編寫Lennard Jones潛在的Fortran代碼,並從文件posinp_38.xyz讀取座標,但我遇到了SIGSEGV, segmentation fault occurred 我怎麼能找到問題出在哪裏。我是Fortran的新成員,所以任何幫助都很有幫助。從Fortran文件中讀取數字,SIGSEGV錯誤

PROGRAM lennardjones_1 
IMPLICIT NONE 
REAL(8), allocatable :: rat(:,:) ! coordinates of atoms 
REAL(8), allocatable :: fat(:,:) ! force between atoms 
INTEGER :: nat     ! number of atoms 
!INTEGER :: iat, jat    ! loop counter 
REAL :: epot      ! potential energy 
REAL :: ftot      ! total force on atoms 
CHARACTER(len=20) :: filename ! Input data file name 
CHARACTER(len=3) :: sat   ! for reading the file 
INTEGER :: status   ! I/O status: 0 for success 


! Get the name of the file containing the input data. 
WRITE (*,1000) 
1000 FORMAT (1X,'Enter the file name with the data to be sorted: ') 
WRITE (*,*) 'The file name is: posinp_38.xyz or posinp_1000.xyz ' 
READ (*,'(A20)') filename 

! Open input data file. 
OPEN (UNIT=21, FILE=filename, status='OLD', ACTION='READ', & 
     IOSTAT=status) 
READ (21,*) nat 
READ (21,*) 

CALL force_energy(rat, nat) 
    write (*,*) epot, ftot 
END PROGRAM lennardjones_1 

SUBROUTINE force_energy(rat,nat) 
IMPLICIT NONE 
REAL(8), allocatable :: rat(:,:) 
REAL(8), allocatable :: fat(:,:) 
INTEGER, INTENT(IN)  :: nat 
INTEGER :: iat, jat  ! local variables 
REAL :: epot 
REAL :: r , dx, dy, dz, d 
REAL :: ftot 
INTEGER :: status  ! I/O status: 0 for success 
CHARACTER(len=3) :: sat 

allocate (rat(3,nat)) 
allocate (fat(3,nat)) 
! Was the OPEN successful? 
fileopen: IF (status == 0) THEN  ! Open successful 
    DO iat = 1, nat 
     READ (21,*) sat, rat(1, iat), rat(2, iat), rat(3, iat) 
    END DO 
    CLOSE(21) 
END if fileopen 

DO iat = 1, nat 
    DO jat = iat+1, nat 
     dx = rat(1,jat)-rat(1,iat) 
     dy = rat(2,jat)-rat(2,iat) 
     dz = rat(3,jat)-rat(3,iat) 
     r = sqrt(dx**2 + dy**2 + dz**2) 
     d = 4*(-12/r**14 + 6/r**8) 
     fat(1,iat) = fat(1,iat) + d * dx 
     fat(2,iat) = fat(2,iat) + d * dy 
     fat(3,iat) = fat(3,iat) + d * dz 
     fat(1,jat) = fat(1,jat) - d * dx 
     fat(2,jat) = fat(1,jat) - d * dy 
     fat(3,jat) = fat(1,jat) - d * dz 
     ftot = ftot + (fat(1,iat)**2+fat(2,iat)**2+fat(3,iat)**2)+ & 
      (fat(1,jat)**2+fat(2,jat)**2+fat(3,jat)**2) 
     epot = epot+4*(1/r**12-1/r**6) 
    END DO 
END DO 
END SUBROUTINE force_energy 
+0

你知道使用調試器嗎?如果這是在Linux或Unix上,用'-g'編譯並使用'gdb'運行。 – wallyk 2014-10-11 17:39:07

+0

這是在Linux中,關於調試器從來沒有。我谷歌它。 – Abolfazl 2014-10-11 17:41:42

+0

請務必使用標籤[tag:fortran],並在必要時添加版本以區分您的問題是否具體。例如,您不能使用Fortran 2008,但只能使用Fortran 90. – 2015-12-17 11:54:45

回答

1

我很驚訝你得到了編譯代碼。您已經定義了一個帶有可分配參數的子例程,但沒有提供明確的接口,符合標準的編譯器應該能夠發現並提出錯誤。事實上,我很驚訝,我懷疑你沒有編譯發佈的代碼,並且錯誤源於一些完全不同的問題。

但是,如果這真的是你的代碼最簡單的方式來解決這個問題是

END PROGRAM lennardjones_1 

招行的源文件的末尾,並在已騰出的空間,插入行

CONTAINS 

這些更改將使程序內部的子例程和編譯器將負責定義顯式接口。

一旦你做出這些改變,在子程序中將INTENT(OUT)添加到rat的聲明中。

+0

很高興爲您感到驚訝! :) – Abolfazl 2014-10-11 18:05:25

+0

我打印'老鼠',它確實工作並正確地讀取文件。 – Abolfazl 2014-10-11 18:26:19