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

ecs_pre_gmsh.c

/*============================================================================
 *  Définition de la fonction
 *   de lecture d'un fichier de maillage au format Gmsh
 *============================================================================*/

/*
  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_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_gmsh.h"


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


/*============================================================================
 *  Définitions de paramètres-macros
 *============================================================================*/

#define ECS_GMSH_NBR_TYP_ELT        15 /* Nombre de types d'éléments Gmsh */
#define ECS_GMSH_NBR_MAX_SOM        27 /* Nombre max de noeuds par élément
                                          (27 pour hexaèdre parabolique) */


/* Valeurs associées aux dimensionnements pour la lecture des lignes */

#define ECS_LOC_LNG_MAX_CHAINE_GMSH 514 /* Dimension des chaînes de réception
                                           des lignes lues */


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

typedef enum {
  GMSH_SEG2 = 1, /*  1 */
  GMSH_TRIA3,    /*  2 */
  GMSH_QUAD4,    /*  3 */
  GMSH_TETRA4,   /*  4 */
  GMSH_HEXA8,    /*  5 */
  GMSH_PENTA6,   /*  6 */
  GMSH_PYRA5,    /*  7 */
  GMSH_SEG3,     /*  8 */
  GMSH_TRIA6,    /*  9 */
  GMSH_QUAD9,    /* 10 */
  GMSH_TETRA10,  /* 11 */
  GMSH_HEXA27,   /* 12 */
  GMSH_PENTA18,  /* 13 */
  GMSH_PYRA14,   /* 14 */
  GMSH_POINT1    /* 15 */
} ecs_gmsh_elt_typ_t ;

typedef struct {

  ecs_gmsh_elt_typ_t     gmsh_typ   ; /* Type Gmsh de l'élément */
  ecs_elt_typ_t          ecs_typ    ; /* Type ECS de l'élément */
  ecs_int_t              nbr_som    ; /* Nombre de sommets */
                                      /* Liste des numéros de sommet ECS */
  ecs_int_t              num_som[ECS_GMSH_NBR_MAX_SOM] ;

} ecs_gmsh_elt_t ;


/*============================================================================
 *  Définitions de variables globales statiques
 *============================================================================*/

const ecs_gmsh_elt_t ecs_gmsh_elt_liste_c[ECS_GMSH_NBR_TYP_ELT] = {
  {                                /* 1 */
    GMSH_SEG2 ,
    ECS_ELT_TYP_ARE ,
    2 ,
    { 1, 2 }
  } ,
  {                                /* 2 */
    GMSH_TRIA3 ,
    ECS_ELT_TYP_FAC_TRIA ,
    3 ,
    { 1, 2, 3 }
  } ,
  {                                /* 3 */
    GMSH_QUAD4 ,
    ECS_ELT_TYP_FAC_QUAD ,
    4 ,
    { 1, 2, 3, 4 }
  } ,
  {                                /* 4 */
    GMSH_TETRA4 ,
    ECS_ELT_TYP_CEL_TETRA ,
    4 ,
    { 1, 2, 3, 4 }
  } ,
  {                                /* 5 */
    GMSH_HEXA8 ,
    ECS_ELT_TYP_CEL_HEXA ,
    8 ,
    { 1, 2, 3, 4, 5, 6, 7, 8 } ,
  } ,
  {                                /* 6 */
    GMSH_PENTA6 ,
    ECS_ELT_TYP_CEL_PRISM ,
    6 ,
    { 1, 2, 3, 4, 5, 6 }
  } ,
  {                                /* 7 */
    GMSH_PYRA5 ,
    ECS_ELT_TYP_CEL_PYRAM ,
    5 ,
    { 1, 2, 3, 4, 5 }
  } ,
  {                                /* 8 */
    GMSH_SEG3 ,
    ECS_ELT_TYP_ARE ,
    3 ,
    { 1, 2 }
  } ,
  {                                /* 9 */
    GMSH_TRIA6 ,
    ECS_ELT_TYP_FAC_TRIA ,
    6 ,
    { 1, 2, 3 }
  } ,
  {                               /* 10 */
    GMSH_QUAD9 ,
    ECS_ELT_TYP_FAC_QUAD ,
    9 ,
    { 1, 2, 3, 4 }
  } ,
  {                               /* 11 */
    GMSH_TETRA10 ,
    ECS_ELT_TYP_CEL_TETRA ,
    10 ,
    { 1, 2, 3, 4 }
  } ,
  {                               /* 12 */
    GMSH_HEXA27 ,
    ECS_ELT_TYP_CEL_HEXA ,
    27 ,
    { 1, 2, 3, 4, 5, 6, 7, 8 } ,
  } ,
  {                               /* 13 */
    GMSH_PENTA18 ,
    ECS_ELT_TYP_CEL_PRISM ,
    18 ,
    { 1, 2, 3, 4, 5, 6 }
  } ,
  {                               /* 14 */
    GMSH_PYRA14 ,
    ECS_ELT_TYP_CEL_PYRAM ,
    14 ,
    { 1, 2, 3, 4, 5 }
  } ,
  {                               /* 15 */
    GMSH_POINT1 ,
    ECS_ELT_TYP_SOM ,
    1 ,
    { 1 }
  }
} ;


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

