Logo Search packages:      
Sourcecode: ecs version File versions  Download package

ecs_pre_gambit.c

/*============================================================================
 *  Définition de la fonction
 *   de lecture d'un fichier de maillage GAMBIT neutral
 *============================================================================*/

/*
  This file is part of the Code_Saturne Preprocessor, element of the
  Code_Saturne CFD tool.

  Copyright (C) 1999-2007 EDF S.A., France

  contact: saturne-support@edf.fr

  The Code_Saturne Preprocessor 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 Preprocessor 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 Preprocessor; if not, write to the
  Free Software Foundation, Inc.,
  51 Franklin St, Fifth Floor,
  Boston, MA  02110-1301  USA
*/


/*----------------------------------------------------------------------------
 *  Fichiers `include' librairie standard C ou BFT
 *----------------------------------------------------------------------------*/

#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include <bft_file.h>
#include <bft_mem.h>
#include <bft_printf.h>


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles du  paquetage global "Utilitaire"
 *----------------------------------------------------------------------------*/

#include "ecs_chaine_glob.h"
#include "ecs_def.h"
#include "ecs_elt_typ_liste.h"
#include "ecs_tab.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles des paquetages visibles
 *----------------------------------------------------------------------------*/

#include "ecs_descr.h"
#include "ecs_champ.h"
#include "ecs_champ_att.h"
#include "ecs_entmail.h"
#include "ecs_maillage.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles du  paquetage courant
 *----------------------------------------------------------------------------*/

#include "ecs_entmail_pre.h"


/*----------------------------------------------------------------------------
 *  Fichier  `include' du  paquetage courant associé au fichier courant
 *----------------------------------------------------------------------------*/

#include "ecs_pre_gambit.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' privés   du  paquetage courant
 *----------------------------------------------------------------------------*/


/*============================================================================
 *  Structures locales
 *============================================================================*/

/*============================================================================
 *                       Définition de constantes globales statiques
 *============================================================================*/


/* Liste des identificateurs de description des elements finis */
/*=============================================================*/

#define ECS_GAMBIT_EDGE            1
#define ECS_GAMBIT_QUADRILATERAL   2
#define ECS_GAMBIT_TRIANGLE        3
#define ECS_GAMBIT_BRICK           4
#define ECS_GAMBIT_WEDGE           5
#define ECS_GAMBIT_TETRAHEDRON     6
#define ECS_GAMBIT_PYRAMID         7

/* Définition des éléments */
/*=========================*/

typedef struct {

  ecs_int_t       gambit_typ    ; /* Type GAMBIT de l'élément  */
  ecs_elt_typ_t   ecs_typ       ; /* Type ECS    de l'élément  */
  ecs_int_t       nbr_som[4]    ; /* Nombre de sommets GAMBIT (variantes 1-4) */
  ecs_int_t       ind_som[4][8] ; /* Numéros de sommets ECS   (variantes 1-4) */
  ecs_int_t       nbr_sselt     ; /* Nombre de sous-éléments */
  ecs_sous_elt_t  sous_elt[6]   ; /* Déf. sous-éléments (numérotation locale
                                   * usuelle de l'Enveloppe, mais de 0 à n-1
                                   * au lieu de 1 à n) */

} ecs_loc_gambit_elt_t ;


static const ecs_loc_gambit_elt_t  ecs_loc_gambit_elt_liste_c[7] = {

  {                        /* 1 */
    ECS_GAMBIT_EDGE,
    ECS_ELT_TYP_ARE,
    { 2, 3, 0, 0 },
    {
      { 0, 1 },
      { 0, 2 }
    },
    0,
    {                                              /*    1       2            */
      {ECS_ELT_TYP_NUL  , {0}}
    }
  },
  {                        /* 2 */
    ECS_GAMBIT_QUADRILATERAL,
    ECS_ELT_TYP_FAC_QUAD,
    { 4, 8, 9, 0 },
    {
      { 0, 1, 2, 3 },
      { 0, 2, 4, 6 },
      { 0, 2, 4, 6 }
    },
    4,
    {                                              /*  3 x-------x 2          */
      {ECS_ELT_TYP_ARE  , { 0, 1 }} ,              /*    |       |            */
      {ECS_ELT_TYP_ARE  , { 1, 2 }} ,              /*    |       |            */
      {ECS_ELT_TYP_ARE  , { 2, 3 }} ,              /*    |       |            */
      {ECS_ELT_TYP_ARE  , { 3, 0 }}                /*  0 x-------x 1          */
    }                                              /*                         */
  },
  {                        /* 3 */
    ECS_GAMBIT_TRIANGLE,
    ECS_ELT_TYP_FAC_TRIA,
    { 3, 6, 7, 0 },
    {
      { 0, 1, 2 },
      { 0, 2, 4 },
      { 0, 2, 4 }
    },
    3,
    {                                              /*        x 2              */
      {ECS_ELT_TYP_ARE  , { 0, 1 }} ,              /*       / \               */
      {ECS_ELT_TYP_ARE  , { 1, 2 }} ,              /*      /   \              */
      {ECS_ELT_TYP_ARE  , { 2, 0 }}                /*     /     \             */
    }                                              /*  0 x-------x 1          */
  },
  {                        /* 4 */
    ECS_GAMBIT_BRICK,
    ECS_ELT_TYP_CEL_HEXA,
    { 8, 20, 27, 0 },
    {
      {  4,  5,  1,  0,  6,  7,  3,  2 },
      { 12, 14,  2,  0, 17, 19,  7,  5 },
      { 18, 20,  2,  0, 24, 26,  8,  6 }
    },
    6,                                             /*     7 x-------x 6       */
    {                                              /*      /|      /|         */
      {ECS_ELT_TYP_FAC_QUAD, { 3, 2, 1, 0 }},      /*     / |     / |         */
      {ECS_ELT_TYP_FAC_QUAD, { 2, 6, 5, 1 }},      /*  4 x-------x5 |         */
      {ECS_ELT_TYP_FAC_QUAD, { 6, 7, 4, 5 }},      /*    | 3x----|--x 2       */
      {ECS_ELT_TYP_FAC_QUAD, { 7, 3, 0, 4 }},      /*    | /     | /          */
      {ECS_ELT_TYP_FAC_QUAD, { 2, 3, 7, 6 }},      /*    |/      |/           */
      {ECS_ELT_TYP_FAC_QUAD, { 0, 1, 5, 4 }}       /*  0 x-------x 1          */
    }
  },
  {                       /*  5 */
    ECS_GAMBIT_WEDGE,
    ECS_ELT_TYP_CEL_PRISM,
    { 6, 15, 18, 0 },
    {
      { 0,  1,  2,  3,  4,  5 },
      { 0,  2,  5,  9, 11, 14 },
      { 0,  2,  5, 12, 14, 17 }
    },                                             /*  3 x-------x 5          */
    5,                                             /*    |\     /|            */
    {                                              /*    | \   / |            */
      {ECS_ELT_TYP_FAC_QUAD, { 0, 1, 4, 3 }},      /*  0 x- \-/ -x 2          */
      {ECS_ELT_TYP_FAC_QUAD, { 1, 2, 5, 4 }},      /*     \ 4x  /             */
      {ECS_ELT_TYP_FAC_QUAD, { 2, 0, 3, 5 }},      /*      \ | /              */
      {ECS_ELT_TYP_FAC_TRIA, { 0, 2, 1 }   },      /*       \|/               */
      {ECS_ELT_TYP_FAC_TRIA, { 3, 4, 5 }   }       /*        x 1              */
    }
  },
  {                        /* 6 */
    ECS_GAMBIT_TETRAHEDRON,
    ECS_ELT_TYP_CEL_TETRA,
    { 4, 10, 0, 0 },
    {
      { 0,  1,  2,  3 },
      { 0,  2,  5,  9 }
    },                                             /*        x 3              */
    4,                                             /*       /|\               */
    {                                              /*      / | \              */
      {ECS_ELT_TYP_FAC_TRIA, { 1, 0, 2 }},         /*     /  |  \             */
      {ECS_ELT_TYP_FAC_TRIA, { 0, 1, 3 }},         /*  0 x- -|- -x 2          */
      {ECS_ELT_TYP_FAC_TRIA, { 1, 2, 3 }},         /*     \  |  /             */
      {ECS_ELT_TYP_FAC_TRIA, { 2, 0, 3 }}          /*      \ | /              */
    }                                              /*       \|/               */
  },                                               /*        x 1              */
  {                        /* 7 */
    ECS_GAMBIT_PYRAMID,
    ECS_ELT_TYP_CEL_PYRAM,
    { 5, 13, 14, 18 },
    {
      { 0,  1,  3,  2,  4 },
      { 0,  2,  7,  5, 12 },
      { 0,  2,  8,  6, 12 },
      { 0,  2,  8,  6, 17 }
    },                                             /*         4 x             */
    5,                                             /*          /|\            */
    {                                              /*         //| \           */
      {ECS_ELT_TYP_FAC_QUAD, { 0, 3, 2, 1 }},      /*        // |  \          */
      {ECS_ELT_TYP_FAC_TRIA, { 0, 1, 4 }   },      /*     3 x/--|---x 2       */
      {ECS_ELT_TYP_FAC_TRIA, { 1, 2, 4 }   },      /*      //   |  /          */
      {ECS_ELT_TYP_FAC_TRIA, { 2, 3, 4 }   },      /*     //    | /           */
      {ECS_ELT_TYP_FAC_TRIA, { 3, 0, 4 }   }       /*  0 x-------x 1          */
    },
  }
} ;


/* Definition des groupes */
/*========================*/

        /* Longueur des noms de groupe                    */
#define ECS_GAMBIT_LEN_GROUP_NAME                                    40

        /* Nombre max d'entites par ligne                 */
        /* pour la definition des groupes                 */
#define ECS_GAMBIT_NBR_GRP_ENT_PER_LINE2                              2
        /* Idem pour les anciens dataset                  */
#define ECS_GAMBIT_NBR_GRP_ENT_PER_LINE4                              4


/* Codes des entites appartenant a un groupe */
/*-------------------------------------------*/

#define ECS_GAMBIT_TYP_CODE_NODES                                     7
#define ECS_GAMBIT_TYP_CODE_ELEMENTS                                  8



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


/* Pour une lecture de 80 caracteres par ligne  */
/* auxquels il faut ajouter le `\n' et le `\0'  */
/* pour l'affectation dans la chaine receptrice */
/* On ajoute 2 caracteres de securite pour les  */
/* fichiers au format 'DOS'                     */
#define ECS_LOC_LNG_MAX_CHAINE_GAMBIT  84        /* Dimension des chaines */

