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

ecs_entmail_pcp.c

/*============================================================================
 *  Definitions des fonctions de base
 *   associees a la structure `ecs_entmail_t' decrivant une entite de maillage
 *  Ces fonctions concernent les entites de maillage PRINCIPALES
 *   par opposition avec les sous-entites de maillage
 *============================================================================*/

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


/*============================================================================
 *                                 Visibilite
 *============================================================================*/

#include "ecs_config.h"


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

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

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


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

#include "ecs_chaine_glob.h"
#include "ecs_chrono.h"
#include "ecs_param_perio_glob.h"
#include "ecs_param_rc_glob.h"
#include "ecs_def.h"
#include "ecs_tab.h"


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

#include "ecs_post.h"


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

#include "ecs_champ.h"
#include "ecs_champ_chaine.h"
#include "ecs_champ_att.h"
#include "ecs_champ_def.h"
#include "ecs_champ_vec.h"
#include "ecs_champ_vec_int.h"
#include "ecs_champ_vec_real.h"
#include "ecs_famille_chaine.h"


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

#include "ecs_entmail.h"
#include "ecs_entmail_post.h"


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

#include "ecs_entmail_pcp.h"


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

#include "ecs_entmail_priv.h"



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

/*----------------------------------------------------------------------------
 * Fonction locale pour la sélection de faces non conformes à recoller
 *----------------------------------------------------------------------------*/

static ecs_tab_int_t ecs_loc_entmail_pcp__recolle_sel
(
 ecs_entmail_t    *const *const vect_entmail,
 ecs_tab_bool_t          *const tab_bool_fac_select,
 ecs_bool_t                     sel_fac_isolee
) ;


/*----------------------------------------------------------------------------
 * Fonction qui cree des tableaux de booleens par entite principale
 *  Le booleen correspondant a un element de l'entite est a `ECS_TRUE'
 *  si l'element est selectionne par la description donnee
 * Seules sont concernees les entites de type `entmail_sel_e'
 *----------------------------------------------------------------------------*/

static ECS_ENTMAIL_E ecs_loc_entmail_pcp__cree_masq
(
       ecs_tab_bool_t             *const bool_elt_select,
 const ecs_tab_int_t              *const liste_filtre,
       ecs_entmail_t       *const *const vect_entmail,
       ECS_ENTMAIL_E                     entmail_sel_e,
 const char                       *const nom_champ,
 const ecs_int_t                         descr_ident,
 const char                       *const descr_nom
) ;


/*----------------------------------------------------------------------------
 *  Fonction qui construit les listes de faces internes et de bord, ainsi que
 *  les listes de faces avec erreur de connectivité (i.e. qui appartiennent
 *  à 2 cellules ou plus vu d'un même côté, ou qui sont à la fois entrante
 *  et sortante pour une cellule) et de faces isolées.
 *
 *  Un tableau indiquant le type associé à chaque face (0 pour face isolée,
 *  1 ou 2 pour face de bord, 3 pour face interne, et 4 pour tous les autres
 *  cas (faces voyant au moins deux cellules sur un même côté, d'ou erreur
 *  de connectivité) doit être fourni en entrée.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_pcp__listes_fac
(
 const ecs_tab_int_t  *const typ_fac,
       ecs_tab_int_t  *const liste_fac_erreur,
       ecs_tab_int_t  *const liste_fac_interne,
       ecs_tab_int_t  *const liste_fac_de_bord,
       ecs_tab_int_t  *const liste_fac_isolee
) ;


/*----------------------------------------------------------------------------
 *  Fonction qui compte le nombre de faces internes et de bord, ainsi que
 *  le nombre de faces avec erreur de connectivité (i.e. qui appartiennent
 *  à 2 cellules ou plus vu d'un même côté, ou qui sont à la fois entrante
 *  et sortante pour une cellule) et de faces isolées.
 *
 *  Un tableau indiquant le type associé à chaque face (0 pour face isolée,
 *  1 ou 2 pour face de bord, 3 pour face interne, et 4 pour tous les autres
 *  cas (faces voyant au moins deux cellules sur un même côté, d'ou erreur
 *  de connectivité) doit être fourni en entrée.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_pcp__cpt_typ_fac
(
 const ecs_tab_int_t  *const typ_fac,
       size_t         *const nbr_fac_erreur,
       size_t         *const nbr_fac_interne,
       size_t         *const nbr_fac_de_bord,
       size_t         *const nbr_fac_isolee
) ;


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

/*----------------------------------------------------------------------------
 * Fonction realisant la transformation d'une entite principale donnee
 *  a partir du contenu d'une autre entite de maillage principale donnee
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__cree_indice
(
 ecs_entmail_t * this_entmail,      /* <-> Entite de maillage a transformer   */
 ecs_entmail_t * entmail_dep        /* --> Entite de maillage dont depend     */
                                    /*     l'entite de maillage a transformer */
)
{

  ecs_champ_t *champ_label_entmail_dep ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_entmail != NULL && entmail_dep != NULL) ;


  if (entmail_dep->champ[ECS_CHAMP_ATT] != NULL) {


    /* Recuperation de l'adresse du champ de labels */
    /*  de l'entite de maillage `entmail_dep'       */
    /*----------------------------------------------*/

    champ_label_entmail_dep
      = ecs_champ_chaine__trouve_nom(entmail_dep->champ[ECS_CHAMP_ATT],
                                     ECS_CHAMP_NOM_LABEL) ;


    if (champ_label_entmail_dep != NULL) {


      /* Dependance inter-entites */
      /*--------------------------*/

      ecs_champ__reference_en_indice(this_entmail->champ[ECS_CHAMP_DEF],
                                     champ_label_entmail_dep) ;


      /* Dependances intra-entite : dependances inter-champs */
      /*-----------------------------------------------------*/

      /* Aucune dependance intra-entite referencee pour le moment */

    }

  }


}


/*----------------------------------------------------------------------------
 * Fonction qui décompose les cellules d'une entité de maillage principale
 *  en ses faces
 *
 * Renvoie l'entité de maillage  obtenue par décomposition
 *----------------------------------------------------------------------------*/

ecs_entmail_t * ecs_entmail_pcp__decompose_cel
(
 ecs_entmail_t * entmail_cel          /* <-> Entite de maillage a décomposer  */
)
{

  ecs_entmail_t *entmail_fac ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(entmail_cel != NULL) ;


  /* Allocation et initialisation de l'entite de maillage des faces */
  /*----------------------------------------------------------------*/

  entmail_fac = ecs_entmail__cree() ;


  /* Construction       des champs de l'entité de maillage des faces    */
  /*  par décomposition des champs de l'entité de maillage des cellules */
  /*--------------------------------------------------------------------*/

  ecs_champ_def__decompose_cel(entmail_fac->champ,
                               entmail_cel->champ[ECS_CHAMP_DEF]);


  return entmail_fac ;

}


/*----------------------------------------------------------------------------
 * Fonction qui décompose les faces d'une entité de maillage principale
 *  en ses arêtes
 *
 * Renvoie l'entité de maillage  obtenue par décomposition
 *----------------------------------------------------------------------------*/

ecs_entmail_t * ecs_entmail_pcp__decompose_fac
(
 ecs_entmail_t * entmail_fac          /* <-> Entité de maillage a décomposer  */
)
{

  ecs_entmail_t *entmail_are ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(entmail_fac != NULL) ;


  /* Allocation et initialisation de l'entité de maillage des arêtes */
  /*-----------------------------------------------------------------*/

  entmail_are = ecs_entmail__cree() ;


  /* Construction       des champs de l'entité de maillage des arêtes */
  /*  par décomposition des champs de l'entité de maillage des faces  */
  /*------------------------------------------------------------------*/

  ecs_champ_def__decompose_fac(entmail_are->champ,
                               entmail_fac->champ[ECS_CHAMP_DEF]);


  return entmail_are ;

}


/*----------------------------------------------------------------------------
 * Fonction realisant la concatenation de deux entites de maillage principales
 *  Les 2 entites doivent etre de meme dimension
 *   c'est-a-dire 2 ECS_ENTMAIL_CEL, ou 2 ECS_ENTMAIL_FAC, etc.)
 *
 * La 2nde entite de maillage `entmail_concat' est concatenee a la suite
 *  de l'entite de maillage receptrice `this_entmail'
 *
 * Le 3eme argument est un tableau sur les entites de maillage
 *  dont les elements non NULL
 *  sont les entites de maillage pour lesquelles le champ "definition"
 *  sera modifie pour prendre en compte
 *  le decalage des references des elements
 *  de l'entite de maillage a concatener
 *  (decalage correspondant au nombre d'elements de l'entite receptrice)
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__concatene
(
 ecs_entmail_t *      this_entmail,
 ecs_entmail_t *      entmail_concat,
 ecs_entmail_t *const liste_entmail_connect[]
)
{

  ecs_int_t ichamp  ;  /* Indice de boucle sur les champs  */
  ecs_int_t ient ;
  size_t    nbr_elt_entmail_receptrice ;
  size_t    nbr_elt_entmail_concat ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_entmail   != NULL) ;
  assert(entmail_concat != NULL) ;


  if (this_entmail                       != NULL &&
      this_entmail->champ[ECS_CHAMP_DEF] != NULL    ) {

    nbr_elt_entmail_receptrice
      = ecs_champ__ret_pos_nbr(this_entmail->champ[ECS_CHAMP_DEF]) - 1 ;

  }

  if (entmail_concat                       != NULL &&
      entmail_concat->champ[ECS_CHAMP_DEF] != NULL    ) {

    nbr_elt_entmail_concat
      = ecs_champ__ret_pos_nbr(entmail_concat->champ[ECS_CHAMP_DEF]) - 1 ;

  }
  else

    return ; /* nbr_elt_entmail_concat = 0 */


  /* On concatene les champs de l'entité `entmail_concat' à ceux de      */
  /* l'entité réceptrice `this_entmail' ; ces champs sont eliminés au    */
  /* fur et à mesure dans `entmail_concat'                               */
  /*---------------------------------------------------------------------*/


  for (ichamp = ECS_CHAMP_DEB ; ichamp < ECS_CHAMP_FIN ; ichamp++) {

    if (this_entmail->champ[ichamp]   != NULL ||
        entmail_concat->champ[ichamp] != NULL) {

      ecs_champ_chaine__concatene(&this_entmail->champ[ichamp],
                                  &entmail_concat->champ[ichamp],
                                  nbr_elt_entmail_receptrice,
                                  nbr_elt_entmail_concat) ;

    }

  }


  if (this_entmail                       != NULL &&
      this_entmail->champ[ECS_CHAMP_DEF] != NULL   ) {

    ient = 0 ;

    while (ient < ECS_ENTMAIL_FIN                  &&
           liste_entmail_connect[ient] != NULL   ) {

      ecs_champ__incremente_val
        (liste_entmail_connect[ient]->champ[ECS_CHAMP_DEF],
         nbr_elt_entmail_receptrice) ;

      ient++ ;

    }

  }


}


