MODULE SimulationFunctions

contains

SUBROUTINE initArray (arr)
  IMPLICIT NONE
  real(kind=4), intent (inout) :: arr(:)
  integer :: j
  real, parameter :: M_PI = 3.141593
  
  DO j = lbound(arr,1), ubound(arr, 1), 1
     arr(j) = sin (M_PI * real(j-1)/ size(arr)) * cos(real(j-1))
  END DO
END SUBROUTINE initArray

SUBROUTINE simulationStep (arr, attenuation)
  IMPLICIT NONE
  real(kind=4), intent (inout) :: arr(:)
  real(kind=4), intent (in) :: attenuation
  integer :: j

  DO j = lbound(arr,1)+1, ubound(arr,1)-1, 1
     arr(j) = attenuation * (arr(j-1) + arr(j+1)) / 2
  END DO
  call sleep (1)
END SUBROUTINE simulationStep

SUBROUTINE printArray (arr)
  IMPLICIT NONE
  real(kind=4), intent (in) :: arr(:)
  integer :: j
  PRINT*, "-----------------------------"
  DO j = lbound(arr,1), ubound(arr,1), 1
     PRINT*, j, arr(j)
  END DO
  PRINT*, ""
END SUBROUTINE printArray

SUBROUTINE incrementStep (stepNr)
  IMPLICIT NONE
  integer, intent (inout) :: stepNr
  stepNr = stepNr + 1
END SUBROUTINE incrementStep

END MODULE SimulationFunctions


PROGRAM AVERAGING
  USE SimulationFunctions
  IMPLICIT NONE

  real, allocatable :: A(:)
  integer, parameter :: size = 10
  integer, parameter :: maxStep = 10000
  integer :: step
  real :: att
  real :: testReal

  allocate (A(size))
 
  att = 1
  step = 1

  call initArray(A)
  DO WHILE (step <= maxStep)
     PRINT*, 'step ', step
     call simulationStep (A, att)
     PRINT*, 'attenuation ', att
     call printArray (A)
     call incrementStep (step)
  END DO

END PROGRAM AVERAGING