static const int ecs_loc_nbr_max_elt_c = 1000 ; /* Nombre initial d'elements  */
static const int ecs_loc_nbr_moy_som_c =    8 ; /* Nombre initial de sommets  */
                                                /*  par element en moyenne    */



/*============================================================================
 *  Prototypes de fonctions privées
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Remplissage d'une chaîne de taille ECS_LOC_LNG_MAX_CHAINE_GAMBIT
 *  par des blancs (initialisation)
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__raz_chaine
(
 char                         *const chaine
) ;

/*----------------------------------------------------------------------------
 *  Lecture de la fin d'une rubrique
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__fin_section
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne      /* <-> Cpt. lignes lues   */
) ;

/*----------------------------------------------------------------------------
 *  Saut d'une rubrique
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__saut_section
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne      /* <-> Cpt. lignes lues   */
) ;


/*----------------------------------------------------------------------------
 *  Lecture de l'entête
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_entete
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne    , /* <-> Cpt. lignes lues   */
 ecs_dim_t                    *const dim_e        , /* --> Dim. espace        */
 ecs_int_t                    *const nbr_som      , /* --> Nb. sommets        */
 ecs_int_t                    *const nbr_elt      , /* --> Nb. éléments       */
 ecs_int_t                    *const nbr_grp      , /* --> Nb. groupes        */
 ecs_int_t                    *const nbr_cl         /* --> Nb. C.L.           */
) ;


/*----------------------------------------------------------------------------
 *  Lecture des coordonnées des sommets
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_coords
(                                          /* <-- Renvoie entite de maillage  */
                                           /*     correspondant aux sommets   */
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 ecs_dim_t      dim_e                    , /* --> Dimension spatiale          */
 ecs_int_t      nbr_som                  , /* --> Nombre de sommets           */
 ecs_real_t     som_val_coord[]          , /* <-- Coordonnées des sommets     */
 ecs_int_t      som_val_label[]          , /* <-- Labels des sommets          */
 ecs_int_t     *num_ligne                  /* <-> Compteur des lignes lues    */
) ;


/*----------------------------------------------------------------------------
 *  Lecture de la table de connectivité
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_elements
(
 bft_file_t  *fic_maillage               , /* --> Descripteur fichier a lire  */
 size_t       nbr_elt                    , /* --> Nombre d'élements           */
 ecs_int_t   *num_ligne                  , /* <-> Compteur des lignes lues    */
 size_t       cpt_elt_ent[]              , /* <-- Nombre d'elems/entité       */
 ecs_size_t  *elt_pos_som_ent[]          , /* <-- Positions numéros som       */
 ecs_int_t   *elt_val_som_ent[]          , /* <-- Numéros des sommets         */
 ecs_int_t   *elt_val_typ_geo_ent[]      , /* <-- Types géométriques          */
 ecs_int_t   *elt_val_label_ent[]          /* <-- Etiquettes                  */
) ;


/*----------------------------------------------------------------------------
 *  Lecture d'un groupe
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_groupe
(
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 ecs_int_t     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_size_t    *nbr_elt_grp              , /* <-- Nombre d'éléments associés  */
 char         **nom_grp                  , /* <-- Nom du groupe associé       */
 ecs_int_t    **num_elt_grp                /* <-- Tableau labels des éléments */
) ;


/*----------------------------------------------------------------------------
 *  Lecture d'une condition aux limites
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_cl
(
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 ecs_int_t     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_size_t    *nbr_elt_cl               , /* <-- Nombre d'éléments associés  */
 char         **nom_cl                   , /* <-- Nom du groupe associé       */
 ecs_int_t    **num_elt_cl               , /* <-- Tableau labels des éléments */
 ecs_int_t    **num_fac_cl                 /* <-- Tableau faces des éléments  */
) ;


/*----------------------------------------------------------------------------
 *  Transformation de numéros de labels en indice.
 *
 *  On utilise une numérotation de 1 à n, avec un signe positif pour
 *  un indice correspondant à l'entité de plus haut niveau, un signe
 *  négatif pour l'entité inférieure, et 0 pour les labels "non trouvés"
 *  (correspondant probablement à une entité inférieure).
 *
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__label_en_indice
(
 ecs_int_t       nbr_lst                  , /* --> Nombre de listes           */
 ecs_size_t      nbr_label_lst[]          , /* --> Nombre de labels par liste */
 ecs_int_t      *val_label_lst[]          , /* <-> Nums. entités /groupes     */
 size_t          nbr_elt_ent[]            , /* --> Nombre d'élts. par entité  */
 ecs_int_t      *val_label_ent[]            /* --> Tableau labels par entité  */
) ;


/*----------------------------------------------------------------------------
 *  Construction des éléments surfaciques supplémentaires.
 *  On convertit les références num_elt_cl[] à une entité principale
 *  en des référence à la sous-entité, et on libère les références
 *  num_fac_cl[] à une face de chaque élément de l'entité principale.
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__cree_ent_sub
(
 ecs_int_t    nbr_cl                     , /* --> Nb. C.L.                   */
 ecs_size_t   nbr_elt_cl[]               , /* --> Nb. entités / C.L.         */
 ecs_int_t   *num_elt_cl[]               , /* --> Nums. entités / C.L.       */
 ecs_int_t   *num_fac_cl[]               , /* --> Nums. faces / C.L.         */
 size_t       nbr_elt_ent[]              , /* <-- Nombre d'elems/entité      */
 ecs_size_t  *elt_pos_som_ent[]          , /* <-- Positions numéros som      */
 ecs_int_t   *elt_val_som_ent[]          , /* <-- Numéros des sommets        */
 ecs_int_t   *elt_val_typ_geo_ent[]        /* <-> Types géométriques         */
) ;


/*----------------------------------------------------------------------------
 *  Construction effective des groupes
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__cree_groupes
(
 ecs_int_t       nbr_grp                  , /* --> Nb. groupes                */
 ecs_size_t      nbr_elt_grp[]            , /* --> Nb. entités / groupe       */
 char           *nom_grp[]                , /* --> Noms des groupes           */
 ecs_int_t      *num_elt_grp[]            , /* --> Nums. entités /groupes     */
 ecs_entmail_t **vect_entmail               /* <-> Entités maillage à remplir */
) ;


/*============================================================================
 *  Fonctions publiques
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Lecture d'un fichier au format GAMBIT neutral
 *   et affectation des donnees dans la structure de maillage
 *
 *  Hypothèses de lecture :
 *   le dataset sur les groupes doit se trouver placer dans le fichier Gambit
 *   après les dataset sur les noeuds et sur les éléments ; le dataset
 *   sur noeuds doit lui-même se trouver après celui sur les systèmes de
 *   coordonnées.
 *----------------------------------------------------------------------------*/

