FE-Project
Loading...
Searching...
No Matches
scale_element_modalfilter.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Element/ ModalFilter
3!!
4!! @par Description
5!! A module for modal filtering
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12 !-----------------------------------------------------------------------------
13 !
14 !++ Used modules
15 !
16 use scale_precision
17 use scale_io
18 use scale_prc
19 use scale_prof
20
21 use scale_element_base, only: &
23
27
28 !-----------------------------------------------------------------------------
29 implicit none
30 private
31 !-----------------------------------------------------------------------------
32 !
33 !++ Public procedures
34 !
35
36 !-----------------------------------------------------------------------------
37 !
38 !++ Public type
39 !
40
41 !> Derived type representing a modal filter
42 type, public :: modalfilter
43 real(rp), allocatable :: filtermat(:,:)
44 contains
45 procedure :: init_line => modalfilter_init_line
46 procedure :: init_quadrilateral => modalfilter_init_quadrilateral
47 procedure :: init_hexahedral => modalfilter_init_hexahedral
48 generic :: init => init_line, init_quadrilateral, init_hexahedral
49 procedure :: final => modalfilter_final
50 end type modalfilter
51
52 !-----------------------------------------------------------------------------
53 !
54 !++ Private procedures & variables
55 !
56 !-------------------
57
58 private :: get_exp_filter
59
60contains
61 subroutine modalfilter_init_line( this, & ! (inout)
62 elem, & ! (in)
63 etac, alpha, ord, & ! (in)
64 tend_flag ) ! (in)
65
66 implicit none
67 class(modalfilter), intent(inout) :: this
68 class(lineelement), intent(in) :: elem
69 real(RP), intent(in) :: etac
70 real(RP), intent(in) :: alpha
71 integer, intent(in) :: ord
72 logical, intent(in), optional :: tend_flag
73
74 real(RP) :: filter1D(elem%Np)
75 integer :: p
76 logical :: tend_flag_
77 !----------------------------------------------------
78
79 tend_flag_ = .false.
80 if ( present(tend_flag) ) tend_flag_ = tend_flag
81
82 call get_exp_filter( filter1d, & ! (out)
83 etac, alpha, ord, elem%Np, elem%PolyOrder, & ! (in)
84 tend_flag_ ) ! (in)
85
86 allocate( this%FilterMat(elem%Np,elem%Np) )
87 this%FilterMat(:,:) = 0.0_rp
88 do p=1, elem%Np
89 this%FilterMat(p,p) = filter1d(p)
90 end do
91 this%FilterMat(:,:) = matmul(this%FilterMat, elem%invV)
92 this%FilterMat(:,:) = matmul(elem%V, this%FilterMat)
93 !$acc enter data copyin(this%FilterMat)
94
95 return
96 end subroutine modalfilter_init_line
97
98 subroutine modalfilter_init_quadrilateral( this, & ! (inout)
99 elem, & ! (in)
100 etac, alpha, ord, & ! (in)
101 tend_flag ) ! (in)
102
103 implicit none
104 class(modalfilter), intent(inout) :: this
105 class(quadrilateralelement), intent(in) :: elem
106 real(RP), intent(in) :: etac
107 real(RP), intent(in) :: alpha
108 integer, intent(in) :: ord
109 logical, intent(in), optional :: tend_flag
110
111 real(RP) :: filter1D(elem%Nfp)
112 integer :: p1, p2
113 integer :: l
114 logical :: tend_flag_
115 !----------------------------------------------------
116
117 tend_flag_ = .false.
118 if ( present(tend_flag) ) tend_flag_ = tend_flag
119
120 call get_exp_filter( filter1d, & ! (out)
121 etac, alpha, ord, elem%Nfp, elem%PolyOrder, & ! (in)
122 tend_flag_ ) ! (in)
123
124 allocate( this%FilterMat(elem%Np,elem%Np) )
125 this%FilterMat(:,:) = 0.0_rp
126 do p2=1, elem%Nfp
127 do p1=1, elem%Nfp
128 l = p1 + (p2-1)*elem%Nfp
129 this%FilterMat(l,l) = filter1d(p1) * filter1d(p2)
130 end do
131 end do
132 this%FilterMat(:,:) = matmul(this%FilterMat, elem%invV)
133 this%FilterMat(:,:) = matmul(elem%V, this%FilterMat)
134 !$acc enter data copyin(this%FilterMat)
135 return
136 end subroutine modalfilter_init_quadrilateral
137
138 subroutine modalfilter_init_hexahedral( this, & ! (inout)
139 elem, & ! (in)
140 etac_h, alpha_h, ord_h, & ! (in)
141 etac_v, alpha_v, ord_v, & ! (in)
142 tend_flag ) ! (in)
143
144 implicit none
145 class(modalfilter), intent(inout) :: this
146 class(hexahedralelement), intent(in) :: elem
147 real(RP), intent(in) :: etac_h
148 real(RP), intent(in) :: alpha_h
149 integer, intent(in) :: ord_h
150 real(RP), intent(in) :: etac_v
151 real(RP), intent(in) :: alpha_v
152 integer, intent(in) :: ord_v
153 logical, intent(in), optional :: tend_flag
154
155 real(RP) :: filter1D_h(elem%Nnode_h1D)
156 real(RP) :: filter1D_v(elem%Nnode_v)
157 integer :: p1, p2, p3
158 integer :: l
159 logical :: tend_flag_
160 !----------------------------------------------------
161
162 tend_flag_ = .false.
163 if ( present(tend_flag) ) tend_flag_ = tend_flag
164
165 call get_exp_filter( filter1d_h, & ! (out)
166 etac_h, alpha_h, ord_h, elem%Nnode_h1D, elem%PolyOrder_h, & ! (in)
167 tend_flag_ ) ! (in)
168
169 call get_exp_filter( filter1d_v, & ! (out)
170 etac_v, alpha_v, ord_v, elem%Nnode_v, elem%PolyOrder_v, & ! (in)
171 tend_flag_ ) ! (in)
172
173 allocate( this%FilterMat(elem%Np,elem%Np) )
174 this%FilterMat(:,:) = 0.0_rp
175 do p3=1, elem%Nnode_v
176 do p2=1, elem%Nnode_h1D
177 do p1=1, elem%Nnode_h1D
178 l = p1 + (p2-1)*elem%Nnode_h1D + (p3-1)*elem%Nnode_h1D**2
179 this%FilterMat(l,l) = filter1d_h(p1) * filter1d_h(p2) * filter1d_v(p3)
180 end do
181 end do
182 end do
183 this%FilterMat(:,:) = matmul(this%FilterMat, elem%invV)
184 this%FilterMat(:,:) = matmul(elem%V, this%FilterMat)
185 !$acc enter data copyin(this%FilterMat)
186 return
187 end subroutine modalfilter_init_hexahedral
188
189 subroutine modalfilter_final( this )
190 implicit none
191
192 class(modalfilter), intent(inout) :: this
193 !--------------------------------------------
194
195 if( allocated(this%FilterMat) ) then
196 !$acc exit data delete(this%FilterMat)
197 deallocate( this%FilterMat )
198 end if
199 return
200 end subroutine modalfilter_final
201
202!-- private --------------------------------------------------
203
204 subroutine get_exp_filter( filter, &
205 etac, alpha, ord, Np, polyOrder, &
206 tend_flag )
207
208 implicit none
209 integer, intent(in) :: Np
210 real(RP), intent(out) :: filter(Np)
211 real(RP), intent(in) :: etac
212 real(RP), intent(in) :: alpha
213 integer , intent(in) :: ord
214 integer , intent(in) :: polyOrder
215 logical, intent(in) :: tend_flag
216
217 integer :: p
218 real(RP) :: eta
219 !-----------------------------------------
220
221 if ( tend_flag ) then
222 filter(:) = 0.0_rp
223 else
224 filter(:) = 1.0_rp
225 end if
226
227 do p=1, np
228 eta = dble(p-1)/dble(polyorder)
229 if ( eta > etac .and. p /= 1) then
230 filter(p) = - alpha * ( ((eta - etac)/(1.0_rp - etac))**ord )
231 if ( .not. tend_flag ) filter(p) = exp( filter(p) )
232 end if
233 end do
234
235 return
236 end subroutine get_exp_filter
237
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Element / line
module FElib / Element/ ModalFilter
subroutine modalfilter_init_line(this, elem, etac, alpha, ord, tend_flag)
module FElib / Element / Quadrilateral
Derived type representing a 1D reference element.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing a hexahedral element.
Derived type representing a line element.
Derived type representing a modal filter.
Derived type representing a quadrilateral element.