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

ecs_pre_nopo.c

/*============================================================================
 *  Définition de la fonction
 *   de lecture d'un fichier de maillage NOPO (INRIA, utilisé par Simail)
 *============================================================================*/

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


/*============================================================================
 *                                 Visibilité
 *============================================================================*/

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

#include <assert.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_nopo.h"


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


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

#define ECS_NOPO_NBR_MAX_SOM           8
#define ECS_NOPO_NBR_MAX_SSELT         8
#define ECS_NOPO_NBR_MAX_TAB_REF      26        /* Valeur max de NMAE + 1
                                                   (nb. sommets + nb. arêtes
                                                   +nb. faces : 8 + 12 + 6)   */

#define ECS_NOPO_NUL                   0        /* Inexistant                 */
#define ECS_NOPO_NODE                  1        /* Noeud                      */
#define ECS_NOPO_SEGMENT               2        /* Segment                    */
#define ECS_NOPO_TRIANGLE              3        /* Triangle                   */
#define ECS_NOPO_QUADRANGLE            4        /* Quadrangle                 */
#define ECS_NOPO_TETRAHEDRON           5        /* Tétraèdre                  */
#define ECS_NOPO_PENTAHEDRON           6        /* Prisme                     */
#define ECS_NOPO_HEXAHEDRON            7        /* Hexaèdre                   */
#define ECS_NOPO_SUPER_ELEMENT         8        /* Super-élément (inutilisé)  */


/*============================================================================
 *                  Définition de structures locales
 *============================================================================*/

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

typedef struct {

  ecs_int_t       nopo_typ;                       /* Type NOPO de l'élément  */
  ecs_elt_typ_t   ecs_typ;                        /* Type ECS  de l'élément  */
  ecs_int_t       num_som[ECS_NOPO_NBR_MAX_SOM];  /* Numéros de sommets ECS  */
  ecs_int_t       nbr_are_vol;                    /* Nombre arêtes si volume */
  ecs_int_t       nbr_sselt;                      /* Nombre de sous-éléments */
  ecs_sous_elt_t  sous_elt[ECS_NOPO_NBR_MAX_SSELT];

} ecs_loc_nopo_elt_t;


static const ecs_loc_nopo_elt_t  ecs_loc_nopo_elt_liste_c[8] = {

  {                        /* 1 */
    ECS_NOPO_NUL,
    ECS_ELT_TYP_NUL,
    { 0 },
    0,
    0,
    {
      {0,{0}}
    }
  },
  {                        /* 1 */
    ECS_NOPO_NODE,
    ECS_ELT_TYP_SOM,
    { 1 },
    0,
    0,
    {
      {0,{0}}
    }
  },
  {                        /* 2 */
    ECS_NOPO_SEGMENT,
    ECS_ELT_TYP_ARE,
    { 1, 2 },
    0,
    2,
    {                                              /*    1       2            */
      {ECS_ELT_TYP_SOM, { 1 }},                    /*    x-------x            */
      {ECS_ELT_TYP_SOM, { 2 }}
    }
  },
  {                        /* 3 */
    ECS_NOPO_TRIANGLE,
    ECS_ELT_TYP_FAC_TRIA,
    { 1, 2, 3 },
    0,
    3,
    {                                              /*        x 3              */
      {ECS_ELT_TYP_ARE  , { 1 , 2 }} ,             /*       / \               */
      {ECS_ELT_TYP_ARE  , { 2 , 3 }} ,             /*      /   \              */
      {ECS_ELT_TYP_ARE  , { 3 , 1 }}               /*     /     \             */
    }                                              /*  1 x-------x 2          */
  },
  {                        /* 4 */
    ECS_NOPO_QUADRANGLE,
    ECS_ELT_TYP_FAC_QUAD,
    { 1, 2, 3, 4 },
    0,
    4,
    {                                              /*  4 x-------x 3          */
      {ECS_ELT_TYP_ARE  , { 1 , 2 }} ,             /*    |       |            */
      {ECS_ELT_TYP_ARE  , { 2 , 3 }} ,             /*    |       |            */
      {ECS_ELT_TYP_ARE  , { 3 , 4 }} ,             /*    |       |            */
      {ECS_ELT_TYP_ARE  , { 4 , 1 }}               /*  1 x-------x 2          */
    }                                              /*                         */
  },
  {                        /* 5 */
    ECS_NOPO_TETRAHEDRON,
    ECS_ELT_TYP_CEL_TETRA,
    { 1, 2, 3, 4 },
    6,                                             /*        x 4              */
    4,                                             /*       /|\               */
    {                                              /*      / | \              */
      {ECS_ELT_TYP_FAC_TRIA, { 1 , 3 , 2 }},       /*     /  |  \             */
      {ECS_ELT_TYP_FAC_TRIA, { 1 , 4 , 3 }},       /*  1 x- -|- -x 3          */
      {ECS_ELT_TYP_FAC_TRIA, { 1 , 2 , 4 }},       /*     \  |  /             */
      {ECS_ELT_TYP_FAC_TRIA, { 2 , 3 , 4 }}        /*      \ | /              */
    }                                              /*       \|/               */
  },                                               /*        x 2              */
  {                       /*  6 */
    ECS_NOPO_PENTAHEDRON,
    ECS_ELT_TYP_CEL_PRISM,
    { 1 , 2 , 3 , 4 , 5 , 6 },
    9,                                             /*  4 x-------x 6          */
    5,                                             /*    |\     /|            */
    {                                              /*    | \   / |            */
      {ECS_ELT_TYP_FAC_TRIA, { 1 , 3 , 2 }    },   /*  1 x- \-/ -x 3          */
      {ECS_ELT_TYP_FAC_QUAD, { 1 , 4 , 6 , 3 }},   /*     \ 5x  /             */
      {ECS_ELT_TYP_FAC_QUAD, { 1 , 2 , 5 , 4 }},   /*      \ | /              */
      {ECS_ELT_TYP_FAC_TRIA, { 4 , 5 , 6 }    },   /*       \|/               */
      {ECS_ELT_TYP_FAC_QUAD, { 2 , 3 , 6 , 5 }}    /*        x 2              */
    }
  },
  {                       /*  7 */
    ECS_NOPO_HEXAHEDRON,
    ECS_ELT_TYP_CEL_HEXA,
    { 1, 2, 3, 4, 5, 6, 7, 8 },
    12,
    6,                                             /*     8 x-------x 7       */
    {                                              /*      /|      /|         */
      {ECS_ELT_TYP_FAC_QUAD, { 1 , 4 , 3 , 2 }},   /*     / |     / |         */
      {ECS_ELT_TYP_FAC_QUAD, { 1 , 5 , 8 , 4 }},   /*  5 x-------x6 |         */
      {ECS_ELT_TYP_FAC_QUAD, { 1 , 2 , 6 , 5 }},   /*    | 4x----|--x 3       */
      {ECS_ELT_TYP_FAC_QUAD, { 5 , 6 , 7 , 8 }},   /*    | /     | /          */
      {ECS_ELT_TYP_FAC_QUAD, { 2 , 3 , 7 , 6 }},   /*    |/      |/           */
      {ECS_ELT_TYP_FAC_QUAD, { 3 , 4 , 8 , 7 }}    /*  1 x-------x 2          */
    }
  }
};


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