ecs_maillage_t * ecs_pre_gambit__lit_maillage
(                                       /* <-- Renvoie un pointeur sur        */
                                        /*      une structure de maillage     */
 const char *const nom_fic_maillage     /* --> Nom du fichier a lire          */
)
{
  /* Variables pour le fichier */
  bft_file_t  *fic_maillage ;
  char         chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ; /* Ligne lue */
  ecs_int_t    num_ligne               ; /* Compteur des lignes lues          */

  /* Variables pour la définition des noeuds */
  ecs_real_t  *som_val_coord ;                       /* Coordonnées noeuds    */
  ecs_int_t   *som_val_label ;                       /* Labels des noeuds     */

  /* Variables pour la définition des éléments*/
  size_t       cpt_elt_ent        [ECS_ENTMAIL_FIN]; /* Nombre d'elems/entité */
  ecs_size_t  *elt_pos_som_ent    [ECS_ENTMAIL_FIN]; /* Positions numéros som */
  ecs_int_t   *elt_val_som_ent    [ECS_ENTMAIL_FIN]; /* Numéros des sommets   */
  ecs_int_t   *elt_val_typ_geo_ent[ECS_ENTMAIL_FIN]; /* Types géométriques    */
  ecs_int_t   *elt_val_label_ent  [ECS_ENTMAIL_FIN]; /* Etiquettes            */

  ecs_int_t    cpt_coul_ent[ECS_ENTMAIL_FIN];    /* Couleurs (tableaux vides) */
  ecs_int_t   *val_coul_ent[ECS_ENTMAIL_FIN];
  ecs_size_t  *cpt_elt_coul_ent[ECS_ENTMAIL_FIN];
  ecs_int_t   *elt_val_color_ent[ECS_ENTMAIL_FIN];

  ecs_maillage_t *maillage ;
  ecs_entmail_t  *vect_entmail[ECS_ENTMAIL_FIN];
  ecs_entmail_t **vect_entmail_ret ;

  /* Autres variables */

  ecs_int_t    ind ; /* Indice de boucle */

  ecs_bool_t   bool_elements_lus = ECS_FALSE ;
  ecs_bool_t   bool_sommets_lus = ECS_FALSE ;

  ecs_dim_t    dim_e   = ECS_DIM_3 ;
  ecs_int_t    nbr_som = 0 ;
  ecs_int_t    nbr_elt = 0 ;
  ecs_int_t    nbr_grp = 0 ;
  ecs_int_t    nbr_cl  = 0 ;

  ecs_int_t    cpt_grp = 0 ;
  ecs_int_t    cpt_cl  = 0 ;

  ecs_size_t  *nbr_elt_grp  = NULL ;
  char       **nom_grp      = NULL ;
  ecs_int_t  **num_elt_grp  = NULL ;

  ecs_size_t  *nbr_elt_cl   = NULL ;
  char       **nom_cl       = NULL ;
  ecs_int_t  **num_elt_cl   = NULL ;
  ecs_int_t  **num_fac_cl   = NULL ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Affichage du titre */
  /*====================*/

  bft_printf(_("\n\n"
               "Reading mesh from file in GAMBIT neutral format\n"
               "----------------------\n")) ;

  bft_printf(_("  Mesh file: %s\n\n\n"),
             nom_fic_maillage) ;


  /* Initialisations */
  /*=================*/

  som_val_coord = NULL ;
  som_val_label = NULL ;

  for (ind = ECS_ENTMAIL_DEB ; ind < ECS_ENTMAIL_FIN ; ind++) {

    /* Couleurs inutilisées ici, mais les tableaux doivent être définis */
    cpt_coul_ent[ind] = 0 ;
    val_coul_ent[ind] = NULL ;
    cpt_elt_coul_ent[ind] = NULL ;
    elt_val_color_ent[ind] = NULL ;

  }

  num_ligne = 1 ;
  dim_e     = ECS_DIM_3 ;


  /* Ouverture du fichier Gambit en lecture */
  /*---------------------------------------*/

  fic_maillage = bft_file_open(nom_fic_maillage,
                               BFT_FILE_MODE_READ,
                               BFT_FILE_TYPE_TEXT) ;


  /*================================================*/
  /* Boucle sur les lignes du fichier de maillage : */
  /* tant qu'on n'a pas atteint la fin de fichier   */
  /*================================================*/


  while (bft_file_gets_try(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                           fic_maillage, &num_ligne) != NULL) {


    /* Décodage selon le type de section de GAMBIT */
    /*=============================================*/

    if (strncmp(chaine, "        CONTROL INFO", 20) == 0) {

      ecs_loc_pre_gambit__lit_entete(fic_maillage,
                                     &num_ligne,
                                     &dim_e,
                                     &nbr_som,
                                     &nbr_elt,
                                     &nbr_grp,
                                     &nbr_cl) ;

      BFT_MALLOC(nbr_elt_grp, nbr_grp, ecs_size_t) ;
      BFT_MALLOC(nom_grp, nbr_grp, char *) ;
      BFT_MALLOC(num_elt_grp, nbr_grp, ecs_int_t *) ;

      for (ind = 0 ; ind < nbr_grp ; ind++) {
        nom_grp[ind] = NULL ;
        num_elt_grp[ind] = NULL ;
      }

      BFT_MALLOC(nbr_elt_cl, nbr_cl, ecs_size_t) ;
      BFT_MALLOC(nom_cl, nbr_cl, char *) ;
      BFT_MALLOC(num_elt_cl, nbr_cl, ecs_int_t *) ;
      BFT_MALLOC(num_fac_cl, nbr_cl, ecs_int_t *) ;

      for (ind = 0 ; ind < nbr_cl ; ind++) {
        nom_cl[ind] = NULL ;
        num_elt_cl[ind] = NULL ;
        num_fac_cl[ind] = NULL ;
      }

    }

    else if (strncmp(chaine, "    APPLICATION DATA", 20) == 0)

      ecs_loc_pre_gambit__saut_section(fic_maillage,
                                       &num_ligne) ;

    else if (strncmp(chaine, "   NODAL COORDINATES", 20) == 0) {

      /* Lecture des coordonnées des noeuds */

      BFT_MALLOC(som_val_coord, nbr_som * ECS_DIM_3, ecs_real_t) ;
      BFT_MALLOC(som_val_label, nbr_som, ecs_int_t) ;


      ecs_loc_pre_gambit__lit_coords(fic_maillage,
                                     dim_e,
                                     nbr_som,
                                     som_val_coord,
                                     som_val_label,
                                     &num_ligne) ;

      bool_sommets_lus = ECS_TRUE ;

    }

    else if (strncmp(chaine, "      ELEMENTS/CELLS", 20) == 0) {

      /* Lecture des connectivités des éléments */

      ecs_loc_pre_gambit__lit_elements(fic_maillage,
                                       nbr_elt,
                                       &num_ligne,
                                       cpt_elt_ent,
                                       elt_pos_som_ent,
                                       elt_val_som_ent,
                                       elt_val_typ_geo_ent,
                                       elt_val_label_ent) ;

      bool_elements_lus = ECS_TRUE ;

    }

    else if (strncmp(chaine, "       ELEMENT GROUP", 20) == 0) {

      /* Lecture des groupes */

      if (cpt_grp >= nbr_grp)

        bft_error(__FILE__, __LINE__, 0,
                  _("Error reading a GAMBIT mesh file:\n"
                    "at line %d of file \"%s\".\n"
                    "The number of groups to read is larger\n"
                    "than that defined by the header (%d).n"),
                  (int)num_ligne, bft_file_get_name(fic_maillage),
                  (int)nbr_grp);


      ecs_loc_pre_gambit__lit_groupe(fic_maillage,
                                     &num_ligne,
                                     &(nbr_elt_grp[cpt_grp]),
                                     &(nom_grp[cpt_grp]),
                                     &(num_elt_grp[cpt_grp])) ;

      cpt_grp += 1 ;

    }

    else if (strncmp(chaine, " BOUNDARY CONDITIONS", 20) == 0) {

      /* Lecture des conditions aux limites */

      if (cpt_cl >= nbr_cl)

        bft_error(__FILE__, __LINE__, 0,
                  _("Error reading a GAMBIT mesh file:\n"
                    "at line %d of file \"%s\".\n"
                    "The number of boundary conditions to read is larger\n"
                    "than that defined by the header (%d).n"),
                  (int)num_ligne, bft_file_get_name(fic_maillage),
                  (int)nbr_cl);


      ecs_loc_pre_gambit__lit_cl(fic_maillage,
                                 &num_ligne,
                                 &(nbr_elt_cl[cpt_cl]),
                                 &(nom_cl[cpt_cl]),
                                 &(num_elt_cl[cpt_cl]),
                                 &(num_fac_cl[cpt_cl])) ;

      cpt_cl += 1 ;

    }

    else if (strncmp(chaine, "   FACE CONNECTIVITY", 20) == 0) {

      ecs_warn() ;
      bft_printf(_("File \"%s\"\n,"
                   "contains a \"FACE CONNECTIVITY\" section\n"
                   "indicating non-conforming faces which are not\n"
                   "automatically handled by the Preprocessor.\n"
                   "-> Use an appropriate joining option.\n"),
                 bft_file_get_name(fic_maillage)) ;

      ecs_loc_pre_gambit__saut_section(fic_maillage,
                                       &num_ligne) ;

    }

    else if (strncmp(chaine, "        TIMESTEPDATA", 20) == 0)

      ecs_loc_pre_gambit__saut_section(fic_maillage,
                                       &num_ligne) ;

    else {

      ecs_warn() ;
      bft_printf(_("Line %d of file \"%s\"\n,"
                   "section: \"%s\" is unknown.\n"),
                 num_ligne, bft_file_get_name(fic_maillage),
                 chaine) ;

      ecs_loc_pre_gambit__saut_section(fic_maillage,
                                       &num_ligne) ;

    }

  }

  /* On vérifie que la fin de fichier a bien été atteinte */

  if (bft_file_eof(fic_maillage) == 0) {
    ecs_warn() ;
    bft_printf(_("Line %d of file \"%s\",\n"
                 "processing is finished but the end of the file\n"
                 "has not been reached.\n\n"),
               (int)num_ligne, bft_file_get_name(fic_maillage)) ;
  }


  /* On verifie qu'on a bien lu des noeuds et des elements */

  if (bool_sommets_lus == ECS_FALSE)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading file \"%s\":\n"
                "Section \"NODAL COORDINATES\" was not found."),
              bft_file_get_name(fic_maillage)) ;

  if (bool_elements_lus == ECS_FALSE)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading file \"%s\":\n"
                "Section \"ELEMENTS/CELLS\" was not found."),
              bft_file_get_name(fic_maillage)) ;


  /* Fermeture du fichier de lecture du maillage */
  /*---------------------------------------------*/

  bft_file_free(fic_maillage) ;


  /* Construction effective du maillage */
  /*====================================*/

  bft_printf
    (_("  Building mesh structure:\n\n")) ;


  /* On Convertit les listes à labels en indices */
  /*---------------------------------------------*/

  ecs_loc_pre_gambit__label_en_indice(nbr_grp,
                                      nbr_elt_grp,
                                      num_elt_grp,
                                      cpt_elt_ent,
                                      elt_val_label_ent) ;

  ecs_loc_pre_gambit__label_en_indice(nbr_cl,
                                      nbr_elt_cl,
                                      num_elt_cl,
                                      cpt_elt_ent,
                                      elt_val_label_ent) ;


  /* On peut maintenant construire les éléments de peau associés aux. C.L. */
  /*=======================================================================*/

  ecs_loc_pre_gambit__cree_ent_sub(nbr_cl,
                                   nbr_elt_cl,
                                   num_elt_cl,
                                   num_fac_cl,
                                   cpt_elt_ent,
                                   elt_pos_som_ent,
                                   elt_val_som_ent,
                                   elt_val_typ_geo_ent) ;


  /* Les conditions aux limites sont maintenant définies comme des
     groupes ; on les transforme en groupes définis sur les
     faces au lieu des cellules */

  if (nbr_cl > 0) {

    BFT_REALLOC(nbr_elt_grp, nbr_grp + nbr_cl, ecs_size_t) ;
    BFT_REALLOC(nom_grp, nbr_grp + nbr_cl, char *) ;
    BFT_REALLOC(num_elt_grp, nbr_grp + nbr_cl, ecs_int_t *) ;

    for (ind = 0 ; ind < nbr_cl ; ind++) {
      nbr_elt_grp[nbr_grp + ind] = nbr_elt_cl[ind] ;
      nom_grp[nbr_grp + ind]     = nom_cl[ind] ;
      num_elt_grp[nbr_grp + ind] = num_elt_cl[ind] ;
    }

    nbr_grp += nbr_cl ;

  }

  BFT_FREE(nbr_elt_cl) ;
  BFT_FREE(nom_cl) ;
  BFT_FREE(num_elt_cl) ;
  BFT_FREE(num_fac_cl) ;


  /* On transfère les données dans la structure d'entité de maillage */
  /*=================================================================*/

  vect_entmail[ECS_ENTMAIL_SOM]
    = ecs_entmail_pre__cree_som(ECS_DIM_3,
                                nbr_som,
                                som_val_coord,
                                som_val_label) ;


  vect_entmail_ret = ecs_entmail_pre__cree_elt(cpt_elt_ent,
                                               elt_pos_som_ent,
                                               elt_val_som_ent,
                                               elt_val_label_ent,
                                               NULL,
                                               elt_val_color_ent,
                                               cpt_coul_ent,
                                               val_coul_ent,
                                               cpt_elt_coul_ent) ;


  for (ind = ECS_ENTMAIL_ARE ; ind < ECS_ENTMAIL_FIN ; ind++)
    vect_entmail[ind] = vect_entmail_ret[ind] ;

  BFT_FREE(vect_entmail_ret) ;


  /* On ajoute les groupes */
  /*-----------------------*/

  ecs_loc_pre_gambit__cree_groupes(nbr_grp,
                                   nbr_elt_grp,
                                   nom_grp,
                                   num_elt_grp,
                                   vect_entmail) ;


  /* Libérations */
  /*=============*/

  if (nbr_grp > 0) {
    for (ind = 0 ; ind < nbr_grp ; ind++) {
      BFT_FREE(nom_grp[ind]) ;
      BFT_FREE(num_elt_grp[ind]) ;
    }
    BFT_FREE(nbr_elt_grp) ;
    BFT_FREE(nom_grp) ;
    BFT_FREE(num_elt_grp) ;
  }


  maillage = ecs_maillage__cree_nodal(ECS_DIM_3,
                                      vect_entmail) ;


  return maillage ;

}


