FE-Project
Loading...
Searching...
No Matches
scale_atm_dyn_dgm_modalfilter.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Fluid dyn solver / Atmosphere / Common / Modal filter
3!!
4!! @par Description
5!! Modal filter for Atmospheric dynamical process.
6!! The modal filter suppresses the numerical instability due to the aliasing errors.
7!!
8!! @author Yuta Kawai, Team SCALE
9!<
10!-------------------------------------------------------------------------------
11#include "scaleFElib.h"
13 !-----------------------------------------------------------------------------
14 !
15 !++ Used modules
16 !
17 use scale_precision
18 use scale_io
19
24
25 !-----------------------------------------------------------------------------
26 implicit none
27 private
28 !-----------------------------------------------------------------------------
29 !
30 !++ Public procedures
31 !
34
35 !-----------------------------------------------------------------------------
36 !
37 !++ Public parameters & variables
38 !
39
40 !-----------------------------------------------------------------------------
41 !
42 !++ Private procedures & variables
43 !
44 !-------------------
45contains
46
47#ifndef _OPENACC
48!OCL SERIAL
50 DDENS_, MOMX_, MOMY_, MOMZ_, DRHOT_, & ! (inout)
51 lmesh, elem, elem_operation, & ! (in)
52 do_weight_gsqrt ) ! (in)
53
54 implicit none
55
56 class(localmeshbase), intent(in) :: lmesh
57 class(elementbase), intent(in) :: elem
58 real(rp), intent(inout) :: ddens_(elem%np,lmesh%nea)
59 real(rp), intent(inout) :: momx_(elem%np,lmesh%nea)
60 real(rp), intent(inout) :: momy_(elem%np,lmesh%nea)
61 real(rp), intent(inout) :: momz_(elem%np,lmesh%nea)
62 real(rp), intent(inout) :: drhot_(elem%np,lmesh%nea)
63 class(elementoperationbase3d), intent(in) :: elem_operation
64 logical, intent(in), optional :: do_weight_gsqrt
65
66 integer :: ke
67 real(rp) :: tmp(elem%np,5)
68 real(rp) :: work(elem%np)
69 real(rp) :: tmp_out(elem%np,5)
70
71 integer :: kk
72 logical :: do_weight_gsqrt_
73 real(rp) :: rgsqrt(elem%np)
74 !------------------------------------
75
76 if ( present( do_weight_gsqrt ) ) then
77 do_weight_gsqrt_ = do_weight_gsqrt
78 else
79 do_weight_gsqrt_ = .false.
80 end if
81
82 if ( do_weight_gsqrt_ ) then
83 !$omp parallel do private( tmp, tmp_out, work, kk, RGsqrt )
84 do ke=lmesh%NeS, lmesh%NeE
85 do kk=1, elem%Np
86 tmp(kk,1) = lmesh%Gsqrt(kk,ke) * ddens_(kk,ke)
87 tmp(kk,2) = lmesh%Gsqrt(kk,ke) * momx_(kk,ke)
88 tmp(kk,3) = lmesh%Gsqrt(kk,ke) * momy_(kk,ke)
89 tmp(kk,4) = lmesh%Gsqrt(kk,ke) * momz_(kk,ke)
90 tmp(kk,5) = lmesh%Gsqrt(kk,ke) * drhot_(kk,ke)
91 end do
92
93 call elem_operation%ModalFilter_var5( tmp, work, &
94 tmp_out ) ! (out)
95
96 rgsqrt(:) = 1.0_rp / lmesh%Gsqrt(:,ke)
97 ddens_(:,ke) = tmp_out(:,1) * rgsqrt(:)
98 momx_(:,ke) = tmp_out(:,2) * rgsqrt(:)
99 momy_(:,ke) = tmp_out(:,3) * rgsqrt(:)
100 momz_(:,ke) = tmp_out(:,4) * rgsqrt(:)
101 drhot_(:,ke) = tmp_out(:,5) * rgsqrt(:)
102 end do
103
104 else
105
106 !$omp parallel do private( tmp, work, kk )
107 do ke=lmesh%NeS, lmesh%NeE
108
109 do kk=1, elem%Np
110 tmp(kk,1) = ddens_(kk,ke)
111 tmp(kk,2) = momx_(kk,ke)
112 tmp(kk,3) = momy_(kk,ke)
113 tmp(kk,4) = momz_(kk,ke)
114 tmp(kk,5) = drhot_(kk,ke)
115 end do
116
117 call elem_operation%ModalFilter_var5( tmp, work, &
118 tmp_out )
119
120 ddens_(:,ke) = tmp(:,1)
121 momx_(:,ke) = tmp(:,2)
122 momy_(:,ke) = tmp(:,3)
123 momz_(:,ke) = tmp(:,4)
124 drhot_(:,ke) = tmp(:,5)
125 end do
126
127 end if
128
129 return
130 end subroutine atm_dyn_dgm_modalfilter_apply
131#else
133 DDENS_, MOMX_, MOMY_, MOMZ_, DRHOT_, & ! (inout)
134 lmesh, elem, elem_operation, & ! (in)
135 do_weight_gsqrt ) ! (in)
136
138 implicit none
139
140 class(localmeshbase), intent(in) :: lmesh
141 class(elementbase), intent(in) :: elem
142 real(rp), intent(inout) :: ddens_(elem%np,lmesh%nea)
143 real(rp), intent(inout) :: momx_(elem%np,lmesh%nea)
144 real(rp), intent(inout) :: momy_(elem%np,lmesh%nea)
145 real(rp), intent(inout) :: momz_(elem%np,lmesh%nea)
146 real(rp), intent(inout) :: drhot_(elem%np,lmesh%nea)
147 class(elementoperationbase3d), intent(in) :: elem_operation
148 logical, intent(in), optional :: do_weight_gsqrt
149
150 integer :: ke
151 real(rp) :: tmp(elem%np,lmesh%ne,5)
152 real(rp) :: work(elem%np,lmesh%ne)
153 real(rp) :: tmp_out(elem%np,lmesh%ne,5)
154 type(elementoperationgpudriver) :: elem_operation_gpu_driver
155
156 integer :: kk
157 logical :: do_weight_gsqrt_
158 real(rp) :: rgsqrt
159 real(rp) :: gsqrt_
160 !------------------------------------
161
162 if ( present( do_weight_gsqrt ) ) then
163 do_weight_gsqrt_ = do_weight_gsqrt
164 else
165 do_weight_gsqrt_ = .false.
166 end if
167
168
169 call elem_operation_gpu_driver%Init( elem_operation )
170 !$acc data create( tmp, work, tmp_out )
171
172 if ( do_weight_gsqrt_ ) then
173 !$acc parallel loop collapse(2) present( DDENS_, MOMX_, MOMY_, MOMZ_, DRHOT_, lmesh, elem ) async(1)
174 do ke=lmesh%NeS, lmesh%NeE
175 do kk=1, elem%Np
176 gsqrt_ = lmesh%Gsqrt(kk,ke)
177 tmp(kk,ke,1) = gsqrt_ * ddens_(kk,ke)
178 tmp(kk,ke,2) = gsqrt_ * momx_(kk,ke)
179 tmp(kk,ke,3) = gsqrt_ * momy_(kk,ke)
180 tmp(kk,ke,4) = gsqrt_ * momz_(kk,ke)
181 tmp(kk,ke,5) = gsqrt_ * drhot_(kk,ke)
182 end do
183 end do
184 else
185 !$acc parallel loop collapse(2) present( DDENS_, MOMX_, MOMY_, MOMZ_, DRHOT_, lmesh, elem ) async(1)
186 do ke=lmesh%NeS, lmesh%NeE
187 do kk=1, elem%Np
188 tmp(kk,ke,1) = ddens_(kk,ke)
189 tmp(kk,ke,2) = momx_(kk,ke)
190 tmp(kk,ke,3) = momy_(kk,ke)
191 tmp(kk,ke,4) = momz_(kk,ke)
192 tmp(kk,ke,5) = drhot_(kk,ke)
193 end do
194 end do
195 end if
196
197 call elementoperationgpu_modalfilter_var5( elem_operation_gpu_driver, tmp, work, lmesh%Ne, &
198 tmp_out ) ! (out)
199
200 if ( do_weight_gsqrt_ ) then
201 !$acc parallel loop collapse(2) present( DDENS_, MOMX_, MOMY_, MOMZ_, DRHOT_, lmesh, elem ) async(1)
202 do ke=lmesh%NeS, lmesh%NeE
203 do kk=1, elem%Np
204 rgsqrt = 1.0_rp / lmesh%Gsqrt(kk,ke)
205 ddens_(kk,ke) = tmp_out(kk,ke,1) * rgsqrt
206 momx_(kk,ke) = tmp_out(kk,ke,2) * rgsqrt
207 momy_(kk,ke) = tmp_out(kk,ke,3) * rgsqrt
208 momz_(kk,ke) = tmp_out(kk,ke,4) * rgsqrt
209 drhot_(kk,ke) = tmp_out(kk,ke,5) * rgsqrt
210 end do
211 end do
212 else
213 !$acc parallel loop collapse(2) present( DDENS_, MOMX_, MOMY_, MOMZ_, DRHOT_, lmesh, elem ) async(1)
214 do ke=lmesh%NeS, lmesh%NeE
215 do kk=1, elem%Np
216 ddens_(kk,ke) = tmp_out(kk,ke,1)
217 momx_(kk,ke) = tmp_out(kk,ke,2)
218 momy_(kk,ke) = tmp_out(kk,ke,3)
219 momz_(kk,ke) = tmp_out(kk,ke,4)
220 drhot_(kk,ke) = tmp_out(kk,ke,5)
221 end do
222 end do
223 end if
224 !$acc wait(1)
225 !$acc end data
226
227 call elem_operation_gpu_driver%Final()
228 return
229 end subroutine atm_dyn_dgm_modalfilter_apply
230#endif
231
232
233!> Apply a modal filtering to tracer variables
234!OCL SERIAL
236 QTRC_, & ! (inout)
237 dens_hyd_, ddens0_, ddens_, & ! (in)
238 lmesh, elem, elem_operation ) ! (in)
239
240 implicit none
241
242 class(localmeshbase), intent(in) :: lmesh
243 class(elementbase), intent(in) :: elem
244 real(rp), intent(inout) :: qtrc_(elem%np,lmesh%nea)
245 real(rp), intent(in) :: dens_hyd_(elem%np,lmesh%nea)
246 real(rp), intent(in) :: ddens0_(elem%np,lmesh%nea)
247 real(rp), intent(in) :: ddens_ (elem%np,lmesh%nea)
248 class(elementoperationbase3d), intent(in) :: elem_operation
249
250 integer :: ke
251 real(rp) :: tmp(elem%np)
252 real(rp) :: work(elem%np)
253 real(rp) :: tmp_out(elem%np)
254 real(rp) :: weight(elem%np)
255
256 real(rp) :: qtrc_avg
257 real(rp) :: gsqrtrhoq_ref(elem%np)
258 integer :: kk
259 !------------------------------------
260
261 !$omp parallel do private( tmp, tmp_out, work, kk, weight, qtrc_avg, GsqrtRHOQ_ref )
262 do ke=lmesh%NeS, lmesh%NeE
263
264 ! ( dens_hyd + ddens0 ) * ( qtrc_av + dqtrc )
265 ! = ( dens_hyd + ddens ) * qtrc_avg + dens_ * dqtrc
266 !
267 ! dens_hyd * qtrc_avg + qtrc_avg [ MF * ddens ]
268 ! + MF_q [ dqtrc ]
269 qtrc_avg = 0.125_rp * sum(elem%IntWeight_lgl(:) * qtrc_(:,ke))
270 gsqrtrhoq_ref(:) = lmesh%Gsqrt(:,ke) * qtrc_avg * ( &
271 dens_hyd_(:,ke) + ddens_(:,ke) - ddens0_(:,ke) )
272
273 do kk=1, elem%Np
274 weight(kk) = lmesh%Gsqrt(kk,ke) &
275 * ( dens_hyd_(kk,ke) + ddens0_(kk,ke) )
276! tmp(kk) = weight(kk) * QTRC_(kk,ke)
277 tmp(kk) = weight(kk) * qtrc_(kk,ke) &
278 - gsqrtrhoq_ref(kk)
279 end do
280
281 ! del(RHO Q) = RHOQ - RHO_hyd Q_avg
282 ! = (RHO_hyd + dRHO) (Q_avg + dQ) - RHO_hyd Q_avg
283 ! = RHO_hyd dQ + dRHO Q_avg + dR
284 ! RHOQ = RHO_hyd Q_avg + del(RHO Q)
285 call elem_operation%ModalFilter_tracer( tmp, work, &
286 tmp_out )
287
288 qtrc_(:,ke) = ( gsqrtrhoq_ref(:) + tmp_out(:) ) / weight(:)
289 end do
290
291 return
293
294! !OCL SERIAL
295! subroutine atm_dyn_dgm_tracer_modalfilter_apply( &
296! QTRC_, & ! (inout)
297! DENS_hyd_, DDENS_, & ! (in)
298! lmesh, elem, elem_operation ) ! (in)
299
300! implicit none
301
302! class(LocalMeshBase), intent(in) :: lmesh
303! class(ElementBase), intent(in) :: elem
304! real(RP), intent(inout) :: QTRC_(elem%Np,lmesh%NeA)
305! real(RP), intent(in) :: DENS_hyd_(elem%Np,lmesh%NeA)
306! real(RP), intent(in) :: DDENS_(elem%Np,lmesh%NeA)
307! class(ElementOperationBase3D), intent(in) :: elem_operation
308
309! integer :: ke
310! real(RP) :: tmp(elem%Np)
311! real(RP) :: work(elem%Np)
312! real(RP) :: tmp_out(elem%Np)
313! real(RP) :: weight(elem%Np)
314! integer :: kk
315! !------------------------------------
316
317! !$omp parallel do private( tmp, tmp_out, work, kk, weight )
318! do ke=lmesh%NeS, lmesh%NeE
319
320! do kk=1, elem%Np
321! weight(kk) = lmesh%Gsqrt(kk,ke) &
322! * ( DENS_hyd_(kk,ke) + DDENS_(kk,ke) )
323! tmp(kk) = weight(kk) * QTRC_(kk,ke)
324! end do
325
326! call elem_operation%ModalFilter_tracer( tmp, work, &
327! tmp_out )
328
329! QTRC_(:,ke) = tmp_out(:) / weight(:)
330! end do
331
332! return
333! end subroutine atm_dyn_dgm_tracer_modalfilter_apply
334
module FElib / Fluid dyn solver / Atmosphere / Common / Modal filter
subroutine, public atm_dyn_dgm_tracer_modalfilter_apply(qtrc_, dens_hyd_, ddens0_, ddens_, lmesh, elem, elem_operation)
Apply a modal filtering to tracer variables.
subroutine, public atm_dyn_dgm_modalfilter_apply(ddens_, momx_, momy_, momz_, drhot_, lmesh, elem, elem_operation, do_weight_gsqrt)
module FElib / Element / Base
module FElib / Element / Operation / Base
module FElib / Element / Driver for operation with 3D tensor product elements using GPU
subroutine, public elementoperationgpu_modalfilter_var5(this, vec_in, vec_work, ne, vec_out)
Apply a modal filter for five variables.
module FElib / Mesh / Local, Base
Derived type representing an arbitrary finite element.
Driver for element operation with 3D tensor product elements using GPU.
Derived type to manage a local computational domain (base type)