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

ecs_pre_ideas.c

/*============================================================================
 *  Définition de la fonction
 *   de lecture d'un fichier de maillage IDEAS-MS au format "universel"
 *============================================================================*/

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

  Copyright (C) 1999-2008 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_ideas_def.h"
#include "ecs_entmail_pre.h"


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

#include "ecs_pre_ideas.h"


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


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

typedef struct _ecs_loc_ideas_sys_coord_t {
  ecs_int_t                            label ;        /* Identificateur   */
  ecs_int_t                            type ;         /* 0 = Cartésien    */
  ecs_real_t                           transf[3][4] ; /* Transformation   */
} ecs_loc_ideas_sys_coord_t;


/*============================================================================
 *  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 */
#define ECS_LOC_LNG_MAX_CHAINE_IDEAS  83        /* 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
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Création d'une table de correspondance des types d'éléments ;
 *  Pour un numéro de type d'élément I-deas donné ityp, la valeur
 *  correspondante à l'indice ityp renvoie l'indice du type correspondant
 *  dans ecs_fic_ideas_init_elt_liste_c[] si le type est géré, ou une
 *  valeur négative ECS_IDEAS_IGNORE, ECS_IDEAS_UNHANDLED, ou ECS_IDEAS_UNKNOWN
 *  sinon
 *----------------------------------------------------------------------------*/

static ecs_tab_int_t ecs_loc_pre_ideas__tab_types
(
 void
) ;


/*----------------------------------------------------------------------------
 *  Lecture des systèmes de coordonnées
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_ideas__lit_sys_coord
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne    , /* <-> Cpt. lignes lues   */
 ecs_tab_int_t                *const ind_coo_sys  , /* <-- Corresp. label
                                                     *     -> sys. coo référ. */
 ecs_loc_ideas_sys_coord_t  * *const coo_sys_ref    /* <-- Systèmes de coord.
                                                     *      de référence      */
) ;


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

static ecs_entmail_t * ecs_loc_pre_ideas__lit_nodes
(                                          /* <-- 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     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_tab_int_t  tab_label_ent[]          , /* <-- Tableau labels par entite   */
 ecs_bool_t     bool_label_ent_a_trier[] , /* <-- Indicateur de labels tries  */
 ecs_tab_int_t  ind_coo_sys              , /* --> Label -> sys. coord. réf.   */
 ecs_loc_ideas_sys_coord_t  coo_sys_ref[]  /* --> Sys. coord. référence  */
) ;


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

static ecs_entmail_t ** ecs_loc_pre_ideas__lit_elements
(                                          /* <-- Renvoie les entites         */
                                           /*      aretes, faces et cellules  */
 bft_file_t    *fic_maillage             , /* --> Descripteur fichier a lire  */
 ecs_int_t     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_tab_int_t  tab_label_ent[]          , /* <-- Tableau labels par entite   */
 ecs_bool_t     bool_label_ent_a_trier[]   /* <-- Indicateur de labels tries  */
) ;


/*----------------------------------------------------------------------------
 *  Lecture des groupes
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_ideas__lit_groups
(
 bft_file_t     *fic_maillage             , /* --> Descripteur fichier a lire */
 ecs_int_t      *num_ligne                , /* <-> Compteur des lignes lues   */
 ecs_int_t       nbr_ent_par_ligne        , /* --> Nombre d'entites a lire    */
                                            /*      par ligne par groupe      */
 ecs_tab_int_t   tab_label_ent[]          , /* --> Tableau labels par entite  */
 ecs_bool_t      bool_label_ent_a_trier[] , /* <-- Indicateur de labels tries */
 ecs_entmail_t **vect_entmail               /* <-> Entites maillage a remplir */
) ;


/*----------------------------------------------------------------------------
 *  Fonction utilitaire pour la lecture des réels d'un fichier I-DEAS
 *
 *  La chaîne contenant un réel avec (ou non) un exposant `d' ou `D'
 *  est convertie en réel avec un exposant `e'
 *----------------------------------------------------------------------------*/

static ecs_real_t ecs_loc_pre_ideas__transf_expo
(
 char *chaine     /* Chaine contenant le reel dont l'exposant est a convertir */
);



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


/*----------------------------------------------------------------------------
 *  Lecture d'un fichier I-DEAS Master Series au format universel
 *   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 Ideas
 *   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_ideas__lit_maillage
(                                       /* <-- Renvoie un pointeur sur        */
                                        /*      une structure de maillage     */
 const char *const nom_fic_maillage     /* --> Nom du fichier a lire          */
)
{
  bft_file_t   * fic_maillage          ; /* Descripteur du fichier            */
  ecs_int_t    retour                  ; /* Retour fnctions `scan' pour test  */
  char       chaine[ECS_LOC_LNG_MAX_CHAINE_IDEAS]  ;           /* Ligne lue   */
  ecs_bool_t     bool_dataset_suivant  ; /* Indicateur de lecture de dataset  */
  ecs_bool_t     bool_dataset_elements ; /* Indicateur de lecture du dataset  */
                                         /*  sur les elements                 */
  ecs_bool_t     bool_dataset_noeuds   ; /* Indicateur de lecture du dataset  */
                                         /*  sur les noeuds                   */
  ecs_int_t    ient                    ; /* Indice de boucle sur les entites  */
  ecs_int_t    entities_per_line       ; /* Nbr d'entites Ideas par ligne     */
  ecs_int_t    num_ligne               ; /* Compteur des lignes lues          */
  ecs_int_t    num_dataset             ; /* Numero du dataset lu              */
  ecs_bool_t     bool_label_ent_a_trier[ECS_ENTMAIL_FIN]; /* Ind labels tries */
  ecs_tab_int_t  tab_label_ent[ECS_ENTMAIL_FIN] ; /* Tabl. labels par entite  */
  ecs_tab_int_t  tab_ind_coo_sys       ; /* Corresp. label -> sys. coo référ. */
  ecs_dim_t       dim_e                ; /* Dimension spatiale                */
  ecs_maillage_t *maillage             ; /* Structure de maillage             */
  ecs_entmail_t  *vect_entmail[ECS_ENTMAIL_FIN]; /* Tabl. entites de maillage */
  ecs_entmail_t **vect_entmail_ret     ;
  ecs_loc_ideas_sys_coord_t  *coo_sys_ref ; /* Syst. coord. de référence   */

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  bft_printf(_("\n\n"
               "Reading mesh from file in I-deas universal format\n"
               "----------------------\n")) ;

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


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

  for (ient = ECS_ENTMAIL_DEB ; ient < ECS_ENTMAIL_FIN ; ient++) {
    bool_label_ent_a_trier[ient] = ECS_FALSE ;
    tab_label_ent[ient].val = NULL ;
    tab_label_ent[ient].nbr = 0    ;
  }

  tab_ind_coo_sys.nbr = 0 ;
  tab_ind_coo_sys.val = NULL ;
  coo_sys_ref = NULL ;

  num_ligne = 1 ;
  dim_e     = ECS_DIM_3 ;


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

  fic_maillage = bft_file_open(nom_fic_maillage,
                               BFT_FILE_MODE_READ,
                               BFT_FILE_TYPE_TEXT) ;


  bool_dataset_suivant  = ECS_FALSE ;

  bool_dataset_elements = ECS_FALSE ;
  bool_dataset_noeuds   = ECS_FALSE ;



  /*================================================*/
  /* 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_IDEAS,
                           fic_maillage, &num_ligne) != NULL) {


    /* Si la chaine lue est la chaine de separation des dataset de Ideas */
    /*===================================================================*/

    if ( strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) == 0 ) {

      if (bool_dataset_suivant == ECS_TRUE) {
        /* On a lu le separateur de fin du dataset precedent           */
        /* On lit maintenant le separateur de debut du dataset suivant */
        if (bft_file_gets_try(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                              fic_maillage, &num_ligne) == NULL)
          bool_dataset_suivant = ECS_FALSE ;
      }
      else {
        /* c'est le premier separateur lu : celui du debut de fichier */
        bool_dataset_suivant = ECS_TRUE;
      }


      if (bool_dataset_suivant == ECS_TRUE) {

        /* Lecture du numero du dataset */
        /*------------------------------*/

        bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                      fic_maillage, &num_ligne) ;

        retour = sscanf(chaine, " %" ECS_FORMAT_ecs_int_t, &num_dataset);

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

        /* Suivant le numero du dataset lu ... */
        /*-------------------------------------*/

        switch(num_dataset) {

        case ECS_IDEAS_DATASET_SYS_COORD_2420:


          /* Lecture de la définition des systèmes de coordonnées */

          ecs_loc_pre_ideas__lit_sys_coord(fic_maillage,
                                           &num_ligne,
                                           &tab_ind_coo_sys,
                                           &coo_sys_ref) ;

          /* On a déjà lu dans la fonction le separateur de fin de dataset */
          bool_dataset_suivant = ECS_FALSE ;

          break ;

        case ECS_IDEAS_DATASET_NODES_2411:


          /* Lecture des coordonnees des noeuds */
          /*------------------------------------*/

          vect_entmail[ECS_ENTMAIL_SOM]
            = ecs_loc_pre_ideas__lit_nodes(fic_maillage,
                                           &dim_e,
                                           &num_ligne,
                                           tab_label_ent,
                                           bool_label_ent_a_trier,
                                           tab_ind_coo_sys,
                                           coo_sys_ref);

          /* On a deja lu dans la fonction le separateur de fin de dataset */
          bool_dataset_suivant = ECS_FALSE ;

          /* On indique qu'on a lu le dataset sur les noeuds */
          bool_dataset_noeuds  = ECS_TRUE  ;

          break;

        case ECS_IDEAS_DATASET_ELEMENTS_2412:


          /* Lecture de la table de connectivite */
          /*-------------------------------------*/

          vect_entmail_ret
            = ecs_loc_pre_ideas__lit_elements(fic_maillage,
                                              &num_ligne,
                                              tab_label_ent,
                                              bool_label_ent_a_trier);


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

          BFT_FREE(vect_entmail_ret) ;

          /* On a deja lu dans la fonction le separateur de fin de dataset */
          bool_dataset_suivant = ECS_FALSE ;

          /* On indique qu'on a lu le dataset sur les elements */
          bool_dataset_elements = ECS_TRUE ;

          break;

        case ECS_IDEAS_DATASET_GROUPS_2430:
        case ECS_IDEAS_DATASET_GROUPS_2432:
        case ECS_IDEAS_DATASET_GROUPS_2435:
        case ECS_IDEAS_DATASET_GROUPS_2452:
        case ECS_IDEAS_DATASET_GROUPS_2467:
        case ECS_IDEAS_DATASET_GROUPS_2477:

          /* La construction du maillage fait l'hypothese                */
          /*  que les noeuds et les elements sont lus avant les groupes. */
          /* On verifie qu'on a lu les datasets sur les noeuds et        */
          /* les elements avant de lire le dataset sur les groupes       */
          /*-------------------------------------------------------------*/

          if (bool_dataset_noeuds == ECS_FALSE ||
              bool_dataset_elements == ECS_FALSE) {

            bft_error(__FILE__, __LINE__, 0,
                      _("Error reading an I-deas universal file:\n"
                        "at line %d of file \"%s\".\n"
                        "Node and element datasets must be read\n"
                        "before the groups dataset."),
                      (int)num_ligne, bft_file_get_name(fic_maillage));
          }

          /* Lecture des groupes dans un format obsolete */
          /*                  ou dans le format actuel   */
          /*---------------------------------------------*/

          if (   num_dataset == ECS_IDEAS_DATASET_GROUPS_2430
              || num_dataset == ECS_IDEAS_DATASET_GROUPS_2432) {
            /* Lecture des groupes dans un format obsolete */
            entities_per_line = ECS_IDEAS_NBR_GRP_ENT_PER_LINE4 ;
          }
          else {
            /* Lecture des groupes dans le format actuel   */
            entities_per_line = ECS_IDEAS_NBR_GRP_ENT_PER_LINE2 ;
          }

          ecs_loc_pre_ideas__lit_groups(fic_maillage,
                                        &num_ligne,
                                        entities_per_line,
                                        tab_label_ent,
                                        bool_label_ent_a_trier,
                                        vect_entmail);

          /* On a deja lu dans la fonction le separateur de fin de dataset */
          bool_dataset_suivant = ECS_FALSE ;

          break;

        default:

          ; /* On poursuit la lecture */

        } /* Fin : `switch(num_dataset)' : numero du dataset lu ... */


      } /* Fin : si on a lu le separateur de dataset */

    } /* Fin : on n'a pas atteint la fin de fichier au cours de la boucle */

  } /* Fin : boucle tant qu'on n'a pas atteint la fin de fichier  */


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

  /* else : la fin de fichier a bien ete atteinte */


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

  if (bool_dataset_noeuds == ECS_FALSE)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading an I-deas universal file:\n"
                "at line %d of file \"%s\".\n"
                "Dataset \"%d\" containing the nodes "
                "definition has not been found."),
              (int)num_ligne, bft_file_get_name(fic_maillage),
              ECS_IDEAS_DATASET_NODES_2411);

  if (bool_dataset_elements == ECS_FALSE)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading an I-deas universal file:\n"
                "at line %d of file \"%s\".\n"
                "Dataset \"%d\" containing the elements "
                "definition has not been found."),
              (int)num_ligne, bft_file_get_name(fic_maillage),
              ECS_IDEAS_DATASET_ELEMENTS_2412);


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

  bft_file_free(fic_maillage) ;


  /* Liberations */
  /*=============*/

  tab_ind_coo_sys.nbr = 0 ;
  BFT_FREE(tab_ind_coo_sys.val) ;
  BFT_FREE(coo_sys_ref) ;

  for (ient = ECS_ENTMAIL_DEB ; ient < ECS_ENTMAIL_FIN ; ient++)
    if (tab_label_ent[ient].val != NULL)
      BFT_FREE(tab_label_ent[ient].val) ;


  maillage = ecs_maillage__cree_nodal(dim_e,
                                      vect_entmail) ;


  return maillage ;


}



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