/*============================================================================
 *  Fonctions privées
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Remplissage d'une chaîne de taille ECS_LOC_LNG_MAX_CHAINE_GAMBIT
 *  par des blancs (initialisation)
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__raz_chaine
(
 char                         *const chaine
)
{
  int ind ;

  for (ind = 0 ; ind < ECS_LOC_LNG_MAX_CHAINE_GAMBIT ; ind++)
    chaine[ind] = ' ' ;

  chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT - 1] = '\0' ;
}

/*----------------------------------------------------------------------------
 *  Lecture de la fin d'une rubrique
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__fin_section
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne      /* <-> Cpt. lignes lues   */
)
{
  char  chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  if (strncmp(chaine, "ENDOFSECTION", 12) != 0)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading line %d of file \"%s\" ;\n"
                "An end of section (ENDOFSECTION) was expected."),
              *num_ligne, bft_file_get_name(fic_maillage));

}


/*----------------------------------------------------------------------------
 *  Saut d'une rubrique
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__saut_section
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne      /* <-> Cpt. lignes lues   */
)
{
  char  chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  do {
    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                  fic_maillage, num_ligne) ;
  } while (strncmp(chaine, "ENDOFSECTION", 12) != 0) ;

}


/*----------------------------------------------------------------------------
 *  Lecture de l'entête
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_entete
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne    , /* <-> Cpt. lignes lues   */
 ecs_dim_t                    *const dim_e        , /* --> Dim. espace        */
 ecs_int_t                    *const nbr_som      , /* --> Nb. sommets        */
 ecs_int_t                    *const nbr_elt      , /* --> Nb. éléments       */
 ecs_int_t                    *const nbr_grp      , /* --> Nb. groupes        */
 ecs_int_t                    *const nbr_cl         /* --> Nb. C.L.           */
)
{
  ecs_int_t  retour ;                 /* Retour fonctions `scan' pour test    */
  char       chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;           /* Ligne lue   */
  char       sch1[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;
  char       sch2[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;
  ecs_int_t  ind ;

  /* Variables GAMBIT lues */

  int numnp, nelem, ngprs, nbsets, ndfcd, ndfvl ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Format */
  /*--------*/

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  if (strncmp(chaine, "** GAMBIT NEUTRAL FILE", 22) != 0)
    bft_error(__FILE__, __LINE__, 0,
              _("Format error for file \"%s\":\n"
                "This file does not seem to be in GAMBIT neutral format\n"
                "(line 2 does not start with \"** GAMBIT NEUTRAL FILE\")."),
                bft_file_get_name(fic_maillage)) ;

  /* Titre */
  /*-------*/

  ecs_loc_pre_gambit__raz_chaine(chaine) ;

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  /*
    Suppression blancs en fin de titre (80 caractères en général rarement
    utilisés) pour affichage sur ligne plus courte
  */

  chaine[80] = '\0' ;
  for (ind = 80 ; ind > 0 && chaine[ind - 1] == ' ' ; ind--)
    chaine[ind] = '\0' ;

  bft_printf(_("  Title        : %.80s\n"), chaine) ;


  /* Source */
  /*--------*/

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  retour = sscanf(chaine, "%*s %s %*s %s", sch1, sch2) ;

  if (retour == 2)
    bft_printf(_("  Created with : %s %s\n"), sch1, sch2) ;


  /* Date et heure */
  /*---------------*/

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  chaine[80] = '\0' ;
  for (ind = 80 ; ind > 0 && chaine[ind - 1] == ' ' ; ind--)
    chaine[ind] = '\0' ;
  for (ind = 0 ; chaine[ind] != '\0' && chaine[ind] == ' ' ; ind++) ;

  bft_printf(_("  Date         : %s\n"), chaine + ind) ;


  /* Infos sur la taille */
  /*---------------------*/

  /* Ligne "     NUMNP     NELEM     NGRPS    NBSETS     NDFCD     NDFVL" */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  /* Ligne avec valeurs à lire */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  retour = sscanf(chaine, "%d %d %d %d %d %d",
                  &numnp, &nelem, &ngprs, &nbsets, &ndfcd, &ndfvl) ;

  if (retour != 6)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading line %d of file \"%s\"."),
              *num_ligne, bft_file_get_name(fic_maillage));

  bft_printf(_("  Initial data: %10d points\n"
               "                %10d elements\n"
               "                %10d groups\n"
               "                %10d boundary conditions\n"
               "                spatial dimension: %d\n"
               "                velocity components: %d\n\n"),
            numnp, nelem, ngprs, nbsets, ndfcd, ndfvl) ;

  /* Fin */
  /*-----*/

  ecs_loc_pre_gambit__fin_section(fic_maillage,
                                  num_ligne);

  *dim_e   = ndfcd ;
  *nbr_som = numnp ;
  *nbr_elt = nelem ;
  *nbr_grp = ngprs ;
  *nbr_cl  = nbsets ;

}


/*----------------------------------------------------------------------------
 *  Lecture des coordonnées des sommets
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_coords
(                                          /* <-- Renvoie entite de maillage  */
                                           /*     correspondant aux sommets   */
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 ecs_dim_t      dim_e                    , /* --> Dimension spatiale          */
 ecs_int_t      nbr_som                  , /* --> Nombre de sommets           */
 ecs_real_t     som_val_coord[]          , /* <-- Coordonnées des sommets     */
 ecs_int_t      som_val_label[]          , /* <-- Labels des sommets          */
 ecs_int_t     *num_ligne                  /* <-> Compteur des lignes lues    */
)
{

  ecs_int_t    retour ;
  ecs_int_t    isom ;
  ecs_int_t    icoo ;

  /* Variables Gambit lues */

  char         chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;
  int          num_nod ;
  double       coord[3];


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /*=========================================================*/
  /* Boucle de lecture des numéros et coordonnées des points */
  /*=========================================================*/

  for (isom = 0 ; isom < nbr_som ; isom++) {

    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                  fic_maillage, num_ligne) ;

    if (dim_e == 3)
      retour = sscanf(chaine, "%d %le %le %le",
                      &num_nod, coord, coord+1, coord+2) ;

    else if (dim_e == 2) {
      retour = sscanf(chaine, "%d %le %le",
                      &num_nod, coord, coord+1) ;
      coord[2] = 0.0 ;
    }

    if (retour != (int)(dim_e + 1))
      bft_error(__FILE__, __LINE__, 0,
                _("Error reading line %d of file \"%s\"\n"
                  "while decoding point %d (of %d)."),
                *num_ligne, bft_file_get_name(fic_maillage),
                (int)(isom + 1), (int)nbr_som) ;

    /* Coordonnees du sommet lu */

    for (icoo = 0 ; icoo < ECS_DIM_3 ; icoo++)
      som_val_coord[isom * ECS_DIM_3 + icoo] = coord[icoo] ;


    /* Etiquette   du sommet lu */

    som_val_label[isom] = num_nod ;

  }

  /* Fin de la rubrique */

  ecs_loc_pre_gambit__fin_section(fic_maillage,
                                  num_ligne);


  /* Maillage en dimension 3 */

  if (dim_e == ECS_DIM_2) {
    ecs_warn() ;
    bft_printf(_("The mesh is 2d.")) ;
  }

}


