51 use hsmg, only : mg_fld
52 use tstep, only : ifield
56 if (ifield > 1) mg_fld = 2
75 use size_m
, only : nx1, ny1, nz1, nelt
76 use hsmg, only : mg_h1_lmax
77 use input, only : param
80 integer :: p_msk, n, l
113 use size_m
, only : lx1, ly1, lz1, lelt
114 use hsmg, only : mg_h1_lmax, mg_h1_n, p_mg_msk, mg_imask, mg_fld
115 use tstep, only : nelfld, ifield
119 real(DP),
intent(out) :: z(*) !>
120 real(DP),
intent(in) :: rhs(*) !>
121 logical,
intent(in) :: if_hybrid !>
123 integer,
parameter :: lt=lx1*ly1*lz1*lelt
124 real(DP),
allocatable :: e(:),w(:),r(:)
127 real(DP) :: op, om, sigma
128 integer :: nel, l, n, is, im, i1, i
140 if (if_hybrid) sigma = 2./3.
143 n = mg_h1_n(l,mg_fld)
150 h1mg_mop = h1mg_mop + 2*n
155 h1mg_mop = h1mg_mop + 2*lt
156 allocate(e(2*lt)); e = 0_dp
157 do l = mg_h1_lmax-1,2,-1
159 n = mg_h1_n(l,mg_fld)
176 p_msk = p_mg_msk(l,mg_fld)
180 call
h1mg_mask(e(is),mg_imask(p_msk),nel)
184 h1mg_mop = h1mg_mop + lt
185 allocate(w(lt)); w = 0_dp
186 do l = 2,mg_h1_lmax-1
189 n = mg_h1_n(l,mg_fld)
192 h1mg_flop = h1mg_flop + n
193 h1mg_mop = h1mg_mop + 3*n
195 e(i1+i) = e(i1+i) + w(i)
200 n = mg_h1_n(l,mg_fld)
203 h1mg_flop = h1mg_flop + n
204 h1mg_mop = h1mg_mop + 3*n
223 use input, only : if3d
224 use hsmg, only : mg_zh, mg_lmax, mg_ah, mg_bh, mg_dh, mg_dht, mg_zh
225 use hsmg, only : mg_nx, mg_nh, mg_nhz, mg_nz
226 use semhat, only : ah, bh, ch, dh, zh, dph, jph, bgl, zgl, dgl, jgl, wh
233 call
generate_semhat(ah,bh,ch,dh,zh,dph,jph,bgl,zgl,dgl,jgl,n,wh)
234 call
copy(mg_zh(1,mg_lmax),zgl,n-1)
237 if( .NOT. if3d) mg_nhz(mg_lmax)=1
242 call
generate_semhat(ah,bh,ch,dh,zh,dph,jph,bgl,zgl,dgl,jgl,n,wh)
243 call
copy(mg_ah(1,l),ah,(n+1)*(n+1))
244 call
copy(mg_bh(1,l),bh,n+1)
245 call
copy(mg_dh(1,l),dh,(n+1)*(n+1))
247 call
copy(mg_zh(1,l),zh,n+1)
259 use hsmg, only : mg_lmax, mg_nh, mg_jh, mg_zh, mg_jht
271 mg_jh(1,l),mg_zh(1,l+1),mg_zh(1,l),nf,nc)
272 call
transpose(mg_jht(1,l),nc,mg_jh(1,l),nf)
286 use size_m
, only : lx1
289 real(DP) :: jh(nf,nc),zf(*),zc(*)
290 real(DP) :: w(2*lx1+2)
305 use size_m
, only : lx1, ly1, lz1, lelv, nelv, ndim
306 use input, only : if3d
307 use hsmg, only : mg_lmax, mg_nh, mg_nhz, mg_fld
308 use hsmg, only : mg_gsh_handle, mg_gsh_schwarz_handle
309 use mesh, only : vertex
313 integer,
parameter :: lxyz=(lx1+2)*(ly1+2)*(lz1+2)
315 integer(i8),
allocatable :: glo_num(:)
316 integer :: nx,ny,nz, ncrnr
324 allocate(glo_num(lxyz*lelv))
330 call
setupds(mg_gsh_handle(l,mg_fld),nx,ny,nz &
331 ,nelv,nelgv,vertex,glo_num)
336 call
setupds(mg_gsh_schwarz_handle(l,mg_fld),nx,ny,nz &
337 ,nelv,nelgv,vertex,glo_num)
344 use size_m
, only : ndim, ldim, nelv, lelv
345 use hsmg, only : mg_mask_index, mg_lmax, mg_rstr_wt_index, mg_nh, mg_nhz
346 use hsmg, only : mg_fld, lmgs, lmg_rwt, mg_rstr_wt
349 real(DP),
allocatable :: work(:)
352 allocate(work(maxval(mg_nh(1:mg_lmax))*maxval(mg_nh(1:mg_lmax))*maxval(mg_nhz(1:mg_lmax))* nelv))
354 i = mg_mask_index(mg_lmax,mg_fld-1)
356 mg_rstr_wt_index(l,mg_fld)=i
357 mg_mask_index(l,mg_fld)=i
358 i=i+mg_nh(l)*mg_nhz(l)*2*ndim*nelv
359 if(i > lmgs*lmg_rwt*2*ldim*lelv)
then
360 itmp = i/(2*ldim*lelv)
361 write(6,*)
'parameter lmg_rwt too small',i,itmp,lmg_rwt
365 , mg_nh(l),mg_nh(l),mg_nhz(l),l, work)
369 mg_mask_index(l,mg_fld)=i
376 use size_m
, only : ndim, ldim, nelv, lelv
377 use hsmg, only : mg_mask_index, mg_lmax, mg_rstr_wt_index, mg_nh, mg_nhz
378 use hsmg, only : lmgs, lmg_rwt, mg_rstr_wt, mg_fld
381 real(DP),
allocatable :: work(:)
384 allocate(work(maxval(mg_nh(1:mg_lmax-1)) &
385 *maxval(mg_nh(1:mg_lmax-1)) &
386 *maxval(mg_nhz(1:mg_lmax-1))* nelv))
388 i = mg_mask_index(mg_lmax,mg_fld-1)
390 mg_rstr_wt_index(l,mg_fld)=i
391 mg_mask_index(l,mg_fld)=i
392 i=i+mg_nh(l)*mg_nhz(l)*2*ndim*nelv
393 if(i > lmgs*lmg_rwt*2*ldim*lelv)
then
394 itmp = i/(2*ldim*lelv)
395 write(6,*)
'parameter lmg_rwt too small',i,itmp,lmg_rwt
399 , mg_nh(l),mg_nh(l),mg_nhz(l),l,work)
403 mg_mask_index(l,mg_fld)=i
409 use hsmg, only : mg_nh, mg_jh, mg_jht
411 real(DP) :: uf(*),uc(*)
413 call
hsmg_tnsr(uf,mg_nh(l+1),uc,mg_nh(l),mg_jh(1,l),mg_jht(1,l))
421 use input, only : if3d
425 real(DP) :: v(*),u(*),A(*),At(*)
427 if ( .NOT. if3d)
then
439 use ctimer, only : h1mg_flop, h1mg_mop
444 real(DP) :: v(nv*nv*nv,nelv),u(nu*nu*nu,nelv),A(*),Bt(*),Ct(*)
446 integer,
parameter :: lwk=(lx1+2)*(ly1+2)*(lz1+2)
447 real(DP) :: work(0:lwk-1),work2(0:lwk-1)
450 h1mg_flop = h1mg_flop + nelv * nv * (2*nu - 1) * nu * nu
451 h1mg_flop = h1mg_flop + nelv * nv * nv * (2*nu - 1) * nu
452 h1mg_flop = h1mg_flop + nelv * nv * nv * nv * (2*nu - 1)
453 h1mg_mop = h1mg_mop + nv**3 + nu**3
456 call
mxm(a,nv,u(1,ie),nu,work,nu*nu)
458 call
mxm(work(nv*nu*i),nv,bt,nu,work2(nv*nv*i),nv)
460 call
mxm(work2,nv*nv,ct,nu,v(1,ie),nv)
469 use ctimer, only : schw_flop, schw_mop
470 use size_m
, only : lx1, ly1, lz1
474 real(DP) :: v(nv*nv*nv),u(nu*nu*nu),A(*),Bt(*),Ct(*)
476 integer,
parameter :: lwk=(lx1+2)*(ly1+2)*(lz1+2)
477 real(DP) :: work(0:lwk-1),work2(0:lwk-1)
480 schw_flop = schw_flop + nv*nu*nu*(2*nu-1)+ nv*nv*nu*(2*nu-1)+ nv*nv*nv*(2*nu-1)
481 schw_mop = schw_mop + nu**3 + nv**3
483 call
mxm(a,nv,u,nu,work,nu*nu)
485 call
mxm(work(nv*nu*i),nv,bt,nu,work2(nv*nv*i),nv)
487 call
mxm(work2,nv*nv,ct,nu,v,nv)
496 use hsmg, only : mg_gsh_handle, mg_fld
505 call
gs_op(mg_gsh_handle(l,mg_fld),u,1,1,0)
517 use hsmg, only : mg_gsh_handle, mg_fld
524 call
gs_op(mg_gsh_handle(l,mg_fld),u,1,2,0)
532 use hsmg, only : mg_gsh_schwarz_handle, mg_fld
541 call
gs_op(mg_gsh_schwarz_handle(l,mg_fld),u,1,1,0)
551 use size_m
, only : nelv
552 use ctimer, only : schw_flop, schw_mop
553 use input, only : if3d
556 integer :: l1,l2,nx,ny,nz
557 real(DP) :: arr1(nx,ny,nz,nelv),arr2(nx,ny,nz,nelv)
560 integer :: i,j,k,ie,i0,i1
567 arr1(l1+1 ,j,1,ie) = f1*arr1(l1+1 ,j,1,ie) &
568 +f2*arr2(l2+1 ,j,1,ie)
569 arr1(nx-l1,j,1,ie) = f1*arr1(nx-l1,j,1,ie) &
570 +f2*arr2(nx-l2,j,1,ie)
573 arr1(i,l1+1 ,1,ie) = f1*arr1(i,l1+1 ,1,ie) &
574 +f2*arr2(i,l2+1 ,1,ie)
575 arr1(i,ny-l1,1,ie) = f1*arr1(i,ny-l1,1,ie) &
576 +f2*arr2(i,nx-l2,1,ie)
580 schw_flop = schw_flop + nelv * 3 * (nx-2)**2 * 6
582 schw_mop = schw_mop + 2 * nelv * nx*ny*nz
584 schw_mop = schw_mop + 2 * nelv * nx*ny*(nz-2)
587 schw_mop = schw_mop + nelv * nx*ny*nz
589 schw_mop = schw_mop + nelv * nx*ny*(nz-2)
596 arr1(i,j,l1+1 ,ie) = f1*arr1(i,j,l1+1 ,ie) &
597 +f2*arr2(i,j,l2+1 ,ie)
602 arr1(i,l1+1 ,k,ie) = f1*arr1(i,l1+1 ,k,ie) &
603 +f2*arr2(i,l2+1 ,k,ie)
606 arr1(l1+1 ,j,k,ie) = f1*arr1(l1+1 ,j,k,ie) &
607 +f2*arr2(l2+1 ,j,k,ie)
608 arr1(nx-l1,j,k,ie) = f1*arr1(nx-l1,j,k,ie) &
609 +f2*arr2(nx-l2,j,k,ie)
612 arr1(i,nx-l1,k,ie) = f1*arr1(i,nx-l1,k,ie) &
613 +f2*arr2(i,nx-l2,k,ie)
618 arr1(i,j,nx-l1,ie) = f1*arr1(i,j,nx-l1,ie) &
619 +f2*arr2(i,j,nx-l2,ie)
630 use hsmg, only : mg_h1_n, mg_fld
634 real(DP) :: e(*),r(*)
635 real(DP),
intent(in) :: sigma
640 n = mg_h1_n(l,mg_fld)
641 schw_flop = schw_flop + n
642 schw_mop = schw_mop + 2*n
649 e(1:n) = e(1:n) * sigma
660 use size_m
, only : nelv
661 use input, only : if3d
662 use hsmg, only : mg_h1_n, p_mg_msk, mg_imask, mg_nh, mg_fld
664 use tstep, only : ifield, nelfld
667 real(DP) :: e(*),r(*)
670 integer :: enx,eny,enz,pm, n, i, l
671 real(DP) :: zero, one, onem
672 real(DP),
allocatable :: work(:)
680 n = mg_h1_n(l,mg_fld)
681 pm = p_mg_msk(l,mg_fld)
687 call
h1mg_mask(r,mg_imask(pm),nelfld(ifield))
689 allocate(work(2*enx*eny*enz*nelv))
697 if( .NOT. if3d) enz=1
698 i = enx*eny*enz*nelv+1
712 call
hsmg_extrude(work,0,zero,work(i),0,one ,enx,eny,enz)
718 call
hsmg_extrude(work(i),0,one ,work,0,onem,enx,eny,enz)
719 call
hsmg_extrude(work(i),2,one,work(i),0,one,enx,eny,enz)
733 call
h1mg_mask(e,mg_imask(pm),nelfld(ifield))
735 tschw = tschw - etime
743 use ctimer, only : schw_mop
744 use size_m
, only : nelv
747 real(DP) :: a(0:n+1,0:n+1,0:n+1,nelv),b(n,n,n,nelv)
750 schw_mop = schw_mop + nelv*((n+2)**3 + n**3)
758 a(i,j,k,ie)=b(i,j,k,ie)
760 a(n+1,j,k,ie) = 0._dp
762 a(:,n+1,k,ie) = 0._dp
764 a(:,:,n+1,ie) = 0._dp
772 use ctimer, only : schw_mop
773 use size_m
, only : nelv
777 real(DP) :: a(0:n+1,0:n+1,0:n+1,nelv),b(n,n,n,nelv)
780 schw_mop = schw_mop + nelv*n**3 + nelv * (n+2)**3
786 b(i,j,k,ie)=a(i,j,k,ie)
796 use size_m
, only : ndim, ldim, nelv, lelv
797 use hsmg, only : mg_fast_d_index, mg_fast_s_index, mg_nx, mg_bh, mg_ah
798 use hsmg, only : mg_fast_d, mg_fast_s, lmg_fastd, lmg_fasts, mg_nh, mg_fld
799 use hsmg, only : mg_lmax
802 integer :: l,i,j,nl, itmp
803 i = mg_fast_s_index(mg_lmax,mg_fld-1)
804 j = mg_fast_d_index(mg_lmax,mg_fld-1)
806 mg_fast_s_index(l,mg_fld)=i
808 i=i+nl*nl*2*ndim*nelv
809 if(i > lmg_fasts*2*ldim*lelv)
then
810 itmp = i/(2*ldim*lelv)
811 write(6,*)
'lmg_fasts too small',i,itmp,lmg_fasts,l
814 mg_fast_d_index(l,mg_fld)=j
816 if(j > lmg_fastd*lelv)
then
817 itmp = i/(2*ldim*lelv)
818 write(6,*)
'lmg_fastd too small',i,itmp,lmg_fastd,l
822 mg_fast_s(mg_fast_s_index(l,mg_fld)) &
823 ,mg_fast_d(mg_fast_d_index(l,mg_fld)) &
824 ,mg_nh(l)+2,mg_ah(1,l),mg_bh(1,l),mg_nx(l))
826 mg_fast_s_index(l,mg_fld)=i
827 mg_fast_d_index(l,mg_fld)=j
833 use size_m
, only : ndim, ldim, nelv, lelv
834 use hsmg, only : mg_fast_d_index, mg_fast_s_index, mg_nx, mg_bh, mg_ah
835 use hsmg, only : mg_fast_d, mg_fast_s, lmg_fastd, lmg_fasts, mg_nh
836 use hsmg, only : mg_lmax, mg_fld
839 integer :: l,i,j,nl, itmp
840 i = mg_fast_s_index(mg_lmax,mg_fld-1)
841 j = mg_fast_d_index(mg_lmax,mg_fld-1)
843 mg_fast_s_index(l,mg_fld)=i
845 i=i+nl*nl*2*ndim*nelv
846 if(i > lmg_fasts*2*ldim*lelv)
then
847 itmp = i/(2*ldim*lelv)
848 write(6,*)
'lmg_fasts too small',i,itmp,lmg_fasts,l
851 mg_fast_d_index(l,mg_fld)=j
853 if(j > lmg_fastd*lelv)
then
854 itmp = i/(2*ldim*lelv)
855 write(6,*)
'lmg_fastd too small',i,itmp,lmg_fastd,l
859 mg_fast_s(mg_fast_s_index(l,mg_fld)) &
860 ,mg_fast_d(mg_fast_d_index(l,mg_fld)) &
861 ,mg_nh(l)+2,mg_ah(1,l),mg_bh(1,l),mg_nx(l))
863 mg_fast_s_index(l,mg_fld)=i
864 mg_fast_d_index(l,mg_fld)=j
872 use hsmg, only : lr, llr, lrr, lmr, ls, lls, lms, lrs, lt, llt, lmt, lrt
873 use size_m
, only : nid, ndim, nelv
874 use input, only : if3d
878 real(DP) :: s(nl*nl,2,ndim,nelv)
879 real(DP) :: d(nl**ndim,nelv)
880 real(DP) :: ah(1),bh(1)
884 integer :: ie,il,nr,ns,nt
885 integer :: lbr,rbr,lbs,rbs,lbt,rbt,two
886 integer :: ierr, ierrmx
887 integer,
external :: iglmax
893 call
get_fast_bc(lbr,rbr,lbs,rbs,lbt,rbt,ie,two,ierr)
898 ,llr(ie),lmr(ie),lrr(ie),ah,bh,n,ie)
900 ,lls(ie),lms(ie),lrs(ie),ah,bh,n,ie)
902 ,llt(ie),lmt(ie),lrt(ie),ah,bh,n,ie)
905 eps = 1.e-5*(maxval(lr(2:nr-1)) + maxval(ls(2:ns-1)))
921 eps = 1.e-5 * (maxval(lr(2:nr-1)) &
922 + maxval(ls(2:ns-1)) + maxval(lt(2:nt-1)))
926 diag = lr(i)+ls(j)+lt(k)
942 ierrmx = iglmax(ierr,1)
944 if (ierr > 0)
write(6,*) nid,ierr,
' BC FAIL'
945 call
exitti(
'A INVALID BC FOUND in genfast$',ierrmx)
952 subroutine hsmg_setup_fast1d(s,lam,nl,lbc,rbc,ll,lm,lr,ah,bh,n,ie)
954 use size_m
, only : lx1
957 integer :: nl,lbc,rbc,n, ie
958 real(DP) :: s(nl,nl,2),lam(nl),ll,lm,lr
959 real(DP) :: ah(0:n,0:n),bh(0:n)
961 integer,
parameter :: lxm=lx1+2
962 real(DP) :: b(2*lxm*lxm),w(2*lxm*lxm)
969 if(lbc > 0) call
row_zero(s,nl,nl,1)
970 if(lbc == 1) call
row_zero(s,nl,nl,2)
971 if(rbc > 0) call
row_zero(s,nl,nl,nl)
972 if(rbc == 1) call
row_zero(s,nl,nl,nl-1)
984 real(DP) :: a(0:n+2,0:n+2),ll,lm,lr
985 real(DP) :: ah(0:n,0:n)
1000 a(i+1,j+1)=fac*ah(i,j)
1005 a(0,0)=fac*ah(n-1,n-1)
1006 a(1,0)=fac*ah(n ,n-1)
1007 a(0,1)=fac*ah(n-1,n )
1008 a(1,1)=a(1,1)+fac*ah(n ,n )
1014 a(n+1,n+1)=a(n+1,n+1)+fac*ah(0,0)
1015 a(n+2,n+1)=fac*ah(1,0)
1016 a(n+1,n+2)=fac*ah(0,1)
1017 a(n+2,n+2)=fac*ah(1,1)
1026 use kinds, only : dp
1029 integer :: lbc,rbc,n
1030 real(DP) :: b(0:n+2,0:n+2),ll,lm,lr
1045 b(i+1,i+1)=fac*bh(i)
1050 b(1,1)=b(1,1)+fac*bh(n )
1056 b(n+1,n+1)=b(n+1,n+1)+fac*bh(0)
1057 b(n+2,n+2)=fac*bh(1)
1067 use kinds, only : dp
1068 use hsmg, only : mg_fast_s, mg_fast_d, mg_fast_s_index, mg_fast_d_index
1069 use hsmg, only : mg_nh, mg_fld
1071 real(DP) :: e(*), r(*)
1074 mg_fast_s(mg_fast_s_index(l,mg_fld)), &
1075 mg_fast_d(mg_fast_d_index(l,mg_fld)), &
1083 use kinds, only : dp
1084 use size_m
, only : ndim, nelv
1085 use size_m
, only : lx1, ly1, lz1
1086 use ctimer, only : schw_flop, schw_mop
1087 use input, only : if3d
1091 real(DP) :: e(nl**ndim,nelv)
1092 real(DP) :: r(nl**ndim,nelv)
1093 real(DP) :: s(nl*nl,2,ndim,nelv)
1094 real(DP) :: d(nl**ndim,nelv)
1098 integer,
parameter :: lwk=(lx1+2)*(ly1+2)*(lz1+2)
1099 real(DP) :: work(0:lwk-1),work2(0:lwk-1)
1102 if( .NOT. if3d)
then
1105 call hsmg_tnsr2d_el(e(1,ie),nl,r(1,ie),nl &
1106 ,s(1,2,1,ie),s(1,1,2,ie))
1108 r(i,ie)=d(i,ie)*e(i,ie)
1110 call hsmg_tnsr2d_el(e(1,ie),nl,r(1,ie),nl &
1111 ,s(1,1,1,ie),s(1,2,2,ie))
1115 schw_flop = schw_flop + nelv*nn
1116 schw_mop = schw_mop + nelv*nn
1119 schw_flop = schw_flop + 3*nn*(2*nl-1)
1120 schw_mop = schw_mop + nn + 3*nl*nl
1122 call
mxm(s(1,2,1,ie),nl,r(1,ie),nl,work,nl*nl)
1124 call
mxm(work(nl*nl*i),nl,s(1,1,2,ie),nl,work2(nl*nl*i),nl)
1126 call
mxm(work2,nl*nl,s(1,1,3,ie),nl,work,nl)
1129 work2(i)=d(i+1,ie)*work(i)
1132 schw_flop = schw_flop + 3*nn*(2*nl-1)
1133 schw_mop = schw_mop + 1*nn + 3*nl*nl
1135 call
mxm(s(1,1,1,ie),nl,work2,nl,work,nl*nl)
1137 call
mxm(work(nl*nl*i),nl,s(1,2,2,ie),nl,work2(nl*nl*i),nl)
1139 call
mxm(work2,nl*nl,s(1,2,3,ie),nl,e(1,ie),nl)
1149 use kinds, only : dp
1150 use size_m
, only : nelv, ndim
1151 use ctimer, only : h1mg_flop, h1mg_mop
1152 use input, only : if3d
1156 real(DP) :: u(nx,ny,nz,nelv)
1157 real(DP) :: wt(nx,nz,2,ndim,nelv)
1159 integer :: i, j, k, ie
1171 if ( .NOT. if3d)
then
1174 u( 1,j,1,ie)=u( 1,j,1,ie)*wt(j,1,1,1,ie)
1175 u(nx,j,1,ie)=u(nx,j,1,ie)*wt(j,1,2,1,ie)
1178 u(i, 1,1,ie)=u(i, 1,1,ie)*wt(i,1,1,2,ie)
1179 u(i,ny,1,ie)=u(i,ny,1,ie)*wt(i,1,2,2,ie)
1183 h1mg_flop = h1mg_flop + 2*nelv*nz*ny + 2*nelv*nz*(nx-2) + 2*nelv*(ny-2)*(nx-2)
1184 h1mg_mop = h1mg_mop + 6*nelv*nz*ny + 6*nelv*nz*(nx-2) + 6*nelv*(ny-2)*(nx-2)
1189 u( 1,j,k,ie)=u( 1,j,k,ie)*wt(j,k,1,1,ie)
1190 u(nx,j,k,ie)=u(nx,j,k,ie)*wt(j,k,2,1,ie)
1195 u(i, 1,k,ie)=u(i, 1,k,ie)*wt(i,k,1,2,ie)
1196 u(i,ny,k,ie)=u(i,ny,k,ie)*wt(i,k,2,2,ie)
1201 u(i,j, 1,ie)=u(i,j, 1,ie)*wt(i,j,1,3,ie)
1202 u(i,j,nz,ie)=u(i,j,nz,ie)*wt(i,j,2,3,ie)
1212 use kinds, only : dp
1213 use size_m
, only : nelv, ndim
1214 use input, only : if3d
1217 integer,
intent(in) :: nx,ny,nz,l
1218 real(DP),
intent(out) :: w(nx,ny,nz,nelv)
1219 real(DP),
intent(out) :: wt(nx,nz,2,ndim,nelv)
1221 integer :: ie, i, j, k
1225 if ( .NOT. if3d)
then
1260 if ( .NOT. if3d)
then
1263 wt(j,1,1,1,ie)=1.0/w(1,j,1,ie)
1264 wt(j,1,2,1,ie)=1.0/w(nx,j,1,ie)
1267 wt(i,1,1,2,ie)=1.0/w(i,1,1,ie)
1268 wt(i,1,2,2,ie)=1.0/w(i,ny,1,ie)
1275 wt(j,k,1,1,ie)=1.0/w(1,j,k,ie)
1276 wt(j,k,2,1,ie)=1.0/w(nx,j,k,ie)
1281 wt(i,k,1,2,ie)=1.0/w(i,1,k,ie)
1282 wt(i,k,2,2,ie)=1.0/w(i,ny,k,ie)
1287 wt(i,j,1,3,ie)=1.0/w(i,j,1,ie)
1288 wt(i,j,2,3,ie)=1.0/w(i,j,nz,ie)
1298 use size_m
, only : ndim, nelv, ldim, lelv
1299 use input, only : if3d
1300 use hsmg, only : mg_schwarz_wt_index, mg_lmax, mg_fld
1301 use hsmg, only : mg_nh, lmg_swt, mg_schwarz_wt
1306 integer :: l,i,nl,nlz, itmp
1308 i = mg_schwarz_wt_index(mg_lmax,mg_fld-1)
1310 mg_schwarz_wt_index(l,mg_fld)=i
1313 if( .NOT. if3d) nlz=1
1314 i=i+nl*nlz*4*ndim*nelv
1315 if(i > lmg_swt*4*ldim*lelv)
then
1316 itmp = i/(4*ldim*lelv)
1317 write(6,*)
'lmg_swt too small',i,itmp,lmg_swt,l
1322 mg_schwarz_wt(mg_schwarz_wt_index(l,mg_fld)),l,ifsqrt)
1325 mg_schwarz_wt_index(l,mg_fld)=i
1332 use size_m
, only : ndim, ldim, nelv, lelv
1333 use hsmg, only : mg_schwarz_wt_index, mg_schwarz_wt, mg_lmax, mg_fld
1334 use hsmg, only : mg_nh, mg_nhz, lmg_swt
1339 integer :: l,i,nl,nlz, itmp
1341 i = mg_schwarz_wt_index(mg_lmax,mg_fld-1)
1344 mg_schwarz_wt_index(l,mg_fld)=i
1347 i = i+nl*nlz*4*ndim*nelv
1349 if (i > lmg_swt*4*ldim*lelv)
then
1350 itmp = i/(4*ldim*lelv)
1351 write(6,*)
'lmg_swt too small',i,itmp,lmg_swt,l
1356 mg_schwarz_wt(mg_schwarz_wt_index(l,mg_fld)),l,ifsqrt)
1360 mg_schwarz_wt_index(l,mg_fld)=i
1367 use kinds, only : dp
1368 use input, only : if3d
1369 use hsmg, only : mg_schwarz_wt, mg_schwarz_wt_index, mg_fld, mg_nh
1375 if( .NOT. if3d) call hsmg_schwarz_wt2d( &
1376 e,mg_schwarz_wt(mg_schwarz_wt_index(l,mg_fld)),mg_nh(l))
1379 e,mg_schwarz_wt(mg_schwarz_wt_index(l,mg_fld)),mg_nh(l))
1385 use kinds, only : dp
1386 use size_m
, only : nelv
1387 use ctimer, only : schw_flop, schw_mop
1391 real(DP) :: e(n,n,n,nelv)
1392 real(DP) :: wt(n,n,4,3,nelv)
1395 schw_flop = schw_flop + 4*nelv*n*n + 4*nelv*n*(n-4) + 4*nelv*(n-4)*(n-4)
1396 schw_mop = schw_mop + 12*nelv*n*n + 2*nelv*n*n*n
1400 e(:,:,1 ,ie)=e(:,:,1 ,ie)*wt(:,:,1,3,ie)
1401 e(:,:,2 ,ie)=e(:,:,2 ,ie)*wt(:,:,2,3,ie)
1403 e(:,1 ,k,ie)=e(:,1 ,k,ie)*wt(:,k,1,2,ie)
1404 e(:,2 ,k,ie)=e(:,2 ,k,ie)*wt(:,k,2,2,ie)
1406 e(1 ,j,k,ie)=e(1 ,j,k,ie)*wt(j,k,1,1,ie)
1407 e(2 ,j,k,ie)=e(2 ,j,k,ie)*wt(j,k,2,1,ie)
1408 e(n-1,j,k,ie)=e(n-1,j,k,ie)*wt(j,k,3,1,ie)
1409 e(n ,j,k,ie)=e(n ,j,k,ie)*wt(j,k,4,1,ie)
1411 e(:,n-1,k,ie)=e(:,n-1,k,ie)*wt(:,k,3,2,ie)
1412 e(:,n ,k,ie)=e(:,n ,k,ie)*wt(:,k,4,2,ie)
1414 e(:,:,n-1,ie)=e(:,:,n-1,ie)*wt(:,:,3,3,ie)
1415 e(:,:,n ,ie)=e(:,:,n ,ie)*wt(:,:,4,3,ie)
1422 use kinds, only : dp
1425 use tstep, only : ifield
1427 use hsmg, only : use_spectral_coarse
1430 real(DP) :: e(:),r(:)
1432 if (icalld == 0)
then
1446 if (use_spectral_coarse)
then
1461 use size_m
, only : nelv, lelv
1462 use hsmg, only : mg_lmax, mg_nh, mg_nhz, lmg_solve, mg_fld, mg_solve_index
1465 integer :: l,i, itmp
1467 i = mg_solve_index(mg_lmax+1,mg_fld-1)
1469 mg_solve_index(l,mg_fld)=i
1470 i=i+mg_nh(l)*mg_nh(l)*mg_nhz(l)*nelv
1471 if(i > lmg_solve*lelv)
then
1473 write(6,*)
'lmg_solve too small',i,itmp,lmg_solve,l
1477 mg_solve_index(l,mg_fld)=i
1484 use size_m
, only : lx2, nx1, ly1, lz1, lx1, nid
1485 use input, only : if3d
1486 use hsmg, only : mg_lmax, mg_nz, mg_ny, mg_nx
1489 integer :: p82, mgnx1, mgnx2, i
1491 integer,
save :: mgn2(10) = (/ 1, 2, 2, 2, 2, 3, 3, 5, 5, 5/)
1498 if (lx1 == 4) mg_lmax = 2
1504 if ( .NOT. if3d) mg_nz(1) = 0
1506 mgnx2 = 2*(lx2/4) + 1
1507 if (lx1 == 5) mgnx2 = 3
1509 if (lx1 <= 10) mgnx2 = mgn2(nx1)
1510 if (lx1 == 8) mgnx2 = 4
1511 if (lx1 == 8) mgnx2 = 3
1518 if ( .NOT. if3d) mg_nz(2) = 0
1523 if ( .NOT. if3d) mg_nz(3) = 0
1525 mg_nx(mg_lmax) = lx1-1
1526 mg_ny(mg_lmax) = ly1-1
1527 mg_nz(mg_lmax) = lz1-1
1529 if (nid == 0)
write(*,*)
'mg_nx:',(mg_nx(i),i=1,mg_lmax)
1530 if (nid == 0)
write(*,*)
'mg_ny:',(mg_ny(i),i=1,mg_lmax)
1531 if (nid == 0)
write(*,*)
'mg_nz:',(mg_nz(i),i=1,mg_lmax)
1539 use hsmg, only : mg_rstr_wt_index, mg_solve_index, lmgn, lmgs
1540 use hsmg, only : mg_fast_s_index, mg_fast_d_index, mg_schwarz_wt_index
1541 use hsmg, only : mg_mask_index
1548 mg_rstr_wt_index = 0
1552 mg_schwarz_wt_index = 0
1559 use kinds, only : dp
1570 nmg_mask = nmg_mask + 1
1576 tmg_mask = tmg_mask + (
dnekclock() - etime)
1582 subroutine mg_mask_e(w,mask) ! Zero out Dirichlet conditions
1583 use kinds, only : dp
1587 integer :: mask(0:1)
1601 use kinds, only : dp
1602 use input, only : if3d
1606 real(DP) :: v(1),A(1),At(1)
1608 if ( .NOT. if3d)
then
1619 use kinds, only : dp
1620 use ctimer, only : h1mg_flop, h1mg_mop
1621 use size_m
, only : lx1, ly1, lz1, nelv
1625 real(DP) :: v(*),A(*),Bt(*),Ct(*)
1627 integer,
parameter :: lwk=(lx1+2)*(ly1+2)*(lz1+2)
1628 real(DP) :: work(0:lwk-1),work2(0:lwk-1)
1629 integer :: e,e0,ee,es
1630 integer :: nu3, nv3, iu, iv, i
1645 h1mg_flop = h1mg_flop + nelv * nv * (2*nu - 1) * nu * nu
1646 h1mg_flop = h1mg_flop + nelv * nv * nv * (2*nu - 1) * nu
1647 h1mg_flop = h1mg_flop + nelv * nv * nv * nv * (2*nu - 1)
1648 h1mg_mop = h1mg_mop + nv3 + nu3
1653 call
mxm(a,nv,v(iu),nu,work,nu*nu)
1655 call
mxm(work(nv*nu*i),nv,bt,nu,work2(nv*nv*i),nv)
1657 call
mxm(work2,nv*nv,ct,nu,v(iv),nv)
1666 use kinds, only : dp
1667 use hsmg, only : mg_rstr_wt, mg_rstr_wt_index, mg_nh, mg_nhz, mg_jht
1668 use hsmg, only : mg_jh, mg_fld
1674 call
hsmg_do_wt(r,mg_rstr_wt(mg_rstr_wt_index(l+1,mg_fld)) &
1675 ,mg_nh(l+1),mg_nh(l+1),mg_nhz(l+1))
1677 call
hsmg_tnsr1(r,mg_nh(l),mg_nh(l+1),mg_jht(1,l),mg_jh(1,l))
1686 use size_m
, only : lx2, nx1, lx1, ly1, lz1, ldimt1, nid
1687 use input, only : if3d
1688 use hsmg, only : mg_h1_n, mg_lmax, mg_h1_lmax, mg_nz, mg_ny, mg_nx
1689 use tstep, only : nelfld
1692 integer :: mgn2(10) = (/ 1, 2, 2, 2, 2, 3, 3, 5, 5, 5/)
1693 integer :: p82, mgnx1, mgnx2, i, ifld, l
1700 if (lx1 == 4) mg_h1_lmax = 2
1706 if ( .NOT. if3d) mg_nz(1) = 0
1708 mgnx2 = 2*(lx2/4) + 1
1709 if (lx1 == 5) mgnx2 = 3
1711 if (lx1 <= 10) mgnx2 = mgn2(nx1)
1712 if (lx1 == 8) mgnx2 = 4
1713 if (lx1 == 8) mgnx2 = 3
1715 mgnx2 = min(3,mgnx2)
1720 if ( .NOT. if3d) mg_nz(2) = 0
1725 if ( .NOT. if3d) mg_nz(3) = 0
1727 mg_nx(mg_h1_lmax) = lx1-1
1728 mg_ny(mg_h1_lmax) = ly1-1
1729 mg_nz(mg_h1_lmax) = lz1-1
1731 if (nid == 0)
write(*,*)
'h1_mg_nx:',(mg_nx(i),i=1,mg_h1_lmax)
1732 if (nid == 0)
write(*,*)
'h1_mg_ny:',(mg_ny(i),i=1,mg_h1_lmax)
1733 if (nid == 0)
write(*,*)
'h1_mg_nz:',(mg_nz(i),i=1,mg_h1_lmax)
1737 mg_h1_n(l,ifld)=(mg_nx(l)+1) &
1739 *(mg_nz(l)+1)*nelfld(ifld)
1749 use hsmg, only : mg_h1_lmax, mg_nx, mg_ah, mg_bh, mg_dh, mg_dht, mg_zh
1750 use hsmg, only : mg_nh, mg_nhz, mg_nz
1751 use semhat, only : ah, bh, ch, dh, zh, dph, jph, bgl, zgl, dgl, jgl, wh
1758 call
generate_semhat(ah,bh,ch,dh,zh,dph,jph,bgl,zgl,dgl,jgl,n,wh)
1759 call
copy(mg_ah(1,l),ah,(n+1)*(n+1))
1760 call
copy(mg_bh(1,l),bh,n+1)
1761 call
copy(mg_dh(1,l),dh,(n+1)*(n+1))
1763 call
copy(mg_zh(1,l),zh,n+1)
1766 mg_nhz(l)=mg_nz(l)+1
1773 use kinds, only : i8
1774 use size_m
, only : lx1, ly1, lz1, lelt, nelv, ndim
1775 use input, only : if3d
1776 use hsmg, only : mg_lmax, mg_nh, mg_nhz, mg_fld
1777 use hsmg, only : mg_gsh_handle, mg_gsh_schwarz_handle
1778 use mesh, only : vertex
1782 integer,
parameter :: lxyz=(lx1+2)*(ly1+2)*(lz1+2)
1784 integer(i8),
allocatable :: glo_num(:)
1785 integer :: nx,ny,nz, ncrnr
1793 allocate(glo_num(lxyz*lelt))
1798 call
setupds(mg_gsh_handle(l,mg_fld),nx,ny,nz &
1799 ,nelv,nelgv,vertex,glo_num)
1803 if( .NOT. if3d) nz=1
1804 call
setupds(mg_gsh_schwarz_handle(l,mg_fld),nx,ny,nz &
1805 ,nelv,nelgv,vertex,glo_num)
1811 use kinds, only : dp
1812 use hsmg, only : mg_h1_lmax, p_mg_msk, mg_nh, mg_nhz, mg_imask
1813 use hsmg, only : mg_h1_n, mg_fld
1814 use tstep, only : ifield, nelfld
1817 integer :: p_msk, l0
1819 real(DP),
allocatable :: work(:)
1820 integer :: l, n, nx, ny, nz, nm
1822 p_mg_msk(l,mg_fld) = 0
1823 n = mg_h1_n(l,mg_fld)
1825 allocate(work(maxval(mg_nh(1:mg_h1_lmax))*maxval(mg_nh(1:mg_h1_lmax))*maxval(mg_nhz(1:mg_h1_lmax))*nelfld(ifield)))
1827 do l=mg_h1_lmax,1,-1
1832 p_msk = p_mg_msk(l,mg_fld)
1835 (mg_imask(p_msk),nm,nx,ny,nz,nelfld(ifield),l,work)
1837 if (l > 1) p_mg_msk(l-1,mg_fld)=p_mg_msk(l,mg_fld)+nm
1841 p_msk = p_mg_msk(l0,mg_fld)
1848 use kinds, only : dp
1849 use size_m
, only : nid
1850 use input, only : if3d
1854 integer :: nx,ny,nz,nel,l
1855 real(DP) :: w(nx,ny,nz,nel)
1857 integer :: e,count,ptr
1858 integer :: lbr,rbr,lbs,rbs,lbt,rbt,two
1859 integer :: nxyz, n, ierrmx, i, ierr, nm
1860 integer,
external :: iglmax
1862 real(DP) :: w_flat(nx*ny*nz)
1874 call
get_fast_bc(lbr,rbr,lbs,rbs,lbt,rbt,e,two,ierr)
1878 if (lbr == 1) call
facev(w,e,4,zero,nx,ny,nz)
1879 if (rbr == 1) call
facev(w,e,2,zero,nx,ny,nz)
1880 if (lbs == 1) call
facev(w,e,1,zero,nx,ny,nz)
1881 if (rbs == 1) call
facev(w,e,3,zero,nx,ny,nz)
1883 if (lbt == 1) call
facev(w,e,5,zero,nx,ny,nz)
1884 if (rbt == 1) call
facev(w,e,6,zero,nx,ny,nz)
1886 ierrmx = max(ierrmx,ierr)
1909 w_flat = reshape(w(:,:,:,e), (/nxyz/))
1911 if (w_flat(i) == 0)
then
1915 mask(ptr) = i + nxyz*(e-1)
1929 ierrmx = iglmax(ierrmx,1)
1930 if (ierrmx > 0)
then
1931 if (ierr > 0)
write(6,*) nid,ierr,
' BC FAIL h1'
1932 call
exitti(
'D INVALID BC FOUND in h1mg_setup_mask$',ierrmx)
1940 use kinds, only : dp
1941 use size_m
, only : ndim
1943 real(DP) :: wt(1),work(1)
1955 use kinds, only : dp
1956 use size_m
, only : nelv
1961 real(DP) :: wt(n,n,4,3,nelv)
1962 real(DP) :: work(n,n,n)
1964 integer :: i,j,k, ii, ierr
1969 wt(j,k,1,1,ie)=1.0/work(1,j,k)
1970 wt(j,k,2,1,ie)=1.0/work(2,j,k)
1971 wt(j,k,3,1,ie)=1.0/work(n-1,j,k)
1972 wt(j,k,4,1,ie)=1.0/work(n,j,k)
1977 wt(i,k,1,2,ie)=1.0/work(i,1,k)
1978 wt(i,k,2,2,ie)=1.0/work(i,2,k)
1979 wt(i,k,3,2,ie)=1.0/work(i,n-1,k)
1980 wt(i,k,4,2,ie)=1.0/work(i,n,k)
1985 wt(i,j,1,3,ie)=1.0/work(i,j,1)
1986 wt(i,j,2,3,ie)=1.0/work(i,j,2)
1987 wt(i,j,3,3,ie)=1.0/work(i,j,n-1)
1988 wt(i,j,4,3,ie)=1.0/work(i,j,n)
1996 wt(i,j,k,ii,ie)=sqrt(wt(i,j,k,ii,ie))
2008 use kinds, only : dp
2009 use input, only : if3d
2010 use hsmg, only : mg_h1_n, p_mg_msk, mg_nh, mg_fld
2011 use tstep, only : ifield, nelfld
2018 integer :: enx,eny,enz,pm, n, ns, i, nx, ny, nz, nxyz, k, ie
2019 real(DP) :: zero, one, onem
2020 real(DP),
allocatable :: work(:)
2026 n = mg_h1_n(l,mg_fld)
2027 pm = p_mg_msk(l,mg_fld)
2032 if( .NOT. if3d) enz=1
2033 ns = enx*eny*enz*nelfld(ifield)
2036 allocate(work(2*ns))
2037 work(1:ns) = 0._dp; work(i:i+ns-1) = 1._dp
2040 call
hsmg_extrude(work,0,zero,work(i),0,one ,enx,eny,enz)
2042 call
hsmg_extrude(work(i),0,one ,work,0,onem,enx,eny,enz)
2043 call
hsmg_extrude(work(i),2,one, work(i),0,one,enx,eny,enz)
2045 if( .NOT. if3d)
then
2057 if ( .NOT. if3d) nz=1
2060 do ie=1,nelfld(ifield)
subroutine h1mg_setup_wtmask
subroutine, public hsmg_setup()
Sets up hybrid Schwarz multi-grid preconditioner.
subroutine hsmg_setup_fast1d_a(a, lbc, rbc, ll, lm, lr, ah, n)
subroutine hsmg_tnsr1_3d(v, nv, nu, A, Bt, Ct)
compute v = [C (x) B (x) A] v (in-place)
subroutine row_zero(a, m, n, e)
zero the eth row of a
subroutine hsmg_setup_rstr_wt(wt, nx, ny, nz, l, w)
subroutine get_fast_bc(lbr, rbr, lbs, rbs, lbt, rbt, e, bsym, ierr)
subroutine hsmg_setup_fast1d_b(b, lbc, rbc, ll, lm, lr, bh, n)
subroutine hsmg_schwarz_toreg3d(b, a, n)
subroutine transpose(a, lda, b, ldb)
subroutine hsmg_dsprod(u, l)
subroutine hsmg_fdm(e, r, l)
clobbers r
subroutine mxm(a, n1, b, n2, c, n3)
Compute matrix-matrix product C = A*B.
subroutine hsmg_tnsr3d(v, nv, u, nu, A, Bt, Ct)
computes: v = [C (x) B (x) A] u .
subroutine hsmg_intp(uf, uc, l)
subroutine h1mg_schwarz_part1(e, r, l)
subroutine h1mg_setup_dssum
subroutine hsmg_schwarz_dssum(u, l)
Module containing data for HSMG.
subroutine geom_reset(icall)
Generate geometry data.
subroutine dsavg(u)
Take direct stiffness avg of u.
subroutine hsmg_index_0
initialize index sets
subroutine hsmg_setup_intp
subroutine hsmg_extrude(arr1, l1, f1, arr2, l2, f2, nx, ny, nz)
subroutine hsmg_setup_fast(s, d, nl, ah, bh, n)
not sure
subroutine hsmg_schwarz_wt3d(e, wt, n)
subroutine fd_weights_full(xx, x, n, m, c)
This routine evaluates the derivative based on all points in the stencils. It is more memory efficien...
subroutine hsmg_do_fast(e, r, s, d, nl)
clobbers r
real(dp) function dnekclock()
subroutine h1mg_setup_mask(mask, nm, nx, ny, nz, nel, l, w)
subroutine hsmg_schwarz_toext3d(a, b, n)
subroutine mg_set_msk(p_msk, l0)
subroutine h1mg_setup_fdm()
subroutine hsmg_setup_fast1d(s, lam, nl, lbc, rbc, ll, lm, lr, ah, bh, n, ie)
subroutine hsmg_do_wt(u, wt, nx, ny, nz)
u = wt .* u
subroutine, public h1mg_solve(z, rhs, if_hybrid)
Solve preconditioner: z = M rhs, where .
subroutine h1mg_schwarz(e, r, sigma, l)
subroutine, public spectral_solve(u, rhs)
subroutine h1mg_setup_mg_nx()
subroutine h1mg_setup_schwarz_wt3d_2(wt, ie, n, work, ifsqrt)
subroutine generalev(a, b, lam, n, w)
Solve the generalized eigenvalue problem A x = lam B x.
subroutine hsmg_setup_mg_nx()
subroutine h1mg_rstr(r, l, ifdssum)
r =J r, l is coarse level
subroutine h1mg_setup_schwarz_wt(ifsqrt)
subroutine setupds(gs_handle, nx, ny, nz, nel, melg, vertex, glo_num)
setup data structures for direct stiffness operations
subroutine h1mg_setup_semhat
SEM hat matrices for each level.
subroutine hsmg_setup_semhat
subroutine generate_semhat(a, b, c, d, z, dgll, jgll, bgl, zgl, dgl, jgl, n, w)
Generate matrices for single element, 1D operators:
subroutine h1mg_setup_schwarz_wt_1(wt, l, ifsqrt)
subroutine h1mg_setup_schwarz_wt_2(wt, ie, n, work, ifsqrt)
subroutine hsmg_setup_solve
subroutine, public h1mg_setup()
Sets up Poisson preconditioner.
subroutine h1mg_mask(w, mask, nel)
subroutine hsmg_coarse_solve(e, r)
subroutine hsmg_tnsr(v, nv, u, nu, A, At)
computes v = [A (x) A] u or v = [A (x) A (x) A] u
subroutine hsmg_dssum(u, l)
subroutine hsmg_setup_fdm()
subroutine hsmg_tnsr1(v, nv, nu, A, At)
compute v = [A (x) A] u or v = [A (x) A (x) A] u
subroutine hsmg_setup_wtmask
subroutine hsmg_setup_dssum
subroutine facev(a, ie, iface, val, nx, ny, nz)
Assign the value VAL to face(IFACE,IE) of array A. IFACE is the input in the pre-processor ordering s...
subroutine hsmg_setup_intpm(jh, zf, zc, nf, nc)
subroutine exitti(stringi, idata)
subroutine hsmg_tnsr3d_el(v, nv, u, nu, A, Bt, Ct)
computes v = [C (x) B (x) A] u
subroutine hsmg_setup_schwarz_wt(ifsqrt)
subroutine hsmg_schwarz_wt(e, l)
subroutine mg_mask_e(w, mask)