/*----------------------------------------------------------------------------
 *  Lecture de la table de connectivité ; on lit les éléments présents dans
 *  le maillage, mais on y ajoute des éléments correspondant aux
 *  sous-éléments référencés, afin de porter ces références. On ne traite
 *  ainsi que les sous-éléments de niveau directement inféreieur ;
 *  Ainsi, si deux faces et trois arêtes d'un tétraèdre donné sont référencées
 *  (colorées), on créera en plus du tétraèdre deux triangles portant
 *  les  références des faces, mais aucune arête.
 *----------------------------------------------------------------------------*/

static ecs_entmail_t ** ecs_loc_pre_nopo__cree_elements
(                                          /* <-  Renvoie les entités         */
                                           /*      sommets à cellules         */
 ecs_int_t     *nop5,                      /*  -> Tableau NOP5                */
 ecs_real_t   **som_val_coord,             /*  -> Coordonnées des sommets     */
 ecs_int_t      ndsr,                      /*  -> Numéro de référence maximal */
 ecs_int_t      ndsd,                      /*  -> Numéro sous-domaine maximal */
 ecs_int_t      ncopnp,                    /*  -> 1 si sommets = noeuds       */
 ecs_int_t      ne,                        /*  -> Nombre d'éléments           */
 ecs_int_t      np                         /*  -> Nombre de points            */
);


/*----------------------------------------------------------------------------
 * Lecture d'un enregistrement d'un fichier NOPO. Chaque enregistrement
 * est un enregistrement de type binaire Fortran, constitué de mots de 4
 * ou 8 octets; dans le cas de mots de 4 octets, le premier mot donne la
 * dimension restante de l'enregistrement, et sera ignoré (i.e. pour un
 * tableau de n mots, on aura n + 1 entières, la première étant un entier
 * valant n).
 *
 * Le tableau des valeurs est alloué ici.
 *----------------------------------------------------------------------------*/

static void ecs_loc_pre_nopo__lit_int
(
       bft_file_t      *const  fic_maillage,   /*  -> Descripteur du fichier  */
 const char            *const  nom_tableau,    /*  -> Nom du tableau          */
       size_t                  elt_size,       /*  -> Taille d'un élément     */
       size_t                  n_elt,          /*  -> Taille du tableau       */
       size_t                  n_seg,          /*  -> N. segments             */
       size_t                  l_seg,          /*  -> Taille d'un segment     */
       ecs_int_t     * *const  tableau         /* <-  Valeurs du tableau      */
);

static void ecs_loc_pre_nopo__lit_real
(
       bft_file_t      *const  fic_maillage,   /*  -> Descripteur du fichier  */
 const char            *const  nom_tableau,    /*  -> Nom du tableau          */
       size_t                  elt_size,       /*  -> Taille d'un élément     */
       size_t                  n_elt,          /*  -> Taille du tableau       */
       size_t                  n_seg,          /*  -> N. segments             */
       size_t                  l_seg,          /*  -> Taille d'un segment     */
       ecs_real_t    * *const  tableau         /* <-  Valeurs du tableau      */
);

/*----------------------------------------------------------------------------
 *  Compactage des couleurs. On fournit en entrée le numéro de couleur
 *  d'une liste d'entités, on obtient en sortie (dans le même tableau)
 *  la position de cette couleur dans le tableau compacté ; on récupère
 *  le tableau des valeurs des couleurs correspondant à chaque indice,
 *  ainsi que le nombre de couleurs total et le nombre d'entités par couleur.
 *
 *  Si on n'a aucune couleur, on renvoie des pointeurs à NULL.
 *----------------------------------------------------------------------------*/

void ecs_loc_pre_nopo__compct_ref
(
 const ecs_int_t           nbr_ent          , /*  -> Nb. entités              */
 const ecs_int_t           num_coul_max     , /*  -> Numéro de couleur max.   */
       ecs_int_t    *const cpt_coul_ent     , /* <-  Nombre de couleurs       */
       ecs_int_t  * *const elt_val_coul_ent , /* <-> Couleurs des entités     */
       ecs_size_t * *const cpt_elt_coul_ent , /* <-  Nb. entités par couleur  */
       ecs_int_t  * *const val_coul_ent       /* <-  Num. couleurs/indice     */
);


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

/*----------------------------------------------------------------------------
 *  Lecture d'un fichier NOPO (Format INRIA utilisé par Simail)
 *   et affectation des donnees dans la structure de maillage
 *----------------------------------------------------------------------------*/

