
!=======================================================================
!      Advection schemes for momentum
!=======================================================================


 subroutine adv_flux_u_2nd(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of zonal momentum
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      integer :: i,j,k,js,je
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_)
      real*8 :: adv_fn(nx_,ny_,nz_) 

      js=max(2,js_pe); je = min(je_pe,ny-1)
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         adv_fe(i,j,k)=0.5*( u(i  ,j,k,tau) + u(i+1,j,k,tau) )*  &
         (u(i,j,k,tau)+u(i+1,j,k,tau)) *0.5*maskU(i+1,j,k)*maskU(i,j,k)
        enddo
       enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         adv_fn(i,j,k)= 0.5*( u(i,j,k,tau) + u(i,j+1,k,tau) )*   &
         (v(i,j,k,tau)+v(i+1,j,k,tau)) *0.5*maskU(i,j+1,k)*maskU(i,j,k)
        enddo
       enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)
      do k=1,nz-1
       do j=js,je
        do i=2,nx-1
         adv_ft(i,j,k)= 0.5*(u(i,j,k,tau)+u(i,j,k+1,tau))*   &
         (w(i,j,k,tau)+w(i+1,j,k,tau))*0.5*maskU(i,j,k+1)*maskU(i,j,k)
        enddo
       enddo
      enddo
 end subroutine adv_flux_u_2nd


 subroutine adv_flux_v_2nd(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of meridional momentum
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      integer :: i,j,k,js,je
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_)
      real*8 :: adv_fn(nx_,ny_,nz_) 
      js=max(2,js_pe); je = min(je_pe,ny-1)
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         adv_fe(i,j,k)= 0.5*( v(i  ,j,k,tau) + v(i+1,j,k,tau) )*  &
          (u(i,j,k,tau)+u(i,j+1,k,tau)) *0.5*maskV(i+1,j,k)*maskV(i,j,k)
        enddo
       enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         adv_fn(i,j,k)= 0.5*( v(i,j,k,tau) + v(i,j+1,k,tau) )*  &
         (v(i,j,k,tau)+v(i,j+1,k,tau)) *0.5*maskV(i,j+1,k)*maskV(i,j,k)
        enddo
       enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)
      do k=1,nz-1
       do j=js,je
        do i=2,nx-1
         adv_ft(i,j,k)= 0.5*( v(i,j,k,tau) + v(i,j,k+1,tau) )*  &
         (w(i,j,k,tau)+w(i,j+1,k,tau)) *0.5*maskV(i,j,k+1)*maskV(i,j,k)
        enddo
       enddo
      enddo
 end subroutine adv_flux_v_2nd




 subroutine adv_flux_w_2nd(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of vertical momentum
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,js,je
      js=max(2,js_pe); je = min(je_pe,ny-1)
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         adv_fe(i,j,k)= 0.5*( w(i  ,j,k,tau) + w(i+1,j,k,tau) )*  &
               (u(i,j,k,tau)+u(i,j,k+1,tau)) *0.5*maskW(i+1,j,k)*maskW(i,j,k)
        enddo
       enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         adv_fn(i,j,k)= 0.5*( w(i,j,k,tau) + w(i,j+1,k,tau) )*  &
           (v(i,j,k,tau)+v(i,j,k+1,tau)) *0.5*maskW(i,j+1,k)*maskW(i,j,k)
        enddo
       enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)
      do k=1,nz-1
       do j=js,je
        do i=2,nx-1
         adv_ft(i,j,k)= 0.5*( w(i,j,k,tau) + w(i,j,k+1,tau) )*  &
           (w(i,j,k,tau)+w(i,j,k+1,tau)) *0.5*maskW(i,j,k+1)*maskW(i,j,k)
        enddo
       enddo
      enddo
 end subroutine adv_flux_w_2nd







