34 procedure :: final => hexhedralelement_final
35 procedure :: genintgausslegendreintrpmat => hexhedralelement_gen_intgausslegendreintrpmat
42 private :: construct_element
53 elem, elemOrder_h, elemOrder_v, &
58 integer,
intent(in) :: elemOrder_h
59 integer,
intent(in) :: elemOrder_v
60 logical,
intent(in) :: LumpedMassMatFlag
64 elem%PolyOrder_h = elemorder_h
65 elem%PolyOrder_v = elemorder_v
66 elem%Nnode_h1D = elemorder_h + 1
67 elem%Nnode_v = elemorder_v + 1
72 elem%Nfaces = elem%Nfaces_h + elem%Nfaces_v
74 elem%Nfp_h = elem%Nnode_h1D*elem%Nnode_v
75 elem%Nfp_v = elem%Nnode_h1D**2
76 elem%NfpTot = elem%Nfp_h*elem%Nfaces_h + elem%Nfp_v*elem%Nfaces_v
78 elem%Np = elem%Nfp_v * elem%Nnode_v
81 call construct_element(elem)
90 subroutine hexhedralelement_final(elem)
99 end subroutine hexhedralelement_final
102 subroutine construct_element(elem)
118 integer :: nodes_ijk(elem%Nnode_h1D, elem%Nnode_h1D, elem%Nnode_v)
120 real(RP) :: lglPts1D_h(elem%Nnode_h1D)
121 real(RP) :: lglPts1D_v(elem%Nnode_v)
123 real(DP) :: intWeight_lgl1DPts_h(elem%Nnode_h1D)
124 real(DP) :: intWeight_lgl1DPts_v(elem%Nnode_v)
126 real(RP) :: P1D_ori_h(elem%Nnode_h1D, elem%Nnode_h1D)
127 real(RP) :: P1D_ori_v(elem%Nnode_v, elem%Nnode_v)
128 real(RP) :: DP1D_ori_h(elem%Nnode_h1D, elem%Nnode_h1D)
129 real(RP) :: DP1D_ori_v(elem%Nnode_v, elem%Nnode_v)
130 real(RP) :: DLagr1D_h(elem%Nnode_h1D, elem%Nnode_h1D)
131 real(RP) :: DLagr1D_v(elem%Nnode_v, elem%Nnode_v)
132 real(RP) :: V2D_h(elem%Nfp_h, elem%Nfp_h)
133 real(RP) :: V2D_v(elem%Nfp_v, elem%Nfp_v)
134 real(RP) :: Emat(elem%Np, elem%NfpTot)
135 real(RP) :: MassEdge_h(elem%Nfp_h, elem%Nfp_h)
136 real(RP) :: MassEdge_v(elem%Nfp_v, elem%Nfp_v)
139 integer :: p1, p2, p3
145 integer :: fp, fp_h1, fp_h2, fp_v
163 do j=1, elem%Nnode_h1D
164 do i=1, elem%Nnode_h1D
165 nodes_ijk(i,j,k) = i + (j-1)*elem%Nnode_h1D + (k-1)*elem%Nnode_h1D**2
172 elem%Fmask_h(:,1) = reshape(nodes_ijk(:,1,:), (/ elem%Nfp_h /))
173 elem%Fmask_h(:,2) = reshape(nodes_ijk(elem%Nnode_h1D,:,:), (/ elem%Nfp_h /))
174 elem%Fmask_h(:,3) = reshape(nodes_ijk(:,elem%Nnode_h1D,:), (/ elem%Nfp_h /))
175 elem%Fmask_h(:,4) = reshape(nodes_ijk(1,:,:), (/ elem%Nfp_h /))
177 elem%Fmask_v(:,1) = reshape(nodes_ijk(:,:,1), (/ elem%Nfp_v /))
178 elem%Fmask_v(:,2) = reshape(nodes_ijk(:,:,elem%Nnode_v), (/ elem%Nfp_v /))
184 do j=1, elem%Nnode_h1D
185 do i=1, elem%Nnode_h1D
186 n = i + (j-1)*elem%Nnode_h1D
187 elem%Colmask(:,n) = nodes_ijk(i,j,:)
195 elem%Hslice(:,k) = reshape(nodes_ijk(:,:,k), (/ elem%Nfp_v /))
202 do j=1, elem%Nnode_h1D
203 do i=1, elem%Nnode_h1D
204 n = i + (j-1)*elem%Nnode_h1D + (k-1)*elem%Nnode_h1D**2
205 elem%IndexH2Dto3D(n) = nodes_ijk(i,j,1)
213 call elem2d%Init( elem%PolyOrder_h, .false. )
216 do fp_v=1, elem%Nnode_v
217 do fp_h1=1, elem%Nnode_h1D
218 fp = fp_h1 + (fp_v-1)*elem%Nnode_h1D + (f_h-1)*elem%Nfp_h
219 elem%IndexH2Dto3D_bnd(fp) = elem2d%Fmask(fp_h1,f_h)
224 do fp_h2=1, elem%Nnode_h1D
225 do fp_h1=1, elem%Nnode_h1D
226 fp = fp_h1 + (fp_h2-1)*elem%Nnode_h1D &
227 + (f_v-1) * elem%Nfp_v &
228 + 4 * elem%Nnode_h1D * elem%Nnode_v
229 elem%IndexH2Dto3D_bnd(fp) = fp_h1 + (fp_h2-1)*elem%Nnode_h1D
240 do j=1, elem%Nnode_h1D
241 do i=1, elem%Nnode_h1D
242 n = i + (j-1)*elem%Nnode_h1D + (k-1)*elem%Nnode_h1D**2
243 elem%IndexZ1Dto3D(n) = k
251 elem%Dx1(:,:) = 0.0_rp
252 elem%Dx2(:,:) = 0.0_rp
253 elem%Dx3(:,:) = 0.0_rp
256 do j=1, elem%Nnode_h1D
257 do i=1, elem%Nnode_h1D
258 n = i + (j-1)*elem%Nnode_h1D + (k-1)*elem%Nnode_h1D**2
261 elem%x1(n) = lglpts1d_h(i)
262 elem%x2(n) = lglpts1d_h(j)
263 elem%x3(n) = lglpts1d_v(k)
266 do p3=1, elem%Nnode_v
267 do p2=1, elem%Nnode_h1D
268 do p1=1, elem%Nnode_h1D
269 l = p1 + (p2-1)*elem%Nnode_h1D + (p3-1)*elem%Nnode_h1D**2
270 elem%V(n,l) = (p1d_ori_h(i,p1)*p1d_ori_h(j,p2)*p1d_ori_v(k,p3)) &
271 * sqrt((dble(p1-1) + 0.5_dp)*(dble(p2-1) + 0.5_dp)*(dble(p3-1) + 0.5_dp))
273 if(p2==j .and. p3==k) elem%Dx1(n,l) = dlagr1d_h(p1,i)
274 if(p1==i .and. p3==k) elem%Dx2(n,l) = dlagr1d_h(p2,j)
275 if(p1==i .and. p2==j) elem%Dx3(n,l) = dlagr1d_v(p3,k)
291 do j=1, elem%Nnode_h1D
292 do i=1, elem%Nnode_h1D
293 l = i + (j-1)*elem%Nnode_h1D + (k-1)*elem%Nnode_h1D**2
294 elem%IntWeight_lgl(l) = &
295 intweight_lgl1dpts_h(i) * intweight_lgl1dpts_h(j) * intweight_lgl1dpts_v(k)
303 if (elem%IsLumpedMatrix())
then
304 elem%invM(:,:) = 0.0_rp
307 do j=1, elem%Nnode_h1D
308 do i=1, elem%Nnode_h1D
309 l = i + (j-1)*elem%Nnode_h1D + (k-1)*elem%Nnode_h1D**2
310 elem%M(l,l) = elem%IntWeight_lgl(l)
311 elem%invM(l,l) = 1.0_dp/elem%IntWeight_lgl(l)
334 do i=1, elem%Nnode_h1D
335 n = i + (k-1)*elem%Nnode_h1D
336 do p3=1, elem%Nnode_v
337 do p1=1, elem%Nnode_h1D
338 l = p1 + (p3-1)*elem%Nnode_h1D
339 v2d_h(n,l) = p1d_ori_h(i,p1)*p1d_ori_v(k,p3) &
340 * sqrt( (dble(p1-1) + 0.5_dp)*(dble(p3-1) + 0.5_dp) )
345 do j=1, elem%Nnode_h1D
346 do i=1, elem%Nnode_h1D
347 n = i + (j-1)*elem%Nnode_h1D
348 do p2=1, elem%Nnode_h1D
349 do p1=1, elem%Nnode_h1D
350 l = p1 + (p2-1)*elem%Nnode_h1D
351 v2d_v(n,l) = p1d_ori_h(i,p1)*p1d_ori_h(j,p2) &
352 * sqrt( (dble(p1-1) + 0.5_dp)*(dble(p2-1) + 0.5_dp) )
361 do f=1, elem%Nfaces_h
362 if (elem%IsLumpedMatrix())
then
363 massedge_h(:,:) = 0.0_rp
365 do i=1, elem%Nnode_h1D
366 l = i + (k-1)*elem%Nnode_h1D
367 massedge_h(l,l) = intweight_lgl1dpts_h(i) * intweight_lgl1dpts_v(k)
375 is = (f-1)*elem%Nfp_h + 1
376 ie = is + elem%Nfp_h - 1
377 emat(elem%Fmask_h(:,f), is:ie) = massedge_h
380 do f=1, elem%Nfaces_v
381 if (elem%IsLumpedMatrix())
then
382 massedge_v(:,:) = 0.0_rp
383 do j=1, elem%Nnode_h1D
384 do i=1, elem%Nnode_h1D
385 l = i + (j-1)*elem%Nnode_h1D
386 massedge_v(l,l) = intweight_lgl1dpts_h(i) * intweight_lgl1dpts_h(j)
394 is = elem%Nfaces_h*elem%Nfp_h + (f-1)*elem%Nfp_v + 1
395 ie = is + elem%Nfp_v - 1
396 emat(elem%Fmask_v(:,f), is:ie) = massedge_v
404 end subroutine construct_element
407 function hexhedralelement_gen_intgausslegendreintrpmat( this, IntrpPolyOrder, &
408 intw_intrp, x_intrp, y_intrp, z_intrp )
result(IntrpMat)
418 integer,
intent(in) :: IntrpPolyOrder
419 real(RP),
intent(out),
optional :: intw_intrp(IntrpPolyOrder**3)
420 real(RP),
intent(out),
optional :: x_intrp(IntrpPolyOrder**3)
421 real(RP),
intent(out),
optional :: y_intrp(IntrpPolyOrder**3)
422 real(RP),
intent(out),
optional :: z_intrp(IntrpPolyOrder**3)
423 real(RP) :: IntrpMat(IntrpPolyOrder**3,this%Np)
425 real(RP) :: r_int1D_i(IntrpPolyOrder)
426 real(RP) :: r_int1Dw_i(IntrpPolyOrder)
427 real(RP) :: P_int1D_ori_h(IntrpPolyOrder,this%Nnode_h1D)
428 real(RP) :: P_int1D_ori_v(IntrpPolyOrder,this%Nnode_v)
429 real(RP) :: Vint(IntrpPolyOrder**3,this%Np)
431 integer :: p1, p2, p3, p1_, p2_, p3_
432 integer :: n_, l_, m_
440 do p3_=1, intrppolyorder
441 do p2_=1, intrppolyorder
442 do p1_=1, intrppolyorder
443 n_= p1_ + (p2_-1)*intrppolyorder + (p3_-1)*intrppolyorder**2
444 if (
present(intw_intrp)) intw_intrp(n_) = r_int1dw_i(p1_) * r_int1dw_i(p2_) * r_int1dw_i(p3_)
445 if (
present(x_intrp)) x_intrp(n_) = r_int1d_i(p1_)
446 if (
present(y_intrp)) y_intrp(n_) = r_int1d_i(p2_)
447 if (
present(z_intrp)) z_intrp(n_) = r_int1d_i(p3_)
449 do p3=1, this%Nnode_v
450 do p2=1, this%Nnode_h1D
451 do p1=1, this%Nnode_h1D
452 l_ = p1 + (p2-1)*this%Nnode_h1D + (p3-1)*this%Nnode_h1D**2
453 vint(n_,l_) = p_int1d_ori_h(p1_,p1) * sqrt(dble(p1-1) + 0.5_dp) &
454 * p_int1d_ori_h(p2_,p2) * sqrt(dble(p2-1) + 0.5_dp) &
455 * p_int1d_ori_v(p3_,p3) * sqrt(dble(p3-1) + 0.5_dp)
462 intrpmat(:,:) = matmul(vint, this%invV)
465 end function hexhedralelement_gen_intgausslegendreintrpmat
module FElib / Element / Base
subroutine, public elementbase3d_init(elem, lumpedmat_flag)
Initialize an object to manage a 3D 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.
module FElib / Element / hexahedron
subroutine hexhedralelement_init(elem, elemorder_h, elemorder_v, lumpedmassmatflag)
Initialize an object to manage a hexahedral element.
module FElib / Element / Quadrilateral
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 3D reference element.
Derived type representing a hexahedral element.
Derived type representing a quadrilateral element.