/*----------------------------------------------------------------------------
 *  Lecture de la table de connectivité
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_elements
(
 bft_file_t  *fic_maillage               , /* --> Descripteur fichier a lire  */
 size_t       nbr_elt                    , /* --> Nombre d'élements           */
 ecs_int_t   *num_ligne                  , /* <-> Compteur des lignes lues    */
 size_t       cpt_elt_ent[]              , /* <-- Nombre d'elems/entité       */
 ecs_size_t  *elt_pos_som_ent[]          , /* <-- Positions numéros som       */
 ecs_int_t   *elt_val_som_ent[]          , /* <-- Numéros des sommets         */
 ecs_int_t   *elt_val_typ_geo_ent[]      , /* <-- Types géométriques          */
 ecs_int_t   *elt_val_label_ent[]          /* <-- Etiquettes                  */
)
{

  ecs_int_t    retour               ; /* Retour fonctions `scan' pour test    */
  char         chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;          /* Ligne lue  */

  /* Variables GAMBIT lues */
  int          ne                   ; /* Numéro (label) de l'élément          */
  int          ntype                ; /* Type GAMBIT de l'élément             */
  int          ndp                  ; /* Nombre de noeuds de l'élément        */
  char         str_som_lus[27][9]   ; /* Sommets lus                          */
  ecs_int_t    som_elt[8]           ; /* Numeros des noeuds lus de l'élément  */

  ecs_int_t    nbr_som_elt          ; /* Nb de noeuds à lire = nbr de sommets */
  ecs_int_t    nbr_elt_ent_max      ;
  ecs_int_t    nbr_nod_elt_reste    ;
  ecs_int_t    nbr_nod_ligne        ;
  ecs_int_t    taille_connect_max   ;

  ecs_int_t    ind_ent              ; /* Indice de l'entité concernée         */
  ecs_int_t    num_pos              ; /* Nouvel indice de stockage            */

  size_t       ielt                 ; /* Indice de boucle sur les éléments    */
  ecs_int_t    inod                 ; /* Indice de boucle sur les noeuds      */
  ecs_int_t    inod_ligne           ; /* Indice de boucle sur une ligne       */
  ecs_int_t    isom                 ; /* Indice de boucle sur les sommets     */
  ecs_int_t    isub                 ; /* Indice de boucle sur sous-types      */

  const ecs_loc_gambit_elt_t  *type_elt_gambit ;
  const ecs_int_t             *ind_som_elt ;     /* Corresp. num. GAMBIT      *
                                                  * / num. locale des         *
                                                  * sommets d'un élément      */


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /*====================================================*/
  /* Initialisations et allocations des tableaux locaux */
  /*====================================================*/


  /* Attention au decalage de `1' !!!         */
  /* On n'alloue pas les tableaux locaux pour */
  /* `ECS_ENTMAIL_DEB = ECS_ENTMAIL_SOM'      */

  for (ind_ent = ECS_ENTMAIL_SOM ; ind_ent < ECS_ENTMAIL_FIN ; ind_ent++) {

    cpt_elt_ent        [ind_ent] = 0 ;

    elt_pos_som_ent     [ind_ent] = NULL ;
    elt_val_som_ent     [ind_ent] = NULL ;
    elt_val_typ_geo_ent [ind_ent] = NULL ;
    elt_val_label_ent   [ind_ent] = NULL ;

  }

  for (inod = 0; inod < 27 ; inod++)
    str_som_lus[inod][8] = '\0' ;


  /*==================================================*/
  /* Boucle de lecture des connectivités des éléments */
  /*==================================================*/

  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {

    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                  fic_maillage, num_ligne) ;

    /* Lecture des caracteristiques de l'element */
    /*===========================================*/

    /* Format Gambit : I8, 1X, I2, 1X, I2, 1X, 7I8 */

    retour = sscanf(chaine,"%d %d %d",
                    &ne,
                    &ntype,
                    &ndp) ;

    if (retour != 3)
      bft_error(__FILE__, __LINE__, 0,
                _("Error reading line %d of file \"%s\"\n"
                  "while decoding element %ld (of %ld)."),
                *num_ligne, bft_file_get_name(fic_maillage),
                (long)ielt, (long)nbr_elt) ;


    /* Vérification du type et détermination du sous-type */

    isub = -1 ;
    type_elt_gambit = NULL ;

    if (ntype > 0 && ntype < 8) {
      type_elt_gambit = ecs_loc_gambit_elt_liste_c + ntype - 1 ;
      for (isub = 0 ;
           isub < 4 && type_elt_gambit->nbr_som[isub] != ndp ;
           isub++) ;
      if (isub == 4)
        type_elt_gambit = NULL ;
    }


    if (type_elt_gambit == NULL)
      bft_error(__FILE__, __LINE__, 0,
                _("Error reading a GAMBIT mesh file:\n"
                  "at line %d of file \"%s\".\n"
                  "Type identifier <%d> for element <%d> is not recognized."),
                (int)(*num_ligne), bft_file_get_name(fic_maillage),
                (int)ntype, (int)ne);


    /* Lecture des numéros de noeuds constituant l'élément */
    /*=====================================================*/

    /* Format Gambit : 15X, 7I8 (pour chaque ligne) */

    isom     = 0 ;
    inod     = 0 ;

    while (inod < ndp) {

      nbr_nod_elt_reste = ndp - inod ;
      nbr_nod_ligne     = ECS_MIN(nbr_nod_elt_reste, 7) ;

      /* Le caractère nul à la fin de chaque chaîne a déjà été positionné */

      for (inod_ligne = 0 ; inod_ligne < nbr_nod_ligne ; inod_ligne++) {
        memcpy(str_som_lus[inod], chaine + 15 + (inod_ligne*8), 8) ;
        inod += 1;
      }

      /* Passage à une nouvelle ligne si nécessaire */

      if (inod < ndp)
        bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                      fic_maillage, num_ligne) ;

    } ;

    /* La lecture est terminée, on peut maintenant récuperer les
       numéros des sommets parmi les noeuds */

    nbr_som_elt = ecs_fic_elt_typ_liste_c[type_elt_gambit->ecs_typ].nbr_som ;
    ind_som_elt = type_elt_gambit->ind_som[isub] ;

    for (isom = 0 ; isom < nbr_som_elt ; isom++)
      som_elt[isom] = atoi(str_som_lus[ind_som_elt[isom]]) ;


    /* Stockage des valeurs lues avant transfert dans la structure `maillage' */
    /*========================================================================*/

    /* Identification de l'entite concernée */
    /*--------------------------------------*/

    ind_ent = ecs_entmail_pre__ret_typ_geo(type_elt_gambit->ecs_typ);


    if (cpt_elt_ent[ind_ent] == 0) {

      /* Si c'est la première fois que l'entité est concernée,
       * on initialise les allocations des tableaux ; il ne peut
       * rester plus de (nbr_elt - nombre d'éléments traités)
       * éléments à traiter pour cette entité. */

      nbr_elt_ent_max = nbr_elt - ielt ;

      BFT_MALLOC(elt_pos_som_ent[ind_ent], nbr_elt_ent_max + 1, ecs_size_t) ;

      taille_connect_max = nbr_elt_ent_max*8 ;
      if (ind_ent == ECS_ENTMAIL_FAC)
        taille_connect_max = nbr_elt_ent_max*4 ;
      else if (ind_ent == ECS_ENTMAIL_ARE)
        taille_connect_max = nbr_elt_ent_max*2 ;

      BFT_MALLOC(elt_val_som_ent[ind_ent], taille_connect_max, ecs_int_t) ;

      BFT_MALLOC(elt_val_typ_geo_ent[ind_ent], nbr_elt_ent_max, ecs_int_t) ;
      BFT_MALLOC(elt_val_label_ent[ind_ent],   nbr_elt_ent_max, ecs_int_t) ;

      elt_pos_som_ent[ind_ent][0] = 1 ;

    }

    num_pos = elt_pos_som_ent[ind_ent][cpt_elt_ent[ind_ent]] - 1 + nbr_som_elt ;

    /* Connectivité de l'élément par ses numéros de sommets */
    /*------------------------------------------------------*/

    elt_pos_som_ent[ind_ent][cpt_elt_ent[ind_ent] + 1]
      = elt_pos_som_ent[ind_ent][cpt_elt_ent[ind_ent]] + nbr_som_elt ;

    for (isom = 0 ; isom < nbr_som_elt ; isom++)
      elt_val_som_ent
        [ind_ent][elt_pos_som_ent[ind_ent][cpt_elt_ent[ind_ent]] - 1 + isom]
        = som_elt[isom];


    /* Type de l'élément lu */
    /*----------------------*/

    elt_val_typ_geo_ent[ind_ent][cpt_elt_ent[ind_ent]]
      = type_elt_gambit->ecs_typ ;


    /* Etiquette de l'élément lu */
    /*---------------------------*/

    elt_val_label_ent[ind_ent][cpt_elt_ent[ind_ent]] = ne ;


    /* Incrémentation du nombre d'éléments lus */
    /*=========================================*/

    cpt_elt_ent[ind_ent]++ ;


  } /* Fin de la boucle de lecture des éléments */

  /* Fin de la rubrique */

  ecs_loc_pre_gambit__fin_section(fic_maillage,
                                  num_ligne);


  /* Réallocations des tableaux locaux (potentiellement surdimensionnés) */
  /*=====================================================================*/

  for (ind_ent = ECS_ENTMAIL_ARE ; ind_ent < ECS_ENTMAIL_FIN ; ind_ent++) {

    if (cpt_elt_ent[ind_ent] != 0) {

      if (cpt_elt_ent[ind_ent] != nbr_elt) {
        BFT_REALLOC(elt_pos_som_ent[ind_ent],
                    cpt_elt_ent[ind_ent] + 1,
                    ecs_size_t) ;
        BFT_REALLOC(elt_val_typ_geo_ent[ind_ent],
                    cpt_elt_ent[ind_ent],
                    ecs_int_t) ;
        BFT_REALLOC(elt_val_label_ent[ind_ent],
                    cpt_elt_ent[ind_ent],
                    ecs_int_t) ;
      }
      BFT_REALLOC(elt_val_som_ent[ind_ent],
                  elt_pos_som_ent[ind_ent][cpt_elt_ent[ind_ent]] - 1,
                  ecs_int_t) ;

    }

  }

}


/*----------------------------------------------------------------------------
 *  Lecture d'un groupe
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_groupe
(
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 ecs_int_t     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_size_t    *nbr_elt_grp              , /* <-- Nombre d'éléments associés  */
 char         **nom_grp                  , /* <-- Nom du groupe associé       */
 ecs_int_t    **num_elt_grp                /* <-- Tableau labels des éléments */
)
{

  ecs_int_t  retour ;
  ecs_int_t  ind ;
  ecs_int_t  ielgp ;
  ecs_int_t  ielgp_ligne ;
  ecs_int_t  nbr_elgp_reste ;
  ecs_int_t  nbr_elgp_ligne ;

  /* Variables Gambit lues */

  int  ngp ;
  int  nelgp ;
  int  mtyp ;
  int  nflags ;

  char     chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;
  char     ch_num_elt[9] ;

  const char *mtyp_name[6] = { "Undefined",
                               "Conjugate",
                               "Fluid",
                               "Porous",
                               "Solid",
                               "Deformable" } ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Ligne de description du groupe */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  retour = sscanf(chaine, "%*s %d %*s %d %*s %d %*s %d",
                  &ngp, &nelgp, &mtyp, &nflags) ;

  if (retour != 4)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading line %d of file \"%s\"\n"
                "while defining a group."),
              *num_ligne, bft_file_get_name(fic_maillage)) ;

  if (mtyp < 0 || mtyp > 5)
    mtyp = 0 ;

  /* Nom du groupe */

  ecs_loc_pre_gambit__raz_chaine(chaine) ;

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  chaine[32] = '\0' ;
  for (ind = 32 ; ind > 0 && chaine[ind - 1] == ' ' ; ind--)
    chaine[ind] = '\0' ;
  for (ind = 0 ; chaine[ind] != '\0' && chaine[ind] == ' ' ; ind++) ;

  /* Stockage du nom de groupe */

  BFT_MALLOC(*nom_grp, strlen(chaine + ind) + 1, char) ;
  strcpy(*nom_grp, chaine + ind) ;

  /* Affichage */

  bft_printf(_("\n"
               "  Group %10d: \"%s\"\n"
               "                      type:       %s\n"
               "                      elements:   %d\n"
               "                      indicators: %d\n\n"),
             ngp, chaine + ind, mtyp_name[mtyp], nelgp, nflags) ;


  /* Saut des indicateurs éventuels (10 / ligne) */

  while (nflags > 0) {
    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                  fic_maillage, num_ligne) ;
   nflags -= 10 ;
  }

  /* Initialisations */
  /*=================*/

  ch_num_elt[8] = '\0' ;

  *nbr_elt_grp = nelgp ;

  BFT_MALLOC(*num_elt_grp, nelgp, ecs_int_t) ;


  /*==========================================*/
  /* Boucle de lecture des numéros de groupes */
  /*==========================================*/

  /* Format Gambit : 10I8 (pour chaque ligne) */

  ielgp = 0 ;

  while (ielgp < nelgp) {

    /* Lecture d'une nouvelle ligne */

    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                  fic_maillage, num_ligne) ;

    nbr_elgp_reste = nelgp - ielgp ;
    nbr_elgp_ligne= ECS_MIN(nbr_elgp_reste, 10) ;

    /* Le caractère nul à la fin la chaîne a déjà été positionné */

    for (ielgp_ligne = 0 ; ielgp_ligne < nbr_elgp_ligne ; ielgp_ligne++) {
      memcpy(ch_num_elt, chaine + (ielgp_ligne*8), 8) ;
      (*num_elt_grp)[ielgp] = atoi(ch_num_elt) ;
      ielgp += 1 ;
    }

  } ;

  /* Fin de la rubrique */

  ecs_loc_pre_gambit__fin_section(fic_maillage,
                                  num_ligne);

}