/*----------------------------------------------------------------------------
 *  Création d'une table de correspondance des types d'éléments ;
 *  Pour un numéro de type d'élément I-deas donné ityp, la valeur
 *  correspondante à l'indice ityp renvoie l'indice du type correspondant
 *  dans ecs_fic_ideas_init_elt_liste_c[] si le type est géré, ou une
 *  valeur négative ECS_IDEAS_IGNORE, ECS_IDEAS_UNHANDLED, ou ECS_IDEAS_UNKNOWN
 *  sinon
 *----------------------------------------------------------------------------*/

static ecs_tab_int_t ecs_loc_pre_ideas__tab_types
(
 void
)
{

  ecs_tab_int_t  tab_types ;
  size_t         ind ;
  size_t         ityp ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  tab_types.nbr = 232 + 1 ;
  BFT_MALLOC(tab_types.val, tab_types.nbr, ecs_int_t) ;

  /* Initialisation */

  for (ityp = 0 ; ityp < tab_types.nbr ; ityp++)
    tab_types.val[ityp] = ECS_IDEAS_UNKNOWN ;

  /* Éléments 1 D */

  tab_types.val[ 11] = ECS_IDEAS_LINEAR_BEAM ;           /* Rod */
  tab_types.val[ 21] = ECS_IDEAS_LINEAR_BEAM ;           /* Linear beam */
  tab_types.val[ 22] = ECS_IDEAS_LINEAR_BEAM ;           /* Tapered beam */
  tab_types.val[ 23] = ECS_IDEAS_UNHANDLED ;             /* Curved beam */
  tab_types.val[ 24] = ECS_IDEAS_PARABOLIC_BEAM ;        /* Parabolic beam */
  tab_types.val[ 31] = ECS_IDEAS_UNHANDLED ;             /* Straight pipe */
  tab_types.val[ 32] = ECS_IDEAS_UNHANDLED ;             /* Curved pipe */

  /* Éléments de type "Plane Stress" */

  tab_types.val[ 41] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[ 42] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[ 43] = ECS_IDEAS_SHELL_CUBIC_TRI ;
  tab_types.val[ 44] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[ 45] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;
  tab_types.val[ 46] = ECS_IDEAS_SHELL_CUBIC_QUAD ;

  /* Éléments de type "Plane Strain" */

  tab_types.val[ 51] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[ 52] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[ 53] = ECS_IDEAS_SHELL_CUBIC_TRI ;
  tab_types.val[ 54] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[ 55] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;
  tab_types.val[ 56] = ECS_IDEAS_SHELL_CUBIC_QUAD ;

  /* Éléments de type "Plate" */

  tab_types.val[ 61] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[ 62] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[ 63] = ECS_IDEAS_SHELL_CUBIC_TRI ;
  tab_types.val[ 64] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[ 65] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;
  tab_types.val[ 66] = ECS_IDEAS_SHELL_CUBIC_QUAD ;

  /* Éléments de type "Membrane" */

  tab_types.val[ 71] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[ 72] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[ 73] = ECS_IDEAS_SHELL_CUBIC_TRI ;
  tab_types.val[ 74] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[ 75] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;
  tab_types.val[ 76] = ECS_IDEAS_SHELL_CUBIC_QUAD ;

  /* Éléments de type "Axisymetric Solid" */

  tab_types.val[ 81] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[ 82] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[ 84] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[ 85] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;

  /* Éléments de type "Thin Shell" */

  tab_types.val[ 91] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[ 92] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[ 93] = ECS_IDEAS_SHELL_CUBIC_TRI ;
  tab_types.val[ 94] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[ 95] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;
  tab_types.val[ 96] = ECS_IDEAS_SHELL_CUBIC_QUAD ;

  /* Éléments de type "Thick Shell" */

  tab_types.val[101] = ECS_IDEAS_SHELL_LINEAR_TRI ;
  tab_types.val[102] = ECS_IDEAS_SHELL_PARABOLIC_TRI ;
  tab_types.val[103] = ECS_IDEAS_SHELL_CUBIC_TRI ;
  tab_types.val[104] = ECS_IDEAS_SHELL_LINEAR_QUAD ;
  tab_types.val[105] = ECS_IDEAS_SHELL_PARABOLIC_QUAD ;
  tab_types.val[106] = ECS_IDEAS_SHELL_CUBIC_QUAD ;

  /* Éléments de type "Solid" */

  tab_types.val[111] = ECS_IDEAS_SOLID_LINEAR_TETRA ;
  tab_types.val[112] = ECS_IDEAS_SOLID_LINEAR_WEDGE ;
  tab_types.val[113] = ECS_IDEAS_SOLID_PARABOLIC_WEDGE ;
  tab_types.val[114] = ECS_IDEAS_SOLID_CUBIC_WEDGE ;
  tab_types.val[115] = ECS_IDEAS_SOLID_LINEAR_BRICK ;
  tab_types.val[116] = ECS_IDEAS_SOLID_PARABOLIC_BRICK ;
  tab_types.val[117] = ECS_IDEAS_SOLID_CUBIC_BRICK ;
  tab_types.val[118] = ECS_IDEAS_SOLID_PARABOLIC_TETRA ;

  /* Autres éléments, ignorés */

  tab_types.val[121] = ECS_IDEAS_IGNORE ;
  tab_types.val[122] = ECS_IDEAS_IGNORE ;
  tab_types.val[136] = ECS_IDEAS_IGNORE ;
  tab_types.val[137] = ECS_IDEAS_IGNORE ;
  tab_types.val[138] = ECS_IDEAS_IGNORE ;
  tab_types.val[139] = ECS_IDEAS_IGNORE ;
  tab_types.val[141] = ECS_IDEAS_IGNORE ;
  tab_types.val[151] = ECS_IDEAS_IGNORE ;
  tab_types.val[152] = ECS_IDEAS_IGNORE ;
  tab_types.val[161] = ECS_IDEAS_IGNORE ; /* Lumped Mass */
  tab_types.val[171] = ECS_IDEAS_IGNORE ; /* Axisymetric Linear Shell */
  tab_types.val[172] = ECS_IDEAS_IGNORE ; /* Axisymetric Parabolic Shell */
  tab_types.val[181] = ECS_IDEAS_IGNORE ; /* Constraint */
  tab_types.val[191] = ECS_IDEAS_IGNORE ; /* Plastic Cold Runner */
  tab_types.val[192] = ECS_IDEAS_IGNORE ; /* Plastic Hot Runner */
  tab_types.val[193] = ECS_IDEAS_IGNORE ; /* Plastic Water Line */
  tab_types.val[194] = ECS_IDEAS_IGNORE ; /* Plastic Fountain */
  tab_types.val[195] = ECS_IDEAS_IGNORE ; /* Plastic Baffle */
  tab_types.val[196] = ECS_IDEAS_IGNORE ; /* Plastic Rod Heater */
  tab_types.val[201] = ECS_IDEAS_IGNORE ; /* Linear node-to-node interface */
  tab_types.val[202] = ECS_IDEAS_IGNORE ; /* Linear edge-to-edge interface */
  tab_types.val[203] = ECS_IDEAS_IGNORE ; /* Parab. edge-to-edge interface */
  tab_types.val[204] = ECS_IDEAS_IGNORE ; /* Linear face-to-face interface */
  tab_types.val[208] = ECS_IDEAS_IGNORE ; /* Parab. face-to-face interface */
  tab_types.val[212] = ECS_IDEAS_IGNORE ; /* Linear axisymetric interface */
  tab_types.val[213] = ECS_IDEAS_IGNORE ; /* Parab. axisymetric interface */
  tab_types.val[221] = ECS_IDEAS_IGNORE ; /* Linear rigid surface */
  tab_types.val[222] = ECS_IDEAS_IGNORE ; /* Parabolic rigid surface */
  tab_types.val[231] = ECS_IDEAS_IGNORE ; /* Axisym. linear rigid surface */
  tab_types.val[232] = ECS_IDEAS_IGNORE ; /* Axisym. parab. rigid surface */

  /* Renumérotation des types gérés */

  for (ityp = 0 ; ityp < tab_types.nbr ; ityp++) {

    if (tab_types.val[ityp] > 0) {

      for (ind = 0 ;
           (   ind < ECS_IDEAS_NBR_ELT_TYP
            && (  ecs_fic_ideas_init_elt_liste_c[ind].ideas_typ
                != tab_types.val[ityp])) ;
           ind++) ;

      assert(ind < ECS_IDEAS_NBR_ELT_TYP) ;
      tab_types.val[ityp] = ind ;

    }

  }

  /* Renvoi du tableau crée et initialisé */

  return tab_types ;

}


