navier5.f

Go to the documentation of this file.
00001 c-----------------------------------------------------------------------
00002       subroutine q_filter(wght)
00003 c
00004 c     filter vx,vy,vz, and p by simple interpolation
00005 c
00006       include 'SIZE'
00007       include 'TOTAL'
00008 c
00009 c
00010 c     These are the dimensions that we interpolate onto for v and p:
00011       parameter(lxv=lx1-1)
00012       parameter(lxp=lx2-1)
00013 c
00014       real intdv(lx1,lx1)
00015       real intuv(lx1,lx1)
00016       real intdp(lx1,lx1)
00017       real intup(lx1,lx1)
00018       real intv(lx1,lx1)
00019       real intp(lx1,lx1)
00020 c
00021       save intdv
00022       save intuv
00023       save intdp
00024       save intup
00025       save intv
00026       save intp
00027 
00028       common /ctmp0/ intw,intt
00029      $             , wk1,wk2
00030      $             , zgmv,wgtv,zgmp,wgtp,tmax(100),omax(103)
00031 
00032       real intw(lx1,lx1)
00033       real intt(lx1,lx1)
00034       real wk1  (lx1,lx1,lx1,lelt)
00035       real wk2  (lx1,lx1,lx1)
00036       real zgmv(lx1),wgtv(lx1),zgmp(lx1),wgtp(lx1)
00037 c
00038 c     outpost arrays
00039       parameter (lt=lx1*ly1*lz1*lelv)
00040       common /scruz/ w1(lt),w2(lt),w3(lt),wt(lt)
00041 
00042       character*18 sfmt
00043 
00044       integer icalld
00045       save    icalld
00046       data    icalld /0/
00047 
00048       logical if_fltv
00049 
00050       imax = nid
00051       imax = iglmax(imax,1)
00052       jmax = iglmax(imax,1)
00053       if (icalld.eq.0) then
00054          icalld = 1
00055          ncut = param(101)+1
00056          call build_new_filter(intv,zgm1,nx1,ncut,wght,nio)
00057       elseif (icalld.lt.0) then   ! old (std.) filter
00058          icalld = 1
00059          call zwgll(zgmv,wgtv,lxv)
00060          call igllm(intuv,intw,zgmv,zgm1,lxv,nx1,lxv,nx1)
00061          call igllm(intdv,intw,zgm1,zgmv,nx1,lxv,nx1,lxv)
00062 c
00063          call zwgl (zgmp,wgtp,lxp)
00064          call iglm (intup,intw,zgmp,zgm2,lxp,nx2,lxp,nx2)
00065          call iglm (intdp,intw,zgm2,zgmp,nx2,lxp,nx2,lxp)
00066 c
00067 c        Multiply up and down interpolation into single operator
00068 c
00069          call mxm(intup,nx2,intdp,lxp,intp,nx2)
00070          call mxm(intuv,nx1,intdv,lxv,intv,nx1)
00071 c
00072 c        Weight the filter to make it a smooth (as opposed to truncated)
00073 c        decay in wave space
00074 
00075          w0 = 1.-wght
00076          call ident(intup,nx2)
00077          call add2sxy(intp,wght,intup,w0,nx2*nx2)
00078 
00079          call ident   (intuv,nx1)
00080          call add2sxy (intv ,wght,intuv,w0,nx1*nx1)
00081 
00082       endif
00083 
00084       ifldt  = ifield
00085 c     ifield = 1
00086 
00087       if_fltv = .false.
00088       if ( ifflow .and. .not. ifmhd ) if_fltv = .true.
00089       if ( ifield.eq.1  .and. ifmhd ) if_fltv = .true.
00090 
00091 c     Adam Peplinski; to take into account freezing of base flow
00092       if ( .not.ifbase             ) if_fltv = .false. ! base-flow frozen
00093 
00094       if ( if_fltv ) then
00095          call filterq(vx,intv,nx1,nz1,wk1,wk2,intt,if3d,umax)
00096          call filterq(vy,intv,nx1,nz1,wk1,wk2,intt,if3d,vmax)
00097          if (if3d)
00098      $      call filterq(vz,intv,nx1,nz1,wk1,wk2,intt,if3d,wmax)
00099          if (ifsplit.and..not.iflomach) 
00100      $      call filterq(pr,intv,nx1,nz1,wk1,wk2,intt,if3d,pmax)
00101       endif
00102 c
00103       if (ifmhd.and.ifield.eq.ifldmhd) then
00104          call filterq(bx,intv,nx1,nz1,wk1,wk2,intt,if3d,umax)
00105          call filterq(by,intv,nx1,nz1,wk1,wk2,intt,if3d,vmax)
00106          if (if3d)
00107      $   call filterq(bz,intv,nx1,nz1,wk1,wk2,intt,if3d,wmax)
00108       endif
00109 c
00110       if (ifpert) then
00111         do j=1,npert
00112 
00113          ifield = 1
00114          call filterq(vxp(1,j),intv,nx1,nz1,wk1,wk2,intt,if3d,umax)
00115          call filterq(vyp(1,j),intv,nx1,nz1,wk1,wk2,intt,if3d,vmax)
00116          if (if3d)
00117      $   call filterq(vzp(1,j),intv,nx1,nz1,wk1,wk2,intt,if3d,wmax)
00118 
00119          ifield = 2
00120          if (ifheat .and. .not.ifcvode) 
00121      $   call filterq(tp(1,j,1),intv,nx1,nz1,wk1,wk2,intt,if3d,wmax)
00122 
00123         enddo
00124       endif
00125 c
00126       mmax = 0
00127       if (ifflow) then
00128 c        pmax    = glmax(pmax,1)
00129          omax(1) = glmax(umax,1)
00130          omax(2) = glmax(vmax,1)
00131          omax(3) = glmax(wmax,1)
00132          mmax = ndim
00133       endif
00134          
00135 c
00136       nfldt = 1+npscal
00137       if (ifheat .and. .not.ifcvode) then
00138          do ifld=1,nfldt
00139             ifield = ifld + 1
00140             call filterq(t(1,1,1,1,ifld),intv
00141      $                  ,nx1,nz1,wk1,wk2,intt,if3d,tmax(ifld))
00142             mmax = mmax+1
00143             omax(mmax) = glmax(tmax(ifld),1)
00144          enddo
00145       endif
00146 
00147       if (nio.eq.0) then
00148          if (npscal.eq.0) then
00149 c           write(6,101) mmax
00150 c           write(sfmt,101) mmax
00151 c 101       format('''(i8,1p',i1,'e12.4,a6)''')
00152 c           write(6,sfmt) istep,(omax(k),k=1,mmax),' qfilt'
00153 c         write(6,'(i8,1p4e12.4,a6)') istep,(omax(k),k=1,mmax),' qfilt'
00154          else
00155             if (if3d) then
00156                write(6,1) istep,ifield,umax,vmax,wmax
00157             else
00158                write(6,1) istep,ifield,umax,vmax
00159             endif
00160     1       format(4x,i7,i3,' qfilt:',1p3e12.4)
00161             if(ifheat .and. .not.ifcvode) 
00162      &            write(6,'(1p50e12.4)') (tmax(k),k=1,nfldt)
00163          endif
00164       endif
00165 
00166       ifield = ifldt   ! RESTORE ifield
00167 
00168 
00169       return
00170       end
00171 c-----------------------------------------------------------------------
00172       subroutine filterq(v,f,nx,nz,w1,w2,ft,if3d,dmax)
00173 c
00174       include 'SIZE'
00175       include 'TSTEP'
00176 
00177       real v(nx*nx*nz,nelt),w1(1),w2(1)
00178       logical if3d
00179 c
00180       real f(nx,nx),ft(nx,nx)
00181 c
00182       integer e
00183 c
00184       call transpose(ft,nx,f,nx)
00185 c
00186       nxyz=nx*nx*nz
00187       dmax = 0.
00188 
00189 
00190       nel = nelfld(ifield)
00191 
00192 
00193       if (if3d) then
00194          do e=1,nel
00195 c           Filter
00196             call copy(w2,v(1,e),nxyz)
00197             call mxm(f,nx,w2,nx,w1,nx*nx)
00198             i=1
00199             j=1
00200             do k=1,nx
00201                call mxm(w1(i),nx,ft,nx,w2(j),nx)
00202                i = i+nx*nx
00203                j = j+nx*nx
00204             enddo
00205             call mxm (w2,nx*nx,ft,nx,w1,nx)
00206             call sub3(w2,v(1,e),w1,nxyz)
00207             call copy(v(1,e),w1,nxyz)
00208             smax = vlamax(w2,nxyz)
00209             dmax = max(dmax,abs(smax))
00210          enddo
00211 c
00212       else
00213          do e=1,nel
00214 c           Filter
00215             call copy(w1,v(1,e),nxyz)
00216             call mxm(f ,nx,w1,nx,w2,nx)
00217             call mxm(w2,nx,ft,nx,w1,nx)
00218 c
00219             call sub3(w2,v(1,e),w1,nxyz)
00220             call copy(v(1,e),w1,nxyz)
00221             smax = vlamax(w2,nxyz)
00222             dmax = max(dmax,abs(smax))
00223          enddo
00224       endif
00225 c
00226       return
00227       end
00228 c-----------------------------------------------------------------------
00229       subroutine outmatx(a,m,n,io,name)
00230       real a(m*n)
00231       character*4 name
00232 c
00233       open(unit=io,file=name)
00234       do i=1,m*n
00235          write(io,1) a(i)
00236       enddo
00237     1 format(1p1e22.13)
00238       close(unit=io)
00239 c
00240       return
00241       end
00242 c-----------------------------------------------------------------------
00243       subroutine drag_calc(scale)
00244 c
00245       INCLUDE 'SIZE'  
00246       INCLUDE 'TOTAL' 
00247 c
00248       common /scrns/         pm1(lx1,ly1,lz1,lelv)
00249      $,vxx(lx1,ly1,lz1,lelv),vxy(lx1,ly1,lz1,lelv),vxz(lx1,ly1,lz1,lelv)
00250      $,vyx(lx1,ly1,lz1,lelv),vyy(lx1,ly1,lz1,lelv),vyz(lx1,ly1,lz1,lelv)
00251       common /scruz/ 
00252      $ vzx(lx1,ly1,lz1,lelv),vzy(lx1,ly1,lz1,lelv),vzz(lx1,ly1,lz1,lelv)
00253      $,one(lx1,ly1,lz1,lelv)
00254        real work(1)
00255        equivalence (work,one)
00256 c
00257       common /cdrag/ dragx(0:maxobj),dragy(0:maxobj),dragz(0:maxobj)
00258      $             ,  momx(0:maxobj), momy(0:maxobj), momz(0:maxobj)
00259      $             ,  dpdx_mean,dpdy_mean,dpdz_mean
00260       real momx ,momy ,momz
00261 c
00262       common /tdrag/ drag(11)
00263       real dragpx,dragpy,dragpz,dragvx,dragvy,dragvz
00264       real momvx ,momvy ,momvz
00265       real check1,check2
00266 c
00267       equivalence (dragpx,drag(1)),(dragpy,drag(2)),(dragpz,drag(3))
00268       equivalence (dragvx,drag(4)),(dragvy,drag(5)),(dragvz,drag(6))
00269       equivalence (momvx ,drag(7)),(momvy ,drag(8)),(momvz ,drag(9)) 
00270       equivalence (check1,drag(10)),(check2,drag(11))
00271 
00272       common /cvflow_r/ flow_rate,base_flow,domain_length,xsec
00273      $                , scale_vf(3)
00274 
00275       ntot1  = nx1*ny1*nz1*nelv
00276 
00277 c    Map pressure onto mesh 1   (vxx and vyy are used as work arrays)
00278       call mappr(pm1,pr,vxx,vyy)
00279       call rone (one,ntot1)
00280 c
00281 c    Add mean_pressure_gradient.X to p:
00282 
00283       if (param(55).ne.0) then
00284          dpdx_mean = -scale_vf(1)
00285          dpdy_mean = -scale_vf(2)
00286          dpdz_mean = -scale_vf(3)
00287       endif
00288 
00289       call add2s2(pm1,xm1,dpdx_mean,ntot1)  ! Doesn't work if object is cut by 
00290       call add2s2(pm1,ym1,dpdy_mean,ntot1)  ! periodicboundary.  In this case,
00291       call add2s2(pm1,zm1,dpdz_mean,ntot1)  ! set ._mean=0 and compensate in
00292 c                                           ! usrchk()  [ pff 10/21/04 ].
00293 
00294 c    Compute du/dn
00295                 CALL DUDXYZ (vxx,vx,RXM1,SXM1,TXM1,JACM1,1,1)
00296                 CALL DUDXYZ (vxy,vx,RYM1,SYM1,TYM1,JACM1,1,1)
00297       if (if3d) CALL DUDXYZ (vxz,vx,RZM1,SZM1,TZM1,JACM1,1,1)
00298 c
00299                 CALL DUDXYZ (vyx,vy,RXM1,SXM1,TXM1,JACM1,1,1)
00300                 CALL DUDXYZ (vyy,vy,RYM1,SYM1,TYM1,JACM1,1,1)
00301       if (if3d) CALL DUDXYZ (vyz,vy,RZM1,SZM1,TZM1,JACM1,1,1)
00302 c
00303       if (if3d) then
00304                 CALL DUDXYZ (vzx,vz,RXM1,SXM1,TXM1,JACM1,1,1)
00305                 CALL DUDXYZ (vzy,vz,RYM1,SYM1,TYM1,JACM1,1,1)
00306                 CALL DUDXYZ (vzz,vz,RZM1,SZM1,TZM1,JACM1,1,1)
00307       endif
00308 c
00309 c     Fill up viscous array w/ default
00310 c
00311       if (istep.lt.1) call cfill(vdiff,param(2),ntot1)
00312 c
00313       call col2(vxx,vdiff,ntot1)
00314       call col2(vxy,vdiff,ntot1)
00315       call col2(vxz,vdiff,ntot1)
00316       call col2(vyx,vdiff,ntot1)
00317       call col2(vyy,vdiff,ntot1)
00318       call col2(vyz,vdiff,ntot1)
00319       call col2(vzx,vdiff,ntot1)
00320       call col2(vzy,vdiff,ntot1)
00321       call col2(vzz,vdiff,ntot1)
00322 c
00323       dragxt=0.0
00324       dragyt=0.0
00325       dragzt=0.0
00326 c
00327       DO 100 II=1,NHIS
00328          IF (HCODE(10,II).NE.'I') GOTO 100
00329          IOBJ   = LOCHIS(1,II)
00330          MEMTOT = NMEMBER(IOBJ)
00331 C
00332 c
00333          IF (HCODE(1,II).NE.' ' .OR. HCODE(2,II).NE.' ' .OR.
00334      $       HCODE(3,II).NE.' ' ) THEN
00335             IFIELD = 1
00336 c
00337 c---------------------------------------------------------------------------
00338 c           Compute drag for this object
00339 c---------------------------------------------------------------------------
00340 c
00341             dragvx=0.0
00342             dragvy=0.0
00343             dragvz=0.0
00344             dragpx=0.0
00345             dragpy=0.0
00346             dragpz=0.0
00347 c
00348             momvx=0.0
00349             momvy=0.0
00350             momvz=0.0
00351 c
00352             check1=0.0
00353             check2=0.0
00354             DO 50 MEM=1,MEMTOT
00355                ISK   = 0
00356                IEG   = OBJECT(IOBJ,MEM,1)
00357                IFC   = OBJECT(IOBJ,MEM,2)
00358                IF (GLLNID(IEG).EQ.NID) THEN
00359 C                 This processor has a contribution
00360                   IE = GLLEL(IEG)
00361 c
00362 c                 Pressure drag
00363                   check1=check1+facint(one,one,area,ifc,ie)
00364                   check2=check2+facint(one,uny,area,ifc,ie)
00365 c
00366                   dragpx=dragpx+facint(pm1,unx,area,ifc,ie)
00367                   dragpy=dragpy+facint(pm1,uny,area,ifc,ie)
00368                   if (if3d) dragpz=dragpz+facint(pm1,unz,area,ifc,ie)
00369 c
00370 c                 Viscous drag
00371                   if (if3d) then
00372                      dragvx=dragvx+facint(vxx,unx,area,ifc,ie)
00373      $                            +facint(vxy,uny,area,ifc,ie)
00374      $                            +facint(vxz,unz,area,ifc,ie)
00375      $                            +facint(vxx,unx,area,ifc,ie)
00376      $                            +facint(vyx,uny,area,ifc,ie)
00377      $                            +facint(vzx,unz,area,ifc,ie)
00378                      dragvy=dragvy+facint(vyx,unx,area,ifc,ie)
00379      $                            +facint(vyy,uny,area,ifc,ie)
00380      $                            +facint(vyz,unz,area,ifc,ie)
00381      $                            +facint(vxy,unx,area,ifc,ie)
00382      $                            +facint(vyy,uny,area,ifc,ie)
00383      $                            +facint(vzy,unz,area,ifc,ie)
00384                      dragvz=dragvz+facint(vzx,unx,area,ifc,ie)
00385      $                            +facint(vzy,uny,area,ifc,ie)
00386      $                            +facint(vzz,unz,area,ifc,ie)
00387      $                            +facint(vxz,unx,area,ifc,ie)
00388      $                            +facint(vyz,uny,area,ifc,ie)
00389      $                            +facint(vzz,unz,area,ifc,ie)
00390 c
00391                      momvx=momvx-facint2(vxy,unx,unz,area,ifc,ie)
00392      $                        -facint2(vyx,unx,unz,area,ifc,ie)
00393      $                        -facint2(vyy,uny,unz,area,ifc,ie)
00394      $                        -facint2(vyy,uny,unz,area,ifc,ie)
00395      $                        -facint2(vzy,unz,unz,area,ifc,ie)
00396      $                        -facint2(vyz,unz,unz,area,ifc,ie)
00397      $                        +facint2(vxz,unx,uny,area,ifc,ie)
00398      $                        +facint2(vzx,unx,uny,area,ifc,ie)
00399      $                        +facint2(vyz,uny,uny,area,ifc,ie)
00400      $                        +facint2(vzy,uny,uny,area,ifc,ie)
00401      $                        +facint2(vzz,unz,uny,area,ifc,ie)
00402      $                        +facint2(vzz,unz,uny,area,ifc,ie)
00403                      momvy=momvy+facint2(vxx,unx,unz,area,ifc,ie)
00404      $                        +facint2(vxx,unx,unz,area,ifc,ie)
00405      $                        +facint2(vyx,uny,unz,area,ifc,ie)
00406      $                        +facint2(vxy,uny,unz,area,ifc,ie)
00407      $                        +facint2(vzx,unz,unz,area,ifc,ie)
00408      $                        +facint2(vxz,unz,unz,area,ifc,ie)
00409      $                        -facint2(vxz,unx,unx,area,ifc,ie)
00410      $                        -facint2(vzx,unx,unx,area,ifc,ie)
00411      $                        -facint2(vyz,uny,unx,area,ifc,ie)
00412      $                        -facint2(vzy,uny,unx,area,ifc,ie)
00413      $                        -facint2(vzz,unz,unx,area,ifc,ie)
00414      $                        -facint2(vzz,unz,unx,area,ifc,ie)
00415                      momvz=momvz-facint2(vxx,unx,uny,area,ifc,ie)
00416      $                        -facint2(vxx,unx,uny,area,ifc,ie)
00417      $                        -facint2(vyx,uny,uny,area,ifc,ie)
00418      $                        -facint2(vxy,uny,uny,area,ifc,ie)
00419      $                        -facint2(vzx,unz,uny,area,ifc,ie)
00420      $                        -facint2(vxz,unz,uny,area,ifc,ie)
00421      $                        +facint2(vxy,unx,unx,area,ifc,ie)
00422      $                        +facint2(vyx,unx,unx,area,ifc,ie)
00423      $                        +facint2(vyy,uny,unx,area,ifc,ie)
00424      $                        +facint2(vyy,uny,unx,area,ifc,ie)
00425      $                        +facint2(vzy,unz,unx,area,ifc,ie)
00426      $                        +facint2(vyz,unz,unx,area,ifc,ie) 
00427 c
00428                   else
00429                      dragvx=dragvx+facint(vxx,unx,area,ifc,ie)
00430      $                            +facint(vxy,uny,area,ifc,ie)
00431                      dragvy=dragvy+facint(vyx,unx,area,ifc,ie)
00432      $                            +facint(vyy,uny,area,ifc,ie)
00433                   endif
00434                ENDIF
00435    50       CONTINUE
00436 c
00437 c          Sum contributions from all processors
00438             call gop(drag,work,'+  ',11)
00439             dragvx = -dragvx
00440             dragvy = -dragvy
00441             dragvz = -dragvz
00442          ENDIF
00443 c
00444 c        Scale by user specified scale factor (for convenience)
00445 c
00446          dragvx = scale*dragvx
00447          dragvy = scale*dragvy
00448          dragvz = scale*dragvz
00449 c
00450          dragpx = scale*dragpx
00451          dragpy = scale*dragpy
00452          dragpz = scale*dragpz
00453 c
00454          dragx(iobj) = dragvx+dragpx
00455          dragy(iobj) = dragvy+dragpy
00456          dragz(iobj) = dragvz+dragpz
00457 c
00458 c
00459          momx(iobj)  = 0.5*momvx
00460          momy(iobj)  = 0.5*momvy
00461          momz(iobj)  = 0.5*momvz
00462 c
00463          dragxt = dragxt + dragx(iobj)
00464          dragyt = dragyt + dragy(iobj)
00465          dragzt = dragzt + dragz(iobj)
00466 c
00467          if (nio.eq.0.and.istep.eq.1) 
00468      $      write(6,*) 'drag_calc: scale=',scale
00469          if (nio.eq.0) then
00470             write(6,6) istep,time,dragx(iobj),dragpx,dragvx,'dragx',iobj
00471             write(6,6) istep,time,dragy(iobj),dragpy,dragvy,'dragy',iobj
00472             if (if3d) 
00473      $      write(6,6) istep,time,dragz(iobj),dragpz,dragvz,'dragz',iobj
00474 c
00475 c done by zly (3/17/03)
00476 c          if(if3d) then
00477 c             write(6,113) istep,time,momx,momy,momz
00478 c          else
00479 c             write(6,112) istep,time,momx,momy
00480 c          endif
00481 c         
00482          endif
00483     6    format(i8,1p4e15.7,2x,a5,i5)
00484   112    format(i6,1p3e15.7,'  momx')
00485   113    format(i6,1p4e15.7,'  momx')
00486          if (istep.lt.10.and.nio.eq.0) 
00487      $      write(6,9) 'check:',check1,check2,dpdx_mean,istep
00488     9    format(a6,1p3e16.8,i9)
00489 c        if (time.gt.1.0.and.dragx.gt.10.) call emerxit
00490   100 continue
00491 c
00492       if (nio.eq.0) then
00493          write(6,6) istep,time,dragxt,dragpx,dragvx,'drgxt',iobj
00494          write(6,6) istep,time,dragyt,dragpy,dragvy,'drgyt',iobj
00495          if (if3d) 
00496      $   write(6,6) istep,time,dragzt,dragpz,dragvz,'drgzt',iobj
00497       endif
00498 c
00499       dragx(0) = dragxt
00500       dragy(0) = dragyt
00501       dragz(0) = dragzt
00502 c
00503       return
00504       end
00505 c-----------------------------------------------------------------------
00506       subroutine mappr(pm1,pm2,pa,pb)
00507 c
00508       INCLUDE 'SIZE'
00509       INCLUDE 'TOTAL'
00510       real pm1(lx1,ly1,lz1,lelv),pm2(lx2,ly2,lz2,lelv)
00511      $    ,pa (lx1,ly2,lz2)     ,pb (lx1,ly1,lz2)
00512 c
00513 C     Map the pressure onto the velocity mesh
00514 C
00515       NGLOB1 = NX1*NY1*NZ1*NELV
00516       NYZ2   = NY2*NZ2
00517       NXY1   = NX1*NY1
00518       NXYZ   = NX1*NY1*NZ1
00519 C
00520       IF (IFSPLIT) THEN
00521          CALL COPY(PM1,PM2,NGLOB1)
00522       ELSE
00523          DO 1000 IEL=1,NELV
00524             CALL MXM (IXM21,NX1,PM2(1,1,1,IEL),NX2,pa (1,1,1),NYZ2)
00525             DO 100 IZ=1,NZ2
00526                CALL MXM (PA(1,1,IZ),NX1,IYTM21,NY2,PB(1,1,IZ),NY1)
00527  100        CONTINUE
00528             CALL MXM (PB(1,1,1),NXY1,IZTM21,NZ2,PM1(1,1,1,IEL),NZ1)
00529  1000    CONTINUE
00530 
00531 C     Average the pressure on elemental boundaries
00532        IFIELD=1
00533        CALL DSSUM (PM1,NX1,NY1,NZ1)
00534        CALL COL2  (PM1,VMULT,NGLOB1)
00535 
00536       ENDIF
00537 C
00538 C
00539       return
00540       end
00541 c
00542 c-----------------------------------------------------------------------
00543       function facint_a(a,area,f,e)
00544 c     Integrate areal array a() on face f of element e.  27 June, 2012 pff
00545 
00546 c     f  is in the preprocessor notation
00547 
00548       include 'SIZE'
00549       include 'TOPOL'
00550       real a(lx1,lz1,6,lelt),area(lx1,lz1,6,lelt)
00551 
00552       integer e,f
00553 
00554       sum=0.0
00555       do i=1,lx1*lz1
00556          sum = sum + a(i,1,f,e)*area(i,1,f,e)
00557       enddo
00558 
00559       facint_a = sum
00560 
00561       return
00562       end
00563 c-----------------------------------------------------------------------
00564       function facint_v(a,area,f,e)
00565 c     Integrate volumetric array a() on face f of element e
00566 
00567 c        f  is in the preprocessor notation
00568 c        fd  is the dssum notation.
00569 c        27 June, 2012            PFF
00570 
00571       include 'SIZE'
00572       include 'TOPOL'
00573       real a(lx1,ly1,lz1,lelt),area(lx1,lz1,6,lelt)
00574 
00575       integer e,f,fd
00576 
00577       call dsset(nx1,ny1,nz1) ! set counters
00578       fd     = eface1(f)
00579       js1    = skpdat(1,fd)
00580       jf1    = skpdat(2,fd)
00581       jskip1 = skpdat(3,fd)
00582       js2    = skpdat(4,fd)
00583       jf2    = skpdat(5,fd)
00584       jskip2 = skpdat(6,fd)
00585 
00586       sum=0.0
00587       i = 0
00588       do 100 j2=js2,jf2,jskip2
00589       do 100 j1=js1,jf1,jskip1
00590          i = i+1
00591          sum = sum + a(j1,j2,1,e)*area(i,1,f,e)
00592   100 continue
00593 
00594       facint_v = sum
00595 
00596       return
00597       end
00598 c-----------------------------------------------------------------------
00599       function facint(a,b,area,ifc,ie)
00600 c
00601 C
00602 C     Take the dot product of A and B on the surface IFACE1 of element IE.
00603 C
00604 C         IFACE1 is in the preprocessor notation
00605 C         IFACE  is the dssum notation.
00606 C         5 Jan 1989 15:12:22      PFF
00607 C
00608       INCLUDE 'SIZE'
00609       INCLUDE 'TOPOL'
00610       DIMENSION A    (LX1,LY1,LZ1,lelv)
00611      $         ,B    (lx1,lz1,6,lelv)
00612      $         ,area (lx1,lz1,6,lelv)
00613 C
00614 C     Set up counters
00615 C
00616       CALL DSSET(NX1,NY1,NZ1)
00617       IFACE  = EFACE1(IFC)
00618       JS1    = SKPDAT(1,IFACE)
00619       JF1    = SKPDAT(2,IFACE)
00620       JSKIP1 = SKPDAT(3,IFACE)
00621       JS2    = SKPDAT(4,IFACE)
00622       JF2    = SKPDAT(5,IFACE)
00623       JSKIP2 = SKPDAT(6,IFACE)
00624 C
00625       SUM=0.0
00626       I = 0
00627       DO 100 J2=JS2,JF2,JSKIP2
00628       DO 100 J1=JS1,JF1,JSKIP1
00629          I = I+1
00630          SUM = SUM + A(J1,J2,1,ie)*B(I,1,ifc,ie)*area(I,1,ifc,ie)
00631 c        SUM = SUM + A(J1,J2,1,ie)*B(J1,J2,1,ie)*area(I,1,ifc,ie)
00632   100 CONTINUE
00633 C
00634       facint = SUM
00635 c
00636       return
00637       end
00638 c-----------------------------------------------------------------------
00639       function facint2(a,b,c,area,ifc,ie)
00640       include 'SIZE'
00641       include 'TOPOL'
00642       dimension a    (lx1,ly1,lz1,lelv)
00643      $        , b    (lx1,lz1,6,lelv)
00644      $        , c    (lx1,lz1,6,lelv)
00645      $        , area (lx1,lz1,6,lelv) 
00646       call dsset(nx1,ny1,nz1)
00647       iface  = eface1(ifc)
00648       js1    = skpdat(1,iface)
00649       jf1    = skpdat(2,iface)
00650       jskip1 = skpdat(3,iface)
00651       js2    = skpdat(4,iface)
00652       jf2    = skpdat(5,iface)
00653       jskip2 = skpdat(6,iface)
00654       sum=0.0
00655       i=0
00656       do j2=js2,jf2,jskip2
00657       do j1=js1,jf1,jskip1
00658          i=i+1
00659          sum=sum+a(j1,j2,1,ie)*b(i,1,ifc,ie)*c(i,1,ifc,ie)
00660      $          *area(i,1,ifc,ie)
00661       end do
00662       end do 
00663       facint2=sum
00664       return
00665       end 
00666 c-----------------------------------------------------------------------
00667       subroutine out_csrmats(acsr,ia,ja,n,name9)
00668       real    acsr(1)
00669       integer ia(1),ja(1)
00670 c
00671       character*9 name9
00672       character*9 s(16)
00673 c
00674       nnz = ia(n+1)-ia(1)
00675 c
00676       write(6,1) name9,n,nnz
00677     1 format(/,'CSR Mat:',a9,3x,'n =',i5,3x,'nnz =',i5,/)
00678 c
00679       n16 = min(n,16)
00680       n29 = min(n,29)
00681       do i=1,n29
00682          call blank(s,9*16)
00683          n1 = ia(i)
00684          n2 = ia(i+1)-1
00685          do jj=n1,n2
00686             j = ja  (jj)
00687             a = acsr(jj)
00688             if (a.ne.0..and.j.le.n16) write(s(j),9) a
00689          enddo
00690          write(6,16) (s(k),k=1,n16)
00691       enddo
00692     9 format(f9.4)
00693    16 format(16a9)
00694 c
00695       return
00696       end
00697 c-----------------------------------------------------------------------
00698       subroutine local_grad3(ur,us,ut,u,N,e,D,Dt)
00699 c     Output: ur,us,ut         Input:u,N,e,D,Dt
00700       real ur(0:N,0:N,0:N),us(0:N,0:N,0:N),ut(0:N,0:N,0:N)
00701       real u (0:N,0:N,0:N,1)
00702       real D (0:N,0:N),Dt(0:N,0:N)
00703       integer e
00704 c
00705       m1 = N+1
00706       m2 = m1*m1
00707 c
00708       call mxm(D ,m1,u(0,0,0,e),m1,ur,m2)
00709       do k=0,N
00710          call mxm(u(0,0,k,e),m1,Dt,m1,us(0,0,k),m1)
00711       enddo
00712       call mxm(u(0,0,0,e),m2,Dt,m1,ut,m1)
00713 c
00714       return
00715       end
00716 c-----------------------------------------------------------------------
00717       subroutine local_grad2(ur,us,u,N,e,D,Dt)
00718 c     Output: ur,us         Input:u,N,e,D,Dt
00719       real ur(0:N,0:N),us(0:N,0:N)
00720       real u (0:N,0:N,1)
00721       real D (0:N,0:N),Dt(0:N,0:N)
00722       integer e
00723 c
00724       m1 = N+1
00725 c
00726       call mxm(D ,m1,u(0,0,e),m1,ur,m1)
00727       call mxm(u(0,0,e),m1,Dt,m1,us,m1)
00728 c
00729       return
00730       end
00731 c-----------------------------------------------------------------------
00732       subroutine gradm1(ux,uy,uz,u)
00733 c
00734 c     Compute gradient of T -- mesh 1 to mesh 1 (vel. to vel.)
00735 c
00736       include 'SIZE'
00737       include 'DXYZ'
00738       include 'GEOM'
00739       include 'INPUT'
00740       include 'TSTEP'
00741 c
00742       parameter (lxyz=lx1*ly1*lz1)
00743       real ux(lxyz,1),uy(lxyz,1),uz(lxyz,1),u(lxyz,1)
00744 
00745       common /ctmp1/ ur(lxyz),us(lxyz),ut(lxyz)
00746 
00747       integer e
00748 
00749       nxyz = nx1*ny1*nz1
00750       ntot = nxyz*nelt
00751 
00752       N = nx1-1
00753       do e=1,nelt
00754          if (if3d) then
00755             call local_grad3(ur,us,ut,u,N,e,dxm1,dxtm1)
00756             do i=1,lxyz
00757                ux(i,e) = jacmi(i,e)*(ur(i)*rxm1(i,1,1,e)
00758      $                             + us(i)*sxm1(i,1,1,e)
00759      $                             + ut(i)*txm1(i,1,1,e) )
00760                uy(i,e) = jacmi(i,e)*(ur(i)*rym1(i,1,1,e)
00761      $                             + us(i)*sym1(i,1,1,e)
00762      $                             + ut(i)*tym1(i,1,1,e) )
00763                uz(i,e) = jacmi(i,e)*(ur(i)*rzm1(i,1,1,e)
00764      $                             + us(i)*szm1(i,1,1,e)
00765      $                             + ut(i)*tzm1(i,1,1,e) )
00766             enddo
00767          else
00768             if (ifaxis) call setaxdy (ifrzer(e))
00769             call local_grad2(ur,us,u,N,e,dxm1,dytm1)
00770             do i=1,lxyz
00771                ux(i,e) =jacmi(i,e)*(ur(i)*rxm1(i,1,1,e)
00772      $                            + us(i)*sxm1(i,1,1,e) )
00773                uy(i,e) =jacmi(i,e)*(ur(i)*rym1(i,1,1,e)
00774      $                            + us(i)*sym1(i,1,1,e) )
00775             enddo
00776          endif
00777       enddo
00778 c
00779       return
00780       end
00781 c-----------------------------------------------------------------------
00782       subroutine comp_vort3(vort,work1,work2,u,v,w)
00783 c
00784       include 'SIZE'
00785       include 'TOTAL'
00786 c
00787       parameter(lt=lx1*ly1*lz1*lelv)
00788       real vort(lt,3),work1(1),work2(1),u(1),v(1),w(1)
00789 c
00790       ntot  = nx1*ny1*nz1*nelv
00791       if (if3d) then
00792 c        work1=dw/dy ; work2=dv/dz
00793            call dudxyz(work1,w,rym1,sym1,tym1,jacm1,1,2)
00794            call dudxyz(work2,v,rzm1,szm1,tzm1,jacm1,1,3)
00795            call sub3(vort(1,1),work1,work2,ntot)
00796 c        work1=du/dz ; work2=dw/dx
00797            call dudxyz(work1,u,rzm1,szm1,tzm1,jacm1,1,3)
00798            call dudxyz(work2,w,rxm1,sxm1,txm1,jacm1,1,1)
00799            call sub3(vort(1,2),work1,work2,ntot)
00800 c        work1=dv/dx ; work2=du/dy
00801            call dudxyz(work1,v,rxm1,sxm1,txm1,jacm1,1,1)
00802            call dudxyz(work2,u,rym1,sym1,tym1,jacm1,1,2)
00803            call sub3(vort(1,3),work1,work2,ntot)
00804       else
00805 c        work1=dv/dx ; work2=du/dy
00806            call dudxyz(work1,v,rxm1,sxm1,txm1,jacm1,1,1)
00807            call dudxyz(work2,u,rym1,sym1,tym1,jacm1,1,2)
00808            call sub3(vort,work1,work2,ntot)
00809       endif
00810 c
00811 c    Avg at bndry
00812 c
00813       ifielt = ifield
00814       ifield = 1
00815       if (if3d) then
00816          do idim=1,ndim
00817             call col2  (vort(1,idim),bm1,ntot)
00818             call dssum (vort(1,idim),nx1,ny1,nz1)
00819             call col2  (vort(1,idim),binvm1,ntot)
00820          enddo
00821       else
00822          call col2  (vort,bm1,ntot)
00823          call dssum (vort,nx1,ny1,nz1)
00824          call col2  (vort,binvm1,ntot)
00825       endif
00826       ifield = ifielt
00827 c
00828       return
00829       end
00830 c-----------------------------------------------------------------------
00831       subroutine surface_int(sint,sarea,a,e,f)
00832 C
00833       include 'SIZE'
00834       include 'GEOM'
00835       include 'PARALLEL'
00836       include 'TOPOL'
00837       real a(lx1,ly1,lz1,1)
00838 
00839       integer e,f
00840 
00841       call dsset(nx1,ny1,nz1)
00842 
00843       iface  = eface1(f)
00844       js1    = skpdat(1,iface)
00845       jf1    = skpdat(2,iface)
00846       jskip1 = skpdat(3,iface)
00847       js2    = skpdat(4,iface)
00848       jf2    = skpdat(5,iface)
00849       jskip2 = skpdat(6,iface)
00850 
00851       sarea = 0.
00852       sint  = 0.
00853       i     = 0
00854 
00855       do 100 j2=js2,jf2,jskip2
00856       do 100 j1=js1,jf1,jskip1
00857          i = i+1
00858          sarea = sarea+area(i,1,f,e)
00859          sint  = sint +area(i,1,f,e)*a(j1,j2,1,e)
00860   100 continue
00861 
00862       return
00863       end
00864 c-----------------------------------------------------------------------
00865       subroutine surface_flux(dq,qx,qy,qz,e,f,w)
00866 
00867       include 'SIZE'
00868       include 'GEOM'
00869       include 'INPUT'
00870       include 'PARALLEL'
00871       include 'TOPOL'
00872       parameter (l=lx1*ly1*lz1)
00873 
00874       real qx(l,1),qy(l,1),qz(l,1),w(lx1,ly1,lz1)
00875       integer e,f
00876 
00877       call           faccl3  (w,qx(1,e),unx(1,1,f,e),f)
00878       call           faddcl3 (w,qy(1,e),uny(1,1,f,e),f)
00879       if (if3d) call faddcl3 (w,qz(1,e),unz(1,1,f,e),f)
00880 
00881       call dsset(nx1,ny1,nz1)
00882       iface  = eface1(f)
00883       js1    = skpdat(1,iface)
00884       jf1    = skpdat(2,iface)
00885       jskip1 = skpdat(3,iface)
00886       js2    = skpdat(4,iface)
00887       jf2    = skpdat(5,iface)
00888       jskip2 = skpdat(6,iface)
00889 
00890       dq = 0
00891       i  = 0
00892       do 100 j2=js2,jf2,jskip2
00893       do 100 j1=js1,jf1,jskip1
00894          i = i+1
00895          dq    = dq + area(i,1,f,e)*w(j1,j2,1)
00896   100 continue
00897 
00898       return
00899       end
00900 c-----------------------------------------------------------------------
00901       subroutine gaujordf(a,m,n,indr,indc,ipiv,ierr,rmult)
00902 C
00903 C     Gauss-Jordan matrix inversion with full pivoting
00904 c
00905 c     Num. Rec. p. 30, 2nd Ed., Fortran
00906 c
00907 C
00908 C     a     is an m x n matrix
00909 C     rmult is a  work array of dimension m
00910 C
00911 c
00912       real a(m,n),rmult(m)
00913       integer indr(m),indc(n),ipiv(n)
00914 
00915 c     call outmat(a,m,n,'ab4',n)
00916 c     do i=1,m
00917 c        write(6,1) (a(i,j),j=1,n)
00918 c     enddo
00919 c 1   format('mat: ',1p6e12.4)
00920 
00921       ierr = 0
00922       eps = 1.e-9
00923       call izero(ipiv,m)
00924 
00925       do k=1,m
00926          amx=0.
00927          do i=1,m                    ! Pivot search
00928             if (ipiv(i).ne.1) then
00929                do j=1,m
00930                   if (ipiv(j).eq.0) then
00931                     if (abs(a(i,j)).ge.amx) then
00932                        amx = abs(a(i,j))
00933                        ir  = i
00934                        jc  = j
00935                     endif
00936                  elseif (ipiv(j).gt.1) then
00937                     ierr = -ipiv(j)
00938                     return
00939                  endif
00940               enddo
00941            endif
00942         enddo
00943         ipiv(jc) = ipiv(jc) + 1
00944 c
00945 c       Swap rows
00946         if (ir.ne.jc) then
00947            do j=1,n
00948               tmp     = a(ir,j)
00949               a(ir,j) = a(jc,j)
00950               a(jc,j) = tmp
00951            enddo
00952         endif
00953         indr(k)=ir
00954         indc(k)=jc
00955 c       write(6 ,*) k,' Piv:',jc,a(jc,jc)
00956 c       write(28,*) k,' Piv:',jc,a(jc,jc)
00957         if (abs(a(jc,jc)).lt.eps) then
00958            write(6 ,*) 'small Gauss Jordan Piv:',jc,a(jc,jc)
00959            write(28,*) 'small Gauss Jordan Piv:',jc,a(jc,jc)
00960            ierr = jc
00961            call exitt
00962            return
00963         endif
00964         piv = 1./a(jc,jc)
00965         a(jc,jc)=1.
00966         do j=1,n
00967            a(jc,j) = a(jc,j)*piv
00968         enddo
00969 c
00970         do j=1,n
00971            work    = a(jc,j)
00972            a(jc,j) = a(1 ,j)
00973            a(1 ,j) = work
00974         enddo
00975         do i=2,m
00976            rmult(i) = a(i,jc)
00977            a(i,jc)  = 0.
00978         enddo
00979 c
00980         do j=1,n
00981         do i=2,m
00982            a(i,j) = a(i,j) - rmult(i)*a(1,j)
00983         enddo
00984         enddo
00985 c
00986         do j=1,n
00987            work    = a(jc,j)
00988            a(jc,j) = a(1 ,j)
00989            a(1 ,j) = work
00990         enddo
00991 c
00992 c       do i=1,m
00993 c          if (i.ne.jc) then
00994 c             rmult   = a(i,jc)
00995 c             a(i,jc) = 0.
00996 c             do j=1,n
00997 c                a(i,j) = a(i,j) - rmult*a(jc,j)
00998 c             enddo
00999 c          endif
01000 c       enddo
01001 c
01002       enddo
01003 c
01004 c     Unscramble matrix
01005       do j=m,1,-1
01006          if (indr(j).ne.indc(j)) then
01007             do i=1,m
01008                tmp=a(i,indr(j))
01009                a(i,indr(j))=a(i,indc(j))
01010                a(i,indc(j))=tmp
01011             enddo
01012          endif
01013       enddo
01014 c
01015       return
01016       end
01017 c-----------------------------------------------------------------------
01018       subroutine legendre_poly(L,x,N)
01019 c
01020 c     Evaluate Legendre polynomials of degrees 0-N at point x
01021 c
01022       real L(0:N)
01023 c
01024       L(0) = 1.
01025       L(1) = x
01026 c
01027       do j=2,N
01028          L(j) = ( (2*j-1) * x * L(j-1) - (j-1) * L(j-2) ) / j 
01029       enddo
01030 c
01031       return
01032       end
01033 c-----------------------------------------------------------------------
01034       subroutine build_new_filter(intv,zpts,nx,kut,wght,nio)
01035 c
01036 c     This routing builds a 1D filter with a transfer function that
01037 c     looks like:
01038 c
01039 c
01040 c        ^
01041 c    d_k |
01042 c        |                 |
01043 c     1  |__________      _v_
01044 c        |          -_     
01045 c        |            \  wght
01046 c        |             \  ___
01047 c        |             |   ^
01048 c     0  |-------------|---|>
01049 c
01050 c        0         c   N   k-->
01051 c
01052 c        Where c := N-kut is the point below which d_k = 1.
01053 c
01054 c
01055 c
01056 c      Here, nx = number of points
01057 c
01058       real intv(nx,nx),zpts(nx)
01059 c
01060       parameter (lm=40)
01061       parameter (lm2=lm*lm)
01062       real      phi(lm2),pht(lm2),diag(lm2),rmult(lm),Lj(lm)
01063       integer   indr(lm),indc(lm),ipiv(lm)
01064 c
01065       if (nx.gt.lm) then
01066          write(6,*) 'ABORT in build_new_filter:',nx,lm
01067          call exitt
01068       endif
01069 c
01070       kj = 0
01071       n  = nx-1
01072       do j=1,nx
01073          z = zpts(j)
01074          call legendre_poly(Lj,z,n)
01075          kj = kj+1
01076          pht(kj) = Lj(1)
01077          kj = kj+1
01078          pht(kj) = Lj(2)
01079          do k=3,nx
01080             kj = kj+1
01081             pht(kj) = Lj(k)-Lj(k-2)
01082          enddo
01083       enddo
01084       call transpose (phi,nx,pht,nx)
01085       call copy      (pht,phi,nx*nx)
01086       call gaujordf  (pht,nx,nx,indr,indc,ipiv,ierr,rmult)
01087 c
01088 c     Set up transfer function
01089 c
01090       call ident   (diag,nx)
01091 c
01092       k0 = nx-kut
01093       do k=k0+1,nx
01094          kk = k+nx*(k-1)
01095          amp = wght*(k-k0)*(k-k0)/(kut*kut)   ! quadratic growth
01096          diag(kk) = 1.-amp
01097       enddo
01098 c
01099       call mxm  (diag,nx,pht,nx,intv,nx)      !          -1
01100       call mxm  (phi ,nx,intv,nx,pht,nx)      !     V D V
01101       call copy (intv,pht,nx*nx)
01102 c
01103       do k=1,nx*nx
01104          pht(k) = 1.-diag(k)
01105       enddo
01106       np1 = nx+1
01107       if (nio.eq.0) then
01108          write(6,6) 'filt amp',(pht (k),k=1,nx*nx,np1)
01109          write(6,6) 'filt trn',(diag(k),k=1,nx*nx,np1)
01110    6     format(a8,16f7.4,6(/,8x,16f7.4))
01111       endif
01112 c
01113       return
01114       end
01115 c-----------------------------------------------------------------------
01116       subroutine avg_all
01117 c
01118 c     This routine computes running averages E(X),E(X^2),E(X*Y)
01119 c     and outputs to avg*.fld*, rms*.fld*, and rm2*.fld* for all
01120 c     fields.
01121 c
01122 c     E denotes the expected value operator and X,Y two
01123 c     real valued random variables.
01124 c
01125 c     variances and covariances can be computed in a post-processing step:
01126 c
01127 c        var(X)   := E(X^X) - E(X)*E(X) 
01128 c        cov(X,Y) := E(X*Y) - E(X)*E(Y)  
01129 c
01130 c     Note: The E-operator is linear, in the sense that the expected
01131 c           value is given by E(X) = 1/N * sum[ E(X)_i ], where E(X)_i
01132 c           is the expected value of the sub-ensemble i (i=1...N).
01133 c
01134       include 'SIZE'  
01135       include 'TOTAL' 
01136       include 'AVG'
01137 
01138       logical ifverbose
01139       integer icalld
01140       save    icalld
01141       data    icalld  /0/
01142 
01143       if (ax1.ne.lx1 .or. ay1.ne.ly1 .or. az1.ne.lz1) then
01144          if(nid.eq.0) write(6,*)
01145      $     'ABORT: wrong size of ax1,ay1,az1 in avg_all(), check SIZE!'
01146          call exitt
01147       endif
01148       if (ax2.ne.lx2 .or. ay2.ne.ay2 .or. az2.ne.lz2) then
01149          if(nid.eq.0) write(6,*)
01150      $     'ABORT: wrong size of ax2,ay2,az2 in avg_all(), check SIZE!'
01151          call exitt
01152       endif
01153 
01154       ntot  = nx1*ny1*nz1*nelv
01155       ntott = nx1*ny1*nz1*nelt
01156       nto2  = nx2*ny2*nz2*nelv
01157 
01158       ! initialization
01159       if (icalld.eq.0) then
01160          icalld = icalld + 1
01161          atime  = 0.
01162          timel  = time
01163 
01164          call rzero(uavg,ntot)
01165          call rzero(vavg,ntot)
01166          call rzero(wavg,ntot)
01167          call rzero(pavg,nto2)
01168          do i = 1,ldimt
01169             call rzero(tavg(1,1,1,1,i),ntott)
01170          enddo
01171 
01172          call rzero(urms,ntot)
01173          call rzero(vrms,ntot)
01174          call rzero(wrms,ntot)
01175          call rzero(prms,nto2)
01176          do i = 1,ldimt
01177             call rzero(trms(1,1,1,1,i),ntott)
01178          enddo
01179 
01180          call rzero(vwms,ntot)
01181          call rzero(wums,ntot)
01182          call rzero(uvms,ntot)
01183       endif
01184 
01185       dtime = time  - timel
01186       atime = atime + dtime
01187 
01188       ! dump freq
01189       iastep = param(68)
01190       if  (iastep.eq.0) iastep=param(15)   ! same as iostep
01191       if  (iastep.eq.0) iastep=500
01192 
01193       ifverbose=.false.
01194       if (istep.le.10) ifverbose=.true.
01195       if  (mod(istep,iastep).eq.0) ifverbose=.true.
01196 
01197       if (atime.ne.0..and.dtime.ne.0.) then
01198          if(nio.eq.0) write(6,*) 'Compute statistics ...'
01199          beta  = dtime/atime
01200          alpha = 1.-beta
01201          ! compute averages E(X)
01202          call avg1    (uavg,vx,alpha,beta,ntot ,'um  ',ifverbose)
01203          call avg1    (vavg,vy,alpha,beta,ntot ,'vm  ',ifverbose)
01204          call avg1    (wavg,vz,alpha,beta,ntot ,'wm  ',ifverbose)
01205          call avg1    (pavg,pr,alpha,beta,nto2 ,'prm ',ifverbose)
01206          call avg1    (tavg,t ,alpha,beta,ntott,'tm  ',ifverbose)
01207          do i = 2,ldimt
01208             call avg1 (tavg(1,1,1,1,i),t(1,1,1,1,i),alpha,beta,
01209      &                 ntott,'psav',ifverbose)
01210          enddo
01211 
01212          ! compute averages E(X^2) 
01213          call avg2    (urms,vx,alpha,beta,ntot ,'ums ',ifverbose)
01214          call avg2    (vrms,vy,alpha,beta,ntot ,'vms ',ifverbose)
01215          call avg2    (wrms,vz,alpha,beta,ntot ,'wms ',ifverbose)
01216          call avg2    (prms,pr,alpha,beta,nto2 ,'prms',ifverbose)
01217          call avg2    (trms,t ,alpha,beta,ntott,'tms ',ifverbose)
01218          do i = 2,ldimt
01219             call avg2 (trms(1,1,1,1,i),t(1,1,1,1,i),alpha,beta,
01220      &                 ntott,'psms',ifverbose)
01221          enddo
01222 
01223          ! compute averages E(X*Y) (for now just for the velocities)
01224          call avg3    (uvms,vx,vy,alpha,beta,ntot,'uvm ',ifverbose)
01225          call avg3    (vwms,vy,vz,alpha,beta,ntot,'vwm ',ifverbose)
01226          call avg3    (wums,vz,vx,alpha,beta,ntot,'wum ',ifverbose)
01227       endif
01228 c
01229 c-----------------------------------------------------------------------
01230       if ( (mod(istep,iastep).eq.0.and.istep.gt.1) .or.lastep.eq.1) then
01231 
01232          time_temp = time
01233          time      = atime   ! Output the duration of this avg
01234 
01235          call outpost2(uavg,vavg,wavg,pavg,tavg,ldimt,'avg')
01236          call outpost2(urms,vrms,wrms,prms,trms,ldimt,'rms')
01237          call outpost (uvms,vwms,wums,prms,trms,      'rm2')
01238 
01239          atime = 0.
01240          time  = time_temp  ! Restore clock
01241 
01242       endif
01243 c
01244       timel = time
01245 c
01246       return
01247       end
01248 c-----------------------------------------------------------------------
01249       subroutine avg1(avg,f,alpha,beta,n,name,ifverbose)
01250       include 'SIZE'
01251       include 'TSTEP'
01252 c
01253       real avg(n),f(n)
01254       character*4 name
01255       logical ifverbose
01256 c
01257       do k=1,n
01258          avg(k) = alpha*avg(k) + beta*f(k)
01259       enddo
01260 c
01261       if (ifverbose) then
01262          avgmax = glmax(avg,n)
01263          avgmin = glmin(avg,n)
01264          if (nio.eq.0) write(6,1) istep,time,avgmin,avgmax
01265      $                           ,alpha,beta,name
01266     1    format(i9,1p5e13.5,1x,a4,' av1mnx')
01267       endif
01268 c
01269       return
01270       end
01271 c-----------------------------------------------------------------------
01272       subroutine avg2(avg,f,alpha,beta,n,name,ifverbose)
01273       include 'SIZE'
01274       include 'TSTEP'
01275 c
01276       real avg(n),f(n)
01277       character*4 name
01278       logical ifverbose
01279 c
01280       do k=1,n
01281          avg(k) = alpha*avg(k) + beta*f(k)*f(k)
01282       enddo
01283 c
01284       if (ifverbose) then
01285          avgmax = glmax(avg,n)
01286          avgmin = glmin(avg,n)
01287          if (nio.eq.0) write(6,1) istep,time,avgmin,avgmax
01288      $                           ,alpha,beta,name
01289     1    format(i9,1p5e13.5,1x,a4,' av2mnx')
01290       endif
01291 c
01292       return
01293       end
01294 c-----------------------------------------------------------------------
01295       subroutine avg3(avg,f,g,alpha,beta,n,name,ifverbose)
01296       include 'SIZE'
01297       include 'TSTEP'
01298 c
01299       real avg(n),f(n),g(n)
01300       character*4 name
01301       logical ifverbose
01302 c
01303       do k=1,n
01304          avg(k) = alpha*avg(k) + beta*f(k)*g(k)
01305       enddo
01306 c
01307       if (ifverbose) then
01308          avgmax = glmax(avg,n)
01309          avgmin = glmin(avg,n)
01310          if (nio.eq.0) write(6,1) istep,time,avgmin,avgmax
01311      $                           ,alpha,beta,name
01312     1    format(i9,1p5e13.5,1x,a4,' av3mnx')
01313       endif
01314 c
01315       return
01316       end
01317 c-----------------------------------------------------------------------
01318       subroutine build_legend_transform(Lj,Ljt,zpts,nx)
01319 c
01320       real Lj(nx*nx),Ljt(nx*nx),zpts(nx)
01321 c
01322       parameter (lm=90)
01323       integer   indr(lm),indc(lm),ipiv(lm)
01324 c
01325       if (nx.gt.lm) then
01326          write(6,*) 'ABORT in build_legend_transform:',nx,lm
01327          call exitt
01328       endif
01329 c
01330       j = 1
01331       n = nx-1
01332       do i=1,nx
01333          z = zpts(i)
01334          call legendre_poly(Lj(j),z,n)  ! Return Lk(z), k=0,...,n
01335          j = j+nx
01336       enddo
01337       call transpose1(Lj,nx)
01338 c     call outmat(Lj,nx,nx,'Lj ',n)
01339 c     call exitt
01340       call gaujordf  (Lj,nx,nx,indr,indc,ipiv,ierr,rmult)
01341       call transpose (Ljt,nx,Lj,nx)
01342 c
01343       return
01344       end
01345 c-----------------------------------------------------------------------
01346       subroutine local_err_est(err,u,nx,Lj,Ljt,uh,w,if3d)
01347 c
01348 c     Local error estimates for u_e
01349 c
01350       include 'SIZE'
01351       real err(5,2),u(1),uh(nx,nx,nx),w(1),Lj(1),Ljt(1)
01352       logical if3d
01353 c
01354       call rzero(err,10)
01355 c
01356       nxyz = nx**ndim
01357       utot = vlsc2(u,u,nxyz)
01358       if (utot.eq.0) return
01359 c
01360       call tensr3(uh,nx,u,nx,Lj,Ljt,Ljt,w)    !  Go to Legendre space
01361 c
01362 c
01363 c     Get energy in low modes
01364 c
01365       m = nx-2
01366 c
01367       if (if3d) then
01368          amp2_l = 0.
01369          do k=1,m
01370          do j=1,m
01371          do i=1,m
01372             amp2_l = amp2_l + uh(i,j,k)**2
01373          enddo
01374          enddo
01375          enddo
01376 c
01377 c        Energy in each spatial direction
01378 c        
01379          amp2_t = 0
01380          do k=m+1,nx
01381          do j=1,m
01382          do i=1,m
01383             amp2_t = amp2_t + uh(i,j,k)**2
01384          enddo
01385          enddo
01386          enddo
01387 c        
01388          amp2_s = 0
01389          do k=1,m
01390          do j=m+1,nx
01391          do i=1,m
01392             amp2_s = amp2_s + uh(i,j,k)**2
01393          enddo
01394          enddo
01395          enddo
01396 c        
01397          amp2_r = 0
01398          do k=1,m
01399          do j=1,m
01400          do i=m+1,nx
01401             amp2_r = amp2_r + uh(i,j,k)**2
01402          enddo
01403          enddo
01404          enddo
01405 c
01406          amp2_h = 0
01407          do k=m+1,nx
01408          do j=m+1,nx
01409          do i=m+1,nx
01410             amp2_h = amp2_h + uh(i,j,k)**2
01411          enddo
01412          enddo
01413          enddo
01414 c
01415          etot = amp2_l + amp2_r + amp2_s + amp2_t + amp2_h
01416 c
01417          relr = amp2_r / (amp2_r + amp2_l)
01418          rels = amp2_s / (amp2_s + amp2_l)
01419          relt = amp2_t / (amp2_t + amp2_l)
01420          relh = (amp2_r + amp2_s + amp2_t + amp2_h) / etot
01421 c
01422       else
01423          k = 1
01424          amp2_l = 0.
01425          do j=1,m
01426          do i=1,m
01427             amp2_l = amp2_l + uh(i,j,k)**2
01428          enddo
01429          enddo
01430          if (amp2_l.eq.0) return
01431 c
01432 c        Energy in each spatial direction
01433 c        
01434          amp2_t = 0
01435 c        
01436          amp2_s = 0
01437          do j=m+1,nx
01438          do i=1,m
01439             amp2_s = amp2_s + uh(i,j,k)**2
01440          enddo
01441          enddo
01442 c        
01443          amp2_r = 0
01444          do j=1,m
01445          do i=m+1,nx
01446             amp2_r = amp2_r + uh(i,j,k)**2
01447          enddo
01448          enddo
01449 c
01450          amp2_h = 0
01451          do j=m+1,nx
01452          do i=m+1,nx
01453             amp2_h = amp2_h + uh(i,j,k)**2
01454          enddo
01455          enddo
01456 c
01457          etot = amp2_l + amp2_r + amp2_s + amp2_h
01458 c
01459          relr = amp2_r / (amp2_r + amp2_l)
01460          rels = amp2_s / (amp2_s + amp2_l)
01461          relt = 0
01462          relh = (amp2_r + amp2_s + amp2_h) / etot
01463 c
01464       endif
01465 c
01466       err (1,1) = sqrt(relr)
01467       err (2,1) = sqrt(rels)
01468       if (if3d) err (3,1) = sqrt(relt)
01469       err (4,1) = sqrt(relh)
01470       err (5,1) = sqrt(etot)
01471 c
01472       err (1,2) = sqrt(amp2_r)
01473       err (2,2) = sqrt(amp2_s)
01474       if (if3d) err (3,2) = sqrt(amp2_t)
01475       err (4,2) = sqrt(amp2_h)
01476       err (5,2) = sqrt(utot)
01477 c
01478       return
01479       end
01480 c-----------------------------------------------------------------------
01481       subroutine transpose1(a,n)
01482       real a(n,n)
01483 c
01484       do j=1,n
01485       do i=j+1,n
01486          ta     = a(i,j)
01487          a(i,j) = a(j,i)
01488          a(j,i) = ta
01489       enddo
01490       enddo
01491       return
01492       end
01493 c-----------------------------------------------------------------------
01494       subroutine get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
01495       integer ex,ey,ez,eg
01496 c
01497       nelxy = nelx*nely
01498 c
01499       ez = 1 +  (eg-1)/nelxy
01500       ey = mod1 (eg,nelxy)
01501       ey = 1 +  (ey-1)/nelx
01502       ex = mod1 (eg,nelx)
01503 c
01504       return
01505       end
01506 c-----------------------------------------------------------------------
01507       subroutine dump_header2d(excode,nx,ny,nlx,nly,ierr)
01508 
01509       include 'SIZE'
01510       include 'TOTAL'
01511 
01512       character*2 excode(15)
01513 
01514       real*4         test_pattern
01515 
01516       character*1 fhdfle1(132)
01517       character*132 fhdfle
01518       equivalence (fhdfle,fhdfle1)
01519 
01520       jstep = istep
01521       if (jstep.gt.10000) jstep = jstep / 10
01522       if (jstep.gt.10000) jstep = jstep / 10
01523       if (jstep.gt.10000) jstep = jstep / 10
01524       if (jstep.gt.10000) jstep = jstep / 10
01525       if (jstep.gt.10000) jstep = jstep / 10
01526 
01527       nlxy = nlx*nly
01528       nzz  = 1
01529 
01530 c     write(6,'(4i4,1PE14.7,i5,1x,15a2,1x,a12)')
01531 c    $  nlxy,nx,ny,nzz,TIME,jstep,(excode(i),i=1,15),
01532 c    $  'NELT,NX,NY,N'
01533 c
01534       p66 = 0.
01535       ierr= 0
01536       IF (p66.EQ.1.0) THEN
01537 C       unformatted i/o
01538         WRITE(24)
01539      $  nlxy,nx,ny,nzz,TIME,jstep,(excode(i),i=1,15)
01540       ELSEIF (p66.EQ.3.0) THEN
01541 C       formatted i/o to header file
01542         WRITE(27,'(4I4,1pe14.7,I5,1X,15A2,1X,A12)')
01543      $  nlxy,nx,ny,nzz,TIME,jstep,(excode(i),i=1,15),
01544      $  'NELT,NX,NY,N'
01545       ELSEIF (p66.eq.4.0) THEN
01546 C       formatted i/o to header file
01547         WRITE(fhdfle,'(4I4,1pe14.7,I5,1X,15A2,1X,A12)')
01548      $  nlxy,nx,ny,nzz,TIME,jstep,(excode(i),i=1,15),
01549      $  ' 4 NELT,NX,NY,N'
01550         call byte_write(fhdfle,20,ierr)
01551       ELSEIF (p66.eq.5.0) THEN
01552 C       formatted i/o to header file
01553         WRITE(fhdfle,'(4I4,1pe14.7,I5,1X,15A2,1X,A12)')
01554      $  nlxy,nx,ny,nzz,TIME,jstep,(excode(i),i=1,15),
01555      $  ' 8 NELT,NX,NY,N'
01556         call byte_write(fhdfle,20,ierr)
01557       ELSE
01558 C       formatted i/o
01559         WRITE(24,'(4I4,1pe14.7,I5,1X,15A2,1X,A12)')
01560      $  nlxy,nx,ny,nzz,TIME,jstep,(excode(i),i=1,15),
01561      $  'NELT,NX,NY,N'
01562       ENDIF
01563 C     cdrror is a dummy cerror value for now.
01564       CDRROR=0.0
01565       IF (p66.EQ.1.0) THEN
01566 C       unformatted i/o
01567         WRITE(24)(CDRROR,I=1,nlxy)
01568       ELSEIF (p66.eq.3. .or. p66.eq.4.0) then
01569 C       write byte-ordering test pattern to byte file...
01570         test_pattern = 6.54321
01571         call byte_write(test_pattern,1,ierr)
01572       ELSEIF (p66.eq.5.) then
01573         test_pattern8 = 6.54321
01574         call byte_write(test_pattern8,2,ierr)
01575       ELSE
01576 C       formatted i/o
01577         WRITE(24,'(6G11.4)')(CDRROR,I=1,nlxy)
01578       ENDIF
01579  
01580       return
01581       end
01582 c-----------------------------------------------------------------------
01583       subroutine outfld2d_p(u,v,w,nx,ny,nlx,nly,name,ifld,jid,npido,ir)
01584 
01585       include 'SIZE'
01586       include 'TOTAL'
01587 
01588       integer icalld
01589       save    icalld
01590       data    icalld /0/
01591 
01592       real u(nx*ny*nlx*nly)
01593       real v(nx*ny*nlx*nly)
01594       real w(nx*ny*nlx*nly)
01595       character*4 name
01596 
01597       character*2  excode(15)
01598       character*12 fm
01599       character*20 outfile
01600 
01601       character*1 slash,dot
01602       save        slash,dot
01603       data        slash,dot  / '/' , '.' /
01604 
01605       icalld = icalld+1
01606 
01607       call blank(excode,30)
01608       excode(4) = 'U '
01609       excode(5) = '  '
01610       excode(6) = 'T '
01611       nthings   =  3
01612       ir = 0 !error code for dump_header2d
01613 
01614       call blank(outfile,20)
01615       if (npido.lt.100) then
01616          if (ifld.lt.100) then
01617             write(outfile,22) jid,slash,name,ifld
01618    22       format('B',i2.2,a1,a4,'.fld',i2.2)
01619          elseif (ifld.lt.1000) then
01620             write(outfile,23) jid,slash,name,ifld
01621    23       format('B',i2.2,a1,a4,'.fld',i3)
01622          elseif (ifld.lt.10000) then
01623             write(outfile,24) jid,slash,name,ifld
01624    24       format('B',i2.2,a1,a4,'.fld',i4)
01625          elseif (ifld.lt.100000) then
01626             write(outfile,25) jid,slash,name,ifld
01627    25       format('B',i2.2,a1,a4,'.fld',i5)
01628          elseif (ifld.lt.1000000) then
01629             write(outfile,26) jid,slash,name,ifld
01630    26       format('B',i2.2,a1,a4,'.fld',i6)
01631          endif
01632       else
01633          if (ifld.lt.100) then
01634             write(outfile,32) jid,slash,name,ifld
01635    32       format('B',i3.3,a1,a4,'.fld',i2.2)
01636          elseif (ifld.lt.1000) then
01637             write(outfile,33) jid,slash,name,ifld
01638    33       format('B',i3.3,a1,a4,'.fld',i3)
01639          elseif (ifld.lt.10000) then
01640             write(outfile,34) jid,slash,name,ifld
01641    34       format('B',i3.3,a1,a4,'.fld',i4)
01642          elseif (ifld.lt.100000) then
01643             write(outfile,35) jid,slash,name,ifld
01644    35       format('B',i3.3,a1,a4,'.fld',i5)
01645          elseif (ifld.lt.1000000) then
01646             write(outfile,36) jid,slash,name,ifld
01647    36       format('B',i3.3,a1,a4,'.fld',i6)
01648          endif
01649       endif
01650 
01651       if (icalld.le.4) write(6,*) nid,outfile,' OPEN',nlx,nly
01652       open(unit=24,file=outfile,status='unknown')
01653       call dump_header2d(excode,nx,ny,nlx,nly,ir)
01654 
01655       n = nx*ny*nlx*nly
01656       write(fm,10) nthings
01657       write(24,fm) (u(i),v(i),w(i),i=1,n)
01658    10 format('(1p',i1,'e14.6)')
01659       close(24)
01660 
01661       return
01662       end
01663 c-----------------------------------------------------------------------
01664       subroutine outfld2d(u,v,w,nx,ny,nlx,nly,name,ifld)
01665 
01666       include 'SIZE'
01667       include 'TOTAL'
01668 
01669       real u(nx*ny*nlx*nly)
01670       real v(nx*ny*nlx*nly)
01671       real w(nx*ny*nlx*nly)
01672       character*3 name
01673 
01674       character*2  excode(15)
01675       character*12 fm
01676       character*20 outfile
01677 
01678 c     if (istep.le.10) write(6,*) nid,' in out2d:',iz
01679 
01680       call blank(excode,30)
01681 c
01682 c     excode(1) = 'X '
01683 c     excode(2) = 'Y '
01684 c     excode(3) = 'U '
01685 c     excode(4) = 'V '
01686 c     excode(5) = 'P '
01687 c     excode(6) = 'T '
01688 c
01689       excode(4) = 'U '
01690       excode(5) = '  '
01691       excode(6) = 'T '
01692       nthings   =  3
01693 
01694       ierr = 0 
01695       if (nid.eq.0) then
01696          call blank(outfile,20)
01697          if (ifld.lt.100) then
01698             write(outfile,2) name,ifld
01699     2       format(a3,'2d.fld',i2.2)
01700          elseif (ifld.lt.1000) then
01701             write(outfile,3) name,ifld
01702     3       format(a3,'2d.fld',i3)
01703          elseif (ifld.lt.10000) then
01704             write(outfile,4) name,ifld
01705     4       format(a3,'2d.fld',i4)
01706          elseif (ifld.lt.100000) then
01707             write(outfile,5) name,ifld
01708     5       format(a3,'2d.fld',i5)
01709          elseif (ifld.lt.1000000) then
01710             write(outfile,6) name,ifld
01711     6       format(a3,'2d.fld',i6)
01712          endif
01713          open(unit=24,file=outfile,status='unknown')
01714          call dump_header2d(excode,nx,ny,nlx,nly,ierr)
01715 
01716          n = nx*ny*nlx*nly
01717          write(fm,10) nthings
01718 c        write(6,*) fm
01719 c        call exitt
01720          write(24,fm) (u(i),v(i),w(i),i=1,n)
01721    10    format('(1p',i1,'e14.6)')
01722 c  10    format('''(1p',i1,'e15.7)''')
01723 c  10    format(1p7e15.7)
01724 c
01725          close(24)
01726       endif
01727       call err_chk(ierr,'Error using byte_write,outfld2d. Abort.$')
01728 
01729       return
01730       end
01731 c-----------------------------------------------------------------------
01732       subroutine planar_average_z(ua,u,w1,w2)
01733 c
01734 c     Compute r-s planar average of quantity u()
01735 c
01736       include 'SIZE'
01737       include 'GEOM'
01738       include 'PARALLEL'
01739       include 'WZ'
01740       include 'ZPER'
01741 c
01742       real ua(nz1,nelz),u(nx1*ny1,nz1,nelv),w1(nz1,nelz),w2(nz1,nelz)
01743       integer e,eg,ez
01744 c
01745       melxy = nelx*nely
01746 c
01747       nz = nz1*nelz
01748       call rzero(ua,nz)
01749       call rzero(w1,nz)
01750 c
01751       do e=1,nelt
01752 c
01753          eg = lglel(e)
01754          ez = 1 + (eg-1)/melxy
01755 c
01756          do k=1,nz1
01757          do i=1,nx1*ny1
01758             zz = (1.-zgm1(k,3))/2.  ! = 1 for k=1, = 0 for k=nz1
01759             aa = zz*area(i,1,5,e) + (1-zz)*area(i,1,6,e)  ! wgtd jacobian
01760             w1(k,ez) = w1(k,ez) + aa
01761             ua(k,ez) = ua(k,ez) + aa*u(i,k,e)
01762          enddo
01763          enddo
01764       enddo
01765 c
01766       call gop(ua,w2,'+  ',nz)
01767       call gop(w1,w2,'+  ',nz)
01768 c
01769       do i=1,nz
01770          ua(i,1) = ua(i,1) / w1(i,1)   ! Normalize
01771       enddo
01772 c
01773       return
01774       end
01775 c-----------------------------------------------------------------------
01776       subroutine drgtrq(dgtq,xm0,ym0,zm0,sij,pm1,visc,f,e)
01777 c
01778       INCLUDE 'SIZE'
01779       INCLUDE 'GEOM'
01780       INCLUDE 'INPUT'
01781       INCLUDE 'TOPOL'
01782       INCLUDE 'TSTEP'
01783 c
01784       real dgtq(3,4)
01785       real xm0 (lx1,ly1,lz1,lelt)
01786       real ym0 (lx1,ly1,lz1,lelt)
01787       real zm0 (lx1,ly1,lz1,lelt)
01788       real sij (lx1,ly1,lz1,3*ldim-3,lelv)
01789       real pm1 (lx1,ly1,lz1,lelv)
01790       real visc(lx1,ly1,lz1,lelv)
01791 c
01792       real dg(3,2)
01793 c
01794       integer f,e,pf
01795       real    n1,n2,n3
01796 c
01797       call dsset(nx1,ny1,nz1)    ! set up counters
01798       pf     = eface1(f)         ! convert from preproc. notation
01799       js1    = skpdat(1,pf)
01800       jf1    = skpdat(2,pf)
01801       jskip1 = skpdat(3,pf)
01802       js2    = skpdat(4,pf)
01803       jf2    = skpdat(5,pf)
01804       jskip2 = skpdat(6,pf)
01805 C
01806       call rzero(dgtq,12)
01807 c
01808       if (if3d.or.ifaxis) then
01809        i = 0
01810        a = 0
01811        do j2=js2,jf2,jskip2
01812        do j1=js1,jf1,jskip1
01813          i = i+1
01814          n1 = unx(i,1,f,e)*area(i,1,f,e)
01815          n2 = uny(i,1,f,e)*area(i,1,f,e)
01816          n3 = unz(i,1,f,e)*area(i,1,f,e)
01817          a  = a +          area(i,1,f,e)
01818 c
01819          v  = visc(j1,j2,1,e)
01820 c
01821          s11 = sij(j1,j2,1,1,e)
01822          s21 = sij(j1,j2,1,4,e)
01823          s31 = sij(j1,j2,1,6,e)
01824 c
01825          s12 = sij(j1,j2,1,4,e)
01826          s22 = sij(j1,j2,1,2,e)
01827          s32 = sij(j1,j2,1,5,e)
01828 c
01829          s13 = sij(j1,j2,1,6,e)
01830          s23 = sij(j1,j2,1,5,e)
01831          s33 = sij(j1,j2,1,3,e)
01832 c
01833          dg(1,1) = pm1(j1,j2,1,e)*n1     ! pressure drag
01834          dg(2,1) = pm1(j1,j2,1,e)*n2
01835          dg(3,1) = pm1(j1,j2,1,e)*n3
01836 c
01837          dg(1,2) = -v*(s11*n1 + s12*n2 + s13*n3) ! viscous drag
01838          dg(2,2) = -v*(s21*n1 + s22*n2 + s23*n3)
01839          dg(3,2) = -v*(s31*n1 + s32*n2 + s33*n3)
01840 c
01841          r1 = xm0(j1,j2,1,e)
01842          r2 = ym0(j1,j2,1,e)
01843          r3 = zm0(j1,j2,1,e)
01844 c
01845          do l=1,2
01846          do k=1,3
01847             dgtq(k,l) = dgtq(k,l) + dg(k,l)
01848          enddo
01849          enddo
01850 c
01851          dgtq(1,3) = dgtq(1,3) + (r2*dg(3,1)-r3*dg(2,1)) ! pressure
01852          dgtq(2,3) = dgtq(2,3) + (r3*dg(1,1)-r1*dg(3,1)) ! torque
01853          dgtq(3,3) = dgtq(3,3) + (r1*dg(2,1)-r2*dg(1,1))
01854 c
01855          dgtq(1,4) = dgtq(1,4) + (r2*dg(3,2)-r3*dg(2,2)) ! viscous
01856          dgtq(2,4) = dgtq(2,4) + (r3*dg(1,2)-r1*dg(3,2)) ! torque
01857          dgtq(3,4) = dgtq(3,4) + (r1*dg(2,2)-r2*dg(1,2))
01858        enddo
01859        enddo
01860 
01861       else ! 2D
01862 
01863        i = 0
01864        a = 0
01865        do j2=js2,jf2,jskip2
01866        do j1=js1,jf1,jskip1
01867          i = i+1
01868          n1 = unx(i,1,f,e)*area(i,1,f,e)
01869          n2 = uny(i,1,f,e)*area(i,1,f,e)
01870          a  = a +          area(i,1,f,e)
01871          v  = visc(j1,j2,1,e)
01872 
01873          s11 = sij(j1,j2,1,1,e)
01874          s12 = sij(j1,j2,1,3,e)
01875          s21 = sij(j1,j2,1,3,e)
01876          s22 = sij(j1,j2,1,2,e)
01877 
01878          dg(1,1) = pm1(j1,j2,1,e)*n1     ! pressure drag
01879          dg(2,1) = pm1(j1,j2,1,e)*n2
01880          dg(3,1) = 0
01881 
01882          dg(1,2) = -v*(s11*n1 + s12*n2) ! viscous drag
01883          dg(2,2) = -v*(s21*n1 + s22*n2)
01884          dg(3,2) = 0.
01885 
01886          r1 = xm0(j1,j2,1,e)
01887          r2 = ym0(j1,j2,1,e)
01888          r3 = 0.
01889 
01890          do l=1,2
01891          do k=1,3
01892             dgtq(k,l) = dgtq(k,l) + dg(k,l)
01893          enddo
01894          enddo
01895 
01896          dgtq(1,3) = 0! dgtq(1,3) + (r2*dg(3,1)-r3*dg(2,1)) ! pressure
01897          dgtq(2,3) = 0! dgtq(2,3) + (r3*dg(1,1)-r1*dg(3,1)) ! torque
01898          dgtq(3,3) = dgtq(3,3) + (r1*dg(2,1)-r2*dg(1,1))
01899 
01900          dgtq(1,4) = 0! dgtq(1,4) + (r2*dg(3,2)-r3*dg(2,2)) ! viscous
01901          dgtq(2,4) = 0! dgtq(2,4) + (r3*dg(1,2)-r1*dg(3,2)) ! torque
01902          dgtq(3,4) = dgtq(3,4) + (r1*dg(2,2)-r2*dg(1,2))
01903        enddo
01904        enddo
01905       endif
01906 
01907       return
01908       end
01909 c-----------------------------------------------------------------------
01910       subroutine torque_calc(scale,x0,ifdout,iftout)
01911 c
01912 c     Compute torque about point x0
01913 c
01914 c     Scale is a user-supplied multiplier so that results may be
01915 c     scaled to any convenient non-dimensionalization.
01916 c
01917 c
01918       INCLUDE 'SIZE'  
01919       INCLUDE 'TOTAL' 
01920 
01921       common /cvflow_r/ flow_rate,base_flow,domain_length,xsec
01922      $                , scale_vf(3)
01923 
01924 c
01925       real x0(3),w1(0:maxobj)
01926       logical ifdout,iftout
01927 c
01928       common /scrns/         sij (lx1*ly1*lz1*6*lelv)
01929       common /scrcg/         pm1 (lx1,ly1,lz1,lelv)
01930       common /scrsf/         xm0(lx1,ly1,lz1,lelt)
01931      $,                      ym0(lx1,ly1,lz1,lelt)
01932      $,                      zm0(lx1,ly1,lz1,lelt)
01933 c
01934       parameter (lr=lx1*ly1*lz1)
01935       common /scruz/         ur(lr),us(lr),ut(lr)
01936      $                     , vr(lr),vs(lr),vt(lr)
01937      $                     , wr(lr),ws(lr),wt(lr)
01938 c
01939       common /ctorq/ dragx(0:maxobj),dragpx(0:maxobj),dragvx(0:maxobj)
01940      $             , dragy(0:maxobj),dragpy(0:maxobj),dragvy(0:maxobj)
01941      $             , dragz(0:maxobj),dragpz(0:maxobj),dragvz(0:maxobj)
01942 c
01943      $             , torqx(0:maxobj),torqpx(0:maxobj),torqvx(0:maxobj)
01944      $             , torqy(0:maxobj),torqpy(0:maxobj),torqvy(0:maxobj)
01945      $             , torqz(0:maxobj),torqpz(0:maxobj),torqvz(0:maxobj)
01946 c
01947      $             , dpdx_mean,dpdy_mean,dpdz_mean
01948      $             , dgtq(3,4)
01949 c
01950 c
01951       n = nx1*ny1*nz1*nelv
01952 c
01953       call mappr(pm1,pr,xm0,ym0) ! map pressure onto Mesh 1
01954 c
01955 c    Add mean_pressure_gradient.X to p:
01956 
01957       if (param(55).ne.0) then
01958          dpdx_mean = -scale_vf(1)
01959          dpdy_mean = -scale_vf(2)
01960          dpdz_mean = -scale_vf(3)
01961       endif
01962 
01963       call add2s2(pm1,xm1,dpdx_mean,n)  ! Doesn't work if object is cut by 
01964       call add2s2(pm1,ym1,dpdy_mean,n)  ! periodicboundary.  In this case,
01965       call add2s2(pm1,zm1,dpdz_mean,n)  ! set ._mean=0 and compensate in
01966 c
01967 c    Compute sij
01968 c
01969       nij = 3
01970       if (if3d.or.ifaxis) nij=6
01971       call comp_sij(sij,nij,vx,vy,vz,ur,us,ut,vr,vs,vt,wr,ws,wt)
01972 c
01973 c
01974 c     Fill up viscous array w/ default
01975 c
01976       if (istep.lt.1) call cfill(vdiff,param(2),n)
01977 c
01978       call cadd2(xm0,xm1,-x0(1),n)
01979       call cadd2(ym0,ym1,-x0(2),n)
01980       call cadd2(zm0,zm1,-x0(3),n)
01981 c
01982       x1min=glmin(xm0(1,1,1,1),n)
01983       x2min=glmin(ym0(1,1,1,1),n)
01984       x3min=glmin(zm0(1,1,1,1),n)
01985 c
01986       x1max=glmax(xm0(1,1,1,1),n)
01987       x2max=glmax(ym0(1,1,1,1),n)
01988       x3max=glmax(zm0(1,1,1,1),n)
01989 c
01990       do i=0,maxobj
01991          dragpx(i) = 0   ! BIG CODE  :}
01992          dragvx(i) = 0
01993          dragx (i) = 0
01994          dragpy(i) = 0
01995          dragvy(i) = 0
01996          dragy (i) = 0
01997          dragpz(i) = 0
01998          dragvz(i) = 0
01999          dragz (i) = 0
02000          torqpx(i) = 0
02001          torqvx(i) = 0
02002          torqx (i) = 0
02003          torqpy(i) = 0
02004          torqvy(i) = 0
02005          torqy (i) = 0
02006          torqpz(i) = 0
02007          torqvz(i) = 0
02008          torqz (i) = 0
02009       enddo
02010 c
02011 c
02012       nobj = 0
02013       do ii=1,nhis
02014         if (hcode(10,ii).EQ.'I') then
02015           iobj   = lochis(1,ii)
02016           memtot = nmember(iobj)
02017           nobj   = max(iobj,nobj)
02018 c
02019           if (hcode(1,ii).ne.' ' .or. hcode(2,ii).ne.' ' .or.
02020      $      hcode(3,ii).ne.' ' ) then
02021             ifield = 1
02022 c
02023 c           Compute drag for this object
02024 c
02025             do mem=1,memtot
02026                ieg   = object(iobj,mem,1)
02027                ifc   = object(iobj,mem,2)
02028                if (gllnid(ieg).eq.nid) then ! this processor has a contribution
02029                   ie = gllel(ieg)
02030                   call drgtrq(dgtq,xm0,ym0,zm0,sij,pm1,vdiff,ifc,ie)
02031 c
02032                   call cmult(dgtq,scale,12)
02033 c
02034                   dragpx(iobj) = dragpx(iobj) + dgtq(1,1)  ! pressure 
02035                   dragpy(iobj) = dragpy(iobj) + dgtq(2,1)
02036                   dragpz(iobj) = dragpz(iobj) + dgtq(3,1)
02037 c
02038                   dragvx(iobj) = dragvx(iobj) + dgtq(1,2)  ! viscous
02039                   dragvy(iobj) = dragvy(iobj) + dgtq(2,2)
02040                   dragvz(iobj) = dragvz(iobj) + dgtq(3,2)
02041 c
02042                   torqpx(iobj) = torqpx(iobj) + dgtq(1,3)  ! pressure 
02043                   torqpy(iobj) = torqpy(iobj) + dgtq(2,3)
02044                   torqpz(iobj) = torqpz(iobj) + dgtq(3,3)
02045 c
02046                   torqvx(iobj) = torqvx(iobj) + dgtq(1,4)  ! viscous
02047                   torqvy(iobj) = torqvy(iobj) + dgtq(2,4)
02048                   torqvz(iobj) = torqvz(iobj) + dgtq(3,4)
02049 c
02050                endif
02051             enddo
02052           endif
02053         endif
02054       enddo
02055 c
02056 c     Sum contributions from all processors
02057 c
02058       call gop(dragpx,w1,'+  ',maxobj+1)
02059       call gop(dragpy,w1,'+  ',maxobj+1)
02060       call gop(dragpz,w1,'+  ',maxobj+1)
02061       call gop(dragvx,w1,'+  ',maxobj+1)
02062       call gop(dragvy,w1,'+  ',maxobj+1)
02063       call gop(dragvz,w1,'+  ',maxobj+1)
02064 c
02065       call gop(torqpx,w1,'+  ',maxobj+1)
02066       call gop(torqpy,w1,'+  ',maxobj+1)
02067       call gop(torqpz,w1,'+  ',maxobj+1)
02068       call gop(torqvx,w1,'+  ',maxobj+1)
02069       call gop(torqvy,w1,'+  ',maxobj+1)
02070       call gop(torqvz,w1,'+  ',maxobj+1)
02071 c
02072       nobj = iglmax(nobj,1)
02073 c
02074       do i=1,nobj
02075          dragx(i) = dragpx(i) + dragvx(i)
02076          dragy(i) = dragpy(i) + dragvy(i)
02077          dragz(i) = dragpz(i) + dragvz(i)
02078 c
02079          torqx(i) = torqpx(i) + torqvx(i)
02080          torqy(i) = torqpy(i) + torqvy(i)
02081          torqz(i) = torqpz(i) + torqvz(i)
02082 c
02083          dragpx(0) = dragpx (0) + dragpx (i)
02084          dragvx(0) = dragvx (0) + dragvx (i)
02085          dragx (0) = dragx  (0) + dragx  (i)
02086 c
02087          dragpy(0) = dragpy (0) + dragpy (i)
02088          dragvy(0) = dragvy (0) + dragvy (i)
02089          dragy (0) = dragy  (0) + dragy  (i)
02090 c
02091          dragpz(0) = dragpz (0) + dragpz (i)
02092          dragvz(0) = dragvz (0) + dragvz (i)
02093          dragz (0) = dragz  (0) + dragz  (i)
02094 c
02095          torqpx(0) = torqpx (0) + torqpx (i)
02096          torqvx(0) = torqvx (0) + torqvx (i)
02097          torqx (0) = torqx  (0) + torqx  (i)
02098 c
02099          torqpy(0) = torqpy (0) + torqpy (i)
02100          torqvy(0) = torqvy (0) + torqvy (i)
02101          torqy (0) = torqy  (0) + torqy  (i)
02102 c
02103          torqpz(0) = torqpz (0) + torqpz (i)
02104          torqvz(0) = torqvz (0) + torqvz (i)
02105          torqz (0) = torqz  (0) + torqz  (i)
02106 c
02107       enddo
02108 c
02109       i0 = 0
02110       if (nobj.le.1) i0 = 1  ! one output for single-object case
02111 c
02112       do i=i0,nobj
02113         if (nio.eq.0) then
02114           if (if3d.or.ifaxis) then
02115            if (ifdout) then
02116             write(6,6) istep,time,dragx(i),dragpx(i),dragvx(i),i,'dragx'
02117             write(6,6) istep,time,dragy(i),dragpy(i),dragvy(i),i,'dragy'
02118             write(6,6) istep,time,dragz(i),dragpz(i),dragvz(i),i,'dragz'
02119            endif
02120            if (iftout) then
02121             write(6,6) istep,time,torqx(i),torqpx(i),torqvx(i),i,'torqx'
02122             write(6,6) istep,time,torqy(i),torqpy(i),torqvy(i),i,'torqy'
02123             write(6,6) istep,time,torqz(i),torqpz(i),torqvz(i),i,'torqz'
02124            endif
02125           else
02126            if (ifdout) then
02127             write(6,6) istep,time,dragx(i),dragpx(i),dragvx(i),i,'dragx'
02128             write(6,6) istep,time,dragy(i),dragpy(i),dragvy(i),i,'dragy'
02129            endif
02130            if (iftout) then
02131             write(6,6) istep,time,torqz(i),torqpz(i),torqvz(i),i,'torqz'
02132            endif
02133           endif
02134         endif
02135     6   format(i8,1p4e19.11,2x,i5,a5)
02136       enddo
02137 c
02138       return
02139       end
02140 c-----------------------------------------------------------------------
02141       subroutine comp_sij(sij,nij,u,v,w,ur,us,ut,vr,vs,vt,wr,ws,wt)
02142 c                                       du_i       du_j
02143 c     Compute the stress tensor S_ij := ----   +   ----
02144 c                                       du_j       du_i
02145 c
02146       include 'SIZE'
02147       include 'TOTAL'
02148 c
02149       integer e
02150 c
02151       real sij(lx1*ly1*lz1,nij,lelv)
02152       real u  (lx1*ly1*lz1,lelv)
02153       real v  (lx1*ly1*lz1,lelv)
02154       real w  (lx1*ly1*lz1,lelv)
02155       real ur (1) , us (1) , ut (1)
02156      $   , vr (1) , vs (1) , vt (1)
02157      $   , wr (1) , ws (1) , wt (1)
02158 
02159       real j ! Inverse Jacobian
02160 
02161       n    = nx1-1      ! Polynomial degree
02162       nxyz = nx1*ny1*nz1
02163 
02164       if (if3d) then     ! 3D CASE
02165        do e=1,nelv
02166         call local_grad3(ur,us,ut,u,N,e,dxm1,dxtm1)
02167         call local_grad3(vr,vs,vt,v,N,e,dxm1,dxtm1)
02168         call local_grad3(wr,ws,wt,w,N,e,dxm1,dxtm1)
02169 
02170         do i=1,nxyz
02171 
02172          j = jacmi(i,e)
02173 
02174          sij(i,1,e) = j*  ! du/dx + du/dx
02175      $   2*(ur(i)*rxm1(i,1,1,e)+us(i)*sxm1(i,1,1,e)+ut(i)*txm1(i,1,1,e))
02176 
02177          sij(i,2,e) = j*  ! dv/dy + dv/dy
02178      $   2*(vr(i)*rym1(i,1,1,e)+vs(i)*sym1(i,1,1,e)+vt(i)*tym1(i,1,1,e))
02179 
02180          sij(i,3,e) = j*  ! dw/dz + dw/dz
02181      $   2*(wr(i)*rzm1(i,1,1,e)+ws(i)*szm1(i,1,1,e)+wt(i)*tzm1(i,1,1,e))
02182 
02183          sij(i,4,e) = j*  ! du/dy + dv/dx
02184      $   (ur(i)*rym1(i,1,1,e)+us(i)*sym1(i,1,1,e)+ut(i)*tym1(i,1,1,e) +
02185      $    vr(i)*rxm1(i,1,1,e)+vs(i)*sxm1(i,1,1,e)+vt(i)*txm1(i,1,1,e) )
02186 
02187          sij(i,5,e) = j*  ! dv/dz + dw/dy
02188      $   (wr(i)*rym1(i,1,1,e)+ws(i)*sym1(i,1,1,e)+wt(i)*tym1(i,1,1,e) +
02189      $    vr(i)*rzm1(i,1,1,e)+vs(i)*szm1(i,1,1,e)+vt(i)*tzm1(i,1,1,e) )
02190 
02191          sij(i,6,e) = j*  ! du/dz + dw/dx
02192      $   (ur(i)*rzm1(i,1,1,e)+us(i)*szm1(i,1,1,e)+ut(i)*tzm1(i,1,1,e) +
02193      $    wr(i)*rxm1(i,1,1,e)+ws(i)*sxm1(i,1,1,e)+wt(i)*txm1(i,1,1,e) )
02194 
02195         enddo
02196        enddo
02197 
02198       elseif (ifaxis) then  ! AXISYMMETRIC CASE  
02199 
02200 c
02201 c        Notation:                       ( 2  x  Acheson, p. 353)
02202 c                     Cylindrical
02203 c            Nek5k    Coordinates
02204 c
02205 c              x          z
02206 c              y          r
02207 c              z          theta
02208 c
02209 
02210          do e=1,nelv
02211             call setaxdy ( ifrzer(e) )  ! change dytm1 if on-axis
02212             call local_grad2(ur,us,u,N,e,dxm1,dytm1)
02213             call local_grad2(vr,vs,v,N,e,dxm1,dytm1)
02214             call local_grad2(wr,ws,w,N,e,dxm1,dytm1)
02215 
02216             do i=1,nxyz
02217                j = jacmi(i,e)
02218                r = ym1(i,1,1,e)                              ! Cyl. Coord:
02219 
02220                sij(i,1,e) = j*  ! du/dx + du/dx              ! e_zz
02221      $           2*(ur(i)*rxm1(i,1,1,e)+us(i)*sxm1(i,1,1,e))
02222 
02223                sij(i,2,e) = j*  ! dv/dy + dv/dy              ! e_rr
02224      $           2*(vr(i)*rym1(i,1,1,e)+vs(i)*sym1(i,1,1,e))
02225 
02226                if (r.gt.0) then                              ! e_@@
02227                   sij(i,3,e) = v(i,e)/r  ! v / r 
02228                else
02229                   sij(i,3,e) = j*  ! L'Hopital's rule: e_@@ = dv/dr
02230      $            2*(vr(i)*rym1(i,1,1,e)+vs(i)*sym1(i,1,1,e))
02231                endif
02232 
02233                sij(i,4,e) = j*  ! du/dy + dv/dx             ! e_zr
02234      $            ( ur(i)*rym1(i,1,1,e)+us(i)*sym1(i,1,1,e) +
02235      $              vr(i)*rxm1(i,1,1,e)+vs(i)*sxm1(i,1,1,e) )
02236 
02237                if (r.gt.0) then                             ! e_r@
02238                   sij(i,5,e) = j*  ! dw/dy 
02239      $              ( wr(i)*rym1(i,1,1,e)+ws(i)*sym1(i,1,1,e) )
02240      $              - w(i,e) / r
02241                else
02242                   sij(i,5,e) = 0
02243                endif
02244 
02245                sij(i,6,e) = j*  ! dw/dx                     ! e_@z
02246      $            ( wr(i)*rxm1(i,1,1,e)+ws(i)*sxm1(i,1,1,e) )
02247 
02248             enddo
02249          enddo
02250 
02251       else              ! 2D CASE
02252 
02253          do e=1,nelv
02254             call local_grad2(ur,us,u,N,e,dxm1,dxtm1)
02255             call local_grad2(vr,vs,v,N,e,dxm1,dxtm1)
02256 
02257             do i=1,nxyz
02258                j = jacmi(i,e)
02259 
02260                sij(i,1,e) = j*  ! du/dx + du/dx
02261      $           2*(ur(i)*rxm1(i,1,1,e)+us(i)*sxm1(i,1,1,e))
02262 
02263                sij(i,2,e) = j*  ! dv/dy + dv/dy
02264      $           2*(vr(i)*rym1(i,1,1,e)+vs(i)*sym1(i,1,1,e))
02265 
02266                sij(i,3,e) = j*  ! du/dy + dv/dx
02267      $           (ur(i)*rym1(i,1,1,e)+us(i)*sym1(i,1,1,e) +
02268      $            vr(i)*rxm1(i,1,1,e)+vs(i)*sxm1(i,1,1,e) )
02269 
02270             enddo
02271          enddo
02272       endif
02273       return
02274       end
02275 c-----------------------------------------------------------------------
02276       subroutine auto_averager(fname127) ! simple average of files
02277 
02278 c     This routine reads files specificed of file.list and averages
02279 c     them with uniform weight
02280 c
02281 c     Note that it relies on scravg and scruz common blocks. pff 12/7/14
02282 c
02283 
02284       include 'SIZE'
02285       include 'TOTAL'
02286       include 'ZPER'
02287 
02288       character*127 fname127
02289       character*1   f1(127)
02290 
02291       parameter (lt=lx1*ly1*lz1*lelt)
02292       common /scravg/ ua(lt),va(lt),wa(lt),pa(lt)
02293       common /scrsf/  ta(lt,ldimt)
02294 
02295       character*1 s1(127)
02296       equivalence (s1,initc) ! equivalence to initial condition
02297 
02298       if (nid.eq.0) then
02299          ib=indx1(fname127,' ',1)-1
02300          call chcopy(f1,fname127,ib)
02301          write(6,2) (f1(k),k=1,ib)
02302     2    format('Open file: ',127a1)
02303       endif
02304 
02305       ierr = 0
02306       if (nid.eq.0) open(77,file=fname127,status='old',err=199)
02307       ierr = iglmax(ierr,1)
02308       if (ierr.gt.0) goto 199
02309       n = nx1*ny1*nz1*nelt
02310       n2= nx2*ny2*nz2*nelt
02311 
02312       call rzero (ua,n)
02313       call rzero (va,n)
02314       call rzero (wa,n)
02315       call rzero (pa,n2)
02316       do k=1,npscal+1
02317          call rzero (ta(1,k),n)
02318       enddo
02319 
02320       icount = 0
02321       do ipass=1,9999999
02322 
02323          call blank(initc,127)
02324          initc(1) = 'done '
02325          if (nid.eq.0) read(77,127,end=998) initc(1)
02326   998    call bcast(initc,127)
02327   127    format(a127)
02328 
02329          iblank = indx1(initc,' ',1)-1
02330          if (nio.eq.0) write(6,1) ipass,(s1(k),k=1,iblank)
02331     1    format(i8,'Reading: ',127a1)
02332 
02333          if (indx1(initc,'done ',5).eq.0) then ! We're not done
02334 
02335             nfiles = 1
02336             call restart(nfiles)  ! Note -- time is reset.
02337 
02338             call opadd2 (ua,va,wa,vx,vy,vz)
02339             call add2   (pa,pr,n2)
02340             do k=1,npscal+1
02341                call add2(ta(1,k),t(1,1,1,1,k),n)
02342             enddo
02343             icount = icount+1
02344 
02345          else
02346             goto 999
02347          endif
02348 
02349       enddo
02350 
02351   999 continue  ! clean up averages
02352       if (nid.eq.0) close(77)
02353 
02354       scale = 1./icount
02355       call cmult2(vx,ua,scale,n)
02356       call cmult2(vy,va,scale,n)
02357       call cmult2(vz,wa,scale,n)
02358       call cmult2(pr,pa,scale,n2)
02359       do k=1,npscal+1
02360          call cmult2(t(1,1,1,1,k),ta(1,k),scale,n)
02361       enddo
02362       return
02363 
02364   199 continue ! exception handle for file not found
02365       ierr = 1
02366       if (nid.eq.0) ierr = iglmax(ierr,1)
02367       call exitti('Auto averager did not find list file.$',ierr)
02368 
02369       return
02370       end
02371 c-----------------------------------------------------------------------
02372       subroutine x_average(ua,u,w1,w2)
02373 c
02374 c     Compute the x average of quantity u() - assumes global tens.prod.
02375 c
02376       include 'SIZE'
02377       include 'GEOM'
02378       include 'PARALLEL'
02379       include 'WZ'
02380       include 'ZPER'
02381 
02382       real ua(ny1,nz1,nely,nelz),u (nx1,ny1,nz1,nelv)
02383      $    ,w1(ny1,nz1,nely,nelz),w2(ny1,nz1,nely,nelz)
02384       integer e,eg,ex,ey,ez
02385       real dy2
02386 
02387       nelyz = nely*nelz
02388       if (nelyz.gt.lely*lelz) call exitti
02389      $  ('ABORT IN x_average. Increase lely*lelz in SIZE:$',nelyz)
02390 
02391       myz = nely*nelz*ny1*nz1
02392       call rzero(ua,myz)
02393       call rzero(w1,myz)
02394 
02395       do e=1,nelt
02396 
02397          eg = lglel(e)
02398          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
02399 
02400          do k=1,nz1
02401          do j=1,ny1
02402             do i=1,nx1
02403                dx2 = 1.0  !  Assuming uniform element size in "x" direction
02404                ua(j,k,ey,ez) = ua(j,k,ey,ez)+dx2*wzm1(i)*u(i,j,k,e)
02405                w1(j,k,ey,ez) = w1(j,k,ey,ez)+dx2*wzm1(i) ! redundant but clear
02406             enddo
02407          enddo
02408          enddo
02409       enddo
02410 
02411       call gop(ua,w2,'+  ',myz)
02412       call gop(w1,w2,'+  ',myz)
02413 
02414       do i=1,myz
02415          ua(i,1,1,1) = ua(i,1,1,1) / w1(i,1,1,1)   ! Normalize
02416       enddo
02417 
02418       return
02419       end
02420 c-----------------------------------------------------------------------
02421       subroutine x_average_transpose(u,ua) ! distribute ua to each z-plane
02422 
02423       include 'SIZE'
02424       include 'GEOM'
02425       include 'PARALLEL'
02426       include 'WZ'
02427       include 'ZPER'
02428 
02429       real u(nx1,ny1,nz1,nelv),ua(ny1,nz1,nely,nelz)
02430 
02431       integer e,eg,ex,ey,ez
02432 
02433 
02434       do e=1,nelt
02435 
02436          eg = lglel(e)
02437          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
02438 
02439          do k=1,nz1
02440          do j=1,ny1
02441             do i=1,nx1
02442                u(i,j,k,e) = ua(j,k,ey,ez)
02443             enddo
02444          enddo
02445          enddo
02446       enddo
02447 
02448       return
02449       end
02450 c-----------------------------------------------------------------------
02451       subroutine x_distribute(u)
02452 c
02453 c     Compute the x average of quantity u() and redistribute
02454 c
02455 c     Assumes you have nelx*nely elements, in the same order,
02456 c     within each x plane
02457 c
02458 c
02459       include 'SIZE'
02460       include 'TOTAL'
02461       include 'ZPER'
02462 
02463       real u(1)
02464 
02465       parameter (lyavg = ly1*lz1*lely*lelz)
02466       common /scravg/ ua(lyavg)
02467      $              , w1(lyavg)
02468      $              , w2(lyavg)
02469 
02470       call x_average          (ua,u,w1,w2)
02471       call x_average_transpose(u,ua) ! distribute ua to each z-plane
02472 
02473       return
02474       end
02475 c-----------------------------------------------------------------------
02476       subroutine x_distribute2(ua,u)
02477 c
02478 c     Compute the x average of quantity u() and redistribute
02479 c
02480 c     Assumes you have nelx*nely elements, in the same order,
02481 c     within each x plane
02482 c
02483 c
02484       include 'SIZE'
02485       include 'TOTAL'
02486       include 'ZPER'
02487 
02488       real ua(1),u(1)
02489 
02490       parameter (lyavg = ly1*lz1*lely*lelz)
02491       common /scravg/ w1(lyavg)
02492      $              , w2(lyavg)
02493 
02494       call x_average          (ua,u,w1,w2)
02495       call x_average_transpose(u,ua) ! distribute ua to each z-plane
02496 
02497       return
02498       end
02499 c-----------------------------------------------------------------------
02500       subroutine y_slice (ua,u,w1,w2)
02501 c
02502 c     Extract a y slice of quantity u() - assumes global tens.prod.
02503 c
02504       include 'SIZE'
02505       include 'GEOM'
02506       include 'PARALLEL'
02507       include 'WZ'
02508       include 'ZPER'
02509 c
02510       real ua(nx1,nz1,nelx,nelz),u (nx1,ny1,nz1,nelv)
02511      $    ,w1(nx1,nz1,nelx,nelz),w2(nx1,nz1,nelx,nelz)
02512       integer e,eg,ex,ey,ez
02513       real dy2
02514 c
02515       mxz = nelx*nelz*nx1*nz1
02516       call rzero(ua,mxz)
02517 c
02518       do e=1,nelt
02519 c
02520          eg = lglel(e)
02521          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
02522 
02523          j = 1
02524          if (ey.eq.1) then
02525             do k=1,nz1
02526             do i=1,nx1
02527                ua(i,k,ex,ez) = u(i,j,k,e)
02528             enddo
02529             enddo
02530          endif
02531       enddo
02532 
02533       call gop(ua,w2,'+  ',mxz)
02534 
02535       return
02536       end
02537 c-----------------------------------------------------------------------
02538       subroutine z_slice_g (uz,u,w1,kz,ezi,nx,ny,nz,nlxy)
02539 c
02540 c     Extract a z slice of quantity u() 
02541 c
02542 c     ASSUMES data is in a global tensor-product structure, nlxy x nelz,
02543 c             as would be produced by n2to3 or genbox.
02544 c
02545 c     Arguments:
02546 c
02547 c     uz(nx1,ny1,nlxy):       extracted z-slice data
02548 c     u (nx1,ny1,nz1,nelt):   input data
02549 c     w1(nx1,ny1,nlxy):       work array
02550 c     kz:                     z-plane within element ezi to be extracted
02551 c     ezi:                    elemental z-slab to be extracted
02552 c     nx,ny,nz:               dimensions for 3D spectral element input
02553 c     nlxy:                   global number of elements in x-y plane.
02554 
02555       include 'SIZE'
02556       include 'GEOM'
02557       include 'PARALLEL'
02558       include 'WZ'
02559 
02560       real uz(nx,ny,nlxy),u (nx,ny,nz,nelv),w1(nx,ny,nlxy)
02561       integer e,eg,ex,ey,ez,ezi
02562       real dy2
02563 
02564       nxy = nx*ny
02565       mxy = nxy*nlxy
02566 
02567       call rzero(uz,mxy) ! zero out the entire plane
02568 
02569       do e=1,nelt
02570          eg = lglel(e)
02571          call get_exyz(ex,ey,ez,eg,nlxy,1,1)
02572 
02573          if (ez.eq.ezi) 
02574      $      call copy(uz(1,1,ex),u(1,1,kz,e),nxy) ! u(zlice) --> uz()
02575 
02576       enddo
02577 
02578       call gop(uz,w1,'+  ',mxy) ! Collect partial contributions from all procs
02579 
02580       return
02581       end
02582 c-----------------------------------------------------------------------
02583       subroutine z_slice (ua,u,w1,w2)
02584 c
02585 c     Extract a z slice of quantity u() - assumes global tens.prod.
02586 c
02587       include 'SIZE'
02588       include 'GEOM'
02589       include 'PARALLEL'
02590       include 'WZ'
02591       include 'ZPER'
02592 c
02593       real ua(nx1,ny1,nelx,nely),u (nx1,ny1,nz1,nelv)
02594      $    ,w1(nx1,ny1,nelx,nely),w2(nx1,ny1,nelx,nely)
02595       integer e,eg,ex,ey,ez
02596       real dy2
02597 c
02598       mxy = nelx*nely*nx1*ny1
02599       call rzero(ua,mxy)
02600 c
02601       do e=1,nelt
02602 c
02603          eg = lglel(e)
02604          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
02605 
02606          k = 1
02607          if (ez.eq.1) then
02608             do j=1,ny1
02609             do i=1,nx1
02610                ua(i,j,ex,ey) = u(i,j,k,e)
02611             enddo
02612             enddo
02613          endif
02614       enddo
02615 
02616       call gop(ua,w2,'+  ',mxy)
02617 
02618       return
02619       end
02620 c-----------------------------------------------------------------------
02621       subroutine y_average(ua,u,w1,w2)
02622 c
02623 c     Compute the y average of quantity u() - assumes global tens.prod.
02624 c
02625       include 'SIZE'
02626       include 'GEOM'
02627       include 'PARALLEL'
02628       include 'WZ'
02629       include 'ZPER'
02630 c
02631       real ua(nx1,nz1,nelx,nelz),u (nx1,ny1,nz1,nelv)
02632      $    ,w1(nx1,nz1,nelx,nelz),w2(nx1,nz1,nelx,nelz)
02633       integer e,eg,ex,ey,ez
02634       real dy2
02635 c
02636       mxz = nelx*nelz*nx1*nz1
02637       call rzero(ua,mxz)
02638       call rzero(w1,mxz)
02639 c
02640       do e=1,nelt
02641 c
02642          eg = lglel(e)
02643          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
02644 c
02645          do k=1,nz1
02646          do i=1,nx1
02647 c           dy2 = .5*( ym1(i,ny1,k,e) - ym1(i,1,k,e) )
02648             dy2 = 1.0  !  Assuming uniform in "y" direction
02649             do j=1,ny1
02650                ua(i,k,ex,ez) = ua(i,k,ex,ez)+dy2*wym1(j)*u(i,j,k,e)
02651                w1(i,k,ex,ez) = w1(i,k,ex,ez)+dy2*wym1(j) ! redundant but clear
02652             enddo
02653          enddo
02654          enddo
02655       enddo
02656 c
02657       call gop(ua,w2,'+  ',mxz)
02658       call gop(w1,w2,'+  ',mxz)
02659 c
02660       do i=1,mxz
02661          ua(i,1,1,1) = ua(i,1,1,1) / w1(i,1,1,1)   ! Normalize
02662       enddo
02663 c
02664       return
02665       end
02666 c-----------------------------------------------------------------------
02667       subroutine y_avg_buff(ux,uy,uz,c2,name,icount)
02668 c
02669 c     Compute the y average of quantity u() - assumes global tens.prod.
02670 c
02671       include 'SIZE'
02672       include 'TOTAL'
02673       include 'ZPER'
02674 
02675       real ux(1),uy(1),uz(1)
02676       character*2 c2,name
02677 
02678       parameter (lyavg = lx1*lz1*lelx*lelz)
02679       common /scravg/ u (lyavg)
02680      $              , v (lyavg)
02681      $              , w (lyavg)
02682      $              , w1(lyavg)
02683      $              , w2(lyavg)
02684 
02685       call y_average(u,ux,w1,w2)
02686       call y_average(v,uy,w1,w2)
02687       call y_average(w,uz,w1,w2)
02688 
02689       call buff_2d_out(u,v,w,nx1,nz1,nelx,nelz,c2,name,icount)
02690 
02691       return
02692       end
02693 c-----------------------------------------------------------------------
02694       subroutine z_avg_buff(ux,uy,uz,c2,name,icount)
02695 c
02696 c     Compute the z average of quantity u() - assumes global tens.prod.
02697 c
02698       include 'SIZE'
02699       include 'TOTAL'
02700       include 'ZPER'
02701 c
02702       real ux(1),uy(1),uz(1)
02703       character*2 c2,name
02704 c
02705       parameter (lyavg = lx1*ly1*lelx*lely)
02706       common /scravg/ u (lyavg)
02707      $              , v (lyavg)
02708      $              , w (lyavg)
02709      $              , w1(lyavg)
02710      $              , w2(lyavg)
02711 c
02712       call z_average(u,ux,w1,w2)
02713       call z_average(v,uy,w1,w2)
02714       call z_average(w,uz,w1,w2)
02715 
02716       call buff_2d_out(u,v,w,nx1,ny1,nelx,nely,c2,name,icount)
02717 
02718       return
02719       end
02720 c-----------------------------------------------------------------------
02721       subroutine y_ins_buff(ux,uy,uz,c2,name,icount)
02722 c
02723 c     Compute the z average of quantity u() - assumes global tens.prod.
02724 c
02725       include 'SIZE'
02726       include 'TOTAL'
02727       include 'ZPER'
02728 c
02729       real ux(1),uy(1),uz(1)
02730       character*2 c2,name
02731 c
02732       parameter (lyavg = lx1*lz1*lelx*lelz)
02733       common /scravg/ u (lyavg)
02734      $              , v (lyavg)
02735      $              , w (lyavg)
02736      $              , w1(lyavg)
02737      $              , w2(lyavg)
02738 c
02739       call y_slice  (u,ux,w1,w2)
02740       call y_slice  (v,uy,w1,w2)
02741       call y_slice  (w,uz,w1,w2)
02742 c
02743       call buff_2d_out(u,v,w,nx1,nz1,nelx,nelz,c2,name,icount)
02744 c
02745       return
02746       end
02747 c-----------------------------------------------------------------------
02748       subroutine z_ins_buff(ux,uy,uz,c2,name,icount)
02749 c
02750 c     Compute the z average of quantity u() - assumes global tens.prod.
02751 c
02752       include 'SIZE'
02753       include 'TOTAL'
02754       include 'ZPER'
02755 c
02756       real ux(1),uy(1),uz(1)
02757       character*2 c2,name
02758 c
02759       parameter (lyavg = lx1*ly1*lelx*lely)
02760       common /scravg/ u (lyavg)
02761      $              , v (lyavg)
02762      $              , w (lyavg)
02763      $              , w1(lyavg)
02764      $              , w2(lyavg)
02765 c
02766       call z_slice  (u,ux,w1,w2)
02767       call z_slice  (v,uy,w1,w2)
02768       call z_slice  (w,uz,w1,w2)
02769 c
02770       call buff_2d_out(u,v,w,nx1,ny1,nelx,nely,c2,name,icount)
02771 c
02772       return
02773       end
02774 c-----------------------------------------------------------------------
02775       subroutine buff_2d_out(u,v,w,nx,ny,nex,ney,c2,name,ifld)
02776 c
02777       include 'SIZE'
02778       include 'TOTAL'
02779 
02780       real u(1),v(1),w(1)
02781       character*2 c2,name
02782       character*4  bname
02783       save         bname
02784 
02785       parameter (lyzm = lelx*max(lely,lelz))
02786       common /scrav2/ ub(lx1,lz1,lyzm),vb(lx1,lz1,lyzm),wb(lx1,lz1,lyzm)
02787 
02788       integer ibfld,icalld,nxf,nyf,nexf,neyf
02789       save    ibfld,icalld,nxf,nyf,nexf,neyf
02790       data    ibfld,icalld,nxf,nyf,nexf,neyf  / 6*0 /
02791 
02792 c     npido = 64             !  64 files buffered
02793       npido = 128            !  64 files buffered
02794       npido =  min(npido,np) !  P  files buffered
02795 
02796       mpido = np/npido     ! stride between processors (e.g., 128/64 = 2)
02797 
02798       jcalld = mod(icalld,npido)       ! call # 0,1,...,63,0,1,...
02799       if (mod(nid,mpido) .eq. 0) then  ! this is a buffering/writing proc
02800 
02801          jid = nid/mpido
02802          if (jid.eq.jcalld) then       ! save this buffer on this proc
02803 c           write(6,1) nid,jid,istep,icalld,jcalld,c2,name,nex,ney,ifld
02804 c   1       format(5i7,' buffering: ',2a2,3i7)
02805             write(bname,4) c2,name
02806     4       format(2a2)
02807             n = nx*ny*nex*ney
02808             ibfld = ifld
02809             call copy(ub,u,n)
02810             call copy(vb,v,n)
02811             call copy(wb,w,n)
02812             nxf  = nx
02813             nyf  = ny
02814             nexf = nex
02815             neyf = ney
02816          endif
02817 
02818          if (jcalld .eq. npido-1) call  ! output buffer
02819      $  outfld2d_p(ub,vb,wb,nxf,nyf,nexf,neyf,bname,ibfld,jid,npido,ir)
02820 
02821       endif
02822       call err_chk(ir,'Error with byte_write, buff_2d_out $')
02823       icalld = icalld+1
02824       return
02825       end
02826 c-----------------------------------------------------------------------
02827       subroutine y2d(u,v,w,p,c1,icount)
02828 c
02829 c     Compute the y average of quantity u() - assumes global tens.prod.
02830 c
02831 
02832       include 'SIZE'
02833       include 'TOTAL'
02834       real u(1),v(1),w(1),p(1)
02835       character*1 c1,c2(2)
02836 
02837       common /scrns/ ur(lx1*ly1*lz1*lelv)
02838      $             , ut(lx1*ly1*lz1*lelv)
02839      $             , wr(lx1*ly1*lz1*lelv)
02840      $             , wt(lx1*ly1*lz1*lelv)
02841      $             , wp(lx1*ly1*lz1*lelv)
02842 c
02843 c     Convert velocities to poloidal-toroidal
02844 c
02845       n = nx1*ny1*nz1*nelv
02846       do i=1,n
02847          rr = xm1(i,1,1,1)*xm1(i,1,1,1)+ym1(i,1,1,1)*ym1(i,1,1,1)
02848          rr = sqrt(rr)
02849          ct = xm1(i,1,1,1)/rr
02850          st = ym1(i,1,1,1)/rr
02851          ur(i) = ct*u(i)+st*v(i)
02852          ut(i) = ct*v(i)-st*u(i)
02853          wr(i) = ur(i)**2
02854          wt(i) = ut(i)**2
02855          wp(i) = w (i)**2
02856       enddo
02857 
02858       c2(1) = c1
02859       c2(2) = 'y'
02860 
02861       call y_avg_buff(ur,w ,ut,c2,'ub',icount)
02862       call y_avg_buff(wr,wp,wt,c2,'u2',icount)
02863 
02864       do i=1,n
02865          wr(i) = ur(i)*ut(i)
02866          wt(i) = ut(i)*w (i)
02867          wp(i) = w (i)*ur(i)
02868       enddo
02869       call y_avg_buff(wr,wt,wp,c2,'uv',icount)
02870 
02871       call y_ins_buff(ur,w ,ut,c2,'ui',icount)
02872 
02873       return
02874       end
02875 c-----------------------------------------------------------------------
02876       subroutine z2d(u,v,w,p,c1,icount)
02877 c
02878 c     Compute the y average of quantity u() - assumes global tens.prod.
02879 c
02880 
02881       include 'SIZE'
02882       include 'TOTAL'
02883       real u(1),v(1),w(1),p(1)
02884       character*1 c1,c2(2)
02885 
02886       common /scrns/ ur(lx1*ly1*lz1*lelv)
02887      $             , ut(lx1*ly1*lz1*lelv)
02888      $             , wr(lx1*ly1*lz1*lelv)
02889      $             , wt(lx1*ly1*lz1*lelv)
02890      $             , wp(lx1*ly1*lz1*lelv)
02891 c
02892 c
02893 c     Convert velocities to poloidal-toroidal
02894 c
02895       n = nx1*ny1*nz1*nelv
02896       do i=1,n
02897          wr(i) = u (i)**2
02898          wt(i) = v (i)**2
02899          wp(i) = w (i)**2
02900       enddo
02901 
02902       c2(1) = c1
02903       c2(2) = 'z'
02904 
02905       call z_avg_buff(u ,v ,w ,c2,'ub',icount)
02906       call z_avg_buff(wr,wt,wp,c2,'u2',icount)
02907 
02908       do i=1,n
02909          wr(i) = u(i)*v(i)
02910          wt(i) = v(i)*w(i)
02911          wp(i) = w(i)*u(i)
02912       enddo
02913       call z_avg_buff(wr,wt,wp,c2,'uv',icount)
02914 
02915       call z_ins_buff(u ,v ,w ,c2,'ui',icount)
02916 
02917       return
02918       end
02919 c-----------------------------------------------------------------------
02920       subroutine anal_2d
02921 
02922       include 'SIZE'
02923       include 'TOTAL'
02924       include 'ZPER'
02925 
02926       integer icount
02927       save    icount
02928 
02929       if (nelx.gt.lelx .or.
02930      $    nely.gt.lely .or.
02931      $    nelz.gt.lelz ) then
02932          if (nio.eq.0) write(6,1) nelx,nely,nelz,lelx,lely,lelz
02933     1    format('anal_2d fail:',6i6)
02934          return
02935       endif
02936 
02937       if (istep.eq.0) then   ! dump four times, just to keep phase
02938 
02939          icount = 0
02940          call z2d(xm1,ym1,zm1,pr,'u',icount)
02941          if (ifmhd) call z2d(xm1,ym1,zm1,pm,'b',icount)
02942 
02943          call y2d(xm1,ym1,zm1,pr,'u',icount)
02944          if (ifmhd) call y2d(xm1,ym1,zm1,pm,'b',icount)
02945 
02946       endif
02947 
02948       icount = icount + 1
02949 
02950       call z2d(vx,vy,vz,pr,'u',icount)
02951       if (ifmhd) call z2d(bx,by,bz,pm,'b',icount)
02952 
02953       call y2d(vx,vy,vz,pr,'u',icount)
02954       if (ifmhd) call y2d(bx,by,bz,pm,'b',icount)
02955 
02956       return
02957       end
02958 c-----------------------------------------------------------------------
02959       subroutine chkit(u,name4,n)
02960 
02961       include 'SIZE'
02962       include 'TOTAL'
02963 
02964       character*4 name4
02965       real u(1)
02966 
02967 
02968       integer icalld
02969       save    icalld
02970       data    icalld /0/
02971       
02972       icalld = icalld + 1
02973 
02974       u2   = vlsc2(u,u,n)
02975       umin = vlmin(u,n)
02976       umax = vlmax(u,n)
02977       ulst = u(n)
02978       if (nio.eq.0)
02979      $write(6,1) nid,icalld,istep,n,umin,umax,ulst,name4,' chkit',nid
02980     1 format(4i7,1p3e12.4,a4,a6,i1)
02981 
02982       return
02983       end
02984 c-----------------------------------------------------------------------
02985       subroutine outmesh
02986       include 'SIZE'
02987       include 'TOTAL'
02988       integer e,eg
02989 
02990       common /cmesh/ xt(2**ldim,ldim)
02991 
02992       len = wdsize*ndim*(2**ndim)
02993 
02994       if (nid.eq.0) open(unit=29,file='rea.new')
02995 
02996       do eg=1,nelgt
02997          mtype = eg
02998          call nekgsync()          !  belt
02999          jnid = gllnid(eg)
03000          e    = gllel (eg)
03001          if (jnid.eq.0 .and. nid.eq.0) then
03002             call get_el(xt,xm1(1,1,1,e),ym1(1,1,1,e),zm1(1,1,1,e))
03003             call out_el(xt,eg)
03004          elseif (nid.eq.0) then
03005             call crecv(mtype,xt,len)
03006             call out_el(xt,eg)
03007          elseif (jnid.eq.nid) then
03008             call get_el(xt,xm1(1,1,1,e),ym1(1,1,1,e),zm1(1,1,1,e))
03009             call csend(mtype,xt,len,0,0)
03010          endif
03011          call nekgsync()          !  suspenders
03012       enddo
03013 
03014       if (nid.eq.0) close(29)
03015       call nekgsync()
03016       call exitt
03017 
03018       return
03019       end
03020 c-----------------------------------------------------------------------
03021       subroutine out_el(xt,e)
03022       include 'SIZE'
03023       include 'TOTAL'
03024 
03025       real xt(2**ldim,ldim)
03026       integer e
03027 
03028       integer ed(8)
03029       save    ed
03030       data    ed  / 1,2,4,3 , 5,6,8,7 /
03031 
03032       write(29,1) e
03033       write(29,2) ((xt(ed(k),j),k=1,4),j=1,ndim)
03034       write(29,2) ((xt(ed(k),j),k=5,8),j=1,ndim)
03035 
03036     1 format(12x,'ELEMENT',i6,' [    1 ]    GROUP     0')
03037     2 format(1p4e18.10)
03038 
03039       return
03040       end
03041 c-----------------------------------------------------------------------
03042       subroutine get_el(xt,x,y,z)
03043       include 'SIZE'
03044       include 'TOTAL'
03045 
03046       real xt(2**ldim,ldim)
03047       real x(nx1,ny1,nz1),y(nx1,ny1,nz1),z(nx1,ny1,nz1)
03048 
03049       l = 0
03050       do k=1,nz1,nz1-1
03051       do j=1,ny1,ny1-1
03052       do i=1,nx1,nx1-1
03053          l = l+1
03054          xt(l,1) = x(i,j,k)
03055          xt(l,2) = y(i,j,k)
03056          xt(l,3) = z(i,j,k)
03057       enddo
03058       enddo
03059       enddo
03060 
03061       return
03062       end
03063 c-----------------------------------------------------------------------
03064       subroutine shear_calc_max(strsmx,scale,x0,ifdout,iftout)
03065 c
03066 c     Compute maximum shear stress on objects
03067 c
03068 c     Scale is a user-supplied multiplier so that results may be
03069 c     scaled to any convenient non-dimensionalization.
03070 c
03071 c
03072       INCLUDE 'SIZE'  
03073       INCLUDE 'TOTAL' 
03074 
03075       real    strsmx(maxobj),x0(3),w1(0:maxobj)
03076       logical ifdout,iftout
03077 
03078       common /cvflow_r/ flow_rate,base_flow,domain_length,xsec
03079      $                , scale_vf(3)
03080 
03081 
03082       common /scrns/         sij (lx1*ly1*lz1*6*lelv)
03083       common /scrcg/         pm1 (lx1,ly1,lz1,lelv)
03084       common /scrsf/         xm0(lx1,ly1,lz1,lelt)
03085      $,                      ym0(lx1,ly1,lz1,lelt)
03086      $,                      zm0(lx1,ly1,lz1,lelt)
03087 
03088       parameter (lr=lx1*ly1*lz1)
03089       common /scruz/         ur(lr),us(lr),ut(lr)
03090      $                     , vr(lr),vs(lr),vt(lr)
03091      $                     , wr(lr),ws(lr),wt(lr)
03092 
03093 
03094       n = nx1*ny1*nz1*nelv
03095 
03096       call mappr(pm1,pr,xm0,ym0) ! map pressure onto Mesh 1
03097 
03098 c    Add mean_pressure_gradient.X to p:
03099 
03100       if (param(55).ne.0) then
03101          dpdx_mean = -scale_vf(1)
03102          dpdy_mean = -scale_vf(2)
03103          dpdz_mean = -scale_vf(3)
03104       endif
03105 
03106       call add2s2(pm1,xm1,dpdx_mean,n)  ! Doesn't work if object is cut by 
03107       call add2s2(pm1,ym1,dpdy_mean,n)  ! periodicboundary.  In this case,
03108       call add2s2(pm1,zm1,dpdz_mean,n)  ! set ._mean=0 and compensate in
03109 c
03110 c    Compute sij
03111 c
03112       nij = 3
03113       if (if3d.or.ifaxis) nij=6
03114       call comp_sij(sij,nij,vx,vy,vz,ur,us,ut,vr,vs,vt,wr,ws,wt)
03115 c
03116 c
03117 c     Fill up viscous array w/ default
03118 c
03119       if (istep.lt.1) call cfill(vdiff,param(2),n)
03120 c
03121       call cadd2(xm0,xm1,-x0(1),n)
03122       call cadd2(ym0,ym1,-x0(2),n)
03123       call cadd2(zm0,zm1,-x0(3),n)
03124 c
03125       x1min=glmin(xm0(1,1,1,1),n)
03126       x2min=glmin(ym0(1,1,1,1),n)
03127       x3min=glmin(zm0(1,1,1,1),n)
03128 c
03129       x1max=glmax(xm0(1,1,1,1),n)
03130       x2max=glmax(ym0(1,1,1,1),n)
03131       x3max=glmax(zm0(1,1,1,1),n)
03132 c
03133       call rzero(strsmx,maxobj)
03134 c
03135 c
03136       nobj = 0
03137       do ii=1,nhis
03138         if (hcode(10,ii).EQ.'I') then
03139           iobj   = lochis(1,ii)
03140           memtot = nmember(iobj)
03141           nobj   = max(iobj,nobj)
03142 c
03143           if (hcode(1,ii).ne.' ' .or. hcode(2,ii).ne.' ' .or.
03144      $      hcode(3,ii).ne.' ' ) then
03145             ifield = 1
03146 c
03147 c           Compute max stress for this object
03148 c
03149             strsmx(ii) = 0.
03150             do mem=1,memtot
03151                ieg   = object(iobj,mem,1)
03152                ifc   = object(iobj,mem,2)
03153                if (gllnid(ieg).eq.nid) then ! this processor has a contribution
03154 
03155                   ie = gllel(ieg)
03156                   call get_strsmax
03157      $                    (strsmxl,xm0,ym0,zm0,sij,pm1,vdiff,ifc,ie)
03158 
03159                   call cmult(strsmxl,scale,1)
03160                   strsmx(ii)=max(strsmx(ii),strsmxl)
03161 
03162                endif
03163             enddo
03164           endif
03165         endif
03166       enddo
03167 c
03168 c     Max contributions over all processors
03169 c
03170       call gop(strsmx,w1,'M  ',maxobj)
03171 
03172 
03173       return
03174       end
03175 c-----------------------------------------------------------------------
03176       subroutine get_strsmax(strsmax,xm0,ym0,zm0,sij,pm1,visc,f,e)
03177 c
03178       INCLUDE 'SIZE'
03179       INCLUDE 'GEOM'
03180       INCLUDE 'INPUT'
03181       INCLUDE 'TOPOL'
03182       INCLUDE 'TSTEP'
03183 c
03184       real dgtq(3,4)
03185       real xm0 (lx1,ly1,lz1,lelt)
03186       real ym0 (lx1,ly1,lz1,lelt)
03187       real zm0 (lx1,ly1,lz1,lelt)
03188       real sij (lx1,ly1,lz1,3*ldim-3,lelv)
03189       real pm1 (lx1,ly1,lz1,lelv)
03190       real visc(lx1,ly1,lz1,lelv)
03191 
03192       integer f,e,pf
03193       real    n1,n2,n3
03194 
03195       call dsset(nx1,ny1,nz1)    ! set up counters
03196       pf     = eface1(f)         ! convert from preproc. notation
03197       js1    = skpdat(1,pf)
03198       jf1    = skpdat(2,pf)
03199       jskip1 = skpdat(3,pf)
03200       js2    = skpdat(4,pf)
03201       jf2    = skpdat(5,pf)
03202       jskip2 = skpdat(6,pf)
03203 
03204       if (if3d.or.ifaxis) then
03205          i       = 0
03206          strsmax = 0
03207          do j2=js2,jf2,jskip2
03208          do j1=js1,jf1,jskip1
03209             i = i+1
03210             n1 = unx(i,1,f,e)
03211             n2 = uny(i,1,f,e)
03212             n3 = unz(i,1,f,e)
03213 c
03214             v  = visc(j1,j2,1,e)
03215 c
03216             s11 = sij(j1,j2,1,1,e)
03217             s21 = sij(j1,j2,1,4,e)
03218             s31 = sij(j1,j2,1,6,e)
03219 c
03220             s12 = sij(j1,j2,1,4,e)
03221             s22 = sij(j1,j2,1,2,e)
03222             s32 = sij(j1,j2,1,5,e)
03223 
03224             s13 = sij(j1,j2,1,6,e)
03225             s23 = sij(j1,j2,1,5,e)
03226             s33 = sij(j1,j2,1,3,e)
03227 
03228             stress1 = -v*(s11*n1 + s12*n2 + s13*n3) ! viscous drag
03229             stress2 = -v*(s21*n1 + s22*n2 + s23*n3)
03230             stress3 = -v*(s31*n1 + s32*n2 + s33*n3)
03231 
03232             strsnrm = stress1*stress1+stress2*stress2+stress3*stress3
03233             strsmax = max(strsmax,strsnrm)
03234 
03235          enddo
03236          enddo
03237 
03238       else ! 2D
03239 
03240          i       = 0
03241          strsmax = 0
03242          do j2=js2,jf2,jskip2
03243          do j1=js1,jf1,jskip1
03244             i = i+1
03245             n1 = unx(i,1,f,e)*area(i,1,f,e)
03246             n2 = uny(i,1,f,e)*area(i,1,f,e)
03247             v  = visc(j1,j2,1,e)
03248 
03249             s11 = sij(j1,j2,1,1,e)
03250             s12 = sij(j1,j2,1,3,e)
03251             s21 = sij(j1,j2,1,3,e)
03252             s22 = sij(j1,j2,1,2,e)
03253 
03254             stress1 = -v*(s11*n1 + s12*n2) ! viscous drag
03255             stress2 = -v*(s21*n1 + s22*n2)
03256 
03257             strsnrm = stress1*stress1+stress2*stress2
03258             strsmax = max(strsmax,strsnrm)
03259 
03260        enddo
03261        enddo
03262 
03263       endif
03264 
03265       if (strsmax.gt.0) strsmax = sqrt(strsmax)
03266 
03267       return
03268       end
03269 c-----------------------------------------------------------------------
03270       subroutine fix_geom ! fix up geometry irregularities
03271 
03272       include 'SIZE'
03273       include 'TOTAL'
03274 
03275       parameter (lt = lx1*ly1*lz1)
03276       common /scrns/ xb(lt,lelt),yb(lt,lelt),zb(lt,lelt)
03277       common /scruz/ tmsk(lt,lelt),tmlt(lt,lelt),w1(lt),w2(lt)
03278 
03279       integer e,f
03280       character*3 cb
03281 
03282       n      = nx1*ny1*nz1*nelt
03283       nxyz   = nx1*ny1*nz1
03284       nfaces = 2*ndim
03285       ifield = 1                   ! velocity field
03286       if (ifheat) ifield = 2       ! temperature field
03287 
03288 
03289       call rone  (tmlt,n)
03290       call dssum (tmlt,nx1,ny1,nz1)  ! denominator
03291 
03292       call rone  (tmsk,n)
03293       do e=1,nelfld(ifield)      ! fill mask where bc is periodic
03294       do f=1,nfaces              ! so we don't translate periodic bcs (z only)
03295          cb =cbc(f,e,ifield)
03296          if (cb.eq.'P  ') call facev (tmsk,e,f,0.0,nx1,ny1,nz1)
03297       enddo
03298       enddo
03299 
03300       do kpass = 1,ndim+1   ! This doesn't work for 2D, yet.
03301                             ! Extra pass is just to test convergence
03302 
03303 c        call opcopy (xb,yb,zb,xm1,ym1,zm1) ! Must use WHOLE field,
03304 c        call opdssum(xb,yb,zb)             ! not just fluid domain.
03305          call copy   (xb,xm1,n)
03306          call copy   (yb,ym1,n)
03307          call copy   (zb,zm1,n)
03308          call dssum  (xb,nx1,ny1,nz1)
03309          call dssum  (yb,nx1,ny1,nz1)
03310          call dssum  (zb,nx1,ny1,nz1)
03311 
03312          xm = 0.
03313          ym = 0.
03314          zm = 0.
03315 
03316          do e=1,nelfld(ifield)
03317             do i=1,nxyz                       ! compute averages of geometry
03318                s     = 1./tmlt(i,e)
03319                xb(i,e) = s*xb(i,e)
03320                yb(i,e) = s*yb(i,e)
03321                zb(i,e) = s*zb(i,e)
03322 
03323                xb(i,e) = xb(i,e) - xm1(i,1,1,e)   ! local displacements
03324                yb(i,e) = yb(i,e) - ym1(i,1,1,e)
03325                zb(i,e) = zb(i,e) - zm1(i,1,1,e)
03326                xb(i,e) = xb(i,e)*tmsk(i,e)
03327                yb(i,e) = yb(i,e)*tmsk(i,e)
03328                zb(i,e) = zb(i,e)*tmsk(i,e)
03329 
03330                xm = max(xm,abs(xb(i,e)))
03331                ym = max(ym,abs(yb(i,e)))
03332                zm = max(zm,abs(zb(i,e)))
03333             enddo
03334 
03335             if (kpass.le.ndim) then
03336                call gh_face_extend(xb(1,e),zgm1,nx1,kpass,w1,w2)
03337                call gh_face_extend(yb(1,e),zgm1,nx1,kpass,w1,w2)
03338                call gh_face_extend(zb(1,e),zgm1,nx1,kpass,w1,w2)
03339             endif
03340 
03341          enddo
03342 
03343          if (kpass.le.ndim) then
03344             call add2(xm1,xb,n)
03345             call add2(ym1,yb,n)
03346             call add2(zm1,zb,n)
03347          endif
03348          
03349          xx = glamax(xb,n)
03350          yx = glamax(yb,n)
03351          zx = glamax(zb,n)
03352 
03353          xm = glmax(xm,1)
03354          ym = glmax(ym,1)
03355          zm = glmax(zm,1)
03356 
03357          if (nio.eq.0) write(6,1) xm,ym,zm,xx,yx,zx,kpass
03358     1    format(1p6e12.4,' xyz repair',i2)
03359 
03360       enddo
03361 
03362       param(59) = 1.       ! ifdef = .true.
03363       call geom_reset(1)   ! reset metrics, etc.
03364       
03365       return
03366       end
03367 c-----------------------------------------------------------------------
03368       subroutine gh_face_extend(x,zg,n,gh_type,e,v)
03369       include 'SIZE'
03370 
03371       real x(1),zg(1),e(1),v(1)
03372       integer gh_type
03373 
03374       if (ndim.eq.2) then
03375          call gh_face_extend_2d(x,zg,n,gh_type,e,v)
03376       else
03377          call gh_face_extend_3d(x,zg,n,gh_type,e,v)
03378       endif
03379       
03380       return
03381       end
03382 c-----------------------------------------------------------------------
03383       subroutine gh_face_extend_2d(x,zg,n,gh_type,e,v)
03384 c
03385 c     Extend 2D faces into interior via gordon hall
03386 c
03387 c     gh_type:  1 - vertex only
03388 c               2 - vertex and faces
03389 c
03390 c
03391       real x(n,n)
03392       real zg(n)
03393       real e(n,n)
03394       real v(n,n)
03395       integer gh_type
03396 c
03397 c     Build vertex interpolant
03398 c
03399       ntot=n*n
03400       call rzero(v,ntot)
03401       do jj=1,n,n-1
03402       do ii=1,n,n-1
03403          do j=1,n
03404          do i=1,n
03405             si     = 0.5*((n-ii)*(1-zg(i))+(ii-1)*(1+zg(i)))/(n-1)
03406             sj     = 0.5*((n-jj)*(1-zg(j))+(jj-1)*(1+zg(j)))/(n-1)
03407             v(i,j) = v(i,j) + si*sj*x(ii,jj)
03408          enddo
03409          enddo
03410       enddo
03411       enddo
03412       if (gh_type.eq.1) then
03413          call copy(x,v,ntot)
03414          return
03415       endif
03416 
03417 
03418 c     Extend 4 edges
03419       call rzero(e,ntot)
03420 c
03421 c     x-edges
03422 c
03423       do jj=1,n,n-1
03424          do j=1,n
03425          do i=1,n
03426             hj     = 0.5*((n-jj)*(1-zg(j))+(jj-1)*(1+zg(j)))/(n-1)
03427             e(i,j) = e(i,j) + hj*(x(i,jj)-v(i,jj))
03428          enddo
03429          enddo
03430       enddo
03431 c
03432 c     y-edges
03433 c
03434       do ii=1,n,n-1
03435          do j=1,n
03436          do i=1,n
03437             hi     = 0.5*((n-ii)*(1-zg(i))+(ii-1)*(1+zg(i)))/(n-1)
03438             e(i,j) = e(i,j) + hi*(x(ii,j)-v(ii,j))
03439          enddo
03440          enddo
03441       enddo
03442 
03443       call add3(x,e,v,ntot)
03444 
03445       return
03446       end
03447 c-----------------------------------------------------------------------
03448       subroutine gh_face_extend_3d(x,zg,n,gh_type,e,v)
03449 c
03450 c     Extend faces into interior via gordon hall
03451 c
03452 c     gh_type:  1 - vertex only
03453 c               2 - vertex and edges
03454 c               3 - vertex, edges, and faces
03455 c
03456 c
03457       real x(n,n,n)
03458       real zg(n)
03459       real e(n,n,n)
03460       real v(n,n,n)
03461       integer gh_type
03462 c
03463 c     Build vertex interpolant
03464 c
03465       ntot=n*n*n
03466       call rzero(v,ntot)
03467       do kk=1,n,n-1
03468       do jj=1,n,n-1
03469       do ii=1,n,n-1
03470          do k=1,n
03471          do j=1,n
03472          do i=1,n
03473             si       = 0.5*((n-ii)*(1-zg(i))+(ii-1)*(1+zg(i)))/(n-1)
03474             sj       = 0.5*((n-jj)*(1-zg(j))+(jj-1)*(1+zg(j)))/(n-1)
03475             sk       = 0.5*((n-kk)*(1-zg(k))+(kk-1)*(1+zg(k)))/(n-1)
03476             v(i,j,k) = v(i,j,k) + si*sj*sk*x(ii,jj,kk)
03477          enddo
03478          enddo
03479          enddo
03480       enddo
03481       enddo
03482       enddo
03483       if (gh_type.eq.1) then
03484          call copy(x,v,ntot)
03485          return
03486       endif
03487 c
03488 c
03489 c     Extend 12 edges
03490       call rzero(e,ntot)
03491 c
03492 c     x-edges
03493 c
03494       do kk=1,n,n-1
03495       do jj=1,n,n-1
03496          do k=1,n
03497          do j=1,n
03498          do i=1,n
03499             hj       = 0.5*((n-jj)*(1-zg(j))+(jj-1)*(1+zg(j)))/(n-1)
03500             hk       = 0.5*((n-kk)*(1-zg(k))+(kk-1)*(1+zg(k)))/(n-1)
03501             e(i,j,k) = e(i,j,k) + hj*hk*(x(i,jj,kk)-v(i,jj,kk))
03502          enddo
03503          enddo
03504          enddo
03505       enddo
03506       enddo
03507 c
03508 c     y-edges
03509 c
03510       do kk=1,n,n-1
03511       do ii=1,n,n-1
03512          do k=1,n
03513          do j=1,n
03514          do i=1,n
03515             hi       = 0.5*((n-ii)*(1-zg(i))+(ii-1)*(1+zg(i)))/(n-1)
03516             hk       = 0.5*((n-kk)*(1-zg(k))+(kk-1)*(1+zg(k)))/(n-1)
03517             e(i,j,k) = e(i,j,k) + hi*hk*(x(ii,j,kk)-v(ii,j,kk))
03518          enddo
03519          enddo
03520          enddo
03521       enddo
03522       enddo
03523 c
03524 c     z-edges
03525 c
03526       do jj=1,n,n-1
03527       do ii=1,n,n-1
03528          do k=1,n
03529          do j=1,n
03530          do i=1,n
03531             hi       = 0.5*((n-ii)*(1-zg(i))+(ii-1)*(1+zg(i)))/(n-1)
03532             hj       = 0.5*((n-jj)*(1-zg(j))+(jj-1)*(1+zg(j)))/(n-1)
03533             e(i,j,k) = e(i,j,k) + hi*hj*(x(ii,jj,k)-v(ii,jj,k))
03534          enddo
03535          enddo
03536          enddo
03537       enddo
03538       enddo
03539 c
03540       call add2(e,v,ntot)
03541 c
03542       if (gh_type.eq.2) then
03543          call copy(x,e,ntot)
03544          return
03545       endif
03546 c
03547 c     Extend faces
03548 c
03549       call rzero(v,ntot)
03550 c
03551 c     x-edges
03552 c
03553       do ii=1,n,n-1
03554          do k=1,n
03555          do j=1,n
03556          do i=1,n
03557             hi       = 0.5*((n-ii)*(1-zg(i))+(ii-1)*(1+zg(i)))/(n-1)
03558             v(i,j,k) = v(i,j,k) + hi*(x(ii,j,k)-e(ii,j,k))
03559          enddo
03560          enddo
03561          enddo
03562       enddo
03563 c
03564 c     y-edges
03565 c
03566       do jj=1,n,n-1
03567          do k=1,n
03568          do j=1,n
03569          do i=1,n
03570             hj       = 0.5*((n-jj)*(1-zg(j))+(jj-1)*(1+zg(j)))/(n-1)
03571             v(i,j,k) = v(i,j,k) + hj*(x(i,jj,k)-e(i,jj,k))
03572          enddo
03573          enddo
03574          enddo
03575       enddo
03576 c
03577 c     z-edges
03578 c
03579       do kk=1,n,n-1
03580          do k=1,n
03581          do j=1,n
03582          do i=1,n
03583             hk       = 0.5*((n-kk)*(1-zg(k))+(kk-1)*(1+zg(k)))/(n-1)
03584             v(i,j,k) = v(i,j,k) + hk*(x(i,j,kk)-e(i,j,kk))
03585          enddo
03586          enddo
03587          enddo
03588       enddo
03589 c
03590       call add2(v,e,ntot)
03591       call copy(x,v,ntot)
03592 
03593       return
03594       end
03595 c-----------------------------------------------------------------------
03596       function ran1(idum)
03597 c
03598       integer idum,ia,im,iq,ir,ntab,ndiv
03599       real    ran1,am,eps,rnmx
03600 c
03601       parameter (ia=16807,im=2147483647,am=1./im,iq=127773,ir=2836)
03602       parameter (ntab=32,ndiv=1+(im-1)/ntab,eps=1.2e-7,rnmx=1.-eps)
03603 c
03604 c     Numerical Rec. in Fortran, 2nd eD.  P. 271
03605 c
03606       integer j,k
03607       integer iv(ntab),iy
03608       save    iv,iy
03609       data    iv,iy /ntab*0,0/
03610 c
03611       if (idum.le.0.or.iy.eq.0) then
03612          idum=max(-idum,1)
03613          do j=ntab+8,1,-1
03614             k    = idum/iq
03615             idum = ia*(idum-k*iq)-ir*k
03616             if(idum.lt.0) idum = idum+im
03617             if (j.le.ntab) iv(j) = idum
03618          enddo
03619          iy = iv(1)
03620       endif
03621       k    = idum/iq
03622       idum = ia*(idum-k*iq)-ir*k
03623       if(idum.lt.0) idum = idum+im
03624       j     = 1+iy/ndiv
03625       iy    = iv(j)
03626       iv(j) = idum
03627       ran1  = min(am*iy,rnmx)
03628 c     ran1  = cos(ran1*1.e8)
03629 
03630       return
03631       end
03632 c-----------------------------------------------------------------------
03633       subroutine rand_fld_h1(x)
03634 
03635       include 'SIZE'
03636       real x(1)
03637 
03638       n=nx1*ny1*nz1*nelt
03639       id = n
03640       do i=1,n
03641          x(i) = ran1(id)
03642       enddo
03643       call dsavg(x)
03644 
03645       return
03646       end
03647 c-----------------------------------------------------------------------
03648       subroutine rescale_x (x,x0,x1)
03649       include 'SIZE'
03650       real x(1)
03651 
03652       n = nx1*ny1*nz1*nelt
03653       xmin = glmin(x,n)
03654       xmax = glmax(x,n)
03655 
03656       if (xmax.le.xmin) return
03657 
03658       scale = (x1-x0)/(xmax-xmin)
03659       do i=1,n
03660          x(i) = x0 + scale*(x(i)-xmin)
03661       enddo
03662 
03663       return
03664       end
03665 c-----------------------------------------------------------------------
03666       subroutine z_distribute(u)
03667 c
03668 c     Compute the z average of quantity u() and redistribute
03669 c
03670 c     Assumes you have nelx*nely elements, in the same order,
03671 c     within each z plane
03672 c
03673 c
03674       include 'SIZE'
03675       include 'TOTAL'
03676       include 'ZPER'
03677 
03678       real ux(1),uy(1),uz(1)
03679       character*2 c2,name
03680 
03681       parameter (lyavg = lx1*ly1*lelx*lely)
03682       common /scravg/ ua(lyavg)
03683      $              , w1(lyavg)
03684      $              , w2(lyavg)
03685 
03686       call z_average          (ua,u,w1,w2)
03687       call z_average_transpose(u,ua) ! distribute ua to each z-plane
03688 
03689       return
03690       end
03691 c-----------------------------------------------------------------------
03692       subroutine z_average(ua,u,w1,w2)
03693 c
03694 c     Compute the z average of quantity u() - assumes global tens.prod.
03695 c
03696       include 'SIZE'
03697       include 'GEOM'
03698       include 'PARALLEL'
03699       include 'WZ'
03700       include 'ZPER'
03701 
03702       real ua(nx1,ny1,nelx,nely),u (nx1,ny1,nz1,nelv)
03703      $    ,w1(nx1,ny1,nelx,nely),w2(nx1,ny1,nelx,nely)
03704       integer e,eg,ex,ey,ez
03705       real dy2
03706 
03707       nelxy = nelx*nely
03708       if (nelxy.gt.lelx*lely) call exitti
03709      $  ('ABORT IN z_average. Increase lelx*lely in SIZE:$',nelxy)
03710 
03711       mxy = nelx*nely*nx1*ny1
03712       call rzero(ua,mxy)
03713       call rzero(w1,mxy)
03714 
03715       do e=1,nelt
03716 
03717          eg = lglel(e)
03718          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
03719 
03720          do j=1,ny1
03721          do i=1,nx1
03722             dz2 = 1.0  !  Assuming uniform in "z" direction
03723             do k=1,nz1
03724                ua(i,j,ex,ey) = ua(i,j,ex,ey)+dz2*wzm1(k)*u(i,j,k,e)
03725                w1(i,j,ex,ey) = w1(i,j,ex,ey)+dz2*wzm1(k) ! redundant but clear
03726             enddo
03727          enddo
03728          enddo
03729       enddo
03730 
03731       call gop(ua,w2,'+  ',mxy)
03732       call gop(w1,w2,'+  ',mxy)
03733 
03734       do i=1,mxy
03735          ua(i,1,1,1) = ua(i,1,1,1) / w1(i,1,1,1)   ! Normalize
03736       enddo
03737 
03738       return
03739       end
03740 c-----------------------------------------------------------------------
03741       subroutine z_average_transpose(u,ua) ! distribute ua to each z-plane
03742 
03743       include 'SIZE'
03744       include 'GEOM'
03745       include 'PARALLEL'
03746       include 'WZ'
03747       include 'ZPER'
03748 
03749       real u(nx1,ny1,nz1,nelv),ua(nx1,ny1,nelx,nely)
03750 
03751       integer e,eg,ex,ey,ez
03752 
03753 
03754       do e=1,nelt
03755 
03756          eg = lglel(e)
03757          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
03758 
03759          do j=1,ny1
03760          do i=1,nx1
03761             do k=1,nz1
03762                u(i,j,k,e) = ua(i,j,ex,ey)
03763             enddo
03764          enddo
03765          enddo
03766       enddo
03767 
03768       return
03769       end
03770 c-----------------------------------------------------------------------
03771       subroutine no_z_profile(u)
03772 
03773 c     Subtract the z_profile from u for a tensor-product array of elements
03774 
03775 c     Assumes you have nelx*nely*nelz elements, in the same order,
03776 c     and that lelx,lely,lelz are defined to be >= nelx,nely,nelz
03777 
03778 
03779       include 'SIZE'
03780       include 'TOTAL'
03781       include 'ZPER'         ! nelx,nely,nelz
03782 
03783       real u(1)
03784 
03785       parameter (lyavg = ly1*lely)
03786       common /scravg/ ua(lyavg)
03787      $              , w1(lyavg)
03788      $              , w2(lyavg)
03789       common /scrmg/  ub(lx1*ly1*lz1*lelt)
03790 
03791       call z_profile          (ua,u,w1,w2)
03792       call z_profile_transpose(ub,ua) ! distribute ua to each z-plane
03793 
03794       n = nx1*ny1*nz1*nelv
03795       call sub2(u,ub,n)
03796 
03797       return
03798       end
03799 c-----------------------------------------------------------------------
03800       subroutine z_profile(ua,u,w1,w2)
03801 c
03802 c     Compute the z profile of quantity u() - assumes global tens.prod.
03803 c
03804       include 'SIZE'
03805       include 'GEOM'
03806       include 'PARALLEL'
03807       include 'WZ'
03808       include 'ZPER'
03809 
03810       real ua(lz1,lelz),u (nx1,ny1,nz1,nelv)
03811      $    ,w1(lz1,lelz),w2(lz1,lelz)
03812       integer e,eg,ex,ey,ez
03813 
03814       mz = nz1*nelz
03815       call rzero(ua,mz)
03816       call rzero(w1,mz)
03817 
03818       do e=1,nelt
03819 
03820          eg = lglel(e)
03821          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
03822 
03823          do k=1,nz1
03824          do i=1,nx1*ny1
03825             ua(k,ez) = ua(k,ez) + area(i,1,5,e)*u(i,1,k,e)
03826             w1(k,ez) = w1(k,ez) + area(i,1,5,e)
03827          enddo
03828          enddo
03829 
03830       enddo
03831 
03832       call gop(ua,w2,'+  ',mz)
03833       call gop(w1,w2,'+  ',mz)
03834 
03835       do i=1,mz
03836          ua(i,1) = ua(i,1) / w1(i,1)   ! Normalize
03837       enddo
03838 
03839       return
03840       end
03841 c-----------------------------------------------------------------------
03842       subroutine z_profile_transpose(u,ua) ! distribute ua to each z-plane
03843 
03844       include 'SIZE'
03845       include 'PARALLEL'
03846       include 'ZPER'
03847 
03848       real u(nx1,ny1,nz1,nelv),ua(lz1,lelz)
03849       integer e,eg,ex,ey,ez
03850 
03851       do e=1,nelt
03852 
03853          eg = lglel(e)
03854          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
03855 
03856          do k=1,nz1
03857          do i=1,nx1*ny1
03858             u(i,1,k,e) = ua(k,ez)
03859          enddo
03860          enddo
03861 
03862       enddo
03863 
03864       return
03865       end
03866 c-----------------------------------------------------------------------
03867       subroutine no_y_profile(u)
03868 
03869 c     Subtract the y_profile from u for a tensor-product array of elements
03870 
03871 c     Assumes you have nelx*nely*nelz elements, in the same order,
03872 c     and that lelx,lely,lelz are defined to be >= nelx,nely,nelz
03873 
03874 
03875       include 'SIZE'
03876       include 'TOTAL'
03877       include 'ZPER'         ! nelx,nely,nelz
03878 
03879       real u(1)
03880 
03881       parameter (lyavg = ly1*lely)
03882       common /scravg/ ua(lyavg)
03883      $              , w1(lyavg)
03884      $              , w2(lyavg)
03885       common /scrmg/  ub(lx1*ly1*lz1*lelt)
03886 
03887       call y_profile          (ua,u,w1,w2)
03888       call y_profile_transpose(ub,ua) ! distribute ua to each y-plane
03889 
03890       n = nx1*ny1*nz1*nelv
03891       call sub2(u,ub,n)
03892 
03893       return
03894       end
03895 c-----------------------------------------------------------------------
03896       subroutine y_profile(ua,u,w1,w2)
03897 c
03898 c     Compute the z profile of quantity u() - assumes global tens.prod.
03899 c
03900       include 'SIZE'
03901       include 'GEOM'
03902       include 'PARALLEL'
03903       include 'WZ'
03904       include 'ZPER'
03905 
03906       real ua(lz1,lelz),u (nx1,ny1,nz1,nelv)
03907      $    ,w1(lz1,lelz),w2(lz1,lelz)
03908       integer e,eg,ex,ey,ez
03909 
03910       my = ny1*nely
03911       call rzero(ua,my)
03912       call rzero(w1,my)
03913 
03914       do e=1,nelt
03915 
03916          eg = lglel(e)
03917          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
03918 
03919          do k=1,nz1
03920          do j=1,ny1
03921          do i=1,nx1
03922             ua(j,ey) = ua(j,ey) + area(i,k,1,e)*u(i,j,k,e)
03923             w1(j,ey) = w1(j,ey) + area(i,k,1,e)
03924          enddo
03925          enddo
03926          enddo
03927 
03928       enddo
03929 
03930       call gop(ua,w2,'+  ',my)
03931       call gop(w1,w2,'+  ',my)
03932 
03933       do i=1,my
03934          ua(i,1) = ua(i,1) / w1(i,1)   ! Normalize
03935       enddo
03936 
03937       return
03938       end
03939 c-----------------------------------------------------------------------
03940       subroutine y_profile_transpose(u,ua) ! distribute ua to each z-plane
03941 
03942       include 'SIZE'
03943       include 'PARALLEL'
03944       include 'ZPER'
03945 
03946       real u(nx1,ny1,nz1,nelv),ua(lz1,lelz)
03947       integer e,eg,ex,ey,ez
03948 
03949       do e=1,nelt
03950 
03951          eg = lglel(e)
03952          call get_exyz(ex,ey,ez,eg,nelx,nely,nelz)
03953 
03954          do k=1,nz1
03955          do j=1,ny1
03956          do i=1,nx1
03957             u(i,j,k,e) = ua(j,ey)
03958          enddo
03959          enddo
03960          enddo
03961 
03962       enddo
03963 
03964       return
03965       end
03966 c-----------------------------------------------------------------------
03967       subroutine build_filter(f,diag,nx)
03968       include 'SIZE'
03969 
03970       real f(nx,nx),diag(nx),zpts(nx)
03971 
03972       parameter (lm=4*lx1) ! Totally arbitrary
03973       parameter (lm2=lm*lm)
03974 
03975       common /cfilt1/ phi,pht,ft,rmult,Lj,gpts,indr,indc,ipiv
03976       real      phi(lm2),pht(lm2),ft(lm2),rmult(lm),Lj(lm),gpts(lm)
03977       integer   indr(lm),indc(lm),ipiv(lm)
03978 
03979       integer nxl
03980       save    nxl
03981       data    nxl / -9 /
03982 
03983       if (nx.gt.lm) call exitti('ABORT in build_filter:$',nx)
03984 
03985       if (nx.ne.nxl) then
03986 
03987         nxl = nx
03988 
03989         call zwgll (gpts,f,nx)  ! Get nx GLL points
03990 
03991         kj = 0
03992         n  = nx-1
03993         do j=1,nx
03994          z = gpts(j)
03995          call legendre_poly(Lj,z,n)
03996          kj = kj+1
03997          pht(kj) = Lj(1)
03998          kj = kj+1
03999          pht(kj) = Lj(2)
04000          do k=3,nx
04001             kj = kj+1
04002             pht(kj) = Lj(k)-Lj(k-2)
04003          enddo
04004         enddo
04005 
04006         call transpose (phi,nx,pht,nx)
04007         call copy      (pht,phi,nx*nx)
04008         call gaujordf  (pht,nx,nx,indr,indc,ipiv,ierr,rmult)
04009 
04010       endif ! End of save section
04011 
04012       ij=0
04013       do j=1,nx
04014       do i=1,nx
04015          ij = ij+1
04016          ft(ij) = diag(i)*pht(ij)
04017       enddo
04018       enddo
04019                                           !          -1
04020       call mxm  (phi,nx,ft,nx,f,nx)       !     V D V
04021 
04022       return
04023       end
04024 c-----------------------------------------------------------------------
04025       subroutine g_filter(u,diag,ifld)
04026 c
04027 c     Generalized filter: F(u) with F = J^T D J, where D=diag(diag)
04028 c
04029       include 'SIZE'
04030       include 'TOTAL'
04031 
04032       real u(1),diag(1)
04033 
04034       parameter (lxx=lx1*lx1,lxyz=lx1*ly1*lz1)
04035       common /ctmp0/ f(lxx),wk1(lxyz),wk2(lxyz),wk3(lxyz)
04036 
04037       ifldt = ifield
04038       ifield = ifld
04039 
04040       call build_filter(f,diag,nx1)
04041       call filterq(u,f,nx1,nz1,wk1,wk2,wk3,if3d,umax)
04042 
04043       ifield = ifldt
04044 
04045       return
04046       end
04047 c-----------------------------------------------------------------------
04048       subroutine cut_off_filter(u,mx,ifld) ! mx=max saved mode
04049 c
04050 c     Generalized filter: F(u) with F = J^T D J, where D=diag(diag)
04051 c
04052       include 'SIZE'
04053       include 'TOTAL'
04054 
04055       real u(1)
04056 
04057       parameter (lxx=lx1*lx1,lxyz=lx1*ly1*lz1)
04058       common /ctmp0/ f(lxx),wk1(lxyz),wk2(lxyz),wk3(lxyz),diag(lx1)
04059 
04060       ifldt = ifield
04061       ifield = ifld
04062 
04063       call rone(diag,nx1)
04064       do i=mx+1,nx1
04065          diag(i)=0.
04066       enddo
04067 
04068       call build_filter(f,diag,nx1)
04069       call filterq(u,f,nx1,nz1,wk1,wk2,wk3,if3d,umax)
04070 
04071       ifield = ifldt
04072 
04073       return
04074       end
04075 c-----------------------------------------------------------------------
04076       subroutine filter_d2(v,nx,nz,wgt,ifd4)
04077 
04078       include 'SIZE'
04079       include 'TOTAL'
04080 
04081       parameter (lt=lx1*ly1*lz1)
04082       real v(lt,nelt)
04083       logical ifd4
04084 
04085       common /ctmp1/ w(lt,lelt),ur(lt),us(lt),ut(lt),w1(2*lt)
04086 
04087       integer e
04088 
04089       n   = nx1*ny1*nz1*nelt
04090       nn  = nx-1
04091       nel = nelfld(ifield)
04092 
04093       bmax = glamax(v,n)
04094 
04095       if (if3d) then
04096         do e=1,nel
04097           call local_grad3(ur,us,ut,v(1,e),nn,1,dxm1,dxtm1)
04098           do i=1,lt
04099             ur(i) = ur(i)*w3m1(i,1,1)
04100             us(i) = us(i)*w3m1(i,1,1)
04101             ut(i) = ut(i)*w3m1(i,1,1)
04102           enddo
04103           call local_grad3_t(w(1,e),ur,us,ut,nn,1,dxm1,dxtm1,w1)
04104         enddo
04105         call dsavg(w)  !NOTE STILL NEED BC TREATMENT !
04106 
04107         if (ifd4) then
04108            wght = 20./(nx1**4)
04109            do e=1,nel
04110              do i=1,lt
04111                w(i,e)  = wght*w(i,e)/w3m1(i,1,1)
04112              enddo
04113              call local_grad3(ur,us,ut,w(1,e),nn,1,dxm1,dxtm1)
04114              do i=1,lt
04115                ur(i) = ur(i)*w3m1(i,1,1)
04116                us(i) = us(i)*w3m1(i,1,1)
04117                ut(i) = ut(i)*w3m1(i,1,1)
04118              enddo
04119              call local_grad3_t(w(1,e),ur,us,ut,nn,1,dxm1,dxtm1,w1)
04120            enddo
04121            call dsavg(w)  !NOTE STILL NEED BC TREATMENT !
04122         endif
04123 
04124         wght = wgt/(nx1**4)
04125         do e=1,nel
04126           do i=1,lt
04127             v(i,e)  = v(i,e) - wght*w(i,e)/w3m1(i,1,1)
04128           enddo
04129         enddo
04130 
04131       else  ! 2D
04132 
04133         do e=1,nel
04134           call local_grad2(ur,us,v(1,e),nn,1,dxm1,dxtm1)
04135           do i=1,lt
04136             ur(i) = ur(i)*w3m1(i,1,1)
04137             us(i) = us(i)*w3m1(i,1,1)
04138           enddo
04139           call local_grad2_t(w(1,e),ur,us,nn,1,dxm1,dxtm1,w1)
04140         enddo
04141         call dsavg(w)  !NOTE STILL NEED BC TREATMENT !
04142 
04143         if (ifd4) then
04144            wght = 200./(nx1**4)
04145            do e=1,nel
04146              do i=1,lt
04147                w(i,e)  = wght*w(i,e)/w3m1(i,1,1)
04148              enddo
04149              call local_grad2(ur,us,w(1,e),nn,1,dxm1,dxtm1)
04150              do i=1,lt
04151                ur(i) = ur(i)*w3m1(i,1,1)
04152                us(i) = us(i)*w3m1(i,1,1)
04153              enddo
04154              call local_grad2_t(w(1,e),ur,us,nn,1,dxm1,dxtm1,w1)
04155            enddo
04156            call dsavg(w)  !NOTE STILL NEED BC TREATMENT !
04157         endif
04158 
04159         wght = wgt/(nx1**4)
04160         do e=1,nel
04161           do i=1,lt
04162             v(i,e)  = v(i,e) - wght*w(i,e)/w3m1(i,1,1)
04163           enddo
04164         enddo
04165 
04166       endif
04167 
04168       vmax = glamax(v,n)
04169       if (nio.eq.0) write(6,1) istep,time,vmax,bmax,' filter max'
04170     1 format(i9,1p3e12.4,a11)
04171 
04172       return
04173       end
04174 c-------------------------------------------------------------------------
04175       function dist3d(a,b,c,x,y,z)
04176 
04177       d = (a-x)**2 + (b-y)**2 + (c-z)**2
04178 
04179       dist3d = 0.
04180       if (d.gt.0) dist3d = sqrt(d)
04181 
04182       return
04183       end
04184 c-----------------------------------------------------------------------
04185       function dist2d(a,b,x,y)
04186 
04187       d = (a-x)**2 + (b-y)**2
04188 
04189       dist2d = 0.
04190       if (d.gt.0) dist2d = sqrt(d)
04191 
04192       return
04193       end
04194 c-----------------------------------------------------------------------
04195       subroutine domain_size(xmin,xmax,ymin,ymax,zmin,zmax)
04196 
04197       include 'SIZE'
04198       include 'TOTAL'
04199 
04200       n = nx1*ny1*nz1*nelt
04201 
04202       xmin = glmin(xm1,n)
04203       xmax = glmax(xm1,n)
04204       ymin = glmin(ym1,n)
04205       ymax = glmax(ym1,n)
04206       if (if3d) then
04207          zmin = glmin(zm1,n)
04208          zmax = glmax(zm1,n)
04209       else
04210          zmin = 0.
04211          zmax = 0.
04212       endif
04213 
04214       return
04215       end
04216 c-----------------------------------------------------------------------
04217       subroutine cheap_dist(d,ifld,b)
04218 
04219 c     Finds a pseudo-distance function.
04220 
04221 c     INPUT:  ifld - field type for which distance function is to be found.
04222 c             ifld = 1 for velocity
04223 c             ifld = 2 for temperature, etc.
04224 
04225 c     OUTPUT: d = "path" distance to nearest wall
04226 
04227 c     This approach has a significant advantage that it works for
04228 c     periodict boundary conditions, whereas most other approaches
04229 c     will not.
04230 
04231       include 'SIZE'
04232       include 'GEOM'       ! Coordinates
04233       include 'INPUT'      ! cbc()
04234       include 'TSTEP'      ! nelfld
04235       include 'PARALLEL'   ! gather-scatter handle for field "ifld"
04236 
04237       real d(lx1,ly1,lz1,lelt)
04238 
04239       character*3 b  ! Boundary condition of interest
04240 
04241       integer e,eg,f
04242 
04243       nel = nelfld(ifld)
04244       n = nx1*ny1*nz1*nel
04245 
04246       call domain_size(xmin,xmax,ymin,ymax,zmin,zmax)
04247 
04248       xmn = min(xmin,ymin)
04249       xmx = max(xmax,ymax)
04250       if (if3d) xmn = min(xmn ,zmin)
04251       if (if3d) xmx = max(xmx ,zmax)
04252 
04253       big = 10*(xmx-xmn)
04254       call cfill(d,big,n)
04255 
04256 
04257       nface = 2*ndim
04258       do e=1,nel     ! Set d=0 on walls
04259       do f=1,nface
04260          if (cbc(f,e,ifld).eq.b) call facev(d,e,f,0.,nx1,ny1,nz1)
04261       enddo
04262       enddo
04263 
04264       do ipass=1,10000
04265          dmax    = 0
04266          nchange = 0
04267          do e=1,nel
04268            do k=1,nz1
04269            do j=1,ny1
04270            do i=1,nx1
04271              i0=max(  1,i-1)
04272              j0=max(  1,j-1)
04273              k0=max(  1,k-1)
04274              i1=min(nx1,i+1)
04275              j1=min(ny1,j+1)
04276              k1=min(nz1,k+1)
04277              do kk=k0,k1
04278              do jj=j0,j1
04279              do ii=i0,i1
04280 
04281               if (if3d) then
04282                dtmp = d(ii,jj,kk,e) + dist3d(
04283      $           xm1(ii,jj,kk,e),ym1(ii,jj,kk,e),zm1(ii,jj,kk,e)
04284      $          ,xm1(i ,j ,k ,e),ym1(i ,j ,k ,e),zm1(i ,j ,k ,e))
04285               else
04286                dtmp = d(ii,jj,kk,e) + dist2d(
04287      $           xm1(ii,jj,kk,e),ym1(ii,jj,kk,e)
04288      $          ,xm1(i ,j ,k ,e),ym1(i ,j ,k ,e))
04289               endif
04290 
04291               if (dtmp.lt.d(i,j,k,e)) then
04292                 d(i,j,k,e) = dtmp
04293                 nchange = nchange+1
04294                 dmax = max(dmax,d(i,j,k,e))
04295               endif
04296              enddo
04297              enddo
04298              enddo
04299 
04300            enddo
04301            enddo
04302            enddo
04303          enddo
04304          call gs_op(gsh_fld(ifld),d,1,3,0) ! min over all elements
04305          nchange = iglsum(nchange,1)
04306          dmax = glmax(dmax,1)
04307          if (nio.eq.0) write(6,1) ipass,nchange,dmax,b
04308     1    format(i9,i12,1pe12.4,' max distance b: ',a3)
04309          if (nchange.eq.0) goto 1000
04310       enddo
04311  1000 return
04312       end
04313 c-----------------------------------------------------------------------
04314       subroutine distf(d,ifld,b,dmin,emin,xn,yn,zn)
04315 
04316 c     Generate a distance function to boundary with bc "b".
04317 c     This approach does not yet work with periodic boundary conditions.
04318 
04319 c     INPUT:  ifld - field type for which distance function is to be found.
04320 c             ifld = 1 for velocity
04321 c             ifld = 2 for temperature, etc.
04322 
04323 c     OUTPUT: d = distance to nearest boundary with boundary condition "b"
04324 
04325 c     Work arrays:  dmin,emin,xn,yn,zn
04326 
04327       include 'SIZE'
04328       include 'GEOM'       ! Coordinates
04329       include 'INPUT'      ! cbc()
04330       include 'TSTEP'      ! nelfld
04331       include 'PARALLEL'   ! gather-scatter handle for field "ifld"
04332 
04333       real d(lx1,ly1,lz1,lelt)
04334       character*3 b
04335 
04336       real dmin(lx1,ly1,lz1,lelt),emin(lx1,ly1,lz1,lelt)
04337       real xn(lx1,ly1,lz1,lelt),yn(lx1,ly1,lz1,lelt)
04338       real zn(lx1,ly1,lz1,lelt)
04339 
04340 
04341       integer e,eg,f
04342 
04343       nel = nelfld(ifld)
04344       n = nx1*ny1*nz1*nel
04345 
04346       call domain_size(xmin,xmax,ymin,ymax,zmin,zmax)
04347 
04348       xmn = min(xmin,ymin)
04349       xmx = max(xmax,ymax)
04350       if (if3d) xmn = min(xmn ,zmin)
04351       if (if3d) xmx = max(xmx ,zmax)
04352 
04353       big = 10*(xmx-xmn)
04354       call cfill (d,big,n)
04355 
04356       call opcopy(xn,yn,zn,xm1,ym1,zm1)
04357 
04358       nface = 2*ndim
04359       do e=1,nel     ! Set d=0 on walls
04360       do f=1,nface
04361          if (cbc(f,e,1).eq.b) call facev(d,e,f,0.,nx1,ny1,nz1)
04362       enddo
04363       enddo
04364 
04365       nxyz = nx1*ny1*nz1
04366 
04367       do ipass=1,10000
04368          dmax    = 0
04369          nchange = 0
04370          do e=1,nel
04371             do k=1,nz1
04372             do j=1,ny1
04373             do i=1,nx1
04374               i0=max(  1,i-1)
04375               j0=max(  1,j-1)
04376               k0=max(  1,k-1)
04377               i1=min(nx1,i+1)
04378               j1=min(ny1,j+1)
04379               k1=min(nz1,k+1)
04380               do kk=k0,k1
04381               do jj=j0,j1
04382               do ii=i0,i1
04383 
04384                dself  = d(i,j,k,e)
04385                dneigh = d(ii,jj,kk,e)
04386                if (dneigh.lt.dself) then  ! check neighbor's nearest point
04387                   d2 = (xm1(i,j,k,e)-xn(ii,jj,kk,e))**2
04388      $               + (ym1(i,j,k,e)-yn(ii,jj,kk,e))**2
04389                   if (if3d) d2 = d2 + (zm1(i,j,k,e)-zn(ii,jj,kk,e))**2
04390                   if (d2.gt.0) d2 = sqrt(d2)
04391                   if (d2.lt.dself) then
04392                     nchange = nchange+1
04393                     d (i,j,k,e) = d2
04394                     xn(i,j,k,e) = xn(ii,jj,kk,e)
04395                     yn(i,j,k,e) = yn(ii,jj,kk,e)
04396                     zn(i,j,k,e) = zn(ii,jj,kk,e)
04397                     dmax = max(dmax,d(i,j,k,e))
04398                   endif
04399                endif
04400               enddo
04401               enddo
04402               enddo
04403 
04404             enddo
04405             enddo
04406             enddo
04407 
04408             re = lglel(e)
04409             call cfill(emin(1,1,1,e),re,nxyz)
04410             call copy (dmin(1,1,1,e),d(1,1,1,e),nxyz)
04411 
04412          enddo
04413          nchange = iglsum(nchange,1)
04414 
04415          call gs_op(gsh_fld(ifld),dmin,1,3,0) ! min over all elements
04416 
04417 
04418          nchange2=0
04419          do e=1,nel
04420          do i=1,nxyz
04421           if (dmin(i,1,1,e).ne.d(i,1,1,e)) then
04422              nchange2 = nchange2+1
04423              emin(i,1,1,e) = 0  ! Flag
04424           endif
04425          enddo
04426          enddo
04427          call copy(d,dmin,n)                !   Ensure updated distance
04428          nchange2 = iglsum(nchange2,1)
04429          nchange  = nchange + nchange2
04430          call gs_op(gsh_fld(ifld),emin,1,4,0) ! max over all elements
04431 
04432          do e=1,nel    ! Propagate nearest wall points
04433          do i=1,nxyz
04434           eg = emin(i,1,1,e)
04435           if (eg.ne.lglel(e)) then
04436              xn(i,1,1,e) = 0
04437              yn(i,1,1,e) = 0
04438              zn(i,1,1,e) = 0
04439           endif
04440          enddo
04441          enddo
04442          call gs_op(gsh_fld(ifld),xn,1,1,0) !   Sum over all elements to
04443          call gs_op(gsh_fld(ifld),yn,1,1,0) !   convey nearest point
04444          call gs_op(gsh_fld(ifld),zn,1,1,0) !   to shared neighbor.
04445 
04446          dmax = glmax(dmax,1)
04447          if (nio.eq.0) write(6,1) ipass,nchange,dmax
04448     1    format(i9,i12,1pe12.4,' max wall distance 2')
04449          if (nchange.eq.0) goto 1000
04450       enddo
04451  1000 continue
04452 
04453 c     wgt = 0.3
04454 c     call filter_d2(d,nx1,nz1,wgt,.true.)
04455 
04456       return
04457       end
04458 c-----------------------------------------------------------------------
04459       subroutine turb_outflow(d,m1,rq,uin)
04460 
04461 c     . Set div U > 0 in elements with 'O  ' bc.
04462 c
04463 c     . rq is nominally the ratio of Qout/Qin and is typically 1.5
04464 c
04465 c     . uin is normally zero, unless your flow is zero everywhere 
04466 c
04467 c     . d and m1 are work arrays of size (lx1,ly1,lz1,lelt), assumed persistant
04468 c
04469 c     This routine may or may not work with multiple outlets --- it has
04470 c     not been tested for this case.
04471 c
04472 c
04473 c     TYPICAL USAGE -- ADD THESE LINES TO userchk() in your .usr file:
04474 c                      (uncommented)
04475 c
04476 c     common /myoutflow/ d(lx1,ly1,lz1,lelt),m1(lx1*ly1*lz1,lelt)
04477 c     real m1
04478 c     rq  = 2.
04479 c     uin = 0.
04480 c     call turb_outflow(d,m1,rq,uin)
04481 c
04482 
04483       include 'SIZE'
04484       include 'TOTAL'
04485 
04486       real d(lx2,ly2,lz2,lelt),m1(lx1*ly1*lz1,lelt)
04487 
04488       parameter (lw = 3*lx1*ly1*lz1)
04489       common /ctmp1/ w(lw)
04490 
04491       integer icalld,noutf,e,f
04492       save    icalld,noutf
04493       data    icalld,noutf /0,0/
04494 
04495       real ddmax,cso
04496       save ddmax,cso
04497       logical ifout
04498 
04499       character*3 b
04500 
04501       n     = nx1*ny1*nz1*nelv
04502       n2    = nx2*ny2*nz2*nelv
04503       nxyz  = nx1*ny1*nz1
04504       nxyz2 = nx2*ny2*nz2
04505 
04506       if (icalld.eq.0) then
04507          icalld = 1
04508 
04509          b = 'O  '
04510          call cheap_dist(m1,1,b)
04511 
04512          call rzero (d,n2)
04513 
04514          ddmax = 0.
04515          noutf = 0
04516 
04517          do e=1,nelv
04518            ifout = .false.
04519            do f=1,2*ndim
04520              if (cbc(f,e,1).eq.b) ifout = .true. ! outflow
04521              if (cbc(f,e,1).eq.b) noutf = noutf+1
04522            enddo
04523            if (ifout) then
04524             if (lx2.lt.lx1) then ! Map distance function to Gauss
04525              call maph1_to_l2(d(1,1,1,e),nx2,m1(1,e),nx1,if3d,w,lw)
04526             else
04527              call copy(d(1,1,1,e),m1(1,e),nxyz)
04528             endif
04529             dmax  = vlmax(m1(1,e),nxyz)
04530             ddmax = max(ddmax,dmax)
04531             call rzero(m1(1,e),nxyz) ! mask points at outflow
04532            else
04533              call rone (m1(1,e),nxyz)
04534            endif
04535          enddo
04536 
04537          ddmax = glamax(ddmax,1)
04538 
04539          do e=1,nelv
04540            ifout = .false.
04541            do f=1,2*ndim
04542              if (cbc(f,e,1).eq.b) ifout = .true. ! outflow
04543            enddo
04544            if (ifout) then
04545               do i=1,nxyz2
04546                 d(i,1,1,e) = (ddmax - d(i,1,1,e))/ddmax
04547               enddo
04548            endif
04549          enddo
04550          noutf = iglsum(noutf,1)
04551       endif
04552 
04553       if (noutf.eq.0) return
04554 
04555       if (uin.ne.0) then ! Use user-supplied characteristic velocity
04556          ubar = uin
04557       else
04558          ubar = glsc3(vx,bm1,m1,n)   ! Masked average
04559          vbar = glsc3(vy,bm1,m1,n)
04560          wbar = glsc3(vz,bm1,m1,n)
04561          volu = glsc2(bm1,m1,n)
04562          ubar = abs(ubar)+abs(vbar)
04563          if (if3d) ubar = abs(ubar)+abs(wbar)
04564          ubar = ubar/volu
04565       endif
04566 
04567       cs = 3*(rq-1.)*(ubar/ddmax)
04568       if (.not.ifsplit) cs = cs*bd(1)/dt
04569 
04570       do i=1,n2
04571          usrdiv(i,1,1,1) = cs*(d(i,1,1,1)**2)
04572       enddo
04573 
04574       return
04575       end
04576 c-----------------------------------------------------------------------
04577       subroutine add_temp(f2tbc,nbc,npass)
04578 
04579 c     add multiple passive scalar fields (npass new ones)
04580 
04581       include 'SIZE'
04582       include 'TOTAL'
04583 
04584       character*3 f2tbc(2,nbc)
04585 
04586       do i=1,npass
04587          call add_temp_1(f2tbc,nbc)
04588       enddo
04589 
04590       igeom = 2
04591       call setup_topo  ! Set gs handles and multiplicity
04592 
04593       return
04594       end
04595 c-----------------------------------------------------------------------
04596       subroutine add_temp_1(f2tbc,nbc)
04597 
04598 c
04599 c     TYPICAL USAGE:  Add the below to usrdat().
04600 c
04601 c     parameter (lbc=10) ! Maximum number of bc types
04602 c     character*3 f2tbc(2,lbc)
04603 c
04604 c     f2tbc(1,1) = 'W  '   ! Any 'W  ' bc is swapped to ft2bc(2,1)
04605 c     f2tbc(2,1) = 'I  '
04606 c
04607 c     f2tbc(1,2) = 'v  '   ! Any 'v  ' bc is swapped to ft2bc(2,2)
04608 c     f2tbc(2,2) = 't  '
04609 c
04610 c     nbc = 2      ! Number of boundary condition pairings (e.g., W-->t)
04611 c     do i=1,ldimt-1
04612 c        call add_temp(f2tbc,nbc)
04613 c     enddo
04614 
04615       include 'SIZE'
04616       include 'TOTAL'
04617       character*3 f2tbc(2,nbc)
04618 
04619       integer e,f
04620 
04621       nfld=nfield+1
04622 
04623       if (nio.eq.0) write(6,*) 'add temp: ',nfld,nfield,istep
04624 
04625       nelfld(nfld) = nelfld(nfield)
04626       nel = nelfld(nfield)
04627       call copy  (bc(1,1,1,nfld),bc(1,1,1,nfield),30*nel)
04628       call chcopy(cbc(1,1,nfld),cbc(1,1,nfield),3*6*nel)
04629 
04630       do k=1,3
04631          cpfld(nfld,k)=cpfld(nfield,k)
04632          call copy (cpgrp(-5,nfld,k),cpgrp(-5,nfield,k),16)
04633       enddo
04634       call icopy(matype(-5,nfld),matype(-5,nfield),16)
04635 
04636       param(7) = param(1)  ! rhoCP   = rho
04637       param(8) = param(2)  ! conduct = dyn. visc
04638 
04639       ifheat       = .true.
04640       ifadvc(nfld) = .true.
04641       iftmsh(nfld) = .true.
04642       ifvarp(nfld) = ifvarp(nfield)
04643       if (nfld.eq.2) ifto = .true.
04644       if (nfld.gt.2) ifpsco(nfld-2) = .true.
04645       if (nfld.gt.2) npscal = npscal+1
04646 
04647 
04648       nfield = nfld
04649 
04650       nface = 2*ndim
04651       do k=1,nbc               ! BC conversion
04652         do e=1,nelfld(nfld)
04653         do f=1,nface
04654           if (cbc(f,e,nfld).eq.f2tbc(1,k)) cbc(f,e,nfld)=f2tbc(2,k)
04655         enddo
04656         enddo
04657       enddo
04658 
04659 
04660       return
04661       end
04662 c-----------------------------------------------------------------------
Generated on Mon Jun 6 19:19:57 2016 for nek5000 by  doxygen 1.6.3