Segmentation fault problem in fortran 90

  • Context: Fortran 
  • Thread starter Thread starter s_hy
  • Start date Start date
  • Tags Tags
    Fault Fortran
Click For Summary
SUMMARY

The discussion centers on a segmentation fault error encountered in a Fortran 90 program implementing a finite difference method for a scalar wave equation. Key issues identified include incorrect array declarations for the variable 'u' and the variable 'x', which lead to out-of-bounds access. The correct declaration for 'u' should be "real, allocatable :: u(:,:)" instead of "real,dimension(:,,allocatable :: u". Additionally, the variable 'x' should be declared as "real, dimension(:) :: x" to allow for proper indexing. These corrections are essential for resolving the segmentation fault.

PREREQUISITES
  • Understanding of Fortran 90 syntax and array declarations
  • Familiarity with finite difference methods in numerical analysis
  • Knowledge of debugging techniques for Fortran programs
  • Basic concepts of memory allocation in programming
NEXT STEPS
  • Review Fortran 90 array declaration and allocation best practices
  • Learn about debugging tools for Fortran, such as GDB or Valgrind
  • Explore finite difference methods and their stability conditions in numerical simulations
  • Investigate common causes of segmentation faults in programming
USEFUL FOR

This discussion is beneficial for Fortran developers, numerical analysts, and anyone involved in scientific computing who is troubleshooting segmentation faults in their code.

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:
Technology news 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 ::
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
18K
  • · Replies 8 ·
Replies
8
Views
6K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
Replies
1
Views
2K
Replies
3
Views
27K
  • · Replies 3 ·
Replies
3
Views
13K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K