ecs_maillage_t * ecs_pre_nopo__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            */
                                         /*  sur les noeuds                   */
  ecs_dim_t        dim_e;                /* Dimension spatiale                */
  ecs_maillage_t  *maillage;             /* Structure de maillage             */
  ecs_entmail_t  **vect_entmail;

  ecs_real_t  * som_val_coord;

  ecs_int_t     ind;
  int32_t       ind_test;

  size_t        lnop0; /* nombre de mots dans NOP0 */
  size_t        lnop1; /* nombre de mots dans NOP1 */
  size_t        lnop2; /* nombre de mots dans NOP2 */
  size_t        lnop3; /* nombre de mots dans NOP3 */
  size_t        lnop4; /* nombre de mots dans NOP4 */
  size_t        lnop5; /* nombre de mots dans NOP5 */

  ecs_int_t     *nop0;
  ecs_int_t     *nop1;
  ecs_int_t     *nop3;
  ecs_int_t     *nop2;
  ecs_real_t    *nop4;
  ecs_int_t     *nop5;

  ecs_int_t     ndsr;    /* numéro de référence maximal */
  ecs_int_t     ndsd;    /* numéro de sous-domaine maximal */
  ecs_int_t     ncopnp;  /* 1 si sommets = noeuds, 0 sinon */
  ecs_int_t     ne;      /* nombre d'éléments */
  ecs_int_t     nepo;    /* nombre d'éléments point */
  ecs_int_t     nesg;    /* nombre de segments */
  ecs_int_t     ntri;    /* nombre de triangles */
  ecs_int_t     nqua;    /* nombre de quadrangles */
  ecs_int_t     ntet;    /* nombre de tétraèdres */
  ecs_int_t     npen;    /* nombre de pentaèdres */
  ecs_int_t     nhex;    /* nombre d'hexaèdres */
  ecs_int_t     noe;     /* nombre de noeuds */
  ecs_int_t     np;      /* nombre de points */
  ecs_int_t     ntacoo;  /* type de système de coordonnées :
                            1 : cartésien ; 2 : cyl ; 3 : sphérique */

  size_t  taille_e   = 56; /* 56 pour mode 32-bit, 208 pour 64-bit */
  size_t  taille_elt =  4; /* 4:32 bit ou 6: 64 bit */

  size_t  ne0 = 0, le0 = 0; /* Segmentation du tableau NOP0 */
  size_t  ne1 = 0, le1 = 0; /* Segmentation du tableau NOP1 */
  size_t  ne2 = 0, le2 = 0; /* Segmentation du tableau NOP2 */
  size_t  ne3 = 0, le3 = 0; /* Segmentation du tableau NOP3 */
  size_t  ne4 = 0, le4 = 0; /* Segmentation du tableau NOP4 */
  size_t  ne5 = 0, le5 = 0; /* Segmentation du tableau NOP5 */


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

  bft_printf(_("\n\n"
               "Reading mesh from file in NOPO (Simail) format\n"
               "----------------------\n"));

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


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


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

  fic_maillage = bft_file_open(nom_fic_maillage,
                               BFT_FILE_MODE_READ,
                               BFT_FILE_TYPE_BINARY);


  /* Test si le fichier est au format natif ou non */

  bft_file_read((ecs_byte_t *)(&ind_test), sizeof(int32_t), 1,
                fic_maillage);

  if (ind_test != 56 && ind_test != 208) {

    bft_file_swap_endian((ecs_byte_t *)(&ind_test), (ecs_byte_t *)(&ind_test),
                         sizeof(int32_t), 1);

    if (ind_test == 56 || ind_test == 208) {

      bft_file_set_swap_endian
        (fic_maillage,
         (bft_file_get_swap_endian(fic_maillage) == 1) ? 0 : 1);

    }
    else

      bft_error(__FILE__, __LINE__, 0,
                _("Format error for file \"%s\" :\n"
                  "This file does not seem to be in NOPO format\n"
                  "(the header length is not 56 (32-bit) or 208 (64-bit))."),
                bft_file_get_name(fic_maillage));

  }

  taille_e = ind_test;

  /*  On lit l'entête du fichier donnant les dimensions des tableaux */


  /*
    Attention, la première valeur d'un tableau NOP* donne la
    dimension du tableau, et le tableau est donc de taille n+1 ;
    les valeurs utiles étant aux positions 1 à n : on utilise donc
    une indexation entre 1 et n plutôt qu'entre 0 et n-1 pour
    y accéder.
  */

  if (taille_e == 56) { /* 32-bit */

    int32_t nopo_e[14];


    bft_file_read((ecs_byte_t *)nopo_e, sizeof(int32_t),
                  taille_e / sizeof(int32_t),
                  fic_maillage);

    bft_file_read((ecs_byte_t *)(&ind_test), sizeof(int32_t), 1,
                  fic_maillage);

    assert(ind_test == (int32_t)taille_e);

#if 0 && defined(DEBUG) && !defined(NDEBUG)
    for (ind = 0; ind < 14; ind++)
      printf("nopo_e[%d] = %d\n", ind, nopo_e[ind]);
#endif

    /*
      D'après la documentation, la 5ème position de l'entête est réservée et
      vaut 0. En pratique, on constate qu'elle correspond à la dimension du
      tableau NOP3, qui existe lorsque l'on a des super-éléments ou des
      descriptions (contrairement toujours à la documentation Simail, qui
      ne semble pas à jour car elle indique que ce tableau est inutilisé).
    */

    lnop0 = nopo_e[2];
    lnop1 = nopo_e[3];
    lnop2 = nopo_e[4];
    lnop3 = nopo_e[5];
    lnop4 = nopo_e[6];
    lnop5 = nopo_e[7];

    if (   nopo_e[ 1] !=  6 || nopo_e[ 2] != 32 || nopo_e[ 4] != 27
        || nopo_e[ 8] !=  1 || nopo_e[ 9] !=  1 || nopo_e[10] !=  1
        || nopo_e[11] !=  1 || nopo_e[12] !=  2 || nopo_e[13] !=  1)

      bft_error(__FILE__, __LINE__, 0,
                _("Format error for file \"%s\" :\n"
                  "The reserved descriptor values are not those expected;\n"
                  "this file is probably not a NOPO/Simail file."),
                bft_file_get_name(fic_maillage));

  }
  else if (taille_e == 208) { /* 64-bit */

    int64_t nopo_e[26];
    int32_t nopo_e_0[2];

    bft_file_read(nopo_e, sizeof(int64_t),
                  taille_e / sizeof(int64_t),
                  fic_maillage);

    bft_file_read((ecs_byte_t *)(&ind_test), sizeof(int32_t), 1,
                  fic_maillage);

    assert(ind_test == (int32_t)taille_e);

    /* Le premier entier 64 bits contient en fait 2 entiers 32 bits */

    if (bft_file_get_swap_endian(fic_maillage) == 1) {
      bft_file_swap_endian(&(nopo_e[0]), &(nopo_e[0]), 8, 1);
      bft_file_swap_endian(&(nopo_e[0]), &(nopo_e[0]), 4, 2);
    }
    memcpy(nopo_e_0, &(nopo_e[0]), 8);

#if 0 && defined(DEBUG) && !defined(NDEBUG)
    for (ind = 1; ind < 26; ind++)
      printf("nopo_e[%d] = %d\n", ind, nopo_e[ind]);
#endif

    /*
      La 5ème position de l'entête vaut généralement 0. Elle correspond
      à la dimension du tableau NOP3, qui existe lorsque l'on a des
      super-éléments ou des descriptions.
    */

    lnop0 = nopo_e[2];
    lnop1 = nopo_e[3];
    lnop2 = nopo_e[4];
    lnop3 = nopo_e[5];
    lnop4 = nopo_e[6];
    lnop5 = nopo_e[7];

    /* Segmentation des tableaux */

    ne0 = nopo_e[14]; le0 = nopo_e[15];
    ne1 = nopo_e[16]; le1 = nopo_e[17];
    ne2 = nopo_e[18]; le2 = nopo_e[19];
    ne3 = nopo_e[20]; le3 = nopo_e[21];
    ne4 = nopo_e[22]; le4 = nopo_e[23];
    ne5 = nopo_e[24]; le5 = nopo_e[25];

    /* D'après la documentation, le tableau contient 26 enregistrements
       sur 64 bits pour 27 valeurs; en fait, les deux premières valeurs
       correspondnet à 2 entiers 23 bits, contenus dans un entier 64 bit. */

    if (nopo_e_0[1] == 64)
      taille_elt = 8;

    if (   nopo_e_0[0] != 26 || ((nopo_e_0[1] != 32) && (nopo_e_0[1] != 64))
        || nopo_e[ 1] !=  6 || nopo_e[ 2] != 32 || nopo_e[ 4] != 27
        || nopo_e[ 8] !=  1 || nopo_e[ 9] !=  1 || nopo_e[10] !=  1
        || nopo_e[11] !=  1 || nopo_e[12] !=  2 || nopo_e[13] !=  1)

      bft_error(__FILE__, __LINE__, 0,
                _("Format error for file \"%s\" :\n"
                  "The reserved descriptor values are not those expected;\n"
                  "this file is probably not a NOPO/Simail file."),
                bft_file_get_name(fic_maillage));

  }

  /* On peut passer en binaire Fortran une fois cet enregistrement lu */

  bft_file_set_type(fic_maillage, BFT_FILE_TYPE_FORTRAN_BINARY);


  /* Lecture du tableau NOP0 */
  /* ----------------------- */

  ecs_loc_pre_nopo__lit_int(fic_maillage, "NOP0", taille_elt,
                            lnop0, ne0, le0, &nop0);

  /*
    On rappelle que la première valeur d'un tableau NOP* donne la
    dimension du tableau, et le tableau est donc de taille n+1 ;
    On utilise donc une indexation entre 1 et n plutôt qu'entre 0 et n-1
    pour accéder aux autres valeurs.
  */

  /*
    NOP0 contient des chaînes de caractères codées sur des entiers,
    qu'il convient de remettre dans l'ordre si l'on a permuté les
    octets.
  */

  if (bft_file_get_swap_endian(fic_maillage) == 1) {
    bft_file_swap_endian((ecs_byte_t *)nop0,
                         (ecs_byte_t *)nop0,
                         taille_elt, 29);
  }

  /*
    Suppression blancs en fin de titre (80 caractères en général rarement
     utilisés) pour affichage sur ligne plus courte
  */
  for (ind = 80; ind > 0 && *((char *)(nop0) + ind) == ' '; ind--) {
    *((char *)(nop0) + ind) = '\0';
  }

  bft_printf(_("  Title     : %.80s\n"), (char *)nop0);
  bft_printf(_("  Date      : %2.2s/%2.2s/%4.4s\n"),
             (char *)(nop0 + 20),
             ((char *)(nop0 + 20)) + 2, ((char *)(nop0 + 20)) + 4);
  bft_printf(_("  Creator   : %24.24s\n"), (char *)(nop0 + 22));

  if (strncmp("NOPO", (char *)(nop0 + 28), 4) != 0)
    bft_error(__FILE__, __LINE__, 0,
              _("Format error for file \"%s\" :\n"
                "String 'NOPO' does not appear in header;\n"
                "this file is probably not a NOPO/Simail file."),
              bft_file_get_name(fic_maillage));


