multimesh.f

Go to the documentation of this file.
00001 c-----------------------------------------------------------------------
00002       subroutine get_session_info(intracomm)
00003       include 'mpif.h'
00004       include 'SIZE'
00005       include 'GLOBALCOM' 
00006       include 'TSTEP' 
00007       include 'INPUT' 
00008       
00009       common /happycallflag/ icall
00010       common /nekmpi/ nid_,np,nekcomm,nekgroup,nekreal
00011       integer nid_global_root(0:nsessmax-1)
00012       character*132 session_mult(0:nsessmax-1), path_mult(0:nsessmax-1)
00013 
00014       logical ifhigh
00015 
00016 C     nsessmax = upper limit for number of sessions
00017 C     npmax = upper limit for number of processors in each session 
00018 
00019 
00020 C     Read from a file: number of sessions (nsessions), 
00021 C     session name (SESSION_MULT(n-1)),
00022 C     number of pocessors in each session (npsess(n-1)) 
00023 C     and path (PATH_MULT(n-1))
00024 
00025 
00026       call mpi_initialized(mpi_is_initialized, ierr) !  Initialize MPI
00027       if ( mpi_is_initialized .eq. 0 ) call mpi_init (ierr)
00028 
00029       call mpi_comm_size(mpi_comm_world,np_global,ierr)
00030       call mpi_comm_rank(mpi_comm_world,nid_global,ierr)
00031 
00032       nid=nid_global
00033       nekcomm=mpi_comm_world
00034 
00035       ierr = 0
00036       if (nid_global.eq.0) then
00037          open (unit=8,file='SESSION.NAME',status='old',err=24)
00038          read(8,*) nsessions
00039          do n=0,nsessions-1
00040             call blank(session_mult(n),132)
00041             call blank(path_mult(n)   ,132)
00042             read(8,10) session_mult(n)
00043             read(8,10) path_mult(n)
00044             read(8,*)  npsess(n)
00045          enddo
00046  10      format(a132)
00047          close(unit=8)
00048          goto 23
00049  24      ierr = 1
00050       endif
00051  23   continue
00052       
00053       call err_chk(ierr,' Cannot open SESSION.NAME!$')
00054 
00055       call bcast(nsessions,4)
00056 
00057       if (nsessions.gt.2) 
00058      &  call exitti(
00059 'More than 2 sessions are currently      &  not supported!$',1)
00060 
00061       do n=0,nsessions-1
00062          call bcast(npsess(n),4)
00063          call bcast(session_mult(n),132)
00064          call bcast(path_mult(n),132)
00065       enddo
00066 
00067       npall=0
00068       do n=0,nsessions-1
00069          npall=npall+npsess(n)
00070       enddo
00071      
00072 C     Check if number of processors in each session is consistent 
00073 C     with the total number of processors
00074 
00075       if (npall.ne.np_global) 
00076      &  call exitti('Wrong number of processors!$',1)
00077 
00078 C     Assign key for splitting into multiple groups
00079 
00080       nid_global_root_next=0
00081       do n=0,nsessions-1
00082          nid_global_root(n)=nid_global_root_next
00083          nid_global_root_next=nid_global_root(n)+npsess(n)
00084          if (nid_global.ge.nid_global_root(n).and.
00085      &   nid_global.lt.nid_global_root_next) 
00086      &    idsess=n
00087       enddo
00088          
00089       call mpi_comm_split(mpi_comm_world,idsess,nid,intracomm,ierr)
00090  
00091       session = session_mult(idsess)
00092       path    = path_mult   (idsess)
00093 
00094 C     Intercommunications set up only for 2 sessions 
00095 
00096       if (nsessions.gt.1) then
00097 
00098          if (idsess.eq.0) idsess_neighbor=1
00099          if (idsess.eq.1) idsess_neighbor=0
00100  
00101          call mpi_intercomm_create(intracomm,0,mpi_comm_world, 
00102      &     nid_global_root(idsess_neighbor), 10,intercomm,ierr)
00103 
00104          np_neighbor=npsess(idsess_neighbor)
00105       
00106          call iniproc(intracomm)
00107 
00108          ifhigh=.true.
00109          call mpi_intercomm_merge(intercomm, ifhigh, iglobalcomm, ierr)
00110       
00111          ifneknek   = .true.
00112          ifneknekm  = .false.
00113 
00114          ninter = 1 ! Initialize NEKNEK interface extrapolation order to 1.
00115 
00116          icall = 0  ! Emergency exit call flag
00117 
00118       endif 
00119 
00120       return
00121       end
00122 C-----------------------------------------------------------------------
00123       subroutine multimesh_create
00124 
00125       include 'SIZE'
00126       include 'TOTAL'
00127       integer iList_all(ldim+2,nmaxcom)
00128       real    pts(ldim,nmaxcom)
00129 
00130       integer icalld
00131       save    icalld
00132       data    icalld  /0/
00133 
00134 C     Set interpolation flag: points with bc = 'int' get intflag=1. 
00135 C     Boundary conditions are changed back to 'v' or 't'.
00136 
00137       if (icalld.eq.0) then
00138          call set_intflag
00139          call neknekmv()
00140          icalld = icalld + 1
00141       endif 
00142 
00143 c     Every processor sends all the points with intflag=1 to the processors 
00144 c     of remote session
00145 c     (send_points)
00146 
00147 C    Root processor receives all the boundary points from remote session
00148 C    and redistributes it among its processors for efficient 
00149 C    localization of points (recv_points)
00150 
00151       call exchange_points(pts,iList_all,npoints_all)
00152       
00153 C     Find which boundary points of remote session are
00154 C     within the local mesh (intpts_locate).  
00155 C     Communicate the point info(iList) to the remote processors
00156 C     Points which are inside the mesh are masked and
00157 C     their identities are stored in array 
00158 
00159 c     write(6,*) nelgv,nid,npoints_all,' npoints_all'
00160       call intpts_locate (pts,iList_all,npoints_all)
00161 
00162       return
00163       end
00164 C-------------------------------------------------------------
00165       subroutine set_intflag 
00166       include 'SIZE'
00167       include 'TOTAL'
00168       include 'NEKNEK'
00169       character*3 cb
00170       character*2 cb2
00171       equivalence (cb2,cb)
00172       integer e,f
00173 
00174 C     Set interpolation flag: points with boundary condition = 'int' 
00175 c     get intflag=1. 
00176 c
00177 C     Boundary conditions are changed back to 'v' or 't'.
00178 
00179       if (ifflow) then
00180          ifield = 1
00181       elseif (ifheat) then
00182          ifield   = 2
00183       endif   
00184 
00185       nfaces = 2*ndim
00186       nel    = nelfld(ifield)
00187       
00188       nflag=nel*nfaces
00189       call izero(intflag,nflag)
00190 
00191       do e=1,nel
00192       do f=1,nfaces
00193          cb=cbc(f,e,ifield)
00194          if (cb2.eq.'in') then
00195             intflag(f,e)=1
00196             if (ifield.eq.2) cbc(f,e,ifield)='t  '
00197             if (ifield.eq.1) cbc(f,e,ifield)='v  '
00198             if (cb.eq.'inp') cbc(f,e,ifield)='o  ' ! Pressure
00199          endif
00200       enddo
00201       enddo
00202 
00203       return
00204       end
00205 c-------------------------------------------------------------
00206       subroutine exchange_points(pts,iList_all,npoints_all)
00207       include 'SIZE'
00208       include 'TOTAL'
00209       include 'NEKUSE'
00210       include 'NEKNEK'
00211       include 'mpif.h'
00212       common /nekmpi/ mid,mp,nekcomm,nekgroup,nekreal
00213       integer status(mpi_status_size)
00214       real    pts(ldim,nmaxcom)   
00215       integer jsend((ldim+2)*nmaxl),jrecv((ldim+2)*nmaxl)
00216       common /exchr/ rsend(ldim*nmaxl), rrecv(ldim*nmaxl) 
00217       integer iList_all(ldim+2,nmaxcom)
00218     
00219 C     Look for boundary points with Diriclet b.c. (candidates for
00220 C     interpolation)
00221 
00222       
00223       if (ifflow) then
00224          ifield = 1
00225       elseif (ifheat) then
00226          ifield   = 2
00227       endif   
00228 
00229       nfaces = 2*ndim
00230       nel    = nelfld(ifield)
00231 
00232       ip = 0
00233       do 2010 iel=1,nel
00234       do 2010 iface=1,nfaces
00235          if (intflag(iface,iel).eq.1) then
00236             call facind (kx1,kx2,ky1,ky2,kz1,kz2,nx1,ny1,nz1,iface)
00237             do 100 iz=kz1,kz2
00238             do 100 iy=ky1,ky2
00239             do 100 ix=kx1,kx2
00240                call nekasgn (ix,iy,iz,iel)
00241                ip=ip+1
00242 
00243                if (if3d) then
00244                  jsend((ldim+2)*(ip-1)+1)=ix
00245                  jsend((ldim+2)*(ip-1)+2)=iy
00246                  jsend((ldim+2)*(ip-1)+3)=iz
00247                  jsend((ldim+2)*(ip-1)+4)=iel
00248                  jsend((ldim+2)*(ip-1)+5)=nid
00249 
00250                  rsend(ldim*(ip-1)+1)=x
00251                  rsend(ldim*(ip-1)+2)=y
00252                  rsend(ldim*(ip-1)+3)=z
00253                else
00254                  jsend((ldim+2)*(ip-1)+1)=ix
00255                  jsend((ldim+2)*(ip-1)+2)=iy
00256                  jsend((ldim+2)*(ip-1)+3)=iel
00257                  jsend((ldim+2)*(ip-1)+4)=nid
00258 
00259                  rsend(ldim*(ip-1)+1)=x
00260                  rsend(ldim*(ip-1)+2)=y
00261                endif
00262 
00263                if (ip.gt.nmaxl) then
00264                   write(6,*) nid,
00265      &            ' ABORT: nbp (current ip) too large',ip,nmaxl
00266                   call exitt
00267                endif
00268 
00269   100       continue
00270          endif
00271  2010 continue
00272 
00273       nbp = ip
00274 
00275       call izero(iList_all,(ldim+2)*nmaxcom)
00276       call rzero(pts,  ldim*nmaxcom)
00277 
00278 C     Send amount of points boundary points, its coordinates and 
00279 c     its local identities 
00280 C     to the the processors of remote session (for load balancing) 
00281 
00282 C     Determine amount of points to send to each processor
00283 
00284       ndistrib = nbp/np_neighbor
00285       iremainder = nbp - ndistrib*np_neighbor
00286 
00287       ip=0
00288       iaddress=1
00289       iraddress=1
00290 
00291       do id=0,np_neighbor-1
00292         if(id.le.iremainder-1) then
00293             nsend = ndistrib + 1
00294             else 
00295             nsend = ndistrib
00296         endif
00297 
00298          len=isize
00299          call mpi_irecv (nrecv,len,mpi_byte, id, id, 
00300      &                                    intercomm, msg,ierr)
00301          call mpi_send  (nsend,len,mpi_byte, id, nid, 
00302      &                                    intercomm, ierr)
00303 
00304          call mpi_wait (msg,status,ierr)
00305 
00306          len=(ldim+2)*nrecv*isize
00307          call mpi_irecv (jrecv, len ,mpi_byte, id, 100+id, 
00308      &                                     intercomm, msg, ierr)
00309          len=(ldim+2)*nsend*isize
00310          call mpi_send (jsend(iaddress),len,mpi_byte, id, 100+nid, 
00311      &                                           intercomm, ierr)
00312          iaddress=iaddress+(ldim+2)*nsend
00313 
00314          call mpi_wait (msg, status, ierr)
00315 
00316          len=ldim*nrecv*wdsize
00317          call mpi_irecv (rrecv, len ,mpi_byte, id, 200+id, 
00318      &                                  intercomm, msg, ierr)
00319          len=ldim*nsend*wdsize
00320          call mpi_send (rsend(iraddress),len,mpi_byte, id, 200+nid, 
00321      &                                        intercomm, ierr)
00322          iraddress=iraddress+ldim*nsend
00323 
00324          call mpi_wait (msg, status, ierr)
00325 
00326          do n=1,nrecv
00327             ip = ip + 1
00328 
00329             if (ip.gt.nmaxcom) then
00330                write(6,*) nid,'ABORT: increase nmaxcom',ip,nmaxcom
00331                call exitt
00332             endif
00333 
00334             
00335            do j=1,ldim+2
00336               iList_all(j,ip)=jrecv((ldim+2)*(n-1)+j)
00337            enddo
00338            do j=1,ldim
00339                pts(j,ip)=rrecv(ldim*(n-1)+j)
00340            enddo
00341 
00342          enddo ! n
00343 
00344       enddo    ! id
00345 
00346       call neknekgsync()
00347 
00348       npoints_all = ip    
00349 
00350       return
00351       end
00352 C-------------------------------------------------------------------------
00353       subroutine intpts_locate (pts,iList_all,npoints_all)
00354 
00355       include 'SIZE'
00356       include 'TOTAL'
00357       include 'NEKNEK'
00358       include 'mpif.h'  
00359       integer jsend((ldim+1)*nmaxl),jrecv((ldim+1)*nmaxl)
00360       integer rcode_all(nmaxcom),elid_all(nmaxcom),proc_all(nmaxcom)
00361       real    dist(nmaxcom)
00362       real    pts(ldim,nmaxcom)
00363       real    dist_all(nmaxcom)
00364       real    rst_all(nmaxcom*ldim)
00365       integer iList_all(ldim+2,nmaxcom)
00366       character*3 CB
00367       integer status(mpi_status_size)
00368       logical ifcomm
00369 
00370       integer icalld
00371       save    icalld
00372       data    icalld /0/
00373 
00374       if (icalld.le.1) then
00375          icalld=icalld+1
00376       else
00377          call intpts_done(inth_multi)
00378       endif
00379 
00380       call intpts_setup(-1.0,inth_multi) ! use default tolerance
00381         
00382 
00383       call findpts(inth_multi,rcode_all,1,
00384      &             proc_all,1,
00385      &             elid_all,1,
00386      &             rst_all,ndim,
00387      &             dist_all,1,
00388      &             pts(1,1),ndim,
00389      &             pts(2,1),ndim,
00390      &             pts(3,1),ndim,npoints_all)
00391 
00392       ierror=0
00393 
00394 c     Rearrange arrays so that only the points which are found within 
00395 c     the mesh are marked for interpolation: those are truly internal 
00396 c     points (rcode_all=0) plus some of the "boundary points" 
00397 c     (rcode_all=1) which fall on the boundaries of the elements 
00398 c     of another domain (essentially also internal points) or 
00399 c     wall or periodic boundaries 
00400 c
00401 c     Points with rcode_all(i)=1 which fall on the "interpolation" 
00402 c     boundaries of another domain are treated with boundary 
00403 c     conditions and not with interpolation routines, and are 
00404 c     therefore excluded.
00405 c
00406 c     rcode_all, proc_all ... npoints_all represent all boundary points,
00407 c     rcode, proc ... npoints - only interpolation points 
00408 c     (used by interpolation routines)
00409 c     Contained in a common block /multipts_r/, /multipts_i/ (in NEKNEK)
00410 
00411 C
00412 
00413 C     Exclude "true" boundary points 
00414 
00415       if (ifflow) then
00416          ifield = 1
00417       elseif (ifheat) then
00418          ifield   = 2
00419       endif 
00420 
00421       nel   = nelfld(ifield)
00422       nxyz  = nx1*ny1*nz1
00423       ntot  = nxyz*nel
00424 
00425       call izero(imask,ntot) 
00426 
00427       ip=0
00428       icount=0
00429       ierror=0
00430 
00431       do 100 i=1,npoints_all
00432          
00433       if (rcode_all(i).lt.2) then
00434 
00435         iel  = elid_all(i) + 1
00436 
00437         if (rcode_all(i).eq.1.and.dist_all(i).gt.1e-02) then
00438            if (ndim.eq.2) write(6,'(A,3E15.7)') 
00439      &     'WARNING: point on boundary or outside the mesh xy[z]d^2: ',
00440      &     (pts(k,i),k=1,ndim),dist_all(i)  
00441            if (ndim.eq.3) write(6,'(A,4E15.7)') 
00442      &     'WARNING: point on boundary or outside the mesh xy[z]d^2: ',
00443      &     (pts(k,i),k=1,ndim),dist_all(i)  
00444            goto 100
00445          endif
00446          ip=ip+1
00447          rcode(ip) = rcode_all(i)
00448          elid(ip)  = elid_all(i)
00449          proc(ip)  = proc_all(i)
00450          do j=1,ndim
00451            rst(ndim*(ip-1)+j)   = rst_all(ndim*(i-1)+j)
00452          enddo
00453          do n=1,ndim+1
00454            iList(n,ip) = iList_all(n,i)
00455          enddo
00456 
00457 c        Check receiving remote processor id information 
00458          n=ndim+2
00459 c        First point 
00460          if (ip.eq.1) then
00461             icount=1
00462             infosend(icount,1)=iList_all(n,i)
00463             infosend(icount,2)=ip
00464             iprocp=iList_all(n,i)
00465          else
00466             iproc  = iList_all(n,i)
00467             if (iproc.ne.iprocp) then
00468              if (iproc.gt.iprocp) then
00469                icount=icount+1
00470                infosend(icount,1)=iproc
00471                infosend(icount,2)=ip
00472                iprocp=iproc
00473              else
00474                write(6,*) 'Attention: intrinsic sorting is not achieved'
00475                write(6,'(a7,3i7,1x,a10)') 'switch', ip, 
00476      &         iproc,iprocp, session
00477                ierror = 1
00478                goto 100
00479              endif
00480             endif
00481          endif
00482       
00483       endif  !  rcode_all
00484 
00485  100  continue
00486 
00487       call iglmax(ierror,1)
00488       if (ierror.eq.1) call exitt
00489 
00490       npoints=ip
00491       npsend=icount
00492 
00493 c     Store point counts (infosend(:,2)) instead of pointers 
00494 
00495       do n=2,npsend
00496          ip=infosend(n-1,2)
00497          ic=infosend(n,2)
00498          infosend(n-1,2)=ic-ip
00499       enddo
00500       infosend(npsend,2)=npoints-infosend(npsend,2)+1
00501 
00502       if (istep.eq.0) write(6,'(a7,i12,1x,a10)') 'found', npoints, 
00503      &                     session
00504 
00505 c     Sending all processors information about the number 
00506 c     of receiving points, including zero points
00507 c     ifcomm=.false. means there are no more processors
00508 c     with non-zero receiving points (either if npsend=0 
00509 c     or if we already notified all the relevant processors)
00510 
00511       if (npsend.eq.0) then
00512          ifcomm=.false.
00513       else
00514          ifcomm=.true.
00515          icount=1
00516       endif   
00517 
00518       il=0
00519       do id=0,np_neighbor-1
00520 
00521          if (ifcomm) then
00522 
00523             idsend=infosend(icount,1)
00524 
00525             if (id.lt.idsend) then
00526                nsend=0
00527             elseif (id.eq.idsend) then
00528                nsend=infosend(icount,2)
00529                icount =icount+1
00530             endif
00531 
00532          else   !  not(ifcomm)
00533             nsend=0
00534          endif
00535 
00536          if (ifcomm.and.(icount.gt.npsend)) ifcomm=.false.
00537 
00538          len=isize   
00539          call mpi_send (nsend,len,mpi_byte, id, nid, intercomm, ierr)
00540 
00541          if (nsend.ne.0) then
00542 c           Send the points identity to communicating processors
00543             len=(ldim+1)*nsend*isize
00544                do i=1,nsend
00545                il=il+1
00546                do j=1,ldim+1
00547                   jsend((ldim+1)*(i-1)+j)=iList(j,il)
00548                enddo
00549             enddo   
00550 
00551             call mpi_send(jsend,len,mpi_byte,id,100+nid, intercomm,ierr)
00552 
00553          endif
00554 
00555       enddo   
00556 
00557 
00558 c     Receive information about sending processors
00559  6    irecvcnt=0
00560       il=0
00561       do id=0,np_neighbor-1
00562          len=isize
00563 
00564          call mpi_recv(nrecv,len,mpi_byte,id,id,intercomm,status,ierr)
00565 
00566          if (nrecv.ne.0) then
00567             irecvcnt=irecvcnt+1
00568             inforecv(irecvcnt,1)=id
00569             inforecv(irecvcnt,2)=nrecv
00570 
00571 c     Receive information about point identities
00572             len=(ldim+1)*nrecv*isize
00573             call mpi_recv
00574      $        (jrecv,len,mpi_byte,id,100+id,intercomm,status,ierr)
00575          
00576 c     Receiving processor nid masks which points he receives from 
00577 c     remote processor id as interpolation points using the identity 
00578 c     information contained in array 'jrecv'. Those points are masked 
00579 c     with imask=1 (imask=0 for all other points). 
00580 
00581       do ii=1,nrecv
00582          ix=jrecv((ldim+1)*(ii-1)+1)
00583          iy=jrecv((ldim+1)*(ii-1)+2)
00584          iz = 1
00585          if (if3d) iz=jrecv((ldim+1)*(ii-1)+3)
00586          ie=jrecv((ldim+1)*(ii-1)+ldim+1)
00587          il=il+1
00588             iden(1,il)=ix
00589             iden(2,il)=iy
00590             if (if3d) iden(3,il)=iz
00591             iden(ldim+1,il)=ie
00592             imask(ix,iy,iz,ie)=1
00593          enddo
00594 
00595       endif  !  jrecv.ne.0
00596       
00597       enddo  !  all remote processors
00598 
00599       nprecv=irecvcnt
00600 
00601       call neknekgsync()
00602       return
00603       end
00604 C----------------------------------------------------------------
00605       subroutine get_values(which_field)
00606       include 'SIZE'
00607       include 'TOTAL'
00608       include 'NEKNEK'
00609       include 'mpif.h' 
00610 
00611       parameter (lt=lx1*ly1*lz1*lelt,lxyz=lx1*ly1*lz1)
00612       common /scrcg/ pm1(lt),wk1(lxyz),wk2(lxyz)
00613 
00614       character*3 which_field(nfld_neknek)
00615       real field(lx1*ly1*lz1*lelt,nfldmax)
00616       real rsend(nfldmax*nmaxl), rrecv(nfldmax*nmaxl)
00617       real fieldout(nfldmax,nmaxl)
00618 
00619       integer status(mpi_status_size)
00620 
00621 c     Information about communication of points is contained in common 
00622 c     block /proclist/.
00623  
00624 C     iden(1,:) = ix
00625 C     iden(2,:) = iy
00626 C     iden(3,:) = iz
00627 C     iden(4,:) = iel
00628 
00629 
00630 c     Put field values for the field ifld=1,nfld_neknek to the working array 
00631 c     field (:,:,:,:,nfld_neknek) used byt the findpts_value routine according 
00632 c     to the field identificator which_field(ifld) 
00633 
00634       if (nfld_neknek.eq.0) 
00635      $ call exitti('Error: set nfld_neknek in usrchk. Session:$',idsess)
00636       
00637 
00638       call mappr(pm1,pr,wk1,wk2)  ! Map pressure to pm1 
00639 
00640       nv = nx1*ny1*nz1*nelv
00641       nt = nx1*ny1*nz1*nelt
00642 
00643       do ifld=1,nfld_neknek
00644         if (which_field(ifld).eq.'t' ) call copy(field(1,ifld),t  ,nt)
00645         if (which_field(ifld).eq.'vx') call copy(field(1,ifld),vx ,nt)
00646         if (which_field(ifld).eq.'vy') call copy(field(1,ifld),vy ,nt)
00647         if (which_field(ifld).eq.'vz') call copy(field(1,ifld),vz ,nt)
00648         if (which_field(ifld).eq.'pr') call copy(field(1,ifld),pm1,nt)
00649 
00650 C       Find interpolation values      
00651          call findpts_eval(inth_multi,fieldout(ifld,1),nfldmax,
00652      &                     rcode,1,
00653      &                     proc,1,
00654      &                     elid,1,
00655      &                     rst,ndim,npoints,
00656      &                     field(1,ifld))
00657 
00658        enddo  
00659 
00660 C     Send interpolation values to the corresponding processors 
00661 C     of remote session
00662 
00663       call neknekgsync()
00664 
00665       il=0
00666       do n=1,npsend   
00667          id       = infosend(n,1)
00668          nsend    = infosend(n,2)
00669          do i=1,nsend
00670             il=il+1
00671             do ifld=1,nfld_neknek
00672                rsend(nfld_neknek*(i-1)+ifld)=fieldout(ifld,il)
00673            enddo
00674          enddo
00675          len=nfld_neknek*nsend*wdsize
00676          call mpi_send (rsend,len,mpi_byte, id, nid, intercomm, ierr)
00677       enddo
00678 
00679       il=0 
00680       do n=1,nprecv
00681          id    = inforecv(n,1)
00682          nrecv = inforecv(n,2)
00683          len=nfld_neknek*nrecv*wdsize
00684          call mpi_recv (rrecv,len,mpi_byte,id,id,intercomm,status,ierr)
00685          do i=1,nrecv ! Extract point identity
00686             il=il+1
00687             ix = iden(1,il)
00688             iy = iden(2,il)
00689             iz = 1
00690             if (if3d) iz=iden(3,il)
00691             ie=iden(ldim+1,il)      
00692             do ifld=1,nfld_neknek
00693                valint(ix,iy,iz,ie,ifld)=rrecv(nfld_neknek*(i-1)+ifld)
00694             enddo
00695          enddo
00696       enddo 
00697 
00698       call neknekgsync()
00699 
00700       return
00701       end
00702 C--------------------------------------------------------------------------
00703       subroutine userchk_set_xfer
00704       include 'SIZE'
00705       include 'TOTAL'
00706       include 'NEKNEK'
00707       real l2,linf
00708       character*3 which_field(nfldmax+1)
00709 
00710 c     nfld_neknek is the number of fields to interpolate.
00711 c     nfld_neknek = 3 for just veliocities, nfld_neknek = 4 for velocities + temperature
00712 
00713       which_field(1)='vx'
00714       which_field(2)='vy'
00715       which_field(3)='vz'
00716       which_field(ndim+1)='pr'
00717       if (nfld_neknek.gt.ndim+1) which_field(ndim+2)='t'
00718 
00719       if (nsessions.gt.1) call get_values(which_field)
00720 
00721       return
00722       end
00723 c------------------------------------------------------------------------
00724       subroutine bcopy
00725       include 'SIZE'
00726       include 'TOTAL'
00727       include 'NEKNEK'
00728 
00729       n    = nx1*ny1*nz1*nelt
00730 
00731       do k=1,nfld_neknek
00732          call copy(bdrylg(1,k,2),bdrylg(1,k,1),n)
00733          call copy(bdrylg(1,k,1),bdrylg(1,k,0),n)
00734          call copy(bdrylg(1,k,0),valint(1,1,1,1,k),n)
00735       enddo
00736 
00737 c     Order of extrpolation is contolled by the parameter NINTER contained 
00738 c     in NEKNEK. First order interface extrapolation, NINTER=1 (time lagging) 
00739 c     is activated. It is unconditionally stable.  If you want to use 
00740 c     higher-order interface extrapolation schemes, you need to increase 
00741 c     ngeom to ngeom=3-5 for scheme to be stable.
00742 
00743       if (NINTER.eq.1.or.istep.eq.0) then
00744        c0=1
00745        c1=0
00746        c2=0
00747        else if (NINTER.eq.2.or.istep.eq.1) then
00748          c0=2
00749          c1=-1
00750          c2=0
00751        else 
00752          c0=3
00753          c1=-3
00754          c2=1
00755       endif
00756      
00757       do k=1,nfld_neknek
00758       do i=1,n
00759          ubc(i,1,1,1,k) = 
00760      $      c0*bdrylg(i,k,0)+c1*bdrylg(i,k,1)+c2*bdrylg(i,k,2)
00761       enddo
00762       enddo
00763 
00764       return
00765       end
00766 C---------------------------------------------------------------------
00767       subroutine setintercomm(nekcommtrue,nptrue) 
00768       include 'SIZE' 
00769       include 'GLOBALCOM'
00770       common /nekmpi/ nid_,np,nekcomm,nekgroup,nekreal 
00771       
00772       nekcommtrue=nekcomm
00773       nekcomm=iglobalcomm
00774 
00775       nptrue=np
00776       np=np_global
00777 
00778       return
00779       end
00780 c-----------------------------------------------------------------------
00781       subroutine unsetintercomm(nekcommtrue,nptrue)
00782       include 'SIZE' 
00783       include 'GLOBALCOM'
00784       common /nekmpi/ nid_,np,nekcomm,nekgroup,nekreal 
00785 
00786       nekcomm=nekcommtrue
00787       np=nptrue
00788 
00789       return
00790       end
00791 c-----------------------------------------------------------------------
00792       function uglmin(a,n)
00793       real a(1)
00794 
00795       call happy_check(1)
00796       call setintercomm(nekcommtrue,nptrue)    ! nekcomm=iglobalcomml
00797       uglmin=glmin(a,n)
00798       call unsetintercomm(nekcommtrue,nptrue)  ! nekcomm=nekcomm_original
00799 
00800       return
00801       end
00802 c-----------------------------------------------------------------------
00803       function uglamax(a,n)
00804       real a(1)
00805 
00806       call happy_check(1)
00807       call setintercomm(nekcommtrue,nptrue)    ! nekcomm=iglobalcomml
00808       uglamax=glamax(a,n)
00809       call unsetintercomm(nekcommtrue,nptrue)  ! nekcomm=nekcomm_original
00810 
00811       return
00812       end
00813 c------------------------------------------------------------------------
00814       subroutine neknekgsync()
00815       include 'SIZE' 
00816       include 'GLOBALCOM'
00817 
00818       call happy_check(1)
00819       call mpi_barrier(intercomm,ierr)
00820       return
00821       end
00822 c------------------------------------------------------------------------
00823       subroutine happy_check(ihappy)
00824       include 'SIZE'
00825       include 'TOTAL'
00826       common /happycallflag/ icall
00827 
00828 c     Happy check
00829       call setintercomm(nekcommtrue,nptrue)    ! nekcomm=iglobalcomml
00830       iglhappy=iglmin(ihappy,1)
00831       call unsetintercomm(nekcommtrue,nptrue)  ! nekcomm=nekcomm_original
00832       if (ihappy.eq.1.and.iglhappy.eq.0) then
00833          if (nid.eq.0) then
00834          write (6,*) '       '
00835          write (6,'(A,1i7,A,1e13.5)') 
00836      $   ' Emergency exit due to the other session:',
00837      $     ISTEP,'   time =',TIME
00838          write (6,*)   
00839          endif
00840          icall=1
00841        call exitt
00842       endif 
00843 
00844       return
00845       end
00846 c------------------------------------------------------------------------
00847       subroutine chk_outflow_short ! Assign neighbor velocity to outflow
00848 
00849 c
00850 c     This is just an experimental routine for PnPn only...
00851 c
00852 
00853 
00854       include 'SIZE'
00855       include 'TOTAL'
00856       include 'NEKUSE'
00857       include 'NEKNEK'
00858       integer e,eg,f
00859 
00860       n = nx1*ny1*nz1*nelt
00861       ipfld=ndim
00862 c     if (ifsplit) ipfld=ndim+1
00863       ipfld=ndim+1                ! Now for both split and nonsplit (12/14/15)
00864       itfld=ipfld+1
00865 
00866       do i=1,n ! The below has not been checked for ifheat=.true., pff 6/27/15
00867          if (imask(i,1,1,1).eq.1) then
00868             vx(i,1,1,1) = ubc(i,1,1,1,1)
00869             vy(i,1,1,1) = ubc(i,1,1,1,2)
00870             if (if3d)    vz(i,1,1,1)  = ubc(i,1,1,1,3)
00871             if (ifsplit) pr(i,1,1,1)  = ubc(i,1,1,1,ipfld)
00872             if (ifheat)  t(i,1,1,1,1) = ubc(i,1,1,1,itfld)
00873          endif
00874       enddo
00875 
00876       return
00877       end
00878 c-----------------------------------------------------------------------
00879       subroutine chk_outflow ! Assign neighbor velocity to outflow if
00880                              ! characteristics are going the wrong way.
00881 
00882       include 'SIZE'
00883       include 'TOTAL'
00884       include 'NEKUSE'
00885       include 'NEKNEK'
00886       integer e,eg,f
00887 
00888       nface = 2*ndim
00889       do e=1,nelv
00890       do f=1,nface
00891          if (cbc(f,e,1).eq.'o  ') then
00892            eg = lglel(e)
00893            call facind (i0,i1,j0,j1,k0,k1,nx1,ny1,nz1,f)
00894            l=0
00895            do k=k0,k1
00896            do j=j0,j1
00897            do i=i0,i1
00898               l=l+1
00899               vo=vx(i,j,k,e)*unx(l,1,f,e)
00900      $          +vy(i,j,k,e)*uny(l,1,f,e)
00901      $          +vz(i,j,k,e)*unz(l,1,f,e)
00902               if (vo.lt.0) then            ! We have inflow
00903                  cbu = cbc(f,e,1)
00904                  call userbc(i,j,k,f,eg)
00905                  vx(i,j,k,e) = ux
00906                  vy(i,j,k,e) = uy
00907                  vz(i,j,k,e) = uz
00908               endif
00909            enddo
00910            enddo
00911            enddo
00912          endif
00913       enddo
00914       enddo
00915 
00916       return
00917       end
00918 c-----------------------------------------------------------------------
00919       subroutine neknekmv()
00920       include 'SIZE'
00921       include 'TOTAL'
00922 
00923       integer imove
00924 
00925       imove=1
00926       if (ifmvbd) imove=0
00927       call neknekgsync()
00928 
00929       call setintercomm(nekcommtrue,nptrue)    ! nekcomm=iglobalcomml
00930       iglmove=iglmin(imove,1)
00931       call unsetintercomm(nekcommtrue,nptrue)  ! nekcomm=nekcomm_original
00932 
00933       if (iglmove.eq.0) then
00934          ifneknekm=.true.
00935       endif
00936 
00937       return
00938       end
00939 c-----------------------------------------------------------------------
00940 
Generated on Mon Jun 6 19:19:57 2016 for nek5000 by  doxygen 1.6.3