/*============================================================================
*
*                    Code_Saturne version 1.3
*                    ------------------------
*
*
*     This file is part of the Code_Saturne Kernel, element of the
*     Code_Saturne CFD tool.
*
*     Copyright (C) 1998-2007 EDF S.A., France
*
*     contact: saturne-support@edf.fr
*
*     The Code_Saturne Kernel 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.
*
*     The Code_Saturne Kernel 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 the Code_Saturne Kernel; if not, write to the
*     Free Software Foundation, Inc.,
*     51 Franklin St, Fifth Floor,
*     Boston, MA  02110-1301  USA
*
*============================================================================*/

#ifndef __CS_PERIO_H__
#define __CS_PERIO_H__

/*============================================================================
 * Structure associée au paramétrage d'une périodicité
 *============================================================================*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/*----------------------------------------------------------------------------
 *  Fichiers `include' locaux
 *----------------------------------------------------------------------------*/

#include "cs_base.h"


/*=============================================================================
 * Définitions de macros
 *============================================================================*/

#define CS_NPHSMX                3                /* Nombre maximum de phases */


/*============================================================================
 * Définitions d'énumérations
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Type de periodicité considéréé
 *----------------------------------------------------------------------------*/

typedef enum {

  CS_PERIO_TYPE_NUL          , /* Périodicité indéfinie                       */
  CS_PERIO_TYPE_TRANS        , /* Périodicité de translation                  */
  CS_PERIO_TYPE_ROTA           /* Périodicité de rotation                     */

} cs_perio_typ_t ;



/*============================================================================
 * Définitions de types
 *============================================================================*/

typedef struct _cs_param_perio_t {

  cs_int_t        num_perio      ;    /* Numéro de la périodicité             */
  cs_perio_typ_t  type_perio     ;    /* Translation ou rotation              */
  cs_real_t  translation[3] ;  /* Vecteur translation                        */
  cs_real_t  point_inv[3] ;    /* Point invariant de la rotation             */
  cs_real_t  matrice[3][3] ;   /* Matrice                                    */

} cs_param_perio_t ;


/*=============================================================================
 * Prototypes de fonctions
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Communication entre cellules periodiques
 * VARIJ represente la variable a laquelle on impose la periodicite
 *
 * Les cas de periodicite qui peuvent etre traites sont :
 *
 * - Periodicite d'un scalaire (IDIMTE = 0, ITENSO = 0) que ce soit une
 *   periodicite de translation ou de rotation, le tableau change est VAR11
 * - Periodicite d'un scalaire (IDIMTE = 0, ITENSO = 1) en translation
 *   seulement, la variable changee est VAR11. Elle sert a impliciter les
 *   conditions de periodicite sur les composantes d'un tenseur
 * - Periodicite d'un scalaire (IDIMTE = 0, ITENSO = 11)
 *   reprend (IDIMTE = 0, ITENSO = 1) et, en outre, en rotation seulement,
 *   la variable VAR11 est annulee. On utilise l'option pour annuler le halo
 *   des periodicites de rotation dans les solveurs iteratifs lors des
 *   resolutions par increment des vecteurs et des tenseurs. Il s'agit d'une
 *   condition approchee mais en attendant les tests pas pire qu'une autre
 * - Periodicite d'un vecteur (IDIMTE = 0, ITENSO = 2) en translation
 *   seulement, les tableaux changes sont VAR11, VAR22, VAR33
 * - Periodicite d'un vecteur (IDIMTE = 1, ITENSO = *) en translation et
 *   rotation, les tableaux changes sont VAR11, VAR22, VAR33
 * - Periodicite d'un tenseur d'ordre 2 (IDIMTE = 2, ITENSO = *) en
 *   translation et rotation, les tableaux changes sont VAR11, VAR13, VAR13,
 *   VAR21, VAR22, VAR23, VAR31, VAR32, VAR33
 * - Periodicite d'un tenseur d'ordre 2 (IDIMTE = 21, ITENSO = *) en
 *   translation et rotation, les tableaux changes sont VAR11, VAR22, VAR33
 *   (on suppose le tenseur diagonal)
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERCOM
 * *****************
 *
 * INTEGER          IDIMTE        :  -> : dimension de la variable (maximum 3)
 *                                        0 : scalaire (VAR11), ou assimile
 *                                            scalaire
 *                                        1 : vecteur (VAR11,VAR22,VAR33)
 *                                        2 : tenseur d'ordre 2 (VARIJ)
 *                                       21 : tenseur d'ordre 2 suppose
 *                                            diagonal (VAR11, VAR22, VAR33)
 * INTEGER          ITENSO        :  -> : pour l'explicitation de la rotation
 *                                        0 : scalaire (VAR11)
 *                                        1 : composante de vecteur ou de
 *                                            tenseur (VAR11) implicite pour
 *                                            la translation
 *                                       11 : reprend le traitement ITENSO=1
 *                                            et composante de vecteur ou de
 *                                            tenseur annulee pour la rotation
 *                                        2 : vecteur (VAR11 et VAR22 et VAR33)
 *                                            implicite pour la rotation
 * DOUBLE PRECISION VAR11(NCELET) :  -  : composante 11 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR12(NCELET) :  -  : composante 12 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR13(NCELET) :  -  : composante 13 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR21(NCELET) :  -  : composante 21 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR22(NCELET) :  -  : composante 22 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR23(NCELET) :  -  : composante 23 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR31(NCELET) :  -  : composante 31 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR32(NCELET) :  -  : composante 32 du tenseur d'ordre 2
 * DOUBLE PRECISION VAR33(NCELET) :  -  : composante 33 du tenseur d'ordre 2
 *----------------------------------------------------------------------------*/

