FE-Project
Loading...
Searching...
No Matches
scale_element_line.F90
Go to the documentation of this file.
1!> module FElib / Element / line
2!!
3!! @par Description
4!! A module for a line 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 line element
32 type, public, extends(elementbase1d) :: lineelement
33 contains
34 procedure :: init => lineelement_init
35 procedure :: final => lineelement_final
36 procedure :: genintgausslegendreintrpmat => lineelement_gen_intgausslegendreintrpmat
37 end type lineelement
38
39 !-----------------------------------------------------------------------------
40 !
41 !++ Private procedure
42 !
43 private :: construct_element
44
45contains
46
47!> Initialize an object to manage a line element
48!!
49!! @param elem Object of finite element
50!! @param elemOrder Polynomial order
51!! @param LumpedMassMatFlag Flag whether mass lumping is considered
52!OCL SERIAL
53 subroutine lineelement_init( &
54 elem, elemOrder, &
55 LumpedMassMatFlag )
56
57 implicit none
58
59 class(lineelement), intent(inout) :: elem
60 integer, intent(in) :: elemOrder
61 logical, intent(in) :: LumpedMassMatFlag
62
63 !-----------------------------------------------------------------------------
64
65 elem%PolyOrder = elemorder
66 elem%Nv = 2
67 elem%Np = elemorder + 1
68 elem%Nfp = 1
69 elem%Nfaces = 2
70 elem%NfpTot = elem%Nfp*elem%Nfaces
71
72 call elementbase1d_init(elem, lumpedmassmatflag)
73 call construct_element(elem)
74
75 return
76 end subroutine lineelement_init
77
78!> Finalize an object to manage a line element
79!!
80!! @param elem Object of finite element
81!OCL SERIAL
82 subroutine lineelement_final(elem)
83 implicit none
84
85 class(lineelement), intent(inout) :: elem
86 !-----------------------------------------------------------------------------
87
88 call elementbase1d_final(elem)
89
90 return
91 end subroutine lineelement_final
92
93 !> Construct the element matrices and coordinates of LGL points
94!OCL SERIAL
95 subroutine construct_element(elem)
97 use scale_polynomial, only: &
101 use scale_element_base, only: &
104
105 implicit none
106
107 type(lineelement), intent(inout) :: elem
108
109 integer :: nodes(elem%Np)
110
111 real(RP) :: lglPts1D(elem%Np)
112 real(DP) :: intWeight_lgl1DPts(elem%Np)
113
114 real(RP) :: P1D_ori(elem%Np, elem%Np)
115 real(RP) :: DP1D_ori(elem%Np, elem%Np)
116 real(RP) :: DLagr1D(elem%Np, elem%Np)
117 real(RP) :: Emat(elem%Np, elem%Nfp*elem%Nfaces)
118 real(RP) :: MassEdge(elem%Nfp, elem%Nfp)
119
120 integer :: i
121 integer :: p1
122 integer :: n, l, f
123 integer :: Nord
124 !-----------------------------------------------------------------------------
125
126 lglpts1d(:) = polynomial_gengausslobattopt( elem%PolyOrder )
127
128 p1d_ori(:,:) = polynomial_genlegendrepoly( elem%PolyOrder, lglpts1d )
129 dp1d_ori(:,:) = polynomial_gendlegendrepoly( elem%PolyOrder, lglpts1d, p1d_ori )
130 dlagr1d(:,:) = polynomial_gendlagrangepoly_lglpt(elem%PolyOrder, lglpts1d)
131
132 !* Preparation
133
134 do i=1, elem%Np
135 nodes(i) = i
136 end do
137
138 ! Set the mask to extract the values at faces
139
140 elem%Fmask(:,1) = 1
141 elem%Fmask(:,2) = elem%Np
142 !$acc update device(elem%Fmask)
143
144 !* Set the coordinates of LGL points, and the Vandermonde and differential matricies
145
146 elem%Dx1(:,:) = 0.0_rp
147
148 do n=1, elem%Np
149 !* Set the coordinates of LGL points
150 elem%x1(n) = lglpts1d(n)
151
152 !* Set the Vandermonde and differential matricies
153 do l=1, elem%Np
154 elem%V(n,l) = p1d_ori(n,l) * sqrt(dble(l-1) + 0.5_rp)
155 elem%Dx1(n,l) = dlagr1d(l,n)
156 end do
157 end do
158 elem%invV(:,:) = linalgebra_inv(elem%V)
159 !$acc update device(elem%x1, elem%V, elem%Dx1, elem%invV)
160
161 !* Set the weights at LGL points to integrate over element
162
163 elem%IntWeight_lgl(:) = polynomial_gengausslobattoptintweight(elem%PolyOrder)
164 !$acc update device(elem%IntWeight_lgl)
165
166 !* Set the mass matrix
167
168 if (elem%IsLumpedMatrix()) then
169 elem%invM(:,:) = 0.0_rp
170 elem%M(:,:) = 0.0_rp
171 do i=1, elem%Np
172 elem%M(i,i) = elem%IntWeight_lgl(i)
173 elem%invM(i,i) = 1.0_rp/elem%IntWeight_lgl(i)
174 end do
175 else
176 call elementbase_construct_massmat( elem%V, elem%Np, & ! (in)
177 elem%M, elem%invM ) ! (out)
178 end if
179 !$acc update device(elem%M, elem%invM)
180
181 !* Set the stiffness matrix
182
183 call elementbase_construct_stiffmat( elem%M, elem%invM, elem%Dx1, elem%Np, & ! (in)
184 elem%Sx1 ) ! (out)
185 !$acc update device(elem%Sx1)
186
187 !* Set the lift matrix
188
189 emat(:,:) = 0.0_rp
190 do f=1, elem%Nfaces
191 massedge(:,:) = 0.0_rp
192 do l=1, elem%Nfp
193 massedge(l,l) = 1.0_rp
194 end do
195 emat(elem%Fmask(:,f), (f-1)*elem%Nfp+1:f*elem%Nfp) = massedge
196 end do
197 call elementbase_construct_liftmat( elem%invM, emat, elem%Np, elem%NfpTot, & ! (in)
198 elem%Lift ) ! (out)
199 !$acc update device(elem%Lift)
200
201 return
202 end subroutine construct_element
203
204!OCL SERIAL
205 function lineelement_gen_intgausslegendreintrpmat( this, IntrpPolyOrder, &
206 intw_intrp, x_intrp ) result(IntrpMat)
207
208 use scale_polynomial, only: &
212
213 implicit none
214
215 class(lineelement), intent(in) :: this
216 integer, intent(in) :: IntrpPolyOrder
217 real(RP), intent(out), optional :: intw_intrp(IntrpPolyOrder)
218 real(RP), intent(out), optional :: x_intrp(IntrpPolyOrder)
219 real(RP) :: IntrpMat(IntrpPolyOrder,this%Np)
220
221 real(RP) :: r_int1D_i(IntrpPolyOrder)
222 real(RP) :: r_int1Dw_i(IntrpPolyOrder)
223 real(RP) :: P_int1D_ori(IntrpPolyOrder,this%PolyOrder+1)
224 real(RP) :: Vint(IntrpPolyOrder,this%PolyOrder+1)
225
226 integer :: p1, p1_
227 !-----------------------------------------------------
228
229 r_int1d_i(:) = polynomial_gengausslegendrept( intrppolyorder )
230 r_int1dw_i(:) = polynomial_gengausslegendreptintweight( intrppolyorder )
231 p_int1d_ori(:,:) = polynomial_genlegendrepoly( this%PolyOrder, r_int1d_i)
232
233 do p1_=1, intrppolyorder
234 if (present(intw_intrp)) intw_intrp(p1_) = r_int1dw_i(p1_)
235 if (present(x_intrp)) x_intrp(p1_) = r_int1d_i(p1_)
236 do p1=1, this%Np
237 vint(p1_,p1) = p_int1d_ori(p1_,p1) * sqrt(real(p1-1,kind=rp) + 0.5_rp)
238 end do
239 end do
240 intrpmat(:,:) = matmul(vint, this%invV)
241
242 return
243 end function lineelement_gen_intgausslegendreintrpmat
244
245end module scale_element_line
module FElib / Element / Base
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.
subroutine, public elementbase1d_init(elem, lumpedmat_flag)
Initialize an object to manage a 1D reference element.
subroutine, public elementbase1d_final(elem)
Finalize an object to manage a 1D reference element.
module FElib / Element / line
subroutine lineelement_init(elem, elemorder, lumpedmassmatflag)
Initialize an object to manage a line 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 / Polynomial.
real(rp) function, dimension(nord), public polynomial_gengausslegendreptintweight(nord)
A function to calculate the Gauss-Legendre (GL) weights.
real(rp) function, dimension(size(x), nord+1), public polynomial_gendlegendrepoly(nord, x, p)
A function to obtain differential values of Legendre polynomials which are evaluated at arbitrary poi...
real(rp) function, dimension(size(x), nord+1), public polynomial_genlegendrepoly(nord, x)
A function to obtain the values of Legendre polynomials which are evaluated at arbitrary points.
real(rp) function, dimension(nord+1), public polynomial_gengausslobattopt(nord)
A function to calculate the Legendre-Gauss-Lobatto (LGL) points.
real(rp) function, dimension(size(x), nord+1), public polynomial_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), public polynomial_gengausslegendrept(nord)
A function to calculate the Gauss-Legendre (GL) points.
real(rp) real(rp) function, dimension(n, k), public polynomial_gendlagrangepoly_lglpt(nord, x_lgl)
Differential values of Lagrange basis functions at the GLL points.
real(rp) function, dimension(nord+1), public polynomial_gengausslobattoptintweight(nord)
A function to calculate the Gauss-Lobbato weights.
Derived type representing a 1D reference element.
Derived type representing a line element.