/*----------------------------------------------------------------------------
 * Fonction realisant la fusion des elements topologiquement identiques
 *  d'une entite de maillage principale donnee
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__fusionne
(
 ecs_entmail_t *      entmail,
 ecs_entmail_t *const liste_entmail_connect[]
)
{

  int            ient ;
  size_t         nbr_elt_new ;
  ecs_type_t     typ_e ;
  ecs_tab_int_t  vect_transf ;
  ecs_tab_int_t  signe_elt ;

  ecs_champ_t   *ptr_champ ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(entmail != NULL) ;


  /*--------------------------------------------------------------------------*/
  /* 1ere etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Tri et compactage des definitions des elements                           */
  /*                                                                          */
  /* Determination du vecteur de transformation permettant de passer          */
  /*  de la liste initiale des elements                                       */
  /*  a une liste ordonnee et compactee des elements                          */
  /*--------------------------------------------------------------------------*/


  typ_e = ecs_champ__ret_val_typ(entmail->champ[ECS_CHAMP_DEF]) ;
  nbr_elt_new = 0 ;


  switch (typ_e) {


  case ECS_TYPE_ecs_int_t:


    /*------------------------------------------------------------------------*/
    /*                                                                        */
    /* Determination du signe des elements apres tri de leur definition       */
    /*                                                                        */
    /*------------------------------------------------------------------------*/

    signe_elt.nbr = 0 ;
    signe_elt.val = NULL ;


    vect_transf = ecs_champ_def__int_fusionne(entmail->champ[ECS_CHAMP_DEF],
                                              &nbr_elt_new,
                                              &signe_elt) ;

    break ;


  case ECS_TYPE_ecs_real_t:


    vect_transf = ecs_champ_def__real_fusionne(entmail->champ[ECS_CHAMP_DEF],
                                               &nbr_elt_new) ;


    break ;


  default:

    assert(typ_e == ECS_TYPE_ecs_int_t ||
           typ_e == ECS_TYPE_ecs_real_t       ) ;

  } /* Fin du `switch' */



  /*--------------------------------------------------------------------------*/
  /* 2eme etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Application du vecteur de transformation sur les autres champs           */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  /*-------------------------------------------------------------------*/
  /* Traitement des champs pour lesquels il faut realiser              */
  /*  la fusion des proprietes des elements topologiquement identiques */
  /*-------------------------------------------------------------------*/

  /* Traitement des champs "attribut" */
  /*----------------------------------*/

  ecs_champ_chaine__transforme(entmail->champ[ECS_CHAMP_ATT],
                               nbr_elt_new,
                               vect_transf,
                               ecs_champ_att__fusionne) ;


  /*--------------------------------------------------------------------------*/
  /* 3eme etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Application du vecteur de transformation et du signe des elements        */
  /*  sur la definition des elements des entites de maillage                  */
  /*  de `liste_entmail_connect'                                              */
  /*                                                                          */
  /* Cette transformation doit aussi être appliquée sur les champs attribut   */
  /* de statut ECS_CHAMP_STATUT_REF_ELT de l'entité en cours                  */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  /* Champs référencant l'entité en cours */

  ptr_champ = entmail->champ[ECS_CHAMP_ATT] ;

  while (ptr_champ != NULL) {

    ptr_champ = ecs_champ_chaine__trouve_statut(ptr_champ,
                                                ECS_CHAMP_STATUT_REF_ELT) ;

    if (ptr_champ != NULL) {

      ecs_champ__renumerote_et_sgn(ptr_champ,
                                   vect_transf,
                                   signe_elt) ;

      ptr_champ = ecs_champ_chaine__ret_suivant(ptr_champ) ;

    }

  }


  /* Définitions des entités de maillage de `liste_entmail_connect' */

  ient = 0 ;

  if (typ_e == ECS_TYPE_ecs_int_t) {

    while (ient < ECS_ENTMAIL_FIN                  &&
           liste_entmail_connect[ient] != NULL   ) {

     ecs_champ__renumerote_et_sgn
       (liste_entmail_connect[ient]->champ[ECS_CHAMP_DEF],
        vect_transf,
        signe_elt) ;

     ient++ ;

    }

    BFT_FREE(signe_elt.val) ;

  }
  else {

    while (ient < ECS_ENTMAIL_FIN              &&
           liste_entmail_connect[ient] != NULL   ) {

      ecs_champ__renumerote(liste_entmail_connect[ient]->champ[ECS_CHAMP_DEF],
                            vect_transf) ;

      ient++ ;

    }

  }


  BFT_FREE(vect_transf.val) ;


}


/*----------------------------------------------------------------------------
 *  Fusion des sommets confondus et suppression des éléments dégénérés.
 *
 *  On ne met pas à jour les champs de type attribut non héritable,
 *  de type ECS_CHAMP_STATUT_REF_ELT (ex : champ_fac_perio), ces champs
 *  pouvant être construits après l'appel de cette fonction.
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__nettoie_descend
(
       ecs_entmail_t  *const *const vect_entmail
)
{

  ecs_champ_t  *champ_def_som = NULL ;
  ecs_champ_t  *champ_def_are = NULL ;
  ecs_champ_t  *champ_def_fac = NULL ;

  ecs_champ_t  *champ_are_old_new ;
  ecs_champ_t  *champ_fac_old_new ;

  ecs_champ_t  *champ_fac_att_tete ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  if (   vect_entmail[ECS_ENTMAIL_SOM] == NULL
      || vect_entmail[ECS_ENTMAIL_ARE] == NULL)
    return ;


  champ_def_som = vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF] ;
  champ_def_are = vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF] ;


  if (vect_entmail[ECS_ENTMAIL_FAC] != NULL)
    champ_def_fac = vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF] ;


  /* Suppression éventuelle des attributs associés aux sommets
     ou arêtes (il ne devrait déjà plus y en avoir à ce stade) */

  ecs_champ_chaine__detruit
    (&vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_ATT]) ;

  ecs_champ_chaine__detruit
    (&vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_ATT]) ;


  /* Fusion des sommets confondus (connectivité des arêtes mise à jour) */
  /*--------------------------------------------------------------------*/

  ecs_champ_def__nettoie_som_are(champ_def_som,
                                 champ_def_are) ;


  /* Arêtes */
  /*--------*/

  champ_are_old_new = ecs_champ_def__nettoie_are(champ_def_are) ;

  if (champ_are_old_new != NULL) {

    /* Remplacement des références dans la définition des faces */

    if (vect_entmail[ECS_ENTMAIL_FAC] != NULL)
      ecs_champ__remplace_ref
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF],
         champ_are_old_new) ;

    ecs_champ__detruit(champ_are_old_new) ;

  }
  else

    return ;


  /* Faces */
  /*-------*/

  champ_fac_old_new = ecs_champ_def__nettoie_fac(champ_def_fac) ;

  if (champ_fac_old_new != NULL) {

    /* Héritage des champs "attribut" */

    champ_fac_att_tete
      = ecs_champ_chaine__herite
          (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
           champ_fac_old_new,
           vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;

    ecs_champ_chaine__detruit
      (&vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]) ;

    vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT] = champ_fac_att_tete ;

    /* Remplacement des références dans la définition des faces */

    if (vect_entmail[ECS_ENTMAIL_CEL] != NULL)
      ecs_champ__remplace_ref
        (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
         champ_fac_old_new) ;

    ecs_champ__detruit(champ_fac_old_new) ;

  }

}


/*----------------------------------------------------------------------------
 * Suppression des sommets ne participant pas à la connectivité
 *  et fusion des éléments surfaciques confondus éventuels
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__nettoie_nodal
(
       ecs_entmail_t  *const *const vect_entmail
)
{


  ecs_champ_t  *champ_def_som = NULL ;
  ecs_champ_t  *champ_def_are = NULL ;
  ecs_champ_t  *champ_def_fac = NULL ;
  ecs_champ_t  *champ_def_cel = NULL ;

  ecs_champ_t  *champ_som_old_new ;
  ecs_champ_t  *champ_som_att_tete ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_SOM] != NULL) ;

  if (vect_entmail[ECS_ENTMAIL_SOM] == NULL)
    return ;


  champ_def_som = vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF] ;

  if (vect_entmail[ECS_ENTMAIL_ARE] != NULL)
    champ_def_are = vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF] ;

  if (vect_entmail[ECS_ENTMAIL_FAC] != NULL)
    champ_def_fac = vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF] ;

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL)
    champ_def_cel = vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF] ;


  champ_som_old_new = ecs_champ_def__nettoie_nodal(champ_def_som,
                                                   champ_def_are,
                                                   champ_def_fac,
                                                   champ_def_cel) ;


  /* Si pas de renumérotation, rien à faire */

  if (champ_som_old_new == NULL)
    return ;


  /* Mise à jour de la connectivité nodale */

  if (champ_def_are != NULL)
    ecs_champ__remplace_ref(champ_def_are,
                            champ_som_old_new) ;

  if (champ_def_fac != NULL)
    ecs_champ__remplace_ref(champ_def_fac,
                            champ_som_old_new) ;

  if (champ_def_cel != NULL)
    ecs_champ__remplace_ref(champ_def_cel,
                            champ_som_old_new) ;


  /* Mise à jour des champs de type attribut héritables */

  champ_som_att_tete
    = ecs_champ_chaine__herite
        (vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_ATT],
         champ_som_old_new,
         vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF]) ;

  ecs_champ_chaine__detruit
    (&vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_ATT]) ;

  vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_ATT] = champ_som_att_tete ;


  /* Libération du champ de renumérotation des sommets */

  ecs_champ__detruit(champ_som_old_new) ;

}


/*----------------------------------------------------------------------------
 *  Correction si nécessaire de l'orientation des éléments en
 *   connectivité nodale.
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__orient_nodal
(
       ecs_entmail_t  *const *const vect_entmail,   /*  -> Déf. maillage      */
       ecs_tab_int_t  *const        liste_cel_err,  /* <-  Liste cels. erreur
                                                     *     (optionnelle)      */
       ecs_tab_int_t  *const        liste_cel_cor,  /* <-  Liste cels. corr.
                                                     *     (optionnelle)      */
 const ecs_bool_t                   correc_orient   /*  -> Correction ou non  */
)
{

  ecs_champ_t  *champ_def_som = NULL ;
  ecs_champ_t  *champ_def_fac = NULL ;
  ecs_champ_t  *champ_def_cel = NULL ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_SOM] != NULL) ;

  if (vect_entmail[ECS_ENTMAIL_SOM] == NULL)
    return ;


  champ_def_som = vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF] ;

  if (vect_entmail[ECS_ENTMAIL_FAC] != NULL)
    champ_def_fac = vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF] ;

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL)
    champ_def_cel = vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF] ;


  ecs_champ_def__orient_nodal(champ_def_som,
                              champ_def_fac,
                              champ_def_cel,
                              liste_cel_err,
                              liste_cel_cor,
                              correc_orient) ;

}


/*----------------------------------------------------------------------------
 * Fonction qui renvoie le nombre de faces de type "polygone"
 *  de l'entité de maillage de type "faces" donnée
 *  (faces définies par plus de 4 arêtes)
 *----------------------------------------------------------------------------*/

size_t  ecs_entmail_pcp__nbr_fac_poly
(
 ecs_entmail_t * entmail_fac
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(entmail_fac != NULL) ;
  assert(entmail_fac->champ[ECS_CHAMP_DEF] != NULL) ;


  return ecs_champ_def__nbr_fac_poly(entmail_fac->champ[ECS_CHAMP_DEF]) ;

}


