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

!                      Code_Saturne version 4.0.3
!                      --------------------------
! This file is part of Code_Saturne, a general-purpose CFD tool.
!
! Copyright (C) 1998-2015 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.

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

!===============================================================================
! Function:
! ---------

! Basic example of cs_user_boundary_conditions subroutine.f90
!
!-------------------------------------------------------------------------------

!-------------------------------------------------------------------------------
! Arguments
!______________________________________________________________________________.
!  mode           name          role                                           !
!______________________________________________________________________________!
!> \param[in]     nvar          total number of variables
!> \param[in]     nscal         total number of scalars
!> \param[out]    icodcl        boundary condition code:
!>                               - 1 Dirichlet
!>                               - 2 Radiative outlet
!>                               - 3 Neumann
!>                               - 4 sliding and
!>                                 \f$ \vect{u} \cdot \vect{n} = 0 \f$
!>                               - 5 smooth wall and
!>                                 \f$ \vect{u} \cdot \vect{n} = 0 \f$
!>                               - 6 rough wall and
!>                                 \f$ \vect{u} \cdot \vect{n} = 0 \f$
!>                               - 9 free inlet/outlet
!>                                 (input mass flux blocked to 0)
!> \param[in]     itrifb        indirection for boundary faces ordering
!> \param[in,out] itypfb        boundary face types
!> \param[out]    izfppp        boundary face zone number
!> \param[in]     dt            time step (per cell)
!> \param[in,out] rcodcl        boundary condition values:
!>                               - rcodcl(1) value of the dirichlet
!>                               - rcodcl(2) value of the exterior exchange
!>                                 coefficient (infinite if no exchange)
!>                               - rcodcl(3) value flux density
!>                                 (negative if gain) in w/m2 or roughness
!>                                 in m if icodcl=6
!>                                 -# for the velocity \f$ (\mu+\mu_T)
!>                                    \gradt \, \vect{u} \cdot \vect{n}  \f$
!>                                 -# for the pressure \f$ \Delta t
!>                                    \grad P \cdot \vect{n}  \f$
!>                                 -# for a scalar \f$ cp \left( K +
!>                                     \dfrac{K_T}{\sigma_T} \right)
!>                                     \grad T \cdot \vect{n} \f$
!_______________________________________________________________________________



subroutine cs_user_boundary_conditions &
 ( nvar   , nscal  ,                                              &
   icodcl , itrifb , itypfb , izfppp ,                            &
   dt     ,                                                       &
   rcodcl )

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

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

use paramx
use numvar
use optcal
use cstphy
use cstnum
use entsor
use parall
use period
use ihmpre
use ppppar
use ppthch
use coincl
use cpincl
use ppincl
use ppcpfu
use atincl
use ctincl
use cs_fuel_incl
use mesh
use field
use user_module
use iso_c_binding
use cs_c_bindings

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

implicit none

! Arguments

integer          nvar   , nscal

integer          icodcl(nfabor,nvarcl)
integer          itrifb(nfabor), itypfb(nfabor)
integer          izfppp(nfabor)

double precision dt(ncelet)
double precision rcodcl(nfabor,nvarcl,3)

! Local variables

!< [loc_var_dec]
integer          ifac, iel, ii, ivar
integer          izone
integer          ilelt, nlelt
double precision uref2, d2s3
double precision rhomoy, xdh, xustar2
double precision xitur
double precision xkent, xeent

integer, allocatable, dimension(:) :: lstelt
double precision, dimension(:), pointer :: bfpro_rom
!< [loc_var_dec]

! USER
integer          ipass
data             ipass /0/
save             ipass

character*1000   header
! number of dimensions
integer          nd
data             nd /2/   
! the number of points in i-th dir. for the raw data grid
integer          ng(2) 
data             ng(1) /2/, ng(2) /2/
integer          sizepg
data             sizepg /131/
double precision velxg(131)
double precision velyg(131)
double precision velzg(131)
double precision epslg(131)
double precision rixxg(131)
double precision riyyg(131)
double precision rizzg(131)
double precision xglob(262)


! cubic interpolation if set to 1, 0 linear
integer          cubint
data             cubint /1/
! derivatives at boundaries = 0 if set to 1
! second order derivatives at boundaries = 0 if set to 0 (natural splines)
integer          dernull
data             dernull /1/
! handle stretched grid if set to 1
integer          stretched
data             stretched /1/
integer          id, ig, i1, i2, i3