/*----------------------------------------------------------------------------
 *  Lecture des systèmes de coordonnées
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_ideas__lit_sys_coord
(
 bft_file_t                   *const fic_maillage , /* --> Descr. fichier     */
 ecs_int_t                    *const num_ligne    , /* <-> Cpt. lignes lues   */
 ecs_tab_int_t                *const ind_coo_sys  , /* <-- Corresp. label
                                                     *     -> sys. coo référ. */
 ecs_loc_ideas_sys_coord_t  * *const coo_sys_ref    /* <-- Systèmes de coord.
                                                     *      de référence      */
)
{
  ecs_int_t    retour               ; /* Retour fonctions `scan' pour test    */
  ecs_int_t    num_rec              ; /* Numéro local de l'enregistrement     */
  ecs_int_t    iloc                 ;
  ecs_int_t    jloc                 ;

  ecs_bool_t   debut_part ;
  ecs_bool_t   erreur_decod ;
  ecs_bool_t   sys_trivial ;

  ecs_loc_ideas_sys_coord_t   coo_sys_loc ;
  ecs_int_t                   nbr_part ;
  ecs_int_t                   nbr_sys_triv ;
  ecs_int_t                   nbr_sys_cyl ;
  ecs_int_t                   nbr_sys_sphr ;
  size_t                      num_label_max ;

  char         chaine[ECS_LOC_LNG_MAX_CHAINE_IDEAS] ;          /* Ligne lue   */

  /* Variables I-DEAS lues */
  ecs_int_t    ideas_part_uid          ; /* Numéro du "part" I-DEAS           */
  ecs_int_t    ideas_sys_coo_num       ; /* Numéro du système de coordonnées  */
  ecs_int_t    ideas_sys_coo_type      ; /* Type du système de coordonnées    */
  ecs_int_t    ideas_sys_coo_color     ; /* Couleur du système                */

  char         ideas_ch_val[3][ECS_LOC_LNG_MAX_CHAINE_IDEAS];
                                         /* Chaines receptrices des valeurs   */
                                         /* avant transformation en réel      */

  ecs_real_t   transf_triv[3][4] = {{1.0, 0.0, 0.0, 0.0},
                                    {0.0, 1.0, 0.0, 0.0},
                                    {0.0, 0.0, 1.0, 0.0}} ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  nbr_part = 0 ;
  nbr_sys_triv = 0 ;
  nbr_sys_cyl  = 0 ;
  nbr_sys_sphr = 0 ;
  num_label_max = 0 ;

  ind_coo_sys->nbr = 5 ;
  BFT_MALLOC(ind_coo_sys->val, ind_coo_sys->nbr, ecs_int_t) ;

  *coo_sys_ref = NULL ;

  num_rec = 1 ;

  debut_part = ECS_FALSE ;
  erreur_decod = ECS_FALSE ;


  /*========================================================*/
  /* Tant qu'on n'a pas atteint la fin de fichier           */
  /* et que la ligne lue n'est pas le separateur de dataset */
  /*========================================================*/

  while (bft_file_gets_try(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                           fic_maillage, num_ligne) != NULL
         && strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0) {


    /* Lecture d'un système de coordonnées */
    /*=====================================*/

    /*
     * On ne sait pas à priori si on change de "part" (enregistrements
     * 1 et 2 non répétés pour systèmes d'un même "part") ; dans un cas
     * on lit les enregistrements 1 à 8, dans l'autre on ne lit que les
     * enregistrements 3 à 8.
     */

    switch (num_rec) {

    case 1: /* UID de part (format 1I10) */
    case 3: /* label, type, et couleur du système (format 3I10) */

      /* On vérifie si on n'est pas déjà à l'enregistrement 3 :          */

      retour = sscanf(chaine,
                      " %" ECS_FORMAT_ecs_int_t
                      " %" ECS_FORMAT_ecs_int_t
                      " %" ECS_FORMAT_ecs_int_t,
                      &ideas_sys_coo_num,
                      &ideas_sys_coo_type,
                      &ideas_sys_coo_color) ;

      if (retour == 3) {

        coo_sys_loc.label = ideas_sys_coo_num ;
        coo_sys_loc.type  = ideas_sys_coo_type ;

        if (num_rec == 1) /* On a bien lu l'enregistrement 3, et non 1 */
          num_rec = 3 ;

      }
      else if (num_rec == 1) {

        /* UID de part (format 3I10) */
        retour = sscanf(chaine,
                        " %" ECS_FORMAT_ecs_int_t,
                        &ideas_part_uid) ;

        if (retour != 1)
          erreur_decod = ECS_TRUE ;
        else
          debut_part = ECS_TRUE ;

      }

      else
        erreur_decod = ECS_TRUE ;

      break ;

    case 2: /* Nom de part associé           (format 40A2) inutile ici */
    case 4: /* Nom de système de coordonnées (format 40A2) inutile ici */

      break ;

    case 5: /* 1ère rangée de la matrice de transformation (format 1P3D25.16) */
    case 6: /* 2ème rangée de la matrice de transformation (format 1P3D25.16) */
    case 7: /* 3ème rangée de la matrice de transformation (format 1P3D25.16) */
    case 8: /* 4ème rangée de la matrice de transformation (format 1P3D25.16) */

      /* I-DEAS peut sortir des coordonnées avec un exposant D        */
      /* qui ne peuvent pas etre relues de maniere portable par le C. */
      /* On lit donc les coordonnées en les placant dans des chaînes  */

    /* Format Ideas : 1P3D25.16 */

    retour = sscanf(chaine, " %s %s %s",
                    ideas_ch_val[0], ideas_ch_val[1], ideas_ch_val[2]);

    if ( retour != 3 )
      erreur_decod = ECS_TRUE ;

    else {

    /* On transforme les coordonnées sous forme de chaîne          */
    /* en substituant l'exposant D par un exposant E et on renvoie */
    /* le réel correspondant                                       */

    for (jloc = 0 ; jloc < 3 ; jloc++)
      coo_sys_loc.transf[jloc][num_rec - 5]
        = ecs_loc_pre_ideas__transf_expo(ideas_ch_val[jloc]) ;

    }

    break ;

    default:
      assert(num_rec > 0 && num_rec < 9) ;

    }

    if (erreur_decod == ECS_TRUE)
      bft_error(__FILE__, __LINE__, errno,
                _("Error reading line %d of file \"%s\"."),
                *num_ligne, bft_file_get_name(fic_maillage));

    num_rec += 1 ;


    /* On a terminé pour le système de coordonnées en cours */
    /*------------------------------------------------------*/

    if (num_rec > 8) {

      num_rec = 1 ;

      /* En fait, les coordonnées des points sont décrites en fonction
         du système de coordonnées principal attaché à la part,
         et non du système de coordonnées local */

      if (debut_part == ECS_TRUE) {

        nbr_part += 1 ;
        BFT_REALLOC(*coo_sys_ref, nbr_part, ecs_loc_ideas_sys_coord_t) ;

        (*coo_sys_ref)[nbr_part - 1] = coo_sys_loc ;

        debut_part = ECS_FALSE ;

        /* Repérage des systèmes de coordonnées "triviaux"
           ou non cartésiens */

        sys_trivial = ECS_TRUE ;

        if (coo_sys_loc.type == 0) {
          for (jloc = 0 ; jloc < 3 ; jloc++) {
            for (iloc = 0 ; iloc < 4 ; iloc++) {
              if (ECS_ABS(  coo_sys_loc.transf[jloc][iloc]
                          - transf_triv[jloc][iloc])
                  > ECS_REAL_PRECISION)
                sys_trivial = ECS_FALSE ;
            }
          }
        }
        else {
          sys_trivial = ECS_FALSE ;
          if (coo_sys_loc.type == 1)
            nbr_sys_cyl += 1 ;
          else if (coo_sys_loc.type == 2)
            nbr_sys_sphr += 1 ;
        }

        if (sys_trivial == ECS_TRUE)
          nbr_sys_triv += 1 ;

      }

      num_label_max = ECS_MAX(coo_sys_loc.label, (ecs_int_t)num_label_max) ;

      if (num_label_max > ind_coo_sys->nbr) {
        ind_coo_sys->nbr = num_label_max*2 ;
        BFT_REALLOC(ind_coo_sys->val, ind_coo_sys->nbr, ecs_int_t) ;
      }

      ind_coo_sys->val[coo_sys_loc.label - 1] = nbr_part - 1 ;

    }

  }

  ind_coo_sys->nbr = num_label_max ;
  BFT_REALLOC(ind_coo_sys->val, ind_coo_sys->nbr, ecs_int_t) ;

  /* Les systèmes de coordonnées ne pris en compte que si nécessaire */

  if (nbr_sys_cyl > 0 || nbr_sys_sphr >0) {
    bft_printf(_("    %d cylindrical system(s) and "
                 "%d spherical system(s) not converted;\n"),
               (int)nbr_sys_cyl, (int)nbr_sys_sphr) ;

    bft_printf(_("    probable problems depending on I-deas "
                 "construction and export\n\n")) ;
  }

  if (getenv("ECS_PRE_IDEAS_IGNORE_SYS_COO") != NULL) {
    if (atoi(getenv("ECS_PRE_IDEAS_IGNORE_SYS_COO")) > 0 ) {

      if (nbr_part - nbr_sys_triv > 0) {

        bft_printf(_("  Ignored coordinate systems:\n")) ;
        bft_printf(_("    %d non-identity transformation(s) ignored:\n"),
                   (int)(nbr_part - nbr_sys_triv)) ;

        nbr_sys_triv = nbr_part ;
      }
    }
  }

  if (nbr_sys_triv == nbr_part) {
    ind_coo_sys->nbr = 0 ;
    BFT_FREE(ind_coo_sys->val) ;
    BFT_FREE(*coo_sys_ref) ;
  }

}


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

