!-------------------------------------------------------------------------------

!                      Code_Saturne version 3.1.0-alpha
!                      --------------------------
! This file is part of Code_Saturne, a general-purpose CFD tool.
!
! Copyright (C) 1998-2012 EDF S.A.
!
! This program is free software; you can redistribute it and/or modify it under
! the terms of the GNU General Public License as published by the Free Software
! Foundation; either version 2 of the License, or (at your option) any later
! version.
!
! This program is distributed in the hope that it will be useful, but WITHOUT
! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
! FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
! details.
!
! You should have received a copy of the GNU General Public License along with
! this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
! Street, Fifth Floor, Boston, MA 02110-1301, USA.

!-------------------------------------------------------------------------------

subroutine cs_user_extra_operations &
!==================================

 ( nvar   , nscal  ,                                              &
   nbpmax , nvp    , nvep   , nivep  , ntersl , nvlsta , nvisbr , &
   itepa  ,                                                       &
   dt     , rtpa   , rtp    , propce , propfa , propfb ,          &
   ettp   , ettpa  , tepa   , statis , stativ , tslagr , parbor )

!===============================================================================
! Purpose:
! -------

!    User subroutine.

!    Called at end of each time step, very general purpose
!    (i.e. anything that does not have another dedicated user subroutine)

