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  limiter = present( limiter_sign )
86 
87  !$acc data copy(data) create(work1, work2)
88  !$acc data copyin(limiter_sign) if(limiter)
89 
90  ! reduce grid-scale variation
91  do ite = 1, nite
92 
93  call comm_vars8( data(:,:), 1 )
94  call comm_wait ( data(:,:), 1, .false. )
95 
96  !$omp parallel do
97  !$acc kernels
98  do j = 1, ja
99  do i = 1, ia
100  work2(i,j) = data(i,j)
101  end do
102  end do
103  !$acc end kernels
104 
105  p1 => work2
106  p2 => work1
107  do n = 1, order
108  !$omp parallel do
109  !$acc kernels
110  !$acc loop collapse(2) independent
111  do j = max(js,2), min(je,ja-1)
112  do i = max(is,2), min(ie,ia-1)
113  p2(i,j) = ( - p1(i+1,j) + p1(i,j)*2.0_rp - p1(i-1,j) &
114  - p1(i,j+1) + p1(i,j)*2.0_rp - p1(i,j-1) ) / 8.0_rp
115  end do
116  end do
117  !$acc end kernels
118  if ( js == 1 ) then
119  !$acc kernels
120  !$acc loop independent
121  do i = max(is,2), min(ie,ia-1)
122  p2(i,js) = ( - p1(i+1,js) + p1(i,js)*2.0_rp - p1(i-1,js) &
123  - p1(i,js+1) + p1(i,js) ) / 6.0_rp
124  end do
125  !$acc end kernels
126  else
127  !$acc kernels
128  !$acc loop independent
129  do i = max(is,2), min(ie,ia-1)
130  p2(i,js-1) = p2(i,js)
131  end do
132  !$acc end kernels
133  end if
134  if ( je == ja ) then
135  !$acc kernels
136  !$acc loop independent
137  do i = max(is,2), min(ie,ia-1)
138  p2(i,je) = ( - p1(i+1,je) + p1(i,je)*2.0_rp - p1(i-1,je) &
139  + p1(i,je) - p1(i,je-1) ) / 6.0_rp
140  end do
141  !$acc end kernels
142  else
143  !$acc kernels
144  !$acc loop independent
145  do i = max(is,2), min(ie,ia-1)
146  p2(i,je+1) = p2(i,je)
147  end do
148  !$acc end kernels
149  end if
150  if ( is == 1 ) then
151  !$acc kernels
152  !$acc loop independent
153  do j = max(js,2), min(je,ja-1)
154  p2(is,j) = ( - p1(is+1,j) + p1(is,j) &
155  - p1(is,j+1) + p1(is,j)*2.0_rp - p1(is,j-1) ) / 6.0_rp
156  end do
157  !$acc end kernels
158  if ( js == 1 ) then
159  !$acc kernels
160  p2(is,js) = ( - p1(is+1,js) + p1(is,js) &
161  - p1(is,js+1) + p1(is,js) ) / 4.0_rp
162  !$acc end kernels
163  end if
164  if ( je == ja ) then
165  !$acc kernels
166  p2(is,je) = ( - p1(is+1,je) + p1(is,je) &
167  + p1(is,je) - p1(is,je-1) ) / 4.0_rp
168  !$acc end kernels
169  end if
170  else
171  !$acc kernels
172  do j = max(js-1,1), min(je+1,ja)
173  p2(is-1,j) = p2(is,j)
174  end do
175  !$acc end kernels
176  end if
177  if ( ie == ia ) then
178  !$acc kernels
179  !$acc loop independent
180  do j = max(js,2), min(je,ja-1)
181  p2(ie,j) = ( + p1(ie,j) - p1(ie-1,j) &
182  - p1(ie,j+1) + p1(ie,j)*2.0_rp - p1(ie,j-1) ) / 6.0_rp
183  end do
184  !$acc end kernels
185  if ( js == 1 ) then
186  !$acc kernels
187  p2(ie,js) = ( + p1(ie,js) - p1(ie-1,js) &
188  - p1(ie,js+1) + p1(ie,js) ) / 4.0_rp
189  !$acc end kernels
190  end if
191  if ( je == ja ) then
192  !$acc kernels
193  p2(ie,je) = ( + p1(ie,je) - p1(ie-1,je) &
194  + p1(ie,je) - p1(ie,je-1) ) / 4.0_rp
195  !$acc end kernels
196  end if
197  else
198  !$acc kernels
199  do j = max(js-1,1), min(je+1,ja)
200  p2(ie+1,j) = p2(ie,j)
201  end do
202  !$acc end kernels
203  end if
204 
205  call comm_vars8( p2(:,:), 1 )
206  call comm_wait ( p2(:,:), 1, .false. )
207 
208  if ( mod(n,2) == 0 ) then
209  p1 => work2
210  p2 => work1
211  else
212  p1 => work1
213  p2 => work2
214  end if
215  end do
216 
217  !$omp parallel do
218  !$acc kernels
219  do j = js, je
220  do i = is, ie
221  data(i,j) = data(i,j) - p1(i,j)
222  end do
223  end do
224  !$acc end kernels
225 
226  if ( limiter ) then
227  !$omp parallel do
228  !$acc kernels
229  do j = js, je
230  do i = is, ie
231  data(i,j) = sign( max( data(i,j) * limiter_sign(i,j), 0.0_rp ), limiter_sign(i,j) )
232  end do
233  end do
234  !$acc end kernels
235  end if
236  end do
237 
238  !$acc end data
239  !$acc end data
240 
241  call prof_rapend('FILTER', 3)
242 
243  return
244  end subroutine filter_hyperdiff_2d
245 
246  !-----------------------------------------------------------------------------
248  subroutine filter_hyperdiff_3d( &
249  KA, KS, KE, IA, IS, IE, JA, JS, JE, &
250  data, order, nite, &
251  limiter_sign )
252  use scale_comm_cartesc, only: &
253  comm_vars8, &
254  comm_wait
255  use scale_prc, only: &
256  prc_abort
257  integer, intent(in) :: KA, KS, KE
258  integer, intent(in) :: IA, IS, IE
259  integer, intent(in) :: JA, JS, JE
260 
261  real(RP), intent(inout) :: data(KA,IA,JA)
262 
263  integer, intent(in) :: order
264  integer, intent(in) :: nite
265 
266  real(RP), intent(in), optional :: limiter_sign(KA,IA,JA)
267 
268  real(RP) :: work_data(IA,JA)
269  real(RP) :: work_sign(IA,JA)
270 
271  logical :: flag
272 
273  integer :: k, i, j
274 
275  if ( present(limiter_sign) ) then
276  flag = .true.
277  else
278  flag = .false.
279  end if
280 
281  !$acc data copy(data) create(work_data)
282  !$acc data copyin(limiter_sign) create(work_sign) if(flag)
283 
284  do k = ks, ke
285 
286  !$omp parallel do
287  !$acc kernels
288  do j = js, je
289  do i = is, ie
290  work_data(i,j) = data(k,i,j)
291  end do
292  end do
293  !$acc end kernels
294  if ( flag ) then
295  !$omp parallel do
296  !$acc kernels
297  do j = js, je
298  do i = is, ie
299  work_sign(i,j) = limiter_sign(k,i,j)
300  end do
301  end do
302  !$acc end kernels
303 
304  call filter_hyperdiff_2d( ia, is, ie, ja, js, je, &
305  work_data(:,:), order, nite, &
306  limiter_sign = work_sign )
307 
308  else
309 
310  call filter_hyperdiff_2d( ia, is, ie, ja, js, je, &
311  work_data(:,:), order, nite )
312  end if
313 
314 
315  !$omp parallel do
316  !$acc kernels
317  do j = 1, ja
318  do i = 1, ia
319  data(k,i,j) = work_data(i,j)
320  end do
321  end do
322  !$acc end kernels
323 
324  end do
325 
326  !$acc end data
327  !$acc end data
328 
329  return
330  end subroutine filter_hyperdiff_3d
331 
332 end module scale_filter
scale_prc::prc_abort
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:350
scale_precision
module PRECISION
Definition: scale_precision.F90:14
scale_prof::prof_rapstart
subroutine, public prof_rapstart(rapname_base, level, disable_barrier)
Start raptime.
Definition: scale_prof.F90:174
scale_filter::filter_hyperdiff_3d
subroutine filter_hyperdiff_3d(KA, KS, KE, IA, IS, IE, JA, JS, JE, data, order, nite, limiter_sign)
Hyper diffusion filter 3D.
Definition: scale_filter.F90:252
scale_prc
module PROCESS
Definition: scale_prc.F90:11
scale_io
module STDIO
Definition: scale_io.F90:10
scale_prof
module profiler
Definition: scale_prof.F90:11
scale_comm_cartesc
module COMMUNICATION
Definition: scale_comm_cartesC.F90:11
scale_filter
module FILTER
Definition: scale_filter.F90:11
scale_prof::prof_rapend
subroutine, public prof_rapend(rapname_base, level, disable_barrier)
Save raptime.
Definition: scale_prof.F90:246