16 use scale_const,
only: &
18 use scale_prc,
only: &
51 integer :: eval_type_id
55 real(rp),
allocatable :: fftintrpmat(:,:)
56 real(rp),
allocatable :: fft_xi(:)
57 integer :: nsampleptperelem
59 real(rp),
allocatable :: intintrpmat(:,:)
60 real(rp),
allocatable :: intweight(:)
61 real(rp),
allocatable :: intxi(:)
70 real(rp) :: xmin_gl, xmax_gl
73 real(rp),
allocatable :: k(:)
74 real(rp),
allocatable :: spectral_coef(:,:,:)
78 procedure :: init => meshfield_spetraltransform1d_init
79 procedure :: final => meshfield_spetraltransform1d_final
80 procedure :: transform => meshfield_spetraltransform1d_transform
90 real(rp) :: xmin_gl, xmax_gl
92 real(rp) :: ymin_gl, ymax_gl
99 integer :: nsampleptperelem1d
101 real(rp),
allocatable :: k(:)
102 real(rp),
allocatable :: l(:)
103 real(rp),
allocatable :: spectral_coef(:,:,:,:)
108 procedure :: init => meshfield_spetraltransform2d_init
109 procedure :: final => meshfield_spetraltransform2d_final
110 procedure :: transform => meshfield_spetraltransform2d_transform
136 subroutine meshfield_spetraltransformbase_init( this, eval_type, ndim, var_num, NintGLpt, NsamplePtPerElem )
139 integer,
intent(in) :: eval_type
140 integer,
intent(in) :: ndim
141 integer,
intent(in) :: var_num
142 integer,
intent(in),
optional :: nintglpt
143 integer,
intent(in),
optional :: nsampleptperelem
146 this%eval_type_id = eval_type
147 call check_eval_type_id( eval_type )
150 this%var_num = var_num
154 if ( .not.
present(nintglpt) )
then
155 log_info(
"MeshField_SpetralTransformBase_Init",*)
"The order of Gaussian quadrature should be given. Check!"
158 this%NintGLPt = nintglpt
164 if ( .not.
present(nsampleptperelem) )
then
165 log_info(
"MeshField_SpetralTransformBase_Init",*)
"NsamplePtPerElem shouled be given. Check!"
167 this%NsamplePtPerElem = nsampleptperelem
170 this%NsamplePtPerElem = -1
172 log_info(
"MeshField_SpetralTransformBase_Init",*)
"NintGLPt=", this%NintGLpt,
"NsamplePtPerElem=", this%NsamplePtPerElem
175 end subroutine meshfield_spetraltransformbase_init
177 subroutine check_eval_type_id( eval_type )
179 integer,
intent(in) :: eval_type
181 select case(eval_type)
185 log_info(
"MeshField_SpetralTransformBase_Init",*)
"Unsupported evaluation type is specified. Check!"
189 end subroutine check_eval_type_id
192 subroutine meshfield_spetraltransformbase_final( this )
197 if ( this%NintGLpt > 0 ) &
198 deallocate( this%IntIntrpMat, this%IntXi, this%IntWeight )
200 if ( this%NsamplePtPerElem > 0 ) &
201 deallocate( this%FFTIntrpMat, this%FFT_xi )
204 end subroutine meshfield_spetraltransformbase_final
209 subroutine meshfield_spetraltransform1d_init( this, eval_type, ks, ke, mesh1D, var_num, &
210 GLQuadOrd, NsamplePtPerElem )
213 integer,
intent(in) :: eval_type
214 integer,
intent(in) :: ks, ke
215 class(
meshbase1d),
intent(in),
target :: mesh1d
216 integer,
intent(in) :: var_num
217 integer,
optional :: glquadord
218 integer,
optional :: nsampleptperelem
230 lmesh => mesh1d%lcmesh_list(1)
231 elem => lmesh%refElem1D
233 call meshfield_spetraltransformbase_init( this, eval_type, 1, var_num, &
234 glquadord, nsampleptperelem )
236 this%ks = ks; this%ke = ke
237 this%kall = ke - ks + 1
239 this%xmin_gl = mesh1d%xmin_gl
240 this%xmax_gl = mesh1d%xmax_gl
241 this%delx = 1.0_rp / real(mesh1d%NeG,kind=rp)
243 allocate( this%k(ks:ke) )
244 lx = this%xmax_gl - this%xmin_gl
246 this%k(i) = i * 2.0_rp * pi / lx
249 allocate( this%spectral_coef(ks:ke,2,var_num) )
251 call elem_dummy%Init(elem%PolyOrder, .false.)
253 if ( this%NintGLpt > 0 )
then
254 allocate( this%IntIntrpMat(this%NintGLpt,elem%Np) )
255 allocate( this%IntXi(this%NintGLpt), this%IntWeight(this%NintGLpt) )
257 this%IntIntrpMat(:,:) = elem_dummy%GenIntGaussLegendreIntrpMat( glquadord, this%IntWeight, this%IntXi )
260 if ( this%NsamplePtPerElem > 0 )
then
261 allocate( this%FFTIntrpMat(this%NsamplePtPerElem,elem%Np) )
262 allocate( this%FFT_Xi(this%NsamplePtPerElem) )
264 dx = 2.0_rp / real(this%NsamplePtPerElem,kind=rp)
265 do i=1, this%NsamplePtPerElem
266 this%FFT_Xi(i) = -1.0_rp + real(i - 0.5_rp,kind=rp) * dx
270 call this%fft%Init( nsampleptperelem * mesh1d%NeG )
273 call elem_dummy%Final()
276 end subroutine meshfield_spetraltransform1d_init
279 subroutine meshfield_spetraltransform1d_final( this )
284 call meshfield_spetraltransformbase_final( this )
286 if ( this%NsamplePtPerElem > 0 )
then
287 call this%fft%Final()
290 deallocate( this%k, this%spectral_coef )
293 end subroutine meshfield_spetraltransform1d_final
296 subroutine meshfield_spetraltransform1d_transform( this, q_list, mesh_num )
299 integer,
intent(in) :: mesh_num
306 mesh1d => q_list(1,1)%ptr%mesh
307 lmesh => mesh1d%lcmesh_list(1)
309 select case( this%eval_type_id )
311 call spectral_transform1d_dft( this%spectral_coef, &
312 q_list, this%var_num, mesh_num, &
313 this%ks, this%ke, lmesh%refElem1D%Np, lmesh%Ne, this%NsamplePtPerElem, &
314 this%fft, this%FFTIntrpMat, this%FFT_xi, &
315 this%xmin_gl, this%delx, this%xmax_gl - this%xmin_gl )
317 call spectral_transform1d_l2projection( this%spectral_coef, &
318 q_list, this%var_num, mesh_num, &
319 this%ks, this%ke, lmesh%refElem1D%Np, lmesh%Ne, &
320 this%IntIntrpMat, this%IntXi, this%IntWeight, this%NintGLPt, &
321 this%xmin_gl, this%delx, this%xmax_gl - this%xmin_gl )
325 end subroutine meshfield_spetraltransform1d_transform
330 subroutine meshfield_spetraltransform2d_init( this, eval_type, ks, ke, ls, le, mesh2D, var_num, &
331 GLQuadOrd, NsamplePtPerElem1D )
338 integer,
intent(in) :: eval_type
339 integer,
intent(in) :: ks, ke
340 integer,
intent(in) :: ls, le
341 class(
meshbase2d),
intent(in),
target :: mesh2d
342 integer,
intent(in) :: var_num
343 integer,
optional :: glquadord
344 integer,
optional :: nsampleptperelem1d
357 lmesh => mesh2d%lcmesh_list(1)
358 elem => lmesh%refElem2D
360 call meshfield_spetraltransformbase_init( this, eval_type, 1, var_num, glquadord, nsampleptperelem1d )
362 this%ks = ks; this%ke = ke
363 this%kall = ke - ks + 1
365 this%ls = ls; this%le = le
366 this%lall = le - ls + 1
368 select type(ptr_mesh2d => mesh2d)
370 this%xmin_gl = ptr_mesh2d%xmin_gl
371 this%xmax_gl = ptr_mesh2d%xmax_gl
372 this%delx = ( this%xmax_gl - this%xmin_gl ) / real(ptr_mesh2d%NeGX, kind=rp)
374 this%ymin_gl = ptr_mesh2d%ymin_gl
375 this%ymax_gl = ptr_mesh2d%ymax_gl
376 this%dely = ( this%ymax_gl - this%ymin_gl ) / real(ptr_mesh2d%NeGY, kind=rp)
378 this%NeGX = ptr_mesh2d%NeGX
379 this%NeGY = ptr_mesh2d%NeGY
380 this%NprcX = ptr_mesh2d%NprcX
381 this%NprcY = ptr_mesh2d%NprcY
383 log_info(
'MeshField_SpetralTransform2D_Init',*)
'Unexpected mesh type is given. Check!'
387 allocate( this%k(ks:ke) )
388 lx = this%xmax_gl - this%xmin_gl
390 this%k(i) = i * 2.0_rp * pi / lx
393 allocate( this%l(ls:le) )
394 ly = this%ymax_gl - this%ymin_gl
396 this%l(j) = j * 2.0_rp * pi / ly
399 allocate( this%spectral_coef(ks:ke,ls:le,2,var_num) )
401 call elem_dummy%Init(elem%PolyOrder, .false.)
403 if ( this%NintGLpt > 0 )
then
404 allocate( this%IntIntrpMat(this%NintGLpt,elem%Nfp) )
405 allocate( this%IntXi(this%NintGLpt), this%IntWeight(this%NintGLpt) )
407 this%IntIntrpMat(:,:) = elem_dummy%GenIntGaussLegendreIntrpMat( glquadord, this%IntWeight, this%IntXi )
410 if ( this%NsamplePtPerElem > 0 )
then
411 this%NsamplePtPerElem1D = nsampleptperelem1d
412 allocate( this%FFTIntrpMat(this%NsamplePtPerElem1D,elem%Nfp) )
413 allocate( this%FFT_Xi(this%NsamplePtPerElem1D) )
415 dx = 2.0_rp / real(this%NsamplePtPerElem1D,kind=rp)
416 do i=1, this%NsamplePtPerElem1D
417 this%FFT_Xi(i) = -1.0_rp + real(i - 0.5_rp,kind=rp) * dx
421 call this%fft_x%Init( this%NsamplePtPerElem1D * this%NeGX )
422 call this%fft_y%Init( this%NsamplePtPerElem1D * this%NeGY )
425 call elem_dummy%Final()
427 end subroutine meshfield_spetraltransform2d_init
430 subroutine meshfield_spetraltransform2d_final( this )
435 call meshfield_spetraltransformbase_final( this )
437 if ( this%NsamplePtPerElem > 0 )
then
438 call this%fft_x%Final()
439 call this%fft_y%Final()
442 deallocate( this%k, this%l, this%spectral_coef )
444 end subroutine meshfield_spetraltransform2d_final
447 subroutine meshfield_spetraltransform2d_transform( this, q_list, mesh_num_x, mesh_num_y )
450 integer,
intent(in) :: mesh_num_x, mesh_num_y
451 type(
meshfield2dlist),
target :: q_list(this%var_num,mesh_num_x,mesh_num_y)
457 mesh2d => q_list(1,1,1)%ptr%mesh
458 lmesh => mesh2d%lcmesh_list(1)
460 select case( this%eval_type_id )
462 call spectral_transform2d_dft( this%spectral_coef, &
463 q_list, this%var_num, mesh_num_x, mesh_num_y, &
464 this%ks, this%ke, this%ls, this%le, lmesh%refElem2D%Nfp, lmesh%NeX, lmesh%NeY, &
465 this%NeGY, this%NprcY, this%NsamplePtPerElem1D, &
466 this%fft_x, this%fft_y, this%FFTIntrpMat )
468 call spectral_transform2d_l2projection( this%spectral_coef, &
469 q_list, this%var_num, mesh_num_x*mesh_num_y, &
470 this%ks, this%ke, this%ls, this%le, lmesh%refElem2D%Nfp, lmesh%NeX, lmesh%NeY, &
471 this%IntIntrpMat, this%IntXi, this%IntWeight, this%NintGLPt, &
472 this%xmin_gl, this%delx, this%xmax_gl - this%xmin_gl, &
473 this%ymin_gl, this%dely, this%ymax_gl - this%ymin_gl )
477 end subroutine meshfield_spetraltransform2d_transform
482 subroutine spectral_transform1d_dft( spectral_coef, &
483 q_list, var_num, mesh_num, ks, ke, Np, Ne, NsamplePerElem, &
484 fft, FFTIntrpMat, FFT_xi, &
488 use scale_prc,
only: &
491 integer,
intent(in) :: ks, ke
492 integer,
intent(in) :: np
493 integer,
intent(in) :: ne
494 integer,
intent(in) :: nsampleperelem
495 integer,
intent(in) :: var_num
496 integer,
intent(in) :: mesh_num
497 real(rp),
intent(out) :: spectral_coef(ks:ke,2,var_num)
500 real(rp),
intent(in) :: fftintrpmat(nsampleperelem,np)
501 real(rp),
intent(in) :: fft_xi(nsampleperelem)
502 real(rp),
intent(in) :: xmin_gl
503 real(rp),
intent(in) :: delx
504 real(rp),
intent(in) :: lx
506 real(rp) :: g_q(nsampleperelem,ne,mesh_num,var_num)
507 real(rp) :: q_tmp(np)
508 complex(RP) :: s_q(nsampleperelem*ne*mesh_num,var_num)
517 real(rp) :: x_(nsampleperelem)
524 q_tmp(:) = q_list(v,m)%ptr%local(1)%val(:,kel)
525 g_q(:,kel,m,v) = matmul( fftintrpmat, q_tmp )
532 call fft%Forward_real( g_q(:,:,:,v), s_q(:,v) )
535 nall = nsampleperelem * ne * mesh_num
539 spectral_coef(kk-1,1,v) = real(s_q(kk,v))
540 spectral_coef(kk-1,2,v) = aimag(s_q(kk,v))
543 spectral_coef(kk-1-nall,1,v) = real(s_q(kk,v))
544 spectral_coef(kk-1-nall,2,v) = aimag(s_q(kk,v))
548 end subroutine spectral_transform1d_dft
551 subroutine spectral_transform1d_l2projection( spectral_coef, &
552 q_list, var_num, mesh_num, ks, ke, Np, Ne, IntIntrpMat, IntXi, IntWeight, NintGLPt, &
556 use scale_prc,
only: &
559 integer,
intent(in) :: ks, ke
560 integer,
intent(in) :: np
561 integer,
intent(in) :: ne
562 integer,
intent(in) :: var_num
563 integer,
intent(in) :: mesh_num
565 real(rp),
intent(out) :: spectral_coef(ks:ke,2,var_num)
566 integer,
intent(in) :: nintglpt
567 real(rp),
intent(in) :: intintrpmat(nintglpt,np)
568 real(rp),
intent(in) :: intxi(nintglpt)
569 real(rp),
intent(in) :: intweight(nintglpt)
570 real(rp),
intent(in) :: xmin_gl
571 real(rp),
intent(in) :: delx
572 real(rp),
intent(in) :: lx
574 real(rp),
allocatable :: s_coef_lc(:,:,:)
575 real(rp),
allocatable :: s_coef(:,:,:)
576 real(rp),
allocatable :: q_tmp(:,:,:)
595 allocate( s_coef_lc(vec_size,2,0:km) )
596 allocate( s_coef(vec_size,2,0:km) )
599 mesh1d => q_list(1,1)%ptr%mesh
600 lmesh => mesh1d%lcmesh_list(1)
604 allocate( q_tmp(np,vec_size,ne) )
606 s_coef_lc(:,:,:) = 0.0_rp
608 do meshid=1, mesh_num
609 mesh1d => q_list(1,meshid)%ptr%mesh
611 do ldom=1, mesh1d%LOCAL_MESH_NUM
613 lcfields(v)%ptr => q_list(v,meshid)%ptr%local(ldom)
616 do kel=lmesh%NeS, lmesh%NeE
618 q_tmp(:,v,kel) = lcfields(v)%ptr%val(:,kel)
621 call spectral_transform1d_l2projection_lc( s_coef_lc, &
622 q_tmp, 0, km, np, ne, vec_size, intintrpmat, intxi, intweight, nintglpt, &
623 (lmesh%xmin - xmin_gl)/lx-0.5_rp, delx/lx )
628 call mpi_allreduce( s_coef_lc, s_coef, vec_size * (km+1) * 2, &
629 mpi_double_precision, mpi_sum, prc_local_comm_world, ierr )
636 spectral_coef(k,1,v) = s_coef(v,1,kk)
637 spectral_coef(k,2,v) = s_coef(v,2,kk)
642 end subroutine spectral_transform1d_l2projection
644 subroutine spectral_transform1d_l2projection_lc( spectral_coef, &
645 q, ks, ke, Np, Ne, vec_size, IntIntrpMat, IntXi, IntWeight, NintGLPt, &
648 integer,
intent(in) :: ks, ke
649 integer,
intent(in) :: np
650 integer,
intent(in) :: ne
651 integer,
intent(in) :: vec_size
652 real(rp),
intent(in) :: q(np,vec_size,ne)
653 real(rp),
intent(inout) :: spectral_coef(vec_size,2,ks:ke)
654 integer,
intent(in) :: nintglpt
655 real(rp),
intent(in) :: intintrpmat(nintglpt,np)
656 real(rp),
intent(in) :: intxi(nintglpt)
657 real(rp),
intent(in) :: intweight(nintglpt)
658 real(rp),
intent(in) :: xmin_lc
659 real(rp),
intent(in) :: delx
665 real(rp) :: q_intrp(nintglpt,vec_size,ne)
666 real(rp) :: int_x(nintglpt,ne)
668 real(rp) :: phi(nintglpt)
669 real(rp) :: cos_kx(nintglpt)
670 real(rp) :: sin_kx(nintglpt)
672 real(rp) :: int_w(nintglpt)
675 int_w(:) = 0.5_rp * intweight(:) * delx
680 int_x(:,kel) = 2.0_rp * pi * ( xmin_lc + delx * ( ( kel - 1.0_rp ) + 0.5_rp * ( 1.0_rp + intxi(:) ) ) )
681 q_intrp(:,:,kel) = matmul(intintrpmat, q(:,:,kel))
686 phi(:) = mod( k * int_x(:,kel), 2.0_rp * pi )
687 cos_kx(:) = cos( phi )
688 sin_kx(:) = sin( phi )
691 spectral_coef(v,1,k) = spectral_coef(v,1,k) + sum(int_w(:) * cos_kx(:) * q_intrp(:,v,kel))
692 spectral_coef(v,2,k) = spectral_coef(v,2,k) - sum(int_w(:) * sin_kx(:) * q_intrp(:,v,kel))
698 end subroutine spectral_transform1d_l2projection_lc
703 subroutine spectral_transform2d_dft( spectral_coef, &
704 q_list, var_num, mesh_num_x, mesh_num_y, ks, ke, ls, le, Np1D, NeX, NeY, NeGY, NprcY, NsamplePerElem1D, &
705 fft_x, fft_y, FFTIntrpMat )
708 use scale_prc,
only: &
711 integer,
intent(in) :: ks, ke
712 integer,
intent(in) :: ls, le
713 integer,
intent(in) :: np1d
714 integer,
intent(in) :: nex
715 integer,
intent(in) :: ney, negy, nprcy
716 integer,
intent(in) :: nsampleperelem1d
717 integer,
intent(in) :: var_num
718 integer,
intent(in) :: mesh_num_x
719 integer,
intent(in) :: mesh_num_y
720 real(rp),
intent(out) :: spectral_coef(ks:ke,ls:le,2,var_num)
721 class(
meshfield2dlist),
target :: q_list(var_num,mesh_num_x,mesh_num_y)
724 real(rp),
intent(in) :: fftintrpmat(nsampleperelem1d,np1d)
726 real(rp) :: fftintrpmat_tr(np1d,nsampleperelem1d)
728 real(rp) :: g_q(nsampleperelem1d*nex*mesh_num_x,nsampleperelem1d*ney*mesh_num_y*var_num)
729 complex(RP) :: s_qx(nsampleperelem1d*nex*mesh_num_x,size(g_q,2))
730 complex(RP) :: g_qy(nsampleperelem1d*ney*mesh_num_y*nprcy,var_num,nsampleperelem1d*nex*mesh_num_x/nprcy)
731 complex(RP) :: s_q_lc(nsampleperelem1d*negy,var_num,nsampleperelem1d*nex*mesh_num_x/nprcy)
732 complex(RP) :: s_q(nsampleperelem1d*negy,var_num,nsampleperelem1d*nex*mesh_num_x)
739 integer :: nall_x, nall_y
740 integer :: kk, ll, kk_os
742 integer :: sendcount, recvcount
743 complex(RP) :: sendbuf(nsampleperelem1d*ney*mesh_num_y*var_num,nsampleperelem1d*nex*mesh_num_x)
744 complex(RP) :: recvbuf(nsampleperelem1d*ney*mesh_num_y,var_num,nsampleperelem1d*nex*mesh_num_x/nprcy,nprcy)
745 integer :: nx, local_nx
746 integer :: ny, local_ny
751 nall_x = nsampleperelem1d * nex * mesh_num_x
752 nall_y = nsampleperelem1d * negy
755 fftintrpmat_tr(:,:) = transpose(fftintrpmat)
756 call spectral_transform2d_dft_sampling( g_q, &
757 q_list, var_num, mesh_num_x, mesh_num_y, np1d, nex, ney, nsampleperelem1d, &
763 call fft_x%Forward( g_q(:,v), s_qx(:,v) )
770 local_ny = nsampleperelem1d * ney * mesh_num_y * var_num
771 ny = nsampleperelem1d * negy * var_num
773 sendbuf(:,:) = transpose(s_qx)
774 sendcount = local_ny * (nx / nprcy)
775 recvcount = sendcount
776 call mpi_alltoall( sendbuf, sendcount, mpi_double_complex, &
777 recvbuf, recvcount, mpi_double_complex, prc_local_comm_world, ierr )
779 local_ny = nsampleperelem1d * ney * mesh_num_y
782 do xdim=1, nsampleperelem1d*nex*mesh_num_x/nprcy
784 g_qy(j+(prcy-1)*local_ny,v,xdim) = recvbuf(j,v,xdim,prcy)
794 call fft_y%Forward( g_qy(:,v,xdim), s_q_lc(:,v,xdim) )
798 sendcount =
size(s_q_lc)
799 recvcount =
size(s_q_lc)
800 call mpi_allgather( s_q_lc, sendcount, mpi_double_complex, &
801 s_q, recvcount, mpi_double_complex, prc_local_comm_world, ierr )
808 spectral_coef(kk-1,ll-1,1,v) = real(s_q(ll,v,kk))
809 spectral_coef(kk-1,ll-1,2,v) = aimag(s_q(ll,v,kk))
811 do kk=nall_x/2+1, nall_x
812 spectral_coef(kk-1-nall_x,ll-1,1,v) = real(s_q(ll,v,kk))
813 spectral_coef(kk-1-nall_x,ll-1,2,v) = aimag(s_q(ll,v,kk))
816 do ll=nall_y/2+1, nall_y
818 spectral_coef(kk-1,ll-1-nall_y,1,v) = real(s_q(ll,v,kk))
819 spectral_coef(kk-1,ll-1-nall_y,2,v) = aimag(s_q(ll,v,kk))
821 do kk=nall_x/2+1, nall_x
822 spectral_coef(kk-1-nall_x,ll-1-nall_y,1,v) = real(s_q(ll,v,kk))
823 spectral_coef(kk-1-nall_x,ll-1-nall_y,2,v) = aimag(s_q(ll,v,kk))
828 end subroutine spectral_transform2d_dft
831 subroutine spectral_transform2d_dft_sampling( g_q, &
832 q_list, var_num, mesh_num_x, mesh_num_y, Np1D, NeX, NeY, NsamplePerElem1D, &
836 use scale_prc,
only: &
839 integer,
intent(in) :: np1d
840 integer,
intent(in) :: nex, ney
841 integer,
intent(in) :: nsampleperelem1d
842 integer,
intent(in) :: var_num
843 integer,
intent(in) :: mesh_num_x
844 integer,
intent(in) :: mesh_num_y
845 real(rp),
intent(out) :: g_q(nsampleperelem1d,nex,mesh_num_x,nsampleperelem1d,ney,mesh_num_y,var_num)
846 class(
meshfield2dlist),
intent(in) :: q_list(var_num,mesh_num_x,mesh_num_y)
847 real(rp),
intent(in) :: fftintrpmat_tr(np1d,nsampleperelem1d)
849 real(rp) :: q_tmp(np1d,np1d)
850 real(rp) :: q_intrp1(nsampleperelem1d,np1d)
851 real(rp) :: q_intrp2(nsampleperelem1d,nsampleperelem1d)
854 integer :: kel_x, kel_y, kel
855 integer :: p, p1, pp1, p2, pp2
864 kel = kel_x + (kel_y-1)*nex
868 q_tmp(p1,p2) = q_list(v,mx,my)%ptr%local(1)%val(p,kel)
872 q_intrp1(:,:) = 0.0_rp
874 do p1=1, nsampleperelem1d
876 q_intrp1(p1,p2) = q_intrp1(p1,p2) + fftintrpmat_tr(pp1,p1) * q_tmp(pp1,p2)
880 q_intrp2(:,:) = 0.0_rp
881 do p2=1, nsampleperelem1d
883 do p1=1, nsampleperelem1d
884 q_intrp2(p1,p2) = q_intrp2(p1,p2) + fftintrpmat_tr(pp2,p2) * q_intrp1(p1,pp2)
889 do p2=1, nsampleperelem1d
890 g_q(:,kel_x,mx,p2,kel_y,my,v) = q_intrp2(:,p2)
898 end subroutine spectral_transform2d_dft_sampling
901 subroutine spectral_transform2d_l2projection( spectral_coef, &
902 q_list, var_num, mesh_num, ks, ke, ls, le, Np1D, NeX, NeY, &
903 IntIntrpMat1D, IntXi1D, IntWeight1D, NintGLPt1D, &
904 xmin_gl, delx, Lx, ymin_gl, dely, Ly )
907 use scale_prc,
only: &
910 integer,
intent(in) :: ks, ke
911 integer,
intent(in) :: ls, le
912 integer,
intent(in) :: np1d
913 integer,
intent(in) :: nex, ney
914 integer,
intent(in) :: var_num
915 integer,
intent(in) :: mesh_num
917 real(rp),
intent(out) :: spectral_coef(ks:ke,ls:le,2,var_num)
918 integer,
intent(in) :: nintglpt1d
919 real(rp),
intent(in) :: intintrpmat1d(nintglpt1d,np1d)
920 real(rp),
intent(in) :: intxi1d(nintglpt1d)
921 real(rp),
intent(in) :: intweight1d(nintglpt1d)
922 real(rp),
intent(in) :: xmin_gl
923 real(rp),
intent(in) :: delx
924 real(rp),
intent(in) :: lx
925 real(rp),
intent(in) :: ymin_gl
926 real(rp),
intent(in) :: dely
927 real(rp),
intent(in) :: ly
929 real(rp),
allocatable :: s_coef_lc(:,:,:,:)
930 real(rp),
allocatable :: s_coef(:,:,:,:)
931 real(rp),
allocatable :: q_tmp(:,:,:)
933 real(rp) :: intintrpmat1d_tr(np1d,nintglpt1d)
953 allocate( s_coef_lc(vec_size,2,0:km,ls:le) )
954 allocate( s_coef(vec_size,2,0:km,ls:le) )
957 mesh2d => q_list(1,1)%ptr%mesh
958 lmesh => mesh2d%lcmesh_list(1)
960 intintrpmat1d_tr(:,:) = transpose(intintrpmat1d)
963 allocate( q_tmp(np1d**2,vec_size,nex*ney) )
965 s_coef_lc(:,:,:,:) = 0.0_rp
967 do meshid=1, mesh_num
968 mesh2d => q_list(1,meshid)%ptr%mesh
969 do ldom=1, mesh2d%LOCAL_MESH_NUM
970 lmesh => mesh2d%lcmesh_list(ldom)
973 lcfields(v)%ptr => q_list(v,meshid)%ptr%local(ldom)
976 do kel=lmesh%NeS, lmesh%NeE
978 q_tmp(:,v,kel) = lcfields(v)%ptr%val(:,kel)
981 call spectral_transform2d_l2projection_lc( s_coef_lc, &
982 q_tmp, 0, km, ls, le, np1d, nex, ney, vec_size, &
983 intintrpmat1d_tr, intxi1d, intweight1d, nintglpt1d, &
984 (lmesh%xmin - xmin_gl)/lx-0.5_rp, delx/lx, &
985 (lmesh%ymin - ymin_gl)/ly-0.5_rp, dely/ly )
990 call mpi_allreduce( s_coef_lc, s_coef, vec_size * (km+1)*(le-ls+1) * 2, &
991 mpi_double_precision, mpi_sum, prc_local_comm_world, ierr )
1000 spectral_coef(k,l,1,v) = s_coef(v,1,kk,l)
1001 spectral_coef(k,l,2,v) = s_coef(v,2,kk,l)
1003 spectral_coef(k,l,1,v) = s_coef(v,1,kk,-l)
1004 spectral_coef(k,l,2,v) = - s_coef(v,2,kk,-l)
1011 end subroutine spectral_transform2d_l2projection
1013 subroutine spectral_transform2d_l2projection_lc( spectral_coef, &
1014 q, ks, ke, ls, le, Np1D, NeX, NeY, vec_size, IntIntrpMat1D_tr, IntXi1D, IntWeight1D, NintGLpt1D, &
1015 xmin_lc, delx, ymin_lc, dely )
1017 integer,
intent(in) :: ks, ke
1018 integer,
intent(in) :: ls, le
1019 integer,
intent(in) :: np1d
1020 integer,
intent(in) :: nex
1021 integer,
intent(in) :: ney
1022 integer,
intent(in) :: vec_size
1023 real(rp),
intent(in) :: q(np1d,np1d,vec_size,nex,ney)
1024 real(rp),
intent(inout) :: spectral_coef(vec_size,2,ks:ke,ls:le)
1025 integer,
intent(in) :: nintglpt1d
1026 real(rp),
intent(in) :: intintrpmat1d_tr(np1d,nintglpt1d)
1027 real(rp),
intent(in) :: intxi1d(nintglpt1d)
1028 real(rp),
intent(in) :: intweight1d(nintglpt1d)
1029 real(rp),
intent(in) :: xmin_lc
1030 real(rp),
intent(in) :: delx
1031 real(rp),
intent(in) :: ymin_lc
1032 real(rp),
intent(in) :: dely
1035 integer :: kel_x, kel_y
1036 integer :: p, px, py
1039 real(rp) :: q_intrp_tmp(nintglpt1d,np1d,vec_size)
1040 real(rp) :: q_intrp_tmp2(nintglpt1d**2,vec_size)
1041 real(rp) :: q_intrp(nintglpt1d**2,vec_size,nex,ney)
1042 real(rp) :: int_x(nintglpt1d,nex)
1043 real(rp) :: int_y(nintglpt1d,ney)
1045 real(rp) :: phi(nintglpt1d**2)
1046 real(rp) :: cos_phi(nintglpt1d**2)
1047 real(rp) :: sin_phi(nintglpt1d**2)
1049 real(rp) :: int_w(nintglpt1d**2)
1056 p = px + (py-1)*nintglpt1d
1057 int_w(p) = 0.25_rp * delx * dely * intweight1d(px) * intweight1d(py)
1062 int_x(:,kel_x) = 2.0_rp * pi * ( xmin_lc + delx * ( ( kel_x - 1.0_rp ) + 0.5_rp * ( 1.0_rp + intxi1d(:) ) ) )
1066 int_y(:,kel_y) = 2.0_rp * pi * ( ymin_lc + dely * ( ( kel_y - 1.0_rp ) + 0.5_rp * ( 1.0_rp + intxi1d(:) ) ) )
1071 q_intrp_tmp(:,:,:) = 0.0_rp
1075 q_intrp_tmp(px,py,v) = q_intrp_tmp(px,py,v) &
1076 + sum(intintrpmat1d_tr(:,px) * q(:,py,v,kel_x,kel_y))
1081 q_intrp_tmp2(:,:) = 0.0_rp
1085 p = px + (py-1)*nintglpt1d
1086 q_intrp_tmp2(p,v) = q_intrp_tmp2(p,v) &
1087 + sum(intintrpmat1d_tr(:,py) * q_intrp_tmp(px,:,v))
1091 q_intrp(:,:,kel_x,kel_y) = q_intrp_tmp2(:,:)
1101 p = px + (py-1)*nintglpt1d
1102 phi(p) = mod( k * int_x(px,kel_x) + l * int_y(py,kel_y), 2.0_rp * pi )
1105 cos_phi(:) = cos( phi(:) )
1106 sin_phi(:) = sin( phi(:) )
1109 spectral_coef(v,1,k,l) = spectral_coef(v,1,k,l) + sum(int_w(:) * cos_phi(:) * q_intrp(:,v,kel_x,kel_y))
1110 spectral_coef(v,2,k,l) = spectral_coef(v,2,k,l) - sum(int_w(:) * sin_phi(:) * q_intrp(:,v,kel_x,kel_y))
1118 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 / Data / base
module FElib / Mesh / Base 1D
module FElib / Mesh / Base 2D
module FElib / Mesh / Rectangle 2D domain
module FElib / Data / base
Module common / Polynomial.
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.
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 representing a local mesh for 1D domain.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type representing a field with 1D local mesh.
Derived type to manage a computational mesh (base type for 1D domain)
Derived type to manage a computational mesh (base type for 2D domain)
Derived type to manage a rectangular 2D computational domain.
Derived type representing a field with 1D mesh.
Derived type representing a field with 2D mesh.