static ecs_entmail_t * ecs_loc_pre_ideas__lit_nodes
(                                          /* <-- 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     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_tab_int_t  tab_label_ent[]          , /* <-- Tableau labels par entite   */
 ecs_bool_t     bool_label_ent_a_trier[] , /* <-- Indicateur de labels tries  */
 ecs_tab_int_t  ind_coo_sys              , /* --> Label -> sys. coord. réf.   */
 ecs_loc_ideas_sys_coord_t  coo_sys_ref[]  /* --> Sys. coord. référence  */

)
{

  ecs_int_t    retour               ; /* Retour des fnctions `scan' pour test */
  char       chaine[ECS_LOC_LNG_MAX_CHAINE_IDEAS]  ;           /* Ligne lue   */

  /* Variables Ideas lues */
  ecs_int_t    ideas_num_nod           ; /* Numero  Ideas du noeud            */
  ecs_int_t    ideas_sys_coo           ; /* Sys. coo. de référence du noeud   */

  char       ideas_ch_coord[3][ECS_LOC_LNG_MAX_CHAINE_IDEAS];
                                         /* Chaines receptrices des coords    */
                                         /* avant transformation en reel      */

  ecs_real_t   coord[3]                ; /* Coordonnees reelles du sommet     */
  ecs_int_t    max_som                 ; /* Dim d'allocation de tab. locaux   */
  ecs_int_t    nbr_som_max             ; /* Nombre initial de sommets         */

  ecs_int_t    icoo                    ; /* Indice de boucle sur les comp.    */
                                         /* des coordonnees (X, Y et Z)       */
  ecs_dim_t    dim_loc_e               ;

  /* Stockage avant transfert */
  /*--------------------------*/

  ecs_int_t    cpt_som = 0             ; /* Compteur des sommets lus          */
  ecs_int_t  * som_val_label           ;

  ecs_real_t * som_val_coord           ;

  ecs_entmail_t *entmail_som           ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  dim_loc_e = ECS_DIM_2 ;

  nbr_som_max = ecs_loc_nbr_max_elt_c * ecs_loc_nbr_moy_som_c ;

  max_som   = nbr_som_max ;

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


  /*========================================================*/
  /* Tant qu'on n'a pas atteint la fin de fichier           */
  /* et que la ligne lue n'est pas le separateur de dataset */
  /*========================================================*/

  while (bft_file_gets_try(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                           fic_maillage, num_ligne) != NULL
         && strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0) {


    /* Lecture des caracteristiques du noeud */
    /*=======================================*/

    /* Format Ideas : 4I10 */

    retour = sscanf(chaine,
                    " %" ECS_FORMAT_ecs_int_t " %" ECS_FORMAT_ecs_int_t,
                    &ideas_num_nod, &ideas_sys_coo) ;

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

    /* Lecture des coordonnees du sommet */
    /*===================================*/

    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                  fic_maillage, num_ligne) ;

    /* Ideas peut sortir des coordonnees avec un exposant D         */
    /* qui ne peuvent pas etre relues de maniere portable par le C. */
    /* On lit donc les coordonnees en les placant dans des chaines  */

    /* Format Ideas : 1P3D25.16 */

    retour = sscanf(chaine, " %s %s %s",
                    ideas_ch_coord[0], ideas_ch_coord[1], ideas_ch_coord[2]);

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

    /* On transforme les coordonnees sous forme de chaine          */
    /* en substituant l'exposant D par un exposant E et on renvoit */
    /* le reel correspondant                                       */

    for ( icoo = 0 ; icoo < ECS_DIM_3 ; icoo++ ) {
      coord[icoo] = ecs_loc_pre_ideas__transf_expo( ideas_ch_coord[icoo] ) ;
    }

    if (ECS_ABS(coord[ECS_DIM_2]) > ECS_REAL_PRECISION)
      dim_loc_e = ECS_DIM_3 ;


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

    /* Reallocation eventuelles des tableaux locaux */
    /*----------------------------------------------*/

    if (max_som   <= cpt_som) {

      max_som = ECS_MAX(max_som * 2, cpt_som + 1) ;

      BFT_REALLOC(som_val_coord,   max_som * ECS_DIM_3, ecs_real_t) ;
      BFT_REALLOC(som_val_label,   max_som, ecs_int_t) ;

    }


    /* Coordonnees du sommet lu */
    /*--------------------------*/

    if (ind_coo_sys.nbr > 0) {

      ideas_sys_coo = ind_coo_sys.val[ideas_sys_coo - 1] ;

      for ( icoo = 0 ; icoo < ECS_DIM_3 ; icoo++ ) {
        som_val_coord[cpt_som * ECS_DIM_3 + icoo]
          = (  coo_sys_ref[ideas_sys_coo].transf[icoo][0] * coord[0]
             + coo_sys_ref[ideas_sys_coo].transf[icoo][1] * coord[1]
             + coo_sys_ref[ideas_sys_coo].transf[icoo][2] * coord[2]
             + coo_sys_ref[ideas_sys_coo].transf[icoo][3]) ;
      }

    }
    else {

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

    }


    /* Etiquette   du sommet lu */
    /*--------------------------*/

    if ((bool_label_ent_a_trier[ECS_ENTMAIL_SOM] == ECS_FALSE) &&
        (cpt_som > 0) && (som_val_label[cpt_som - 1] > ideas_num_nod))
      bool_label_ent_a_trier[ECS_ENTMAIL_SOM] = ECS_TRUE ;

    som_val_label[cpt_som] = ideas_num_nod ;


    /* Incrementation du compteur de sommets lus */
    /*===========================================*/

    cpt_som++ ;


  } /* Fin : tant qu'il y a une ligne a lire et                       */
    /*       tant que la ligne lue n'est pas le separateur de dataset */

  if (strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0)

    bft_file_read_check_error(fic_maillage,
                              *num_ligne) ;


  /* else : on a lu jusqu'au separateur de dataset */



  /* Reallocations des tableaux locaux */
  /*===================================*/


  BFT_REALLOC(som_val_coord,   cpt_som * ECS_DIM_3, ecs_real_t);
  BFT_REALLOC(som_val_label,   cpt_som            , ecs_int_t);


  /* Transfert des valeurs lues dans la structure d'entite de maillage */
  /*===================================================================*/


  entmail_som = ecs_entmail_pre__cree_som(ECS_DIM_3,
                                          cpt_som,
                                          som_val_coord,
                                          som_val_label) ;


  /* On ne tient pas compte de l'appartenance de sommets à des   */
  /* groupes, et on n'a plus besoin des labels                   */
  /*=============================================================*/


  tab_label_ent[ECS_ENTMAIL_SOM].val = NULL ;
  tab_label_ent[ECS_ENTMAIL_SOM].nbr = 0 ;


  /* Maillage en dimension 3 */
  *dim_e = ECS_DIM_3 ;

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


  return entmail_som ;

}


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

