Segmentation fault problem in fortran 90

  • Context: Fortran 
  • Thread starter Thread starter s_hy
  • Start date Start date
  • Tags Tags
    Fault Fortran
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
2 replies · 3K views
s_hy
Messages
57
Reaction score
0
dear all,

i have a code with line segmentation fault error. please anyone advice me how to debug this code. thank you...
Mentor note: Added code tags, combined numerous variable declarations, and indented some do loops
Fortran:
!##################################################################

Program Main

IMPLICIT NONE

call fd1d
return
END PROGRAM Main! 1d scalar wave equation with fd method and stability condition = 1
SUBROUTINE fd1d
implicit none

real,dimension(1) :: x
real :: x_delta,  t_delta, c, xlast, xinit, tinit, tlast
real :: k, x0
real,dimension(:,,allocatable :: u
real :: alpha
integer :: iinit, ilast, ninit, nlast, i, n
real, parameter :: pi = 3.141592654

allocate (u(0:200,0:600))

!initialisation
c = 300
x_delta = 0.005
t_delta = x_delta/c
alpha = c*t_delta/x_delta
xlast = 1.0
xinit = 0
iinit = 0
ilast = int ((xlast-xinit)/x_delta)
tlast = 0.01
tinit = 0
ninit = 0
nlast = int ((tlast-tinit)/t_delta)
x(iinit) = xinit
x(ilast) = xlast

!initial profile
k = 1000.0
x0 = 0.3
do i = iinit,ilast
    u(i,0) = 0.0
    u(i,-1) = 0.0
end do

open (unit=100,file='n0.dat',action='write')
do i = iinit, ilast
    x(i) = x(iinit) + i*x_delta
    u(i,0) = exp (-k*(x(i)-x0)**2)
    u(i,-1) = exp (-k*(x(i)-x0)**2)
    Print *, u(i,0)
    write (*,*) u(i,0)
end do
close (unit = 100)

open (unit=110,file='n1.dat',action='write')
do n = 0, nlast
    do i = iinit, ilast
        u(i,n+1) = 2*(1-(alpha**2))*u(i,n)-u(i,n-1)+(alpha**2)*(u(i+1,n)+u(i-1,n))
    end do !i

    !boundary condition
    u(0,n+1) = 0
    u(ilast,n+1) = 0
    !end of boundary condition
    !export data
    print *, u(i,n+1)
    write (110,*) u(i,n+1)
end do !n
close (unit = 110)

return
end SUBROUTINE fd1d
 
Last edited by a moderator:
on Phys.org
@s_hy, if you're still around, something that could be the source of your problem is what seems to be a questionable declaration of the variable u.
Line 19 has this:
Fortran:
real,dimension(:,,allocatable :: u
For one thing, there is a missing right parenthesis. Per this web page I found from a class at Princeton (http://kea.princeton.edu/che422/arrays.htm), the above should look more like this, at least in Fortran 90/95:
Fortran:
real, allocatable :: u(:,:)

After the array has been declared to be allocatable, you then use allocate to actually set aside storage on the heap for the array itself, as you did in line 24 of your code:
Fortran:
allocate (u(0:200,0:600))

The declaration in line 16 is an error, I believe...
Fortran:
real,dimension(1) :: x
... at least insofar as how you used x in lines 39, 40, and 52. The array x is capable of holding one real number, so the only valid index is 1. Lines 39, 40, and 52 attempt to put numbers in places other than at index 1, if iinit, ilast are any values other than 1.
Fortran:
x(iinit) = xinit
x(ilast) = xlast
...
x(i) = x(iinit) + i*x_delta

According to how the array u is defined, the first index can be any integer from 0 through 200, and the second index can be any integer from 0 through 600. In lines 47 and 54 the second index is -1, which is not in the range of indexes you specified.
 
Mark44 said:
Per this web page I found from a class at Princeton (http://kea.princeton.edu/che422/arrays.htm), the above should look more like this, at least in Fortran 90/95:
Fortran:
real, allocatable :: u(:,:)
For completeness, let me say that I would prefer
Fortran:
real, dimension(:,:), allocatable :: u
I think it is "neater" and more readable to have all attributes appear before the ::