10#include "scaleFElib.h"
20 use scale_prc,
only: prc_abort
35 integer :: polyorder_h_intrp
36 integer :: nnodeh1d_gl
37 integer :: np3d_hglvgll
39 real(rp),
allocatable :: intrpmat1d_gll2gl(:,:)
40 real(rp),
allocatable :: intrpmat1d_gll2gl_tr(:,:)
42 real(rp),
allocatable :: v1d_gl(:,:)
43 real(rp),
allocatable :: inv_v1d_gl(:,:)
44 real(rp),
allocatable :: intrpmat1d_gl2gll(:,:)
45 real(rp),
allocatable :: intrpmat1d_gl2gll_tr(:,:)
49 procedure :: final => elementoptrtensorprod3dinterp_final
50 procedure :: do_gll2gl => elementoptrtensorprod3dinterp_gll2gl
51 procedure :: do_gl2gll => elementoptrtensorprod3dinterp_gl2gll
81 integer,
intent(in) :: Polyorder_h_ip
83 real(RP) :: r_int1D_i(Polyorder_h_ip+1)
84 real(RP) :: r_int1Dw_i(Polyorder_h_ip+1)
85 real(RP) :: P_int1D_ori_h(Polyorder_h_ip+1,elem%PolyOrder_h+1)
86 real(RP) :: Vint1D(Polyorder_h_ip+1,elem%PolyOrder_h+1)
88 real(RP) :: P1D_gl_h(Polyorder_h_ip+1,Polyorder_h_ip+1)
89 real(RP) :: P1D_gll_h(elem%Nnode_h1D,Polyorder_h_ip+1)
90 real(RP) :: Vint1D_gl(elem%Nnode_h1D,Polyorder_h_ip+1)
99 this%PolyOrder_h_intrp = polyorder_h_ip
100 this%NnodeH1D_GL = polyorder_h_ip + 1
101 this%Np3D_hGLvGLL = this%NnodeH1D_GL**2 * elem%Nnode_v
104 allocate( this%IntrpMat1D_gll2gl(this%NnodeH1D_GL,elem%Nnode_h1D) )
105 allocate( this%IntrpMat1D_gll2gl_tr(elem%Nnode_h1D,this%NnodeH1D_GL) )
108 call elem1d%Init( elem%PolyOrder_h, .false. )
113 do p1_=1,this%NnodeH1D_GL
115 do p1=1, elem%Nnode_h1D
117 vint1d(n_,l_) = p_int1d_ori_h(p1_,p1) * sqrt( real(p1-1,kind=rp) + 0.5_rp )
120 this%IntrpMat1D_gll2gl(:,:) = matmul( vint1d, elem1d%invV )
121 this%IntrpMat1D_gll2gl_tr(:,:) = transpose(this%IntrpMat1D_gll2gl)
124 allocate( this%V1D_GL(this%NnodeH1D_GL,polyorder_h_ip+1) )
125 allocate( this%inv_V1D_GL(polyorder_h_ip+1,this%NnodeH1D_GL) )
126 allocate( this%IntrpMat1D_gl2gll(elem%Nnode_h1D,this%NnodeH1D_GL) )
127 allocate( this%IntrpMat1D_gl2gll_tr(this%NnodeH1D_GL,elem%Nnode_h1D) )
132 do p1_=1, this%NnodeH1D_GL
134 do p1=1, polyorder_h_ip+1
136 this%V1D_GL(n_,l_) = p1d_gl_h(p1_,p1) * sqrt( real(p1-1,kind=rp) + 0.5_rp )
141 vint1d_gl(:,:) = 0.0_rp
142 do p1_=1,this%elem%Nnode_h1D
144 do p1=1, this%NnodeH1D_GL
146 vint1d_gl(n_,l_) = p1d_gll_h(p1_,p1) * sqrt( real(p1-1,kind=rp) + 0.5_rp )
149 this%IntrpMat1D_gl2gll(:,:) = matmul( vint1d_gl, this%inv_V1D_GL )
150 this%IntrpMat1D_gl2gll_tr(:,:) = transpose(this%IntrpMat1D_gl2gll(:,:))
158 subroutine elementoptrtensorprod3dinterp_final( this )
162 deallocate( this%IntrpMat1D_gll2gl, this%IntrpMat1D_gll2gl_tr )
164 deallocate( this%V1D_GL, this%inv_V1D_GL )
165 deallocate( this%IntrpMat1D_gl2gll, this%IntrpMat1D_gl2gll_tr )
167 end subroutine elementoptrtensorprod3dinterp_final
170 subroutine elementoptrtensorprod3dinterp_gll2gl( this, q, q_intrp )
173 real(RP),
intent(in) :: q(this%Np3D)
174 real(RP),
intent(out) :: q_intrp(this%Np3D_hGLvGLL)
177 call intrp_core( q_intrp, &
178 q, this%elem%Nnode_h1D, this%NnodeH1D_GL, this%elem%Nnode_v, &
179 this%IntrpMat1D_gll2gl_tr )
181 end subroutine elementoptrtensorprod3dinterp_gll2gl
184 subroutine elementoptrtensorprod3dinterp_gl2gll( this, q, q_intrp )
187 real(RP),
intent(in) :: q(this%Np3D_hGLvGLL)
188 real(RP),
intent(out) :: q_intrp(this%Np3D)
191 call intrp_core( q_intrp, &
192 q, this%NnodeH1D_GL, this%elem%Nnode_h1D, this%elem%Nnode_v, &
193 this%IntrpMat1D_gl2gll_tr )
195 end subroutine elementoptrtensorprod3dinterp_gl2gll
199 subroutine intrp_core( q_intrp, &
200 q, Nnode_h1D, Nnode_h1D_ip, Nnode_v, IntrpMat1D_tr )
201 integer,
intent(in) :: Nnode_h1D
202 integer,
intent(in) :: Nnode_h1D_ip
203 integer,
intent(in) :: Nnode_v
204 real(RP),
intent(out) :: q_intrp(Nnode_h1D_ip,Nnode_h1D_ip,Nnode_v)
205 real(RP),
intent(in) :: q(Nnode_h1D,Nnode_h1D,Nnode_v)
206 real(RP),
intent(in) :: IntrpMat1D_tr(Nnode_h1D,Nnode_h1D_ip)
208 integer :: p1, p2, p3
211 real(RP) :: q_tmp(Nnode_h1D_ip,Nnode_h1D)
216 do p1=1, nnode_h1d_ip
219 tmp = tmp + intrpmat1d_tr(pp,p1) * q(pp,p2,p3)
225 q_intrp(:,:,p3) = 0.0_rp
226 do p2=1, nnode_h1d_ip
228 do p1=1, nnode_h1d_ip
229 q_intrp(p1,p2,p3) = q_intrp(p1,p2,p3) + intrpmat1d_tr(pp,p2) * q_tmp(p1,pp)
235 end subroutine intrp_core
module FElib / Element / Base
module FElib / Element / line
module FElib / Element / Interpolation with 3D tensor product elements
subroutine elementoptrtensorprod3dinterp_init(this, elem, polyorder_h_ip)
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_genlegendrepoly(nord, x)
A function to obtain the values of Legendre polynomials which are evaluated at arbitrary points.
real(rp) function, dimension(nord), public polynomial_gengausslegendrept(nord)
A function to calculate the Gauss-Legendre (GL) points.
Derived type representing a 3D reference element.
Derived type representing a line element.
Derived type for interpolation operation with 3D tensor product element.