/*----------------------------------------------------------------------------
 * Fonction qui realise le tri des elements
 *  de l'entite de maillage principale donnee
 *  suivant leur type geometrique
 * La fonction affiche le nombre d'elements par type geometrique
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__trie_typ_geo
(
 ecs_entmail_t  * entmail,
 ECS_ENTMAIL_E    typ_entmail
)
{

  int            dim_elt ;
  ecs_tab_int_t  vect_renum ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(entmail != NULL) ;


  if (typ_entmail == ECS_ENTMAIL_ARE)
    dim_elt = 1 ;
  else if (typ_entmail == ECS_ENTMAIL_FAC)
    dim_elt = 2 ;
  else if (typ_entmail == ECS_ENTMAIL_CEL)
    dim_elt = 3 ;
  else
    dim_elt = 0 ;


  /* Tri des types géometriques des éléments (si nécessaire) */
  /*---------------------------------------------------------*/

  vect_renum.nbr = 0 ;
  vect_renum.val = NULL ;

  if (entmail->champ[ECS_CHAMP_DEF] != NULL)

    vect_renum = ecs_champ_def__trie_typ(entmail->champ[ECS_CHAMP_DEF],
                                         dim_elt) ;


  /* Application du vecteur de renumerotation sur les autres champs */
  /*----------------------------------------------------------------*/

  if (vect_renum.val != NULL) {

    /* Inversion du tableau de renumerotation */

    ecs_tab_int__inverse(&vect_renum) ;


    /* Traitement du champ representant les définitions */

    ecs_champ_chaine__transforme(entmail->champ[ECS_CHAMP_DEF],
                                 vect_renum.nbr,
                                 vect_renum,
                                 ecs_champ__transforme_pos) ;


    /* Traitement des champs "attribut" */

    ecs_champ_chaine__transforme(entmail->champ[ECS_CHAMP_ATT],
                                 vect_renum.nbr,
                                 vect_renum,
                                 ecs_champ__transforme_pos) ;


    BFT_FREE(vect_renum.val) ;


  } /* Fin : si le vecteur de renumerotation n'est pas NULL */

}


/*----------------------------------------------------------------------------
 * Fonction réalisant le découpage des faces polygonales en triangles
 *  de l'entité de maillage principale des faces
 *
 * Le maillage doit être en connectivité nodale (faces -> sommets)
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__dec_poly_tria
(
 ecs_entmail_t  *const *const vect_entmail
)
{

  size_t           nbr_fac ;

  ecs_champ_t    * champ_fac_dec ;
  ecs_champ_t    * champ_fac_att_tete ;
  ecs_champ_t    * champ_fac_att_suite ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_ARE] == NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_SOM] != NULL) ;


  /*--------------------------------------------------------------------------*/
  /* 1ere etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Nouvelle definition des faces en fonction des sommets :                  */
  /*  -    anciennes faces non decoupees (triangles ou quadrangles)           */
  /*  - et nouvelles faces (nouveaux triangles)                               */
  /* Renvoi de la definition des anciennes faces en fonction des nouvelles    */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/

  /* Traitement des champs principaux */

  champ_fac_dec
    = ecs_champ_def__dec_poly_tria
        (vect_entmail[ECS_ENTMAIL_FAC]->champ,
         vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF]) ;


  /*--------------------------------------------------------------------------*/
  /* 2eme etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Construction des autres champs pour les nouvelles faces (triangles)      */
  /*                                                                          */
  /* Determination des valeurs des attributs pour les triangles               */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/

  /* On met à jour les champs de type attribut héritables */

  champ_fac_att_tete
    = ecs_champ_chaine__herite
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
         champ_fac_dec,
         vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;


  /* On met à jour les champs de type attribut non héritable,
     de type ECS_CHAMP_STATUT_REF_ELT (ex : champ_fac_perio)  */

  nbr_fac
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) - 1 ;

  champ_fac_att_suite
    = ecs_champ_chaine__renum
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
         champ_fac_dec,
         nbr_fac) ;


  ecs_champ_chaine__detruit
    (&vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]) ;

  vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT] = champ_fac_att_tete ;


  if (champ_fac_att_suite != NULL)
    ecs_champ_chaine__ajoute
      (&(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]),
       champ_fac_att_suite) ;


  /*--------------------------------------------------------------------------*/
  /* 3eme etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Remplacement des references aux anciennes faces                          */
  /*  par les references aux triangles, dans la definition des cellules       */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL) {

    ecs_champ__remplace_ref(vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                            champ_fac_dec) ;

  }

  ecs_champ__detruit(champ_fac_dec) ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui crée la liste des faces intérieures à un maillage.
 *  On ne compte pas ici les faces périodiques parmi les faces intérieures,
 *  cette fonction étant destinée à filtrer le post-triatment, et les
 *  faces périodiques étant déjà affichables par ailleurs.
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_entmail_pcp__liste_fac_int
(
 ecs_entmail_t  *const   vect_entmail[]
)
{
  ecs_int_t   cpt_fac_interne ;
  size_t      ifac ;

  ecs_tab_int_t  typ_fac_cel ;
  ecs_tab_int_t  liste_fac_interne ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;


  liste_fac_interne.nbr = 0 ;
  liste_fac_interne.val = NULL ;

  /* Determination du type de connectivité associé à chaque face */

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL) {

    typ_fac_cel = ecs_champ_def__typ_fac_cel
                    (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                     vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;

    /* Comptage et allocation */

    cpt_fac_interne = 0 ;

    for (ifac = 0 ; ifac < typ_fac_cel.nbr ; ifac++) {
      if (typ_fac_cel.val[ifac] == 3)
        cpt_fac_interne++ ;
    }

    liste_fac_interne.nbr = cpt_fac_interne ;
    BFT_MALLOC(liste_fac_interne.val, liste_fac_interne.nbr, ecs_int_t) ;

    /* Remplissage de la liste */

    cpt_fac_interne = 0 ;

    for (ifac = 0 ; ifac < typ_fac_cel.nbr ; ifac++) {
      if (typ_fac_cel.val[ifac] == 3)
        liste_fac_interne.val[cpt_fac_interne++] = ifac ;
    }

  }

  return liste_fac_interne ;

}


/*----------------------------------------------------------------------------
 * Fonction qui compte les faces intérieures et de bord et crée une liste
 * correspondant a chacun de ces deux ensembles. On peut aussi renvoyer
 * d'éventuelles listes de faces isolées ou de faces appartenant à plus de
 * deux cellules (erreur de connectivité en cas de cellules partiellement
 * superposées).
 *
 * Dans chaque cas, si l'argument pointeur vers une liste donnée est
 * à NULL, cette liste n'est pas crée.
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__compte_typ_fac
(
 ecs_entmail_t  *const   vect_entmail[],
 ecs_tab_int_t  *const   liste_fac_erreur,
 ecs_tab_int_t  *const   liste_fac_interne,
 ecs_tab_int_t  *const   liste_fac_de_bord,
 ecs_tab_int_t  *const   liste_fac_isolee
)
{

  ecs_tab_int_t  typ_fac_cel ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;


  /* Determination du type de connectivité associé à chaque face */

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL) {

    typ_fac_cel = ecs_champ_def__typ_fac_cel
                    (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                     vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;

    /* Mise à jour de typ_fac_cel en fonction des périodicités éventuelles */

    ecs_champ_chaine__typ_fac_perio
      (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
       &typ_fac_cel) ;

    ecs_loc_entmail_pcp__listes_fac(&typ_fac_cel,
                                    liste_fac_erreur,
                                    liste_fac_interne,
                                    liste_fac_de_bord,
                                    liste_fac_isolee) ;

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

    if (liste_fac_erreur != NULL) {
      if (liste_fac_erreur->nbr != 0) {
        ecs_warn() ;
        bft_printf(_("There are %d faces of which one same side belongs\n"
                     "to at least 2 cells --> bad connectivity."),
                   liste_fac_erreur->nbr) ;
      }
    }

    if (liste_fac_isolee != NULL) {
      if (liste_fac_isolee->nbr != 0) {
        ecs_warn() ;
        bft_printf(_("There is/are %d isolated face(s)\n"),
                   liste_fac_isolee->nbr) ;
      }
    }

  }
  else {

    if (liste_fac_erreur != NULL) {
      liste_fac_erreur->nbr = 0 ;
      liste_fac_erreur->val = NULL ;
    }

    if (liste_fac_interne != NULL) {
      liste_fac_interne->nbr = 0 ;
      liste_fac_interne->val = NULL ;
    }

    if (liste_fac_de_bord != NULL) {
      liste_fac_de_bord->nbr = 0 ;
      liste_fac_de_bord->val = NULL ;
    }

    if (liste_fac_isolee != NULL) {
      liste_fac_isolee->nbr = 0 ;
      liste_fac_isolee->val = NULL ;
    }

  }

}


/*----------------------------------------------------------------------------
 *  Fonction qui construit la liste des cellules attachées à une liste
 *  de faces fournie en argument.
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_entmail_pcp__liste_cel_fac
(
       ecs_entmail_t  *const vect_entmail[],
 const ecs_tab_int_t         liste_fac
)
{
  size_t     nbr_fac ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_CEL] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;

  nbr_fac = ecs_champ__ret_pos_nbr
             (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) -1 ;

  return ecs_champ_def__liste_cel_fac
           (nbr_fac,
            vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
            liste_fac) ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui definit de nouvelles entites de maillage principales
 *   par extraction d'une partie des elements
 *   d'une entite de maillage principale donnee
 *  Les elements a extraire sont ceux qui ont un booleen a `ECS_TRUE'
 *
 *  On construit automatiquement une filiation.
 *----------------------------------------------------------------------------*/