/*----------------------------------------------------------------------------
 *  Lecture et vérification de la version du format (pour version 2.0)
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gmsh__lit_vers_format
(
 bft_file_t     *fic_maillage ,             /* --> Descripteur fichier a lire */
 int            *version      ,             /* <-- Version du format Gmsh     */
 int            *type         ,             /* <-- Type (ascii ou binaire)    */
 int            *num_ligne                  /* <-> Compteur des lignes lues   */
 ) ;


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

static ecs_entmail_t  * ecs_loc_pre_gmsh__lit_nodes
(                                          /* <-- Renvoie entite de maillage  */
                                           /*     correspondant aux sommets   */
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 int            type_fmt_gmsh            , /* --> Type (ascii ou binaire)     */
 int           *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_bool_t     bool_label_ent_a_trier[]   /* <-- Indicateur de labels tries  */
) ;


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

static ecs_entmail_t ** ecs_loc_pre_gmsh__lit_elements
(                                          /* <-- Renvoie les entites         */
                                           /*      aretes, faces et cellules  */
 bft_file_t    *fic_maillage             , /* --> Descripteur fichier a lire  */
 int            version_fmt_gmsh         , /* --> Version du format Gmsh      */
 int            type_fmt_gmsh            , /* --> Type du format Gmsh         */
 int           *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_bool_t     bool_label_ent_a_trier[]   /* <-- Indicateur de labels tries  */
) ;


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

/*----------------------------------------------------------------------------
 *  Lecture d'un fichier de maillage au format Gmsh
 *   et affectation des donnees dans la structure de maillage
 *----------------------------------------------------------------------------*/

