/*============================================================================
*
*                    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_MAILLAGE_H__
#define __CS_MAILLAGE_H__

/*============================================================================
 * Structure principale associée à un maillage
 *============================================================================*/

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

/*----------------------------------------------------------------------------
 *  Fichiers `include' BFT ou FVM
 *----------------------------------------------------------------------------*/

#include "fvm_defs.h"

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

#include "cs_base.h"
#include "cs_perio.h"


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

/* Type de voisinage étendu, recu de l'Enveloppe */

#define CS_MAILLAGE_TYPE_VOISET_SANS       0 /* Pas de voisinage étendu      */
#define CS_MAILLAGE_TYPE_VOISET_DANS_HALO  1 /* Voisinage étendu traité
                                                     dans le halo standard   */
#define CS_MAILLAGE_TYPE_VOISET_SEPARE     2 /* Voisinage étendu séparé      */


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

/* Structure associée à un maillage */

typedef struct {

  /* Indicateurs globaux */

  cs_int_t   dim;                  /* Dimension de l'espace */
  cs_int_t   num_dom;              /* Numéro du domaine local */
  cs_int_t   nbr_dom;              /* Nombre global de domaines */
  cs_int_t   nbr_per;              /* Nombre de périodicités */
  cs_int_t   ind_type_voiset;      /* Type de voisinage étendu :
                                      = CS_VOISET_TYPE_SANS
                                            : pas de voisinage étendu
                                      = CS_VOISET_TYPE_DANS_HALO
                                            : voisinage étendu dans le halo std
                                      = CS_VOISET_TYPE_SEPARE
                                            : voisinage étendu séparé  */

  /* Dimensions locales */

  cs_int_t   nbr_cel;              /* Nombre de cellules du maillage */
  cs_int_t   nbr_fac;              /* Nombre de faces internes du maillage */
  cs_int_t   nbr_fbr;              /* Nombre de faces de bord du maillage */
  cs_int_t   nbr_som;              /* Nombre de sommets du maillage */

  cs_int_t   lng_fac_som;          /* Taille connectivité faces -> sommets */
  cs_int_t   lng_fbr_som;          /* Taille de la connectivité
                                      faces de bord -> sommets */

  cs_int_t   nbr_cel_etendu;       /* Nombre de cellules étendu
                                      (nbr_cel + nbr_cel_fac_par) */
  cs_int_t   nbr_cel_fac_par;      /* Nombre de cellules "fantômes" */
  cs_int_t   nbr_dom_fac_par;      /* Nombre de domaines sur frontière
                                      parallèle */
  cs_int_t   nbr_cel_fac_par_voiset;
                                   /* Nombre de cellules "fantômes" pour le
                                      voisinage étendu séparé  */
  cs_int_t   nbr_dom_fac_par_voiset;
                                   /* Nombre de domaines sur frontière
                                      parallèle pour le
                                      voisinage étendu séparé  */
  cs_int_t   nbr_val_connect_voiset_cel_cel_dom;
                                   /* Longueur lelvse du tableau
                                      val_connect_voiset_cel_cel_dom des valeurs
                                      de la connectivité du voisinage étendu
                                      On pourrait s'affranchir de cette variable
                                      (dont la valeur est égale à
                                      pos_connect_voiset_cel_cel_dom[nbr_cel]-1)
                                      dans la mesure où, actuellement,
                                        - le tableau des positions
                                          pos_connect_voiset_cel_cel_dom
                                          est envoyé par l'enveloppe avant
                                          le tableau des valeurs
                                          val_connect_voiset_cel_cel_dom
                                        - le tableau des valeurs est alloué
                                          en C uniquement et pas en FORTRAN   */

  /* Dimensions globales */

  cs_int_t   nbr_cel_glob;         /* Nombre de cellules global */
  cs_int_t   nbr_fac_glob;         /* Nombre de faces internes global */
  cs_int_t   nbr_fbr_glob;         /* Nombre de faces de bord global */
  cs_int_t   nbr_som_glob;         /* Nombre de sommets global */

  /* Structures locales */

  cs_real_t  *coo_som;             /* Coordonnées des sommets */
  cs_int_t   *fac_cel;             /* Connectivité faces internes -> cellules */
  cs_int_t   *fbr_cel;             /* Connectivité faces de bord -> cellules */
  cs_int_t   *pos_fac_som;         /* Positions de départ dans la
                                      connectivité faces internes -> sommets */
  cs_int_t   *val_fac_som;         /* Connectivité faces internes -> sommets */
  cs_int_t   *pos_fbr_som;         /* Positions de départ dans la
                                      connectivité faces de bord -> sommets */
  cs_int_t   *val_fbr_som;         /* Connectivité faces de bord -> sommets */

  /* Numérotations globales */

  fvm_gnum_t  *num_cel;            /* Numéros globaux des cellules */
  fvm_gnum_t  *num_fac;            /* Numéros globaux des faces internes
                                      (restent en numérot. locale initiale) */
  fvm_gnum_t  *num_fbr;            /* Numéros globaux des faces de bord
                                      (restent en numérot. locale initiale) */
  fvm_gnum_t  *num_som;            /* Numéros globaux des sommets */

  /* Structures auxiliaires pour parallélisme et périodicité */

  cs_int_t   *pos_dom_fac_par;     /* Pointeurs sur blocs de cellules "fantômes"
                                      associés à une frontière parallèle */
  cs_int_t   *pos_per_fac_par;     /* Pointeurs sur blocs de cellules "fantômes"
                                      associés à une frontière parallèle dans
                                      le cas d'une périodicité */
  cs_int_t   *num_cel_fac_par;     /* Numéros locaux des cellules "fantômes" */
  cs_int_t   *num_dom_fac_par;     /* Numéros de domaines sur frontière
                                      parallèle */

  cs_param_perio_t *liste_param_per;   /* Paramètres de périodicité */

  /* Structures associées aux voisinages étendus */

  cs_int_t   *pos_dom_fac_par_voiset; /* Pointeurs sur blocs de cellules
                                         "fantômes" associés à une frontière
                                         parallèle pour le voisinage
                                         étendu séparé */
  cs_int_t   *pos_per_fac_par_voiset; /* Pointeurs sur blocs de cellules
                                         "fantômes" associés à une frontière
                                         parallèle dans le cas d'une périodicité
                                         pour le voisinage étendu séparé */
  cs_int_t   *num_cel_fac_par_voiset; /* Numéros locaux des cellules "fantômes"
                                         pour le voisinage étendu séparé  */
  cs_int_t   *num_dom_fac_par_voiset; /* Numéros de domaines sur frontière
                                         parallèle pour le voisinage
                                         étendu séparé  */
  cs_real_t   *coord_cel_avec_voiset; /* Coordonnées du centre des cellules
                                         réelles et "fantômes"
                                         pour le voisinage étendu séparé  */

  cs_int_t  *pos_connect_voiset_cel_cel_dom;
                                      /* Position de la première cellule dans la
                                         connectivité voisinage étendu : ipcvse */
  cs_int_t  *val_connect_voiset_cel_cel_dom;
                                      /* Numéro local des cellules dans la
                                         connectivité voisinage étendu : ielvse */

  /* Historique des numérotations (pour échanges et suites) */

  cs_int_t   *num_fac_ini;            /* Numérotation ini. des faces internes
                                         (si ces faces sont renumérotées) */
  cs_int_t   *num_fbr_ini;            /* Numérotation ini. des faces de bord
                                         (si ces faces sont renumérotées) */

  /* Références des faces (groupes et familles) */

  cs_int_t    nbr_grp;                /* Nombre de groupes associés */
  cs_int_t   *pos_grp;                /* Position de départ de chaque groupe
                                         dans le tableau des noms de groupe */
  char       *nom_grp;                /* Tableau des noms des groupes */

  cs_int_t    nbr_prop_fam_max;       /* Nombre de propriétés maximal pour
                                         une famille */
  cs_int_t    nbr_fam;                /* Nombre de familles */

  cs_int_t   *prop_fam;               /* Propriétés des familles */
  cs_int_t   *fam_cel;                /* Familles des cellules */
  cs_int_t   *fam_fbr;                /* Familles des faces de bord */

} cs_maillage_t ;