ecs_entmail_t * * ecs_entmail_pcp__extrait
(
       ecs_entmail_t    *const vect_entmail[],
       ECS_ENTMAIL_E           entmail_e,
 const ecs_tab_bool_t          bool_elt_select[],
 const ecs_bool_t              herite_attributs
)
{

  ecs_champ_t    *   champ_def_old_new[ECS_ENTMAIL_FIN] ;
  ecs_champ_t    *   champ_att_filiation ;
  size_t             nbr_elt_extrait  ;
  ecs_int_t          ient ;

  ecs_entmail_t  * * vect_entmail_new ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[entmail_e] != NULL) ;


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


  BFT_MALLOC(vect_entmail_new, ECS_ENTMAIL_FIN, ecs_entmail_t *) ;

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

     vect_entmail_new[ient] = NULL ;

  }


  for (ient = (ecs_int_t)entmail_e ;
       ient >= (ecs_int_t)ECS_ENTMAIL_DEB ;
       ient--) {

    vect_entmail_new[ient] = ecs_entmail__cree() ;

  }


  /*--------------------------------------------------------------------------*/
  /* 1ere etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Construction de la connectivite descendante du nouveau maillage extrait  */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/

  /*--------------------------------------------------------------------------*/
  /* 1ere sous-etape : traitement de l'entite de maillage correspondant       */
  /*                   a l'entite de maillage des elements a extraire         */
  /*--------------------------------------------------------------------------*/

  /* Extraction des elements selectionnes de l'entite de maillage             */
  /* (qui sont renumerotes a partir de 1 mais qui sont toujours               */
  /*  definis par les sous-elements non renumerotes)                          */
  /* Creation d'un champ donnant                                              */
  /*  pour chaque ancien numero de l'element avant extraction                 */
  /*  le nouveau numero de l'element selectionne et renumerote a partir de 1  */

  champ_def_old_new[entmail_e]
    = ecs_champ__extrait(&vect_entmail_new[entmail_e]->champ[ECS_CHAMP_DEF],
                         vect_entmail[entmail_e]->champ[ECS_CHAMP_DEF],
                         bool_elt_select[entmail_e]) ;


  /*--------------------------------------------------------------------------*/
  /* 2nde sous-etape : traitement des entites de maillage                     */
  /*                   de dimension inferieure                                */
  /*--------------------------------------------------------------------------*/

  for (ient = (ecs_int_t)entmail_e - 1 ;
       ient >= (ecs_int_t)ECS_ENTMAIL_DEB ;
       ient--) {


    /* Construction de la liste de selection des sous-elements a extraire */

    ecs_champ_def__cree_masque(bool_elt_select[ient],
                               vect_entmail_new[ient+1]->champ[ECS_CHAMP_DEF]);


    /* Extraction des sous-elements selectionnes                              */
    /* Creation d'un champ donnant                                            */
    /*  pour chaque ancien numero du sous-element avant extraction            */
    /*  le nouveau numero du sous-elt selectionne et renumerote a partir de 1 */

    champ_def_old_new[ient]
      = ecs_champ__extrait(&vect_entmail_new[ient]->champ[ECS_CHAMP_DEF],
                           vect_entmail[ient]->champ[ECS_CHAMP_DEF],
                           bool_elt_select[ient]) ;


    /* Remplacement des anciens numeros des sous-elements  */
    /*  par les nouveaux numeros (numerote a partir de 1)  */
    /*  dans la definition des elements                    */

    ecs_champ__remplace_ref(vect_entmail_new[ient+1]->champ[ECS_CHAMP_DEF],
                            champ_def_old_new[ient]) ;

  }



  /*--------------------------------------------------------------------------*/
  /* 2eme etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Construction des autres champs pour les nouveaux elements                */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  for (ient = 0 ; ient <= (ecs_int_t)entmail_e ; ient++) {


    /*------------------------------------------------------------------------*/
    /* 1ere sous-etape : construction des champs principaux                   */
    /*------------------------------------------------------------------------*/

    nbr_elt_extrait
      = ecs_champ__ret_pos_nbr(vect_entmail_new[ient]->champ[ECS_CHAMP_DEF]) -1;


    /*------------------------------------------------------------------------*/
    /* 2eme sous-etape : construction des champs de type "attribut"           */
    /*------------------------------------------------------------------------*/

    if (herite_attributs == ECS_TRUE) {

      vect_entmail_new[ient]->champ[ECS_CHAMP_ATT]
        = ecs_champ_chaine__herite
        (vect_entmail[ient]->champ[ECS_CHAMP_ATT],
         champ_def_old_new[ient],
         vect_entmail_new[ient]->champ[ECS_CHAMP_DEF]) ;

    }


    /*------------------------------------------------------------------------*/
    /* 3eme sous-etape : destruction des anciennes filiations                */
    /*------------------------------------------------------------------------*/

    champ_att_filiation
      = ecs_champ_chaine__trouve_nom
      (vect_entmail_new[ient]->champ[ECS_CHAMP_ATT],
       ECS_CHAMP_NOM_FILIATION) ;

    if (champ_att_filiation != NULL) {

      ecs_champ_chaine__supprime
        (&champ_att_filiation,
         &vect_entmail_new[ient]->champ[ECS_CHAMP_ATT]);

      champ_att_filiation = ecs_champ__detruit(champ_att_filiation) ;

    }


    /*------------------------------------------------------------------------*/
    /* 4eme sous-etape : construction d'un nouvel attribut qui donne,         */
    /*                   pour chaque element de la nouvelle entite extraite,  */
    /*                   la reference de l'element                            */
    /*                   dans l'entite de maillage d'origine                  */
    /*------------------------------------------------------------------------*/

    if (ient == (ecs_int_t)entmail_e) {

      champ_att_filiation
        = ecs_champ_att__filialise(champ_def_old_new[ient],
                                   nbr_elt_extrait) ;

      ecs_entmail__ajoute_champ(vect_entmail_new[ient],
                                champ_att_filiation,
                                ECS_CHAMP_ATT) ;

    }

    ecs_champ__detruit(champ_def_old_new[ient]) ;

  }


  return vect_entmail_new ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui définit de nouvelles entités de maillage principales
 *   en connectivité nodale par extraction d'une partie des éléments
 *   d'une entité de maillage principale donnée
 *  Les éléments à extraire sont ceux qui ont un booleen à `ECS_TRUE'
 *----------------------------------------------------------------------------*/

ecs_entmail_t * * ecs_entmail_pcp__extrait_nodal
(
       ecs_entmail_t    *const vect_entmail[],
       ECS_ENTMAIL_E           entmail_e,
 const ecs_tab_bool_t          bool_elt_select[]

)
{

  ecs_champ_t    *   champ_def_old_new[ECS_ENTMAIL_FIN] ;
  ecs_int_t          ient ;

  ecs_entmail_t  * * vect_entmail_new ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[entmail_e] != NULL) ;


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


  BFT_MALLOC(vect_entmail_new, ECS_ENTMAIL_FIN, ecs_entmail_t *) ;

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

     vect_entmail_new[ient] = NULL ;

  }


  for (ient = (ecs_int_t)entmail_e ;
       ient >= (ecs_int_t)ECS_ENTMAIL_DEB ;
       ient--) {

    vect_entmail_new[ient] = ecs_entmail__cree() ;

  }


  /*--------------------------------------------------------------------------*/
  /* Construction de la connectivité nodale du nouveau maillage extrait       */
  /*--------------------------------------------------------------------------*/

  /* Extraction des éléments selectionnés de l'entité de maillage             */
  /* (qui sont renumérotés à partir de 1 mais qui sont toujours               */
  /*  définis par les sommets non renumerotés)                                */
  /* Création d'un champ donnant                                              */
  /*  pour chaque ancien numéro de l'élément avant extraction                 */
  /*  le nouveau numéro de l'élément selectionné et renumeroté à partir de 1  */

  champ_def_old_new[entmail_e]
    = ecs_champ__extrait(&vect_entmail_new[entmail_e]->champ[ECS_CHAMP_DEF],
                         vect_entmail[entmail_e]->champ[ECS_CHAMP_DEF],
                         bool_elt_select[entmail_e]) ;

  ecs_champ__detruit(champ_def_old_new[entmail_e]) ;


  /*--------------------------------------------------------------------------*/
  /* 2nde sous-etape : traitement des sommets                                 */
  /*--------------------------------------------------------------------------*/

  /* Construction de la liste de selection des sommets a extraire */

  ecs_champ_def__cree_masque(bool_elt_select[ECS_ENTMAIL_SOM],
                             vect_entmail_new[entmail_e]->champ[ECS_CHAMP_DEF]);


  /* Extraction des sommets selectionnés                                      */
  /* Création d'un champ donnant                                              */
  /*  pour chaque ancien numéro du sommet avant extraction                    */
  /*  le nouveau numéro du sommet selectionné et renumeroté à partir de 1     */

  champ_def_old_new[ECS_ENTMAIL_SOM]
    = ecs_champ__extrait
       (&vect_entmail_new[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF],
        vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF],
        bool_elt_select[ECS_ENTMAIL_SOM]) ;


  /* Remplacement des anciens numéros des sommets        */
  /*  par les nouveaux numéros (numérotés à partir de 1) */
  /*  dans la définition des éléments                    */

  ecs_champ__remplace_ref(vect_entmail_new[entmail_e]->champ[ECS_CHAMP_DEF],
                          champ_def_old_new[ECS_ENTMAIL_SOM]) ;

  ecs_champ__detruit(champ_def_old_new[ECS_ENTMAIL_SOM]) ;


  /*--------------------------------------------------------------------------*/
  /* On renvoie l'entité de maillage extraite                                 */
  /*--------------------------------------------------------------------------*/

  return vect_entmail_new ;

}


/*----------------------------------------------------------------------------
 * Fonction qui selectionne les elements des differentes entites principales
 *  ayant une des couleurs de la liste des couleurs
 *  ou appartenant a un des groupes de la liste des groupes
 * Seules sont concernees les entites de type `entmail_sel_e'
 *----------------------------------------------------------------------------*/

ecs_tab_bool_t * ecs_entmail_pcp__selectionne
(
       ecs_entmail_t        *const *const vect_entmail,
       ECS_ENTMAIL_E                      entmail_sel_e,
 const ecs_tab_int_t        *const        liste_filtre,
 const ecs_tab_int_t                      liste_couleur,
 const ecs_tab_char_t                     liste_groupe,
       ecs_bool_t                         inv_selection
)
{

  ecs_tab_bool_t * bool_elt_select ;

  ECS_ENTMAIL_E    entmail_cou_max_e ;
  ECS_ENTMAIL_E    entmail_grp_max_e ;

  size_t         nbr_elt ;

  size_t         iloc ;
  size_t         icou ;
  size_t         igrp ;
  size_t         ielt ;

  ecs_int_t      ient ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  BFT_MALLOC(bool_elt_select, ECS_ENTMAIL_FIN, ecs_tab_bool_t) ;

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

    bool_elt_select[ient].val = NULL ;
    bool_elt_select[ient].nbr = 0 ;

  }


  for (ient = (ecs_int_t)entmail_sel_e ;
       ient >= (ecs_int_t)ECS_ENTMAIL_DEB ;
       ient--) {

    if (vect_entmail[ient] != NULL) {

      nbr_elt
        = ecs_champ__ret_pos_nbr(vect_entmail[ient]->champ[ECS_CHAMP_DEF]) - 1 ;

      BFT_MALLOC(bool_elt_select[ient].val, nbr_elt, ecs_bool_t) ;
      bool_elt_select[ient].nbr = nbr_elt ;

      for (ielt = 0 ; ielt < nbr_elt ; ielt++)
        bool_elt_select[ient].val[ielt] = ECS_FALSE ;

    }
    else {
      bool_elt_select[ient].nbr = 0 ;
      bool_elt_select[ient].val = NULL ;
    }

  }


  if (liste_couleur.nbr == 0 && liste_groupe.nbr == 0) {

    ient = (ecs_int_t)entmail_sel_e ;

    if (liste_filtre == NULL) {

      nbr_elt
        = ecs_champ__ret_pos_nbr(vect_entmail[ient]->champ[ECS_CHAMP_DEF]) - 1 ;

      for (ielt = 0 ; ielt < nbr_elt ; ielt++)
        bool_elt_select[ient].val[ielt] = ECS_TRUE ;

    }
    else {

      for (ielt = 0 ; ielt < liste_filtre->nbr ; ielt++)
        bool_elt_select[ient].val[liste_filtre->val[ielt]] = ECS_TRUE ;

    }

  }


  for (icou = 0 ; icou < liste_couleur.nbr ; icou++) {


    if (icou == 0) {

      if (inv_selection == ECS_FALSE)
        bft_printf(_("  Selected colors:\n\n")) ;
      else if (inv_selection == ECS_TRUE)
        bft_printf(_("  De-selected colors:\n\n")) ;

    }

    bft_printf("    %s %" ECS_FORMAT_ecs_int_t "\n",
              _("Color"), liste_couleur.val[icou]) ;

    entmail_cou_max_e = ecs_loc_entmail_pcp__cree_masq(bool_elt_select,
                                                       liste_filtre,
                                                       vect_entmail,
                                                       entmail_sel_e,
                                                       ECS_CHAMP_NOM_COULEUR,
                                                       liste_couleur.val[icou],
                                                       NULL) ;

    if (entmail_cou_max_e == ECS_ENTMAIL_FIN) {

      if (inv_selection == ECS_FALSE)

        bft_printf(_("\n    There is no selectable element"
                     " with color \"%d\".\n"),
                   (int)(liste_couleur.val[icou])) ;

      else if (inv_selection == ECS_TRUE)

        bft_printf(_("\n    There is no de-selectable element"
                     " with color \"%d\".\n"),
                   (int)(liste_couleur.val[icou])) ;

      if (liste_filtre != NULL)
        bft_printf(_("    (This may be due to the selection's restriction\n"
                     "    to interior or boundary faces).\n\n")) ;
      else
        bft_printf("\n") ;

    }



  } /* Fin de la boucle sur les couleurs selectionnees */


  for (igrp = 0 ; igrp < liste_groupe.nbr ; igrp++) {


    if (igrp == 0) {

      if (liste_couleur.nbr > 0)
        bft_printf("\n\n") ;

      if (inv_selection == ECS_FALSE)
        bft_printf(_("  Selected groups:\n\n")) ;
      else if (inv_selection == ECS_TRUE)
        bft_printf(_("  De-selected groups:\n\n")) ;

    }

    bft_printf("    %s \"%s\"\n", _("Group"),
               liste_groupe.val[igrp]) ;

    entmail_grp_max_e = ecs_loc_entmail_pcp__cree_masq(bool_elt_select,
                                                       liste_filtre,
                                                       vect_entmail,
                                                       entmail_sel_e,
                                                       ECS_CHAMP_NOM_GROUPE,
                                                       0,
                                                       liste_groupe.val[igrp]) ;

    if (entmail_grp_max_e == ECS_ENTMAIL_FIN) {

      if (inv_selection == ECS_FALSE)

        bft_printf(_("\n    There is no selectable element"
                     " belonging to group \"%s\".\n"),
                   liste_groupe.val[igrp]) ;

      else if (inv_selection == ECS_TRUE)

        bft_printf(_("\n    There is no de-selectable element"
                     " belonging to group \"%s\".\n"),
                   liste_groupe.val[igrp]) ;

      if (liste_filtre != NULL)
        bft_printf(_("    (This may be due to the selection's restriction\n"
                     "    to interior or boundary faces).\n\n")) ;
      else
        bft_printf("\n") ;

    }


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


  if (inv_selection == ECS_TRUE) {

    ient = (ecs_int_t)entmail_sel_e ;

    for (ielt = 0 ; ielt < bool_elt_select[ient].nbr ; ielt++)
      bool_elt_select[ient].val[ielt]
        = (bool_elt_select[ient].val[ielt] == ECS_TRUE)
        ? ECS_FALSE : ECS_TRUE ;

    /*
      Désélection éventuelle d'élements à filtrer
      (par exemple, des faces intérieures).
    */

    if (liste_filtre != NULL) {

      ient = (ecs_int_t)entmail_sel_e ;

      for (ielt = 0 ;
           ielt < (size_t)(liste_filtre->val[0]) ;
           ielt++)

        bool_elt_select[ient].val[ielt] = ECS_FALSE ;

      for (iloc = 0 ; iloc < liste_filtre->nbr - 1 ; iloc++) {

        for (ielt = liste_filtre->val[iloc] + 1 ;
             ielt < (size_t)(liste_filtre->val[iloc +1 ]) ;
             ielt++)

          bool_elt_select[ient].val[ielt] = ECS_FALSE ;

      }

      for (ielt = liste_filtre->val[liste_filtre->nbr - 1] + 1 ;
           ielt < bool_elt_select[ient].nbr ;
           ielt++)

        bool_elt_select[ient].val[ielt] = ECS_FALSE ;

    }

  }


  bft_printf("\n") ;

  return bool_elt_select ;

}