subroutine adv_flux_u_4th(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of zonal momentum 4th order
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,js,je,ip2,im1,jp2,jm1,kp2,km1
      real*8,parameter  :: a2nd = 1.0,     b2nd = 0.0
      real*8,parameter  :: a4th = 7.0/6.0, b4th = -1.0/6.0
      real*8 :: mask,totvel

      js=max(2,js_pe); je=min(je_pe,ny-1)

      do j=js,je
       do k=2,nz-1
        do i=1,nx-1
         ip2=i+2
         if (ip2>nx.and..not.enable_cyclic_x) ip2=nx
         if (ip2>nx.and.     enable_cyclic_x) ip2=3
         im1=i-1
         if (im1<1.and..not. enable_cyclic_x) im1=1
         if (im1<1.and.      enable_cyclic_x) im1=nx-2
         mask = maskU(im1,j,k)*maskU(ip2,j,k)
         totvel = (u(i+1,j,k,tau)*maskU(i+1,j,k) +u(i,j,k,tau)*maskU(i,j,k))/2.0
         adv_fe(i,j,k) = 0.5*totvel*( &
             (a2nd*(1.0-mask) + a4th*mask)*(u(i,  j,k,tau) +  u(i+1,j,k,tau))+ &
             (b2nd*(1.0-mask) + b4th*mask)*(u(im1,j,k,tau) +  u(ip2,j,k,tau)))
        enddo
       enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)

      do j=js,je
       do k=2,nz-1
        do i=2,nx-1
         jp2=j+2
         if (jp2>ny.and..not.enable_cyclic_y) jp2=ny
         if (jp2>ny.and.     enable_cyclic_y) jp2=3
         jm1=j-1
         if (jm1<1.and..not. enable_cyclic_y) jm1=1
         if (jm1<1.and.      enable_cyclic_y) jm1=ny-2
         mask = maskU(i,jm1,k)*maskU(i,jp2,k)
         totvel = (v(i+1,j,k,tau)*maskV(i+1,j,k)      +v(i,j,k,tau)*maskV(i,j,k))/2.0
         adv_fn(i,j,k) = 0.5*totvel*(  &
             (a2nd*(1.0-mask) + a4th*mask)*(u(i,  j,k,tau) +    u(i,j+1,k,tau))+  &
             (b2nd*(1.0-mask) + b4th*mask)*(u(i,jm1,k,tau) +    u(i,jp2,k,tau)))
        enddo
       enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)
 
      do j=js,je
       do k=1,nz-1
        do i=2,nx-1
         kp2=min(k+2,nz)
         km1=max(1,k-1)
         mask = maskU(i,j,km1)*maskU(i,j,kp2)
         totvel = (w(i+1,j,k,tau)*maskW(i+1,j,k)  +w(i,j,k,tau)*maskW(i,j,k))/2.0
         adv_ft(i,j,k) = 0.5*totvel*(  &
               (a2nd*(1.0-mask) + a4th*mask)*(u(i,j,  k,tau) +  u(i,j,k+1,tau))+  &
               (b2nd*(1.0-mask) + b4th*mask)*(u(i,j,km1,tau) +  u(i,j,kp2,tau)))
        enddo
       enddo
      enddo
end subroutine adv_flux_u_4th