double precision xyscratch

double precision, allocatable, dimension(:) :: xintu ! locations of intp points
double precision, allocatable, dimension(:) :: xintl ! locations of intp points
double precision, dimension(:), pointer :: cvar_ep, cvar_omg, cvar_al
double precision, dimension(:), pointer :: cvar_r12, cvar_r13, cvar_r23 
! END USER

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

interface
   subroutine cub_interpolate(cubint, dernull, stretched, nd,   &
                              ng, xglob, pglob, ni, xintp, pintp)     &
        bind(C, name='cs_cub_interpolate')
     use, intrinsic :: iso_c_binding
     implicit none
     integer(c_int), value :: cubint, dernull, stretched, nd, ni
     real(kind=c_double), dimension(*) :: xglob, pglob, xintp, pintp
     integer(c_int), dimension(*) :: ng
   end subroutine cub_interpolate
end interface

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

!< [init]
allocate(lstelt(nfabor))  ! temporary array for boundary faces selection

d2s3 = 2.d0/3.d0

call field_get_val_s(ibrom, bfpro_rom)
if (iturb.eq.32) then
  ! EB RSM
  call field_get_val_s(ivarfl(ir12), cvar_r12)
  call field_get_val_s(ivarfl(ir13), cvar_r13)
  call field_get_val_s(ivarfl(ir23), cvar_r23)
  call field_get_val_s(ivarfl(ial), cvar_al)
  call field_get_val_s(ivarfl(iep), cvar_ep)
else if (iturb.eq.60) then
  ! K omg
  call field_get_val_s(ivarfl(iomg), cvar_omg)
else if (iturb.eq.51) then
  ! v2f bl v2/k
  call field_get_val_s(ivarfl(ial), cvar_al)
  call field_get_val_s(ivarfl(iep), cvar_ep)
endif
!< [init]

!===============================================================================
! Assign boundary conditions to boundary faces here

! For each subset:
! - use selection criteria to filter boundary faces of a given subset
! - loop on faces from a subset
!   - set the boundary condition for each face
!===============================================================================

if (ipass.eq.0) then

  ! File reading
  open(1234,file='/scratch/sacripante/CONJ-2Dp/FLUID/SRC/Inlet.dat',form='formatted',status='unknown')
  ig = sizepg
  read(1234,*) header
  do while (ig > 0) 
    read(1234,*) velxg(ig), velyg(ig), velzg(ig), &
         epslg(ig), rixxg(ig), riyyg(ig), &
         rizzg(ig), xglob(sizepg + ig)
    xglob(ig) = xglob(sizepg + ig) 
    ig = ig - 1
  enddo
  close(1234)

  ! In the listing file to check reading is correct 
  write(nfecra,*) ''
  write(nfecra,*) '*** BC:    ****'
  write(nfecra,*) 'y vx vy vz eps r11 r22 r33'
  write(nfecra,"(a, 8e11.3)") 'line  1:', xglob(1) , velxg(1),         &
       velyg(1),  velzg(1), epslg(1), rixxg(1), riyyg(1), rizzg(1)
  write(nfecra,"(a, 8e11.3)") 'line  2:', xglob(2) , velxg(2),         &
       velyg(2),  velzg(2), epslg(2), rixxg(2), riyyg(2), rizzg(2)
  write(nfecra,"(a, 8e11.3)") 'line  3:', xglob(3) , velxg(3),         &
       velyg(3),  velzg(3), epslg(3), rixxg(3), riyyg(3), rizzg(3)
  write(nfecra,"(a, 8e11.3)") 'line  13:', xglob(13) , velxg(13),      &
       velyg(13),  velzg(13), epslg(13), rixxg(13), riyyg(13),         &
       rizzg(13)
  write(nfecra,"(a, 8e11.3)") 'line  14:', xglob(14) , velxg(14),      &
       velyg(14),  velzg(14), epslg(14), rixxg(14), riyyg(14),         &
       rizzg(14)
  write(nfecra,"(a, 8e11.3)") 'line  15:', xglob(15) , velxg(15),      &
       velyg(15),  velzg(15), epslg(15), rixxg(15), riyyg(15),         &  
       rizzg(15)
  write(nfecra,"(a, 8e11.3)") 'line  131:', xglob(131) , velxg(131),   &
       velyg(131),  velzg(131), epslg(131), rixxg(131), riyyg(131),    &
       rizzg(131)
  write(nfecra,*) '***        ****'