/*----------------------------------------------------------------------------
 * Fonction qui construit la liste des éléments de l'entité principale
 *  sélectionnée portant des numéros de familles marqués dans le tableau
 *  indic_famille
 *----------------------------------------------------------------------------*/

ecs_tab_int_t  ecs_entmail_pcp__liste_ent_fam
(
       ecs_entmail_t        *const *const vect_entmail,
       ECS_ENTMAIL_E                      entmail_sel_e,
 const ecs_tab_int_t        *const        liste_filtre,
 const ecs_tab_bool_t       *const        indic_famille
)
{

  ecs_tab_int_t  liste_elt_select ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  liste_elt_select.nbr = 0 ;
  liste_elt_select.val = NULL ;

  if (vect_entmail[entmail_sel_e] != NULL) {

    ecs_champ_t   * champ_famille ;

    champ_famille = ecs_champ_chaine__trouve_nom
                      (vect_entmail[entmail_sel_e]->champ[ECS_CHAMP_ATT],
                       ECS_CHAMP_NOM_FAMILLE) ;

    if (champ_famille != NULL) {

      liste_elt_select
        = ecs_champ_att__liste_elt_fam(champ_famille,
                                       liste_filtre,
                                       indic_famille) ;

    }

  }

  return liste_elt_select ;

}


/*----------------------------------------------------------------------------
 * Fonction qui transforme
 *     la  definition des faces en aretes
 *  en une definition des faces en sommets
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__def_fac_som
(
       ecs_entmail_t *const entmail_fac,
 const ecs_entmail_t *const entmail_are
)
{

  ecs_champ_t * champ_connect_fac_nod ;

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  assert(entmail_fac != NULL) ;
  assert(entmail_are != NULL) ;
  assert(entmail_fac->champ[ECS_CHAMP_DEF] != NULL) ;
  assert(entmail_are->champ[ECS_CHAMP_DEF] != NULL) ;


  champ_connect_fac_nod
    = ecs_champ_def__cree_fac_som(entmail_fac->champ[ECS_CHAMP_DEF],
                                  entmail_are->champ[ECS_CHAMP_DEF]) ;

  ecs_champ__detruit(entmail_fac->champ[ECS_CHAMP_DEF]) ;

  entmail_fac->champ[ECS_CHAMP_DEF] = champ_connect_fac_nod ;

}


/*----------------------------------------------------------------------------
 * Fonction qui calcule les coordonnées min et max du domaine
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__calc_coo_ext
(
 const ecs_entmail_t *const entmail_som
)
{
  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  assert(entmail_som != NULL) ;
  assert(entmail_som->champ[ECS_CHAMP_DEF] != NULL) ;


  ecs_champ_def__calc_coo_ext(entmail_som->champ[ECS_CHAMP_DEF]) ;

}


/*----------------------------------------------------------------------------
 *  Fonction qui modifie les coordonnées du maillage
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__transf_coo
(
 const ecs_entmail_t  *const entmail_som,
 const double                matrice[3][4]
)
{
  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/

  assert(entmail_som != NULL) ;
  assert(entmail_som->champ[ECS_CHAMP_DEF] != NULL) ;


  ecs_champ_def__transf_coo(entmail_som->champ[ECS_CHAMP_DEF],
                            matrice) ;

}


/*----------------------------------------------------------------------------
 * Fonction qui recolle les faces non conformes
 *
 * Les listes des faces nouvelles ou modifiées sont construites (et allouées)
 * ici ; les structures liste_fac_new et liste_fac_mod correspondantes sont
 * donc vides en entrée ; idem pour liste_fac_err qui indiquera les indices
 * des faces pour lesquelles le découpage en sous-faces a échoué
 *
 * On prend en entrée soit le nom d'un champ définissant une "visibilité"
 * entre faces à recoller (par exemple une filiation), ou alors un
 * tableau indicateur de faces sélectionnées.
 * L'un de nom_champ_vis_vis et tab_bool_fac_select doit donc
 * être à NULL, et l'autre non.
 *
 * On renvoie 1 si l'on a effectivement appellé le recollement, 0 sinon
 * (i.e. si la sélection de faces à recoller est vide ou le champ de type
 * "visibilité" est introuvable.
 *----------------------------------------------------------------------------*/

ecs_int_t ecs_entmail_pcp__recolle
(
       ecs_entmail_t    *const *const vect_entmail,
 const char                    *const nom_champ_vis,
       ecs_tab_bool_t          *const tab_bool_fac_select,
       ecs_tab_int_t           *const liste_fac_new,
       ecs_tab_int_t           *const liste_fac_mod,
       ecs_tab_int_t           *const liste_fac_err,
 const ecs_param_rc_t                 param_rc
)
{

  size_t           nbr_fac ;

  ecs_int_t        lng_var_nbr ;

  ecs_bool_t       sel_fac_isolee ;

  size_t           liste_nbr_elt_ent[ECS_ENTMAIL_FIN] ;

  ecs_tab_int_t    tab_fac_de_bord_select ;
  ecs_tab_int_t  * tab_fac_select_aux ;

  ecs_champ_t    * champ_fac_att_tete ;
  ecs_champ_t    * champ_fac_att_suite ;
  ecs_champ_t    * champ_fac_old_new  ;
  ecs_champ_t    * champ_fac_perio ;

  ecs_champ_t    * ptr_champ ;
  ecs_champ_t    * champ_fac_vis ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_ARE] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_SOM] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF] != NULL) ;

  assert(vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_ATT] == NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_ATT] == NULL) ;


  /* Determination des nombres d'elements par entite */

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL)
    liste_nbr_elt_ent[ECS_ENTMAIL_CEL]
      = ecs_champ__ret_pos_nbr
          (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF]) - 1;
  else
    liste_nbr_elt_ent[ECS_ENTMAIL_CEL] = 0 ;

  liste_nbr_elt_ent[ECS_ENTMAIL_FAC]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) - 1 ;

  liste_nbr_elt_ent[ECS_ENTMAIL_ARE]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF]) - 1 ;

  liste_nbr_elt_ent[ECS_ENTMAIL_SOM]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF]) - 1 ;


  /*------------------------------------------------------*/
  /* Creation de la liste des faces de bord selectionnées */
  /*------------------------------------------------------*/

  /* Sélection des faces isolées possible pour recollement
     conforme, pas pour recollement périodique */

  if (param_rc.param_perio == NULL)
    sel_fac_isolee = ECS_TRUE ;
  else
    sel_fac_isolee = ECS_FALSE ;

  if (nom_champ_vis == NULL && tab_bool_fac_select != NULL) {

    tab_fac_de_bord_select
      = ecs_loc_entmail_pcp__recolle_sel(vect_entmail,
                                         tab_bool_fac_select,
                                         sel_fac_isolee) ;

    if (tab_fac_de_bord_select.nbr == 0)
      return 0 ;

    tab_fac_select_aux = &tab_fac_de_bord_select ;

    champ_fac_vis = NULL ;

  }

  else if (nom_champ_vis != NULL && tab_bool_fac_select == NULL) {

    tab_fac_de_bord_select.nbr = 0 ;
    tab_fac_de_bord_select.val = NULL ;

    tab_fac_select_aux = NULL ;

    champ_fac_vis = NULL ;

    ptr_champ = vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT] ;

    if (ptr_champ != NULL)
      champ_fac_vis = ecs_champ_chaine__trouve_nom(ptr_champ,
                                                   nom_champ_vis) ;

    if (champ_fac_vis == 0)
      return 0 ;

    /*
      Message d'information pour l'utilisateur
      (non affiché avant de savoir si on a un champ de "visibilité")
    */

    bft_printf("\n\n%s", _("Joining of non-conforming faces "
                           "based on mesh structure\n"
                           "--------------------------------"
                           "------------------------\n")) ;

  }

  else {

    assert (   (nom_champ_vis == NULL && tab_bool_fac_select != NULL)
            || (nom_champ_vis != NULL && tab_bool_fac_select == NULL)) ;
    return 0 ;

  }

  /*--------------------------------------------------------------------------*/
  /* 1ère étape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Nouvelles définitions :                                                  */
  /* - des sommets                                                            */
  /* - des arêtes  en fonction des sommets                                    */
  /* - des faces   en fonction des arêtes                                     */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  champ_fac_old_new = NULL ;
  champ_fac_perio = NULL ;

  ecs_champ_def__recolle(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF],
                         vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF],
                         vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF],
                         &champ_fac_old_new,
                         &champ_fac_perio,
                         champ_fac_vis,
                         tab_fac_select_aux,
                         liste_fac_new,
                         liste_fac_mod,
                         liste_fac_err,
                         param_rc) ;


  if (tab_fac_select_aux != NULL)
    BFT_FREE(tab_fac_de_bord_select.val) ;

  else if (champ_fac_vis != NULL) {

      /* Le champ de visibilité faces est obsolète et n'a plus lieu d'être */

      ecs_champ_chaine__supprime
        (&champ_fac_vis,
         &(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT])) ;

      ecs_champ__detruit(champ_fac_vis) ;

  }


  /*--------------------------------------------------------------------------*/
  /* 2ème etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Construction des autres champs pour les nouveaux sommets                 */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  liste_nbr_elt_ent[ECS_ENTMAIL_SOM]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF]) - 1 ;


  /*--------------------------------------------------------------------------*/
  /* 3ème etape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Construction des autres champs pour les nouvelles arêtes                 */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  liste_nbr_elt_ent[ECS_ENTMAIL_ARE]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF]) - 1 ;


  /*--------------------------------------------------------------------------*/
  /* 4ème étape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Construction des autres champs pour les nouvelles faces                  */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  liste_nbr_elt_ent[ECS_ENTMAIL_FAC]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) - 1 ;


  /* Construction des champs "attribut" pour les nouvelles faces */
  /*-------------------------------------------------------------*/

  /* On met à jour les champs de type attribut héritables */

  champ_fac_att_tete
    = ecs_champ_chaine__herite
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
         champ_fac_old_new,
         vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;


  /* On met à jour les champs de type attribut non héritable,
     de type ECS_CHAMP_STATUT_REF_ELT (ex : champ_fac_perio)  */

  nbr_fac
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) - 1 ;

  champ_fac_att_suite
    = ecs_champ_chaine__renum
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
         champ_fac_old_new,
         nbr_fac) ;


  ecs_champ_chaine__detruit
    (&vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]) ;

  vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT] = champ_fac_att_tete ;

  if (champ_fac_att_suite != NULL)
    ecs_champ_chaine__ajoute
      (&(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]),
       champ_fac_att_suite) ;


  /* Construction du champ donnant les correspondances des faces périodiques */

  if (param_rc.param_perio != NULL)
      ecs_champ_chaine__ajoute
        (&(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]),
         champ_fac_perio) ;



  /*--------------------------------------------------------------------------*/
  /* 5ème étape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Remplacement des références aux anciennes faces                          */
  /*  par les références aux nouvelles faces dans la définition des cellules  */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL) {

    ecs_champ__remplace_ref(vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                            champ_fac_old_new) ;

  }

  ecs_champ__detruit(champ_fac_old_new) ;


  bft_printf("\n\n  %s\n\n", _("Number of elements after joining")) ;


  lng_var_nbr = (int)strlen(_("Number of selected boundary faces")) ;

  ecs_entmail__aff_nbr_par_ent(liste_nbr_elt_ent,
                               lng_var_nbr) ;


  /* Retour */


  return 1 ;

}