/* Structures de type "tampon" associées à un maillage */

#if defined(_CS_HAVE_MPI)

typedef struct {

  cs_int_t       nbr_dom_var_assembl;
                                   /* Nombre de domaines auxquels le processeur
                                      courant envoie de l'information        */
  cs_int_t       nbr_dom_var_assembl_voiset;
                                   /* Nombre de domaines auxquels le processeur
                                      courant envoie de l'information du
                                      voisinage étendu, s'il est traité
                                      séparément */

  MPI_Request   *mpi_request;      /* Tableau de requêtes MPI */
  MPI_Status    *mpi_status;       /* Tableau de codes de retour MPI */

  cs_int_t      *num_cel_loc_par;  /* Numéro local des cellules à envoyer */
  cs_int_t      *pos_dom_var_assembl;
                                   /* Repérage des cases destinées aux
                                      différents voisins dans var_assembl */
  cs_int_t      *num_dom_var_assembl;
                                   /* Numéro des domaines auxquels le processeur
                                      courant envoie de l'information  */

  cs_int_t      *num_cel_loc_par_voiset;
                                   /* Numéro local des cellules à envoyer
                                      pour le voisinage étendu s'il est traité
                                      séparément */
  cs_int_t      *pos_dom_var_assembl_voiset;
                                   /* Repérage des cases destinées aux
                                      différents voisins dans var_assembl
                                      pour le voisinage étendu s'il est traité
                                      séparément */
  cs_int_t      *num_dom_var_assembl_voiset;
                                   /* Numéro des domaines auxquels le processeur
                                      courant envoie de l'information du
                                      voisinage étendu s'il est traité
                                      séparément */

  cs_real_t     *var_assembl;      /* Tableau d'assemblage temporaire */

  cs_real_t     *var_assembl_voiset;
                                   /* Tableau d'assemblage temporaire
                                      pour le voisinage étendu s'il est traité
                                      séparément */

  cs_real_t     *var_cel_avec_voiset;
                                   /* Tableau de réception pour
                                      le voisinage étendu s'il est traité
                                      séparément : longueur ncelet+voiset*/

} cs_maillage_tmp_t ;

