FE-Project
Loading...
Searching...
No Matches
scale_element_operation_general.F90
Go to the documentation of this file.
1
2!-------------------------------------------------------------------------------
3!> module FElib / Element / Operation with arbitary elements
4!!
5!! @par Description
6!! A module for providing mathematical operations with arbitary elements using a module for SpMV
7!!
8!! @author Yuta Kawai, Xuanzhengbo Ren, and Team SCALE
9!!
10!<
11#include "scaleFElib.h"
13
14 !-----------------------------------------------------------------------------
15 !
16 !++ used modules
17 !
18 use scale_precision
19
20 use scale_element_base, only: &
23
24 use scale_sparsemat, only: &
27
29
30 !-----------------------------------------------------------------------------
31 implicit none
32 private
33
34 !-----------------------------------------------------------------------------
35 !
36 !++ Public type & procedure
37 !
38
39 !> Derived type for elementwise operations with arbitary elements
41 type(sparsemat), pointer :: dx_sm
42 type(sparsemat), pointer :: dy_sm
43 type(sparsemat), pointer :: dz_sm
44 type(sparsemat), pointer :: lift_sm
45 real(rp), allocatable :: intrpmat_vpordm1(:,:)
46
47 type(modalfilter) :: mfilter
48 type(modalfilter) :: mfilter_tracer
49 contains
50 procedure, public :: init => element_operation_general_init
51 procedure, public :: final => element_operation_general_final
52 procedure, public :: dx => element_operation_general_dx
53 procedure, public :: dy => element_operation_general_dy
54 procedure, public :: dz => element_operation_general_dz
55 procedure, public :: lift => element_operation_general_lift
56 procedure, public :: dxdydzlift => element_operation_general_dxdydzlift
57 procedure, public :: div => element_operation_general_div
58 procedure, public :: div_var5 => element_operation_general_div_var5
59 procedure, public :: div_var5_2 => element_operation_general_div_var5_2
60 procedure, public :: lift_var5 => element_operation_general_lift_var5
61 procedure, public :: vfilterpm1 => element_operation_general_vfilterpm1
62 !-
63 procedure, public :: setup_modalfilter => element_operation_general_setup_modalfilter
64 procedure, public :: setup_modalfilter_tracer => element_operation_general_setup_modalfilter_tracer
65 procedure, public :: modalfilter_tracer => element_operation_general_modalfilter_tracer
66 procedure, public :: modalfilter_var5 => element_operation_general_modalfilter_var5
68
70 module procedure element_operation_general_generate_vpordm1
71 end interface
73
74contains
75
76 !> Initialization
77 !!
78!OCL SERIAL
79 subroutine element_operation_general_init( this, elem3D, &
80 Dx, Dy, Dz, Lift )
82 implicit none
83 class(ElementOperationGeneral), intent(inout) :: this
84 class(ElementBase3D), intent(in), target :: elem3D
85 type(SparseMat), intent(in), target :: Dx
86 type(SparseMat), intent(in), target :: Dy
87 type(SparseMat), intent(in), target :: Dz
88 type(SparseMat), intent(in), target :: Lift
89 !----------------------------------------------------------
90
91 this%operator_type = element_operator_type_general
92
93 this%elem3D => elem3d
94 this%Dx_sm => dx
95 this%Dy_sm => dy
96 this%Dz_sm => dz
97 this%Lift_sm => lift
98
99 !--
100 allocate( this%IntrpMat_VPOrdM1(elem3d%Np,elem3d%Np) )
101 call element_operation_general_generate_vpordm1( this%IntrpMat_VPOrdM1, &
102 elem3d )
103
104 return
105 end subroutine element_operation_general_init
106
107 !> Generate a vertical filter matrix to remove the highest mode
108 !!
109!OCL SERIAL
110 subroutine element_operation_general_generate_vpordm1( IntrpMat_VPOrdM1, &
111 elem3D )
112 implicit none
113 class(elementbase3d), intent(in), target :: elem3D
114 real(RP), intent(out) :: IntrpMat_VPOrdM1(elem3D%Np,elem3D%Np)
115 !----------------------------------------------------------
116 call elem3d%Generate_ModalTruncationMat( elem3d%PolyOrder_h, elem3d%PolyOrder_v-1, & ! (in)
117 intrpmat_vpordm1 ) ! (out)
118 return
119 end subroutine element_operation_general_generate_vpordm1
120
121 !> Setup modal filter
122 !!
123!OCL SERIAL
124 subroutine element_operation_general_setup_modalfilter( this, &
125 MF_ETAC_h, MF_ALPHA_h, MF_ORDER_h, &
126 MF_ETAC_v, MF_ALPHA_v, MF_ORDER_v )
127
128 implicit none
129 class(elementoperationgeneral), intent(inout) :: this
130 real(RP), intent(in) :: MF_ETAC_h
131 real(RP), intent(in) :: MF_ALPHA_h
132 integer, intent(in) :: MF_ORDER_h
133 real(RP), intent(in) :: MF_ETAC_v
134 real(RP), intent(in) :: MF_ALPHA_v
135 integer, intent(in) :: MF_ORDER_v
136 !--------------------------------------------------------
137
138 call setup_modalfilter( this%MFilter, &
139 mf_etac_h, mf_alpha_h, mf_order_h, &
140 mf_etac_v, mf_alpha_v, mf_order_v, &
141 this%elem3D%PolyOrder_h, this%elem3D%PolyOrder_v )
142
143 return
144 end subroutine element_operation_general_setup_modalfilter
145
146 !> Setup modal filter for tracer
147 !!
148!OCL SERIAL
149 subroutine element_operation_general_setup_modalfilter_tracer( this, &
150 MF_ETAC_h, MF_ALPHA_h, MF_ORDER_h, &
151 MF_ETAC_v, MF_ALPHA_v, MF_ORDER_v )
152 implicit none
153 class(elementoperationgeneral), intent(inout) :: this
154 real(RP), intent(in) :: MF_ETAC_h
155 real(RP), intent(in) :: MF_ALPHA_h
156 integer, intent(in) :: MF_ORDER_h
157 real(RP), intent(in) :: MF_ETAC_v
158 real(RP), intent(in) :: MF_ALPHA_v
159 integer, intent(in) :: MF_ORDER_v
160 !--------------------------------------------------------
161
162 call setup_modalfilter( this%MFilter_tracer, &
163 mf_etac_h, mf_alpha_h, mf_order_h, &
164 mf_etac_v, mf_alpha_v, mf_order_v, &
165 this%elem3D%PolyOrder_h, this%elem3D%PolyOrder_v )
166
167 return
168 end subroutine element_operation_general_setup_modalfilter_tracer
169
170
171 !> Finalization
172 !!
173 !OCL SERIAL
174 subroutine element_operation_general_final( this )
175 implicit none
176 class(elementoperationgeneral), intent(inout) :: this
177 !----------------------------------------------------------
178
179 nullify( this%elem3D )
180 nullify( this%Dx_sm, this%Dy_sm, this%Dz_sm, this%Lift_sm )
181
182 deallocate( this%IntrpMat_VPOrdM1 )
183
184 return
185 end subroutine element_operation_general_final
186
187!> Calculate the differential in x-direction
188!!
189!OCL SERIAL
190 subroutine element_operation_general_dx( this, vec_in, vec_out )
191 implicit none
192 class(elementoperationgeneral), intent(in) :: this
193 real(RP), intent(in) :: vec_in(this%elem3D%Np)
194 real(RP), intent(out) :: vec_out(this%elem3D%Np)
195 !----------------------------------------------------------
196 call sparsemat_matmul( this%Dx_sm, vec_in, vec_out )
197 return
198 end subroutine element_operation_general_dx
199
200!> Calculate the differential in y-direction
201!!
202!OCL SERIAL
203 subroutine element_operation_general_dy( this, vec_in, vec_out )
204 implicit none
205 class(elementoperationgeneral), intent(in) :: this
206 real(RP), intent(in) :: vec_in(this%elem3D%Np)
207 real(RP), intent(out) :: vec_out(this%elem3D%Np)
208 !----------------------------------------------------------
209 call sparsemat_matmul( this%Dy_sm, vec_in, vec_out )
210 return
211 end subroutine element_operation_general_dy
212
213!> Calculate the differential in z-direction
214!!
215!OCL SERIAL
216 subroutine element_operation_general_dz( this, vec_in, vec_out )
217 implicit none
218 class(elementoperationgeneral), intent(in) :: this
219 real(RP), intent(in) :: vec_in(this%elem3D%Np)
220 real(RP), intent(out) :: vec_out(this%elem3D%Np)
221 !----------------------------------------------------------
222 call sparsemat_matmul( this%Dz_sm, vec_in, vec_out )
223 return
224 end subroutine element_operation_general_dz
225
226!> Calculate the differential in z-direction
227!!
228!OCL SERIAL
229 subroutine element_operation_general_lift( this, vec_in, vec_out )
230 implicit none
231 class(elementoperationgeneral), intent(in) :: this
232 real(RP), intent(in) :: vec_in(this%elem3D%NfpTot)
233 real(RP), intent(out) :: vec_out(this%elem3D%Np)
234 !----------------------------------------------------------
235 call sparsemat_matmul( this%Lift_sm, vec_in, vec_out )
236 return
237 end subroutine element_operation_general_lift
238
239!> Calculate the 3D gradient
240!!
241!OCL SERIAL
242 subroutine element_operation_general_dxdydzlift( this, vec_in, vec_in_lift, vec_out_dx, vec_out_dy, vec_out_dz, vec_out_lift )
243 implicit none
244 class(elementoperationgeneral), intent(in) :: this
245 real(RP), intent(in) :: vec_in(this%elem3D%Np)
246 real(RP), intent(in) :: vec_in_lift(this%elem3D%NfpTot)
247 real(RP), intent(out) :: vec_out_dx(this%elem3D%Np)
248 real(RP), intent(out) :: vec_out_dy(this%elem3D%Np)
249 real(RP), intent(out) :: vec_out_dz(this%elem3D%Np)
250 real(RP), intent(out) :: vec_out_lift(this%elem3D%Np)
251 !----------------------------------------------------------
252
253 call sparsemat_matmul( this%Dx_sm, vec_in, vec_out_dx )
254 call sparsemat_matmul( this%Dy_sm, vec_in, vec_out_dy )
255 call sparsemat_matmul( this%Dz_sm, vec_in, vec_out_dz )
256 call sparsemat_matmul( this%Lift_sm, vec_in_lift, vec_out_lift )
257 return
258 end subroutine element_operation_general_dxdydzlift
259
260!> Calculate the 3D gradient
261!!
262!OCL SERIAL
263 subroutine element_operation_general_div( this, vec_in, vec_in_lift, &
264 vec_out )
265 implicit none
266 class(elementoperationgeneral), intent(in) :: this
267 real(RP), intent(in) :: vec_in(this%elem3D%Np,3)
268 real(RP), intent(in) :: vec_in_lift(this%elem3D%NfpTot)
269 real(RP), intent(out) :: vec_out(this%elem3D%Np,4)
270 !---------------------------------------------------------------
271
272 call sparsemat_matmul( this%Dx_sm, vec_in(:,1), vec_out(:,1) )
273 call sparsemat_matmul( this%Dy_sm, vec_in(:,2), vec_out(:,2) )
274 call sparsemat_matmul( this%Dz_sm, vec_in(:,3), vec_out(:,3) )
275 call sparsemat_matmul( this%Lift_sm, vec_in_lift, vec_out(:,4) )
276 return
277 end subroutine element_operation_general_div
278
279
280!> Calculate the 3D gradient
281!!
282!OCL SERIAL
283 subroutine element_operation_general_div_var5( this, vec_in, vec_in_lift, &
284 vec_out_d )
285 implicit none
286 class(elementoperationgeneral), intent(in) :: this
287 real(RP), intent(in) :: vec_in(this%elem3D%Np,3,5)
288 real(RP), intent(in) :: vec_in_lift(this%elem3D%NfpTot,5)
289 real(RP), intent(out) :: vec_out_d(this%elem3D%Np,4,5)
290
291 integer :: iv
292 !---------------------------------------------------------------
293
294 do iv=1, 5
295 call sparsemat_matmul( this%Dx_sm, vec_in(:,1,iv), vec_out_d(:,1,iv) )
296 call sparsemat_matmul( this%Dy_sm, vec_in(:,2,iv), vec_out_d(:,2,iv) )
297 call sparsemat_matmul( this%Dz_sm, vec_in(:,3,iv), vec_out_d(:,3,iv) )
298 end do
299 do iv=1, 5
300 call sparsemat_matmul( this%Lift_sm, vec_in_lift(:,iv), vec_out_d(:,4,iv) )
301 end do
302 return
303 end subroutine element_operation_general_div_var5
304
305!> Calculate the 3D gradient
306!!
307!OCL SERIAL
308 subroutine element_operation_general_div_var5_2( this, vec_in, &
309 vec_out_d )
310 implicit none
311 class(elementoperationgeneral), intent(in) :: this
312 real(RP), intent(in) :: vec_in(this%elem3D%Np,3,5)
313 real(RP), intent(out) :: vec_out_d(this%elem3D%Np,3,5)
314
315 integer :: iv
316 !---------------------------------------------------------------
317
318 do iv=1, 5
319 call sparsemat_matmul( this%Dx_sm, vec_in(:,1,iv), vec_out_d(:,1,iv) )
320 call sparsemat_matmul( this%Dy_sm, vec_in(:,2,iv), vec_out_d(:,2,iv) )
321 call sparsemat_matmul( this%Dz_sm, vec_in(:,3,iv), vec_out_d(:,3,iv) )
322 end do
323 return
324 end subroutine element_operation_general_div_var5_2
325!> Calculate the differential in z-direction
326!!
327!OCL SERIAL
328 subroutine element_operation_general_lift_var5( this, vec_in, vec_out )
329 implicit none
330 class(elementoperationgeneral), intent(in) :: this
331 real(RP), intent(in) :: vec_in(this%elem3D%NfpTot,5)
332 real(RP), intent(out) :: vec_out(this%elem3D%Np,5)
333
334 integer :: iv
335 !----------------------------------------------------------
336 do iv=1,5
337 call sparsemat_matmul( this%Lift_sm, vec_in(:,iv), vec_out(:,iv) )
338 end do
339 return
340 end subroutine element_operation_general_lift_var5
341
342!OCL SERIAL
343 subroutine element_operation_general_vfilterpm1( this, vec_in, vec_out )
344 implicit none
345 class(elementoperationgeneral), intent(in) :: this
346 real(RP), intent(in) :: vec_in(this%elem3D%Np)
347 real(RP), intent(out) :: vec_out(this%elem3D%Np)
348 !---------------------------------------------------------------
349
350 call matmul_( this%IntrpMat_VPOrdM1, vec_in, this%elem3D%Np, &
351 vec_out )
352 return
353 end subroutine element_operation_general_vfilterpm1
354!--
355!OCL SERIAL
356 subroutine matmul_( IntrpMat_VPOrdM1, vec_in_, Np, vec_out_ )
357 implicit none
358 integer, intent(in) :: Np
359 real(RP), intent(in) :: IntrpMat_VPOrdM1(Np,Np)
360 real(RP), intent(in) :: vec_in_(Np)
361 real(RP), intent(out) :: vec_out_(Np)
362 !-------------------------------------------
363 vec_out_(:) = matmul( intrpmat_vpordm1(:,:), vec_in_(:) )
364 return
365 end subroutine matmul_
366
367!OCL SERIAL
368 subroutine element_operation_general_modalfilter_tracer( this, vec_in, vec_work, vec_out )
369 implicit none
370 class(elementoperationgeneral), intent(in) :: this
371 real(RP), intent(in) :: vec_in(this%elem3D%Np)
372 real(RP), intent(out) :: vec_work(this%elem3D%Np)
373 real(RP), intent(out) :: vec_out(this%elem3D%Np)
374
375 integer :: ii, kk, Np
376 real(RP) :: Mik
377 !---------------------------------------------
378
379 np = this%elem3D%Np
380 vec_out(:) = 0.0_rp
381
382 do ii=1, np
383 do kk=1, np
384 mik = this%MFilter_tracer%FilterMat(ii,kk)
385 vec_out(ii) = vec_out(ii) + mik * vec_in(kk)
386 end do
387 end do
388
389 return
390 end subroutine element_operation_general_modalfilter_tracer
391
392!OCL SERIAL
393 subroutine element_operation_general_modalfilter_var5( this, vec_in, vec_work, vec_out )
394 implicit none
395 class(elementoperationgeneral), intent(in) :: this
396 real(RP), intent(in) :: vec_in(this%elem3D%Np,5)
397 real(RP), intent(out) :: vec_work(this%elem3D%Np)
398 real(RP), intent(out) :: vec_out(this%elem3D%Np,5)
399
400 integer :: ii, kk, Np
401 real(RP) :: Mik
402 !---------------------------------------------
403
404 np = this%elem3D%Np
405 vec_out(:,:) = 0.0_rp
406
407 do ii=1, np
408 do kk=1, np
409 mik = this%MFilter%FilterMat(ii,kk)
410
411 vec_out(ii,1) = vec_out(ii,1) + mik * vec_in(kk,1)
412 vec_out(ii,2) = vec_out(ii,2) + mik * vec_in(kk,2)
413 vec_out(ii,3) = vec_out(ii,3) + mik * vec_in(kk,3)
414 vec_out(ii,4) = vec_out(ii,4) + mik * vec_in(kk,4)
415 vec_out(ii,5) = vec_out(ii,5) + mik * vec_in(kk,5)
416 end do
417 end do
418
419 return
420 end subroutine element_operation_general_modalfilter_var5
421
422!- private -
423
424!OCL SERIAL
425 subroutine setup_modalfilter( MFilter, &
426 MF_ETAC_h, MF_ALPHA_h, MF_ORDER_h, &
427 MF_ETAC_v, MF_ALPHA_v, MF_ORDER_v, &
428 PolyOrder_h, PolyOrder_v )
429
431 implicit none
432
433 class(modalfilter), intent(inout) :: MFilter
434 real(RP), intent(in) :: MF_ETAC_h
435 real(RP), intent(in) :: MF_ALPHA_h
436 integer, intent(in) :: MF_ORDER_h
437 real(RP), intent(in) :: MF_ETAC_v
438 real(RP), intent(in) :: MF_ALPHA_v
439 integer, intent(in) :: MF_ORDER_v
440 integer, intent(in) :: PolyOrder_h
441 integer, intent(in) :: PolyOrder_v
442
443 type(hexahedralelement) :: elem3D
444 !--------------------------------------------------------
445
446 call elem3d%Init( polyorder_h, polyorder_v, .false. )
447
448 call mfilter%Init( &
449 elem3d, & ! (in)
450 mf_etac_h, mf_alpha_h, mf_order_h, & ! (in)
451 mf_etac_v, mf_alpha_v, mf_order_v ) ! (in)
452
453 call elem3d%Final()
454 return
455 end subroutine setup_modalfilter
456
module FElib / Element / Base
subroutine, public elementbase3d_init(elem, lumpedmat_flag)
Initialize an object to manage a 3D reference element.
subroutine, public elementbase3d_final(elem)
Finalize an object to manage a 3D reference element.
module FElib / Element / hexahedron
module FElib / Element/ ModalFilter
module FElib / Element / Operation / Base
integer, public element_operator_type_general
Type ID of general operator.
module FElib / Element / Operation with arbitary elements
Module common / sparsemat.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
Derived type representing a modal filter.
Derived type for elementwise operations with arbitary elements.
Derived type to manage a sparse matrix.