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