/*----------------------------------------------------------------------------
 *  Lecture d'une condition aux limites
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__lit_cl
(
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 ecs_int_t     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_size_t    *nbr_elt_cl               , /* <-- Nombre d'éléments associés  */
 char         **nom_cl                   , /* <-- Nom du groupe associé       */
 ecs_int_t    **num_elt_cl               , /* <-- Tableau labels des éléments */
 ecs_int_t    **num_fac_cl                 /* <-- Tableau faces des éléments  */
)
{

  ecs_int_t  retour ;
  ecs_int_t  ind ;

  int        nbr_codes ;
  int        nbr_val_loc ;

  /* Variables Gambit lues */

  int  ibcode[5] ;
  int  nentry ;
  int  type ;
  int  nvalues ;

  char  chaine[ECS_LOC_LNG_MAX_CHAINE_GAMBIT] ;
  char  ch_num_elt[11] ;
  char  ch_num_fac[6] ;
  char  ch_nom_cl[33] ;
  int   ibcode1_tmp ;

  const char *nom_type[3] = { "node",
                              "element/cell",
                              "undefined (incorrect)" } ;

  const char *nom_ibcode[54] = { "UNSPECIFIED",           /*  0 */
                                 "AXIS",                  /*  1 */
                                 "CONJUGATE",             /*  2 */
                                 "CONVECTION",            /*  3 */
                                 "CYCLIC",                /*  4 */
                                 "DEAD",                  /*  5 */
                                 "ELEMENT_SIDE",          /*  6 */
                                 "ESPECIES",              /*  7 */
                                 "EXHAUST_FAN",           /*  8 */
                                 "FAN",                   /*  9 */
                                 "FREE_SURFACE",          /* 10 */
                                 "GAP",                   /* 11 */
                                 "INFLOW",                /* 12 */
                                 "INLET",                 /* 13 */
                                 "INLET_VENT",            /* 14 */
                                 "INTAKE_FAN",            /* 15 */
                                 "INTERFACE",             /* 16 */
                                 "INTERIOR",              /* 17 */
                                 "INTERNAL",              /* 18 */
                                 "LIVE",                  /* 19 */
                                 "MASS_FLOW_INLET",       /* 20 */
                                 "MELT",                  /* 21 */
                                 "MELT_INTERFACE",        /* 22 */
                                 "MOVING_BOUNDARY",       /* 23 */
                                 "NODE",                  /* 24 */
                                 "OUTFLOW",               /* 25 */
                                 "OUTLET",                /* 26 */
                                 "OUTLET_VENT",           /* 27 */
                                 "PERIODIC",              /* 28 */
                                 "PLOT",                  /* 29 */
                                 "POROUS",                /* 30 */
                                 "POROUS_JUMP",           /* 31 */
                                 "PRESSURE",              /* 32 */
                                 "PRESSURE_FAR_FIELD",    /* 33 */
                                 "PRESSURE_INFLOW",       /* 34 */
                                 "PRESSURE_INLET",        /* 35 */
                                 "PRESSURE_OUTFLOW",      /* 36 */
                                 "PRESSURE_OUTLET",       /* 37 */
                                 "RADIATION",             /* 38 */
                                 "RADIATOR",              /* 39 */
                                 "RECIRCULATION_INLET",   /* 40 */
                                 "RECIRCULATION_OUTLET",  /* 41 */
                                 "SLIP",                  /* 42 */
                                 "SREACTION",             /* 43 */
                                 "SURFACE",               /* 44 */
                                 "SYMMETRY",              /* 45 */
                                 "TRACTION",              /* 46 */
                                 "TRAJECTORY",            /* 47 */
                                 "VELOCITY",              /* 48 */
                                 "VELOCITY_INLET",        /* 49 */
                                 "VENT",                  /* 50 */
                                 "WALL",                  /* 51 */
                                 "SPRING",                /* 52 */
                                 "?" } ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Initialisations */
  /*=================*/

  *nbr_elt_cl = 0 ;
  *nom_cl     = NULL ;
  *num_elt_cl = NULL ;


  /* Ligne de description de la condition aux limites */

  ecs_loc_pre_gambit__raz_chaine(chaine) ;

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                fic_maillage, num_ligne) ;

  memcpy(ch_nom_cl, chaine, 32) ;
  ch_nom_cl[32] = '\0' ;

  retour = sscanf(chaine + 32, "%d %d %d %d %d %d %d %d",
                  &type, &nentry, &nvalues,
                  ibcode, ibcode+1, ibcode+2, ibcode+3, ibcode+4) ;

  if (retour < 3)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading line %d of file \"%s\"\n"
                "while defining a boundary condition."),
              *num_ligne, bft_file_get_name(fic_maillage)) ;

  if (type < 0 || type > 1)
    type = 2 ;

  nbr_codes = retour - 3 ;

  /* Suppression des blancs en début et fin et stockage du nom */

  for (ind = 32 ; ind > 0 && ch_nom_cl[ind - 1] == ' ' ; ind--)
    ch_nom_cl[ind] = '\0' ;
  for (ind = 0 ; ch_nom_cl[ind] != '\0' && ch_nom_cl[ind] == ' ' ; ind++) ;
  if (ind > 0)
    memmove(ch_nom_cl, ch_nom_cl + ind, 33 - ind) ;


  /* Affichage */
  /*-----------*/

  bft_printf(_("\n"
               "  Boundary condition: \"%s\"\n"
               "                          type:    %s\n"
               "                          entities: %d\n"
               "                          values:   %d\n"),
             ch_nom_cl, nom_type[type], nentry, nvalues) ;


  if (nbr_codes > 0) {

    ibcode1_tmp = ibcode[0] ;
    if (ibcode1_tmp < 0 || ibcode1_tmp > 52)
      ibcode1_tmp = 53 ;

    bft_printf(_("                          code1:   %d (%s)\n"),
               ibcode[0], nom_ibcode[ibcode[0]]) ;

  }

  for (ind = 1 ; ind < nbr_codes ; ind++)
    bft_printf(_("                          code%1d:   %d\n"),
               ind + 1, ibcode[ind]) ;

  bft_printf("\n") ;

  /* On ne traite pas les C.L. définies aux sommets */
  /*================================================*/

  if (type != 1) {

    ecs_loc_pre_gambit__saut_section(fic_maillage,
                                     num_ligne) ;

    return ;

  }

  /* Lecture et ajout de la C.L. à la liste */
  /*========================================*/

  *nbr_elt_cl = nentry ;

  BFT_MALLOC(*nom_cl, strlen(ch_nom_cl) + 1, char) ;
  strcpy(*nom_cl, ch_nom_cl) ;

  BFT_MALLOC(*num_elt_cl, nentry, ecs_int_t) ;
  BFT_MALLOC(*num_fac_cl, nentry, ecs_int_t) ;


  /*============================*/
  /* Boucle de lecture des C.L. */
  /*============================*/

  /* Format Gambit : I10, I5, I5 / (4E20.12) */

  ch_num_elt[10] = '\0' ;
  ch_num_fac[5] = '\0' ;

  for (ind = 0 ; ind < nentry ; ind++) {

    /* Lecture d'une nouvelle ligne */

    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                  fic_maillage, num_ligne) ;

    /* Le caractère nul à la fin des chaînes a déjà été positionné */

    memcpy(ch_num_elt, chaine,     10) ;
    memcpy(ch_num_fac, chaine + 15, 5) ;

    (*num_elt_cl)[ind] = atoi(ch_num_elt) ;
    (*num_fac_cl)[ind] = atoi(ch_num_fac) ;

    /* Saut des valeurs éventuelles (4 / ligne) */

    for (nbr_val_loc = nvalues ; nbr_val_loc > 0 ; nbr_val_loc -= 4)
      bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GAMBIT,
                    fic_maillage, num_ligne) ;

  } ;

  /* Fin de la rubrique */

  ecs_loc_pre_gambit__fin_section(fic_maillage,
                                  num_ligne);

}


