C ----------------------------------------------------------------------- C Serial Example - Wave Equation - Fortran Version C FILE: ser_wave.f C DESCRIPTION: C This program implements the concurrent wave equation described C in Chapter 5 of Fox et al., 1988, Solving Problems on Concurrent C Processors, vol 1. C C A vibrating string is decomposed into points. In the parallel C version, each processor is responsible for updating the amplitude C of a number of points over time. C C At each iteration, each processor exchanges boundary points with C nearest neighbors. C C AUTHOR: R. Arnowitz C LAST REVISED: 11/25/95 Blaise Barney C ------------------------------------------------------------------------ C Explanation of constants and variables used in common blocks and C include files C tpoints = total points along wave C nsteps = number of time steps C values(0:1001) = values at time t C oldval(0:1001) = values at time (t-dt) C newval(0:1001) = values at time (t+dt) C ------------------------------------------------------------------------ program wave implicit none print *, 'Serial Wave Program Running ' C Get program parameters and initialize wave values call init_param call init_line C Update values along the wave for nstep time steps call update end C ------------------------------------------------------------------------ C Obtains input values from user C ------------------------------------------------------------------------ subroutine init_param implicit none integer tpoints, nsteps common/inputs/tpoints, nsteps integer MAXPOINTS, MAXSTEPS integer MINPOINTS parameter (MAXPOINTS = 1000) parameter (MAXSTEPS = 10000) parameter (MINPOINTS = 20) tpoints = 0 nsteps = 0 do while ((tpoints .lt. MINPOINTS) .or. (tpoints .gt. MAXPOINTS)) write (*,*)'Enter number of points along vibrating string' read (*,*) tpoints if ((tpoints .lt. MINPOINTS) .or. (tpoints .gt. MAXPOINTS)) & write (*,*) 'enter value between ',MINPOINTS,' and ',MAXPOINTS end do do while ((nsteps .lt. 1) .or. (nsteps .gt. MAXSTEPS)) write (*,*) 'Enter number of time steps' read (*,*) nsteps if ((nsteps .lt. 1) .or. (nsteps .gt. MAXSTEPS)) & write (*,*) 'enter value between 1 and ', MAXSTEPS end do write (*,10) tpoints, nsteps 10 format(' points = ', I5, ' steps = ', I5) end C ------------------------------------------------------------------------ C Initialize points on line C ----------------------------------------------------------------------- subroutine init_line implicit none integer tpoints, nsteps common/inputs/tpoints, nsteps integer npoints, first common/decomp/npoints, first real*8 values(0:1001), oldval(0:1001), newval(0:1001) common/data/values, oldval, newval real*8 PI parameter (PI = 3.14159265) integer i, j, k real*8 x, fac C Calculate initial values based on sine curve fac = 2.0 * PI k = 0 do j = 1, tpoints x = float(k)/float(tpoints - 1) values(j) = sin (fac * x) k = k + 1 end do do i = 1, tpoints oldval(i) = values(i) end do end C ------------------------------------------------------------------------- C Calculate new values using wave equation C ------------------------------------------------------------------------- subroutine do_math(i) implicit none integer i integer tpoints, nsteps common/inputs/tpoints, nsteps real*8 values(0:1001), oldval(0:1001), newval(0:1001) common/data/values, oldval, newval real*8 dtime, c, dx, tau, sqtau dtime = 0.3 c = 1.0 dx = 1.0 tau = (c * dtime / dx) sqtau = tau * tau newval(i) = (2.0 * values(i)) - oldval(i) & + (sqtau * (values(i-1) - (2.0 * values(i)) + values(i+1))) end C ------------------------------------------------------------------------- C Update all values along line a specified number of times C ------------------------------------------------------------------------- subroutine update implicit none integer tpoints, nsteps, tpts common/inputs/tpoints, nsteps real*8 values(0:1001), oldval(0:1001), newval(0:1001) common/data/values, oldval, newval integer i, j C Update values for each point along string do i = 1, nsteps C Update points along line do j = 1, tpoints C Global endpoints if ((j .eq. 1).or.(j .eq. tpoints))then newval(j) = 0.0 else call do_math(j) end if end do do j = 1, tpoints oldval(j) = values(j) values(j) = newval(j) end do end do if (tpoints .lt. 10) then tpts = tpoints else tpts = 10 end if write (*,200) tpts, (values(i), i = 1, tpts) 200 format('first ', I5, ' points (for validation):'/ & 10(f4.2, ' ')) end