subroutine adv_flux_v_4th(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of meridional momentum 4th order
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,js,je,ip2,im1,jp2,jm1,kp2,km1
      real*8,parameter  :: a2nd = 1.0,     b2nd = 0.0
      real*8,parameter  :: a4th = 7.0/6.0, b4th = -1.0/6.0
      real*8 :: mask,totvel

      js=max(2,js_pe); je=min(je_pe,ny-1)

      do j=js,je
       do k=2,nz-1
        do i=1,nx-1
         ip2=i+2
         if (ip2>nx.and..not.enable_cyclic_x) ip2=nx
         if (ip2>nx.and.     enable_cyclic_x) ip2=3
         im1=i-1
         if (im1<1.and..not. enable_cyclic_x) im1=1
         if (im1<1.and.      enable_cyclic_x) im1=nx-2
         mask = maskV(im1,j,k)*maskV(ip2,j,k)
         totvel = (u(i,j+1,k,tau)*maskU(i,j+1,k)  +u(i,j,k,tau)*maskU(i,j,k))/2.0
         adv_fe(i,j,k) = 0.5*totvel*(  &
             (a2nd*(1.0-mask) + a4th*mask)*(v(i,  j,k,tau) + v(i+1,j,k,tau))+  &
             (b2nd*(1.0-mask) + b4th*mask)*(v(im1,j,k,tau) + v(ip2,j,k,tau)))
        enddo
       enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)

      do j=js,je
       do k=2,nz-1
        do i=2,nx-1
         jp2=j+2
         if (jp2>ny.and..not.enable_cyclic_y) jp2=ny
         if (jp2>ny.and.     enable_cyclic_y) jp2=3
         jm1=j-1
         if (jm1<1.and..not. enable_cyclic_y) jm1=1
         if (jm1<1.and.      enable_cyclic_y) jm1=ny-2
         mask = maskV(i,jm1,k)*maskV(i,jp2,k)
         totvel = (v(i,j+1,k,tau)*maskV(i,j+1,k) +v(i,j,k,tau)*maskV(i,j,k))/2.0
         adv_fn(i,j,k) = 0.5*totvel*(   &
             (a2nd*(1.0-mask) + a4th*mask)*(v(i,  j,k,tau) +  v(i,j+1,k,tau))+   &
             (b2nd*(1.0-mask) + b4th*mask)*(v(i,jm1,k,tau) +  v(i,jp2,k,tau)))
        enddo
       enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)
 
      do j=js,je
       do k=1,nz-1
        do i=2,nx-1
         kp2=min(k+2,nz)
         km1=max(1,k-1)
         mask = maskV(i,j,km1)*maskV(i,j,kp2)
         totvel = (w(i,j+1,k,tau)*maskW(i,j+1,k) +w(i,j,k,tau)*maskW(i,j,k))/2.0
         adv_ft(i,j,k) = 0.5*totvel*(   &
               (a2nd*(1.0-mask) + a4th*mask)*(v(i,j,  k,tau) + v(i,j,k+1,tau))+   &
               (b2nd*(1.0-mask) + b4th*mask)*(v(i,j,km1,tau) + v(i,j,kp2,tau)))
        enddo
       enddo
      enddo
end subroutine adv_flux_v_4th




subroutine adv_flux_w_4th(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of vertical momentum 4th order
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,js,je,ip2,im1,jp2,jm1,kp2,km1
      real*8,parameter  :: a2nd = 1.0,     b2nd = 0.0
      real*8,parameter  :: a4th = 7.0/6.0, b4th = -1.0/6.0
      real*8 :: mask,totvel

      js=max(2,js_pe); je=min(je_pe,ny-1)

      do j=js,je
       do k=2,nz-1
        do i=1,nx-1
         ip2=i+2
         if (ip2>nx.and..not.enable_cyclic_x) ip2=nx
         if (ip2>nx.and.     enable_cyclic_x) ip2=3
         im1=i-1
         if (im1<1.and..not. enable_cyclic_x) im1=1
         if (im1<1.and.      enable_cyclic_x) im1=nx-2
         mask = maskW(im1,j,k)*maskW(ip2,j,k)
         totvel = (u(i,j,k+1,tau)*maskU(i,j,k+1) +u(i,j,k,tau)*maskU(i,j,k))/2.0
         adv_fe(i,j,k) = 0.5*totvel*(  &
             (a2nd*(1.0-mask) + a4th*mask)*(w(i,  j,k,tau) +   w(i+1,j,k,tau))+  &
             (b2nd*(1.0-mask) + b4th*mask)*(w(im1,j,k,tau) +   w(ip2,j,k,tau)))
        enddo
       enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)

      do j=js,je
       do k=2,nz-1
        do i=2,nx-1
         jp2=j+2
         if (jp2>ny.and..not.enable_cyclic_y) jp2=ny
         if (jp2>ny.and.     enable_cyclic_y) jp2=3
         jm1=j-1
         if (jm1<1.and..not. enable_cyclic_y) jm1=1
         if (jm1<1.and.      enable_cyclic_y) jm1=ny-2
         mask = maskW(i,jm1,k)*maskW(i,jp2,k)
         totvel = (v(i,j,k+1,tau)*maskV(i,j,k+1) +v(i,j,k,tau)*maskV(i,j,k))/2.0
         adv_fn(i,j,k) = 0.5*totvel*(  &
             (a2nd*(1.0-mask) + a4th*mask)*(w(i,  j,k,tau) +  w(i,j+1,k,tau))+  &
             (b2nd*(1.0-mask) + b4th*mask)*(w(i,jm1,k,tau) +  w(i,jp2,k,tau)))
        enddo
       enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)
 
      do j=js,je
       do k=1,nz-1
        do i=2,nx-1
         kp2=min(k+2,nz)
         km1=max(1,k-1)
         mask = maskW(i,j,km1)*maskW(i,j,kp2)
         totvel = (w(i,j,k+1,tau)*maskW(i,j,k+1) +w(i,j,k,tau)*maskW(i,j,k))/2.0
         adv_ft(i,j,k) = 0.5*totvel*(  &
               (a2nd*(1.0-mask) + a4th*mask)*(w(i,j,  k,tau) +  w(i,j,k+1,tau))+  &
               (b2nd*(1.0-mask) + b4th*mask)*(w(i,j,km1,tau) +  w(i,j,kp2,tau)))
        enddo
       enddo
      enddo