ecs_maillage_t  * ecs_pre_gmsh__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            */
  char           chaine[ECS_LOC_LNG_MAX_CHAINE_GMSH]  ;         /* Ligne lue  */
                                         /*  sur les noeuds                   */
  ecs_int_t      ient                  ; /* Indice de boucle sur les entités  */
  int            num_ligne             ; /* Compteur des lignes lues          */
  int            version_fmt_gmsh      ;
  int            type_fmt_gmsh         ;
  ecs_bool_t     bool_label_ent_a_trier[ECS_ENTMAIL_FIN]; /* Ind labels tries */
  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_bool_t     bool_elements = ECS_FALSE ;
  ecs_bool_t     bool_noeuds   = ECS_FALSE ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  bft_printf(_("\n\n"
               "Reading mesh from file in Gmsh 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 ;

  num_ligne = 0 ;
  dim_e     = ECS_DIM_3 ;

  /* Par défaut, la version est 1.0 en ASCII */

  version_fmt_gmsh = 1;
  type_fmt_gmsh = 0;


  /* Ouverture du fichier Gmsh 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 pa atteint la fin du fichier    */
  /*================================================*/


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


    /* Si la chaine lue est un descripteur de format */

    if (strncmp(chaine, "$MeshFormat", strlen("$MeshFormat")) == 0 )

      ecs_loc_pre_gmsh__lit_vers_format(fic_maillage,
                                        &version_fmt_gmsh,
                                        &type_fmt_gmsh,
                                        &num_ligne) ;

    /* Si la chaine lue marque le début de la section des noeuds */

    else if (   (strncmp(chaine, "$Nodes", strlen("$Nodes")) == 0 )
             || (strncmp(chaine, "$NOD", strlen("$NOD")) == 0 )) {

      vect_entmail[ECS_ENTMAIL_SOM]
        = ecs_loc_pre_gmsh__lit_nodes(fic_maillage,
                                      type_fmt_gmsh,
                                      &num_ligne,
                                      bool_label_ent_a_trier) ;

      bool_noeuds = ECS_TRUE ;

    }

    /* Si la chaine lue marque le début de la section des éléments */

    else if (   (strncmp(chaine, "$Elements", strlen("$Elements")) == 0 )
             || (strncmp(chaine, "$ELM", strlen("$ELM")) == 0 )) {

      vect_entmail_ret
        = ecs_loc_pre_gmsh__lit_elements(fic_maillage,
                                         version_fmt_gmsh,
                                         type_fmt_gmsh,
                                         &num_ligne,
                                         bool_label_ent_a_trier);

      bool_elements = ECS_TRUE ;

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

      BFT_FREE(vect_entmail_ret) ;

    }

  }

  if (bft_file_eof(fic_maillage) == 0)
    bft_error(__FILE__, __LINE__, errno,
              _("Error reading line %ld of file \"%s\"."),
              (long)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_noeuds == ECS_FALSE)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading a Gmsh mesh file:\n"
                "at line %ld of file \"%s\".\n"
                "The points definition was not found."),
              (long)num_ligne, bft_file_get_name(fic_maillage)) ;

  if (bool_elements == ECS_FALSE)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading a Gmsh mesh file:\n"
                "at line %ld of file \"%s\".\n"
                "The elements definition was not found."),
              (long)num_ligne, bft_file_get_name(fic_maillage)) ;


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

  bft_file_free(fic_maillage) ;


  /* Création structure et retour */
  /*==============================*/

  maillage = ecs_maillage__cree_nodal(dim_e,
                                      vect_entmail) ;

  return maillage ;

}


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

/*----------------------------------------------------------------------------
 *  Lecture et vérification de la version du format (pour version 2.0)
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_gmsh__lit_vers_format
(
 bft_file_t     *fic_maillage ,             /* --> Descripteur fichier a lire */
 int            *version      ,             /* <-- Version du format Gmsh     */
 int            *type         ,             /* <-- Type (ascii ou binaire)    */
 int            *num_ligne                  /* <-> Compteur des lignes lues   */
)
{
  char  chaine[ECS_LOC_LNG_MAX_CHAINE_GMSH] ;
  int   retour ;
  int   taille_coo ;
  float fversion ;

  /* Décodage de la chaine de version */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

  retour = sscanf(chaine,"%f %d %d", &fversion, type, &taille_coo) ;

  if (retour != 3)
    bft_error(__FILE__, __LINE__, 0,
              _("The Gmsh version specification of file\n"
                "\"%s\" is invalid or unreadable.)")) ;

  if (*type != 0 && *type != 1)
    bft_error(__FILE__, __LINE__, 0,
              _("The Gmsh type specification of file\n"
                "\"%s\" is neither 0 (text file) nor 1 (binary file).\n"
                "This case is currently not handled.")) ;

  bft_printf(_("  Gmsh format version:     %2.1f\n"
               "  Size given for real numbers: %d\n\n"),
             fversion, taille_coo) ;

  *version = (int) fversion ;

  if (*type == 1) {

    int   un;

    bft_file_set_type(fic_maillage, BFT_FILE_TYPE_BINARY) ;
    bft_file_read(&un, 4, 1, fic_maillage) ;
    if (un != 1)
      bft_file_set_swap_endian(fic_maillage, 1) ;

    bft_file_set_type(fic_maillage, BFT_FILE_TYPE_TEXT) ;
    bft_file_gets(chaine, 2, fic_maillage, num_ligne) ;

  }

  /* Ligne de fin de rubrique */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

  if (strncmp(chaine, "$EndMeshFormat", strlen("$EndMeshFormat")) != 0 )
    bft_error(__FILE__, __LINE__, 0,
              _("The Gmsh format version specification end for file\n"
                "\"%s\" is not present at the expected place.)")) ;

}

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