/*----------------------------------------------------------------------------
 *  Fonction ne conservant d'une entité de maillage que les champs
 *  'filiation' et 'type géométrique' (les seuls nécessaires sur les
 *  faces d'un maillage destiné à une coupe après la sortie du maillage
 *  pour le postraitement des variables affectées aux faces)
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__epure_coupe
(
 ecs_entmail_t   *const entmail_coupe
)
{

  ecs_int_t      ichamp ;

  ecs_champ_t  * champ_filiation ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Sortie  des champs à conserver de la liste chaînée */

  champ_filiation = ecs_champ_chaine__trouve_nom
                      (entmail_coupe->champ[ECS_CHAMP_ATT],
                       ECS_CHAMP_NOM_FILIATION) ;

  ecs_champ_chaine__supprime(&champ_filiation,
                             &entmail_coupe->champ[ECS_CHAMP_ATT]) ;


  /* Destruction des listes chaînées de champs */

  for (ichamp = (ecs_int_t) ECS_CHAMP_DEB ;
       ichamp < (ecs_int_t) ECS_CHAMP_FIN ;
       ichamp++)

    ecs_champ_chaine__detruit(&entmail_coupe->champ[ichamp]) ;


  /* Reconstitution de la liste chaînée */

  ecs_champ_chaine__ajoute(&entmail_coupe->champ[ECS_CHAMP_ATT],
                           champ_filiation) ;

}


/*----------------------------------------------------------------------------
 * Fonction qui verifie la cohérence d'un maillage.
 *----------------------------------------------------------------------------*/

ecs_bool_t ecs_entmail_pcp__verif
(
 ecs_entmail_t     *const *const vect_entmail,
 ecs_post_t               *const cas_post
)
{

  size_t            ind_per ;

  size_t            nbr_cel ;
  size_t            nbr_fac ;
  size_t            nbr_som ;

  size_t            nbr_fac_erreur ;
  size_t            nbr_fac_interne ;
  size_t            nbr_fac_de_bord ;
  size_t            nbr_fac_isolee ;

  ecs_tab_int_t     nbr_fac_perio ;
  ecs_tab_int_t     typ_fac_cel ;
  ecs_tab_int_t     indic_erreur_cel ;
  ecs_tab_int_t     liste_fac_erreur ;

  ecs_bool_t        bool_post_verif ;

  ecs_bool_t        bool_coherent ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_CEL] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_ARE] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_SOM] != NULL) ;


  /*------------------------------------------------------------------------*/
  /*                                                                        */
  /* Informations générales pour les calculs de vérification                */
  /*                                                                        */
  /*------------------------------------------------------------------------*/


  bool_coherent = ECS_TRUE ;

  /* Détermination s'il y a lieu de post-traiter ou non */

  bool_post_verif = ECS_FALSE ;

  if (cas_post != NULL) {
    if (cas_post->post_ens == ECS_TRUE
#if defined(HAVE_CGNS)
        || cas_post->post_cgns == ECS_TRUE
#endif
#if defined(HAVE_MED)
        || cas_post->post_med == ECS_TRUE
#endif
        )
      bool_post_verif = ECS_TRUE ;
  }


  /* Détermination du nombre de cellules et de faces */

  nbr_cel = ecs_champ__ret_pos_nbr
              (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF]) - 1 ;

  nbr_fac = ecs_champ__ret_pos_nbr
              (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) - 1 ;

  nbr_som = ecs_champ__ret_pos_nbr
              (vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF]) - 1 ;


  /* Construction des listes de faces */
  /*----------------------------------*/

  typ_fac_cel = ecs_champ_def__typ_fac_cel
                  (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                   vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;

  /* Mise à jour de typ_fac_cel en fonction des périodicités éventuelles */

  ecs_champ_chaine__typ_fac_perio
    (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
     &typ_fac_cel) ;

  ecs_loc_entmail_pcp__listes_fac(&typ_fac_cel,
                                  &liste_fac_erreur,
                                  NULL,
                                  NULL,
                                  NULL) ;

  ecs_loc_entmail_pcp__cpt_typ_fac(&typ_fac_cel,
                                   &nbr_fac_erreur,
                                   &nbr_fac_interne,
                                   &nbr_fac_de_bord,
                                   &nbr_fac_isolee) ;

  if (nbr_fac_erreur > 0)
    bool_coherent = ECS_FALSE ;

  nbr_fac_perio = ecs_champ_chaine__nbr_fac_perio
                    (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT]) ;


  /* Affichage des infos sur les maillage */
  /*--------------------------------------*/

  bft_printf(_("\n\nMain mesh properties\n"
               "--------------------\n\n")) ;

  bft_printf(_("  Number of cells:                            %10d\n"
               "  Number of internal faces:                   %10d\n"),
             (int)nbr_cel,
             (int)nbr_fac_interne) ;


  if (nbr_fac_perio.nbr > 0) {
    bft_printf(_("    including periodic faces:\n")) ;
    for (ind_per = 0 ; ind_per < nbr_fac_perio.nbr ; ind_per++)
      bft_printf(_("      periodicity %3d:                        %10d\n"),
                 (int)(ind_per+1), (int)nbr_fac_perio.val[ind_per]) ;
    BFT_FREE(nbr_fac_perio.val) ;
  }


  bft_printf(_("  Number of boundary faces:                   %10d\n"),
             (int)nbr_fac_de_bord) ;


  if (nbr_som != 0)
    bft_printf(_("  Number of vertices:                         %10d\n"),
               (int)nbr_som) ;


  /* En case de faces avec erreur de connectivité,
     on effectue un post traitement pour analyse de problème */

  if (liste_fac_erreur.nbr > 0 && bool_post_verif == ECS_TRUE) {

    indic_erreur_cel = ecs_champ_def__err_cel_connect
                         (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                          &typ_fac_cel) ;

    ecs_entmail_post__ecr_tab_int(_(ECS_MAILLAGE_NOM_PRINCIPAL),
                                  _("connectivity_error"),
                                  &indic_erreur_cel,
                                  cas_post) ;

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

  }

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

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

  return bool_coherent ;
}


/*----------------------------------------------------------------------------
 * Fonction qui construit les familles
 *----------------------------------------------------------------------------*/

