# Compilation error most of the times

**URL:** <https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619>\
**Category:** Homework\
**Created:** [May 31, 2022, 11:40am UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619 "2022-05-31T11:40:26Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jorvz](https://avatars.discourse-cdn.com/v4/letter/j/8edcca/32.png) [@jorvz](https://fortran-lang.discourse.group/u/jorvz)\
**Post date:** [May 31, 2022, 11:40am UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/1 "2022-05-31T11:40:26Z")

</div>

In most of the times i try to to run this code, it returns the error:

```auto
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0 0xffffffff
#1 0xffffffff
#2 0xffffffff
#3 0xffffffff
#4 0xffffffff
#5 0xffffffff
#6 0xffffffff
#7 0xffffffff
#8 0xffffffff
#9 0xffffffff
#10 0xffffffff
#11 0xffffffff
#12 0xffffffff
#13 0xffffffff
#14 0xffffffff

```

I’m still strugglin to learn the language but it’s (or it must be) a code for partciles collision using monte carlo method. I think the problem is the subroutine that change the velocities but i really have no idea. I know it is’nt the most efficient whey of writting this type of code and some of the code it’s temporary but the idea is pretty much it

```auto
program collision
    use rf_mod, only: rf
    implicit none
    
    integer :: n_particles = 10, i, j, k=0, t, ts=1000
    real(8), parameter :: radius=0.06, dt=0.00008, c=1.0
    integer, dimension(:,:) , allocatable :: id_pairs, id_pairs_collide
    real(8), dimension(:) , allocatable :: ids, d_pairs
    real(8), dimension(:,:) , allocatable :: r, v, v1, v2,v1new, v2new, r1, r2
    real(8), dimension(:,:,:), allocatable :: rs, vs
    
    
    !GENARATING THE PARTICLES
    allocate(r(2,n_particles)) !position of the particles
    allocate(v(2,n_particles)) !vellocities of the particles
    allocate(ids(n_particles))
    
    allocate(rs(ts, 2, n_particles))
    allocate(vs(ts, 2, n_particles))
    rs = 0.0
    vs = 0.0
    
    ids = [(i, i=1, n_particles)]
    
    call random_number(r)
    !do i=1, 2 !randomly positioning each particle
        !do j=1, n_particles
            !r(i,j) = rf()
        !end do
    !end do
    
    open(40, file = 'pos.txt', status='unknown')        
        do j =1, n_particles
                if(r(1,j) > 0.5) then
                    write(40,1)r(:,j)!, 'red'
                    1 format(2f20.6)
                else
                    write(40,2)r(:,j)!, 'green'
                    2 format(2f20.6)
                end if
        end do
    close(40)
    !call system ('gnuplot -p grafico.plt')
    
    !initial vellocities
    !if the particle is in the left corner, v=100.
    !if it's in the right, v=-100
    v(2,:) = 0
    where(r(1,:) < 0.5)
        v(1,:) = 100.
    elsewhere
        v(1,:) = -100.
    end where
    
    !DISTANCE BETWEEN ALL THE PAIR OF PARTICLES
    
    !all pair of particles
    id_pairs = combination(ids)
    d_pairs = get_deltad_pairs(r)
    

    do t=1, ts
    
        do i=1, size(d_pairs)
            if((d_pairs(i) <2*radius) .eqv. .true.) then
                k = k+1
            end if
        enddo
       
        allocate(id_pairs_collide(2,k))
    
        j=1
        do i=1, size(d_pairs)
            if(d_pairs(i) < 2*radius) then 
                id_pairs_collide(:,j) = id_pairs(:,i)
                j=j+1
            end if
        enddo

    !Now, we need to calculate the velocities of each particle, iterate, compare distances and change the vellocities
        v1 = v(:, id_pairs_collide(1,:)) !particle i
        v2 = v(:, id_pairs_collide(2,:)) !particle j
        r1 = r(:, id_pairs_collide(1,:))
        r2 = r(:, id_pairs_collide(2,:))
      
        call get_new_v(v1, v2, v1new, v2new) 
        v(:, id_pairs_collide(1,:)) = v1new
        v(:, id_pairs_collide(2,:)) = v2new
        
        
        where(r(1,:) > 1.0)
            v(1,:) = -abs(v(1,:))
        end where
        where(r(1,:) < 0.0)
            v(1,:) = abs(v(1,:))
        end where
        where(r(2,:) > 1.0)
            v(2,:) = -abs(v(2,:))
        end where
        where(r(2,:) < 0.0)
            v(2,:) = abs(v(2,:))
        end where
                
          
        r = r + v*dt
        rs(i,:,:) = r(:,:)
        vs(i,:,:) = v(:,:)

        deallocate(id_pairs_collide)
        deallocate(v1)
        deallocate(v2)
        deallocate(r1)
        deallocate(r2)
        !print *, r(:,1)

    enddo
    open(40, file = 'all_pos.txt', status='unknown')        
    do i = 1, ts
            write(40,*)rs(i,2,:)
    end do
    close(40)
    PRINT*, v1new
contains

function get_deltad_pairs(r)
    !get the distance between all the particles
    !d_ij = sqrt(x_ij ^ 2 + y_ij ^ 2)
    real(8), allocatable :: get_deltad_pairs(:), r(:,:)
    
    get_deltad_pairs = sqrt(diff(combination(r(1,:)))**2 + diff(combination(r(2,:)))**2)

end function get_deltad_pairs

function combination(arg) result(comb)
    implicit none
    real(8), dimension(:,:), allocatable :: comb
    real(8), intent(in), dimension(:) :: arg
    integer :: M, N, counter, i, j

    N=size(arg)
    M=int(N*(N-1)/2)
    allocate(comb(2,M))
    counter=1
    do i=1,N
        do j=i+1,N
            comb(1,counter)=arg(i)
            comb(2,counter)=arg(j)
            counter = counter + 1
        enddo
    enddo
    
end function combination

function diff(v)
    implicit none
    real(8), intent(in), dimension(:,:) :: v
    real(8), allocatable:: diff(:), v1(:), v2(:)
    integer :: n 

    n = size(v)/2
    allocate(v1(n))
    allocate(v2(n))
    v1 = v(1,:)
    v2 = v(2,:)
    diff = abs(v1 - v2)
end function diff

subroutine get_new_v(v1, v2, v1n, v2n)
    
    implicit none
    real(8), dimension(:,:), intent(in) :: v1, v2
    real(8), dimension(:,:), allocatable :: G, gr, grnew
    real(8), dimension(:,:), allocatable, intent(out) :: v1n, v2n
    real(8) :: cosx, sinx, e, RF1, RF2, PI=4.D0*DATAN(1.D0)
    integer :: i, j
    
    gr = v1 - v2 !relative velocities
    G = (v1 + v2)/2.0 !relative velocities o the center of mass
    
    do i=1, 2
        do j=1, size(gr)/2
            call random_number(RF2)
            call random_number(RF1)
            cosx = 2.0*RF1 - 1.0
            sinx = sqrt(1 - cosx**2)
            e = 2*RF2*pi

            if(i==1) then
                
                grnew(i,j) = sqrt(sum(gr(i,:)**2))*cosx
                
            else 
                
                grnew(i,j) = sqrt(sum(gr(i,:)**2))*sinx*sin(e)
                
            endif
        enddo
    enddo

    v1n = G + 0.5*grnew
    v2n = G - 0.5*grnew
    return

end subroutine get_new_v 

end program

module rf_mod
    contains
    DOUBLE PRECISION FUNCTION RF()
        IMPLICIT DOUBLE PRECISION (A-H, O-Z)
        data IX1,IX2,IX3,IX4,IX5,IX6/1500419,1400159,1364,1528,1,3/
        RR1=1.0/FLOAT(IX1)
        RR2=1.0/FLOAT(IX2)
        IX5=MOD(IX5*IX3,IX1)
        IX6=MOD(IX6*IX4,IX2)
        RF=RR1*IX5+RR2*IX6
        IF(RF.GE.1.0)RF=RF-1.0
    END FUNCTION

end module

```

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [May 31, 2022, 12:02pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/2 "2022-05-31T12:02:10Z")

</div>

In subroutine **get\_newv()**, you are using the 2-D allocatable array **grnew** without allocating it!

Another thing to check: does your code satisfies the following rule?

_If a vector subscript has two or more elements with the same value, an array section with that vector subscript shall not appear in a variable definition context_

---

<div class="post-metadata">

**Author:** ![Ali](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ali/32/751_2.png) [@Ali](https://fortran-lang.discourse.group/u/Ali)\
**Post date:** [May 31, 2022, 12:38pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/3 "2022-05-31T12:38:31Z")

</div>

I see these problems in your code:

- Some allocatable variables are not allocated
- Mixed mode arithmetic
- Mixed mode variable assignments
- real(kind=4) instead of real(kind=8)

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [May 31, 2022, 12:38pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/4 "2022-05-31T12:38:35Z")

</div>

Using debugging compiler options can aid in debugging. On WSL2, compiling with  
`gfortran -g -fbacktrace collision.f90` and running

gives

```auto
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0 0x7fe1bdf1d700 in ???
#1 0x7fe1bdf1c8a5 in ???
#2 0x7fe1bdc0120f in ???
#3 0x55df3f479b98 in get_new_v
	at /mnt/c/fortran/test/collision.f90:207
#4 0x55df3f47ce6d in collision
	at /mnt/c/fortran/test/collision.f90:130
#5 0x55df3f47f0e9 in main
	at /mnt/c/fortran/test/collision.f90:18
Segmentation fault

```

The code was rearranged to put the module before the main program:

> **collision.f90**
>
> ```auto
> module rf_mod
> contains
> DOUBLE PRECISION FUNCTION RF()
> IMPLICIT DOUBLE PRECISION (A-H, O-Z)
> data IX1,IX2,IX3,IX4,IX5,IX6/1500419,1400159,1364,1528,1,3/
> RR1=1.0/FLOAT(IX1)
> RR2=1.0/FLOAT(IX2)
> IX5=MOD(IX5*IX3,IX1)
> IX6=MOD(IX6*IX4,IX2)
> RF=RR1*IX5+RR2*IX6
> IF(RF.GE.1.0)RF=RF-1.0
> END FUNCTION
> 
> end module
> 
> program collision
> use rf_mod, only: rf
> implicit none
>     
> integer :: n_particles = 10, i, j, k=0, t, ts=1000
> real(8), parameter :: radius=0.06, dt=0.00008, c=1.0
> integer, dimension(:,:) , allocatable :: id_pairs, id_pairs_collide
> real(8), dimension(:) , allocatable :: ids, d_pairs
> real(8), dimension(:,:) , allocatable :: r, v, v1, v2,v1new, v2new, r1, r2
> real(8), dimension(:,:,:), allocatable :: rs, vs
>     
>     
> !GENARATING THE PARTICLES
> allocate(r(2,n_particles)) !position of the particles
> allocate(v(2,n_particles)) !vellocities of the particles
> allocate(ids(n_particles))
>     
> allocate(rs(ts, 2, n_particles))
> allocate(vs(ts, 2, n_particles))
> rs = 0.0
> vs = 0.0
>     
> ids = [(i, i=1, n_particles)]
>     
> call random_number(r)
> !do i=1, 2 !randomly positioning each particle
> !do j=1, n_particles
> !r(i,j) = rf()
> !end do
> !end do
>     
> open(40, file = 'pos.txt', status='unknown')        
> do j =1, n_particles
> if(r(1,j) > 0.5) then
> write(40,1)r(:,j)!, 'red'
> 1 format(2f20.6)
> else
> write(40,2)r(:,j)!, 'green'
> 2 format(2f20.6)
> end if
> end do
> close(40)
> !call system ('gnuplot -p grafico.plt')
>     
> !initial vellocities
> !if the particle is in the left corner, v=100.
> !if it's in the right, v=-100
> v(2,:) = 0
> where(r(1,:) < 0.5)
> v(1,:) = 100.
> elsewhere
> v(1,:) = -100.
> end where
>     
> !DISTANCE BETWEEN ALL THE PAIR OF PARTICLES
>     
> !all pair of particles
> id_pairs = combination(ids)
> d_pairs = get_deltad_pairs(r)
>     
> 
> do t=1, ts
>     
> do i=1, size(d_pairs)
> if((d_pairs(i) <2*radius) .eqv. .true.) then
> k = k+1
> end if
> enddo
>        
> allocate(id_pairs_collide(2,k))
>     
> j=1
> do i=1, size(d_pairs)
> if(d_pairs(i) < 2*radius) then 
> id_pairs_collide(:,j) = id_pairs(:,i)
> j=j+1
> end if
> enddo
> 
> !Now, we need to calculate the velocities of each particle, iterate, compare distances and change the vellocities
> v1 = v(:, id_pairs_collide(1,:)) !particle i
> v2 = v(:, id_pairs_collide(2,:)) !particle j
> r1 = r(:, id_pairs_collide(1,:))
> r2 = r(:, id_pairs_collide(2,:))
>       
> call get_new_v(v1, v2, v1new, v2new) 
> v(:, id_pairs_collide(1,:)) = v1new
> v(:, id_pairs_collide(2,:)) = v2new
>         
>         
> where(r(1,:) > 1.0)
> v(1,:) = -abs(v(1,:))
> end where
> where(r(1,:) < 0.0)
> v(1,:) = abs(v(1,:))
> end where
> where(r(2,:) > 1.0)
> v(2,:) = -abs(v(2,:))
> end where
> where(r(2,:) < 0.0)
> v(2,:) = abs(v(2,:))
> end where
>                 
>           
> r = r + v*dt
> rs(i,:,:) = r(:,:)
> vs(i,:,:) = v(:,:)
> 
> deallocate(id_pairs_collide)
> deallocate(v1)
> deallocate(v2)
> deallocate(r1)
> deallocate(r2)
> !print *, r(:,1)
> 
> enddo
> open(40, file = 'all_pos.txt', status='unknown')        
> do i = 1, ts
> write(40,*)rs(i,2,:)
> end do
> close(40)
> PRINT*, v1new
> contains
> 
> function get_deltad_pairs(r)
> !get the distance between all the particles
> !d_ij = sqrt(x_ij ^ 2 + y_ij ^ 2)
> real(8), allocatable :: get_deltad_pairs(:), r(:,:)
>     
> get_deltad_pairs = sqrt(diff(combination(r(1,:)))**2 + diff(combination(r(2,:)))**2)
> 
> end function get_deltad_pairs
> 
> function combination(arg) result(comb)
> implicit none
> real(8), dimension(:,:), allocatable :: comb
> real(8), intent(in), dimension(:) :: arg
> integer :: M, N, counter, i, j
> 
> N=size(arg)
> M=int(N*(N-1)/2)
> allocate(comb(2,M))
> counter=1
> do i=1,N
> do j=i+1,N
> comb(1,counter)=arg(i)
> comb(2,counter)=arg(j)
> counter = counter + 1
> enddo
> enddo
>     
> end function combination
> 
> function diff(v)
> implicit none
> real(8), intent(in), dimension(:,:) :: v
> real(8), allocatable:: diff(:), v1(:), v2(:)
> integer :: n 
> 
> n = size(v)/2
> allocate(v1(n))
> allocate(v2(n))
> v1 = v(1,:)
> v2 = v(2,:)
> diff = abs(v1 - v2)
> end function diff
> 
> subroutine get_new_v(v1, v2, v1n, v2n)
>     
> implicit none
> real(8), dimension(:,:), intent(in) :: v1, v2
> real(8), dimension(:,:), allocatable :: G, gr, grnew
> real(8), dimension(:,:), allocatable, intent(out) :: v1n, v2n
> real(8) :: cosx, sinx, e, RF1, RF2, PI=4.D0*DATAN(1.D0)
> integer :: i, j
>     
> gr = v1 - v2 !relative velocities
> G = (v1 + v2)/2.0 !relative velocities o the center of mass
>     
> do i=1, 2
> do j=1, size(gr)/2
> call random_number(RF2)
> call random_number(RF1)
> cosx = 2.0*RF1 - 1.0
> sinx = sqrt(1 - cosx**2)
> e = 2*RF2*pi
> 
> if(i==1) then
>                 
> grnew(i,j) = sqrt(sum(gr(i,:)**2))*cosx
>                 
> else 
>                 
> grnew(i,j) = sqrt(sum(gr(i,:)**2))*sinx*sin(e)
>                 
> endif
> enddo
> enddo
> 
> v1n = G + 0.5*grnew
> v2n = G - 0.5*grnew
> return
> 
> end subroutine get_new_v 
> 
> end program
> 
> ```

Line 207 is  
` grnew(i,j) = sqrt(sum(gr(i,:)**2))*cosx`  
consistent with what @mecej4 wrote. Other gfortran debugging options were [discussed at Stack Overflow](https://stackoverflow.com/questions/3676322/what-flags-do-you-set-for-your-gfortran-debugger-compiler-to-catch-faulty-code).

Btw your question is about a run-time error, not a compilation error.

---

<div class="post-metadata">

**Author:** ![jorvz](https://avatars.discourse-cdn.com/v4/letter/j/8edcca/32.png) [@jorvz](https://fortran-lang.discourse.group/u/jorvz)\
**Post date:** [May 31, 2022, 3:33pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/6 "2022-05-31T15:33:59Z")

</div>

about line 207, i don’t think i understood what’s wrong

---

<div class="post-metadata">

**Author:** ![jorvz](https://avatars.discourse-cdn.com/v4/letter/j/8edcca/32.png) [@jorvz](https://fortran-lang.discourse.group/u/jorvz)\
**Post date:** [May 31, 2022, 3:35pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/7 "2022-05-31T15:35:05Z")

</div>

Thanks, but could you point me on how to fix those problems?

---

<div class="post-metadata">

**Author:** ![Abhilash](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/abhilash/32/1635_2.png) [@Abhilash](https://fortran-lang.discourse.group/u/Abhilash)\
**Post date:** [May 31, 2022, 4:58pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/8 "2022-05-31T16:58:00Z")

</div>

Jorvz, looks like you missed this:

> [@mecej4](#):
>
> In subroutine **get\_newv()**, you are using the 2-D allocatable array **grnew** without allocating it!

You need to allocate the allocatable arrays before using them. It looks like you did not explicitly allocate `gr`, `G`, or `grnew`. `gr` got allocated through the automatically allocated on assignment feature on the line which reads `gr=v1-v2`. Similar with `G`. `grnew` array is being used without being allocated.

---

<div class="post-metadata">

**Author:** ![Ali](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ali/32/751_2.png) [@Ali](https://fortran-lang.discourse.group/u/Ali)\
**Post date:** [May 31, 2022, 10:25pm UTC](https://fortran-lang.discourse.group/t/compilation-error-most-of-the-times/3619/9 "2022-05-31T22:25:28Z")

</div>

- You need to allocate all allocatable variables, like `gr`, `G`, `grnew`, …

- I would like to suggest you to use a module for kinds as follows:

```auto
!==============================================================================
MODULE MOD_KINDS

   INTEGER, PARAMETER :: REL8 = 8

END MODULE MOD_KINDS
!==============================================================================

```

Now to declare and define a variable using module `MOD_KINDS` you can use:  
`real(REL8)` instead of `real(8)`,  
`rs = 0.0_REL8` instead of `rs = 0.0`,  
`0.5_REL8` instead of `0.5`  
and `2.0_REL8*radius` instead of `2*radius`. Find all the same problems and fix them.

- To convert `x` to real(kind=8), you can use `REAL(x,KIND=REL8)`.

- `ids` is `real(kind=8)`: `ids = REAL([(i, i=1, n_particles)], KIND=REL8)`

- Check `n = size(v)/2` and `M = int(N*(N-1)/2)`. Are they correct?

- I think there are more problems but you can find them yourself, also debug each function and subroutine with a test program first, then use them in your program, and finally debug your main program. (as @beliavsky mentioned use `-g -fbacktrace` flags.)