static ecs_entmail_t  * ecs_loc_pre_gmsh__lit_nodes
(                                          /* <-- Renvoie entite de maillage  */
                                           /*     correspondant aux sommets   */
 bft_file_t    *fic_maillage             , /* --> Descripteur du fichier      */
 int            type_fmt_gmsh            , /* --> Type du format Gmsh         */
 int           *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_bool_t     bool_label_ent_a_trier[]   /* <-- Indicateur de labels tries  */
)
{

  char   chaine[ECS_LOC_LNG_MAX_CHAINE_GMSH] ;
  int    retour ;

  /* Variables Gmsh lues */

  long         label ;
  double       coord[3] ;
  ecs_int_t    nbr_nod ;

  ecs_int_t    icoo ;

  /* Stockage avant transfert */

  ecs_int_t    ind_nod = 0 ;
  ecs_int_t  * som_val_label ;

  ecs_real_t * som_val_coord ;

  ecs_entmail_t *entmail_som ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  /* Décodage du nombre de noeuds */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

  nbr_nod = (ecs_int_t)(atol(chaine)) ;

  /* Allocation mémoire associée */

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


  /* Boucle de lecture des noeuds */
  /*==============================*/

  if (type_fmt_gmsh == 0) {

    for (ind_nod = 0 ; ind_nod < nbr_nod ; ind_nod++) {

      bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

      retour = sscanf(chaine,"%ld %lg %lg %lg", &label, coord, coord+1, coord+2) ;

      if (retour != 4)
        bft_error(__FILE__, __LINE__, 0,
                  _("Error decoding line %ld of file\n\"%s\" :\n"
                    "The description of point <%ld> was expected in the form "
                    "\"label x y z\"."),
                  (long)(*num_ligne), bft_file_get_name(fic_maillage),
                  (long)(ind_nod+1)) ;

      /* Étiquette du noeud lu */

      som_val_label[ind_nod] = (ecs_int_t)label ;

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

      /* Coordonnées du noeud lu */

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

    }

  }
  else {

    bft_file_set_type(fic_maillage, BFT_FILE_TYPE_BINARY) ;

    for (ind_nod = 0 ; ind_nod < nbr_nod ; ind_nod++) {

      double xyz[3] ;

      bft_file_read(&som_val_label[ind_nod], sizeof(int), 1, fic_maillage) ;
      bft_file_read(&xyz, sizeof(double), 3, fic_maillage) ;

      for (icoo = 0 ; icoo < ECS_DIM_3 ; icoo++)
        som_val_coord[ind_nod * ECS_DIM_3 + icoo] = xyz[icoo] ;

    }

    bft_file_set_type(fic_maillage, BFT_FILE_TYPE_TEXT);

    bft_file_gets(chaine, 2, fic_maillage, num_ligne) ;

  }

  /* Ligne de fin de rubrique */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

  if (   (strncmp(chaine, "$EndNodes", strlen("$EndNodes")) != 0)
      && (strncmp(chaine, "$ENDNOD", strlen("$ENDNOD")) != 0))
    bft_error(__FILE__, __LINE__, 0,
              _("The end of the points list specification of file\n"
                "\"%s\" is not present at the expected place.)"),
              bft_file_get_name(fic_maillage)) ;


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

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

  return entmail_som ;

}

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