static ecs_entmail_t ** ecs_loc_pre_ideas__lit_elements
(                                          /* <-- Renvoie les entites         */
                                           /*      aretes, faces et cellules  */
 bft_file_t    *fic_maillage             , /* --> Descripteur fichier a lire  */
 ecs_int_t     *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_tab_int_t  tab_label_ent[]          , /* <-- Tableau labels par entite   */
 ecs_bool_t     bool_label_ent_a_trier[]   /* <-- Indicateur de labels tries  */
)
{

  int        retour ;                 /* Retour fonctions `scan' pour test    */
  char       chaine[ECS_LOC_LNG_MAX_CHAINE_IDEAS] ;            /* Ligne lue   */
  char      *ssch ;                   /* Sous-chaine de lecture               */

  /* Variables Ideas lues */
  int          ideas_num_elt        ; /* Numero         Ideas de l'element    */
  int          ideas_fe_des_id      ; /* Identificateur Ideas de l'element    */
  int          ideas_color          ; /* Couleur        Ideas de l'element    */
  int          ideas_nbr_nod_elt    ; /* Nombre de noeuds     de l'element    */
  int          ideas_nod_elt[ECS_IDEAS_NBR_MAX_SOM] ;
                                      /* Numeros des noeuds de l'element      */

  int          nbr_som_elt          ; /* Nb de noeuds a lire = nbr de sommets */
  int          nbr_nod_elt_reste    ; /* Nb de noeuds de l'elt restant a lire */
  int          nbr_nod_ligne        ; /* Nb de noeuds par ligne lue           */
  ecs_int_t    ent_num              ; /* Numero de l'entite concernee         */
  size_t       max_som_ent[ECS_ENTMAIL_FIN]; /* Longueur alloc tableaux loc.  */
  size_t       max_elt_ent[ECS_ENTMAIL_FIN]; /* Longueur alloc tableaux loc.  */
  size_t       num_pos              ; /* Nouvel indice de stockage            */

  ecs_int_t    icoul                ; /* Indice de boucle sur les couleurs    */
  ecs_int_t    ient                 ; /* Indice de boucle sur les entites     */
  ecs_int_t    inod                 ; /* Indice de boucle sur les noeuds      */
  ecs_int_t    inod_lig             ; /* Indice de boucle des noeuds sur      */
                                      /*  1 ligne de lecture                  */
  ecs_int_t    inum_som             ; /* Indice Ideas des sommets             */
  ecs_int_t    isom                 ; /* Indice de boucle sur les sommets     */
  ecs_int_t    ityp                 ; /* Boucle sur les types d'elements      */
  size_t       ival ;
  ecs_int_t    cpt_coul_ent[ECS_ENTMAIL_FIN]; /* Compteur de couleurs         */
  ecs_int_t   *val_coul_ent[ECS_ENTMAIL_FIN]; /* Tableau valeurs des couleurs */
  ecs_size_t  *cpt_elt_coul_ent[ECS_ENTMAIL_FIN];

  ecs_tab_int_t  corresp_typ ;        /* Tableau de correspondance des types  */


  /* Stockage avant transfert */
  /*--------------------------*/

  size_t       cpt_elt_ent        [ECS_ENTMAIL_FIN]; /* Nombre d'elems/entite */

  ecs_size_t  *elt_pos_som_ent    [ECS_ENTMAIL_FIN]; /* Positions numeros som */
  ecs_int_t   *elt_val_som_ent    [ECS_ENTMAIL_FIN]; /* Numeros des sommets   */
  ecs_int_t   *elt_val_label_ent  [ECS_ENTMAIL_FIN]; /* Etiquettes            */
  ecs_int_t   *elt_val_color_ent  [ECS_ENTMAIL_FIN]; /* Couleurs              */

  ecs_entmail_t **vect_entmail ;


  /*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 (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++) {

    cpt_elt_ent        [ient] = 0 ;

    cpt_coul_ent       [ient] = 0    ;
    cpt_elt_coul_ent   [ient] = NULL ;
    val_coul_ent       [ient] = NULL ;

    max_som_ent        [ient] = ecs_loc_nbr_max_elt_c * ecs_loc_nbr_moy_som_c ;
    max_elt_ent        [ient] = ecs_loc_nbr_max_elt_c ;

  }

  corresp_typ = ecs_loc_pre_ideas__tab_types() ;

  /*========================================================*/
  /* Tant qu'on n'a pas atteint la fin de fichier           */
  /* et que la ligne lue n'est pas le separateur de dataset */
  /*========================================================*/


#define ECS_FCT_TYP(ityp) ecs_fic_ideas_init_elt_liste_c[ityp].ecs_typ


  while (bft_file_gets_try(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                           fic_maillage, num_ligne) != NULL
         && strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0){


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

    /* Format Ideas : 6I10 */

    retour = sscanf(chaine,
                    " %"  ECS_FORMAT_ecs_int_t
                    " %"  ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %"  ECS_FORMAT_ecs_int_t
                    " %"  ECS_FORMAT_ecs_int_t,
                    &ideas_num_elt,
                    &ideas_fe_des_id,
                    &ideas_color,
                    &ideas_nbr_nod_elt);


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


    /* Est-ce un element dont le type Ideas est reconnu ?              */
    /* Est-ce un element `non lineaire' (`cubique' ou `parabolique') ? */
    /*-----------------------------------------------------------------*/

    if (ideas_fe_des_id < (int)(corresp_typ.nbr))
      ityp = corresp_typ.val[ideas_fe_des_id] ;
    else
      ityp = ECS_IDEAS_UNKNOWN ;

    if (ityp == ECS_IDEAS_UNKNOWN || ityp == ECS_IDEAS_UNHANDLED) {

      /* Le type Ideas de l'element n'est pas reconnu */

      if (ityp == ECS_IDEAS_UNKNOWN)
        bft_error(__FILE__, __LINE__, 0,
                  _("Error reading an I-deas universal file:\n"
                    "at line %d of file \"%s\".\n"
                    "Type identifier <%d> of element <%d> not recognized."),
                  (int)(*num_ligne), bft_file_get_name(fic_maillage),
                  (int)ideas_fe_des_id, (int)ideas_num_elt);

      else /* if (ityp == ECS_IDEAS_UNHANDLED) */
        bft_error(__FILE__, __LINE__, 0,
                  _("Error reading an I-deas universal file:\n"
                    "at line %d of file \"%s\".\n"
                    "Type identifier <%d> of element <%d> recognized "
                    "but not handled."),
                  (int)(*num_ligne), bft_file_get_name(fic_maillage),
                  (int)ideas_fe_des_id, (int)ideas_num_elt);

    }
    /* else :  le type Ideas de l'element est reconnu */


    /* Est-ce un element `poutre' (`beam') ? */
    /*---------------------------------------*/

    if (ityp > -1 && ityp < ECS_IDEAS_NBR_ELT_BEAM) {

      /* On saute la ligne qui contient les champs propres aux `beam' */

      /* Format Ideas : 3I10 */

      bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                    fic_maillage, num_ligne) ;

    }


    /* Lecture des numeros de noeuds constituant l'element */
    /*=====================================================*/

    /* Format Ideas : 8I10 (pour chaque ligne) */

    /* Nombre de noeuds a lire =              */
    /*  nombre de noeuds qui sont des sommets */
    nbr_som_elt = ecs_fic_elt_typ_liste_c[ECS_FCT_TYP(ityp)].nbr_som ;

    nbr_nod_elt_reste = ideas_nbr_nod_elt ;

    isom     = 0 ;
    inod     = 0 ;
    inum_som = 0 ;

    do {

      bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                    fic_maillage, num_ligne) ;

      /* Lecture des numeros de noeuds pour la ligne courante */

      nbr_nod_ligne
        = ECS_MIN(nbr_nod_elt_reste, ECS_IDEAS_NBR_NODE_PER_LINE) ;

      ssch = strtok(chaine, " ");

      for ( inod_lig = 0 ; inod_lig <  nbr_nod_ligne ; inod_lig++ ) {

        if (inod == (ecs_fic_ideas_init_elt_liste_c[ityp].num_som[inum_som]-1)){
          retour = sscanf(ssch,"%"ECS_FORMAT_ecs_int_t, &ideas_nod_elt[isom++]);
          ssch   = strtok(NULL, " ");
          inum_som++ ;
        }
        else {
          retour = sscanf(ssch, "%*" ECS_FORMAT_ecs_int_t "");
          ssch   = strtok(NULL, " ");
        }

        inod++ ;

      }
      if (ssch != NULL)
        bft_error(__FILE__, __LINE__, errno,
                  _("Error reading line %d of file \"%s\"."),
                  *num_ligne, bft_file_get_name(fic_maillage));

      nbr_nod_elt_reste = nbr_nod_elt_reste - nbr_nod_ligne ;

    } while (nbr_nod_elt_reste != 0);

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

    /* Si ce type d'élément est à ignorer, on passe au suivant */

    if (ityp == ECS_IDEAS_IGNORE)
      continue ;

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

    /* Identification de l'entite concernee */
    /*--------------------------------------*/

    ent_num =
      ecs_entmail_pre__ret_typ_geo(ecs_fic_ideas_init_elt_liste_c[ityp].ecs_typ);


    if (cpt_elt_ent[ent_num] != 0) {

      /* Reallocations eventuelles des tableaux locaux */
      /*-----------------------------------------------*/

      if (max_elt_ent[ent_num] <= cpt_elt_ent[ent_num]) {

        max_elt_ent[ent_num] = ECS_MAX(max_elt_ent[ent_num] * 2,
                                       cpt_elt_ent[ent_num] + 1) ;

        BFT_REALLOC(elt_val_label_ent[ent_num],   max_elt_ent[ent_num],
                    ecs_int_t) ;

        BFT_REALLOC(elt_val_color_ent[ent_num],   max_elt_ent[ent_num],
                    ecs_int_t) ;

        BFT_REALLOC(elt_pos_som_ent[ent_num],     max_elt_ent[ent_num] + 1,
                    ecs_size_t) ;

      }

    }
    else { /* cpt_elt_ent[ent_num] == 0 */

      /* C'est la premiere fois que l'entite est concernee */
      /* On initialise les allocations des tableaux        */
      /*---------------------------------------------------*/

      BFT_MALLOC(elt_pos_som_ent[ent_num]    ,
                 max_elt_ent[ent_num] + 1    , ecs_size_t) ;
      BFT_MALLOC(elt_val_som_ent[ent_num]    ,
                 max_som_ent[ent_num]        , ecs_int_t) ;
      BFT_MALLOC(elt_val_label_ent[ent_num]  ,
                 max_elt_ent[ent_num]        , ecs_int_t) ;
      BFT_MALLOC(elt_val_color_ent[ent_num]  ,
                 max_elt_ent[ent_num]        , ecs_int_t) ;

      elt_pos_som_ent[ent_num][0] = 1 ;

    }


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

    if (max_som_ent[ent_num] <= num_pos) {
      max_som_ent[ent_num] = ECS_MAX(max_som_ent[ent_num] * 2, num_pos + 1) ;
      BFT_REALLOC(elt_val_som_ent[ent_num], max_som_ent[ent_num], ecs_int_t) ;
    }


    /* Determination de la position des numeros de sommets */
    /* du prochain element                                 */
    /*-----------------------------------------------------*/

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


    /* Connectivite de l'element par ses numeros de sommets */
    /*------------------------------------------------------*/

    for ( inod = 0 ; inod <  nbr_som_elt ; inod++ ) {

      elt_val_som_ent
        [ent_num]
        [elt_pos_som_ent[ent_num][cpt_elt_ent[ent_num]] - 1 + inod]
        = ideas_nod_elt[inod];

    }


    /* Etiquette de l'element lu */
    /*---------------------------*/

    if (((bool_label_ent_a_trier[ent_num]) == ECS_FALSE) &&
        (cpt_elt_ent[ent_num] > 0) &&
        (elt_val_label_ent[ent_num][cpt_elt_ent[ent_num] - 1] > ideas_num_elt))
        bool_label_ent_a_trier[ent_num] = ECS_TRUE ;

    elt_val_label_ent[ent_num][cpt_elt_ent[ent_num]] = ideas_num_elt ;


    /* Couleur   de l'element lu */
    /*---------------------------*/

    icoul = 0 ;
    while (icoul < cpt_coul_ent[ent_num]               &&
           val_coul_ent[ent_num][icoul] != ideas_color    )
      icoul++ ;

    if (icoul == cpt_coul_ent[ent_num]) {

      /* La valeur de la couleur n'a pas encore ete stockee */

      BFT_REALLOC(val_coul_ent[ent_num]    , cpt_coul_ent[ent_num] + 1,
                  ecs_int_t) ;
      BFT_REALLOC(cpt_elt_coul_ent[ent_num], cpt_coul_ent[ent_num] + 1,
                  ecs_size_t) ;
      cpt_elt_coul_ent[ent_num][icoul] = 0 ;
      val_coul_ent[ent_num][icoul] = ideas_color ;
      cpt_coul_ent[ent_num]++ ;

    }

    cpt_elt_coul_ent[ent_num][icoul]++ ;
    elt_val_color_ent[ent_num][cpt_elt_ent[ent_num]] = icoul + 1 ;


    /* Incrementation du nombre d'elements lus */
    /*=========================================*/

    cpt_elt_ent[ent_num]++ ;


  } /* Fin : tant qu'il y a une ligne a lire et                       */
    /*       tant que la ligne lue n'est pas le separateur de dataset */