#if 0 && defined(DEBUG) && !defined(NDEBUG)
  printf("nop0[   30] NIVEAU = %d\n",  nop0[29]);
  printf("nop0[   31] ETAT   = %d\n",  nop0[30]);
  printf("nop0[   32] NTACM  = %d\n",  nop0[31]);
#endif

  BFT_FREE(nop0);


  /* Lecture du tableau NOP1 */
  /* ----------------------- */

  /*
   * Ce tableau contient des tableaux auxiliaires, en général inutiles.
   */

  if (lnop1 != 0) {

    ecs_loc_pre_nopo__lit_int(fic_maillage, "NOP1",  taille_elt,
                              lnop1, ne1, le1, &nop1);

    BFT_FREE(nop1);

  }

  nop1    = NULL;


  /* Lecture du tableau NOP2 */
  /* ----------------------- */

  ecs_loc_pre_nopo__lit_int(fic_maillage, "NOP2", taille_elt,
                            lnop2, ne2, le2, &nop2);

  /* Dimension du maillage */

  if (nop2[0] == 2)
    dim_e = ECS_DIM_2;
  else
    dim_e = ECS_DIM_3;

  bft_printf(_("  Type      : %d bit\n"
               "  Dimension : %d\n\n"),
             (int)(taille_elt*8), (int) (nop2[0]));


  assert(nop2[0] == 2 || nop2[0] == 3);

  /* Autres dimensions et paramètres */

  ndsr   = (ecs_int_t) nop2[1];  /* numéro de référence maximal */
  ndsd   = (ecs_int_t) nop2[2];  /* numéro de sous-domaine maximal */
  ncopnp = (ecs_int_t) nop2[3];  /* 1 si sommets = noeuds, 0 sinon */
  ne     = (ecs_int_t) nop2[4];  /* nombre d'éléments */
  nepo   = (ecs_int_t) nop2[5];  /* nombre d'éléments point */
  nesg   = (ecs_int_t) nop2[6];  /* nombre de segments */
  ntri   = (ecs_int_t) nop2[7];  /* nombre de triangles */
  nqua   = (ecs_int_t) nop2[8];  /* nombre de quadrangles */
  ntet   = (ecs_int_t) nop2[9];  /* nombre de tétraèdres */
  npen   = (ecs_int_t) nop2[10]; /* nombre de pentaèdres */
  nhex   = (ecs_int_t) nop2[11]; /* nombre d'hexaèdres */
  noe    = (ecs_int_t) nop2[14]; /* nombre de noeuds */

  /*
   * Valeurs non utilisées ici :
   *
   * Remarque : on a d'après la documentation le nombre de mots dans NOP5
   *            en 27ème position de NOP2, et en 8ème position du tableau
   *            entête. Sur certains cas test (issus de Simail), la valeur
   *            fournie dans NOP2 n'est pas cohérente ; on l'ignore donc, et
   *            on conserve la valeur lue initialement. De la même manière,
   *            la présence de NOP3 dépend de LNOP3 (5ème valeur de l'entête)
   *            et non de NBEGM.
   *
   * nsup   = (ecs_int_t) nop2[12] ;  nombre de super éléments
   * nef    = (ecs_int_t) nop2[13] ;  nombre d'éléments de bord
   * n1     = (ecs_int_t) nop2[15] ;  nb. noeuds intérieurs segment ou arête
   * iset   = (ecs_int_t) nop2[16] ;  nb. noeuds intérieurs triangle ou face
   * iseq   = (ecs_int_t) nop2[17] ;  nb. noeuds intérieurs quadrangle ou face
   * isete  = (ecs_int_t) nop2[18] ;  nb. noeuds intérieurs tetraèdre
   * isepe  = (ecs_int_t) nop2[19] ;  nb. noeuds intérieurs pentaèdre
   * isehe  = (ecs_int_t) nop2[20] ;  nb. noeuds intérieurs hexaèdre
   * ntycoo = (ecs_int_t) nop2[22] ;  type de valeurs de coordonnées (2 ici)
   * lpgdn  = (ecs_int_t) nop2[23]    plus grande diff. num. noeuds même élé.
   * nbegm  = (ecs_int_t) nop2[24] ;  nombre de super-éléments dans NOP3
   * lnop5  = (ecs_int_t) nop2[25] ;  nombre de mots dans NOP5
   */

  np     = (ecs_int_t) nop2[21];  /* nombre de points */

  ntacoo = (ecs_int_t) nop2[26];  /* type de système de coordonnées :
                                     1 : cartésien ; 2 : cyl ; 3 : sphérique */


  BFT_FREE(nop2);

  bft_printf(_("  Initial data: %10d points\n"
               "                %10d nodes\n"
               "                %10d point elements\n"
               "                %10d segments\n"
               "                %10d triangles\n"
               "                %10d quadrangles\n"),
             np, noe, nepo, nesg, ntri, nqua);

  if (dim_e == ECS_DIM_2)
    bft_printf("\n");
  else
    bft_printf(_("                %10d tetrahedra\n"
                 "                %10d pentahedra\n"
                 "                %10d hexahedra\n\n"),
              ntet, npen, nhex);

  if (ntacoo != 1)
    bft_error(__FILE__, __LINE__, 0,
              _("Error reading NOPO file:\n\"%s\";\n"
                "The coordinate system is cylindrical or spherical,\n"
                "and this case is not currently handled"),
              bft_file_get_name(fic_maillage));


  /* "Blindages" (pas forcément nécessaires, mais on préfère être prudent) */

  assert(np <= noe);
  if (ncopnp == 1 && np == 0)
    np = noe;
  assert(np > 0);


  /* Lecture du tableau NOP3 */
  /* ----------------------- */

  /* Ce tableau contient des tableaux relatifs aux super-éléments */

  if (lnop3 != 0) {

    ecs_loc_pre_nopo__lit_int(fic_maillage, "NOP3",  taille_elt,
                              lnop3, ne3, le3, &nop3);

    BFT_FREE(nop3);

  }

  nop3 = NULL;


  /* Lecture du tableau NOP4 */
  /* ----------------------- */

  ecs_loc_pre_nopo__lit_real(fic_maillage, "NOP4", taille_elt,
                             lnop4, ne4, le4, &nop4);


  /*
    Ce tableau peut ne pas contenir de coordonnée "z" en 2D. Comme on
    ne s'intéresse qu'aux points et non aux noeuds intérieurs, on ne
    conserve que cette partie du tableau (les noeuds viennent après).
  */

  if (dim_e == ECS_DIM_3) {

    som_val_coord = nop4;
    nop4 = NULL;

  }
  else  if (dim_e == ECS_DIM_2) {

    BFT_MALLOC(som_val_coord, np * ECS_DIM_3, ecs_real_t);

    for (ind = 0; ind < np; ind++) {
      som_val_coord[ind*3    ] = nop4[ind*2];
      som_val_coord[ind*3 + 1] = nop4[ind*2 + 1];
      som_val_coord[ind*3 + 2] = 0.0;
    }

    BFT_FREE(nop4);

  }