end subroutine adv_flux_w_4th




subroutine adv_flux_u_quicker(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of zonal momentum,   3th order upwind
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,ip2,jp2,kp2,im1,jm1,km1,js,je
      real*8 :: totvel,upos,uneg,eastmsk,westmsk
      js=max(2,js_pe); je = min(je_pe,ny-1)
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         ip2=i+2
         if (ip2>nx.and..not.enable_cyclic_x) ip2=nx
         if (ip2>nx.and.     enable_cyclic_x) ip2=3
         im1=i-1
         if (im1<1.and..not. enable_cyclic_x) im1=1
         if (im1<1.and.      enable_cyclic_x) im1=nx-2

         totvel = 0.5*(u(i+1,j,k,tau)+u(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskU(i,j,k)*maskU(i+1,j,k)
         uneg = .5*(totvel - abs(totvel)) *maskU(i+1,j,k)*maskU(i,j,k)
         eastmsk=maskU(i,j,k)*(1-maskU(im1,j,k))
         westmsk=maskU(i+1,j,k)*(1-maskU(ip2,j,k))
         adv_fe(i,j,k) = 0.5*totvel*(u(i,j,k,tau)+u(i+1,j,k,tau))   &
              - 0.5*upos*(0.25*u(i+1,j,k,taum1)-0.5*u(i,j,k,taum1)   &
                     +0.25*(u(im1,j,k,taum1)*(1-eastmsk) +u(i,j,k,taum1)*eastmsk))   &
              - 0.5*uneg*(0.25*(u(ip2,j,k,taum1)*(1-westmsk)+   &
                u(i+1,j,k,taum1)*westmsk)-0.5*u(i+1,j,k,taum1) +0.25*u(i,j,k,taum1))
          enddo
        enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)

      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         jp2=j+2
         if (jp2>ny.and..not.enable_cyclic_y) jp2=ny
         if (jp2>ny.and.     enable_cyclic_y) jp2=3
         jm1=j-1
         if (jm1<1.and..not. enable_cyclic_y) jm1=1
         if (jm1<1.and.      enable_cyclic_y) jm1=ny-2

         totvel = 0.5*(v(i+1,j,k,tau)+v(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskU(i,j,k)*maskU(i,j+1,k)
         uneg = .5*(totvel - abs(totvel)) *maskU(i,j+1,k)*maskU(i,j,k)
         eastmsk=maskU(i,j,k)*(1-maskU(i,jm1,k))
         westmsk=maskU(i,j+1,k)*(1-maskU(i,jp2,k))
         adv_fn(i,j,k) = 0.5*totvel*(u(i,j,k,tau)+u(i,j+1,k,tau))   &
              - 0.5*upos*(0.25*u(i,j+1,k,taum1)-0.5*u(i,j,k,taum1)   &
                     +0.25*(u(i,jm1,k,taum1)*(1-eastmsk) +u(i,j,k,taum1)*eastmsk))   &
              - 0.5*uneg*(0.25*(u(i,jp2,k,taum1)*(1-westmsk)+   &
                u(i,j+1,k,taum1)*westmsk)-0.5*u(i,j+1,k,taum1) +0.25*u(i,j,k,taum1))
          enddo
        enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)

      do k=1,nz-1
       do j=js,je
        do i=2,nx-1
         kp2=min(k+2,nz)
         km1=max(1,k-1)
         totvel = 0.5*(w(i+1,j,k,tau)+w(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskU(i,j,k)*maskU(i,j,k+1)
         uneg = .5*(totvel - abs(totvel)) *maskU(i,j,k+1)*maskU(i,j,k)
         eastmsk=maskU(i,j,k)*(1-maskU(i,j,km1))
         westmsk=maskU(i,j,k+1)*(1-maskU(i,j,kp2))
         adv_ft(i,j,k) = 0.5*totvel*(u(i,j,k,tau)+u(i,j,k+1,tau))   &
              - 0.5*upos*(0.25*u(i,j,k+1,taum1)-0.5*u(i,j,k,taum1)   &
                     +0.25*(u(i,j,km1,taum1)*(1-eastmsk) +u(i,j,k,taum1)*eastmsk))   &
              - 0.5*uneg*(0.25*(u(i,j,kp2,taum1)*(1-westmsk)+   &
                u(i,j,k+1,taum1)*westmsk)-0.5*u(i,j,k+1,taum1) +0.25*u(i,j,k,taum1))
          enddo
        enddo
      enddo
end subroutine adv_flux_u_quicker





subroutine adv_flux_v_quicker(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of meridional momentum,   3th order upwind
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,ip2,jp2,kp2,im1,jm1,km1,js,je
      real*8 :: totvel,upos,uneg,eastmsk,westmsk
      js=max(2,js_pe); je = min(je_pe,ny-1)
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         ip2=i+2
         if (ip2>nx.and..not.enable_cyclic_x) ip2=nx
         if (ip2>nx.and.     enable_cyclic_x) ip2=3
         im1=i-1
         if (im1<1.and..not. enable_cyclic_x) im1=1
         if (im1<1.and.      enable_cyclic_x) im1=nx-2

         totvel = 0.5*(u(i,j+1,k,tau)+u(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskV(i,j,k)*maskV(i+1,j,k)
         uneg = .5*(totvel - abs(totvel)) *maskV(i+1,j,k)*maskV(i,j,k)
         eastmsk=maskV(i,j,k)*(1-maskV(im1,j,k))
         westmsk=maskV(i+1,j,k)*(1-maskV(ip2,j,k))
         adv_fe(i,j,k) = 0.5*totvel*(v(i,j,k,tau)+v(i+1,j,k,tau))  &
              - 0.5*upos*(0.25*v(i+1,j,k,taum1)-0.5*v(i,j,k,taum1)  &
                     +0.25*(v(im1,j,k,taum1)*(1-eastmsk) +v(i,j,k,taum1)*eastmsk))  &
              - 0.5*uneg*(0.25*(v(ip2,j,k,taum1)*(1-westmsk)+  &
                v(i+1,j,k,taum1)*westmsk)-0.5*v(i+1,j,k,taum1) +0.25*v(i,j,k,taum1))
          enddo
        enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)

      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         jp2=j+2
         if (jp2>ny.and..not.enable_cyclic_y) jp2=ny
         if (jp2>ny.and.     enable_cyclic_y) jp2=3
         jm1=j-1
         if (jm1<1.and..not. enable_cyclic_y) jm1=1
         if (jm1<1.and.      enable_cyclic_y) jm1=ny-2

         totvel = 0.5*(v(i,j+1,k,tau)+v(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskV(i,j,k)*maskV(i,j+1,k)
         uneg = .5*(totvel - abs(totvel)) *maskV(i,j+1,k)*maskV(i,j,k)
         eastmsk=maskV(i,j,k)*(1-maskV(i,jm1,k))
         westmsk=maskV(i,j+1,k)*(1-maskV(i,jp2,k))
         adv_fn(i,j,k) = 0.5*totvel*(v(i,j,k,tau)+v(i,j+1,k,tau))  &
              - 0.5*upos*(0.25*v(i,j+1,k,taum1)-0.5*v(i,j,k,taum1)  &
                     +0.25*(v(i,jm1,k,taum1)*(1-eastmsk) +v(i,j,k,taum1)*eastmsk))  &
              - 0.5*uneg*(0.25*(v(i,jp2,k,taum1)*(1-westmsk)+  &
                v(i,j+1,k,taum1)*westmsk)-0.5*v(i,j+1,k,taum1) +0.25*v(i,j,k,taum1))
          enddo
        enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)

      do k=1,nz-1
       do j=js,je
        do i=2,nx-1
         kp2=min(k+2,nz)
         km1=max(1,k-1)
         totvel = 0.5*(w(i,j+1,k,tau)+w(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskV(i,j,k)*maskV(i,j,k+1)
         uneg = .5*(totvel - abs(totvel)) *maskV(i,j,k+1)*maskV(i,j,k)
         eastmsk=maskV(i,j,k)*(1-maskV(i,j,km1))
         westmsk=maskV(i,j,k+1)*(1-maskV(i,j,kp2))
         adv_ft(i,j,k) = 0.5*totvel*(v(i,j,k,tau)+v(i,j,k+1,tau))  &
              - 0.5*upos*(0.25*v(i,j,k+1,taum1)-0.5*v(i,j,k,taum1)  &
                     +0.25*(v(i,j,km1,taum1)*(1-eastmsk) +v(i,j,k,taum1)*eastmsk))  &
              - 0.5*uneg*(0.25*(v(i,j,kp2,taum1)*(1-westmsk)+  &
                v(i,j,k+1,taum1)*westmsk)-0.5*v(i,j,k+1,taum1) +0.25*v(i,j,k,taum1))
          enddo
        enddo
      enddo
end subroutine adv_flux_v_quicker



subroutine adv_flux_w_quicker(nx_,ny_,nz_,adv_fe,adv_fn,adv_ft)
!=======================================================================
!       advection of vertical momentum,   3th order upwind
!       fluxes are stored in adv_fe,adv_fn and adv_ft
!=======================================================================
      use pyOM_module   
      implicit none
      integer :: nx_,ny_,nz_
      real*8 :: adv_fe(nx_,ny_,nz_), adv_ft(nx_,ny_,nz_), adv_fn(nx_,ny_,nz_) 
      integer :: i,j,k,ip2,jp2,kp2,im1,jm1,km1,js,je
      real*8 :: totvel,upos,uneg,eastmsk,westmsk
      js=max(2,js_pe); je = min(je_pe,ny-1)
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         ip2=i+2
         if (ip2>nx.and..not.enable_cyclic_x) ip2=nx
         if (ip2>nx.and.     enable_cyclic_x) ip2=3
         im1=i-1
         if (im1<1.and..not. enable_cyclic_x) im1=1
         if (im1<1.and.      enable_cyclic_x) im1=nx-2

         totvel = 0.5*(u(i,j,k+1,tau)+u(i,j,k,tau))
         upos = .5*(totvel + abs(totvel)) *maskW(i,j,k)*maskW(i+1,j,k)
         uneg = .5*(totvel - abs(totvel)) *maskW(i+1,j,k)*maskW(i,j,k)
         eastmsk=maskW(i,j,k)*(1-maskW(im1,j,k))
         westmsk=maskW(i+1,j,k)*(1-maskW(ip2,j,k))
         adv_fe(i,j,k) = 0.5*totvel*(w(i,j,k,tau)+w(i+1,j,k,tau))  &
              - 0.5*upos*(0.25*w(i+1,j,k,taum1)-0.5*w(i,j,k,taum1)  &
                     +0.25*(w(im1,j,k,taum1)*(1-eastmsk) +w(i,j,k,taum1)*eastmsk))  &
              - 0.5*uneg*(0.25*(w(ip2,j,k,taum1)*(1-westmsk)+  &
                w(i+1,j,k,taum1)*westmsk)-0.5*w(i+1,j,k,taum1) +0.25*w(i,j,k,taum1))
          enddo
        enddo
      enddo
      call setcyclic3D(nx_,ny_,nz_,adv_fe)

      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         jp2=j+2
         if (jp2>ny.and..not.enable_cyclic_y) jp2=ny
         if (jp2>ny.and.     enable_cyclic_y) jp2=3
         jm1=j-1
         if (jm1<1.and..not. enable_cyclic_y) jm1=1
         if (jm1<1.and.      enable_cyclic_y) jm1=ny-2

         totvel = 0.5*(v(i,j,k+1,tau)+v(i,j,k,tau))
         upos = .5*(totvel + abs(totvel))   *maskW(i,j,k)*maskW(i,j+1,k)
         uneg = .5*(totvel - abs(totvel))   *maskW(i,j+1,k)*maskW(i,j,k)
         eastmsk=maskW(i,j,k)*(1-maskW(i,jm1,k))
         westmsk=maskW(i,j+1,k)*(1-maskW(i,jp2,k))
         adv_fn(i,j,k) =  0.5*totvel*(w(i,j,k,tau)+w(i,j+1,k,tau))  &
              - 0.5*upos*(0.25*w(i,j+1,k,taum1)-0.5*w(i,j,k,taum1)  &
                     +0.25*(w(i,jm1,k,taum1)*(1-eastmsk)     +w(i,j,k,taum1)*eastmsk))  &
              - 0.5*uneg*(0.25*(w(i,jp2,k,taum1)*(1-westmsk)+  &
                w(i,j+1,k,taum1)*westmsk)-0.5*w(i,j+1,k,taum1)  +0.25*w(i,j,k,taum1))
          enddo
        enddo
      enddo
      call border_exchg3D(nx_,ny_,nz_,adv_fn,1); call setcyclic3D(nx_,ny_,nz_,adv_fn)

      do k=1,nz-1
       do j=js,je
        do i=2,nx-1
         kp2=min(k+2,nz)
         km1=max(1,k-1)
         totvel = 0.5*(w(i,j,k+1,tau)+w(i,j,k,tau))
         upos = .5*(totvel + abs(totvel))    *maskW(i,j,k)*maskW(i,j,k+1)
         uneg = .5*(totvel - abs(totvel))    *maskW(i,j,k+1)*maskW(i,j,k)
         eastmsk=maskW(i,j,k)*(1-maskW(i,j,km1))
         westmsk=maskW(i,j,k+1)*(1-maskW(i,j,kp2))
         adv_ft(i,j,k) = 0.5*totvel*(w(i,j,k,tau)+w(i,j,k+1,tau))   &
              - 0.5*upos*(0.25*w(i,j,k+1,taum1)-0.5*w(i,j,k,taum1)   &
                     +0.25*(w(i,j,km1,taum1)*(1-eastmsk)    +w(i,j,k,taum1)*eastmsk))   &
              - 0.5*uneg*(0.25*(w(i,j,kp2,taum1)*(1-westmsk)+   &
                w(i,j,k+1,taum1)*westmsk)-0.5*w(i,j,k+1,taum1) +0.25*w(i,j,k,taum1))
          enddo
        enddo
      enddo
end subroutine adv_flux_w_quicker



