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

! 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.

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

!> \file entsor.f90
!> \brief Module for input/output

module entsor

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

  use paramx

  implicit none

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

  !> \defgroup entsor Module for input/output

  !> \addtogroup entsor
  !> \{

  !> standard output
  integer, save :: nfecra

  !> characterizes the level of detail of the outputs for the
  !> variable \c ivar (from 1 to \ref dimens::nvar "nvar").
  !> The quantity of information increases with its value.
  !> Impose the value 0 or 1 for a reasonable listing size. Impose the value 2
  !> to get a maximum quantity of information, in case of problem during the
  !> execution.  Always useful.
  integer, save :: iwarni(nvarmx)

  !> unit of the upstream restart file for the vortex method.
  !> Useful if and only if isuivo=1 and  ivrtex=1.
  integer, save :: impmvo

  !> unit of the downstream restart file for the vortex method.
  !> Useful if and only if ivrtex=1.
  integer, save :: impvvo

  !> unit of the \ref vorinc::ficvor "ficvor" data files for the vortex method.
  !> These files are text files. Their number and names are specified by the user
  !> in the \ref usvort subroutine.
  !> (Although it corresponds to an 'upstream' data file, \ref impdvo is
  !> initialized to 20 because, in case of multiple vortex entries,
  !> it is opened at the same time as the upstream restart file,
  !> which already uses unit 11)
  !> useful if and only if \ref optcal::ivrtex "ivrtex"=1
  integer, save :: impdvo

  !> name of file, see usvort module.
  character(len=13), save :: ficdat

  !> saving period of the restart filesy5
  !>   - -2: no restart at all
  !>   - -1: only at the end of the calculation
  !>   - 0: by default (four times during the calculation)
  !>   - \>0: period
  integer, save :: ntsuit

  !> field key for output label
  integer, save :: keylbl = -1

  !> field keys for logging and postprocessing output
  integer, save :: keylog = -1
  integer, save :: keyvis = -1

  !> field key for start position in global postprocessing (ipp index) arrays
  integer, save :: keyipp = -1

  !> \}

  !> \defgroup userfile Additional user files

  !> \addtogroup userfile
  !> \{

  !> name of the thermochemical data file. The launch script is designed
  !> to copy the user specified thermochemical data file in the temporary
  !> execution directory under the name \em dp_thch, for \e Code_Saturne to open
  !> it properly.  Should the value of \ref ficfpp be changed, the launch script
  !> would have to be adapted.
  !> Useful in case of gas or pulverised coal combustion.
  character(len=32), save :: ficfpp

  !> logical unit of the thermochemical data file.
  !> Useful in case of gas or pulverised coal combustion or electric arcs;
  integer, save :: impfpp

  !> perform Janaf (=1) or not (=0)
  integer, save :: indjon

  !> Input files for the atmospheric specific physics
  !> (name of the meteo profile file)
  character(len=32), save :: ficmet
  !> logical unit of the meteo profile file
  integer, save :: impmet

  !> \}

  !> \defgroup history History user files

  !> \addtogroup history
  !> \{

  !> Maximum number of user chronological files.
  !> In the case where \ref ushist is used.
  integer    nushmx
  parameter(nushmx=16)

  !> directory in which the potential chronological record files generated by
  !> the Kernel will be written (path related to the execution directory)
  !> - it is recommended to keep the default value and, if necessary, to modify
  !> the launch script to copy the files in the alternate destination directory
  !> - useful if and only if chronological record files are generated
  !> (i.e. there is \c n for which \ref ihisvr "ihisvr"(n, 1) \f$\ne\f$ 0)
  character(len=80), save :: emphis

  !> prefix of history files
  character(len=80), save :: prehis

  !> units of the user chronological record files.
  !> Useful if and only if the subroutine \ref ushist is used.
  integer, save :: impush(nushmx)

  !> names of the user chronological record files.
  !> In the case of a non-parallel
  !> calculation, the suffix applied the file name is a three digit number:
  !> \f$ \texttt{ush001}\f$, \f$\texttt{ush002}\f$, \f$\texttt{ush003}\f$...
  !> In the case of a parallel-running calculation,
  !> the four digit processor index-number is added to the suffix.
  !> For instance, for a calculation running on two processors:
  !>  -from \f$ \texttt{ush001.n\_0001} \f$ to  \f$ \texttt{ush010.n\_0001} \f$
  !>  -and \f$ \texttt{ush001.n\_0002} \f$ to \f$ \texttt{ush010.n\_0002} \f$.
  !>  - ush001.n_0002, ush002.n_0002, ush003.n_0002...
  !> The opening, closing, format and location of these files must be managed
  !> by the user. Useful if and only if the subroutine \ref ushist is used
  character(len=13), save :: ficush(nushmx)

  !> stock file and mobile structure variables output unit
  integer, save :: impsth(2)

  !> maximum number of probes
  !> see associated format in \ref ecrhis
  integer    ncaptm
  parameter(ncaptm=100)

  !> time plot format (1: .dat, 2: .csv, 3: both)
  integer, save :: tplfmt

  !> total number of probes (limited to \ref ncaptm=100)
  integer, save :: ncapt

  !> output period of the chronological record files:
  !> - -1: no output
  !> - \>0: period  (every \ref nthist time step)
  !>
  !> The default value is -1 if there is no chronological record file to
  !> generate (if there is no probe, \ref ncapt = 0, or if \ref ihisvr "ihisvr"(n, 1)=0 for
  !> all the variables) and 1 otherwise.
  !> If chronological records are generated, it is usually wise to keep the default
  !> value \ref nthist=1, in order to avoid missing any high frequency evolution (unless
  !> the total number of time steps is much too big).
  !> Useful if and only if chronological record files are generated (
  !> i.e. there are probes (\ref ncapt>0) there is \c n for which
  !> \ref ihisvr "ihisvr"(n, 1) \f$\ne\f$ 0)
  integer, save :: nthist

  !> frhist : output frequency in seconds
  double precision, save :: frhist

  !> saving period the chronological record files (they are first stored in a
  !> temporary file and then saved every \ref nthsav time step):
  !>    - 0: by default (4 times during a calculation)
  !>    - -1: saving at the end of the calculation
  !>    - >0: period (every \ref nthsav time step)
  !>
  !> During the calculation, the user can read the chronological record files
  !> in the execution directory when they have been saved, i.e. at the first
  !> time step, at the tenth time step and when the time step number is a multiple of
  !> \ref nthsav (multiple of (\ref optcal::ntmabs "ntmabs"
  !> - \ref optcal::ntpabs "ntpabs")/4 if \ref nthsav=0).
  !> \note Using the \a control_file file allows to update the value of
  !> \ref optcal::ntmabs "ntmabs". Hence, if the calculation is at the time step n,
  !> the saving of the chronological record files can be forced by changing
  !> \ref optcal::ntmabs "ntmabs" to
  !> \ref optcal::ntpabs "ntpabs"+4(n+1)
  !>
  !> Using \a control_file; after the files have been saved,
  !> \ref optcal::ntmabs "ntmabs" can be
  !> reset to its original value, still using \a control_file.
  !> Useful if and only if chronological record files are generated (\em
  !> i.e. there are probes (\ref ncapt>0) there is n for which
  !> \ref ihisvr "ihisvr"(n, 1) \f$\ne\f$ 0)
  integer, save :: nthsav

  !> number \ref ihisvr "ihisvr(n, 1)" and index-numbers \ref ihisvr "ihisvr"(n, j>1)
  !> of the record probes to be used for each variable, em i.e. calculation variable
  !> or physical property defined at the cell centers.
  !> With \ref ihisvr "ihisvr"(n, 1)=-999 or -1, \ref ihisvr "ihisvr"(n, j>1) is useless.
  !>  - \ref ihisvr "ihisvr"(n, 1): number of record probes to use
  !> for the variable N.
  !>     * = -999: by default: chronogical records are generated on
  !> all the probes if N is one of the main variables (pressure, velocity,
  !> turbulence, scalars), the local time step or the turbulent
  !> viscosity. For the other quantities, no chronological record is generated.
  !>     * = -1: chronological records are produced on all the probes.
  !>     * = 0: no chronological record on any probe.
  !>     * > 0: chronological record on \ref ihisvr "ihisvr"(n, 1) probes to be
  !> specified with  \ref ihisvr "ihisvr"(n, j>1).
  !> always useful, must be inferior or equal to \ref ncapt.
  !>  - \ref ihisvr "ihisvr"(n, j>1): index-numbers of the probes
  !> used for the variable n.
  !> (with j <= \ref ihisvr "ihisvr"(n,1)+1).
  !>     * = -999: by default: if \ref ihisvr "ihisvr"(n, 1) \f$\ne\f$ -999
  !> the  code stops. Otherwise, refer to the description of the case
  !> \ref ihisvr "ihisvr"(n, 1)=-999.
  !>
  !> Useful if and only if \ref ihisvr "ihisvr"(n, 1) > 0 .
  !>
  !> The condition \ref ihisvr "ihisvr"(n, j) <= \ref ncapt must be respected.
  !> For an easier use, it is recommended to simply specify \ref ihisvr "ihisvr"(n,1)=-1 for
  !> all the interesting variables.
  integer, save :: ihisvr(nvppmx,ncaptm+1)

  !> write indicator (O or 1) for history of internal mobile structures
  integer, save :: ihistr

  !> probes corresponding element
  integer, save :: nodcap(ncaptm)

  !> row of process containing nodcap (in parallel processing)
  integer, save :: ndrcap(ncaptm)

  !> xyzcap : required position for a probe
  !> 3D-coordinates of the probes.
  !> the coordinates are written: \ref xyzcap "xyzcap"(i,j), with i = 1,2 or 3
  !> and j <= \ref ncapt.
  !> Useful if and only if \ref ncapt > 0.
  double precision, save :: xyzcap(3,ncaptm)

  !> tplflw : time plot flush wall-time interval (none if <= 0)
  double precision, save :: tplflw

  !> \}

  !> \defgroup lagrange Lagrange files

  !> \addtogroup lagrange
  !> \{

  !> name of Lagrange listing
  character(len=6), save :: ficlal

  !> logical unit of Lagrange listing
  integer, save :: implal
  !> output period of Lagrange listing
  integer, save :: ntlal


  !> unit of a file specific to Lagrangian modelling.
  !> Useful in case of Lagrangian modelling.
  integer, save :: impla1

  !> unit of a file specific to Lagrangian modelling.
  !> Useful in case of Lagrangian modelling.
  integer, save :: impla2

  !> unit of a file specific to Lagrangian modelling.
  !> Useful in case of Lagrangian modelling.
  integer, save :: impla3

  !> unit of a file specific to Lagrangian modelling.
  !> Useful in case of Lagrangian modelling.
  integer, save :: impla4

  !> units of files specific to Lagrangian modelling. 15-dimension array.
  !> Useful in case of Lagrangian modelling.
  integer, save :: impla5(15)

  !> \}

  !> \addtogroup userfile
  !> \{

  ! --- Fichiers utilisateurs

  !> maximal number of user files
  integer    nusrmx
  parameter(nusrmx=20)

  !> unit numbers for potential user specified files.
  !> Useful if and only if the user needs files
  !> (therefore always useful, by security)
  integer, save ::      impusr(nusrmx)

  !> name of the potential user specified files. In the case of a non-parallel
  !> calculation, the suffix applied the file name is a two digit number:
  !> from \f$ \texttt{usrf01} \f$ to \f$ \texttt{usrf10} \f$ .
  !> In the case of a parallel-running calculation, the four digit processor index-number is
  !> added to the suffix. For instance, for a calculation running on two
  !> processors: from \f$ \texttt{usrf01.n\_0001} \f$ to  \f$ \texttt{usrf10.n\_0001} \f$ and
  !> from \f$ \texttt{usrf01.n\_0002} \f$ to \f$ \texttt{usrf10.n\_0002} \f$ . The opening,
  !> closing, format and location of these files must be managed by the user.
  !> useful if and only if the user needs files (therefore always useful, by security)
  character(len=13), save :: ficusr(nusrmx)

  !> \}

  !> \defgroup listing Output listing

  !> \addtogroup listing
  !> \{

  !> temporary variable name for some algebraic operations

  character(len=80), save :: nomva0

  !> locator pointer for variables output
  integer, save :: ipppro(npromx)
  !> locator pointer for variables output
  integer, save :: ippdt
  !> locator pointer for variables output
  integer, save :: ipptx
  !> locator pointer for variables output
  integer, save :: ippty
  !> locator pointer for variables output
  integer, save :: ipptz

  !> writing period in the execution report file.
  !>   - -1: no writing
  !>   - \> 0: period (every \ref ntlist time step). The value of
  !> \ref ntlist must be adapted according to the number of iterations
  !> carried out in the calculation. Keeping \ref ntlist to 1 will indeed provide
  !> a maximum volume of information, but if the number of time steps
  !> is too large the execution report file might become too big and unusable
  !> (problems with disk space, memory problems while opening the file with a
  !> text editor, problems finding the desired information in the file, ...).
  integer, save :: ntlist

  !> \defgroup other_output Boundary post-processing

  !> \addtogroup other_output
  !> \{

  !> indicates the data to post-process on the boundary mesh (the boundary mesh must
  !> be associated with an active writer). \ref ipstdv "ipstdv"(key) indicates which
  !> fields should be created and output on the boundary, with \c key in
  !> \ref ipstfo, \ref ipstyp, \ref ipsttp, \ref ipstft, \ref ipstnu.
  integer, save :: ipstdv(5)

  !> post-processed property: Efforts (0: none 1: all; 2: tangent; 4: normal)
  integer    ipstfo
  !> post-processed property: \f$ y^+ \f$ at the boundary
  integer    ipstyp
  !> post-processed property :\f$ T^+ \f$ at the boundary
  integer    ipsttp
  !> post-processed property: thermal flux at the boundary (in  \f$ W\,m^{-2} \f$),
  integer    ipstft
  !> post-processed property: Nusselt
  integer    ipstnu
  parameter (ipstfo=1, ipstyp=2, ipsttp= 3, ipstft=4, ipstnu=5)

  !> margin in seconds on the remaining CPU time which is necessary to allow
  !> the calculation to stop automatically and write all the required results
  !> (for the machines having a queue manager).
  !>   - -1: calculated automatically,
  !>   - 0: margin defined by the user.
  !> Always useful, but the default value should not be changed.
  double precision, save :: tmarus
  !> \}
  !> \}

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


