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

!VERS

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

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

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

!> \file cs_user_physical_properties.f90
!> \brief Definition of physical variable laws.
!>
!> usphyv
!> \brief Definition of physical variable laws.
!>
!> \section Warning
!>
!> It is \b forbidden to modify turbulent viscosity \c visct here
!> (a specific subroutine is dedicated to that: \ref usvist)
!>
!> - icp = 1 must <b> have been specified </b>
!>    in \ref usipph if we wish to define a variable specific heat
!>    cpro_cp (otherwise: memory overwrite).
!>
!> - ivisls = 1 must <b> have been specified </b>
!>    in \ref usipsc if we wish to define a variable viscosity
!>    \c viscls (otherwise: memory overwrite).
!>
!>
!> \remarks
!>  - This routine is called at the beginning of each time step
!>    Thus, <b> AT THE FIRST TIME STEP </b> (non-restart case), the only
!>    values initialized before this call are those defined
!>      - in the GUI or  \ref usipsu (cs_user_parameters.f90)
!>             - density    (initialized at \c ro0)
!>             - viscosity  (initialized at \c viscl0)
!>      - in the GUI or \ref cs_user_initialization
!>             - calculation variables (initialized at 0 by defaut
!>             or to the value given in the GUI or in \ref cs_user_initialization)
!>
!>  - We may define here variation laws for cell properties, for:
!>     - density:                                    rom    kg/m3
!>     - density at boundary faces:                  romb   kg/m3)
!>     - molecular viscosity:                        cpro_viscl  kg/(m s)
!>     - specific heat:                              cpro_cp     J/(kg degrees)
!>     - diffusivities associated with scalars:      cpro_vscalt kg/(m s)
!>
!> \b Warning: if the scalar is the temperature, cpro_vscalt corresponds
!> to its conductivity (Lambda) in W/(m K)
!>
!>
!> The types of boundary faces at the previous time step are available
!>   (except at the first time step, where arrays \c itypfb and \c itrifb have
!>   not been initialized yet)
!>
!> It is recommended to keep only the minimum necessary in this file
!>   (i.e. remove all unused example code)
!>
!>
!> \section cell_id Cells identification
!>
!> Cells may be identified using the \ref getcel subroutine.
!> The syntax of this subroutine is described in the
!> \ref cs_user_boundary_conditions subroutine,
!> but a more thorough description can be found in the user guide.
!
!-------------------------------------------------------------------------------

!-------------------------------------------------------------------------------
! Arguments
!______________________________________________________________________________.
!  mode           name          role                                           !
!______________________________________________________________________________!
!> \param[in]     nvar          total number of variables
!> \param[in]     nscal         total number of scalars
!> \param[in]     mbrom         indicator of filling of romb array
!> \param[in]     dt            time step (per cell)
!_______________________________________________________________________________

subroutine usphyv &
 ( mbrom  )

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

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

use paramx
use pointe
use numvar
use optcal
use cstphy
use entsor
use parall
use period
use field
use mesh

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

implicit none

! Arguments

integer          mbrom
!double precision dt(ncelet)
!double precision dt(ncelet)

! Local variables

integer          ivart, iel, ifac
double precision vara, varb, varc
double precision xrtp
double precision, dimension(:), pointer :: coefap, coefbp
double precision, dimension(:), pointer :: bfpro_rom, cpro_rom
double precision, dimension(:), pointer :: cpro_beta
double precision, dimension(:), pointer :: cvar_scalt

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

! TEST_TO_REMOVE_FOR_USE_OF_SUBROUTINE_START
!===============================================================================

if (1.eq.1) return

!===============================================================================
! TEST_TO_REMOVE_FOR_USE_OF_SUBROUTINE_END


!===============================================================================
! 0. Initializations to keep
!===============================================================================

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

!   The following examples should be adapted by the user
!   ====================================================

!  Each example is bounded by a test using .false. as a precaution.
!  Replace .false. by .true to activate the example.

!  It is recommended to keep only the minimum necessary in this file
!  (i.e. remove all unused example code)


!  example 1: variable density as a function of temperature
!  example 2: variable viscosity as a function of tempeprature
!  example 3: variable specific heat as a function of tempeprature
!  example 4: variable Lambda/CP as a function of temperature
!             for temperature or enthalpy
!  example 5: variable sclalars diffusivity as a function of temperature
!===============================================================================


!===============================================================================
!  Example 1: variable density as a function of temperature
!  =========
!    Below, we define the same density law
!    Values of this property must be defined at cell centers
!      (and optionally, at boundary faces).
!  ===================================================================

