FE-Project
Loading...
Searching...
No Matches
scale_element_operation_tensorprod3D_interp.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Element / Interpolation with 3D tensor product elements
3!!
4!! @par Description
5!! A module for providing interpolation operations assuming a 3D tensor product element with (p+1)^3 DOF
6!!
7!! @author Yuta Kawai, Xuanzhengbo Ren, and Team SCALE
8!!
9!<
10#include "scaleFElib.h"
12
13 !-----------------------------------------------------------------------------
14 !
15 !++ used modules
16 !
17 use scale_precision
18 use scale_io
19 use scale_prof
20 use scale_prc, only: prc_abort
21
23
24 !-----------------------------------------------------------------------------
25 implicit none
26 private
27 !-----------------------------------------------------------------------------
28 !
29 !++ Public type & procedure
30 !
31
32 !> Derived type for interpolation operation with 3D tensor product element
34 class(elementbase3d), pointer :: elem
35 integer :: polyorder_h_intrp
36 integer :: nnodeh1d_gl
37 integer :: np3d_hglvgll
38 integer :: np3d
39 real(rp), allocatable :: intrpmat1d_gll2gl(:,:)
40 real(rp), allocatable :: intrpmat1d_gll2gl_tr(:,:)
41
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(:,:)
46
47 contains
49 procedure :: final => elementoptrtensorprod3dinterp_final
50 procedure :: do_gll2gl => elementoptrtensorprod3dinterp_gll2gl
51 procedure :: do_gl2gll => elementoptrtensorprod3dinterp_gl2gll
53
54 !-----------------------------------------------------------------------------
55 !
56 !++ Public parameters & variables
57 !
58 !-----------------------------------------------------------------------------
59 !
60 !++ Private procedure
61 !
62 !-----------------------------------------------------------------------------
63 !
64 !++ Private parameters & variables
65 !
66 private :: intrp_core
67
68contains
69!OCL SERIAL
70 subroutine elementoptrtensorprod3dinterp_init( this, elem, PolyOrder_h_ip )
72 use scale_polynomial, only: &
77 use scale_prc
78 implicit none
79 class(elementoptrtensorprod3dinterp), intent(inout) :: this
80 type(elementbase3d), intent(in), target :: elem
81 integer, intent(in) :: Polyorder_h_ip
82
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)
87
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)
91
92 integer :: p1, p1_
93 integer :: n_, l_
94
95 type(lineelement) :: elem1D
96 !----------------------------------------
97
98 this%elem => elem
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
102 this%Np3D = elem%Np
103
104 allocate( this%IntrpMat1D_gll2gl(this%NnodeH1D_GL,elem%Nnode_h1D) )
105 allocate( this%IntrpMat1D_gll2gl_tr(elem%Nnode_h1D,this%NnodeH1D_GL) )
106
107 !-
108 call elem1d%Init( elem%PolyOrder_h, .false. )
109 r_int1d_i(:) = polynomial_gengausslegendrept( this%NnodeH1D_GL )
110 r_int1dw_i(:) = polynomial_gengausslegendreptintweight(this%NnodeH1D_GL )
111 p_int1d_ori_h(:,:) = polynomial_genlegendrepoly( elem%PolyOrder_h, r_int1d_i )
112
113 do p1_=1,this%NnodeH1D_GL
114 n_ = p1_
115 do p1=1, elem%Nnode_h1D
116 l_ = p1
117 vint1d(n_,l_) = p_int1d_ori_h(p1_,p1) * sqrt( real(p1-1,kind=rp) + 0.5_rp )
118 end do
119 end do
120 this%IntrpMat1D_gll2gl(:,:) = matmul( vint1d, elem1d%invV )
121 this%IntrpMat1D_gll2gl_tr(:,:) = transpose(this%IntrpMat1D_gll2gl)
122
123 !-
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) )
128
129 p1d_gl_h(:,:) = polynomial_genlegendrepoly( polyorder_h_ip, r_int1d_i )
130 p1d_gll_h(:,:) = polynomial_genlegendrepoly( polyorder_h_ip, elem1d%x1 )
131
132 do p1_=1, this%NnodeH1D_GL
133 n_ = p1_
134 do p1=1, polyorder_h_ip+1
135 l_ = p1
136 this%V1D_GL(n_,l_) = p1d_gl_h(p1_,p1) * sqrt( real(p1-1,kind=rp) + 0.5_rp )
137 end do
138 end do
139 this%inv_V1D_GL(:,:) = linalgebra_inv( this%V1D_GL(:,:) )
140
141 vint1d_gl(:,:) = 0.0_rp
142 do p1_=1,this%elem%Nnode_h1D
143 n_ = p1_
144 do p1=1, this%NnodeH1D_GL
145 l_ = p1
146 vint1d_gl(n_,l_) = p1d_gll_h(p1_,p1) * sqrt( real(p1-1,kind=rp) + 0.5_rp )
147 end do
148 end do
149 this%IntrpMat1D_gl2gll(:,:) = matmul( vint1d_gl, this%inv_V1D_GL )
150 this%IntrpMat1D_gl2gll_tr(:,:) = transpose(this%IntrpMat1D_gl2gll(:,:))
151
152 !-
153 call elem1d%Final()
154 return
156
157!OCL SERIAL
158 subroutine elementoptrtensorprod3dinterp_final( this )
159 implicit none
160 class(elementoptrtensorprod3dinterp), intent(inout) :: this
161 !----------------------------------------
162 deallocate( this%IntrpMat1D_gll2gl, this%IntrpMat1D_gll2gl_tr )
163
164 deallocate( this%V1D_GL, this%inv_V1D_GL )
165 deallocate( this%IntrpMat1D_gl2gll, this%IntrpMat1D_gl2gll_tr )
166 return
167 end subroutine elementoptrtensorprod3dinterp_final
168
169!OCL SERIAL
170 subroutine elementoptrtensorprod3dinterp_gll2gl( this, q, q_intrp )
171 implicit none
172 class(elementoptrtensorprod3dinterp), intent(in) :: this
173 real(RP), intent(in) :: q(this%Np3D)
174 real(RP), intent(out) :: q_intrp(this%Np3D_hGLvGLL)
175 !----------------------------------------
176
177 call intrp_core( q_intrp, &
178 q, this%elem%Nnode_h1D, this%NnodeH1D_GL, this%elem%Nnode_v, &
179 this%IntrpMat1D_gll2gl_tr )
180 return
181 end subroutine elementoptrtensorprod3dinterp_gll2gl
182
183!OCL SERIAL
184 subroutine elementoptrtensorprod3dinterp_gl2gll( this, q, q_intrp )
185 implicit none
186 class(elementoptrtensorprod3dinterp), intent(in) :: this
187 real(RP), intent(in) :: q(this%Np3D_hGLvGLL)
188 real(RP), intent(out) :: q_intrp(this%Np3D)
189 !----------------------------------------
190
191 call intrp_core( q_intrp, &
192 q, this%NnodeH1D_GL, this%elem%Nnode_h1D, this%elem%Nnode_v, &
193 this%IntrpMat1D_gl2gll_tr )
194 return
195 end subroutine elementoptrtensorprod3dinterp_gl2gll
196
197!---------
198!OCL SERIAL
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)
207
208 integer :: p1, p2, p3
209 integer :: pp
210 real(RP) :: tmp
211 real(RP) :: q_tmp(Nnode_h1D_ip,Nnode_h1D)
212 !--------------------------------
213
214 do p3=1, nnode_v
215 do p2=1, nnode_h1d
216 do p1=1, nnode_h1d_ip
217 tmp = 0.0_rp
218 do pp=1, nnode_h1d
219 tmp = tmp + intrpmat1d_tr(pp,p1) * q(pp,p2,p3)
220 end do
221 q_tmp(p1,p2)= tmp
222 end do
223 end do
224
225 q_intrp(:,:,p3) = 0.0_rp
226 do p2=1, nnode_h1d_ip
227 do pp=1, nnode_h1d
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)
230 end do
231 end do
232 end do
233 end do
234 return
235 end subroutine intrp_core
236
module FElib / Element / Base
module FElib / Element / line
module FElib / Element / Interpolation with 3D tensor product elements
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.