#undef ECS_FCT_TYP


  if (strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0)

    bft_file_read_check_error(fic_maillage,
                              *num_ligne) ;


  /* else : on a lu jusqu'au separateur de dataset */

  corresp_typ.nbr = 0 ;
  BFT_FREE(corresp_typ.val) ;


  /* Reallocations des tableaux locaux */
  /*===================================*/


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

    if (cpt_elt_ent[ient] != 0) {
      BFT_REALLOC(elt_pos_som_ent[ient]    ,
                  cpt_elt_ent[ient] + 1    , ecs_size_t) ;
      BFT_REALLOC(elt_val_som_ent[ient]    ,
                  elt_pos_som_ent[ient][cpt_elt_ent[ient]] - 1, ecs_int_t) ;
      BFT_REALLOC(elt_val_label_ent[ient]  ,
                  cpt_elt_ent[ient]        , ecs_int_t) ;
      BFT_REALLOC(elt_val_color_ent[ient]  ,
                  cpt_elt_ent[ient]        , ecs_int_t) ;
    }

  }



  /* On conserve les listes des labels pour la lecture des groupes */
  /*===============================================================*/


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

    /* S'il y a au moins un element de cette entite de maillage */

    if (cpt_elt_ent[ient] != 0) {

      BFT_MALLOC(tab_label_ent[ient].val, cpt_elt_ent[ient], ecs_int_t);
      for (ival = 0 ; ival < cpt_elt_ent[ient] ; ival++)
        tab_label_ent[ient].val[ival] = elt_val_label_ent[ient][ival] ;
      tab_label_ent[ient].nbr = cpt_elt_ent[ient] ;

    }

  }



  /* Transfert des valeurs lues dans les structures d'entite de maillage */
  /*=====================================================================*/


  vect_entmail = 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) ;


  return vect_entmail ;


}