!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name             !type!mode ! role                                           !
!__________________!____!_____!________________________________________________!
! nvar             ! i  ! <-- ! total number of variables                      !
! nscal            ! i  ! <-- ! total number of scalars                        !
! nbpmax           ! i  ! <-- ! max. number of particles allowed               !
! nvp              ! i  ! <-- ! number of particle-defined variables           !
! nvep             ! i  ! <-- ! number of real particle properties             !
! nivep            ! i  ! <-- ! number of integer particle properties          !
! ntersl           ! i  ! <-- ! number of return coupling source terms         !
! nvlsta           ! i  ! <-- ! number of Lagrangian statistical variables     !
! nvisbr           ! i  ! <-- ! number of boundary statistics                  !
! itepa            ! ia ! <-- ! integer particle attributes                    !
!  (nbpmax, nivep) !    !     !   (containing cell, ...)                       !
! dt(ncelet)       ! ra ! <-- ! time step (per cell)                           !
! rtp, rtpa        ! ra ! <-- ! calculated variables at cell centers           !
!  (ncelet, *)     !    !     !  (at current and previous time steps)          !
! propce(ncelet, *)! ra ! <-- ! physical properties at cell centers            !
! propfa(nfac, *)  ! ra ! <-- ! physical properties at interior face centers   !
! propfb(nfabor, *)! ra ! <-- ! physical properties at boundary face centers   !
! ettp, ettpa      ! ra ! <-- ! particle-defined variables                     !
!  (nbpmax, nvp)   !    !     !  (at current and previous time steps)          !
! tepa             ! ra ! <-- ! real particle properties                       !
!  (nbpmax, nvep)  !    !     !  (statistical weight, ...                      !
! statis           ! ra ! <-- ! statistic means                                !
!  (ncelet, nvlsta)!    !     !                                                !
! stativ(ncelet,   ! ra ! <-- ! accumulator for variance of volume statisitics !
!        nvlsta -1)!    !     !                                                !
! tslagr           ! ra ! <-- ! Lagrangian return coupling term                !
!  (ncelet, ntersl)!    !     !  on carrier phase                              !
! parbor           ! ra ! <-- ! particle interaction properties                !
!  (nfabor, nvisbr)!    !     !  on boundary faces                             !
!__________________!____!_____!________________________________________________!

!     Type: i (integer), r (real), s (string), a (array), l (logical),
!           and composite types (ex: ra real array)
!     mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================

!===============================================================================
! Module files
!===============================================================================

use paramx
use dimens, only: ndimfb
use pointe
use numvar
use optcal
use cstphy
use cstnum
use entsor
use lagpar
use lagran
use parall
use period
use ppppar
use ppthch
use ppincl
use mesh

use field
!===============================================================================

implicit none

! Arguments

integer          nvar   , nscal
integer          nbpmax , nvp    , nvep  , nivep
integer          ntersl , nvlsta , nvisbr

integer          itepa(nbpmax,nivep)

double precision dt(ncelet), rtp(ncelet,*), rtpa(ncelet,*)
double precision propce(ncelet,*)
double precision propfa(nfac,*), propfb(ndimfb,*)
double precision ettp(nbpmax,nvp) , ettpa(nbpmax,nvp)
double precision tepa(nbpmax,nvep)
double precision statis(ncelet,nvlsta), stativ(ncelet,nvlsta-1)
double precision tslagr(ncelet,ntersl)
double precision parbor(nfabor,nvisbr)


! Local variables

! INSERT_VARIABLE_DEFINITIONS_HERE

!===============================================================================

!===============================================================================
! Initialization
!===============================================================================

! New variables for Nusselt number, velocity and min-max locations output
double precision xmin,xmax,ymin,ymax,xmid_x,xmid_y,xLength,xNum,xrhom,xdelx,xdelz,xfac,xTm
double precision xUmx,xUmx_max,adim_xUmx,xUmx_max_y,xUmy,xUmy_max,adim_xUmy,xUmy_max_x
double precision xTh,xTc,xNu_lw,xgradT

integer iel, iel1, iel2,ifac
integer iflmas, ipcrom, iscal,ivar, ifac1,ifac2

!===============================================================================
! User operations
!===============================================================================
double precision, dimension(:), pointer :: coefap
!,coefbp, cofafp, cofbfp
!double precision, allocatable, dimension(:,:) :: grad

!===============================================================================

  iscal = iscalt         ! temperature scalar number
  ivar = isca(iscal)     ! temperature variable number

  ! Boundary condition pointers for gradients and advection
  call field_get_coefa_s(ivarfl(ivar), coefap)

  ! Physical quantity indices
  ipcrom = ipproc(irom)
  iflmas = ipprof(ifluma(ivar))

  ! Parallel and periodic update for cell values    
  if (irangp.ge.0.or.iperio.eq.1) then
    call synsca(rtp(1,ivar))
    call synsca(propce(1,ipcrom))
  endif

  ! --> Compute the thickness of the domain (in the z direction)
  ifac1 = idebty(isymet)
  ifac2 = min(idebty(isymet)+int((ifinty(isymet)-idebty(isymet))/2)+1,ifinty(isymet))
  xdelz = abs(cdgfbo(3,itrifb(ifac1))-cdgfbo(3,itrifb(ifac2)))

  ! --> Compute the geometric characteristics of the computational domain and the
  !  	temperatures of the hot and cold walls.
  !===============================================================================

  ifac1 = idebty(iparoi)
  ifac2 = ifinty(iparoi)

  xmin = 1.0d+12
  xmax = -1.0d+12
  xTc = 1.0d+12
  xTh = -1.0d+12  
  ymin = 1.0d+12
  ymax = -1.0d+12
  
  do ifac = itrifb(ifac1), itrifb(ifac2) ! cycle through the wall boundary faces

    if (coefap(ifac).gt.0.0d0) then ! Choose the fixed temperature (vertical) walls

    ! Find the X positions of the vertical boundaries and the temperature extremas at those boundaries
      if (cdgfbo(1,ifac).lt.xmin) then
        xmin = cdgfbo(1,ifac)
	xTh = max(xTh,coefap(ifac))
      else if (cdgfbo(1,ifac).gt.xmax) then
	xmax = cdgfbo(1,ifac)
	xTc = min(xTc,coefap(ifac))
      end if	

    else ! Choose the adiabatic (horizontal) walls

    ! Find the Y positions of the horizontal boundaries
      if (cdgfbo(2,ifac).lt.ymin) then
        ymin = cdgfbo(2,ifac)
      else if (cdgfbo(2,ifac).gt.ymax) then
        ymax = cdgfbo(2,ifac)
      end if

    end if

  end do

  xLength = xmax-xmin ! Computational domain length
  xmid_x = (xmin+xmax)*0.5d0 ! Vertical mid-point
  xmid_y = (ymin+ymax)*0.5d0 ! Horizontal mid-point

  !--> Compute the Nusselt number at the left wall 
  !================================================

  xNu_lw = 0.0d0
  do ifac = itrifb(ifac1), itrifb(ifac2)
    iel = ifabor(ifac)
    if (cdgfbo(1,ifac).le.xmin) then ! Choose the left-wall faces
      xdelx = xyzcen(1,iel)-cdgfbo(1,ifac)
      xfac = 1.0d0/((xTh-xTc)*xdelz)
      xgradT = xfac*(rtp(iel,ivar)-coefap(ifac))*surfbn(ifac)/xdelx
      xNu_lw = xNu_lw-xgradT
      end if
  end do

  !--> Compute the Nusselt number and find the maximum velocity in the X
  !    direction at the central vertical plane
  !    (the velocity is adimensionalised for comparison with the reference results)
  !================================================================================

  xNum = 0.0d0
  xUmx_max = -1.0d-12
  xUmx_max_y = -1.0d-12

  do ifac = 1, nfac

    iel1 = ifacel(1,ifac)
    iel2 = ifacel(2,ifac)
		
    if ((xyzcen(1,iel1)-xmid_x)*(xyzcen(1,iel2)-xmid_x) .lt. 0.0d0) then !find mid-face with straddling cells

      !Nusselt number
      !--------------
      ! Compute product (u*T) at the central vertical plane using 
      ! mean values of velocity and temperature
      xrhom = (propce(iel1,ipcrom)+propce(iel2,ipcrom))*0.5d0 ! mean density
      xTm = (rtp(iel1,ivar)+rtp(iel2,ivar))*0.5d0             ! mean temperature
      xUmx = abs(surfac(1,ifac)/surfan(ifac))*propfa(ifac,iflmas)/(surfan(ifac)*xrhom) ! face velocity - x direction

      xdelx = xyzcen(1,iel1)-xyzcen(1,iel2)
      xfac = 1.0d0/((xTh-xTc)*xdelz)

      xNum = xNum+xfac*( &
	(ro0*cp0/visls0(1))*xUmx*(xTm-xTc)*surfan(ifac)-  &
	(rtp(iel1,ivar)-rtp(iel2,ivar))*surfan(ifac)/xdelx )

      !Maximum X velocity and location
      !-------------------------------
!      adim_xUmx = ro0*xUmx*xLength/visls0(1)
      adim_xUmx = ro0*cp0*xUmx*xLength/visls0(1)
      if (abs(adim_xUmx).gt.abs(xUmx_max)) then
        xUmx_max = adim_xUmx
        xUmx_max_y = xyzcen(2,iel1)
      end if

    end if

  enddo
  
  !--> Find the maximum velocity in the Y direction at the central horizontal plane
  !    (the velocity is adimensionalised for comparison with the reference results)
  !================================================================================

  xUmy_max = -1.0d-12
  xUmy_max_x = -1.0d-12

  do ifac = 1, nfac
    iel1 = ifacel(1,ifac)
    iel2 = ifacel(2,ifac)

    if ((xyzcen(2,iel1)-xmid_y)*(xyzcen(2,iel2)-xmid_y) .lt. 0.0d0) then
	
      xrhom = (propce(iel1,ipcrom)+propce(iel2,ipcrom))*0.5d0 ! mean density
      xTm = (rtp(iel1,ivar)+rtp(iel2,ivar))*0.5d0             ! mean temperature
      xUmy = abs(surfac(2,ifac)/surfan(ifac))*propfa(ifac,iflmas)/(surfan(ifac)*xrhom) ! face velocity - y direction

      !Maximum Y velocity and location
      !-------------------------------
      adim_xUmy = ro0*cp0*xUmy*xLength/visls0(1)
      if (abs(adim_xUmy).gt.abs(xUmy_max)) then
        xUmy_max = adim_xUmy
	xUmy_max_x = xyzcen(1,iel1)
      end if
    end if

  enddo

  !--> Output the results to the 'listing' file at each iteration/time step
  !========================================================================
  write(nfecra,1000)ntcabs,xNum,xNu_lw,xUmx_max,xUmx_max_y/xLength, &
		xUmy_max,xUmy_max_x/xLength

!--------
! Formats
!--------

1000 format                                               &
  (/,                                                     &
   3X,'** Heated Cavity Solution **', /,                  &
   3X,'   ----------------------', /,                     &
   '------------------------------------------------',    &
   '-----------------------------------------------', /,  &
   '              Iter   Nu_mid       Nu_lw        ',     &
   'Ux_max       y(Ux_max)    Uy_max       x(Uy_max)', /, &
   'us_extraops: ',i4, 6(1X,e12.4), /,                    &
   '------------------------------------------------',    &
   '-----------------------------------------------',/)


!----
! End
!----


return
end subroutine cs_user_extra_operations