!    The test on .false. allows deactivating instructions (which are defined
!       only as a starting example)

if (.true.) then

  ! Position of variables, coefficients
  ! -----------------------------------

  ! --- Number of the thermal variable
  !       (and of its boundary conditions)
  !       To use user scalar 2 instead, write 'ivart = isca(2)'

  if (iscalt.gt.0) then
    ivart = isca(iscalt)
    call field_get_val_s(ivarfl(ivart), cvar_scalt)
  else
    write(nfecra,9010) iscalt
    call csexit (1)
  endif

  ! --- Pointers to density values

  call field_get_val_s(icrom, cpro_rom)
  call field_get_val_s(ibrom, bfpro_rom)

  ! --- Coefficients of laws chosen by the user
  !       Values given here are fictitious

  vara  = -4.0668d-3
  varb  = -5.0754d-2
  varc  =  1000.9d0

  ! Density at cell centers
  !------------------------
  ! law                    rho  = t  * ( a *  t +  b) +   c
  ! so      cpro_rom(iel) = xrtp * (vara*xrtp+varb) + varc

  ! Volumic thermal expansion coefficient
  !--------------------------------------
  ! law                     cpro_beta  = -1/rho * (d rho / d T)
  ! so cpro_beta(iel) = (-1.d0/cpro_rom(iel))*(2.d0*vara*xrtp+varb)

  call field_get_val_s(iprpfl(ibeta), cpro_beta)

  do iel = 1, ncel
    xrtp = cvar_scalt(iel)
    cpro_rom(iel) = xrtp * (vara*xrtp+varb) + varc
    cpro_beta(iel)= (-1.d0/cpro_rom(iel))*(2.d0*vara*xrtp+varb)
  enddo


  ! Density at boundary faces
  !---------------------------

  ! By default, the value of rho at the boundary is the value taken
  !   at the center of adjacent cells. This is the recommended approach.
  ! To be in this case, nothing needs to be done:
  !   do not prescribe a value for bfpro_rom(ifac) and
  !   do not modify mbrom

  ! For users who do not wish to follow this recommendation, we
  !   note that the boundary temperature may be fictitious, simply
  !   defined so as to conserve a flux (this is especially the case
  !   at walls). The value of rho which is computed at the boundary
  !   when introducing this fictitious temperature in a physical law
  !   may thus be completely false (negative for example).

  ! If we wish to specify a law anyways:
  !                        rho  = t  * ( a *  t +  b) +   c
  ! so      bfpro_rom(ifac) = xrtp * (vara*xrtp+varb) + varc

  ! 't' being the temperature at boundary face centers, we may use the
  ! following lines of code (voluntarily deactived, as the must be used
  ! with caution):

  ! Note that when we prescribe the density at the boundary, it must be done
  ! at ALL boundary faces.
  !    ===

  if (.true.) then

    ! Boundary condition coefficients
    call field_get_coefa_s(ivarfl(ivart), coefap)
    call field_get_coefb_s(ivarfl(ivart), coefbp)

    ! Caution: mbrom = 1 is necessary for the law to be taken
    !                           into account.
    mbrom = 1

    do ifac = 1, nfabor

      ! ifabor(ifac) is the cell adjacent to the boundary face
      iel = ifabor(ifac)
      xrtp = coefap(ifac) + cvar_scalt(iel)*coefbp(ifac)
      bfpro_rom(ifac) = xrtp * (vara*xrtp+varb) + varc
    enddo

  endif ! --- Test on .false.

endif ! --- Test on .false.




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

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