/*----------------------------------------------------------------------------
 *  Lecture des groupes
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_ideas__lit_groups
(
 bft_file_t     *fic_maillage             , /* --> Descripteur fichier a lire */
 ecs_int_t      *num_ligne                , /* <-> Compteur des lignes lues   */
 ecs_int_t       nbr_ent_par_ligne        , /* --> Nombre d'entites a lire    */
                                            /*      par ligne par groupe      */
 ecs_tab_int_t   tab_label_ent[]          , /* --> Tableau labels par entite  */
 ecs_bool_t      bool_label_ent_a_trier[] , /* <-- Indicateur de labels tries */
 ecs_entmail_t **vect_entmail               /* <-> Entites maillage a remplir */
)
{

  ecs_int_t    retour                ; /* Retour fonctions `scan' pour test   */
  char       chaine[ECS_LOC_LNG_MAX_CHAINE_IDEAS]  ;           /* Ligne lue   */
  char     * ssch                    ; /* Sous-chaine de lecture              */

  /* Variables Ideas lues */
  ecs_int_t    ideas_grp_num         ; /* Numero Ideas du groupe              */
  ecs_int_t    ideas_nbr_entities    ; /* Nombre d'entites a lire par groupe  */
  char       ideas_grp_name[ECS_IDEAS_LEN_GROUP_NAME]; /* Nom du groupe       */
  ecs_int_t  * ideas_typ_entity      ; /* Types Ideas des entites du groupe   */
  ecs_int_t  * ideas_tag_entity      ; /* Etiquettes Ideas des entites du grp */

  ecs_descr_t  * descr_grp           ; /* Pointeur sur descripteur de champ   */
  ecs_int_t    nbr_entities_lues     ; /* Nbr d'entites du groupe lues        */
  ecs_int_t    nbr_entities_ligne    ; /* Nbr d'entites  par ligne lue        */
  ecs_int_t    num_ent               ; /* Numero de l'entite                  */
  size_t       num_label             ; /* Numero d'indice de l'etiquette      */
  ecs_tab_int_t  tab_num             ;
  ecs_tab_int_t  tab_tag             ;
  ecs_tab_int_t  tab_label_elt       ; /* Vecteur des labels des elements     */
                                       /*  pour l'ensemble des entites        */
  ecs_tab_int_t  tab_label_elt_trie  ;
  ecs_tab_int_t  vect_renum_val_elt  ;

  size_t       cpt_elt               ;
  size_t       nbr_elt               ;
  size_t       nbr_elt_ent           ;
  size_t       ielt                  ; /* Indice de boucle sur les elements   */
  size_t       ient                  ; /* Indice de boucle sur les entites    */
  ecs_int_t    ient_sup              ;
  ecs_int_t    ientity               ; /* Indice de boucle sur les elements   */
                                       /*  d'un groupe IDEAS                  */
  size_t       ipos                  ;
  size_t       ival                  ;

  ecs_bool_t   bool_aff_grp          ;
  ecs_bool_t   bool_label_elt_a_trier  ;
  size_t       ent_nbr_elt[ECS_ENTMAIL_FIN];
  ecs_int_t    min_val_ent[ECS_ENTMAIL_FIN];
  ecs_int_t    max_val_ent[ECS_ENTMAIL_FIN];
  ecs_int_t    tab_ent[ECS_ENTMAIL_FIN]    ;
  ecs_int_t    ind_ent                 ;
  ecs_int_t    min_ent                 ;
  ecs_int_t    tmp_ent                 ;

  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 ;
    }

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

    ent_champ_grp[ient] = NULL ;

  }


  tab_tag.nbr = 1 ;
  tab_num.nbr = 1 ;
  BFT_MALLOC(tab_num.val, 1, ecs_int_t) ;


  /*-------------------------------------------------------------------------*/
  /* On cherche s'il est possible d'ordonner les labels des elements         */
  /*  sans effectuer de tri :                                                */
  /*  simplement en ordonnant les entites                                    */
  /*                                                                         */
  /* Ce n'est possible que si :                                              */
  /* - les labels pour chaque entite sont ordonnes                           */
  /*   (`bool_label_ent_a_trier[ient] == ECS_TRUE')                          */
  /* - les labels entre les differentes entites ne se chevauchent pas        */
  /*                                                                         */
  /* Exemple :                                                               */
  /*  -    si les labels des aretes   sont compris entre 7 et  9             */
  /*  - et si les labels des faces    sont compris entre 3 et  5             */
  /*  - et si les labels des cellules sont compris entre 1 et  2             */
  /* en concatenant les labels des cellules, puis des faces, puis des aretes */
  /*  l'ensemble des labels sur les elements sera ordonne                    */
  /*-------------------------------------------------------------------------*/

  bool_label_elt_a_trier = ECS_FALSE ;

  nbr_elt = 0 ;
  tab_ent[ECS_ENTMAIL_SOM] = ECS_ENTMAIL_SOM ;
  for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++) {
      nbr_elt += tab_label_ent[ient].nbr ;
      tab_ent[ient] = ient ;
      if (bool_label_ent_a_trier[ient] == ECS_TRUE)
        bool_label_elt_a_trier = ECS_TRUE ;
  }


  if (bool_label_elt_a_trier == ECS_FALSE) {

    for (ient =  (ecs_int_t)ECS_ENTMAIL_CEL ;
         ient >= (ecs_int_t)ECS_ENTMAIL_ARE ; ient--) {

      if (tab_label_ent[ient].nbr != 0) {

        min_val_ent[ient]= tab_label_ent[ient].val[0] ;
        max_val_ent[ient]= tab_label_ent[ient].val[tab_label_ent[ient].nbr - 1];

        min_ent = ient ;

      }

    }

    for (ient = min_ent ;
         ient < ECS_ENTMAIL_FIN && bool_label_elt_a_trier == ECS_FALSE ;
         ient++) {

      if (tab_label_ent[ient].nbr != 0) {

        for (ient_sup = ient + 1 ;
             ient_sup < ECS_ENTMAIL_FIN && bool_label_elt_a_trier == ECS_FALSE ;
             ient_sup++) {

          if (tab_label_ent[ient_sup].nbr != 0) {

            if((min_val_ent[tab_ent[ient_sup]]<max_val_ent[tab_ent[ient]]&&
                max_val_ent[tab_ent[ient_sup]]>max_val_ent[tab_ent[ient]] )||
               (min_val_ent[tab_ent[ient_sup]]<min_val_ent[tab_ent[ient]]&&
                max_val_ent[tab_ent[ient_sup]]>min_val_ent[tab_ent[ient]] )  ){

              /* Les valeurs des labels entre entites se chevauchent :    */
              /*  il faut ordonner l'ensemble des labels sur les elements */

              bool_label_elt_a_trier = ECS_TRUE ;

            }
            else if(max_val_ent[tab_ent[ient_sup]]<min_val_ent[tab_ent[ient]]){

              /* On echange l'ordre des entites    */
              /*  pour la concatenation des labels */

              tmp_ent           = tab_ent[ient] ;
              tab_ent[ient]     = tab_ent[ient_sup] ;
              tab_ent[ient_sup] = tmp_ent ;

            }
            /* else : rien a faire (les entites sont bien ordonnees */

          } /* Fin : s'il y a des labels pour cette entite superieure */

        } /* Fin : boucle sur les entites superieures a l'entite courante */

      } /* Fin : s'il y a des labels pour cette entite */

    } /* Fin : boucle sur les entites */

  } /* Fin : si toute les entites ont des labels ordonnes */


  if (bool_label_elt_a_trier == ECS_TRUE)
    for (ient = ECS_ENTMAIL_ARE ; ient < ECS_ENTMAIL_FIN ; ient++)
      tab_ent[ient] = ient ;



  BFT_MALLOC(tab_label_elt.val, nbr_elt, ecs_int_t) ;
  tab_label_elt.nbr = nbr_elt ;

  cpt_elt = 0 ;

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

    for (ielt = 0 ; ielt <  tab_label_ent[tab_ent[ient]].nbr ; ielt++)
      tab_label_elt.val[cpt_elt++] = tab_label_ent[tab_ent[ient]].val[ielt] ;

  }


  /*------------------------------------------------*/
  /* Ordination des elements suivant leur etiquette */
  /*------------------------------------------------*/

  BFT_MALLOC(vect_renum_val_elt.val, nbr_elt, ecs_int_t) ;
  vect_renum_val_elt.nbr = nbr_elt ;

  if (bool_label_elt_a_trier == ECS_TRUE) {

    tab_label_elt_trie = ecs_tab_int__trie_et_renvoie(tab_label_elt,
                                                      vect_renum_val_elt) ;
  }
  else {
    tab_label_elt_trie = tab_label_elt ;
    for (ipos = 0 ; ipos < nbr_elt ; ipos++)
      vect_renum_val_elt.val[ipos] = ipos ;
  }


  ideas_typ_entity   = NULL ; /* Pour le REALLOC au 1er passage */
  ideas_tag_entity   = NULL ; /* Pour le REALLOC au 1er passage */
  ideas_nbr_entities = 0    ;


  /*========================================================*/
  /* Tant qu'on n'a pas atteint la fin de fichier           */
  /* et que la ligne lue n'est pas le separateur de dataset */
  /*========================================================*/


  while (bft_file_gets_try(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                           fic_maillage, num_ligne) != NULL
         && strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0) {


    /* On alloue et initialise pour le groupe a lire */
    /*===============================================*/

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

      ent_cpt_elt[ient] = 0 ;
      ent_val_grp[ient] = NULL ;

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

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


    /* lecture d'un groupe */
    /*=====================*/

    /* Lecture des caracteristiques du groupe */
    /*----------------------------------------*/

    /* Format Ideas : 8I10 */

    retour = sscanf(chaine,
                    " %"  ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %*" ECS_FORMAT_ecs_int_t
                    " %"  ECS_FORMAT_ecs_int_t,
                    &ideas_grp_num,
                    &ideas_nbr_entities);

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


    /* Lecture du nom du groupe */
    /*--------------------------*/

    /* Format Ideas : 20A2 */

    bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                  fic_maillage, num_ligne) ;

    /* retour = sscanf(chaine, "%[^\n\f\r]",ideas_grp_name); */

    strcpy(ideas_grp_name, "\0");
    ssch = strtok(chaine, " \n");
    strcat(ideas_grp_name, ssch);
    while ( (ssch = strtok(NULL, " \n")) != NULL ) {
      strcat(ideas_grp_name, " ");
      strcat(ideas_grp_name, ssch);
    }


    /* Lecture des caracteristiques des elements du groupe */
    /*-----------------------------------------------------*/

    /* Format Ideas : 8I10 (pour chaque ligne) */

    BFT_REALLOC(ideas_typ_entity, ideas_nbr_entities, ecs_int_t) ;
    BFT_REALLOC(ideas_tag_entity, ideas_nbr_entities, ecs_int_t) ;

    nbr_entities_lues = 0 ;

    while (nbr_entities_lues != ideas_nbr_entities) {

      bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_IDEAS,
                    fic_maillage, num_ligne) ;

      /* Lecture des types et numeros des elements pour la ligne courante */

      nbr_entities_ligne
        = ECS_MIN(ideas_nbr_entities - nbr_entities_lues, nbr_ent_par_ligne) ;

      ssch = strtok(chaine, " ");

      for (ientity = 0 ; ientity < nbr_entities_ligne ; ientity++) {

        retour = sscanf(ssch, "%" ECS_FORMAT_ecs_int_t,
                        &ideas_typ_entity[nbr_entities_lues + ientity]) ;
        ssch   = strtok(NULL, " ");
        retour = sscanf(ssch, "%" ECS_FORMAT_ecs_int_t,
                        &ideas_tag_entity[nbr_entities_lues + ientity]) ;
        ssch   = strtok(NULL, " ");

        if (nbr_ent_par_ligne == ECS_IDEAS_NBR_GRP_ENT_PER_LINE2) {

          retour = sscanf(ssch, "%*" ECS_FORMAT_ecs_int_t);
          ssch   = strtok(NULL, " ");
          retour = sscanf(ssch, "%*" ECS_FORMAT_ecs_int_t);
          ssch   = strtok(NULL, " ");

        }

      }

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

      nbr_entities_lues += nbr_entities_ligne ;

    }


    /* Determination de l'entite a laquelle correspondent */
    /*  les elements du groupe                            */
    /*----------------------------------------------------*/


    for (ientity = 0 ; ientity < ideas_nbr_entities ; ientity++) {


      tab_tag.val = &ideas_tag_entity[ientity] ;


      if (ideas_typ_entity[ientity] == ECS_IDEAS_TYP_CODE_ELEMENTS) {

        /*---------------------------------------*/
        /* Recherche de l'indice correspondant   */
        /*  au label `ideas_typ_entity[ientity]' */
        /*---------------------------------------*/

        ecs_tab_int__recherche(tab_tag,
                               tab_label_elt_trie,
                               tab_num) ;

        if (tab_num.val[0] == -1)
          bft_error(__FILE__, __LINE__, 0,
                    _("Error reading an I-deas universal file:\n"
                      "at line %d of file \"%s\".\n"
                      "I-deas label number \"%d\" of group \"%s\"\n"
                      "is not referenced as node or element.\n"
                      "I-deas label read: %d"),
                    (int)(*num_ligne), bft_file_get_name(fic_maillage),
                    (int)(ientity + 1), ideas_grp_name, (int)(*tab_tag.val));


        num_label = vect_renum_val_elt.val[tab_num.val[0]] ;


        ind_ent = ECS_ENTMAIL_ARE ;
        num_ent = tab_ent[ind_ent] ;
        nbr_elt_ent = ent_nbr_elt[num_ent] ;
        while (   ind_ent   < ECS_ENTMAIL_FIN
               && (num_label + 1) > nbr_elt_ent) {
          num_label -=  nbr_elt_ent ;
          num_ent = tab_ent[++ind_ent] ;
          nbr_elt_ent = ent_nbr_elt[num_ent] ;
        }

        assert(ind_ent != ECS_ENTMAIL_FIN) ;


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

        ent_val_grp[num_ent][num_label] = ent_cpt_grp[num_ent] + 1 ;


        /* Incrementation du nombre d'objets lus */

        ent_cpt_elt[num_ent]++ ;

      }

    } /* Fin : boucle sur les entites Ideas du groupe */


    /* Boucle de remplissage des entites du maillage */
    /*===============================================*/


    bool_aff_grp = ECS_FALSE ;


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


      /*--------------------------------------------------------------------*/
      /* S'il y a au moins un element du groupe de cette entite de maillage */
      /*--------------------------------------------------------------------*/


      if (ent_cpt_elt[ient] != 0) {


        bool_aff_grp = ECS_TRUE ;

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

        ent_cpt_grp[ient]++ ;


        /* Creation du descripteur de champ correspondant au groupe lu */
        /*-------------------------------------------------------------*/

        descr_grp = ecs_descr__cree(ECS_DESCR_TYP_GROUPE,
                                    ECS_DESCR_IDE_NUL,
                                    ideas_grp_name) ;


        /* Transformation du tableau referencant le groupe en une table */
        /*--------------------------------------------------------------*/

        champ_grp = ecs_champ__transforme_tableau(ent_nbr_elt[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'elements referencant le groupe n'est pas nul */

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


    /* Affichage du bilan des donnees lues pour les groupes */
    /*======================================================*/

    if (bool_aff_grp == ECS_TRUE)
      bft_printf("  %s %" ECS_FORMAT_ecs_int_t " \"%s\"\n",
                 _("Group"),
                 ideas_grp_num, ideas_grp_name) ;

    ecs_entmail__aff_nbr_par_ent(ent_cpt_elt,
                                 0) ;


    /* Incrementation du compteur sur les groupes */
    /*--------------------------------------------*/

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

    /* Re-initialisation des compteurs par entite pour le groupe suivant */
    for (ient = ECS_ENTMAIL_DEB ; ient < ECS_ENTMAIL_FIN ; ient++)
      ent_cpt_elt[ient] = 0 ;


  } /* Fin : tant qu'il y a une ligne a lire et                       */
    /*       tant que la ligne lue n'est pas le separateur de dataset */


  if (strcmp(chaine, ECS_IDEAS_SEPARATEUR_DATASET) != 0)

    bft_file_read_check_error(fic_maillage,
                              *num_ligne) ;


  /* else : on a lu jusqu'au separateur de dataset */



  /* Transfert des champs groupe dans les entites 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 ) ;

    }

  }


  /* Liberation des tableaux locaux */
  /*================================*/

  BFT_FREE(tab_label_elt.val) ;
  BFT_FREE(tab_num.val) ;

  if (bool_label_elt_a_trier == ECS_TRUE)
    BFT_FREE(tab_label_elt_trie.val) ;

  BFT_FREE(vect_renum_val_elt.val) ;

  BFT_FREE(ideas_typ_entity);
  BFT_FREE(ideas_tag_entity);


}


/*----------------------------------------------------------------------------
 *  Fonction utilitaire pour la lecture des réels d'un fichier I-DEAS
 *
 *  La chaine contenant un réel avec (ou non) un exposant `d' ou `D'
 *  est convertie en réel avec un exposant `e'
 *----------------------------------------------------------------------------*/

static ecs_real_t ecs_loc_pre_ideas__transf_expo
(
 char *chaine     /* Chaine contenant le reel dont l'exposant est a convertir */
)
{
  char       * s                                    ;
  char         s_atof[ECS_LOC_LNG_MAX_CHAINE_IDEAS] ;
  ecs_real_t   f_atof                               ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  s = s_atof ;

  /* Copie de la partie de la chaine en entree `chaine'              */
  /*  qui precede le caractere `D' ou `d'                            */
  /*  ou copie de toute la chaine si `D' ou `d' ne sont pas presents */

  while( *chaine != 'D' && *chaine != 'd' && *chaine != '\0' ) {
    *s = *chaine ;
    s++ ;
    chaine++ ;
  }

  /* Toute la chaine en entree a-t-elle ete parcourue ? */

  if ( *chaine != '\0' ) {

    /* La chaine en entree n'a pas ete entierement parcourue :     */
    /*  le caractere `D' ou `d' est remplace par `e' dans sa copie */

    *s = 'e' ;

    /* Le reste de la chaine est copie tel quel */

    while( (*++s = *++chaine) )
      ;

  }
  else {

    /* Toute la chaine a ete parcourue.      */
    /* On ajoute le `\0' final dans la copie */

    *s = *chaine ;

  }

  /* L'exposant `D' ou `d' a ete remplace par `e' :                  */
  /*  on peut maintenant extraire le reel de la chaine de caracteres */

  sscanf(s_atof, " %lf", &f_atof) ;

  return f_atof ;

}

Generated by  Doxygen 1.6.0   Back to index