#if 0 && defined(DEBUG) && !defined(NDEBUG)
  printf("Coordonnées\n");
  for (ind = 0; ind < np; ind++)
    printf("%d : % 10.5e % 10.5e % 10.5e\n",
           ind + 1, som_val_coord[ind*3    ],
           som_val_coord[ind*3 + 1], som_val_coord[ind*3 + 2]);
#endif


  /* Lecture du tableau NOP5 */
  /* ----------------------- */

  ecs_loc_pre_nopo__lit_int(fic_maillage, "NOP5", taille_elt,
                            lnop5, ne5, le5, &nop5);


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

  bft_file_free(fic_maillage);


  /* Décodage du tableau NOP5 */
  /* ------------------------ */

  vect_entmail = ecs_loc_pre_nopo__cree_elements(nop5,
                                                 &som_val_coord,
                                                 ndsr,
                                                 ndsd,
                                                 ncopnp,
                                                 ne,
                                                 np);

  BFT_FREE(nop5);


  /* Retour */
  /*--------*/


  maillage = ecs_maillage__cree_nodal(dim_e,
                                      vect_entmail);


  BFT_FREE(vect_entmail);


  return maillage;


}



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

/*----------------------------------------------------------------------------
 *  Lecture de la table de connectivité ; on lit les éléments présents dans
 *  le maillage, mais on y ajoute des éléments correspondant aux
 *  sous-éléments référencés, afin de porter ces références. On ne traite
 *  ainsi que les sous-éléments de niveau directement inféreieur ;
 *  Ainsi, si deux faces et trois arêtes d'un tétraèdre donné sont référencées
 *  (colorées), on créera en plus du tétraèdre deux triangles portant
 *  les  références des faces, mais aucune arête.
 *----------------------------------------------------------------------------*/

static ecs_entmail_t  ** ecs_loc_pre_nopo__cree_elements
(                                          /* <-  Renvoie les entités         */
                                           /*      sommets à cellules         */
 ecs_int_t     *nop5           ,           /*  -> Tableau NOP5                */
 ecs_real_t   **som_val_coord  ,           /*  -> Coordonnées des sommets     */
 ecs_int_t      ndsr           ,           /*  -> Numéro de référence maximal */
 ecs_int_t      ndsd           ,           /*  -> Numéro sous-domaine maximal */
 ecs_int_t      ncopnp         ,           /*  -> 1 si sommets = noeuds       */
 ecs_int_t      ne             ,           /*  -> Nombre d'éléments           */
 ecs_int_t      np                         /*  -> Nombre de points            */
)
{

  ecs_int_t    def_som_elt[ECS_NOPO_NBR_MAX_SOM];

  ecs_int_t    nbr_som;
  ecs_int_t    nbr_sselt;

  ecs_int_t    nbr_pos_ent[ECS_ENTMAIL_FIN];
  ecs_int_t    nbr_val_ent[ECS_ENTMAIL_FIN];
  ecs_int_t    nbr_pos_add[ECS_ENTMAIL_FIN];
  ecs_int_t    nbr_val_add[ECS_ENTMAIL_FIN];

  ecs_int_t    cpt_coul_ent[ECS_ENTMAIL_FIN];
  ecs_int_t   *val_coul_ent[ECS_ENTMAIL_FIN];
  ecs_size_t  *cpt_elt_coul_ent[ECS_ENTMAIL_FIN];

  ecs_int_t    ient;
  ecs_int_t    ind;
  ecs_int_t    iel;
  ecs_int_t    iloc;
  ecs_int_t    ipos;
  ecs_int_t    isom;
  ecs_int_t    isselt;
  ecs_int_t    issent;

  ecs_int_t    tsselt;

  ecs_int_t    ncge;          /* Type d'élément */
  ecs_int_t    nmae;
  ecs_int_t    ndsde;
  ecs_int_t    nno;
  ecs_int_t    npo;
  ecs_int_t    ining;
  ecs_int_t    iref;
  ecs_int_t    tab_ref[ECS_NOPO_NBR_MAX_TAB_REF];


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

  size_t       cpt_elt_ent        [ECS_ENTMAIL_FIN]; /* Nombre d'elems/entite */
  ecs_int_t    ind_elt_add        [ECS_ENTMAIL_FIN]; /* Indice ajouts/entité  */

  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_coul_ent   [ECS_ENTMAIL_FIN]; /* Couleurs              */

  ecs_entmail_t **vect_entmail;
  ecs_entmail_t  *entmail_som;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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


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

    cpt_elt_ent[ient] = 0;
    nbr_pos_ent[ient] = 1; /* Positions et valeurs éléments principaux */
    nbr_val_ent[ient] = 0;
    nbr_pos_add[ient] = 0; /* Positions et valeurs sous-éléments */
    nbr_val_add[ient] = 0;

  }

  elt_val_coul_ent[ECS_ENTMAIL_SOM] = NULL;