endif

call getfbr('1', nlelt, lstelt)

if (ipass.eq.0) then
   
  allocate(xintu(nd*nlelt))

  call init_user_module(nlelt, 0)


  do ilelt = 1, nlelt
    ifac = lstelt(ilelt)
    xintu(ilelt+nlelt) = cdgfbo(2, ifac)
    xintu(ilelt)       = cdgfbo(3, ifac)
  enddo

  if (nlelt > 0) then
    cubint = 0
    dernull = 0
    stretched = 0
    call cub_interpolate(cubint, dernull, stretched, nd, &
         ng, xglob, velxg, nlelt, xintu, velxu)
    call cub_interpolate(cubint, dernull, stretched, nd, &
       ng, xglob, velyg, nlelt, xintu, velyu)
    call cub_interpolate(cubint, dernull, stretched, nd, &
         ng, xglob, velzg, nlelt, xintu, velzu)
    call cub_interpolate(cubint, dernull, stretched, nd, &
         ng, xglob, epslg, nlelt, xintu, epslu)
    call cub_interpolate(cubint, dernull, stretched, nd, &
         ng, xglob, rixxg, nlelt, xintu, rixxu)
    call cub_interpolate(cubint, dernull, stretched, nd, &
         ng, xglob, riyyg, nlelt, xintu, riyyu)
    call cub_interpolate(cubint, dernull, stretched, nd, &
         ng, xglob, rizzg, nlelt, xintu, rizzu)
  endif

  deallocate(xintu)
endif

do ilelt = 1, nlelt

  ifac = lstelt(ilelt)
  iel = ifabor(ifac)

  itypfb(ifac) = ientre

  rcodcl(ifac,iu,1) = velxu(ilelt)
  rcodcl(ifac,iv,1) = velyu(ilelt)
  rcodcl(ifac,iw,1) = velzu(ilelt)

  if (iturb.eq.32) then
    rcodcl(ifac,iep,1) = max(epslu(ilelt),epzero)
    rcodcl(ifac,ir11,1) = max(rixxu(ilelt),epzero)
    rcodcl(ifac,ir22,1) = max(riyyu(ilelt),epzero)
    rcodcl(ifac,ir33,1) = max(rizzu(ilelt),epzero)

    if (ipass.eq.0) then
      rcodcl(ifac,ir12,1) = epzero
      rcodcl(ifac,ir13,1) = epzero
      rcodcl(ifac,ir23,1) = epzero
      rcodcl(ifac,iep,1)  = 0.d0
      rcodcl(ifac,ial,1)  = 1.d0
    else
      rcodcl(ifac,ir12,1) = cvar_r12(iel)
      rcodcl(ifac,ir13,1) = cvar_r13(iel)
      rcodcl(ifac,ir23,1) = cvar_r23(iel)
      rcodcl(ifac,iep,1)  = cvar_ep(iel)
      rcodcl(ifac,ial,1)  = cvar_al(iel)
    endif
  else if (iturb.eq.60) then
    rcodcl(ifac,ik,1)  = max(5.d-1*(rixxu(ilelt)+riyyu(ilelt)+rizzu(ilelt)),epzero)
    if (ipass.eq.0) then
      rcodcl(ifac,iomg,1) = 0.d0
    else
      rcodcl(ifac,iomg,1) = cvar_omg(iel)
    endif
  else if (iturb.eq.51) then
    rcodcl(ifac,ik,1)   = max(5.d-1*(rixxu(ilelt)+riyyu(ilelt)+rizzu(ilelt)),epzero)
    rcodcl(ifac,iphi,1) = riyyu(ilelt)*riyyu(ilelt) / rcodcl(ifac,ik,1)
    if (ipass.eq.0) then
      rcodcl(ifac,iep,1) = 0.d0
      rcodcl(ifac,ial,1) = 1.d0
    else
      rcodcl(ifac,iep,1) = cvar_ep(iel)
      rcodcl(ifac,ial,1) = cvar_al(iel)
    endif
  endif
enddo

ipass = 1

!call csexit(1)

!< [finalize]
deallocate(lstelt)  ! temporary array for boundary faces selection
!< [finalize]

return
end subroutine cs_user_boundary_conditions
