-
Notifications
You must be signed in to change notification settings - Fork 69
/
Copy pathtest_filtermodule.f90
171 lines (135 loc) · 5.34 KB
/
test_filtermodule.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
!!
!! Copyright (C) 2009-2017 Johns Hopkins University
!7
!! This file is part of lesgo.
!!
!! lesgo is free software: you can redistribute it and/or modify
!! it under the terms of the GNU General Public License as published by
!! the Free Software Foundation, either version 3 of the License, or
!! (at your option) any later version.
!!
!! lesgo is distributed in the hope that it will be useful,
!! but WITHOUT ANY WARRANTY; without even the implied warranty of
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
!! GNU General Public License for more details.
!!
!! You should have received a copy of the GNU General Public License
!! along with lesgo. If not, see <http://www.gnu.org/licenses/>.
!!
!*******************************************************************************
module test_filtermodule
!*******************************************************************************
use types, only : rprec
use param, only : lh, ny
private lh, ny
! the implicit filter (1=grid size)
integer, parameter :: filter_size=1
! alpha is ratio of test filter to grid filter widths
real(rprec) :: alpha_test = 2.0_rprec * filter_size
real(rprec) :: alpha_test_test = 4.0_rprec * filter_size
real(rprec), dimension(:,:), allocatable :: G_test, G_test_test
contains
!*******************************************************************************
subroutine test_filter_init()
!*******************************************************************************
! Creates the kernels which will be used for filtering the field
use types, only : rprec
use param, only : lh, nx, ny, dx, dy, pi, ifilter, sgs_model
use fft
implicit none
real(rprec) :: delta_test, kc2_test, delta_test_test, kc2_test_test
! Allocate the arrays
allocate( G_test(lh,ny) )
! Include the normalization for the forward FFT
G_test = 1._rprec/(nx*ny)
! Filter characteristic width
! "2d-delta", not full 3d one
delta_test = alpha_test * sqrt(dx*dy)
! Calculate the kernel
! spectral cutoff filter
if(ifilter==1) then
if (sgs_model==6.OR.sgs_model==7) then
print *, 'Use Gaussian or Top-hat filter for mixed models'
stop
endif
kc2_test = (pi/(delta_test))**2
where (real(k2, rprec) >= kc2_test) G_test = 0._rprec
! Gaussian filter
else if(ifilter==2) then
G_test=exp(-(delta_test)**2*k2/(4._rprec*6._rprec))*G_test
! Top-hat (Box) filter
else if(ifilter==3) then
G_test = (sin(kx*delta_test/2._rprec)*sin(ky*delta_test/2._rprec)+1E-8)/ &
(kx*delta_test/2._rprec*ky*delta_test/2._rprec+1E-8)*G_test
endif
! since our k2 has zero at Nyquist, we have to do this by hand
G_test(lh,:) = 0._rprec
G_test(:,ny/2+1) = 0._rprec
! Second test filter, if necessary (with scale dependent dynamic)
if ((sgs_model == 3) .or. (sgs_model == 5)) then
! Allocate the arrays
allocate ( G_test_test(lh,ny) )
! Include the normalization
G_test_test = 1._rprec/(nx*ny)
! Filter characteristic width
delta_test_test = alpha_test_test * sqrt(dx*dy)
! Calculate the kernel
! spectral cutoff filter
if (ifilter==1) then
if (sgs_model==6.OR.sgs_model==7) then
print *, 'Use Gaussian or Top-hat filter for mixed models'
stop
endif
kc2_test_test = (pi/(delta_test_test))**2
where (real(k2, rprec) >= kc2_test_test) G_test_test = 0._rprec
! Gaussian filter
else if(ifilter==2) then
G_test_test=exp(-(delta_test_test)**2*k2/(4._rprec*6._rprec)) &
* G_test_test
! Top-hat (Box) filter
else if(ifilter==3) then
G_test_test= (sin(kx*delta_test_test/2._rprec) &
* sin(ky*delta_test_test/2._rprec)+1E-8) &
/ (kx*delta_test_test/2._rprec*ky*delta_test_test/2._rprec+1E-8) &
* G_test_test
endif
! since our k2 has zero at Nyquist, we have to do this by hand
G_test_test(lh,:) = 0._rprec
G_test_test(:,ny/2+1) = 0._rprec
endif
end subroutine test_filter_init
!*******************************************************************************
subroutine test_filter(f)
!*******************************************************************************
! note: this filters in-place, so input is ruined
use types, only : rprec
use fft
use param, only : ny
use emul_complex, only : OPERATOR(.MULR.)
implicit none
real(rprec), dimension(:,:), intent(inout) :: f
! Perform in-place FFT
call dfftw_execute_dft_r2c(forw, f, f)
! Perform f = G_test*f, emulating f as complex
! Nyquist frequency and normalization is taken care of with G_test
f = f .MULR. G_test
call dfftw_execute_dft_c2r(back, f, f)
end subroutine test_filter
!*******************************************************************************
subroutine test_test_filter(f)
!*******************************************************************************
! note: this filters in-place, so input is ruined
use types, only : rprec
use fft
use param, only : ny
use emul_complex, only : OPERATOR(.MULR.)
implicit none
real(rprec), dimension(:,:), intent(inout) :: f
! Perform in-place FFT
call dfftw_execute_dft_r2c(forw, f, f)
! Perform f = G_test*f, emulating f as complex
! Nyquist frequency and normalization is taken care of with G_test_test
f = f .MULR. G_test_test
call dfftw_execute_dft_c2r(back, f, f)
end subroutine test_test_filter
end module test_filtermodule