ecs_famille_t * * ecs_entmail_pcp__cree_famille
(
 ecs_entmail_t  *const vect_entmail[]
)
{

  ecs_int_t       ient ;
  ecs_int_t       ifam_ent ;
  ecs_int_t       incr_num_descr ;
  size_t          nbr_elt_ent ;
  ecs_int_t       num_fam_deb ;

  ecs_int_t     * nbr_fam_ent ;
  ecs_int_t     * cpt_elt_fam ;

  ecs_champ_t     * champ_att           = NULL ;
  ecs_champ_t     * champ_att_copie     = NULL ;
  ecs_champ_t     * champ_att_grp       = NULL ;
  ecs_champ_t     * champ_att_grp_copie = NULL ;
  ecs_champ_t     * champ_fam           = NULL ;

  ecs_famille_t * * vect_fam_tete ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  BFT_MALLOC(vect_fam_tete, ECS_FAMILLE_FIN, ecs_famille_t *) ;
  for (ifam_ent = 0 ; ifam_ent < ECS_FAMILLE_FIN ; ifam_ent++)
    vect_fam_tete[ifam_ent] = NULL ;

  BFT_MALLOC(nbr_fam_ent, ECS_FAMILLE_FIN, ecs_int_t) ;
  for (ifam_ent = ECS_FAMILLE_DEB ; ifam_ent < ECS_FAMILLE_FIN ; ifam_ent++)
    nbr_fam_ent[ifam_ent] = 0 ;


  num_fam_deb = 1 ;


  /*------------------------*/
  /* Boucle sur les entites */
  /*------------------------*/

  for (ient = ECS_ENTMAIL_FIN - 1 ; ient >= ECS_ENTMAIL_DEB ; ient--) {

    if (vect_entmail[ient] != NULL) {


      if (vect_entmail[ient]->champ[ECS_CHAMP_ATT] != NULL) {


        /* Recuperation de l'adresse du champ des couleurs */

        champ_att
          = ecs_champ_chaine__trouve_nom
              (vect_entmail[ient]->champ[ECS_CHAMP_ATT],
               ECS_CHAMP_NOM_COULEUR) ;

        if (champ_att != NULL) {

          nbr_elt_ent =
            ecs_champ__ret_pos_nbr(vect_entmail[ient]->champ[ECS_CHAMP_DEF]) -1;
          incr_num_descr = ecs_champ__ret_descr_nbr(champ_att) ;

          champ_att_copie = ecs_champ__copie(champ_att) ;

        }


        /* Recuperation de l'adresse du champ des groupes */

        champ_att_grp
          = ecs_champ_chaine__trouve_nom
              (vect_entmail[ient]->champ[ECS_CHAMP_ATT],
               ECS_CHAMP_NOM_GROUPE) ;

        if (champ_att_grp != NULL) {

          champ_att_grp_copie = ecs_champ__copie(champ_att_grp) ;


          if (champ_att != NULL) {

            /* Incrémentation des valeurs de l'attribut pour les éléments */
            /*  de l'attribut à assembler                                 */

            ecs_champ__incremente_val(champ_att_grp_copie,
                                      incr_num_descr) ;


            /* Assemblage des 2 champs "attribut" en 1 seul champ "attribut" */

            ecs_champ_att__assemble(champ_att_copie,
                                    champ_att_grp_copie,
                                    "attribut") ;

          }
          else {

            nbr_elt_ent = ecs_champ__ret_pos_nbr
                            (vect_entmail[ient]->champ[ECS_CHAMP_DEF]) -1 ;
            champ_att_copie = champ_att_grp_copie ;

          }


        }


        if (champ_att_copie != NULL) {

          /*------------------------------------*/
          /* Construction des familles à partir */
          /*  des champs "attribut" de l'entité */
          /*------------------------------------*/

           champ_fam = ecs_champ_att__construit_fam(champ_att_copie,
                                                   &(vect_fam_tete[ient]),
                                                   nbr_elt_ent,
                                                   num_fam_deb,
                                                   &(nbr_fam_ent[ient]),
                                                   &cpt_elt_fam) ;

          if (nbr_fam_ent[ient] > 0 && champ_fam != NULL)

            ecs_entmail__ajoute_champ(vect_entmail[ient],
                                      champ_fam,
                                      ECS_CHAMP_ATT) ;


          champ_att_copie = ecs_champ__detruit(champ_att_copie) ;


#if 0 && defined(DEBUG) && !defined(NDEBUG)

          if (nbr_fam_ent[ient] > 0) {

            ecs_int_t   ifam ;
            ecs_int_t   cpt_elt_fam_ent[ECS_ENTMAIL_FIN] ;
            ecs_int_t   ind ;


            if (num_fam_deb == 1)
              bft_printf(_("\n"
                           "Families associated with elements:\n"
                           "----------------------------------\n\n")) ;


            for (ind = ECS_ENTMAIL_DEB ; ind < ECS_ENTMAIL_FIN ; ind++)
              cpt_elt_fam_ent[ind] = 0 ;


            /* Affichage des définitions des familles */
            /*----------------------------------------*/

            for (ifam = 0 ;
                 ifam < nbr_fam_ent[ient] ;
                 ifam++) {

              assert(vect_fam_tete[ient] != NULL) ;

              ecs_famille_chaine__affiche(ifam + 1,
                                          vect_fam_tete[ient]) ;

              cpt_elt_fam_ent[ient] = cpt_elt_fam[ifam + num_fam_deb -1] ;

              ecs_entmail__aff_nbr_par_ent(cpt_elt_fam_ent, 0) ;

              cpt_elt_fam_ent[ient] = 0 ;

            }

          }

#endif

          if (cpt_elt_fam != NULL)
            BFT_FREE(cpt_elt_fam) ;

          num_fam_deb += nbr_fam_ent[ient] ;

        }


      } /* Fin : si il y a des champs "attribut" pour cette entité */


    } /* Fin : si cette entité de maillage est à prendre en considération */


  } /* Fin : boucle sur les entités de maillage */


#if 0 && defined(DEBUG) && !defined(NDEBUG)

  if (num_fam_deb > 1)
    bft_printf("\n") ;

#endif


  BFT_FREE(nbr_fam_ent) ;


  /* Retour de la tete de la liste chainee des familles */
  /*----------------------------------------------------*/

  return vect_fam_tete ;


}


/*----------------------------------------------------------------------------
 * Fonction qui detruit le champ attribut déterminé par son nom
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__detruit_att_nom
(
       ecs_entmail_t  *const this_entmail,
 const char           *const nom_champ
)
{

  ecs_champ_t * champ_suppr ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_entmail != NULL) ;


  if (this_entmail->champ[ECS_CHAMP_ATT] != NULL) {

    champ_suppr = ecs_champ_chaine__trouve_nom
                    (this_entmail->champ[ECS_CHAMP_ATT],
                     nom_champ) ;

  }
  else {

    champ_suppr = NULL ;

  }


  if (champ_suppr != NULL) {

    ecs_champ_chaine__supprime(&champ_suppr,
                               &this_entmail->champ[ECS_CHAMP_ATT]) ;

    ecs_champ__detruit(champ_suppr) ;

  }


}


/*----------------------------------------------------------------------------
 * Fonction qui construit les attributs "groupe" et "couleur"
 *  a partir des familles
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__cree_attribut
(
 ecs_entmail_t *const this_entmail,
 ecs_famille_t *const famille
)
{

  ecs_champ_t * champ_couleur ;
  ecs_champ_t * champ_famille ;
  ecs_champ_t * champ_groupe ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_entmail != NULL) ;


  if (this_entmail->champ[ECS_CHAMP_ATT] != NULL) {

    champ_famille = ecs_champ_chaine__trouve_nom
                      (this_entmail->champ[ECS_CHAMP_ATT],
                       ECS_CHAMP_NOM_FAMILLE) ;

  }
  else {

    champ_famille = NULL ;

  }


  if (champ_famille != NULL) {


    /* Creation des champs "couleur" et "groupe" */

    ecs_champ_att__cree_att_fam(champ_famille,
                                famille,
                                &champ_couleur,
                                &champ_groupe) ;


    /* Suppression du champ "famille"             */
    /*  de la liste chainee des champs "attribut" */

    ecs_champ_chaine__supprime(&champ_famille,
                               &this_entmail->champ[ECS_CHAMP_ATT]) ;


    /* Liberation du champ "famille" */

    ecs_champ__detruit(champ_famille) ;


    /* Ajout des champs "couleur" et "groupe"    */
    /*  a la liste chainee des champs "attribut" */

    ecs_champ_chaine__ajoute(&this_entmail->champ[ECS_CHAMP_ATT],
                             champ_couleur) ;

    ecs_champ_chaine__ajoute(&this_entmail->champ[ECS_CHAMP_ATT],
                             champ_groupe) ;

  }


}


/*----------------------------------------------------------------------------
 * Fonction qui supprime les attributs "groupe" et "couleur"
 *----------------------------------------------------------------------------*/

void ecs_entmail_pcp__suppr_attribut
(
 ecs_entmail_t *const this_entmail
)
{

  ecs_int_t     iatt ;
  ecs_champ_t * champ_att ;

  const char  *const nom_att[2] = {ECS_CHAMP_NOM_COULEUR,
                                   ECS_CHAMP_NOM_GROUPE} ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_entmail != NULL) ;

  if (this_entmail->champ[ECS_CHAMP_ATT] != NULL) {

    for (iatt = 0 ; iatt < 2 ; iatt++) {

      champ_att
        = ecs_champ_chaine__trouve_nom(this_entmail->champ[ECS_CHAMP_ATT],
                                       nom_att[iatt]) ;

      if (champ_att != NULL) {

        /* Suppression du champ de la liste chaînée des champs "attribut" */

        ecs_champ_chaine__supprime(&champ_att,
                                   &this_entmail->champ[ECS_CHAMP_ATT]) ;

        /* Liberation du champ */

        ecs_champ__detruit(champ_att) ;

      }

    }

  }

}


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

/*----------------------------------------------------------------------------
 * Fonction locale pour la sélection de faces non conformes à recoller
 *----------------------------------------------------------------------------*/

static ecs_tab_int_t ecs_loc_entmail_pcp__recolle_sel
(
 ecs_entmail_t    *const *const vect_entmail,
 ecs_tab_bool_t          *const tab_bool_fac_select,
 ecs_bool_t                     sel_fac_isolee
)
{

  size_t        cpt_fac_de_bord_select ;
  size_t        ifac ;
  size_t        ifac_bord ;
  size_t        lng_var_nbr ;
  ecs_int_t     num_fac ;

  size_t        liste_nbr_elt_ent[ECS_ENTMAIL_FIN] ;

  ecs_tab_int_t   typ_fac_cel ;
  ecs_tab_int_t   liste_fac_de_bord ;
  ecs_tab_int_t   liste_fac_isolee ;
  ecs_tab_int_t   tab_fac_de_bord_select ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_entmail[ECS_ENTMAIL_FAC] != NULL) ;
  assert(vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF] != NULL) ;


  /* Determination des nombres d'elements par entite */

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL)
    liste_nbr_elt_ent[ECS_ENTMAIL_CEL]
      = ecs_champ__ret_pos_nbr
          (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF]) - 1;
  else
    liste_nbr_elt_ent[ECS_ENTMAIL_CEL] = 0 ;

  liste_nbr_elt_ent[ECS_ENTMAIL_FAC]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) - 1 ;

  liste_nbr_elt_ent[ECS_ENTMAIL_ARE]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_ARE]->champ[ECS_CHAMP_DEF]) - 1 ;

  liste_nbr_elt_ent[ECS_ENTMAIL_SOM]
    = ecs_champ__ret_pos_nbr
        (vect_entmail[ECS_ENTMAIL_SOM]->champ[ECS_CHAMP_DEF]) - 1 ;


  /*--------------------------------------------*/
  /* Construction de la liste des faces de bord */
  /*--------------------------------------------*/

  if (vect_entmail[ECS_ENTMAIL_CEL] != NULL) {

    typ_fac_cel = ecs_champ_def__typ_fac_cel
                    (vect_entmail[ECS_ENTMAIL_CEL]->champ[ECS_CHAMP_DEF],
                     vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_DEF]) ;

    /* Mise à jour de typ_fac_cel en fonction des périodicités éventuelles */

    ecs_champ_chaine__typ_fac_perio
      (vect_entmail[ECS_ENTMAIL_FAC]->champ[ECS_CHAMP_ATT],
       &typ_fac_cel) ;

    ecs_loc_entmail_pcp__listes_fac(&typ_fac_cel,
                                    NULL,
                                    NULL,
                                    &liste_fac_de_bord,
                                    &liste_fac_isolee) ;

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

    /* On met bout à bout les faces de bord et les faces isolees */

    if (sel_fac_isolee == ECS_FALSE) {
      liste_fac_isolee.nbr = 0 ;
      BFT_FREE(liste_fac_isolee.val) ;
    }

    if (liste_fac_isolee.nbr != 0) {

      BFT_REALLOC(liste_fac_de_bord.val,
                  liste_fac_de_bord.nbr + liste_fac_isolee.nbr, ecs_int_t);

      for (ifac = 0 ; ifac < liste_fac_isolee.nbr ; ifac++)
        liste_fac_de_bord.val[liste_fac_de_bord.nbr + ifac]
          = liste_fac_isolee.val[ifac] ;

      liste_fac_de_bord.nbr = liste_fac_de_bord.nbr + liste_fac_isolee.nbr ;

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

    }

  }
  else {

    liste_fac_de_bord.nbr = liste_nbr_elt_ent[ECS_ENTMAIL_FAC] ;
    BFT_MALLOC(liste_fac_de_bord.val, liste_fac_de_bord.nbr, ecs_int_t);
    for (ifac = 0 ; ifac < liste_nbr_elt_ent[ECS_ENTMAIL_FAC] ; ifac++)
      liste_fac_de_bord.val[ifac] = ifac ;

  }


  /*------------------------------------------------------*/
  /* Creation de la liste des faces de bord sélectionnées */
  /*------------------------------------------------------*/

  tab_fac_de_bord_select.nbr = liste_fac_de_bord.nbr ;
  BFT_MALLOC(tab_fac_de_bord_select.val,
             tab_fac_de_bord_select.nbr, ecs_int_t) ;

  cpt_fac_de_bord_select = 0 ;

  for (ifac_bord = 0 ; ifac_bord < liste_fac_de_bord.nbr ; ifac_bord++) {

    num_fac = liste_fac_de_bord.val[ifac_bord] ;

    if (tab_bool_fac_select->val[num_fac] == ECS_TRUE) {

      tab_fac_de_bord_select.val[cpt_fac_de_bord_select++] = num_fac ;

    }

  }

  /* liste_fac_de_bord.val libéré ici, mais                         */
  /* liste_fac_de_bord.nbr utilisé plus tard pour infos utilisateur */
  BFT_FREE(liste_fac_de_bord.val) ;

  BFT_REALLOC(tab_fac_de_bord_select.val, cpt_fac_de_bord_select, ecs_int_t) ;
  tab_fac_de_bord_select.nbr = cpt_fac_de_bord_select ;

  bft_printf("  %s\n\n", _("Number of elements before joining")) ;

  lng_var_nbr = (int)strlen(_("Number of selected boundary faces")) ;

  ecs_entmail__aff_nbr_par_ent(liste_nbr_elt_ent,
                               lng_var_nbr) ;

  bft_printf("    ") ;
  ecs_print_padded_str(_("Number of boundary faces"), lng_var_nbr) ;
  bft_printf(" : %*ld\n", ECS_LNG_AFF_ENT, (long)(liste_fac_de_bord.nbr)) ;

  bft_printf("    ") ;
  ecs_print_padded_str(_("Number of selected boundary faces"), lng_var_nbr) ;
  bft_printf(" : %*ld\n", ECS_LNG_AFF_ENT, (long)(liste_fac_de_bord.nbr)) ;


  /* Renvoie la liste des faces de bord sélectionnées */

  return tab_fac_de_bord_select ;

}