void CS_PROCF (percom, PERCOM)
(
 const cs_int_t    *idimte,
 const cs_int_t    *itenso,
       cs_real_t    var11[],
       cs_real_t    var12[],
       cs_real_t    var13[],
       cs_real_t    var21[],
       cs_real_t    var22[],
       cs_real_t    var23[],
       cs_real_t    var31[],
       cs_real_t    var32[],
       cs_real_t    var33[]
) ;


/*----------------------------------------------------------------------------
 * Initialisation pour la périodicité (actualisation des cdg et des familles
 * des cellules halos).
 *----------------------------------------------------------------------------*/

void cs_perio_sync_geo
(
 void
) ;


/*----------------------------------------------------------------------------
 * Mise à jour du voisinage étendu d'une variable au centre des cellules
 *   dans le voisinage étendu s'il est traité séparément du reste du halo
 *
 * Fonction calquée sur PERCOM, pour la périodicité de translation uniquement
 *
 * Le rôle de cette fonction consiste à recopier les valeurs sur les
 * cellules principales en frontière périodique non parallèle
 * (indices entre 1 et ncel) vers les cellules halo du domaine en
 * cours.
 *
 *----------------------------------------------------------------------------*/

void cs_perio_percve
(
 const cs_real_t * const var       ,/* --> variable au centre des cellules */
       cs_real_t *       var_voiset /* <-> variable au centre des cellules
                                           dans le voisinage étendu        */
) ;


/*----------------------------------------------------------------------------
 * Interface FORTRAN pour les echanges sur le voisinage étendu lorsqu'il est
 *   traité séparément du halo classique. Le tableau traité est supposé
 *   correctement dimensionné (ncelet + nombre de cellules halo étendu).
 *
 * Appelée en périodique uniquement.
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERCVE
 * *****************
 *
 *    & ( PVAR )
 *
 *----------------------------------------------------------------------------*/

void CS_PROCF (percve, PERCVE)
(
       cs_real_t         pvar[]       /* <-> tab. echangé                     */
 CS_ARGF_SUPP_CHAINE                  /*     (arguments 'longueur' éventuels,
                                             Fortran, inutilisés lors de
                                             l'appel mais placés par de
                                             nombreux compilateurs)           */
);


