

  subroutine background_state_buoyancy(ierr)
!=======================================================================
!  add effect of a prescribed background stratification in buoyancy
!  to buoyancy budget. Also the effect of background zonal and meridional
!  velocity (but not both).
!
!    the case 
!    b=b'(x,y,z,t) + B(z)
!    p=p'(x,y,t,z)+P(z) with P_z = -B,  P(z=0)=0
!    u=u'(x,y,z,t)+U(z)
!
!    b'_t = -(u'b')_x - (vb')_y - (wb')_z + diffusion(b')+convection(b+B)
!             -(wB)_z-(u'B)_x-(vB)_y-(Ub')_x
!    
!    u'_t =-p_x -(u'u')_x-(vu')_y-(wu')_z+friction(u')  -(Uu')_x  -(u'U)_x-(vU)_y-(wU)_z
!    v'_t =-p_y -(u'v)_x-(vv)_y-(wv)_z+friction(v)  -(Uv)_x
!    w'_t =-p_z -(u'w)_x-(vw)_y-(ww)_z+friction(w)  -(Uw)_x - b 
!
!   with Coriolis force: specify U(z) and B=f y U_z with U(0)=0
!   thus best to set U=U_0 z/h  and B=f y U_0/h 
!
!    P_y = -fU(z)   ->  P(y,z)= - f y U(z) + f(z),  note that U(0)=0, such that P(0)=0
!    P_z = -B, ->  B= f y U_z + f'Q
!
!   numerically consistent:  B_{j+1}=B_{j} + dx*U_z (coriolis_t(j  )+coriolis_t(j+1))/2.0
!
!    U(z), P(y,z), B(y,z)
!
!    b'_t = -(u'b')_x - (vb')_y - (wb')_z + diffusion(b')+convection(b+B)
!             -(wB)_z-(u'B)_x-(vB)_y-(Ub')_x
!    u'_t =fv  -p_x -(u'u')_x-(vu')_y-(wu')_z  -(Uu')_x  -(u'U)_x-(vU)_y-(wU)_z
!    v'_t =-fu' -p_y -(u'v)_x-(vv)_y-(wv)_z  -(Uv)_x 
!
!    non-hydrostatic and U(z), P(y,z) and B(y,z):
!    b'_t = -(u'b')_x - (vb')_y - (wb')_z + diffusion(b')+convection(b+B)
!             -(wB)_z-(u'B)_x-(vB)_y-(Ub')_x
!    u'_t =fv -f_h w -p_x -(u'u')_x-(vu')_y-(wu')_z  -(Uu')_x -(u'U)_x-(vU)_y-(wU)_z
!    v'_t =-fu'      -p_y -(u'v)_x-(vv)_y-(wv)_z     -(Uv)_x 
!    w'_t =f_h u'    -p_z -(u'w)_x-(vw)_y-(ww)_z     -(Uw)_x  -b + f_h U 
!                                  (the last term is not yet implemented!!!!)
!
!=======================================================================
      use pyOM_module   
      implicit none
      integer, intent(out) :: ierr
      integer :: i,j,k,js,je
      real*8 :: adv_fe(nx,ny,nz), adv_ft(nx,ny,nz), adv_fn(nx,ny,nz)
      real*8 :: uback(nx,ny,nz),vback(nx,ny,nz),wback(nx,ny,nz)
      ierr = 0
      js=max(2,js_pe); je = min(je_pe,ny-1)
!---------------------------------------------------------------------------------
!     background stratification  
!---------------------------------------------------------------------------------
      adv_fe(:,js_pe:je_pe,:)=0; adv_fn(:,js_pe:je_pe,:)=0; adv_ft(:,js_pe:je_pe,:)=0
      call adv_flux(nx,ny,nz,adv_fe,adv_fn,adv_ft,back)
      call border_exchg3D(nx,ny,nz,adv_fn,1)
      call setcyclic3D(nx,ny,nz,adv_fe); 
      call setcyclic3D(nx,ny,nz,adv_fn)
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         b(i,j,k,taup1)=b(i,j,k,taup1)+maskT(i,j,k)*c2dt*(  &
        -(adv_fe(i,j,k)-adv_fe(i-1,j,k))/dx &
        -(adv_fn(i,j,k)-adv_fn(i,j-1,k))/dx &
        -(adv_ft(i,j,k)-adv_ft(i,j,k-1))/dz )
        enddo
       enddo
      enddo

   if (enable_back_zonal_flow) then  
!---------------------------------------------------------------------------------
!     effect of zonal background velocity on density
!---------------------------------------------------------------------------------
      do j=js_pe,je_pe
       uback(:,j,:)=u(:,j,:,tau);
       vback(:,j,:)=v(:,j,:,tau);
       wback(:,j,:)=w(:,j,:,tau);
       u(:,j,:,tau)=u0(:,j,:); v(:,j,:,tau)=0.; w(:,j,:,tau)=0.
      enddo
      adv_fe(:,js_pe:je_pe,:)=0; adv_fn(:,js_pe:je_pe,:)=0; adv_ft(:,js_pe:je_pe,:)=0
      call adv_flux(nx,ny,nz,adv_fe,adv_fn,adv_ft,b)
      u(:,js_pe:je_pe,:,tau)=uback(:,js_pe:je_pe,:)
      v(:,js_pe:je_pe,:,tau)=vback(:,js_pe:je_pe,:)
      w(:,js_pe:je_pe,:,tau)=wback(:,js_pe:je_pe,:)
      call border_exchg3D(nx,ny,nz,adv_fn,1)
      call setcyclic3D(nx,ny,nz,adv_fe); 
      call setcyclic3D(nx,ny,nz,adv_fn)
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         b(i,j,k,taup1)=b(i,j,k,taup1)+maskT(i,j,k)*c2dt*(   &
        -(adv_fe(i,j,k)-adv_fe(i-1,j,k))/dx  &
        -(adv_fn(i,j,k)-adv_fn(i,j-1,k))/dx  &
        -(adv_ft(i,j,k)-adv_ft(i,j,k-1))/dz )
        enddo
       enddo
      enddo
   endif

   if (enable_back_meridional_flow) then  
!---------------------------------------------------------------------------------
!     effect of meridional background velocity on density
!---------------------------------------------------------------------------------
      do j=js_pe,je_pe
       uback(:,j,:)=u(:,j,:,tau);
       vback(:,j,:)=v(:,j,:,tau);
       wback(:,j,:)=w(:,j,:,tau);
       v(:,j,:,tau)=u0(:,j,:); u(:,j,:,tau)=0.;w(:,j,:,tau)=0.
      enddo
      adv_fe(:,js_pe:je_pe,:)=0; adv_fn(:,js_pe:je_pe,:)=0; adv_ft(:,js_pe:je_pe,:)=0
      call adv_flux(nx,ny,nz,adv_fe,adv_fn,adv_ft,b)
      u(:,js_pe:je_pe,:,tau)=uback(:,js_pe:je_pe,:)
      v(:,js_pe:je_pe,:,tau)=vback(:,js_pe:je_pe,:)
      w(:,js_pe:je_pe,:,tau)=wback(:,js_pe:je_pe,:)
      call border_exchg3D(nx,ny,nz,adv_fn,1)
      call setcyclic3D(nx,ny,nz,adv_fe); 
      call setcyclic3D(nx,ny,nz,adv_fn)
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         b(i,j,k,taup1)=b(i,j,k,taup1)+maskT(i,j,k)*c2dt*(   &
        -(adv_fe(i,j,k)-adv_fe(i-1,j,k))/dx  &
        -(adv_fn(i,j,k)-adv_fn(i,j-1,k))/dx  &
        -(adv_ft(i,j,k)-adv_ft(i,j,k-1))/dz )
        enddo
       enddo
      enddo
   endif

!---------------------------------------------------------------------------------
!      Boundary exchange 
!---------------------------------------------------------------------------------
!      call border_exchg3D(nx,ny,nz,b(:,:,:,taup1),2);
!      call setcyclic3D(nx,ny,nz,b(:,:,:,taup1) )
  end subroutine background_state_buoyancy



  subroutine background_state_momentum(ierr)
!-----------------------------------------------------------------------
!    apply effect of background velocity on momentum
!-----------------------------------------------------------------------
      use pyOM_module   
      implicit none
      integer, intent(out) :: ierr
      integer :: i,j,k,js,je
      real*8 :: adv_fe(nx,ny,nz), adv_ft(nx,ny,nz), adv_fn(nx,ny,nz)
      ierr = 0
      js=max(2,js_pe); je = min(je_pe,ny-1)

!-----------------------------------------------------------------------
!    zonal momentum equation
!-----------------------------------------------------------------------
   if (enable_back_zonal_flow) then  
      adv_fe(:,js_pe:je_pe,:)=0.0; adv_fn(:,js_pe:je_pe,:)=0.0; adv_ft(:,js_pe:je_pe,:)=0.0; 
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         adv_fe(i,j,k)=2* 0.5*( u0(i  ,j,k) + u0(i+1,j,k) )*   &
              (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*( u0(i,j,k) + u0(i,j+1,k) )*  &
            (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*(u0(i,j,k)+u0(i,j,k+1))*  &
                  (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
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         fu(i,j,k)= fu(i,j,k)+maskU(i,j,k)*(   &
            -(adv_fe(i,j,k) - adv_fe(i-1,j,k) )/dx   &
            -(adv_fn(i,j,k) - adv_fn(i,j-1,k) )/dx   &
            -(adv_ft(i,j,k) - adv_ft(i,j,k-1) )/dz  )
        enddo
       enddo
      enddo
   endif

   if (enable_back_meridional_flow) then  
      adv_fn(:,js_pe:je_pe,:)=0.0; 
      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) )*   &
         (u0(i,j,k)+u0(i+1,j,k))   *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=2,nz-1
       do j=js,je
        do i=2,nx-1
         fu(i,j,k)= fu(i,j,k)+maskU(i,j,k)*(-(adv_fn(i,j,k) - adv_fn(i,j-1,k) )/dx )
        enddo
       enddo
      enddo
    endif

!-----------------------------------------------------------------------
!    meridional momentum equation
!-----------------------------------------------------------------------
   if (enable_back_zonal_flow) then  
      adv_fe(:,js_pe:je_pe,:)=0.0; 
      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) )*  &
          (u0(i,j,k)+u0(i,j+1,k))       *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
         fv(i,j,k)= fv(i,j,k)+maskV(i,j,k)*( -(adv_fe(i,j,k) - adv_fe(i-1,j,k) )/dx)
        enddo
       enddo
      enddo
   endif

   if (enable_back_meridional_flow) then  
      adv_fe(:,js_pe:je_pe,:)=0.0; adv_fn(:,js_pe:je_pe,:)=0.0; adv_ft(:,js_pe:je_pe,:)=0.0; 
      do k=2,nz-1
       do j=js,je
        do i=1,nx-1
         adv_fe(i,j,k)=0.5*( u0(i  ,j,k) + u0(i+1,j,k) )*  &
          (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)=2* 0.5*( u0(i,j,k) + u0(i,j+1,k) )*  &
         (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*( u0(i,j,k) + u0(i,j,k+1) )*  &
         (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
      do k=2,nz-1
       do j=js,je
        do i=2,nx-1
         fv(i,j,k)= fv(i,j,k)+maskV(i,j,k)*(    &
          -(adv_fe(i,j,k) - adv_fe(i-1,j,k) )/dx    &
          -(adv_fn(i,j,k) - adv_fn(i,j-1,k) )/dx    &
          -(adv_ft(i,j,k) - adv_ft(i,j,k-1) )/dz  )
        enddo
       enddo
      enddo
    endif

   if (.not. enable_hydrostatic) then
!-----------------------------------------------------------------------
!    vertical momentum equation
!-----------------------------------------------------------------------

   if (enable_back_zonal_flow) then  
       adv_fe(:,js_pe:je_pe,:)=0.0
       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) )*   &
               (u0(i,j,k)+u0(i,j,k+1))      *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
          fw(i,j,k)= fw(i,j,k)+maskW(i,j,k)*( -(adv_fe(i,j,k) - adv_fe(i-1,j,k) )/dx)
         enddo
        enddo
       enddo
   endif
   if (enable_back_meridional_flow) then  
      adv_fn(:,js_pe:je_pe,:)=0.0; 
      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) )*   &
           (u0(i,j,k)+u0(i,j,k+1))     *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=2,nz-1
       do j=js,je
         do i=2,nx-1
          fw(i,j,k)= fw(i,j,k)+maskW(i,j,k)*(-(adv_fn(i,j,k) - adv_fn(i,j-1,k) )/dx)
        enddo
       enddo
      enddo
   endif
   endif


!   if (enable_back_meridional_flow .or. enable_back_zonal_flow) then  
!      call border_exchg3D(nx,ny,nz,fu,1); call setcyclic3D(nx,ny,nz,fu)
!      call border_exchg3D(nx,ny,nz,fv,1); call setcyclic3D(nx,ny,nz,fv)
!      if (.not. enable_hydrostatic) then
!       call border_exchg3D(nx,ny,nz,fw,1); call setcyclic3D(nx,ny,nz,fw)
!      endif
!   endif

  end subroutine background_state_momentum

