FE-Project
Loading...
Searching...
No Matches
scale_element_quadrilateral.F90
Go to the documentation of this file.
1!> module FElib / Element / Quadrilateral
2!!
3!! @par Description
4!! A module for a quadrilateral finite element
5!!
6!! @author Yuta Kawai, Team SCALE
7!!
8!<
9#include "scaleFElib.h"
11
12 !-----------------------------------------------------------------------------
13 !
14 !++ used modules
15 !
16 use scale_precision
17
18 use scale_element_base, only: &
21
22 !-----------------------------------------------------------------------------
23 implicit none
24 private
25
26 !-----------------------------------------------------------------------------
27 !
28 !++ Public type & procedure
29 !
30
31 !> Derived type representing a quadrilateral element
32 type, public, extends(elementbase2d) :: quadrilateralelement
33 contains
34 procedure :: init => quadrilateralelement_init
35 procedure :: final => quadrilateralelement_final
36 procedure :: genintgausslegendreintrpmat => quadrilateralelement_gen_intgausslegendreintrpmat
38
39 !-----------------------------------------------------------------------------
40 !
41 !++ Private procedure
42 !
43 private :: construct_element
44
45contains
46
47!> Initialize an object to manage a hexahedral element
48!!
49!! @param elem Object of finite element
50!! @param elemOrder Polynomial order with 1D direction
51!! @param LumpedMassMatFlag Flag whether mass lumping is considered
52!OCL SERIAL
54 elem, elemOrder, &
55 LumpedMassMatFlag )
56
57 implicit none
58
59 class(quadrilateralelement), intent(inout) :: elem
60 integer, intent(in) :: elemOrder
61 logical, intent(in) :: LumpedMassMatFlag
62
63 !-----------------------------------------------------------------------------
64
65 elem%PolyOrder = elemorder
66 elem%Nv = 4
67 elem%Np = (elemorder + 1)**2
68 elem%Nfp = elemorder + 1
69 elem%Nfaces = 4
70 elem%NfpTot = elem%Nfp*elem%Nfaces
71
72 call elementbase2d_init(elem, lumpedmassmatflag)
73 call construct_element(elem)
74
75 return
76 end subroutine quadrilateralelement_init
77
78!> Finalize an object to manage a quadrilateral element
79!!
80!! @param elem Object of finite element
81!OCL SERIAL
82 subroutine quadrilateralelement_final(elem)
83 implicit none
84
85 class(quadrilateralelement), intent(inout) :: elem
86 !-----------------------------------------------------------------------------
87
88 call elementbase2d_final(elem)
89
90 return
91 end subroutine quadrilateralelement_final
92
93!OCL SERIAL
94 subroutine construct_element(elem)
95
97 use scale_polynominal, only: &
101 use scale_element_base, only: &
104
105 implicit none
106
107 type(quadrilateralelement), intent(inout) :: elem
108
109 integer :: nodes_ij(elem%Nfp, elem%Nfp)
110
111 real(RP) :: lglPts1D(elem%Nfp)
112 real(DP) :: intWeight_lgl1DPts(elem%Nfp)
113
114 real(RP) :: P1D_ori(elem%Nfp, elem%Nfp)
115 real(RP) :: DP1D_ori(elem%Nfp, elem%Nfp)
116 real(RP) :: DLagr1D(elem%Nfp, elem%Nfp)
117 real(RP) :: V1D(elem%Nfp, elem%Nfp)
118 real(RP) :: Emat(elem%Np, elem%NfpTot)
119 real(RP) :: MassEdge(elem%Nfp, elem%Nfp)
120
121 real(RP) :: eta, etac
122 real(RP) :: filter1D(elem%Nfp), filter2D(elem%Np)
123
124 integer :: i, j
125 integer :: p1, p2
126 integer :: n, l, f
127 integer :: Nord
128 !-----------------------------------------------------------------------------
129
130 lglpts1d(:) = polynominal_gengausslobattopt( elem%PolyOrder )
131 p1d_ori(:,:) = polynominal_genlegendrepoly( elem%PolyOrder, lglpts1d )
132 dp1d_ori(:,:) = polynominal_gendlegendrepoly( elem%PolyOrder, lglpts1d, p1d_ori )
133 dlagr1d(:,:) = polynominal_gendlagrangepoly_lglpt(elem%PolyOrder, lglpts1d)
134
135 !* Preparation
136
137 do j=1, elem%Nfp
138 do i=1, elem%Nfp
139 nodes_ij(i,j) = i + (j-1)*elem%Nfp
140 end do
141 end do
142
143 ! Set the mask to extract the values at faces
144
145 elem%Fmask(:,1) = nodes_ij(:,1)
146 elem%Fmask(:,2) = nodes_ij(elem%Nfp,:)
147 elem%Fmask(:,3) = nodes_ij(:,elem%Nfp)
148 elem%Fmask(:,4) = nodes_ij(1,:)
149
150 !* Set the coordinates of LGL points, and the Vandermonde and differential matricies
151
152 elem%Dx1(:,:) = 0.0_rp
153 elem%Dx2(:,:) = 0.0_rp
154
155 do j=1, elem%Nfp
156 do i=1, elem%Nfp
157 n = i + (j-1)*elem%Nfp
158
159 !* Set the coordinates of LGL points
160 elem%x1(n) = lglpts1d(i)
161 elem%x2(n) = lglpts1d(j)
162
163 !* Set the Vandermonde and differential matricies
164 do p2=1, elem%Nfp
165 do p1=1, elem%Nfp
166 l = p1 + (p2-1)*elem%Nfp
167 elem%V(n,l) = (p1d_ori(i,p1)*p1d_ori(j,p2)) &
168 * sqrt((dble(p1-1) + 0.5_dp)*(dble(p2-1) + 0.5_dp))
169
170 if(p2==j) elem%Dx1(n,l) = dlagr1d(p1,i)
171 if(p1==i) elem%Dx2(n,l) = dlagr1d(p2,j)
172 end do
173 end do
174 end do
175 end do
176 elem%invV(:,:) = linalgebra_inv(elem%V)
177
178 !* Set the weights at LGL points to integrate over element
179
180 intweight_lgl1dpts(:) = polynominal_gengausslobattoptintweight(elem%PolyOrder)
181
182 do j=1, elem%Nfp
183 do i=1, elem%Nfp
184 l = i + (j - 1)*elem%Nfp
185 elem%IntWeight_lgl(l) = &
186 intweight_lgl1dpts(i) * intweight_lgl1dpts(j)
187 end do
188 end do
189
190 !* Set the mass matrix
191
192 if (elem%IsLumpedMatrix()) then
193 elem%invM(:,:) = 0.0_rp
194 elem%M(:,:) = 0.0_rp
195 do j=1, elem%Nfp
196 do i=1, elem%Nfp
197 l = i + (j - 1)*elem%Nfp
198 elem%M(l,l) = elem%IntWeight_lgl(l)
199 elem%invM(l,l) = 1.0_rp/elem%IntWeight_lgl(l)
200 end do
201 end do
202 else
203 call elementbase_construct_massmat( elem%V, elem%Np, & ! (in)
204 elem%M, elem%invM ) ! (out)
205 end if
206
207 !* Set the stiffness matrix
208
209 call elementbase_construct_stiffmat( elem%M, elem%invM, elem%Dx1, elem%Np, & ! (in)
210 elem%Sx1 ) ! (out)
211 call elementbase_construct_stiffmat( elem%M, elem%invM, elem%Dx2, elem%Np, & ! (in)
212 elem%Sx2 ) ! (out)
213
214 !* Set the lift matrix
215
216 do p1=1, elem%Nfp
217 v1d(:,p1) = p1d_ori(:,p1)*sqrt(dble(p1-1) + 0.5_dp)
218 end do
219
220 emat(:,:) = 0.0_rp
221 do f=1, elem%Nfaces
222
223 if (elem%IsLumpedMatrix()) then
224 massedge = 0.0_rp
225 do l=1, elem%Nfp
226 massedge(l,l) = intweight_lgl1dpts(l)
227 end do
228 else
229 call elementbase_construct_massmat( v1d, elem%Nfp, & ! (in)
230 massedge ) ! (out)
231 end if
232
233 emat(elem%Fmask(:,f), (f-1)*elem%Nfp+1:f*elem%Nfp) = massedge
234 end do
235 call elementbase_construct_liftmat( elem%invM, emat, elem%Np, elem%NfpTot, & ! (in)
236 elem%Lift ) ! (out)
237
238 !* Construct filter matrix
239
240 return
241 end subroutine construct_element
242
243!OCL SERIAL
244 function quadrilateralelement_gen_intgausslegendreintrpmat( this, IntrpPolyOrder, &
245 intw_intrp, x_intrp, y_intrp ) result(IntrpMat)
246
247 use scale_polynominal, only: &
251
252 implicit none
253
254 class(quadrilateralelement), intent(in) :: this
255 integer, intent(in) :: IntrpPolyOrder
256 real(RP), intent(out), optional :: intw_intrp(IntrpPolyOrder**2)
257 real(RP), intent(out), optional :: x_intrp(IntrpPolyOrder**2)
258 real(RP), intent(out), optional :: y_intrp(IntrpPolyOrder**2)
259 real(RP) :: IntrpMat(IntrpPolyOrder**2,this%Np)
260
261 real(RP) :: r_int1D_i(IntrpPolyOrder)
262 real(RP) :: r_int1Dw_i(IntrpPolyOrder)
263 real(RP) :: P_int1D_ori(IntrpPolyOrder,this%PolyOrder+1)
264 real(RP) :: Vint(IntrpPolyOrder**2,(this%PolyOrder+1)**2)
265
266 integer :: p1, p2, p1_, p2_
267 integer :: n_, l_
268 !-----------------------------------------------------
269
270 r_int1d_i(:) = polynominal_gengausslegendrept( intrppolyorder )
271 r_int1dw_i(:) = polynominal_gengausslegendreptintweight( intrppolyorder )
272 p_int1d_ori(:,:) = polynominal_genlegendrepoly( this%PolyOrder, r_int1d_i)
273
274 do p2_=1, intrppolyorder
275 do p1_=1, intrppolyorder
276 n_= p1_ + (p2_-1)*intrppolyorder
277 if (present(intw_intrp)) intw_intrp(n_) = r_int1dw_i(p1_) * r_int1dw_i(p2_)
278 if (present(x_intrp)) x_intrp(n_) = r_int1d_i(p1_)
279 if (present(y_intrp)) y_intrp(n_) = r_int1d_i(p2_)
280
281 do p2=1, this%Nfp
282 do p1=1, this%Nfp
283 l_ = p1 + (p2-1)*this%Nfp
284 vint(n_,l_) = p_int1d_ori(p1_,p1) * sqrt(dble(p1-1) + 0.5_dp) &
285 * p_int1d_ori(p2_,p2) * sqrt(dble(p2-1) + 0.5_dp)
286 end do
287 end do
288 end do
289 end do
290 intrpmat(:,:) = matmul(vint, this%invV)
291
292 return
293 end function quadrilateralelement_gen_intgausslegendreintrpmat
294
295 !-------------------
296
module FElib / Element / Base
subroutine, public elementbase2d_final(elem)
Finalize an object to manage a 2D reference element.
subroutine, public elementbase2d_init(elem, lumpedmat_flag)
Initialize an object to manage a 2D reference element.
subroutine, public elementbase_construct_massmat(v, np, massmat, invmassmat)
Construct mass matrix M^-1 = V V^T M = ( M^-1 )^-1.
subroutine, public elementbase_construct_stiffmat(massmat, invmassmat, dmat, np, stiffmat)
Construct stiffness matrix StiffMat_i = M^-1 ( M D_xi )^T.
subroutine, public elementbase_construct_liftmat(invm, emat, np, nfptot, liftmat)
Construct stiffness matrix StiffMat_i = M^-1 ( M D_xi )^T.
module FElib / Element / Quadrilateral
subroutine quadrilateralelement_init(elem, elemorder, lumpedmassmatflag)
Initialize an object to manage a hexahedral element.
Module common / Linear algebra.
real(rp) function, dimension(size(a, 1), size(a, 2)), public linalgebra_inv(a)
Calculate a inversion of matrix A.
Module common / Polynominal.
real(rp) function, dimension(nord), public polynominal_gengausslegendreptintweight(nord)
A function to calculate the Gauss-Legendre (GL) weights.
real(rp) function, dimension(nord), public polynominal_gengausslegendrept(nord)
A function to calculate the Gauss-Legendre (GL) points.
real(rp) function, dimension(size(x), nord+1), public polynominal_genlagrangepoly(nord, x_lgl, x)
A function to obtain the Lagrange basis functions related to the Gauss-Legendre-Lobatto (GLL) points.
real(rp) function, dimension(nord+1), public polynominal_gengausslobattopt(nord)
A function to calculate the Legendre-Gauss-Lobatto (LGL) points.
real(rp) function, dimension(size(x), nord+1), public polynominal_genlegendrepoly(nord, x)
A function to obtain the values of Legendre polynomials which are evaluated at arbitrary points.
real(rp) function, dimension(size(x), nord+1), public polynominal_gendlegendrepoly(nord, x, p)
A function to obtain differential values of Legendre polynomials which are evaluated at arbitrary poi...
real(rp) function, dimension(nord+1), public polynominal_gengausslobattoptintweight(nord)
A function to calculate the Gauss-Lobbato weights.
real(rp) function, dimension(nord+1, nord+1), public polynominal_gendlagrangepoly_lglpt(nord, x_lgl)
A function to obtain the differential values of Lagrange basis functions at the GLL points.
Derived type representing a 2D reference element.
Derived type representing a quadrilateral element.