Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
navier8.F90
Go to the documentation of this file.
1 !-----------------------------------------------------------------------
4 subroutine set_vert(glo_num,ngv,nx,nel,vertex,ifcenter)
5  use kinds, only : i8
6  use size_m, only : nid
7  use input, only : if3d
8  implicit none
9 
10  integer(i8) :: glo_num(1),ngv
11  integer :: vertex(*),nx, nel
12  logical :: ifcenter
13 
14  integer :: nz
15 
16  if (if3d) then
17  call setvert3d(glo_num,ngv,nx,nel,vertex,ifcenter)
18  else
19 !max call setvert2d(glo_num,ngv,nx,nel,vertex,ifcenter)
20  endif
21 
22 ! Check for single-element periodicity 'p' bc
23  nz = 1
24  if (if3d) nz = nx
25  call check_p_bc(glo_num,nx,nx,nz,nel)
26 
27  if(nid == 0) write(6,*) 'call usrsetvert'
28  call usrsetvert(glo_num,nel,nx,nx,nx)
29  if(nid == 0) write(6,'(A,/)') ' done :: usrsetvert'
30 
31  return
32 end subroutine set_vert
33 
35 subroutine set_up_h1_crs
36  use kinds, only : dp, i8
37  use size_m, only : nx1, ny1, nz1, nelv, ndim, nid
38  use size_m, only : lx1, ly1, lz1, lelv
39  use ctimer, only : dnekclock
40  use domain, only : nx_crs, nxyz_c, se_to_gcrs, lcr
41  use geom, only : ifvcor, ifbcor
42  use input, only : if3d, ifldmhd, cbc
43  use mesh, only : vertex
44  use parallel, only : xxth, mp=>np, nekcomm
45  use tstep, only : ifield
46  implicit none
47 
48  integer :: gs_handle
49  integer :: null_space
50 
51  character(3) :: cb
52  real(DP) :: cmlt(lcr,lelv),mask(lcr,lelv)
53  integer, allocatable :: ia(:,:,:), ja(:,:,:)
54  real(DP) :: z
55 
56  real(DP), allocatable :: a(:)
57 
58  real(DP), allocatable :: h1(:), h2(:), w1(:), w2(:)
59 
60  integer(i8) :: ngv
61 
62  real(DP) :: t0
63  integer :: nxc, ncr, ntot, nzc, nfaces, ie, iface, nz, n
64 
65  allocate(ia(lcr,lcr,lelv), ja(lcr,lcr,lelv))
66  t0 = dnekclock()
67 
68 ! nxc is order of coarse grid space + 1, nxc=2, linear, 3=quad,etc.
69 ! nxc=param(82)
70 ! if (nxc.gt.lxc) then
71 ! nxc=lxc
72 ! write(6,*) 'WARNING :: coarse grid space too large',nxc,lxc
73 ! endif
74 ! if (nxc.lt.2) nxc=2
75 
76  nxc = 2
77  nx_crs = nxc
78 
79  if(nid == 0) write(6,*) 'setup h1 coarse grid, nx_crs=', nx_crs
80 
81  ncr = nxc**ndim
82  nxyz_c = ncr
83 
84 ! Set SEM_to_GLOB
85 
86  call get_vertex
87  call set_vert(se_to_gcrs,ngv,nxc,nelv,vertex, .true. )
88 
89 ! Set mask
90  z=0
91  ntot=nelv*nxyz_c
92  nzc=1
93  if (if3d) nzc=nxc
94  mask = 1._dp
95  cmlt = 1._dp
96  nfaces=2*ndim
97 ! ifield=1 !c? avo: set in set_overlap through 'TSTEP'?
98 
99  if (ifield == 1) then
100  do ie=1,nelv
101  do iface=1,nfaces
102  cb=cbc(iface,ie,ifield)
103  if (cb == 'O ' .OR. cb == 'ON ' .OR. cb == 'MM ' .OR. &
104  cb == 'mm ' .OR. cb == 'ms ' .OR. cb == 'MS ') &
105  call facev(mask,ie,iface,z,nxc,nxc,nzc) ! 'S* ' & 's* ' ?avo?
106  enddo
107  enddo
108  elseif (ifield == ifldmhd) then ! no ifmhd ?avo?
109  do ie=1,nelv
110  do iface=1,nfaces
111  cb=cbc(iface,ie,ifield)
112  if (cb == 'ndd' .OR. cb == 'dnd' .OR. cb == 'ddn') &
113  call facev(mask,ie,iface,z,nxc,nxc,nzc)
114  enddo
115  enddo
116  endif
117 
118 ! Set global index of dirichlet nodes to zero; xxt will ignore them
119 
120  call gs_setup(gs_handle,se_to_gcrs,ntot,nekcomm,mp)
121  call gs_op(gs_handle,mask,1,2,0) ! "*"
122  call gs_op(gs_handle,cmlt,1,1,0) ! "+"
123  call gs_free(gs_handle)
124  call set_jl_crs_mask(ntot,mask,se_to_gcrs)
125 
126  cmlt = 1._dp / cmlt
127 
128 ! Setup local SEM-based Neumann operators (for now, just full...)
129 
130 ! if (param(51).eq.1) then ! old coarse grid
131 ! nxyz1=nx1*ny1*nz1
132 ! lda = 27*nxyz1*lelt
133 ! ldw = 7*nxyz1*lelt
134 ! call get_local_crs(a,lda,nxc,h1,h2,w,ldw)
135 ! else
136 ! NOTE: a(),h1,...,w2() must all be large enough
137  n = nx1*ny1*nz1*nelv
138  allocate(h1(nx1*ny1*nz1*nelv),h2(nx1*ny1*nz1*nelv))
139  allocate(a(27*lx1*ly1*lz1*lelv))
140  allocate(w1(lx1*ly1*lz1*lelv),w2(lx1*ly1*lz1*lelv))
141  h1=1._dp; h2 = 0._dp
142  call get_local_crs_galerkin(a,ncr,nxc,h1,h2,w1,w2)
143  deallocate(h1,h2,w1,w2)
144 ! endif
145 
146  call set_mat_ij(ia,ja,ncr,nelv)
147  null_space=0
148  if (ifield == 1) then
149  if (ifvcor) null_space=1
150  elseif (ifield == ifldmhd) then
151  if (ifbcor) null_space=1
152  endif
153 
154  nz=ncr*ncr*nelv
155  call crs_setup(xxth(ifield),nekcomm,mp, ntot,se_to_gcrs, &
156  nz,ia,ja,a, null_space)
157  deallocate(a)
158 ! call crs_stats(xxth(ifield))
159 
160  t0 = dnekclock()-t0
161  if (nid == 0) then
162  write(6,*) 'done :: setup h1 coarse grid ',t0, ' sec'
163  write(6,*) ' '
164  endif
165 
166  return
167 end subroutine set_up_h1_crs
168 
169 !-----------------------------------------------------------------------
170 subroutine set_jl_crs_mask(n, mask, se_to_gcrs)
171  use kinds, only : dp, i8
172  implicit none
173  integer :: n
174  real(DP) :: mask(*)
175  integer(i8) :: se_to_gcrs(*)
176 
177  integer :: i
178  do i=1,n
179  if(mask(i) < 0.1) se_to_gcrs(i)=0
180  enddo
181  return
182 end subroutine set_jl_crs_mask
183 
184 !-----------------------------------------------------------------------
185 subroutine set_mat_ij(ia,ja,n,ne)
186  implicit none
187  integer :: n,ne
188  integer :: ia(n,n,ne), ja(n,n,ne)
189 
190  integer :: i,j,ie
191  do ie=1,ne
192  do j=1,n
193  do i=1,n
194  ia(i,j,ie)=(ie-1)*n+i-1
195  ja(i,j,ie)=(ie-1)*n+j-1
196  enddo
197  enddo
198  enddo
199  return
200 end subroutine set_mat_ij
201 
202 !-----------------------------------------------------------------------
204 subroutine ituple_sort(a,lda,n,key,nkey,ind,aa)
205  implicit none
206 
207  integer :: lda, n, nkey
208  integer :: a(lda,n),aa(lda)
209  integer :: ind(*),key(nkey)
210  logical :: iftuple_ialtb
211 
212  integer :: j, L, ir, ii, i
213 
214  dO 10 j=1,n
215  ind(j)=j
216  10 END DO
217 
218  if (n <= 1) return
219  l=n/2+1
220  ir=n
221  100 continue
222  if (l > 1) then
223  l=l-1
224  ! aa = a (l)
225  aa = a(:,l)
226  ii = ind(l)
227  else
228  ! aa = a(ir)
229  aa = a(:,ir)
230  ii = ind(ir)
231  ! a(ir) = a( 1)
232  a(:,ir) = a(:,1)
233  ind(ir) = ind( 1)
234  ir=ir-1
235  if (ir == 1) then
236  ! a(1) = aa
237  a(:,1) = aa
238  ind(1) = ii
239  return
240  endif
241  endif
242  i=l
243  j=l+l
244  200 continue
245  if (j <= ir) then
246  if (j < ir) then
247  if (iftuple_ialtb(a(1,j),a(1,j+1),key,nkey)) j=j+1
248  endif
249  if (iftuple_ialtb(aa,a(1,j),key,nkey)) then
250  ! a(i) = a(j)
251  a(:,i) = a(:,j)
252  ind(i) = ind(j)
253  i=j
254  j=j+j
255  else
256  j=ir+1
257  endif
258  goto 200
259  endif
260 ! a(i) = aa
261  a(:,i) = aa
262  ind(i) = ii
263  goto 100
264 end subroutine ituple_sort
265 
266 !-----------------------------------------------------------------------
267 logical function iftuple_ialtb(a,b,key,nkey)
268  implicit none
269  integer :: nkey
270  integer :: a(*),b(*)
271  integer :: key(nkey)
272 
273  integer :: i, k
274 
275  do i=1,nkey
276  k=key(i)
277  if (a(k) < b(k)) then
278  iftuple_ialtb = .true.
279  return
280  elseif (a(k) > b(k)) then
281  iftuple_ialtb = .false.
282  return
283  endif
284  enddo
285  iftuple_ialtb = .false.
286  return
287 end function iftuple_ialtb
288 
289 !-----------------------------------------------------------------------
290 logical function iftuple_ianeb(a,b,key,nkey)
291  implicit none
292  integer :: nkey
293  integer :: a(*),b(*)
294  integer :: key(nkey)
295 
296  integer :: i, k
297  do i=1,nkey
298  k=key(i)
299  if (a(k) /= b(k)) then
300  iftuple_ianeb = .true.
301  return
302  endif
303  enddo
304  iftuple_ianeb = .false.
305  return
306 end function iftuple_ianeb
307 
308 !-----------------------------------------------------------------------
313 subroutine specmpn(b,nb,a,na,ba,ab,if3d,w,ldw)
314  use kinds, only : dp
315  implicit none
316 
317  logical, intent(in) :: if3d
318  integer, intent(in) :: nb, na, ldw
319  real(DP), intent(out) :: b(nb,nb,nb)
320  real(DP), intent(in) :: a(na,na,na)
321  real(DP), intent(out) :: w(ldw) !>
322 
323  integer :: ltest, nab, nbb, k, l, iz
324  real(DP) :: ba, ab
325 
326  ltest = na*nb
327  if (if3d) ltest = na*na*nb + nb*na*na
328  if (ldw < ltest) then
329  write(6,*) 'ERROR specmp:',ldw,ltest,if3d
330  call exitt
331  endif
332 
333  if (if3d) then
334  nab = na*nb
335  nbb = nb*nb
336  call mxm(ba,nb,a,na,w,na*na)
337  k=1
338  l=na*na*nb + 1
339  do iz=1,na
340  call mxm(w(k),nb,ab,na,w(l),nb)
341  k=k+nab
342  l=l+nbb
343  enddo
344  l=na*na*nb + 1
345  call mxm(w(l),nbb,ab,na,b,nb)
346  else
347  call mxm(ba,nb,a,na,w,na)
348  call mxm(w,nb,ab,na,b,nb)
349  endif
350  return
351 end subroutine specmpn
352 
353 !-----------------------------------------------------------------------
355 subroutine irank(A,IND,N)
356  implicit none
357  integer :: A(*),IND(*), n
358 
359  integer :: j, L, ir, i, q, indx
360 
361  if (n <= 1) return
362  DO 10 j=1,n
363  ind(j)=j
364  10 END DO
365 
366  if (n == 1) return
367  l=n/2+1
368  ir=n
369  100 continue
370  IF (l > 1) THEN
371  l=l-1
372  indx=ind(l)
373  q=a(indx)
374  ELSE
375  indx=ind(ir)
376  q=a(indx)
377  ind(ir)=ind(1)
378  ir=ir-1
379  if (ir == 1) then
380  ind(1)=indx
381  return
382  endif
383  ENDIF
384  i=l
385  j=l+l
386  200 continue
387  IF (j <= ir) THEN
388  IF (j < ir) THEN
389  IF ( a(ind(j)) < a(ind(j+1)) ) j=j+1
390  ENDIF
391  IF (q < a(ind(j))) THEN
392  ind(i)=ind(j)
393  i=j
394  j=j+j
395  ELSE
396  j=ir+1
397  ENDIF
398  goto 200
399  ENDIF
400  ind(i)=indx
401  goto 100
402 end subroutine irank
403 
404 !-----------------------------------------------------------------------
407 subroutine get_local_crs_galerkin(a,ncl,nxc,h1,h2,w1,w2)
408  use kinds, only : dp
409  use size_m, only : nx1, ny1, nz1, nelv, lx1, ldim
410  implicit none
411 
412  integer :: ncl, nxc
413  real(DP) :: a(ncl,ncl,*),h1(*),h2(*)
414  real(DP) :: w1(nx1*ny1*nz1,nelv),w2(nx1*ny1*nz1,nelv)
415 
416  integer, parameter :: lcrd=lx1**ldim
417  real(DP) :: b(lcrd,8)
418 
419  integer :: e, i, j, isd, imsh, nxyz
420  real(DP), external :: ddot
421 
422  do j=1,ncl
423  call gen_crs_basis(b(1,j),j) ! bi- or tri-linear interpolant
424  enddo
425 
426  isd = 1
427  imsh = 1
428 
429  nxyz = nx1*ny1*nz1
430  do j = 1,ncl
431  do e = 1,nelv
432  call copy(w1(1,e),b(1,j),nxyz)
433  enddo
434 
435  call axhelm(w2,w1,h1,h2,imsh,isd) ! A^e * bj
436 
437  do e = 1,nelv
438  do i = 1,ncl
439  a(i,j,e) = ddot(nxyz, b(:,i), 1, w2(:,e), 1) ! bi^T * A^e * bj
440  enddo
441  enddo
442 
443  enddo
444 
445  return
446 end subroutine get_local_crs_galerkin
447 
448 !-----------------------------------------------------------------------
449 subroutine gen_crs_basis(b,j) ! bi- tri-linear
450  use kinds, only : dp
451  use size_m, only : lx1, nx1, ny1, nz1, ndim
452  use speclib, only : zwgll
453  implicit none
454 
455  real(DP) :: b(nx1,ny1,nz1)
456  integer :: j
457 
458  real(DP) :: z0(lx1),z1(lx1)
459  real(DP) :: zr(lx1),zs(lx1),zt(lx1)
460 
461  integer :: p,q,r
462  integer :: i
463 
464  call zwgll(zr,zs,nx1)
465 
466  do i=1,nx1
467  z0(i) = .5*(1-zr(i)) ! 1-->0
468  z1(i) = .5*(1+zr(i)) ! 0-->1
469  enddo
470 
471  call copy(zr,z0,nx1)
472  call copy(zs,z0,nx1)
473  call copy(zt,z0,nx1)
474 
475  if (mod(j,2) == 0) call copy(zr,z1,nx1)
476  if (j == 3 .OR. j == 4 .OR. j == 7 .OR. j == 8) call copy(zs,z1,nx1)
477  if (j > 4) call copy(zt,z1,nx1)
478 
479  if (ndim == 3) then
480  do r=1,nx1
481  do q=1,nx1
482  do p=1,nx1
483  b(p,q,r) = zr(p)*zs(q)*zt(r)
484  enddo
485  enddo
486  enddo
487  else
488  do q=1,nx1
489  do p=1,nx1
490  b(p,q,1) = zr(p)*zs(q)
491  enddo
492  enddo
493  endif
494 
495  return
496 end subroutine gen_crs_basis
497 
498 !-----------------------------------------------------------------------
499 subroutine get_vertex
500  use zper, only : ifgtp
501  implicit none
502 
503  integer, save :: icalld = 0
504 
505  if (icalld > 0) return
506  icalld = 1
507 
508  if (ifgtp) then
509  write(*,*) "Oops: ifgtp"
510 !max call gen_gtp_vertex (vertex, ncrnr)
511  else
512  call get_vert
513  endif
514 
515  return
516 end subroutine get_vertex
517 
518 !-----------------------------------------------------------------------
519 subroutine assign_gllnid(gllnid,iunsort,nelgt,nelgv,np)
520  implicit none
521  integer :: gllnid(*),iunsort(*),nelgt,nelgv, np
522  integer :: eg
523 
524  integer :: nelgs, nnpstr, npstar, log2p, np2
525  integer, external :: log2
526  integer :: e, ip, k, nel, nmod, npp
527 
528  log2p = log2(np)
529  np2 = 2**log2p
530  if (np2 == np .AND. nelgv == nelgt) then ! std power of 2 case
531 
532  npstar = maxval(gllnid(1:nelgt))+1
533  nnpstr = npstar/np
534  do eg=1,nelgt
535  gllnid(eg) = gllnid(eg)/nnpstr
536  enddo
537 
538  return
539 
540  elseif (np2 == np) then ! std power of 2 case, conjugate heat xfer
541 
542  ! Assign fluid elements
543  npstar = max(np,maxval(gllnid(1:nelgv))+1)
544  nnpstr = npstar/np
545  do eg=1,nelgv
546  gllnid(eg) = gllnid(eg)/nnpstr
547  enddo
548 
549  ! Assign solid elements
550  nelgs = nelgt-nelgv ! number of solid elements
551  npstar = max(np,maxval(gllnid(nelgv+1:nelgv+nelgs))+1)
552  nnpstr = npstar/np
553  do eg=nelgv+1,nelgt
554  gllnid(eg) = gllnid(eg)/nnpstr
555  enddo
556 
557  return
558 
559  elseif (nelgv /= nelgt) then
560  call exitti &
561  ('Conjugate heat transfer requires P=power of 2.$',np)
562  endif
563 
564 
565 ! Below is the code for P a non-power of two:
566 
567 ! Split the sorted gllnid array (read from .map file)
568 ! into np contiguous partitions.
569 
570 ! To load balance the partitions in case of mod(nelgt,np)>0
571 ! add 1 contiguous entry out of the sorted list to NODE_i
572 ! where i = np-mod(nelgt,np) ... np
573 
574  nel = nelgt/np ! number of elements per processor
575  nmod = mod(nelgt,np) ! bounded between 1 ... np-1
576  npp = np - nmod ! how many paritions of size nel
577 
578 ! sort gllnid
579  call isort(gllnid,iunsort,nelgt)
580 
581 ! setup partitions of size nel
582  k = 0
583  do ip = 0,npp-1
584  do e = 1,nel
585  k = k + 1
586  gllnid(k) = ip
587  enddo
588  enddo
589 ! setup partitions of size nel+1
590  if(nmod > 0) then
591  do ip = npp,np-1
592  do e = 1,nel+1
593  k = k + 1
594  gllnid(k) = ip
595  enddo
596  enddo
597  endif
598 
599 ! unddo sorting to restore initial ordering by
600 ! global element number
601  call iswapt_ip(gllnid,iunsort,nelgt)
602 
603  return
604 end subroutine assign_gllnid
605 
606 !-----------------------------------------------------------------------
607 subroutine get_vert
608  use size_m, only : ndim
609  use input, only : ifmoab
610  use mesh, only : vertex
611  use parallel, only : nelgt
612  use zper, only : ifgfdm
613  implicit none
614 
615  integer :: ncrnr
616  integer, save :: icalld = 0
617 
618  if (icalld > 0) return
619  icalld = 1
620 
621  ncrnr = 2**ndim
622 
623  if (ifmoab) then
624 #ifdef MOAB
625  call nekmoab_loadconn(vertex, nelgt, ncrnr)
626 #endif
627  else
628  call get_vert_map(vertex, ncrnr, nelgt, '.map', ifgfdm)
629  endif
630 
631  return
632 end subroutine get_vert
633 
634 !-----------------------------------------------------------------------
635 subroutine get_vert_map(vertex, nlv, nel, suffix, ifgfdm)
636  use size_m, only : lx1, ly1, lz1, lelv, nelt, nelv
637  use input, only : reafle
638  use parallel, only : np, gllnid, gllel, lglel, nelgt, nelgv
639  use string, only : ltrunc
640  use parallel, only : nid, init_gllnid, wdsize
641  use mesh, only : shape_x, ieg_to_xyz, boundaries
642  implicit none
643 
644  logical :: ifgfdm
645 
646  integer :: nlv, nel
647  integer :: vertex(nlv,*)
648  character(4) :: suffix
649 
650  integer, parameter :: mdw=2
651  integer, parameter :: ndw=lx1*ly1*lz1*lelv/mdw
652  integer :: lshape(3)
653 
654  integer :: e,eg,eg0,eg1, ieg, iok, lfname, neli, nnzi, npass
655  integer :: ipass, m, ntuple, iflag, mid
656  integer, external :: iglmax, irecv
657  integer :: ix(3)
658 
659  character(132) :: mapfle
660  character(1) :: mapfle1(132)
661  equivalence(mapfle,mapfle1)
662  iflag = 0
663 
664  iok = 0
665  if (nid == 0) then
666  lfname = ltrunc(reafle,132) - 4
667  call blank(mapfle,132)
668  call chcopy(mapfle,reafle,lfname)
669  call chcopy(mapfle1(lfname+1),suffix,4)
670  open(unit=80,file=mapfle,status='old',err=99)
671  read(80,*,err=99) neli,nnzi,shape_x
672  close(80)
673  iok = 1
674  endif
675  99 continue
676  iok = iglmax(iok,1)
677  if (iok == 0) goto 999 ! Mapfile not found
678 
679  call bcast(shape_x,3*wdsize)
680 
681  lshape = shape_x
682  if (shape_x(1) < 0) lshape(1) = -lshape(1) + 1
683  if (shape_x(2) < 0) lshape(2) = -lshape(2) + 1
684  if (shape_x(3) < 0) lshape(3) = -lshape(3) + 1
685  shape_x = abs(shape_x)
686 
687  if (nid == 0) then
688  neli = iglmax(neli,1) ! communicate to all procs
689  else
690  neli = 0
691  neli = iglmax(neli,1) ! communicate neli to all procs
692  endif
693 
694  npass = 1 + (neli/ndw)
695  if (npass > np) then
696  if (nid == 0) write(6,*) npass,np,neli,ndw,'Error get_vert_map'
697  call exitt
698  endif
699 
700  call init_gllnid()
701 
702  nelt = neli / np
703  nelv = neli / np
704 
705  if (np <= 64) write(6,*) nid,nelv,nelt,nelgv,nelgt,' NELV'
706 
707 ! NOW: crystal route vertex by processor id
708 
709 
710  do e = 1, nelt
711  ieg = lglel(e)
712  ix = ieg_to_xyz(ieg)
713  vertex(1,e) = 1 + mod(ix(1) + 0, lshape(1)) + mod(ix(2) + 0, lshape(2))*lshape(1) &
714  + mod(ix(3) + 0, lshape(3)) * lshape(1) * lshape(2)
715  vertex(2,e) = 1 + mod(ix(1) + 1, lshape(1)) + mod(ix(2) + 0, lshape(2))*lshape(1) &
716  + mod(ix(3) + 0, lshape(3)) * lshape(1) * lshape(2)
717  vertex(3,e) = 1 + mod(ix(1) + 0, lshape(1)) + mod(ix(2) + 1, lshape(2))*lshape(1) &
718  + mod(ix(3) + 0, lshape(3)) * lshape(1) * lshape(2)
719  vertex(4,e) = 1 + mod(ix(1) + 1, lshape(1)) + mod(ix(2) + 1, lshape(2))*lshape(1) &
720  + mod(ix(3) + 0, lshape(3)) * lshape(1) * lshape(2)
721  vertex(5,e) = 1 + mod(ix(1) + 0, lshape(1)) + mod(ix(2) + 0, lshape(2))*lshape(1) &
722  + mod(ix(3) + 1, lshape(3)) * lshape(1) * lshape(2)
723  vertex(6,e) = 1 + mod(ix(1) + 1, lshape(1)) + mod(ix(2) + 0, lshape(2))*lshape(1) &
724  + mod(ix(3) + 1, lshape(3)) * lshape(1) * lshape(2)
725  vertex(7,e) = 1 + mod(ix(1) + 0, lshape(1)) + mod(ix(2) + 1, lshape(2))*lshape(1) &
726  + mod(ix(3) + 1, lshape(3)) * lshape(1) * lshape(2)
727  vertex(8,e) = 1 + mod(ix(1) + 1, lshape(1)) + mod(ix(2) + 1, lshape(2))*lshape(1) &
728  + mod(ix(3) + 1, lshape(3)) * lshape(1) * lshape(2)
729  enddo
730 
731  iflag = iglmax(iflag,1)
732  if (iflag > 0) then
733  do mid=0,np-1
734  call nekgsync
735  if (mid == nid) &
736  write(6,*) nid,ntuple,nelv,nelt,nelgt,' NELT FB'
737  call nekgsync
738  enddo
739  call nekgsync
740  call exitt
741  endif
742 
743  return
744 
745  999 continue
746  if (nid == 0) write(6,*) 'ABORT: Could not find map file ',mapfle
747  call exitt
748 
749  if (nid == 0) write(6,*)ipass,npass,eg0,eg1,mdw,m,eg,'get v fail'
750  call exitt0 ! Emergency exit
751 
752  return
753 end subroutine get_vert_map
754 !-----------------------------------------------------------------------
766 subroutine irank_vecn(ind,nn,a,m,n,key,nkey,aa)
767  implicit none
768  integer :: nn, m, n, nkey
769  integer :: ind(n),a(m,n)
770  integer :: key(nkey),aa(m)
771 
772  logical :: iftuple_ianeb,a_ne_b
773  integer :: nk, i
774 
775  nk = min(nkey,m)
776  call ituple_sort(a,m,n,key,nk,ind,aa)
777 
778 ! Find unique a's
779  aa = a(:,1)
780  nn = 1
781  ind(1) = nn
782 
783  do i=2,n
784  a_ne_b = iftuple_ianeb(aa,a(1,i),key,nk)
785  if (a_ne_b) then
786  aa = a(:,i)
787  nn = nn+1
788  endif
789  ind(i) = nn ! set ind() to rank
790  enddo
791 
792  return
793 end subroutine irank_vecn
794 
795 !-----------------------------------------------------------------------
802 subroutine gbtuple_rank(tuple,m,n,nmax,cr_h,nid,np,ind)
803  implicit none
804  integer :: m, n, nmax, nid, np
805  integer :: ind(nmax),tuple(m,nmax),cr_h
806 
807  integer, parameter :: mmax=40
808  integer :: key(mmax),wtuple(mmax)
809  integer :: nk, i, k, nkey, ni, ky, nimx, nu, nu_tot, nu_prior
810  integer, external :: iglmax, igl_running_sum
811 
812  if (m > mmax) then
813  write(6,*) nid,m,mmax,' gbtuple_rank fail'
814  call exitt
815  endif
816 
817  do i=1,n
818  tuple(1,i) = mod(tuple(3,i),np) ! destination processor
819  tuple(2,i) = i ! return location
820  enddo
821 
822  ni= n
823  ky=1 ! Assumes crystal_new already called
824  call crystal_ituple_transfer(cr_h, tuple,m,ni,nmax, ky)
825 
826  nimx = iglmax(ni,1)
827  if (ni > nmax) write(6,*) ni,nmax,n,'cr_xfer problem, A'
828  if (nimx > nmax) call exitt
829 
830  nkey = m-2
831  do k=1,nkey
832  key(k) = k+2
833  enddo
834 
835  call irank_vecn(ind,nu,tuple,m,ni,key,nkey,wtuple)! tuple re-ordered,
836 ! but contents same
837 
838  nu_tot = igl_running_sum(nu) ! running sum over P processors
839  nu_prior = nu_tot - nu
840 
841  do i=1,ni
842  tuple(3,i) = ind(i) + nu_prior ! global ranking
843  enddo
844 
845  call crystal_ituple_transfer(cr_h, tuple,m,ni,nmax, ky)
846 
847  nk = 1 ! restore to original order, local rank: 2; global: 3
848  key(1) = 2
849  call ituple_sort(tuple,m,n,key,nk,ind,wtuple)
850 
851  return
852 end subroutine gbtuple_rank
853 
854 !-----------------------------------------------------------------------
860 subroutine setvert3d(glo_num,ngv,nx,nel,vertex,ifcenter)
861  use kinds, only : i8
862  use size_m, only : lelt, ndim, nid, nelt
863  use parallel, only : cr_h, np, nelgt, lglel
864  use topol, only : icface, skpdat
865  implicit none
866 
867  integer(i8) :: glo_num(*),ngv
868  integer :: vertex(0:1,0:1,0:1,*),nx
869  logical :: ifcenter
870 
871  integer :: edge(0:1,0:1,0:1,3,lelt),enum(12,lelt),fnum(6,lelt)
872 
873  integer, parameter :: nsafe=8 ! OFTEN, nsafe=2 suffices
874 
875  integer :: vertex_flat(8)
876  integer :: etuple(4,12*lelt*nsafe)
877  integer :: ftuple(5,6,lelt*nsafe)
878  integer :: ind(12*lelt*nsafe)
879  equivalence(etuple,ftuple)
880 
881  integer :: gvf(4),facet(4),key(3),e
882  logical :: ifij
883 
884  integer(i8) :: igv,ig0
885  integer(i8) :: ngvv,ngve,ngvs,ngvi,ngvm
886  integer(i8) :: n_on_edge,n_on_face,n_in_interior
887  integer(i8) :: i8glmax
888 
889  integer :: ny, nz, nxyz, nlv, nel, k, j, i, il, ile, kswap, m, n, nmax
890  integer :: n_unique_edges, iedg_loc, i0, i0e, nfaces, ncrnr, ifac, icrn
891  integer :: n_unique_faces, iface, i1, is, j0, j1, js, idir, jdir, it, jt
892  integer :: nxx, l
893  integer, external :: iglmax
894 
895  ny = nx
896  nz = nx
897  nxyz = nx*ny*nz
898 
899  key(1)=1
900  key(2)=2
901  key(3)=3
902 
903  ngvs = -1
904 
905 ! Assign hypercube ordering of vertices
906 ! -------------------------------------
907 
908 ! Count number of unique vertices
909  nlv = 2**ndim
910  ngvv = iglmax(vertex,nlv*nel)
911 
912  do e=1,nel
913  do k=0,1
914  do j=0,1
915  do i=0,1
916  ! Local to global node number (vertex)
917  il = 1 + (nx-1)*i + nx*(nx-1)*j + nx*nx*(nx-1)*k
918  ile = il + nx*ny*nz*(e-1)
919  glo_num(ile) = vertex(i,j,k,e)
920  enddo
921  enddo
922  enddo
923  enddo
924  ngv = ngvv
925 
926  if (nx == 2) return
927 
928 ! Assign global vertex numbers to SEM nodes on each edge
929 ! ------------------------------------------------------
930 
931 ! Assign edge labels by bounding vertices.
932  do e=1,nel
933  do k=0,1
934  do j=0,1
935  do i=0,1
936  edge(i,j,k,1,e) = vertex(i,j,k,e) ! r-edge
937  edge(j,i,k,2,e) = vertex(i,j,k,e) ! s-edge
938  edge(k,i,j,3,e) = vertex(i,j,k,e) ! t-edge
939  enddo
940  enddo
941  enddo
942  enddo
943 
944 ! Sort edges by bounding vertices.
945  do e=1,nel
946  do i = 1,3
947  do k=0,1
948  do j=0,1
949  if (edge(0,j,k,i,e) > edge(1,j,k,i,e)) then
950  kswap = edge(0,j,k,i,e)
951  edge(0,j,k,i,e) = edge(1,j,k,i,e)
952  edge(1,j,k,i,e) = kswap
953  endif
954  etuple(3,1+j+k*2+(i-1)*4+12*(e-1)) = edge(0,j,k,i,e)
955  etuple(4,1+j+k*2+(i-1)*4+12*(e-1)) = edge(1,j,k,i,e)
956  enddo
957  enddo
958  enddo
959  enddo
960 
961 ! Assign a number (rank) to each unique edge
962  m = 4
963  n = 12*nel
964  nmax = 12*lelt*nsafe ! nsafe for crystal router factor of safety
965  call gbtuple_rank(etuple,m,n,nmax,cr_h,nid,np,ind)
966  do i=1,nel
967  do j = 1,12
968  enum(j,i) = etuple(3,j+(i-1)*12)
969  enddo
970  enddo
971  n_unique_edges = iglmax(enum,12*nel)
972 
973  n_on_edge = nx-2
974  ngve = n_unique_edges*n_on_edge
975  do e=1,nel
976  iedg_loc = 0
977 
978  ! Edges 1-4
979  do k=0,1
980  do j=0,1
981  igv = ngv + n_on_edge*(enum(iedg_loc+1,e)-1)
982  i0 = nx*(nx-1)*j + nx*nx*(nx-1)*k
983  i0e = i0 + nxyz*(e-1)
984  if (glo_num(i0e+1) < glo_num(i0e+nx)) then
985  do i=2,nx-1 ! std forward case
986  glo_num(i0e+i) = igv + i-1
987  enddo
988  else
989  do i=2,nx-1 ! backward case
990  glo_num(i0e+i) = igv + 1 + n_on_edge-(i-1)
991  enddo
992  endif
993  iedg_loc = iedg_loc + 1
994  enddo
995  enddo
996 
997  ! Edges 5-8
998  do k=0,1
999  do i=0,1
1000  igv = ngv + n_on_edge*(enum(iedg_loc+1,e)-1)
1001  i0 = 1+(nx-1)*i + nx*nx*(nx-1)*k
1002  i0e = i0 + nxyz*(e-1)
1003  if (glo_num(i0e) < glo_num(i0e+nx*(nx-1))) then
1004  do j=2,nx-1 ! std forward case
1005  glo_num(i0e+(j-1)*nx) = igv + j-1
1006  enddo
1007  else
1008  do j=2,nx-1 ! backward case
1009  glo_num(i0e+(j-1)*nx) = igv + 1 + n_on_edge-(j-1)
1010  enddo
1011  endif
1012  iedg_loc = iedg_loc + 1
1013  enddo
1014  enddo
1015 
1016  ! Edges 9-12
1017  do j=0,1
1018  do i=0,1
1019  igv = ngv + n_on_edge*(enum(iedg_loc+1,e)-1)
1020  i0 = 1 + (nx-1)*i + nx*(nx-1)*j
1021  i0e = i0 + nxyz*(e-1)
1022  if (glo_num(i0e) < glo_num(i0e+nx*nx*(nx-1))) then
1023  do k=2,nx-1 ! std forward case
1024  glo_num(i0e+(k-1)*nx*nx) = igv + k-1
1025  enddo
1026  else
1027  do k=2,nx-1 ! backward case
1028  glo_num(i0e+(k-1)*nx*nx) = igv + 1 + n_on_edge-(k-1)
1029  enddo
1030  endif
1031  iedg_loc = iedg_loc + 1
1032  enddo
1033  enddo
1034  enddo
1035  ngv = ngv + ngve
1036 
1037 ! Asign global node numbers on the interior of each face
1038 ! ------------------------------------------------------
1039 
1040 ! Assign faces by 3-tuples
1041 
1042 ! (The following variables all take the symmetric
1043 ! notation of IFACE as arguments:)
1044 
1045 ! ICFACE(i,IFACE) - Gives the 4 vertices which reside on face IFACE
1046 ! as depicted below, e.g. ICFACE(i,2)=2,4,6,8.
1047 
1048 ! 3+-----+4 ^ Y
1049 ! / 2 /| |
1050 ! Edge 1 extends / / | |
1051 ! from vertex 7+-----+8 +2 +----> X
1052 ! 1 to 2. | 4 | / /
1053 ! | |/ /
1054 ! 5+-----+6 Z
1055 ! 3
1056 
1057  nfaces=ndim*2
1058  ncrnr =2**(ndim-1)
1059  do e=1,nel
1060  vertex_flat = reshape(vertex(:,:,:,e), (/8/))
1061  do ifac=1,nfaces
1062  do icrn=1,ncrnr
1063  i = icface(icrn,ifac)
1064  facet(icrn) = vertex_flat(i)
1065  enddo
1066  call isort(facet,ind,ncrnr)
1067  ftuple(3:1+ncrnr, ifac, e) = facet(1:ncrnr-1)
1068  enddo
1069  enddo
1070 
1071 ! Assign a number (rank) to each unique face
1072  m = 5
1073  n = 6*nel
1074  nmax = 6*lelt*nsafe ! nsafe for crystal router factor of safety
1075  call gbtuple_rank(ftuple,m,n,nmax,cr_h,nid,np,ind)
1076  do e = 1,nel
1077  do i=1,6
1078  fnum(i,e) = ftuple(3,i,e)
1079  enddo
1080  enddo
1081  n_unique_faces = iglmax(fnum,6*nel)
1082 
1083  call dsset(nx,ny,nz)
1084  do e=1,nel
1085  do iface=1,nfaces
1086  i0 = skpdat(1,iface)
1087  i1 = skpdat(2,iface)
1088  is = skpdat(3,iface)
1089  j0 = skpdat(4,iface)
1090  j1 = skpdat(5,iface)
1091  js = skpdat(6,iface)
1092 
1093  ! On each face, count from minimum global vertex number,
1094  ! towards smallest adjacent vertex number. e.g., suppose
1095  ! the face is defined by the following global vertex numbers:
1096 
1097 
1098  ! 11+--------+81
1099  ! |c d|
1100  ! | |
1101  ! | |
1102  ! |a b|
1103  ! 15+--------+62
1104 
1105  ! We would count from c-->a, then towards d.
1106 
1107  gvf(1) = int(glo_num(i0+nx*(j0-1)+nxyz*(e-1)))
1108  gvf(2) = int(glo_num(i1+nx*(j0-1)+nxyz*(e-1)))
1109  gvf(3) = int(glo_num(i0+nx*(j1-1)+nxyz*(e-1)))
1110  gvf(4) = int(glo_num(i1+nx*(j1-1)+nxyz*(e-1)))
1111 
1112  call irank(gvf,ind,4)
1113 
1114  ! ind(1) tells which element of gvf() is smallest.
1115 
1116  ifij = .false.
1117  if (ind(1) == 1) then
1118  idir = 1
1119  jdir = 1
1120  if (gvf(2) < gvf(3)) ifij = .true.
1121  elseif (ind(1) == 2) then
1122  idir = -1
1123  jdir = 1
1124  if (gvf(1) < gvf(4)) ifij = .true.
1125  elseif (ind(1) == 3) then
1126  idir = 1
1127  jdir = -1
1128  if (gvf(4) < gvf(1)) ifij = .true.
1129  elseif (ind(1) == 4) then
1130  idir = -1
1131  jdir = -1
1132  if (gvf(3) < gvf(2)) ifij = .true.
1133  else
1134  idir = 0
1135  jdir = 0
1136  write(*,*) "Wasn't supposed to get here!"
1137  endif
1138 
1139  if (idir < 0) then
1140  it=i0
1141  i0=i1
1142  i1=it
1143  is=-is
1144  endif
1145 
1146  if (jdir < 0) then
1147  jt=j0
1148  j0=j1
1149  j1=jt
1150  js=-js
1151  endif
1152 
1153  nxx = nx*nx
1154  n_on_face = (nx-2)*(ny-2)
1155  ngvs = n_unique_faces*n_on_face
1156  ig0 = ngv + n_on_face*(fnum(iface,e)-1)
1157  if (ifij) then
1158  k=0
1159  l=0
1160  do j=j0,j1,js
1161  do i=i0,i1,is
1162  k=k+1
1163  ! this is a serious kludge to stay on the face interior
1164  if (k > nx .AND. k < nxx-nx .AND. &
1165  mod(k,nx) /= 1 .AND. mod(k,nx) /= 0) then
1166  ! interior
1167  l = l+1
1168  glo_num(i+nx*(j-1)+nxyz*(e-1)) = l + ig0
1169  endif
1170  enddo
1171  enddo
1172  else
1173  k=0
1174  l=0
1175  do i=i0,i1,is
1176  do j=j0,j1,js
1177  k=k+1
1178  ! this is a serious kludge to stay on the face interior
1179  if (k > nx .AND. k < nxx-nx .AND. &
1180  mod(k,nx) /= 1 .AND. mod(k,nx) /= 0) then
1181  ! interior
1182  l = l+1
1183  glo_num(i+nx*(j-1)+nxyz*(e-1)) = l + ig0
1184  endif
1185  enddo
1186  enddo
1187  endif
1188  enddo
1189  enddo
1190  ngv = ngv + ngvs
1191 
1192 ! Finally, number interiors (only ifcenter=.true.)
1193 ! -------------------------------------------------
1194 
1195  n_in_interior = (nx-2)*(ny-2)*(nz-2)
1196  ngvi = n_in_interior*nelgt
1197  if (ifcenter) then
1198  do e=1,nel
1199  ig0 = ngv + n_in_interior*(lglel(e)-1)
1200  l = 0
1201  do k=2,nz-1
1202  do j=2,ny-1
1203  do i=2,nx-1
1204  l = l+1
1205  glo_num(i+nx*(j-1)+nx*ny*(k-1)+nxyz*(e-1)) = ig0+l
1206  enddo
1207  enddo
1208  enddo
1209  enddo
1210  ngv = ngv + ngvi
1211  else
1212  do e=1,nel
1213  l = 0
1214  do k=2,nz-1
1215  do j=2,ny-1
1216  do i=2,nx-1
1217  l = l+1
1218  glo_num(i+nx*(j-1)+nx*ny*(k-1)+nxyz*(e-1)) = 0
1219  enddo
1220  enddo
1221  enddo
1222  enddo
1223  endif
1224 
1225 ! Quick check on maximum #dofs:
1226  m = nxyz*nelt
1227  ngvm = i8glmax(glo_num,m)
1228  ngvv = ngvv + ngve + ngvs ! number of unique ids w/o interior
1229  ngvi = ngvi + ngvv ! total number of unique ids
1230  if (nid == 0) write(6,1) nx,ngvv,ngvi,ngv,ngvm
1231  1 format(' setvert3d:',i4,4i12)
1232 
1233  return
1234 end subroutine setvert3d
1235 
1236 !-----------------------------------------------------------------------
1237 subroutine check_p_bc(glo_num,nx,ny,nz,nel)
1238  use kinds, only : i8
1239  use size_m, only : ndim, nelt
1240  use input, only : ifflow, cbc
1241  implicit none
1242 
1243  integer :: nx, ny, nz, nel
1244  integer(i8) :: glo_num(nx,ny,nz,nel)
1245 
1246  integer(i8) :: gmn
1247  integer :: e,f,fo,ef,efo, ifld, nface, k, j, i
1248  integer, save :: eface0(6) = (/ 4,2,1,3,5,6 /)
1249 
1250  ifld = 2
1251  if (ifflow) ifld = 1
1252 
1253  nface=2*ndim
1254  do e=1,nelt
1255  do f=1,nface,2
1256  fo = f+1
1257  ef = eface0(f)
1258  efo = eface0(fo)
1259  if (cbc(ef,e,ifld) == 'p ' .AND. cbc(efo,e,ifld) == 'p ') then
1260  if (f == 1) then ! r=-/+1
1261  do k=1,nz
1262  do j=1,ny
1263  gmn = min(glo_num(1,j,k,e),glo_num(nx,j,k,e))
1264  glo_num(1 ,j,k,e) = gmn
1265  glo_num(nx,j,k,e) = gmn
1266  enddo
1267  enddo
1268  elseif (f == 3) then ! s=-/+1
1269  do k=1,nz
1270  do i=1,nx
1271  gmn = min(glo_num(i,1,k,e),glo_num(i,ny,k,e))
1272  glo_num(i,1 ,k,e) = gmn
1273  glo_num(i,ny,k,e) = gmn
1274  enddo
1275  enddo
1276  else
1277  do j=1,ny
1278  do i=1,nx
1279  gmn = min(glo_num(i,j,1,e),glo_num(i,j,nz,e))
1280  glo_num(i,j,1 ,e) = gmn
1281  glo_num(i,j,nz,e) = gmn
1282  enddo
1283  enddo
1284  endif
1285  endif
1286  enddo
1287  enddo
1288 
1289  return
1290 end subroutine check_p_bc
1291 
1292 !-----------------------------------------------------------------------
integer function gllel(ieg)
subroutine bcast(buf, len)
Definition: comm_mpi.F90:289
cleaned
Definition: tstep_mod.F90:2
Input parameters from preprocessors.
Definition: input_mod.F90:11
subroutine mxm(a, n1, b, n2, c, n3)
Compute matrix-matrix product C = A*B.
Definition: mxm_wrapper.F90:7
subroutine dsset(nx, ny, nz)
Set up arrays IXCN,ESKIP,SKPDAT,NEDG,NOFFST for new NX,NY,NZ.
Definition: connect1.F90:549
subroutine axhelm(au, u, helm1, helm2, imesh, isd)
Compute the (Helmholtz) matrix-vector product, AU = helm1*[A]u + helm2*[B]u, for NEL elements...
Definition: hmholtz.F90:79
Arrays for direct stiffness summation. cleaned.
Definition: topol_mod.F90:3
void exitt()
Definition: comm_mpi.F90:411
#define gs_setup
Definition: gs.c:29
integer function, dimension(3) ieg_to_xyz(ieg)
Definition: mesh_mod.F90:32
#define gs_free
Definition: gs.c:30
subroutine init_gllnid()
cleaned
Definition: mesh_mod.F90:2
real(dp) function dnekclock()
Definition: ctimer_mod.F90:103
integer function lglel(iel)
subroutine copy(a, b, n)
Definition: math.F90:52
Cleaned.
Definition: zper_mod.F90:2
integer function gllnid(ieg)
subroutine isort(a, ind, n)
Use Heap Sort (p 231 Num. Rec., 1st Ed.)
Definition: math.F90:421
cleaned
Definition: parallel_mod.F90:2
subroutine blank(A, N)
blank a string
Definition: math.F90:38
subroutine exitt0
Definition: comm_mpi.F90:390
#define gs_op
Definition: gs.c:15
subroutine nekgsync()
Definition: comm_mpi.F90:318
Geometry arrays.
Definition: geom_mod.F90:2
subroutine, public zwgll(Z, W, NP)
Definition: speclib.F90:95
#define crs_setup
Definition: crs.h:8
subroutine chcopy(a, b, n)
Definition: math.F90:63
subroutine iswapt_ip(x, p, n)
Definition: math.F90:570
static uint np
Definition: findpts_test.c:63
integer function ltrunc(string, l)
Definition: string_mod.F90:260
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...
Definition: connect1.F90:1041
subroutine exitti(stringi, idata)
Definition: comm_mpi.F90:328