2014-10-11 1 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

+0

그것은 리눅스에 있습니다. 디버거에 관한 것입니다. 나는 그것을 google한다. – Abolfazl

+0

항상 태그 [tag : fortran]을 사용하고 질문이 구체적이라는 것을 구별하기 위해 필요한 경우에만 버전을 추가하십시오. 예를 들어 포트란 2008을 사용할 수는 없지만 포트란 90 만 사용할 수 있습니다. –

답변

1

나는 그 코드를 컴파일하는 데 놀랐습니다. 할당 가능한 인수로 서브 루틴을 정의했지만 명시 적 인터페이스를 제공하지 않으면 표준 호환 컴파일러가이를 찾아 내서 오류를 제기해야합니다. 사실, 나는 놀란다. 나는 당신이 코드를 컴파일하지 않았고 그 오류가 완전히 다른 문제에서 기인한다고 생각한다. 그것은 정말 문제를 해결하는 쉬운 방법은 코드의 경우

하지만, 라인을 삽입, 그것은 비워 한 공간에있는 소스 파일의 끝에 선을

END PROGRAM lennardjones_1 

를 이동하는 것입니다

CONTAINS 

이러한 변경은 서브 루틴을 프로그램 내부로 만들고 컴파일러는 명시 적 인터페이스를 정의 할 것입니다.

이러한 변경을 수행하면 INTENT(OUT)을 서브 루틴의 rat 선언에 추가하십시오.

+0

놀랐습니다! :) – Abolfazl

+0

'rat'을 출력했는데 제대로 작동하고 파일을 올바르게 읽었습니다. – Abolfazl