#define ECS_FCT_TYP(ncge) ecs_loc_nopo_elt_liste_c[ncge].ecs_typ

  /*========================================================*/
  /* Première boucle sur les éléments :                     */
  /* - comptages pour le dimensionnement des éléments       */
  /* - traitement des références des sommets                */
  /*========================================================*/

  ind = 0;

  for (iel = 0; iel < ne; iel++) {

    ncge   = nop5[ind++];

    /* Calcul de l'entité correspondante */

    if (ncge == ECS_NOPO_NODE)
      ient = ECS_ENTMAIL_SOM;
    else if (ncge == ECS_NOPO_SEGMENT)
      ient = ECS_ENTMAIL_ARE;
    else if (ncge < ECS_NOPO_TETRAHEDRON)
      ient = ECS_ENTMAIL_FAC;
    else if (ncge < ECS_NOPO_SUPER_ELEMENT)
      ient = ECS_ENTMAIL_CEL;
    else
      ient = ECS_ENTMAIL_FIN;


    nmae   = nop5[ind++]; /* Nombre de mots pour réf. faces, arêtes, ... */
    ndsde  = nop5[ind++]; /* Numéro de sous-domaine */
    nno    = nop5[ind++]; /* Nombre de noeuds pour l'élément */

    nbr_som = ecs_fic_elt_typ_liste_c[ECS_FCT_TYP(ncge)].nbr_som;

#if 0 && defined(DEBUG) && !defined(NDEBUG)
    printf("ele %d : t %d; nmae %d; ndsde %d; nno %d (nbse %d)\n",
           iel + 1, ncge, nmae, ndsde, nno, nbr_som);
#endif

    for (isom = 0; isom < nno && isom < nbr_som; isom++)
      def_som_elt[isom] = nop5[ind++];
    for (        ; isom < nno                  ; isom++)
      ind++;

    if (ncopnp == 0) {     /* Si sommets non confondus avec les noeuds,
                              on prend les sommets (->éléments linéaires) */
      npo = nop5[ind++];
      assert (npo == nbr_som);
      for (isom = 0; isom < npo; isom++)
        def_som_elt[isom] = nop5[ind++];

    }

    if (nmae != 0) {

      ining = nop5[ind++];

      /* D'après la documention : boucle de 2 à NMAE (équiv. 0 à NMAE - 2) */

      for (iref = 0; iref < nmae - 1; iref++)
        tab_ref[iref] = nop5[ind++];

      /* En fonction de INING, on compte le nombre sous-éléments référencés */

      if (   (ining  < 3 && ient == ECS_ENTMAIL_FAC)
          || (ining == 1 && ient == ECS_ENTMAIL_CEL)) {

        nbr_sselt = ecs_loc_nopo_elt_liste_c[ncge].nbr_sselt;

        for (isselt = 0; isselt < nbr_sselt; isselt++) {

          if (tab_ref[isselt] != 0) {

            tsselt = ecs_loc_nopo_elt_liste_c[ncge].sous_elt[isselt].elt_typ;

            nbr_pos_add[ient - 1] += 1;
            nbr_val_add[ient - 1] += ecs_fic_elt_typ_liste_c[tsselt].nbr_som;

          }

        }

      }


    }

    /* Traitement selon l'entité correspondante */

    if (ient > ECS_ENTMAIL_SOM && ient < ECS_ENTMAIL_FIN) {

      nbr_pos_ent[ient] += 1;
      nbr_val_ent[ient] += nbr_som;

    }


  }


  /*========================================================*/
  /* Création de la structure associée aux sommets          */
  /*========================================================*/


  /* Sommets */

  entmail_som = ecs_entmail_pre__cree_som(ECS_DIM_3,
                                          np,
                                          (*som_val_coord),
                                          NULL);


  /* Des tableaux sont libérés par ecs_entmail_pre__cree_som */

  *som_val_coord = NULL;

  elt_val_coul_ent[ECS_ENTMAIL_SOM] = NULL;
  cpt_coul_ent    [ECS_ENTMAIL_SOM] = 0;
  val_coul_ent    [ECS_ENTMAIL_SOM] = NULL;
  cpt_elt_coul_ent[ECS_ENTMAIL_SOM] = NULL;


  /*========================================================*/
  /* Allocations restantes                                  */
  /*========================================================*/

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

    if (nbr_pos_ent[ient] + nbr_pos_add[ient] > 1) {

      BFT_MALLOC(elt_pos_som_ent[ient],
                 nbr_pos_ent[ient] + nbr_pos_add[ient],
                 ecs_size_t);
      BFT_MALLOC(elt_val_som_ent[ient],
                 nbr_val_ent[ient] + nbr_val_add[ient],
                 ecs_int_t);
      BFT_MALLOC(elt_val_coul_ent[ient],
                 nbr_pos_ent[ient] + nbr_pos_add[ient] - 1,
                 ecs_int_t);

      elt_pos_som_ent[ient][0] = 1;

      /* Valeurs pos correspondant à fin éléments et début ajout */

      ind_elt_add[ient] = nbr_pos_ent[ient] - 1;

      elt_pos_som_ent[ient][ind_elt_add[ient]] = nbr_val_ent[ient] + 1;

    }
    else {

      elt_pos_som_ent[ient]     = NULL;
      elt_val_som_ent[ient]     = NULL;
      elt_val_coul_ent[ient]    = NULL;

      ind_elt_add[ient] = 0;

    }

  }


  /*========================================================*/
  /* Seconde boucle sur les éléments                        */
  /*========================================================*/

  ind = 0;

  for (iel = 0; iel < ne; iel++) {

    ncge   = nop5[ind++];

    /* Calcul de l'entité correspondante */

    if (ncge == ECS_NOPO_NODE)
      ient = ECS_ENTMAIL_SOM;
    else if (ncge == ECS_NOPO_SEGMENT)
      ient = ECS_ENTMAIL_ARE;
    else if (ncge < ECS_NOPO_TETRAHEDRON)
      ient = ECS_ENTMAIL_FAC;
    else if (ncge < ECS_NOPO_SUPER_ELEMENT)
      ient = ECS_ENTMAIL_CEL;
    else
      ient = ECS_ENTMAIL_FIN;


    nmae   = nop5[ind++]; /* Nombre de mots pour réf. faces, arêtes, ... */
    ndsde  = nop5[ind++]; /* Numéro de sous-domaine */
    nno    = nop5[ind++]; /* Nombre de noeuds pour l'élément */

    nbr_som = ecs_fic_elt_typ_liste_c[ECS_FCT_TYP(ncge)].nbr_som;

    for (isom = 0; isom < nno && isom < nbr_som; isom++)
      def_som_elt[isom] = nop5[ind++];
    for (        ; isom < nno                  ; isom++)
      ind++;

    if (ncopnp == 0) {     /* Si sommets non confondus avec les noeuds,
                              on prend les sommets (->éléments linéaires) */
      npo = nop5[ind++];
      for (isom = 0; isom < npo; isom++)
        def_som_elt[isom] = nop5[ind++];

    }

    if (nmae != 0) {

      ining = nop5[ind++];

      /* D'après la documention : boucle de 2 à NMAE (équiv. 0 à NMAE - 2) */

      for (iref = 0; iref < nmae - 1; iref++)
        tab_ref[iref] = nop5[ind++];

      /* En fonction de INING, on crée des sous-éléments référencés */

      if (   (ining  < 3 && ient == ECS_ENTMAIL_FAC)
          || (ining == 1 && ient == ECS_ENTMAIL_CEL)) {

        nbr_sselt = ecs_loc_nopo_elt_liste_c[ncge].nbr_sselt;

        for (isselt = 0; isselt < nbr_sselt; isselt++) {

          if (tab_ref[isselt] != 0) {

            /* Définition des sommets */

            tsselt = ecs_loc_nopo_elt_liste_c[ncge].sous_elt[isselt].elt_typ;

            issent = ient - 1;

            nbr_som = ecs_fic_elt_typ_liste_c[tsselt].nbr_som;

            ipos = elt_pos_som_ent[issent][ind_elt_add[issent]] - 1;

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

              iloc
                = ecs_loc_nopo_elt_liste_c[ncge].sous_elt[isselt].som[isom] - 1;

              elt_val_som_ent[issent][ipos + isom] = def_som_elt[iloc];

            }


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

            elt_pos_som_ent[issent][ind_elt_add[issent] + 1] =
              elt_pos_som_ent[issent][ind_elt_add[issent]] + nbr_som;


            /* Couleur de l'élément ajouté (sera compactée plus tard) */

            elt_val_coul_ent[issent][ind_elt_add[issent]] = tab_ref[isselt];


            /* Incrémentation de l'indice d'éléments ajoutés */

            ind_elt_add[issent]++;

          }

        }

      }

    }

    /* Ajout de l'élément à l'entité correspondante (sauf pour les sommets) */

   if (ient > ECS_ENTMAIL_SOM && ient < ECS_ENTMAIL_FIN) {

     nbr_som = ecs_fic_elt_typ_liste_c[ECS_FCT_TYP(ncge)].nbr_som;


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

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

        elt_val_som_ent
          [ient][elt_pos_som_ent[ient][cpt_elt_ent[ient]] - 1 + isom]
          = def_som_elt[ecs_loc_nopo_elt_liste_c[ncge].num_som[isom] - 1];

      }


      /* Position des numéros de sommets du prochain element */

      elt_pos_som_ent[ient][cpt_elt_ent[ient] + 1] =
        elt_pos_som_ent[ient][cpt_elt_ent[ient]] + nbr_som;


      /* Couleur de l'élément lu (sera compactée plus tard) */

      elt_val_coul_ent[ient][cpt_elt_ent[ient]] = ndsde;


      /* Incrementation du nombre d'éléments lus */

      cpt_elt_ent[ient]++;

    }


  }