static ecs_entmail_t ** ecs_loc_pre_gmsh__lit_elements
(                                          /* <-- Renvoie les entites         */
                                           /*      aretes, faces et cellules  */
 bft_file_t    *fic_maillage             , /* --> Descripteur fichier a lire  */
 int            version_fmt_gmsh         , /* --> Version du format Gmsh      */
 int            type_fmt_gmsh            , /* --> Type du format Gmsh         */
 int           *num_ligne                , /* <-> Compteur des lignes lues    */
 ecs_bool_t     bool_label_ent_a_trier[]   /* <-- Indicateur de labels tries  */
)
{

  char        chaine[ECS_LOC_LNG_MAX_CHAINE_GMSH] ;
  char       *ssch ;

  /* Variables Gmsh lues */

  long        label ;
  ecs_int_t   type_ecs ;
  ecs_int_t   coul_elt ;
  ecs_int_t   ind_elt ;
  ecs_int_t   nbr_elt ;
  ecs_int_t   nbr_elt_lus ;
  ecs_int_t   nbr_elt_tot ;
  ecs_int_t   ind_nod_elt ;
  ecs_int_t   ind_som_elt ;
  ecs_int_t   nbr_som_elt ;
  ecs_int_t   ind_tag_elt ;
  ecs_int_t   nbr_tag_elt ;

  ecs_int_t   header[3] ;
  ecs_int_t   data[100] ;

  int         type_gmsh ;
  ecs_int_t   nbr_nod_elt_gmsh ;
  ecs_int_t   num_nod_elt_gmsh[ECS_GMSH_NBR_MAX_SOM] ;
  ecs_int_t   ent_num ;

  ecs_int_t   icoul ;
  ecs_int_t   ient ;

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


  /* 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 ;

  ecs_int_t cpt_are   = 0 ;
  ecs_int_t cpt_point = 0 ;

  ecs_bool_t ligne_decodee = ECS_TRUE ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  /* Décodage du nombre d'éléments (toutes dimensions confondues */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

  nbr_elt = (ecs_int_t)(atol(chaine)) ;


  /* 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 ;

  }

  /*
    On surdimensionne les tableaux de lecture des éléments ; on les
    redimensionnera à la fin.
  */

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

    BFT_MALLOC(elt_val_label_ent[ient],   nbr_elt, ecs_int_t) ;
    BFT_MALLOC(elt_val_color_ent[ient],   nbr_elt, ecs_int_t) ;
    BFT_MALLOC(elt_pos_som_ent[ient],     nbr_elt, ecs_size_t) ;

    elt_pos_som_ent[ient][0] = 1 ;

  }

  /*
    Plus "gros" élément linéaire disponible :
    - quadrangle (4 sommets) pour les faces
    - hexaèdre (8 sommets) pour les cellules.
  */

  BFT_MALLOC(elt_val_som_ent[ECS_ENTMAIL_FAC], nbr_elt * 4, ecs_int_t) ;
  BFT_MALLOC(elt_val_som_ent[ECS_ENTMAIL_CEL], nbr_elt * 8, ecs_int_t) ;


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

  if (type_fmt_gmsh == 0) {

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

      if (ligne_decodee == ECS_FALSE)
        break ;

      ligne_decodee = ECS_FALSE ;

      bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH,
                    fic_maillage, num_ligne) ;

      /* Au format Gmsh 1.0, pour chaque élément, on a les entiers suivants :
         label type num_ent_phys num_ent_elem nb_sommets <liste_sommets> */

      /* Au format Gmsh 2.0, pour chaque élément, on a les entiers suivants :
         label type nb_tags <tag> <liste_sommets> */

      /* Lecture du label de l'élément courant */

      ssch = strtok(chaine, " ");
      if (ssch == NULL)
        break ;

      label = atol(ssch) ;

      /* Lecture du type de l'élément courant */

      ssch   = strtok(NULL, " ");
      if (ssch == NULL)
        break ;

      type_gmsh = atoi(ssch) ;

      if (type_gmsh < (int)GMSH_SEG2 || type_gmsh > (int) GMSH_POINT1)
        bft_error(__FILE__, __LINE__, 0,
                  _("Error reading a Gmsh mesh file:\n"
                    "at line %ld of file \"%s\".\n"
                    "Type identifier <%d> for element <%ld> is not recognized."),
                  (long)(*num_ligne), bft_file_get_name(fic_maillage),
                  (int)type_gmsh, (long)label);

      type_ecs         = ecs_gmsh_elt_liste_c[type_gmsh - 1].ecs_typ ;
      nbr_nod_elt_gmsh = ecs_gmsh_elt_liste_c[type_gmsh - 1].nbr_som ;
      nbr_som_elt      = ecs_fic_elt_typ_liste_c[type_ecs].nbr_som ;

      if (type_gmsh == GMSH_POINT1) {
        cpt_point += 1 ;
        ligne_decodee = ECS_TRUE ;
        continue ;
      }
      else if (type_ecs == ECS_ELT_TYP_ARE) {
        cpt_are += 1 ;
        ligne_decodee = ECS_TRUE ;
        continue ;
      }

      /* Lecture des "tags" de l'élément courant */

      coul_elt = 0 ;

      if (version_fmt_gmsh == 2) {

        ssch   = strtok(NULL, " ");
        if (ssch == NULL)
          break ;

        nbr_tag_elt = (ecs_int_t)(atol(ssch)) ;

        for (ind_tag_elt = 0 ; ind_tag_elt < nbr_tag_elt ; ind_tag_elt++) {

          ssch   = strtok(NULL, " ");
          if (ssch == NULL)
            break ;

          /* Par défaut, Gmsh écrit des fichiers avec 2 "tags",
             le premier correspondant à un numéro d'entité physique,
             le second à une entité géométrique élémentaire ;
             on associe le premier à une couleur */

          if (ind_tag_elt == 0)
            coul_elt = (ecs_int_t)(atol(ssch)) ;

        }

        if (ssch == NULL && ind_tag_elt < nbr_tag_elt)
          break ;

      }
      else { /* Ancienne version 1 du format Gmsh */

        /* On interprête reg-phys (numéro d'entité physique) comme
           étant une couleur */

        ssch   = strtok(NULL, " ");
        if (ssch == NULL)
          break ;

        coul_elt = (ecs_int_t)(atol(ssch)) ;

        /* On saute la valeur reg-elem (numéro d'entité élémentaire) */

        ssch   = strtok(NULL, " ");
        if (ssch == NULL)
          break ;

        /* On saute le nombre de noeuds, redondant */

        ssch   = strtok(NULL, " ");
        if (ssch == NULL)
          break ;

      }

      /* Lecture des numéros des sommets de l'élément courant */

      for (ind_nod_elt = 0 ; ind_nod_elt < nbr_nod_elt_gmsh ; ind_nod_elt++) {

        ssch   = strtok(NULL, " ");
        if (ssch == NULL)
          break ;

        num_nod_elt_gmsh[ind_nod_elt] = (ecs_int_t)(atol(ssch)) ;

      }

      if (ssch == NULL && ind_nod_elt < nbr_nod_elt_gmsh)
        break ;

      ligne_decodee = ECS_TRUE ;


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

      /* Identification de l'entité concernée */

      ent_num = ecs_entmail_pre__ret_typ_geo(type_ecs);

      /* Position des numéros de sommets du prochain élément */

      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 ;

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

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

        elt_val_som_ent
          [ent_num]
          [elt_pos_som_ent[ent_num][cpt_elt_ent[ent_num]] - 1 + ind_som_elt]
          = num_nod_elt_gmsh
          [ecs_gmsh_elt_liste_c[type_gmsh - 1].num_som[ind_som_elt] - 1] ;

      }

      /* Étiquette de l'élément 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] > label))
        bool_label_ent_a_trier[ent_num] = ECS_TRUE ;

      elt_val_label_ent[ent_num][cpt_elt_ent[ent_num]] = label ;

      /* Couleur (tag) de l'élément lu */

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

      if (icoul == cpt_coul_ent[ent_num]) {

        /* La valeur de la couleur n'a pas encore été stockée */

        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] = coul_elt ;
        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 ;

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

      cpt_elt_ent[ent_num]++ ;

    }


    /* Fin de la boucle de lecture sur les éléments
       (et sur les lignes du fichier) */

    if (ligne_decodee == ECS_FALSE)
      bft_error(__FILE__, __LINE__, 0,
                _("Error decoding line %ld "
                  "(corresponding to element <%ld>) of file\n"
                  "\"%s\"."),
                (long)(*num_ligne), (long)(ind_elt+1),
                bft_file_get_name(fic_maillage));

  }
  else {

    bft_file_set_type(fic_maillage, BFT_FILE_TYPE_BINARY) ;

    nbr_elt_lus = 0 ;
    nbr_elt_tot = nbr_elt ;

    while (nbr_elt_lus != nbr_elt_tot) {

      bft_file_read(&header, 4, 3, fic_maillage) ;

      type_gmsh   = header[0] ;
      nbr_elt     = header[1] ;
      nbr_tag_elt = header[2] ;

      if (type_gmsh < (int)GMSH_SEG2 || type_gmsh > (int) GMSH_POINT1)
        bft_error(__FILE__, __LINE__, 0,
                  _("Error reading a Gmsh mesh file:\n"
                    "Type identifier <%d> is not recognized."),
                  bft_file_get_name(fic_maillage), (int)type_gmsh);

      type_ecs         = ecs_gmsh_elt_liste_c[type_gmsh - 1].ecs_typ ;
      nbr_nod_elt_gmsh = ecs_gmsh_elt_liste_c[type_gmsh - 1].nbr_som ;
      nbr_som_elt      = ecs_fic_elt_typ_liste_c[type_ecs].nbr_som ;

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

        bft_file_read(&data, sizeof(int), 1 + nbr_tag_elt + nbr_nod_elt_gmsh, fic_maillage) ;

        if (type_gmsh == GMSH_POINT1) {
          cpt_point += 1 ;
          continue ;
        }
        else if (type_ecs == ECS_ELT_TYP_ARE) {
          cpt_are += 1 ;
          continue ;
        }

        /* Par défaut, Gmsh écrit des fichiers avec 2 "tags",
           le premier correspondant à un numéro d'entité physique,
           le second à une entité géométrique élémentaire ;
           on associe le premier à une couleur */

        label    = data[0] ;
        coul_elt = data[1] ;

        /* Lecture des numéros des sommets de l'élément courant */

        for (ind_nod_elt = 0 ; ind_nod_elt < nbr_nod_elt_gmsh ; ind_nod_elt++) {

          num_nod_elt_gmsh[ind_nod_elt] = data[1 + nbr_tag_elt + ind_nod_elt] ;

        }


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

        /* Identification de l'entité concernée */

        ent_num = ecs_entmail_pre__ret_typ_geo(type_ecs);

        /* Position des numéros de sommets du prochain élément */

        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 ;

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

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

          elt_val_som_ent
            [ent_num]
            [elt_pos_som_ent[ent_num][cpt_elt_ent[ent_num]] - 1 + ind_som_elt]
            = num_nod_elt_gmsh
            [ecs_gmsh_elt_liste_c[type_gmsh - 1].num_som[ind_som_elt] - 1] ;

        }

        /* Étiquette de l'élément 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] > label))
          bool_label_ent_a_trier[ent_num] = ECS_TRUE ;

        elt_val_label_ent[ent_num][cpt_elt_ent[ent_num]] = label ;

        /* Couleur (tag) de l'élément lu */

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

        if (icoul == cpt_coul_ent[ent_num]) {

          /* La valeur de la couleur n'a pas encore été stockée */

          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] = coul_elt ;
          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 ;

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

        cpt_elt_ent[ent_num]++ ;

      }

      nbr_elt_lus += nbr_elt ;

    }

    bft_file_set_type(fic_maillage, BFT_FILE_TYPE_TEXT) ;

    bft_file_gets(chaine, 2, fic_maillage, num_ligne) ;

  }


  /* Indications */

  if (cpt_point > -1 || cpt_are > 0)
      bft_printf("\n") ;
  if (cpt_point > -1)
      bft_printf(_("  %ld elements of type \"point\" ignored\n"),
                 (long)cpt_point) ;
  if (cpt_are > -1)
      bft_printf(_("  %ld elements of type \"edge\" ignored\n"),
                 (long)cpt_are) ;
  if (cpt_point > -1 || cpt_are > 0)
      bft_printf("\n") ;


  /* Ligne de fin de rubrique */

  bft_file_gets(chaine, ECS_LOC_LNG_MAX_CHAINE_GMSH, fic_maillage, num_ligne) ;

  if (   (strncmp(chaine, "$EndElements", strlen("$EndElements")) != 0)
      && (strncmp(chaine, "$ENDELM", strlen("$ENDELM")) != 0))
    bft_error(__FILE__, __LINE__, 0,
              _("The end of the elements list specification of file\n"
                "\"%s\" is not present at the expected place.)"),
              bft_file_get_name(fic_maillage)) ;


  /* Réallocations 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) ;
    }

  }


  /* Transfert des valeurs lues dans les structures d'entités 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 ;

}


Generated by  Doxygen 1.6.0   Back to index