#endif

/*=============================================================================
 * Variables globales_statiques
 *============================================================================*/

extern cs_maillage_t *cs_glob_maillage; /* Pointeur sur le maillage principal */

#if defined(_CS_HAVE_MPI)
extern cs_maillage_tmp_t *cs_glob_maillage_tmp ; /* Pointeur sur la structure
                                                    de tampons associée au
                                                    maillage principal */
#endif


/*============================================================================
 *  Fonctions publiques pour API Fortran
 *============================================================================*/

/*----------------------------------------------------------------------------
 * Recherche du numéro de groupe correspondant à un nom donné. Si le groupe
 * existe, le numéro renvoyé correspond au rang du groupe (commençant à 1)
 * dans la liste des groupes du maillage, et multiplié par -1. Cette
 * numérotation est celle utilisée dans le tableau IPRFML(NFML, NPRFML)
 * de description des familles.
 *
 * Si le groupe de nom indiqué n'existe pas, on renvoie 9999.
 *
 * Interface Fortran :
 *
 * FUNCTION NUMGRP (NOMGRP, LNGNOM)
 * ***************
 *
 * CHARACTER*       NOMGRP      : --> : Nom du groupe recherché
 * INTEGER          LNGNOM      : --> : Longueur du nom du groupe
 *----------------------------------------------------------------------------*/