/*----------------------------------------------------------------------------
 * Gestion de la périodicité pour INIMAS
 *
 * Dans le cas ou INIMAS est appele dans NAVSTO :
 *    On suppose que le gradient aux cellules halo obtenu par une rotation
 *    est connu et est celui de la vitesse au pas de temps précédent
 * Dans le cas ou INIMAS est appele dans DIVRIJ :
 *    On suppose (et ceci est plus justifiable que ce qui précède) que le
 *    gradient aux cellules halo obtenu par une rotation est celui des
 *    varaibles Rij au pas de temps précédent
 *
 * Il reste encore à tester cette approche
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERMAS
 * *****************
 *
 * INTEGER          IMASPE      :  -> : suivant l'appel de INIMAS
 *                                          = 1 si appel de RESOLP ou NAVSTO
 *                                          = 2 si appel de DIVRIJ
 * INTEGER          IPHAS       :  -> : numero de phase courante
 * INTEGER          IMASPE      :  -> : indicateur d'appel dans INIMAS
 *                                          = 1 si appel au debut
 *                                          = 2 si appel a la fin
 * DOUBLE PRECISION ROM(NCELET) :  -> : masse volumique aux cellules
 * DOUBLE PRECISION DUDXYZ      :  -> : gradient de U aux cellules halo pour
 *                                      l'approche explicite en periodicite
 * DOUBLE PRECISION DRDXYZ      :  -> : gradient de R aux cellules halo pour
 *                                      l'approche explicite en periodicite
 * DOUBLE PRECISION WDUDXY      :  -  : tableau de travail pour DUDXYZ
 * DOUBLE PRECISION WDRDXY      :  -  : tableau de travail pour DRDXYZ
 *
 * Les tableaux DUDXYZ et WDUDXY sont de taille (NCELET-NCEL)*3*3*NPHAS
 * Les tableaux DRDXYZ et WDRDXY sont de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (permas, PERMAS)
(
 const cs_int_t    *imaspe,
 const cs_int_t    *iphas,
 const cs_int_t    *iappel,
 const cs_real_t    rom[],
       cs_real_t   *dudxyz,
       cs_real_t   *drdxyz,
       cs_real_t   *wdudxy,
       cs_real_t   *wdrdxy
) ;


/*----------------------------------------------------------------------------
 * Préparation des tableaux DPDX, DPDY et DPDZ pour GRADRC en cas de
 * périodicité de rotation pour la vitesse et les tensions de Reynolds
 *
 * Pour la vitesse et les tensions de Reynolds, on récupère le gradient estimé
 * par PERINU et PERINR (PHYVAR) dans le tableau représentant le halo et on
 * l'affect au gradient DPDX, DPDY, DPDZ (tableaux NCELET).
 *
 *  La nécessité de disposer des trois composantes interdit la prise en compte
 * implicite des périodicités de rotation du gradient de grandeurs non
 * scalaires dans GRADRC.
 *  Les valeurs correspondant à des périodicités de translation peuvent par
 * contre etre traitées en implicite : elles seront écrasées plus loin dans
 * GRADRC.
 *  Pour les variables U er R, on indique donc qu'il ne reste qu'à transférer
 * les valeurs de périodicité de translation, et pour cela on positionne
 * IDIMTE=0, ITENSO=2.
 *  Pour les autres variables, on suppose qu'il est correst de traiter toutes
 * les périodicités en implicite dans GRADRC, et on positionne alors IDIMTE=1,
 * ITENSO=0.
 *
 * Interface Fortran :
 *
 * SUBROUTINE PERING
 * *****************
 *
 * INTEGER          NPHAS        :  -> : numero de phase courante
 * INTEGER          IVAR         :  -> : numero de la variable
 * INTEGER          IDIMTE       :  -> : dimension de la variable (maximum 3)
 *                                        0 : scalaire (VAR11), ou assimile
 *                                            scalaire
 *                                        1 : vecteur (VAR11,VAR22,VAR33)
 *                                        2 : tenseur d'ordre 2 (VARIJ)
 *                                       21 : tenseur d'ordre 2 suppose
 *                                            diagonal (VAR11, VAR22, VAR33)
 * INTEGER          ITENSO       :  -> : pour l'explicitation de la rotation
 *                                        0 : scalaire (VAR11)
 *                                        1 : composante de vecteur ou de
 *                                            tenseur (VAR11) implicite pour
 *                                            la translation
 *                                       11 : reprend le traitement ITENSO=1
 *                                            et composante de vecteur ou de
 *                                            tenseur annulee pour la rotation
 *                                        2 : vecteur (VAR11 et VAR22 et VAR33)
 *                                            implicite pour la rotation
 * INTEGER          IPEROT       :  -> : indicateur du nombre de periodicte de
 *                                       rotation
 * INTEGER          IGUPER       :  -> : 0/1 indique qu'on a /n'a pas calcule
 *                                       les gradients dans DUDXYZ
 * INTEGER          IGRPER       :  -> : 0/1 indique qu'on a /n'a pas calcule
 *                                       les gradients dans DRDXYZ
 * INTEGER          IU           :  -> : position de la Vitesse(x,y,z)
 * INTEGER          IV           :  -> : dans RTP, RTPA
 * INTEGER          IW           :  -> :     "                   "
 * INTEGER          ITYTUR       :  -> : turbulence (Rij-epsilon ITYTUR = 3)
 * INTEGER          IR11         :  -> : position des Tensions de Reynolds
 * INTEGER          IR22         :  -> : en Rij dans RTP, RTPA
 * INTEGER          IR33         :  -> :     "                   "
 * INTEGER          IR12         :  -> :     "                   "
 * INTEGER          IR13         :  -> :     "                   "
 * INTEGER          IR23         :  -> :     "                   "
 * DOUBLE PRECISION DPDX(NCELET) :  -> : gradient de IVAR
 * DOUBLE PRECISION DPDY(NCELET) :  -> :    "        "
 * DOUBLE PRECISION DPDZ(NCELET) :  -> :    "        "
 * DOUBLE PRECISION DUDXYZ       :  -> : gradient de U aux cellules halo pour
 *                                       l'approche explicite en periodicite
 * DOUBLE PRECISION DRDXYZ       :  -> : gradient de R aux cellules halo pour
 *                                       l'approche explicite en periodicite
 *
 * Le tableau DUDXYZ est de taille (NCELET-NCEL)*3*3*NPHAS
 * Le tableau DRDXYZ est de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (pering, PERING)
(
 const cs_int_t    *nphas,
 const cs_int_t    *ivar,
       cs_int_t    *idimte,
       cs_int_t    *itenso,
 const cs_int_t    *iperot,
 const cs_int_t    *iguper,
 const cs_int_t    *igrper,
 const cs_int_t     iu[CS_NPHSMX],
 const cs_int_t     iv[CS_NPHSMX],
 const cs_int_t     iw[CS_NPHSMX],
 const cs_int_t     itytur[CS_NPHSMX],
 const cs_int_t     ir11[CS_NPHSMX],
 const cs_int_t     ir22[CS_NPHSMX],
 const cs_int_t     ir33[CS_NPHSMX],
 const cs_int_t     ir12[CS_NPHSMX],
 const cs_int_t     ir13[CS_NPHSMX],
 const cs_int_t     ir23[CS_NPHSMX],
       cs_real_t    dpdx[],
       cs_real_t    dpdy[],
       cs_real_t    dpdz[],
       cs_real_t   *dudxyz,
       cs_real_t   *drdxyz
) ;


/*----------------------------------------------------------------------------
 * Routine d'echange de tableaux pour PERINU
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINU1
 * *****************
 *
 * INTEGER          ISOU          :  -> : composante de la vitesse
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DUDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 * DOUBLE PRECISION W1..3(NCELET) :  -  : tableaux de travail
 *
 * Le tableau DUDXYZ est de taille (NCELET-NCEL)*3*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinu1, PEINU1)
(
 const cs_int_t    *isou,
 const cs_int_t    *iphas,
       cs_real_t   *dudxyz,
       cs_real_t    w1[],
       cs_real_t    w2[],
       cs_real_t    w3[]
) ;


/*----------------------------------------------------------------------------
 * On fait tourner le tenseur DUDXYZ
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINU2 (VAR)
 * *****************
 *
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DUDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 *
 * Le tableau DUDXYZ est de taille (NCELET-NCEL)*3*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinu2, PEINU2)
(
 const cs_int_t    *iphas,
       cs_real_t   *dudxyz

) ;


/*----------------------------------------------------------------------------
 * Routine d'echange de tableaux pour PERINR
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINR1 (VAR)
 * *****************
 *
 * INTEGER          ISOU          :  -> : composante du tenseur de Reynolds
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DRDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 * DOUBLE PRECISION W1..3(NCELET) :  -  : tableaux de travail
 *
 * Le tableau DRDXYZ est de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinr1, PEINR1)
(
 const cs_int_t    *isou,
 const cs_int_t    *iphas,
       cs_real_t   *drdxyz,
       cs_real_t    w1[],
       cs_real_t    w2[],
       cs_real_t    w3[]
) ;


/*----------------------------------------------------------------------------
 * On fait tourner le tenseur DRDXYZ
 *
 * Interface Fortran :
 *
 * SUBROUTINE PEINR2 (VAR)
 * *****************
 *
 * INTEGER          IPHAS         :  -> : numero de phase courante
 * DOUBLE PRECISION DRDXYZ        :  -> : gradient de U aux cellules halo pour
 *                                        l'approche explicite en periodicite
 *
 * Le tableau DRDXYZ est de taille (NCELET-NCEL)*6*3*NPHAS
 *----------------------------------------------------------------------------*/

void CS_PROCF (peinr2, PEINR2)
(
 const cs_int_t    *iphas,
       cs_real_t   *drdxyz
) ;


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __CS_PERIO_H__ */

