16 use scale_const,
only: &
18 use scale_prc,
only: &
48 integer :: eval_type_id
52 real(rp),
allocatable :: fftintrpmat(:,:)
53 real(rp),
allocatable :: fft_xi(:)
54 integer :: nsampleptperelem
56 real(rp),
allocatable :: intintrpmat(:,:)
57 real(rp),
allocatable :: intweight(:)
58 real(rp),
allocatable :: intxi(:)
67 real(rp) :: xmin_gl, xmax_gl
70 real(rp),
allocatable :: k(:)
71 real(rp),
allocatable :: spectral_coef(:,:,:)
75 procedure :: init => meshfield_spetraltransform1d_init
76 procedure :: final => meshfield_spetraltransform1d_final
77 procedure :: transform => meshfield_spetraltransform1d_transform
87 real(rp) :: xmin_gl, xmax_gl
89 real(rp) :: ymin_gl, ymax_gl
96 integer :: nsampleptperelem1d
98 real(rp),
allocatable :: k(:)
99 real(rp),
allocatable :: l(:)
100 real(rp),
allocatable :: spectral_coef(:,:,:,:)
105 procedure :: init => meshfield_spetraltransform2d_init
106 procedure :: final => meshfield_spetraltransform2d_final
107 procedure :: transform => meshfield_spetraltransform2d_transform
133 subroutine meshfield_spetraltransformbase_init( this, eval_type, ndim, var_num, NintGLpt, NsamplePtPerElem )
136 integer,
intent(in) :: eval_type
137 integer,
intent(in) :: ndim
138 integer,
intent(in) :: var_num
139 integer,
intent(in),
optional :: nintglpt
140 integer,
intent(in),
optional :: nsampleptperelem
143 this%eval_type_id = eval_type
144 call check_eval_type_id( eval_type )
147 this%var_num = var_num
151 if ( .not.
present(nintglpt) )
then
152 log_info(
"MeshField_SpetralTransformBase_Init",*)
"The order of Gaussian quadrature should be given. Check!"
155 this%NintGLPt = nintglpt
161 if ( .not.
present(nsampleptperelem) )
then
162 log_info(
"MeshField_SpetralTransformBase_Init",*)
"NsamplePtPerElem shouled be given. Check!"
164 this%NsamplePtPerElem = nsampleptperelem
167 this%NsamplePtPerElem = -1
169 log_info(
"MeshField_SpetralTransformBase_Init",*)
"NintGLPt=", this%NintGLpt,
"NsamplePtPerElem=", this%NsamplePtPerElem
172 end subroutine meshfield_spetraltransformbase_init
174 subroutine check_eval_type_id( eval_type )
176 integer,
intent(in) :: eval_type
178 select case(eval_type)
182 log_info(
"MeshField_SpetralTransformBase_Init",*)
"Unsupported evaluation type is specified. Check!"
186 end subroutine check_eval_type_id
189 subroutine meshfield_spetraltransformbase_final( this )
194 if ( this%NintGLpt > 0 ) &
195 deallocate( this%IntIntrpMat, this%IntXi, this%IntWeight )
197 if ( this%NsamplePtPerElem > 0 ) &
198 deallocate( this%FFTIntrpMat, this%FFT_xi )
201 end subroutine meshfield_spetraltransformbase_final
206 subroutine meshfield_spetraltransform1d_init( this, eval_type, ks, ke, mesh1D, var_num, &
207 GLQuadOrd, NsamplePtPerElem )
210 integer,
intent(in) :: eval_type
211 integer,
intent(in) :: ks, ke
212 class(
meshbase1d),
intent(in),
target :: mesh1d
213 integer,
intent(in) :: var_num
214 integer,
optional :: glquadord
215 integer,
optional :: nsampleptperelem
227 lmesh => mesh1d%lcmesh_list(1)
228 elem => lmesh%refElem1D
230 call meshfield_spetraltransformbase_init( this, eval_type, 1, var_num, &
231 glquadord, nsampleptperelem )
233 this%ks = ks; this%ke = ke
234 this%kall = ke - ks + 1
236 this%xmin_gl = mesh1d%xmin_gl
237 this%xmax_gl = mesh1d%xmax_gl
238 this%delx = 1.0_rp / real(mesh1d%NeG,kind=rp)
240 allocate( this%k(ks:ke) )
241 lx = this%xmax_gl - this%xmin_gl
243 this%k(i) = i * 2.0_rp * pi / lx
246 allocate( this%spectral_coef(ks:ke,2,var_num) )
248 call elem_dummy%Init(elem%PolyOrder, .false.)
250 if ( this%NintGLpt > 0 )
then
251 allocate( this%IntIntrpMat(this%NintGLpt,elem%Np) )
252 allocate( this%IntXi(this%NintGLpt), this%IntWeight(this%NintGLpt) )
254 this%IntIntrpMat(:,:) = elem_dummy%GenIntGaussLegendreIntrpMat( glquadord, this%IntWeight, this%IntXi )
257 if ( this%NsamplePtPerElem > 0 )
then
258 allocate( this%FFTIntrpMat(this%NsamplePtPerElem,elem%Np) )
259 allocate( this%FFT_Xi(this%NsamplePtPerElem) )
261 dx = 2.0_rp / real(this%NsamplePtPerElem,kind=rp)
262 do i=1, this%NsamplePtPerElem
263 this%FFT_Xi(i) = -1.0_rp + real(i - 0.5_rp,kind=rp) * dx
267 call this%fft%Init( nsampleptperelem * mesh1d%NeG )
270 call elem_dummy%Final()
273 end subroutine meshfield_spetraltransform1d_init
276 subroutine meshfield_spetraltransform1d_final( this )
281 call meshfield_spetraltransformbase_final( this )
283 if ( this%NsamplePtPerElem > 0 )
then
284 call this%fft%Final()
287 deallocate( this%k, this%spectral_coef )
290 end subroutine meshfield_spetraltransform1d_final
293 subroutine meshfield_spetraltransform1d_transform( this, q_list, mesh_num )
296 integer,
intent(in) :: mesh_num
303 mesh1d => q_list(1,1)%ptr%mesh
304 lmesh => mesh1d%lcmesh_list(1)
306 select case( this%eval_type_id )
308 call spectral_transform1d_dft( this%spectral_coef, &
309 q_list, this%var_num, mesh_num, &
310 this%ks, this%ke, lmesh%refElem1D%Np, lmesh%Ne, this%NsamplePtPerElem, &
311 this%fft, this%FFTIntrpMat, this%FFT_xi, &
312 this%xmin_gl, this%delx, this%xmax_gl - this%xmin_gl )
314 call spectral_transform1d_l2projection( this%spectral_coef, &
315 q_list, this%var_num, mesh_num, &
316 this%ks, this%ke, lmesh%refElem1D%Np, lmesh%Ne, &
317 this%IntIntrpMat, this%IntXi, this%IntWeight, this%NintGLPt, &
318 this%xmin_gl, this%delx, this%xmax_gl - this%xmin_gl )
322 end subroutine meshfield_spetraltransform1d_transform
327 subroutine meshfield_spetraltransform2d_init( this, eval_type, ks, ke, ls, le, mesh2D, var_num, &
328 GLQuadOrd, NsamplePtPerElem1D )
335 integer,
intent(in) :: eval_type
336 integer,
intent(in) :: ks, ke
337 integer,
intent(in) :: ls, le
338 class(
meshbase2d),
intent(in),
target :: mesh2d
339 integer,
intent(in) :: var_num
340 integer,
optional :: glquadord
341 integer,
optional :: nsampleptperelem1d
354 lmesh => mesh2d%lcmesh_list(1)
355 elem => lmesh%refElem2D
357 call meshfield_spetraltransformbase_init( this, eval_type, 1, var_num, glquadord, nsampleptperelem1d )
359 this%ks = ks; this%ke = ke
360 this%kall = ke - ks + 1
362 this%ls = ls; this%le = le
363 this%lall = le - ls + 1
365 select type(ptr_mesh2d => mesh2d)
367 this%xmin_gl = ptr_mesh2d%xmin_gl
368 this%xmax_gl = ptr_mesh2d%xmax_gl
369 this%delx = ( this%xmax_gl - this%xmin_gl ) / real(ptr_mesh2d%NeGX, kind=rp)
371 this%ymin_gl = ptr_mesh2d%ymin_gl
372 this%ymax_gl = ptr_mesh2d%ymax_gl
373 this%dely = ( this%ymax_gl - this%ymin_gl ) / real(ptr_mesh2d%NeGY, kind=rp)
375 this%NeGX = ptr_mesh2d%NeGX
376 this%NeGY = ptr_mesh2d%NeGY
377 this%NprcX = ptr_mesh2d%NprcX
378 this%NprcY = ptr_mesh2d%NprcY
380 log_info(
'MeshField_SpetralTransform2D_Init',*)
'Unexpected mesh type is given. Check!'
384 allocate( this%k(ks:ke) )
385 lx = this%xmax_gl - this%xmin_gl
387 this%k(i) = i * 2.0_rp * pi / lx
390 allocate( this%l(ls:le) )
391 ly = this%ymax_gl - this%ymin_gl
393 this%l(j) = j * 2.0_rp * pi / ly
396 allocate( this%spectral_coef(ks:ke,ls:le,2,var_num) )
398 call elem_dummy%Init(elem%PolyOrder, .false.)
400 if ( this%NintGLpt > 0 )
then
401 allocate( this%IntIntrpMat(this%NintGLpt,elem%Nfp) )
402 allocate( this%IntXi(this%NintGLpt), this%IntWeight(this%NintGLpt) )
404 this%IntIntrpMat(:,:) = elem_dummy%GenIntGaussLegendreIntrpMat( glquadord, this%IntWeight, this%IntXi )
407 if ( this%NsamplePtPerElem > 0 )
then
408 this%NsamplePtPerElem1D = nsampleptperelem1d
409 allocate( this%FFTIntrpMat(this%NsamplePtPerElem1D,elem%Nfp) )
410 allocate( this%FFT_Xi(this%NsamplePtPerElem1D) )
412 dx = 2.0_rp / real(this%NsamplePtPerElem1D,kind=rp)
413 do i=1, this%NsamplePtPerElem1D
414 this%FFT_Xi(i) = -1.0_rp + real(i - 0.5_rp,kind=rp) * dx
418 call this%fft_x%Init( this%NsamplePtPerElem1D * this%NeGX )
419 call this%fft_y%Init( this%NsamplePtPerElem1D * this%NeGY )
422 call elem_dummy%Final()
424 end subroutine meshfield_spetraltransform2d_init
427 subroutine meshfield_spetraltransform2d_final( this )
432 call meshfield_spetraltransformbase_final( this )
434 if ( this%NsamplePtPerElem > 0 )
then
435 call this%fft_x%Final()
436 call this%fft_y%Final()
439 deallocate( this%k, this%l, this%spectral_coef )
441 end subroutine meshfield_spetraltransform2d_final
444 subroutine meshfield_spetraltransform2d_transform( this, q_list, mesh_num_x, mesh_num_y )
447 integer,
intent(in) :: mesh_num_x, mesh_num_y
448 type(
meshfield2dlist),
target :: q_list(this%var_num,mesh_num_x,mesh_num_y)
454 mesh2d => q_list(1,1,1)%ptr%mesh
455 lmesh => mesh2d%lcmesh_list(1)
457 select case( this%eval_type_id )
459 call spectral_transform2d_dft( this%spectral_coef, &
460 q_list, this%var_num, mesh_num_x, mesh_num_y, &
461 this%ks, this%ke, this%ls, this%le, lmesh%refElem2D%Nfp, lmesh%NeX, lmesh%NeY, &
462 this%NeGY, this%NprcY, this%NsamplePtPerElem1D, &
463 this%fft_x, this%fft_y, this%FFTIntrpMat )
465 call spectral_transform2d_l2projection( this%spectral_coef, &
466 q_list, this%var_num, mesh_num_x*mesh_num_y, &
467 this%ks, this%ke, this%ls, this%le, lmesh%refElem2D%Nfp, lmesh%NeX, lmesh%NeY, &
468 this%IntIntrpMat, this%IntXi, this%IntWeight, this%NintGLPt, &
469 this%xmin_gl, this%delx, this%xmax_gl - this%xmin_gl, &
470 this%ymin_gl, this%dely, this%ymax_gl - this%ymin_gl )
474 end subroutine meshfield_spetraltransform2d_transform
479 subroutine spectral_transform1d_dft( spectral_coef, &
480 q_list, var_num, mesh_num, ks, ke, Np, Ne, NsamplePerElem, &
481 fft, FFTIntrpMat, FFT_xi, &
485 use scale_prc,
only: &
488 integer,
intent(in) :: ks, ke
489 integer,
intent(in) :: np
490 integer,
intent(in) :: ne
491 integer,
intent(in) :: nsampleperelem
492 integer,
intent(in) :: var_num
493 integer,
intent(in) :: mesh_num
494 real(rp),
intent(out) :: spectral_coef(ks:ke,2,var_num)
497 real(rp),
intent(in) :: fftintrpmat(nsampleperelem,np)
498 real(rp),
intent(in) :: fft_xi(nsampleperelem)
499 real(rp),
intent(in) :: xmin_gl
500 real(rp),
intent(in) :: delx
501 real(rp),
intent(in) :: lx
503 real(rp) :: g_q(nsampleperelem,ne,mesh_num,var_num)
504 real(rp) :: q_tmp(np)
505 complex(RP) :: s_q(nsampleperelem*ne*mesh_num,var_num)
514 real(rp) :: x_(nsampleperelem)
521 q_tmp(:) = q_list(v,m)%ptr%local(1)%val(:,kel)
522 g_q(:,kel,m,v) = matmul( fftintrpmat, q_tmp )
529 call fft%Forward_real( g_q(:,:,:,v), s_q(:,v) )
532 nall = nsampleperelem * ne * mesh_num
536 spectral_coef(kk-1,1,v) = real(s_q(kk,v))
537 spectral_coef(kk-1,2,v) = aimag(s_q(kk,v))
540 spectral_coef(kk-1-nall,1,v) = real(s_q(kk,v))
541 spectral_coef(kk-1-nall,2,v) = aimag(s_q(kk,v))
545 end subroutine spectral_transform1d_dft
548 subroutine spectral_transform1d_l2projection( spectral_coef, &
549 q_list, var_num, mesh_num, ks, ke, Np, Ne, IntIntrpMat, IntXi, IntWeight, NintGLPt, &
553 use scale_prc,
only: &
556 integer,
intent(in) :: ks, ke
557 integer,
intent(in) :: np
558 integer,
intent(in) :: ne
559 integer,
intent(in) :: var_num
560 integer,
intent(in) :: mesh_num
562 real(rp),
intent(out) :: spectral_coef(ks:ke,2,var_num)
563 integer,
intent(in) :: nintglpt
564 real(rp),
intent(in) :: intintrpmat(nintglpt,np)
565 real(rp),
intent(in) :: intxi(nintglpt)
566 real(rp),
intent(in) :: intweight(nintglpt)
567 real(rp),
intent(in) :: xmin_gl
568 real(rp),
intent(in) :: delx
569 real(rp),
intent(in) :: lx
571 real(rp),
allocatable :: s_coef_lc(:,:,:)
572 real(rp),
allocatable :: s_coef(:,:,:)
573 real(rp),
allocatable :: q_tmp(:,:,:)
591 allocate( s_coef_lc(vec_size,2,0:km) )
592 allocate( s_coef(vec_size,2,0:km) )
595 mesh1d => q_list(1,1)%ptr%mesh
596 lmesh => mesh1d%lcmesh_list(1)
600 allocate( q_tmp(np,vec_size,ne) )
602 s_coef_lc(:,:,:) = 0.0_rp
604 do meshid=1, mesh_num
605 mesh1d => q_list(1,meshid)%ptr%mesh
606 do ldom=1, mesh1d%LOCAL_MESH_NUM
607 lmesh => mesh1d%lcmesh_list(ldom)
609 do kel=lmesh%NeS, lmesh%NeE
611 q_tmp(:,v,kel) = q_list(v,meshid)%ptr%local(ldom)%val(:,kel)
614 call spectral_transform1d_l2projection_lc( s_coef_lc, &
615 q_tmp, 0, km, np, ne, vec_size, intintrpmat, intxi, intweight, nintglpt, &
616 (lmesh%xmin - xmin_gl)/lx-0.5_rp, delx/lx )
621 call mpi_allreduce( s_coef_lc, s_coef, vec_size * (km+1) * 2, &
622 mpi_double_precision, mpi_sum, prc_local_comm_world, ierr )
629 spectral_coef(k,1,v) = s_coef(v,1,kk)
630 spectral_coef(k,2,v) = s_coef(v,2,kk)
635 end subroutine spectral_transform1d_l2projection
637 subroutine spectral_transform1d_l2projection_lc( spectral_coef, &
638 q, ks, ke, Np, Ne, vec_size, IntIntrpMat, IntXi, IntWeight, NintGLPt, &
641 integer,
intent(in) :: ks, ke
642 integer,
intent(in) :: np
643 integer,
intent(in) :: ne
644 integer,
intent(in) :: vec_size
645 real(rp),
intent(in) :: q(np,vec_size,ne)
646 real(rp),
intent(inout) :: spectral_coef(vec_size,2,ks:ke)
647 integer,
intent(in) :: nintglpt
648 real(rp),
intent(in) :: intintrpmat(nintglpt,np)
649 real(rp),
intent(in) :: intxi(nintglpt)
650 real(rp),
intent(in) :: intweight(nintglpt)
651 real(rp),
intent(in) :: xmin_lc
652 real(rp),
intent(in) :: delx
658 real(rp) :: q_intrp(nintglpt,vec_size,ne)
659 real(rp) :: int_x(nintglpt,ne)
661 real(rp) :: phi(nintglpt)
662 real(rp) :: cos_kx(nintglpt)
663 real(rp) :: sin_kx(nintglpt)
665 real(rp) :: int_w(nintglpt)
668 int_w(:) = 0.5_rp * intweight(:) * delx
673 int_x(:,kel) = 2.0_rp * pi * ( xmin_lc + delx * ( ( kel - 1.0_rp ) + 0.5_rp * ( 1.0_rp + intxi(:) ) ) )
674 q_intrp(:,:,kel) = matmul(intintrpmat, q(:,:,kel))
679 phi(:) = mod( k * int_x(:,kel), 2.0_rp * pi )
680 cos_kx(:) = cos( phi )
681 sin_kx(:) = sin( phi )
684 spectral_coef(v,1,k) = spectral_coef(v,1,k) + sum(int_w(:) * cos_kx(:) * q_intrp(:,v,kel))
685 spectral_coef(v,2,k) = spectral_coef(v,2,k) - sum(int_w(:) * sin_kx(:) * q_intrp(:,v,kel))
691 end subroutine spectral_transform1d_l2projection_lc
696 subroutine spectral_transform2d_dft( spectral_coef, &
697 q_list, var_num, mesh_num_x, mesh_num_y, ks, ke, ls, le, Np1D, NeX, NeY, NeGY, NprcY, NsamplePerElem1D, &
698 fft_x, fft_y, FFTIntrpMat )
701 use scale_prc,
only: &
704 integer,
intent(in) :: ks, ke
705 integer,
intent(in) :: ls, le
706 integer,
intent(in) :: np1d
707 integer,
intent(in) :: nex
708 integer,
intent(in) :: ney, negy, nprcy
709 integer,
intent(in) :: nsampleperelem1d
710 integer,
intent(in) :: var_num
711 integer,
intent(in) :: mesh_num_x
712 integer,
intent(in) :: mesh_num_y
713 real(rp),
intent(out) :: spectral_coef(ks:ke,ls:le,2,var_num)
714 class(
meshfield2dlist),
target :: q_list(var_num,mesh_num_x,mesh_num_y)
717 real(rp),
intent(in) :: fftintrpmat(nsampleperelem1d,np1d)
719 real(rp) :: fftintrpmat_tr(np1d,nsampleperelem1d)
721 real(rp) :: g_q(nsampleperelem1d*nex*mesh_num_x,nsampleperelem1d*ney*mesh_num_y*var_num)
722 complex(RP) :: s_qx(nsampleperelem1d*nex*mesh_num_x,size(g_q,2))
723 complex(RP) :: g_qy(nsampleperelem1d*ney*mesh_num_y*nprcy,var_num,nsampleperelem1d*nex*mesh_num_x/nprcy)
724 complex(RP) :: s_q_lc(nsampleperelem1d*negy,var_num,nsampleperelem1d*nex*mesh_num_x/nprcy)
725 complex(RP) :: s_q(nsampleperelem1d*negy,var_num,nsampleperelem1d*nex*mesh_num_x)
732 integer :: nall_x, nall_y
733 integer :: kk, ll, kk_os
735 integer :: sendcount, recvcount
736 complex(RP) :: sendbuf(nsampleperelem1d*ney*mesh_num_y*var_num,nsampleperelem1d*nex*mesh_num_x)
737 complex(RP) :: recvbuf(nsampleperelem1d*ney*mesh_num_y,var_num,nsampleperelem1d*nex*mesh_num_x/nprcy,nprcy)
738 integer :: nx, local_nx
739 integer :: ny, local_ny
744 nall_x = nsampleperelem1d * nex * mesh_num_x
745 nall_y = nsampleperelem1d * negy
748 fftintrpmat_tr(:,:) = transpose(fftintrpmat)
749 call spectral_transform2d_dft_sampling( g_q, &
750 q_list, var_num, mesh_num_x, mesh_num_y, np1d, nex, ney, nsampleperelem1d, &
756 call fft_x%Forward( g_q(:,v), s_qx(:,v) )
763 local_ny = nsampleperelem1d * ney * mesh_num_y * var_num
764 ny = nsampleperelem1d * negy * var_num
766 sendbuf(:,:) = transpose(s_qx)
767 sendcount = local_ny * (nx / nprcy)
768 recvcount = sendcount
769 call mpi_alltoall( sendbuf, sendcount, mpi_double_complex, &
770 recvbuf, recvcount, mpi_double_complex, prc_local_comm_world, ierr )
772 local_ny = nsampleperelem1d * ney * mesh_num_y
775 do xdim=1, nsampleperelem1d*nex*mesh_num_x/nprcy
777 g_qy(j+(prcy-1)*local_ny,v,xdim) = recvbuf(j,v,xdim,prcy)
787 call fft_y%Forward( g_qy(:,v,xdim), s_q_lc(:,v,xdim) )
791 sendcount =
size(s_q_lc)
792 recvcount =
size(s_q_lc)
793 call mpi_allgather( s_q_lc, sendcount, mpi_double_complex, &
794 s_q, recvcount, mpi_double_complex, prc_local_comm_world, ierr )
801 spectral_coef(kk-1,ll-1,1,v) = real(s_q(ll,v,kk))
802 spectral_coef(kk-1,ll-1,2,v) = aimag(s_q(ll,v,kk))
804 do kk=nall_x/2+1, nall_x
805 spectral_coef(kk-1-nall_x,ll-1,1,v) = real(s_q(ll,v,kk))
806 spectral_coef(kk-1-nall_x,ll-1,2,v) = aimag(s_q(ll,v,kk))
809 do ll=nall_y/2+1, nall_y
811 spectral_coef(kk-1,ll-1-nall_y,1,v) = real(s_q(ll,v,kk))
812 spectral_coef(kk-1,ll-1-nall_y,2,v) = aimag(s_q(ll,v,kk))
814 do kk=nall_x/2+1, nall_x
815 spectral_coef(kk-1-nall_x,ll-1-nall_y,1,v) = real(s_q(ll,v,kk))
816 spectral_coef(kk-1-nall_x,ll-1-nall_y,2,v) = aimag(s_q(ll,v,kk))
821 end subroutine spectral_transform2d_dft
824 subroutine spectral_transform2d_dft_sampling( g_q, &
825 q_list, var_num, mesh_num_x, mesh_num_y, Np1D, NeX, NeY, NsamplePerElem1D, &
829 use scale_prc,
only: &
832 integer,
intent(in) :: np1d
833 integer,
intent(in) :: nex, ney
834 integer,
intent(in) :: nsampleperelem1d
835 integer,
intent(in) :: var_num
836 integer,
intent(in) :: mesh_num_x
837 integer,
intent(in) :: mesh_num_y
838 real(rp),
intent(out) :: g_q(nsampleperelem1d,nex,mesh_num_x,nsampleperelem1d,ney,mesh_num_y,var_num)
839 class(
meshfield2dlist),
intent(in) :: q_list(var_num,mesh_num_x,mesh_num_y)
840 real(rp),
intent(in) :: fftintrpmat_tr(np1d,nsampleperelem1d)
842 real(rp) :: q_tmp(np1d,np1d)
843 real(rp) :: q_intrp1(nsampleperelem1d,np1d)
844 real(rp) :: q_intrp2(nsampleperelem1d,nsampleperelem1d)
847 integer :: kel_x, kel_y, kel
848 integer :: p, p1, pp1, p2, pp2
857 kel = kel_x + (kel_y-1)*nex
861 q_tmp(p1,p2) = q_list(v,mx,my)%ptr%local(1)%val(p,kel)
865 q_intrp1(:,:) = 0.0_rp
867 do p1=1, nsampleperelem1d
869 q_intrp1(p1,p2) = q_intrp1(p1,p2) + fftintrpmat_tr(pp1,p1) * q_tmp(pp1,p2)
873 q_intrp2(:,:) = 0.0_rp
874 do p2=1, nsampleperelem1d
876 do p1=1, nsampleperelem1d
877 q_intrp2(p1,p2) = q_intrp2(p1,p2) + fftintrpmat_tr(pp2,p2) * q_intrp1(p1,pp2)
882 do p2=1, nsampleperelem1d
883 g_q(:,kel_x,mx,p2,kel_y,my,v) = q_intrp2(:,p2)
891 end subroutine spectral_transform2d_dft_sampling
894 subroutine spectral_transform2d_l2projection( spectral_coef, &
895 q_list, var_num, mesh_num, ks, ke, ls, le, Np1D, NeX, NeY, &
896 IntIntrpMat1D, IntXi1D, IntWeight1D, NintGLPt1D, &
897 xmin_gl, delx, Lx, ymin_gl, dely, Ly )
900 use scale_prc,
only: &
903 integer,
intent(in) :: ks, ke
904 integer,
intent(in) :: ls, le
905 integer,
intent(in) :: np1d
906 integer,
intent(in) :: nex, ney
907 integer,
intent(in) :: var_num
908 integer,
intent(in) :: mesh_num
910 real(rp),
intent(out) :: spectral_coef(ks:ke,ls:le,2,var_num)
911 integer,
intent(in) :: nintglpt1d
912 real(rp),
intent(in) :: intintrpmat1d(nintglpt1d,np1d)
913 real(rp),
intent(in) :: intxi1d(nintglpt1d)
914 real(rp),
intent(in) :: intweight1d(nintglpt1d)
915 real(rp),
intent(in) :: xmin_gl
916 real(rp),
intent(in) :: delx
917 real(rp),
intent(in) :: lx
918 real(rp),
intent(in) :: ymin_gl
919 real(rp),
intent(in) :: dely
920 real(rp),
intent(in) :: ly
922 real(rp),
allocatable :: s_coef_lc(:,:,:,:)
923 real(rp),
allocatable :: s_coef(:,:,:,:)
924 real(rp),
allocatable :: q_tmp(:,:,:)
926 real(rp) :: intintrpmat1d_tr(np1d,nintglpt1d)
944 allocate( s_coef_lc(vec_size,2,0:km,ls:le) )
945 allocate( s_coef(vec_size,2,0:km,ls:le) )
948 mesh2d => q_list(1,1)%ptr%mesh
949 lmesh => mesh2d%lcmesh_list(1)
951 intintrpmat1d_tr(:,:) = transpose(intintrpmat1d)
954 allocate( q_tmp(np1d**2,vec_size,nex*ney) )
956 s_coef_lc(:,:,:,:) = 0.0_rp
958 do meshid=1, mesh_num
959 mesh2d => q_list(1,meshid)%ptr%mesh
960 do ldom=1, mesh2d%LOCAL_MESH_NUM
961 lmesh => mesh2d%lcmesh_list(ldom)
964 do kel=lmesh%NeS, lmesh%NeE
966 q_tmp(:,v,kel) = q_list(v,meshid)%ptr%local(ldom)%val(:,kel)
969 call spectral_transform2d_l2projection_lc( s_coef_lc, &
970 q_tmp, 0, km, ls, le, np1d, nex, ney, vec_size, &
971 intintrpmat1d_tr, intxi1d, intweight1d, nintglpt1d, &
972 (lmesh%xmin - xmin_gl)/lx-0.5_rp, delx/lx, &
973 (lmesh%ymin - ymin_gl)/ly-0.5_rp, dely/ly )
978 call mpi_allreduce( s_coef_lc, s_coef, vec_size * (km+1)*(le-ls+1) * 2, &
979 mpi_double_precision, mpi_sum, prc_local_comm_world, ierr )
988 spectral_coef(k,l,1,v) = s_coef(v,1,kk,l)
989 spectral_coef(k,l,2,v) = s_coef(v,2,kk,l)
991 spectral_coef(k,l,1,v) = s_coef(v,1,kk,-l)
992 spectral_coef(k,l,2,v) = - s_coef(v,2,kk,-l)
999 end subroutine spectral_transform2d_l2projection
1001 subroutine spectral_transform2d_l2projection_lc( spectral_coef, &
1002 q, ks, ke, ls, le, Np1D, NeX, NeY, vec_size, IntIntrpMat1D_tr, IntXi1D, IntWeight1D, NintGLpt1D, &
1003 xmin_lc, delx, ymin_lc, dely )
1005 integer,
intent(in) :: ks, ke
1006 integer,
intent(in) :: ls, le
1007 integer,
intent(in) :: np1d
1008 integer,
intent(in) :: nex
1009 integer,
intent(in) :: ney
1010 integer,
intent(in) :: vec_size
1011 real(rp),
intent(in) :: q(np1d,np1d,vec_size,nex,ney)
1012 real(rp),
intent(inout) :: spectral_coef(vec_size,2,ks:ke,ls:le)
1013 integer,
intent(in) :: nintglpt1d
1014 real(rp),
intent(in) :: intintrpmat1d_tr(np1d,nintglpt1d)
1015 real(rp),
intent(in) :: intxi1d(nintglpt1d)
1016 real(rp),
intent(in) :: intweight1d(nintglpt1d)
1017 real(rp),
intent(in) :: xmin_lc
1018 real(rp),
intent(in) :: delx
1019 real(rp),
intent(in) :: ymin_lc
1020 real(rp),
intent(in) :: dely
1023 integer :: kel_x, kel_y
1024 integer :: p, px, py
1027 real(rp) :: q_intrp_tmp(nintglpt1d,np1d,vec_size)
1028 real(rp) :: q_intrp_tmp2(nintglpt1d**2,vec_size)
1029 real(rp) :: q_intrp(nintglpt1d**2,vec_size,nex,ney)
1030 real(rp) :: int_x(nintglpt1d,nex)
1031 real(rp) :: int_y(nintglpt1d,ney)
1033 real(rp) :: phi(nintglpt1d**2)
1034 real(rp) :: cos_phi(nintglpt1d**2)
1035 real(rp) :: sin_phi(nintglpt1d**2)
1037 real(rp) :: int_w(nintglpt1d**2)
1044 p = px + (py-1)*nintglpt1d
1045 int_w(p) = 0.25_rp * delx * dely * intweight1d(px) * intweight1d(py)
1050 int_x(:,kel_x) = 2.0_rp * pi * ( xmin_lc + delx * ( ( kel_x - 1.0_rp ) + 0.5_rp * ( 1.0_rp + intxi1d(:) ) ) )
1054 int_y(:,kel_y) = 2.0_rp * pi * ( ymin_lc + dely * ( ( kel_y - 1.0_rp ) + 0.5_rp * ( 1.0_rp + intxi1d(:) ) ) )
1059 q_intrp_tmp(:,:,:) = 0.0_rp
1063 q_intrp_tmp(px,py,v) = q_intrp_tmp(px,py,v) &
1064 + sum(intintrpmat1d_tr(:,px) * q(:,py,v,kel_x,kel_y))
1069 q_intrp_tmp2(:,:) = 0.0_rp
1073 p = px + (py-1)*nintglpt1d
1074 q_intrp_tmp2(p,v) = q_intrp_tmp2(p,v) &
1075 + sum(intintrpmat1d_tr(:,py) * q_intrp_tmp(px,:,v))
1079 q_intrp(:,:,kel_x,kel_y) = q_intrp_tmp2(:,:)
1089 p = px + (py-1)*nintglpt1d
1090 phi(p) = mod( k * int_x(px,kel_x) + l * int_y(py,kel_y), 2.0_rp * pi )
1093 cos_phi(:) = cos( phi(:) )
1094 sin_phi(:) = sin( phi(:) )
1097 spectral_coef(v,1,k,l) = spectral_coef(v,1,k,l) + sum(int_w(:) * cos_phi(:) * q_intrp(:,v,kel_x,kel_y))
1098 spectral_coef(v,2,k,l) = spectral_coef(v,2,k,l) - sum(int_w(:) * sin_phi(:) * q_intrp(:,v,kel_x,kel_y))
1106 end subroutine spectral_transform2d_l2projection_lc
module FElib / Element / Base
module FElib / Element / line
module FElib / Mesh / Local 1D
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Base 1D
module FElib / Mesh / Base 2D
module FElib / Mesh / Rectangle 2D domain
module FElib / Data / base
Module common / Polynominal.
real(rp) function, dimension(size(x), nord+1), public polynominal_genlagrangepoly(nord, x_lgl, x)
A function to obtain the Lagrange basis functions related to the Gauss-Legendre-Lobatto (GLL) points.
Derived type representing a 1D reference element.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing a line element.
Derived type to manage a local 3D computational domain.
Derived type representing a field with 1D mesh.
Derived type representing a field with 2D mesh.