#undef ECS_FCT_TYP


  /* Mise à jour des dimensions */

  for (ient = ECS_ENTMAIL_ARE; ient < ECS_ENTMAIL_FIN; ient++)
    cpt_elt_ent[ient] = ind_elt_add[ient];


  /* Compactage des couleurs des éléments */

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

    if (cpt_elt_ent[ient] > 0) {

      ecs_loc_pre_nopo__compct_ref(cpt_elt_ent[ient],
                                   ECS_MAX(ndsd, ndsr),
                                   &(cpt_coul_ent[ient]),
                                   &(elt_val_coul_ent[ient]),
                                   &(cpt_elt_coul_ent[ient]),
                                   &(val_coul_ent[ient]));

    }
    else {

      BFT_FREE(elt_val_coul_ent[ient]);

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

    }

  }


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


  vect_entmail = ecs_entmail_pre__cree_elt(cpt_elt_ent,
                                           elt_pos_som_ent,
                                           elt_val_som_ent,
                                           NULL,
                                           NULL,
                                           elt_val_coul_ent,
                                           cpt_coul_ent,
                                           val_coul_ent,
                                           cpt_elt_coul_ent);


  vect_entmail[ECS_ENTMAIL_SOM] = entmail_som;

  return vect_entmail;


}


/*----------------------------------------------------------------------------
 * Lecture d'un enregistrement d'un fichier NOPO. Chaque enregistrement
 * est un enregistrement de type binaire Fortran, constitué de mots de 4
 * ou 8 octets; dans le cas de mots de 4 octets, le premier mot donne la
 * dimension restante de l'enregistrement, et sera ignoré (i.e. pour un
 * tableau de n mots, on aura n + 1 entières, la première étant un entier
 * valant n).
 *
 * Le tableau des valeurs est alloué ici.
 *----------------------------------------------------------------------------*/

void ecs_loc_pre_nopo__lit_int
(
       bft_file_t      *const  fic_maillage,   /*  -> Descripteur du fichier  */
 const char            *const  nom_tableau,    /*  -> Nom du tableau          */
       size_t                  elt_size,       /*  -> Taille d'un élément     */
       size_t                  n_elt,          /*  -> Taille du tableau       */
       size_t                  n_seg,          /*  -> N. segments             */
       size_t                  l_seg,          /*  -> Taille d'un segment     */
       ecs_int_t     * *const  tableau         /* <-  Valeurs du tableau      */
)
{
  const char size_err_str[] = N_("Error reading NOPO file\n\"%s\"."
                                 "size of record \"%s\" is %d words\n"
                                 "but %d were expected.");

  BFT_MALLOC(*tableau, n_elt, ecs_int_t);

  if (elt_size == 4) {

    size_t i, j;
    size_t l_rem = n_elt - n_seg*l_seg;
    size_t l_max = ECS_MAX(l_seg, l_rem);
    int32_t *_tab = NULL;

    BFT_MALLOC(_tab, l_max + 1, int32_t);

    for (i = 0; i < n_seg; i++) {

      bft_file_read(_tab, elt_size, l_seg + 1, fic_maillage);

      if ((size_t) (_tab[0]) != l_seg)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) ((*tableau)[0]), (int) l_seg);

      for (j = 0; j < l_seg; j++)
        (*tableau)[l_seg*i + j] = _tab[j+1];

    }

    if (l_rem > 0) {

      bft_file_read(_tab, elt_size, l_rem + 1, fic_maillage);

      if ((size_t) (_tab[0]) != l_rem)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) ((*tableau)[0]), (int) l_rem);

      for (j = 0; j < l_rem; j++)
        (*tableau)[l_seg*n_seg + j] = _tab[j+1];

    }

    BFT_FREE(_tab);
  }

  else if (elt_size == 8) {

    size_t i, j;
    size_t l_rem = n_elt - n_seg*l_seg;
    size_t l_max = ECS_MAX(l_seg, l_rem);
    int64_t *_tab = NULL;

    BFT_MALLOC(_tab, l_max + 1, int64_t);

    for (i = 0; i < n_seg; i++) {

      bft_file_read(_tab, elt_size, l_seg + 1, fic_maillage);

      if ((size_t) (_tab[0]) != l_seg)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) ((*tableau)[0]), (int) l_seg);

      for (j = 0; j < l_seg; j++)
        (*tableau)[l_seg*i + j] = _tab[j+1];

    }

    if (l_rem > 0) {

      bft_file_read(_tab, elt_size, l_rem + 1, fic_maillage);

      if ((size_t) (_tab[0]) != l_rem)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) ((*tableau)[0]), (int) l_rem);

      for (j = 0; j < l_rem; j++)
        (*tableau)[l_seg*n_seg + j] = _tab[j+1];

    }

    BFT_FREE(_tab);
  }

}