contains

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

  !> \brief Flush Fortran log

  subroutine flush_nfecra() bind(C, name='cs_f_flush_logs')
    flush(nfecra)
  end subroutine flush_nfecra

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

  !> \brief Map a field to time plot (probes) activation array.
  !> This will set the "post_id" keyword for the given field, if not
  !> already set.

  !> \param[in]  f_id  id of given field

  !> \return  starting position of this field in the \ref ihisvr array.

  function field_post_id(f_id) result(ipp)

    use, intrinsic :: iso_c_binding
    use field
    implicit none

    ! Arguments

    integer(c_int), value :: f_id
    integer(c_int)        :: ipp

    ! Local variables

    logical :: interleaved
    integer :: f_dim
    integer, save :: keypp = -1
    integer, save :: nvpp = 1

    if (keypp.lt.0) then
      call field_get_key_id("post_id", keypp)
    endif

    call field_get_key_int(f_id, keypp, ipp)

    ! Define if not already done

    if (ipp.le.1) then

      call field_get_dim(f_id, f_dim, interleaved)

      ipp = nvpp + 1

      nvpp = nvpp + f_dim

      ! Check limit on NVPP

      if (nvpp.gt.nvppmx) then
        write(nfecra,1000) nvpp, nvppmx
        call csexit (1)
        !==========
      endif

      call field_set_key_int(f_id, keypp, ipp)

    endif

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

 1000 format(                                                     &
'@'                                                            ,/,&
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
'@'                                                            ,/,&
'@ @@ WARNING: STOP AT THE INITIAL DATA VERIFICATION'          ,/,&
'@    ======='                                                 ,/,&
'@     Number of possible time plots too large'                ,/,&
'@'                                                            ,/,&
'@  The type of calcultion defined'                            ,/,&
'@    leads to a number of potential time plots'               ,/,&
'@    for active fields equal to ', i10                        ,/,&
'@  The maximum number of time plots defined'                  ,/,&
'@    in paramx.f90 is NVPPMX = ', i10                         ,/,&
'@'                                                            ,/,&
'@  The calculation will not be run.'                          ,/,&
'@'                                                            ,/,&
'@  Contact support, or rebuild code with increased NVPPMX.'   ,/,&
'@'                                                            ,/,&
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',/,&
'@'                                                            ,/)

  end function field_post_id

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

end module entsor
