! sprfft - Program to compute the power spectrum of a ! coupled mass-spring system. program sprfft integer*4 MAXnStep parameter( MAXnStep = 100000 ) integer*4 nState, i, iStep, nStep, nPrint real*8 x(3), v(3), state(6), param(1) real*8 time, tau, pi, k_over_m, window real*8 xplot(MAXnStep,3), tplot(MAXnStep) real*8 f(MAXnStep), spect(MAXnStep), spectW(MAXnStep) complex*16 x1fft(MAXnStep), x1fftW(MAXnStep) external sprrk !* Set parameters for the system (initial positions, etc.). nState = 6 write(*,*) 'Enter initial displacements x(1),x(2),x(3) = ' read(*,*) x(1), x(2), x(3) v(1) = 0.0 v(2) = 0.0 ! Masses are initially at rest v(3) = 0.0 state(1) = x(1) state(2) = x(2) state(3) = x(3) state(4) = v(1) state(5) = v(2) state(6) = v(3) write(*,*) 'Enter timestep: ' read(*,*) tau k_over_m = 1 ! Ratio of spring const. over mass param(1) = k_over_m !* Loop over the desired number of time steps. time = 0 ! Set initial time nStep = 256 ! Number of steps in the main loop nPrint = nStep/8 ! Number of steps between printing progress do iStep=1,nStep !* Use Runge-Kutta to find new displacements of the masses. call rk4(state,nState,time,tau,sprrk,param) time = time + tau !* Record the positions for graphing and to compute spectra. xplot(iStep,1) = state(1) ! Record positions xplot(iStep,2) = state(2) xplot(iStep,3) = state(3) tplot(iStep) = time if( mod(iStep,nprint) .lt. 1 ) then write(*,*) 'Finished ', iStep, ' out of ', nStep, ' steps' endif enddo !* Calculate the power spectrum of the time series for mass #1 do i=1,nStep f(i) = (i-1)/(tau*nStep) ! Frequency x1fft(i) = xplot(i,1) ! Displacement of mass 1 enddo call fft(x1fft, nStep) ! Fourier transform of displacement do i=1,nStep ! Power spectrum of displacement spect(i) = abs(x1fft(i))**2 enddo !* Apply the Hanning window to the time series and calculate ! the resulting power spectrum pi = 3.141592654 do i=1,nStep window = 0.5*(1.0-cos(2.0*pi*(i-1.0)/nStep)) ! Hanning window x1fftW(i) = xplot(i,1) * window ! Windowed time series enddo call fft(x1fftW, nStep) ! Fourier transf. (windowed data) do i=1,nStep ! Power spectrum (windowed data) spectW(i) = abs(x1fftW(i))**2 enddo !* Print out the plotting variables: ! tplot, xplot, f, spect, spectw open(11,file='tplot.txt',status='unknown') open(12,file='xplot.txt',status='unknown') open(13,file='f.txt',status='unknown') open(14,file='spect.txt',status='unknown') open(15,file='spectw.txt',status='unknown') do i=1,nStep write(11,*) tplot(i) write(12,*) xplot(i,1), xplot(i,2), xplot(i,3) write(13,*) f(i) write(14,*) spect(i) write(15,*) spectW(i) enddo stop end !***** To plot in MATLAB; use the script below ******************** !load tplot.txt; load xplot.txt; load f.txt; !load spect.txt; load spectw.txt !nstep = length(tplot); nprint = nstep/8; !%* Graph the displacements of the three masses. !figure(1); clf; % Clear figure 1 window and bring forward !ipr = 1:nprint:nstep; % Used to graph limited number of symbols !plot(tplot(ipr),xplot(ipr,1),'o',tplot(ipr),xplot(ipr,2),'+',... ! tplot(ipr),xplot(ipr,3),'*',... ! tplot,xplot(:,1),'-',tplot,xplot(:,2),'-.',... ! tplot,xplot(:,3),'--'); !legend('Mass #1','Mass #2','Mass #3'); !title('Displacement of masses (relative to rest positions)'); !xlabel('Time'); ylabel('Displacement'); !%* Graph the power spectra for original and windowed data !figure(2); clf; % Clear figure 2 window and bring forward !semilogy(f(1:(nstep/2)),spect(1:(nstep/2)),'-',... ! f(1:(nstep/2)),spectw(1:(nstep/2)),'--'); !title('Power spectrum (dashed is windowed data)'); !xlabel('Frequency'); ylabel('Power'); !******************************************************************