static void ecs_loc_pre_nopo__lit_real
(
       bft_file_t      *const  fic_maillage,   /*  -> Descripteur du fichier  */
 const char            *const  nom_tableau,    /*  -> Nom du tableau          */
       size_t                  elt_size,       /*  -> Taille d'un élément     */
       size_t                  n_elt,          /*  -> Taille du tableau       */
       size_t                  n_seg,          /*  -> N. segments             */
       size_t                  l_seg,          /*  -> Taille d'un segment     */
       ecs_real_t    * *const  tableau         /* <-  Valeurs du tableau      */
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  const char size_err_str[] = N_("Error reading NOPO file\n\"%s\"."
                                 "size of record \"%s\" is %d words\n"
                                 "but %d were expected.");

  BFT_MALLOC(*tableau, n_elt, ecs_real_t);

  if (elt_size == 4) {

    size_t i, j;
    size_t l_rem = n_elt - n_seg*l_seg;
    size_t l_max = ECS_MAX(l_seg, l_rem);
    float *_tab = NULL;

    if (sizeof(float) != 4)
      bft_error(__FILE__, __LINE__, 0,
                _("This function has been compiled with a "
                  "\"float\" type of size other than 4.\n"
                  "(Porting error making conversion of single-precision\n"
                  "NOPO coordinates to standard Code_Saturne Preprocessor\n"
                  "coordinates impossible)."));

    BFT_MALLOC(_tab, l_max + 1, float);

    for (i = 0; i < n_seg; i++) {

      bft_file_read(_tab, elt_size, l_seg + 1, fic_maillage);

      if ((size_t) (((int32_t *)_tab)[0]) != l_seg)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) (((int32_t *)_tab)[0]), (int) l_seg);

      for (j = 0; j < l_seg; j++)
        (*tableau)[l_seg*i + j] = _tab[j+1];

    }

    if (l_rem > 0) {

      bft_file_read(_tab, elt_size, l_rem + 1, fic_maillage);

      if ((size_t) (((int32_t *)_tab)[0]) != l_rem)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) (((int32_t *)_tab)[0]), (int) l_rem);

      for (j = 0; j < l_rem; j++)
        (*tableau)[l_seg*n_seg + j] = _tab[j+1];

    }

    BFT_FREE(_tab);
  }

  else if (elt_size == 8) {

    size_t i, j;
    size_t l_rem = n_elt - n_seg*l_seg;
    size_t l_max = ECS_MAX(l_seg, l_rem);
    double *_tab = NULL;

    if (sizeof(double) != 8)
      bft_error(__FILE__, __LINE__, 0,
                _("This function has been compiled with a "
                  "\"double\" type of size other than 8.\n"
                  "(Porting error making conversion of double-precision\n"
                  "NOPO coordinates to standard Code_Saturne Preprocessor\n"
                  "coordinates impossible)."));

    BFT_MALLOC(_tab, l_max + 1, double);

    for (i = 0; i < n_seg; i++) {

      bft_file_read(_tab, elt_size, l_seg + 1, fic_maillage);

      if ((size_t) (((int64_t *)_tab)[0]) != l_seg)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) (((int64_t *)_tab)[0]), (int) l_seg);

      for (j = 0; j < l_seg; j++)
        (*tableau)[l_seg*i + j] = _tab[j+1];

    }

    if (l_rem > 0) {

      bft_file_read(_tab, elt_size, l_rem + 1, fic_maillage);

      if ((size_t) (((int64_t *)_tab)[0]) != l_rem)
        bft_error(__FILE__, __LINE__, 0, _(size_err_str),
                  bft_file_get_name(fic_maillage), nom_tableau,
                  (int) (((int64_t *)_tab)[0]), (int) l_rem);

      for (j = 0; j < l_rem; j++)
        (*tableau)[l_seg*n_seg + j] = _tab[j+1];

    }

    BFT_FREE(_tab);

  }

}


/*----------------------------------------------------------------------------
 *  Compactage des couleurs. On fournit en entrée le numéro de couleur
 *  d'une liste d'entités, on obtient en sortie (dans le même tableau)
 *  la position de cette couleur dans le tableau compacté ; on récupère
 *  le tableau des valeurs des couleurs correspondant à chaque indice,
 *  ainsi que le nombre de couleurs total et le nombre d'entités par couleur.
 *
 *  Si on n'a aucune couleur, on renvoie des pointeurs à NULL.
 *----------------------------------------------------------------------------*/

void ecs_loc_pre_nopo__compct_ref
(
 const ecs_int_t           nbr_ent          , /*  -> Nb. entités              */
 const ecs_int_t           num_coul_max     , /*  -> Numéro de couleur max.   */
       ecs_int_t    *const cpt_coul_ent     , /* <-  Nombre de couleurs       */
       ecs_int_t  * *const elt_val_coul_ent , /* <-> Couleurs des entités     */
       ecs_size_t * *const cpt_elt_coul_ent , /* <-  Nb. entités par couleur  */
       ecs_int_t  * *const val_coul_ent       /* <-  Num. couleurs/indice     */
)
{

  ecs_int_t   ind;
  ecs_int_t   ind_cpt;
  ecs_int_t  *renum;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  BFT_MALLOC(*cpt_elt_coul_ent, num_coul_max + 1, ecs_size_t);

  for (ind = 0; ind < num_coul_max + 1; ind++)
    (*cpt_elt_coul_ent)[ind] = 0;

  for (ind = 0; ind < nbr_ent; ind++)
    (*cpt_elt_coul_ent)[(*elt_val_coul_ent)[ind]] += 1;


  /* Compactage des références réellement utilisées */

  BFT_MALLOC(*val_coul_ent, num_coul_max + 1, ecs_int_t);
  BFT_MALLOC(renum, num_coul_max + 1, ecs_int_t);

  ind_cpt = 0;

  for (ind = 0; ind < num_coul_max + 1; ind++) {

    if ((*cpt_elt_coul_ent)[ind] > 0) {

      (*val_coul_ent)[ind_cpt] = ind;
      (*cpt_elt_coul_ent)[ind_cpt] = (*cpt_elt_coul_ent)[ind];

      /* On ajoute 1 pour une numérotation de 1 à n et non de 0 à n-1 */

      renum[ind] = ind_cpt + 1;

      ind_cpt += 1;

    }

  }

  *cpt_coul_ent = ind_cpt;

  for (ind = 0; ind < nbr_ent; ind++)
    (*elt_val_coul_ent)[ind] = renum[(*elt_val_coul_ent)[ind]];

  BFT_FREE(renum);

  BFT_REALLOC(*cpt_elt_coul_ent, *cpt_coul_ent, ecs_size_t);


  /* Test si on n'a que la couleur 0 (équivaut à aucune couleur) */

  if (*cpt_coul_ent == 1) {

    if ((*val_coul_ent)[0] == 0) {

      *cpt_coul_ent = 0;

      BFT_FREE(*cpt_elt_coul_ent);
      BFT_FREE(*elt_val_coul_ent);
      BFT_FREE(*val_coul_ent);

    }

  }

}


Generated by  Doxygen 1.6.0   Back to index