/*----------------------------------------------------------------------------
 *  Transformation de numéros de labels en indice.
 *
 *  On utilise une numérotation de 1 à n, avec un signe positif pour
 *  un indice correspondant à l'entité de plus haut niveau, un signe
 *  négatif pour l'entité inférieure, et 0 pour les labels "non trouvés"
 *  (correspondant probablement à une entité inférieure).
 *
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__label_en_indice
(
 ecs_int_t       nbr_lst                  , /* --> Nombre de listes           */
 ecs_size_t      nbr_label_lst[]          , /* --> Nombre de labels par liste */
 ecs_int_t      *val_label_lst[]          , /* <-> Nums. entités /groupes     */
 size_t          nbr_elt_ent[]            , /* --> Nombre d'élts. par entité  */
 ecs_int_t      *val_label_ent[]            /* --> Tableau labels par entité  */
)
{

  size_t       ind ;
  ecs_int_t    ind_lst ;
  ecs_int_t    ient ;

  ecs_int_t    ient_sub ;
  ecs_int_t    ient_pcp ;

  ecs_int_t    label_min ;
  ecs_int_t    label_max ;

  ecs_tab_int_t  tab_label_elt ;
  ecs_tab_int_t  tab_label_elt_ord ;
  ecs_tab_int_t  tab_ind ;
  ecs_tab_int_t  tab_ord ;

  int sgn ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Détermination de l'entité principale et de sa sous-entité */
  /*-----------------------------------------------------------*/

  ient_pcp = ECS_ENTMAIL_ARE ;

  for (ient = ECS_ENTMAIL_FAC ; ient < ECS_ENTMAIL_FIN ; ient++) {
    if (nbr_elt_ent[ient] > 0)
      ient_pcp = ient ;
  }

  ient_sub = ient_pcp - 1 ;


  /* On recherche les labels parmi ceux des éléments */
  /*-------------------------------------------------*/

  for (ient = ient_sub ; ient <= ient_pcp ; ient++) {

    if (nbr_elt_ent[ient] == 0)
      continue;

    if (ient == ient_sub)
      sgn = -1;
    else
      sgn = 1;

    tab_label_elt.nbr = nbr_elt_ent[ient] ;
    tab_label_elt.val = val_label_ent[ient] ;

    /* On vérifie si la numérotation des labels est dense ou presque */

    label_min = tab_label_elt.val[0];
    label_max = tab_label_elt.val[0];

    for (ind = 1 ; ind < tab_label_elt.nbr ; ind++) {
      if (tab_label_elt.val[ind] > label_max)
        label_max = tab_label_elt.val[ind];
      else if (tab_label_elt.val[ind] < label_min)
        label_min = tab_label_elt.val[ind];
    }

    /* Avec une numérotation assez dense, on utilise une indirection */

    if (label_max - label_min < (ecs_int_t)(2*tab_label_elt.nbr)) {

      tab_ind.nbr = label_max - label_min + 1;
      BFT_MALLOC(tab_ind.val, tab_ind.nbr, ecs_int_t) ;
      for (ind = 0 ; ind < tab_ind.nbr ; ind++)
        tab_ind.val[ind] = -1 ;

      for (ind = 0 ; ind < tab_label_elt.nbr ; ind++)
        tab_ind.val[tab_label_elt.val[ind] - label_min] = ind ;

      /* On transforme les labels en indices */

      for (ind_lst = 0 ; ind_lst < nbr_lst ; ind_lst++) {

        ecs_tab_int_t  tab_label ;
        size_t      nbr_label = nbr_label_lst[ind_lst] ;
        ecs_int_t  *val_label = val_label_lst[ind_lst] ;

        tab_label.nbr = nbr_label ;
        BFT_MALLOC(tab_label.val, tab_label.nbr, ecs_int_t) ;
        for (ind = 0 ; ind < nbr_label ; ind++) {
          tab_label.val[ind] = val_label[ind] ;
          val_label[ind] = 0 ;
        }

        for (ind = 0 ; ind < tab_label.nbr ; ind++) {
          if (tab_ind.val[tab_label.val[ind] - label_min] > -1)
            val_label[ind]
              = (tab_ind.val[tab_label.val[ind] - label_min] + 1) * sgn ;
        }

        BFT_FREE(tab_label.val) ;

      }

      /* Libération mémoire */

      BFT_FREE(tab_ind.val);

    }

    /* Avec une numérotation creuse, on utilise une recherche par dichotomie */

    else {

      tab_ord.nbr = nbr_elt_ent[ient] ;
      BFT_MALLOC(tab_ord.val, tab_ord.nbr, ecs_int_t) ;

      tab_label_elt_ord = ecs_tab_int__trie_et_renvoie(tab_label_elt, tab_ord) ;

      for (ind_lst = 0 ; ind_lst < nbr_lst ; ind_lst++) {

        ecs_tab_int_t  tab_label ;
        size_t      nbr_label = nbr_label_lst[ind_lst] ;
        ecs_int_t  *val_label = val_label_lst[ind_lst] ;

        if (nbr_label < 1)
          continue;

        tab_label.nbr = nbr_label ;
        BFT_MALLOC(tab_label.val, tab_label.nbr, ecs_int_t) ;
        for (ind = 0 ; ind < nbr_label ; ind++) {
          tab_label.val[ind] = val_label[ind] ;
          val_label[ind] = 0 ;
        }

        tab_ind.nbr = tab_label.nbr ;
        BFT_MALLOC(tab_ind.val, tab_ind.nbr, ecs_int_t) ;

        ecs_tab_int__recherche(tab_label, tab_label_elt_ord, tab_ind) ;

        /* On transforme les labels en indices */

        for (ind = 0 ; ind < tab_label.nbr ; ind++) {
          if (tab_ind.val[ind] > -1)
            val_label[ind] = (tab_ord.val[tab_ind.val[ind]] + 1) * sgn ;
        }

        BFT_FREE(tab_ind.val) ;
        BFT_FREE(tab_label.val) ;

      }

      /* Libération mémoire */

      BFT_FREE(tab_label_elt_ord.val);
      BFT_FREE(tab_ord.val);
    }

  }

}


/*----------------------------------------------------------------------------
 *  Construction des éléments surfaciques supplémentaires.
 *  On convertit les références num_elt_cl[] à une entité principale
 *  en des référence à la sous-entité, et on libère les références
 *  num_fac_cl[] à une face de chaque élément de l'entité principale.
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__cree_ent_sub
(
 ecs_int_t    nbr_cl                     , /* --> Nb. C.L.                   */
 ecs_size_t   nbr_elt_cl[]               , /* --> Nb. entités / C.L.         */
 ecs_int_t   *num_elt_cl[]               , /* --> Nums. entités / C.L.       */
 ecs_int_t   *num_fac_cl[]               , /* --> Nums. faces / C.L.         */
 size_t       nbr_elt_ent[]              , /* <-- Nombre d'elems/entité      */
 ecs_size_t  *elt_pos_som_ent[]          , /* <-- Positions numéros som      */
 ecs_int_t   *elt_val_som_ent[]          , /* <-- Numéros des sommets        */
 ecs_int_t   *elt_val_typ_geo_ent[]        /* <-> Types géométriques         */
)
{

  size_t       cpt_elt_sub ;
  size_t       taille_connect_sub ;

  size_t       ind ;
  ecs_int_t    ind_cl ;
  ecs_int_t    ind_elt ;
  ecs_int_t    ind_fac ;
  ecs_int_t    ind_ent_pcp ;
  ecs_int_t    ind_ent_sub ;
  ecs_int_t    ind_indic ;
  ecs_int_t    ind_som ;
  ecs_int_t    nbr_som_sub ;

  ecs_int_t    type_pcp ;
  ecs_int_t    type_sub ;

  const ecs_sous_elt_t  *sous_elt ;

  ecs_int_t   *val_typ_geo_pcp ;
  ecs_int_t   *p_connect_elt ;
  ecs_int_t   *p_connect_sub ;

  ecs_int_t   *indic_pcp = NULL ;

  int  type_gambit[ECS_ELT_TYP_FIN] ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  if (nbr_cl == 0)
    return ;


  /* Tableau pour correspondance types Enveloppe et GAMBIT */

  for (ind = 0 ; ind < ECS_ELT_TYP_FIN ; ind++)
    type_gambit[ind] = -1 ;

  for (ind = 0 ; ind < 7 ; ind++)
    type_gambit[ecs_loc_gambit_elt_liste_c[ind].ecs_typ] = ind ;


  /* Détermination de l'entité principale et de sa sous-entité */
  /*-----------------------------------------------------------*/

  ind_ent_pcp = ECS_ENTMAIL_ARE ;

  for (ind = ECS_ENTMAIL_FAC ; ind < ECS_ENTMAIL_FIN ; ind++) {
    if (nbr_elt_ent[ind] > 0)
      ind_ent_pcp = ind ;
  }

  ind_ent_sub = ind_ent_pcp - 1 ;

  cpt_elt_sub = nbr_elt_ent[ind_ent_sub] ;

  if (nbr_elt_ent[ind_ent_sub] > 0)
    taille_connect_sub
      = elt_pos_som_ent[ind_ent_sub][nbr_elt_ent[ind_ent_sub]] - 1 ;
  else
    taille_connect_sub = 0 ;

  val_typ_geo_pcp = elt_val_typ_geo_ent[ind_ent_pcp] ;


  /* Préparation d'un indicateur sur les cellules (6 faces/cellule max.) */
  /*---------------------------------------------------------------------*/

  BFT_MALLOC(indic_pcp, nbr_elt_ent[ind_ent_pcp] * 6, ecs_int_t) ;

  for (ind = 0 ; ind < (nbr_elt_ent[ind_ent_pcp] * 6) ; ind++)
    indic_pcp[ind] = 0 ;


  /* Boucles sur les C.L. pour le comptage */
  /*---------------------------------------*/

  for (ind_cl = 0 ; ind_cl < nbr_cl ; ind_cl++) {

    for (ind = 0 ; ind < nbr_elt_cl[ind_cl] ; ind++) {

      /* On ignore les C.L. sur des sous-sous-entités */

      if (num_elt_cl[ind_cl][ind] > 0) {

        ind_elt = num_elt_cl[ind_cl][ind] - 1 ;

        /* Ajout "face" si nécessaire */

        ind_indic = ind_elt*6 + num_fac_cl[ind_cl][ind] - 1 ;

        if (indic_pcp[ind_indic] == 0) {

          ind_fac = num_fac_cl[ind_cl][ind] - 1 ;
          type_pcp = type_gambit[val_typ_geo_pcp[ind_elt]] ;
          assert(   ecs_loc_gambit_elt_liste_c[type_pcp].nbr_sselt
                 >= num_fac_cl[ind_cl][ind]) ;
          sous_elt = &((ecs_loc_gambit_elt_liste_c
                        [type_pcp]).sous_elt[ind_fac]) ;
          type_sub = sous_elt->elt_typ ;

          cpt_elt_sub    += 1 ;
          taille_connect_sub += (ecs_fic_elt_typ_liste_c[type_sub]).nbr_som ;

          indic_pcp[ind_indic] = cpt_elt_sub ;

        }

      }

    }

  }


  /* Redimensionnement des tableaux associés à la connectivité */
  /*-----------------------------------------------------------*/

  /* On ne mettra nbr_elt_ent à jour qu'à la fin */

  if (cpt_elt_sub > nbr_elt_ent[ind_ent_sub]) {

    BFT_REALLOC(elt_pos_som_ent[ind_ent_sub], cpt_elt_sub + 1, ecs_size_t) ;
    BFT_REALLOC(elt_val_som_ent[ind_ent_sub], taille_connect_sub, ecs_int_t) ;

    if (nbr_elt_ent[ind_ent_sub] == 0)
      elt_pos_som_ent[ind_ent_sub][0] = 1 ;

  }


  /* Remise des compteurs à leur valeur initiale */

  cpt_elt_sub = nbr_elt_ent[ind_ent_sub] ;

  if (nbr_elt_ent[ind_ent_sub] > 0)
    taille_connect_sub
      = elt_pos_som_ent[ind_ent_sub][nbr_elt_ent[ind_ent_sub]] - 1 ;
  else
    taille_connect_sub = 0 ;

  for (ind = 0 ; ind < (nbr_elt_ent[ind_ent_pcp] * 6) ; ind++)
    indic_pcp[ind] = 0 ;


  /* Boucle de construction effective des entités */
  /*-----------------------------------------------*/

  for (ind_cl = 0 ; ind_cl < nbr_cl ; ind_cl++) {

    for (ind = 0 ; ind < nbr_elt_cl[ind_cl] ; ind++) {

      /* On ignore les C.L. sur des sous-sous-entités */

      if (num_elt_cl[ind_cl][ind] > 0) {

        ind_elt = num_elt_cl[ind_cl][ind] - 1 ;

        /* Ajout "face" si nécessaire */

        ind_fac   = num_fac_cl[ind_cl][ind] - 1 ;
        ind_indic = ind_elt*6 + ind_fac ;

        if (indic_pcp[ind_indic] == 0) {

          type_pcp = type_gambit[val_typ_geo_pcp[ind_elt]] ;
          assert(  ecs_loc_gambit_elt_liste_c[type_pcp].nbr_sselt > ind_fac) ;
          sous_elt = &((ecs_loc_gambit_elt_liste_c
                        [type_pcp]).sous_elt[ind_fac]) ;
          type_sub = sous_elt->elt_typ ;

          p_connect_elt =   elt_val_som_ent[ind_ent_pcp]
                          + elt_pos_som_ent[ind_ent_pcp][ind_elt] - 1 ;
          p_connect_sub = elt_val_som_ent[ind_ent_sub] + taille_connect_sub ;

          nbr_som_sub = (ecs_fic_elt_typ_liste_c[type_sub]).nbr_som ;

          for (ind_som = 0 ; ind_som < nbr_som_sub ; ind_som++)
            p_connect_sub[ind_som] = p_connect_elt[sous_elt->som[ind_som]] ;

          cpt_elt_sub += 1 ;
          taille_connect_sub += (ecs_fic_elt_typ_liste_c[type_sub]).nbr_som ;

          elt_pos_som_ent[ind_ent_sub][cpt_elt_sub] = taille_connect_sub + 1 ;

          indic_pcp[ind_indic] = cpt_elt_sub ;

        }

        /* On convertit la référence à une face de l'entité principale
           en une référence à un élement de la sous-entité */

        num_elt_cl[ind_cl][ind] = - indic_pcp[ind_indic] ;

      }
      else

        num_elt_cl[ind_cl][ind] = 0 ;

    }

    /* On n'a plus besoin du tableau num_fac_cl[ind_cl] */

    BFT_FREE(num_fac_cl[ind_cl]) ;

  }

  nbr_elt_ent[ind_ent_sub] = cpt_elt_sub ;

  assert(taille_connect_sub == elt_pos_som_ent[ind_ent_sub][cpt_elt_sub] - 1) ;


  /* Libération mémoire */
  /*--------------------*/

  for (ind = ECS_ENTMAIL_FAC ; ind < ECS_ENTMAIL_FIN ; ind++) {
    if (elt_val_typ_geo_ent[ind] != NULL)
      BFT_FREE(elt_val_typ_geo_ent[ind]) ;
  }

  BFT_FREE(indic_pcp) ;

}