#if defined(_CS_LANG_FR)

 ! 1000 format(                                                     &
! '@                                                            ',/,&
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@                                                            ',/,&
! '@ @@ ATTENTION : ARRET LORS DU CALCUL DES GRANDEURS PHYSIQUES',/,&
! '@    =========                                               ',/,&
! '@    DONNEES DE CALCUL INCOHERENTES                          ',/,&
! '@                                                            ',/,&
! '@      usipph indique que la chaleur specifique est uniforme ',/,&
! '@        ICP = ',I10   ,' alors que                          ',/,&
! '@      usphyv impose une chaleur specifique variable.        ',/,&
! '@                                                            ',/,&
! '@    Le calcul ne sera pas execute.                          ',/,&
! '@                                                            ',/,&
! '@    Modifier usipph ou usphyv.                              ',/,&
! '@                                                            ',/,&
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@                                                            ',/)
 ! 1010 format(                                                     &
! '@                                                            ',/,&
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@                                                            ',/,&
! '@ @@ ATTENTION : ARRET LORS DU CALCUL DES GRANDEURS PHYSIQUES',/,&
! '@    =========                                               ',/,&
! '@    DONNEES DE CALCUL INCOHERENTES                          ',/,&
! '@                                                            ',/,&
! '@    Pour le scalaire ',I10                                   ,/,&
! '@      usipsc indique que la diffusivite est uniforme        ',/,&
! '@        IVISLS(',I10   ,') = ',I10   ,' alors que           ',/,&
! '@      usphyv impose une diffusivite variable.               ',/,&
! '@                                                            ',/,&
! '@    Le calcul ne sera pas execute.                          ',/,&
! '@                                                            ',/,&
! '@    Modifier usipsc ou usphyv.                              ',/,&
! '@                                                            ',/,&
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@                                                            ',/)
 9010 format(                                                     &
'@                                                            ',/,&
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
'@                                                            ',/,&
'@ @@ ATTENTION : ARRET LORS DU CALCUL DES GRANDEURS PHYSIQUES',/,&
'@    =========                                               ',/,&
'@    APPEL A csexit DANS LE SOUS PROGRAMME usphyv            ',/,&
'@                                                            ',/,&
'@    La variable dont dependent les proprietes physiques ne  ',/,&
'@      semble pas etre une variable de calcul.               ',/,&
'@    En effet, on cherche a utiliser la temperature alors que',/,&
'@      ISCALT = ',I10                                         ,/,&
'@    Le calcul ne sera pas execute.                          ',/,&
'@                                                            ',/,&
'@    Verifier le codage de usphyv (et le test lors de la     ',/,&
'@      definition de IVART).                                 ',/,&
'@    Verifier la definition des variables de calcul dans     ',/,&
'@      usipsu. Si un scalaire doit jouer le role de la       ',/,&
'@      temperature, verifier que ISCALT a ete renseigne.     ',/,&
'@                                                            ',/,&
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
'@                                                            ',/)

#else

 ! 1000 format(                                                     &
! '@',/,                                                            &
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@',/,                                                            &
! '@ @@ WARNING:  stop when computing physical quantities',/,       &
! '@    =======',/,                                                 &
! '@    Inconsistent calculation data',/,                           &
! '@',/,                                                            &
! '@      usipph specifies that the specific heat is uniform',/,    &
! '@        icp = ',i10   ,' while',/,                              &
! '@      usphyv prescribes a variable specific heat.',/,           &
! '@',/,                                                            &
! '@    The calculation will not be run.',/,                        &
! '@',/,                                                            &
! '@    Modify usipph or usphyv.',/,                                &
! '@                                                            ',/,&
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@',/)
 ! 1010 format(                                                     &
! '@',/,                                                            &
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@',/,                                                            &
! '@ @@ WARNING:  stop when computing physical quantities',/,       &
! '@    =======',/,                                                 &
! '@    Inconsistent calculation data',/,                           &
! '@',/,                                                            &
! '@    For scalar', i10,/,                                         &
! '@      usipsu specifies that the diffusivity is uniform',/,      &
! '@        ivislc(',i10   ,') = ',i10   ,' while',/,               &
! '@      usphyv prescribes a variable diffusivity.',/,             &
! '@',/,                                                            &
! '@    The calculation will not be run.',/,                        &
! '@',/,                                                            &
! '@    Modify usipsu or usphyv.',/,                                &
! '@                                                            ',/,&
! '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
! '@',/)
 9010 format(                                                     &
'@',/,                                                            &
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
'@',/,                                                            &
'@ @@ WARNING:  stop when computing physical quantities',/,       &
'@    =======',/,                                                 &
'@',/,                                                            &
'@    The variable on which physical properties depend does',/,   &
'@      seem to be a calculation variable.',/,                    &
'@    Indeed, we are trying to use the temperature while',/,      &
'@      iscalt = ',i10                                  ,/,&
'@',/,                                                            &
'@    The calculation will not be run.',/,                        &
'@',/,                                                            &
'@    Check the programming in usphyv (and the test when',/,      &
'@      defining ivart).',/,                                      &
'@    Check the definition of calculation variables in',/,        &
'@      usipsu. If a scalar should represent the,',/,             &
'@      temperature, check that iscalt has been defined',/,       &
'@',/,                                                            &
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
'@',/)

#endif

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

return
end subroutine usphyv


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