cs_int_t CS_PROCF (numgrp, NUMGRP)
(
 const char       *const nomgrp,  /* --> Nom du groupe                        */
 const cs_int_t   *const lngnom   /* --> Longueur du nom                      */
 CS_ARGF_SUPP_CHAINE              /*     (arguments 'longueur' éventuels F77, */
                                  /*     inutilisés lors de l'appel mais      */
                                  /*     placés par de nombreux compilateurs) */
);


/*----------------------------------------------------------------------------
 * Sauvegarde des numérotations initiales des faces
 *
 * Remarque : lorsque des faces sont renumérotées, les connectivités et
 *            variables basées sur les faces sont toutes mises à jour, sauf
 *            les numéros globaux associés à ces faces (en cas de parallélisme)
 *            et conservés dans la structure maillage ('num_fac'et num_fbr') ;
 *            en effet, cette numérotation est destinée à se ramener à la
 *            numérotation initiale, notamment pour l'écriture et la lecture de
 *            fichiers suite indépendants du nombre de domaines en parallélisme
 *            ou d'une renumérotation vectorielle, et il est plus aisé de la
 *            manipuler si elle n'est pas modifiée.
 *
 * Interface Fortran :
 *
 * SUBROUTINE SAVNUM (IVECTV, IVECTB, INUMFI, INUMFB)
 * *****************
 *
 * INTEGER          IVECTV      : --> : Indicateur renum. faces internes
 * INTEGER          IVECTB      : --> : Indicateur renum. faces de bord
 * INTEGER          INUMFI      : --> : Table de renum. des faces internes
 * INTEGER          INUMFB      : --> : Table de renum. des faces de bord
 *----------------------------------------------------------------------------*/

void CS_PROCF (savnum, SAVNUM)
(
 const cs_int_t   *const ivectv,  /* --> Indicateur renum. faces internes     */
 const cs_int_t   *const ivectb,  /* --> Indicateur renum. faces de bord      */
 const cs_int_t   *const inumfi,  /* --> Table de renum. des faces internes   */
 const cs_int_t   *const inumfb   /* --> Table de renum. des faces de bord    */
);


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

/*----------------------------------------------------------------------------
 * Création d'une structure maillage
 *----------------------------------------------------------------------------*/

cs_maillage_t * cs_maillage_cree
(
  void
);


/*----------------------------------------------------------------------------
 * Destruction d'une structure maillage
 *----------------------------------------------------------------------------*/

cs_maillage_t * cs_maillage_detruit
(
  cs_maillage_t * maillage
);


/*----------------------------------------------------------------------------
 * Renumérotation des sommets de manière à assurer que :
 * si i < j, maillage->num_som[i] < maillage->num_som[j]
 * (ce qui n'est pas assuré par la numérotation initialement
 * fournie par l'Enveloppe).
 *----------------------------------------------------------------------------*/

void cs_maillage_ordonne_sommets
(
 cs_maillage_t      *const maillage      /* <-> Structure maillage associée   */
);


/*----------------------------------------------------------------------------
 * Affichage d'informations relatives à un maillage
 *----------------------------------------------------------------------------*/

void cs_maillage_info
(
 const cs_maillage_t  *maillage
);


#if defined(_CS_HAVE_MPI)

/*----------------------------------------------------------------------------
 * Création d'une structure de tampons associée à un maillage
 *----------------------------------------------------------------------------*/

cs_maillage_tmp_t * cs_maillage_tmp_cree
(
 cs_maillage_t  * maillage
);


/*----------------------------------------------------------------------------
 * Desctruction d'une structure de tampons associée à un maillage
 *----------------------------------------------------------------------------*/

cs_maillage_tmp_t * cs_maillage_tmp_detruit
(
 cs_maillage_tmp_t * maillage_tmp
);


/*----------------------------------------------------------------------------
 * Tableaux supplémentaires d'un maillage pour le parallélisme
 *----------------------------------------------------------------------------*/

void cs_maillage_init_parallel
(
 cs_maillage_t      *maillage,
 cs_maillage_tmp_t  *maillage_tmp
);


#endif /* _CS_HAVE_MPI */


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __CS_MAILLAGE_H__ */
