SCALE-RM
scale_filter.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
10 #include "scalelib.h"
12  !-----------------------------------------------------------------------------
13  !
14  !++ used modules
15  !
16  use scale_precision
17  use scale_io
18  use scale_prof
19  !-----------------------------------------------------------------------------
20  implicit none
21  private
22  !-----------------------------------------------------------------------------
23  !
24  !++ Public procedure
25  !
26  public :: filter_hyperdiff
27 
28  interface filter_hyperdiff
29  module procedure filter_hyperdiff_2d
30  module procedure filter_hyperdiff_3d
31  end interface filter_hyperdiff
32 
33  !-----------------------------------------------------------------------------
34  !
35  !++ Public parameters & variables
36  !
37  !-----------------------------------------------------------------------------
38  !
39  !++ Private procedure
40  !
41  !-----------------------------------------------------------------------------
42  !
43  !++ Private parameters & variables
44  !
45  !-----------------------------------------------------------------------------
46 contains
47  !-----------------------------------------------------------------------------
49  subroutine filter_hyperdiff_2d( &
50  IA, IS, IE, JA, JS, JE, &
51  data, order, nite, &
52  limiter_sign )
53  use scale_comm_cartesc, only: &
54  comm_vars8, &
55  comm_wait
56  use scale_prc, only: &
57  prc_abort
58  integer, intent(in) :: ia, is, ie
59  integer, intent(in) :: ja, js, je
60 
61  real(RP), intent(inout) :: data(ia,ja)
62 
63  integer, intent(in) :: order
64  integer, intent(in) :: nite
65 
66  real(RP), intent(in), optional :: limiter_sign(ia,ja)
67 
68  real(RP), pointer :: p1(:,:)
69  real(RP), pointer :: p2(:,:)
70  real(RP), target :: work1(ia,ja)
71  real(RP), target :: work2(ia,ja)
72 
73  logical :: limiter
74 
75  integer :: i, j
76  integer :: ite, n
77 
78  call prof_rapstart('FILTER', 3)
79 
80  if ( mod(order,2) .ne. 0 ) then
81  log_error("FILTER_hyperdiff_2D", *) "order must be even"
82  call prc_abort
83  end if
84 
85  if ( is < 2 ) then
86  log_error("FILTER_hyperdiff_2D", *) "IS must be >= 2"
87  call prc_abort
88  end if
89  if ( ie > ia-1 ) then
90  log_error("FILTER_hyperdiff_2D", *) "IS must be <= IA-1"
91  call prc_abort
92  end if
93  if ( js < 2 ) then
94  log_error("FILTER_hyperdiff_2D", *) "JS must be >= 2"
95  call prc_abort
96  end if
97  if ( je > ja-1 ) then
98  log_error("FILTER_hyperdiff_2D", *) "JS must be <= JA-1"
99  call prc_abort
100  end if
101 
102 
103  limiter = present( limiter_sign )
104 
105  ! reduce grid-scale variation
106  do ite = 1, nite
107 
108  call comm_vars8( data(:,:), 1 )
109  call comm_wait ( data(:,:), 1, .true. )
110 
111  !$omp parallel do
112  do j = 1, ja
113  do i = 1, ia
114  work2(i,j) = data(i,j)
115  end do
116  end do
117 
118  p1 => work2
119  p2 => work1
120  do n = 1, order
121  !$omp parallel do
122  do j = js, je
123  do i = is, ie
124  p2(i,j) = ( - p1(i+1,j) + p1(i,j)*2.0_rp - p1(i-1,j) &
125  - p1(i,j+1) + p1(i,j)*2.0_rp - p1(i,j-1) ) / 8.0_rp
126  end do
127  end do
128 
129  call comm_vars8( p2(:,:), 1 )
130  call comm_wait ( p2(:,:), 1, .true. )
131 
132  if ( mod(n,2) == 0 ) then
133  p1 => work2
134  p2 => work1
135  else
136  p1 => work1
137  p2 => work2
138  end if
139  end do
140 
141  !$omp parallel do
142  do j = js, je
143  do i = is, ie
144  data(i,j) = data(i,j) - p1(i,j)
145  end do
146  end do
147 
148  if ( limiter ) then
149  !$omp parallel do
150  do j = js, je
151  do i = is, ie
152  data(i,j) = sign( max( data(i,j) * limiter_sign(i,j), 0.0_rp ), limiter_sign(i,j) )
153  end do
154  end do
155  end if
156  end do
157 
158  call prof_rapend('FILTER', 3)
159 
160  return
161  end subroutine filter_hyperdiff_2d
162 
163  !-----------------------------------------------------------------------------
165  subroutine filter_hyperdiff_3d( &
166  KA, KS, KE, IA, IS, IE, JA, JS, JE, &
167  data, order, nite, &
168  limiter_sign )
169  use scale_comm_cartesc, only: &
170  comm_vars8, &
171  comm_wait
172  use scale_prc, only: &
173  prc_abort
174  integer, intent(in) :: KA, KS, KE
175  integer, intent(in) :: IA, IS, IE
176  integer, intent(in) :: JA, JS, JE
177 
178  real(RP), intent(inout) :: data(ka,ia,ja)
179 
180  integer, intent(in) :: order
181  integer, intent(in) :: nite
182 
183  real(RP), intent(in), optional :: limiter_sign(ka,ia,ja)
184 
185  real(RP) :: work_data(ia,ja)
186  real(RP) :: work_sign(ia,ja)
187 
188  logical :: flag
189 
190  integer :: k, i, j
191 
192  if ( present(limiter_sign) ) then
193  flag = .true.
194  else
195  flag = .false.
196  end if
197 
198  do k = ks, ke
199 
200  !$omp parallel do
201  do j = js, je
202  do i = is, ie
203  work_data(i,j) = data(k,i,j)
204  end do
205  end do
206  if ( flag ) then
207  !$omp parallel do
208  do j = js, je
209  do i = is, ie
210  work_sign(i,j) = limiter_sign(k,i,j)
211  end do
212  end do
213 
214  call filter_hyperdiff_2d( ia, is, ie, ja, js, je, &
215  work_data(:,:), order, nite, &
216  limiter_sign = work_sign )
217 
218  else
219 
220  call filter_hyperdiff_2d( ia, is, ie, ja, js, je, &
221  work_data(:,:), order, nite )
222  end if
223 
224 
225  !$omp parallel do
226  do j = 1, ja
227  do i = 1, ia
228  data(k,i,j) = work_data(i,j)
229  end do
230  end do
231 
232  end do
233 
234 
235  return
236  end subroutine filter_hyperdiff_3d
237 
238 end module scale_filter
subroutine filter_hyperdiff_3d(KA, KS, KE, IA, IS, IE, JA, JS, JE, data, order, nite, limiter_sign)
Hyper diffusion filter 3D.
module COMMUNICATION
module FILTER
module PROCESS
Definition: scale_prc.F90:11
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:338
subroutine, public prof_rapstart(rapname_base, level)
Start raptime.
Definition: scale_prof.F90:157
module profiler
Definition: scale_prof.F90:11
module PRECISION
module STDIO
Definition: scale_io.F90:10
subroutine, public prof_rapend(rapname_base, level)
Save raptime.
Definition: scale_prof.F90:210