/*----------------------------------------------------------------------------
 *  Construction effective des groupes
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gambit__cree_groupes
(
 ecs_int_t       nbr_grp                  , /* --> Nb. groupes                */
 ecs_size_t      nbr_elt_grp[]            , /* --> Nb. entités / groupe       */
 char           *nom_grp[]                , /* --> Noms des groupes           */
 ecs_int_t      *num_elt_grp[]            , /* --> Nums. entités /groupes     */
 ecs_entmail_t **vect_entmail               /* <-> Entités maillage à remplir */
)
{

  ecs_descr_t  *descr_grp ; /* Pointeur sur descripteur de champ */
  ecs_int_t     num_label ; /* Numéro d'indice de l'étiquette */

  size_t       ielgrp ;
  size_t       ival ;
  ecs_int_t    igrp ;
  ecs_int_t    ient ;

  ecs_bool_t   bool_aff_grp ;
  size_t       nbr_elt_ent[ECS_ENTMAIL_FIN];
  ecs_int_t    ind_ent ;
  ecs_int_t    ind_ent_pcp ;
  ecs_int_t    ind_ent_sub ;

  size_t       ent_cpt_elt[ECS_ENTMAIL_FIN]; /* Nombre d'elements par entite  */

  /* Stockage avant transfert */
  ecs_int_t  * ent_val_grp[ECS_ENTMAIL_FIN]; /* Reference /entite et /groupe, */
                                             /*  les elts. appart. au groupe  */
  ecs_int_t    ent_cpt_grp[ECS_ENTMAIL_FIN]; /* Compteur sur les groupes      */

  ecs_champ_t  * ent_champ_def[ECS_ENTMAIL_FIN];
  ecs_champ_t  * ent_champ_grp[ECS_ENTMAIL_FIN];
  ecs_champ_t  * champ_grp               ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Initialisations */
  /*=================*/


  for (ient = ECS_ENTMAIL_DEB ; ient < ECS_ENTMAIL_FIN ; ient++) {

    ent_cpt_grp[ient] = 0 ;

    if (vect_entmail[ient] != NULL)
      ent_champ_def[ient] = ecs_entmail__ret_champ(vect_entmail[ient],
                                                   ECS_CHAMP_DEF) ;
    else
      ent_champ_def[ient] = NULL ;

    ent_cpt_elt[ient] = 0 ;

    if (ent_champ_def[ient] != NULL)
      nbr_elt_ent[ient] = ecs_champ__ret_pos_nbr(ent_champ_def[ient]) - 1 ;
    else
      nbr_elt_ent[ient] = 0    ;

    ent_champ_grp[ient] = NULL ;

  }


  /* Détermination de l'entité principale et de sa sous-entité */
  /*-----------------------------------------------------------*/

  ind_ent_pcp = ECS_ENTMAIL_ARE ;

  for (ient = ECS_ENTMAIL_FAC ; ient < ECS_ENTMAIL_FIN ; ient++) {
    if (nbr_elt_ent[ient] > 0)
      ind_ent_pcp = ient ;
  }

  ind_ent_sub = ind_ent_pcp - 1 ;


  /*===================================*/
  /* Boucle principale sur les groupes */
  /*===================================*/


  for (igrp = 0 ; igrp < nbr_grp ; igrp++) {

    /* On alloue et initialise pour le groupe à traiter */
    /*==================================================*/

    for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++) {

      ent_cpt_elt[ient] = 0 ;

      if (nbr_elt_ent[ient] != 0)
        BFT_MALLOC(ent_val_grp[ient], nbr_elt_ent[ient], ecs_int_t) ;

      for (ival = 0 ; ival < nbr_elt_ent[ient] ; ival++)
        ent_val_grp[ient][ival] = 0 ;

    }


    /* traitement d'un groupe */
    /*========================*/

    for (ielgrp = 0 ; ielgrp < nbr_elt_grp[igrp] ; ielgrp++) {

      /* Entité à laquelle correspond un élément du groupe ? */
      /*-----------------------------------------------------*/

      num_label = num_elt_grp[igrp][ielgrp] ;

      if (num_label > 0)
        ind_ent = ind_ent_pcp ;

      else if (num_label < 0) {
        ind_ent = ind_ent_sub ;
        num_label = -num_label ;
      }

      else
        ind_ent = ECS_ENTMAIL_FIN ;


      if (   ind_ent != ECS_ENTMAIL_FIN
          && ent_val_grp[ind_ent] != NULL) {

        /* Stockage des valeurs lues avant transfert dans maillage */

        ent_val_grp[ind_ent][num_label - 1] = ent_cpt_grp[ind_ent] + 1 ;


        /* Incrémentation du nombre d'objets traités */

        ent_cpt_elt[ind_ent]++ ;

      }

    }


    /* Boucle de remplissage des entités du maillage */
    /*===============================================*/


    bool_aff_grp = ECS_FALSE ;


    for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++) {


      /*--------------------------------------------------------------------*/
      /* S'il y a au moins un élement du groupe de cette entité de maillage */
      /*--------------------------------------------------------------------*/

      if (ent_cpt_elt[ient] != 0) {

        bool_aff_grp = ECS_TRUE ;

        assert(ent_cpt_elt[ient] <= nbr_elt_ent[ient]) ;

        ent_cpt_grp[ient]++ ;


        /* Création du descripteur de champ correspondant au groupe lu */
        /*-------------------------------------------------------------*/

        descr_grp = ecs_descr__cree(ECS_DESCR_TYP_GROUPE,
                                    ECS_DESCR_IDE_NUL,
                                    nom_grp[igrp]) ;


        /* Transformation du tableau référencant le groupe en une table */
        /*--------------------------------------------------------------*/

        champ_grp = ecs_champ__transforme_tableau(nbr_elt_ent[ient],
                                                  ent_val_grp[ient],
                                                  ECS_CHAMP_NOM_GROUPE,
                                                  descr_grp,
                                                  ECS_CHAMP_STATUT_HERITABLE) ;

        if (ent_champ_grp[ient] != NULL)
          ecs_champ_att__assemble(ent_champ_grp[ient],
                                  champ_grp,
                                  NULL) ;

        else
          ent_champ_grp[ient] = champ_grp ;


      } /* Fin si le nombre d'éléments référencant le groupe n'est pas nul */

    } /* Fin de la boucle sur les entités */


    /* Affichage du bilan des données lues pour les groupes */
    /*======================================================*/

    if (bool_aff_grp == ECS_TRUE)
      bft_printf("  %s %" ECS_FORMAT_ecs_int_t " \"%s\"\n",
                 _("Group"),
                 igrp + 1, nom_grp[igrp]) ;

    ecs_entmail__aff_nbr_par_ent(ent_cpt_elt, 0) ;


    /* Incrémentation du compteur sur les groupes */
    /*--------------------------------------------*/

    for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++)
      if (nbr_elt_ent[ient] != 0)
        BFT_FREE(ent_val_grp[ient]) ;

    /* Ré-initialisation des compteurs par entité pour le groupe suivant */
    for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++)
      ent_cpt_elt[ient] = 0 ;


  } /* Fin de la boucle sur les groupes */


  /* Transfert des champs groupe dans les entités de maillage correspondantes */
  /*==========================================================================*/

  for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++) {

    if (vect_entmail[ient] != NULL && ent_champ_grp[ient] != NULL)
      ecs_entmail__ajoute_champ(vect_entmail[ient] ,
                                ent_champ_grp[ient] ,
                                ECS_CHAMP_ATT ) ;


  }

}

Generated by  Doxygen 1.6.0   Back to index