/*----------------------------------------------------------------------------
 * Fonction qui cree des tableaux de booleens par entite principale
 *  Le booleen correspondant a un element de l'entite est a `ECS_TRUE'
 *  si l'element est selectionne par la description donnee.
 * Seules sont concernees les entites de type `entmail_sel_e'
 *----------------------------------------------------------------------------*/

static ECS_ENTMAIL_E ecs_loc_entmail_pcp__cree_masq
(
       ecs_tab_bool_t             *const bool_elt_select,
 const ecs_tab_int_t              *const liste_filtre,
       ecs_entmail_t       *const *const vect_entmail,
       ECS_ENTMAIL_E                     entmail_sel_e,
 const char                       *const nom_champ,
 const ecs_int_t                         descr_ident,
 const char                       *const descr_nom
)
{

  ecs_champ_t   * champ_select ;

  size_t          entmail_nbr_elt_select[ECS_ENTMAIL_FIN] ;
  ECS_ENTMAIL_E   entmail_max_e ;

  ecs_int_t       ient ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


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

    entmail_nbr_elt_select[ient] = 0 ;

  }


  ient = entmail_sel_e ;


  /*------------------------------------------------------------------------*/
  /*                                                                        */
  /* Construction de la liste des elements ayant la description donnee      */
  /*                                                                        */
  /*------------------------------------------------------------------------*/


  champ_select
    = ecs_champ_chaine__trouve_nom(vect_entmail[ient]->champ[ECS_CHAMP_ATT],
                                   nom_champ) ;

  if (champ_select != NULL) {

    entmail_nbr_elt_select[ient]
      = ecs_champ_att__cree_masque(&(bool_elt_select[ient]),
                                   liste_filtre,
                                   champ_select,
                                   descr_ident,
                                   descr_nom) ;

  }


  /* else : rien a faire */


  /* Affichage du nombre d'elements selectionnes par entite */
  /*--------------------------------------------------------*/

  ecs_entmail__aff_nbr_par_ent(entmail_nbr_elt_select,
                               0) ;

  /* Determination de l'entite max */
  /*-------------------------------*/

  if      (entmail_nbr_elt_select[ECS_ENTMAIL_CEL] != 0)
    entmail_max_e = ECS_ENTMAIL_CEL ;
  else if (entmail_nbr_elt_select[ECS_ENTMAIL_FAC] != 0)
    entmail_max_e = ECS_ENTMAIL_FAC ;
  else if (entmail_nbr_elt_select[ECS_ENTMAIL_ARE] != 0)
    entmail_max_e = ECS_ENTMAIL_ARE ;
  else if (entmail_nbr_elt_select[ECS_ENTMAIL_SOM] != 0)
    entmail_max_e = ECS_ENTMAIL_SOM ;
  else
    entmail_max_e = ECS_ENTMAIL_FIN ;

  return entmail_max_e ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui construit les listes de faces internes et de bord, ainsi que
 *  les listes de faces avec erreur de connectivité (i.e. qui appartiennent
 *  à 2 cellules ou plus vu d'un même côté, ou qui sont à la fois entrante
 *  et sortante pour une cellule) et de faces isolées.
 *
 *  Un tableau indiquant le type associé à chaque face (0 pour face isolée,
 *  1 ou 2 pour face de bord, 3 pour face interne, et 4 pour tous les autres
 *  cas (faces voyant au moins deux cellules sur un même côté, d'ou erreur
 *  de connectivité) doit être fourni en entrée.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_pcp__listes_fac
(
 const ecs_tab_int_t  *const typ_fac,
       ecs_tab_int_t  *const liste_fac_erreur,
       ecs_tab_int_t  *const liste_fac_interne,
       ecs_tab_int_t  *const liste_fac_de_bord,
       ecs_tab_int_t  *const liste_fac_isolee
)
{

  ecs_int_t   cpt_fac_erreur ;
  ecs_int_t   cpt_fac_de_bord ;
  ecs_int_t   cpt_fac_interne ;
  ecs_int_t   cpt_fac_isolee ;

  size_t      ifac ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(typ_fac != NULL) ;


  /* Initialisations */

  cpt_fac_erreur  = 0 ;
  cpt_fac_interne = 0 ;
  cpt_fac_de_bord = 0 ;
  cpt_fac_isolee  = 0 ;


  /* Première boucle sur les faces : comptage */
  /*------------------------------------------*/

  for (ifac = 0 ; ifac < typ_fac->nbr ; ifac++) {

    switch(typ_fac->val[ifac]) {

    case 0:
      cpt_fac_isolee++ ;
      break ;

    case 1:
    case 2:
      cpt_fac_de_bord++ ;
      break ;

    case 3:
      cpt_fac_interne++ ;
      break;

    default:
      cpt_fac_erreur++ ;

    }

  }


  /* Initialisation et allocation des listes */

  if (liste_fac_erreur != NULL) {
    liste_fac_erreur->nbr = cpt_fac_erreur ;
    BFT_MALLOC(liste_fac_erreur->val, liste_fac_erreur->nbr, ecs_int_t) ;
  }

  if (liste_fac_interne != NULL) {
    liste_fac_interne->nbr = cpt_fac_interne ;
    BFT_MALLOC(liste_fac_interne->val, liste_fac_interne->nbr, ecs_int_t) ;
  }

  if (liste_fac_de_bord != NULL) {
    liste_fac_de_bord->nbr = cpt_fac_de_bord ;
    BFT_MALLOC(liste_fac_de_bord->val, liste_fac_de_bord->nbr, ecs_int_t) ;
  }

  if (liste_fac_isolee != NULL) {
    liste_fac_isolee->nbr = cpt_fac_isolee ;
    BFT_MALLOC(liste_fac_isolee->val, liste_fac_isolee->nbr, ecs_int_t) ;
  }

  /* Seconde boucle sur les faces : remplissage des listes */
  /*-------------------------------------------------------*/

  cpt_fac_erreur  = 0 ;
  cpt_fac_interne = 0 ;
  cpt_fac_de_bord = 0 ;
  cpt_fac_isolee  = 0 ;

  for (ifac = 0 ; ifac < typ_fac->nbr ; ifac++) {

    switch(typ_fac->val[ifac]) {

    case 3:
      if (liste_fac_interne != NULL)
        liste_fac_interne->val[cpt_fac_interne++] = ifac ;
      break ;

    case 1:
    case 2:
      if (liste_fac_de_bord != NULL)
        liste_fac_de_bord->val[cpt_fac_de_bord++] = ifac ;
      break ;

    case 0:
      if (liste_fac_isolee != NULL)
        liste_fac_isolee->val[cpt_fac_isolee++] = ifac ;
      break ;

    default:
      if (liste_fac_erreur != NULL)
        liste_fac_erreur->val[cpt_fac_erreur++] = ifac ;
      break ;

    }

  }

}


/*----------------------------------------------------------------------------
 *  Fonction qui compte le nombre de faces internes et de bord, ainsi que
 *  le nombre de faces avec erreur de connectivité (i.e. qui appartiennent
 *  à 2 cellules ou plus vu d'un même côté, ou qui sont à la fois entrante
 *  et sortante pour une cellule) et de faces isolées.
 *
 *  Un tableau indiquant le type associé à chaque face (0 pour face isolée,
 *  1 ou 2 pour face de bord, 3 pour face interne, et 4 pour tous les autres
 *  cas (faces voyant au moins deux cellules sur un même côté, d'ou erreur
 *  de connectivité) doit être fourni en entrée.
 *----------------------------------------------------------------------------*/

static void ecs_loc_entmail_pcp__cpt_typ_fac
(
 const ecs_tab_int_t  *const typ_fac,
       size_t         *const nbr_fac_erreur,
       size_t         *const nbr_fac_interne,
       size_t         *const nbr_fac_de_bord,
       size_t         *const nbr_fac_isolee
)
{

  size_t      ifac ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(typ_fac != NULL) ;


  /* Initialisations */

  *nbr_fac_erreur  = 0 ;
  *nbr_fac_interne = 0 ;
  *nbr_fac_de_bord = 0 ;
  *nbr_fac_isolee  = 0 ;


  /* Première boucle sur les faces : comptage */
  /*------------------------------------------*/

  for (ifac = 0 ; ifac < typ_fac->nbr ; ifac++) {

    switch(typ_fac->val[ifac]) {

    case 0:
      *nbr_fac_isolee += 1 ;
      break ;

    case 1:
    case 2:
      *nbr_fac_de_bord += 1 ;
      break ;

    case 3:
      *nbr_fac_interne += 1 ;
      break ;

    default:
      *nbr_fac_erreur += 1 ;

    }

  }

}


Generated by  Doxygen 1.6.0   Back to index