FE-Project
Loading...
Searching...
No Matches
scale_element_base.F90
Go to the documentation of this file.
1!> module FElib / Element / Base
2!!
3!! @par Description
4!! A base module for finite element
5!!
6!! @author Yuta Kawai, Team SCALE
7!!
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12
13 !-----------------------------------------------------------------------------
14 !
15 !++ used modules
16 !
17 use scale_precision
18
19 !-----------------------------------------------------------------------------
20 implicit none
21 private
22 !-----------------------------------------------------------------------------
23 !
24 !++ Public type & procedure
25 !
26
27 !- Base
28
29 !> Derived type representing an arbitrary finite element
30 type, public :: elementbase
31 integer :: np !< Number of nodes within an element
32 integer :: nfaces !< Number of faces
33 integer :: nfptot !< Total number of nodes on faces
34 integer :: nv !< Number of vertices with an element
35 logical, private :: lumpedmatflag !< Flag whether the lumped mass matrix is used
36
37 real(rp), allocatable :: v(:,:) !< The Vandermonde matrix (V) whose size is Np x Np
38 real(rp), allocatable :: invv(:,:) !< Inversion of the Vandermonde matrix (V^-1) whose size is Np x Np
39 real(rp), allocatable :: m(:,:) !< Mass matrix (M) whose size is Np x Np
40 real(rp), allocatable :: invm(:,:) !< Inversion of the mass matrix (M^-1) whose size Np x NP
41 real(rp), allocatable :: lift(:,:) !< Lifting matrix with element boundary integrals whose size Np x NfpTot
42 real(rp), allocatable :: intweight_lgl(:) !< Weights of gaussian quadrature with the LGL nodes
43 contains
44 procedure :: islumpedmatrix => elementbase_islumpedmatrix
45 end type elementbase
49
50 !- 1D
51
52 !> Derived type representing a 1D reference element
53 type, public, extends(elementbase) :: elementbase1d
54 integer :: polyorder !< Polynomial order
55 integer :: nfp !< Number of nodes on an element face
56 integer, allocatable :: fmask(:,:) !< Array saving indices to extract nodal values on the faces
57
58 real(rp), allocatable :: x1(:) !< Array saving x1-coordinate of nodes within the reference element
59
60 real(rp), allocatable :: dx1(:,:) !< Elementwise differential matrix for the x1-coordinate direction (Dx1 = M^-1 Sx1)
61
62 real(rp), allocatable :: sx1(:,:) !< Elementwise stiffness matrix for the x1-coordinate direction
63 end type elementbase1d
64
65 public :: elementbase1d_init
66 public :: elementbase1d_final
67
68 !- 2D
69
70 !> Derived type representing a 2D reference element
71 type, public, extends(elementbase) :: elementbase2d
72 integer :: polyorder !< Polynomial order
73 integer :: nfp !< Number of nodes on an element face
74 integer, allocatable :: fmask(:,:) !< Array saving indices to extract nodal values on the faces
75
76 real(rp), allocatable :: x1(:) !< Array saving x1-coordinate of nodes within the reference element
77 real(rp), allocatable :: x2(:) !< Array saving x2-coordinate of nodes within the reference element
78
79 real(rp), allocatable :: dx1(:,:) !< Elementwise differential matrix for the x1-coordinate direction (Dx1 = M^-1 Sx1)
80 real(rp), allocatable :: dx2(:,:) !< Elementwise differential matrix for the x2-coordinate direction (Dx2 = M^-1 Sx2)
81
82 real(rp), allocatable :: sx1(:,:) !< Elementwise stiffness matrix for the x1-coordinate direction
83 real(rp), allocatable :: sx2(:,:) !< Elementwise stiffness matrix for the x2-coordinate direction
84 end type elementbase2d
85
86 public :: elementbase2d_init
87 public :: elementbase2d_final
88
89 interface
90 function elementbase2d_genintgausslegendreintrpmat(this, IntrpPolyOrder, &
91 intw_intrp, x_intrp, y_intrp ) result(IntrpMat)
92
93 import elementbase2d
94 import rp
95 class(elementbase2d), intent(in) :: this
96 integer, intent(in) :: intrppolyorder
97 real(rp), intent(out), optional :: intw_intrp(intrppolyorder**2)
98 real(rp), intent(out), optional :: x_intrp(intrppolyorder**2)
99 real(rp), intent(out), optional :: y_intrp(intrppolyorder**2)
100 real(rp) :: intrpmat(intrppolyorder**2,this%np)
102 end interface
103
104 !- 3D
105
106 !> Derived type representing a 3D reference element
107 type, public, extends(elementbase) :: elementbase3d
108 integer :: polyorder_h !< Polynomial order with the horizontal direction
109 integer :: nnode_h1d !< Number of nodes along the horizontal coordinate
110 integer :: nfaces_h !< Number of nodes on an horizontal face of the reference element
111 integer :: nfp_h !< Number of horizontal faces of the reference element
112 integer, allocatable :: fmask_h(:,:) !< Array saving indices to extract nodal values on the horizontal faces
113
114 integer :: polyorder_v !< Polynomial order with the vertical direction
115 integer :: nnode_v !< Number of nodes along the vertical coordinate
116 integer :: nfaces_v !< Number of nodes on an vertical face of the reference element
117 integer :: nfp_v !< Number of vertical faces of the reference element
118 integer, allocatable :: fmask_v(:,:) !< Number of vertical faces of the reference element
119
120 integer, allocatable :: colmask(:,:) !< Array saving indices to extract nodal values on the vertical columns
121 integer, allocatable :: hslice(:,:) !< Array saving indices to extract nodal values on the horizontal plane
122 integer, allocatable :: indexh2dto3d(:) !< Array saving indices to expand 2D horizontal nodal values into the 3D nodal values
123 integer, allocatable :: indexh2dto3d_bnd(:) !< Array saving indices to expand 2D horizontal nodal values into the 3D nodal values on element faces
124 integer, allocatable :: indexz1dto3d(:) !< Array saving indices to expand 1D vertical nodal values into the 3D nodal values
125
126 real(rp), allocatable :: x1(:) !< Array saving x1-coordinate of nodes within the reference element
127 real(rp), allocatable :: x2(:) !< Array saving x2-coordinate of nodes within the reference element
128 real(rp), allocatable :: x3(:) !< Array saving x3-coordinate of nodes within the reference element
129
130 real(rp), allocatable :: dx1(:,:) !< Elementwise differential matrix for the x1-coordinate direction (Dx1 = M^-1 Sx1)
131 real(rp), allocatable :: dx2(:,:) !< Elementwise differential matrix for the x2-coordinate direction (Dx2 = M^-1 Sx2)
132 real(rp), allocatable :: dx3(:,:) !< Elementwise differential matrix for the x3-coordinate direction (Dx3 = M^-1 Sx3)
133
134 real(rp), allocatable :: sx1(:,:) !< Elementwise stiffness matrix for the x1-coordinate direction
135 real(rp), allocatable :: sx2(:,:) !< Elementwise stiffness matrix for the x2-coordinate direction
136 real(rp), allocatable :: sx3(:,:) !< Elementwise stiffness matrix for the x3-coordinate direction
137 end type elementbase3d
138
139 public :: elementbase3d_init
140 public :: elementbase3d_final
141
142 !-----------------------------------------------------------------------------
143 !
144 !++ Private type & procedure
145 !
146
147 private :: elementbase_init
148 private :: elementbase_final
149
150contains
151 !-- Base Element ------------------------------------------------------------------------------
152
153!> Initialize a base object to manage a reference element
154!OCL SERIAL
155 subroutine elementbase_init( elem, lumpedmat_flag )
156 implicit none
157
158 class(elementbase), intent(inout) :: elem
159 logical, intent(in) :: lumpedmat_flag
160 !-----------------------------------------------------------------------------
161
162 allocate( elem%M(elem%Np, elem%Np) )
163 allocate( elem%invM(elem%Np, elem%Np) )
164 allocate( elem%V(elem%Np, elem%Np) )
165 allocate( elem%invV(elem%Np, elem%Np) )
166 allocate( elem%Lift(elem%Np, elem%NfpTot) )
167
168 allocate( elem%IntWeight_lgl(elem%Np) )
169
170 elem%LumpedMatFlag = lumpedmat_flag
171
172 return
173 end subroutine elementbase_init
174
175!> Finalize a base object to manage a reference element
176!OCL SERIAL
177 subroutine elementbase_final( elem )
178 implicit none
179
180 class(elementbase), intent(inout) :: elem
181 !-----------------------------------------------------------------------------
182
183 if ( allocated(elem%M) ) then
184 deallocate( elem%M )
185 deallocate( elem%invM )
186 deallocate( elem%V )
187 deallocate( elem%invV )
188 deallocate( elem%Lift )
189 deallocate( elem%IntWeight_lgl )
190 end if
191
192 return
193 end subroutine elementbase_final
194
195!> Get a flag whether the lumped mass matrix is used
196!OCL SERIAL
197 function elementbase_islumpedmatrix( elem ) result(lumpedmat_flag)
198 implicit none
199 class(elementbase), intent(in) :: elem
200 logical :: lumpedmat_flag
201 !---------------------------------------------
202
203 lumpedmat_flag = elem%LumpedMatFlag
204 return
205 end function elementbase_islumpedmatrix
206
207
208!> Construct mass matrix
209!! M^-1 = V V^T
210!! M = ( M^-1 )^-1
211!OCL SERIAL
212 subroutine elementbase_construct_massmat( V, Np, &
213 MassMat, invMassMat )
215 implicit none
216 integer, intent(in) :: np
217 real(rp), intent(in) :: v(np,np)
218 real(rp), intent(out) :: massmat(np,np)
219 real(rp), intent(out), optional :: invmassmat(np,np)
220
221 real(rp) :: tmpmat(np,np)
222 real(rp) :: invm(np,np)
223 !------------------------------------
224
225 tmpmat(:,:) = transpose(v)
226 invm(:,:) = matmul( v, tmpmat )
227 massmat(:,:) = linalgebra_inv( invm )
228
229 if ( present(invmassmat) ) invmassmat(:,:) = invm(:,:)
230 return
231 end subroutine elementbase_construct_massmat
232
233!> Construct stiffness matrix
234!! StiffMat_i = M^-1 ( M D_xi )^T
235!OCL SERIAL
236 subroutine elementbase_construct_stiffmat( MassMat, invMassMat, DMat, Np, &
237 StiffMat )
238 implicit none
239 integer, intent(in) :: np
240 real(rp), intent(in) :: massmat(np,np)
241 real(rp), intent(in) :: invmassmat(np,np)
242 real(rp), intent(in) :: dmat(np,np)
243 real(rp), intent(out) :: stiffmat(np,np)
244
245 real(rp) :: tmpmat1(np,np)
246 real(rp) :: tmpmat2(np,np)
247 !------------------------------------
248
249 tmpmat1(:,:) = matmul( massmat, dmat )
250 tmpmat2(:,:) = transpose( tmpmat1 )
251 stiffmat(:,:) = matmul( invmassmat, tmpmat2 )
252
253 return
254 end subroutine elementbase_construct_stiffmat
255
256!> Construct stiffness matrix
257!! StiffMat_i = M^-1 ( M D_xi )^T
258!OCL SERIAL
259 subroutine elementbase_construct_liftmat( invM, EMat, Np, NfpTot, &
260 LiftMat )
261 implicit none
262 integer, intent(in) :: np
263 integer, intent(in) :: nfptot
264 real(rp), intent(in) :: invm(np,np)
265 real(rp), intent(in) :: emat(np,nfptot)
266 real(rp), intent(out) :: liftmat(np,nfptot)
267 !------------------------------------
268
269 liftmat(:,:) = matmul( invm, emat )
270 return
271 end subroutine elementbase_construct_liftmat
272
273 !-- 1D Element ------------------------------------------------------------------------------
274
275!> Initialize an object to manage a 1D reference element
276!!
277!! @param elem Object of finite element
278!! @param elem Flag whether mass lumping is considered
279!OCL SERIAL
280 subroutine elementbase1d_init( elem, lumpedmat_flag )
281 implicit none
282
283 class(elementbase1d), intent(inout) :: elem
284 logical, intent(in) :: lumpedmat_flag
285 !-----------------------------------------------------------------------------
286
287 call elementbase_init( elem, lumpedmat_flag )
288
289 allocate( elem%x1(elem%Np) )
290 allocate( elem%Fmask(elem%Nfp, elem%Nfaces) )
291
292 allocate( elem%Dx1(elem%Np, elem%Np) )
293 allocate( elem%Sx1(elem%Np, elem%Np) )
294
295 return
296 end subroutine elementbase1d_init
297
298!> Finalize an object to manage a 1D reference element
299!OCL SERIAL
300 subroutine elementbase1d_final( elem )
301 implicit none
302
303 class(elementbase1d), intent(inout) :: elem
304 !-----------------------------------------------------------------------------
305
306 if ( allocated( elem%x1 ) ) then
307 deallocate( elem%x1 )
308 deallocate( elem%Dx1 )
309 deallocate( elem%Sx1 )
310 deallocate( elem%Fmask )
311 end if
312
313 call elementbase_final( elem )
314
315 return
316 end subroutine elementbase1d_final
317
318 !-- 2D Element ------------------------------------------------------------------------------
319
320!> Initialize an object to manage a 2D reference element
321!!
322!! @param elem Object of finite element
323!! @param elem Flag whether mass lumping is considered
324!OCL SERIAL
325 subroutine elementbase2d_init( elem, lumpedmat_flag )
326 implicit none
327
328 class(elementbase2d), intent(inout) :: elem
329 logical, intent(in) :: lumpedmat_flag
330 !-----------------------------------------------------------------------------
331
332 call elementbase_init( elem, lumpedmat_flag )
333
334 allocate( elem%x1(elem%Np), elem%x2(elem%Np) )
335 allocate( elem%Fmask(elem%Nfp, elem%Nfaces) )
336
337 allocate( elem%Dx1(elem%Np, elem%Np), elem%Dx2(elem%Np, elem%Np) )
338 allocate( elem%Sx1(elem%Np, elem%Np), elem%Sx2(elem%Np, elem%Np) )
339
340 return
341 end subroutine elementbase2d_init
342
343!> Finalize an object to manage a 2D reference element
344!OCL SERIAL
345 subroutine elementbase2d_final( elem )
346 implicit none
347
348 class(elementbase2d), intent(inout) :: elem
349 !-----------------------------------------------------------------------------
350
351 if ( allocated( elem%x1 ) ) then
352 deallocate( elem%x1, elem%x2 )
353 deallocate( elem%Fmask )
354
355 deallocate( elem%Dx1, elem%Dx2 )
356 deallocate( elem%Sx1, elem%Sx2 )
357 end if
358
359 call elementbase_final( elem )
360
361 return
362 end subroutine elementbase2d_final
363
364 !-- 3D Element ------------------------------------------------------------------------------
365
366!> Initialize an object to manage a 3D reference element
367!!
368!! @param elem Object of finite element
369!! @param elem Flag whether mass lumping is considered
370!OCL SERIAL
371 subroutine elementbase3d_init( elem, lumpedmat_flag )
372 implicit none
373
374 class(elementbase3d), intent(inout) :: elem
375 logical, intent(in) :: lumpedmat_flag
376 !-----------------------------------------------------------------------------
377
378 call elementbase_init( elem, lumpedmat_flag )
379
380 allocate( elem%x1(elem%Np), elem%x2(elem%Np), elem%x3(elem%Np) )
381 allocate( elem%Dx1(elem%Np, elem%Np), elem%Dx2(elem%Np, elem%Np), elem%Dx3(elem%Np, elem%Np) )
382 allocate( elem%Sx1(elem%Np, elem%Np), elem%Sx2(elem%Np, elem%Np), elem%Sx3(elem%Np, elem%Np) )
383 allocate( elem%Fmask_h(elem%Nfp_h, elem%Nfaces_h), elem%Fmask_v(elem%Nfp_v, elem%Nfaces_v) )
384 allocate( elem%Colmask(elem%Nnode_v,elem%Nfp_v))
385 allocate( elem%Hslice(elem%Nfp_v,elem%Nnode_v) )
386 allocate( elem%IndexH2Dto3D(elem%Np) )
387 allocate( elem%IndexH2Dto3D_bnd(elem%NfpTot) )
388 allocate( elem%IndexZ1Dto3D(elem%Np) )
389
390 return
391 end subroutine elementbase3d_init
392
393!> Finalize an object to manage a 3D reference element
394!OCL SERIAL
395 subroutine elementbase3d_final( elem )
396 implicit none
397
398 class(elementbase3d), intent(inout) :: elem
399 !-----------------------------------------------------------------------------
400
401 if ( allocated( elem%x1 ) ) then
402 deallocate( elem%x1, elem%x2, elem%x3 )
403 deallocate( elem%Dx1, elem%Dx2, elem%Dx3 )
404 deallocate( elem%Sx1, elem%Sx2, elem%Sx3 )
405 deallocate( elem%Fmask_h, elem%Fmask_v )
406 deallocate( elem%Colmask, elem%Hslice )
407 deallocate( elem%IndexH2Dto3D, elem%IndexH2Dto3D_bnd )
408 deallocate( elem%IndexZ1Dto3D )
409 end if
410
411 call elementbase_final( elem )
412
413 return
414 end subroutine elementbase3d_final
415
416end module scale_element_base
module FElib / Element / Base
subroutine, public elementbase2d_final(elem)
Finalize an object to manage a 2D reference element.
subroutine, public elementbase3d_init(elem, lumpedmat_flag)
Initialize an object to manage a 3D 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.
subroutine, public elementbase3d_final(elem)
Finalize an object to manage a 3D reference element.
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 common / Linear algebra.
real(rp) function, dimension(size(a, 1), size(a, 2)), public linalgebra_inv(a)
Calculate a inversion of matrix A.
Derived type representing a 1D reference element.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing an arbitrary finite element.