Since my post someone has added a Fortran version based on the algorithm used in the C++11 code. It's a little faster than the C++11 code and it's much nicer looking:
http://benchmarksgame.alioth.debian.org/u32/program.php?test=nbody&lang=ifc&id=5


pure subroutine advance(tstep, x, v, mass)
  real*8, intent(in) :: tstep
  real*8, dimension(4,nb), intent(inout) :: x, v
  real*8, dimension(nb), intent(in) :: mass
  real*8 :: r(4,N),mag(N)

  real*8 :: distance, d2
  integer :: i, j, m
  m = 1
  do i = 1, nb
     do j = i + 1, nb
        r(1,m) = x(1,i) - x(1,j)
        r(2,m) = x(2,i) - x(2,j)
        r(3,m) = x(3,i) - x(3,j)
        m = m + 1
     end do
  end do

  do m = 1, N
     d2 = r(1,m)**2 + r(2,m)**2 + r(3,m)**2
     distance = 1/sqrt(real(d2))
distance = distance * (1.5d0 - 0.5d0 * d2 * distance * distance) !distance = distance * (1.5d0 - 0.5d0 * d2 * distance * distance)
     mag(m) = tstep * distance**3
  end do

  m = 1
  do i = 1, nb
     do j = i + 1, nb
        v(1,i) = v(1,i) - r(1,m) * mass(j) * mag(m)
        v(2,i) = v(2,i) - r(2,m) * mass(j) * mag(m)
        v(3,i) = v(3,i) - r(3,m) * mass(j) * mag(m)

        v(1,j) = v(1,j) + r(1,m) * mass(i) * mag(m)
        v(2,j) = v(2,j) + r(2,m) * mass(i) * mag(m)
        v(3,j) = v(3,j) + r(3,m) * mass(i) * mag(m)

        m = m + 1
     end do
  end do

  do i = 1, nb
     x(1,i) = x(1,i) + tstep * v(1,i)
     x(2,i) = x(2,i) + tstep * v(2,i)
     x(3,i) = x(3,i) + tstep * v(3,i)
  end do
  end subroutine advance


Bye,
bearophile

Reply via email to