spectralFilter_mod sourceΒΆ

  1module spectralFilter_mod
  2  ! MODULE spectralFilter_mod (prefix='spf' category='8. Low-level utilities and constants')
  3  !
  4  !:Purpose: For computing spectral filter functions.
  5  !
  6  implicit none
  7  save
  8  private
  9
 10  ! public procedures
 11  public :: spf_FilterResponseFunction
 12
 13CONTAINS
 14
 15!--------------------------------------------------------------------------
 16! spf_FilterResponseFunction
 17!--------------------------------------------------------------------------
 18  function spf_FilterResponseFunction(totalWaveNumber, waveBandIndex, waveBandPeaks, nWaveBand) result(ResponseFunction) 
 19    implicit none
 20
 21    ! Arguments:
 22    real(8), intent(in) :: totalWaveNumber
 23    integer, intent(in) :: waveBandIndex
 24    integer, intent(in) :: nWaveBand
 25    integer, intent(in) :: waveBandPeaks(:)
 26    ! Result:
 27    real(8) :: ResponseFunction 
 28
 29    ! Locals:
 30    real(8) :: linearResponse, lowerLimit, center, upperLimit
 31    real(8), parameter :: pi = 2.d0*asin(1.d0)
 32
 33    if (waveBandIndex == nWaveBand ) then
 34       ! This wave band contains the largest scales.
 35       !
 36       ! The response function is 1 total wave number <= waveBandPeaks(nWaveBand)
 37       ! and decreases to 0 at waveBandPeaks(nWaveBand-1)
 38       !
 39       !                    response=1 |---
 40       !                               |   \
 41       !                               |    \
 42       !                    response=0 |------------
 43       !       waveBandPeaks(nWaveBand) <-|  |-> waveBandPeaks(nWaveBand-1)
 44       !
 45       lowerlimit = real(waveBandPeaks(waveBandIndex  ),8)
 46       upperlimit = real(waveBandPeaks(waveBandIndex-1),8)
 47
 48       if ( totalWaveNumber < lowerlimit ) then
 49          ResponseFunction = 1.d0
 50       else if ( totalWaveNumber <= upperlimit ) then
 51          linearResponse = (upperlimit-totalWaveNumber) / (upperlimit-lowerlimit)
 52          ResponseFunction = sin( (pi/2.d0) * linearResponse)**2
 53       else
 54          ResponseFunction = 0.d0
 55       end if
 56
 57    else if ( waveBandIndex /= 1 ) then
 58       ! This wave band contains intermediate scales (i.e., not the largest or the smallest).
 59       !
 60       ! The response function is 1 (only) for the total wave number = waveBandPeaks(waveBandIndex)
 61       ! and decreases to 0 at both waveBandPeaks(waveBandIndex+1) and waveBandPeaks(waveBandIndex-1)
 62       !
 63       !                    response=1 |      -
 64       !                               |     / \
 65       !                               |    /   \
 66       !                    response=0 |------------
 67       !  waveBandPeaks(waveBandIndex+1) <-|     |-> waveBandPeaks(waveBandIndex-1)
 68       !                                      |-> waveBandPeaks(waveBandIndex)
 69       !
 70       center     = real(waveBandPeaks(waveBandIndex  ),8)
 71       upperlimit = real(waveBandPeaks(waveBandIndex-1),8)
 72       lowerlimit = real(waveBandPeaks(waveBandIndex+1),8)
 73
 74       if (      totalWaveNumber >  lowerlimit .and. &
 75                 totalWaveNumber <= center     ) then
 76          linearResponse = (totalWaveNumber-lowerlimit) / (center-lowerlimit)
 77          ResponseFunction = sin( (pi/2.d0) * linearResponse)**2
 78       else if ( totalWaveNumber >  center      .and. &
 79                 totalWaveNumber <  upperlimit  ) then
 80          linearResponse = (upperlimit-totalWaveNumber) / (upperlimit-center)
 81          ResponseFunction = sin( (pi/2.d0) * linearResponse)**2
 82       else
 83          ResponseFunction = 0.d0
 84       end if
 85
 86    else
 87       !
 88       ! This wave band contains the smallest scales.
 89       !
 90       ! The response function is 1 total wave number >= waveBandPeaks(nWaveBand)
 91       ! and decreases to 0 at waveBandPeaks(nWaveBand-1)
 92       !
 93       !                    response=1 |    ---
 94       !                               |   /
 95       !                               |  / 
 96       !                    response=0 |------------
 97       !waveBandPeaks(waveBandIndex+1) <-|  |-> waveBandPeaks(1)
 98       !
 99       upperlimit = real(waveBandPeaks(waveBandIndex  ),8)
100       lowerlimit = real(waveBandPeaks(waveBandIndex+1),8)
101
102       if      ( totalWaveNumber > upperlimit ) then
103          ResponseFunction = 1.d0
104       else if ( totalWaveNumber > lowerlimit ) then
105          linearResponse = (totalWaveNumber-lowerlimit) / (upperlimit-lowerlimit)
106          ResponseFunction = sin( (pi/2.d0) * linearResponse)**2
107       else
108          ResponseFunction = 0.d0
109       end if
110
111    end if
112
113  end function spf_FilterResponseFunction
114
115END MODULE SpectralFilter_mod